summaryrefslogtreecommitdiffstats
path: root/nova/api
diff options
context:
space:
mode:
authorRick Harris <rick.harris@rackspace.com>2011-02-25 16:47:08 +0000
committerRick Harris <rick.harris@rackspace.com>2011-02-25 16:47:08 +0000
commit7ae64e06643025e4945ae0ef056f9fb2184904ff (patch)
tree467ff2123559b9ce06ed1c343bd9ec12cce2c16b /nova/api
parent079b532a1080da9fe5d99e90fa9c60d16506de06 (diff)
parent645bc7a7dea6ba01d76589632200636e243641ec (diff)
Merging trunk, conflicts fixed
Diffstat (limited to 'nova/api')
-rw-r--r--nova/api/ec2/admin.py111
-rw-r--r--nova/api/openstack/__init__.py1
-rw-r--r--nova/api/openstack/auth.py6
-rw-r--r--nova/api/openstack/servers.py14
4 files changed, 116 insertions, 16 deletions
diff --git a/nova/api/ec2/admin.py b/nova/api/ec2/admin.py
index 735951082..e2a05fce1 100644
--- a/nova/api/ec2/admin.py
+++ b/nova/api/ec2/admin.py
@@ -21,14 +21,18 @@ Admin API controller, exposed through http via the api worker.
"""
import base64
+import datetime
from nova import db
from nova import exception
+from nova import flags
from nova import log as logging
+from nova import utils
from nova.auth import manager
from nova.compute import instance_types
+FLAGS = flags.FLAGS
LOG = logging.getLogger('nova.api.ec2.admin')
@@ -55,12 +59,25 @@ def project_dict(project):
return {}
-def host_dict(host):
+def host_dict(host, compute_service, instances, volume_service, volumes, now):
"""Convert a host model object to a result dict"""
- if host:
- return host.state
- else:
- return {}
+ rv = {'hostanme': 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(name, inst):
@@ -71,6 +88,25 @@ def instance_dict(name, inst):
'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'] = vpn_instance['ec2_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 utils.vpn_ping(project.vpn_ip, project.vpn_port):
+ rv['state'] = 'running'
+ else:
+ rv['state'] = 'down'
+ else:
+ rv['state'] = 'pending'
+ return rv
+
+
class AdminController(object):
"""
API Controller for users, hosts, nodes, and workers.
@@ -223,19 +259,68 @@ class AdminController(object):
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'] == FLAGS.vpn_image_id
+ and not instance['state_description'] in
+ ['shutting_down', 'shutdown']):
+ 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()
+ try:
+ pipe.launch_vpn_instance(project)
+ 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': instance['ec2_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):
+ def describe_hosts(self, context, **_kwargs):
"""Returns status info for all nodes. Includes:
- * Disk Space
- * Instance List
- * RAM used
- * CPU used
- * DHCP servers running
- * Iptables / bridges
+ * Hostname
+ * Compute (up, down, None)
+ * Instance count
+ * Volume (up, down, None)
+ * Volume Count
"""
- return {'hostSet': [host_dict(h) for h in db.host_get_all()]}
+ services = db.service_get_all(context)
+ now = datetime.datetime.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 describe_host(self, _context, name, **_kwargs):
"""Returns status info for single node."""
diff --git a/nova/api/openstack/__init__.py b/nova/api/openstack/__init__.py
index d0b18eced..b1b38ed2d 100644
--- a/nova/api/openstack/__init__.py
+++ b/nova/api/openstack/__init__.py
@@ -81,6 +81,7 @@ class APIRouter(wsgi.Router):
server_members['suspend'] = 'POST'
server_members['resume'] = 'POST'
server_members['reset_network'] = 'POST'
+ server_members['inject_network_info'] = 'POST'
mapper.resource("zone", "zones", controller=zones.Controller(),
collection={'detail': 'GET'})
diff --git a/nova/api/openstack/auth.py b/nova/api/openstack/auth.py
index 1dfdd5318..dff69a7f2 100644
--- a/nova/api/openstack/auth.py
+++ b/nova/api/openstack/auth.py
@@ -103,11 +103,11 @@ class AuthMiddleware(wsgi.Middleware):
2 days ago.
"""
ctxt = context.get_admin_context()
- token = self.db.auth_get_token(ctxt, token_hash)
+ token = self.db.auth_token_get(ctxt, token_hash)
if token:
delta = datetime.datetime.now() - token.created_at
if delta.days >= 2:
- self.db.auth_destroy_token(ctxt, token)
+ self.db.auth_token_destroy(ctxt, token.id)
else:
return self.auth.get_user(token.user_id)
return None
@@ -131,6 +131,6 @@ class AuthMiddleware(wsgi.Middleware):
token_dict['server_management_url'] = req.url
token_dict['storage_url'] = ''
token_dict['user_id'] = user.id
- token = self.db.auth_create_token(ctxt, token_dict)
+ token = self.db.auth_token_create(ctxt, token_dict)
return token, user
return None, None
diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py
index bf5663f60..f7ad0b8ae 100644
--- a/nova/api/openstack/servers.py
+++ b/nova/api/openstack/servers.py
@@ -274,6 +274,20 @@ class Controller(wsgi.Controller):
return faults.Fault(exc.HTTPUnprocessableEntity())
return exc.HTTPAccepted()
+ def inject_network_info(self, req, id):
+ """
+ Inject network info for an instance (admin only).
+
+ """
+ context = req.environ['nova.context']
+ try:
+ self.compute_api.inject_network_info(context, id)
+ except:
+ readable = traceback.format_exc()
+ LOG.exception(_("Compute.api::inject_network_info %s"), readable)
+ return faults.Fault(exc.HTTPUnprocessableEntity())
+ return exc.HTTPAccepted()
+
def pause(self, req, id):
""" Permit Admins to Pause the server. """
ctxt = req.environ['nova.context']