Skip to content

Commit a93a1ce

Browse files
committed
Adds system/tmos and authz/tokens apis
Issues: Fixes #1305 Problem: These apis were not in the sdk Analysis: This patch adds them Tests: functional test
1 parent 7bd4928 commit a93a1ce

11 files changed

Lines changed: 340 additions & 5 deletions

File tree

f5/bigip/cm/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"""Classes and functions for configuring BIG-IP"""
1818

1919
from f5.bigip.cm.autodeploy import Autodeploy
20+
from f5.bigip.cm.system import System
2021
from f5.bigip.resource import OrganizingCollection
2122

2223

@@ -25,5 +26,6 @@ class Cm(OrganizingCollection):
2526
def __init__(self, bigip):
2627
super(Cm, self).__init__(bigip)
2728
self._meta_data['allowed_lazy_attributes'] = [
28-
Autodeploy
29+
Autodeploy,
30+
System
2931
]

f5/bigip/cm/system.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# coding=utf-8
2+
#
3+
# Copyright 2017 F5 Networks Inc.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
18+
19+
from f5.bigip.resource import Collection
20+
from f5.bigip.resource import OrganizingCollection
21+
from f5.bigip.resource import Resource
22+
from f5.sdk_exception import UnsupportedMethod
23+
24+
25+
class System(OrganizingCollection):
26+
def __init__(self, shared):
27+
super(System, self).__init__(shared)
28+
self._meta_data['allowed_lazy_attributes'] = [
29+
Authn
30+
]
31+
32+
33+
class Authn(OrganizingCollection):
34+
def __init__(self, system):
35+
super(Authn, self).__init__(system)
36+
self._meta_data['allowed_lazy_attributes'] = [
37+
Providers
38+
]
39+
40+
41+
class Providers(OrganizingCollection):
42+
def __init__(self, authn):
43+
super(Providers, self).__init__(authn)
44+
self._meta_data['allowed_lazy_attributes'] = [
45+
Tmos_s
46+
]
47+
48+
49+
class Tmos_s(Collection):
50+
def __init__(self, providers):
51+
super(Tmos_s, self).__init__(providers)
52+
self._meta_data['required_json_kind'] = 'cm:system:authn:providers:tmos:mcpremoteprovidercollectionstate'
53+
self._meta_data['allowed_lazy_attributes'] = [Tmos]
54+
self._meta_data['attribute_registry'] = {
55+
'cm:system:authn:providers:tmos:mcpremoteproviderstate': Tmos
56+
}
57+
58+
59+
class Tmos(Resource):
60+
def __init__(self, tokens):
61+
super(Tmos, self).__init__(tokens)
62+
self._meta_data['required_json_kind'] = 'cm:system:authn:providers:tmos:mcpremoteproviderstate'
63+
self._meta_data['required_load_parameters'] = set(('id',))
64+
65+
def create(self, **kwargs):
66+
raise UnsupportedMethod(
67+
"Only a single remote mcp auth provider allowed."
68+
)
69+
70+
def update(self, **kwargs):
71+
# You can technically do this, but it will really screw up the system
72+
raise UnsupportedMethod
73+
74+
def modify(self, **kwargs):
75+
# You can technically do this, but it will really screw up the system
76+
raise UnsupportedMethod
77+
78+
def delete(self, **kwargs):
79+
# You can technically do this, but it will really screw up the system
80+
raise UnsupportedMethod

f5/bigip/cm/test/__init__.py

Whitespace-only changes.

f5/bigip/cm/test/unit/__init__.py

