From b580bba092120362867f37a5a691dc8a1fd00d7c Mon Sep 17 00:00:00 2001 From: Dave Henderson Date: Thu, 8 Jun 2017 20:41:41 -0400 Subject: Namespacing the AWS funcs Signed-off-by: Dave Henderson --- aws/ec2info_test.go | 20 --------------- aws/testutils.go | 37 +++++++++++++++++++++++++++ funcs.go | 56 ++++++++++++++++++++++++++++++++++++++++ funcs/aws.go | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++ funcs/aws_test.go | 21 +++++++++++++++ gomplate.go | 51 +------------------------------------ 6 files changed, 188 insertions(+), 70 deletions(-) create mode 100644 funcs.go create mode 100644 funcs/aws.go create mode 100644 funcs/aws_test.go diff --git a/aws/ec2info_test.go b/aws/ec2info_test.go index c99fe161..3155b9c9 100644 --- a/aws/ec2info_test.go +++ b/aws/ec2info_test.go @@ -8,26 +8,6 @@ import ( "github.com/stretchr/testify/assert" ) -// test doubles -type DummyInstanceDescriber struct { - tags []*ec2.Tag -} - -func (d DummyInstanceDescriber) DescribeInstances(*ec2.DescribeInstancesInput) (*ec2.DescribeInstancesOutput, error) { - output := &ec2.DescribeInstancesOutput{ - Reservations: []*ec2.Reservation{ - { - Instances: []*ec2.Instance{ - { - Tags: d.tags, - }, - }, - }, - }, - } - return output, nil -} - func TestTag_MissingKey(t *testing.T) { server, ec2meta := MockServer(200, `"i-1234"`) defer server.Close() diff --git a/aws/testutils.go b/aws/testutils.go index 32c8d408..188dee7a 100644 --- a/aws/testutils.go +++ b/aws/testutils.go @@ -5,6 +5,8 @@ import ( "net/http" "net/http/httptest" "net/url" + + "github.com/aws/aws-sdk-go/service/ec2" ) // MockServer - @@ -24,3 +26,38 @@ func MockServer(code int, body string) (*httptest.Server, *Ec2Meta) { client := &Ec2Meta{server.URL + "/", httpClient, false, make(map[string]string)} return server, client } + +// NewDummyEc2Info - +func NewDummyEc2Info(metaClient *Ec2Meta) *Ec2Info { + i := &Ec2Info{ + metaClient: metaClient, + describer: func() InstanceDescriber { return DummyInstanceDescriber{} }, + } + return i +} + +// NewDummyEc2Meta - +func NewDummyEc2Meta() *Ec2Meta { + return &Ec2Meta{nonAWS: true} +} + +// DummyInstanceDescriber - test doubles +type DummyInstanceDescriber struct { + tags []*ec2.Tag +} + +// DescribeInstances - +func (d DummyInstanceDescriber) DescribeInstances(*ec2.DescribeInstancesInput) (*ec2.DescribeInstancesOutput, error) { + output := &ec2.DescribeInstancesOutput{ + Reservations: []*ec2.Reservation{ + { + Instances: []*ec2.Instance{ + { + Tags: d.tags, + }, + }, + }, + }, + } + return output, nil +} diff --git a/funcs.go b/funcs.go new file mode 100644 index 00000000..ac790090 --- /dev/null +++ b/funcs.go @@ -0,0 +1,56 @@ +package main + +import ( + "net/url" + "strings" + "text/template" + + "github.com/hairyhenderson/gomplate/funcs" +) + +// initFuncs - The function mappings are defined here! +func initFuncs(data *Data) template.FuncMap { + env := &Env{} + typeconv := &TypeConv{} + stringfunc := &stringFunc{} + + f := template.FuncMap{ + "getenv": env.Getenv, + "bool": typeconv.Bool, + "has": typeconv.Has, + "json": typeconv.JSON, + "jsonArray": typeconv.JSONArray, + "yaml": typeconv.YAML, + "yamlArray": typeconv.YAMLArray, + "toml": typeconv.TOML, + "csv": typeconv.CSV, + "csvByRow": typeconv.CSVByRow, + "csvByColumn": typeconv.CSVByColumn, + "slice": typeconv.Slice, + "indent": typeconv.indent, + "join": typeconv.Join, + "toJSON": typeconv.ToJSON, + "toJSONPretty": typeconv.toJSONPretty, + "toYAML": typeconv.ToYAML, + "toTOML": typeconv.ToTOML, + "toCSV": typeconv.ToCSV, + "contains": strings.Contains, + "hasPrefix": strings.HasPrefix, + "hasSuffix": strings.HasSuffix, + "replaceAll": stringfunc.replaceAll, + "split": strings.Split, + "splitN": strings.SplitN, + "title": strings.Title, + "toUpper": strings.ToUpper, + "toLower": strings.ToLower, + "trim": strings.Trim, + "trimSpace": strings.TrimSpace, + "urlParse": url.Parse, + "datasource": data.Datasource, + "ds": data.Datasource, + "datasourceExists": data.DatasourceExists, + "include": data.include, + } + funcs.AWSFuncs(f) + return f +} diff --git a/funcs/aws.go b/funcs/aws.go new file mode 100644 index 00000000..695922be --- /dev/null +++ b/funcs/aws.go @@ -0,0 +1,73 @@ +package funcs + +import ( + "sync" + + "github.com/hairyhenderson/gomplate/aws" +) + +var ( + af *Funcs + afInit sync.Once +) + +// AWSNS - the aws namespace +func AWSNS() *Funcs { + afInit.Do(func() { af = &Funcs{} }) + return af +} + +// AWSFuncs - +func AWSFuncs(f map[string]interface{}) { + f["aws"] = AWSNS + + // global aliases - for backwards compatibility + f["ec2meta"] = AWSNS().EC2Meta + f["ec2dynamic"] = AWSNS().EC2Dynamic + f["ec2tag"] = AWSNS().EC2Tag + f["ec2region"] = AWSNS().EC2Region +} + +// Funcs - +type Funcs struct { + meta *aws.Ec2Meta + metaInit sync.Once + info *aws.Ec2Info + infoInit sync.Once +} + +// EC2Region - +func (a *Funcs) EC2Region(def ...string) string { + a.metaInit.Do(a.initMeta) + return a.meta.Region(def...) +} + +// EC2Meta - +func (a *Funcs) EC2Meta(key string, def ...string) string { + a.metaInit.Do(a.initMeta) + return a.meta.Meta(key, def...) +} + +// EC2Dynamic - +func (a *Funcs) EC2Dynamic(key string, def ...string) string { + a.metaInit.Do(a.initMeta) + return a.meta.Dynamic(key, def...) +} + +// EC2Tag - +func (a *Funcs) EC2Tag(tag string, def ...string) string { + a.infoInit.Do(a.initInfo) + return a.info.Tag(tag, def...) +} + +func (a *Funcs) initMeta() { + if a.meta == nil { + a.meta = aws.NewEc2Meta() + } +} + +func (a *Funcs) initInfo() { + if a.info == nil { + a.info = aws.NewEc2Info() + } +} diff --git a/funcs/aws_test.go b/funcs/aws_test.go new file mode 100644 index 00000000..4d79d7c2 --- /dev/null +++ b/funcs/aws_test.go @@ -0,0 +1,21 @@ +package funcs + +import ( + "testing" + + "github.com/hairyhenderson/gomplate/aws" + "github.com/stretchr/testify/assert" +) + +func TestNSIsIdempotent(t *testing.T) { + assert.True(t, AWSNS() == AWSNS()) +} +func TestFuncs(t *testing.T) { + m := aws.NewDummyEc2Meta() + i := aws.NewDummyEc2Info(m) + af := &Funcs{meta: m, info: i} + assert.Equal(t, "unknown", af.EC2Region()) + assert.Equal(t, "", af.EC2Meta("foo")) + assert.Equal(t, "", af.EC2Tag("foo")) + assert.Equal(t, "unknown", af.EC2Region()) +} diff --git a/gomplate.go b/gomplate.go index f02c6f14..71530368 100644 --- a/gomplate.go +++ b/gomplate.go @@ -3,11 +3,7 @@ package main import ( "io" "log" - "net/url" - "strings" "text/template" - - "github.com/hairyhenderson/gomplate/aws" ) func (g *Gomplate) createTemplate() *template.Template { @@ -36,55 +32,10 @@ func (g *Gomplate) RunTemplate(text string, out io.Writer) { // NewGomplate - func NewGomplate(data *Data, leftDelim, rightDelim string) *Gomplate { - env := &Env{} - typeconv := &TypeConv{} - stringfunc := &stringFunc{} - ec2meta := aws.NewEc2Meta() - ec2info := aws.NewEc2Info() return &Gomplate{ leftDelim: leftDelim, rightDelim: rightDelim, - funcMap: template.FuncMap{ - "getenv": env.Getenv, - "bool": typeconv.Bool, - "has": typeconv.Has, - "json": typeconv.JSON, - "jsonArray": typeconv.JSONArray, - "yaml": typeconv.YAML, - "yamlArray": typeconv.YAMLArray, - "toml": typeconv.TOML, - "csv": typeconv.CSV, - "csvByRow": typeconv.CSVByRow, - "csvByColumn": typeconv.CSVByColumn, - "slice": typeconv.Slice, - "indent": typeconv.indent, - "join": typeconv.Join, - "toJSON": typeconv.ToJSON, - "toJSONPretty": typeconv.toJSONPretty, - "toYAML": typeconv.ToYAML, - "toTOML": typeconv.ToTOML, - "toCSV": typeconv.ToCSV, - "ec2meta": ec2meta.Meta, - "ec2dynamic": ec2meta.Dynamic, - "ec2tag": ec2info.Tag, - "ec2region": ec2meta.Region, - "contains": strings.Contains, - "hasPrefix": strings.HasPrefix, - "hasSuffix": strings.HasSuffix, - "replaceAll": stringfunc.replaceAll, - "split": strings.Split, - "splitN": strings.SplitN, - "title": strings.Title, - "toUpper": strings.ToUpper, - "toLower": strings.ToLower, - "trim": strings.Trim, - "trimSpace": strings.TrimSpace, - "urlParse": url.Parse, - "datasource": data.Datasource, - "ds": data.Datasource, - "datasourceExists": data.DatasourceExists, - "include": data.include, - }, + funcMap: initFuncs(data), } } -- cgit v1.2.3