formatron 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.coveralls.yml +1 -0
- data/.gitignore +12 -0
- data/.rspec +2 -0
- data/.rubocop.yml +3 -0
- data/.simplecov +7 -0
- data/.travis.yml +17 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +6 -0
- data/Guardfile +16 -0
- data/LICENSE.txt +21 -0
- data/README.md +93 -0
- data/Rakefile +16 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/exe/formatron +20 -0
- data/formatron.gemspec +52 -0
- data/lib/formatron.rb +357 -0
- data/lib/formatron/aws.rb +197 -0
- data/lib/formatron/chef.rb +156 -0
- data/lib/formatron/chef/berkshelf.rb +55 -0
- data/lib/formatron/chef/keys.rb +48 -0
- data/lib/formatron/chef/knife.rb +169 -0
- data/lib/formatron/chef_clients.rb +73 -0
- data/lib/formatron/cli.rb +33 -0
- data/lib/formatron/cli/completion.rb +26 -0
- data/lib/formatron/cli/deploy.rb +57 -0
- data/lib/formatron/cli/destroy.rb +57 -0
- data/lib/formatron/cli/generators/bootstrap.rb +250 -0
- data/lib/formatron/cli/generators/credentials.rb +100 -0
- data/lib/formatron/cli/generators/instance.rb +118 -0
- data/lib/formatron/cli/provision.rb +59 -0
- data/lib/formatron/cloud_formation.rb +54 -0
- data/lib/formatron/cloud_formation/resources/cloud_formation.rb +27 -0
- data/lib/formatron/cloud_formation/resources/ec2.rb +336 -0
- data/lib/formatron/cloud_formation/resources/iam.rb +94 -0
- data/lib/formatron/cloud_formation/resources/route53.rb +54 -0
- data/lib/formatron/cloud_formation/scripts.rb +128 -0
- data/lib/formatron/cloud_formation/template.rb +114 -0
- data/lib/formatron/cloud_formation/template/parameters.rb +20 -0
- data/lib/formatron/cloud_formation/template/vpc.rb +181 -0
- data/lib/formatron/cloud_formation/template/vpc/subnet.rb +187 -0
- data/lib/formatron/cloud_formation/template/vpc/subnet/acl.rb +147 -0
- data/lib/formatron/cloud_formation/template/vpc/subnet/bastion.rb +66 -0
- data/lib/formatron/cloud_formation/template/vpc/subnet/chef_server.rb +205 -0
- data/lib/formatron/cloud_formation/template/vpc/subnet/instance.rb +162 -0
- data/lib/formatron/cloud_formation/template/vpc/subnet/instance/policy.rb +74 -0
- data/lib/formatron/cloud_formation/template/vpc/subnet/instance/security_group.rb +117 -0
- data/lib/formatron/cloud_formation/template/vpc/subnet/instance/setup.rb +68 -0
- data/lib/formatron/cloud_formation/template/vpc/subnet/nat.rb +94 -0
- data/lib/formatron/completion.rb +26 -0
- data/lib/formatron/completion/completion.sh.erb +35 -0
- data/lib/formatron/config.rb +31 -0
- data/lib/formatron/config/reader.rb +29 -0
- data/lib/formatron/dsl.rb +15 -0
- data/lib/formatron/dsl/formatron.rb +25 -0
- data/lib/formatron/dsl/formatron/global.rb +19 -0
- data/lib/formatron/dsl/formatron/global/ec2.rb +17 -0
- data/lib/formatron/dsl/formatron/vpc.rb +17 -0
- data/lib/formatron/dsl/formatron/vpc/subnet.rb +27 -0
- data/lib/formatron/dsl/formatron/vpc/subnet/acl.rb +18 -0
- data/lib/formatron/dsl/formatron/vpc/subnet/chef_server.rb +32 -0
- data/lib/formatron/dsl/formatron/vpc/subnet/chef_server/organization.rb +22 -0
- data/lib/formatron/dsl/formatron/vpc/subnet/instance.rb +29 -0
- data/lib/formatron/dsl/formatron/vpc/subnet/instance/chef.rb +22 -0
- data/lib/formatron/dsl/formatron/vpc/subnet/instance/policy.rb +21 -0
- data/lib/formatron/dsl/formatron/vpc/subnet/instance/policy/statement.rb +23 -0
- data/lib/formatron/dsl/formatron/vpc/subnet/instance/security_group.rb +21 -0
- data/lib/formatron/dsl/formatron/vpc/subnet/instance/setup.rb +22 -0
- data/lib/formatron/dsl/formatron/vpc/subnet/instance/setup/variable.rb +23 -0
- data/lib/formatron/external.rb +61 -0
- data/lib/formatron/external/dsl.rb +171 -0
- data/lib/formatron/external/outputs.rb +25 -0
- data/lib/formatron/generators/bootstrap.rb +90 -0
- data/lib/formatron/generators/bootstrap/config.rb +62 -0
- data/lib/formatron/generators/bootstrap/ec2.rb +17 -0
- data/lib/formatron/generators/bootstrap/formatronfile.rb +52 -0
- data/lib/formatron/generators/bootstrap/formatronfile/Formatronfile.erb +79 -0
- data/lib/formatron/generators/bootstrap/ssl.rb +35 -0
- data/lib/formatron/generators/credentials.rb +17 -0
- data/lib/formatron/generators/instance.rb +64 -0
- data/lib/formatron/generators/instance/config.rb +47 -0
- data/lib/formatron/generators/instance/formatronfile.rb +47 -0
- data/lib/formatron/generators/instance/formatronfile/Formatronfile.erb +16 -0
- data/lib/formatron/generators/util.rb +14 -0
- data/lib/formatron/generators/util/cookbook.rb +65 -0
- data/lib/formatron/generators/util/gitignore.rb +16 -0
- data/lib/formatron/generators/util/readme.rb +18 -0
- data/lib/formatron/logger.rb +8 -0
- data/lib/formatron/s3/chef_server_cert.rb +85 -0
- data/lib/formatron/s3/chef_server_keys.rb +103 -0
- data/lib/formatron/s3/cloud_formation_template.rb +61 -0
- data/lib/formatron/s3/configuration.rb +58 -0
- data/lib/formatron/s3/path.rb +30 -0
- data/lib/formatron/util/dsl.rb +107 -0
- data/lib/formatron/util/shell.rb +20 -0
- data/lib/formatron/util/vpc.rb +15 -0
- data/lib/formatron/version.rb +4 -0
- data/support/cloudformation_describe_stacks_response.rb +36 -0
- data/support/dsl_test.rb +123 -0
- data/support/route53_get_hosted_zone_response.rb +21 -0
- data/support/s3_get_object_response.rb +21 -0
- data/support/template_test.rb +41 -0
- metadata +414 -0
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
require 'aws-sdk'
|
|
2
|
+
|
|
3
|
+
class Formatron
|
|
4
|
+
# shared AWS clients
|
|
5
|
+
# rubocop:disable Metrics/ClassLength
|
|
6
|
+
class AWS
|
|
7
|
+
attr_reader :region
|
|
8
|
+
|
|
9
|
+
REGIONS = {
|
|
10
|
+
'us-east-1' => {
|
|
11
|
+
ami: 'ami-ff02509a'
|
|
12
|
+
},
|
|
13
|
+
'us-west-2' => {
|
|
14
|
+
ami: 'ami-8ee605bd'
|
|
15
|
+
},
|
|
16
|
+
'us-west-1' => {
|
|
17
|
+
ami: 'ami-198a495d'
|
|
18
|
+
},
|
|
19
|
+
'eu-west-1' => {
|
|
20
|
+
ami: 'ami-37360a40'
|
|
21
|
+
},
|
|
22
|
+
'eu-central-1' => {
|
|
23
|
+
ami: 'ami-46272b5b'
|
|
24
|
+
},
|
|
25
|
+
'ap-southeast-1' => {
|
|
26
|
+
ami: 'ami-42170410'
|
|
27
|
+
},
|
|
28
|
+
'ap-southeast-2' => {
|
|
29
|
+
ami: 'ami-6d6c2657'
|
|
30
|
+
},
|
|
31
|
+
'ap-northeast-1' => {
|
|
32
|
+
ami: 'ami-402e4c40'
|
|
33
|
+
},
|
|
34
|
+
'sa-east-1' => {
|
|
35
|
+
ami: 'ami-1f4bda02'
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
CAPABILITIES = %w(CAPABILITY_IAM)
|
|
40
|
+
|
|
41
|
+
STACK_READY_STATES = %w(
|
|
42
|
+
CREATE_COMPLETE
|
|
43
|
+
UPDATE_COMPLETE
|
|
44
|
+
UPDATE_ROLLBACK_COMPLETE
|
|
45
|
+
ROLLBACK_COMPLETE
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
def initialize(credentials:)
|
|
49
|
+
@credentials = JSON.parse(File.read(credentials))
|
|
50
|
+
@region = @credentials['region']
|
|
51
|
+
_create_aws_credentials
|
|
52
|
+
_create_s3_client
|
|
53
|
+
_create_cloudformation_client
|
|
54
|
+
_create_route53_client
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def upload_file(kms_key:, bucket:, key:, content:)
|
|
58
|
+
@s3_client.put_object(
|
|
59
|
+
bucket: bucket,
|
|
60
|
+
key: key,
|
|
61
|
+
body: content,
|
|
62
|
+
server_side_encryption: 'aws:kms',
|
|
63
|
+
ssekms_key_id: kms_key
|
|
64
|
+
)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def delete_file(bucket:, key:)
|
|
68
|
+
@s3_client.delete_object(
|
|
69
|
+
bucket: bucket,
|
|
70
|
+
key: key
|
|
71
|
+
)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def download_file(bucket:, key:, path:)
|
|
75
|
+
@s3_client.get_object(
|
|
76
|
+
bucket: bucket,
|
|
77
|
+
key: key,
|
|
78
|
+
response_target: path
|
|
79
|
+
)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def get_file(bucket:, key:)
|
|
83
|
+
@s3_client.get_object(
|
|
84
|
+
bucket: bucket,
|
|
85
|
+
key: key
|
|
86
|
+
).body.read
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# rubocop:disable Metrics/MethodLength
|
|
90
|
+
def deploy_stack(stack_name:, template_url:, parameters:)
|
|
91
|
+
aws_parameters = parameters.map do |key, value|
|
|
92
|
+
{
|
|
93
|
+
parameter_key: key,
|
|
94
|
+
parameter_value: value,
|
|
95
|
+
use_previous_value: false
|
|
96
|
+
}
|
|
97
|
+
end
|
|
98
|
+
@cloudformation_client.create_stack(
|
|
99
|
+
stack_name: stack_name,
|
|
100
|
+
template_url: template_url,
|
|
101
|
+
capabilities: CAPABILITIES,
|
|
102
|
+
on_failure: 'DO_NOTHING',
|
|
103
|
+
parameters: aws_parameters
|
|
104
|
+
)
|
|
105
|
+
rescue Aws::CloudFormation::Errors::AlreadyExistsException
|
|
106
|
+
_update_stack(
|
|
107
|
+
stack_name: stack_name,
|
|
108
|
+
template_url: template_url,
|
|
109
|
+
parameters: aws_parameters
|
|
110
|
+
)
|
|
111
|
+
end
|
|
112
|
+
# rubocop:enable Metrics/MethodLength
|
|
113
|
+
|
|
114
|
+
def hosted_zone_name(hosted_zone_id)
|
|
115
|
+
@route53_client.get_hosted_zone(
|
|
116
|
+
id: hosted_zone_id
|
|
117
|
+
).hosted_zone.name.chomp '.'
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def _update_stack(stack_name:, template_url:, parameters:)
|
|
121
|
+
@cloudformation_client.update_stack(
|
|
122
|
+
stack_name: stack_name,
|
|
123
|
+
template_url: template_url,
|
|
124
|
+
capabilities: CAPABILITIES,
|
|
125
|
+
parameters: parameters
|
|
126
|
+
)
|
|
127
|
+
rescue Aws::CloudFormation::Errors::ValidationError => error
|
|
128
|
+
raise error unless error.message.eql?(
|
|
129
|
+
'No updates are to be performed.'
|
|
130
|
+
)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def delete_stack(stack_name:)
|
|
134
|
+
@cloudformation_client.delete_stack(
|
|
135
|
+
stack_name: stack_name
|
|
136
|
+
)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def stack_outputs(stack_name:)
|
|
140
|
+
description = @cloudformation_client.describe_stacks(
|
|
141
|
+
stack_name: stack_name
|
|
142
|
+
).stacks[0]
|
|
143
|
+
status = description.stack_status
|
|
144
|
+
fail "CloudFormation stack, #{stack_name}, " \
|
|
145
|
+
"is not ready: #{status}" unless STACK_READY_STATES.include? status
|
|
146
|
+
description.outputs.each_with_object({}) do |output, outputs|
|
|
147
|
+
outputs[output.output_key] = output.output_value
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def stack_ready!(stack_name:)
|
|
152
|
+
status = @cloudformation_client.describe_stacks(
|
|
153
|
+
stack_name: stack_name
|
|
154
|
+
).stacks[0].stack_status
|
|
155
|
+
fail "CloudFormation stack, #{stack_name}, " \
|
|
156
|
+
"is not ready: #{status}" unless STACK_READY_STATES.include? status
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def _create_aws_credentials
|
|
160
|
+
@aws_credentials = Aws::Credentials.new(
|
|
161
|
+
@credentials['access_key_id'],
|
|
162
|
+
@credentials['secret_access_key']
|
|
163
|
+
)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def _create_s3_client
|
|
167
|
+
@s3_client = ::Aws::S3::Client.new(
|
|
168
|
+
region: @region,
|
|
169
|
+
signature_version: 'v4',
|
|
170
|
+
credentials: @aws_credentials
|
|
171
|
+
)
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def _create_cloudformation_client
|
|
175
|
+
@cloudformation_client = ::Aws::CloudFormation::Client.new(
|
|
176
|
+
region: @region,
|
|
177
|
+
credentials: @aws_credentials
|
|
178
|
+
)
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def _create_route53_client
|
|
182
|
+
@route53_client = ::Aws::Route53::Client.new(
|
|
183
|
+
region: @region,
|
|
184
|
+
credentials: @aws_credentials
|
|
185
|
+
)
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
private(
|
|
189
|
+
:_create_aws_credentials,
|
|
190
|
+
:_create_s3_client,
|
|
191
|
+
:_create_cloudformation_client,
|
|
192
|
+
:_create_route53_client,
|
|
193
|
+
:_update_stack
|
|
194
|
+
)
|
|
195
|
+
end
|
|
196
|
+
# rubocop:enable Metrics/ClassLength
|
|
197
|
+
end
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
require 'formatron/cloud_formation'
|
|
2
|
+
require 'formatron/logger'
|
|
3
|
+
require_relative 'chef/keys'
|
|
4
|
+
require_relative 'chef/berkshelf'
|
|
5
|
+
require_relative 'chef/knife'
|
|
6
|
+
|
|
7
|
+
class Formatron
|
|
8
|
+
# manage the instance provisioning with Chef
|
|
9
|
+
# rubocop:disable Metrics/ClassLength
|
|
10
|
+
class Chef
|
|
11
|
+
# rubocop:disable Metrics/MethodLength
|
|
12
|
+
# rubocop:disable Metrics/ParameterLists
|
|
13
|
+
def initialize(
|
|
14
|
+
aws:,
|
|
15
|
+
bucket:,
|
|
16
|
+
name:,
|
|
17
|
+
target:,
|
|
18
|
+
ec2_key:,
|
|
19
|
+
username:,
|
|
20
|
+
organization:,
|
|
21
|
+
ssl_verify:,
|
|
22
|
+
chef_sub_domain:,
|
|
23
|
+
bastions:,
|
|
24
|
+
hosted_zone_name:,
|
|
25
|
+
server_stack:,
|
|
26
|
+
guid:,
|
|
27
|
+
configuration:,
|
|
28
|
+
databag_secret:
|
|
29
|
+
)
|
|
30
|
+
@aws = aws
|
|
31
|
+
@name = name
|
|
32
|
+
@target = target
|
|
33
|
+
@chef_sub_domain = chef_sub_domain
|
|
34
|
+
@hosted_zone_name = hosted_zone_name
|
|
35
|
+
@organization = organization
|
|
36
|
+
@server_stack = server_stack
|
|
37
|
+
@bastions = bastions
|
|
38
|
+
chef_server_url = _chef_server_url
|
|
39
|
+
@keys = Keys.new(
|
|
40
|
+
aws: @aws,
|
|
41
|
+
bucket: bucket,
|
|
42
|
+
name: server_stack,
|
|
43
|
+
target: @target,
|
|
44
|
+
guid: guid,
|
|
45
|
+
ec2_key: ec2_key
|
|
46
|
+
)
|
|
47
|
+
@knife = Knife.new(
|
|
48
|
+
keys: @keys,
|
|
49
|
+
chef_server_url: chef_server_url,
|
|
50
|
+
username: username,
|
|
51
|
+
organization: organization,
|
|
52
|
+
ssl_verify: ssl_verify,
|
|
53
|
+
name: @name,
|
|
54
|
+
databag_secret: databag_secret,
|
|
55
|
+
configuration: configuration
|
|
56
|
+
)
|
|
57
|
+
@berkshelf = Berkshelf.new(
|
|
58
|
+
keys: @keys,
|
|
59
|
+
chef_server_url: chef_server_url,
|
|
60
|
+
username: username,
|
|
61
|
+
ssl_verify: ssl_verify
|
|
62
|
+
)
|
|
63
|
+
end
|
|
64
|
+
# rubocop:enable Metrics/ParameterLists
|
|
65
|
+
# rubocop:enable Metrics/MethodLength
|
|
66
|
+
|
|
67
|
+
def init
|
|
68
|
+
CloudFormation.stack_ready!(
|
|
69
|
+
aws: @aws,
|
|
70
|
+
name: @server_stack,
|
|
71
|
+
target: @target
|
|
72
|
+
)
|
|
73
|
+
@keys.init
|
|
74
|
+
@knife.init
|
|
75
|
+
@berkshelf.init
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def deploy_databag
|
|
79
|
+
Formatron::LOG.info do
|
|
80
|
+
"Deploying data bag to chef server: #{@chef_sub_domain}"
|
|
81
|
+
end
|
|
82
|
+
@knife.deploy_databag
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def delete_databag
|
|
86
|
+
Formatron::LOG.info do
|
|
87
|
+
"Deleting data bag from chef server: #{@chef_sub_domain}"
|
|
88
|
+
end
|
|
89
|
+
@knife.delete_databag
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# rubocop:disable Metrics/MethodLength
|
|
93
|
+
def provision(
|
|
94
|
+
sub_domain:,
|
|
95
|
+
cookbook:,
|
|
96
|
+
bastion:
|
|
97
|
+
)
|
|
98
|
+
Formatron::LOG.info do
|
|
99
|
+
"Provision #{sub_domain} with Chef cookbook: #{cookbook}"
|
|
100
|
+
end
|
|
101
|
+
bastion ||= @bastions.keys[0]
|
|
102
|
+
bastion_hostname = _hostname(
|
|
103
|
+
sub_domain: @bastions[bastion]
|
|
104
|
+
)
|
|
105
|
+
CloudFormation.stack_ready!(
|
|
106
|
+
aws: @aws,
|
|
107
|
+
name: @name,
|
|
108
|
+
target: @target
|
|
109
|
+
)
|
|
110
|
+
cookbook_name = File.basename cookbook
|
|
111
|
+
hostname = _hostname(
|
|
112
|
+
sub_domain: sub_domain
|
|
113
|
+
)
|
|
114
|
+
@knife.create_environment environment: sub_domain
|
|
115
|
+
@berkshelf.upload environment: sub_domain, cookbook: cookbook
|
|
116
|
+
@knife.bootstrap(
|
|
117
|
+
bastion_hostname: bastion_hostname,
|
|
118
|
+
environment: sub_domain,
|
|
119
|
+
cookbook: cookbook_name,
|
|
120
|
+
hostname: hostname
|
|
121
|
+
)
|
|
122
|
+
end
|
|
123
|
+
# rubocop:enable Metrics/ParameterLists
|
|
124
|
+
# rubocop:enable Metrics/MethodLength
|
|
125
|
+
|
|
126
|
+
def destroy(sub_domain:)
|
|
127
|
+
Formatron::LOG.info do
|
|
128
|
+
"Delete Chef configuration for node: #{sub_domain}"
|
|
129
|
+
end
|
|
130
|
+
@knife.delete_node node: sub_domain
|
|
131
|
+
@knife.delete_client client: sub_domain
|
|
132
|
+
@knife.delete_environment environment: sub_domain
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def unlink
|
|
136
|
+
@keys.unlink
|
|
137
|
+
@knife.unlink
|
|
138
|
+
@berkshelf.unlink
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def _chef_server_url
|
|
142
|
+
"https://#{@chef_sub_domain}.#{@hosted_zone_name}" \
|
|
143
|
+
"/organizations/#{@organization}"
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def _hostname(sub_domain:)
|
|
147
|
+
"#{sub_domain}.#{@hosted_zone_name}"
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
private(
|
|
151
|
+
:_chef_server_url,
|
|
152
|
+
:_hostname
|
|
153
|
+
)
|
|
154
|
+
end
|
|
155
|
+
# rubocop:enable Metrics/ClassLength
|
|
156
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
require 'formatron/util/shell'
|
|
2
|
+
require 'English'
|
|
3
|
+
|
|
4
|
+
class Formatron
|
|
5
|
+
class Chef
|
|
6
|
+
# Wrapper for the berkshelf cli
|
|
7
|
+
class Berkshelf
|
|
8
|
+
CONFIG_FILE_CONTENTS = <<-EOH.gsub(/^ {8}/, '')
|
|
9
|
+
{
|
|
10
|
+
"chef": {
|
|
11
|
+
"chef_server_url": "%{server_url}",
|
|
12
|
+
"node_name": "%{user}",
|
|
13
|
+
"client_key": "%{key_file}"
|
|
14
|
+
},
|
|
15
|
+
"ssl": {
|
|
16
|
+
"verify": %{ssl_verify}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
EOH
|
|
20
|
+
|
|
21
|
+
def initialize(keys:, chef_server_url:, username:, ssl_verify:)
|
|
22
|
+
@keys = keys
|
|
23
|
+
@chef_server_url = chef_server_url
|
|
24
|
+
@username = username
|
|
25
|
+
@ssl_verify = ssl_verify
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def init
|
|
29
|
+
@config_file = Tempfile.new 'formatron-berkshelf-'
|
|
30
|
+
@config_file.write CONFIG_FILE_CONTENTS % {
|
|
31
|
+
server_url: @chef_server_url,
|
|
32
|
+
user: @username,
|
|
33
|
+
key_file: @keys.user_key,
|
|
34
|
+
ssl_verify: @ssl_verify
|
|
35
|
+
}
|
|
36
|
+
@config_file.close
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def upload(cookbook:, environment:)
|
|
40
|
+
# rubocop:disable Metrics/LineLength
|
|
41
|
+
command = "berks install -b #{File.join(cookbook, 'Berksfile')}"
|
|
42
|
+
fail "failed to download cookbooks for opscode environment: #{environment}" unless Util::Shell.exec command
|
|
43
|
+
command = "berks upload -c #{@config_file.path} -b #{File.join(cookbook, 'Berksfile')}"
|
|
44
|
+
fail "failed to upload cookbooks for opscode environment: #{environment}" unless Util::Shell.exec command
|
|
45
|
+
command = "berks apply #{environment} -c #{@config_file.path} -b #{File.join(cookbook, 'Berksfile.lock')}"
|
|
46
|
+
fail "failed to apply cookbooks to opscode environment: #{environment}" unless Util::Shell.exec command
|
|
47
|
+
# rubocop:enable Metrics/LineLength
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def unlink
|
|
51
|
+
@config_file.unlink unless @config_file.nil?
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
require 'formatron/s3/chef_server_keys'
|
|
2
|
+
|
|
3
|
+
class Formatron
|
|
4
|
+
class Chef
|
|
5
|
+
# Download the Chef Server keys
|
|
6
|
+
class Keys
|
|
7
|
+
# rubocop:disable Metrics/ParameterLists
|
|
8
|
+
def initialize(aws:, bucket:, name:, target:, guid:, ec2_key:)
|
|
9
|
+
@aws = aws
|
|
10
|
+
@bucket = bucket
|
|
11
|
+
@name = name
|
|
12
|
+
@target = target
|
|
13
|
+
@guid = guid
|
|
14
|
+
@ec2_key = ec2_key
|
|
15
|
+
end
|
|
16
|
+
# rubocop:enable Metrics/ParameterLists
|
|
17
|
+
|
|
18
|
+
def init
|
|
19
|
+
@directory = Dir.mktmpdir 'formatron-chef-server-keys-'
|
|
20
|
+
S3::ChefServerKeys.get(
|
|
21
|
+
aws: @aws,
|
|
22
|
+
bucket: @bucket,
|
|
23
|
+
name: @name,
|
|
24
|
+
target: @target,
|
|
25
|
+
guid: @guid,
|
|
26
|
+
directory: @directory
|
|
27
|
+
)
|
|
28
|
+
File.write ec2_key, @ec2_key
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def user_key
|
|
32
|
+
S3::ChefServerKeys.user_pem_path directory: @directory
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def organization_key
|
|
36
|
+
S3::ChefServerKeys.organization_pem_path directory: @directory
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def ec2_key
|
|
40
|
+
File.join @directory, 'ec2_key'
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def unlink
|
|
44
|
+
FileUtils.rm_rf @directory unless @directory.nil?
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|