FWaaS Horizon panel

Implements: blueprint fwaas-horizon

Change-Id: I1017573887922b4dea0a42d46965de2b86325b0e
This commit is contained in:
KC Wang 2013-07-05 03:37:27 -07:00 committed by Akihiro MOTOKI
parent 46462b122e
commit 1255766344
39 changed files with 3109 additions and 5 deletions

View File

@ -0,0 +1,155 @@
horizon.firewalls = {
user_decided_length: false,
rules_selected: [],
rules_available: [],
getConsoleLog: function(via_user_submit) {
var form_element = $("#tail_length"),
data;
if (!via_user_submit) {
via_user_submit = false;
}
if(this.user_decided_length) {
data = $(form_element).serialize();
} else {
data = "length=35";
}
$.ajax({
url: $(form_element).attr('action'),
data: data,
method: 'get',
success: function(response_body) {
$('pre.logs').text(response_body);
},
error: function(response) {
if(via_user_submit) {
horizon.clearErrorMessages();
horizon.alert('error', gettext('There was a problem communicating with the server, please try again.'));
}
}
});
},
/*
* Gets the html select element associated with a given
* rule id for rule_id.
**/
get_rule_element: function(rule_id) {
return $('li > label[for^="id_rule_' + rule_id + '"]');
},
/*
* Initializes an associative array of lists of the current
* rules.
**/
init_rule_list: function() {
horizon.firewalls.rules_selected = [];
horizon.firewalls.rules_available = [];
$(this.get_rule_element("")).each(function(){
var $this = $(this);
var $input = $this.children("input");
var rule_property = {
name:$this.text().replace(/^\s+/,""),
id:$input.attr("id"),
value:$input.attr("value")
};
if($input.is(':checked')) {
horizon.firewalls.rules_selected.push(rule_property);
} else {
horizon.firewalls.rules_available.push(rule_property);
}
});
},
/*
* Generates the HTML structure for a rule that will be displayed
* as a list item in the rule list.
**/
generate_rule_element: function(name, id, value) {
var $li = $('<li>');
$li.attr('name', value).html(name + '<em class="rule_id">(' + value + ')</em><a href="#" class="btn btn-primary"></a>');
return $li;
},
/*
* Generates the HTML structure for the Rule List.
**/
generate_rulelist_html: function() {
var self = this;
var updateForm = function() {
var lists = $("#ruleListId div.input li").attr('data-index',100);
var active_rules = $("#selected_rule > li").map(function(){
return $(this).attr("name");
});
$("#ruleListId div.input input:checkbox").removeAttr('checked');
active_rules.each(function(index, value){
$("#ruleListId div.input input:checkbox[value=" + value + "]")
.attr('checked','checked')
.parents("li").attr('data-index',index);
});
$("#ruleListId div.input ul").html(
lists.sort(function(a,b){
if( $(a).data("index") < $(b).data("index")) return -1;
if( $(a).data("index") > $(b).data("index")) return 1;
return 0;
})
);
};
$("#ruleListSortContainer").show();
$("#ruleListIdContainer").hide();
self.init_rule_list();
// Make sure we don't duplicate the rules in the list
$("#available_rule").empty();
$.each(self.rules_available, function(index, value){
$("#available_rule").append(self.generate_rule_element(value.name, value.id, value.value));
});
// Make sure we don't duplicate the rules in the list
$("#selected_rule").empty();
$.each(self.rules_selected, function(index, value){
$("#selected_rule").append(self.generate_rule_element(value.name, value.id, value.value));
});
$(".rulelist > li > a.btn").click(function(e){
var $this = $(this);
e.preventDefault();
e.stopPropagation();
if($this.parents("ul#available_rule").length > 0) {
$this.parent().appendTo($("#selected_rule"));
} else if ($this.parents("ul#selected_rule").length > 0) {
$this.parent().appendTo($("#available_rule"));
}
updateForm();
});
if ($("#ruleListId > div.control-group.error").length > 0) {
var errortext = $("#ruleListId > div.control-group.error").find("span.help-inline").text();
$("#selected_rule_h4").before($('<div class="dynamic-error">').html(errortext));
}
$(".rulelist").sortable({
connectWith: "ul.rulelist",
placeholder: "ui-state-highlight",
distance: 5,
start:function(e,info){
$("#selected_rule").addClass("dragging");
},
stop:function(e,info){
$("#selected_rule").removeClass("dragging");
updateForm();
}
}).disableSelection();
},
workflow_init: function(modal) {
// Initialise the drag and drop rule list
horizon.firewalls.generate_rulelist_html();
}
};
horizon.addInitFunction(function () {
$(document).on('submit', '#tail_length', function (evt) {
horizon.firewalls.user_decided_length = true;
horizon.firewalls.getConsoleLog(true);
evt.preventDefault();
});
});

View File

@ -41,7 +41,7 @@
<script src='{{ STATIC_URL }}horizon/js/horizon.heattop.js' type='text/javascript' charset='utf-8'></script>
<script src='{{ STATIC_URL }}horizon/lib/rickshaw.js' type='text/javascript' charset='utf-8'></script>
<script src='{{ STATIC_URL }}horizon/js/horizon.d3linechart.js' type='text/javascript' charset='utf-8'></script>
<script src='{{ STATIC_URL }}horizon/js/horizon.firewalls.js' type='text/javascript' charset='utf-8'></script>
{% block custom_js_files %}{% endblock %}
{% endcompress %}

View File

@ -36,3 +36,16 @@ def password_validator():
def password_validator_msg():
return conf.HORIZON_CONFIG["password_validator"]["help_text"]
def validate_port_or_colon_separated_port_range(port_range):
"""accepts a port number or a single-colon separated range"""
if port_range.count(':') > 1:
raise ValidationError("One colon allowed in port range")
ports = port_range.split(':')
for port in ports:
try:
if int(port) not in range(-1, 65536):
raise ValidationError("Not a valid port number")
except ValueError:
raise ValidationError("Port number must be integer")

View File

@ -36,6 +36,7 @@ Keystone/Nova/Glance/Swift et. al.
from openstack_dashboard.api import base
from openstack_dashboard.api import ceilometer
from openstack_dashboard.api import cinder
from openstack_dashboard.api import fwaas
from openstack_dashboard.api import glance
from openstack_dashboard.api import heat
from openstack_dashboard.api import keystone
@ -49,13 +50,14 @@ from openstack_dashboard.api import vpn
assert base
assert cinder
assert heat
assert fwaas
assert glance
assert heat
assert keystone
assert network
assert nova
assert neutron
assert lbaas
assert network
assert neutron
assert nova
assert swift
assert ceilometer
assert trove

View File

@ -0,0 +1,184 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013, Big Switch Networks, Inc.
#
# 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.
from __future__ import absolute_import
from openstack_dashboard.api import neutron
neutronclient = neutron.neutronclient
class Rule(neutron.NeutronAPIDictWrapper):
"""Wrapper for neutron firewall rule"""
def get_dict(self):
rule_dict = self._apidict
rule_dict['rule_id'] = rule_dict['id']
return rule_dict
class Policy(neutron.NeutronAPIDictWrapper):
"""Wrapper for neutron firewall policy"""
def get_dict(self):
policy_dict = self._apidict
policy_dict['policy_id'] = policy_dict['id']
return policy_dict
class Firewall(neutron.NeutronAPIDictWrapper):
"""Wrapper for neutron firewall"""
def get_dict(self):
firewall_dict = self._apidict
firewall_dict['firewall_id'] = firewall_dict['id']
return firewall_dict
def rule_create(request, **kwargs):
"""Create a firewall rule
:param request: request context
:param name: name for rule
:param description: description for rule
:param protocol: protocol for rule
:param action: action for rule
:param source_ip_address: source IP address or subnet
:param source_port: integer in [1, 65535] or range in a:b
:param destination_ip_address: destination IP address or subnet
:param destination_port: integer in [1, 65535] or range in a:b
:param shared: boolean (default false)
:param enabled: boolean (default true)
:return: Rule object
"""
body = {'firewall_rule': kwargs}
rule = neutronclient(request).create_firewall_rule(
body).get('firewall_rule')
return Rule(rule)
def rules_list(request, **kwargs):
rules = neutronclient(request).list_firewall_rules(
**kwargs).get('firewall_rules')
return [Rule(r) for r in rules]
def rule_get(request, rule_id):
rule = neutronclient(request).show_firewall_rule(
rule_id).get('firewall_rule')
return Rule(rule)
def rule_delete(request, rule_id):
neutronclient(request).delete_firewall_rule(rule_id)
def rule_update(request, rule_id, **kwargs):
body = {'firewall_rule': kwargs}
rule = neutronclient(request).update_firewall_rule(
rule_id, body).get('firewall_rule')
return Rule(rule)
def policy_create(request, **kwargs):
"""Create a firewall policy
:param request: request context
:param name: name for policy
:param description: description for policy
:param firewall_rules: ordered list of rules in policy
:param shared: boolean (default false)
:param audited: boolean (default false)
:return: Policy object
"""
body = {'firewall_policy': kwargs}
policy = neutronclient(request).create_firewall_policy(
body).get('firewall_policy')
return Policy(policy)
def policies_list(request, **kwargs):
policies = neutronclient(request).list_firewall_policies(
**kwargs).get('firewall_policies')
return [Policy(p) for p in policies]
def policy_get(request, policy_id):
policy = neutronclient(request).show_firewall_policy(
policy_id).get('firewall_policy')
return Policy(policy)
def policy_delete(request, policy_id):
neutronclient(request).delete_firewall_policy(policy_id)
def policy_update(request, policy_id, **kwargs):
body = {'firewall_policy': kwargs}
policy = neutronclient(request).update_firewall_policy(
policy_id, body).get('firewall_policy')
return Policy(policy)
def policy_insert_rule(request, policy_id, **kwargs):
policy = neutronclient(request).firewall_policy_insert_rule(
policy_id, kwargs)
return Policy(policy)
def policy_remove_rule(request, policy_id, **kwargs):
policy = neutronclient(request).firewall_policy_remove_rule(
policy_id, kwargs)
return Policy(policy)
def firewall_create(request, **kwargs):
"""Create a firewall for specified policy
:param request: request context
:param name: name for firewall
:param description: description for firewall
:param firewall_policy_id: policy id used by firewall
:param shared: boolean (default false)
:param admin_state_up: boolean (default true)
:return: Firewall object
"""
body = {'firewall': kwargs}
firewall = neutronclient(request).create_firewall(body).get('firewall')
return Firewall(firewall)
def firewalls_list(request, **kwargs):
firewalls = neutronclient(request).list_firewalls(
**kwargs).get('firewalls')
return [Firewall(f) for f in firewalls]
def firewall_get(request, firewall_id):
firewall = neutronclient(request).show_firewall(
firewall_id).get('firewall')
return Firewall(firewall)
def firewall_delete(request, firewall_id):
neutronclient(request).delete_firewall(firewall_id)
def firewall_update(request, firewall_id, **kwargs):
body = {'firewall': kwargs}
firewall = neutronclient(request).update_firewall(
firewall_id, body).get('firewall')
return Firewall(firewall)

View File

@ -35,6 +35,7 @@ class NetworkPanels(horizon.PanelGroup):
panels = ('networks',
'routers',
'loadbalancers',
'firewalls',
'network_topology',
'vpn',)

View File

