
- add devstack plugin - update openstack common - move unit tests to unit folder - update infrastructural files Change-Id: Id72006f70110dbd1762f42b582470ac5f3439f2a
164 lines
5.9 KiB
Python
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)
|