220 lines
7.5 KiB
Python
220 lines
7.5 KiB
Python
# 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 re
|
|
|
|
from django.conf import settings
|
|
from django import shortcuts
|
|
from django.utils.translation import ugettext_lazy as _
|
|
from django.views import generic
|
|
|
|
from openstack_dashboard import api
|
|
from openstack_dashboard.api.rest import utils as rest_utils
|
|
|
|
from horizon import exceptions
|
|
|
|
from gbpui import client
|
|
|
|
from netaddr import IPAddress
|
|
from netaddr import IPNetwork
|
|
|
|
import logging
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
|
|
class PolicyTargets(generic.View):
|
|
# todo: This is a direct port from the old form version; it needs to be
|
|
# tested and revised; It may be dodgy and/or redundant because:
|
|
# 1) The created regex might be nonsenseical (needs testing)
|
|
# 2) The proxy_group_ids might be logical duplication of the third
|
|
# third conditional
|
|
@staticmethod
|
|
def is_proxy_group(policy_target, proxy_group_ids):
|
|
if hasattr(settings, 'GBPUI_HIDE_PTG_NAMES_FROM_MEMBER_CREATE'):
|
|
regex = "(" + ")|(".join(
|
|
settings.GBPUI_HIDE_PTG_NAMES_FROM_MEMBER_CREATE) \
|
|
+ ")"
|
|
|
|
if re.match(regex, policy_target.get('name')):
|
|
return True
|
|
|
|
if policy_target.id in proxy_group_ids:
|
|
return True
|
|
|
|
if policy_target.get('proxied_group_id'):
|
|
return True
|
|
|
|
return False
|
|
|
|
@rest_utils.ajax()
|
|
def get(self, request):
|
|
policy_targets = client.policy_target_list(
|
|
request, tenant_id=request.user.tenant_id
|
|
)
|
|
|
|
proxy_group_ids = [pt.get('proxy_group_id') for pt in policy_targets
|
|
if pt.get('proxy_group_id')]
|
|
|
|
try:
|
|
policy_target_objects = []
|
|
|
|
for policy_target in policy_targets:
|
|
if not self.is_proxy_group(policy_target, proxy_group_ids):
|
|
subnet_objects = []
|
|
|
|
for subnet_id in policy_target.subnets:
|
|
try:
|
|
subnet = api.neutron.subnet_get(request, subnet_id)
|
|
allocation_pool_objects = []
|
|
|
|
allocation_pools = subnet['allocation_pools']
|
|
if allocation_pools:
|
|
for allocation_pool in allocation_pools:
|
|
allocation_pool_object = {
|
|
"start": allocation_pool['start'],
|
|
"end": allocation_pool['end']
|
|
}
|
|
allocation_pool_objects.append(
|
|
allocation_pool_object)
|
|
|
|
subnet_object = {
|
|
"cidr": subnet['cidr'],
|
|
"allocation_pools": allocation_pool_objects
|
|
}
|
|
subnet_objects.append(subnet_object)
|
|
except Exception:
|
|
LOG.exception("Unable to retrieve subnet.")
|
|
|
|
policy_target_object = {
|
|
"id": policy_target.id,
|
|
"name_or_id": policy_target.name_or_id,
|
|
"subnets": subnet_objects
|
|
}
|
|
policy_target_objects.append(policy_target_object)
|
|
|
|
return rest_utils.JSONResponse(policy_target_objects)
|
|
except Exception:
|
|
msg = _("Failed to retrieve groups")
|
|
LOG.error(msg)
|
|
exceptions.handle(request, msg, redirect=shortcuts.redirect)
|
|
|
|
|
|
class Members(generic.View):
|
|
optional_arguments = [
|
|
'block_device_mapping',
|
|
'block_device_mapping_v2',
|
|
'availability_zone',
|
|
'admin_pass', 'disk_config',
|
|
'config_drive'
|
|
]
|
|
|
|
@rest_utils.ajax()
|
|
def post(self, request):
|
|
instance_count = request.DATA['instance_count']
|
|
|
|
try:
|
|
if instance_count == 1:
|
|
self.create_instance(request)
|
|
elif instance_count > 1:
|
|
for i in range(0, instance_count):
|
|
self.create_instance(request, "_" + str(i))
|
|
|
|
except Exception:
|
|
instance_name = request.DATA['name']
|
|
|
|
error = _("Unable to launch member %(count)s with name %(name)s")
|
|
message = error % {
|
|
'count': instance_count,
|
|
'name': instance_name
|
|
}
|
|
LOG.exception(message)
|
|
|
|
raise rest_utils.AjaxError(400, message)
|
|
|
|
return rest_utils.CreatedResponse('/api/nova/servers/%s')
|
|
|
|
def create_instance(self, request, suffix=""):
|
|
# Instances need to be created one by one, because each instance
|
|
# needs to have it's own GBP port
|
|
kw = {
|
|
'instance_count': 1
|
|
}
|
|
|
|
# Mandatory creation arguments and port creation
|
|
try:
|
|
instance_name = request.DATA['name'] + suffix
|
|
|
|
meta_data, nics = self.create_ports(request, instance_name)
|
|
|
|
kw['meta'] = meta_data
|
|
kw['nics'] = nics
|
|
|
|
args = (
|
|
request,
|
|
instance_name,
|
|
request.DATA['source_id'],
|
|
request.DATA['flavor_id'],
|
|
request.DATA['key_name'],
|
|
request.DATA['user_data'],
|
|
request.DATA['security_groups'],
|
|
)
|
|
|
|
except KeyError as e:
|
|
raise rest_utils.AjaxError(400, 'Missing required parameter '
|
|
"'%s'" % e.args[0])
|
|
|
|
# Optional creation arguments
|
|
for name in self.optional_arguments:
|
|
if name in request.DATA:
|
|
kw[name] = request.DATA[name]
|
|
|
|
return api.nova.server_create(*args, **kw)
|
|
|
|
# 1) Missing request.DATA entries get propagated to 'create_instance' as
|
|
# KeyError
|
|
# 2) All other errors are propagated to 'post' as generic failure Exception
|
|
@staticmethod
|
|
def create_ports(request, instance_name):
|
|
nics = []
|
|
pts = []
|
|
|
|
for policy_target_id in request.DATA["group_policy_targets"]:
|
|
policy_target = client.policy_target_get(request,
|
|
policy_target_id['id'])
|
|
|
|
args = {
|
|
'policy_target_group_id': policy_target.id,
|
|
'name': instance_name[:41] + "_gbpui"
|
|
}
|
|
|
|
for subnet_id in policy_target.subnets:
|
|
subnet = api.neutron.subnet_get(request, subnet_id)
|
|
|
|
if 'fixed_ip' in policy_target_id and IPAddress(
|
|
policy_target_id['fixed_ip']) in \
|
|
IPNetwork(subnet['cidr']):
|
|
args['fixed_ips'] = [{
|
|
'subnet_id': subnet['id'],
|
|
'ip_address': policy_target_id['fixed_ip']
|
|
}]
|
|
|
|
port = client.pt_create(request, **args)
|
|
|
|
nics.append({
|
|
'port-id': port.port_id
|
|
})
|
|
pts.append(port.id)
|
|
|
|
meta_data = {'pts': ','.join(pts)}
|
|
|
|
return meta_data, nics
|