@ -0,0 +1,304 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013, Big Switch Networks, Inc
#
# 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.
#
# @author: KC Wang
import logging
from django.core.urlresolvers import reverse # noqa
from django.utils.translation import ugettext_lazy as _ # noqa
from horizon import exceptions
from horizon import forms
from horizon import messages
from horizon.utils import fields
from horizon.utils import validators
from openstack_dashboard import api
port_validator = validators.validate_port_or_colon_separated_port_range
LOG = logging.getLogger(__name__)
class UpdateRule(forms.SelfHandlingForm):
name = forms.CharField(max_length=80, label=_("Name"), required=False)
description = forms.CharField(
required=False,
max_length=80, label=_("Description"))
protocol = forms.ChoiceField(
label=_("Protocol"), required=False,
help_text=_('Protocol for the firewall rule'))
action = forms.ChoiceField(
label=_("Action"), required=False,
help_text=_('Action for the firewall rule'))
source_ip_address = fields.IPField(
label=_("Source IP Address/Subnet"),
version=fields.IPv4 | fields.IPv6,
required=False, mask=True,
help_text=_('Source IP address or subnet'))
destination_ip_address = fields.IPField(
label=_('Destination IP Address/Subnet'),
version=fields.IPv4 | fields.IPv6,
required=False, mask=True,
help_text=_('Destination IP address or subnet'))
source_port = forms.CharField(
max_length=80,
label=_("Source Port/Port Range"),
required=False,
validators=[port_validator],
help_text=_('Source port (integer in [1, 65535] or range in a:b)'))
destination_port = forms.CharField(
max_length=80,
label=_("Destination Port/Port Range"),
required=False,
validators=[port_validator],
help_text=_('Destination port (integer in [1, 65535] or range'
'in a:b)'))
shared = forms.BooleanField(label=_("Shared"), required=False)
enabled = forms.BooleanField(label=_("Enabled"), required=False)
failure_url = 'horizon:project:firewalls:index'
def __init__(self, request, *args, **kwargs):
super(UpdateRule, self).__init__(request, *args, **kwargs)
protocol = kwargs['initial']['protocol'].upper()
action = kwargs['initial']['action'].upper()
protocol_choices = [(protocol, protocol)]
for tup in [('TCP', _('TCP')), ('UDP', _('UDP')), ('ICMP', _('ICMP'))]:
if tup[0] != protocol:
protocol_choices.append(tup)
self.fields['protocol'].choices = protocol_choices
action_choices = [(action, action)]
for tup in [('ALLOW', _('ALLOW')), ('DENY', _('DENY'))]:
if tup[0] != action:
action_choices.append(tup)
self.fields['action'].choices = action_choices
def handle(self, request, context):
rule_id = self.initial['rule_id']
name_or_id = context.get('name') or rule_id
for f in ['source_ip_address', 'destination_ip_address',
'source_port', 'destination_port']:
if not context[f]:
context[f] = None
try:
rule = api.fwaas.rule_update(request, rule_id, **context)
msg = _('Rule %s was successfully updated.') % name_or_id
LOG.debug(msg)
messages.success(request, msg)
return rule
except Exception as e:
msg = _('Failed to update rule %(name)s: %(reason)s' %
{'name': name_or_id, 'reason': e})
LOG.error(msg)
redirect = reverse(self.failure_url)
exceptions.handle(request, msg, redirect=redirect)
class UpdatePolicy(forms.SelfHandlingForm):
name = forms.CharField(max_length=80, label=_("Name"), required=False)
description = forms.CharField(required=False,
max_length=80, label=_("Description"))
shared = forms.BooleanField(label=_("Shared"), required=False)
audited = forms.BooleanField(label=_("Audited"), required=False)
failure_url = 'horizon:project:firewalls:index'
def handle(self, request, context):
policy_id = self.initial['policy_id']
name_or_id = context.get('name') or policy_id
try:
policy = api.fwaas.policy_update(request, policy_id, **context)
msg = _('Policy %s was successfully updated.') % name_or_id
LOG.debug(msg)
messages.success(request, msg)
return policy
except Exception as e:
msg = _('Failed to update policy %(name)s: %(reason)s' %
{'name': name_or_id, 'reason': e})
LOG.error(msg)
redirect = reverse(self.failure_url)
exceptions.handle(request, msg, redirect=redirect)
class UpdateFirewall(forms.SelfHandlingForm):
name = forms.CharField(max_length=80,
label=_("Name"),
required=False)
description = forms.CharField(max_length=80,
label=_("Description"),
required=False)
firewall_policy_id = forms.ChoiceField(label=_("Policy"),
required=True)
admin_state_up = forms.BooleanField(label=_("Admin State Up"),
required=False)
failure_url = 'horizon:project:firewalls:index'
def __init__(self, request, *args, **kwargs):
super(UpdateFirewall, self).__init__(request, *args, **kwargs)
try:
tenant_id = self.request.user.tenant_id
policies = api.fwaas.policies_list(request, tenant_id=tenant_id)
policies = sorted(policies, key=lambda policy: policy.name)
except Exception:
exceptions.handle(request,
_('Unable to retrieve policy list.'))
policies = []
policy_id = kwargs['initial']['firewall_policy_id']
policy_name = [p.name for p in policies if p.id == policy_id][0]
firewall_policy_id_choices = [(policy_id, policy_name)]
for p in policies:
if p.id != policy_id:
p.set_id_as_name_if_empty()
firewall_policy_id_choices.append((p.id, p.name))
self.fields['firewall_policy_id'].choices = firewall_policy_id_choices
def handle(self, request, context):
firewall_id = self.initial['firewall_id']
name_or_id = context.get('name') or firewall_id
try:
firewall = api.fwaas.firewall_update(request, firewall_id,
**context)
msg = _('Firewall %s was successfully updated.') % name_or_id
LOG.debug(msg)
messages.success(request, msg)
return firewall
except Exception as e:
msg = _('Failed to update firewall %(name)s: %(reason)s' %
{'name': name_or_id, 'reason': e})
LOG.error(msg)
redirect = reverse(self.failure_url)
exceptions.handle(request, msg, redirect=redirect)
class InsertRuleToPolicy(forms.SelfHandlingForm):
firewall_rule_id = forms.ChoiceField(label=_("Insert Rule"))
insert_before = forms.ChoiceField(label=_("Before"),
required=False)
insert_after = forms.ChoiceField(label=_("After"),
required=False)
failure_url = 'horizon:project:firewalls:index'
def __init__(self, request, *args, **kwargs):
super(InsertRuleToPolicy, self).__init__(request, *args, **kwargs)
tenant_id = self.request.user.tenant_id
try:
all_rules = api.fwaas.rules_list(request, tenant_id=tenant_id)
for r in all_rules:
r.set_id_as_name_if_empty()
all_rules = sorted(all_rules, key=lambda rule: rule.name)
available_rules = [r for r in all_rules
if not r.firewall_policy_id]
current_rules = []
for r in kwargs['initial']['firewall_rules']:
r_obj = [rule for rule in all_rules if r == rule.id][0]
current_rules.append(r_obj)
available_choices = [(r.id, r.name) for r in available_rules]
current_choices = [(r.id, r.name) for r in current_rules]
except Exception as e:
msg = _('Failed to retrieve available rules: %s') % e
LOG.error(msg)
redirect = reverse(self.failure_url)
exceptions.handle(request, msg, redirect=redirect)
self.fields['firewall_rule_id'].choices = available_choices
self.fields['insert_before'].choices = [('', '')] + current_choices
self.fields['insert_after'].choices = [('', '')] + current_choices
def handle(self, request, context):
policy_id = self.initial['policy_id']
try:
body = {'firewall_rule_id': context['firewall_rule_id'],
'insert_before': context['insert_before'],
'insert_after': context['insert_after']}
policy = api.fwaas.policy_insert_rule(request, policy_id, **body)
msg = _('Rule %(rule)s was successfully inserted to policy '
'%(policy)s.' %
{'rule': context['firewall_rule_id'], 'policy': policy_id})
LOG.debug(msg)
messages.success(request, msg)
return policy
except Exception as e:
msg = _('Failed to insert rule to policy %(name)s: %(reason)s' %
{'name': policy_id, 'reason': e})
LOG.error(msg)
redirect = reverse(self.failure_url)
exceptions.handle(request, msg, redirect=redirect)
class RemoveRuleFromPolicy(forms.SelfHandlingForm):
firewall_rule_id = forms.ChoiceField(label=_("Remove Rule"),
required=False)
failure_url = 'horizon:project:firewalls:index'
def __init__(self, request, *args, **kwargs):
super(RemoveRuleFromPolicy, self).__init__(request, *args, **kwargs)
tenant_id = request.user.tenant_id
try:
all_rules = api.fwaas.rules_list(request, tenant_id=tenant_id)
for r in all_rules:
r.set_id_as_name_if_empty()
current_rules = []
for r in kwargs['initial']['firewall_rules']:
r_obj = [rule for rule in all_rules if r == rule.id][0]
current_rules.append(r_obj)
current_choices = [(r.id, r.name) for r in current_rules]
except Exception as e:
msg = _('Failed to retrieve current rules in policy %(name)s: '
'%(reason)s' %
{'name': self.initial['name'], 'reason': e})
LOG.error(msg)
redirect = reverse(self.failure_url)
exceptions.handle(request, msg, redirect=redirect)
self.fields['firewall_rule_id'].choices = current_choices
def handle(self, request, context):
policy_id = self.initial['policy_id']
try:
body = {'firewall_rule_id': context['firewall_rule_id'], }
policy = api.fwaas.policy_remove_rule(request, policy_id, **body)
msg = _('Rule %(rule)s was successfully removed from policy '
'%(policy)s.' %
{'rule': context['firewall_rule_id'],
'policy': self.initial['name']})
LOG.debug(msg)
messages.success(request, msg)
return policy
except Exception as e:
msg = _('Failed to remove rule from policy %(name)s: %(reason)s' %
{'name': self.initial['name'], 'reason': e})
LOG.error(msg)
redirect = reverse(self.failure_url)
exceptions.handle(request, msg, redirect=redirect)

View File

@ -0,0 +1,18 @@
from django.conf import settings # noqa
from django.utils.translation import ugettext_lazy as _ # noqa
import horizon
from openstack_dashboard.dashboards.project import dashboard
class Firewall(horizon.Panel):
name = _("Firewalls")
slug = "firewalls"
permissions = ('openstack.services.network',)
if getattr(settings,
'OPENSTACK_NEUTRON_NETWORK',
{}).get('enable_firewall', False):
dashboard.Project.register(Firewall)

View File

@ -0,0 +1,187 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013, Big Switch Networks, Inc.
#
# 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.
#
# @author: KC Wang, Big Switch Networks
import logging
from django.core.urlresolvers import reverse # noqa
from django.utils.translation import ugettext as _ # noqa
from horizon import tables
LOG = logging.getLogger(__name__)
class AddRuleLink(tables.LinkAction):
name = "addrule"
verbose_name = _("Add Rule")
url = "horizon:project:firewalls:addrule"
classes = ("ajax-modal", "btn-create",)
class AddPolicyLink(tables.LinkAction):
name = "addpolicy"
verbose_name = _("Add Policy")
url = "horizon:project:firewalls:addpolicy"
classes = ("ajax-modal", "btn-addpolicy",)
class AddFirewallLink(tables.LinkAction):
name = "addfirewall"
verbose_name = _("Create Firewall")
url = "horizon:project:firewalls:addfirewall"
classes = ("ajax-modal", "btn-addfirewall",)
class DeleteRuleLink(tables.DeleteAction):
name = "deleterule"
action_present = _("Delete")
action_past = _("Scheduled deletion of")
data_type_singular = _("Rule")
data_type_plural = _("Rules")
class DeletePolicyLink(tables.DeleteAction):
name = "deletepolicy"
action_present = _("Delete")
action_past = _("Scheduled deletion of")
data_type_singular = _("Policy")
data_type_plural = _("Policies")
class DeleteFirewallLink(tables.DeleteAction):
name = "deletefirewall"
action_present = _("Delete")
action_past = _("Scheduled deletion of")
data_type_singular = _("Firewall")
data_type_plural = _("Firewalls")
class UpdateRuleLink(tables.LinkAction):
name = "updaterule"
verbose_name = _("Edit Rule")
classes = ("ajax-modal", "btn-update",)
def get_link_url(self, rule):
base_url = reverse("horizon:project:firewalls:updaterule",
kwargs={'rule_id': rule.id})
return base_url
class UpdatePolicyLink(tables.LinkAction):
name = "updatepolicy"
verbose_name = _("Edit Policy")
classes = ("ajax-modal", "btn-update",)
def get_link_url(self, policy):
base_url = reverse("horizon:project:firewalls:updatepolicy",
kwargs={'policy_id': policy.id})
return base_url
class UpdateFirewallLink(tables.LinkAction):
name = "updatefirewall"
verbose_name = _("Edit Firewall")
classes = ("ajax-modal", "btn-update",)
def get_link_url(self, firewall):
base_url = reverse("horizon:project:firewalls:updatefirewall",
kwargs={'firewall_id': firewall.id})
return base_url
class InsertRuleToPolicyLink(tables.LinkAction):
name = "insertrule"
verbose_name = _("Insert Rule")
classes = ("ajax-modal", "btn-update",)
def get_link_url(self, policy):
base_url = reverse("horizon:project:firewalls:insertrule",
kwargs={'policy_id': policy.id})
return base_url
class RemoveRuleFromPolicyLink(tables.LinkAction):
name = "removerule"
verbose_name = _("Remove Rule")
classes = ("ajax-modal", "btn-update",)
def get_link_url(self, policy):
base_url = reverse("horizon:project:firewalls:removerule",
kwargs={'policy_id': policy.id})
return base_url
class RulesTable(tables.DataTable):
name = tables.Column("name",
verbose_name=_("Name"),
link="horizon:project:firewalls:ruledetails")
protocol = tables.Column("protocol",
verbose_name=_("Protocol"))
source_ip_address = tables.Column("source_ip_address",
verbose_name=_("Source IP"))
source_port = tables.Column("source_port",
verbose_name=_("Source Port"))
destination_ip_address = tables.Column("destination_ip_address",
verbose_name=_("Destination IP"))
destination_port = tables.Column("destination_port",
verbose_name=_("Destination Port"))
action = tables.Column("action",
verbose_name=_("Action"))
enabled = tables.Column("enabled",
verbose_name=_("Enabled"))
firewall_policy_id = tables.Column("firewall_policy_id",
verbose_name=_("In Policy"))
class Meta:
name = "rulestable"
verbose_name = _("Rules")
table_actions = (AddRuleLink, DeleteRuleLink)
row_actions = (UpdateRuleLink, DeleteRuleLink)
class PoliciesTable(tables.DataTable):
name = tables.Column("name",
verbose_name=_("Name"),
link="horizon:project:firewalls:policydetails")
firewall_rules = tables.Column("firewall_rules",
verbose_name=_("Rules"))
audited = tables.Column("audited",
verbose_name=_("Audited"))
class Meta:
name = "policiestable"
verbose_name = _("Policies")
table_actions = (AddPolicyLink, DeletePolicyLink)
row_actions = (UpdatePolicyLink, InsertRuleToPolicyLink,
RemoveRuleFromPolicyLink, DeletePolicyLink)
class FirewallsTable(tables.DataTable):
name = tables.Column("name",
verbose_name=_("Name"),
link="horizon:project:firewalls:firewalldetails")
firewall_policy_id = tables.Column("firewall_policy_id",
verbose_name=_("Policy"))
status = tables.Column("status",
verbose_name=_("Status"))
class Meta:
name = "firewallstable"
verbose_name = _("Firewalls")
table_actions = (AddFirewallLink, DeleteFirewallLink)
row_actions = (UpdateFirewallLink, DeleteFirewallLink)

