diff --git a/examples/lang/env0.mcl b/examples/lang/env0.mcl new file mode 100644 index 00000000..4e7c7ea6 --- /dev/null +++ b/examples/lang/env0.mcl @@ -0,0 +1,20 @@ +# read and print environment variable +# env TEST=123 EMPTY= ./mgmt run --tmp-prefix --lang=examples/lang/env0.mcl --converged-timeout=5 + +$x = getenv("TEST", "321") + +print "print1" { + msg => printf("the value of the environment variable TEST is: %s", $x), +} + +$y = getenv("DOESNOTEXIT", "321") + +print "print2" { + msg => printf("environment variable DOESNOTEXIT does not exist, defaulting to: %s", $y), +} + +$z = getenv("EMPTY", "456") + +print "print3" { + msg => printf("same goes for epmty variables like EMPTY: %s", $z), +} diff --git a/lang/funcs/simple/env_func.go b/lang/funcs/simple/env_func.go new file mode 100644 index 00000000..55ffa3c1 --- /dev/null +++ b/lang/funcs/simple/env_func.go @@ -0,0 +1,84 @@ +// Mgmt +// Copyright (C) 2013-2018+ James Shubin and the project contributors +// Written by James Shubin and the project contributors +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +package simple // TODO: should this be in its own individual package? + +import ( + "os" + "strings" + + "github.com/purpleidea/mgmt/lang/types" +) + +func init() { + Register("getenv", &types.FuncValue{ + T: types.NewType("func(str) str"), + V: GetEnv, + }) + Register("defaultenv", &types.FuncValue{ + T: types.NewType("func(str, str) str"), + V: DefaultEnv, + }) + Register("hasenv", &types.FuncValue{ + T: types.NewType("func(str) bool"), + V: HasEnv, + }) + Register("env", &types.FuncValue{ + T: types.NewType("func() {str: str}"), + V: Env, + }) +} + +// GetEnv gets environment variable by name or returns empty string if non existing. +func GetEnv(input []types.Value) (types.Value, error) { + return &types.StrValue{ + V: os.Getenv(input[0].Str()), + }, nil +} + +// DefaultEnv gets environment variable by name or returns default if non existing. +func DefaultEnv(input []types.Value) (types.Value, error) { + value, exists := os.LookupEnv(input[0].Str()) + if !exists { + value = input[1].Str() + } + return &types.StrValue{ + V: value, + }, nil +} + +// HasEnv returns true if environment variable exists. +func HasEnv(input []types.Value) (types.Value, error) { + _, exists := os.LookupEnv(input[0].Str()) + return &types.BoolValue{ + V: exists, + }, nil +} + +// Env returns a map of all keys and their values. +func Env(input []types.Value) (types.Value, error) { + environ := make(map[types.Value]types.Value) + for _, keyval := range os.Environ() { + if i := strings.IndexRune(keyval, '='); i != -1 { + environ[&types.StrValue{V: keyval[:i]}] = &types.StrValue{V: keyval[i+1:]} + } + } + return &types.MapValue{ + T: types.NewType("{str: str}"), + V: environ, + }, nil +} diff --git a/test/shell/env0.mcl b/test/shell/env0.mcl new file mode 100644 index 00000000..530d16e4 --- /dev/null +++ b/test/shell/env0.mcl @@ -0,0 +1,19 @@ +$tmpdir = defaultenv("TMPDIR", "/tmp") + +$x = getenv("TEST") +$y = getenv("DOESNOTEXIST") +$z = getenv("EMPTY") + +$a = defaultenv("TEST", "321") +$b = defaultenv("DOESNOTEXIST", "321") +$c = defaultenv("EMPTY", "456") + +$t = hasenv("TEST") +$f = hasenv("DOESNOTEXIST") + +$env = env() +$m = maplookup($env, "TEST", "321") + +file "${tmpdir}/environ" { + content => printf("%s,%s,%s:%s,%s,%s:%t,%t:%s", $x, $y, $z, $a, $b, $c, $t, $f, $m), +} diff --git a/test/shell/env0.sh b/test/shell/env0.sh new file mode 100755 index 00000000..73bb4a24 --- /dev/null +++ b/test/shell/env0.sh @@ -0,0 +1,21 @@ +#!/bin/bash -e + +set -o errexit +set -o pipefail + +. ../util.sh + +# these values represent environment variable values below or defaults set in test/shell/env0.mcl +regex="123,,:123,321,:true,false:123" + +tmpdir="$($mktemp --tmpdir -d tmp.XXX)" + +env TMPDIR="${tmpdir}" TEST=123 EMPTY="" $timeout -sKILL 60s "$MGMT" run --tmp-prefix --converged-timeout=5 --lang env0.mcl +e=$? + +egrep "$regex" "$tmpdir/environ" || fail_test "Could not match '$(cat "$tmpdir/environ")' in '$tmpdir/environ' to '$regex'." + +# cleanup if everything went well +rm -r "$tmpdir" + +exit $e