Whitespace-only changes.
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Copyright 2017 F5 Networks Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
#
15+
16+
from f5.bigip.cm.system import Tmos
17+
from f5.sdk_exception import UnsupportedMethod
18+
19+
import mock
20+
import pytest
21+
22+
23+
@pytest.fixture
24+
def FakeTmos():
25+
mo = mock.MagicMock()
26+
resource = Tmos(mo)
27+
return resource
28+
29+
30+
class TestTmos(object):
31+
def test_create(self, FakeTmos):
32+
with pytest.raises(UnsupportedMethod):
33+
FakeTmos.create()
34+
35+
def test_modify(self, FakeTmos):
36+
with pytest.raises(UnsupportedMethod):
37+
FakeTmos.modify()
38+
39+
def test_update(self, FakeTmos):
40+
with pytest.raises(UnsupportedMethod):
41+
FakeTmos.update()
42+
43+
def test_delete(self, FakeTmos):
44+
with pytest.raises(UnsupportedMethod):
45+
FakeTmos.delete()

f5/bigip/shared/__init__.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
# coding=utf-8
22
#
3-
"""Classes and functions for configuring BIG-IP"""
43
# Copyright 2016 F5 Networks Inc.
54
#
65
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,6 +16,7 @@
1716
#
1817

1918
from f5.bigip.resource import OrganizingCollection
19+
from f5.bigip.shared.authz import Authz
2020
from f5.bigip.shared.file_transfer import File_Transfer
2121
from f5.bigip.shared.iapp import Iapp
2222

@@ -27,5 +27,6 @@ def __init__(self, mgmt):
2727
super(Shared, self).__init__(mgmt)
2828
self._meta_data['allowed_lazy_attributes'] = [
2929
File_Transfer,
30-
Iapp
30+
Iapp,
31+
Authz
3132
]