View File

@ -0,0 +1,161 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013, Big Switch Networks, Inc.
#
# 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.
#
# @author: KC Wang, Big Switch Networks
from django.utils.translation import ugettext as _ # noqa
from horizon import exceptions
from horizon import tabs
from openstack_dashboard import api
from openstack_dashboard.dashboards.project.firewalls import tables
FirewallsTable = tables.FirewallsTable
PoliciesTable = tables.PoliciesTable
RulesTable = tables.RulesTable
class RulesTab(tabs.TableTab):
table_classes = (RulesTable,)
name = _("Firewall Rules")
slug = "rules"
template_name = "horizon/common/_detail_table.html"
def get_rulestable_data(self):
try:
tenant_id = self.request.user.tenant_id
rules = api.fwaas.rules_list(self.tab_group.request,
tenant_id=tenant_id)
except Exception:
rules = []
exceptions.handle(self.tab_group.request,
_('Unable to retrieve rules list.'))
for r in rules:
r.set_id_as_name_if_empty()
return rules
class PoliciesTab(tabs.TableTab):
table_classes = (PoliciesTable,)
name = _("Firewall Policies")
slug = "policies"
template_name = "horizon/common/_detail_table.html"
def get_policiestable_data(self):
try:
tenant_id = self.request.user.tenant_id
policies = api.fwaas.policies_list(self.tab_group.request,
tenant_id=tenant_id)
except Exception:
policies = []
exceptions.handle(self.tab_group.request,
_('Unable to retrieve policies list.'))
for p in policies:
p.set_id_as_name_if_empty()
return policies
class FirewallsTab(tabs.TableTab):
table_classes = (FirewallsTable,)
name = _("Firewalls")
slug = "firewalls"
template_name = "horizon/common/_detail_table.html"
def get_firewallstable_data(self):
try:
tenant_id = self.request.user.tenant_id
firewalls = api.fwaas.firewalls_list(self.tab_group.request,
tenant_id=tenant_id)
except Exception:
firewalls = []
exceptions.handle(self.tab_group.request,
_('Unable to retrieve firewall list.'))
for f in firewalls:
f.set_id_as_name_if_empty()
return firewalls
class RuleDetailsTab(tabs.Tab):
name = _("Firewall Rule Details")
slug = "ruledetails"
template_name = "project/firewalls/_rule_details.html"
def get_context_data(self, request):
rid = self.tab_group.kwargs['rule_id']
try:
rule = api.fwaas.rule_get(request, rid)
except Exception:
rule = []
exceptions.handle(request,
_('Unable to retrieve rule details.'))
return {'rule': rule}
class PolicyDetailsTab(tabs.Tab):
name = _("Firewall Policy Details")
slug = "policydetails"
template_name = "project/firewalls/_policy_details.html"
def get_context_data(self, request):
pid = self.tab_group.kwargs['policy_id']
try:
policy = api.fwaas.policy_get(request, pid)
except Exception:
policy = []
exceptions.handle(request,
_('Unable to retrieve policy details.'))
return {'policy': policy}
class FirewallDetailsTab(tabs.Tab):
name = _("Firewall Details")
slug = "firewalldetails"
template_name = "project/firewalls/_firewall_details.html"
def get_context_data(self, request):
fid = self.tab_group.kwargs['firewall_id']
try:
firewall = api.fwaas.firewall_get(request, fid)
except Exception:
firewall = []
exceptions.handle(self.tab_group.request,
_('Unable to retrieve firewall details.'))
return {'firewall': firewall}
class FirewallTabs(tabs.TabGroup):
slug = "fwtabs"
tabs = (FirewallsTab, PoliciesTab, RulesTab)
sticky = True
class RuleDetailsTabs(tabs.TabGroup):
slug = "ruletabs"
tabs = (RuleDetailsTab,)
class PolicyDetailsTabs(tabs.TabGroup):
slug = "policytabs"
tabs = (PolicyDetailsTab,)
class FirewallDetailsTabs(tabs.TabGroup):
slug = "firewalltabs"
tabs = (FirewallDetailsTab,)

View File

@ -0,0 +1,31 @@
{% load i18n sizeformat parse_date %}
{% load url from future %}
<div class="info row-fluid detail">
<hr class="header_rule">
<dl>
<dt>{% trans "Name" %}</dt>
<dd>{{ firewall.name|default:_("None") }}</dd>
<dt>{% trans "Description" %}</dt>
<dd>{{ firewall.description|default:_("None") }}</dd>
<dt>{% trans "ID" %}</dt>
<dd>{{ firewall.id }} </dd>
<dt>{% trans "Project ID" %}</dt>
<dd>{{ firewall.tenant_id }}</dd>
<dt>{% trans "Policy ID" %}</dt>
<dd>
{% url 'horizon:project:firewalls:policydetails' firewall.firewall_policy_id as policy_url%}
<a href="{{ policy_url }}">{{ firewall.firewall_policy_id }}</a>
</dd>
<dt>{% trans "Status" %}</dt>
<dd>{{ firewall.status }}</dd>
<dt>{% trans "Admin State Up" %}</dt>
<dd>{{ firewall.admin_state_up }}</dd>
</dl>
</div>

View File

@ -0,0 +1,28 @@
{% extends "horizon/common/_modal_form.html" %}
{% load i18n %}
{% load url from future %}
{% block form_id %}update_policy_form{% endblock %}
{% block form_action %}{% url 'horizon:project:firewalls:insertrule' policy_id %}{% endblock %}
{% block modal-header %}{% trans "Insert Rule to Policy" %}{% endblock %}
{% block modal-body %}
<div class="left">
<fieldset>
{% include "horizon/common/_form_fields.html" %}
</fieldset>
</div>
<div class="right">
<h3>{% trans "Description:" %}</h3>
<p>{% blocktrans %}Choose the rule you want to insert. Specify
either the rule you want to insert immediately before, or the rule
to insert immediately after. If both are specified, the prior
takes precedence.{% endblocktrans %}</p>
</div>
{% endblock %}
{% block modal-footer %}
<input class="btn btn-primary pull-right" type="submit" value="{% trans "Save Changes" %}" />
<a href="{% url 'horizon:project:firewalls:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
{% endblock %}

View File

@ -0,0 +1,27 @@
{% load i18n sizeformat parse_date %}
<div class="info row-fluid detail">
<hr class="header_rule">
<dl>
<dt>{% trans "Name" %}</dt>
<dd>{{ policy.name|default:_("None") }}</dd>
<dt>{% trans "Description" %}</dt>
<dd>{{ policy.description|default:_("None") }}</dd>
<dt>{% trans "ID" %}</dt>
<dd>{{ policy.id }}</dd>
<dt>{% trans "Project ID" %}</dt>
<dd>{{ policy.tenant_id }}</dd>
<dt>{% trans "Rules" %}</dt>
<dd>{{ policy.firewall_rules }}</dd>
<dt>{% trans "Shared" %}</dt>
<dd>{{ policy.shared }}</dd>
<dt>{% trans "Audited" %}</dt>
<dd>{{ policy.audited }}</dd>
</dl>
</div>

View File

@ -0,0 +1,25 @@
{% extends "horizon/common/_modal_form.html" %}
{% load i18n %}
{% load url from future %}
{% block form_id %}update_policy_form{% endblock %}
{% block form_action %}{% url 'horizon:project:firewalls:removerule' policy_id %}{% endblock %}
{% block modal-header %}{% trans "Remove Rule from Policy" %}{% endblock %}
{% block modal-body %}
<div class="left">
<fieldset>
{% include "horizon/common/_form_fields.html" %}
</fieldset>
</div>
<div class="right">
<h3>{% trans "Description:" %}</h3>
<p>{% trans "Choose the rule you want to remove." %}</p>
</div>
{% endblock %}
{% block modal-footer %}
<input class="btn btn-primary pull-right" type="submit" value="{% trans "Save Changes" %}" />
<a href="{% url 'horizon:project:firewalls:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
{% endblock %}

View File

@ -0,0 +1,52 @@
{% load i18n sizeformat parse_date %}
{% load url from future %}
<div class="info row-fluid detail">
<hr class="header_rule">
<dl>
<dt>{% trans "Name" %}</dt>
<dd>{{ rule.name|default:_("None") }}</dd>
<dt>{% trans "Description" %}</dt>
<dd>{{ rule.description|default:_("None") }}</dd>
<dt>{% trans "ID" %}</dt>
<dd>{{ rule.id }}</dd>
<dt>{% trans "Project ID" %}</dt>
<dd>{{ rule.tenant_id }}</dd>
<dt>{% trans "Action" %}</dt>
<dd>{{ rule.action }}</dd>
<dt>{% trans "Protocol" %}</dt>
<dd>{{ rule.protocol }}</dd>
<dt>{% trans "Source IP Address" %}</dt>
<dd>{{ rule.source_ip_address }}</dd>
<dt>{% trans "Source Port" %}</dt>
<dd>{{ rule.source_port }}</dd>
<dt>{% trans "Destination IP Address" %}</dt>
<dd>{{ rule.destination_ip_address }}</dd>
<dt>{% trans "Destination Port: "%}</dt>
<dd>{{ rule.destination_port }}</dd>
<dt>{% trans "Used in Policy" %}</dt>
<dd>
{% url 'horizon:project:firewalls:policydetails' rule.firewall_policy_id as policy_url%}
<a href="{{ policy_url }}">{{ rule.firewall_policy_id }}</a>
</dd>
<dt>{% trans "Position in Policy" %}</dt>
<dd>{{ rule.position }}</dd>
<dt>{% trans "Shared" %}</dt>
<dd>{{ rule.shared }}</dd>
<dt>{% trans "Enabled" %}</dt>
<dd>{{ rule.enabled }}</dd>
</dl>
</div>

