Merge pull request #970 from hashicorp/f-pass-env
Pass environment variables from host to exec based tasks
This commit is contained in:
commit
abcf97e937
|
@ -10,6 +10,18 @@ import (
|
|||
"github.com/hashicorp/nomad/nomad/structs"
|
||||
)
|
||||
|
||||
var (
|
||||
// DefaultEnvBlacklist is the default set of environment variables that are
|
||||
// filtered when passing the environment variables of the host to a task.
|
||||
DefaultEnvBlacklist = strings.Join([]string{
|
||||
"CONSUL_TOKEN",
|
||||
"VAULT_TOKEN",
|
||||
"ATLAS_TOKEN",
|
||||
"AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "AWS_SESSION_TOKEN",
|
||||
"GOOGLE_APPLICATION_CREDENTIALS",
|
||||
}, ",")
|
||||
)
|
||||
|
||||
// RPCHandler can be provided to the Client if there is a local server
|
||||
// to avoid going over the network. If not provided, the Client will
|
||||
// maintain a connection pool to the servers
|
||||
|
|
|
@ -2,6 +2,7 @@ package env
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
|
@ -305,6 +306,39 @@ func (t *TaskEnvironment) AppendEnvvars(m map[string]string) *TaskEnvironment {
|
|||
return t
|
||||
}
|
||||
|
||||
// AppendHostEnvvars adds the host environment variables to the tasks. The
|
||||
// filter parameter can be use to filter host environment from entering the
|
||||
// tasks.
|
||||
func (t *TaskEnvironment) AppendHostEnvvars(filter []string) *TaskEnvironment {
|
||||
hostEnv := os.Environ()
|
||||
if t.Env == nil {
|
||||
t.Env = make(map[string]string, len(hostEnv))
|
||||
}
|
||||
|
||||
// Index the filtered environment variables.
|
||||
index := make(map[string]struct{}, len(filter))
|
||||
for _, f := range filter {
|
||||
index[f] = struct{}{}
|
||||
}
|
||||
|
||||
for _, e := range hostEnv {
|
||||
parts := strings.Split(e, "=")
|
||||
key, value := parts[0], parts[1]
|
||||
|
||||
// Skip filtered environment variables
|
||||
if _, filtered := index[key]; filtered {
|
||||
continue
|
||||
}
|
||||
|
||||
// Don't override the tasks environment variables.
|
||||
if _, existing := t.Env[key]; !existing {
|
||||
t.Env[key] = value
|
||||
}
|
||||
}
|
||||
|
||||
return t
|
||||
}
|
||||
|
||||
func (t *TaskEnvironment) ClearEnvvars() *TaskEnvironment {
|
||||
t.Env = nil
|
||||
return t
|
||||
|
|
|
@ -2,8 +2,10 @@ package env
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/nomad/nomad/mock"
|
||||
|
@ -204,3 +206,22 @@ func TestEnvironment_Interprolate(t *testing.T) {
|
|||
t.Fatalf("env.List() returned %v; want %v", act, exp)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnvironment_AppendHostEnvVars(t *testing.T) {
|
||||
host := os.Environ()
|
||||
if len(host) < 2 {
|
||||
t.Skip("No host environment variables. Can't test")
|
||||
}
|
||||
skip := strings.Split(host[0], "=")[0]
|
||||
env := testTaskEnvironment().
|
||||
AppendHostEnvvars([]string{skip}).
|
||||
Build()
|
||||
|
||||
act := env.EnvMap()
|
||||
if len(act) < 1 {
|
||||
t.Fatalf("Host environment variables not properly set")
|
||||
}
|
||||
if _, ok := act[skip]; ok {
|
||||
t.Fatalf("Didn't filter environment variable %q", skip)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"log"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
|
@ -74,13 +75,18 @@ func (d *ExecDriver) Start(ctx *ExecContext, task *structs.Task) (DriverHandle,
|
|||
if err := mapstructure.WeakDecode(task.Config, &driverConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Get the command to be ran
|
||||
command := driverConfig.Command
|
||||
if err := validateCommand(command, "args"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Create a location to download the artifact.
|
||||
// Set the host environment variables.
|
||||
filter := strings.Split(d.config.ReadDefault("env.blacklist", config.DefaultEnvBlacklist), ",")
|
||||
d.taskEnv.AppendHostEnvvars(filter)
|
||||
|
||||
// Get the task directory for storing the executor logs.
|
||||
taskDir, ok := ctx.AllocDir.TaskDirs[d.DriverContext.taskName]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("Could not find task directory for task: %v", d.DriverContext.taskName)
|
||||
|
|
|
@ -117,6 +117,11 @@ func (d *JavaDriver) Start(ctx *ExecContext, task *structs.Task) (DriverHandle,
|
|||
if err := mapstructure.WeakDecode(task.Config, &driverConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Set the host environment variables.
|
||||
filter := strings.Split(d.config.ReadDefault("env.blacklist", config.DefaultEnvBlacklist), ",")
|
||||
d.taskEnv.AppendHostEnvvars(filter)
|
||||
|
||||
taskDir, ok := ctx.AllocDir.TaskDirs[d.DriverContext.taskName]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("Could not find task directory for task: %v", d.DriverContext.taskName)
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"log"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/go-plugin"
|
||||
|
@ -82,6 +83,10 @@ func (d *RawExecDriver) Start(ctx *ExecContext, task *structs.Task) (DriverHandl
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// Set the host environment variables.
|
||||
filter := strings.Split(d.config.ReadDefault("env.blacklist", config.DefaultEnvBlacklist), ",")
|
||||
d.taskEnv.AppendHostEnvvars(filter)
|
||||
|
||||
bin, err := discover.NomadExecutable()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to find the nomad binary: %v", err)
|
||||
|
|
|
@ -370,6 +370,17 @@ documentation [here](/docs/drivers/index.html)
|
|||
If the whitelist is empty, all drivers are fingerprinted and enabled where
|
||||
applicable.
|
||||
|
||||
* `env.blacklist`: Nomad passes the host environment variables to `exec`,
|
||||
`raw_exec` and `java` tasks. `env.blacklist` is a comma seperated list of
|
||||
environment variable keys not to pass to these tasks. If specified, the
|
||||
defaults are overriden. The following are the default:
|
||||
|
||||
* `CONSUL_TOKEN`
|
||||
* `VAULT_TOKEN`
|
||||
* `ATLAS_TOKEN`
|
||||
* `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `AWS_SESSION_TOKEN`
|
||||
* `GOOGLE_APPLICATION_CREDENTIALS`
|
||||
|
||||
* `fingerprint.whitelist`: A comma separated list of whitelisted fingerprinters.
|
||||
If specified, fingerprinters not in the whitelist will be disabled. If the
|
||||
whitelist is empty, all fingerprinters are used.
|
||||
|
|
Loading…
Reference in New Issue