Add support for NTLM the WinRM communicator.

WinRM exposes an HTTP transport decorator that can be used for different
authentication schemes.  Windows on Azures requires this if one is to use
the out of the box configuration.
This commit is contained in:
Christopher Boumenot 2016-03-10 10:47:30 -08:00
parent cd83c3f2eb
commit b57ed27352
5 changed files with 33 additions and 22 deletions

2
Godeps/Godeps.json generated
View File

@ -329,7 +329,7 @@
},
{
"ImportPath": "github.com/packer-community/winrmcp/winrmcp",
"Rev": "3d184cea22ee1c41ec1697e0d830ff0c78f7ea97"
"Rev": "f1bcf36a69fa2945e65dd099eee11b560fbd3346"
},
{
"ImportPath": "github.com/pierrec/lz4",

View File

@ -41,6 +41,11 @@ func New(config *Config) (*Communicator, error) {
// Create the client
params := winrm.DefaultParameters()
if config.TransportDecorator != nil {
params.TransportDecorator = config.TransportDecorator
}
params.Timeout = formatDuration(config.Timeout)
client, err := winrm.NewClientWithParameters(
endpoint, config.Username, config.Password, params)
@ -155,5 +160,6 @@ func (c *Communicator) newCopyClient() (*winrmcp.Winrmcp, error) {
Insecure: c.config.Insecure,
OperationTimeout: c.config.Timeout,
MaxOperationsPerShell: 15, // lowest common denominator
TransportDecorator: c.config.TransportDecorator,
})
}

View File

@ -1,16 +1,18 @@
package winrm
import (
"net/http"
"time"
)
// Config is used to configure the WinRM connection
type Config struct {
Host string
Port int
Username string
Password string
Timeout time.Duration
Https bool
Insecure bool
Host string
Port int
Username string
Password string
Timeout time.Duration
Https bool
Insecure bool
TransportDecorator func(*http.Transport) http.RoundTripper
}

View File

@ -3,6 +3,7 @@ package communicator
import (
"errors"
"fmt"
"net/http"
"os"
"time"
@ -32,13 +33,14 @@ type Config struct {
SSHFileTransferMethod string `mapstructure:"ssh_file_transfer_method"`
// WinRM
WinRMUser string `mapstructure:"winrm_username"`
WinRMPassword string `mapstructure:"winrm_password"`
WinRMHost string `mapstructure:"winrm_host"`
WinRMPort int `mapstructure:"winrm_port"`
WinRMTimeout time.Duration `mapstructure:"winrm_timeout"`
WinRMUseSSL bool `mapstructure:"winrm_use_ssl"`
WinRMInsecure bool `mapstructure:"winrm_insecure"`
WinRMUser string `mapstructure:"winrm_username"`
WinRMPassword string `mapstructure:"winrm_password"`
WinRMHost string `mapstructure:"winrm_host"`
WinRMPort int `mapstructure:"winrm_port"`
WinRMTimeout time.Duration `mapstructure:"winrm_timeout"`
WinRMUseSSL bool `mapstructure:"winrm_use_ssl"`
WinRMInsecure bool `mapstructure:"winrm_insecure"`
WinRMTransportDecorator func(*http.Transport) http.RoundTripper
}
// Port returns the port that will be used for access based on config.

View File

@ -124,13 +124,14 @@ func (s *StepConnectWinRM) waitForWinRM(state multistep.StateBag, cancel <-chan
log.Println("[INFO] Attempting WinRM connection...")
comm, err = winrm.New(&winrm.Config{
Host: host,
Port: port,
Username: user,
Password: password,
Timeout: s.Config.WinRMTimeout,
Https: s.Config.WinRMUseSSL,
Insecure: s.Config.WinRMInsecure,
Host: host,
Port: port,
Username: user,
Password: password,
Timeout: s.Config.WinRMTimeout,
Https: s.Config.WinRMUseSSL,
Insecure: s.Config.WinRMInsecure,
TransportDecorator: s.Config.WinRMTransportDecorator,
})
if err != nil {
log.Printf("[ERROR] WinRM connection err: %s", err)