1
# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
# Copyright 2013, Big Switch Networks, Inc.
4
# Licensed under the Apache License, Version 2.0 (the "License"); you may
5
# not use this file except in compliance with the License. You may obtain
6
# a copy of the License at
8
# http://www.apache.org/licenses/LICENSE-2.0
10
# Unless required by applicable law or agreed to in writing, software
11
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
# License for the specific language governing permissions and limitations
16
# @author: KC Wang, Big Switch Networks
18
from django.utils.translation import ugettext_lazy as _ # noqa
20
from horizon import exceptions
21
from horizon import forms
22
from horizon.utils import fields
23
from horizon.utils import validators
24
from horizon import workflows
26
from openstack_dashboard import api
28
port_validator = validators.validate_port_or_colon_separated_port_range
31
class AddRuleAction(workflows.Action):
32
name = forms.CharField(
36
description = forms.CharField(
38
label=_("Description"),
40
protocol = forms.ChoiceField(
42
choices=[('tcp', _('TCP')),
46
action = forms.ChoiceField(
48
choices=[('allow', _('ALLOW')),
49
('deny', _('DENY'))],)
50
source_ip_address = fields.IPField(
51
label=_("Source IP Address/Subnet"),
52
version=fields.IPv4 | fields.IPv6,
53
required=False, mask=True)
54
destination_ip_address = fields.IPField(
55
label=_("Destination IP Address/Subnet"),
56
version=fields.IPv4 | fields.IPv6,
57
required=False, mask=True)
58
source_port = forms.CharField(
60
label=_("Source Port/Port Range"),
62
validators=[port_validator])
63
destination_port = forms.CharField(
65
label=_("Destination Port/Port Range"),
67
validators=[port_validator])
68
shared = forms.BooleanField(
69
label=_("Shared"), initial=False, required=False)
70
enabled = forms.BooleanField(
71
label=_("Enabled"), initial=True, required=False)
73
def __init__(self, request, *args, **kwargs):
74
super(AddRuleAction, self).__init__(request, *args, **kwargs)
78
permissions = ('openstack.services.network',)
79
help_text = _("Create a firewall rule.\n\n"
80
"Protocol and action must be specified. "
81
"Other fields are optional.")
84
class AddRuleStep(workflows.Step):
85
action_class = AddRuleAction
86
contributes = ("name", "description", "protocol", "action",
87
"source_ip_address", "source_port",
88
"destination_ip_address", "destination_port",
91
def contribute(self, data, context):
92
context = super(AddRuleStep, self).contribute(data, context)
94
if context['protocol'] == 'any':
95
del context['protocol']
96
for field in ['source_port',
99
'destination_ip_address']:
100
if not context[field]:
105
class AddRule(workflows.Workflow):
108
finalize_button_name = _("Add")
109
success_message = _('Added Rule "%s".')
110
failure_message = _('Unable to add Rule "%s".')
111
success_url = "horizon:project:firewalls:index"
112
# fwaas is designed to support a wide range of vendor
113
# firewalls. Considering the multitude of vendor firewall
114
# features in place today, firewall_rule definition can
115
# involve more complex configuration over time. Hence,
116
# a workflow instead of a single form is used for
117
# firewall_rule add to be ready for future extension.
118
default_steps = (AddRuleStep,)
120
def format_status_message(self, message):
121
return message % self.context.get('name')
123
def handle(self, request, context):
125
api.fwaas.rule_create(request, **context)
127
except Exception as e:
128
msg = self.format_status_message(self.failure_message) + str(e)
129
exceptions.handle(request, msg)
133
class SelectRulesAction(workflows.Action):
134
rule = forms.MultipleChoiceField(
137
widget=forms.CheckboxSelectMultiple(),
138
help_text=_("Create a policy with selected rules."))
142
permissions = ('openstack.services.network',)
143
help_text = _("Select rules for your policy.")
145
def populate_rule_choices(self, request, context):
147
tenant_id = self.request.user.tenant_id
148
rules = api.fwaas.rules_list(request, tenant_id=tenant_id)
150
r.set_id_as_name_if_empty()
151
rules = sorted(rules,
152
key=lambda rule: rule.name)
153
rule_list = [(rule.id, rule.name) for rule in rules
154
if not rule.firewall_policy_id]
155
except Exception as e:
157
exceptions.handle(request,
158
_('Unable to retrieve rules.') + str(e))
162
class SelectRulesStep(workflows.Step):
163
action_class = SelectRulesAction
164
template_name = "project/firewalls/_update_rules.html"
165
contributes = ("firewall_rules",)
167
def contribute(self, data, context):
169
rules = self.workflow.request.POST.getlist("rule")
171
rules = [r for r in rules if r != '']
172
context['firewall_rules'] = rules
176
class AddPolicyAction(workflows.Action):
177
name = forms.CharField(max_length=80,
180
description = forms.CharField(max_length=80,
181
label=_("Description"),
183
shared = forms.BooleanField(label=_("Shared"),
186
audited = forms.BooleanField(label=_("Audited"),
190
def __init__(self, request, *args, **kwargs):
191
super(AddPolicyAction, self).__init__(request, *args, **kwargs)
194
name = _("AddPolicy")
195
permissions = ('openstack.services.network',)
196
help_text = _("Create a firewall policy with an ordered list "
197
"of firewall rules.\n\n"
198
"A name must be given. Firewall rules are "
199
"added in the order placed under the Rules tab.")
202
class AddPolicyStep(workflows.Step):
203
action_class = AddPolicyAction
204
contributes = ("name", "description", "shared", "audited")
206
def contribute(self, data, context):
207
context = super(AddPolicyStep, self).contribute(data, context)
212
class AddPolicy(workflows.Workflow):
214
name = _("Add Policy")
215
finalize_button_name = _("Add")
216
success_message = _('Added Policy "%s".')
217
failure_message = _('Unable to add Policy "%s".')
218
success_url = "horizon:project:firewalls:index"
219
default_steps = (AddPolicyStep, SelectRulesStep)
221
def format_status_message(self, message):
222
return message % self.context.get('name')
224
def handle(self, request, context):
226
api.fwaas.policy_create(request, **context)
228
except Exception as e:
229
msg = self.format_status_message(self.failure_message) + str(e)
230
exceptions.handle(request, msg)
234
class AddFirewallAction(workflows.Action):
235
name = forms.CharField(max_length=80,
238
description = forms.CharField(max_length=80,
239
label=_("Description"),
241
firewall_policy_id = forms.ChoiceField(label=_("Policy"),
243
shared = forms.BooleanField(label=_("Shared"),
246
admin_state_up = forms.BooleanField(label=_("Admin State"),
250
def __init__(self, request, *args, **kwargs):
251
super(AddFirewallAction, self).__init__(request, *args, **kwargs)
253
firewall_policy_id_choices = [('', _("Select a Policy"))]
255
tenant_id = self.request.user.tenant_id
256
policies = api.fwaas.policies_list(request, tenant_id=tenant_id)
257
policies = sorted(policies, key=lambda policy: policy.name)
258
except Exception as e:
259
exceptions.handle(request,
260
_('Unable to retrieve policy list.') + str(e))
263
p.set_id_as_name_if_empty()
264
firewall_policy_id_choices.append((p.id, p.name))
265
self.fields['firewall_policy_id'].choices = firewall_policy_id_choices
266
# only admin can set 'shared' attribute to True
267
if not request.user.is_superuser:
268
self.fields['shared'].widget.attrs['disabled'] = 'disabled'
271
name = _("AddFirewall")
272
permissions = ('openstack.services.network',)
273
help_text = _("Create a firewall based on a policy.\n\n"
274
"A policy must be selected. "
275
"Other fields are optional.")
278
class AddFirewallStep(workflows.Step):
279
action_class = AddFirewallAction
280
contributes = ("name", "firewall_policy_id", "description",
281
"shared", "admin_state_up")
283
def contribute(self, data, context):
284
context = super(AddFirewallStep, self).contribute(data, context)
288
class AddFirewall(workflows.Workflow):
290
name = _("Add Firewall")
291
finalize_button_name = _("Add")
292
success_message = _('Added Firewall "%s".')
293
failure_message = _('Unable to add Firewall "%s".')
294
success_url = "horizon:project:firewalls:index"
295
# fwaas is designed to support a wide range of vendor
296
# firewalls. Considering the multitude of vendor firewall
297
# features in place today, firewall definition can
298
# involve more complex configuration over time. Hence,
299
# a workflow instead of a single form is used for
300
# firewall_rule add to be ready for future extension.
301
default_steps = (AddFirewallStep,)
303
def format_status_message(self, message):
304
return message % self.context.get('name')
306
def handle(self, request, context):
308
api.fwaas.firewall_create(request, **context)
310
except Exception as e:
311
msg = self.format_status_message(self.failure_message) + str(e)
312
exceptions.handle(request, msg)