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
changes/58/499858/6
Michael Johnson 5 years ago committed by Jacky Hu
parent ec394cd7d9
commit d49b14ac01
  1. 420
      octavia_dashboard/api/rest/lbaasv2.py
  2. 4
      octavia_dashboard/locale/de/LC_MESSAGES/djangojs.po
  3. 4
      octavia_dashboard/locale/id/LC_MESSAGES/djangojs.po
  4. 4
      octavia_dashboard/locale/ja/LC_MESSAGES/djangojs.po
  5. 4
      octavia_dashboard/locale/ru/LC_MESSAGES/djangojs.po
  6. 4
      octavia_dashboard/locale/zh_CN/LC_MESSAGES/djangojs.po
  7. 16
      octavia_dashboard/static/app/core/openstack-service-api/lbaasv2.service.js
  8. 7
      octavia_dashboard/static/app/core/openstack-service-api/lbaasv2.service.spec.js
  9. 2
      octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/create/create.action.service.js
  10. 2
      octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/actions/create/create.action.service.spec.js
  11. 4
      octavia_dashboard/static/dashboard/project/lbaasv2/healthmonitors/detail.html
  12. 4
      octavia_dashboard/static/dashboard/project/lbaasv2/listeners/detail.html
  13. 15
      octavia_dashboard/static/dashboard/project/lbaasv2/members/detail.controller.js
  14. 10
      octavia_dashboard/static/dashboard/project/lbaasv2/members/detail.controller.spec.js
  15. 4
      octavia_dashboard/static/dashboard/project/lbaasv2/members/detail.html
  16. 92
      octavia_dashboard/static/dashboard/project/lbaasv2/members/members.service.js
  17. 107
      octavia_dashboard/static/dashboard/project/lbaasv2/members/members.service.spec.js
  18. 11
      octavia_dashboard/static/dashboard/project/lbaasv2/members/table.controller.js
  19. 10
      octavia_dashboard/static/dashboard/project/lbaasv2/members/table.controller.spec.js
  20. 10
      octavia_dashboard/static/dashboard/project/lbaasv2/pools/detail.html
  21. 1
      requirements.txt

@ -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']
healthmonitor = neutronclient(request).update_lbaas_healthmonitor(
monitor_id, {'healthmonitor': monitor_spec}).get('healthmonitor')
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'))
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<loadbalancer_id>[^/]+)/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
if pool.get('healthmonitor_id'):
monitor_id = pool['healthmonitor_id']
monitor = neutronclient(request).show_lbaas_healthmonitor(
monitor_id).get('healthmonitor')
member_list = _sdk_object_to_list(
conn.load_balancer.members(pool_id))
resources['members'] = member_list
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
if pool.get('healthmonitor_id'):
monitor_id = pool['healthmonitor_id']
monitor = neutronclient(request).show_lbaas_healthmonitor(
monitor_id).get('healthmonitor')
member_list = _sdk_object_to_list(
conn.load_balancer.members(pool_id))
resources['members'] = member_list
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<healthmonitor_id>[^/]+)/$'
url_regex = r'lbaas/healthmonitors/(?P<health_monitor_id>[^/]+)/$'
@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.
"""

@ -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 "

@ -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 "

@ -449,8 +449,8 @@ msgstr "サブネット<span class=\"hz-icon-required fa fa-asterisk\"></span>"
msgid "Subnet ID"
msgstr "サブネット ID"
msgid "Tenant ID"
msgstr "テナント ID"
msgid "Project ID"
msgstr "プロジェクト ID"
msgid "The URL path is not valid."
msgstr "URLは有効ではありません。"

@ -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 адрес не действителен."

@ -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 "

@ -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
/**

@ -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',

@ -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']] })
]);
}

@ -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() {

@ -33,8 +33,8 @@
<dd>{$ ctrl.healthmonitor.admin_state_up | yesno $}</dd>
<dt translate>Monitor ID</dt>
<dd>{$ ::ctrl.healthmonitor.id $}</dd>
<dt translate>Tenant ID</dt>
<dd>{$ ::ctrl.healthmonitor.tenant_id $}</dd>
<dt translate>Project ID</dt>
<dd>{$ ::ctrl.healthmonitor.project_id $}</dd>
</dl>
</div>
</div>

@ -33,8 +33,8 @@
</dd>
<dt translate>Listener ID</dt>
<dd>{$ ::ctrl.listener.id $}</dd>
<dt translate>Tenant ID</dt>
<dd>{$ ::ctrl.listener.tenant_id $}</dd>
<dt translate>Project ID</dt>
<dd>{$ ::ctrl.listener.project_id $}</dd>
</dl>
</div>
</div>

@ -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);
}

@ -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() {

@ -29,8 +29,8 @@
<dd>{$ ctrl.member.admin_state_up | yesno $}</dd>
<dt translate>Member ID</dt>
<dd>{$ ::ctrl.member.id $}</dd>
<dt translate>Tenant ID</dt>
<dd>{$ ::ctrl.member.tenant_id $}</dd>
<dt translate>Project ID</dt>
<dd>{$ ::ctrl.member.project_id $}</dd>
</dl>
</div>
</div>

@ -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;
}
}
}
});
}
}
}());

@ -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');
});
});
})();

@ -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*/) {

@ -18,7 +18,7 @@
'use strict';
describe('LBaaS v2 Members Table Controller', function() {