Skip to content

Commit b2f5e1b

Browse files
authored
Merge pull request #1316 from caphrim007/bugfix.allow-asm-tasks-to-import-to-partition
Adds the ability for ASM tasks to import to different partititions
2 parents 09998ae + fbb41a9 commit b2f5e1b

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)