Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@
#

from f5.bigip import BigIP
import mock
import pytest

from icontrol.session import iControlRESTSession


def pytest_addoption(parser):
parser.addoption("--bigip", action="store",
Expand All @@ -33,6 +36,19 @@ def pytest_addoption(parser):
default='11.6.0')


@pytest.fixture
def fakeicontrolsession(monkeypatch):
class Response(object):
def json(self):
return {'selfLink': 'https://localhost/mgmt/tm/sys?ver=11.6.0'}
fakesessionclass = mock.create_autospec(iControlRESTSession, spec_set=True)
fakesessioninstance =\
mock.create_autospec(iControlRESTSession('A', 'B'), spec_set=True)
fakesessioninstance.get = mock.MagicMock(return_value=Response())
fakesessionclass.return_value = fakesessioninstance
monkeypatch.setattr('f5.bigip.iControlRESTSession', fakesessionclass)


@pytest.fixture
def opt_bigip(request):
return request.config.getoption("--bigip")
Expand Down
19 changes: 18 additions & 1 deletion f5/bigip/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@


from icontrol.session import iControlRESTSession
from urlparse import parse_qs
from urlparse import urlparse


from f5.bigip.cm import Cm
from f5.bigip.resource import PathElement
Expand Down Expand Up @@ -54,8 +57,10 @@ def __init__(self, hostname, username, password, **kwargs):
'bigip': self,
'icontrol_version': icontrol_version,
'username': username,
'password': password
'password': password,
'tmos_version': None,
}
self._get_tmos_version()

@property
def hostname(self):
Expand All @@ -65,6 +70,18 @@ def hostname(self):
def icontrol_version(self):
return self._meta_data['icontrol_version']

@property
def tmos_version(self):
return self._meta_data['tmos_version']

def _get_tmos_version(self):
connect = self._meta_data['bigip']._meta_data['icr_session']
base_uri = self._meta_data['uri'] + 'tm/sys/'
response = connect.get(base_uri)
ver = response.json()
version = parse_qs(urlparse(ver['selfLink']).query)['ver'][0]
self._meta_data['tmos_version'] = version


class BigIP(ManagementRoot):
"""A shim class used to access the default config resources in 'mgmt/tm.'
Expand Down
6 changes: 3 additions & 3 deletions f5/bigip/cm/autodeploy/test/test_software_image_uploads.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
CHUNKSIZE = 20


def test_software_image_uploads_80a(tmpdir):
def test_software_image_uploads_80a(tmpdir, fakeicontrolsession):
filepath = tmpdir.mkdir('testdir').join('eightya.iso')
filepath.write(80*'a')
mr = ManagementRoot('FAKENETLOC', 'FAKENAME', 'FAKEPASSWORD')
Expand All @@ -37,7 +37,7 @@ def test_software_image_uploads_80a(tmpdir):
assert d == 'a'*CHUNKSIZE


def test_software_image_uploads_70a(tmpdir):
def test_software_image_uploads_70a(tmpdir, fakeicontrolsession):
filepath = tmpdir.mkdir('testdir').join('seventya.iso')
filepath.write(70*'a')
mr = ManagementRoot('FAKENETLOC', 'FAKENAME', 'FAKEPASSWORD')
Expand All @@ -53,7 +53,7 @@ def test_software_image_uploads_70a(tmpdir):
assert 10*'a' == lchunk


def test_non_ISO_extension(tmpdir):
def test_non_ISO_extension(tmpdir, fakeicontrolsession):
filepath = tmpdir.mkdir('testdir').join('wrong.name')
mr = ManagementRoot('FAKENETLOC', 'FAKENAME', 'FAKEPASSWORD')
sius = mr.cm.autodeploy.software_image_uploads
Expand Down
18 changes: 18 additions & 0 deletions f5/bigip/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ class UnsupportedMethod(F5SDKError):
pass


class UnsupportedTmosVersion(F5SDKError):
"""Raise the error if a class of an API is instantiated,

on a TMOS version where API was not yet implemented/supported.
"""
pass


class LazyAttributesRequired(F5SDKError):
"""Raised when a object accesses a lazy attribute that is not listed"""
pass
Expand Down Expand Up @@ -101,10 +109,20 @@ def __getattr__(container, name):
if name == lazy_attribute.__name__.lower():
attribute = lazy_attribute(container)
bases = [base.__name__ for base in lazy_attribute.__bases__]
# Doing version check per each resource
container._check_supported_versions(attribute)
if 'Resource' not in bases:
setattr(container, name, attribute)
return attribute

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


class ExclusiveAttributesMixin(object):
"""Overrides ``__setattr__`` to remove exclusive attrs from the object."""
Expand Down
4 changes: 4 additions & 0 deletions f5/bigip/resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ class PathElement(LazyAttributeMixin):
those elements and does not support any of the CURDLE methods that
the other objects do.
"""

