mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-20 11:48:24 -06:00
It appears that the cacert option for the winrm provisioner was not getting passed correctly to the winrm package. Log output showed that CACert was false regardless of configuration. While the validation of the connector looked for cacert, the winrm communicator looked for ca_cert.
124 lines
3.2 KiB
Go
124 lines
3.2 KiB
Go
package winrm
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"path/filepath"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/hashicorp/terraform/communicator/shared"
|
|
"github.com/hashicorp/terraform/terraform"
|
|
"github.com/mitchellh/mapstructure"
|
|
)
|
|
|
|
const (
|
|
// DefaultUser is used if there is no user given
|
|
DefaultUser = "Administrator"
|
|
|
|
// DefaultPort is used if there is no port given
|
|
DefaultPort = 5985
|
|
|
|
// DefaultScriptPath is used as the path to copy the file to
|
|
// for remote execution if not provided otherwise.
|
|
DefaultScriptPath = "C:/Temp/terraform_%RAND%.cmd"
|
|
|
|
// DefaultTimeout is used if there is no timeout given
|
|
DefaultTimeout = 5 * time.Minute
|
|
)
|
|
|
|
// connectionInfo is decoded from the ConnInfo of the resource. These are the
|
|
// only keys we look at. If a KeyFile is given, that is used instead
|
|
// of a password.
|
|
type connectionInfo struct {
|
|
User string
|
|
Password string
|
|
Host string
|
|
Port int
|
|
HTTPS bool
|
|
Insecure bool
|
|
CACert string `mapstructure:"cacert"`
|
|
Timeout string
|
|
ScriptPath string `mapstructure:"script_path"`
|
|
TimeoutVal time.Duration `mapstructure:"-"`
|
|
}
|
|
|
|
// parseConnectionInfo is used to convert the ConnInfo of the InstanceState into
|
|
// a ConnectionInfo struct
|
|
func parseConnectionInfo(s *terraform.InstanceState) (*connectionInfo, error) {
|
|
connInfo := &connectionInfo{}
|
|
decConf := &mapstructure.DecoderConfig{
|
|
WeaklyTypedInput: true,
|
|
Result: connInfo,
|
|
}
|
|
dec, err := mapstructure.NewDecoder(decConf)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if err := dec.Decode(s.Ephemeral.ConnInfo); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Check on script paths which point to the default Windows TEMP folder because files
|
|
// which are put in there very early in the boot process could get cleaned/deleted
|
|
// before you had the change to execute them.
|
|
//
|
|
// TODO (SvH) Needs some more debugging to fully understand the exact sequence of events
|
|
// causing this...
|
|
if strings.HasPrefix(filepath.ToSlash(connInfo.ScriptPath), "C:/Windows/Temp") {
|
|
return nil, fmt.Errorf(
|
|
`Using the C:\Windows\Temp folder is not supported. Please use a different 'script_path'.`)
|
|
}
|
|
|
|
if connInfo.User == "" {
|
|
connInfo.User = DefaultUser
|
|
}
|
|
|
|
// Format the host if needed.
|
|
// Needed for IPv6 support.
|
|
connInfo.Host = shared.IpFormat(connInfo.Host)
|
|
|
|
if connInfo.Port == 0 {
|
|
connInfo.Port = DefaultPort
|
|
}
|
|
if connInfo.ScriptPath == "" {
|
|
connInfo.ScriptPath = DefaultScriptPath
|
|
}
|
|
if connInfo.Timeout != "" {
|
|
connInfo.TimeoutVal = safeDuration(connInfo.Timeout, DefaultTimeout)
|
|
} else {
|
|
connInfo.TimeoutVal = DefaultTimeout
|
|
}
|
|
|
|
return connInfo, nil
|
|
}
|
|
|
|
// safeDuration returns either the parsed duration or a default value
|
|
func safeDuration(dur string, defaultDur time.Duration) time.Duration {
|
|
d, err := time.ParseDuration(dur)
|
|
if err != nil {
|
|
log.Printf("Invalid duration '%s', using default of %s", dur, defaultDur)
|
|
return defaultDur
|
|
}
|
|
return d
|
|
}
|
|
|
|
func formatDuration(duration time.Duration) string {
|
|
h := int(duration.Hours())
|
|
m := int(duration.Minutes()) - h*60
|
|
s := int(duration.Seconds()) - (h*3600 + m*60)
|
|
|
|
res := "PT"
|
|
if h > 0 {
|
|
res = fmt.Sprintf("%s%dH", res, h)
|
|
}
|
|
if m > 0 {
|
|
res = fmt.Sprintf("%s%dM", res, m)
|
|
}
|
|
if s > 0 {
|
|
res = fmt.Sprintf("%s%dS", res, s)
|
|
}
|
|
|
|
return res
|
|
}
|