cfer-provisioning 0.1.0 → 0.2.0.pre.alpha1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0aa1b48f4bffa706855d32177faaa55a4476736b
4
- data.tar.gz: 0ada7fd8a30530eaafe67a570f82a04f41fa45df
3
+ metadata.gz: 407c0fc6b3f6927a53f759f123c43d6ff9824a61
4
+ data.tar.gz: 762144fd8522c9c29ff09e5fb3678dceeed3c826
5
5
  SHA512:
6
- metadata.gz: f61e01d00c87ea8b1d416e923e67703461ad1acb15818d5677d9d4d54bfd52435f8c7e23c4ccb22f9dee431ccb4cb1f0f6fe3c9ab1e3f509df2f5879e8caa8af
7
- data.tar.gz: 9513daf68578dc9356eb928cde89944cb3fcdd5b73d2393df47f6016f436a21f30362063ebaea92d867db7264ecef9cb7a74d8064b0d99cfb49002d57fa25949
6
+ metadata.gz: ba2d1791fe5e28fdf3bb1f2c21419129320400ff0a76283fb28c7bce3fa8345792bd2b40f9596967962f791e4c4446d913d9a365db388d8ecb194b409946f72b
7
+ data.tar.gz: f4dd4137445217bf4737b1255229fc3dd9b05dbd198f635124a8e93ade1c4e3b9104d639ba69c7fcfc87fc9730d290f02f52f4f16bdc3e7570233ceba7c5b7b4
@@ -21,8 +21,9 @@ Gem::Specification.new do |spec|
21
21
 
22
22
  spec.add_development_dependency "bundler", "~> 1.10"
23
23
  spec.add_development_dependency "rake", "~> 10.0"
24
- spec.add_development_dependency "rspec", '~> 3.4'
25
- spec.add_development_dependency "serverspec", '~> 2.34'
24
+ spec.add_development_dependency "rspec"
25
+ spec.add_development_dependency "serverspec"
26
26
 
27
- spec.add_runtime_dependency 'cfer', '~> 0.4'
27
+ spec.add_runtime_dependency 'cfer'
28
+ spec.add_runtime_dependency 'erubis', '~> 2.7.0'
28
29
  end
@@ -0,0 +1,47 @@
1
+ module Cfer
2
+ DEFAULT_CAPTURE_REGEXP = /C\{(?<directive>.*?)\}/
3
+
4
+ class Cfizer
5
+ begin
6
+ include Cfer::Core::Functions
7
+ rescue NameError => _
8
+ # we need to fall back to the old Cfer setup
9
+ include Cfer::Core
10
+ include Cfer::Cfn
11
+ end
12
+
13
+ def cfize(directive)
14
+ instance_eval directive
15
+ end
16
+ end
17
+
18
+ def self.cfize(text, capture_regexp: nil)
19
+ raise "'text' must be a string." unless text.is_a?(String)
20
+
21
+ capture_regexp ||= DEFAULT_CAPTURE_REGEXP
22
+
23
+ raise "'capture_regexp' must be a Regexp." unless capture_regexp.is_a?(Regexp)
24
+ raise "'capture_regexp' must include a 'contents' named 'directive'." \
25
+ unless capture_regexp.named_captures.key?('directive')
26
+
27
+ working = []
28
+ until(working[-2] == "" && working[-1] == "") do
29
+ if (working.size == 0)
30
+ working = text.partition(capture_regexp)
31
+ else
32
+ working[-1] = working[-1].partition(capture_regexp)
33
+ working = working.flatten
34
+ end
35
+ end
36
+
37
+ cfizer = Cfizer.new
38
+ Cfizer::Fn.join("", working.map do |token|
39
+ match = capture_regexp.match(token)
40
+ if (match.nil?)
41
+ token
42
+ else
43
+ cfizer.cfize(match['directive'])
44
+ end
45
+ end.reject { |t| t == ""})
46
+ end
47
+ end
@@ -0,0 +1,30 @@
1
+ #! /bin/bash -xe
2
+
3
+ function error_exit
4
+ {
5
+ <% unless @options[:signal].nil? %>
6
+ /usr/local/bin/cfn-signal -s 'false' \
7
+ --resource '<%= @options[:signal] %>' \
8
+ --stack 'C{AWS.stack_name}' \
9
+ --region 'C{AWS.region}'
10
+ <% end %>
11
+
12
+ exit 1
13
+ }
14
+
15
+ /usr/local/bin/cfn-init \
16
+ --resource '<%= @resource_name %>' \
17
+ --stack 'C{AWS.stack_name}' \
18
+ --region 'C{AWS.region}' \
19
+ --configsets '<%= @options[:cfn_init_config_set].join(",") %>' || error_exit 'cfn-init failed to start'
20
+
21
+ <% unless @options[:cfn_hup_config_set].nil? -%>
22
+ /usr/local/bin/cfn-hup || error_exit 'cfn-hup failed to start'
23
+ <% end -%>
24
+
25
+ <% unless @options[:signal].nil? -%>
26
+ /usr/local/bin/cfn-signal -s 'true' \
27
+ --resource '<%= @options[:signal] %>' \
28
+ --stack 'C{AWS.stack_name}' \
29
+ --region 'C{AWS.region}'
30
+ <% end -%>
@@ -1,4 +1,7 @@
1
+ require 'erubis'
2
+
1
3
  module Cfer::Provisioning