View File

@ -0,0 +1,4 @@
{% load i18n horizon %}
<p>{% blocktrans %}Choose rule(s) from Available Rules to Selected Rule by push button or drag and drop,
you may change their order by drag and drop as well. {% endblocktrans %}</p>

View File

@ -0,0 +1,45 @@
{% load i18n %}
<noscript><h3>{{ step }}</h3></noscript>
<table class="table-fixed" id="ruleListSortContainer">
<tbody>
<tr>
<td class="actions">
<h4 id="selected_rule_h4">{% trans "Selected Rules" %}</h4>
<ul id="selected_rule" class="rulelist">
</ul>
<h4>{% trans "Available Rules" %}</h4>
<ul id="available_rule" class="rulelist">
</ul>
</td>
<td class="help_text">
{% include "project/firewalls/_update_rule_help.html" %}
</td>
</tr>
</tbody>
</table>
<table class="table-fixed" id="ruleListIdContainer">
<tbody>
<tr>
<td class="actions">
<div id="ruleListId">
{% include "horizon/common/_form_fields.html" %}
</div>
</td>
<td class="help_text">
{{ step.get_help_text }}
</td>
</tr>
</tbody>
</table>
<script>
if (typeof $ !== 'undefined') {
horizon.firewalls.workflow_init($(".workflow"));
} else {
addHorizonLoadEvent(function() {
horizon.firewalls.workflow_init($(".workflow"));
});
}
</script>

View File

@ -0,0 +1,25 @@
{% extends "horizon/common/_modal_form.html" %}
{% load i18n %}
{% load url from future %}
{% block form_id %}update_firewall_form{% endblock %}
{% block form_action %}{% url 'horizon:project:firewalls:updatefirewall' firewall_id %}{% endblock %}
{% block modal-header %}{% trans "Edit Firewall" %}{% endblock %}
{% block modal-body %}
<div class="left">
<fieldset>
{% include "horizon/common/_form_fields.html" %}
</fieldset>
</div>
<div class="right">
<h3>{% trans "Description:" %}</h3>
<p>{% trans "You may update firewall details here." %}</p>
</div>
{% endblock %}
{% block modal-footer %}
<input class="btn btn-primary pull-right" type="submit" value="{% trans "Save Changes" %}" />
<a href="{% url 'horizon:project:firewalls:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
{% endblock %}

View File

@ -0,0 +1,25 @@
{% extends "horizon/common/_modal_form.html" %}
{% load i18n %}
{% load url from future %}
{% block form_id %}update_policy_form{% endblock %}
{% block form_action %}{% url 'horizon:project:firewalls:updatepolicy' policy_id %}{% endblock %}
{% block modal-header %}{% trans "Edit Policy" %}{% endblock %}
{% block modal-body %}
<div class="left">
<fieldset>
{% include "horizon/common/_form_fields.html" %}
</fieldset>
</div>
<div class="right">
<h3>{% trans "Description:" %}</h3>
<p>{% trans "You may update policy details here. Use 'Insert Rule' or 'Remove Rule' links instead to insert or remove a rule" %}</p>
</div>
{% endblock %}
{% block modal-footer %}
<input class="btn btn-primary pull-right" type="submit" value="{% trans "Save Changes" %}" />
<a href="{% url 'horizon:project:firewalls:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
{% endblock %}

View File

@ -0,0 +1,25 @@
{% extends "horizon/common/_modal_form.html" %}
{% load i18n %}
{% load url from future %}
{% block form_id %}update_rule_form{% endblock %}
{% block form_action %}{% url 'horizon:project:firewalls:updaterule' rule_id %}{% endblock %}
{% block modal-header %}{% trans "Edit Rule" %}{% endblock %}
{% block modal-body %}
<div class="left">
<fieldset>
{% include "horizon/common/_form_fields.html" %}
</fieldset>
</div>
<div class="right">
<h3>{% trans "Description:" %}</h3>
<p>{% trans "You may update rule details here." %}</p>
</div>
{% endblock %}
{% block modal-footer %}
<input class="btn btn-primary pull-right" type="submit" value="{% trans "Save Changes" %}" />
<a href="{% url 'horizon:project:firewalls:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
{% endblock %}

View File

@ -0,0 +1,11 @@
{% extends 'base.html' %}
{% load i18n %}
{% block title %}{% trans "Add New Firewall" %}{% endblock %}
{% block page_header %}
{% include "horizon/common/_page_header.html" with title=_("Add New Firewall") %}
{% endblock page_header %}
{% block main %}
{% include 'horizon/common/_workflow.html' %}
{% endblock %}

View File

@ -0,0 +1,11 @@
{% extends 'base.html' %}
{% load i18n %}
{% block title %}{% trans "Add New Policy" %}{% endblock %}
{% block page_header %}
{% include "horizon/common/_page_header.html" with title=_("Add New Policy") %}
{% endblock page_header %}
{% block main %}
{% include 'horizon/common/_workflow.html' %}
{% endblock %}

View File

@ -0,0 +1,11 @@
{% extends 'base.html' %}
{% load i18n %}
{% block title %}{% trans "Add New Rule" %}{% endblock %}
{% block page_header %}
{% include "horizon/common/_page_header.html" with title=_("Add New Rule") %}
{% endblock page_header %}
{% block main %}
{% include 'horizon/common/_workflow.html' %}
{% endblock %}

View File

@ -0,0 +1,15 @@
{% extends 'base.html' %}
{% load i18n %}
{% block title %}{% trans "Firewalls" %}{% endblock %}
{% block page_header %}
{% include "horizon/common/_page_header.html" with title=_("Firewalls") %}
{% endblock page_header %}
{% block main %}
<div class="row-fluid">
<div class="span12">
{{ tab_group.render }}
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,11 @@
{% extends 'base.html' %}
{% load i18n %}
{% block title %}{% trans "Insert Rule to Policy" %}{% endblock %}
{% block page_header %}
{% include "horizon/common/_page_header.html" with title=_("Insert Rule to Policy") %}
{% endblock page_header %}
{% block main %}
{% include 'project/firewalls/_insert_rule_to_policy.html' %}
{% endblock %}

View File

@ -0,0 +1,11 @@
{% extends 'base.html' %}
{% load i18n %}
{% block title %}{% trans "Remove Rule from Policy" %}{% endblock %}
{% block page_header %}
{% include "horizon/common/_page_header.html" with title=_("Remove Rule from Policy") %}
{% endblock page_header %}
{% block main %}
{% include 'project/firewalls/_remove_rule_from_policy.html' %}
{% endblock %}

View File

@ -0,0 +1,11 @@
{% extends 'base.html' %}
{% load i18n %}
{% block title %}{% trans "Edit Firewall" %}{% endblock %}
{% block page_header %}
{% include "horizon/common/_page_header.html" with title=_("Edit Firewall ")|add:name %}
{% endblock page_header %}
{% block main %}
{% include 'project/firewalls/_updatefirewall.html' %}
{% endblock %}

View File

@ -0,0 +1,11 @@
{% extends 'base.html' %}
{% load i18n %}
{% block title %}{% trans "Edit Policy" %}{% endblock %}
{% block page_header %}
{% include "horizon/common/_page_header.html" with title=_("Edit Policy ")|add:name %}
{% endblock page_header %}
{% block main %}
{% include 'project/firewalls/_updatepolicy.html' %}
{% endblock %}

View File

@ -0,0 +1,11 @@
{% extends 'base.html' %}
{% load i18n %}
{% block title %}{% trans "Edit Rule" %}{% endblock %}
{% block page_header %}
{% include "horizon/common/_page_header.html" with title=_("Edit Rule ")|add:name %}
{% endblock page_header %}
{% block main %}
{% include 'project/firewalls/_updaterule.html' %}
{% endblock %}

View File

