15
15
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16
16
# License for the specific language governing permissions and limitations
17
17
# under the License
20
from nova import compute
20
21
from nova import exception
22
from nova import log as logging
21
23
from nova import network
22
24
from nova import rpc
23
25
from nova.api.openstack import faults
24
26
from nova.api.openstack import extensions
29
LOG = logging.getLogger('nova.api.openstack.contrib.floating_ips')
27
32
def _translate_floating_ip_view(floating_ip):
28
33
result = {'id': floating_ip['id'],
29
34
'ip': floating_ip['address']}
30
if 'fixed_ip' in floating_ip:
31
36
result['fixed_ip'] = floating_ip['fixed_ip']['address']
37
except (TypeError, KeyError):
33
38
result['fixed_ip'] = None
34
39
if 'instance' in floating_ip:
35
40
result['instance_id'] = floating_ip['instance']['id']
41
46
def _translate_floating_ips_view(floating_ips):
42
return {'floating_ips': [_translate_floating_ip_view(floating_ip)
43
for floating_ip in floating_ips]}
47
return {'floating_ips': [_translate_floating_ip_view(ip)['floating_ip']
48
for ip in floating_ips]}
46
51
class FloatingIPController(object):
68
73
floating_ip = self.network_api.get_floating_ip(context, id)
69
74
except exception.NotFound:
70
return faults.Fault(exc.HTTPNotFound())
75
return faults.Fault(webob.exc.HTTPNotFound())
72
77
return _translate_floating_ip_view(floating_ip)
74
79
def index(self, req):
75
80
context = req.environ['nova.context']
77
floating_ips = self.network_api.list_floating_ips(context)
83
# FIXME(ja) - why does self.network_api.list_floating_ips raise?
84
floating_ips = self.network_api.list_floating_ips(context)
85
except exception.FloatingIpNotFoundForProject:
79
88
return _translate_floating_ips_view(floating_ips)
81
def create(self, req):
90
def create(self, req, body=None):
82
91
context = req.environ['nova.context']
94
return {'allocated': {
96
"floating_ip": ip['address']}}
103
return _translate_floating_ip_view(ip)
98
105
def delete(self, req, id):
99
106
context = req.environ['nova.context']
101
ip = self.network_api.get_floating_ip(context, id)
102
self.network_api.release_floating_ip(context, address=ip)
104
return {'released': {
106
"floating_ip": ip['address']}}
108
def associate(self, req, id, body):
109
""" /floating_ips/{id}/associate fixed ip in body """
110
context = req.environ['nova.context']
111
floating_ip = self._get_ip_by_id(context, id)
113
fixed_ip = body['associate_address']['fixed_ip']
116
self.network_api.associate_floating_ip(context,
117
floating_ip, fixed_ip)
118
except rpc.RemoteError:
121
return {'associated':
123
"floating_ip_id": id,
124
"floating_ip": floating_ip,
125
"fixed_ip": fixed_ip}}
127
def disassociate(self, req, id):
128
""" POST /floating_ips/{id}/disassociate """
129
context = req.environ['nova.context']
130
107
floating_ip = self.network_api.get_floating_ip(context, id)
131
address = floating_ip['address']
132
fixed_ip = floating_ip['fixed_ip']['address']
135
self.network_api.disassociate_floating_ip(context, address)
136
except rpc.RemoteError:
139
return {'disassociated': {'floating_ip': address,
140
'fixed_ip': fixed_ip}}
109
if 'fixed_ip' in floating_ip:
110
self.network_api.disassociate_floating_ip(context,
111
floating_ip['address'])
113
self.network_api.release_floating_ip(context,
114
address=floating_ip['address'])
115
return webob.exc.HTTPAccepted()
142
117
def _get_ip_by_id(self, context, value):
143
118
"""Checks that value is id and then returns its address."""
147
122
class Floating_ips(extensions.ExtensionDescriptor):
124
self.compute_api = compute.API()
125
self.network_api = network.API()
126
super(Floating_ips, self).__init__()
128
def _add_floating_ip(self, input_dict, req, instance_id):
129
"""Associate floating_ip to an instance."""
130
context = req.environ['nova.context']
133
address = input_dict['addFloatingIp']['address']
135
msg = _("Missing parameter dict")
136
raise webob.exc.HTTPBadRequest(explanation=msg)
138
msg = _("Address not specified")
139
raise webob.exc.HTTPBadRequest(explanation=msg)
141
self.compute_api.associate_floating_ip(context, instance_id, address)
143
return webob.Response(status_int=202)
145
def _remove_floating_ip(self, input_dict, req, instance_id):
146
"""Dissociate floating_ip from an instance."""
147
context = req.environ['nova.context']
150
address = input_dict['removeFloatingIp']['address']
152
msg = _("Missing parameter dict")
153
raise webob.exc.HTTPBadRequest(explanation=msg)
155
msg = _("Address not specified")
156
raise webob.exc.HTTPBadRequest(explanation=msg)
158
floating_ip = self.network_api.get_floating_ip_by_ip(context, address)
159
if 'fixed_ip' in floating_ip:
160
self.network_api.disassociate_floating_ip(context, address)
162
return webob.Response(status_int=202)
148
164
def get_name(self):
149
165
return "Floating_ips"
166
182
res = extensions.ResourceExtension('os-floating-ips',
167
183
FloatingIPController(),
170
'disassociate': 'POST'})
171
185
resources.append(res)
189
def get_actions(self):
190
"""Return the actions the extension adds, as required by contract."""
192
extensions.ActionExtension("servers", "addFloatingIp",
193
self._add_floating_ip),
194
extensions.ActionExtension("servers", "removeFloatingIp",
195
self._remove_floating_ip),