4
+ DEFAULT_HUP_INTERVAL_IN_MINUTES = 1
2
5
 
3
6
  def cfn_metadata
4
7
  self[:Metadata] ||= {}
@@ -11,83 +14,11 @@ module Cfer::Provisioning
11
14
 
12
15
  def cfn_init_setup(options = {})
13
16
  cfn_metadata['AWS::CloudFormation::Init'] = {}
14
-
15
- script = [ "#!/bin/bash -xe\n" ]
16
-
17
- script.concat [
18
- "command -v cfn-init 2>&1 || {\n",
19
- ]
20
- script.concat case options[:flavor]
21
- when :redhat, :centos, :amazon
22
- [
23
- "rpm -Uvh https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.amzn1.noarch.rpm\n"
24
- ]
25
- when :ubuntu, :debian, nil
26
- [
27
- "apt-get update --fix-missing\n",
28
- "apt-get install -y python-pip\n",
29
- "pip install setuptools\n",
30
- "easy_install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz\n",
31
- ]
32
- end
33
- script.concat [
34
- "}\n"
35
- ]
36
-
37
- script.concat [
38
- "# Helper function\n",
39
- "function error_exit\n",
40
- "{\n",
41
- ]
42
-
43
- if options[:signal]
44
- script.concat [
45
- "/usr/local/bin/cfn-signal",
46
- " -s false",
47
- " --resource '", options[:signal], "'",
48
- " --stack ", Cfer::Cfn::AWS::stack_name,
49
- " --region ", Cfer::Cfn::AWS::region,
50
- "\n"
51
- ]
52
- end
53
-
54
- script.concat [
55
- " exit 1\n",
56
- "}\n"
57
- ]
58
-
59
-
60
- script.concat [
61
- "/usr/local/bin/cfn-init",
62
- " --configsets '", Cfer::Core::Fn::join(',', options[:cfn_init_config_set]) || raise('Please specify a `cfn_init_config_set`'), "'",
63
- " --stack ", Cfer::Cfn::AWS::stack_name,
64
- " --resource ", @name,
65
- " --region ", Cfer::Cfn::AWS::region,
66
- " || error_exit 'Failed to run cfn-init'\n"
67
- ]
17
+ cfn_init_set_cloud_init(options)
68
18
 
69
19
  if options[:cfn_hup_config_set]
70
20
  cfn_hup(options)
71
-
72
- script.concat [
73
- "/usr/local/bin/cfn-hup || error_exit 'Failed to start cfn-hup'\n"
74
- ]
75
- end
76
-
77
- if options[:signal]
78
- script.concat [
79
- "/usr/local/bin/cfn-signal",
80
- " -s true",
81
- " --resource '", options[:signal], "'",
82
- " --stack ", Cfer::Cfn::AWS::stack_name,
83
- " --region ", Cfer::Cfn::AWS::region,
84
- "\n"
85
- ]
86
21
  end
87
-
88
- user_data Cfer::Core::Fn::base64(
89
- Cfer::Core::Fn::join('', script)
90
- )
91
22
  end
92
23
 
93
24
  def config_set(name)
@@ -152,44 +83,69 @@ module Cfer::Provisioning
152
83
 
153
84
  def cfn_hup(options)
154
85
  resource_name = @name
