Skip to content
This repository has been archived by the owner on Sep 22, 2021. It is now read-only.

Commit

Permalink
added env substitution to the cft files..
Browse files Browse the repository at this point in the history
  • Loading branch information
jdamick authored and jdamick committed Aug 29, 2017
1 parent 9a66ec2 commit 0d58d12
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 0 deletions.
9 changes: 9 additions & 0 deletions resources/user-data-env.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
UserData:
"Fn::Base64": !Sub |
#!/bin/bash
yum install -y aws-cfn-bootstrap
${Local::IncludeEnv TEMP_ENV_VAL}
/opt/aws/bin/cfn-init -v --region ${AWS::Region} --stack ${AWS::StackName} --resource ECSLaunchConfiguration
/opt/aws/bin/cfn-signal -e $? --region ${AWS::Region} --stack ${AWS::StackName} --resource ECSAutoScalingGroup
UserData2-${Local::IncludeEnv TEMP_ENV_VAL}:
temp: !Local::IncludeEnv TEMP_ENV_VAL
56 changes: 56 additions & 0 deletions utils/include_env.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package utils

import (
"bufio"
"bytes"
"io"
"os"
"regexp"

log "github.com/Sirupsen/logrus"
)

var (
// Matches literal string: ${Local::IncludeEnv <key>}
// example: ${Local::IncludeEnv HOME}
literalIncludeEnvRe = regexp.MustCompile(`\${[ ]*Local::IncludeEnv[ ]+([[:ascii:]]+)}`)
// Matches tag !Local::IncludeEnv <key>
// for example: !Local::IncludeEnv HOME
valueIncludeEnvTagRe = regexp.MustCompile(`!Local::IncludeEnv[ ]+([[:ascii:]]+)`)
)

func ApplyIncludeEnvDirective(reader io.Reader) []byte {
output := bytes.NewBuffer([]byte{})
scanner := bufio.NewScanner(reader)
for scanner.Scan() {
line := scanner.Bytes()

loc := literalIncludeEnvRe.FindIndex(line)
tagLoc := valueIncludeEnvTagRe.FindIndex(line)

if len(loc) == 2 {
envName := string(literalIncludeEnvRe.FindSubmatch(line)[1])
log.Debugf("loading include env: %s", envName)

output.Write(line[0:loc[0]])
envValue := os.Getenv(envName)
output.WriteString(envValue)
output.Write(line[loc[1]:])

} else if len(tagLoc) == 2 {
envName := string(valueIncludeEnvTagRe.FindSubmatch(line)[1])
log.Debugf("loading include env: %s", envName)

output.Write(line[0:tagLoc[0]])
envValue := os.Getenv(envName)
output.WriteString(envValue)
output.Write(line[tagLoc[1]:])

} else {
output.Write(line)
}

output.WriteByte('\n')
}
return output.Bytes()
}
51 changes: 51 additions & 0 deletions utils/include_env_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//
// Copyright 2016 Capital One Services, LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and limitations under the License.
//
// SPDX-Copyright: Copyright (c) Capital One Services, LLC
// SPDX-License-Identifier: Apache-2.0
//
package utils

import (
"os"
"testing"

"github.com/stretchr/testify/assert"
)

var expectedEnvIncl = `UserData:
"Fn::Base64": !Sub |
#!/bin/bash
yum install -y aws-cfn-bootstrap
something
/opt/aws/bin/cfn-init -v --region ${AWS::Region} --stack ${AWS::StackName} --resource ECSLaunchConfiguration
/opt/aws/bin/cfn-signal -e $? --region ${AWS::Region} --stack ${AWS::StackName} --resource ECSAutoScalingGroup
UserData2-something:
temp: something
`

func TestApplyIncludeEnvDirective(t *testing.T) {
fname := "../resources/" + "user-data-env.yaml"
TemporaryChdir("../resources", func() {
f, err := os.Open(fname)
assert.Nil(t, err)
defer f.Close()
var result []byte
TemporaryEnv("TEMP_ENV_VAL", "something", func() {
result = ApplyIncludeEnvDirective(f)
})

assert.Equal(t, expectedEnvIncl, string(result))
})
}
16 changes: 16 additions & 0 deletions utils/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,3 +315,19 @@ func MaxInt(x, y int) int {
}
return y
}

// testing util

func TemporaryEnv(name, value string, runIt func()) {
old, ok := os.LookupEnv(name)
os.Setenv(name, value)
defer func() {
if !ok {
os.Unsetenv(name)
} else {
os.Setenv(name, old)
}
}()

runIt()
}
28 changes: 28 additions & 0 deletions utils/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@ package utils

import (
"io/ioutil"
"os"
"path/filepath"
"strings"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

const (
Expand Down Expand Up @@ -124,3 +126,29 @@ func TestSpecialFnIncludeLinesMissingFile(t *testing.T) {
assert.Equal(t, valid, string(cftJson))

}

func TestTemporaryEnvNew(t *testing.T) {
const key = "TEMP_ENV_1"
require.Equal(t, "", os.Getenv(key))
TemporaryEnv(key, "asdf", func() {
require.Equal(t, "asdf", os.Getenv(key))
})
require.Equal(t, "", os.Getenv(key))
v, ok := os.LookupEnv(key)
require.False(t, ok)
require.Equal(t, "", v)
}

func TestTemporaryEnvExisting(t *testing.T) {
const key = "TEMP_ENV_2"
os.Setenv(key, "qwerty")

require.Equal(t, "qwerty", os.Getenv(key))
TemporaryEnv(key, "asdf", func() {
require.Equal(t, "asdf", os.Getenv(key))
})
require.Equal(t, "qwerty", os.Getenv(key))
v, ok := os.LookupEnv(key)
require.True(t, ok)
require.Equal(t, "qwerty", v)
}

0 comments on commit 0d58d12

Please sign in to comment.