Skip to content

Commit 653ed0c

Browse files
priyalpalkarcaphrim007
authored andcommitted
Firewall Policies, global rules and analytics settings. (#1358)
* Firewall Policies, global rules and analytics settings. Analysis: Firewall policies, firewall global rules and analytics settings can now be added/modified. Tests: Functional and unit tests for the above features have been added. * Fix style issues
1 parent 9c7e99d commit 653ed0c

7 files changed

Lines changed: 285 additions & 4 deletions

File tree

f5/bigip/tm/security/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
"""
2929

3030
from f5.bigip.resource import OrganizingCollection
31+
from f5.bigip.tm.security.analytics import Analytics
3132
from f5.bigip.tm.security.dos import Dos
3233
from f5.bigip.tm.security.firewall import Firewall
3334

@@ -37,4 +38,4 @@ class Security(OrganizingCollection):
3738

3839
def __init__(self, tm):
3940
super(Security, self).__init__(tm)
40-
self._meta_data['allowed_lazy_attributes'] = [Dos, Firewall]
41+
self._meta_data['allowed_lazy_attributes'] = [Dos, Firewall, Analytics]

f5/bigip/tm/security/analytics.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# coding=utf-8
2+
#
3+
# Copyright 2015-2017 F5 Networks Inc.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
18+
"""BIG-IP® Advanced Firewall Manager™ (AFM®) module.
19+
20+
REST URI
21+
``http://localhost/mgmt/tm/security/analytics``
22+
23+
GUI Path
24+
``Security --> Network Firewall``
25+
26+
REST Kind
27+
``tm:security:analytics:*``
28+
"""
29+
from f5.bigip.resource import OrganizingCollection
30+
from f5.bigip.resource import UnnamedResource
31+
32+
33+
class Analytics(OrganizingCollection):
34+
"""BIG-IP® AFM® Analytics organizing collection."""
35+
36+
def __init__(self, security):
37+
super(Analytics, self).__init__(security)
38+
self._meta_data['allowed_lazy_attributes'] = [Settings]
39+
40+
41+
class Settings(UnnamedResource):
42+
"""BIG-IP® Analytics settings resource"""
43+
def __init__(self, settings):
44+
super(Settings, self).__init__(settings)
45+
self._meta_data['required_json_kind'] = \
46+
'tm:security:analytics:settings:settingsstate'

f5/bigip/tm/security/firewall.py

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,14 @@
2626
REST Kind
2727
``tm:security:firewall:*``
2828
"""
29+
from distutils.version import LooseVersion
2930
from f5.bigip.mixins import CheckExistenceMixin
3031
from f5.bigip.resource import Collection
3132
from f5.bigip.resource import OrganizingCollection
3233
from f5.bigip.resource import Resource
34+
from f5.bigip.resource import UnnamedResource
3335
from f5.sdk_exception import NonExtantFirewallRule
3436

35-
from distutils.version import LooseVersion
36-
3737

3838
class Firewall(OrganizingCollection):
3939
"""BIG-IP® AFM® Firewall organizing collection."""
@@ -43,7 +43,9 @@ def __init__(self, security):
4343
self._meta_data['allowed_lazy_attributes'] = [
4444
Address_Lists,
4545
Port_Lists,
46-
Rule_Lists]
46+
Rule_Lists,
47+
Policy_s,
48+
Global_Rules]
4749

4850

4951
class Address_Lists(Collection):
@@ -198,3 +200,35 @@ def _exists_11_6(self, **kwargs):
198200

199201
return self._check_existence_by_collection(
200202
self._meta_data['container'], kwargs['name'])
203+
204+
205+
class Policy_s(Collection):
206+
"""BIG-IP® AFM® Policy collection"""
207+
def __init__(self, firewall):
208+
super(Policy_s, self).__init__(firewall)
209+
self._meta_data['allowed_lazy_attributes'] = [Policy]
210+
self._meta_data['attribute_registry'] = \
211+
{'tm:security:firewall:policy:policystate':
212+
Policy}
213+
214+
215+
class Policy(Resource):
216+
"""BIG-IP® AFM® Policy resource"""
217+
def __init__(self, policy_s):
218+
super(Policy, self).__init__(policy_s)
219+
self._meta_data['required_json_kind'] = \
220+
'tm:security:firewall:policy:policystate'
221+
self._meta_data['required_creation_parameters'].update(('partition',))
222+
self._meta_data['required_load_parameters'].update(('partition',))
223+
self._meta_data['allowed_lazy_attributes'] = [Rules_s]
224+
self._meta_data['attribute_registry'] = \
225+
{'tm:security:firewall:rule-list:rules:rulescollectionstate':
226+
Rules_s}
227+
228+
229+
class Global_Rules(UnnamedResource):
230+
"""BIG-IP® AFM® Global Rules resource"""
231+
def __init__(self, global_rules):
232+
super(Global_Rules, self).__init__(global_rules)
233+
self._meta_data['required_json_kind'] = \
234+
'tm:security:firewall:global-rules:global-rulesstate'
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Copyright 2017 F5 Networks Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
#
15+
16+
17+
class TestAnalytics(object):
18+
_enable_settings = {"aclRules": {"collectClientIp": "enabled"}}
19+
_disable_settings = {"aclRules": {"collectClientIp": "disabled"}}
20+
21+
def test_modify_settings(self, mgmt_root):
22+
settings = mgmt_root.tm.security.analytics.settings.load()
23+
assert "aclRules" in settings.__dict__
24+
assert settings.aclRules["collectClientIp"] == "enabled"
25+
settings.modify(**self._disable_settings)
26+
assert settings.aclRules["collectClientIp"] == "disabled"
27+
settings.modify(**self._enable_settings)

