Merge lp:~smoser/cloud-init/trunk.1568940 into lp:~cloud-init-dev/cloud-init/trunk

Proposed by Scott Moser
Status: Merged
Merged at revision: 1207
Proposed branch: lp:~smoser/cloud-init/trunk.1568940
Merge into: lp:~cloud-init-dev/cloud-init/trunk
Diff against target: 174 lines (+84/-13)
4 files modified
cloudinit/config/cc_chef.py (+17/-9)
doc/examples/cloud-config-chef.txt (+3/-1)
templates/chef_client.rb.tmpl (+1/-1)
tests/unittests/test_handler/test_handler_chef.py (+63/-2)
To merge this branch: bzr merge lp:~smoser/cloud-init/trunk.1568940
Reviewer Review Type Date Requested Status
cloud-init Commiters Pending
Review via email: mp+291635@code.launchpad.net

Commit message

chef: straighten out validation_cert and validation_key

Now, validation_key is always a path to a file, as it is in
chef's client.rb syntax.

validation_cert is always the *content* of that file that should
be written. However, if validation_cert is the string "system",
then we do not write that value, but rather assume the file exists.

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'cloudinit/config/cc_chef.py'
--- cloudinit/config/cc_chef.py 2016-04-04 19:17:28 +0000
+++ cloudinit/config/cc_chef.py 2016-04-12 14:47:21 +0000
@@ -38,8 +38,10 @@
38 chef:38 chef:
39 directories: (defaulting to /etc/chef, /var/log/chef, /var/lib/chef,39 directories: (defaulting to /etc/chef, /var/log/chef, /var/lib/chef,
40 /var/cache/chef, /var/backups/chef, /var/run/chef)40 /var/cache/chef, /var/backups/chef, /var/run/chef)
41 validation_key or validation_cert: (optional string to be written to41 validation_cert: (optional string to be written to file validation_key)
42 /etc/chef/validation.pem)42 special value 'system' means set use existing file
43 validation_key: (optional the path for validation_cert. default
44 /etc/chef/validation.pem)
43 firstboot_path: (path to write run_list and initial_attributes keys that45 firstboot_path: (path to write run_list and initial_attributes keys that
44 should also be present in this configuration, defaults46 should also be present in this configuration, defaults
45 to /etc/chef/firstboot.json)47 to /etc/chef/firstboot.json)
@@ -64,6 +66,7 @@
64 server_url:66 server_url:
65 show_time:67 show_time:
66 ssl_verify_mode:68 ssl_verify_mode:
69 validation_cert:
67 validation_key:70 validation_key:
68 validation_name:71 validation_name:
69"""72"""
@@ -105,6 +108,7 @@
105 # These are not symbols...108 # These are not symbols...
106 'log_location': '/var/log/chef/client.log',109 'log_location': '/var/log/chef/client.log',
107 'validation_key': CHEF_VALIDATION_PEM_PATH,110 'validation_key': CHEF_VALIDATION_PEM_PATH,
111 'validation_cert': None,
108 'client_key': "/etc/chef/client.pem",112 'client_key': "/etc/chef/client.pem",
109 'json_attribs': CHEF_FB_PATH,113 'json_attribs': CHEF_FB_PATH,
110 'file_cache_path': "/var/cache/chef",114 'file_cache_path': "/var/cache/chef",
@@ -201,13 +205,17 @@
201 for d in itertools.chain(chef_dirs, REQUIRED_CHEF_DIRS):205 for d in itertools.chain(chef_dirs, REQUIRED_CHEF_DIRS):
202 util.ensure_dir(d)206 util.ensure_dir(d)
203207
204 # Set the validation key based on the presence of either 'validation_key'208 vkey_path = chef_cfg.get('validation_key', CHEF_VALIDATION_PEM_PATH)
205 # or 'validation_cert'. In the case where both exist, 'validation_key'209 vcert = chef_cfg.get('validation_cert')
206 # takes precedence210 # special value 'system' means do not overwrite the file
207 for key in ('validation_key', 'validation_cert'):211 # but still render the template to contain 'validation_key'
208 if key in chef_cfg and chef_cfg[key]:212 if vcert:
209 util.write_file(CHEF_VALIDATION_PEM_PATH, chef_cfg[key])213 if vcert != "system":
210 break214 util.write_file(vkey_path, vcert)
215 elif not os.path.isfile(vkey_path):
216 log.warn("chef validation_cert provided as 'system', but "
217 "validation_key path '%s' does not exist.",
218 vkey_path)
211219
212 # Create the chef config from template220 # Create the chef config from template
213 template_fn = cloud.get_template_filename('chef_client.rb')221 template_fn = cloud.get_template_filename('chef_client.rb')
214222
=== modified file 'doc/examples/cloud-config-chef.txt'
--- doc/examples/cloud-config-chef.txt 2012-12-12 15:39:43 +0000
+++ doc/examples/cloud-config-chef.txt 2016-04-12 14:47:21 +0000
@@ -67,7 +67,9 @@
6767
68 # Default validation name is chef-validator68 # Default validation name is chef-validator
69 validation_name: "yourorg-validator"69 validation_name: "yourorg-validator"
70 validation_key: |70 # if validation_cert's value is "system" then it is expected
71 # that the file already exists on the system.
72 validation_cert: |
71 -----BEGIN RSA PRIVATE KEY-----73 -----BEGIN RSA PRIVATE KEY-----
72 YOUR-ORGS-VALIDATION-KEY-HERE74 YOUR-ORGS-VALIDATION-KEY-HERE
73 -----END RSA PRIVATE KEY-----75 -----END RSA PRIVATE KEY-----
7476
=== modified file 'templates/chef_client.rb.tmpl'
--- templates/chef_client.rb.tmpl 2014-10-11 23:59:50 +0000
+++ templates/chef_client.rb.tmpl 2016-04-12 14:47:21 +0000
@@ -26,7 +26,7 @@
26{% if validation_name %}26{% if validation_name %}
27validation_client_name "{{validation_name}}"27validation_client_name "{{validation_name}}"
28{% endif %}28{% endif %}
29{% if validation_key %}29{% if validation_cert %}
30validation_key "{{validation_key}}"30validation_key "{{validation_key}}"
31{% endif %}31{% endif %}
32{% if client_key %}32{% if client_key %}
3333
=== modified file 'tests/unittests/test_handler/test_handler_chef.py'
--- tests/unittests/test_handler/test_handler_chef.py 2015-02-10 20:32:32 +0000
+++ tests/unittests/test_handler/test_handler_chef.py 2016-04-12 14:47:21 +0000
@@ -75,17 +75,28 @@
75 'chef': {75 'chef': {
76 'server_url': 'localhost',76 'server_url': 'localhost',
77 'validation_name': 'bob',77 'validation_name': 'bob',
78 'validation_key': "/etc/chef/vkey.pem",
79 'validation_cert': "this is my cert",
78 },80 },
79 }81 }
80 cc_chef.handle('chef', cfg, self.fetch_cloud('ubuntu'), LOG, [])82 cc_chef.handle('chef', cfg, self.fetch_cloud('ubuntu'), LOG, [])
81 for d in cc_chef.CHEF_DIRS:83 for d in cc_chef.CHEF_DIRS:
82 self.assertTrue(os.path.isdir(d))84 self.assertTrue(os.path.isdir(d))
83 c = util.load_file(cc_chef.CHEF_RB_PATH)85 c = util.load_file(cc_chef.CHEF_RB_PATH)
86
87 # the content of these keys is not expected to be rendered to tmpl
88 unrendered_keys = ('validation_cert',)
84 for k, v in cfg['chef'].items():89 for k, v in cfg['chef'].items():
90 if k in unrendered_keys:
91 continue
85 self.assertIn(v, c)92 self.assertIn(v, c)
86 for k, v in cc_chef.CHEF_RB_TPL_DEFAULTS.items():93 for k, v in cc_chef.CHEF_RB_TPL_DEFAULTS.items():
87 if isinstance(v, six.string_types):94 if k in unrendered_keys:
88 self.assertIn(v, c)95 continue
96 # the value from the cfg overrides that in the default
97 val = cfg['chef'].get(k, v)
98 if isinstance(val, six.string_types):
99 self.assertIn(val, c)
89 c = util.load_file(cc_chef.CHEF_FB_PATH)100 c = util.load_file(cc_chef.CHEF_FB_PATH)
90 self.assertEqual({}, json.loads(c))101 self.assertEqual({}, json.loads(c))
91102
@@ -131,3 +142,53 @@
131 c = util.load_file(cc_chef.CHEF_RB_PATH)142 c = util.load_file(cc_chef.CHEF_RB_PATH)
132 self.assertNotIn('json_attribs', c)143 self.assertNotIn('json_attribs', c)
133 self.assertNotIn('Formatter.show_time', c)144 self.assertNotIn('Formatter.show_time', c)
145
146 @t_help.skipIf(not os.path.isfile(CLIENT_TEMPL),
147 CLIENT_TEMPL + " is not available")
148 def test_validation_cert_and_validation_key(self):
149 # test validation_cert content is written to validation_key path
150 tpl_file = util.load_file('templates/chef_client.rb.tmpl')
151 self.patchUtils(self.tmp)
152 self.patchOS(self.tmp)
153
154 util.write_file('/etc/cloud/templates/chef_client.rb.tmpl', tpl_file)
155 v_path = '/etc/chef/vkey.pem'
156 v_cert = 'this is my cert'
157 cfg = {
158 'chef': {
159 'server_url': 'localhost',
160 'validation_name': 'bob',
161 'validation_key': v_path,
162 'validation_cert': v_cert
163 },
164 }
165 cc_chef.handle('chef', cfg, self.fetch_cloud('ubuntu'), LOG, [])
166 content = util.load_file(cc_chef.CHEF_RB_PATH)
167 self.assertIn(v_path, content)
168 util.load_file(v_path)
169 self.assertEqual(v_cert, util.load_file(v_path))
170
171 def test_validation_cert_with_system(self):
172 # test validation_cert content is not written over system file
173 tpl_file = util.load_file('templates/chef_client.rb.tmpl')
174 self.patchUtils(self.tmp)
175 self.patchOS(self.tmp)
176
177 v_path = '/etc/chef/vkey.pem'
178 v_cert = "system"
179 expected_cert = "this is the system file certificate"
180 cfg = {
181 'chef': {
182 'server_url': 'localhost',
183 'validation_name': 'bob',
184 'validation_key': v_path,
185 'validation_cert': v_cert
186 },
187 }
188 util.write_file('/etc/cloud/templates/chef_client.rb.tmpl', tpl_file)
189 util.write_file(v_path, expected_cert)
190 cc_chef.handle('chef', cfg, self.fetch_cloud('ubuntu'), LOG, [])
191 content = util.load_file(cc_chef.CHEF_RB_PATH)
192 self.assertIn(v_path, content)
193 util.load_file(v_path)
194 self.assertEqual(expected_cert, util.load_file(v_path))