Skip to content

Commit

Permalink
Fn::ImportValue support
Browse files Browse the repository at this point in the history
  • Loading branch information
mweagle committed Oct 1, 2016
1 parent ceff34a commit 9656501
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 0 deletions.
5 changes: 5 additions & 0 deletions func.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@ func unmarshalFunc(data []byte) (Func, error) {
if err := json.Unmarshal(data, &f); err == nil {
return f, nil
}
case "Fn::ImportValue":
f := ImportValueFunc{}
if err := json.Unmarshal(data, &f); err == nil {
return f, nil
}
default:
return nil, UnknownFunctionError{Name: key}
}
Expand Down
43 changes: 43 additions & 0 deletions func_importvalue.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package cloudformation

// ImportValue returns a new instance of ImportValue that imports valueToImport.
func ImportValue(valueToImport string) ImportValueFunc {
return ImportValueFunc{ValueToImport: valueToImport}
}

// ImportValueFunc represents an invocation of the Fn::ImportValue intrinsic.
// The intrinsic function Fn::ImportValue returns the value of an output exported by
// another stack. You typically use this function to create cross-stack references.
// In the following example template snippets, Stack A exports VPC security group
// values and Stack B imports them.
//
// Note
// The following restrictions apply to cross-stack references:
// For each AWS account, Export names must be unique within a region.
// You can't create cross-stack references across different regions. You can
// use the intrinsic function Fn::ImportValue only to import values that
// have been exported within the same region.
// For outputs, the value of the Name property of an Export can't use
// functions (Ref or GetAtt) that depend on a resource.
// Similarly, the ImportValue function can't include functions (Ref or GetAtt)
// that depend on a resource.
// You can't delete a stack if another stack references one of its outputs.
// You can't modify or remove the output value as long as it's referenced by another stack.
//
// See http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-importvalue.html
type ImportValueFunc struct {
ValueToImport string `json:"Fn::ImportValue"`
}

// String returns this reference as a StringExpr
func (r ImportValueFunc) String() *StringExpr {
return &StringExpr{Func: r}
}

// StringList returns this reference as a StringListExpr
func (r ImportValueFunc) StringList() *StringListExpr {
return &StringListExpr{Func: r}
}

var _ StringFunc = ImportValueFunc{}
var _ StringListFunc = ImportValueFunc{}
41 changes: 41 additions & 0 deletions func_importvalue_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package cloudformation

import (
"encoding/json"

. "gopkg.in/check.v1"
)

type ImportValueFuncTest struct{}

var _ = Suite(&ImportValueFuncTest{})

func (testSuite *ImportValueFuncTest) TestRef(c *C) {
inputBuf := `{"Fn::ImportValue" : "sharedValueToImport"}`
f, err := unmarshalFunc([]byte(inputBuf))
c.Assert(err, IsNil)
c.Assert(f.(StringFunc).String(), DeepEquals, ImportValue("sharedValueToImport").String())

// tidy the JSON input
inputStruct := map[string]interface{}{}
_ = json.Unmarshal([]byte(inputBuf), &inputStruct)
expectedBuf, _ := json.Marshal(inputStruct)

buf, err := json.Marshal(f)
c.Assert(err, IsNil)
c.Assert(string(buf), Equals, string(expectedBuf))
}

func (testSuite *ImportValueFuncTest) TestFailures(c *C) {
inputBuf := `{"Fn::ImportValue": {"Fn::ImportValue": "foo"}}`
_, err := unmarshalFunc([]byte(inputBuf))
c.Assert(err, ErrorMatches, "cannot decode function")

inputBuf = `{"Fn::ImportValue": ["1"]}`
_, err = unmarshalFunc([]byte(inputBuf))
c.Assert(err, ErrorMatches, "cannot decode function")

inputBuf = `{"Fn::ImportValue": true}`
_, err = unmarshalFunc([]byte(inputBuf))
c.Assert(err, ErrorMatches, "cannot decode function")
}

0 comments on commit 9656501

Please sign in to comment.