Merge pull request #7413 from hashicorp/b-communicator-rand-seed

communicator/{ssh,winrm}: seed random script paths
This commit is contained in:
Paul Hinze 2016-06-29 10:37:32 -05:00 committed by GitHub
commit 1f7f71461c
4 changed files with 60 additions and 4 deletions

View File

@ -34,6 +34,7 @@ type Communicator struct {
config *sshConfig
conn net.Conn
address string
rand *rand.Rand
}
type sshConfig struct {
@ -68,6 +69,8 @@ func New(s *terraform.InstanceState) (*Communicator, error) {
comm := &Communicator{
connInfo: connInfo,
config: config,
// Seed our own rand source so that script paths are not deterministic
rand: rand.New(rand.NewSource(time.Now().UnixNano())),
}
return comm, nil
@ -185,7 +188,7 @@ func (c *Communicator) Timeout() time.Duration {
func (c *Communicator) ScriptPath() string {
return strings.Replace(
c.connInfo.ScriptPath, "%RAND%",
strconv.FormatInt(int64(rand.Int31()), 10), -1)
strconv.FormatInt(int64(c.rand.Int31()), 10), -1)
}
// Start implementation of communicator.Communicator interface

View File

@ -225,7 +225,18 @@ func TestScriptPath(t *testing.T) {
}
for _, tc := range cases {
comm := &Communicator{connInfo: &connectionInfo{ScriptPath: tc.Input}}
r := &terraform.InstanceState{
Ephemeral: terraform.EphemeralState{
ConnInfo: map[string]string{
"type": "winrm",
"script_path": tc.Input,
},
},
}
comm, err := New(r)
if err != nil {
t.Fatalf("err: %s", err)
}
output := comm.ScriptPath()
match, err := regexp.Match(tc.Pattern, []byte(output))
@ -238,6 +249,20 @@ func TestScriptPath(t *testing.T) {
}
}
func TestScriptPath_randSeed(t *testing.T) {
// Pre GH-4186 fix, this value was the deterministic start the pseudorandom
// chain of unseeded math/rand values for Int31().
staticSeedPath := "/tmp/terraform_1298498081.sh"
c, err := New(&terraform.InstanceState{})
if err != nil {
t.Fatalf("err: %s", err)
}
path := c.ScriptPath()
if path == staticSeedPath {
t.Fatalf("rand not seeded! got: %s", path)
}
}
const testClientPrivateKey = `-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAxOgNXOJ/jrRDxBZTSk2X9otNy9zcpUmJr5ifDi5sy7j2ZiQS
beBt1Wf+tLNWis8Cyq06ttEvjjRuM75yucyD6GrqDTXVCSm4PeOIQeDhPhw26wYZ

View File

@ -24,6 +24,7 @@ type Communicator struct {
connInfo *connectionInfo
client *winrm.Client
endpoint *winrm.Endpoint
rand *rand.Rand
}
// New creates a new communicator implementation over WinRM.
@ -44,6 +45,8 @@ func New(s *terraform.InstanceState) (*Communicator, error) {
comm := &Communicator{
connInfo: connInfo,
endpoint: endpoint,
// Seed our own rand source so that script paths are not deterministic
rand: rand.New(rand.NewSource(time.Now().UnixNano())),
}
return comm, nil
@ -121,7 +124,7 @@ func (c *Communicator) Timeout() time.Duration {
func (c *Communicator) ScriptPath() string {
return strings.Replace(
c.connInfo.ScriptPath, "%RAND%",
strconv.FormatInt(int64(rand.Int31()), 10), -1)
strconv.FormatInt(int64(c.rand.Int31()), 10), -1)
}
// Start implementation of communicator.Communicator interface

View File

@ -131,7 +131,18 @@ func TestScriptPath(t *testing.T) {
}
for _, tc := range cases {
comm := &Communicator{connInfo: &connectionInfo{ScriptPath: tc.Input}}
r := &terraform.InstanceState{
Ephemeral: terraform.EphemeralState{
ConnInfo: map[string]string{
"type": "winrm",
"script_path": tc.Input,
},
},
}
comm, err := New(r)
if err != nil {
t.Fatalf("err: %s", err)
}
output := comm.ScriptPath()
match, err := regexp.Match(tc.Pattern, []byte(output))
@ -143,3 +154,17 @@ func TestScriptPath(t *testing.T) {
}
}
}
func TestScriptPath_randSeed(t *testing.T) {
// Pre GH-4186 fix, this value was the deterministic start the pseudorandom
// chain of unseeded math/rand values for Int31().
staticSeedPath := "C:/Temp/terraform_1298498081.cmd"
c, err := New(&terraform.InstanceState{})
if err != nil {
t.Fatalf("err: %s", err)
}
path := c.ScriptPath()
if path == staticSeedPath {
t.Fatalf("rand not seeded! got: %s", path)
}
}