From d49b14ac019995ca7443646157533afae5ea054d Mon Sep 17 00:00:00 2001 From: Michael Johnson Date: Thu, 31 Aug 2017 17:19:51 -0700 Subject: [PATCH] Convert octavia-dashboard to use Octavia v2 API This patch coverts the Octavia dasboard over to use the openstack SDK and the new Octavia v2 API. It's octavia-dashboard, now with less neutron-lbaas (ok, no neutron-lbaas) Change-Id: I71fd67128210c3ff365838414920a1de1883ebd2 --- octavia_dashboard/api/rest/lbaasv2.py | 414 ++++++++++-------- .../locale/de/LC_MESSAGES/djangojs.po | 4 +- .../locale/id/LC_MESSAGES/djangojs.po | 4 +- .../locale/ja/LC_MESSAGES/djangojs.po | 4 +- .../locale/ru/LC_MESSAGES/djangojs.po | 4 +- .../locale/zh_CN/LC_MESSAGES/djangojs.po | 4 +- .../openstack-service-api/lbaasv2.service.js | 16 - .../lbaasv2.service.spec.js | 7 - .../actions/create/create.action.service.js | 2 +- .../create/create.action.service.spec.js | 2 +- .../lbaasv2/healthmonitors/detail.html | 4 +- .../project/lbaasv2/listeners/detail.html | 4 +- .../lbaasv2/members/detail.controller.js | 15 +- .../lbaasv2/members/detail.controller.spec.js | 10 +- .../project/lbaasv2/members/detail.html | 4 +- .../lbaasv2/members/members.service.js | 92 ---- .../lbaasv2/members/members.service.spec.js | 107 ----- .../lbaasv2/members/table.controller.js | 11 +- .../lbaasv2/members/table.controller.spec.js | 10 +- .../project/lbaasv2/pools/detail.html | 10 +- requirements.txt | 1 + 21 files changed, 252 insertions(+), 477 deletions(-) delete mode 100644 octavia_dashboard/static/dashboard/project/lbaasv2/members/members.service.js delete mode 100644 octavia_dashboard/static/dashboard/project/lbaasv2/members/members.service.spec.js diff --git a/octavia_dashboard/api/rest/lbaasv2.py b/octavia_dashboard/api/rest/lbaasv2.py index 819bc627..c1cd4297 100644 --- a/octavia_dashboard/api/rest/lbaasv2.py +++ b/octavia_dashboard/api/rest/lbaasv2.py @@ -17,9 +17,12 @@ from six.moves import _thread as thread from time import sleep +from django.conf import settings from django.views import generic from horizon import conf +from openstack import connection +from openstack import profile from openstack_dashboard.api import neutron from openstack_dashboard.api.rest import urls @@ -28,6 +31,54 @@ from openstack_dashboard.api.rest import utils as rest_utils neutronclient = neutron.neutronclient +def _get_sdk_connection(request): + """Creates an SDK connection based on the request. + + :param request: Django request object + :returns: SDK connection object + """ + prof = profile.Profile() + prof.set_region(profile.Profile.ALL, request.user.services_region) + + insecure = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False) + cacert = getattr(settings, 'OPENSTACK_SSL_CACERT', None) + return connection.Connection(profile=prof, + verify=insecure, + cert=cacert, + user_agent='octavia-dashboard', + auth_plugin='token', + project_id=request.user.project_id, + default_domain_id=request.user.domain_id, + token=request.user.token.unscoped_token, + auth_url=request.user.endpoint) + + +def _sdk_object_to_list(object): + """Converts an SDK generator object to a list of dictionaries. + + :param object: SDK generator object + :returns: List of dictionaries + """ + result_list = [] + for item in object: + result_list.append(_get_sdk_object_dict(item)) + return result_list + + +def _get_sdk_object_dict(object): + """Converts an SDK object to a dictionary. + + Fixes any SDK imposed object oddities. + + :param object: SDK object + :returns: Dictionary + """ + item_dict = object.to_dict() + if 'is_admin_state_up' in item_dict: + item_dict['admin_state_up'] = item_dict['is_admin_state_up'] + return item_dict + + def poll_loadbalancer_status(request, loadbalancer_id, callback, from_state='PENDING_UPDATE', to_state='ACTIVE', callback_kwargs=None): @@ -47,9 +98,9 @@ def poll_loadbalancer_status(request, loadbalancer_id, callback, status = from_state while status == from_state: sleep(interval) - lb = neutronclient(request).show_loadbalancer( - loadbalancer_id).get('loadbalancer') - status = lb['provisioning_status'] + conn = _get_sdk_connection(request) + lb = conn.load_balancer.get_load_balancer(loadbalancer_id) + status = lb.provisioning_status if status == to_state: kwargs = {'loadbalancer_id': loadbalancer_id} @@ -60,27 +111,26 @@ def poll_loadbalancer_status(request, loadbalancer_id, callback, def create_loadbalancer(request): data = request.DATA - spec = { - 'vip_subnet_id': data['loadbalancer']['subnet'] - } - if data['loadbalancer'].get('name'): - spec['name'] = data['loadbalancer']['name'] - if data['loadbalancer'].get('description'): - spec['description'] = data['loadbalancer']['description'] - if data['loadbalancer'].get('ip'): - spec['vip_address'] = data['loadbalancer']['ip'] - loadbalancer = neutronclient(request).create_loadbalancer( - {'loadbalancer': spec}).get('loadbalancer') + + conn = _get_sdk_connection(request) + loadbalancer = conn.load_balancer.create_load_balancer( + project_id=request.user.project_id, + vip_subnet_id=data['loadbalancer']['subnet'], + name=data['loadbalancer'].get('name'), + description=data['loadbalancer'].get('description'), + vip_address=data['loadbalancer'].get('ip')) + if data.get('listener'): # There is work underway to add a new API to LBaaS v2 that will # allow us to pass in all information at once. Until that is # available we use a separate thread to poll for the load # balancer status and create the other resources when it becomes # active. - args = (request, loadbalancer['id'], create_listener) + args = (request, loadbalancer.id, create_listener) kwargs = {'from_state': 'PENDING_CREATE'} thread.start_new_thread(poll_loadbalancer_status, args, kwargs) - return loadbalancer + + return _get_sdk_object_dict(loadbalancer) def create_listener(request, **kwargs): @@ -88,28 +138,30 @@ def create_listener(request, **kwargs): """ data = request.DATA - listenerSpec = { - 'protocol': data['listener']['protocol'], - 'protocol_port': data['listener']['port'], - 'loadbalancer_id': kwargs['loadbalancer_id'] - } - if data['listener'].get('name'): - listenerSpec['name'] = data['listener']['name'] - if data['listener'].get('description'): - listenerSpec['description'] = data['listener']['description'] - if data.get('certificates'): - listenerSpec['default_tls_container_ref'] = data['certificates'][0] - listenerSpec['sni_container_refs'] = data['certificates'] - listener = neutronclient(request).create_listener( - {'listener': listenerSpec}).get('listener') + try: + default_tls_ref = data['certificates'][0] + except (KeyError, IndexError): + default_tls_ref = None + + conn = _get_sdk_connection(request) + # TODO(johnsom) Add SNI support + # https://bugs.launchpad.net/octavia/+bug/1714294 + listener = conn.load_balancer.create_listener( + protocol=data['listener']['protocol'], + protocol_port=data['listener']['port'], + load_balancer_id=kwargs['loadbalancer_id'], + name=data['listener'].get('name'), + description=data['listener'].get('description'), + default_tls_container_ref=default_tls_ref, + sni_container_refs=None) if data.get('pool'): args = (request, kwargs['loadbalancer_id'], create_pool) - kwargs = {'callback_kwargs': {'listener_id': listener['id']}} + kwargs = {'callback_kwargs': {'listener_id': listener.id}} thread.start_new_thread(poll_loadbalancer_status, args, kwargs) - return listener + return _get_sdk_object_dict(listener) def create_pool(request, **kwargs): @@ -117,29 +169,26 @@ def create_pool(request, **kwargs): """ data = request.DATA - poolSpec = { - 'protocol': data['pool']['protocol'], - 'lb_algorithm': data['pool']['method'], - 'listener_id': kwargs['listener_id'] - } - if data['pool'].get('name'): - poolSpec['name'] = data['pool']['name'] - if data['pool'].get('description'): - poolSpec['description'] = data['pool']['description'] - pool = neutronclient(request).create_lbaas_pool( - {'pool': poolSpec}).get('pool') + + conn = _get_sdk_connection(request) + pool = conn.load_balancer.create_pool( + protocol=data['pool']['protocol'], + lb_algorithm=data['pool']['method'], + listener_id=kwargs['listener_id'], + name=data['pool'].get('name'), + description=data['pool'].get('description')) if data.get('members'): args = (request, kwargs['loadbalancer_id'], add_member) - kwargs = {'callback_kwargs': {'pool_id': pool['id'], + kwargs = {'callback_kwargs': {'pool_id': pool.id, 'index': 0}} thread.start_new_thread(poll_loadbalancer_status, args, kwargs) elif data.get('monitor'): args = (request, kwargs['loadbalancer_id'], create_health_monitor) - kwargs = {'callback_kwargs': {'pool_id': pool['id']}} + kwargs = {'callback_kwargs': {'pool_id': pool.id}} thread.start_new_thread(poll_loadbalancer_status, args, kwargs) - return pool + return _get_sdk_object_dict(pool) def create_health_monitor(request, **kwargs): @@ -147,21 +196,19 @@ def create_health_monitor(request, **kwargs): """ data = request.DATA - monitorSpec = { - 'type': data['monitor']['type'], - 'delay': data['monitor']['interval'], - 'timeout': data['monitor']['timeout'], - 'max_retries': data['monitor']['retry'], - 'pool_id': kwargs['pool_id'] - } - if data['monitor'].get('method'): - monitorSpec['http_method'] = data['monitor']['method'] - if data['monitor'].get('path'): - monitorSpec['url_path'] = data['monitor']['path'] - if data['monitor'].get('status'): - monitorSpec['expected_codes'] = data['monitor']['status'] - return neutronclient(request).create_lbaas_healthmonitor( - {'healthmonitor': monitorSpec}).get('healthmonitor') + + conn = _get_sdk_connection(request) + health_mon = conn.load_balancer.create_health_monitor( + type=data['monitor']['type'], + delay=data['monitor']['interval'], + timeout=data['monitor']['timeout'], + max_retries=data['monitor']['retry'], + pool_id=kwargs['pool_id'], + http_method=data['monitor'].get('method'), + url_path=data['monitor'].get('path'), + expected_codes=data['monitor'].get('status')) + + return _get_sdk_object_dict(health_mon) def add_member(request, **kwargs): @@ -182,16 +229,14 @@ def add_member(request, **kwargs): loadbalancer_id = kwargs.get('loadbalancer_id') member = members[index] - memberSpec = { - 'address': member['address'], - 'protocol_port': member['port'], - 'subnet_id': member['subnet'] - } - if member.get('weight'): - memberSpec['weight'] = member['weight'] - member = neutronclient(request).create_lbaas_member( - pool_id, {'member': memberSpec}).get('member') + conn = _get_sdk_connection(request) + member = conn.load_balancer.create_member( + pool_id, + address=member['address'], + protocol_port=member['port'], + subnet_id=member['subnet'], + weight=member.get('weight')) index += 1 if kwargs.get('members_to_add'): @@ -214,7 +259,7 @@ def add_member(request, **kwargs): kwargs = {'callback_kwargs': {'pool_id': pool_id}} thread.start_new_thread(poll_loadbalancer_status, args, kwargs) - return member + return _get_sdk_object_dict(member) def remove_member(request, **kwargs): @@ -229,7 +274,9 @@ def remove_member(request, **kwargs): members_to_delete = kwargs['members_to_delete'] member_id = members_to_delete.pop(0) - neutronclient(request).delete_lbaas_member(member_id, pool_id) + conn = _get_sdk_connection(request) + conn.load_balancer.delete_member(member_id, pool_id, + ignore_missing=True) args = (request, loadbalancer_id, update_member_list) kwargs = {'callback_kwargs': { @@ -244,15 +291,15 @@ def update_loadbalancer(request, **kwargs): """ data = request.DATA - spec = {} loadbalancer_id = kwargs.get('loadbalancer_id') - if data['loadbalancer'].get('name'): - spec['name'] = data['loadbalancer']['name'] - if data['loadbalancer'].get('description'): - spec['description'] = data['loadbalancer']['description'] - return neutronclient(request).update_loadbalancer( - loadbalancer_id, {'loadbalancer': spec}).get('loadbalancer') + conn = _get_sdk_connection(request) + loadbalancer = conn.load_balancer.update_load_balancer( + loadbalancer_id, + name=data['loadbalancer'].get('name'), + description=data['loadbalancer'].get('description')) + + return _get_sdk_object_dict(loadbalancer) def update_listener(request, **kwargs): @@ -260,23 +307,20 @@ def update_listener(request, **kwargs): """ data = request.DATA - listener_spec = {} listener_id = data['listener'].get('id') loadbalancer_id = data.get('loadbalancer_id') - if data['listener'].get('name'): - listener_spec['name'] = data['listener']['name'] - if data['listener'].get('description'): - listener_spec['description'] = data['listener']['description'] - - listener = neutronclient(request).update_listener( - listener_id, {'listener': listener_spec}).get('listener') + conn = _get_sdk_connection(request) + listener = conn.load_balancer.update_listener( + listener=listener_id, + name=data['listener'].get('name'), + description=data['listener'].get('description')) if data.get('pool'): args = (request, loadbalancer_id, update_pool) thread.start_new_thread(poll_loadbalancer_status, args) - return listener + return _get_sdk_object_dict(listener) def update_pool(request, **kwargs): @@ -284,23 +328,20 @@ def update_pool(request, **kwargs): """ data = request.DATA - pool_spec = {} pool_id = data['pool'].get('id') loadbalancer_id = data.get('loadbalancer_id') - if data['pool'].get('name'): - pool_spec['name'] = data['pool']['name'] - if data['pool'].get('description'): - pool_spec['description'] = data['pool']['description'] - - pools = neutronclient(request).update_lbaas_pool( - pool_id, {'pool': pool_spec}).get('pools') + conn = _get_sdk_connection(request) + pool = conn.load_balancer.update_pool( + pool=pool_id, + name=data['pool'].get('name'), + description=data['pool'].get('description')) # Assemble the lists of member id's to add and remove, if any exist - tenant_id = request.user.project_id request_member_data = data.get('members', []) - existing_members = neutronclient(request).list_lbaas_members( - pool_id, tenant_id=tenant_id).get('members') + + existing_members = _sdk_object_to_list(conn.load_balancer.members(pool_id)) + (members_to_add, members_to_delete) = get_members_to_add_remove( request_member_data, existing_members) @@ -315,7 +356,7 @@ def update_pool(request, **kwargs): args = (request, loadbalancer_id, update_monitor) thread.start_new_thread(poll_loadbalancer_status, args) - return pools + return _get_sdk_object_dict(pool) def update_monitor(request, **kwargs): @@ -323,26 +364,19 @@ def update_monitor(request, **kwargs): """ data = request.DATA - monitor_spec = {} monitor_id = data['monitor']['id'] - if data['monitor'].get('interval'): - monitor_spec['delay'] = data['monitor']['interval'] - if data['monitor'].get('timeout'): - monitor_spec['timeout'] = data['monitor']['timeout'] - if data['monitor'].get('retry'): - monitor_spec['max_retries'] = data['monitor']['retry'] - if data['monitor'].get('method'): - monitor_spec['http_method'] = data['monitor']['method'] - if data['monitor'].get('path'): - monitor_spec['url_path'] = data['monitor']['path'] - if data['monitor'].get('status'): - monitor_spec['expected_codes'] = data['monitor']['status'] + conn = _get_sdk_connection(request) + healthmonitor = conn.load_balancer.update_health_monitor( + monitor_id, + delay=data['monitor'].get('interval'), + timeout=data['monitor'].get('timeout'), + max_retries=data['monitor'].get('timeout'), + http_method=data['monitor'].get('method'), + url_path=data['monitor'].get('path'), + expected_codes=data['monitor'].get('status')) - healthmonitor = neutronclient(request).update_lbaas_healthmonitor( - monitor_id, {'healthmonitor': monitor_spec}).get('healthmonitor') - - return healthmonitor + return _get_sdk_object_dict(healthmonitor) def update_member_list(request, **kwargs): @@ -411,12 +445,12 @@ class LoadBalancers(generic.View): The listing result is an object with property "items". """ - tenant_id = request.user.project_id - loadbalancers = neutronclient(request).list_loadbalancers( - tenant_id=tenant_id).get('loadbalancers') + conn = _get_sdk_connection(request) + lb_list = _sdk_object_to_list(conn.load_balancer.load_balancers( + project_id=request.user.project_id)) if request.GET.get('full') and neutron.floating_ip_supported(request): - add_floating_ip_info(request, loadbalancers) - return {'items': loadbalancers} + add_floating_ip_info(request, lb_list) + return {'items': lb_list} @rest_utils.ajax() def post(self, request): @@ -428,23 +462,6 @@ class LoadBalancers(generic.View): return create_loadbalancer(request) -@urls.register -class LoadBalancerStatusTree(generic.View): - """API for retrieving the resource status tree for a single load balancer. - - """ - url_regex = r'lbaas/loadbalancers/(?P[^/]+)/statuses/$' - - @rest_utils.ajax() - def get(self, request, loadbalancer_id): - """Get the status tree for a specific load balancer. - - http://localhost/api/lbaas/loadbalancers/cc758c90-3d98-4ea1-af44-aab405c9c915/statuses - """ - return neutronclient(request).retrieve_loadbalancer_status( - loadbalancer_id) - - @urls.register class LoadBalancer(generic.View): """API for retrieving, updating, and deleting a single load balancer. @@ -458,11 +475,12 @@ class LoadBalancer(generic.View): http://localhost/api/lbaas/loadbalancers/cc758c90-3d98-4ea1-af44-aab405c9c915 """ - loadbalancer = neutronclient(request).show_loadbalancer( - loadbalancer_id).get('loadbalancer') + conn = _get_sdk_connection(request) + loadbalancer = conn.load_balancer.find_load_balancer(loadbalancer_id) + loadbalancer_dict = _get_sdk_object_dict(loadbalancer) if request.GET.get('full') and neutron.floating_ip_supported(request): - add_floating_ip_info(request, [loadbalancer]) - return loadbalancer + add_floating_ip_info(request, [loadbalancer_dict]) + return loadbalancer_dict @rest_utils.ajax() def put(self, request, loadbalancer_id): @@ -478,7 +496,9 @@ class LoadBalancer(generic.View): http://localhost/api/lbaas/loadbalancers/cc758c90-3d98-4ea1-af44-aab405c9c915 """ - neutronclient(request).delete_loadbalancer(loadbalancer_id) + conn = _get_sdk_connection(request) + conn.load_balancer.delete_load_balancer(loadbalancer_id, + ignore_missing=True) @urls.register @@ -495,9 +515,10 @@ class Listeners(generic.View): The listing result is an object with property "items". """ loadbalancer_id = request.GET.get('loadbalancerId') - tenant_id = request.user.project_id - result = neutronclient(request).list_listeners(tenant_id=tenant_id) - listener_list = result.get('listeners') + conn = _get_sdk_connection(request) + listener_list = _sdk_object_to_list(conn.load_balancer.listeners( + project_id=request.user.project_id)) + if loadbalancer_id: listener_list = self._filter_listeners(listener_list, loadbalancer_id) @@ -517,7 +538,7 @@ class Listeners(generic.View): filtered_listeners = [] for listener in listener_list: - if listener['loadbalancers'][0]['id'] == loadbalancer_id: + if listener['load_balancers'][0]['id'] == loadbalancer_id: filtered_listeners.append(listener) return filtered_listeners @@ -540,8 +561,9 @@ class Listener(generic.View): http://localhost/api/lbaas/listeners/cc758c90-3d98-4ea1-af44-aab405c9c915 """ - listener = neutronclient(request).show_listener( - listener_id).get('listener') + conn = _get_sdk_connection(request) + listener = conn.load_balancer.find_listener(listener_id) + listener = _get_sdk_object_dict(listener) if request.GET.get('includeChildResources'): resources = {} @@ -549,20 +571,20 @@ class Listener(generic.View): if listener.get('default_pool_id'): pool_id = listener['default_pool_id'] - pool = neutronclient(request).show_lbaas_pool( - pool_id).get('pool') + pool = conn.load_balancer.find_pool(pool_id) + pool = _get_sdk_object_dict(pool) resources['pool'] = pool if pool.get('members'): - tenant_id = request.user.project_id - members = neutronclient(request).list_lbaas_members( - pool_id, tenant_id=tenant_id).get('members') - resources['members'] = members + member_list = _sdk_object_to_list( + conn.load_balancer.members(pool_id)) + resources['members'] = member_list - if pool.get('healthmonitor_id'): - monitor_id = pool['healthmonitor_id'] - monitor = neutronclient(request).show_lbaas_healthmonitor( - monitor_id).get('healthmonitor') + if pool.get('healt_hmonitor_id'): + monitor_id = pool['health_monitor_id'] + monitor = conn.load_balancer.find_health_monitor( + monitor_id) + monitor = _get_sdk_object_dict(monitor) resources['monitor'] = monitor return resources @@ -583,7 +605,8 @@ class Listener(generic.View): http://localhost/api/lbaas/listeners/cc758c90-3d98-4ea1-af44-aab405c9c915 """ - neutronclient(request).delete_listener(listener_id) + conn = _get_sdk_connection(request) + conn.load_balancer.delete_listener(listener_id, ignore_missing=True) @urls.register @@ -622,22 +645,24 @@ class Pool(generic.View): http://localhost/api/lbaas/pools/cc758c90-3d98-4ea1-af44-aab405c9c915 """ - pool = neutronclient(request).show_lbaas_pool(pool_id).get('pool') + conn = _get_sdk_connection(request) + pool = conn.load_balancer.find_pool(pool_id) + pool = _get_sdk_object_dict(pool) if request.GET.get('includeChildResources'): resources = {} resources['pool'] = pool if pool.get('members'): - tenant_id = request.user.project_id - members = neutronclient(request).list_lbaas_members( - pool_id, tenant_id=tenant_id).get('members') - resources['members'] = members + member_list = _sdk_object_to_list( + conn.load_balancer.members(pool_id)) + resources['members'] = member_list - if pool.get('healthmonitor_id'): - monitor_id = pool['healthmonitor_id'] - monitor = neutronclient(request).show_lbaas_healthmonitor( - monitor_id).get('healthmonitor') + if pool.get('health_monitor_id'): + monitor_id = pool['health_monitor_id'] + monitor = conn.load_balancer.find_health_monitor( + monitor_id) + monitor = _get_sdk_object_dict(monitor) resources['monitor'] = monitor return resources @@ -658,7 +683,8 @@ class Pool(generic.View): http://localhost/api/lbaas/pools/cc758c90-3d98-4ea1-af44-aab405c9c915 """ - neutronclient(request).delete_lbaas_pool(pool_id) + conn = _get_sdk_connection(request) + conn.load_balancer.delete_pool(pool_id) @urls.register @@ -674,10 +700,9 @@ class Members(generic.View): The listing result is an object with property "items". """ - tenant_id = request.user.project_id - result = neutronclient(request).list_lbaas_members(pool_id, - tenant_id=tenant_id) - return {'items': result.get('members')} + conn = _get_sdk_connection(request) + members_list = _sdk_object_to_list(conn.load_balancer.members(pool_id)) + return {'items': members_list} @rest_utils.ajax() def put(self, request, pool_id): @@ -685,10 +710,12 @@ class Members(generic.View): """ # Assemble the lists of member id's to add and remove, if any exist - tenant_id = request.user.project_id request_member_data = request.DATA.get('members', []) - existing_members = neutronclient(request).list_lbaas_members( - pool_id, tenant_id=tenant_id).get('members') + + conn = _get_sdk_connection(request) + existing_members = _sdk_object_to_list( + conn.load_balancer.members(pool_id)) + (members_to_add, members_to_delete) = get_members_to_add_remove( request_member_data, existing_members) @@ -713,8 +740,9 @@ class Member(generic.View): """Get a specific member belonging to a specific pool. """ - return neutronclient(request).show_lbaas_member( - member_id, pool_id).get('member') + conn = _get_sdk_connection(request) + member = conn.load_balancer.find_member(member_id, pool_id) + return _get_sdk_object_dict(member) @rest_utils.ajax() def put(self, request, member_id, pool_id): @@ -722,11 +750,10 @@ class Member(generic.View): """ data = request.DATA - spec = { - 'weight': data['weight'] - } - return neutronclient(request).update_lbaas_member( - member_id, pool_id, {'member': spec}) + conn = _get_sdk_connection(request) + member = conn.load_balancer.update_member( + member_id, pool_id, weight=data['weight']) + return _get_sdk_object_dict(member) @urls.register @@ -751,26 +778,29 @@ class HealthMonitor(generic.View): """API for retrieving a single health monitor. """ - url_regex = r'lbaas/healthmonitors/(?P[^/]+)/$' + url_regex = r'lbaas/healthmonitors/(?P[^/]+)/$' @rest_utils.ajax() - def get(self, request, healthmonitor_id): + def get(self, request, health_monitor_id): """Get a specific health monitor. """ - return neutronclient(request).show_lbaas_healthmonitor( - healthmonitor_id).get('healthmonitor') + conn = _get_sdk_connection(request) + health_mon = conn.load_balancer.find_health_monitor(health_monitor_id) + return _get_sdk_object_dict(health_mon) @rest_utils.ajax() - def delete(self, request, healthmonitor_id): + def delete(self, request, health_monitor_id): """Delete a specific health monitor. http://localhost/api/lbaas/healthmonitors/cc758c90-3d98-4ea1-af44-aab405c9c915 """ - neutronclient(request).delete_lbaas_healthmonitor(healthmonitor_id) + conn = _get_sdk_connection(request) + conn.load_balancer.delete_health_monitor(health_monitor_id, + ignore_missing=True) @rest_utils.ajax() - def put(self, request, healthmonitor_id): + def put(self, request, health_monitor_id): """Edit a health monitor. """ diff --git a/octavia_dashboard/locale/de/LC_MESSAGES/djangojs.po b/octavia_dashboard/locale/de/LC_MESSAGES/djangojs.po index b7928f0a..02e741e8 100644 --- a/octavia_dashboard/locale/de/LC_MESSAGES/djangojs.po +++ b/octavia_dashboard/locale/de/LC_MESSAGES/djangojs.po @@ -701,8 +701,8 @@ msgstr "" msgid "Subnet ID" msgstr "Subnetz-ID" -msgid "Tenant ID" -msgstr "Mandanten-ID" +msgid "Project ID" +msgstr "Projekt-ID" msgid "" "The Available Instances table contains existing compute instances that can " diff --git a/octavia_dashboard/locale/id/LC_MESSAGES/djangojs.po b/octavia_dashboard/locale/id/LC_MESSAGES/djangojs.po index 16620a7a..23cd21e8 100644 --- a/octavia_dashboard/locale/id/LC_MESSAGES/djangojs.po +++ b/octavia_dashboard/locale/id/LC_MESSAGES/djangojs.po @@ -696,8 +696,8 @@ msgstr "" msgid "Subnet ID" msgstr "Subnet ID (ID subnet)" -msgid "Tenant ID" -msgstr "Tenant ID" +msgid "Project ID" +msgstr "Project ID" msgid "" "The Available Instances table contains existing compute instances that can " diff --git a/octavia_dashboard/locale/ja/LC_MESSAGES/djangojs.po b/octavia_dashboard/locale/ja/LC_MESSAGES/djangojs.po index 01eec9eb..f0439e3a 100644 --- a/octavia_dashboard/locale/ja/LC_MESSAGES/djangojs.po +++ b/octavia_dashboard/locale/ja/LC_MESSAGES/djangojs.po @@ -449,8 +449,8 @@ msgstr "サブネット" msgid "Subnet ID" msgstr "サブネット ID" -msgid "Tenant ID" -msgstr "テナント ID" +msgid "Project ID" +msgstr "プロジェクト ID" msgid "The URL path is not valid." msgstr "URLは有効ではありません。" diff --git a/octavia_dashboard/locale/ru/LC_MESSAGES/djangojs.po b/octavia_dashboard/locale/ru/LC_MESSAGES/djangojs.po index ec6a30b9..36f33ec5 100644 --- a/octavia_dashboard/locale/ru/LC_MESSAGES/djangojs.po +++ b/octavia_dashboard/locale/ru/LC_MESSAGES/djangojs.po @@ -628,8 +628,8 @@ msgstr "" msgid "Subnet ID" msgstr "ID подсети" -msgid "Tenant ID" -msgstr "ИД арендатора" +msgid "Project ID" +msgstr "ID проекта" msgid "The IP address is not valid." msgstr "IP адрес не действителен." diff --git a/octavia_dashboard/locale/zh_CN/LC_MESSAGES/djangojs.po b/octavia_dashboard/locale/zh_CN/LC_MESSAGES/djangojs.po index b4f10a9c..9c7da8ab 100644 --- a/octavia_dashboard/locale/zh_CN/LC_MESSAGES/djangojs.po +++ b/octavia_dashboard/locale/zh_CN/LC_MESSAGES/djangojs.po @@ -672,8 +672,8 @@ msgstr "" msgid "Subnet ID" msgstr "子网ID" -msgid "Tenant ID" -msgstr "租户ID" +msgid "Project ID" +msgstr "项目ID" msgid "" "The Available Instances table contains existing compute instances that can " diff --git a/octavia_dashboard/static/app/core/openstack-service-api/lbaasv2.service.js b/octavia_dashboard/static/app/core/openstack-service-api/lbaasv2.service.js index 66c3fdb2..22860aff 100644 --- a/octavia_dashboard/static/app/core/openstack-service-api/lbaasv2.service.js +++ b/octavia_dashboard/static/app/core/openstack-service-api/lbaasv2.service.js @@ -41,7 +41,6 @@ deleteLoadBalancer: deleteLoadBalancer, createLoadBalancer: createLoadBalancer, editLoadBalancer: editLoadBalancer, - getLoadBalancerStatusTree: getLoadBalancerStatusTree, getListeners: getListeners, getListener: getListener, createListener: createListener, @@ -148,21 +147,6 @@ }); } - /** - * @name horizon.app.core.openstack-service-api.lbaasv2.getLoadBalancerStatusTree - * @description - * Get the status tree for a load balancer - * @param {string} id - * Specifies the id of the load balancer to request the status tree for. - */ - - function getLoadBalancerStatusTree(id) { - return apiService.get('/api/lbaas/loadbalancers/' + id + '/statuses/') - .error(function () { - toastService.add('error', gettext('Unable to retrieve load balancer status tree.')); - }); - } - // Listeners /** diff --git a/octavia_dashboard/static/app/core/openstack-service-api/lbaasv2.service.spec.js b/octavia_dashboard/static/app/core/openstack-service-api/lbaasv2.service.spec.js index ee23ad66..3c715a36 100644 --- a/octavia_dashboard/static/app/core/openstack-service-api/lbaasv2.service.spec.js +++ b/octavia_dashboard/static/app/core/openstack-service-api/lbaasv2.service.spec.js @@ -59,13 +59,6 @@ error: 'Unable to delete load balancer.', testInput: [ '1234' ] }, - { - func: 'getLoadBalancerStatusTree', - method: 'get', - path: '/api/lbaas/loadbalancers/1234/statuses/', - error: 'Unable to retrieve load balancer status tree.', - testInput: [ '1234' ] - }, { func: 'getListeners', method: 'get', diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/create/create.action.service.js b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/create/create.action.service.js index 0fe6d742..91274031 100644 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/create/create.action.service.js +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/create/create.action.service.js @@ -73,7 +73,7 @@ poolId = pool.id; return $q.all([ statePromise, - qExtensions.booleanAsPromise(!pool.healthmonitor_id), + qExtensions.booleanAsPromise(!pool.health_monitor_id), policy.ifAllowed({ rules: [['neutron', 'create_health_monitor']] }) ]); } diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/create/create.action.service.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/create/create.action.service.spec.js index 4070c684..6ea7e956 100644 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/create/create.action.service.spec.js +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/create/create.action.service.spec.js @@ -89,7 +89,7 @@ it('should not allow creating a health monitor if one already exists', function() { loadBalancerState.resolve(); init('active', '1', loadBalancerState.promise); - expect(allowed({ healthmonitor_id: '1234' })).toBe(false); + expect(allowed({ health_monitor_id: '1234' })).toBe(false); }); it('should redirect after create', function() { diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/detail.html b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/detail.html index 26df07c9..ace8c65b 100644 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/detail.html +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/detail.html @@ -33,8 +33,8 @@
{$ ctrl.healthmonitor.admin_state_up | yesno $}
Monitor ID
{$ ::ctrl.healthmonitor.id $}
-
Tenant ID
-
{$ ::ctrl.healthmonitor.tenant_id $}
+
Project ID
+
{$ ::ctrl.healthmonitor.project_id $}
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/detail.html b/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/detail.html index 121a1268..4dcd1d3b 100644 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/detail.html +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/listeners/detail.html @@ -33,8 +33,8 @@
Listener ID
{$ ::ctrl.listener.id $}
-
Tenant ID
-
{$ ::ctrl.listener.tenant_id $}
+
Project ID
+
{$ ::ctrl.listener.project_id $}
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/members/detail.controller.js b/octavia_dashboard/static/dashboard/project/lbaasv2/members/detail.controller.js index 8df0504f..44bd344b 100644 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/members/detail.controller.js +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/members/detail.controller.js @@ -25,8 +25,7 @@ 'horizon.dashboard.project.lbaasv2.members.actions.rowActions', '$routeParams', '$q', - 'horizon.dashboard.project.lbaasv2.loadbalancers.service', - 'horizon.dashboard.project.lbaasv2.members.service' + 'horizon.dashboard.project.lbaasv2.loadbalancers.service' ]; /** @@ -41,12 +40,11 @@ * @param $routeParams The angular $routeParams service. * @param $q The angular service for promises. * @param loadBalancersService The LBaaS v2 load balancers service. - * @param membersService The LBaaS v2 members service. * @returns undefined */ function MemberDetailController( - api, rowActions, $routeParams, $q, loadBalancersService, membersService + api, rowActions, $routeParams, $q, loadBalancersService ) { var ctrl = this; @@ -85,15 +83,6 @@ function success(property) { return angular.bind(null, function setProp(property, response) { ctrl[property] = response.data; - - if (property === 'member') { - membersService.associateMemberStatuses( - ctrl.loadbalancerId, - ctrl.listenerId, - ctrl.poolId, - [ctrl.member]); - } - }, property); } diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/members/detail.controller.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/members/detail.controller.spec.js index 93542c1d..0be3109a 100644 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/members/detail.controller.spec.js +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/members/detail.controller.spec.js @@ -17,7 +17,7 @@ 'use strict'; describe('LBaaS v2 Member Detail Controller', function() { - var $controller, lbaasv2API, membersService, apiFail, qAllFail, actions; + var $controller, lbaasv2API, apiFail, qAllFail, actions; function fakePromise(data, reject) { return { @@ -81,13 +81,11 @@ beforeEach(inject(function($injector) { lbaasv2API = $injector.get('horizon.app.core.openstack-service-api.lbaasv2'); actions = $injector.get('horizon.dashboard.project.lbaasv2.members.actions.rowActions'); - membersService = $injector.get('horizon.dashboard.project.lbaasv2.members.service'); spyOn(lbaasv2API, 'getMember').and.callFake(fakeAPI); spyOn(lbaasv2API, 'getPool').and.callFake(fakeAPI); spyOn(lbaasv2API, 'getListener').and.callFake(fakeAPI); spyOn(lbaasv2API, 'getLoadBalancer').and.callFake(loadbalancerAPI); spyOn(actions, 'init').and.callThrough(); - spyOn(membersService, 'associateMemberStatuses'); $controller = $injector.get('$controller'); })); @@ -106,12 +104,6 @@ expect(actions.init).toHaveBeenCalledWith('loadbalancerId', 'poolId'); }); - it('should invoke the "associateMemberStatuses" method', function() { - var ctrl = createController(); - expect(membersService.associateMemberStatuses).toHaveBeenCalledWith( - ctrl.loadbalancerId, ctrl.listenerId, ctrl.poolId, [ctrl.member]); - }); - it('should throw error on API fail', function() { apiFail = true; var init = function() { diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/members/detail.html b/octavia_dashboard/static/dashboard/project/lbaasv2/members/detail.html index 16c2f17d..84d97a47 100644 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/members/detail.html +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/members/detail.html @@ -29,8 +29,8 @@
{$ ctrl.member.admin_state_up | yesno $}
Member ID
{$ ::ctrl.member.id $}
-
Tenant ID
-
{$ ::ctrl.member.tenant_id $}
+
Project ID
+
{$ ::ctrl.member.project_id $}
diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/members/members.service.js b/octavia_dashboard/static/dashboard/project/lbaasv2/members/members.service.js deleted file mode 100644 index 5538dcd3..00000000 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/members/members.service.js +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2016 IBM Corp. - * - * 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. - */ -(function () { - 'use strict'; - - angular - .module('horizon.dashboard.project.lbaasv2.members') - .factory('horizon.dashboard.project.lbaasv2.members.service', membersService); - - membersService.$inject = [ - 'horizon.app.core.openstack-service-api.lbaasv2' - ]; - - /** - * @ngdoc service - * @name horizon.dashboard.project.lbaasv2.members.service - * @description General service for LBaaS v2 members. - * @param api The LBaaS V2 service API. - * @returns The members service. - */ - - function membersService(api) { - var service = { - associateMemberStatuses: associateMemberStatuses - }; - - return service; - - //////////// - - /** - * @ngdoc method - * @name horizon.dashboard.project.lbaasv2.members.service.associateMemberStatuses - * @description Associates the list of specified members with their corresponding statuses - * that are retrieved from the load balancer status tree. - * @param loadBalancerId The load balancer ID. - * @param listenerId The listener ID that the members belong to. - * @param poolId The pool ID that the members belong to. - * @param members The list of members to associate with their corresponding health statuses. - * @returns None - */ - - function associateMemberStatuses(loadBalancerId, listenerId, poolId, members) { - api.getLoadBalancerStatusTree(loadBalancerId).then(function(response) { - - // Collect the member status data for all specified members - var memberStatusData = []; - var listeners = response.data.statuses.loadbalancer.listeners; - for (var listenerIndex = 0; listenerIndex < listeners.length; listenerIndex++) { - var listener = listeners[listenerIndex]; - if (listener.id === listenerId) { - var pools = listener.pools; - for (var poolIndex = 0; poolIndex < pools.length; poolIndex++) { - var pool = pools[poolIndex]; - if (pool.id === poolId) { - memberStatusData = pool.members; - break; - } - } - break; - } - } - - // Attach the status properties to each member object - members.forEach(mapStatusToMember); - function mapStatusToMember(member) { - for (var memberIndex = 0; memberIndex < memberStatusData.length; memberIndex++) { - var memberWithStatuses = memberStatusData[memberIndex]; - if (memberWithStatuses.id === member.id) { - member.operating_status = memberWithStatuses.operating_status; - member.provisioning_status = memberWithStatuses.provisioning_status; - break; - } - } - } - }); - } - } -}()); diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/members/members.service.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/members/members.service.spec.js deleted file mode 100644 index 6352f46c..00000000 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/members/members.service.spec.js +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2016 IBM Corp. - * - * 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. - */ -(function() { - 'use strict'; - - describe('LBaaS v2 Members Service', function() { - var service, $q, scope; - - beforeEach(module('horizon.framework.widgets.toast')); - beforeEach(module('horizon.framework.conf')); - beforeEach(module('horizon.framework.util')); - beforeEach(module('horizon.app.core.openstack-service-api')); - beforeEach(module('horizon.dashboard.project.lbaasv2')); - - beforeEach(module(function($provide) { - $provide.value('horizon.app.core.openstack-service-api.lbaasv2', { - getLoadBalancerStatusTree: function() { - var deferred = $q.defer(); - var response = { - data: { - statuses: { - loadbalancer: { - id: 'loadbalancer1', - listeners: [ - { - id: 'listener0', - pools: [] - }, - { - id: 'listener1', - pools: [ - { - id: 'pool0', - members: [] - }, - { - id: 'pool1', - members: [ - { - id: 'member1', - operating_status: 'ONLINE', - provisioning_status: 'ACTIVE' - }, - { - id: 'member2', - operating_status: 'OFFLINE', - provisioning_status: 'INACTIVE' - } - ] - } - ] - } - ] - } - } - } - }; - deferred.resolve(response); - return deferred.promise; - } - - }); - })); - - beforeEach(inject(function ($injector) { - service = $injector.get('horizon.dashboard.project.lbaasv2.members.service'); - $q = $injector.get('$q'); - scope = $injector.get('$rootScope').$new(); - })); - - it('should define service attributes', function() { - expect(service.associateMemberStatuses).toBeDefined(); - }); - - it('should correctly associate member health statuses', function() { - var members = [ - { id: 'member1' }, - { id: 'member2' } - ]; - - service.associateMemberStatuses('loadbalancer1', 'listener1', 'pool1', members); - scope.$apply(); - - expect(members.length).toBe(2); - expect(members[0].operating_status).toBe('ONLINE'); - expect(members[0].provisioning_status).toBe('ACTIVE'); - expect(members[1].operating_status).toBe('OFFLINE'); - expect(members[1].provisioning_status).toBe('INACTIVE'); - - }); - - }); - -})(); diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/members/table.controller.js b/octavia_dashboard/static/dashboard/project/lbaasv2/members/table.controller.js index e1735448..c1e0268e 100644 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/members/table.controller.js +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/members/table.controller.js @@ -25,8 +25,7 @@ 'horizon.dashboard.project.lbaasv2.members.actions.rowActions', 'horizon.dashboard.project.lbaasv2.members.actions.batchActions', '$routeParams', - 'horizon.dashboard.project.lbaasv2.loadbalancers.service', - 'horizon.dashboard.project.lbaasv2.members.service' + 'horizon.dashboard.project.lbaasv2.loadbalancers.service' ]; /** @@ -41,12 +40,11 @@ * @param batchActions The members batch actions service. * @param $routeParams The angular $routeParams service. * @param loadBalancersService The LBaaS v2 load balancers service. - * @param membersService The LBaaS v2 members service. * @returns undefined */ function MembersTableController( - api, rowActions, batchActions, $routeParams, loadBalancersService, membersService + api, rowActions, batchActions, $routeParams, loadBalancersService ) { var ctrl = this; ctrl.items = []; @@ -76,11 +74,6 @@ function success(response) { ctrl.src = response.data.items; ctrl.loading = false; - membersService.associateMemberStatuses( - ctrl.loadbalancerId, - ctrl.listenerId, - ctrl.poolId, - ctrl.src); } function fail(/*response*/) { diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/members/table.controller.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/members/table.controller.spec.js index 2a2af8e6..f4dec8b2 100644 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/members/table.controller.spec.js +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/members/table.controller.spec.js @@ -18,7 +18,7 @@ 'use strict'; describe('LBaaS v2 Members Table Controller', function() { - var controller, lbaasv2API, membersService, scope; + var controller, lbaasv2API, scope; var items = [{ foo: 'bar' }]; var apiFail = false; @@ -47,10 +47,8 @@ beforeEach(inject(function($injector) { lbaasv2API = $injector.get('horizon.app.core.openstack-service-api.lbaasv2'); - membersService = $injector.get('horizon.dashboard.project.lbaasv2.members.service'); controller = $injector.get('$controller'); spyOn(lbaasv2API, 'getMembers').and.callFake(fakeAPI); - spyOn(membersService, 'associateMemberStatuses'); })); function createController() { @@ -85,12 +83,6 @@ expect(ctrl.src.length).toBe(1); }); - it('should invoke the "associateMemberStatuses" method', function() { - var ctrl = createController(); - expect(membersService.associateMemberStatuses).toHaveBeenCalledWith( - ctrl.loadbalancerId, ctrl.listenerId, ctrl.poolId, ctrl.src); - }); - it('should show error if loading fails', function() { apiFail = true; var ctrl = createController(); diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/detail.html b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/detail.html index 1ef17459..2f8e0c47 100644 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/pools/detail.html +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/pools/detail.html @@ -27,17 +27,17 @@
{$ ctrl.pool.admin_state_up | yesno $}
Health Monitor ID
- - {$ ::ctrl.pool.healthmonitor_id $} + + {$ ::ctrl.pool.health_monitor_id $} - + {$ 'None' | translate $}
Pool ID
{$ ::ctrl.pool.id $}
-
Tenant ID
-
{$ ::ctrl.pool.tenant_id $}
+
Project ID
+
{$ ::ctrl.pool.project_id $}
diff --git a/requirements.txt b/requirements.txt index 735b56f2..9a2c006c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,4 +4,5 @@ pbr!=2.1.0,>=2.0.0 # Apache-2.0 Babel!=2.4.0,>=2.3.4 # BSD +openstacksdk>=0.9.18 # Apache-2.0 python-barbicanclient!=4.5.0,!=4.5.1,>=4.0.0 # Apache-2.0