155
- target_config_set = options[:cfn_hup_config_set] || raise('Please specify a `cfn_hup_config_set`')
86
+ target_config_set = options[:cfn_hup_config_set] ||
87
+ raise('Please specify a `cfn_hup_config_set`')
156
88
 
157
89
  cfn_init_config_set :cfn_hup, [ :cfn_hup ]
158
90
 
159
91
  cfn_init_config(:cfn_hup) do
160
92
  if options[:access_key] && options[:secret_key]
161
- file '/etc/cfn/cfn-credentials', content: Cfer::Core::Fn::join('', [
162
- "AWSAccessKeyId=", options[:access_key], "\n",
163
- "AWSSecretKey=", options[:secret_key], "\n"
164
- ]),
165
- mode: '000400',
166
- owner: 'root',
167
- group: 'root'
93
+ key_content = <<-FILE.strip_heredoc
94
+ AWSAccessKeyId=#{options[:access_key]}
95
+ AWSSecretKey=#{options[:secret_key]}
96
+ FILE
97
+
98
+ file '/etc/cfn/cfn-credentials', content: key_content,
99
+ mode: '000400', owner: 'root', group: 'root'
168
100
  end
169
101
 
170
- file '/etc/cfn/cfn-hup.conf', content: Cfer::Core::Fn::join('', [
171
- "[main]\n",
172
- "stack=", Cfer::Cfn::AWS::stack_name, "\n",
173
- "region=", Cfer::Cfn::AWS::region, "\n",
174
- "interval=", options[:interval] || 1, "\n"
175
- ]),
176
- mode: '000400',
177
- owner: 'root',
178
- group: 'root'
179
-
180
- file '/etc/cfn/hooks.d/cfn-init-reload.conf', content: Cfer::Core::Fn::join('', [
181
- "[cfn-auto-reloader-hook]\n",
182
- "triggers=post.update\n",
183
- "path=Resources.#{resource_name}.Metadata\n",
184
- "action=/usr/local/bin/cfn-init",
185
- " -c '", Cfer::Core::Fn::join(',', target_config_set), "'",
186
- " -s ", Cfer::Cfn::AWS::stack_name,
187
- " --region ", Cfer::Cfn::AWS::region,
188
- " -r #{resource_name}",
189
- "\n",
190
- "runas=root\n"
191
- ])
102
+ hup_conf_content = <<-FILE.strip_heredoc
103
+ [main]
104
+ stack=C{AWS.stack_name}
105
+ region=C{AWS.region}
106
+ interval=#{DEFAULT_HUP_INTERVAL_IN_MINUTES}
107
+ FILE
108
+ file '/etc/cfn/cfn-hup.conf', content: Cfer.cfize(hup_conf_content),
109
+ mode: '000400', owner: 'root', group: 'root'
110
+
111
+ cfn_init_reload_content = <<-FILE.strip_heredoc
112
+ [cfn-auto-reloader-hook]
113
+ triggers=post.update
114
+ path=Resources.#{resource_name}.Metadata
115
+ runas=root
116
+ action=/usr/local/bin/cfn-init -r #{resource_name} --region C{AWS.region} -s C{AWS.stack_name} -c '#{target_config_set.join(",")}'
117
+ FILE
118
+
119
+ file '/etc/cfn/hooks.d/cfn-init-reload.conf',
120
+ content: Cfer.cfize(cfn_init_reload_content),
121
+ mode: '000400', owner: 'root', group: 'root'
192
122
  end
193
123
  end
124
+
125
+ def cfn_init_set_cloud_init(options)
126
+ cloud_init_bootcmds << "mkdir -p /usr/local/bin"
127
+
128
+ case options[:flavor]
129
+ when :redhat, :centos, :amazon
130
+ cloud_init_bootcmds <<
131
+ 'rpm -Uvh https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.amzn1.noarch.rpm'
132
+ when :debian, :ubuntu, nil
133
+ [
134
+ 'apt-get update --fix-missing',
135
+ 'apt-get install -y python-pip',
136
+ 'pip install setuptools',
137
+ 'easy_install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz'
138
+ ].each { |line| cloud_init_bootcmds << line }
139
+ end
140
+
141
+ cfn_script_eruby = Erubis::Eruby.new(IO.read("#{__dir__}/cfn-bootstrap.bash.erb"))
142
+
143
+ cloud_init_write_files << {
144
+ path: '/usr/local/bin/cfn-bootstrap.bash',
145
+ content: cfn_script_eruby.evaluate(resource_name: @name, options: options)
146
+ }
147
+
148
+ cloud_init_runcmds << "bash /usr/local/bin/cfn-bootstrap.bash"
149
+ end
194
150
  end
