2015-04-10 20:34:46 +02:00
|
|
|
package winrm
|
2015-04-30 18:02:33 +02:00
|
|
|
|
|
|
|
import (
|
2015-05-01 17:08:58 +02:00
|
|
|
"bytes"
|
|
|
|
"io"
|
2015-04-30 18:02:33 +02:00
|
|
|
"regexp"
|
2015-05-01 17:08:58 +02:00
|
|
|
"strconv"
|
2015-04-30 18:02:33 +02:00
|
|
|
"testing"
|
2015-05-01 17:08:58 +02:00
|
|
|
|
|
|
|
"github.com/dylanmei/winrmtest"
|
|
|
|
"github.com/hashicorp/terraform/communicator/remote"
|
2020-11-18 16:06:28 +01:00
|
|
|
"github.com/hashicorp/terraform/internal/legacy/terraform"
|
2015-04-30 18:02:33 +02:00
|
|
|
)
|
|
|
|
|
2015-05-01 17:08:58 +02:00
|
|
|
func newMockWinRMServer(t *testing.T) *winrmtest.Remote {
|
|
|
|
wrm := winrmtest.NewRemote()
|
|
|
|
|
|
|
|
wrm.CommandFunc(
|
2015-05-01 18:33:49 +02:00
|
|
|
winrmtest.MatchText("echo foo"),
|
2015-05-01 17:08:58 +02:00
|
|
|
func(out, err io.Writer) int {
|
|
|
|
out.Write([]byte("foo"))
|
|
|
|
return 0
|
|
|
|
})
|
|
|
|
|
|
|
|
wrm.CommandFunc(
|
2015-05-01 18:33:49 +02:00
|
|
|
winrmtest.MatchPattern(`^echo c29tZXRoaW5n >> ".*"$`),
|
2015-05-01 17:08:58 +02:00
|
|
|
func(out, err io.Writer) int {
|
|
|
|
return 0
|
|
|
|
})
|
|
|
|
|
|
|
|
wrm.CommandFunc(
|
2015-05-01 18:33:49 +02:00
|
|
|
winrmtest.MatchPattern(`^powershell.exe -EncodedCommand .*$`),
|
2015-05-01 17:08:58 +02:00
|
|
|
func(out, err io.Writer) int {
|
|
|
|
return 0
|
|
|
|
})
|
|
|
|
|
|
|
|
wrm.CommandFunc(
|
2015-05-01 18:33:49 +02:00
|
|
|
winrmtest.MatchText("powershell"),
|
2015-05-01 17:08:58 +02:00
|
|
|
func(out, err io.Writer) int {
|
|
|
|
return 0
|
|
|
|
})
|
|
|
|
|
|
|
|
return wrm
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestStart(t *testing.T) {
|
|
|
|
wrm := newMockWinRMServer(t)
|
|
|
|
defer wrm.Close()
|
|
|
|
|
|
|
|
r := &terraform.InstanceState{
|
|
|
|
Ephemeral: terraform.EphemeralState{
|
|
|
|
ConnInfo: map[string]string{
|
|
|
|
"type": "winrm",
|
|
|
|
"user": "user",
|
|
|
|
"password": "pass",
|
|
|
|
"host": wrm.Host,
|
|
|
|
"port": strconv.Itoa(wrm.Port),
|
2015-05-01 18:42:23 +02:00
|
|
|
"timeout": "30s",
|
2015-05-01 17:08:58 +02:00
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
c, err := New(r)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error creating communicator: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
var cmd remote.Cmd
|
|
|
|
stdout := new(bytes.Buffer)
|
|
|
|
cmd.Command = "echo foo"
|
|
|
|
cmd.Stdout = stdout
|
|
|
|
|
|
|
|
err = c.Start(&cmd)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error executing remote command: %s", err)
|
|
|
|
}
|
|
|
|
cmd.Wait()
|
|
|
|
|
|
|
|
if stdout.String() != "foo" {
|
|
|
|
t.Fatalf("bad command response: expected %q, got %q", "foo", stdout.String())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestUpload(t *testing.T) {
|
|
|
|
wrm := newMockWinRMServer(t)
|
|
|
|
defer wrm.Close()
|
|
|
|
|
|
|
|
r := &terraform.InstanceState{
|
|
|
|
Ephemeral: terraform.EphemeralState{
|
|
|
|
ConnInfo: map[string]string{
|
|
|
|
"type": "winrm",
|
|
|
|
"user": "user",
|
|
|
|
"password": "pass",
|
|
|
|
"host": wrm.Host,
|
|
|
|
"port": strconv.Itoa(wrm.Port),
|
|
|
|
"timeout": "30s",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
c, err := New(r)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error creating communicator: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
err = c.Connect(nil)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error connecting communicator: %s", err)
|
|
|
|
}
|
|
|
|
defer c.Disconnect()
|
|
|
|
|
|
|
|
err = c.Upload("C:/Temp/terraform.cmd", bytes.NewReader([]byte("something")))
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error uploading file: %s", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-30 18:02:33 +02:00
|
|
|
func TestScriptPath(t *testing.T) {
|
|
|
|
cases := []struct {
|
|
|
|
Input string
|
|
|
|
Pattern string
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
"/tmp/script.sh",
|
|
|
|
`^/tmp/script\.sh$`,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"/tmp/script_%RAND%.sh",
|
|
|
|
`^/tmp/script_(\d+)\.sh$`,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range cases {
|
2016-06-29 15:58:33 +02:00
|
|
|
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)
|
|
|
|
}
|
2015-04-30 18:02:33 +02:00
|
|
|
output := comm.ScriptPath()
|
|
|
|
|
|
|
|
match, err := regexp.Match(tc.Pattern, []byte(output))
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("bad: %s\n\nerr: %s", tc.Input, err)
|
|
|
|
}
|
|
|
|
if !match {
|
|
|
|
t.Fatalf("bad: %s\n\n%s", tc.Input, output)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-06-29 15:58:33 +02:00
|
|
|
|
2018-03-31 04:05:10 +02:00
|
|
|
func TestNoTransportDecorator(t *testing.T) {
|
|
|
|
wrm := newMockWinRMServer(t)
|
|
|
|
defer wrm.Close()
|
|
|
|
|
|
|
|
r := &terraform.InstanceState{
|
|
|
|
Ephemeral: terraform.EphemeralState{
|
|
|
|
ConnInfo: map[string]string{
|
|
|
|
"type": "winrm",
|
|
|
|
"user": "user",
|
|
|
|
"password": "pass",
|
|
|
|
"host": wrm.Host,
|
|
|
|
"port": strconv.Itoa(wrm.Port),
|
|
|
|
"timeout": "30s",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
c, err := New(r)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error creating communicator: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
err = c.Connect(nil)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error connecting communicator: %s", err)
|
|
|
|
}
|
|
|
|
defer c.Disconnect()
|
|
|
|
|
|
|
|
if c.client.TransportDecorator != nil {
|
|
|
|
t.Fatal("bad TransportDecorator: expected nil, got non-nil")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-31 04:01:49 +02:00
|
|
|
func TestTransportDecorator(t *testing.T) {
|
|
|
|
wrm := newMockWinRMServer(t)
|
|
|
|
defer wrm.Close()
|
|
|
|
|
|
|
|
r := &terraform.InstanceState{
|
|
|
|
Ephemeral: terraform.EphemeralState{
|
|
|
|
ConnInfo: map[string]string{
|
|
|
|
"type": "winrm",
|
|
|
|
"user": "user",
|
|
|
|
"password": "pass",
|
|
|
|
"host": wrm.Host,
|
|
|
|
"port": strconv.Itoa(wrm.Port),
|
|
|
|
"use_ntlm": "true",
|
|
|
|
"timeout": "30s",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
c, err := New(r)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error creating communicator: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
err = c.Connect(nil)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error connecting communicator: %s", err)
|
|
|
|
}
|
|
|
|
defer c.Disconnect()
|
|
|
|
|
|
|
|
if c.client.TransportDecorator == nil {
|
2018-03-31 04:05:10 +02:00
|
|
|
t.Fatal("bad TransportDecorator: expected non-nil, got nil")
|
2018-03-31 04:01:49 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-29 15:58:33 +02:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|