2edbdfc8be
The e2e framework instantiates clients for Nomad/Consul but the provisioning of the actual Nomad cluster is left to Terraform. The Terraform provisioning process uses `remote-exec` to deploy specific versions of Nomad so that we don't have to bake an AMI every time we want to test a new version. But Terraform treats the resulting instances as immutable, so we can't use the same tooling to update the version of Nomad in-place. This is a prerequisite for upgrade testing. This changeset extends the e2e framework to provide the option of deploying Nomad (and, in the future, Consul/Vault) with specific versions to running infrastructure. This initial implementation is focused on deploying to a single cluster via `ssh` (because that's our current need), but provides interfaces to hook the test run at the start of the run, the start of each suite, or the start of a given test case. Terraform work includes: * provides Terraform output that written to JSON used by the framework to configure provisioning via `terraform output provisioning`. * provides Terraform output that can be used by test operators to configure their shell via `$(terraform output environment)` * drops `remote-exec` provisioning steps from Terraform * makes changes to the deployment scripts to ensure they can be run multiple times w/ different versions against the same host.
86 lines
2.2 KiB
Go
86 lines
2.2 KiB
Go
package provisioning
|
|
|
|
import (
|
|
"encoding/json"
|
|
"io/ioutil"
|
|
"log"
|
|
"path/filepath"
|
|
)
|
|
|
|
// ProvisionerConfigTerraform targets a Terraform cluster by reading the config
|
|
// from a file, as output by 'terraform output provisioning'. Malformed inputs
|
|
// will log.Fatal so that we halt the test run.
|
|
func ProvisionerConfigTerraform(config ProvisionerConfig) *ProvisioningTargets {
|
|
configFile, err := filepath.Abs(config.TerraformConfig)
|
|
if err != nil {
|
|
log.Fatalf("could not find -provision.terraform file: %v", err)
|
|
}
|
|
|
|
file, err := ioutil.ReadFile(configFile)
|
|
if err != nil {
|
|
log.Fatalf("could not read -provision.terraform file: %v", err)
|
|
}
|
|
|
|
targets := &ProvisioningTargets{}
|
|
err = json.Unmarshal(file, &targets)
|
|
if err != nil {
|
|
log.Fatalf("decoding error: %v\n", err)
|
|
}
|
|
|
|
for _, server := range targets.Servers {
|
|
canonicalize(server, config)
|
|
}
|
|
for _, client := range targets.Clients {
|
|
canonicalize(client, config)
|
|
}
|
|
return targets
|
|
}
|
|
|
|
func canonicalize(target *ProvisioningTarget, config ProvisionerConfig) {
|
|
|
|
// allow the '-nomad.*' command line flags to override
|
|
// the values we get from 'terraform output provisioning'
|
|
if config.NomadVersion != "" {
|
|
target.Deployment.NomadVersion = config.NomadVersion
|
|
}
|
|
if config.NomadSha != "" {
|
|
target.Deployment.NomadSha = config.NomadSha
|
|
}
|
|
if config.NomadLocalBinary != "" {
|
|
target.Deployment.NomadLocalBinary = config.NomadLocalBinary
|
|
}
|
|
|
|
if target.Deployment.RemoteBinaryPath == "" {
|
|
log.Fatal("bad runner config for 'remote_binary_path': missing value")
|
|
}
|
|
key, ok := target.Runner["key"].(string)
|
|
if !ok {
|
|
log.Fatalf("bad runner config for 'key': %v", target.Runner)
|
|
}
|
|
user, ok := target.Runner["user"].(string)
|
|
if !ok {
|
|
log.Fatalf("bad runner config for 'user': %v", target.Runner)
|
|
}
|
|
hostname, ok := target.Runner["host"].(string)
|
|
if !ok {
|
|
log.Fatalf("bad runner config for 'host': %v", target.Runner)
|
|
}
|
|
port, ok := target.Runner["port"].(float64)
|
|
if !ok {
|
|
log.Fatalf("bad runner config for 'port': %v", target.Runner)
|
|
}
|
|
|
|
runner := &SSHRunner{
|
|
Key: key,
|
|
User: user,
|
|
Host: hostname,
|
|
Port: int(port),
|
|
}
|
|
if target.Deployment.Platform == "windows_amd64" {
|
|
runner.copyMethod = copyWindows
|
|
} else {
|
|
runner.copyMethod = copyLinux
|
|
}
|
|
target.runner = runner
|
|
}
|