195
151
 
@@ -1,98 +1,144 @@
1
1
  module Cfer::Provisioning
2
+ def install_chef_solo_with_cloud_init(options = {})
3
+ # we can't use the cloud-init `chef` module because it expects a server/validator.
4
+
5
+ cloud_init_bootcmds <<
6
+ "command -v chef-client || " \
7
+ "curl https://www.opscode.com/chef/install.sh | " \
8
+ "bash -s -- -v #{options[:version] || 'latest'}"
9
+ cloud_init_bootcmds << "mkdir -p /etc/chef/ohai/hints"
10
+ cloud_init_bootcmds << "touch /etc/chef/ohai/hints/ec2.json"
11
+ cloud_init_bootcmds << "mkdir -p '#{options[:cookbook_path]}'"
12
+ cloud_init_bootcmds << "mkdir -p '#{options[:data_bag_path]}'"
13
+ end
2
14
 
3
- def install_chef(options = {})
4
- setup_set = [ :install_chef ]
5
- cfn_init_config :install_chef do
6
- command :install_chef, "curl https://www.opscode.com/chef/install.sh | bash -s -- -v #{options[:version] || 'latest'}"
7
- command :make_ohai_hints, 'mkdir -p /etc/chef/ohai/hints && touch /etc/chef/ohai/hints/ec2.json'
8
- command :make_chefdir, 'mkdir -p /var/chef/cookbooks && mkdir -p /var/chef/data_bags'
9
- end
10
-
11
- if options[:berksfile]
12
- cfn_init_config :install_berkshelf do
13
- file '/var/chef/berkshelf.sh', content: <<-EOF.strip_heredoc
14
- export BERKSHELF_PATH=/var/chef/berkshelf
15
-
16
- # Some cookbooks have UTF-8, and cfn-init uses US-ASCII because of reasons
17
- export LANG=en_US.UTF-8
18
- export RUBYOPTS="-E utf-8"
19
-
20
- # Berkshelf seems a bit unreliable, so retry these commands a couple times.
21
- if [ -e Berksfile.lock ]
22
- then
23
- for i in {1..3}; do /opt/chef/embedded/bin/berks update && break || sleep 15; done
24
- fi
25
- for i in {1..3}; do /opt/chef/embedded/bin/berks vendor /var/chef/cookbooks -b /var/chef/Berksfile && break || sleep 15; done
26
- EOF
27
- command :install_berkshelf, '/opt/chef/embedded/bin/gem install berkshelf --no-ri --no-rdoc'
28
- command :install_git, 'apt-get install -y git'
29
- end
30
- setup_set.append :install_berkshelf
31
- end
15
+ def install_berkshelf(options)
16
+ cloud_init_packages << 'git'
17
+
18
+ cloud_init_bootcmds << '/opt/chef/embedded/bin/gem install berkshelf --no-ri --no-rdoc'
19
+
20
+ berks_content = <<-EOF.strip_heredoc
21
+ # may be run before HOME is established (fixes RbReadLine bug)
22
+ export HOME=/root
23
+ export BERKSHELF_PATH=/var/chef/berkshelf
24
+
25
+ # Some cookbooks have UTF-8, and cfn-init uses US-ASCII because of reasons
26
+ export LANG=en_US.UTF-8
27
+ export RUBYOPTS="-E utf-8"
28
+
29
+ # Berkshelf seems a bit unreliable, so retry these commands a couple times.
30
+ if [ -e Berksfile.lock ]
31
+ then
32
+ for i in {1..3}; do
33
+ /opt/chef/embedded/bin/berks update && break || sleep 15
34
+ done
35
+ fi
36
+ for i in {1..3}; do
37
+ /opt/chef/embedded/bin/berks vendor '#{options[:cookbook_path]}' \
38
+ -b /var/chef/Berksfile && break || sleep 15
39
+ done
40
+ EOF
41
+
42
+ cloud_init_write_files << {
43
+ path: '/var/chef/berkshelf.sh',
44
+ content: berks_content,
45
+ permissions: '0500'
46
+ }
47
+ end
32
48
 
