summaryrefslogtreecommitdiffstats
path: root/nova/api
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2012-11-16 06:10:38 +0000
committerGerrit Code Review <review@openstack.org>2012-11-16 06:10:38 +0000
commit48967d3822299b345589673be79cbcb58fa95d79 (patch)
treed064d7b2902f4ec7c53e04a62dd592ea9294cb5d /nova/api
parentc6d1abd62a4fc26f8cd8cf52af6f2e828e0b0d22 (diff)
parenta220aa15b056914df1b9debc95322d01a0e408e8 (diff)
downloadnova-48967d3822299b345589673be79cbcb58fa95d79.tar.gz
nova-48967d3822299b345589673be79cbcb58fa95d79.tar.xz
nova-48967d3822299b345589673be79cbcb58fa95d79.zip
Merge "API extension for fpinging instances"
Diffstat (limited to 'nova/api')
-rw-r--r--nova/api/openstack/compute/contrib/fping.py162
-rw-r--r--nova/api/openstack/compute/limits.py1
2 files changed, 163 insertions, 0 deletions
diff --git a/nova/api/openstack/compute/contrib/fping.py b/nova/api/openstack/compute/contrib/fping.py
new file mode 100644
index 000000000..3ae876f5a
--- /dev/null
+++ b/nova/api/openstack/compute/contrib/fping.py
@@ -0,0 +1,162 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2011 Grid Dynamics
+# Copyright 2011 OpenStack LLC.
+# 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.
+
+import itertools
+import os
+import time
+
+from webob import exc
+
+from nova.api.openstack import common
+from nova.api.openstack import extensions
+from nova import compute
+from nova import exception
+from nova import flags
+from nova.openstack.common import cfg
+from nova.openstack.common import log as logging
+from nova import utils
+
+
+LOG = logging.getLogger(__name__)
+authorize = extensions.extension_authorizer('compute', 'fping')
+authorize_all_tenants = extensions.extension_authorizer(
+ 'compute', 'fping:all_tenants')
+fping_opts = [
+ cfg.StrOpt("fping_path",
+ default="/usr/sbin/fping",
+ help="Full path to fping."),
+]
+
+FLAGS = flags.FLAGS
+FLAGS.register_opts(fping_opts)
+
+
+class FpingController(object):
+
+ def __init__(self, network_api=None):
+ self.compute_api = compute.API()
+ self.last_call = {}
+
+ def check_fping(self):
+ if not os.access(FLAGS.fping_path, os.X_OK):
+ raise exc.HTTPServiceUnavailable(
+ explanation=_("fping utility is not found."))
+
+ @staticmethod
+ def fping(ips):
+ fping_ret = utils.execute(FLAGS.fping_path, *ips,
+ check_exit_code=False)
+ if not fping_ret:
+ return set()
+ alive_ips = set()
+ for line in fping_ret[0].split("\n"):
+ ip = line.split(" ", 1)[0]
+ if "alive" in line:
+ alive_ips.add(ip)
+ return alive_ips
+
+ @staticmethod
+ def _get_instance_ips(context, instance):
+ ret = []
+ for network in common.get_networks_for_instance(
+ context, instance).values():
+ all_ips = itertools.chain(network["ips"], network["floating_ips"])
+ ret += [ip["address"] for ip in all_ips]
+ return ret
+
+ def index(self, req):
+ context = req.environ["nova.context"]
+ search_opts = dict(deleted=False)
+ if "all_tenants" in req.GET:
+ authorize_all_tenants(context)
+ else:
+ authorize(context)
+ if context.project_id:
+ search_opts["project_id"] = context.project_id
+ else:
+ search_opts["user_id"] = context.user_id
+ self.check_fping()
+ include = req.GET.get("include", None)
+ if include:
+ include = set(include.split(","))
+ exclude = set()
+ else:
+ include = None
+ exclude = req.GET.get("exclude", None)
+ if exclude:
+ exclude = set(exclude.split(","))
+ else:
+ exclude = set()
+
+ instance_list = self.compute_api.get_all(
+ context, search_opts=search_opts)
+ ip_list = []
+ instance_ips = {}
+ instance_projects = {}
+
+ for instance in instance_list:
+ uuid = instance["uuid"]
+ if uuid in exclude or (include is not None and
+ uuid not in include):
+ continue
+ ips = [str(ip) for ip in self._get_instance_ips(context, instance)]
+ instance_ips[uuid] = ips
+ instance_projects[uuid] = instance["project_id"]
+ ip_list += ips
+ alive_ips = self.fping(ip_list)
+ res = []
+ for instance_uuid, ips in instance_ips.iteritems():
+ res.append({
+ "id": instance_uuid,
+ "project_id": instance_projects[instance_uuid],
+ "alive": bool(set(ips) & alive_ips),
+ })
+ return {"servers": res}
+
+ def show(self, req, id):
+ try:
+ context = req.environ["nova.context"]
+ authorize(context)
+ self.check_fping()
+ instance = self.compute_api.get(context, id)
+ ips = [str(ip) for ip in self._get_instance_ips(context, instance)]
+ alive_ips = self.fping(ips)
+ return {
+ "server": {
+ "id": instance["uuid"],
+ "project_id": instance["project_id"],
+ "alive": bool(set(ips) & alive_ips),
+ }
+ }
+ except exception.NotFound:
+ raise exc.HTTPNotFound()
+
+
+class Fping(extensions.ExtensionDescriptor):
+ """Fping Management Extension."""
+
+ name = "Fping"
+ alias = "os-fping"
+ namespace = "http://docs.openstack.org/compute/ext/fping/api/v1.1"
+ updated = "2012-07-06T00:00:00+00:00"
+
+ def get_resources(self):
+ res = extensions.ResourceExtension(
+ "os-fping",
+ FpingController())
+ return [res]
diff --git a/nova/api/openstack/compute/limits.py b/nova/api/openstack/compute/limits.py
index c0ef65670..767280a45 100644
--- a/nova/api/openstack/compute/limits.py
+++ b/nova/api/openstack/compute/limits.py
@@ -212,6 +212,7 @@ DEFAULT_LIMITS = [
Limit("PUT", "*", ".*", 10, PER_MINUTE),
Limit("GET", "*changes-since*", ".*changes-since.*", 3, PER_MINUTE),
Limit("DELETE", "*", ".*", 100, PER_MINUTE),
+ Limit("GET", "*/os-fping", "^/os-fping", 12, PER_HOUR),
]