Skip to content

Commit fbb41a9

Browse files
committed
Adds the ability for ASM tasks to import to different partititions
Issues: Fixes #1315 Problem: Previously you could not import an ASM policy to a specific partition Analysis: This patch provides two methods to import an ASM policy to a partition. First, you can specify the fullPath argument. This is directly mapped to the fullPath attribute of the resource and ASM will import the partition that is specified in the full path. ex, /Partition1/my_policy Second, you can specify a combination of 'name' and 'partition' to the `create` method. This method is just a convenience wrapper on top of the aforementioned method. In the end, this method will generate the fullPath for you. This method is more inline with other APIs that accept a 'partition' argument Tests: functional
1 parent 09998ae commit fbb41a9

3 files changed

Lines changed: 104 additions & 4 deletions

File tree

f5/bigip/tm/asm/tasks.py

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,10 @@
3030
from f5.bigip.resource import AsmTaskResource
3131
from f5.bigip.resource import Collection
3232
from f5.bigip.resource import OrganizingCollection
33+
from f5.sdk_exception import F5SDKError
34+
from f5.sdk_exception import RequiredOneOf
3335
from f5.sdk_exception import UnsupportedOperation
36+
from six import iterkeys
3437

3538

3639
class Tasks(OrganizingCollection):
@@ -125,12 +128,31 @@ class Import_Policy(AsmResource):
125128
def __init__(self, import_policy_s):
126129
super(Import_Policy, self).__init__(import_policy_s)
127130
self._meta_data['required_json_kind'] = 'tm:asm:tasks:import-policy:import-policy-taskstate'
128-
self._meta_data['required_creation_parameters'] = {
129-
'name'
130-
}
131+
self._meta_data['required_creation_parameters'] = set()
131132
self._meta_data['exclusive_attributes'] = ['filename', 'file']
132133
self._meta_data['minimum_additional_parameters'] = {'filename', 'file', 'policyTemplateReference'}
133134