def __init__(self, container):
self._meta_data = {
'container': container,
Expand All @@ -170,6 +171,9 @@ def __init__(self, container):
'icontrol_version': container._meta_data['icontrol_version']
}
self._set_meta_data_uri()
# Supported versions for each class will be defined here.
# List can be modified downstream in each sub-class
self._meta_data['supported_versions'] = set(['11.6.0', '12.0.0'])

def _set_meta_data_uri(self):
base_uri = self.__class__.__name__.lower()
Expand Down
14 changes: 7 additions & 7 deletions f5/bigip/shared/test/test_file_uploads.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
FileMustNotHaveDotISOExtension


def test_file_upload_80a(tmpdir):
def test_file_upload_80a(tmpdir, fakeicontrolsession):
filepath = tmpdir.mkdir('testdir').join('eightya.txt')
filepath.write(80*'a')
mr = ManagementRoot('FAKENETLOC', 'FAKENAME', 'FAKEPASSWORD')
Expand All @@ -35,7 +35,7 @@ def test_file_upload_80a(tmpdir):
assert d == 'aaaaaaaaaaaaaaaaaaaa'


def test_file_upload_70a(tmpdir):
def test_file_upload_70a(tmpdir, fakeicontrolsession):
filepath = tmpdir.mkdir('testdir').join('seventya.txt')
filepath.write(70*'a')
mr = ManagementRoot('FAKENETLOC', 'FAKENAME', 'FAKEPASSWORD')
Expand All @@ -51,7 +51,7 @@ def test_file_upload_70a(tmpdir):
assert 10*'a' == lchunk


def test_ISO_extension(tmpdir):
def test_ISO_extension(tmpdir, fakeicontrolsession):
filepath = tmpdir.mkdir('testdir').join('wrongname.iso')
filepath.write('fake')
mr = ManagementRoot('FAKENETLOC', 'FAKENAME', 'FAKEPASSWORD')
Expand All @@ -61,7 +61,7 @@ def test_ISO_extension(tmpdir):
assert EIO.value.message == 'wrongname.iso'


def test_stringio_upload_80a(tmpdir):
def test_stringio_upload_80a(tmpdir, fakeicontrolsession):
sio = StringIO(80*'a')
mr = ManagementRoot('FAKENETLOC', 'FAKENAME', 'FAKEPASSWORD')
mr._meta_data['icr_session'] = mock.MagicMock()
Expand All @@ -73,7 +73,7 @@ def test_stringio_upload_80a(tmpdir):
assert d == 'aaaaaaaaaaaaaaaaaaaa'


def test_stringio_upload_70a(tmpdir):
def test_stringio_upload_70a(tmpdir, fakeicontrolsession):
sio = StringIO(70*'a')
mr = ManagementRoot('FAKENETLOC', 'FAKENAME', 'FAKEPASSWORD')
mr._meta_data['icr_session'] = mock.MagicMock()
Expand All @@ -87,7 +87,7 @@ def test_stringio_upload_70a(tmpdir):
assert 10*'a' == lchunk


def test_bytes_upload_80a(tmpdir):
def test_bytes_upload_80a(tmpdir, fakeicontrolsession):
bytestring80a = 80*'a'
mr = ManagementRoot('FAKENETLOC', 'FAKENAME', 'FAKEPASSWORD')
mr._meta_data['icr_session'] = mock.MagicMock()
Expand All @@ -99,7 +99,7 @@ def test_bytes_upload_80a(tmpdir):
assert d == 'aaaaaaaaaaaaaaaaaaaa'


def test_bytes_upload_70a(tmpdir):
def test_bytes_upload_70a(tmpdir, fakeicontrolsession):
bytestring70a = 70*'a'
mr = ManagementRoot('FAKENETLOC', 'FAKENAME', 'FAKEPASSWORD')
mr._meta_data['icr_session'] = mock.MagicMock()
Expand Down
4 changes: 2 additions & 2 deletions f5/bigip/test/test___init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@


@pytest.fixture
def FakeBigIP():
def FakeBigIP(fakeicontrolsession):
FBIP = BigIP('FakeHostName', 'admin', 'admin')
FBIP.icontrol = mock.MagicMock()
return FBIP


@pytest.fixture
def FakeBigIPWithPort():
def FakeBigIPWithPort(fakeicontrolsession):
FBIP = BigIP('FakeHostName', 'admin', 'admin', port='10443')
FBIP.icontrol = mock.MagicMock()
return FBIP
Expand Down
2 changes: 1 addition & 1 deletion f5/bigip/tm/auth/test/test_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def FakeUser():


class TestCreate(object):
def test_create_two(self):
def test_create_two(self, fakeicontrolsession):
b = BigIP('localhost', 'admin', 'admin')
n1 = b.auth.users.user
n2 = b.auth.users.user
Expand Down
2 changes: 1 addition & 1 deletion f5/bigip/tm/cm/test/test___init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@


