1
# vim: tabstop=4 shiftwidth=4 softtabstop=4
3
# Copyright 2011 Grid Dynamics
4
# Copyright 2011 OpenStack LLC.
7
# Licensed under the Apache License, Version 2.0 (the "License"); you may
8
# not use this file except in compliance with the License. You may obtain
9
# a copy of the License at
11
# http://www.apache.org/licenses/LICENSE-2.0
13
# Unless required by applicable law or agreed to in writing, software
14
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16
# License for the specific language governing permissions and limitations
25
from nova.api.openstack import common
26
from nova.api.openstack import extensions
27
from nova import compute
28
from nova import exception
29
from nova.openstack.common import cfg
30
from nova.openstack.common import log as logging
31
from nova import utils
34
LOG = logging.getLogger(__name__)
35
authorize = extensions.extension_authorizer('compute', 'fping')
36
authorize_all_tenants = extensions.extension_authorizer(
37
'compute', 'fping:all_tenants')
39
cfg.StrOpt("fping_path",
40
default="/usr/sbin/fping",
41
help="Full path to fping."),
45
CONF.register_opts(fping_opts)
48
class FpingController(object):
50
def __init__(self, network_api=None):
51
self.compute_api = compute.API()
54
def check_fping(self):
55
if not os.access(CONF.fping_path, os.X_OK):
56
raise exc.HTTPServiceUnavailable(
57
explanation=_("fping utility is not found."))
61
fping_ret = utils.execute(CONF.fping_path, *ips,
62
check_exit_code=False)
66
for line in fping_ret[0].split("\n"):
67
ip = line.split(" ", 1)[0]
73
def _get_instance_ips(context, instance):
75
for network in common.get_networks_for_instance(
76
context, instance).values():
77
all_ips = itertools.chain(network["ips"], network["floating_ips"])
78
ret += [ip["address"] for ip in all_ips]
82
context = req.environ["nova.context"]
83
search_opts = dict(deleted=False)
84
if "all_tenants" in req.GET:
85
authorize_all_tenants(context)
88
if context.project_id:
89
search_opts["project_id"] = context.project_id
91
search_opts["user_id"] = context.user_id
93
include = req.GET.get("include", None)
95
include = set(include.split(","))
99
exclude = req.GET.get("exclude", None)
101
exclude = set(exclude.split(","))
105
instance_list = self.compute_api.get_all(
106
context, search_opts=search_opts)
109
instance_projects = {}
111
for instance in instance_list:
112
uuid = instance["uuid"]
113
if uuid in exclude or (include is not None and
114
uuid not in include):
116
ips = [str(ip) for ip in self._get_instance_ips(context, instance)]
117
instance_ips[uuid] = ips
118
instance_projects[uuid] = instance["project_id"]
120
alive_ips = self.fping(ip_list)
122
for instance_uuid, ips in instance_ips.iteritems():
125
"project_id": instance_projects[instance_uuid],
126
"alive": bool(set(ips) & alive_ips),
128
return {"servers": res}
130
def show(self, req, id):
132
context = req.environ["nova.context"]
135
instance = self.compute_api.get(context, id)
136
ips = [str(ip) for ip in self._get_instance_ips(context, instance)]
137
alive_ips = self.fping(ips)
140
"id": instance["uuid"],
141
"project_id": instance["project_id"],
142
"alive": bool(set(ips) & alive_ips),
145
except exception.NotFound:
146
raise exc.HTTPNotFound()
149
class Fping(extensions.ExtensionDescriptor):
150
"""Fping Management Extension."""
154
namespace = "http://docs.openstack.org/compute/ext/fping/api/v1.1"
155
updated = "2012-07-06T00:00:00+00:00"
157
def get_resources(self):
158
res = extensions.ResourceExtension(