f5/bigip/tm/security/test/functional/test_firewall.py

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from distutils.version import LooseVersion
1919
from f5.bigip.resource import MissingRequiredCreationParameter
2020
from f5.bigip.tm.security.firewall import Address_List
21+
from f5.bigip.tm.security.firewall import Policy
2122
from f5.bigip.tm.security.firewall import Port_List
2223
from f5.bigip.tm.security.firewall import Rule
2324
from f5.bigip.tm.security.firewall import Rule_List
@@ -63,6 +64,14 @@ def rule(rulelst):
6364
r1.delete()
6465

6566

67+
@pytest.fixture(scope='function')
68+
def policy(mgmt_root):
69+
p1 = mgmt_root.tm.security.firewall.policy_s.policy.create(
70+
name='fake_policy', partition='Common')
71+
yield p1
72+
p1.delete()
73+
74+
6675
class TestAddressList(object):
6776
def test_create_missing_mandatory_attr_raises(self, mgmt_root):
6877
ac = mgmt_root.tm.security.firewall.address_lists
@@ -477,3 +486,86 @@ def test_rules_subcollection(self, rulelst, rule):
477486
assert isinstance(rc, list)
478487
assert len(rc)
479488
assert isinstance(rc[0], Rule)
489+
490+
491+
class TestPolicy(object):
492+
def test_create_req_args(self, mgmt_root):
493+
p1 = mgmt_root.tm.security.firewall.policy_s.policy.create(
494+
name='fake_policy', partition='Common')
495+
URI = 'https://localhost/mgmt/tm/security/' \
496+
'firewall/policy/~Common~fake_policy'
497+
assert p1.name == 'fake_policy'
498+
assert p1.partition == 'Common'
499+
assert p1.selfLink.startswith(URI)
500+
assert not hasattr(p1, 'description')
501+
p1.delete()
502+
503+
def test_refresh(self, mgmt_root, policy):
504+
p1 = policy
505+
p2 = mgmt_root.tm.security.firewall.policy_s.policy.load(
506+
name='fake_policy', partition='Common')
507+
assert p1.name == p2.name
508+
assert p1.kind == p2.kind
509+
assert p1.selfLink == p2.selfLink
510+
assert not hasattr(p1, 'description')
511+
assert not hasattr(p2, 'description')
512+
p2.modify(description=DESC)
513+
p1.modify(description=DESC)
514+
assert hasattr(p2, 'description')
515+
assert p2.description == DESC
516+
p1.refresh()
517+
assert p1.selfLink == p2.selfLink
518+
assert hasattr(p1, 'description')
519+
assert p1.description == p2.description
520+
521+
def test_delete(self, mgmt_root):
522+
p = mgmt_root.tm.security.firewall.policy_s.policy
523+
p1 = p.create(name='delete_me', partition='Common')
524+
p1.delete()
525+
with pytest.raises(HTTPError) as err:
526+
mgmt_root.tm.security.firewall.policy_s.policy.load(
527+
name='delete_me', partition='Common')
528+
assert err.value.response.status_code == 404
529+
530+
def test_load_no_object(self, mgmt_root):
531+
p = mgmt_root.tm.security.firewall.policy_s.policy
532+
with pytest.raises(HTTPError) as err:
533+
p.load(name='not_exists', partition='Common')
534+
assert err.value.response.status_code == 404
535+
536+
def test_load_and_update(self, mgmt_root, policy):
537+
p1 = policy
538+
URI = 'https://localhost/mgmt/tm/security/' \
539+
'firewall/policy/~Common~fake_policy'
540+
assert p1.name == 'fake_policy'
541+
assert p1.partition == 'Common'
542+
assert p1.selfLink.startswith(URI)
543+
assert not hasattr(p1, 'description')
544+
p1.description = DESC
545+
p1.update()
546+
assert hasattr(p1, 'description')
547+
assert p1.description == DESC
548+
p = mgmt_root.tm.security.firewall.policy_s.policy
549+
p2 = p.load(name='fake_policy', partition='Common')
550+
assert p1.name == p2.name
551+
assert p1.partition == p2.partition
552+
assert p1.selfLink == p2.selfLink
553+
assert hasattr(p2, 'description')
554+
assert p1.description == p2.description
555+
556+
def test_policies_collection(self, mgmt_root, policy):
557+
pc = mgmt_root.tm.security.firewall.policy_s.get_collection()
558+
assert isinstance(pc, list)
559+
assert len(pc)
560+
assert isinstance(pc[0], Policy)
561+
562+
563+
class TestGlobalRules(object):
564+
def test_modify_req_args(self, mgmt_root, policy):
565+
rules = mgmt_root.tm.security.firewall. \
566+
global_rules.load(partition='Common')
567+
assert "enforcedPolicy" not in rules.__dict__
568+
rules.modify(enforcedPolicy='fake_policy', partition='Common')
569+
assert rules.enforcedPolicy == "/Common/fake_policy"
570+
rules.modify(enforcedPolicy='none', partition='Common')
571+
assert "enforcedPolicy" not in rules.__dict__
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Copyright 2017 F5 Networks Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
#
15+
16+
from f5.bigip import ManagementRoot
17+
18+
19+
class TestAnalyticsSettings(object):
20+
def test_analytics_settings_kind(self, fakeicontrolsession):
21+
b = ManagementRoot('192.168.1.1', 'admin', 'admin')
22+
settings = b.tm.security.analytics.settings
23+
kind = "tm:security:analytics:settings:settingsstate"
24+
assert settings._meta_data["required_json_kind"] == kind

