Files
masakari-dashboard/masakaridashboard/api/api.py
Kevin Schwerdtfeger 883dc799bf Support region_name option during connection
Attempt to determine the correct regions before making the initial
connection to OpenStack to ensure that the proper endpoints are
selected from the service catalog in a multi-region deployment.

Without this change, the endpoint selected from the service catalog
is based solely on the service type with no regard for region. This may
lead to the wrong endpoint being selected from the catalog.

Change-Id: Ie396b8239df080dcc225dd77204e5f3980cca2a6
2024-07-24 05:38:55 -05:00

220 lines
7.2 KiB
Python

# Copyright (C) 2018 NTT DATA
# All Rights Reserved.
#
# 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 itertools
from django.conf import settings
from django.utils.translation import gettext_lazy as _
from horizon.utils import functions as utils
from horizon.utils import memoized
from keystoneauth1.identity.generic import token
from keystoneauth1 import session as ks_session
from openstack import connection
from openstack_dashboard.api import nova as nova_api
from masakaridashboard.handle_errors import handle_errors
@memoized.memoized
def openstack_connection(request, version=None):
interface = getattr(settings, 'OPENSTACK_ENDPOINT_TYPE', 'publicURL')
region_name = request.COOKIES.get('services_region')
if not region_name:
default_service_regions = getattr(settings,
'DEFAULT_SERVICE_REGIONS',
{})
region_name = default_service_regions.get('*')
auth = token.Token(
auth_url=request.user.endpoint,
token=request.user.token.id,
project_name=request.user.project_name,
project_id=request.user.tenant_id)
cacert = getattr(settings, 'OPENSTACK_SSL_CACERT')
session = ks_session.Session(auth=auth, verify=cacert or True)
conn = connection.Connection(session=session,
interface=interface,
region_name=region_name,
ha_api_version=version)
return conn.instance_ha
def get_compute_service_list(request):
return nova_api.service_list(request, binary="nova-compute")
@handle_errors(_("Unable to retrieve segments"), [])
def get_segment_list(request, marker='', paginate=False, filters=None):
"""Returns segments as per page size."""
page_size = utils.get_page_size(request)
client = openstack_connection(request)
kwargs = get_request_param(marker, paginate, filters, page_size)
entities_iter = client.segments(**kwargs)
has_prev_data = has_more_data = False
if paginate:
entities, has_more_data, has_prev_data = pagination_process(
entities_iter, kwargs['limit'], page_size, marker)
else:
entities = list(entities_iter)
return entities, has_more_data, has_prev_data
def get_request_param(marker, paginate, filters, page_size):
limit = getattr(settings, 'API_RESULT_LIMIT', 100)
if paginate:
request_size = page_size + 1
else:
request_size = limit
kwargs = {"marker": marker,
"limit": request_size
}
if filters is not None:
kwargs.update(filters)
return kwargs
def pagination_process(data, request_size, page_size, marker):
"""Retrieve a listing of specific entity and handles pagination.
:param request: Request data
:param marker: Pagination marker for large data sets: entity id
:param paginate: If true will perform pagination based on settings.
Default:False
"""
prev_data = more_data = False
entities = list(itertools.islice(data, request_size))
# first and middle page condition
if len(entities) > page_size:
entities.pop()
more_data = True
# middle page condition
if marker is not None:
prev_data = True
elif marker is not None:
prev_data = True
return entities, more_data, prev_data
@handle_errors(_("Unable to retrieve segments"), [])
def segment_list(request):
return list(openstack_connection(request).segments())
def segment_create(request, data):
"""Create segment."""
return openstack_connection(request).create_segment(**data)
@handle_errors(_("Unable to retrieve segment"), [])
def get_segment(request, segment_id):
"""Returns segment by id"""
return openstack_connection(request).get_segment(segment_id)
@handle_errors(_("Unable to delete segment"), [])
def segment_delete(request, segment_id, ignore_missing=True):
return openstack_connection(request).delete_segment(
segment_id, ignore_missing)
@handle_errors(_("Unable to update segment"), [])
def segment_update(request, segment_id, fields_to_update):
"""Update segment."""
return openstack_connection(request).update_segment(
segment_id, **fields_to_update)
def create_host(request, data):
"""Create Host."""
attrs = {'name': data['name'],
'reserved': data['reserved'],
'type': data['type'],
'control_attributes': data['control_attributes'],
'on_maintenance': data['on_maintenance']}
return openstack_connection(request).create_host(
data['segment_id'], **attrs)
@handle_errors(_("Unable to get host list"), [])
def get_host_list(request, segment_id, filters):
"""Returns host list."""
return openstack_connection(request).hosts(segment_id, **filters)
def delete_host(request, host_id, segment_id):
return openstack_connection(request).delete_host(
host_id, segment_id, False)
def update_host(request, host_uuid, failover_segment_id, fields_to_update):
return openstack_connection(request).update_host(
host_uuid, failover_segment_id, **fields_to_update)
def get_host(request, host_id, segment_id):
"""return single host """
return openstack_connection(request).get_host(host_id, segment_id)
def notification_list(request, filters=None, marker='', paginate=False):
"""return notifications list """
page_size = utils.get_page_size(request)
kwargs = get_request_param(marker, paginate, filters, page_size)
entities_iter = openstack_connection(request).notifications(**kwargs)
has_prev_data = has_more_data = False
if paginate:
entities, has_more_data, has_prev_data = pagination_process(
entities_iter, kwargs['limit'], page_size, marker)
else:
entities = list(entities_iter)
return entities, has_more_data, has_prev_data
def get_notification_list(request):
"""return notifications list """
return list(openstack_connection(request).notifications())
def get_notification(request, notification_id):
"""return single notifications"""
return openstack_connection(request).get_notification(notification_id)
def get_notification_with_progress_details(request, notification_id):
return openstack_connection(
request, version='1.1').get_notification(
notification_id)
@handle_errors(_("Unable to get vmoves list"), [])
def get_vmoves_list(request, notification_id, filters):
"""return vmoves list """
return openstack_connection(
request, version='1.3').vmoves(notification_id, **filters)
def get_vmove(request, notification_id, vmove_id):
"""return single vmove"""
return openstack_connection(
request, version='1.3').get_vmove(vmove_id, notification_id)