Skip to content

Commit

Permalink
Merge "Refactoring metadata/base"
Browse files Browse the repository at this point in the history
  • Loading branch information
Jenkins authored and openstack-gerrit committed Feb 28, 2014
2 parents 84b616d + d98bb17 commit cb31014
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 56 deletions.
142 changes: 86 additions & 56 deletions nova/api/metadata/base.py
Expand Up @@ -57,7 +57,6 @@
CONF.register_opts(metadata_opts)
CONF.import_opt('dhcp_domain', 'nova.network.manager')


VERSIONS = [
'1.0',
'2007-01-19',
Expand All @@ -79,6 +78,8 @@
HAVANA,
]

VERSION = "version"
CONTENT = "content"
CONTENT_DIR = "content"
MD_JSON_NAME = "meta_data.json"
VD_JSON_NAME = "vendor_data.json"
Expand Down Expand Up @@ -190,6 +191,22 @@ def __init__(self, instance, address=None, content=None, extra_md=None,
self.vddriver = vdclass(instance=instance, address=address,
extra_md=extra_md, network_info=network_info)

self.route_configuration = None

def _route_configuration(self):
if self.route_configuration:
return self.route_configuration

path_handlers = {UD_NAME: self._user_data,
PASS_NAME: self._password,
VD_JSON_NAME: self._vendor_data,
MD_JSON_NAME: self._metadata_as_json,
VERSION: self._handle_version,
CONTENT: self._handle_content}

self.route_configuration = RouteConfiguration(path_handlers)
return self.route_configuration

def get_ec2_metadata(self, version):
if version == "latest":
version = VERSIONS[-1]
Expand Down Expand Up @@ -275,83 +292,66 @@ def get_ec2_item(self, path_tokens):

def get_openstack_item(self, path_tokens):
if path_tokens[0] == CONTENT_DIR:
if len(path_tokens) == 1:
raise KeyError("no listing for %s" % "/".join(path_tokens))
if len(path_tokens) != 2:
raise KeyError("Too many tokens for /%s" % CONTENT_DIR)
return self.content[path_tokens[1]]

version = path_tokens[0]
if version == "latest":
version = OPENSTACK_VERSIONS[-1]

if version not in OPENSTACK_VERSIONS:
raise InvalidMetadataVersion(version)

path = '/'.join(path_tokens[1:])

if len(path_tokens) == 1:
# request for /version, give a list of what is available
ret = [MD_JSON_NAME]
if self.userdata_raw is not None:
ret.append(UD_NAME)
if self._check_os_version(GRIZZLY, version):
ret.append(PASS_NAME)
if self._check_os_version(HAVANA, version):
ret.append(VD_JSON_NAME)
return ret

if path == UD_NAME:
if self.userdata_raw is None:
raise KeyError(path)
return self.userdata_raw

if path == PASS_NAME and self._check_os_version(GRIZZLY, version):
return password.handle_password

if path == VD_JSON_NAME and self._check_os_version(HAVANA, version):
return json.dumps(self.vddriver.get())

if path != MD_JSON_NAME:
raise KeyError(path)

metadata = {}
metadata['uuid'] = self.uuid
return self._handle_content(path_tokens)
return self._route_configuration().handle_path(path_tokens)

def _metadata_as_json(self, version, path):
metadata = {'uuid': self.uuid}
if self.launch_metadata:
metadata['meta'] = self.launch_metadata

if self.files:
metadata['files'] = self.files

if self.extra_md:
metadata.update(self.extra_md)

if self.launch_metadata:
metadata['meta'] = self.launch_metadata

if self.network_config:
metadata['network_config'] = self.network_config

if self.instance['key_name']:
metadata['public_keys'] = {
self.instance['key_name']: self.instance['key_data']
}

metadata['hostname'] = self._get_hostname()

metadata['name'] = self.instance['display_name']
metadata['launch_index'] = self.instance['launch_index']
metadata['availability_zone'] = self.availability_zone

if self._check_os_version(GRIZZLY, version):
metadata['random_seed'] = base64.b64encode(os.urandom(512))

data = {
MD_JSON_NAME: json.dumps(metadata),
}
return json.dumps(metadata)

def _handle_content(self, path_tokens):
if len(path_tokens) == 1:
raise KeyError("no listing for %s" % "/".join(path_tokens))
if len(path_tokens) != 2:
raise KeyError("Too many tokens for /%s" % CONTENT_DIR)
return self.content[path_tokens[1]]

def _handle_version(self, version, path):
# request for /version, give a list of what is available
ret = [MD_JSON_NAME]
if self.userdata_raw is not None:
ret.append(UD_NAME)
if self._check_os_version(GRIZZLY, version):
ret.append(PASS_NAME)
if self._check_os_version(HAVANA, version):
ret.append(VD_JSON_NAME)

return ret

return data[path]
def _user_data(self, version, path):
if self.userdata_raw is None:
raise KeyError(path)
return self.userdata_raw

def _password(self, version, path):
if self._check_os_version(GRIZZLY, version):
return password.handle_password
raise KeyError(path)

def _vendor_data(self, version, path):
if self._check_os_version(HAVANA, version):
return json.dumps(self.vddriver.get())
raise KeyError(path)

def _check_version(self, required, requested, versions=VERSIONS):
return versions.index(requested) >= versions.index(required)
Expand Down Expand Up @@ -445,6 +445,36 @@ def metadata_for_config_drive(self):
yield ('%s/%s/%s' % ("openstack", CONTENT_DIR, cid), content)


class RouteConfiguration(object):
"""Routes metadata paths to request handlers."""

def __init__(self, path_handler):
self.path_handlers = path_handler

def _version(self, version):
if version == "latest":
version = OPENSTACK_VERSIONS[-1]

if version not in OPENSTACK_VERSIONS:
raise InvalidMetadataVersion(version)

return version

def handle_path(self, path_tokens):
version = self._version(path_tokens[0])
if len(path_tokens) == 1:
path = VERSION
else:
path = '/'.join(path_tokens[1:])

path_handler = self.path_handlers[path]

if path_handler is None:
raise KeyError(path)

return path_handler(version, path)


class VendorDataDriver(object):
"""The base VendorData Drivers should inherit from."""

Expand Down
21 changes: 21 additions & 0 deletions nova/tests/test_metadata.py
Expand Up @@ -387,6 +387,27 @@ def test_version_content_listing(self):
listing = mdinst.lookup("/openstack/2012-08-10")
self.assertIn("meta_data.json", listing)

def test_returns_apis_supported_in_havana_version(self):
mdinst = fake_InstanceMetadata(self.stubs, self.instance)
havana_supported_apis = mdinst.lookup("/openstack/2013-10-17")

self.assertEqual([base.MD_JSON_NAME, base.UD_NAME, base.PASS_NAME,
base.VD_JSON_NAME], havana_supported_apis)

def test_returns_apis_supported_in_folsom_version(self):
mdinst = fake_InstanceMetadata(self.stubs, self.instance)
folsom_supported_apis = mdinst.lookup("/openstack/2012-08-10")

self.assertEqual([base.MD_JSON_NAME, base.UD_NAME],
folsom_supported_apis)

def test_returns_apis_supported_in_grizzly_version(self):
mdinst = fake_InstanceMetadata(self.stubs, self.instance)
grizzly_supported_apis = mdinst.lookup("/openstack/2013-04-04")

self.assertEqual([base.MD_JSON_NAME, base.UD_NAME, base.PASS_NAME],
grizzly_supported_apis)

def test_metadata_json(self):
inst = self.instance.obj_clone()
content = [
Expand Down

0 comments on commit cb31014

Please sign in to comment.