33
- if options[:berksfile]
34
- cfn_init_config :run_berkshelf do
35
- file '/var/chef/Berksfile', content: options[:berksfile].strip_heredoc
36
- command :run_berkshelf, 'bash -l /var/chef/berkshelf.sh', cwd: '/var/chef'
37
- end
49
+ def emit_berksfile(options)
50
+ cfn_init_config :emit_berksfile do
51
+ file '/var/chef/Berksfile', content: Cfer.cfize(options[:berksfile].strip_heredoc),
52
+ mode: '000500', owner: 'root', group: 'root'
38
53
  end
39
-
40
- cfn_init_config_set :install_chef, setup_set
41
54
  end
42
55
 
43
- def set_chef_json(json = {})
44
- self[:Metadata]['CferExt::Provisioning::Chef'] = json || {}
56
+ def run_berkshelf(options)
57
+ cfn_init_config :run_berkshelf do
58
+ command :run_berkshelf, '/var/chef/berkshelf.sh', cwd: '/var/chef'
59
+ end
45
60
  end
46
61
 
47
62
  def build_write_json_cmd(chef_solo_json_path)
48
- Cfer::Core::Fn.join('', [
49
- "mkdir -p #{File.dirname(chef_solo_json_path)} && cfn-get-metadata --region ",
50
- Cfer::Cfn::AWS.region,
51
- ' -s ', Cfer::Cfn::AWS.stack_name, ' -r ', @name,
52
- " | python -c 'import sys; import json; print " \
53
- "json.dumps(json.loads(sys.stdin.read()).get(" \
54
- '"CferExt::Provisioning::Chef", {}), sort_keys=True, indent=2)',
55
- "' > #{chef_solo_json_path}"
56
- ])
63
+ python_json_dump = [
64
+ 'import sys; import json;',
65
+ 'print json.dumps(json.loads(sys.stdin.read())',
66
+ '.get("CferExt::Provisioning::Chef", {}), sort_keys=True, indent=2)'
67
+ ].join('')
68
+
69
+ cmd = <<-BASH.strip_heredoc
70
+ mkdir -p '#{File.dirname(chef_solo_json_path)}' &&
71
+ cfn-get-metadata --region 'C{AWS.region}' \
72
+ -s 'C{AWS.stack_name}' \
73
+ -r #{@name} |
74
+ python -c '#{python_json_dump}' > #{chef_solo_json_path}
75
+ BASH
76
+
77
+ Cfer.cfize(cmd)
57
78
  end
58
79
 
59
80
  def chef_solo(options = {})
60
81
  raise "Chef already configured on this resource" if @chef
61
82
  @chef = true
62
83
 
63
- chef_solo_config_path = options[:config_path] || '/etc/chef/solo.rb'
64
- chef_solo_json_path = options[:json_path] || '/etc/chef/config.json'
84
+ must_install_berkshelf = !options[:berksfile].nil? || options[:force_berkshelf_install]
85
+
86
+ options[:config_path] ||= '/etc/chef/solo.rb'
87
+ options[:json_path] ||= '/etc/chef/node.json'
88
+ options[:cookbook_path] ||= '/var/chef/cookbooks'
89
+ options[:data_bag_path] ||= '/var/chef/data_bags'
90
+ options[:log_path] ||= '/var/log/chef-solo.log'
91
+
92
+ install_chef_solo_with_cloud_init(options) unless options[:no_install]
65
93
 
66
- chef_cookbook_path = options[:cookbook_path] || '/var/chef/cookbooks'
67
- chef_log_path = options[:log_path] || '/var/log/chef-client.log'
94
+ if must_install_berkshelf
95
+ install_berkshelf(options) if must_install_berkshelf # places cloud-init runners
96
+ end
68
97
 
69
- install_chef(options) unless options[:no_install]
98
+ run_set = []
70
99
 
71
- set_chef_json(options[:json])
72
- write_json_cmd = build_write_json_cmd(chef_solo_json_path)
100
+ unless options[:berksfile].nil?
101
+ emit_berksfile(options)
102
+ run_set << :emit_berksfile
103
+ end
73
104
 
