Openstack: Vendor data cleanup
For now, this vendor data handling is just added to openstack. However, in an effort to allow sanely handling of multi-part vendor-data that is namespaced, we add openstack.convert_vendordata_json . That basically takes whatever was loaded from vendordata and takes the 'cloud-init' key if it is a dict. This way the author can namespace cloud-init, basically telling it to ignore everything else.
This commit is contained in:
parent
95fb96e921
commit
7148fe7552
@ -126,12 +126,13 @@ class DataSourceConfigDrive(openstack.SourceMixin, sources.DataSource):
|
|||||||
self.version = results['version']
|
self.version = results['version']
|
||||||
self.files.update(results.get('files', {}))
|
self.files.update(results.get('files', {}))
|
||||||
|
|
||||||
# If there is no vendordata, set vd to an empty dict instead of None
|
vd = results.get('vendordata')
|
||||||
vd = results.get('vendordata', {})
|
self.vendordata_pure = vd
|
||||||
# if vendordata includes 'cloud-init', then read that explicitly
|
try:
|
||||||
# for cloud-init (for namespacing).
|
self.vendordata_raw = openstack.convert_vendordata_json(vd)
|
||||||
if 'cloud-init' in vd:
|
except ValueError as e:
|
||||||
self.vendordata_raw = vd['cloud-init']
|
LOG.warn("Invalid content in vendor-data: %s", e)
|
||||||
|
self.vendordata_raw = None
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -140,13 +140,13 @@ class DataSourceOpenStack(openstack.SourceMixin, sources.DataSource):
|
|||||||
self.version = results['version']
|
self.version = results['version']
|
||||||
self.files.update(results.get('files', {}))
|
self.files.update(results.get('files', {}))
|
||||||
|
|
||||||
# if vendordata includes 'cloud-init', then read that explicitly
|
|
||||||
# for cloud-init (for namespacing).
|
|
||||||
vd = results.get('vendordata')
|
vd = results.get('vendordata')
|
||||||
if isinstance(vd, dict) and 'cloud-init' in vd:
|
self.vendordata_pure = vd
|
||||||
self.vendordata_raw = vd['cloud-init']
|
try:
|
||||||
else:
|
self.vendordata_raw = openstack.convert_vendordata_json(vd)
|
||||||
self.vendordata_raw = vd
|
except ValueError as e:
|
||||||
|
LOG.warn("Invalid content in vendor-data: %s", e)
|
||||||
|
self.vendordata_raw = None
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -459,3 +459,28 @@ class MetadataReader(BaseReader):
|
|||||||
return ec2_utils.get_instance_metadata(ssl_details=self.ssl_details,
|
return ec2_utils.get_instance_metadata(ssl_details=self.ssl_details,
|
||||||
timeout=self.timeout,
|
timeout=self.timeout,
|
||||||
retries=self.retries)
|
retries=self.retries)
|
||||||
|
|
||||||
|
|
||||||
|
def convert_vendordata_json(data, recurse=True):
|
||||||
|
""" data: a loaded json *object* (strings, arrays, dicts).
|
||||||
|
return something suitable for cloudinit vendordata_raw.
|
||||||
|
|
||||||
|
if data is:
|
||||||
|
None: return None
|
||||||
|
string: return string
|
||||||
|
list: return data
|
||||||
|
the list is then processed in UserDataProcessor
|
||||||
|
dict: return convert_vendordata_json(data.get('cloud-init'))
|
||||||
|
"""
|
||||||
|
if not data:
|
||||||
|
return None
|
||||||
|
if isinstance(data, (str, unicode, basestring)):
|
||||||
|
return data
|
||||||
|
if isinstance(data, list):
|
||||||
|
return copy.deepcopy(data)
|
||||||
|
if isinstance(data, dict):
|
||||||
|
if recurse is True:
|
||||||
|
return convert_vendordata_json(data.get('cloud-init'),
|
||||||
|
recurse=False)
|
||||||
|
raise ValueError("vendordata['cloud-init'] cannot be dict")
|
||||||
|
raise ValueError("Unknown data type for vendordata: %s" % type(data))
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
import copy
|
import copy
|
||||||
import json
|
import json
|
||||||
import re
|
import re
|
||||||
|
import unittest
|
||||||
|
|
||||||
from StringIO import StringIO
|
from StringIO import StringIO
|
||||||
|
|
||||||
@ -256,7 +257,8 @@ class TestOpenStackDataSource(test_helpers.HttprettyTestCase):
|
|||||||
self.assertEquals(EC2_META, ds_os.ec2_metadata)
|
self.assertEquals(EC2_META, ds_os.ec2_metadata)
|
||||||
self.assertEquals(USER_DATA, ds_os.userdata_raw)
|
self.assertEquals(USER_DATA, ds_os.userdata_raw)
|
||||||
self.assertEquals(2, len(ds_os.files))
|
self.assertEquals(2, len(ds_os.files))
|
||||||
self.assertEquals(VENDOR_DATA, ds_os.vendordata_raw)
|
self.assertEquals(VENDOR_DATA, ds_os.vendordata_pure)
|
||||||
|
self.assertEquals(ds_os.vendordata_raw, None)
|
||||||
|
|
||||||
@hp.activate
|
@hp.activate
|
||||||
def test_bad_datasource_meta(self):
|
def test_bad_datasource_meta(self):
|
||||||
@ -314,3 +316,34 @@ class TestOpenStackDataSource(test_helpers.HttprettyTestCase):
|
|||||||
found = ds_os.get_data()
|
found = ds_os.get_data()
|
||||||
self.assertFalse(found)
|
self.assertFalse(found)
|
||||||
self.assertIsNone(ds_os.version)
|
self.assertIsNone(ds_os.version)
|
||||||
|
|
||||||
|
|
||||||
|
class TestVendorDataLoading(unittest.TestCase):
|
||||||
|
def cvj(self, data):
|
||||||
|
return openstack.convert_vendordata_json(data)
|
||||||
|
|
||||||
|
def test_vd_load_none(self):
|
||||||
|
# non-existant vendor-data should return none
|
||||||
|
self.assertIsNone(self.cvj(None))
|
||||||
|
|
||||||
|
def test_vd_load_string(self):
|
||||||
|
self.assertEqual(self.cvj("foobar"), "foobar")
|
||||||
|
|
||||||
|
def test_vd_load_list(self):
|
||||||
|
data = [{'foo': 'bar'}, 'mystring', list(['another', 'list'])]
|
||||||
|
self.assertEqual(self.cvj(data), data)
|
||||||
|
|
||||||
|
def test_vd_load_dict_no_ci(self):
|
||||||
|
self.assertEqual(self.cvj({'foo': 'bar'}), None)
|
||||||
|
|
||||||
|
def test_vd_load_dict_ci_dict(self):
|
||||||
|
self.assertRaises(ValueError, self.cvj,
|
||||||
|
{'foo': 'bar', 'cloud-init': {'x': 1}})
|
||||||
|
|
||||||
|
def test_vd_load_dict_ci_string(self):
|
||||||
|
data = {'foo': 'bar', 'cloud-init': 'VENDOR_DATA'}
|
||||||
|
self.assertEqual(self.cvj(data), data['cloud-init'])
|
||||||
|
|
||||||
|
def test_vd_load_dict_ci_list(self):
|
||||||
|
data = {'foo': 'bar', 'cloud-init': ['VD_1', 'VD_2']}
|
||||||
|
self.assertEqual(self.cvj(data), data['cloud-init'])
|
||||||
|
Loading…
x
Reference in New Issue
Block a user