@ -0,0 +1,520 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013, Big Switch Networks, Inc.
#
# 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.
#
# @author: KC Wang, Big Switch Networks
from mox import IsA # noqa
from django.core.urlresolvers import reverse # noqa
from django.core.urlresolvers import reverse_lazy # noqa
from django import http
from openstack_dashboard import api
from openstack_dashboard.api import fwaas
from openstack_dashboard.test import helpers as test
class FirewallTests(test.TestCase):
class AttributeDict(dict):
def __getattr__(self, attr):
return self[attr]
def __setattr__(self, attr, value):
self[attr] = value
DASHBOARD = 'project'
INDEX_URL = reverse_lazy('horizon:%s:firewalls:index' % DASHBOARD)
ADDRULE_PATH = 'horizon:%s:firewalls:addrule' % DASHBOARD
ADDPOLICY_PATH = 'horizon:%s:firewalls:addpolicy' % DASHBOARD
ADDFIREWALL_PATH = 'horizon:%s:firewalls:addfirewall' % DASHBOARD
RULE_DETAIL_PATH = 'horizon:%s:firewalls:ruledetails' % DASHBOARD
POLICY_DETAIL_PATH = 'horizon:%s:firewalls:policydetails' % DASHBOARD
FIREWALL_DETAIL_PATH = 'horizon:%s:firewalls:firewalldetails' % DASHBOARD
UPDATERULE_PATH = 'horizon:%s:firewalls:updaterule' % DASHBOARD
UPDATEPOLICY_PATH = 'horizon:%s:firewalls:updatepolicy' % DASHBOARD
UPDATEFIREWALL_PATH = 'horizon:%s:firewalls:updatefirewall' % DASHBOARD
INSERTRULE_PATH = 'horizon:%s:firewalls:insertrule' % DASHBOARD
REMOVERULE_PATH = 'horizon:%s:firewalls:removerule' % DASHBOARD
def set_up_expect(self):
# retrieve rules
rule1 = self.fw_rules.first()
tenant_id = rule1.tenant_id
api.fwaas.rules_list(
IsA(http.HttpRequest),
tenant_id=tenant_id).AndReturn(self.fw_rules.list())
# retrieves policies
policies = self.fw_policies.list()
api.fwaas.policies_list(
IsA(http.HttpRequest), tenant_id=tenant_id).AndReturn(policies)
# retrieves firewalls
firewalls = self.firewalls.list()
api.fwaas.firewalls_list(
IsA(http.HttpRequest), tenant_id=tenant_id).AndReturn(firewalls)
def set_up_expect_with_exception(self):
rule1 = self.fw_rules.first()
tenant_id = rule1.tenant_id
api.fwaas.rules_list(
IsA(http.HttpRequest),
tenant_id=tenant_id).AndRaise(self.exceptions.neutron)
api.fwaas.policies_list(
IsA(http.HttpRequest),
tenant_id=tenant_id).AndRaise(self.exceptions.neutron)
api.fwaas.firewalls_list(
IsA(http.HttpRequest),
tenant_id=tenant_id).AndRaise(self.exceptions.neutron)
@test.create_stubs({api.fwaas: ('firewalls_list',
'policies_list',
'rules_list')}, )
def test_index_firewalls(self):
self.set_up_expect()
self.mox.ReplayAll()
firewall = self.firewalls.first()
tenant_id = firewall.tenant_id
res = self.client.get(self.INDEX_URL, tenant_id=tenant_id)
self.assertTemplateUsed(res, '%s/firewalls/details_tabs.html'
% self.DASHBOARD)
self.assertTemplateUsed(res, 'horizon/common/_detail_table.html')
self.assertEqual(len(res.context['table'].data),
len(self.firewalls.list()))
@test.create_stubs({api.fwaas: ('firewalls_list',
'policies_list',
'rules_list')}, )
def test_index_policies(self):
self.set_up_expect()
self.mox.ReplayAll()
policy = self.fw_policies.first()
tenant_id = policy.tenant_id
res = self.client.get(self.INDEX_URL + '?tab=fwtabs__policies',
tenant_id=tenant_id)
self.assertTemplateUsed(res, '%s/firewalls/details_tabs.html'
% self.DASHBOARD)
self.assertTemplateUsed(res, 'horizon/common/_detail_table.html')
self.assertEqual(len(res.context['policiestable_table'].data),
len(self.fw_policies.list()))
@test.create_stubs({api.fwaas: ('firewalls_list',
'policies_list',
'rules_list')}, )
def test_index_rules(self):
self.set_up_expect()
self.mox.ReplayAll()
rule = self.fw_rules.first()
tenant_id = rule.tenant_id
res = self.client.get(self.INDEX_URL + '?tab=fwtabs__rules',
tenant_id=tenant_id)
self.assertTemplateUsed(res, '%s/firewalls/details_tabs.html'
% self.DASHBOARD)
self.assertTemplateUsed(res, 'horizon/common/_detail_table.html')
self.assertEqual(len(res.context['rulestable_table'].data),
len(self.fw_rules.list()))
@test.create_stubs({api.fwaas: ('firewalls_list',
'policies_list',
'rules_list')}, )
def test_index_exception_firewalls(self):
self.set_up_expect_with_exception()
self.mox.ReplayAll()
firewall = self.firewalls.first()
tenant_id = firewall.tenant_id
res = self.client.get(self.INDEX_URL, tenant_id=tenant_id)
self.assertTemplateUsed(res,
'%s/firewalls/details_tabs.html'
% self.DASHBOARD)
self.assertTemplateUsed(res,
'horizon/common/_detail_table.html')
self.assertEqual(len(res.context['table'].data), 0)
@test.create_stubs({api.fwaas: ('firewalls_list',
'policies_list',
'rules_list')}, )
def test_index_exception_policies(self):
self.set_up_expect_with_exception()
self.mox.ReplayAll()
policy = self.fw_policies.first()
tenant_id = policy.tenant_id
res = self.client.get(self.INDEX_URL + '?tab=fwtabs__policies',
tenant_id=tenant_id)
self.assertTemplateUsed(res,
'%s/firewalls/details_tabs.html'
% self.DASHBOARD)
self.assertTemplateUsed(res,
'horizon/common/_detail_table.html')
self.assertEqual(len(res.context['policiestable_table'].data), 0)
@test.create_stubs({api.fwaas: ('firewalls_list',
'policies_list',
'rules_list')}, )
def test_index_exception_rules(self):
self.set_up_expect_with_exception()
self.mox.ReplayAll()
rule = self.fw_rules.first()
tenant_id = rule.tenant_id
res = self.client.get(self.INDEX_URL + '?tab=fwtabs__rules',
tenant_id=tenant_id)
self.assertTemplateUsed(res,
'%s/firewalls/details_tabs.html'
% self.DASHBOARD)
self.assertTemplateUsed(res,
'horizon/common/_detail_table.html')
self.assertEqual(len(res.context['rulestable_table'].data), 0)
@test.create_stubs({api.fwaas: ('rule_create',), })
def test_add_rule_post(self):
rule1 = self.fw_rules.first()
form_data = {'name': rule1.name,
'description': rule1.description,
'protocol': rule1.protocol,
'action': rule1.action,
'source_ip_address': rule1.source_ip_address,
'source_port': rule1.source_port,
'destination_ip_address': rule1.destination_ip_address,
'destination_port': rule1.destination_port,
'shared': rule1.shared,
'enabled': rule1.enabled
}
api.fwaas.rule_create(
IsA(http.HttpRequest), **form_data).AndReturn(rule1)
self.mox.ReplayAll()
res = self.client.post(reverse(self.ADDRULE_PATH), form_data)
self.assertNoFormErrors(res)
self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
def test_add_rule_post_with_error(self):
rule1 = self.fw_rules.first()
form_data = {'name': rule1.name,
'description': rule1.description,
'protocol': 'abc',
'action': 'pass',
'source_ip_address': rule1.source_ip_address,
'source_port': rule1.source_port,
'destination_ip_address': rule1.destination_ip_address,
'destination_port': rule1.destination_port,
'shared': rule1.shared,
'enabled': rule1.enabled
}
self.mox.ReplayAll()
res = self.client.post(reverse(self.ADDRULE_PATH), form_data)
self.assertFormErrors(res, 2)
@test.create_stubs({api.fwaas: ('policy_create', 'rules_list'), })
def test_add_policy_post(self):
policy = self.fw_policies.first()
rules = self.fw_rules.list()
tenant_id = policy.tenant_id
form_data = {'name': policy.name,
'description': policy.description,
'firewall_rules': policy.firewall_rules,
'shared': policy.shared,
'audited': policy.audited
}
api.fwaas.rules_list(
IsA(http.HttpRequest), tenant_id=tenant_id).AndReturn(rules)
api.fwaas.policy_create(
IsA(http.HttpRequest), **form_data).AndReturn(policy)
self.mox.ReplayAll()
res = self.client.post(reverse(self.ADDPOLICY_PATH), form_data)
self.assertNoFormErrors(res)
self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
@test.create_stubs({api.fwaas: ('policy_create', 'rules_list'), })
def test_add_policy_post_with_error(self):
policy = self.fw_policies.first()
rules = self.fw_rules.list()
tenant_id = policy.tenant_id
form_data = {'description': policy.description,
'firewall_rules': None,
'shared': policy.shared,
'audited': policy.audited
}
api.fwaas.rules_list(
IsA(http.HttpRequest), tenant_id=tenant_id).AndReturn(rules)
self.mox.ReplayAll()
res = self.client.post(reverse(self.ADDPOLICY_PATH), form_data)
self.assertFormErrors(res, 1)
@test.create_stubs({api.fwaas: ('firewall_create', 'policies_list'), })
def test_add_firewall_post(self):
firewall = self.firewalls.first()
policies = self.fw_policies.list()
tenant_id = firewall.tenant_id
form_data = {'name': firewall.name,
'description': firewall.description,
'firewall_policy_id': firewall.firewall_policy_id,
'shared': firewall.shared,
'admin_state_up': firewall.admin_state_up
}
api.fwaas.policies_list(
IsA(http.HttpRequest), tenant_id=tenant_id).AndReturn(policies)
api.fwaas.firewall_create(
IsA(http.HttpRequest), **form_data).AndReturn(firewall)
self.mox.ReplayAll()
res = self.client.post(reverse(self.ADDFIREWALL_PATH), form_data)
self.assertNoFormErrors(res)
self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
@test.create_stubs({api.fwaas: ('firewall_create', 'policies_list'), })
def test_add_firewall_post_with_error(self):
firewall = self.firewalls.first()
policies = self.fw_policies.list()
tenant_id = firewall.tenant_id
form_data = {'name': firewall.name,
'description': firewall.description,
'firewall_policy_id': None,
'shared': firewall.shared,
'admin_state_up': firewall.admin_state_up
}
api.fwaas.policies_list(
IsA(http.HttpRequest), tenant_id=tenant_id).AndReturn(policies)
self.mox.ReplayAll()
res = self.client.post(reverse(self.ADDFIREWALL_PATH), form_data)
self.assertFormErrors(res, 1)
@test.create_stubs({api.fwaas: ('rule_get', 'rule_update')})
def test_update_rule_post(self):
rule = self.fw_rules.first()
api.fwaas.rule_get(IsA(http.HttpRequest), rule.id).AndReturn(rule)
rule.name = 'new name'
rule.description = 'new desc'
rule.protocol = 'ICMP'
rule.action = 'ALLOW'
rule.shared = False
rule.enabled = True
data = {'name': rule.name,
'description': rule.description,
'protocol': rule.protocol,
'action': rule.action,
'shared': rule.shared,
'enabled': rule.enabled,
'source_ip_address': rule.source_ip_address,
'destination_ip_address': None,
'source_port': None,
'destination_port': rule.destination_port,
}
api.fwaas.rule_update(IsA(http.HttpRequest), rule.id, **data)\
.AndReturn(rule)
self.mox.ReplayAll()
form_data = {'name': rule.name,
'description': rule.description,
'protocol': rule.protocol,
'action': rule.action,
'shared': rule.shared,
'enabled': rule.enabled,
'source_ip_address': rule.source_ip_address,
'destination_ip_address': '',
'source_port': '',
'destination_port': rule.destination_port,
}
res = self.client.post(
reverse(self.UPDATERULE_PATH, args=(rule.id,)), form_data)
self.assertNoFormErrors(res)
self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
@test.create_stubs({api.fwaas: ('policy_get', 'policy_update',
'rules_list')})
def test_update_policy_post(self):
policy = self.fw_policies.first()
api.fwaas.policy_get(IsA(http.HttpRequest),
policy.id).AndReturn(policy)
policy.name = 'new name'
policy.description = 'new desc'
policy.shared = True
policy.audited = False
data = {'name': policy.name,
'description': policy.description,
'shared': policy.shared,
'audited': policy.audited
}
api.fwaas.policy_update(IsA(http.HttpRequest), policy.id, **data)\
.AndReturn(policy)
self.mox.ReplayAll()
res = self.client.post(
reverse(self.UPDATEPOLICY_PATH, args=(policy.id,)), data)
self.assertNoFormErrors(res)
self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
@test.create_stubs({api.fwaas: ('firewall_get', 'policies_list',
'firewall_update')})
def test_update_firewall_post(self):
firewall = self.firewalls.first()
tenant_id = firewall.tenant_id
api.fwaas.firewall_get(IsA(http.HttpRequest),
firewall.id).AndReturn(firewall)
firewall.name = 'new name'
firewall.description = 'new desc'
firewall.admin_state_up = False
data = {'name': firewall.name,
'description': firewall.description,
'firewall_policy_id': firewall.firewall_policy_id,
'admin_state_up': firewall.admin_state_up
}
policies = self.fw_policies.list()
api.fwaas.policies_list(
IsA(http.HttpRequest), tenant_id=tenant_id).AndReturn(policies)
api.fwaas.firewall_update(IsA(http.HttpRequest), firewall.id, **data)\
.AndReturn(firewall)
self.mox.ReplayAll()
res = self.client.post(
reverse(self.UPDATEFIREWALL_PATH, args=(firewall.id,)), data)
self.assertNoFormErrors(res)
self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
@test.create_stubs({api.fwaas: ('policy_get',
'policy_insert_rule',
'rules_list')})
def test_policy_insert_rule(self):
policy = self.fw_policies.first()
tenant_id = policy.tenant_id
rules = self.fw_rules.list()
new_rule_id = rules[2].id
data = {'firewall_rule_id': new_rule_id,
'insert_before': rules[1].id,
'insert_after': rules[0].id}
api.fwaas.policy_get(IsA(http.HttpRequest),
policy.id).AndReturn(policy)
policy.firewall_rules = [rules[0].id,
new_rule_id,
rules[1].id]
api.fwaas.rules_list(
IsA(http.HttpRequest), tenant_id=tenant_id).AndReturn(rules)
api.fwaas.policy_insert_rule(IsA(http.HttpRequest), policy.id, **data)\
.AndReturn(policy)
self.mox.ReplayAll()
res = self.client.post(
reverse(self.INSERTRULE_PATH, args=(policy.id,)), data)
self.assertNoFormErrors(res)
self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
@test.create_stubs({api.fwaas: ('policy_get', 'policy_remove_rule',
'rules_list',)})
def test_policy_remove_rule(self):
policy = self.fw_policies.first()
tenant_id = policy.tenant_id
rules = self.fw_rules.list()
remove_rule_id = policy.firewall_rules[0]
left_rule_id = policy.firewall_rules[1]
data = {'firewall_rule_id': remove_rule_id}
after_remove_policy_dict = {'id': 'abcdef-c3eb-4fee-9763-12de3338041e',
'tenant_id': '1',
'name': 'policy1',
'description': 'policy description',
'firewall_rules': [left_rule_id],
'audited': True,
'shared': True}
after_remove_policy = fwaas.Policy(after_remove_policy_dict)
api.fwaas.policy_get(IsA(http.HttpRequest),
policy.id).AndReturn(policy)
api.fwaas.rules_list(
IsA(http.HttpRequest), tenant_id=tenant_id).AndReturn(rules)
api.fwaas.policy_remove_rule(IsA(http.HttpRequest), policy.id, **data)\
.AndReturn(after_remove_policy)
self.mox.ReplayAll()
res = self.client.post(
reverse(self.REMOVERULE_PATH, args=(policy.id,)), data)
self.assertNoFormErrors(res)
self.assertRedirectsNoFollow(res, str(self.INDEX_URL))

View File