105
+ unless options[:berksfile].nil? || options[:no_run_berkshelf]
106
+ run_berkshelf(options)
107
+ run_set << :run_berkshelf
108
+ end
109
+
110
+ cfn_metadata['CferExt::Provisioning::Chef'] = options[:json] || {}
74
111
  cfn_init_config :write_chef_json do
75
- command :write_chef_json, write_json_cmd
112
+ command :write_chef_json, build_write_json_cmd(options[:json_path])
76
113
  end
114
+ run_set << :write_chef_json
115
+
116
+ cfn_init_config :run_chef_solo do
117
+ solo_rb = <<-RB.strip_heredoc
118
+ cookbook_path '#{options[:cookbook_path]}'
119
+ log_location '#{options[:log_path]}'
77
120
 
78
- cfn_init_config :run_chef do
79
- file chef_solo_config_path, content: options[:solo_rb] || Cfer::Core::Fn.join("\n", [
80
- "cookbook_path '#{chef_cookbook_path}'",
81
- "log_location '#{chef_log_path}'",
82
- ""
83
- ]),
84
- owner: 'root',
85
- group: 'root'
121
+ json_attribs '#{options[:json_path]}'
122
+ RB
86
123
 
87
- chef_cmd = "chef-solo -c '#{chef_solo_config_path}' -j '#{chef_solo_json_path}'"
88
- chef_cmd << " -o '#{options[:run_list].join(',')}'" if options[:run_list]
124
+ file options[:config_path], content: options[:solo_rb] || solo_rb,
125
+ mode: '000400', owner: 'root', group: 'root'
89
126
 
90
- command :run_chef, chef_cmd
127
+ run_list = options[:run_list] || []
128
+
129
+ chef_cmd = "chef-solo -c '#{options[:config_path]}' -j '#{options[:json_path]}'"
130
+ chef_cmd << " -o '#{options[:run_list].join(',')}'" unless options[:run_list].empty?
131
+
132
+ file '/usr/local/bin/run-chef-solo.bash', content: chef_cmd,
133
+ mode: '000500', owner: 'root', group: 'root'
134
+
135
+ command :run_chef, 'bash /usr/local/bin/run-chef-solo.bash'
91
136
  end
137
+ run_set << :run_chef_solo
92
138
 
93
- run_set = [ :write_chef_json, :run_chef ]
94
- run_set.prepend :run_berkshelf if options[:berkshelf]
95
- cfn_init_config_set :run_chef, run_set
139
+ cfn_init_config_set :run_chef_solo, run_set
96
140
  end
141
+
142
+ private
97
143
  end
98
144
 
@@ -0,0 +1,75 @@
1
+ require 'yaml'
2
+
3
+ module Cfer::Provisioning
4
+ def cloud_init
5
+ unless self.key?(:CloudInit)
6
+ self[:CloudInit] = {
7
+ bootcmd: [],
8
+ runcmd: [],
9
+ packages: [],
10
+ ssh_authorized_keys: [],
11
+ write_files: [
12
+ {
13
+ path: '/etc/cfn-resource-name',
14
+ permissions: '0444',
15
+ content: @name.to_s
16
+ },
17
+ {
18
+ path: '/etc/cfn-stack-name',
19
+ permissions: '0444',
20
+ content: 'C{AWS.stack_name}'
21
+ },
22
+ {
23
+ path: '/etc/cfn-region',
24
+ permissions: '0444',
25
+ content: 'C{AWS.region}'
26
+ }
27
+ ],
28
+ output: {}
29
+ }
30
+ end
31
+
32
+ self[:CloudInit]
33
+ end
34
+
35
+ def cloud_init_bootcmds
36
+ cloud_init[:bootcmd]
37
+ end
38
+
39
+ def cloud_init_runcmds
40
+ cloud_init[:runcmd]
41
+ end
42
+
43
+ def cloud_init_outputs
44
+ cloud_init[:output]
45
+ end
46
+
47
+ def cloud_init_packages
48
+ cloud_init[:packages]
49
+ end
50
+
51
+ def cloud_init_write_files
52
+ cloud_init[:write_files]
53
+ end
54
+
55
+ def cloud_init_ssh_authorized_keys
56
+ cloud_init[:ssh_authorized_keys]
57
+ end
58
+
59
+ def cloud_init_finalize!
60
+ cloud_init_outputs[:all] ||= "| tee -a /var/log/cloud-init-output.log"
61
+
62
+ user_data Cfer::Core::Fn.base64( cloud_init_to_user_data(self[:CloudInit]) )
63
+ self.delete :CloudInit
64
+ end
65
+
66
+ private
67
+ def cloud_init_to_user_data(cloud_init)
68
+
69
+ Cfer.cfize([
70
+ '#cloud-config',
71
+ YAML.dump(cloud_init.to_hash_recursive.deep_stringify_keys).gsub(/^---$/, "")
72
+ ].join("\n"))
73
+ end
74
+
75
+ end
@@ -0,0 +1,33 @@
1
+ class Hash
2
+ def to_hash_recursive
3
+ result = self.to_hash
4
+
5
+ result.each do |key, value|
6
+ case value
7
+ when Hash
8
+ result[key] = value.to_hash_recursive
9
+ when Array
10
+ result[key] = value.to_hash_recursive
11
+ end
12
+ end
13
+
14
+ result
15
+ end
16
+ end
17
+
18
+ class Array
19
+ def to_hash_recursive
20
+ result = self
21
+
22
+ result.each_with_index do |value,i|
23
+ case value
24
+ when Hash
25
+ result[i] = value.to_hash_recursive
26
+ when Array
27
+ result[i] = value.to_hash_recursive
28
+ end
29
+ end
30
+
31
+ result
32
+ end
33
+ end
@@ -1,5 +1,5 @@
1
1
  module Cfer
