summaryrefslogtreecommitdiffstats
path: root/nova/api
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2012-02-01 19:08:03 +0000
committerGerrit Code Review <review@openstack.org>2012-02-01 19:08:03 +0000
commitfced0f58bcbaef6fff76c6719e27e7d100aa721b (patch)
tree38914db032abbb1df4d3fc696b0a223c247f40be /nova/api
parentb3b3194d76e22cb9617750c7b13c3a1d4429a636 (diff)
parent62d5fae8d11b6403f9a63a709270ffafebb7ef09 (diff)
downloadnova-fced0f58bcbaef6fff76c6719e27e7d100aa721b.tar.gz
nova-fced0f58bcbaef6fff76c6719e27e7d100aa721b.tar.xz
nova-fced0f58bcbaef6fff76c6719e27e7d100aa721b.zip
Merge "remove unsupported ec2 extensions"
Diffstat (limited to 'nova/api')
-rw-r--r--nova/api/ec2/admin.py418
-rw-r--r--nova/api/ec2/apirequest.py9
-rw-r--r--nova/api/ec2/cloud.py72
3 files changed, 4 insertions, 495 deletions
diff --git a/nova/api/ec2/admin.py b/nova/api/ec2/admin.py
deleted file mode 100644
index 4e81debe4..000000000
--- a/nova/api/ec2/admin.py
+++ /dev/null
@@ -1,418 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2010 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Admin API controller, exposed through http via the api worker.
-"""
-
-import base64
-import urllib
-
-import netaddr
-
-from nova.api.ec2 import ec2utils
-from nova.auth import manager
-from nova import compute
-from nova.compute import instance_types
-from nova.compute import vm_states
-from nova import db
-from nova import exception
-from nova import flags
-from nova import log as logging
-from nova import utils
-
-
-FLAGS = flags.FLAGS
-LOG = logging.getLogger('nova.api.ec2.admin')
-
-
-def user_dict(user, base64_file=None):
- """Convert the user object to a result dict"""
- if user:
- return {
- 'username': user.id,
- 'accesskey': user.access,
- 'secretkey': user.secret,
- 'file': base64_file}
- else:
- return {}
-
-
-def project_dict(project):
- """Convert the project object to a result dict"""
- if project:
- return {
- 'projectname': project.id,
- 'project_manager_id': project.project_manager_id,
- 'description': project.description}
- else:
- return {}
-
-
-def host_dict(host, compute_service, instances, volume_service, volumes, now):
- """Convert a host model object to a result dict"""
- rv = {'hostname': host, 'instance_count': len(instances),
- 'volume_count': len(volumes)}
- if compute_service:
- latest = compute_service['updated_at'] or compute_service['created_at']
- delta = now - latest
- if delta.seconds <= FLAGS.service_down_time:
- rv['compute'] = 'up'
- else:
- rv['compute'] = 'down'
- if volume_service:
- latest = volume_service['updated_at'] or volume_service['created_at']
- delta = now - latest
- if delta.seconds <= FLAGS.service_down_time:
- rv['volume'] = 'up'
- else:
- rv['volume'] = 'down'
- return rv
-
-
-def instance_dict(inst):
- return {'name': inst['name'],
- 'memory_mb': inst['memory_mb'],
- 'vcpus': inst['vcpus'],
- 'disk_gb': inst['root_gb'],
- 'flavor_id': inst['flavorid']}
-
-
-def vpn_dict(project, vpn_instance):
- rv = {'project_id': project.id,
- 'public_ip': project.vpn_ip,
- 'public_port': project.vpn_port}
- if vpn_instance:
- rv['instance_id'] = ec2utils.id_to_ec2_id(vpn_instance['id'])
- rv['created_at'] = utils.isotime(vpn_instance['created_at'])
- address = vpn_instance.get('fixed_ip', None)
- if address:
- rv['internal_ip'] = address['address']
- if project.vpn_ip and project.vpn_port:
- if utils.vpn_ping(project.vpn_ip, project.vpn_port):
- rv['state'] = 'running'
- else:
- rv['state'] = 'down'
- else:
- rv['state'] = 'down - invalid project vpn config'
- else:
- rv['state'] = 'pending'
- return rv
-
-
-class AdminController(object):
- """
- API Controller for users, hosts, nodes, and workers.
- """
-
- def __str__(self):
- return 'AdminController'
-
- def __init__(self):
- self.compute_api = compute.API()
-
- def describe_instance_types(self, context, **_kwargs):
- """Returns all active instance types data (vcpus, memory, etc.)"""
- inst_types = instance_types.get_all_types()
- inst_type_dicts = [instance_dict(i) for i in inst_types.values()]
- return {'instanceTypeSet': inst_type_dicts}
-
- def describe_user(self, _context, name, **_kwargs):
- """Returns user data, including access and secret keys."""
- return user_dict(manager.AuthManager().get_user(name))
-
- def describe_users(self, _context, **_kwargs):
- """Returns all users - should be changed to deal with a list."""
- return {'userSet':
- [user_dict(u) for u in manager.AuthManager().get_users()]}
-
- def register_user(self, context, name, **_kwargs):
- """Creates a new user, and returns generated credentials."""
- LOG.audit(_("Creating new user: %s"), name, context=context)
- return user_dict(manager.AuthManager().create_user(name))
-
- def deregister_user(self, context, name, **_kwargs):
- """Deletes a single user (NOT undoable.)
- Should throw an exception if the user has instances,
- volumes, or buckets remaining.
- """
- LOG.audit(_("Deleting user: %s"), name, context=context)
- manager.AuthManager().delete_user(name)
- return True
-
- def describe_roles(self, context, project_roles=True, **kwargs):
- """Returns a list of allowed roles."""
- roles = manager.AuthManager().get_roles(project_roles)
- return {'roles': [{'role': r} for r in roles]}
-
- def describe_user_roles(self, context, user, project=None, **kwargs):
- """Returns a list of roles for the given user.
- Omitting project will return any global roles that the user has.
- Specifying project will return only project specific roles.
- """
- roles = manager.AuthManager().get_user_roles(user, project=project)
- return {'roles': [{'role': r} for r in roles]}
-
- def modify_user_role(self, context, user, role, project=None,
- operation='add', **kwargs):
- """Add or remove a role for a user and project."""
- if operation == 'add':
- if project:
- msg = _("Adding role %(role)s to user %(user)s"
- " for project %(project)s") % locals()
- LOG.audit(msg, context=context)
- else:
- msg = _("Adding sitewide role %(role)s to"
- " user %(user)s") % locals()
- LOG.audit(msg, context=context)
- manager.AuthManager().add_role(user, role, project)
- elif operation == 'remove':
- if project:
- msg = _("Removing role %(role)s from user %(user)s"
- " for project %(project)s") % locals()
- LOG.audit(msg, context=context)
- else:
- msg = _("Removing sitewide role %(role)s"
- " from user %(user)s") % locals()
- LOG.audit(msg, context=context)
- manager.AuthManager().remove_role(user, role, project)
- else:
- raise exception.ApiError(_('operation must be add or remove'))
-
- return True
-
- def generate_x509_for_user(self, context, name, project=None, **kwargs):
- """Generates and returns an x509 certificate for a single user.
- Is usually called from a client that will wrap this with
- access and secret key info, and return a zip file.
- """
- if project is None:
- project = name
- project = manager.AuthManager().get_project(project)
- user = manager.AuthManager().get_user(name)
- msg = _("Getting x509 for user: %(name)s"
- " on project: %(project)s") % locals()
- LOG.audit(msg, context=context)
- return user_dict(user, base64.b64encode(project.get_credentials(user)))
-
- def describe_project(self, context, name, **kwargs):
- """Returns project data, including member ids."""
- return project_dict(manager.AuthManager().get_project(name))
-
- def describe_projects(self, context, user=None, **kwargs):
- """Returns all projects - should be changed to deal with a list."""
- return {'projectSet':
- [project_dict(u) for u in
- manager.AuthManager().get_projects(user=user)]}
-
- def register_project(self, context, name, manager_user, description=None,
- member_users=None, **kwargs):
- """Creates a new project"""
- msg = _("Create project %(name)s managed by"
- " %(manager_user)s") % locals()
- LOG.audit(msg, context=context)
- return project_dict(
- manager.AuthManager().create_project(
- name,
- manager_user,
- description=None,
- member_users=None))
-
- def modify_project(self, context, name, manager_user, description=None,
- **kwargs):
- """Modifies a project"""
- msg = _("Modify project: %(name)s managed by"
- " %(manager_user)s") % locals()
- LOG.audit(msg, context=context)
- manager.AuthManager().modify_project(name,
- manager_user=manager_user,
- description=description)
- return True
-
- def deregister_project(self, context, name):
- """Permanently deletes a project."""
- LOG.audit(_("Delete project: %s"), name, context=context)
- manager.AuthManager().delete_project(name)
- return True
-
- def describe_project_members(self, context, name, **kwargs):
- project = manager.AuthManager().get_project(name)
- result = {
- 'members': [{'member': m} for m in project.member_ids]}
- return result
-
- def modify_project_member(self, context, user, project, operation,
- **kwargs):
- """Add or remove a user from a project."""
- if operation == 'add':
- msg = _("Adding user %(user)s to project %(project)s") % locals()
- LOG.audit(msg, context=context)
- manager.AuthManager().add_to_project(user, project)
- elif operation == 'remove':
- msg = _("Removing user %(user)s from"
- " project %(project)s") % locals()
- LOG.audit(msg, context=context)
- manager.AuthManager().remove_from_project(user, project)
- else:
- raise exception.ApiError(_('operation must be add or remove'))
- return True
-
- def _vpn_for(self, context, project_id):
- """Get the VPN instance for a project ID."""
- for instance in db.instance_get_all_by_project(context, project_id):
- if (instance['image_id'] == str(FLAGS.vpn_image_id)
- and not instance['vm_state'] in [vm_states.DELETED]):
- return instance
-
- def start_vpn(self, context, project):
- instance = self._vpn_for(context, project)
- if not instance:
- # NOTE(vish) import delayed because of __init__.py
- from nova.cloudpipe import pipelib
- pipe = pipelib.CloudPipe()
- proj = manager.AuthManager().get_project(project)
- user_id = proj.project_manager_id
- try:
- pipe.launch_vpn_instance(project, user_id)
- except db.NoMoreNetworks:
- raise exception.ApiError("Unable to claim IP for VPN instance"
- ", ensure it isn't running, and try "
- "again in a few minutes")
- instance = self._vpn_for(context, project)
- return {'instance_id': ec2utils.id_to_ec2_id(instance['id'])}
-
- def describe_vpns(self, context):
- vpns = []
- for project in manager.AuthManager().get_projects():
- instance = self._vpn_for(context, project.id)
- vpns.append(vpn_dict(project, instance))
- return {'items': vpns}
-
- # FIXME(vish): these host commands don't work yet, perhaps some of the
- # required data can be retrieved from service objects?
-
- def describe_hosts(self, context, **_kwargs):
- """Returns status info for all nodes. Includes:
- * Hostname
- * Compute (up, down, None)
- * Instance count
- * Volume (up, down, None)
- * Volume Count
- """
- services = db.service_get_all(context, False)
- now = utils.utcnow()
- hosts = []
- rv = []
- for host in [service['host'] for service in services]:
- if not host in hosts:
- hosts.append(host)
- for host in hosts:
- compute = [s for s in services if s['host'] == host \
- and s['binary'] == 'nova-compute']
- if compute:
- compute = compute[0]
- instances = db.instance_get_all_by_host(context, host)
- volume = [s for s in services if s['host'] == host \
- and s['binary'] == 'nova-volume']
- if volume:
- volume = volume[0]
- volumes = db.volume_get_all_by_host(context, host)
- rv.append(host_dict(host, compute, instances, volume, volumes,
- now))
- return {'hosts': rv}
-
- def _provider_fw_rule_exists(self, context, rule):
- # TODO(todd): we call this repeatedly, can we filter by protocol?
- for old_rule in db.provider_fw_rule_get_all(context):
- if all([rule[k] == old_rule[k] for k in ('cidr', 'from_port',
- 'to_port', 'protocol')]):
- return True
- return False
-
- def block_external_addresses(self, context, cidr):
- """Add provider-level firewall rules to block incoming traffic."""
- LOG.audit(_('Blocking traffic to all projects incoming from %s'),
- cidr, context=context)
- cidr = urllib.unquote(cidr).decode()
- failed = {'status': 'Failed', 'message': ' 0 rules added'}
- if not utils.is_valid_cidr(cidr):
- msg = 'Improper input. Please provide a valid cidr: ' \
- 'e.g. 121.12.10.11/24.'
- failed['message'] = msg + failed['message']
- return failed
- #Normalizing cidr. e.g. '20.20.20.11/24' -> '20.20.20.0/24', so that
- #db values stay in sync with filters' values (e.g. in iptables)
- cidr = str(netaddr.IPNetwork(cidr).cidr)
- rule = {'cidr': cidr}
- tcp_rule = rule.copy()
- tcp_rule.update({'protocol': 'tcp', 'from_port': 1, 'to_port': 65535})
- udp_rule = rule.copy()
- udp_rule.update({'protocol': 'udp', 'from_port': 1, 'to_port': 65535})
- icmp_rule = rule.copy()
- icmp_rule.update({'protocol': 'icmp', 'from_port': -1,
- 'to_port': None})
- rules_added = 0
- if not self._provider_fw_rule_exists(context, tcp_rule):
- db.provider_fw_rule_create(context, tcp_rule)
- rules_added += 1
- if not self._provider_fw_rule_exists(context, udp_rule):
- db.provider_fw_rule_create(context, udp_rule)
- rules_added += 1
- if not self._provider_fw_rule_exists(context, icmp_rule):
- db.provider_fw_rule_create(context, icmp_rule)
- rules_added += 1
- if not rules_added:
- msg = 'Duplicate Rule.'
- failed['message'] = msg + failed['message']
- return failed
- self.compute_api.trigger_provider_fw_rules_refresh(context)
- return {'status': 'OK', 'message': 'Added %s rules' % rules_added}
-
- def describe_external_address_blocks(self, context):
- blocks = db.provider_fw_rule_get_all(context)
- # NOTE(todd): use a set since we have icmp/udp/tcp rules with same cidr
- blocks = set([b.cidr for b in blocks])
- blocks = [{'cidr': b} for b in blocks]
- return {'externalIpBlockInfo':
- list(sorted(blocks, key=lambda k: k['cidr']))}
-
- def remove_external_address_block(self, context, cidr):
- LOG.audit(_('Removing ip block from %s'), cidr, context=context)
- cidr = urllib.unquote(cidr).decode()
- # Catch the exception and LOG for improper or malicious inputs.
- # Also return a proper status and message in that case
- failed = {'status': 'Failed', 'message': ' 0 rules deleted'}
- if not utils.is_valid_cidr(cidr):
- msg = 'Improper input. Please provide a valid cidr: ' \
- 'e.g. 121.12.10.11/24.'
- failed['message'] = msg + failed['message']
- return failed
- #Normalizing cidr. e.g. '20.20.20.11/24' -> '20.20.20.0/24', so that
- #db values stay in sync with filters' values (e.g. in iptables)
- cidr = str(netaddr.IPNetwork(cidr).cidr)
- rules = db.provider_fw_rule_get_all_by_cidr(context, cidr)
-
- if not rules:
- msg = 'No such CIDR currently blocked.'
- failed['message'] = msg + failed['message']
- return failed
- else:
- for rule in rules:
- db.provider_fw_rule_destroy(context, rule['id'])
- self.compute_api.trigger_provider_fw_rules_refresh(context)
- return {'status': 'OK', 'message': 'Deleted %s rules' % len(rules)}
diff --git a/nova/api/ec2/apirequest.py b/nova/api/ec2/apirequest.py
index ae7204740..01ea19628 100644
--- a/nova/api/ec2/apirequest.py
+++ b/nova/api/ec2/apirequest.py
@@ -24,7 +24,6 @@ import datetime
# TODO(termie): replace minidom with etree
from xml.dom import minidom
-from nova.api.ec2 import admin
from nova.api.ec2 import ec2utils
from nova import exception
from nova import flags
@@ -57,14 +56,6 @@ class APIRequest(object):
def invoke(self, context):
try:
- # Raise NotImplemented exception for Admin specific request if
- # admin flag is set to false in nova.conf
- if (isinstance(self.controller, admin.AdminController)
- and (not FLAGS.allow_ec2_admin_api)):
- ## Raise InvalidRequest exception for EC2 Admin interface ##
- LOG.exception("Unsupported API request")
- raise exception.InvalidRequest()
-
method = getattr(self.controller,
ec2utils.camelcase_to_underscore(self.action))
except AttributeError:
diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py
index 8fa348129..c8bd098b9 100644
--- a/nova/api/ec2/cloud.py
+++ b/nova/api/ec2/cloud.py
@@ -23,10 +23,7 @@ datastore.
"""
import base64
-import os
import re
-import shutil
-import tempfile
import time
import urllib
@@ -253,7 +250,6 @@ class CloudController(object):
'zoneState': 'available'}]}
services = db.service_get_all(context, False)
- now = utils.utcnow()
hosts = []
for host in [service['host'] for service in services]:
if not host in hosts:
@@ -323,9 +319,6 @@ class CloudController(object):
s['ownerId'] = snapshot['project_id']
s['volumeSize'] = snapshot['volume_size']
s['description'] = snapshot['display_description']
-
- s['display_name'] = snapshot['display_name']
- s['display_description'] = snapshot['display_description']
return s
def create_snapshot(self, context, volume_id, **kwargs):
@@ -336,8 +329,8 @@ class CloudController(object):
snapshot = self.volume_api.create_snapshot(
context,
volume,
- kwargs.get('display_name'),
- kwargs.get('display_description'))
+ None,
+ kwargs.get('description'))
return self._format_snapshot(context, snapshot)
def delete_snapshot(self, context, snapshot_id, **kwargs):
@@ -790,15 +783,6 @@ class CloudController(object):
"Timestamp": now,
"output": base64.b64encode(output)}
- def get_ajax_console(self, context, instance_id, **kwargs):
- """Web based ajax terminal for vm.
-
- This is an extension to the normal ec2_api"""
- ec2_id = instance_id[0]
- instance_id = ec2utils.ec2_id_to_id(ec2_id)
- instance = self.compute_api.get(context, instance_id)
- return self.compute_api.get_ajax_console(context, instance)
-
def describe_volumes(self, context, volume_id=None, **kwargs):
if volume_id:
volumes = []
@@ -846,8 +830,6 @@ class CloudController(object):
else:
v['snapshotId'] = None
- v['display_name'] = volume['display_name']
- v['display_description'] = volume['display_description']
return v
def create_volume(self, context, **kwargs):
@@ -863,8 +845,8 @@ class CloudController(object):
volume = self.volume_api.create(context,
size,
- kwargs.get('display_name'),
- kwargs.get('display_description'),
+ None,
+ None,
snapshot)
# TODO(vish): Instance should be None at db layer instead of
# trying to lazy load, but for now we turn it into
@@ -877,18 +859,6 @@ class CloudController(object):
self.volume_api.delete(context, volume)
return True
- def update_volume(self, context, volume_id, **kwargs):
- volume_id = ec2utils.ec2_id_to_id(volume_id)
- updatable_fields = ['display_name', 'display_description']
- changes = {}
- for field in updatable_fields:
- if field in kwargs:
- changes[field] = kwargs[field]
- if changes:
- volume = self.volume_api.get(context, volume_id)
- self.volume_api.update(context, volume, fields=changes)
- return True
-
def attach_volume(self, context, volume_id, instance_id, device, **kwargs):
volume_id = ec2utils.ec2_id_to_id(volume_id)
instance_id = ec2utils.ec2_id_to_id(instance_id)
@@ -1157,8 +1127,6 @@ class CloudController(object):
self._format_instance_type(instance, i)
i['launchTime'] = instance['created_at']
i['amiLaunchIndex'] = instance['launch_index']
- i['displayName'] = instance['display_name']
- i['displayDescription'] = instance['display_description']
self._format_instance_root_device_name(instance, i)
self._format_instance_bdm(context, instance_id,
i['rootDeviceName'], i)
@@ -1265,8 +1233,6 @@ class CloudController(object):
max_count=max_count,
kernel_id=kwargs.get('kernel_id'),
ramdisk_id=kwargs.get('ramdisk_id'),
- display_name=kwargs.get('display_name'),
- display_description=kwargs.get('display_description'),
key_name=kwargs.get('key_name'),
user_data=kwargs.get('user_data'),
security_group=kwargs.get('security_group'),
@@ -1318,35 +1284,6 @@ class CloudController(object):
self.compute_api.start(context, instance)
return True
- def rescue_instance(self, context, instance_id, **kwargs):
- """This is an extension to the normal ec2_api"""
- LOG.debug(_("Going to rescue instance %s") % instance_id)
- _instance_id = ec2utils.ec2_id_to_id(instance_id)
- instance = self.compute_api.get(context, _instance_id)
- self.compute_api.rescue(context, instance)
- return True
-
- def unrescue_instance(self, context, instance_id, **kwargs):
- """This is an extension to the normal ec2_api"""
- LOG.debug(_("Going to unrescue instance %s") % instance_id)
- _instance_id = ec2utils.ec2_id_to_id(instance_id)
- instance = self.compute_api.get(context, _instance_id)
- self.compute_api.unrescue(context, instance)
- return True
-
- def update_instance(self, context, instance_id, **kwargs):
- """This is an extension to the normal ec2_api"""
- updatable_fields = ['display_name', 'display_description']
- changes = {}
- for field in updatable_fields:
- if field in kwargs:
- changes[field] = kwargs[field]
- if changes:
- instance_id = ec2utils.ec2_id_to_id(instance_id)
- instance = self.compute_api.get(context, instance_id)
- self.compute_api.update(context, instance, **changes)
- return True
-
def _get_image(self, context, ec2_id):
try:
internal_id = ec2utils.ec2_id_to_id(ec2_id)
@@ -1391,7 +1328,6 @@ class CloudController(object):
i['imageLocation'] = image['properties'].get('image_location')
i['imageState'] = self._get_image_state(image)
- i['displayName'] = name
i['description'] = image.get('description')
display_mapping = {'aki': 'kernel',
'ari': 'ramdisk',