f5/bigip/shared/authz.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# coding=utf-8
2+
#
3+
# Copyright 2017 F5 Networks Inc.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
18+
19+
from f5.bigip.resource import Collection
20+
from f5.bigip.resource import OrganizingCollection
21+
from f5.bigip.resource import Resource
22+
from f5.sdk_exception import ConstraintError
23+
from f5.sdk_exception import MissingUpdateParameter
24+
25+
26+
class Authz(OrganizingCollection):
27+
def __init__(self, shared):
28+
super(Authz, self).__init__(shared)
29+
self._meta_data['allowed_lazy_attributes'] = [
30+
Tokens_s
31+
]
32+
33+
34+
class Tokens_s(Collection):
35+
def __init__(self, authz):
36+
super(Tokens_s, self).__init__(authz)
37+
self._meta_data['required_json_kind'] = 'shared:authz:tokens:authtokencollectionstate'
38+
self._meta_data['allowed_lazy_attributes'] = [Token]
39+
self._meta_data['attribute_registry'] = {
40+
'shared:authz:tokens:authtokenitemstate': Token
41+
}
42+
43+
44+
class Token(Resource):
45+
def __init__(self, tokens):
46+
super(Token, self).__init__(tokens)
47+
self._meta_data['required_json_kind'] = 'shared:authz:tokens:authtokenitemstate'
48+
49+
# The required parameters are a little vague. It turns out that the "user"
50+
# value that is required is the "link" to the ID
51+
self._meta_data['required_creation_parameters'] = {'token', 'user'}
52+
53+
def update(self, **kwargs):
54+
self._validate_params(**kwargs)
55+
return self._update(**kwargs)
56+
57+
def modify(self, **kwargs):
58+
self._validate_timeout(**kwargs)
59+
return self._modify(**kwargs)
60+
61+
def _validate_params(self, **kwargs):
62+
self._validate_timeout(**kwargs)
63+
self._validate_user(**kwargs)
64+
65+
def _validate_user(self, **kwargs):
66+
try:
67+
assert 'user' in kwargs
68+
assert 'link' in kwargs['user']
69+
except AssertionError:
70+
raise MissingUpdateParameter(
71+
"The 'user' parameter is required when updating."
72+
)
73+
74+
def _validate_timeout(self, **kwargs):
75+
timeout = kwargs.get('timeout', None)
76+
try:
77+
if timeout is not None and int(timeout) > 36000:
78+
raise ConstraintError(
79+
"The provided timeout exceeds the limit of 36000."
80+
)
81+
except ValueError:
82+
raise ConstraintError(
83+
"The provided timeout must be a number between 1 and 36000."
84+
)
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# Copyright 2015 F5 Networks Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
#
15+
16+
17+
import pytest
18+
19+
from distutils.version import LooseVersion
20+
from requests.exceptions import HTTPError
21+
22+
pytestmark = pytest.mark.skipif(
23+
LooseVersion(pytest.config.getoption('--release'))
24+
< LooseVersion('12.0.0'),
25+
reason='Needs v12 TMOS or greater to pass.'
26+
)
27+
28+
29+
@pytest.fixture(scope='function')
30+
def users_link(mgmt_root):
31+
collection = mgmt_root.cm.system.authn.providers.tmos_s.get_collection()
32+
resource = collection[0]
33+
result = resource.attrs['usersReference']
34+
return result
35+
36+
37+
@pytest.fixture(scope='function')
38+
def token(mgmt_root, users_link):
39+
collection = mgmt_root.shared.authz.tokens_s
40+
resource = collection.token.create(
41+
token='T1234512345123451234512345',
42+
user=users_link
43+
)
44+
yield resource
45+
resource.delete()
46+
47+
48+
class TestAuthz(object):
49+
def test_create(self, token):
50+
assert token.kind == 'shared:authz:tokens:authtokenitemstate'
51+
52+
def test_load_no_token(self, mgmt_root):
53+
with pytest.raises(HTTPError) as err:
54+
collection = mgmt_root.shared.authz.tokens_s
55+
collection.token.load(
56+
name='asdasdasd'
57+
)
58+
assert err.value.response.status_code == 404
59+
60+
def test_load(self, mgmt_root, token):
61+
collection = mgmt_root.shared.authz.tokens_s
62+
resource = collection.token.load(name=token.name)
63+
assert token.name == resource.name
64+
assert token.selfLink == resource.selfLink
65+
66+
def test_exists(self, mgmt_root, token):
67+
name = str(token.name)
68+
collection = mgmt_root.shared.authz.tokens_s
69+
exists = collection.token.exists(name=name)
70+
assert exists is True
71+
72+
def test_package_mgmt_tasks_collection(self, mgmt_root, token):
73+
col = mgmt_root.shared.authz.tokens_s.get_collection()
74+
assert isinstance(col, list)
75+
assert len(col) > 0
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Copyright 2017 F5 Networks Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
#
15+
16+
from f5.bigip.shared.authz import Token
17+
from f5.sdk_exception import ConstraintError
18+
from f5.sdk_exception import MissingRequiredCreationParameter
19+
20+
import mock
21+
import pytest
22+
23+
24+
@pytest.fixture
25+
def FakeToken():
26+
mo = mock.MagicMock()
27+
resource = Token(mo)
28+
return resource
29+
30+
31+
class TestToken(object):
32+
def test_invalid_timeout_non_number_value(self, FakeToken):
33+
with pytest.raises(ConstraintError):
34+
FakeToken.update(timeout="abc")
35+
36+
def test_invalid_timeout_number_value(self, FakeToken):
37+
with pytest.raises(ConstraintError):
38+
FakeToken.update(timeout=360000)
39+
40+
def test_create_no_args(self, FakeToken):
41+
with pytest.raises(MissingRequiredCreationParameter):
42+
FakeToken.create()

f5/sdk_exception.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,12 @@ class DraftPolicyNotSupportedInTMOSVersion(F5SDKError):
229229
Raise this if handling Draft work in a Policy class that is
230230
used by legacy, and current, versions of BIG-IP
231231
"""
232+
pass
233+
234+
235+
class ConstraintError(F5SDKError):
236+
"""Raise when a supplied value is outside the limits for that attribute."""
237+
pass
232238

233239

234240
class RequiredOneOf(F5SDKError):

0 commit comments

Comments
 (0)