2
2
  module Provisioning
3
- VERSION = "0.1.0"
3
+ VERSION = "0.2.0-alpha1"
4
4
  end
5
5
  end
@@ -1,4 +1,5 @@
1
1
  require "cfer/provisioning/version"
2
+ require "cfer/cfizer"
2
3
  require 'cfer'
3
4
 
4
5
  require 'base64'
@@ -9,6 +10,9 @@ module Cfer
9
10
  end
10
11
  end
11
12
 
13
+ require 'cfer/provisioning/extensions'
14
+
15
+ require 'cfer/provisioning/cloud-init'
12
16
  require 'cfer/provisioning/cfn-bootstrap'
13
17
  require 'cfer/provisioning/chef'
14
18
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cfer-provisioning
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0.pre.alpha1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sean Edwards
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-05-11 00:00:00.000000000 Z
11
+ date: 2016-07-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -42,44 +42,58 @@ dependencies:
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '3.4'
47
+ version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '3.4'
54
+ version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: serverspec
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: '2.34'
61
+ version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - "~>"
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: '2.34'
68
+ version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: cfer
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: erubis
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
87
  - - "~>"
74
88
  - !ruby/object:Gem::Version
75
- version: '0.4'
89
+ version: 2.7.0
76
90
  type: :runtime
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
80
94
  - - "~>"
81
95
  - !ruby/object:Gem::Version
82
- version: '0.4'
96
+ version: 2.7.0
83
97
  description: Provisioning tools for Cfer
84
98
  email:
85
99
  - stedwards87+git@gmail.com
@@ -96,9 +110,13 @@ files:
96
110
  - README.md
97
111
  - Rakefile
98
112
  - cfer-provisioning.gemspec
113
+ - lib/cfer/cfizer.rb
99
114
  - lib/cfer/provisioning.rb
115
+ - lib/cfer/provisioning/cfn-bootstrap.bash.erb
100
116
  - lib/cfer/provisioning/cfn-bootstrap.rb
101
117
  - lib/cfer/provisioning/chef.rb
118
+ - lib/cfer/provisioning/cloud-init.rb
119
+ - lib/cfer/provisioning/extensions.rb
102
120
  - lib/cfer/provisioning/version.rb
103
121
  - parameters.yaml.example
104
122
  homepage: https://github.com/seanedwards/cfer-provisioning
@@ -116,9 +134,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
116
134
  version: '0'
117
135
  required_rubygems_version: !ruby/object:Gem::Requirement
118
136
  requirements:
119
- - - ">="
137
+ - - ">"
120
138
  - !ruby/object:Gem::Version
121
- version: '0'
139
+ version: 1.3.1
122
140
  requirements: []
123
141
  rubyforge_project:
124
142
  rubygems_version: 2.5.1
@@ -126,4 +144,3 @@ signing_key:
126
144
  specification_version: 4
127
145
  summary: Provisioning tools for Cfer
128
146
  test_files: []
129
- has_rdoc: