gce-api/gceapi/api/instance_address_api.py
Andrey Pavlov 75905790e5 update gce api to current OpenStack
- add devstack plugin
- update openstack common
- move unit tests to unit folder
- update infrastructural files

Change-Id: Id72006f70110dbd1762f42b582470ac5f3439f2a
2015-09-03 17:16:30 +03:00

164 lines
5.9 KiB
Python

# Copyright 2014
# The Cloudscaling Group, Inc.
#
# 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.
from oslo_log import log as logging
from gceapi.api import base_api
from gceapi.api import clients
from gceapi.api import operation_util
from gceapi import exception
from gceapi.i18n import _
LOG = logging.getLogger(__name__)
class API(base_api.API):
"""GCE Access config API."""
KIND = "access_config"
PERSISTENT_ATTRIBUTES = ["id", "instance_name",
"nic", "name", "type", "addr"]
DEFAULT_ACCESS_CONFIG_TYPE = "ONE_TO_ONE_NAT"
DEFAULT_ACCESS_CONFIG_NAME = "External NAT"
def __init__(self, *args, **kwargs):
super(API, self).__init__(*args, **kwargs)
def _get_type(self):
return self.KIND
def _get_persistent_attributes(self):
return self.PERSISTENT_ATTRIBUTES
def get_item(self, context, instance_name, name):
items = self._get_db_items(context)
items = [i for i in items
if i["instance_name"] == instance_name and i["name"] == name]
if len(items) != 1:
raise exception.NotFound
return items[0]
def get_items(self, context, instance_name):
items = self._get_db_items(context)
return [i for i in items if i["instance_name"] == instance_name]
def add_item(self, context, instance_name, nic, addr, addr_type, name):
if not nic:
msg = _("Network interface is invalid or empty")
raise exception.InvalidRequest(msg)
if addr_type is None:
addr_type = self.DEFAULT_ACCESS_CONFIG_TYPE
elif addr_type != self.DEFAULT_ACCESS_CONFIG_TYPE:
msg = _("Only '%s' type of access config currently supported.")\
% self.DEFAULT_ACCESS_CONFIG_TYPE
raise exception.InvalidRequest(msg)
client = clients.nova(context)
instances = client.servers.list(search_opts={"name": instance_name})
if not instances or len(instances) != 1:
raise exception.NotFound
instance = instances[0]
fixed_ip = None
for network in instance.addresses:
if nic != network:
continue
for address in instance.addresses[network]:
atype = address["OS-EXT-IPS:type"]
if atype == "floating":
msg = _('At most one access config currently supported.')
raise exception.InvalidRequest(msg)
if atype == "fixed":
fixed_ip = address["addr"]
if not fixed_ip:
msg = _('Network interface not found')
raise exception.InvalidRequest(msg)
floating_ips = client.floating_ips.list()
if addr is None:
# NOTE(apavlov): try to find unused
for floating_ip in floating_ips:
if floating_ip.instance_id is None:
addr = floating_ip.ip
break
else:
msg = _('There is no unused floating ips.')
raise exception.InvalidRequest(msg)
else:
for floating_ip in floating_ips:
if floating_ip.ip != addr:
continue
if floating_ip.instance_id is None:
break
msg = _("Floating ip '%s' is already associated") % floating_ip
raise exception.InvalidRequest(msg)
else:
msg = _("There is no such floating ip '%s'.") % addr
raise exception.InvalidRequest(msg)
operation_util.start_operation(context)
instance.add_floating_ip(addr, fixed_ip)
return self.register_item(context, instance_name,
nic, addr, addr_type, name)
def register_item(self, context, instance_name,
nic, addr, addr_type, name):
if not nic:
msg = _("Network interface is invalid or empty")
raise exception.InvalidRequest(msg)
if addr_type is None:
addr_type = self.DEFAULT_ACCESS_CONFIG_TYPE
elif addr_type != self.DEFAULT_ACCESS_CONFIG_TYPE:
msg = _("Only '%s' type of access config currently supported.")\
% self.DEFAULT_ACCESS_CONFIG_TYPE
raise exception.InvalidRequest(msg)
if name is None:
name = self.DEFAULT_ACCESS_CONFIG_NAME
if not addr:
msg = _("There is no address to assign.")
raise exception.InvalidRequest(msg)
new_item = {
"id": instance_name + "-" + addr,
"instance_name": instance_name,
"nic": nic,
"name": name,
"type": addr_type,
"addr": addr
}
new_item = self._add_db_item(context, new_item)
return new_item
def delete_item(self, context, instance_name, name):
client = clients.nova(context)
instances = client.servers.list(search_opts={"name": instance_name})
if not instances or len(instances) != 1:
raise exception.NotFound
instance = instances[0]
item = self.get_item(context, instance_name, name)
floating_ip = item["addr"]
operation_util.start_operation(context)
instance.remove_floating_ip(floating_ip)
self._delete_db_item(context, item)
def unregister_item(self, context, instance_name, name):
item = self.get_item(context, instance_name, name)
self._delete_db_item(context, item)