diff --git a/openstack_dashboard/api/lbaas.py b/openstack_dashboard/api/lbaas.py
index 3070e4978b3..3c776b96a6d 100644
--- a/openstack_dashboard/api/lbaas.py
+++ b/openstack_dashboard/api/lbaas.py
@@ -115,6 +115,21 @@ def __init__(self, apiresource):
super(PoolMonitor, self).__init__(apiresource)
+class SSLPolicy(neutron.NeutronAPIDictWrapper):
+ """Wrapper for neutron load balancer ssl policy"""
+
+ def __init__(self, apiresource):
+ super(SSLPolicy, self).__init__(apiresource)
+
+class SSLCertificate(neutron.NeutronAPIDictWrapper):
+ """Wrapper for neutron load balancer ssl certificate"""
+
+ def __init__(self, apiresource):
+ super(SSLCertificate, self).__init__(apiresource)
+
+
+
+
def vip_create(request, **kwargs):
"""Create a vip for a specified pool.
@@ -264,6 +279,104 @@ def pool_health_monitor_delete(request, mon_id):
neutronclient(request).delete_health_monitor(mon_id)
+def ssl_policy_create(request, **kwargs):
+ """Create a SSL Policy
+
+ :param request: request context
+ :param name: name of ssl policy
+ :param description: description of ssl policy
+ :param front_end_enabled: front_end_enabled
+ :param front_end_cipher_suites: front_end_cipher_suites
+ :param back_end_enabled: back_end_enabled
+ :param back_end_cipher_suites: back_end_cipher_suites
+ """
+ body = {'ssl_policy': {'name': kwargs['name'],
+ 'description': kwargs['description'],
+ 'front_end_enabled': kwargs['front_end_enabled'],
+ 'front_end_cipher_suites': kwargs['front_end_cipher_suites'],
+ 'front_end_protocols': kwargs['front_end_protocols'],
+ 'back_end_enabled': 'False',
+ 'back_end_cipher_suites': '',
+ 'back_end_protocols':''
+ }}
+
+ ssl = neutronclient(request).create_ssl_policy(body).get('ssl_policy')
+
+ return SSLPolicy(ssl)
+
+
+def ssl_policies_get(request, **kwargs):
+ sslpolicies = neutronclient(request).list_ssl_policies().get('ssl_policies')
+ return [SSLPolicy(m) for m in sslpolicies]
+
+def ssl_policy_get(request, sslpolicy_id):
+ sslpolicy = neutronclient(request).show_ssl_policy(sslpolicy_id).get('ssl_policy')
+ return SSLPolicy(sslpolicy)
+
+def ssl_policy_update(request, sslpolicy_id, **kwargs):
+ sslpolicy = neutronclient(request).update_ssl_policy(sslpolicy_id, kwargs)
+ return SSLPolicy(sslpolicy)
+
+def ssl_policy_delete(request, sslpolicy_id):
+ neutronclient(request).delete_ssl_policy(sslpolicy_id)
+
+def ssl_certificate_create(request, **kwargs):
+ """Create a SSL Certificate
+
+ :param request: request context
+ :param name: name of ssl certificate
+ :param certificate: certificate
+ :param passphrase: passphrase
+ :param certificate_chain: certificate_chain
+ """
+ body = {'ssl_certificate': {'name': kwargs['name'],
+ 'certificate': kwargs['certificate'],
+ 'passphrase': kwargs['passphrase'],
+ 'certificate_chain': kwargs['certificate_chain']}}
+
+ sslcertificate = neutronclient(request).create_ssl_certificate(body).get('ssl_certificate')
+
+ return SSLCertificate(sslcertificate)
+
+def ssl_certificates_get(request, **kwargs):
+ sslcertificates = neutronclient(request).list_ssl_certificates().get('ssl_certificates')
+ return [SSLCertificate(m) for m in sslcertificates]
+
+def ssl_certificate_get(request, sslcertificate_id):
+ sslcertificate = neutronclient(request).show_ssl_certificate(sslcertificate_id).get('ssl_certificate')
+ return SSLCertificate(sslcertificate)
+
+def ssl_certificate_update(request, sslcertificate_id, **kwargs):
+ sslpolicy = neutronclient(request).update_ssl_certificate(sslcertificate_id, kwargs)
+ return SSLCertificate(sslpolicy)
+
+def ssl_certificate_delete(request, sslcertificate_id):
+ neutronclient(request).delete_ssl_certificate(sslcertificate_id)
+
+def ssl_policy_associate(request, **kwargs):
+
+ body = {'ssl_association': {
+ 'id': kwargs['vip_id'],
+ 'ssl_policy':{
+ 'id':kwargs['ssl_policy_id']},
+ 'ssl_certificates': [
+ { 'id':kwargs['ssl_certificate_id'],
+ 'private_key':kwargs['private_key']}
+ ],
+ 'ssl_trusted_certificates':[],
+ }}
+ neutronclient(request).create_ssl_policy_association(kwargs['vip_id'], body)
+
+def ssl_policy_disassociate(request, **kwargs):
+
+ neutronclient(request).delete_ssl_policy_association(
+ kwargs['vip_id'],
+ kwargs['ssl_policy_id'])
+
+
+
+
+
def member_create(request, **kwargs):
"""Create a load balance member
diff --git a/openstack_dashboard/dashboards/project/loadbalancers/forms.py b/openstack_dashboard/dashboards/project/loadbalancers/forms.py
index f3e517fa1ac..27ad814ec9b 100644
--- a/openstack_dashboard/dashboards/project/loadbalancers/forms.py
+++ b/openstack_dashboard/dashboards/project/loadbalancers/forms.py
@@ -257,3 +257,117 @@ def handle(self, request, context):
LOG.info(msg)
redirect = reverse(self.failure_url)
exceptions.handle(request, msg, redirect=redirect)
+
+FRONT_END_PROTOCOL_CHOICES = (
+ ('SSLv2','SSLv2'),
+ ('SSLv3','SSLv3'),
+ ('TLSv1','TLSv1'),
+ )
+
+class UpdateSSLpolicy(forms.SelfHandlingForm):
+ sslpolicy_id = forms.CharField(label=_("ID"),
+ widget=forms.TextInput(
+ attrs={'readonly': 'readonly'}))
+
+ name = forms.CharField(max_length=80, label=_("Name"))
+ description = forms.CharField(required=False,
+ max_length=80, label=_("Description"))
+
+ front_end_enabled = forms.BooleanField(label=_("Front End Enabled"),
+ initial=True, required=False)
+
+ front_end_cipher_suites = forms.ChoiceField(
+ label=_("Front End Cipher Suite"),
+ choices=[('ALL', _('ALL')),
+ ('HIGH', _('HIGH')),
+ ('MEDIUM', _('MEDIUM')),
+ ('LOW', _('LOW'))])
+
+ front_end_protocols = forms.TypedMultipleChoiceField(required=False,
+ label=_("Front End Protocols"),
+ empty_value='',
+ widget=forms.CheckboxSelectMultiple,
+ choices=FRONT_END_PROTOCOL_CHOICES)
+ """
+ back_end_enabled = forms.BooleanField(label=_("Back End Enabled"),
+ initial=True, required=False)
+
+ back_end_cipher_suites = forms.ChoiceField(
+ label=_("Back End Cipher Suite"),
+ choices=[('ALL', _('ALL')),
+ ('HIGH', _('HIGH')),
+ ('MEDIUM', _('MEDIUM')),
+ ('LOW', _('LOW'))])
+ """
+ failure_url = 'horizon:project:loadbalancers:index'
+
+ def __init__(self, request, *args, **kwargs):
+ super(UpdateSSLpolicy, self).__init__(request, *args, **kwargs)
+
+ def handle(self, request, context):
+ try:
+ data = {'ssl_policy': {
+ 'name': context['name'],
+ 'description': context['description'],
+ 'front_end_enabled': context['front_end_enabled'],
+ 'front_end_protocols': ','.join(context['front_end_protocols']),
+ 'front_end_cipher_suites': context['front_end_cipher_suites']}}
+
+ #'back_end_enabled': context['back_end_enabled'],
+ #'back_end_cipher_suites': context['back_end_cipher_suites']}}
+
+ sslpolicy = api.lbaas.ssl_policy_update(request,
+ context['sslpolicy_id'], **data)
+ msg = _('SSL policy %s was successfully updated.')\
+ % context['sslpolicy_id']
+ LOG.debug(msg)
+ messages.success(request, msg)
+ return sslpolicy
+ except Exception:
+ msg = _('Failed to update SSL policy %s')\
+ % context['sslpolicy_id']
+ LOG.info(msg)
+ redirect = reverse(self.failure_url)
+ exceptions.handle(request, msg, redirect=redirect)
+
+
+class UpdateSSLcertificate(forms.SelfHandlingForm):
+ sslcertificate_id = forms.CharField(label=_("ID"),
+ widget=forms.TextInput(
+ attrs={'readonly': 'readonly'}))
+
+ name = forms.CharField(max_length=80, label=_("Name"))
+ passphrase = forms.CharField(required=False,
+ label=_("Passphrase"))
+ certificate_chain = forms.CharField(required=False,
+ label=_("Certificate Chain"))
+ certificate = forms.CharField(required=False,
+ widget=forms.Textarea,
+ label=_("Certificate"))
+
+ failure_url = 'horizon:project:loadbalancers:index'
+
+ def __init__(self, request, *args, **kwargs):
+ super(UpdateSSLcertificate, self).__init__(request, *args, **kwargs)
+
+ def handle(self, request, context):
+ try:
+ data = {'ssl_certificate': {
+ 'name': context['name'],
+ 'passphrase': context['passphrase'],
+ 'certificate_chain': context['certificate_chain'],
+ 'certificate': context['certificate']}}
+
+ sslcertificate = api.lbaas.ssl_certificate_update(request,
+ context['sslcertificate_id'], **data)
+ msg = _('SSL certificate %s was successfully updated.')\
+ % context['sslcertificate_id']
+ LOG.debug(msg)
+ messages.success(request, msg)
+ return sslcertificate
+ except Exception:
+ msg = _('Failed to update SSL certificate %s')\
+ % context['sslcertificate_id']
+ LOG.info(msg)
+ redirect = reverse(self.failure_url)
+ exceptions.handle(request, msg, redirect=redirect)
diff --git a/openstack_dashboard/dashboards/project/loadbalancers/tables.py b/openstack_dashboard/dashboards/project/loadbalancers/tables.py
index 734498d97c4..37363376bae 100644
--- a/openstack_dashboard/dashboards/project/loadbalancers/tables.py
+++ b/openstack_dashboard/dashboards/project/loadbalancers/tables.py
@@ -62,6 +62,17 @@ class AddMonitorLink(tables.LinkAction):
url = "horizon:project:loadbalancers:addmonitor"
classes = ("ajax-modal", "btn-create",)
+class AddSSLpolicyLink(tables.LinkAction):
+ name = "addsslpolicy"
+ verbose_name = _("Add SSL Policy")
+ url = "horizon:project:loadbalancers:addsslpolicy"
+ classes = ("ajax-modal", "btn-create",)
+
+class AddSSLcertificateLink(tables.LinkAction):
+ name = "addcertificate"
+ verbose_name = _("Add SSL Certificate")
+ url = "horizon:project:loadbalancers:addcertificate"
+ classes = ("ajax-modal", "btn-create",)
class DeleteVipLink(tables.DeleteAction):
name = "deletevip"
@@ -92,6 +103,22 @@ class DeleteMonitorLink(tables.DeleteAction):
data_type_plural = _("Monitors")
+class DeleteSSLpolicyLink(tables.DeleteAction):
+ name = "deletesslpolicy"
+ action_present = _("Delete")
+ action_past = _("Scheduled deletion of")
+ data_type_singular = _("SSL Policy")
+ data_type_plural = _("SSL Policies")
+
+
+class DeleteSSLcertificateLink(tables.DeleteAction):
+ name = "deletesslcertificate"
+ action_present = _("Delete")
+ action_past = _("Scheduled deletion of")
+ data_type_singular = _("SSL Certificate")
+ data_type_plural = _("SSL Certificates")
+
+
class DeleteMemberLink(tables.DeleteAction):
name = "deletemember"
action_present = _("Delete")
@@ -144,6 +171,25 @@ def get_link_url(self, monitor):
base_url = reverse("horizon:project:loadbalancers:updatemonitor",
kwargs={'monitor_id': monitor.id})
return base_url
+
+
+class UpdateSSLpolicyLink(tables.LinkAction):
+ name = "updatesslpolicy"
+ verbose_name = _("Edit SSL Policy")
+
+ def get_link_url(self, sslpolicy):
+ base_url = reverse("horizon:project:loadbalancers:updatesslpolicy",
+ kwargs={'sslpolicy_id': sslpolicy.id})
+ return base_url
+
+class UpdateSSLcertificateLink(tables.LinkAction):
+ name = "updatesslcertificate"
+ verbose_name = _("Edit SSL Certificate")
+
+ def get_link_url(self, sslcertificate):
+ base_url = reverse("horizon:project:loadbalancers:updatesslcertificate",
+ kwargs={'sslcertificate_id': sslcertificate.id})
+ return base_url
def get_vip_link(pool):
@@ -186,6 +232,54 @@ def allowed(self, request, datum=None):
return True
+class AssociateSSLPolicyLink(tables.LinkAction):
+ name = "associatesslpolicy"
+ verbose_name = _("Associate SSL Policy")
+ classes = ("ajax-modal", "btn-create",)
+
+ def get_link_url(self, pool):
+ base_url = reverse("horizon:project:loadbalancers:associatesslpolicy",
+ kwargs={'vip_id': pool.vip_id})
+ return base_url
+
+ def allowed(self, request, datum=None):
+ if datum and not datum.vip_id:
+ return False
+ else:
+ try:
+ vip = api.lbaas.vip_get(request, datum.vip_id)
+ if vip['ssl_policy_id'] != None or vip['protocol'] != 'HTTPS':
+ return False
+ except Exception:
+ exceptions.handle(request, _('Failed to retrieve VIP'))
+
+ return True
+
+
+class DisassociateSSLPolicyLink(tables.LinkAction):
+ name = "disassociatesslpolicy"
+ verbose_name = _("Disassociate SSL Policy")
+ classes = ("ajax-modal", "btn-create",)
+
+ def get_link_url(self, pool):
+ base_url = reverse("horizon:project:loadbalancers:disassociatesslpolicy",
+ kwargs={'vip_id': pool.vip_id})
+ return base_url
+
+ def allowed(self, request, datum=None):
+ if datum and datum.vip_id:
+ try:
+ vip = api.lbaas.vip_get(request, datum.vip_id)
+ if vip['ssl_policy_id'] != None:
+ return True
+
+ except Exception:
+ exceptions.handle(request, _('Failed to retrieve VIP'))
+
+ return False
+
+
+
class PoolsTable(tables.DataTable):
name = tables.Column("name",
verbose_name=_("Name"),
@@ -204,7 +298,8 @@ class Meta:
table_actions = (AddPoolLink, DeletePoolLink)
row_actions = (UpdatePoolLink, AddVipLink, UpdateVipLink,
DeleteVipLink, AddPMAssociationLink,
- DeletePMAssociationLink, DeletePoolLink)
+ DeletePMAssociationLink, DeletePoolLink,
+ AssociateSSLPolicyLink, DisassociateSSLPolicyLink)
def get_pool_link(member):
@@ -245,3 +340,37 @@ class Meta:
verbose_name = _("Monitors")
table_actions = (AddMonitorLink, DeleteMonitorLink)
row_actions = (UpdateMonitorLink, DeleteMonitorLink)
+
+class SSLpoliciesTable(tables.DataTable):
+ name = tables.Column("name",
+ verbose_name=_("Name"),
+ link="horizon:project:loadbalancers:sslpolicydetails")
+ description = tables.Column('description', verbose_name=_("Description"))
+ front_end_enabled = tables.Column('front_end_enabled', verbose_name=_("Front End Enabled"))
+ front_end_cipher_suites = tables.Column('front_end_cipher_suites', verbose_name=_("Front End Cipher Suites"))
+ front_end_protocols = tables.Column('front_end_protocols', verbose_name=_("Front End Protocols"))
+ #back_end_enabled = tables.Column('back_end_enabled', verbose_name=_("Back End Enabled"))
+ #back_end_cipher_suites = tables.Column('back_end_cipher_suites', verbose_name=_("Back End Cipher Suites"))
+
+
+ class Meta:
+ name = "sslpoliciestable"
+ verbose_name = _("SSL Policies")
+ table_actions = (AddSSLpolicyLink, DeleteSSLpolicyLink)
+ row_actions = (UpdateSSLpolicyLink, DeleteSSLpolicyLink)
+
+
+class SSLcertificatesTable(tables.DataTable):
+ name = tables.Column("name",
+ verbose_name=_("Name"),
+ link="horizon:project:loadbalancers:sslcertificatedetails")
+ #certificate = tables.Column('certificate', verbose_name=_("Certificate"))
+ passphrase = tables.Column('passphrase', verbose_name=_("Passphrase"))
+ certificate_chain = tables.Column('certificate_chain', verbose_name=_("Certificate Chain"))
+
+
+ class Meta:
+ name = "sslcertificatestable"
+ verbose_name = _("SSL Certificates")
+ table_actions = (AddSSLcertificateLink, DeleteSSLcertificateLink)
+ row_actions = (UpdateSSLcertificateLink, DeleteSSLcertificateLink)
diff --git a/openstack_dashboard/dashboards/project/loadbalancers/tabs.py b/openstack_dashboard/dashboards/project/loadbalancers/tabs.py
index ca610dc2b73..003535e1fe2 100644
--- a/openstack_dashboard/dashboards/project/loadbalancers/tabs.py
+++ b/openstack_dashboard/dashboards/project/loadbalancers/tabs.py
@@ -82,10 +82,43 @@ def get_monitorstable_data(self):
_('Unable to retrieve monitor list.'))
return monitors
+class SSLpoliciesTab(tabs.TableTab):
+ table_classes = (tables.SSLpoliciesTable,)
+ name = _("SSL Policies")
+ slug = "sslpolicies"
+ template_name = "horizon/common/_detail_table.html"
+
+ def get_sslpoliciestable_data(self):
+ try:
+ tenant_id = self.request.user.tenant_id
+ sslpolicies = api.lbaas.ssl_policies_get(
+ self.tab_group.request, tenant_id=tenant_id)
+ except Exception:
+ sslpolicies = []
+ exceptions.handle(self.tab_group.request,
+ _('Unable to retrieve SSL policy list.'))
+ return sslpolicies
+
+class SSLcertificateTab(tabs.TableTab):
+ table_classes = (tables.SSLcertificatesTable,)
+ name = _("SSL Certificates")
+ slug = "sslcertificates"
+ template_name = "horizon/common/_detail_table.html"
+
+ def get_sslcertificatestable_data(self):
+ try:
+ tenant_id = self.request.user.tenant_id
+ sslcertificates = api.lbaas.ssl_certificates_get(
+ self.tab_group.request, tenant_id=tenant_id)
+ except Exception:
+ sslcertificates = []
+ exceptions.handle(self.tab_group.request,
+ _('Unable to retrieve SSL Certificate list.'))
+ return sslcertificates
class LoadBalancerTabs(tabs.TabGroup):
slug = "lbtabs"
- tabs = (PoolsTab, MembersTab, MonitorsTab)
+ tabs = (PoolsTab, MembersTab, MonitorsTab, SSLpoliciesTab, SSLcertificateTab)
sticky = True
@@ -153,6 +186,36 @@ def get_context_data(self, request):
return {'monitor': monitor}
+class SSLpolicyDetailsTab(tabs.Tab):
+ name = _("SSL Policy Details")
+ slug = "sslpolicydetails"
+ template_name = "project/loadbalancers/_sslpolicy_details.html"
+
+ def get_context_data(self, request):
+ sslpolicyid = self.tab_group.kwargs['sslpolicy_id']
+ try:
+ sslpolicy = api.lbaas.ssl_policy_get(request, sslpolicyid)
+ except Exception:
+ sslpolicy = []
+ exceptions.handle(self.tab_group.request,
+ _('Unable to retrieve SSL policy details.'))
+ return {'sslpolicy': sslpolicy}
+
+class SSLcertificateDetailsTab(tabs.Tab):
+ name = _("SSL Certificate Details")
+ slug = "sslcertificatedetails"
+ template_name = "project/loadbalancers/_sslcertificate_details.html"
+
+ def get_context_data(self, request):
+ sslcertificateid = self.tab_group.kwargs['sslcertificate_id']
+ try:
+ sslcertificate = api.lbaas.ssl_certificate_get(request, sslcertificateid)
+ except Exception:
+ sslcertificate = []
+ exceptions.handle(self.tab_group.request,
+ _('Unable to retrieve SSL certificate details.'))
+ return {'sslcertificate': sslcertificate}
+
class PoolDetailsTabs(tabs.TabGroup):
slug = "pooltabs"
tabs = (PoolDetailsTab,)
@@ -171,3 +234,12 @@ class MemberDetailsTabs(tabs.TabGroup):
class MonitorDetailsTabs(tabs.TabGroup):
slug = "monitortabs"
tabs = (MonitorDetailsTab,)
+
+
+class SSLPolicyDetailsTabs(tabs.TabGroup):
+ slug = "sslpolicytabs"
+ tabs = (SSLpolicyDetailsTab,)
+
+class SSLcertificateDetailsTabs(tabs.TabGroup):
+ slug = "sslcertificatetabs"
+ tabs = (SSLcertificateDetailsTab,)
\ No newline at end of file
diff --git a/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_sslcertificate_details.html b/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_sslcertificate_details.html
new file mode 100644
index 00000000000..5a53020fcc3
--- /dev/null
+++ b/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_sslcertificate_details.html
@@ -0,0 +1,22 @@
+{% load i18n sizeformat parse_date %}
+
+
+
+
+ - {% trans "ID" %}
+ - {{ sslcertificate.id }}
+
+ - {% trans "Name" %}
+ - {{ sslcertificate.name }}
+
+ - {% trans "Passphrase" %}
+ - {{ sslcertificate.passphrase }}
+
+ - {% trans "Certificate Chain" %}
+ - {{ sslcertificate.certificate_chain }}
+
+ - {% trans "Certificate" %}
+ - {{ sslcertificate.certificate }}
+
+
+
\ No newline at end of file
diff --git a/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_sslpolicies_tab.html b/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_sslpolicies_tab.html
new file mode 100644
index 00000000000..c7677aa435e
--- /dev/null
+++ b/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_sslpolicies_tab.html
@@ -0,0 +1,5 @@
+{% block main %}
+
+ {{ table.render }}
+
+{% endblock %}
\ No newline at end of file
diff --git a/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_sslpolicy_details.html b/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_sslpolicy_details.html
new file mode 100644
index 00000000000..a912ffa0452
--- /dev/null
+++ b/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_sslpolicy_details.html
@@ -0,0 +1,37 @@
+{% load i18n sizeformat parse_date %}
+
+
+
+
+ - {% trans "ID" %}
+ - {{ sslpolicy.id }}
+
+ - {% trans "Name" %}
+ - {{ sslpolicy.name }}
+
+ - {% trans "Description" %}
+ - {{ sslpolicy.description }}
+
+ - {% trans "Project ID" %}
+ - {{ sslpolicy.tenant_id }}
+
+ - {% trans "Front End Enabled" %}
+ - {{ sslpolicy.front_end_enabled }}
+
+ - {% trans "Front End Cipher Suites" %}
+ - {{ sslpolicy.front_end_cipher_suites }}
+
+ - {% trans "Front End Protocols" %}
+ - {{ sslpolicy.front_end_protocols }}
+
+
+
\ No newline at end of file
diff --git a/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_updatesslcertificate.html b/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_updatesslcertificate.html
new file mode 100644
index 00000000000..9896c702f11
--- /dev/null
+++ b/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_updatesslcertificate.html
@@ -0,0 +1,25 @@
+{% extends "horizon/common/_modal_form.html" %}
+{% load i18n %}
+{% load url from future %}
+
+{% block form_id %}update_sslcertificate_form{% endblock %}
+{% block form_action %}{% url 'horizon:project:loadbalancers:updatesslcertificate' sslcertificate_id %}{% endblock %}
+
+{% block modal-header %}{% trans "Edit SSL Certificate" %}{% endblock %}
+
+{% block modal-body %}
+
+
+
+
+
{% trans "Description:" %}
+
{% trans "You may update SSL certificate for current tenant here: edit name, certificate, passphrase, certificate chain." %}
+
+{% endblock %}
+
+{% block modal-footer %}
+
+ {% trans "Cancel" %}
+{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_updatesslpolicy.html b/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_updatesslpolicy.html
new file mode 100644
index 00000000000..4c066487746
--- /dev/null
+++ b/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_updatesslpolicy.html
@@ -0,0 +1,25 @@
+{% extends "horizon/common/_modal_form.html" %}
+{% load i18n %}
+{% load url from future %}
+
+{% block form_id %}update_sslpolicy_form{% endblock %}
+{% block form_action %}{% url 'horizon:project:loadbalancers:updatesslpolicy' sslpolicy_id %}{% endblock %}
+
+{% block modal-header %}{% trans "Edit SSL Policy" %}{% endblock %}
+
+{% block modal-body %}
+
+
+
+
+
{% trans "Description:" %}
+
{% trans "You may update SSL policy for current tenant here: edit name, description." %}
+
+{% endblock %}
+
+{% block modal-footer %}
+
+ {% trans "Cancel" %}
+{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/disassociateSsl.html b/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/disassociateSsl.html
new file mode 100644
index 00000000000..908d0da2822
--- /dev/null
+++ b/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/disassociateSsl.html
@@ -0,0 +1,28 @@
+{% load i18n %}
+{% with workflow.get_entry_point as entry_point %}
+
+{% endwith %}
+{% block modal-js %}
+{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/updatesslcertificate.html b/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/updatesslcertificate.html
new file mode 100644
index 00000000000..3f19e9887f2
--- /dev/null
+++ b/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/updatesslcertificate.html
@@ -0,0 +1,11 @@
+{% extends 'base.html' %}
+{% load i18n %}
+{% block title %}{% trans "Edit SSL Certificate" %}{% endblock %}
+
+{% block page_header %}
+ {% include "horizon/common/_page_header.html" with title=_("Edit SSL Certificate") %}
+{% endblock page_header %}
+
+{% block main %}
+ {% include 'project/loadbalancers/_updatesslcertificate.html' %}
+{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/updatesslpolicy.html b/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/updatesslpolicy.html
new file mode 100644
index 00000000000..392844ea70f
--- /dev/null
+++ b/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/updatesslpolicy.html
@@ -0,0 +1,11 @@
+{% extends 'base.html' %}
+{% load i18n %}
+{% block title %}{% trans "Edit SSL Policy" %}{% endblock %}
+
+{% block page_header %}
+ {% include "horizon/common/_page_header.html" with title=_("Edit SSL Policy") %}
+{% endblock page_header %}
+
+{% block main %}
+ {% include 'project/loadbalancers/_updatesslpolicy.html' %}
+{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/loadbalancers/tests.py b/openstack_dashboard/dashboards/project/loadbalancers/tests.py
index 6167daee711..881fa73dc44 100644
--- a/openstack_dashboard/dashboards/project/loadbalancers/tests.py
+++ b/openstack_dashboard/dashboards/project/loadbalancers/tests.py
@@ -54,8 +54,10 @@ def set_up_expect(self):
IsA(http.HttpRequest), tenant_id=self.tenant.id) \
.AndReturn(self.pools.list())
- api.lbaas.vip_get(IsA(http.HttpRequest), vip1.id).AndReturn(vip1)
- api.lbaas.vip_get(IsA(http.HttpRequest), vip2.id).AndReturn(vip2)
+ api.lbaas.vip_get(IsA(http.HttpRequest), vip1.id).MultipleTimes() \
+ .AndReturn(vip1)
+ api.lbaas.vip_get(IsA(http.HttpRequest), vip2.id).MultipleTimes() \
+ .AndReturn(vip2)
# retrieves members
api.lbaas.members_get(
diff --git a/openstack_dashboard/dashboards/project/loadbalancers/urls.py b/openstack_dashboard/dashboards/project/loadbalancers/urls.py
index 6bfd04c0e96..39a8fe540e5 100644
--- a/openstack_dashboard/dashboards/project/loadbalancers/urls.py
+++ b/openstack_dashboard/dashboards/project/loadbalancers/urls.py
@@ -47,4 +47,18 @@
url(r'^member/(?P[^/]+)/$',
views.MemberDetailsView.as_view(), name='memberdetails'),
url(r'^monitor/(?P[^/]+)/$',
- views.MonitorDetailsView.as_view(), name='monitordetails'))
+ views.MonitorDetailsView.as_view(), name='monitordetails'),
+ url(r'^addsslpolicy$', views.AddSSLpolicyView.as_view(), name='addsslpolicy'),
+ url(r'^addcertificate$', views.AddSSLcertificateView.as_view(), name='addcertificate'),
+ url(r'^sslpolicy/(?P[^/]+)/$',
+ views.SSLpolicyDetailsView.as_view(), name='sslpolicydetails'),
+ url(r'^updatesslpolicy/(?P[^/]+)/$',
+ views.UpdateSSLpolicyView.as_view(), name='updatesslpolicy'),
+ url(r'^sslcertificatedetails/(?P[^/]+)/$',
+ views.SSLcertificateDetailsView.as_view(), name='sslcertificatedetails'),
+ url(r'^updatesslcertificate/(?P[^/]+)/$',
+ views.UpdateSSLcertificateView.as_view(), name='updatesslcertificate'),
+ url(r'^associatesslpolicy/(?P[^/]+)/$',
+ views.AssociateSSLPolicyView.as_view(), name='associatesslpolicy'),
+ url(r'^disassociatesslpolicy/(?P[^/]+)/$',
+ views.DisassociateSSLPolicyView.as_view(), name='disassociatesslpolicy'))
diff --git a/openstack_dashboard/dashboards/project/loadbalancers/views.py b/openstack_dashboard/dashboards/project/loadbalancers/views.py
index d4ef769cea3..1d0ae0cdabb 100644
--- a/openstack_dashboard/dashboards/project/loadbalancers/views.py
+++ b/openstack_dashboard/dashboards/project/loadbalancers/views.py
@@ -83,6 +83,22 @@ def post(self, request, *args, **kwargs):
except Exception as e:
exceptions.handle(request,
_('Unable to delete VIP. %s') % e)
+ if m == 'sslpolicy':
+ for obj_id in obj_ids:
+ try:
+ api.lbaas.ssl_policy_delete(request, obj_id)
+ messages.success(request, _('Deleted SSL policy %s') % obj_id)
+ except Exception as e:
+ exceptions.handle(request,
+ _('Unable to delete SSL policy. %s') % e)
+ if m == 'sslcertificate':
+ for obj_id in obj_ids:
+ try:
+ api.lbaas.ssl_certificate_delete(request, obj_id)
+ messages.success(request, _('Deleted SSL certificate %s') % obj_id)
+ except Exception as e:
+ exceptions.handle(request,
+ _('Unable to delete SSL certificate. %s') % e)
return self.get(request, *args, **kwargs)
@@ -130,6 +146,19 @@ def get_initial(self):
initial = super(AddMonitorView, self).get_initial()
return initial
+class AddSSLpolicyView(workflows.WorkflowView):
+ workflow_class = project_workflows.AddSSLpolicy
+
+ def get_initial(self):
+ initial = super(AddSSLpolicyView, self).get_initial()
+ return initial
+
+class AddSSLcertificateView(workflows.WorkflowView):
+ workflow_class = project_workflows.AddSSLcertificate
+
+ def get_initial(self):
+ initial = super(AddSSLcertificateView, self).get_initial()
+ return initial
class PoolDetailsView(tabs.TabView):
tab_group_class = (project_tabs.PoolDetailsTabs)
@@ -149,6 +178,15 @@ class MemberDetailsView(tabs.TabView):
class MonitorDetailsView(tabs.TabView):
tab_group_class = (project_tabs.MonitorDetailsTabs)
template_name = 'project/loadbalancers/details_tabs.html'
+
+
+class SSLpolicyDetailsView(tabs.TabView):
+ tab_group_class = (project_tabs.SSLPolicyDetailsTabs)
+ template_name = 'project/loadbalancers/details_tabs.html'
+
+class SSLcertificateDetailsView(tabs.TabView):
+ tab_group_class = (project_tabs.SSLcertificateDetailsTabs)
+ template_name = 'project/loadbalancers/details_tabs.html'
class UpdatePoolView(forms.ModalFormView):
@@ -289,6 +327,115 @@ def get_initial(self):
'admin_state_up': monitor['admin_state_up']}
+class UpdateSSLpolicyView(forms.ModalFormView):
+ form_class = project_forms.UpdateSSLpolicy
+ template_name = "project/loadbalancers/updatesslpolicy.html"
+ context_object_name = 'sslpolicy'
+ success_url = reverse_lazy("horizon:project:loadbalancers:index")
+
+ def get_context_data(self, **kwargs):
+ context = super(UpdateSSLpolicyView, self).get_context_data(**kwargs)
+ context["sslpolicy_id"] = self.kwargs['sslpolicy_id']
+ return context
+
+ def _get_object(self, *args, **kwargs):
+ if not hasattr(self, "_object"):
+ sslpolicy_id = self.kwargs['sslpolicy_id']
+ try:
+ self._object = api.lbaas.ssl_policy_get(
+ self.request, sslpolicy_id)
+ except Exception as e:
+ redirect = self.success_url
+ msg = _('Unable to retrieve SSL policy details. %s') % e
+ exceptions.handle(self.request, msg, redirect=redirect)
+ return self._object
+
+ def get_initial(self):
+ sslpolicy = self._get_object()
+ return {'sslpolicy_id': sslpolicy['id'],
+ 'name': sslpolicy['name'],
+ 'description': sslpolicy['description'],
+ 'front_end_enabled': sslpolicy['front_end_enabled'],
+ 'front_end_protocols': sslpolicy['front_end_protocols'].split(','),
+ 'front_end_cipher_suites': sslpolicy['front_end_cipher_suites']}
+ #'back_end_enabled': sslpolicy['back_end_enabled'],
+ #'back_end_cipher_suites': sslpolicy['back_end_cipher_suites']}
+
+
+class UpdateSSLcertificateView(forms.ModalFormView):
+ form_class = project_forms.UpdateSSLcertificate
+ template_name = "project/loadbalancers/updatesslcertificate.html"
+ context_object_name = 'sslcertificate'
+ success_url = reverse_lazy("horizon:project:loadbalancers:index")
+
+ def get_context_data(self, **kwargs):
+ context = super(UpdateSSLcertificateView, self).get_context_data(**kwargs)
+ context["sslcertificate_id"] = self.kwargs['sslcertificate_id']
+ return context
+
+ def _get_object(self, *args, **kwargs):
+ if not hasattr(self, "_object"):
+ sslcertificate_id = self.kwargs['sslcertificate_id']
+ try:
+ self._object = api.lbaas.ssl_certificate_get(
+ self.request, sslcertificate_id)
+ except Exception as e:
+ redirect = self.success_url
+ msg = _('Unable to retrieve SSL certificate details. %s') % e
+ exceptions.handle(self.request, msg, redirect=redirect)
+ return self._object
+
+ def get_initial(self):
+ sslcertificate = self._get_object()
+ return {'sslcertificate_id': sslcertificate['id'],
+ 'name': sslcertificate['name'],
+ 'passphrase': sslcertificate['passphrase'],
+ 'certificate_chain': sslcertificate['certificate_chain'],
+ 'certificate': sslcertificate['certificate']}
+
+class AssociateSSLPolicyView(workflows.WorkflowView):
+ workflow_class = project_workflows.AssociateSSLPolicy
+
+ def get_context_data(self, **kwargs):
+ context = super(AssociateSSLPolicyView, self).get_context_data(**kwargs)
+ context['vip_id'] = self.kwargs['vip_id']
+ return context
+
+ def get_initial(self):
+ initial = super(AssociateSSLPolicyView, self).get_initial()
+ initial['vip_id'] = self.kwargs['vip_id']
+ return initial
+
+
+class DisassociateSSLPolicyView(workflows.WorkflowView):
+ workflow_class = project_workflows.DisassociateSSLPolicy
+ ajax_template_name = "project/loadbalancers/disassociateSsl.html"
+
+ def get_context_data(self, **kwargs):
+ context = super(DisassociateSSLPolicyView, self).get_context_data(**kwargs)
+ context['vip_id'] = self.kwargs['vip_id']
+ return context
+
+ def _get_object(self, *args, **kwargs):
+ if not hasattr(self, "_object"):
+ vip_id = self.kwargs['vip_id']
+ try:
+ self._object = api.lbaas.vip_get(self.request, vip_id)
+ except Exception as e:
+ redirect = self.success_url
+ msg = _('Unable to retrieve VIP details. %s') % e
+ exceptions.handle(self.request, msg, redirect=redirect)
+ return self._object
+
+ def get_initial(self):
+ vip = self._get_object()
+ return {'vip_id':vip['id'],
+ 'ssl_policy_id': vip['ssl_policy_id'] }
+
+
+
+
+
class AddPMAssociationView(workflows.WorkflowView):
workflow_class = project_workflows.AddPMAssociation
diff --git a/openstack_dashboard/dashboards/project/loadbalancers/workflows.py b/openstack_dashboard/dashboards/project/loadbalancers/workflows.py
index b5d26d076a0..4720dca4160 100644
--- a/openstack_dashboard/dashboards/project/loadbalancers/workflows.py
+++ b/openstack_dashboard/dashboards/project/loadbalancers/workflows.py
@@ -493,6 +493,202 @@ class Meta:
"HTTP codes upon success.")
+FRONT_END_PROTOCOL_CHOICES = (
+ ('SSLv2','SSLv2'),
+ ('SSLv3','SSLv3'),
+ ('TLSv1','TLSv1'),
+ )
+
+class AddSSLpolicyAction(workflows.Action):
+ name = forms.CharField(max_length=80, label=_("Name"))
+ description = forms.CharField(
+ initial="", required=False,
+ max_length=80, label=_("Description"))
+
+ front_end_enabled = forms.BooleanField(label=_("Front End Enabled"),
+ initial=True, required=False)
+
+ front_end_cipher_suites = forms.ChoiceField(
+ label=_("Front End Cipher Suite"),
+ choices=[('ALL', _('ALL')),
+ ('HIGH', _('HIGH')),
+ ('MEDIUM', _('MEDIUM')),
+ ('LOW', _('LOW'))])
+
+ front_end_protocols = forms.TypedMultipleChoiceField(required=False,
+ label=_("Front End Protocols"),
+ empty_value='',
+ widget=forms.CheckboxSelectMultiple,
+ choices=FRONT_END_PROTOCOL_CHOICES)
+
+ """
+ back_end_enabled = forms.BooleanField(label=_("Back End Enabled"),
+ initial=True, required=False)
+
+ back_end_cipher_suites = forms.ChoiceField(
+ label=_("Back End Cipher Suite"),
+ choices=[('ALL', _('ALL')),
+ ('HIGH', _('HIGH')),
+ ('MEDIUM', _('MEDIUM')),
+ ('LOW', _('LOW'))])
+ """
+ def __init__(self, request, *args, **kwargs):
+ super(AddSSLpolicyAction, self).__init__(request, *args, **kwargs)
+
+ class Meta:
+ name = _("Add New SSL Policy")
+ permissions = ('openstack.services.network',)
+ help_text = _("Create a SSL Policy.\n\n")
+
+class AddSSLcertificateAction(workflows.Action):
+ name = forms.CharField(max_length=80, label=_("Name"))
+ passphrase = forms.CharField(
+ initial="", required=False,
+ label=_("Passphrase"))
+ certificate_chain = forms.CharField(
+ initial="", required=False,
+ label=_("Certificate Chain"))
+ certificate = forms.CharField(
+ initial="", required=False,
+ widget=forms.Textarea,
+ label=_("Certificate"))
+
+ def __init__(self, request, *args, **kwargs):
+ super(AddSSLcertificateAction, self).__init__(request, *args, **kwargs)
+
+ class Meta:
+ name = _("Add New SSL Certificate")
+ permissions = ('openstack.services.network',)
+ help_text = _("Create a SSL Certificate.\n\n")
+
+
+class AssociateSSLPolicyAction(workflows.Action):
+ ssl_policy_id = forms.ChoiceField(label=_("SSL Policy"), required=True)
+ ssl_certificate_id = forms.ChoiceField(label=_("SSL Certificate"), required=True)
+ private_key = forms.CharField(
+ widget=forms.widgets.Textarea(),
+ initial="", required=True,
+ max_length=2048, label=_("Certificate Private Key"))
+
+ def __init__(self, request, *args, **kwargs):
+ super(AssociateSSLPolicyAction, self).__init__(request, *args, **kwargs)
+
+ ssl_policy_id_choices = [('', _("Select a SSL Policy"))]
+ try:
+ tenant_id = self.request.user.tenant_id
+ ssl_policies = api.lbaas.ssl_policies_get(request, tenant_id=tenant_id)
+ except Exception:
+ ssl_policies = []
+ exceptions.handle(request,
+ _('Unable to retrieve SSL Policy list.'))
+ ssl_policies = sorted(ssl_policies,
+ key=lambda ssl_policy: ssl_policy.name)
+ for p in ssl_policies:
+ ssl_policy_id_choices.append((p.id, p.name))
+ self.fields['ssl_policy_id'].choices = ssl_policy_id_choices
+
+ ssl_certificate_id_choices = [('', _("Select SSL Certificate"))]
+ try:
+ tenant_id = self.request.user.tenant_id
+ ssl_certificates = api.lbaas.ssl_certificates_get(request, tenant_id=tenant_id)
+ except Exception:
+ ssl_certificates = []
+ exceptions.handle(request,
+ _('Unable to retrieve SSL Certificate list.'))
+ ssl_policies = sorted(ssl_certificates,
+ key=lambda ssl_certificate: ssl_certificate.name)
+ for p in ssl_certificates:
+ ssl_certificate_id_choices.append((p.id, p.name))
+ self.fields['ssl_certificate_id'].choices = ssl_certificate_id_choices
+
+ def clean(self):
+ cleaned_data = super(AssociateSSLPolicyAction, self).clean()
+ return cleaned_data
+
+ class Meta:
+ name = _("Associate SSL Policy with VIP")
+ permissions = ('openstack.services.network',)
+ help_text = _("Select an SSL Policy to associate with VIP. "
+ "Select SSL Certificate to be used. "
+ "Specify private key for chosen SSL certificate ")
+
+
+class AssociateSSLPolicyStep(workflows.Step):
+ action_class = AssociateSSLPolicyAction
+ depends_on = ("vip_id",)
+ contributes = ("ssl_policy_id", "ssl_certificate_id", "private_key")
+
+ def contribute(self, data, context):
+ context = super(AssociateSSLPolicyStep, self).contribute(data, context)
+ return context
+
+
+class AssociateSSLPolicy(workflows.Workflow):
+ slug = "associatesslpolicy"
+ name = _("Associate SSL Policy")
+ finalize_button_name = _("Associate")
+ success_message = _('Associated.')
+ failure_message = _('Unable to associate.')
+ success_url = "horizon:project:loadbalancers:index"
+ default_steps = (AssociateSSLPolicyStep,)
+
+ def format_status_message(self, message):
+ return message
+
+ def handle(self, request, context):
+ try:
+ api.lbaas.ssl_policy_associate(request, **context)
+ return True
+ except Exception:
+ raise
+ return False
+
+
+class DisassociateSSLPolicyAction(workflows.Action):
+
+ def __init__(self, request, *args, **kwargs):
+ super(DisassociateSSLPolicyAction, self).__init__(request, *args, **kwargs)
+
+ def clean(self):
+ cleaned_data = super(DisassociateSSLPolicyAction, self).clean()
+ return cleaned_data
+
+ class Meta:
+ name = _("Disassociate SSL Policy with VIP")
+ permissions = ('openstack.services.network',)
+ help_text = _( "Dissociate SSL Policy from VIP")
+
+
+class DisassociateSSLPolicyStep(workflows.Step):
+ action_class = DisassociateSSLPolicyAction
+ depends_on = ("vip_id", "ssl_policy_id", )
+
+ def contribute(self, data, context):
+ context = super(DisassociateSSLPolicyStep, self).contribute(data, context)
+ return context
+
+
+class DisassociateSSLPolicy(workflows.Workflow):
+ slug = "disassociatesslpolicy"
+ name = _("Confirm Disassociate SSL Policy")
+ finalize_button_name = _("Disassociate")
+ success_message = _('Disassociate.')
+ failure_message = _('Failed to disassociate.')
+ success_url = "horizon:project:loadbalancers:index"
+ default_steps = (DisassociateSSLPolicyStep,)
+
+ def format_status_message(self, message):
+ return message
+
+ def handle(self, request, context):
+ try:
+ api.lbaas.ssl_policy_disassociate(request, **context)
+ return True
+ except Exception:
+ raise
+ return False
+
+
class AddMonitorStep(workflows.Step):
action_class = AddMonitorAction
contributes = ("type", "delay", "timeout", "max_retries",
@@ -505,6 +701,25 @@ def contribute(self, data, context):
return context
+class AddSSLpolicyStep(workflows.Step):
+ action_class = AddSSLpolicyAction
+ contributes = ("name", "description", "front_end_enabled", "front_end_protocols", "front_end_cipher_suites")
+ #"back_end_enabled", "back_end_cipher_suites")
+
+ def contribute(self, data, context):
+ context = super(AddSSLpolicyStep, self).contribute(data, context)
+ if data:
+ return context
+
+class AddSSLcertificateStep(workflows.Step):
+ action_class = AddSSLcertificateAction
+ contributes = ("name", "certificate", "passphrase", "certificate_chain")
+
+ def contribute(self, data, context):
+ context = super(AddSSLcertificateStep, self).contribute(data, context)
+ if data:
+ return context
+
class AddMonitor(workflows.Workflow):
slug = "addmonitor"
name = _("Add Monitor")
@@ -524,6 +739,44 @@ def handle(self, request, context):
return False
+class AddSSLpolicy(workflows.Workflow):
+ slug = "addsslpolicy"
+ name = _("Add SSL Policy")
+ finalize_button_name = _("Add")
+ success_message = _('Added SSL policy')
+ failure_message = _('Unable to add SSL policy')
+ success_url = "horizon:project:loadbalancers:index"
+ default_steps = (AddSSLpolicyStep,)
+
+ def handle(self, request, context):
+ try:
+ front_end_protocols = ','.join(context['front_end_protocols'])
+ context['front_end_protocols'] = front_end_protocols
+ context['ssl_policy_id'] = api.lbaas.ssl_policy_create(
+ request, **context).get('id')
+ return True
+ except Exception:
+ exceptions.handle(request, _("Unable to add SSL policy."))
+ return False
+
+class AddSSLcertificate(workflows.Workflow):
+ slug = "addsslcertificate"
+ name = _("Add SSL Certificate")
+ finalize_button_name = _("Add")
+ success_message = _('Added SSL certificate')
+ failure_message = _('Unable to add SSL certificate')
+ success_url = "horizon:project:loadbalancers:index"
+ default_steps = (AddSSLcertificateStep,)
+
+ def handle(self, request, context):
+ try:
+ context['ssl_certificate_id'] = api.lbaas.ssl_certificate_create(
+ request, **context).get('id')
+ return True
+ except Exception:
+ exceptions.handle(request, _("Unable to add SSL certificate."))
+ return False
+
class MonitorMixin():
def _get_monitor_display_name(self, monitor):
diff --git a/openstack_dashboard/test/test_data/neutron_data.py b/openstack_dashboard/test/test_data/neutron_data.py
index f3d88c0b16b..95037d5c2bb 100644
--- a/openstack_dashboard/test/test_data/neutron_data.py
+++ b/openstack_dashboard/test/test_data/neutron_data.py
@@ -432,6 +432,7 @@ def add_rule_to_group(secgroup, default_only=True):
'session_persistence': {'type': 'APP_COOKIE',
'cookie_name': 'jssessionid'},
'connection_limit': 10,
+ 'ssl_policy_id':'b1909408-7d70-4fc8-80c2-5a149eceb369',
'admin_state_up': True}
TEST.api_vips.add(vip_dict)
TEST.vips.add(lbaas.Vip(vip_dict))
@@ -451,6 +452,7 @@ def add_rule_to_group(secgroup, default_only=True):
'session_persistence': {'type': 'APP_COOKIE',
'cookie_name': 'jssessionid'},
'connection_limit': 10,
+ 'ssl_policy_id':'b1909408-7d70-4fc8-80c2-5a149eceb379',
'admin_state_up': True}
TEST.api_vips.add(vip_dict)
TEST.vips.add(lbaas.Vip(vip_dict))