Skip to content

Commit 0492585

Browse files
authored
Merge pull request #1284 from caphrim007/feature.add-vcmp-disk-to-sdk
Adds vcmp disk api
2 parents 9381eb5 + 38a6c0d commit 0492585

5 files changed

Lines changed: 311 additions & 1 deletion

File tree

f5/bigip/resource.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1105,6 +1105,10 @@ def exists(self, **kwargs):
11051105
:raises: :exc:`requests.HTTPError`, Any HTTP error that was not status
11061106
code 404.
11071107
"""
1108+
return self._exists(**kwargs)
1109+
1110+
def _exists(self, **kwargs):
1111+
"""wrapped with exists, override that in a subclass to customize """
11081112
requests_params = self._handle_requests_params(kwargs)
11091113
self._check_load_parameters(**kwargs)
11101114
kwargs['uri_as_parts'] = True

f5/bigip/tm/vcmp/__init__.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,13 @@
2929

3030
from f5.bigip.resource import OrganizingCollection
3131
from f5.bigip.tm.vcmp.guest import Guests
32+
from f5.bigip.tm.vcmp.virtual_disk import Virtual_Disks
3233

3334

3435
class Vcmp(OrganizingCollection):
3536
def __init__(self, tm):
3637
super(Vcmp, self).__init__(tm)
37-
self._meta_data['allowed_lazy_attributes'] = [Guests]
38+
self._meta_data['allowed_lazy_attributes'] = [
39+
Guests,
40+
Virtual_Disks
41+
]
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# Copyright 2016 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+
import os
17+
import pytest
18+
import tempfile
19+
import time
20+
21+
from f5.utils.responses.handlers import Stats
22+
23+
24+
try:
25+
vcmp_host = pytest.config.getoption('--vcmp-host')
26+
except Exception as ex:
27+
vcmp_host = None
28+
29+
30+
@pytest.fixture
31+
def software_images(vcmp_host):
32+
collection = vcmp_host.tm.sys.software.images.get_collection()
33+
result = sorted([x.name.split('/')[0] for x in collection])
34+
return result
35+
36+
37+
@pytest.fixture
38+
def vcmp_guest(vcmp_host, software_images):
39+
file = tempfile.NamedTemporaryFile()
40+
name = os.path.basename(file.name)
41+
resource = vcmp_host.tm.vcmp.guests.guest.create(
42+
name=name,
43+
initialImage=software_images[0],
44+
state='provisioned',
45+
managementGw='1.1.1.254',
46+
managementIp='1.1.1.1/24',
47+
managementNetwork='bridged'
48+
)
49+
yield resource
50+
51+
52+
@pytest.mark.skipif(
53+
vcmp_host is None,
54+
reason='Provide --vcmp-host to run vcmp tests.'
55+
)
56+
class TestGuest(object):
57+
def test_delete(self, vcmp_host, software_images):
58+
file = tempfile.NamedTemporaryFile()
59+
name = os.path.basename(file.name)
60+
resource = vcmp_host.tm.vcmp.guests.guest.create(
61+
name=name,
62+
initialImage=software_images[0],
63+
state='provisioned',
64+
managementGw='1.1.1.254',
65+
managementIp='1.1.1.1/24',
66+
managementNetwork='bridged'
67+
)
68+
self._wait_for_provisioned(vcmp_host, resource.name)
69+
70+
disk = resource.virtualDisk
71+
slots = resource.assignedSlots
72+
73+
resource.delete()
74+
75+
for slot in slots:
76+
self._wait_for_virtual_disk_ready(vcmp_host, disk, slot)
77+
vdisk = vcmp_host.tm.vcmp.virtual_disks.virtual_disk.load(
78+
name=disk, slot=slot
79+
)
80+
vdisk.delete()
81+
82+
assert vcmp_host.tm.vcmp.guests.guest.exists(name=name) is False
83+
for slot in slots:
84+
exists = vcmp_host.tm.vcmp.virtual_disks.virtual_disk.exists(
85+
name=disk, slot=slot
86+
)
87+
assert exists is False
88+
89+
def _wait_for_provisioned(self, vcmp_host, name):
90+
resource = vcmp_host.tm.vcmp.guests.guest.load(name=name)
91+
nops = 0
92+
time.sleep(5)
93+
while nops < 3:
94+
try:
95+
stats = Stats(resource.stats.load())
96+
requested_state = stats.stat['requestedState']['description']
97+
vm_status = stats.stat['vmStatus']['description']
98+
99+
if requested_state == 'provisioned' and vm_status == 'stopped':
100+
nops += 1
101+
else:
102+
nops = 0
103+
except Exception:
104+
# This can be caused by restjavad restarting.
105+
pass
106+
time.sleep(10)
107+
108+
def _wait_for_virtual_disk_ready(self, vcmp_host, disk, slot):
109+
resource = vcmp_host.tm.vcmp.virtual_disks.virtual_disk.load(
110+
name=disk, slot=slot
111+
)
112+
nops = 0
113+
time.sleep(5)
114+
while nops < 3:
115+
try:
116+
stats = Stats(resource.stats.load())
117+
status = stats.stat['status']['description']
118+
119+
if status == 'ready':
120+
nops += 1
121+
else:
122+
nops = 0
123+
except Exception:
124+
# This can be caused by restjavad restarting.
125+
pass
126+
time.sleep(10)
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
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+
import mock
17+
import pytest
18+
19+
from f5.bigip.tm.vcmp.virtual_disk import Virtual_Disk
20+
from f5.sdk_exception import UnsupportedMethod
21+
22+
23+
@pytest.fixture
24+
def FakeResource():
25+
mo = mock.MagicMock()
26+
return Virtual_Disk(mo)
27+
28+
29+
def test_create(FakeResource):
30+
with pytest.raises(UnsupportedMethod) as ex:
31+
FakeResource.create()
32+
assert "does not support the create method" in str(ex.value)
33+
34+
35+
def test_update(FakeResource):
36+
with pytest.raises(UnsupportedMethod) as ex:
37+
FakeResource.update()
38+
assert "does not support the update method" in str(ex.value)
39+
40+
41+
def test_modify(FakeResource):
42+
with pytest.raises(UnsupportedMethod) as ex:
43+
FakeResource.modify()
44+
assert "does not support the modify method" in str(ex.value)

f5/bigip/tm/vcmp/virtual_disk.py

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
# coding=utf-8
2+
#
3+
# Copyright 2016 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+
"""BIG-IP® Guest (vcmp) module
19+
20+
REST URI
21+
``http://localhost/mgmt/tm/vcmp/virtual-disk/``
22+
23+
GUI Path
24+
``Virtual Disk List``
25+
26+
REST Kind
27+
``tm:vcmp:virtual-disk:*``
28+
"""
29+
30+
from f5.bigip.resource import Collection
31+
from f5.bigip.resource import Resource
32+
from f5.sdk_exception import DisallowedCreationParameter
33+
from f5.sdk_exception import DisallowedReadParameter
34+
from f5.sdk_exception import F5SDKError
35+
from f5.sdk_exception import UnsupportedMethod
36+
37+
38+
class Virtual_Disks(Collection):
39+
def __init__(self, vcmp):
40+
super(Virtual_Disks, self).__init__(vcmp)
41+
self._meta_data['allowed_lazy_attributes'] = [Virtual_Disk]
42+
self._meta_data['required_json_kind'] = 'tm:vcmp:virtual-disk:virtual-diskcollectionstate'
43+
self._meta_data['attribute_registry'] = {
44+
'tm:vcmp:virtual-disk:virtual-diskstate': Virtual_Disk
45+
}
46+
47+
48+
class Virtual_Disk(Resource):
49+
def __init__(self, collection):
50+
super(Virtual_Disk, self).__init__(collection)
51+
self._meta_data['required_json_kind'] = 'tm:vcmp:virtual-disk:virtual-diskstate'
52+
53+
def load(self, **kwargs):
54+
"""Loads a given resource
55+
56+
Loads a given resource provided a 'name' and an optional 'slot'
57+
parameter. The 'slot' parameter is not a required load parameter
58+
because it is provided as an optional way of constructing the
59+
correct 'name' of the vCMP resource.
60+
61+
:param kwargs:
62+
:return:
63+
"""
64+
kwargs['transform_name'] = True
65+
kwargs = self._mutate_name(kwargs)
66+
return self._load(**kwargs)
67+
68+
def exists(self, **kwargs):
69+
kwargs['transform_name'] = True
70+
kwargs = self._mutate_name(kwargs)
71+
return self._exists(**kwargs)
72+
73+
def delete(self, **kwargs):
74+
kwargs['transform_name'] = True
75+
kwargs = self._mutate_name(kwargs)
76+
return self._delete(**kwargs)
77+
78+
def modify(self, **kwargs):
79+
raise UnsupportedMethod(
80+
"%s does not support the modify method" % self.__class__.__name__
81+
)
82+
83+
def create(self, **kwargs):
84+
raise UnsupportedMethod(
85+
"%s does not support the create method" % self.__class__.__name__
86+
)
87+
88+
def update(self, **kwargs):
89+
raise UnsupportedMethod(
90+
"%s does not support the update method" % self.__class__.__name__
91+
)
92+
93+
def _check_load_parameters(self, **kwargs):
94+
"""Override method for one in resource.py to check partition
95+
96+
The partition cannot be included as a parameter to load a guest.
97+
Raise an exception if a consumer gives the partition parameter.
98+
99+
:raises: DisallowedReadParameter
100+
"""
101+
102+
if 'partition' in kwargs:
103+
msg = "'partition' is not allowed as a load parameter. Vcmp " \
104+
"guests are accessed by name."
105+
raise DisallowedReadParameter(msg)
106+
super(Virtual_Disk, self)._check_load_parameters(**kwargs)
107+
108+
def _check_create_parameters(self, **kwargs):
109+
"""Override method for one in resource.py to check partition
110+
111+
The partition cannot be included as a parameter to create a guest.
112+
Raise an exception if a consumer gives the partition parameter.
113+
114+
:raises: DisallowedCreationParameter
115+
"""
116+
117+
if 'partition' in kwargs:
118+
msg = "'partition' is not allowed as a create parameter. Vcmp " \
119+
"guests are created with the 'name' at least."
120+
raise DisallowedCreationParameter(msg)
121+
super(Virtual_Disk, self)._check_create_parameters(**kwargs)
122+
123+
def _mutate_name(self, kwargs):
124+
slot = kwargs.pop('slot', None)
125+
if slot is not None:
126+
try:
127+
kwargs['name'] = '{0}/{1}'.format(kwargs['name'], int(slot))
128+
except ValueError:
129+
raise F5SDKError(
130+
"The provided 'slot' must be a number"
131+
)
132+
return kwargs

0 commit comments

Comments
 (0)