@ -0,0 +1,46 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013, Big Switch Networks, Inc.
#
# 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.
#
# @author: KC Wang, Big Switch Networks
from django.conf.urls.defaults import patterns # noqa
from django.conf.urls.defaults import url # noqa
from openstack_dashboard.dashboards.project.firewalls import views
urlpatterns = patterns(
'openstack_dashboard.dashboards.project.firewalls.views',
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^addrule$', views.AddRuleView.as_view(), name='addrule'),
url(r'^addpolicy$', views.AddPolicyView.as_view(), name='addpolicy'),
url(r'^addfirewall/(?P<policy_id>[^/]+)/$',
views.AddFirewallView.as_view(), name='addfirewall'),
url(r'^addfirewall$', views.AddFirewallView.as_view(), name='addfirewall'),
url(r'^insertrule/(?P<policy_id>[^/]+)/$',
views.InsertRuleToPolicyView.as_view(), name='insertrule'),
url(r'^removerule/(?P<policy_id>[^/]+)/$',
views.RemoveRuleFromPolicyView.as_view(), name='removerule'),
url(r'^updaterule/(?P<rule_id>[^/]+)/$',
views.UpdateRuleView.as_view(), name='updaterule'),
url(r'^updatepolicy/(?P<policy_id>[^/]+)/$',
views.UpdatePolicyView.as_view(), name='updatepolicy'),
url(r'^updatefirewall/(?P<firewall_id>[^/]+)/$',
views.UpdateFirewallView.as_view(), name='updatefirewall'),
url(r'^rule/(?P<rule_id>[^/]+)/$',
views.RuleDetailsView.as_view(), name='ruledetails'),
url(r'^policy/(?P<policy_id>[^/]+)/$',
views.PolicyDetailsView.as_view(), name='policydetails'),
url(r'^firewall/(?P<firewall_id>[^/]+)/$',
views.FirewallDetailsView.as_view(), name='firewalldetails'))

View File

@ -0,0 +1,285 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013, Big Switch Networks, Inc.
#
# 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.
#
# @author: KC Wang, Big Switch Networks
import logging
import re
from django.core.urlresolvers import reverse_lazy # noqa
from django.utils.translation import ugettext as _ # noqa
from horizon import exceptions
from horizon import forms
from horizon import messages
from horizon import tabs
from horizon import workflows
from openstack_dashboard import api
from openstack_dashboard.dashboards.project.firewalls \
import forms as fw_forms
from openstack_dashboard.dashboards.project.firewalls \
import tabs as fw_tabs
from openstack_dashboard.dashboards.project.firewalls \
import workflows as fw_workflows
InsertRuleToPolicy = fw_forms.InsertRuleToPolicy
RemoveRuleFromPolicy = fw_forms.RemoveRuleFromPolicy
UpdateFirewall = fw_forms.UpdateFirewall
UpdatePolicy = fw_forms.UpdatePolicy
UpdateRule = fw_forms.UpdateRule
FirewallDetailsTabs = fw_tabs.FirewallDetailsTabs
FirewallTabs = fw_tabs.FirewallTabs
PolicyDetailsTabs = fw_tabs.PolicyDetailsTabs
RuleDetailsTabs = fw_tabs.RuleDetailsTabs
AddFirewall = fw_workflows.AddFirewall
AddPolicy = fw_workflows.AddPolicy
AddRule = fw_workflows.AddRule
LOG = logging.getLogger(__name__)
class IndexView(tabs.TabView):
tab_group_class = (FirewallTabs)
template_name = 'project/firewalls/details_tabs.html'
def post(self, request, *args, **kwargs):
obj_ids = request.POST.getlist('object_ids')
action = request.POST['action']
obj_type = re.search('.delete([a-z]+)', action).group(1)
if not obj_ids:
obj_ids.append(re.search('([0-9a-z-]+)$', action).group(1))
if obj_type == 'rule':
for obj_id in obj_ids:
try:
api.fwaas.rule_delete(request, obj_id)
messages.success(request, 'Deleted rule %s' % obj_id)
except Exception as e:
exceptions.handle(request,
_('Unable to delete rule. %s' % e))
if obj_type == 'policy':
for obj_id in obj_ids:
try:
api.fwaas.policy_delete(request, obj_id)
messages.success(request, 'Deleted policy %s' % obj_id)
except Exception as e:
exceptions.handle(request,
_('Unable to delete policy. %s' % e))
if obj_type == 'firewall':
for obj_id in obj_ids:
try:
api.fwaas.firewall_delete(request, obj_id)
messages.success(request, 'Deleted firewall %s' % obj_id)
except Exception as e:
exceptions.handle(request,
_('Unable to delete firewall. %s' % e))
return self.get(request, *args, **kwargs)
class AddRuleView(workflows.WorkflowView):
workflow_class = AddRule
template_name = "project/firewalls/addrule.html"
class AddPolicyView(workflows.WorkflowView):
workflow_class = AddPolicy
template_name = "project/firewalls/addpolicy.html"
class AddFirewallView(workflows.WorkflowView):
workflow_class = AddFirewall
template_name = "project/firewalls/addfirewall.html"
class RuleDetailsView(tabs.TabView):
tab_group_class = (RuleDetailsTabs)
template_name = 'project/firewalls/details_tabs.html'
class PolicyDetailsView(tabs.TabView):
tab_group_class = (PolicyDetailsTabs)
template_name = 'project/firewalls/details_tabs.html'
class FirewallDetailsView(tabs.TabView):
tab_group_class = (FirewallDetailsTabs)
template_name = 'project/firewalls/details_tabs.html'
class UpdateRuleView(forms.ModalFormView):
form_class = UpdateRule
template_name = "project/firewalls/updaterule.html"
context_object_name = 'rule'
success_url = reverse_lazy("horizon:project:firewalls:index")
def get_context_data(self, **kwargs):
context = super(UpdateRuleView, self).get_context_data(**kwargs)
context['rule_id'] = self.kwargs['rule_id']
obj = self._get_object()
if obj:
context['name'] = obj.name
return context
def _get_object(self, *args, **kwargs):
if not hasattr(self, "_object"):
rule_id = self.kwargs['rule_id']
try:
self._object = api.fwaas.rule_get(self.request, rule_id)
self._object.set_id_as_name_if_empty()
except Exception:
redirect = self.success_url
msg = _('Unable to retrieve rule details.')
exceptions.handle(self.request, msg, redirect=redirect)
return self._object
def get_initial(self):
rule = self._get_object()
initial = rule.get_dict()
return initial
class UpdatePolicyView(forms.ModalFormView):
form_class = UpdatePolicy
template_name = "project/firewalls/updatepolicy.html"
context_object_name = 'policy'
success_url = reverse_lazy("horizon:project:firewalls:index")
def get_context_data(self, **kwargs):
context = super(UpdatePolicyView, self).get_context_data(**kwargs)
context["policy_id"] = self.kwargs['policy_id']
obj = self._get_object()
if obj:
context['name'] = obj.name
return context
def _get_object(self, *args, **kwargs):
if not hasattr(self, "_object"):
policy_id = self.kwargs['policy_id']
try:
self._object = api.fwaas.policy_get(self.request, policy_id)
self._object.set_id_as_name_if_empty()
except Exception:
redirect = self.success_url
msg = _('Unable to retrieve policy details.')
exceptions.handle(self.request, msg, redirect=redirect)
return self._object
def get_initial(self):
policy = self._get_object()
initial = policy.get_dict()
return initial
class UpdateFirewallView(forms.ModalFormView):
form_class = UpdateFirewall
template_name = "project/firewalls/updatefirewall.html"
context_object_name = 'firewall'
success_url = reverse_lazy("horizon:project:firewalls:index")
def get_context_data(self, **kwargs):
context = super(UpdateFirewallView, self).get_context_data(**kwargs)
context["firewall_id"] = self.kwargs['firewall_id']
obj = self._get_object()
if obj:
context['name'] = obj.name
return context
def _get_object(self, *args, **kwargs):
if not hasattr(self, "_object"):
firewall_id = self.kwargs['firewall_id']
try:
self._object = api.fwaas.firewall_get(self.request,
firewall_id)
self._object.set_id_as_name_if_empty()
except Exception:
redirect = self.success_url
msg = _('Unable to retrieve firewall details.')
exceptions.handle(self.request, msg, redirect=redirect)
return self._object
def get_initial(self):
firewall = self._get_object()
initial = firewall.get_dict()
return initial
class InsertRuleToPolicyView(forms.ModalFormView):
form_class = InsertRuleToPolicy
template_name = "project/firewalls/insert_rule_to_policy.html"
context_object_name = 'policy'
success_url = reverse_lazy("horizon:project:firewalls:index")
def get_context_data(self, **kwargs):
context = super(InsertRuleToPolicyView,
self).get_context_data(**kwargs)
context["policy_id"] = self.kwargs['policy_id']
obj = self._get_object()
if obj:
context['name'] = obj.name
return context
def _get_object(self, *args, **kwargs):
if not hasattr(self, "_object"):
policy_id = self.kwargs['policy_id']
try:
self._object = api.fwaas.policy_get(self.request, policy_id)
self._object.set_id_as_name_if_empty()
except Exception:
redirect = self.success_url
msg = _('Unable to retrieve policy details.')
exceptions.handle(self.request, msg, redirect=redirect)
return self._object
def get_initial(self):
policy = self._get_object()
initial = policy.get_dict()
initial['policy_id'] = initial['id']
return initial
class RemoveRuleFromPolicyView(forms.ModalFormView):
form_class = RemoveRuleFromPolicy
template_name = "project/firewalls/remove_rule_from_policy.html"
context_object_name = 'policy'
success_url = reverse_lazy("horizon:project:firewalls:index")
def get_context_data(self, **kwargs):
context = super(RemoveRuleFromPolicyView,
self).get_context_data(**kwargs)
context["policy_id"] = self.kwargs['policy_id']
obj = self._get_object()
if obj:
context['name'] = obj.name
return context
def _get_object(self, *args, **kwargs):
if not hasattr(self, "_object"):
policy_id = self.kwargs['policy_id']
try:
self._object = api.fwaas.policy_get(self.request, policy_id)
self._object.set_id_as_name_if_empty()
except Exception:
redirect = self.success_url
msg = _('Unable to retrieve policy details.')
exceptions.handle(self.request, msg, redirect=redirect)
return self._object
def get_initial(self):
policy = self._get_object()
initial = policy.get_dict()
initial['policy_id'] = initial['id']
return initial

View File