f5/bigip/tm/security/test/unit/test_firewall.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
from f5.bigip import ManagementRoot
2020
from f5.bigip.tm.security.firewall import Address_List
21+
from f5.bigip.tm.security.firewall import Policy
2122
from f5.bigip.tm.security.firewall import Port_List
2223
from f5.bigip.tm.security.firewall import Rule
2324
from f5.bigip.tm.security.firewall import Rule_List
@@ -49,6 +50,13 @@ def FakeRuleLst():
4950
return fake_rulelst
5051

5152

53+
@pytest.fixture
54+
def FakePolicy():
55+
fake_col = mock.MagicMock()
56+
fake_policy = Policy(fake_col)
57+
return fake_policy
58+
59+
5260
def Makerulelist(fakeicontrolsession):
5361
b = ManagementRoot('192.168.1.1', 'admin', 'admin')
5462
p = b.tm.security.firewall.rule_lists.rule_list
@@ -58,6 +66,23 @@ def Makerulelist(fakeicontrolsession):
5866
return p
5967

6068

69+
def MakePolicyRules(fakeicontrolsession):
70+
b = ManagementRoot('192.168.1.1', 'admin', 'admin')
71+
p = b.tm.security.firewall.policy_s.policy
72+
p._meta_data['uri'] = \
73+
'https://192.168.1.1:443/mgmt/tm/security/firewall/policy/' \
74+
'~Common~fakepolicy/'
75+
return p
76+
77+
78+
def MakeGlobalRules(fakeicontrolsession):
79+
b = ManagementRoot('192.168.1.1', 'admin', 'admin')
80+
p = b.tm.security.firewall.global_rules
81+
p._meta_data['uri'] = \
82+
'https://192.168.1.1:443/mgmt/tm/security/firewall/global_rules/'
83+
return p
84+
85+
6186
class TestAddressList(object):
6287
def test_create_two(self, fakeicontrolsession):
6388
b = ManagementRoot('192.168.1.1', 'admin', 'admin')
@@ -127,3 +152,35 @@ def test_app_create_no_args_v11(self, fakeicontrolsession):
127152
pc = Rules_s(Makerulelist(fakeicontrolsession))
128153
with pytest.raises(MissingRequiredCreationParameter):
129154
pc.rule.create()
155+
156+
157+
class TestPolicy(object):
158+
def test_create_two(self, fakeicontrolsession):
159+
b = ManagementRoot('192.168.1.1', 'admin', 'admin')
160+
r1 = b.tm.security.firewall.policy_s.policy
161+
r2 = b.tm.security.firewall.policy_s.policy
162+
assert r1 is not r2
163+
164+
def test_create_no_args(self, FakePolicy):
165+
with pytest.raises(MissingRequiredCreationParameter):
166+
FakePolicy.create()
167+
168+
169+
class TestPolicyRuleSubCollection(object):
170+
def test_policy_rule_subcollection(self, fakeicontrolsession):
171+
pc = Rules_s(MakePolicyRules(fakeicontrolsession))
172+
kind = 'tm:security:firewall:rule-list:rules:rulesstate'
173+
test_meta = pc._meta_data['attribute_registry']
174+
test_meta2 = pc._meta_data['allowed_lazy_attributes']
175+
assert isinstance(pc, Rules_s)
176+
assert kind in list(iterkeys(test_meta))
177+
assert Rule in test_meta2
178+
179+
180+
class TestGlobalRules(object):
181+
def test_global_rules(self, fakeicontrolsession):
182+
b = ManagementRoot('192.168.1.1', 'admin', 'admin')
183+
kind = "tm:security:firewall:global-rules:global-rulesstate"
184+
rules = b.tm.security.firewall.global_rules
185+
rules_kind = rules._meta_data["required_json_kind"]
186+
assert rules_kind == kind

0 commit comments

Comments
 (0)