@pytest.fixture
def FakeiControl():
def FakeiControl(fakeicontrolsession):
bigip = BigIP('host', 'fake_admin', 'fake_admin')
mock_session = mock.MagicMock()
mock_session.post.return_value.json.return_value = {}
Expand Down
2 changes: 2 additions & 0 deletions f5/bigip/tm/cm/trust.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ def __init__(self, cm):
self._meta_data['required_json_kind'] = \
'tm:cm:add-to-trust:runstate'
self._meta_data['allowed_commands'].append('run')
self._meta_data['supported_versions'].discard('11.6.0')


class Remove_From_Trust(UnnamedResourceMixin, CommandExecutionMixin, Resource):
Expand All @@ -59,3 +60,4 @@ def __init__(self, cm):
self._meta_data['required_json_kind'] = \
'tm:cm:remove-from-trust:runstate'
self._meta_data['allowed_commands'].append('run')
self._meta_data['supported_versions'].discard('11.6.0')
2 changes: 2 additions & 0 deletions f5/bigip/tm/ltm/profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,7 @@ def __init__(self, profile):
self._meta_data['allowed_lazy_attributes'] = [Iiop]
self._meta_data['attribute_registry'] = \
{'tm:ltm:profile:iiop:iiopstate': Iiop}
self._meta_data['supported_versions'].discard('11.6.0')


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


class Tftp(Resource):
Expand Down
2 changes: 1 addition & 1 deletion f5/bigip/tm/ltm/test/test_nat.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def FakeNat():


class TestCreate(object):
def test_create_two(self):
def test_create_two(self, fakeicontrolsession):
b = BigIP('192.168.1.1', 'admin', 'admin')
n1 = b.ltm.nats.nat
n2 = b.ltm.nats.nat
Expand Down
2 changes: 1 addition & 1 deletion f5/bigip/tm/ltm/test/test_rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def FakeRule():


class TestCreate(object):
def test_create_two(self):
def test_create_two(self, fakeicontrolsession):
b = BigIP('192.168.1.1', 'admin', 'admin')
r1 = b.ltm.rules.rule
r2 = b.ltm.rules.rule
Expand Down
5 changes: 4 additions & 1 deletion f5/bigip/tm/sys/test/test_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,15 @@
@pytest.fixture
def fake_dbs():
fake_sys = mock.MagicMock()
return Dbs(fake_sys)
dbs = Dbs(fake_sys)
dbs._meta_data['bigip'].tmos_version = '11.6.0'
return dbs


class TestDb(object):
def test_create_raises(self):
dbs = fake_dbs()
print(dbs.raw)
db = dbs.db
with pytest.raises(UnsupportedOperation):
db.create()
Expand Down
4 changes: 3 additions & 1 deletion f5/bigip/tm/sys/test/test_folder.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
@pytest.fixture
def FakeFolders():
fake_sys = mock.MagicMock()
return Folders(fake_sys)
folders = Folders(fake_sys)
folders._meta_data['bigip'].tmos_version = '11.6.0'
return folders


class TestFolder(object):
Expand Down
4 changes: 3 additions & 1 deletion f5/bigip/tm/sys/test/test_performance.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@
@pytest.fixture
def FakePerformance():
fake_sys = mock.MagicMock()
return Performances(fake_sys)
performances = Performances(fake_sys)
performances._meta_data['bigip'].tmos_version = '11.6.0'
return performances


class TestPerformance(object):
Expand Down
8 changes: 4 additions & 4 deletions f5/bigip/tm/sys/test/test_sys_application.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ def __init__(self):


class TestServiceCreate(object):
def test_create_two(self):
def test_create_two(self, fakeicontrolsession):
b = BigIP('192.168.1.1', 'admin', 'admin')
serv1 = b.sys.applications.services.service
serv2 = b.sys.applications.services.service
Expand Down Expand Up @@ -323,7 +323,7 @@ def test_update_inherit_tg_false(self, FakeService):


class TestTemplateCreate(object):
def test_create_two(self):
def test_create_two(self, fakeicontrolsession):
b = BigIP('192.168.1.1', 'admin', 'admin')
templ1 = b.sys.applications.templates.template
templ2 = b.sys.applications.templates.template
Expand All @@ -337,7 +337,7 @@ def test_create_no_args(self, FakeTemplate):


class TestAplscript(object):
def test_create_two(self):
def test_create_two(self, fakeicontrolsession):
b = BigIP('192.168.1.1', 'admin', 'admin')
templ1 = b.sys.applications.aplscripts.aplscript
templ2 = b.sys.applications.aplscripts.aplscript
Expand All @@ -350,7 +350,7 @@ def test_create_no_args(self, FakeAplscript):


class TestCustomstat(object):
def test_create_two(self):
def test_create_two(self, fakeicontrolsession):
b = BigIP('192.168.1.1', 'admin', 'admin')
templ1 = b.sys.applications.customstats.customstat
templ2 = b.sys.applications.customstats.customstat
Expand Down
2 changes: 1 addition & 1 deletion f5/multi_device/cluster/test/test_cluster_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def __init__(self, name):


@pytest.fixture
def BigIPs():
def BigIPs(fakeicontrolsession):
mock_bigips = []
for bigip in range(4):
mock_bigips.append(ManagementRoot('test', 'un', 'pw'))
Expand Down