Skip to content

Commit 7c6d825

Browse files
wojtek0806zancas
authored andcommitted
Issues:
Fixes #379, #452, #461, #462 Problem: SDK needs to be able to run on multiple versions of TMOS. Some API endpoints were not implemented in the base 11.6.0, but exist in 12.x. This SDK needs the ability to verify the TMOS version when instantiating the API classes. Analysis: This update forces the tmos version update upon ManagementRoot instantiation. Moreover it adds a new private method into LazyAttributeMixin class: _check_supported_versions which is responsible for veryfing if an instantiated class for the API is supported in the target's device tmos. Files affected: f5\bigip\__init__.py f5\bigip\mixins.py f5\bigip\resource.py f5\bigip\tm\cm\trust.py f5\bigip\tm\ltm\profile.py
1 parent 26b95f8 commit 7c6d825

5 files changed

Lines changed: 50 additions & 1 deletion

File tree

f5/bigip/__init__.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818

1919

2020
from icontrol.session import iControlRESTSession
21+
from urlparse import parse_qs
22+
from urlparse import urlparse
23+
2124

2225
from f5.bigip.cm import Cm
2326
from f5.bigip.resource import PathElement
@@ -54,8 +57,10 @@ def __init__(self, hostname, username, password, **kwargs):
5457
'bigip': self,
5558
'icontrol_version': icontrol_version,
5659
'username': username,
57-
'password': password
60+
'password': password,
61+
'tmos_version': None,
5862
}
63+
self._get_tmos_version()
5964

6065
@property
6166
def hostname(self):
@@ -65,6 +70,18 @@ def hostname(self):
6570
def icontrol_version(self):
6671
return self._meta_data['icontrol_version']
6772

73+
@property
74+
def tmos_version(self):
75+
return self._meta_data['tmos_version']
76+
77+
def _get_tmos_version(self):
78+
connect = self._meta_data['bigip']._meta_data['icr_session']
79+
base_uri = self._meta_data['uri'] + 'tm/sys/'
80+
response = connect.get(base_uri)
81+
ver = response.json()
82+
version = str(parse_qs(urlparse(ver['selfLink']).query)['ver'][0])
83+
self._meta_data['tmos_version'] = version
84+
6885

6986
class BigIP(ManagementRoot):
7087
"""A shim class used to access the default config resources in 'mgmt/tm.'

f5/bigip/mixins.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,14 @@ class UnsupportedMethod(F5SDKError):
3131
pass
3232

3333

34+
class UnsupportedTmosVersion(F5SDKError):
35+
"""Raise the error if a class of an API is instantiated,
36+
37+
on a TMOS version where API was not yet implemented/supported.
38+
"""
39+
pass
40+
41+
3442
class LazyAttributesRequired(F5SDKError):
3543
"""Raised when a object accesses a lazy attribute that is not listed"""
3644
pass
@@ -101,10 +109,20 @@ def __getattr__(container, name):
101109
if name == lazy_attribute.__name__.lower():
102110
attribute = lazy_attribute(container)
103111
bases = [base.__name__ for base in lazy_attribute.__bases__]
112+
# Doing version check per each resource
113+
container._check_supported_versions(attribute)
104114
if 'Resource' not in bases:
105115
setattr(container, name, attribute)
106116
return attribute
107117

118+
def _check_supported_versions(container, attribute):
119+
tmos_v = container._meta_data['bigip'].tmos_version
120+
if tmos_v not in attribute._meta_data['supported_versions']:
121+
error = "There was an attempt to access API which " \
122+
"has not been implemented or supported " \
123+
"in the device's TMOS version: {}".format(tmos_v)
124+
raise UnsupportedTmosVersion(error)
125+
108126

109127
class ExclusiveAttributesMixin(object):
110128
"""Overrides ``__setattr__`` to remove exclusive attrs from the object."""

f5/bigip/resource.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ class PathElement(LazyAttributeMixin):
162162
those elements and does not support any of the CURDLE methods that
163163
the other objects do.
164164
"""
165+
165166
def __init__(self, container):
166167
self._meta_data = {
167168
'container': container,
@@ -170,6 +171,9 @@ def __init__(self, container):
170171
'icontrol_version': container._meta_data['icontrol_version']
171172
}
172173
self._set_meta_data_uri()
174+
# Supported versions for each class will be defined here.
175+
# List can be modified downstream in each sub-class
176+
self._meta_data['supported_versions'] = set(['11.6.0', '12.0.0'])
173177

174178
def _set_meta_data_uri(self):
175179
base_uri = self.__class__.__name__.lower()

f5/bigip/tm/cm/trust.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,17 @@ class Add_To_Trust(UnnamedResourceMixin, ExclusiveAttributesMixin,
3131

3232
def __init__(self, cm):
3333
super(Add_To_Trust, self).__init__(cm)
34+
base_uri = type(self).__name__.replace('_', '-').lower()
35+
self._meta_data['uri'] =\
36+
self._meta_data['container']._meta_data['uri'] + base_uri + '/'
3437
self._meta_data['exclusive_attributes'].append(
3538
('caDevice', 'nonCaDevice'))
3639
self._meta_data['required_creation_parameters'].update(
3740
('device', 'deviceName', 'username', 'password'))
3841
self._meta_data['required_json_kind'] = \
3942
'tm:cm:add-to-trust:runstate'
4043
self._meta_data['allowed_commands'].append('run')
44+
self._meta_data['supported_versions'].discard('11.6.0')
4145

4246

4347
class Remove_From_Trust(UnnamedResourceMixin, CommandExecutionMixin, Resource):
@@ -54,8 +58,12 @@ class Remove_From_Trust(UnnamedResourceMixin, CommandExecutionMixin, Resource):
5458

5559
def __init__(self, cm):
5660
super(Remove_From_Trust, self).__init__(cm)
61+
base_uri = type(self).__name__.replace('_', '-').lower()
62+
self._meta_data['uri'] =\
63+
self._meta_data['container']._meta_data['uri'] + base_uri + '/'
5764
self._meta_data['required_creation_parameters'].update(
5865
('deviceName',))
5966
self._meta_data['required_json_kind'] = \
6067
'tm:cm:remove-from-trust:runstate'
6168
self._meta_data['allowed_commands'].append('run')
69+
self._meta_data['supported_versions'].discard('11.6.0')

f5/bigip/tm/ltm/profile.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,7 @@ def __init__(self, profile):
511511
self._meta_data['allowed_lazy_attributes'] = [Iiop]
512512
self._meta_data['attribute_registry'] = \
513513
{'tm:ltm:profile:iiop:iiopstate': Iiop}
514+
self._meta_data['supported_versions'].discard('11.6.0')
514515

515516

516517
class Iiop(Resource):
@@ -1034,6 +1035,7 @@ def __init__(self, profile):
10341035
self._meta_data['allowed_lazy_attributes'] = [Tftp]
10351036
self._meta_data['attribute_registry'] = \
10361037
{'tm:ltm:profile:tftp:tftpstate': Tftp}
1038+
self._meta_data['supported_versions'].discard('11.6.0')
10371039

10381040

10391041
class Tftp(Resource):

0 commit comments

Comments
 (0)