Skip to content

Commit 0a90b4d

Browse files
Paul Breauxzancas
authored andcommitted
A new method named modify needs to be a selective operation
Issues: Fixes #609 Problem: Instead of puting the whole configuration object in a request to the server, modify will only submit the explicitly specified parameters in its kwargs, in a patch request to the server. This feature should be implemented after #608. Analysis: Added modify in ResourceBase, and created a couple of non-public helper functions to make common usage among _update and _modify. Tests: Unit tests pass, but functionals still need to be written. Only one functional test exists currently.
1 parent 83fa8f5 commit 0a90b4d

3 files changed

Lines changed: 29 additions & 13 deletions

File tree

f5/bigip/resource.py

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -444,9 +444,17 @@ def _modify(self, **kwargs):
444444
requests_params, patch_uri, session, read_only = \
445445
self._prepare_put_or_patch(kwargs)
446446
self._check_for_boolean_pair_reduction(kwargs)
447-
data_dict = self._pop_read_only_attrs(kwargs, read_only)
448-
data_dict.update(kwargs)
449-
response = session.patch(patch_uri, json=data_dict, **requests_params)
447+
448+
read_only_mutations = []
449+
for attr in read_only:
450+
if attr in kwargs:
451+
read_only_mutations.append(attr)
452+
if read_only_mutations:
453+
msg = 'Attempted to mutate read-only attribute(s): %s' \
454+
% read_only_mutations
455+
raise AttemptedMutationOfReadOnly(msg)
456+
457+
response = session.patch(patch_uri, json=kwargs, **requests_params)
450458
self._local_update(response.json())
451459

452460
def modify(self, **kwargs):
@@ -473,13 +481,6 @@ def _prepare_put_or_patch(self, kwargs):
473481
read_only = self._meta_data.get('read_only_attributes', [])
474482
return requests_params, update_uri, session, read_only
475483

476-
def _pop_read_only_attrs(self, kwargs, read_only):
477-
"""Remove any read-only attributes from kwargs"""
478-
479-
for attr in read_only:
480-
kwargs.pop(attr, '')
481-
return kwargs
482-
483484
def _update(self, **kwargs):
484485
"""wrapped with update, override that in a subclass to customize"""
485486

@@ -512,7 +513,8 @@ def _update(self, **kwargs):
512513
# the data dict with the attributes. If they pass in read-only attrs
513514
# in the method call we are going to let BIG-IP® let them know about it
514515
# when it fails
515-
data_dict = self._pop_read_only_attrs(data_dict, read_only)
516+
for attr in read_only:
517+
data_dict.pop(attr, '')
516518

517519
data_dict.update(kwargs)
518520

f5/bigip/test/test_resource.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@
1616
import pytest
1717
import requests
1818

19+
from f5.bigip.resource import AttemptedMutationOfReadOnly
1920
from f5.bigip.resource import BooleansToReduceHaveSameValue
2021
from f5.bigip.resource import Collection
21-
from f5.bigip.resource import AttemptedMutationOfReadOnly
2222
from f5.bigip.resource import DeviceProvidesIncompatibleKey
2323
from f5.bigip.resource import ExclusiveAttributesPresent
2424
from f5.bigip.resource import GenerationMismatch
@@ -346,7 +346,7 @@ def test_Collection_removal(self):
346346
assert 'contained' in r.__dict__
347347
r.modify(a=u"b")
348348
submitted = r._meta_data['bigip']. \
349-
_meta_data['r_session'].patch.call_args[1]['json']
349+
_meta_data['icr_session'].patch.call_args[1]['json']
350350

351351
assert 'contained' not in submitted
352352

test/functional/tm/ltm/test_virtual.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from f5.bigip.resource import MissingRequiredCreationParameter
1919
from f5.bigip.resource import MissingRequiredReadParameter
2020

21+
import copy
2122
from pprint import pprint as pp
2223
import pytest
2324

@@ -63,6 +64,19 @@ def test_virtual_create_refresh_update_delete_load(
6364
virtual2 = vc1.virtual.load(partition='Common', name='vstest1')
6465
assert virtual2.selfLink == virtual1.selfLink
6566

67+
def test_virtual_modify(self, request, mgmt_root, setup_device_snapshot):
68+
virtual1, vc1 = setup_virtual_test(
69+
request, mgmt_root, 'Common', 'modtest1'
70+
)
71+
original_dict = copy.copy(virtual1.__dict__)
72+
desc = 'description'
73+
virtual1.modify(description='Cool mod test')
74+
for k, v in original_dict.items():
75+
if k != desc:
76+
original_dict[k] = virtual1.__dict__[k]
77+
elif k == desc:
78+
virtual1.__dict__[k] == 'Cool mod test'
79+
6680

6781
def test_profiles_CE(
6882
mgmt_root, opt_release, setup_device_snapshot

0 commit comments

Comments
 (0)