@ -0,0 +1,315 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013, Big Switch Networks, Inc.
#
# 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.
#
# @author: KC Wang, Big Switch Networks
import logging
from django.utils.translation import ugettext as _ # noqa
from horizon import exceptions
from horizon import forms
from horizon.utils import fields
from horizon.utils import validators
from horizon import workflows
from openstack_dashboard import api
port_validator = validators.validate_port_or_colon_separated_port_range
LOG = logging.getLogger(__name__)
class AddRuleAction(workflows.Action):
name = forms.CharField(
max_length=80,
label=_("Name"),
required=False)
description = forms.CharField(
max_length=80,
label=_("Description"),
required=False)
protocol = forms.ChoiceField(
label=_("Protocol"),
choices=[('tcp', _('TCP')),
('udp', _('UDP')),
('icmp', _('ICMP')),
(None, _('ANY'))],)
action = forms.ChoiceField(
label=_("Action"),
choices=[('allow', _('ALLOW')),
('deny', _('DENY'))],)
source_ip_address = fields.IPField(
label=_("Source IP Address/Subnet"),
version=fields.IPv4 | fields.IPv6,
required=False, mask=True)
destination_ip_address = fields.IPField(
label=_("Destination IP Address/Subnet"),
version=fields.IPv4 | fields.IPv6,
required=False, mask=True)
source_port = forms.CharField(
max_length=80,
label=_("Source Port/Port Range"),
required=False,
validators=[port_validator])
destination_port = forms.CharField(
max_length=80,
label=_("Destination Port/Port Range"),
required=False,
validators=[port_validator])
shared = forms.BooleanField(
label=_("Shared"), initial=False, required=False)
enabled = forms.BooleanField(
label=_("Enabled"), initial=True, required=False)
def __init__(self, request, *args, **kwargs):
super(AddRuleAction, self).__init__(request, *args, **kwargs)
class Meta:
name = _("AddRule")
permissions = ('openstack.services.network',)
help_text = _("Create a firewall rule.\n\n"
"Protocol and action must be specified. "
"Other fields are optional.")
class AddRuleStep(workflows.Step):
action_class = AddRuleAction
contributes = ("name", "description", "protocol", "action",
"source_ip_address", "source_port",
"destination_ip_address", "destination_port",
"enabled", "shared")
def contribute(self, data, context):
context = super(AddRuleStep, self).contribute(data, context)
if data:
for field in ['source_port',
'destination_port',
'source_ip_address',
'destination_ip_address']:
if not context[field]:
del context[field]
return context
class AddRule(workflows.Workflow):
slug = "addrule"
name = _("Add Rule")
finalize_button_name = _("Add")
success_message = _('Added Rule "%s".')
failure_message = _('Unable to add Rule "%s".')
success_url = "horizon:project:firewalls:index"
# fwaas is designed to support a wide range of vendor
# firewalls. Considering the multitude of vendor firewall
# features in place today, firewall_rule definition can
# involve more complex configuration over time. Hence,
# a workflow instead of a single form is used for
# firewall_rule add to be ready for future extension.
default_steps = (AddRuleStep,)
def format_status_message(self, message):
return message % self.context.get('name')
def handle(self, request, context):
try:
api.fwaas.rule_create(request, **context)
return True
except Exception as e:
msg = self.format_status_message(self.failure_message) + str(e)
exceptions.handle(request, msg)
return False
class SelectRulesAction(workflows.Action):
rule = forms.MultipleChoiceField(
label=_("Rules"),
required=False,
widget=forms.CheckboxSelectMultiple(),
help_text=_("Create a policy with selected rules."))
class Meta:
name = _("Rules")
permissions = ('openstack.services.network',)
help_text = _("Select rules for your policy.")
def populate_rule_choices(self, request, context):
try:
tenant_id = self.request.user.tenant_id
rules = api.fwaas.rules_list(request, tenant_id=tenant_id)
for r in rules:
r.set_id_as_name_if_empty()
rules = sorted(rules,
key=lambda rule: rule.name)
rule_list = [(rule.id, rule.name) for rule in rules
if not rule.firewall_policy_id]
except Exception as e:
rule_list = []
exceptions.handle(request,
_('Unable to retrieve rules.') + str(e))
return rule_list
class SelectRulesStep(workflows.Step):
action_class = SelectRulesAction
template_name = "project/firewalls/_update_rules.html"
contributes = ("firewall_rules",)
def contribute(self, data, context):
if data:
rules = self.workflow.request.POST.getlist("firewall_rules")
if rules:
rules = [r for r in rules if r != '']
context['firewall_rules'] = rules
return context
class AddPolicyAction(workflows.Action):
name = forms.CharField(max_length=80,
label=_("Name"),
required=True)
description = forms.CharField(max_length=80,
label=_("Description"),
required=False)
shared = forms.BooleanField(label=_("Shared"),
initial=False,
required=False)
audited = forms.BooleanField(label=_("Audited"),
initial=False,
required=False)
def __init__(self, request, *args, **kwargs):
super(AddPolicyAction, self).__init__(request, *args, **kwargs)
class Meta:
name = _("AddPolicy")
permissions = ('openstack.services.network',)
help_text = _("Create a firewall policy with an ordered list"
"of firewall rules.\n\n"
"A name must be given. Firewall rules are "
"added in the order placed under the Rules tab.")
class AddPolicyStep(workflows.Step):
action_class = AddPolicyAction
contributes = ("name", "description", "shared", "audited")
def contribute(self, data, context):
context = super(AddPolicyStep, self).contribute(data, context)
if data:
return context
class AddPolicy(workflows.Workflow):
slug = "addpolicy"
name = _("Add Policy")
finalize_button_name = _("Add")
success_message = _('Added Policy "%s".')
failure_message = _('Unable to add Policy "%s".')
success_url = "horizon:project:firewalls:index"
default_steps = (AddPolicyStep, SelectRulesStep)
def format_status_message(self, message):
return message % self.context.get('name')
def handle(self, request, context):
try:
api.fwaas.policy_create(request, **context)
return True
except Exception as e:
msg = self.format_status_message(self.failure_message) + str(e)
exceptions.handle(request, msg)
return False
class AddFirewallAction(workflows.Action):
name = forms.CharField(max_length=80,
label=_("Name"),
required=False)
description = forms.CharField(max_length=80,
label=_("Description"),
required=False)
firewall_policy_id = forms.ChoiceField(label=_("Policy"),
required=True)
shared = forms.BooleanField(label=_("Shared"),
initial=False,
required=False)
admin_state_up = forms.BooleanField(label=_("Admin State"),
initial=True,
required=False)
def __init__(self, request, *args, **kwargs):
super(AddFirewallAction, self).__init__(request, *args, **kwargs)
firewall_policy_id_choices = [('', _("Select a Policy"))]
try:
tenant_id = self.request.user.tenant_id
policies = api.fwaas.policies_list(request, tenant_id=tenant_id)
policies = sorted(policies, key=lambda policy: policy.name)
except Exception as e:
exceptions.handle(request,
_('Unable to retrieve policy list.') + str(e))
policies = []
for p in policies:
p.set_id_as_name_if_empty()
firewall_policy_id_choices.append((p.id, p.name))
self.fields['firewall_policy_id'].choices = firewall_policy_id_choices
# only admin can set 'shared' attribute to True
if not request.user.is_superuser:
self.fields['shared'].widget.attrs['disabled'] = 'disabled'
class Meta:
name = _("AddFirewall")
permissions = ('openstack.services.network',)
help_text = _("Create a firewall based on a policy.\n\n"
"A policy must be selected. "
"Other fields are optional.")
class AddFirewallStep(workflows.Step):
action_class = AddFirewallAction
contributes = ("name", "firewall_policy_id", "description",
"shared", "admin_state_up")
def contribute(self, data, context):
context = super(AddFirewallStep, self).contribute(data, context)
return context
class AddFirewall(workflows.Workflow):
slug = "addfirewall"
name = _("Add Firewall")
finalize_button_name = _("Add")
success_message = _('Added Firewall "%s".')
failure_message = _('Unable to add Firewall "%s".')
success_url = "horizon:project:firewalls:index"
# fwaas is designed to support a wide range of vendor
# firewalls. Considering the multitude of vendor firewall
# features in place today, firewall definition can
# involve more complex configuration over time. Hence,
# a workflow instead of a single form is used for
# firewall_rule add to be ready for future extension.
default_steps = (AddFirewallStep,)
def format_status_message(self, message):
return message % self.context.get('name')
def handle(self, request, context):
try:
api.fwaas.firewall_create(request, **context)
return True
except Exception as e:
msg = self.format_status_message(self.failure_message) + str(e)
exceptions.handle(request, msg)
return False

View File

@ -158,6 +158,7 @@ OPENSTACK_HYPERVISOR_FEATURES = {
# balancer service, security groups, quotas, VPN service.
OPENSTACK_NEUTRON_NETWORK = {
'enable_lb': False,
'enable_firewall': False,
'enable_quotas': True,
'enable_security_group': True,
'enable_vpn': False,

View File

@ -2080,3 +2080,116 @@ label.log-length {
}
/* Styling for draged firewall rule object */
#ruleListSortContainer {
display: none;
}
.rulelist {
padding: 6px;
background: #eee;
border: 1px solid #ccc;
min-height: 2em;
width: auto !important;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
li {
width: 226px;
list-style-type: none;
margin: 6px auto;
padding: 3px;
background: #fff;
border: 1px solid #aaa;
line-height: 18px;
border-radius: 3px;
cursor: move;
padding-left: 23px;
background: white url(/static/dashboard/img/drag.png) no-repeat 11px 50%;
em {
font-size: 0.5em;
line-height: 1em;
color:#999;
font-style: normal;
margin-left: 0.8em;
}
i {
margin-right: 5px;
vertical-align: middle;
}
a.btn {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
font-size: 11px;
line-height: 12px;
padding: 2px 5px 3px;
margin-right: 1px;
width: 18px;
text-align: center;
//position: absolute;
right:5px;
vertical-align: middle;
float: right;
&:before {
content: "+";
}
}
}
li.ui-sortable-helper {
background-color: #def;
}
li.ui-state-highlight {
border: 1px dotted #ccc;
background: #efefef;
height: 0.5em;
}
li:after {
visibility: hidden;
display: block;
font-size: 0;
content: " ";
clear: both;
height: 0;
}
}
#selected_rule {
margin-bottom: 1.5em;
counter-reset:v1 0;
background: #edf9ff;
border:1px solid #c0d9e4;
li {
position: relative;
a.btn {
&:before {
content: "-";
}
}
}
li:before {
content:"rule:"counter(v1);
counter-increment:v1;
display: inline-block;
margin-right: 5px;
background: #666;
color:#fff;
font-size: 90%;
padding: 0px 4px;
vertical-align: middle;
border-radius: 2px;
position: absolute;
left: -2em;
}
&.dragging {
li:before {
content:"rule:";
background-color:rgba(102,102,102,0.5);
padding-right: 10px;
}
li.ui-state-highlight:before {
content:"";
background:transparent;
}
}
}

View File

