From 68bbddd8aea8f8b2d671e0d675524a1e568eb773 Mon Sep 17 00:00:00 2001 From: He Jie Xu Date: Fri, 5 May 2017 14:06:29 +0800 Subject: [PATCH] Totally freeze the extension_info API The extension will be removed from the Nova API totally. The extension_info API is just for backward compatibility. And there is no way to disable/enable the extension, also the discovery policy rules are removed, so it is time to just hard-code most of the logic at here. Partial-implement-blueprint api-no-more-extensions-pike Change-Id: I56d859beb675199b209587bfe0a23cd9b75233ad --- nova/api/openstack/compute/admin_actions.py | 21 - nova/api/openstack/compute/admin_password.py | 19 - nova/api/openstack/compute/config_drive.py | 18 - nova/api/openstack/compute/console_output.py | 18 - nova/api/openstack/compute/create_backup.py | 18 - nova/api/openstack/compute/deferred_delete.py | 18 - nova/api/openstack/compute/evacuate.py | 18 - .../compute/extended_availability_zone.py | 18 - .../compute/extended_server_attributes.py | 19 - nova/api/openstack/compute/extended_status.py | 19 - .../api/openstack/compute/extended_volumes.py | 21 +- nova/api/openstack/compute/extension_info.py | 1176 ++++++++++++----- .../compute/hide_server_addresses.py | 17 - nova/api/openstack/compute/lock_server.py | 18 - nova/api/openstack/compute/migrate_server.py | 17 - nova/api/openstack/compute/multinic.py | 21 - nova/api/openstack/compute/pause_server.py | 18 - nova/api/openstack/compute/rescue.py | 18 - nova/api/openstack/compute/scheduler_hints.py | 17 - nova/api/openstack/compute/server_usage.py | 19 - nova/api/openstack/compute/servers.py | 24 - nova/api/openstack/compute/shelve.py | 19 - nova/api/openstack/compute/suspend_server.py | 18 - .../openstack/compute/test_extension_info.py | 156 +-- 24 files changed, 841 insertions(+), 904 deletions(-) diff --git a/nova/api/openstack/compute/admin_actions.py b/nova/api/openstack/compute/admin_actions.py index de85642dba55..b258e868af95 100644 --- a/nova/api/openstack/compute/admin_actions.py +++ b/nova/api/openstack/compute/admin_actions.py @@ -24,8 +24,6 @@ from nova.compute import vm_states from nova import exception from nova.policies import admin_actions as aa_policies -ALIAS = "os-admin-actions" - # States usable in resetState action # NOTE: It is necessary to update the schema of nova/api/openstack/compute/ # schemas/reset_server_state.py, when updating this state_map. @@ -83,22 +81,3 @@ class AdminActionsController(wsgi.Controller): instance.vm_state = state instance.task_state = None instance.save(admin_state_reset=True) - - -class AdminActions(extensions.V21APIExtensionBase): - """Enable admin-only server actions - - Actions include: resetNetwork, injectNetworkInfo, os-resetState - """ - - name = "AdminActions" - alias = ALIAS - version = 1 - - def get_controller_extensions(self): - controller = AdminActionsController() - extension = extensions.ControllerExtension(self, 'servers', controller) - return [extension] - - def get_resources(self): - return [] diff --git a/nova/api/openstack/compute/admin_password.py b/nova/api/openstack/compute/admin_password.py index c4b6703451e0..09054e288b10 100644 --- a/nova/api/openstack/compute/admin_password.py +++ b/nova/api/openstack/compute/admin_password.py @@ -25,9 +25,6 @@ from nova.i18n import _ from nova.policies import admin_password as ap_policies -ALIAS = "os-admin-password" - - class AdminPasswordController(wsgi.Controller): def __init__(self, *args, **kwargs): @@ -63,19 +60,3 @@ class AdminPasswordController(wsgi.Controller): except NotImplementedError: msg = _("Unable to set password on instance") common.raise_feature_not_supported(msg=msg) - - -class AdminPassword(extensions.V21APIExtensionBase): - """Admin password management support.""" - - name = "AdminPassword" - alias = ALIAS - version = 1 - - def get_resources(self): - return [] - - def get_controller_extensions(self): - controller = AdminPasswordController() - extension = extensions.ControllerExtension(self, 'servers', controller) - return [extension] diff --git a/nova/api/openstack/compute/config_drive.py b/nova/api/openstack/compute/config_drive.py index d23942305fd3..af4f0593e2c1 100644 --- a/nova/api/openstack/compute/config_drive.py +++ b/nova/api/openstack/compute/config_drive.py @@ -17,11 +17,9 @@ from nova.api.openstack.compute.schemas import config_drive as \ schema_config_drive -from nova.api.openstack import extensions from nova.api.openstack import wsgi from nova.policies import config_drive as cd_policies -ALIAS = "os-config-drive" ATTRIBUTE_NAME = "config_drive" @@ -54,22 +52,6 @@ class ConfigDriveController(wsgi.Controller): self._add_config_drive(req, servers) -class ConfigDrive(extensions.V21APIExtensionBase): - """Config Drive Extension.""" - - name = "ConfigDrive" - alias = ALIAS - version = 1 - - def get_controller_extensions(self): - controller = ConfigDriveController() - extension = extensions.ControllerExtension(self, 'servers', controller) - return [extension] - - def get_resources(self): - return [] - - # NOTE(gmann): This function is not supposed to use 'body_deprecated_param' # parameter as this is placed to handle scheduler_hint extension for V2.1. def server_create(server_dict, create_kwargs, body_deprecated_param): diff --git a/nova/api/openstack/compute/console_output.py b/nova/api/openstack/compute/console_output.py index 76800a57eb6c..06129f935c2b 100644 --- a/nova/api/openstack/compute/console_output.py +++ b/nova/api/openstack/compute/console_output.py @@ -27,8 +27,6 @@ from nova import compute from nova import exception from nova.policies import console_output as co_policies -ALIAS = "os-console-output" - class ConsoleOutputController(wsgi.Controller): def __init__(self, *args, **kwargs): @@ -71,19 +69,3 @@ class ConsoleOutputController(wsgi.Controller): output = remove_re.sub('', output) return {'output': output} - - -class ConsoleOutput(extensions.V21APIExtensionBase): - """Console log output support, with tailing ability.""" - - name = "ConsoleOutput" - alias = ALIAS - version = 1 - - def get_controller_extensions(self): - controller = ConsoleOutputController() - extension = extensions.ControllerExtension(self, 'servers', controller) - return [extension] - - def get_resources(self): - return [] diff --git a/nova/api/openstack/compute/create_backup.py b/nova/api/openstack/compute/create_backup.py index 98f0d08f53c8..4f59dd3e9b31 100644 --- a/nova/api/openstack/compute/create_backup.py +++ b/nova/api/openstack/compute/create_backup.py @@ -25,8 +25,6 @@ from nova import compute from nova import exception from nova.policies import create_backup as cb_policies -ALIAS = "os-create-backup" - class CreateBackupController(wsgi.Controller): def __init__(self, *args, **kwargs): @@ -94,19 +92,3 @@ class CreateBackupController(wsgi.Controller): resp.headers['Location'] = image_ref return resp - - -class CreateBackup(extensions.V21APIExtensionBase): - """Create a backup of a server.""" - - name = "CreateBackup" - alias = ALIAS - version = 1 - - def get_controller_extensions(self): - controller = CreateBackupController() - extension = extensions.ControllerExtension(self, 'servers', controller) - return [extension] - - def get_resources(self): - return [] diff --git a/nova/api/openstack/compute/deferred_delete.py b/nova/api/openstack/compute/deferred_delete.py index c47838b03034..cf14e9b02ac1 100644 --- a/nova/api/openstack/compute/deferred_delete.py +++ b/nova/api/openstack/compute/deferred_delete.py @@ -24,8 +24,6 @@ from nova import compute from nova import exception from nova.policies import deferred_delete as dd_policies -ALIAS = 'os-deferred-delete' - class DeferredDeleteController(wsgi.Controller): def __init__(self, *args, **kwargs): @@ -67,19 +65,3 @@ class DeferredDeleteController(wsgi.Controller): raise webob.exc.HTTPNotFound(explanation=e.format_message()) except exception.InstanceIsLocked as e: raise webob.exc.HTTPConflict(explanation=e.format_message()) - - -class DeferredDelete(extensions.V21APIExtensionBase): - """Instance deferred delete.""" - - name = "DeferredDelete" - alias = "os-deferred-delete" - version = 1 - - def get_controller_extensions(self): - controller = DeferredDeleteController() - extension = extensions.ControllerExtension(self, 'servers', controller) - return [extension] - - def get_resources(self): - return [] diff --git a/nova/api/openstack/compute/evacuate.py b/nova/api/openstack/compute/evacuate.py index 79b2cd68f315..be614379d9d2 100644 --- a/nova/api/openstack/compute/evacuate.py +++ b/nova/api/openstack/compute/evacuate.py @@ -31,8 +31,6 @@ from nova import utils CONF = nova.conf.CONF -ALIAS = "os-evacuate" - class EvacuateController(wsgi.Controller): def __init__(self, *args, **kwargs): @@ -133,19 +131,3 @@ class EvacuateController(wsgi.Controller): return {'adminPass': password} else: return None - - -class Evacuate(extensions.V21APIExtensionBase): - """Enables server evacuation.""" - - name = "Evacuate" - alias = ALIAS - version = 1 - - def get_resources(self): - return [] - - def get_controller_extensions(self): - controller = EvacuateController() - extension = extensions.ControllerExtension(self, 'servers', controller) - return [extension] diff --git a/nova/api/openstack/compute/extended_availability_zone.py b/nova/api/openstack/compute/extended_availability_zone.py index 219bbdab43d6..ac562c588a01 100644 --- a/nova/api/openstack/compute/extended_availability_zone.py +++ b/nova/api/openstack/compute/extended_availability_zone.py @@ -15,12 +15,10 @@ """The Extended Availability Zone Status API extension.""" -from nova.api.openstack import extensions from nova.api.openstack import wsgi from nova import availability_zones as avail_zone from nova.policies import extended_availability_zone as eaz_policies -ALIAS = "os-extended-availability-zone" PREFIX = "OS-EXT-AZ" @@ -49,19 +47,3 @@ class ExtendedAZController(wsgi.Controller): for server in servers: db_instance = req.get_db_instance(server['id']) self._extend_server(context, server, db_instance) - - -class ExtendedAvailabilityZone(extensions.V21APIExtensionBase): - """Extended Availability Zone support.""" - - name = "ExtendedAvailabilityZone" - alias = ALIAS - version = 1 - - def get_controller_extensions(self): - controller = ExtendedAZController() - extension = extensions.ControllerExtension(self, 'servers', controller) - return [extension] - - def get_resources(self): - return [] diff --git a/nova/api/openstack/compute/extended_server_attributes.py b/nova/api/openstack/compute/extended_server_attributes.py index b86f91d05b3a..6f2c7f92d7c5 100644 --- a/nova/api/openstack/compute/extended_server_attributes.py +++ b/nova/api/openstack/compute/extended_server_attributes.py @@ -15,14 +15,11 @@ """The Extended Server Attributes API extension.""" from nova.api.openstack import api_version_request -from nova.api.openstack import extensions from nova.api.openstack import wsgi from nova import compute from nova.policies import extended_server_attributes as esa_policies from nova.policies import servers as servers_policies -ALIAS = "os-extended-server-attributes" - class ExtendedServerAttributesController(wsgi.Controller): def __init__(self, *args, **kwargs): @@ -106,19 +103,3 @@ class ExtendedServerAttributesController(wsgi.Controller): self._extend_server(context, server, instance, req) if authorize_host_status: server['host_status'] = host_statuses[server['id']] - - -class ExtendedServerAttributes(extensions.V21APIExtensionBase): - """Extended Server Attributes support.""" - - name = "ExtendedServerAttributes" - alias = ALIAS - version = 1 - - def get_controller_extensions(self): - controller = ExtendedServerAttributesController() - extension = extensions.ControllerExtension(self, 'servers', controller) - return [extension] - - def get_resources(self): - return [] diff --git a/nova/api/openstack/compute/extended_status.py b/nova/api/openstack/compute/extended_status.py index 7a07237ebd3b..e1bb52b2890f 100644 --- a/nova/api/openstack/compute/extended_status.py +++ b/nova/api/openstack/compute/extended_status.py @@ -14,12 +14,9 @@ """The Extended Status Admin API extension.""" -from nova.api.openstack import extensions from nova.api.openstack import wsgi from nova.policies import extended_status as es_policies -ALIAS = "os-extended-status" - class ExtendedStatusController(wsgi.Controller): def _extend_server(self, server, instance): @@ -53,19 +50,3 @@ class ExtendedStatusController(wsgi.Controller): # server['id'] is guaranteed to be in the cache due to # the core API adding it in its 'detail' method. self._extend_server(server, db_instance) - - -class ExtendedStatus(extensions.V21APIExtensionBase): - """Extended Status support.""" - - name = "ExtendedStatus" - alias = ALIAS - version = 1 - - def get_controller_extensions(self): - controller = ExtendedStatusController() - extension = extensions.ControllerExtension(self, 'servers', controller) - return [extension] - - def get_resources(self): - return [] diff --git a/nova/api/openstack/compute/extended_volumes.py b/nova/api/openstack/compute/extended_volumes.py index 28985c27b19d..fbe03fc4f105 100644 --- a/nova/api/openstack/compute/extended_volumes.py +++ b/nova/api/openstack/compute/extended_volumes.py @@ -14,13 +14,10 @@ """The Extended Volumes API extension.""" from nova.api.openstack import api_version_request -from nova.api.openstack import extensions from nova.api.openstack import wsgi from nova import objects from nova.policies import extended_volumes as ev_policies -ALIAS = "os-extended-volumes" - class ExtendedVolumesController(wsgi.Controller): def _extend_server(self, context, server, req, bdms): @@ -35,7 +32,7 @@ class ExtendedVolumesController(wsgi.Controller): # NOTE(mriedem): The os-extended-volumes prefix should not be used for # new attributes after v2.1. They are only in v2.1 for backward compat # with v2.0. - key = "%s:volumes_attached" % ExtendedVolumes.alias + key = "os-extended-volumes:volumes_attached" server[key] = volumes_attached @wsgi.extends @@ -66,19 +63,3 @@ class ExtendedVolumesController(wsgi.Controller): # If that instance has since been deleted, it won't be in the # 'bdms' dictionary though, so use 'get' to avoid KeyErrors. return bdms.get(server['id'], []) - - -class ExtendedVolumes(extensions.V21APIExtensionBase): - """Extended Volumes support.""" - - name = "ExtendedVolumes" - alias = ALIAS - version = 1 - - def get_controller_extensions(self): - controller = ExtendedVolumesController() - extension = extensions.ControllerExtension(self, 'servers', controller) - return [extension] - - def get_resources(self): - return [] diff --git a/nova/api/openstack/compute/extension_info.py b/nova/api/openstack/compute/extension_info.py index 619533b6f39f..60722adfc3a6 100644 --- a/nova/api/openstack/compute/extension_info.py +++ b/nova/api/openstack/compute/extension_info.py @@ -12,34 +12,10 @@ # License for the specific language governing permissions and limitations # under the License. -import copy - from oslo_log import log as logging import webob.exc -from nova.api.openstack.compute import admin_actions -from nova.api.openstack.compute import admin_password -from nova.api.openstack.compute import config_drive -from nova.api.openstack.compute import console_output -from nova.api.openstack.compute import create_backup -from nova.api.openstack.compute import deferred_delete -from nova.api.openstack.compute import evacuate -from nova.api.openstack.compute import extended_availability_zone -from nova.api.openstack.compute import extended_server_attributes -from nova.api.openstack.compute import extended_status -from nova.api.openstack.compute import extended_volumes -from nova.api.openstack.compute import hide_server_addresses -from nova.api.openstack.compute import lock_server -from nova.api.openstack.compute import migrate_server -from nova.api.openstack.compute import multinic -from nova.api.openstack.compute import pause_server -from nova.api.openstack.compute import rescue -from nova.api.openstack.compute import scheduler_hints -from nova.api.openstack.compute import server_usage -from nova.api.openstack.compute import servers -from nova.api.openstack.compute import shelve -from nova.api.openstack.compute import suspend_server from nova.api.openstack import extensions from nova.api.openstack import wsgi from nova import exception @@ -48,352 +24,876 @@ from nova.policies import extensions as ext_policies ALIAS = 'extensions' LOG = logging.getLogger(__name__) -# NOTE(cyeoh): The following mappings are currently incomplete -# Having a v2.1 extension loaded can imply that several v2 extensions -# should also appear to be loaded (although they no longer do in v2.1) -v21_to_v2_extension_list_mapping = { - 'os-quota-sets': [{'name': 'UserQuotas', 'alias': 'os-user-quotas', - 'description': 'Project user quota support.'}, - {'name': 'ExtendedQuotas', - 'alias': 'os-extended-quotas', - 'description': ('Adds ability for admins to delete' - ' quota and optionally force the update Quota' - ' command.')}], - 'os-cells': [{'name': 'CellCapacities', 'alias': 'os-cell-capacities', - 'description': ('Adding functionality to get cell' - ' capacities.')}], - 'os-baremetal-nodes': [{'name': 'BareMetalExtStatus', - 'alias': 'os-baremetal-ext-status', - 'description': ('Add extended status in' - ' Baremetal Nodes v2 API.')}], - 'os-block-device-mapping': [{'name': 'BlockDeviceMappingV2Boot', - 'alias': 'os-block-device-mapping-v2-boot', - 'description': ('Allow boot with the new BDM' - ' data format.')}], - 'os-cloudpipe': [{'name': 'CloudpipeUpdate', - 'alias': 'os-cloudpipe-update', - 'description': ('Adds the ability to set the vpn' - ' ip/port for cloudpipe instances.')}], - 'servers': [{'name': 'Createserverext', 'alias': 'os-create-server-ext', - 'description': ('Extended support to the Create Server' - ' v1.1 API.')}, - {'name': 'ExtendedIpsMac', 'alias': 'OS-EXT-IPS-MAC', - 'description': 'Adds mac address parameter to the ip list.'}, - {'name': 'ExtendedIps', 'alias': 'OS-EXT-IPS', - 'description': 'Adds type parameter to the ip list.'}, - {'name': 'ServerListMultiStatus', - 'alias': 'os-server-list-multi-status', - 'description': ('Allow to filter the servers by a set of' - ' status values.')}, - {'name': 'ServerSortKeys', 'alias': 'os-server-sort-keys', - 'description': 'Add sorting support in get Server v2 API.'}, - {'name': 'ServerStartStop', 'alias': 'os-server-start-stop', - 'description': 'Start/Stop instance compute API support.'}], - 'flavors': [{'name': 'FlavorDisabled', 'alias': 'OS-FLV-DISABLED', - 'description': ('Support to show the disabled status' - ' of a flavor.')}, - {'name': 'FlavorExtraData', 'alias': 'OS-FLV-EXT-DATA', - 'description': 'Provide additional data for flavors.'}, - {'name': 'FlavorSwap', 'alias': 'os-flavor-swap', - 'description': ('Support to show the swap status of a' - ' flavor.')}], - 'os-services': [{'name': 'ExtendedServicesDelete', - 'alias': 'os-extended-services-delete', - 'description': 'Extended services deletion support.'}, - {'name': 'ExtendedServices', 'alias': - 'os-extended-services', - 'description': 'Extended services support.'}], - 'os-evacuate': [{'name': 'ExtendedEvacuateFindHost', - 'alias': 'os-extended-evacuate-find-host', - 'description': ('Enables server evacuation without' - ' target host. Scheduler will select one to target.')}], - 'os-floating-ips': [{'name': 'ExtendedFloatingIps', - 'alias': 'os-extended-floating-ips', - 'description': ('Adds optional fixed_address to the add' - ' floating IP command.')}], - 'os-hypervisors': [{'name': 'ExtendedHypervisors', - 'alias': 'os-extended-hypervisors', - 'description': 'Extended hypervisors support.'}, - {'name': 'HypervisorStatus', - 'alias': 'os-hypervisor-status', - 'description': 'Show hypervisor status.'}], - 'os-networks': [{'name': 'ExtendedNetworks', - 'alias': 'os-extended-networks', - 'description': 'Adds additional fields to networks.'}], - 'os-rescue': [{'name': 'ExtendedRescueWithImage', - 'alias': 'os-extended-rescue-with-image', - 'description': ('Allow the user to specify the image to' - ' use for rescue.')}], - 'os-extended-status': [{'name': 'ExtendedStatus', - 'alias': 'OS-EXT-STS', - 'description': 'Extended Status support.'}], - 'os-used-limits': [{'name': 'UsedLimitsForAdmin', - 'alias': 'os-used-limits-for-admin', - 'description': ('Provide data to admin on limited' - ' resources used by other tenants.')}], - 'os-volumes': [{'name': 'VolumeAttachmentUpdate', - 'alias': 'os-volume-attachment-update', - 'description': ('Support for updating a volume' - ' attachment.')}], - 'os-server-groups': [{'name': 'ServerGroupQuotas', - 'alias': 'os-server-group-quotas', - 'description': 'Adds quota support to server groups.'}], -} -# v2.1 plugins which should never appear in the v2 extension list -# This should be the v2.1 alias, not the V2.0 alias -v2_extension_suppress_list = ['servers', 'images', 'versions', 'flavors', - 'os-block-device-mapping-v1', 'os-consoles', - 'extensions', 'image-metadata', 'ips', 'limits', - 'server-metadata', 'server-migrations', - 'os-server-tags' - ] - -# v2.1 plugins which should appear under a different name in v2 -v21_to_v2_alias_mapping = { - 'image-size': 'OS-EXT-IMG-SIZE', - 'os-remote-consoles': 'os-consoles', - 'os-disk-config': 'OS-DCF', - 'os-extended-availability-zone': 'OS-EXT-AZ', - 'os-extended-server-attributes': 'OS-EXT-SRV-ATTR', - 'os-multinic': 'NMN', - 'os-scheduler-hints': 'OS-SCH-HNT', - 'os-server-usage': 'OS-SRV-USG', - 'os-instance-usage-audit-log': 'os-instance_usage_audit_log', -} - -# NOTE(sdague): this is the list of extension metadata that we display -# to the user for features that we provide. This exists for legacy -# purposes because applications were once asked to look for these -# things to decide if a feature is enabled. As we remove extensions -# completely from the code we're going to have a static list here to -# keep the surface metadata the same. -hardcoded_extensions = [ - {'name': 'Agents', - 'alias': 'os-agents', - 'description': 'Agents support.' +EXTENSION_LIST = [ + { + "alias": "NMN", + "description": "Multiple network support.", + "links": [], + "name": "Multinic", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" }, - {'name': 'Aggregates', - 'alias': 'os-aggregates', - 'description': 'Admin-only aggregate administration.' + { + "alias": "OS-DCF", + "description": "Disk Management Extension.", + "links": [], + "name": "DiskConfig", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" }, - {'name': 'AssistedVolumeSnapshots', - 'alias': 'os-assisted-volume-snapshots', - 'description': 'Assisted volume snapshots.' + { + "alias": "OS-EXT-AZ", + "description": "Extended Availability Zone support.", + "links": [], + "name": "ExtendedAvailabilityZone", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" }, - {'name': 'AvailabilityZone', - 'alias': 'os-availability-zone', - 'description': '1. Add availability_zone to the Create Server API.\n' - ' 2. Add availability zones describing.\n ', + { + "alias": "OS-EXT-IMG-SIZE", + "description": "Adds image size to image listings.", + "links": [], + "name": "ImageSize", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" }, - {'name': 'DiskConfig', - 'alias': 'os-disk-config', - 'description': 'Disk Management Extension.'}, - {'name': 'AccessIPs', - 'description': 'Access IPs support.', - 'alias': 'os-access-ips'}, - {'name': 'PreserveEphemeralOnRebuild', - 'description': ('Allow preservation of the ' - 'ephemeral partition on rebuild.'), - 'alias': 'os-preserve-ephemeral-rebuild'}, - {'name': 'Personality', - 'description': 'Personality support.', - 'alias': 'os-personality'}, - {'name': 'FixedIPs', - 'description': 'Fixed IPs support.', - 'alias': 'os-fixed-ips'}, - {'name': 'Flavors', - 'description': 'Flavors Extension.', - 'alias': 'flavors'}, - {'name': 'FlavorManage', - 'description': 'Flavor create/delete API support.', - 'alias': 'os-flavor-manage'}, - {'name': 'FlavorRxtx', - 'description': 'Support to show the rxtx status of a flavor.', - 'alias': 'os-flavor-rxtx'}, - {'name': 'FlavorExtraSpecs', - 'description': 'Flavors extra specs support.', - 'alias': 'os-flavor-extra-specs'}, - {'name': 'FlavorAccess', - 'description': 'Flavor access support.', - 'alias': 'os-flavor-access'}, - {'name': 'FloatingIpDns', - 'description': 'Floating IP DNS support.', - 'alias': 'os-floating-ip-dns'}, - {'name': 'FloatingIpPools', - 'description': 'Floating IPs support.', - 'alias': 'os-floating-ip-pools'}, - {'name': 'FloatingIps', - 'description': 'Floating IPs support.', - 'alias': 'os-floating-ips'}, - {'name': 'FloatingIpsBulk', - 'description': 'Bulk handling of Floating IPs.', - 'alias': 'os-floating-ips-bulk'}, - {'name': 'OSInstanceUsageAuditLog', - 'description': 'Admin-only Task Log Monitoring.', - 'alias': 'os-instance-usage-audit-log'}, - {'name': 'Keypairs', - 'description': 'Keypair Support.', - 'alias': 'os-keypairs'}, - {'name': 'ServerMetadata', - 'description': 'Server metadata Support.', - 'alias': 'server-metadata'}, - {'name': 'SimpleTenantUsage', - 'description': 'Simple tenant usage extension.', - 'alias': 'os-simple-tenant-usage'} + { + "alias": "OS-EXT-IPS", + "description": "Adds type parameter to the ip list.", + "links": [], + "name": "ExtendedIps", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "OS-EXT-IPS-MAC", + "description": "Adds mac address parameter to the ip list.", + "links": [], + "name": "ExtendedIpsMac", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "OS-EXT-SRV-ATTR", + "description": "Extended Server Attributes support.", + "links": [], + "name": "ExtendedServerAttributes", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "OS-EXT-STS", + "description": "Extended Status support.", + "links": [], + "name": "ExtendedStatus", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "OS-FLV-DISABLED", + "description": "Support to show the disabled status of a flavor.", + "links": [], + "name": "FlavorDisabled", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "OS-FLV-EXT-DATA", + "description": "Provide additional data for flavors.", + "links": [], + "name": "FlavorExtraData", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "OS-SCH-HNT", + "description": "Pass arbitrary key/value pairs to the scheduler.", + "links": [], + "name": "SchedulerHints", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "OS-SRV-USG", + "description": "Adds launched_at and terminated_at on Servers.", + "links": [], + "name": "ServerUsage", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-access-ips", + "description": "Access IPs support.", + "links": [], + "name": "AccessIPs", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-admin-actions", + "description": "Enable admin-only server actions\n\n " + "Actions include: resetNetwork, injectNetworkInfo, " + "os-resetState\n ", + "links": [], + "name": "AdminActions", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-admin-password", + "description": "Admin password management support.", + "links": [], + "name": "AdminPassword", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-agents", + "description": "Agents support.", + "links": [], + "name": "Agents", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-aggregates", + "description": "Admin-only aggregate administration.", + "links": [], + "name": "Aggregates", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-assisted-volume-snapshots", + "description": "Assisted volume snapshots.", + "links": [], + "name": "AssistedVolumeSnapshots", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-attach-interfaces", + "description": "Attach interface support.", + "links": [], + "name": "AttachInterfaces", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-availability-zone", + "description": "1. Add availability_zone to the Create Server " + "API.\n 2. Add availability zones " + "describing.\n ", + "links": [], + "name": "AvailabilityZone", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-baremetal-ext-status", + "description": "Add extended status in Baremetal Nodes v2 API.", + "links": [], + "name": "BareMetalExtStatus", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-baremetal-nodes", + "description": "Admin-only bare-metal node administration.", + "links": [], + "name": "BareMetalNodes", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-block-device-mapping", + "description": "Block device mapping boot support.", + "links": [], + "name": "BlockDeviceMapping", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-block-device-mapping-v2-boot", + "description": "Allow boot with the new BDM data format.", + "links": [], + "name": "BlockDeviceMappingV2Boot", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-cell-capacities", + "description": "Adding functionality to get cell capacities.", + "links": [], + "name": "CellCapacities", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-cells", + "description": "Enables cells-related functionality such as adding " + "neighbor cells,\n listing neighbor cells, " + "and getting the capabilities of the local cell.\n ", + "links": [], + "name": "Cells", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-certificates", + "description": "Certificates support.", + "links": [], + "name": "Certificates", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-cloudpipe", + "description": "Adds actions to create cloudpipe instances.\n\n " + "When running with the Vlan network mode, you need a " + "mechanism to route\n from the public Internet to " + "your vlans. This mechanism is known as a\n " + "cloudpipe.\n\n At the time of creating this class, " + "only OpenVPN is supported. Support for\n a SSH " + "Bastion host is forthcoming.\n ", + "links": [], + "name": "Cloudpipe", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-cloudpipe-update", + "description": "Adds the ability to set the vpn ip/port for cloudpipe " + "instances.", + "links": [], + "name": "CloudpipeUpdate", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-config-drive", + "description": "Config Drive Extension.", + "links": [], + "name": "ConfigDrive", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-console-auth-tokens", + "description": "Console token authentication support.", + "links": [], + "name": "ConsoleAuthTokens", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-console-output", + "description": "Console log output support, with tailing ability.", + "links": [], + "name": "ConsoleOutput", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-consoles", + "description": "Interactive Console support.", + "links": [], + "name": "Consoles", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-create-backup", + "description": "Create a backup of a server.", + "links": [], + "name": "CreateBackup", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-create-server-ext", + "description": "Extended support to the Create Server v1.1 API.", + "links": [], + "name": "Createserverext", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-deferred-delete", + "description": "Instance deferred delete.", + "links": [], + "name": "DeferredDelete", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-evacuate", + "description": "Enables server evacuation.", + "links": [], + "name": "Evacuate", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-extended-evacuate-find-host", + "description": "Enables server evacuation without target host. " + "Scheduler will select one to target.", + "links": [], + "name": "ExtendedEvacuateFindHost", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-extended-floating-ips", + "description": "Adds optional fixed_address to the add floating IP " + "command.", + "links": [], + "name": "ExtendedFloatingIps", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-extended-hypervisors", + "description": "Extended hypervisors support.", + "links": [], + "name": "ExtendedHypervisors", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-extended-networks", + "description": "Adds additional fields to networks.", + "links": [], + "name": "ExtendedNetworks", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-extended-quotas", + "description": "Adds ability for admins to delete quota and " + "optionally force the update Quota command.", + "links": [], + "name": "ExtendedQuotas", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-extended-rescue-with-image", + "description": "Allow the user to specify the image to use for " + "rescue.", + "links": [], + "name": "ExtendedRescueWithImage", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-extended-services", + "description": "Extended services support.", + "links": [], + "name": "ExtendedServices", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-extended-services-delete", + "description": "Extended services deletion support.", + "links": [], + "name": "ExtendedServicesDelete", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-extended-status", + "description": "Extended Status support.", + "links": [], + "name": "ExtendedStatus", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-extended-volumes", + "description": "Extended Volumes support.", + "links": [], + "name": "ExtendedVolumes", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-fixed-ips", + "description": "Fixed IPs support.", + "links": [], + "name": "FixedIPs", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-flavor-access", + "description": "Flavor access support.", + "links": [], + "name": "FlavorAccess", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-flavor-extra-specs", + "description": "Flavors extra specs support.", + "links": [], + "name": "FlavorExtraSpecs", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-flavor-manage", + "description": "Flavor create/delete API support.", + "links": [], + "name": "FlavorManage", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-flavor-rxtx", + "description": "Support to show the rxtx status of a flavor.", + "links": [], + "name": "FlavorRxtx", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-flavor-swap", + "description": "Support to show the swap status of a flavor.", + "links": [], + "name": "FlavorSwap", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-floating-ip-dns", + "description": "Floating IP DNS support.", + "links": [], + "name": "FloatingIpDns", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-floating-ip-pools", + "description": "Floating IPs support.", + "links": [], + "name": "FloatingIpPools", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-floating-ips", + "description": "Floating IPs support.", + "links": [], + "name": "FloatingIps", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-floating-ips-bulk", + "description": "Bulk handling of Floating IPs.", + "links": [], + "name": "FloatingIpsBulk", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-fping", + "description": "Fping Management Extension.", + "links": [], + "name": "Fping", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-hide-server-addresses", + "description": "Support hiding server addresses in certain states.", + "links": [], + "name": "HideServerAddresses", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-hosts", + "description": "Admin-only host administration.", + "links": [], + "name": "Hosts", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-hypervisor-status", + "description": "Show hypervisor status.", + "links": [], + "name": "HypervisorStatus", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-hypervisors", + "description": "Admin-only hypervisor administration.", + "links": [], + "name": "Hypervisors", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-instance-actions", + "description": "View a log of actions and events taken on an " + "instance.", + "links": [], + "name": "InstanceActions", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-instance_usage_audit_log", + "description": "Admin-only Task Log Monitoring.", + "links": [], + "name": "OSInstanceUsageAuditLog", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-keypairs", + "description": "Keypair Support.", + "links": [], + "name": "Keypairs", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-lock-server", + "description": "Enable lock/unlock server actions.", + "links": [], + "name": "LockServer", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-migrate-server", + "description": "Enable migrate and live-migrate server actions.", + "links": [], + "name": "MigrateServer", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-migrations", + "description": "Provide data on migrations.", + "links": [], + "name": "Migrations", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-multiple-create", + "description": "Allow multiple create in the Create Server v2.1 API.", + "links": [], + "name": "MultipleCreate", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-networks", + "description": "Admin-only Network Management Extension.", + "links": [], + "name": "Networks", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-networks-associate", + "description": "Network association support.", + "links": [], + "name": "NetworkAssociationSupport", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-pause-server", + "description": "Enable pause/unpause server actions.", + "links": [], + "name": "PauseServer", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-personality", + "description": "Personality support.", + "links": [], + "name": "Personality", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-preserve-ephemeral-rebuild", + "description": "Allow preservation of the ephemeral partition on " + "rebuild.", + "links": [], + "name": "PreserveEphemeralOnRebuild", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-quota-class-sets", + "description": "Quota classes management support.", + "links": [], + "name": "QuotaClasses", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-quota-sets", + "description": "Quotas management support.", + "links": [], + "name": "Quotas", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-rescue", + "description": "Instance rescue mode.", + "links": [], + "name": "Rescue", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-security-group-default-rules", + "description": "Default rules for security group support.", + "links": [], + "name": "SecurityGroupDefaultRules", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-security-groups", + "description": "Security group support.", + "links": [], + "name": "SecurityGroups", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-server-diagnostics", + "description": "Allow Admins to view server diagnostics through " + "server action.", + "links": [], + "name": "ServerDiagnostics", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-server-external-events", + "description": "Server External Event Triggers.", + "links": [], + "name": "ServerExternalEvents", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-server-group-quotas", + "description": "Adds quota support to server groups.", + "links": [], + "name": "ServerGroupQuotas", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-server-groups", + "description": "Server group support.", + "links": [], + "name": "ServerGroups", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-server-list-multi-status", + "description": "Allow to filter the servers by a set of status " + "values.", + "links": [], + "name": "ServerListMultiStatus", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-server-password", + "description": "Server password support.", + "links": [], + "name": "ServerPassword", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-server-sort-keys", + "description": "Add sorting support in get Server v2 API.", + "links": [], + "name": "ServerSortKeys", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-server-start-stop", + "description": "Start/Stop instance compute API support.", + "links": [], + "name": "ServerStartStop", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-services", + "description": "Services support.", + "links": [], + "name": "Services", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-shelve", + "description": "Instance shelve mode.", + "links": [], + "name": "Shelve", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-simple-tenant-usage", + "description": "Simple tenant usage extension.", + "links": [], + "name": "SimpleTenantUsage", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-suspend-server", + "description": "Enable suspend/resume server actions.", + "links": [], + "name": "SuspendServer", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-tenant-networks", + "description": "Tenant-based Network Management Extension.", + "links": [], + "name": "OSTenantNetworks", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-used-limits", + "description": "Provide data on limited resources that are being " + "used.", + "links": [], + "name": "UsedLimits", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-used-limits-for-admin", + "description": "Provide data to admin on limited resources used by " + "other tenants.", + "links": [], + "name": "UsedLimitsForAdmin", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-user-data", + "description": "Add user_data to the Create Server API.", + "links": [], + "name": "UserData", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-user-quotas", + "description": "Project user quota support.", + "links": [], + "name": "UserQuotas", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-virtual-interfaces", + "description": "Virtual interface support.", + "links": [], + "name": "VirtualInterfaces", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-volume-attachment-update", + "description": "Support for updating a volume attachment.", + "links": [], + "name": "VolumeAttachmentUpdate", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + }, + { + "alias": "os-volumes", + "description": "Volumes support.", + "links": [], + "name": "Volumes", + "namespace": "http://docs.openstack.org/compute/ext/fake_xml", + "updated": "2014-12-03T00:00:00Z" + } ] -# TODO(alex_xu): This is a list of unused extension objs. Add those -# extension objs here for building a compatible extension API. Finally, -# we should remove those extension objs, and add corresponding entries -# in the 'hardcoded_extensions'. -unused_extension_objs = [ - admin_actions.AdminActions, - admin_password.AdminPassword, - config_drive.ConfigDrive, - console_output.ConsoleOutput, - create_backup.CreateBackup, - deferred_delete.DeferredDelete, - evacuate.Evacuate, - extended_availability_zone.ExtendedAvailabilityZone, - extended_server_attributes.ExtendedServerAttributes, - extended_status.ExtendedStatus, - extended_volumes.ExtendedVolumes, - hide_server_addresses.HideServerAddresses, - lock_server.LockServer, - migrate_server.MigrateServer, - multinic.Multinic, - pause_server.PauseServer, - rescue.Rescue, - scheduler_hints.SchedulerHints, - server_usage.ServerUsage, - servers.Servers, - shelve.Shelve, - suspend_server.SuspendServer -] - -# V2.1 does not support XML but we need to keep an entry in the -# /extensions information returned to the user for backwards -# compatibility -FAKE_XML_URL = "http://docs.openstack.org/compute/ext/fake_xml" -FAKE_UPDATED_DATE = "2014-12-03T00:00:00Z" - - -class FakeExtension(object): - def __init__(self, name, alias, description=""): - self.name = name - self.alias = alias - self.__doc__ = description - self.version = -1 +EXTENSION_LIST_LEGACY_V2_COMPATIBLE = EXTENSION_LIST[:] +EXTENSION_LIST_LEGACY_V2_COMPATIBLE.append({ + 'alias': 'OS-EXT-VIF-NET', + 'description': 'Adds network id parameter to the virtual interface list.', + 'links': [], + 'name': 'ExtendedVIFNet', + 'namespace': 'http://docs.openstack.org/compute/ext/fake_xml', + "updated": "2014-12-03T00:00:00Z" +}) +EXTENSION_LIST_LEGACY_V2_COMPATIBLE = sorted( + EXTENSION_LIST_LEGACY_V2_COMPATIBLE, key=lambda x: x['alias']) class ExtensionInfoController(wsgi.Controller): - def __init__(self, extension_info): - self.extension_info = extension_info - - def _translate(self, ext): - ext_data = {} - ext_data["name"] = ext.name - ext_data["alias"] = ext.alias - ext_data["description"] = ext.__doc__ - ext_data["namespace"] = FAKE_XML_URL - ext_data["updated"] = FAKE_UPDATED_DATE - ext_data["links"] = [] - return ext_data - - def _create_fake_ext(self, name, alias, description=""): - return FakeExtension(name, alias, description) - def _add_vif_extension(self, all_extensions): - vif_extension = {} vif_extension_info = {'name': 'ExtendedVIFNet', 'alias': 'OS-EXT-VIF-NET', 'description': 'Adds network id parameter' ' to the virtual interface list.'} - vif_extension[vif_extension_info["alias"]] = self._create_fake_ext( - vif_extension_info["name"], vif_extension_info["alias"], - vif_extension_info["description"]) - all_extensions.update(vif_extension) - - def _get_extensions(self, context): - """Filter extensions list based on policy.""" - - all_extensions = dict() - - for item in hardcoded_extensions: - all_extensions[item['alias']] = self._create_fake_ext( - item['name'], - item['alias'], - item['description'] - ) - - for ext_cls in unused_extension_objs: - ext = ext_cls(None) - all_extensions[ext.alias] = ext - - for alias, ext in self.extension_info.get_extensions().items(): - all_extensions[alias] = ext - - # Add fake v2 extensions to list - extra_exts = {} - for alias in all_extensions: - if alias in v21_to_v2_extension_list_mapping: - for extra_ext in v21_to_v2_extension_list_mapping[alias]: - extra_exts[extra_ext["alias"]] = self._create_fake_ext( - extra_ext["name"], extra_ext["alias"], - extra_ext["description"]) - all_extensions.update(extra_exts) - - # Suppress extensions which we don't want to see in v2 - for suppress_ext in v2_extension_suppress_list: - try: - del all_extensions[suppress_ext] - except KeyError: - pass - - # v2.1 to v2 extension name mapping - for rename_ext in v21_to_v2_alias_mapping: - if rename_ext in all_extensions: - new_name = v21_to_v2_alias_mapping[rename_ext] - mod_ext = copy.deepcopy( - all_extensions.pop(rename_ext)) - mod_ext.alias = new_name - all_extensions[new_name] = mod_ext - - return all_extensions + all_extensions.append(vif_extension_info) @extensions.expected_errors(()) def index(self, req): context = req.environ['nova.context'] context.can(ext_policies.BASE_POLICY_NAME) - all_extensions = self._get_extensions(context) + # NOTE(gmann): This is for v2.1 compatible mode where # extension list should show all extensions as shown by v2. - # Here we add VIF extension which has been removed from v2.1 list. if req.is_legacy_v2(): - self._add_vif_extension(all_extensions) - sorted_ext_list = sorted( - all_extensions.items()) + return dict(extensions=EXTENSION_LIST_LEGACY_V2_COMPATIBLE) - extensions = [] - for _alias, ext in sorted_ext_list: - extensions.append(self._translate(ext)) - - return dict(extensions=extensions) + return dict(extensions=EXTENSION_LIST) @extensions.expected_errors(404) def show(self, req, id): context = req.environ['nova.context'] context.can(ext_policies.BASE_POLICY_NAME) - try: - # NOTE(dprince): the extensions alias is used as the 'id' for show - ext = self._get_extensions(context)[id] - except KeyError: - raise webob.exc.HTTPNotFound() + all_exts = EXTENSION_LIST + # NOTE(gmann): This is for v2.1 compatible mode where + # extension list should show all extensions as shown by v2. + if req.is_legacy_v2(): + all_exts = EXTENSION_LIST_LEGACY_V2_COMPATIBLE - return dict(extension=self._translate(ext)) + # NOTE(dprince): the extensions alias is used as the 'id' for show + for ext in all_exts: + if ext['alias'] == id: + return dict(extension=ext) + + raise webob.exc.HTTPNotFound() class ExtensionInfo(extensions.V21APIExtensionBase): diff --git a/nova/api/openstack/compute/hide_server_addresses.py b/nova/api/openstack/compute/hide_server_addresses.py index 5630e70bb0bf..df787799a486 100644 --- a/nova/api/openstack/compute/hide_server_addresses.py +++ b/nova/api/openstack/compute/hide_server_addresses.py @@ -15,7 +15,6 @@ """Extension for hiding server addresses in certain states.""" -from nova.api.openstack import extensions from nova.api.openstack import wsgi from nova.compute import vm_states import nova.conf @@ -24,8 +23,6 @@ from nova.policies import hide_server_addresses as hsa_policies CONF = nova.conf.CONF -ALIAS = 'os-hide-server-addresses' - class Controller(wsgi.Controller): def __init__(self, *args, **kwargs): @@ -66,17 +63,3 @@ class Controller(wsgi.Controller): if 'addresses' in server: instance = req.get_db_instance(server['id']) self._perhaps_hide_addresses(instance, server) - - -class HideServerAddresses(extensions.V21APIExtensionBase): - """Support hiding server addresses in certain states.""" - - name = 'HideServerAddresses' - alias = ALIAS - version = 1 - - def get_controller_extensions(self): - return [extensions.ControllerExtension(self, 'servers', Controller())] - - def get_resources(self): - return [] diff --git a/nova/api/openstack/compute/lock_server.py b/nova/api/openstack/compute/lock_server.py index 8d4bd55ee9a0..ed616a596f1a 100644 --- a/nova/api/openstack/compute/lock_server.py +++ b/nova/api/openstack/compute/lock_server.py @@ -19,8 +19,6 @@ from nova.api.openstack import wsgi from nova import compute from nova.policies import lock_server as ls_policies -ALIAS = "os-lock-server" - class LockServerController(wsgi.Controller): def __init__(self, *args, **kwargs): @@ -52,19 +50,3 @@ class LockServerController(wsgi.Controller): instance) self.compute_api.unlock(context, instance) - - -class LockServer(extensions.V21APIExtensionBase): - """Enable lock/unlock server actions.""" - - name = "LockServer" - alias = ALIAS - version = 1 - - def get_controller_extensions(self): - controller = LockServerController() - extension = extensions.ControllerExtension(self, 'servers', controller) - return [extension] - - def get_resources(self): - return [] diff --git a/nova/api/openstack/compute/migrate_server.py b/nova/api/openstack/compute/migrate_server.py index ed1f4c1f21a3..5c35be93047f 100644 --- a/nova/api/openstack/compute/migrate_server.py +++ b/nova/api/openstack/compute/migrate_server.py @@ -30,7 +30,6 @@ from nova.i18n import _ from nova.policies import migrate_server as ms_policies LOG = logging.getLogger(__name__) -ALIAS = "os-migrate-server" class MigrateServerController(wsgi.Controller): @@ -131,19 +130,3 @@ class MigrateServerController(wsgi.Controller): message = _("Can't force to a non-provided destination") raise exc.HTTPBadRequest(explanation=message) return force - - -class MigrateServer(extensions.V21APIExtensionBase): - """Enable migrate and live-migrate server actions.""" - - name = "MigrateServer" - alias = ALIAS - version = 1 - - def get_controller_extensions(self): - controller = MigrateServerController() - extension = extensions.ControllerExtension(self, 'servers', controller) - return [extension] - - def get_resources(self): - return [] diff --git a/nova/api/openstack/compute/multinic.py b/nova/api/openstack/compute/multinic.py index 4d44ebc97761..41c1c3b96e24 100644 --- a/nova/api/openstack/compute/multinic.py +++ b/nova/api/openstack/compute/multinic.py @@ -27,9 +27,6 @@ from nova import exception from nova.policies import multinic as multinic_policies -ALIAS = "os-multinic" - - class MultinicController(wsgi.Controller): """This API is deprecated from Microversion '2.44'.""" @@ -75,21 +72,3 @@ class MultinicController(wsgi.Controller): raise exc.HTTPNotFound(explanation=e.format_message()) except exception.FixedIpNotFoundForSpecificInstance as e: raise exc.HTTPBadRequest(explanation=e.format_message()) - - -# Note: The class name is as it has to be for this to be loaded as an -# extension--only first character capitalized. -class Multinic(extensions.V21APIExtensionBase): - """Multiple network support.""" - - name = "Multinic" - alias = ALIAS - version = 1 - - def get_controller_extensions(self): - controller = MultinicController() - extension = extensions.ControllerExtension(self, 'servers', controller) - return [extension] - - def get_resources(self): - return [] diff --git a/nova/api/openstack/compute/pause_server.py b/nova/api/openstack/compute/pause_server.py index ead3ac924957..14b687ab83d6 100644 --- a/nova/api/openstack/compute/pause_server.py +++ b/nova/api/openstack/compute/pause_server.py @@ -22,8 +22,6 @@ from nova import compute from nova import exception from nova.policies import pause_server as ps_policies -ALIAS = "os-pause-server" - class PauseServerController(wsgi.Controller): def __init__(self, *args, **kwargs): @@ -73,19 +71,3 @@ class PauseServerController(wsgi.Controller): raise exc.HTTPNotFound(explanation=e.format_message()) except NotImplementedError: common.raise_feature_not_supported() - - -class PauseServer(extensions.V21APIExtensionBase): - """Enable pause/unpause server actions.""" - - name = "PauseServer" - alias = ALIAS - version = 1 - - def get_controller_extensions(self): - controller = PauseServerController() - extension = extensions.ControllerExtension(self, 'servers', controller) - return [extension] - - def get_resources(self): - return [] diff --git a/nova/api/openstack/compute/rescue.py b/nova/api/openstack/compute/rescue.py index 8bebbfb9a823..77918031ced4 100644 --- a/nova/api/openstack/compute/rescue.py +++ b/nova/api/openstack/compute/rescue.py @@ -27,8 +27,6 @@ from nova import exception from nova.policies import rescue as rescue_policies from nova import utils - -ALIAS = "os-rescue" CONF = nova.conf.CONF @@ -100,19 +98,3 @@ class RescueController(wsgi.Controller): common.raise_http_conflict_for_instance_invalid_state(state_error, 'unrescue', id) - - -class Rescue(extensions.V21APIExtensionBase): - """Instance rescue mode.""" - - name = "Rescue" - alias = ALIAS - version = 1 - - def get_resources(self): - return [] - - def get_controller_extensions(self): - controller = RescueController() - extension = extensions.ControllerExtension(self, 'servers', controller) - return [extension] diff --git a/nova/api/openstack/compute/scheduler_hints.py b/nova/api/openstack/compute/scheduler_hints.py index 5492f0e28b6c..f38ba7702531 100644 --- a/nova/api/openstack/compute/scheduler_hints.py +++ b/nova/api/openstack/compute/scheduler_hints.py @@ -13,23 +13,6 @@ # under the License. from nova.api.openstack.compute.schemas import scheduler_hints as schema -from nova.api.openstack import extensions - -ALIAS = "os-scheduler-hints" - - -class SchedulerHints(extensions.V21APIExtensionBase): - """Pass arbitrary key/value pairs to the scheduler.""" - - name = "SchedulerHints" - alias = ALIAS - version = 1 - - def get_controller_extensions(self): - return [] - - def get_resources(self): - return [] # NOTE(gmann): Accepting request body in this function to fetch "scheduler diff --git a/nova/api/openstack/compute/server_usage.py b/nova/api/openstack/compute/server_usage.py index 69a464e8b612..5448f8bc23f0 100644 --- a/nova/api/openstack/compute/server_usage.py +++ b/nova/api/openstack/compute/server_usage.py @@ -12,13 +12,10 @@ # License for the specific language governing permissions and limitations # under the License. -from nova.api.openstack import extensions from nova.api.openstack import wsgi from nova.policies import server_usage as su_policies -ALIAS = "os-server-usage" - resp_topic = "OS-SRV-USG" @@ -54,19 +51,3 @@ class ServerUsageController(wsgi.Controller): # server['id'] is guaranteed to be in the cache due to # the core API adding it in its 'detail' method. self._extend_server(server, db_instance) - - -class ServerUsage(extensions.V21APIExtensionBase): - """Adds launched_at and terminated_at on Servers.""" - - name = "ServerUsage" - alias = ALIAS - version = 1 - - def get_controller_extensions(self): - controller = ServerUsageController() - extension = extensions.ControllerExtension(self, 'servers', controller) - return [extension] - - def get_resources(self): - return [] diff --git a/nova/api/openstack/compute/servers.py b/nova/api/openstack/compute/servers.py index 49ac271b74bd..922b1bfd9859 100644 --- a/nova/api/openstack/compute/servers.py +++ b/nova/api/openstack/compute/servers.py @@ -54,7 +54,6 @@ from nova import objects from nova.policies import servers as server_policies from nova import utils -ALIAS = 'servers' TAG_SEARCH_FILTERS = ('tags', 'tags-any', 'not-tags', 'not-tags-any') DEVICE_TAGGING_MIN_COMPUTE_VERSION = 14 @@ -1162,26 +1161,3 @@ def remove_invalid_sort_keys(context, sort_keys, sort_dirs, raise exc.HTTPForbidden(explanation=msg) return sort_keys, sort_dirs - - -class Servers(extensions.V21APIExtensionBase): - """Servers.""" - - name = "Servers" - alias = ALIAS - version = 1 - - def get_resources(self): - member_actions = {'action': 'POST'} - collection_actions = {'detail': 'GET'} - resources = [ - extensions.ResourceExtension( - ALIAS, - ServersController(extension_info=self.extension_info), - member_name='server', collection_actions=collection_actions, - member_actions=member_actions)] - - return resources - - def get_controller_extensions(self): - return [] diff --git a/nova/api/openstack/compute/shelve.py b/nova/api/openstack/compute/shelve.py index 36947b8204ae..bc9f0387187e 100644 --- a/nova/api/openstack/compute/shelve.py +++ b/nova/api/openstack/compute/shelve.py @@ -24,9 +24,6 @@ from nova import exception from nova.policies import shelve as shelve_policies -ALIAS = 'os-shelve' - - class ShelveController(wsgi.Controller): def __init__(self, *args, **kwargs): super(ShelveController, self).__init__(*args, **kwargs) @@ -91,19 +88,3 @@ class ShelveController(wsgi.Controller): common.raise_http_conflict_for_instance_invalid_state(state_error, 'unshelve', id) - - -class Shelve(exts.V21APIExtensionBase): - """Instance shelve mode.""" - - name = "Shelve" - alias = ALIAS - version = 1 - - def get_controller_extensions(self): - controller = ShelveController() - extension = exts.ControllerExtension(self, 'servers', controller) - return [extension] - - def get_resources(self): - return [] diff --git a/nova/api/openstack/compute/suspend_server.py b/nova/api/openstack/compute/suspend_server.py index ec3546b34619..cf0b9455275c 100644 --- a/nova/api/openstack/compute/suspend_server.py +++ b/nova/api/openstack/compute/suspend_server.py @@ -21,8 +21,6 @@ from nova import compute from nova import exception from nova.policies import suspend_server as ss_policies -ALIAS = "os-suspend-server" - class SuspendServerController(wsgi.Controller): def __init__(self, *args, **kwargs): @@ -66,19 +64,3 @@ class SuspendServerController(wsgi.Controller): except exception.InstanceInvalidState as state_error: common.raise_http_conflict_for_instance_invalid_state(state_error, 'resume', id) - - -class SuspendServer(extensions.V21APIExtensionBase): - """Enable suspend/resume server actions.""" - - name = "SuspendServer" - alias = ALIAS - version = 1 - - def get_controller_extensions(self): - controller = SuspendServerController() - extension = extensions.ControllerExtension(self, 'servers', controller) - return [extension] - - def get_resources(self): - return [] diff --git a/nova/tests/unit/api/openstack/compute/test_extension_info.py b/nova/tests/unit/api/openstack/compute/test_extension_info.py index 93f36bdcb390..ed901989f5aa 100644 --- a/nova/tests/unit/api/openstack/compute/test_extension_info.py +++ b/nova/tests/unit/api/openstack/compute/test_extension_info.py @@ -12,8 +12,6 @@ # License for the specific language governing permissions and limitations # under the License. -import copy - import mock import webob @@ -24,163 +22,15 @@ from nova import test from nova.tests.unit.api.openstack import fakes -FAKE_UPDATED_DATE = extension_info.FAKE_UPDATED_DATE - -# NOTE(sdague): this whole test module is short term while we shift -# the extensions into main path code. Some short cuts are taken in the -# interim to keep these extension tests. - - -class fake_extension(object): - def __init__(self, name, alias, description, version): - self.name = name - self.alias = alias - self.__doc__ = description - self.version = version - - -fake_extensions = { - 'ext1-alias': fake_extension('ext1', 'ext1-alias', 'ext1 description', 1), - 'ext2-alias': fake_extension('ext2', 'ext2-alias', 'ext2 description', 2), - 'ext3-alias': fake_extension('ext3', 'ext3-alias', 'ext3 description', 1) -} - - -simulated_extension_list = { - 'servers': fake_extension('Servers', 'servers', 'Servers.', 1), - 'images': fake_extension('Images', 'images', 'Images.', 2), - 'os-quota-sets': fake_extension('Quotas', 'os-quota-sets', - 'Quotas management support', 1), - 'os-cells': fake_extension('Cells', 'os-cells', - 'Cells description', 1), - 'os-flavor-access': fake_extension('FlavorAccess', 'os-flavor-access', - 'Flavor access support.', 1) -} - - -class ExtensionInfoTest(test.NoDBTestCase): - - def setUp(self): - super(ExtensionInfoTest, self).setUp() - ext_info = extension_info.LoadedExtensionInfo() - ext_info.extensions = fake_extensions - self.controller = extension_info.ExtensionInfoController(ext_info) - - @mock.patch.object(policy, 'authorize', mock.Mock(return_value=True)) - def test_extension_info_list(self): - req = fakes.HTTPRequestV21.blank('/extensions') - res_dict = self.controller.index(req) - # NOTE(sdague): because of hardcoded extensions the count is - # going to grow, and that's fine. We'll just check that it's - # greater than the 3 that we inserted. - self.assertGreaterEqual(len(res_dict['extensions']), 3) - - # NOTE(sdague): filter the extension list by only ones that - # are the fake alias names, otherwise we get errors as we - # migrate extensions into the hardcoded list. - for e in [x for x in res_dict['extensions'] if '-alias' in x['alias']]: - self.assertIn(e['alias'], fake_extensions) - self.assertEqual(e['name'], fake_extensions[e['alias']].name) - self.assertEqual(e['alias'], fake_extensions[e['alias']].alias) - self.assertEqual(e['description'], - fake_extensions[e['alias']].__doc__) - self.assertEqual(e['updated'], FAKE_UPDATED_DATE) - self.assertEqual(e['links'], []) - self.assertEqual(6, len(e)) - - @mock.patch.object(policy, 'authorize', mock.Mock(return_value=True)) - def test_extension_info_show(self): - req = fakes.HTTPRequestV21.blank('/extensions/ext1-alias') - res_dict = self.controller.show(req, 'ext1-alias') - self.assertEqual(1, len(res_dict)) - self.assertEqual(res_dict['extension']['name'], - fake_extensions['ext1-alias'].name) - self.assertEqual(res_dict['extension']['alias'], - fake_extensions['ext1-alias'].alias) - self.assertEqual(res_dict['extension']['description'], - fake_extensions['ext1-alias'].__doc__) - self.assertEqual(res_dict['extension']['updated'], FAKE_UPDATED_DATE) - self.assertEqual(res_dict['extension']['links'], []) - self.assertEqual(6, len(res_dict['extension'])) - - class ExtensionInfoV21Test(test.NoDBTestCase): def setUp(self): super(ExtensionInfoV21Test, self).setUp() - ext_info = extension_info.LoadedExtensionInfo() - ext_info.extensions = simulated_extension_list - self.controller = extension_info.ExtensionInfoController(ext_info) + self.controller = extension_info.ExtensionInfoController() patcher = mock.patch.object(policy, 'authorize', return_value=True) patcher.start() self.addCleanup(patcher.stop) - def test_extension_info_list(self): - req = fakes.HTTPRequest.blank('/extensions') - res_dict = self.controller.index(req) - # NOTE(sdague): because of hardcoded extensions the count is - # going to grow, and that's fine. We'll just check that it's - # greater than the 12 that we inserted. - self.assertGreaterEqual(len(res_dict['extensions']), 12) - - expected_output = copy.deepcopy(simulated_extension_list) - del expected_output['images'] - del expected_output['servers'] - expected_output['os-cell-capacities'] = fake_extension( - 'CellCapacities', 'os-cell-capacities', 'Adding functionality' - ' to get cell capacities.', -1) - expected_output['os-server-sort-keys'] = fake_extension( - 'ServerSortKeys', 'os-server-sort-keys', 'Add sorting' - ' support in get Server v2 API.', -1) - expected_output['os-user-quotas'] = fake_extension( - 'UserQuotas', 'os-user-quotas', 'Project user quota support.', -1) - expected_output['os-extended-quotas'] = fake_extension( - 'ExtendedQuotas', 'os-extended-quotas', 'Adds ability for' - ' admins to delete quota and optionally force the update' - ' Quota command.', -1) - expected_output['os-create-server-ext'] = fake_extension( - 'Createserverext', 'os-create-server-ext', 'Extended support to' - ' the Create Server v1.1 API.', -1) - expected_output['OS-EXT-IPS'] = fake_extension( - 'ExtendedIps', 'OS-EXT-IPS', 'Adds type parameter to the' - ' ip list.', -1) - expected_output['OS-EXT-IPS-MAC'] = fake_extension( - 'ExtendedIpsMac', 'OS-EXT-IPS-MAC', 'Adds mac address parameter' - ' to the ip list.', -1) - expected_output['os-server-list-multi-status'] = fake_extension( - 'ServerListMultiStatus', 'os-server-list-multi-status', - 'Allow to filter the servers by a set of status values.', -1) - expected_output['os-server-start-stop'] = fake_extension( - 'ServerStartStop', 'os-server-start-stop', 'Start/Stop instance' - ' compute API support.', -1) - - # NOTE(sdague): filter the extension list by only ones that - # are the fake alias names, otherwise we get errors as we - # migrate extensions into the hardcoded list. - for e in [x for x in res_dict['extensions'] if '-alias' in x['alias']]: - self.assertIn(e['alias'], expected_output) - self.assertEqual(e['name'], expected_output[e['alias']].name) - self.assertEqual(e['alias'], expected_output[e['alias']].alias) - self.assertEqual(e['description'], - expected_output[e['alias']].__doc__) - self.assertEqual(e['updated'], FAKE_UPDATED_DATE) - self.assertEqual(e['links'], []) - self.assertEqual(6, len(e)) - - def test_extension_info_show(self): - req = fakes.HTTPRequest.blank('/extensions/os-cells') - res_dict = self.controller.show(req, 'os-cells') - self.assertEqual(1, len(res_dict)) - self.assertEqual(res_dict['extension']['name'], - simulated_extension_list['os-cells'].name) - self.assertEqual(res_dict['extension']['alias'], - simulated_extension_list['os-cells'].alias) - self.assertEqual(res_dict['extension']['description'], - simulated_extension_list['os-cells'].__doc__) - self.assertEqual(res_dict['extension']['updated'], FAKE_UPDATED_DATE) - self.assertEqual(res_dict['extension']['links'], []) - self.assertEqual(6, len(res_dict['extension'])) - def test_extension_info_show_servers_not_present(self): req = fakes.HTTPRequest.blank('/extensions/servers') self.assertRaises(webob.exc.HTTPNotFound, self.controller.show, @@ -190,9 +40,7 @@ class ExtensionInfoV21Test(test.NoDBTestCase): class ExtensionInfoPolicyEnforcementV21(test.NoDBTestCase): def setUp(self): super(ExtensionInfoPolicyEnforcementV21, self).setUp() - ext_info = extension_info.LoadedExtensionInfo() - ext_info.extensions = fake_extensions - self.controller = extension_info.ExtensionInfoController(ext_info) + self.controller = extension_info.ExtensionInfoController() self.req = fakes.HTTPRequest.blank('') def _test_extension_policy_failed(self, action, *args):