ref: v0.2.0 straw/straw.go -rw-r--r-- 5.2 KiB View raw
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
// Package straw defines the types and functions central to
// the straw command.
package straw

import (
	"errors"
	"strings"
)

//go:generate esc -o pkg/template/internal/esctpl/gen_templates.go -pkg esctpl templates

const (
	// ResourceConfigFilename is the name of the default resource
	// configuration file.
	ResourceConfigFilename = "straw.toml"

	// FmtStageResourceConfigFilename is the format string to use with
	// the stage as argument to get the stage-specific resource
	// configuration file.
	FmtStageResourceConfigFilename = "straw_%s.toml"
)

// ErrApplyRequired indicates that terraform apply must be
// called for the generated configuration to be applied.
var ErrApplyRequired = errors.New("terraform apply required")

// RunConfig is the configuration specific to an execution
// of the command, such as source and destination directories,
// stage name, etc.
type RunConfig struct {
	Stage   string
	AppName string

	RootDir               string
	TerraformStageDir     string
	TerraformBootstrapDir string

	RunTerraformApply bool
	RunTerraformInit  bool

	TerraformVersionCondition            string
	TerraformAWSProviderVersionCondition string
}

// Terraformer defines the methods to execute terraform commands.
type Terraformer interface {
	Exec(cmd, dir string) error
	Read(file, variable string) (string, error)
}

// CollectedResources is the collection of resources detected
// during the scan of the source directory.
type CollectedResources struct {
	Resources  []Resource
	Generators []Generator
}

// Registries holds the registered services, resources and
// special environment variables (i.e. the
// ${straw.type.id.attribute} references that may be used
// in configurations' environment sections).
type Registries struct {
	Hooks       []Hook
	Services    map[string]Service
	Resources   map[string]Resource
	Environment map[string]string
}

// A Hook is run before scanning directories for Services and
// Resources. It is used to load core configuration, generate
// bootstrap configuration, etc. It can be extended for multiple
// uses that are not services. As the hook typically has access
// to the RunConfig and CollectedResources, it can manipulate
// those types and affect the generation process.
type Hook interface {
	Run() error
}

// Generator defines the method to generate terraform
// configuration for the stage. Hooks and Services can
// register Generators in the CollectedResources, and after
// all hooks and directory scanning is done, the generators are
// called in order.
type Generator interface {
	// Generate receives the directory where generated terraform
	// files should be stored.
	Generate(dir string, reg *Registries) error
}

// A Service represents a serverless service that can be
// generated, e.g. a queue or a topic.
type Service interface {
	EnvVarMapping() map[string]string
	Principal() *PolicyPrincipal
	Scan(src, dist string) error
	Type() string
}

// A Resource is a configured instance of a service. For example,
// in the func service, each function is a resource. This
// interface defines the methods implemented by all services'
// resources.
type Resource interface {
	TypeID() (string, string)
	Service() Service
	GrantAccessFrom(Resource) error
	RequestAccessTo(Resource) error
	PolicyStatement() *PolicyStatement
	TerraformAttr(string) string
}

// A Validator is a type that must validate itself. Typically,
// a Resource is also a Validator, and validates things like
// its ID and Name for invalid characters, and links to other
// resources for existence (using the provided Registries).
type Validator interface {
	Validate(*Registries) error
}

// FormatTypeID formats the type and id into a unique
// identifier.
func FormatTypeID(typ, id string) string {
	if typ == "" && id == "" {
		return ""
	}
	return typ + "_" + id
}

// ParseTypeID parses a unique typID string into its distinct
// type and id parts.
func ParseTypeID(typID string) (string, string) {
	if ix := strings.Index(typID, "_"); ix >= 0 {
		return typID[:ix], typID[ix+1:]
	}
	return "", ""
}

// A Role defines what a resource or identity can do, via
// its attached policy.
type Role struct {
	ID     string
	Name   string
	Policy *Policy
	Tags   map[string]string
}

// A Policy controls access to a resource via its
// statements.
type Policy struct {
	ID         string
	Statements []*PolicyStatement
}

// PolicyEffect is the type of effect carried by the policy.
type PolicyEffect string

// List of supported policy effects.
const (
	Allow PolicyEffect = "Allow"
	Deny  PolicyEffect = "Deny"
)

// PolicyPrincipal identifies a principal (e.g. an AWS Service)
// in a policy.
type PolicyPrincipal struct {
	Type        string
	Identifiers []string
}

// IDOnly returns the main identifier for this policy principal.
func (pp *PolicyPrincipal) IDOnly() string {
	if len(pp.Identifiers) > 0 {
		return pp.Identifiers[0]
	}
	return ""
}

// PolicyCondition represents a condition that must be
// met for a policy to be applied.
type PolicyCondition struct {
	Test     string
	Variable string
	Values   []string
}

// PolicyStatement is a single statement in a policy.
type PolicyStatement struct {
	Sid        string
	Effect     PolicyEffect
	Actions    []string
	Resources  []string
	Principals []*PolicyPrincipal
	Conditions []*PolicyCondition
}