regentanz 0.3.3 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +268 -0
- data/bin/regentanz +16 -0
- data/lib/regentanz.rb +10 -11
- data/lib/regentanz/cli/common.rb +35 -0
- data/lib/regentanz/cli/compare.rb +85 -0
- data/lib/regentanz/cli/compile.rb +27 -0
- data/lib/regentanz/template_compiler.rb +263 -0
- data/lib/regentanz/version.rb +1 -2
- data/lib/regentanz/yaml-ext.rb +18 -0
- data/spec/regentanz/resources/test/unloaded.rb +11 -0
- data/spec/regentanz/template_compiler_spec.rb +692 -0
- data/spec/spec_helper.rb +2 -0
- metadata +45 -152
- data/.gitignore +0 -5
- data/.rvmrc +0 -4
- data/CHANGELOG.rdoc +0 -26
- data/Gemfile +0 -4
- data/LICENSE +0 -24
- data/README.rdoc +0 -54
- data/Rakefile +0 -23
- data/lib/regentanz/astronomy.rb +0 -69
- data/lib/regentanz/cache.rb +0 -2
- data/lib/regentanz/cache/base.rb +0 -51
- data/lib/regentanz/cache/file.rb +0 -86
- data/lib/regentanz/callbacks.rb +0 -18
- data/lib/regentanz/conditions.rb +0 -3
- data/lib/regentanz/conditions/base.rb +0 -16
- data/lib/regentanz/conditions/current.rb +0 -14
- data/lib/regentanz/conditions/forecast.rb +0 -14
- data/lib/regentanz/configuration.rb +0 -55
- data/lib/regentanz/configurator.rb +0 -22
- data/lib/regentanz/google_weather.rb +0 -151
- data/lib/regentanz/parser.rb +0 -1
- data/lib/regentanz/parser/google_weather.rb +0 -100
- data/lib/regentanz/test_helper.rb +0 -52
- data/regentanz.gemspec +0 -30
- data/test/factories.rb +0 -6
- data/test/support/tmp/.gitignore +0 -1
- data/test/support/valid_response.xml.erb +0 -26
- data/test/test_helper.rb +0 -14
- data/test/unit/astronomy_test.rb +0 -26
- data/test/unit/cache/base_test.rb +0 -53
- data/test/unit/cache/file_test.rb +0 -141
- data/test/unit/callbacks_test.rb +0 -27
- data/test/unit/configuration_test.rb +0 -57
- data/test/unit/current_condition_test.rb +0 -33
- data/test/unit/forecast_condition_test.rb +0 -35
- data/test/unit/google_weather_test.rb +0 -125
- data/test/unit/parser/google_weather_parser_test.rb +0 -71
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 7dd89f8efd4c50cc933e407205c64dd257895ae6
|
4
|
+
data.tar.gz: 57910386c3c39c3c7de7aedd66dc2e133a4cd6a1
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2147f883198e82a80475c32f2610267793fc54a31968974041be14e0d35eb0c4f86bde50c7ec16b99512db6f360ca64e180c96f8d295adc2dbdd27aa56a6cab9
|
7
|
+
data.tar.gz: 61c4ed079798cad6ae1e71d1838fafc4838c714a43e66d7056085eab1857940aadab2e0700052ed114b9f365d51a9e02f8890337cdf5767e52571ffd4a8196d9
|
data/README.md
ADDED
@@ -0,0 +1,268 @@
|
|
1
|
+
# Regentanz
|
2
|
+
|
3
|
+
[![Build Status](https://travis-ci.org/burtcorp/regentanz.png?branch=master)](https://travis-ci.org/burtcorp/regentanz)
|
4
|
+
|
5
|
+
_If you're reading this on GitHub, please note that this is the readme for the development version and that some features described here might not yet have been released. You can find the readme for a specific version via the release tags ([here is an example](https://github.com/burtcorp/regentanz/tree/1.0.0))._
|
6
|
+
|
7
|
+
Regentanz is a compiler and preprocessor for CloudFormation templates. It allows you to split up a template into one file per resource, and also build custom resources that can decrease the complexity of templates.
|
8
|
+
|
9
|
+
> _Looking for Regentanz, Carsten Zimmermann's "Library to access the Google Weather API"? It can still be found at https://github.com/carpodaster/regentanz and if you install v0.3.3 from Rubygems, you'll get that gem._
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
Install it on the command line:
|
14
|
+
|
15
|
+
```shell
|
16
|
+
$ gem install regentanz --version '~> 1.0.0'
|
17
|
+
```
|
18
|
+
|
19
|
+
or add it to your `Gemfile`:
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
gem 'regentanz', '~> 1.0.0'
|
23
|
+
```
|
24
|
+
|
25
|
+
## How to build and run the tests
|
26
|
+
|
27
|
+
The best place to see how to build and run the tests is to look at the `.travis.yml` file, but if you just want to get going run:
|
28
|
+
|
29
|
+
```shell
|
30
|
+
$ bundle
|
31
|
+
$ rake
|
32
|
+
```
|
33
|
+
|
34
|
+
## Examples
|
35
|
+
|
36
|
+
The `examples` directory contains runnable example templates.
|
37
|
+
|
38
|
+
## Usage
|
39
|
+
|
40
|
+
To compile a template you use the `regentanz` command like this:
|
41
|
+
|
42
|
+
```shell
|
43
|
+
$ regentanz compile path/to/template > path/to/compiled/template.json
|
44
|
+
```
|
45
|
+
|
46
|
+
### Template validation
|
47
|
+
|
48
|
+
The compiler will validate the final template with CloudFormation, so you will need to run it with AWS credentials that permit `cloudformation:ValidateTemplate`.
|
49
|
+
|
50
|
+
For the validation to work with templates larger than 51200 bytes you need to specify an S3 bucket in a config file, and need AWS credentials that permit `s3:PutObject` in that bucket.
|
51
|
+
|
52
|
+
To configure a bucket to use for validation of large templates create a file called `.regentanz.yml` in the directory where you will run Regentanz, and add the following:
|
53
|
+
|
54
|
+
```yaml
|
55
|
+
template_url: 's3://some-bucket-name/a_prefix/${TEMPLATE_NAME}.json'
|
56
|
+
```
|
57
|
+
|
58
|
+
You can use `${AWS_REGION}` in the bucket portion, and `${TEMPLATE_NAME}` and `${TIMESTAMP}` in the key portion to create unique URLs. You can, for example, use the buckets that CloudFormation creates for template uploads, like this:
|
59
|
+
|
60
|
+
```yaml
|
61
|
+
template_url: 's3://cf-templates-xyz-${AWS_REGION}/regentanz/${TEMPLATE_NAME}-${TIMESTAMP}.json'
|
62
|
+
```
|
63
|
+
|
64
|
+
Where "xyz" is the unique letter combination for your account.
|
65
|
+
|
66
|
+
### Anatomy of a template
|
67
|
+
|
68
|
+
Just like a CloudFormation template, a Regentanz template consists of conditions, mappings, outputs, parameters, and resources. In contrast with CloudFormation these are not properties of one big JSON or YAML document, but exists as separate files in a directory structure. Each resource has its own file, and there is one file each for conditions, mappings, and parameters. If the template doesn't need conditions, mappings, or parameters these files can be left out.
|
69
|
+
|
70
|
+
The Regentanz compiler will take a directory and output a CloudFormation template in JSON format that can be used with CloudFormation.
|
71
|
+
|
72
|
+
#### Example
|
73
|
+
|
74
|
+
Say you have an application with an auto scaling group, launch configuration, security group, an instance profile, and an IAM role for the instance profile. In a regular CloudFormation template you would declare five different resources in one big JSON or YAML file, but in Regentanz you would instead keep these in five separate files, something like this:
|
75
|
+
|
76
|
+
```
|
77
|
+
my_application/
|
78
|
+
resources/
|
79
|
+
auto_scaling_group.yml
|
80
|
+
iam_role.yml
|
81
|
+
instance_profile.yml
|
82
|
+
launch_configuration.yml
|
83
|
+
security_group.yml
|
84
|
+
```
|
85
|
+
|
86
|
+
You're free to name the files whatever you want, and you can put them in subdirectories too. This is an alternative way to structure the same template:
|
87
|
+
|
88
|
+
```
|
89
|
+
my_application/
|
90
|
+
resources/
|
91
|
+
iam/
|
92
|
+
role.yml
|
93
|
+
instance_profile.yml
|
94
|
+
asg.yml
|
95
|
+
lc.yml
|
96
|
+
sg.yml
|
97
|
+
```
|
98
|
+
|
99
|
+
If you have conditions, mappings, outputs, or parameters you put these in files at the top level:
|
100
|
+
|
101
|
+
my_application/
|
102
|
+
resources/
|
103
|
+
iam/
|
104
|
+
role.yml
|
105
|
+
instance_profile.yml
|
106
|
+
asg.yml
|
107
|
+
lc.yml
|
108
|
+
sg.yml
|
109
|
+
conditions.yml
|
110
|
+
mappings.yml
|
111
|
+
outputs.yml
|
112
|
+
parameters.yml
|
113
|
+
```
|
114
|
+
|
115
|
+
You can use JSON or YAML for your files, and mix between these in the same template.
|
116
|
+
|
117
|
+
The contents of the files is the same thing you would put in a CloudFormation template. In other words, if your CloudFormation looks something like this:
|
118
|
+
|
119
|
+
```yaml
|
120
|
+
Parameters:
|
121
|
+
ServerCount:
|
122
|
+
Type: Number
|
123
|
+
Default: 2
|
124
|
+
MinValue: 0
|
125
|
+
|
126
|
+
Resources:
|
127
|
+
Asg:
|
128
|
+
Type: AWS::EC2::AutoScalingGroup
|
129
|
+
Properties:
|
130
|
+
DesiredCapacity: !Ref ServerCount
|
131
|
+
# …
|
132
|
+
Lc:
|
133
|
+
Type: AWS::EC2::LaunchConfiguration
|
134
|
+
Properties:
|
135
|
+
# …
|
136
|
+
```
|
137
|
+
|
138
|
+
You would put the parameters in `parameters.yml`:
|
139
|
+
|
140
|
+
```yaml
|
141
|
+
Parameters:
|
142
|
+
ServerCount:
|
143
|
+
Type: Number
|
144
|
+
Default: 2
|
145
|
+
MinValue: 0
|
146
|
+
```
|
147
|
+
|
148
|
+
The auto scaling group resource in `resources/asg.yml`:
|
149
|
+
|
150
|
+
```yaml
|
151
|
+
Type: AWS::EC2::AutoScalingGroup
|
152
|
+
Properties:
|
153
|
+
DesiredCapacity: {Ref: DesiredCapacity}
|
154
|
+
# …
|
155
|
+
```
|
156
|
+
|
157
|
+
Unfortunately CloudFormation's YAML syntax for intrinsic functions (e.g. `!Ref`) is not supported, you have to convert it to YAML/JSON (e.g. `{Ref: …}`), like above.
|
158
|
+
|
159
|
+
The launch configuration resource would go in a file called `resources/lc.yml`:
|
160
|
+
|
161
|
+
```yaml
|
162
|
+
Type: AWS::EC2::LaunchConfiguration
|
163
|
+
Properties:
|
164
|
+
# …
|
165
|
+
```
|
166
|
+
|
167
|
+
And when you compile this with the Regentanz compiler you would get the same CloudFormation template back, but in JSON format.
|
168
|
+
|
169
|
+
### Resource references
|
170
|
+
|
171
|
+
The Regentanz compiler will generate resource names based on the relative paths of the files in the template. Currently the scheme is to take the path relative to the root of the template and create a `CamelCase` with no underscores or slashes. You should however not rely on this convention since it could change in the future. Instead you should use two macros provided by Regentanz that work similar to CloudFormation's `Ref` function.
|
172
|
+
|
173
|
+
Wherever you would have used `Ref` in CloudFormation you should use `ResolveRef`, and use the relative path, minus file ending as argument. In the template in the example above you could for example refer to the IAM role with `{ResolveRef: iam/role}`, and the auto scaling group as `{ResolveRef: asg}`.
|
174
|
+
|
175
|
+
In places where you in CloudFormation would have used the name of a resource directly you should use `ResolveName`. For example `{ResolveName: iam/role}` and `{ResolveName: asg}`. Almost the only place you will need `ResolveName` is in `GetAtt`.
|
176
|
+
|
177
|
+
Continuing on the example above the auto scaling group needs to refer to the launch configuration. Using `ResolveRef` that would look like this:
|
178
|
+
|
179
|
+
```yaml
|
180
|
+
Type: AWS::EC2::AutoScalingGroup
|
181
|
+
Properties:
|
182
|
+
LaunchConfigurationName: {ResolveRef: asg}
|
183
|
+
# …
|
184
|
+
```
|
185
|
+
|
186
|
+
## Custom Resources
|
187
|
+
|
188
|
+
If you've written a lot of CloudFormation templates you probably feel like you're constantly repeating yourself. The same patterns appear again and again in multiple templates. To help with this Regentanz lets you write custom resources that can be used in templates and that generate other resources, parameters, mappings, etc. when compiled.
|
189
|
+
|
190
|
+
A custom resource is a Ruby class that lives in the `Regentanz::Resources` module that has a `#compile` method that returns a partial template.
|
191
|
+
|
192
|
+
### Anatomy of a custom resource
|
193
|
+
|
194
|
+
Custom resources will be instantiated by the template compiler and their `#compile` method will be called with the name of the resource and the resource template. The result of this call must be a "template fragment", which is a hash with a `:resources` key, and optionally `:conditions`, `:mappings`, `:outputs`, and `:parameters`. Each of these must be (when specified) a hash that looks like the corresponding CloudFormation structure
|
195
|
+
|
196
|
+
Say you used a custom resource like the following, in a file with the relative path `app/sg.yml`
|
197
|
+
|
198
|
+
```yaml
|
199
|
+
Type: Regentanz::Resources::MySpecialSecurityGroup
|
200
|
+
Properties:
|
201
|
+
Name: special-sg
|
202
|
+
PortsOpenToEveryone:
|
203
|
+
- 22
|
204
|
+
- 80
|
205
|
+
```
|
206
|
+
|
207
|
+
The compiler will, conceptually, do this (`template_fragment` is a the contents of the file):
|
208
|
+
|
209
|
+
```ruby
|
210
|
+
resource = Regentanz::Resources::MyCustomResource
|
211
|
+
result = resource.compile('AppSg', template_fragment)
|
212
|
+
```
|
213
|
+
|
214
|
+
It will then take the result and merge it with the rest of the template.
|
215
|
+
|
216
|
+
This is how you could implement `MySpecialSecurityGroup`:
|
217
|
+
|
218
|
+
```ruby
|
219
|
+
class Regentanz::Resources::MyCustomResource
|
220
|
+
def compile(name, template)
|
221
|
+
ingress_rules = template['Properties']['PortsOpenToEveryone'].map do |port|
|
222
|
+
{'IpProtocol' => 'tcp', 'FromPort' => port, 'ToPort' => port, 'CidrIp' => '0.0.0.0/0'}
|
223
|
+
end
|
224
|
+
{
|
225
|
+
:resources => {
|
226
|
+
name => {
|
227
|
+
'Type' => 'AWS::EC2::SecurityGroup',
|
228
|
+
'Properties' => {
|
229
|
+
'GroupName' => properties['Name'],
|
230
|
+
'SecurityGroupIngress' => ingress_rules
|
231
|
+
}
|
232
|
+
}
|
233
|
+
}
|
234
|
+
}
|
235
|
+
end
|
236
|
+
end
|
237
|
+
```
|
238
|
+
|
239
|
+
You are free to ignore the `name` parameter, but it is strongly recommended that you use it. It is the name Regentanz has generated from the relative path of the file the resource is declared in, so ignoring it will make it harder and more confusing to refer to the resource the custom resource generates. If you generate more than one resource in your template it is recommended that you use `name` as a prefix. For example if you generate an auto scaling group and a launch configuration from the a custom resource generating resources with names like `"#{name}Asg"`, and `"#{name}Lc"` will make it possible to do `{ResolveRef: my_resource/asg}` in another resource.
|
240
|
+
|
241
|
+
If the template fragment returned by `#compile` contains `ResolveRef` or `ResolveName` these will be resolved as expected.
|
242
|
+
|
243
|
+
### Adding custom resources to the load path
|
244
|
+
|
245
|
+
Custom resources must be available on the load path when the template compiler runs. The name of the file must also follow the standard Ruby naming convention, i.e. a resource called `Regentanz::Resources::MyCustomResource` must be declared in a file with the path `regentanz/resources/my_custom_resource.rb`, so that the compiler knows which file to load.
|
246
|
+
|
247
|
+
This can be achieved by manipulating environment variables like `RUBYLIB`, or by packaging your custom resources as a gem, but in most cases the easiest way is to add a config file that tells the template compiler how to modify the load path to be able to load your custom resources.
|
248
|
+
|
249
|
+
You can add a file called `.regentanz.yml` in any parent directory of the directory where you run the compiler. In the file you put a list of paths to add to the Ruby load path:
|
250
|
+
|
251
|
+
```yaml
|
252
|
+
load_path:
|
253
|
+
- path/to/resources
|
254
|
+
- /an/absolute/path
|
255
|
+
```
|
256
|
+
|
257
|
+
Relative paths will be resolved relative to the config file.
|
258
|
+
|
259
|
+
The config file above will allow the template compiler to find custom resources in files such as `path/to/resources/regentanz/resources/my_custom_resource.rb` (relative to the config file) and `/an/absolute/path/regentanz/resources/my_custom_resource.rb`.
|
260
|
+
|
261
|
+
## Limitations
|
262
|
+
|
263
|
+
* Regentanz unfortunately does not support CloudFormation's YAML syntax for intrinsic functions.
|
264
|
+
* The support for validating large templates is currently broken.
|
265
|
+
|
266
|
+
# Copyright
|
267
|
+
|
268
|
+
© 2015-2018 Burt AB, see LICENSE.txt (BSD 3-Clause).
|
data/bin/regentanz
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$LOAD_PATH << File.expand_path('../../lib', __FILE__)
|
4
|
+
|
5
|
+
require 'regentanz/yaml-ext'
|
6
|
+
|
7
|
+
case ARGV.first
|
8
|
+
when 'compare'
|
9
|
+
ARGV.shift
|
10
|
+
require 'regentanz/cli/compare'
|
11
|
+
exit(Regentanz::Cli::Compare.new.run(ARGV))
|
12
|
+
else
|
13
|
+
ARGV.shift if ARGV.first == 'compile'
|
14
|
+
require 'regentanz/cli/compile'
|
15
|
+
exit(Regentanz::Cli::Compile.new.run(ARGV))
|
16
|
+
end
|
data/lib/regentanz.rb
CHANGED
@@ -1,11 +1,10 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
3
|
-
require '
|
4
|
-
require '
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
require 'regentanz/
|
11
|
-
require 'regentanz/google_weather'
|
1
|
+
require 'json'
|
2
|
+
require 'yaml'
|
3
|
+
require 'aws-sdk-s3'
|
4
|
+
require 'aws-sdk-cloudformation'
|
5
|
+
|
6
|
+
module Regentanz
|
7
|
+
Error = Class.new(StandardError)
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'regentanz/template_compiler'
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Regentanz
|
4
|
+
module Cli
|
5
|
+
module Common
|
6
|
+
private def load_config
|
7
|
+
if (path = find_config('.'))
|
8
|
+
config = YAML.load_file(path)
|
9
|
+
Array(config['load_path']).each do |extra_load_path|
|
10
|
+
if extra_load_path.start_with?('/')
|
11
|
+
$LOAD_PATH << extra_load_path
|
12
|
+
else
|
13
|
+
$LOAD_PATH << File.absolute_path(extra_load_path, File.dirname(path))
|
14
|
+
end
|
15
|
+
end
|
16
|
+
if config['default_region'].nil? && (region = ENV['AWS_REGION'] || ENV['AWS_DEFAULT_REGION'])
|
17
|
+
config['default_region'] = region
|
18
|
+
end
|
19
|
+
config
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private def find_config(path)
|
24
|
+
candidates = Dir[File.join(path, '.regentanz.{yaml,yml,json}')]
|
25
|
+
if candidates.first
|
26
|
+
candidates.first
|
27
|
+
elsif path != '/'
|
28
|
+
find_config(File.expand_path(File.join(path, '..')))
|
29
|
+
else
|
30
|
+
nil
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'regentanz'
|
2
|
+
require 'regentanz/cli/common'
|
3
|
+
|
4
|
+
module Regentanz
|
5
|
+
module Cli
|
6
|
+
class Diff
|
7
|
+
def initialize(new_object, old_object)
|
8
|
+
@new_object = new_object
|
9
|
+
@old_object = old_object
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_json(*args)
|
13
|
+
%(\e[31m#{@old_object.to_json(*args)}\e[m\e[32m#{@new_object.to_json(*args)}\e[m)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Compare
|
18
|
+
include Common
|
19
|
+
|
20
|
+
def run(args)
|
21
|
+
config = load_config
|
22
|
+
stack_name, stack_path, _ = *args
|
23
|
+
compiler = TemplateCompiler.new(config)
|
24
|
+
new_template = compiler.compile_from_path(stack_path)
|
25
|
+
compiler.validate_template(stack_path, new_template.to_json)
|
26
|
+
old_template = get_template(config, stack_name)
|
27
|
+
diff = compare(new_template, old_template)
|
28
|
+
if diff.to_json != new_template.to_json
|
29
|
+
output = JSON.pretty_generate(diff)
|
30
|
+
puts(output)
|
31
|
+
1
|
32
|
+
else
|
33
|
+
0
|
34
|
+
end
|
35
|
+
rescue Regentanz::Error => e
|
36
|
+
$stderr.puts(e.message)
|
37
|
+
2
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def get_template(config, stack_name)
|
43
|
+
cf_client = Aws::CloudFormation::Client.new(region: config['default_region'])
|
44
|
+
YAML.load(cf_client.get_template(stack_name: stack_name)[:template_body])
|
45
|
+
rescue Aws::Errors::MissingCredentialsError => e
|
46
|
+
raise Regentanz::Error, 'Retrieving template requires AWS credentials', e.backtrace
|
47
|
+
end
|
48
|
+
|
49
|
+
def compare(new_template, old_template)
|
50
|
+
if new_template.is_a?(Date) && old_template.is_a?(String)
|
51
|
+
new_template = new_template.to_s
|
52
|
+
end
|
53
|
+
if new_template.class != old_template.class
|
54
|
+
Diff.new(new_template, old_template)
|
55
|
+
else
|
56
|
+
case new_template
|
57
|
+
when Hash
|
58
|
+
result = {}
|
59
|
+
new_template.each do |(key, value)|
|
60
|
+
result[key] = compare(value, old_template[key])
|
61
|
+
end
|
62
|
+
old_template.each do |(key, value)|
|
63
|
+
result[key] = compare(nil, value) unless new_template.key?(key)
|
64
|
+
end
|
65
|
+
result
|
66
|
+
when Array
|
67
|
+
if new_template.size != old_template.size
|
68
|
+
Diff.new(new_template, old_template)
|
69
|
+
else
|
70
|
+
new_template.zip(old_template).map do |(left, right)|
|
71
|
+
compare(left, right)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
else
|
75
|
+
if new_template == old_template
|
76
|
+
new_template
|
77
|
+
else
|
78
|
+
Diff.new(new_template, old_template)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'regentanz'
|
2
|
+
require 'regentanz/cli/common'
|
3
|
+
|
4
|
+
module Regentanz
|
5
|
+
module Cli
|
6
|
+
class Compile
|
7
|
+
include Common
|
8
|
+
|
9
|
+
def run(args)
|
10
|
+
config = load_config
|
11
|
+
stack_path = args.first
|
12
|
+
compiler = Regentanz::TemplateCompiler.new(config)
|
13
|
+
template = compiler.compile_from_path(stack_path)
|
14
|
+
template_json = JSON.pretty_generate(template)
|
15
|
+
if template_json.bytesize >= 51200
|
16
|
+
template_json = JSON.generate(template)
|
17
|
+
end
|
18
|
+
compiler.validate_template(stack_path, template_json)
|
19
|
+
puts(template_json)
|
20
|
+
0
|
21
|
+
rescue Regentanz::Error => e
|
22
|
+
$stderr.puts(e.message)
|
23
|
+
1
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|