cps-property-generator 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +115 -0
- data/bin/cps-property-generator +45 -0
- data/lib/generator/config.rb +32 -0
- data/lib/generator/generator.rb +50 -0
- data/lib/generator/globals.rb +85 -0
- data/lib/generator/service.rb +89 -0
- data/lib/helpers/helpers.rb +81 -0
- data/lib/linter/config_linter.rb +106 -0
- data/lib/linter/globals_linter.rb +84 -0
- data/lib/linter/linter.rb +35 -0
- data/lib/linter/report.rb +76 -0
- data/lib/linter/services_linter.rb +186 -0
- data/spec/lib/config_spec.rb +35 -0
- data/spec/lib/global_spec.rb +28 -0
- data/spec/lib/service_spec.rb +35 -0
- data/spec/resources/config/config.yml +23 -0
- data/spec/resources/globals/accounts/123456789012/123456789012.yml +1 -0
- data/spec/resources/globals/accounts/123456789012/environments/my-test-env1.yml +1 -0
- data/spec/resources/globals/globals.yml +1 -0
- data/spec/resources/services/my-microservice-1.yml +16 -0
- data/spec/spec_helper.rb +85 -0
- metadata +136 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b480ea73120071abacc074c6279e1da3b9f62d53
|
4
|
+
data.tar.gz: e2092c1a6218e51058d1ff049cca4e4bc8f19ddd
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f8ceb169740e2ebfb3c0d26379f690507954b166a674081b60080556ecc7994ae9ad4aa0f8856cc4748e81ed89c8730a27e185da864a7679532377d77a642e3b
|
7
|
+
data.tar.gz: b9d8808e6608a4dc7dd0f5625401fba02083d8141f3aca8e97e9472d0246c7ed494f559c5450e3d26dc6b318eaa258a7881fb53719c6e7315e65cdea41a7f682
|
data/README.md
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
## **Getting Started**
|
2
|
+
|
3
|
+
#### Creating your properties project:
|
4
|
+
##### Step 1: Creating your config.yml
|
5
|
+
1. Create your top level directory for your property project.
|
6
|
+
|
7
|
+
`mkdir example-properties`
|
8
|
+
|
9
|
+
2. Create a config directory and inside a config.yml file.
|
10
|
+
|
11
|
+
```sh
|
12
|
+
cd example-properties/
|
13
|
+
mkdir config
|
14
|
+
cd config
|
15
|
+
touch config.yml
|
16
|
+
```
|
17
|
+
|
18
|
+
The config.yml will define essential configurations that the generator needs to create the property json files.
|
19
|
+
In the config.yml file we need three keys set to explain our project to the generator.
|
20
|
+
|
21
|
+
1. The `environments` key. This key will define a array of the environments that we are setting properties for. Environments must be unique and have a one to one mapping with amazon aws regions.
|
22
|
+
2. The `accounts` key. This key will define a array of amazon accounts properties will be uploaded to and served in.
|
23
|
+
3. The `environment_configs` key. This key will define three things.
|
24
|
+
* The one to one mapping or aws regions to environments.
|
25
|
+
* The account a environment lives in.
|
26
|
+
* Interpolations for a given environment. Interpolations will be explained in a separate section.
|
27
|
+
|
28
|
+
Here is a example config.yml
|
29
|
+
```yaml
|
30
|
+
environments:
|
31
|
+
- 'my-test-env1'
|
32
|
+
- 'my-test-env2'
|
33
|
+
|
34
|
+
accounts:
|
35
|
+
- 123456789012
|
36
|
+
- 987654321098
|
37
|
+
|
38
|
+
environment_configs:
|
39
|
+
my-test-env1:
|
40
|
+
region: 'us-east-1'
|
41
|
+
account: 123456789012
|
42
|
+
interpolations:
|
43
|
+
region: 'us-east-1'
|
44
|
+
cloud: 'test-cloud-1'
|
45
|
+
domain: 'my1.com'
|
46
|
+
my-test-env2:
|
47
|
+
region: 'eu-central-1'
|
48
|
+
account: 987654321098
|
49
|
+
interpolations:
|
50
|
+
region: 'eu-central-1'
|
51
|
+
cloud: 'test-cloud-2'
|
52
|
+
domain: 'my2.com'
|
53
|
+
```
|
54
|
+
|
55
|
+
##### Step 2: Creating your globals
|
56
|
+
Globals are properties that get mixed in with service definitions. The hierarchy of the global definition sets the ruling for what that property can supersede.
|
57
|
+
The globals supersedence order is as follows. Any Environmental globals will overwrite account globals. The resultant merge of environmental and account globals overwrite definitions in the top level globals.yml. In short
|
58
|
+
Superscedence from least to greatest is globals.yml, account globals, environment globals. To define globals follow the steps below.
|
59
|
+
###### Top level globals
|
60
|
+
1. Create a globals folder
|
61
|
+
```sh
|
62
|
+
cd example-properties/
|
63
|
+
mkdir globals
|
64
|
+
```
|
65
|
+
2. If you would like top level globals then create a `globals.yml` in your globals folder.
|
66
|
+
```sh
|
67
|
+
cd globals/
|
68
|
+
touch globals.yml
|
69
|
+
```
|
70
|
+
3. Define your yaml values in the globals.yml
|
71
|
+
###### Account globals
|
72
|
+
1. Create a folder called the account id of your aws account.
|
73
|
+
2. In the folder created above create an YAML file named after the account id.
|
74
|
+
3. Define your account level globals in the YAML file you created above.
|
75
|
+
###### Environment Globals
|
76
|
+
1. Create a folder called `environments` inside your folder named after your account.
|
77
|
+
2. Inside the `environments` folder create a yaml file named after the environment you would like to define globals for. Only environments defined in your config are supported. The environment must also be mapped in the config to the account the sharing the same name as the folder the environment global yaml file lives in.
|
78
|
+
3. In the newly created environment's yaml file you may define your globals.
|
79
|
+
|
80
|
+
##### Step 3: Creating your service definitions
|
81
|
+
Service definitions have the highest level of supersedence and will overwrite matching global definitions.
|
82
|
+
To create you service definitions you need to create the services folder and then the services yaml files.
|
83
|
+
```sh
|
84
|
+
cd example-properties/
|
85
|
+
mkdir services
|
86
|
+
cd services
|
87
|
+
touch my-service-name.yml
|
88
|
+
```
|
89
|
+
Service definitions consist of three parts `default`, `environments`, and `encrypted`. Encrypted definitions overwrite environment definitions which will overwrite default definitions. Here is a example of a service file. The name of your service file MUST be the same as your service.
|
90
|
+
```yaml
|
91
|
+
default:
|
92
|
+
database.host: 'my.database.{domain}'
|
93
|
+
database.port: 3306
|
94
|
+
|
95
|
+
environments:
|
96
|
+
my-test-env-1:
|
97
|
+
thread.pool.size: 12
|
98
|
+
my-test-env-2:
|
99
|
+
thread.pool.size: 8
|
100
|
+
|
101
|
+
encrypted:
|
102
|
+
my-test-env-1:
|
103
|
+
my.encrypted.property:
|
104
|
+
$ssm:
|
105
|
+
region: us-east-1
|
106
|
+
encrypted: PRETEND_ENCRYPTED_PROPERTY_CIPHERTEXT
|
107
|
+
```
|
108
|
+
###### Adding interpolations
|
109
|
+
An interpolation is a value that will be dynamically substituted during generation with the correct value for the environment being generated. Interpolations are declared in the config for a given environment. Once declared an interpolation can be used in a property definition by referencing it in braces. If we were to reference the domain interpolation from the example config above we would use `{domain}`.
|
110
|
+
|
111
|
+
##### Step 4: Generating Your Properties (Using the CLI)
|
112
|
+
The bin directory contains the generator.rb cli. An example of running the cli is below. The `project_path` argument specifies the path to the properties repo we are generating a uploading properties from. You must be able to create a session with s3 to upload.
|
113
|
+
```sh
|
114
|
+
./generator.rb generate --project_path "~/projects/project-properties" --upload true --upload_account "123456789012" --upload_region "us-east-1" --upload_bucket "propertiesbucket.my-cloud.com"
|
115
|
+
```
|
@@ -0,0 +1,45 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
require 'thor'
|
4
|
+
require 'yaml'
|
5
|
+
require_relative '../lib/generator/generator.rb'
|
6
|
+
require_relative '../lib/linter/linter.rb'
|
7
|
+
class GeneratorCLI < ::Thor
|
8
|
+
|
9
|
+
desc 'generate', 'Generate properties'
|
10
|
+
option 'project_path', banner: 'PROJECT_PATH', type: :string, desc: 'Path to the property project to generate properties for'
|
11
|
+
option 'output', banner: 'OUTPUT', type: :string, desc: 'Output path for locally dumping generated outputs', :default => '/tmp/'
|
12
|
+
option 'upload', banner: 'UPLOAD', type: :boolean, desc: 'Whether to upload or not', :default => false
|
13
|
+
option 'upload_account', banner: 'UPLOAD_ACCOUNT', type: :string, desc: 'The account you are uploading properties to'
|
14
|
+
option 'upload_region', banner: 'UPLOAD_REGION', type: :string, desc: 'The region your property bucket is in'
|
15
|
+
option 'upload_bucket', banner: 'UPLOAD_BUCKET', type: :string, desc: 'The bucket you are uploading properties to.'
|
16
|
+
|
17
|
+
def generate
|
18
|
+
|
19
|
+
generator = PropertyGenerator::Generator.new(options)
|
20
|
+
out = generator.generate
|
21
|
+
if options['upload']
|
22
|
+
if options['upload_account'].nil? || options['upload_region'].nil? && options['upload_bucket'].nil?
|
23
|
+
puts 'Please specify upload configs'
|
24
|
+
else
|
25
|
+
generator.upload(out, options)
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
desc 'lint', 'Lint YAML files for properties repo'
|
32
|
+
option 'project_path', banner: 'PROJECT_PATH', type: :string, desc: 'Path to the property project to generate properties for'
|
33
|
+
def lint
|
34
|
+
linter = PropertyGenerator::Linter.new(options['project_path'])
|
35
|
+
linter.run_tests
|
36
|
+
linter.display_report
|
37
|
+
if linter.fail_check
|
38
|
+
return 1
|
39
|
+
else
|
40
|
+
return 0
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
GeneratorCLI.start(ARGV)
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module PropertyGenerator
|
2
|
+
require 'yaml'
|
3
|
+
class Config
|
4
|
+
|
5
|
+
attr_accessor :configs
|
6
|
+
|
7
|
+
def initialize(project_path)
|
8
|
+
@project_path = project_path
|
9
|
+
end
|
10
|
+
|
11
|
+
def configs
|
12
|
+
@configs ||= read_configs
|
13
|
+
end
|
14
|
+
|
15
|
+
def environments
|
16
|
+
configs['environments']
|
17
|
+
end
|
18
|
+
|
19
|
+
def accounts
|
20
|
+
configs['accounts']
|
21
|
+
end
|
22
|
+
|
23
|
+
def environment_configs
|
24
|
+
configs['environment_configs']
|
25
|
+
end
|
26
|
+
|
27
|
+
def read_configs
|
28
|
+
file = "#{@project_path}/config/config.yml"
|
29
|
+
YAML.load_file(file)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require_relative 'config'
|
2
|
+
require_relative 'globals'
|
3
|
+
require_relative 'service'
|
4
|
+
require_relative 'helpers'
|
5
|
+
|
6
|
+
module PropertyGenerator
|
7
|
+
class Generator
|
8
|
+
require 'fileutils'
|
9
|
+
require 'securerandom'
|
10
|
+
include PropertyGenerator
|
11
|
+
# purpose: initialize globals and configs
|
12
|
+
# serve as a broker between tasks
|
13
|
+
def initialize(options)
|
14
|
+
project_path = File.expand_path(options['project_path'])
|
15
|
+
@configs = PropertyGenerator::Config.new(project_path)
|
16
|
+
@globals = PropertyGenerator::Globals.new(project_path, @configs)
|
17
|
+
@globals = @globals.globals
|
18
|
+
@output_path = "#{File.expand_path(options['output'])}/properties/#{SecureRandom.hex}"
|
19
|
+
puts "Properties will be output here #{@output_path}"
|
20
|
+
@service_list = PropertyGenerator.read_services(project_path)
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
def generate
|
25
|
+
output = []
|
26
|
+
@service_list.each do | service, path|
|
27
|
+
service_instance = PropertyGenerator::Service.new(YAML.load_file(path), @configs, @globals)
|
28
|
+
service_instance.service
|
29
|
+
service_instance.interpolate
|
30
|
+
|
31
|
+
out = PropertyGenerator.writer(service, service_instance.service, @configs, @output_path)
|
32
|
+
(output << out).flatten!
|
33
|
+
end
|
34
|
+
output
|
35
|
+
end
|
36
|
+
|
37
|
+
def upload(out, config)
|
38
|
+
upload_account = config['upload_account']
|
39
|
+
upload_region = config['upload_region']
|
40
|
+
upload_bucket = config['upload_bucket']
|
41
|
+
out.each do |file|
|
42
|
+
next unless file.include?("#{upload_account}") && file.include?("#{upload_region}")
|
43
|
+
file_region = file.split("/")[-2]
|
44
|
+
PropertyGenerator.sync(upload_region, upload_account, upload_bucket, file, file_region)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module PropertyGenerator
|
2
|
+
class Globals
|
3
|
+
require 'yaml'
|
4
|
+
attr_accessor :globals
|
5
|
+
|
6
|
+
def initialize(project_path, config)
|
7
|
+
@project_path = project_path
|
8
|
+
@environments = config.environments
|
9
|
+
@environment_configs = config.environment_configs
|
10
|
+
@accounts = config.accounts
|
11
|
+
end
|
12
|
+
|
13
|
+
def globals
|
14
|
+
@globals ||= condense_globals
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
def get_main_global
|
19
|
+
top_level = {}
|
20
|
+
if File.exists?("#{@project_path}/globals/globals.yml")
|
21
|
+
top_level = YAML.load_file("#{@project_path}/globals/globals.yml")
|
22
|
+
end
|
23
|
+
top_level
|
24
|
+
end
|
25
|
+
|
26
|
+
def get_account_globals
|
27
|
+
data = {}
|
28
|
+
@accounts.each do |account|
|
29
|
+
next unless Dir.exists?("#{@project_path}/globals/accounts/#{account}")
|
30
|
+
account_default_file = "#{@project_path}/globals/accounts/#{account}/#{account}.yml"
|
31
|
+
data[account] = YAML.load_file(account_default_file) if File.exists?(account_default_file)
|
32
|
+
end
|
33
|
+
data
|
34
|
+
end
|
35
|
+
|
36
|
+
def get_environment_globals
|
37
|
+
data = {}
|
38
|
+
@accounts.each do |account|
|
39
|
+
next unless Dir.exists?("#{@project_path}/globals/accounts/#{account}/environments")
|
40
|
+
data[account] = {}
|
41
|
+
@environments.each do |env|
|
42
|
+
next unless File.exists?("#{@project_path}/globals/accounts/#{account}/environments/#{env}.yml")
|
43
|
+
data[account][env] = YAML.load_file("#{@project_path}/globals/accounts/#{account}/environments/#{env}.yml")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
data
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
#merge environment globals with account globals.
|
51
|
+
def condense_globals
|
52
|
+
condensed = {}
|
53
|
+
# get account and the environmental hash's for said account
|
54
|
+
environment_globals = get_environment_globals
|
55
|
+
account_globals = get_account_globals
|
56
|
+
main_global = get_main_global
|
57
|
+
# nothing to do here if everything is empty
|
58
|
+
return condensed if environment_globals.empty? && account_globals.empty? && main_global.empty?
|
59
|
+
|
60
|
+
environment_globals.each do |account, env_global |
|
61
|
+
# get the env and the values
|
62
|
+
env_global.each do |env, hash|
|
63
|
+
account_globals[account] ||= {}
|
64
|
+
# set the environment globals to be the account global merged with the env globals
|
65
|
+
env_global[env] = account_globals[account].merge(hash) unless hash.empty?
|
66
|
+
condensed[env] = env_global[env]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
unless main_global.empty?
|
71
|
+
# All environments need the main global definitions
|
72
|
+
@environments.each do |env|
|
73
|
+
# If a key/value pair for a environment has not been defined set one so we can merge
|
74
|
+
condensed[env] ||= {}
|
75
|
+
# We need to merge into the globals so any env configs overwrite main global configs.
|
76
|
+
# Dup so we dont modify the original object
|
77
|
+
main_global_dup = main_global.dup
|
78
|
+
condensed[env] = main_global_dup.merge(condensed[env])
|
79
|
+
end
|
80
|
+
end
|
81
|
+
condensed
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module PropertyGenerator
|
2
|
+
class Service
|
3
|
+
attr_accessor :service
|
4
|
+
def initialize(service_data, config, globals)
|
5
|
+
@service_data = service_data
|
6
|
+
@environments = config.environments
|
7
|
+
@globals = globals
|
8
|
+
@environment_configs = config.environment_configs
|
9
|
+
set_service
|
10
|
+
end
|
11
|
+
|
12
|
+
def set_service
|
13
|
+
service_data = merge_env_default(@service_data, @environments)
|
14
|
+
@service = merge_service_with_globals(@globals, service_data, @environments)
|
15
|
+
end
|
16
|
+
|
17
|
+
def service
|
18
|
+
@service
|
19
|
+
end
|
20
|
+
|
21
|
+
def interpolate
|
22
|
+
environments = @environments
|
23
|
+
#read in config
|
24
|
+
#interate through environment and substitute config for values for that environment
|
25
|
+
environments.each do | env|
|
26
|
+
#get the map of config for a env
|
27
|
+
interpolations = @environment_configs[env]['interpolations']
|
28
|
+
|
29
|
+
#interate through the properties for an environment and gsub the config
|
30
|
+
@service[env].each do | property_key, property_value|
|
31
|
+
property_value_dup = property_value.dup
|
32
|
+
interpolations.each do |matcher_key, matcher_value|
|
33
|
+
if property_value.class == String && property_value_dup.include?("{#{matcher_key}}")
|
34
|
+
@service[env][property_key] = property_value_dup.gsub!("{#{matcher_key}}", matcher_value)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
service
|
40
|
+
end
|
41
|
+
|
42
|
+
def merge_env_default(data, environments)
|
43
|
+
#creates a hash of the enviornments merged with the defaults
|
44
|
+
# {service => {env1 => {properties},
|
45
|
+
# env2 => {properties}
|
46
|
+
# }
|
47
|
+
# }
|
48
|
+
output = {}
|
49
|
+
default = data['default']
|
50
|
+
|
51
|
+
environments.each do |env|
|
52
|
+
default_clone = default.dup
|
53
|
+
#if nil, use set to environments as nothing to merge env with
|
54
|
+
data['environments'] ||= {}
|
55
|
+
data['environments'][env] ||= {}
|
56
|
+
environment_data = data['environments'][env].dup
|
57
|
+
if data['encrypted']
|
58
|
+
encrypted = data['encrypted'][env].dup unless data['encrypted'][env].nil?
|
59
|
+
environment_data = data['environments'][env].merge(encrypted) unless encrypted.nil?
|
60
|
+
end
|
61
|
+
if default_clone.nil?
|
62
|
+
merged = environment_data
|
63
|
+
else
|
64
|
+
merged = default_clone.merge(environment_data)
|
65
|
+
end
|
66
|
+
output[env] = merged
|
67
|
+
end
|
68
|
+
output
|
69
|
+
end
|
70
|
+
|
71
|
+
def merge_service_with_globals(globals_data, service_data, environments)
|
72
|
+
#service will now overwrite globals, merging will be done for each environment
|
73
|
+
output = {}
|
74
|
+
envs = environments
|
75
|
+
envs.each do |env|
|
76
|
+
globals_clone = globals_data.dup
|
77
|
+
if globals_clone[env].nil? || globals_clone[env] == false
|
78
|
+
merged = service_data[env]
|
79
|
+
else
|
80
|
+
merged = globals_clone[env].merge(service_data[env])
|
81
|
+
end
|
82
|
+
output[env] = merged
|
83
|
+
end
|
84
|
+
output
|
85
|
+
end
|
86
|
+
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module PropertyGenerator
|
2
|
+
require 'json'
|
3
|
+
require 'fileutils'
|
4
|
+
require 'aws-sdk-s3'
|
5
|
+
class << self
|
6
|
+
|
7
|
+
def test_runner(object, test_list)
|
8
|
+
results = {}
|
9
|
+
test_list.each do |test|
|
10
|
+
results[test] = object.send(test)
|
11
|
+
end
|
12
|
+
results
|
13
|
+
end
|
14
|
+
|
15
|
+
def get_list_of_files(path, ignore_list)
|
16
|
+
#Returns a list of files in given path
|
17
|
+
#Ignores files in a given ignore list
|
18
|
+
Dir.glob(path + "/**/*").select{ |e| File.file? e unless ignore_list.include?(e.split('/')[(e.split('/')).length - 1])}
|
19
|
+
end
|
20
|
+
|
21
|
+
def valid_paths(path)
|
22
|
+
valid_paths = []
|
23
|
+
list_of_file_paths = get_list_of_files(path, [])
|
24
|
+
list_of_file_paths.each do |file_path|
|
25
|
+
begin
|
26
|
+
YAML.load_file(file_path)
|
27
|
+
valid_paths << file_path
|
28
|
+
rescue
|
29
|
+
next
|
30
|
+
end
|
31
|
+
end
|
32
|
+
valid_paths
|
33
|
+
end
|
34
|
+
|
35
|
+
def invalid_paths(path, ignore_list)
|
36
|
+
invalid_paths = []
|
37
|
+
list_of_file_paths = get_list_of_files(path, ignore_list)
|
38
|
+
list_of_file_paths.each do |file_path|
|
39
|
+
begin
|
40
|
+
YAML.load_file(file_path)
|
41
|
+
rescue
|
42
|
+
invalid_paths << file_path
|
43
|
+
end
|
44
|
+
end
|
45
|
+
invalid_paths
|
46
|
+
end
|
47
|
+
|
48
|
+
def read_services(path)
|
49
|
+
Dir.glob("#{path}/services/*.{yaml,yml}").each_with_object({}) do |file, acc|
|
50
|
+
name = File.basename(file)[/(?<service>.*)\.ya?ml$/, :service]
|
51
|
+
path = File.absolute_path(file)
|
52
|
+
acc[name] = path
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def writer(service_name, finalized, configs, output_path)
|
57
|
+
output = []
|
58
|
+
envs = configs.environments
|
59
|
+
environmental_configs = configs.environment_configs
|
60
|
+
envs.each do | env|
|
61
|
+
account = environmental_configs[env]["account"]
|
62
|
+
region = environmental_configs[env]["region"]
|
63
|
+
json = JSON.pretty_generate({"properties" => finalized[env]})
|
64
|
+
FileUtils.mkdir_p("#{output_path}/#{account}/#{region}/") unless Dir.exist?("#{output_path}/#{account}/#{region}/")
|
65
|
+
File.write("#{output_path}/#{account}/#{region}/#{service_name}.json", json)
|
66
|
+
output << "#{output_path}/#{account}/#{region}/#{service_name}.json"
|
67
|
+
end
|
68
|
+
output
|
69
|
+
end
|
70
|
+
|
71
|
+
def sync(region, account, bucket, file, file_region)
|
72
|
+
s3 = Aws::S3::Resource.new(region: region)
|
73
|
+
filename = file.split("/").last
|
74
|
+
puts "Destination: #{account}/#{file_region}/#{filename}"
|
75
|
+
puts "Uploading: #{file}"
|
76
|
+
obj = s3.bucket(bucket).object("#{account}/#{file_region}/#{filename}")
|
77
|
+
obj.upload_file(file)
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|