@ -0,0 +1,321 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013, Big Switch Networks, Inc.
#
# 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.
#
# @author: KC Wang, Big Switch Networks
#
from openstack_dashboard import api
from openstack_dashboard.test import helpers as test
from neutronclient.v2_0.client import Client as neutronclient # noqa
class FwaasApiTests(test.APITestCase):
@test.create_stubs({neutronclient: ('create_firewall_rule',)})
def test_rule_create(self):
rule1 = self.fw_rules.first()
rule1_dict = self.api_fw_rules.first()
form_data = {'name': rule1.name,
'description': rule1.description,
'protocol': rule1.protocol,
'action': rule1.action,
'source_ip_address': rule1.source_ip_address,
'source_port': rule1.source_port,
'destination_ip_address': rule1.destination_ip_address,
'destination_port': rule1.destination_port,
'shared': rule1.shared,
'enabled': rule1.enabled
}
form_dict = {'firewall_rule': form_data}
ret_dict = {'firewall_rule': rule1_dict}
neutronclient.create_firewall_rule(form_dict).AndReturn(ret_dict)
self.mox.ReplayAll()
ret_val = api.fwaas.rule_create(self.request, **form_data)
self.assertIsInstance(ret_val, api.fwaas.Rule)
self.assertEqual(rule1.name, ret_val.name)
self.assertTrue(ret_val.id)
@test.create_stubs({neutronclient: ('list_firewall_rules',)})
def test_rules_list(self):
rules = {'firewall_rules': self.fw_rules.list()}
rules_dict = {'firewall_rules': self.api_fw_rules.list()}
neutronclient.list_firewall_rules().AndReturn(rules_dict)
self.mox.ReplayAll()
ret_val = api.fwaas.rules_list(self.request)
for (v, d) in zip(ret_val, rules['firewall_rules']):
self.assertIsInstance(v, api.fwaas.Rule)
self.assertTrue(v.name, d.name)
self.assertTrue(v.id)
@test.create_stubs({neutronclient: ('show_firewall_rule',)})
def test_rule_get(self):
rule = self.fw_rules.first()
rule_dict = self.api_fw_rules.first()
ret_dict = {'firewall_rule': rule_dict}
neutronclient.show_firewall_rule(rule.id).AndReturn(ret_dict)
self.mox.ReplayAll()
ret_val = api.fwaas.rule_get(self.request, rule.id)
self.assertIsInstance(ret_val, api.fwaas.Rule)
self.assertEqual(rule.name, ret_val.name)
self.assertTrue(ret_val.id)
@test.create_stubs({neutronclient: ('update_firewall_rule',)})
def test_rule_update(self):
rule = self.fw_rules.first()
rule_dict = self.api_fw_rules.first()
rule.name = 'new name'
rule.description = 'new desc'
rule.protocol = 'icmp'
rule.action = 'deny'
rule.shared = True
rule.enabled = False
rule_dict['name'] = 'new name'
rule_dict['description'] = 'new desc'
rule_dict['protocol'] = 'icmp'
rule_dict['action'] = 'deny'
rule_dict['shared'] = True
rule_dict['enabled'] = False
form_data = {'name': rule.name,
'description': rule.description,
'protocol': rule.protocol,
'action': rule.action,
'shared': rule.shared,
'enabled': rule.enabled
}
form_dict = {'firewall_rule': form_data}
ret_dict = {'firewall_rule': rule_dict}
neutronclient.update_firewall_rule(
rule.id, form_dict).AndReturn(ret_dict)
self.mox.ReplayAll()
ret_val = api.fwaas.rule_update(self.request,
rule.id, **form_data)
self.assertIsInstance(ret_val, api.fwaas.Rule)
self.assertEqual(rule.name, ret_val.name)
self.assertTrue(ret_val.id)
@test.create_stubs({neutronclient: ('create_firewall_policy', )})
def test_policy_create(self):
policy1 = self.fw_policies.first()
policy1_dict = self.api_fw_policies.first()
form_data = {'name': policy1.name,
'description': policy1.description,
'firewall_rules': policy1.firewall_rules,
'shared': policy1.shared,
'audited': policy1.audited
}
form_dict = {'firewall_policy': form_data}
ret_dict = {'firewall_policy': policy1_dict}
neutronclient.create_firewall_policy(form_dict).AndReturn(ret_dict)
self.mox.ReplayAll()
ret_val = api.fwaas.policy_create(self.request, **form_data)
self.assertIsInstance(ret_val, api.fwaas.Policy)
self.assertEqual(policy1.name, ret_val.name)
self.assertTrue(ret_val.id)
@test.create_stubs({neutronclient: ('list_firewall_policies',)})
def test_policies_list(self):
policies = {'firewall_policies': self.fw_policies.list()}
policies_dict = {'firewall_policies': self.api_fw_policies.list()}
neutronclient.list_firewall_policies().AndReturn(policies_dict)
self.mox.ReplayAll()
ret_val = api.fwaas.policies_list(self.request)
for (v, d) in zip(ret_val, policies['firewall_policies']):
self.assertIsInstance(v, api.fwaas.Policy)
self.assertTrue(v.name, d.name)
self.assertTrue(v.id)
@test.create_stubs({neutronclient: ('show_firewall_policy',)})
def test_policy_get(self):
policy = self.fw_policies.first()
policy_dict = self.api_fw_policies.first()
ret_dict = {'firewall_policy': policy_dict}
neutronclient.show_firewall_policy(policy.id).AndReturn(ret_dict)
self.mox.ReplayAll()
ret_val = api.fwaas.policy_get(self.request, policy.id)
self.assertIsInstance(ret_val, api.fwaas.Policy)
self.assertEqual(policy.name, ret_val.name)
self.assertTrue(ret_val.id)
@test.create_stubs({neutronclient: ('update_firewall_policy',)})
def test_policy_update(self):
policy = self.fw_policies.first()
policy_dict = self.api_fw_policies.first()
policy.name = 'new name'
policy.description = 'new desc'
policy.shared = True
policy.audited = False
policy_dict['name'] = 'new name'
policy_dict['description'] = 'new desc'
policy_dict['shared'] = True
policy_dict['audited'] = False
form_data = {'name': policy.name,
'description': policy.description,
'shared': policy.shared,
'audited': policy.audited
}
form_dict = {'firewall_policy': form_data}
ret_dict = {'firewall_policy': policy_dict}
neutronclient.update_firewall_policy(
policy.id, form_dict).AndReturn(ret_dict)
self.mox.ReplayAll()
ret_val = api.fwaas.policy_update(self.request,
policy.id, **form_data)
self.assertIsInstance(ret_val, api.fwaas.Policy)
self.assertEqual(policy.name, ret_val.name)
self.assertTrue(ret_val.id)
@test.create_stubs({neutronclient: ('firewall_policy_insert_rule',)})
def test_policy_insert_rule(self):
policy = self.fw_policies.first()
policy_dict = self.api_fw_policies.first()
new_rule_id = 'h0881d38-c3eb-4fee-9763-12de3338041d'
policy.firewall_rules.append(new_rule_id)
policy_dict['firewall_rules'].append(new_rule_id)
body = {'firewall_rule_id': new_rule_id,
'insert_before': policy.firewall_rules[1],
'insert_after': policy.firewall_rules[0]}
neutronclient.firewall_policy_insert_rule(
policy.id, body).AndReturn(policy_dict)
self.mox.ReplayAll()
ret_val = api.fwaas.policy_insert_rule(self.request,
policy.id, **body)
self.assertTrue(new_rule_id in ret_val.firewall_rules)
@test.create_stubs({neutronclient: ('firewall_policy_remove_rule',)})
def test_policy_remove_rule(self):
policy = self.fw_policies.first()
policy_dict = self.api_fw_policies.first()
remove_rule_id = policy.firewall_rules[0]
policy.firewall_rules.remove(remove_rule_id)
body = {'firewall_rule_id': remove_rule_id}
neutronclient.firewall_policy_remove_rule(
policy.id, body).AndReturn(policy_dict)
self.mox.ReplayAll()
ret_val = api.fwaas.policy_remove_rule(self.request,
policy.id, **body)
self.assertFalse(remove_rule_id in ret_val.firewall_rules)
@test.create_stubs({neutronclient: ('create_firewall', )})
def test_firewall_create(self):
firewall = self.firewalls.first()
firewall_dict = self.api_firewalls.first()
form_data = {'name': firewall.name,
'description': firewall.description,
'firewall_policy_id': firewall.firewall_policy_id,
'shared': firewall.shared,
'admin_state_up': firewall.admin_state_up
}
form_dict = {'firewall': form_data}
ret_dict = {'firewall': firewall_dict}
neutronclient.create_firewall(form_dict).AndReturn(ret_dict)
self.mox.ReplayAll()
ret_val = api.fwaas.firewall_create(self.request, **form_data)
self.assertIsInstance(ret_val, api.fwaas.Firewall)
self.assertEqual(firewall.name, ret_val.name)
self.assertTrue(ret_val.id)
@test.create_stubs({neutronclient: ('list_firewalls',)})
def test_firewalls_list(self):
firewalls = {'firewalls': self.firewalls.list()}
firewalls_dict = {'firewalls': self.api_firewalls.list()}
neutronclient.list_firewalls().AndReturn(firewalls_dict)
self.mox.ReplayAll()
ret_val = api.fwaas.firewalls_list(self.request)
for (v, d) in zip(ret_val, firewalls['firewalls']):
self.assertIsInstance(v, api.fwaas.Firewall)
self.assertTrue(v.name, d.name)
self.assertTrue(v.id)
@test.create_stubs({neutronclient: ('show_firewall',)})
def test_firewall_get(self):
firewall = self.firewalls.first()
firewall_dict = self.api_firewalls.first()
ret_dict = {'firewall': firewall_dict}
neutronclient.show_firewall(firewall.id).AndReturn(ret_dict)
self.mox.ReplayAll()
ret_val = api.fwaas.firewall_get(self.request, firewall.id)
self.assertIsInstance(ret_val, api.fwaas.Firewall)
self.assertEqual(firewall.name, ret_val.name)
self.assertTrue(ret_val.id)
@test.create_stubs({neutronclient: ('update_firewall',)})
def test_firewall_update(self):
firewall = self.firewalls.first()
firewall_dict = self.api_firewalls.first()
firewall.name = 'new name'
firewall.description = 'new desc'
firewall.admin_state_up = False
firewall_dict['name'] = 'new name'
firewall_dict['description'] = 'new desc'
firewall_dict['admin_state_up'] = False
form_data = {'name': firewall.name,
'description': firewall.description,
'admin_state_up': firewall.admin_state_up
}
form_dict = {'firewall': form_data}
ret_dict = {'firewall': firewall_dict}
neutronclient.update_firewall(
firewall.id, form_dict).AndReturn(ret_dict)
self.mox.ReplayAll()
ret_val = api.fwaas.firewall_update(self.request,
firewall.id, **form_data)
self.assertIsInstance(ret_val, api.fwaas.Firewall)
self.assertEqual(firewall.name, ret_val.name)
self.assertTrue(ret_val.id)

View File

@ -97,6 +97,7 @@ OPENSTACK_KEYSTONE_BACKEND = {
OPENSTACK_NEUTRON_NETWORK = {
'enable_lb': True,
'enable_firewall': True,
'enable_quotas': False, # Enabled in specific tests only
'enable_vpn': True
}

View File

@ -16,6 +16,7 @@ import copy
import uuid
from openstack_dashboard.api import base
from openstack_dashboard.api import fwaas
from openstack_dashboard.api import lbaas
from openstack_dashboard.api import neutron
from openstack_dashboard.api import vpn
@ -46,6 +47,9 @@ def data(TEST):
TEST.ikepolicies = utils.TestDataContainer()
TEST.ipsecpolicies = utils.TestDataContainer()
TEST.ipsecsiteconnections = utils.TestDataContainer()
TEST.firewalls = utils.TestDataContainer()
TEST.fw_policies = utils.TestDataContainer()
TEST.fw_rules = utils.TestDataContainer()
# data return by neutronclient
TEST.api_agents = utils.TestDataContainer()
@ -69,6 +73,9 @@ def data(TEST):
TEST.api_ikepolicies = utils.TestDataContainer()
TEST.api_ipsecpolicies = utils.TestDataContainer()
TEST.api_ipsecsiteconnections = utils.TestDataContainer()
TEST.api_firewalls = utils.TestDataContainer()
TEST.api_fw_policies = utils.TestDataContainer()
TEST.api_fw_rules = utils.TestDataContainer()
#------------------------------------------------------------
# 1st network
@ -703,3 +710,83 @@ def data(TEST):
TEST.api_ipsecsiteconnections.add(ipsecsiteconnection_dict)
TEST.ipsecsiteconnections.add(
vpn.IPSecSiteConnection(ipsecsiteconnection_dict))
# FWaaS
# 1st rule
rule1_dict = {'id': 'f0881d38-c3eb-4fee-9763-12de3338041d',
'tenant_id': '1',
'name': 'rule1',
'description': 'rule1 description',
'protocol': 'tcp',
'action': 'allow',
'source_ip_address': '1.2.3.0/24',
'source_port': '80',
'destination_ip_address': '4.5.6.7/32',
'destination_port': '1:65535',
'firewall_policy_id': 'abcdef-c3eb-4fee-9763-12de3338041e',
'position': 1,
'shared': True,
'enabled': True}
TEST.api_fw_rules.add(rule1_dict)
TEST.fw_rules.add(fwaas.Rule(rule1_dict))
# 2nd rule
rule2_dict = {'id': 'g0881d38-c3eb-4fee-9763-12de3338041d',
'tenant_id': '1',
'name': 'rule2',
'description': 'rule2 description',
'protocol': 'udp',
'action': 'deny',
'source_ip_address': '1.2.3.0/24',
'source_port': '80',
'destination_ip_address': '4.5.6.7/32',
'destination_port': '1:65535',
'firewall_policy_id': 'abcdef-c3eb-4fee-9763-12de3338041e',
'position': 2,
'shared': True,
'enabled': True}
TEST.api_fw_rules.add(rule2_dict)
TEST.fw_rules.add(fwaas.Rule(rule2_dict))
# 3rd rule
rule3_dict = {'id': 'h0881d38-c3eb-4fee-9763-12de3338041d',
'tenant_id': '1',
'name': 'rule3',
'description': 'rule3 description',
'protocol': 'icmp',
'action': 'allow',
'source_ip_address': '1.2.3.0/24',
'source_port': '80',
'destination_ip_address': '4.5.6.7/32',
'destination_port': '1:65535',
'firewall_policy_id': None,
'position': None,
'shared': True,
'enabled': True}
TEST.api_fw_rules.add(rule3_dict)
TEST.fw_rules.add(fwaas.Rule(rule3_dict))
# 1st policy
policy_dict = {'id': 'abcdef-c3eb-4fee-9763-12de3338041e',
'tenant_id': '1',
'name': 'policy1',
'description': 'policy description',
'firewall_rules': [rule1_dict['id'], rule2_dict['id']],
'audited': True,
'shared': True}
TEST.api_fw_policies.add(policy_dict)
TEST.fw_policies.add(fwaas.Policy(policy_dict))
# 1st firewall
firewall_dict = {'id': '8913dde8-4915-4b90-8d3e-b95eeedb0d49',
'tenant_id': '1',
'firewall_policy_id':
'abcdef-c3eb-4fee-9763-12de3338041e',
'name': 'firewall1',
'description': 'firewall description',
'status': 'PENDING_CREATE',
'shared': True,
'admin_state_up': True}
TEST.api_firewalls.add(firewall_dict)
TEST.firewalls.add(fwaas.Firewall(firewall_dict))