135+
def create(self, **kwargs):
136+
required_one_of = ['name', 'fullPath']
137+
has_any = [x for x in iterkeys(kwargs) if x in required_one_of]
138+
139+
if 'partition' in kwargs and 'name' in kwargs and 'fullPath' not in kwargs:
140+
partition = kwargs.pop('partition', None)
141+
name = kwargs.pop('name', None)
142+
if partition is not None and not partition.startswith('/'):
143+
kwargs['fullPath'] = '/{0}/{1}'.format(partition, name)
144+
elif partition is None:
145+
raise F5SDKError(
146+
"The partition name, if specified, cannot be none"
147+
)
148+
elif partition.startswith('/'):
149+
kwargs['fullPath'] = '{0}/{1}'.format(partition, name)
150+
151+
if len(has_any) == 1:
152+
return self._create(**kwargs)
153+
154+
raise RequiredOneOf(required_one_of)
155+
134156
def modify(self, **kwargs):
135157
"""Modify is not supported for Apply Policy resource
136158

f5/bigip/tm/asm/test/functional/test_tasks.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,26 @@ def file_read():
5555
return result
5656

5757

58+
def remove_policies(mgmt_root, policy=None):
59+
policies = mgmt_root.tm.asm.policies_s.get_collection()
60+
if policy is None:
61+
resources = policies
62+
else:
63+
resources = [p for p in policies if p.name == policy]
64+
for resource in resources:
65+
resource.delete()
66+
67+
68+
@pytest.fixture(scope='function')
69+
def partition(mgmt_root):
70+
file = tempfile.NamedTemporaryFile()
71+
name = os.path.basename(file.name)
72+
partitions = mgmt_root.tm.auth.partitions.partition
73+
local = partitions.create(name=name)
74+
yield local
75+
local.delete()
76+
77+
5878
@pytest.fixture(scope='function')
5979
def check_sig(mgmt_root):
6080
task = mgmt_root.tm.asm.tasks.check_signatures_s.check_signature.fetch()
@@ -221,6 +241,43 @@ def import_policy(mgmt_root):
221241
task.delete()
222242

223243

244+
@pytest.fixture(scope='function')
245+
def import_partitioned_policy(mgmt_root, partition):
246+
content = file_read()
247+
file = tempfile.NamedTemporaryFile()
248+
name = os.path.basename(file.name)
249+
task = mgmt_root.tm.asm.tasks.import_policy_s.import_policy.create(
250+
file=content,
251+
fullPath='/{0}/{1}'.format(partition.name, name)
252+
)
253+
while True:
254+
task.refresh()
255+
if task.status in ['COMPLETED', 'FAILURE']:
256+
break
257+
time.sleep(1)
258+
yield task
259+
task.delete()
260+
261+
262+
@pytest.fixture(scope='function')
263+
def import_partitioned_policy2(mgmt_root, partition):
264+
content = file_read()
265+
file = tempfile.NamedTemporaryFile()
266+
name = os.path.basename(file.name)
267+
task = mgmt_root.tm.asm.tasks.import_policy_s.import_policy.create(
268+
file=content,
269+
name=name,
270+
partition=partition.name
271+
)
272+
while True:
273+
task.refresh()
274+
if task.status in ['COMPLETED', 'FAILURE']:
275+
break
276+
time.sleep(1)
277+
yield task
278+
task.delete()
279+
280+
224281
@pytest.fixture(scope='function')
225282
def import_vuln(mgmt_root, set_policy):
226283
reference = {'link': set_policy}
@@ -423,6 +480,26 @@ def test_create_import_template(self, import_policy_template):
423480
assert imp1.kind == 'tm:asm:tasks:import-policy:import-policy-taskstate'
424481
assert imp1.isBase64 is False
425482

483+
def test_create_import_partitioned(self, mgmt_root, import_partitioned_policy):
484+
imp1 = import_partitioned_policy
485+
endpoint = str(imp1.id)
486+
base_uri = 'https://localhost/mgmt/tm/asm/tasks/import-policy/'
487+
final_uri = base_uri + endpoint
488+
assert imp1.selfLink.startswith(final_uri)
489+
assert imp1.kind == 'tm:asm:tasks:import-policy:import-policy-taskstate'
490+
assert imp1.isBase64 is False
491+
remove_policies(mgmt_root, os.path.basename(imp1.fullPath))
492+
493+
def test_create_import_partitioned2(self, mgmt_root, import_partitioned_policy2):
494+
imp1 = import_partitioned_policy2
495+
endpoint = str(imp1.id)
496+
base_uri = 'https://localhost/mgmt/tm/asm/tasks/import-policy/'
497+
final_uri = base_uri + endpoint
498+
assert imp1.selfLink.startswith(final_uri)
499+
assert imp1.kind == 'tm:asm:tasks:import-policy:import-policy-taskstate'
500+
assert imp1.isBase64 is False
501+
remove_policies(mgmt_root, os.path.basename(imp1.fullPath))
502+
426503
def test_create_import_fails(self, import_policy_base64):
427504
imp1 = import_policy_base64
428505
endpoint = str(imp1.id)

f5/bigip/tm/asm/test/unit/test_tasks.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
from f5.bigip.tm.asm.tasks import Import_Vulnerabilities
2424
from f5.bigip.tm.asm.tasks import Update_Signature
2525
from f5.sdk_exception import MissingRequiredCreationParameter
26+
from f5.sdk_exception import RequiredOneOf
2627
from f5.sdk_exception import UnsupportedOperation
2728
from f5.sdk_exception import UnsupportedTmosVersion
2829

@@ -249,7 +250,7 @@ def test_create_two(self, fakeicontrolsession):
249250
assert t1 is t2
250251

251252
def test_create_no_args(self, FakeImportPolicy):
252-
with pytest.raises(MissingRequiredCreationParameter):
253+
with pytest.raises(RequiredOneOf):
253254
FakeImportPolicy.create()
254255

255256
def test_collection(self, fakeicontrolsession):

0 commit comments

Comments
 (0)