-
Notifications
You must be signed in to change notification settings - Fork 134
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1284 from caphrim007/feature.add-vcmp-disk-to-sdk
Adds vcmp disk api
- Loading branch information
Showing
5 changed files
with
311 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
# Copyright 2016 F5 Networks Inc. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# | ||
|
||
import os | ||
import pytest | ||
import tempfile | ||
import time | ||
|
||
from f5.utils.responses.handlers import Stats | ||
|
||
|
||
try: | ||
vcmp_host = pytest.config.getoption('--vcmp-host') | ||
except Exception as ex: | ||
vcmp_host = None | ||
|
||
|
||
@pytest.fixture | ||
def software_images(vcmp_host): | ||
collection = vcmp_host.tm.sys.software.images.get_collection() | ||
result = sorted([x.name.split('/')[0] for x in collection]) | ||
return result | ||
|
||
|
||
@pytest.fixture | ||
def vcmp_guest(vcmp_host, software_images): | ||
file = tempfile.NamedTemporaryFile() | ||
name = os.path.basename(file.name) | ||
resource = vcmp_host.tm.vcmp.guests.guest.create( | ||
name=name, | ||
initialImage=software_images[0], | ||
state='provisioned', | ||
managementGw='1.1.1.254', | ||
managementIp='1.1.1.1/24', | ||
managementNetwork='bridged' | ||
) | ||
yield resource | ||
|
||
|
||
@pytest.mark.skipif( | ||
vcmp_host is None, | ||
reason='Provide --vcmp-host to run vcmp tests.' | ||
) | ||
class TestGuest(object): | ||
def test_delete(self, vcmp_host, software_images): | ||
file = tempfile.NamedTemporaryFile() | ||
name = os.path.basename(file.name) | ||
resource = vcmp_host.tm.vcmp.guests.guest.create( | ||
name=name, | ||
initialImage=software_images[0], | ||
state='provisioned', | ||
managementGw='1.1.1.254', | ||
managementIp='1.1.1.1/24', | ||
managementNetwork='bridged' | ||
) | ||
self._wait_for_provisioned(vcmp_host, resource.name) | ||
|
||
disk = resource.virtualDisk | ||
slots = resource.assignedSlots | ||
|
||
resource.delete() | ||
|
||
for slot in slots: | ||
self._wait_for_virtual_disk_ready(vcmp_host, disk, slot) | ||
vdisk = vcmp_host.tm.vcmp.virtual_disks.virtual_disk.load( | ||
name=disk, slot=slot | ||
) | ||
vdisk.delete() | ||
|
||
assert vcmp_host.tm.vcmp.guests.guest.exists(name=name) is False | ||
for slot in slots: | ||
exists = vcmp_host.tm.vcmp.virtual_disks.virtual_disk.exists( | ||
name=disk, slot=slot | ||
) | ||
assert exists is False | ||
|
||
def _wait_for_provisioned(self, vcmp_host, name): | ||
resource = vcmp_host.tm.vcmp.guests.guest.load(name=name) | ||
nops = 0 | ||
time.sleep(5) | ||
while nops < 3: | ||
try: | ||
stats = Stats(resource.stats.load()) | ||
requested_state = stats.stat['requestedState']['description'] | ||
vm_status = stats.stat['vmStatus']['description'] | ||
|
||
if requested_state == 'provisioned' and vm_status == 'stopped': | ||
nops += 1 | ||
else: | ||
nops = 0 | ||
except Exception: | ||
# This can be caused by restjavad restarting. | ||
pass | ||
time.sleep(10) | ||
|
||
def _wait_for_virtual_disk_ready(self, vcmp_host, disk, slot): | ||
resource = vcmp_host.tm.vcmp.virtual_disks.virtual_disk.load( | ||
name=disk, slot=slot | ||
) | ||
nops = 0 | ||
time.sleep(5) | ||
while nops < 3: | ||
try: | ||
stats = Stats(resource.stats.load()) | ||
status = stats.stat['status']['description'] | ||
|
||
if status == 'ready': | ||
nops += 1 | ||
else: | ||
nops = 0 | ||
except Exception: | ||
# This can be caused by restjavad restarting. | ||
pass | ||
time.sleep(10) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
# Copyright 2017 F5 Networks Inc. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# | ||
|
||
import mock | ||
import pytest | ||
|
||
from f5.bigip.tm.vcmp.virtual_disk import Virtual_Disk | ||
from f5.sdk_exception import UnsupportedMethod | ||
|
||
|
||
@pytest.fixture | ||
def FakeResource(): | ||
mo = mock.MagicMock() | ||
return Virtual_Disk(mo) | ||
|
||
|
||
def test_create(FakeResource): | ||
with pytest.raises(UnsupportedMethod) as ex: | ||
FakeResource.create() | ||
assert "does not support the create method" in str(ex.value) | ||
|
||
|
||
def test_update(FakeResource): | ||
with pytest.raises(UnsupportedMethod) as ex: | ||
FakeResource.update() | ||
assert "does not support the update method" in str(ex.value) | ||
|
||
|
||
def test_modify(FakeResource): | ||
with pytest.raises(UnsupportedMethod) as ex: | ||
FakeResource.modify() | ||
assert "does not support the modify method" in str(ex.value) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
# coding=utf-8 | ||
# | ||
# Copyright 2016 F5 Networks Inc. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# | ||
|
||
"""BIG-IP® Guest (vcmp) module | ||
REST URI | ||
``http://localhost/mgmt/tm/vcmp/virtual-disk/`` | ||
GUI Path | ||
``Virtual Disk List`` | ||
REST Kind | ||
``tm:vcmp:virtual-disk:*`` | ||
""" | ||
|
||
from f5.bigip.resource import Collection | ||
from f5.bigip.resource import Resource | ||
from f5.sdk_exception import DisallowedCreationParameter | ||
from f5.sdk_exception import DisallowedReadParameter | ||
from f5.sdk_exception import F5SDKError | ||
from f5.sdk_exception import UnsupportedMethod | ||
|
||
|
||
class Virtual_Disks(Collection): | ||
def __init__(self, vcmp): | ||
super(Virtual_Disks, self).__init__(vcmp) | ||
self._meta_data['allowed_lazy_attributes'] = [Virtual_Disk] | ||
self._meta_data['required_json_kind'] = 'tm:vcmp:virtual-disk:virtual-diskcollectionstate' | ||
self._meta_data['attribute_registry'] = { | ||
'tm:vcmp:virtual-disk:virtual-diskstate': Virtual_Disk | ||
} | ||
|
||
|
||
class Virtual_Disk(Resource): | ||
def __init__(self, collection): | ||
super(Virtual_Disk, self).__init__(collection) | ||
self._meta_data['required_json_kind'] = 'tm:vcmp:virtual-disk:virtual-diskstate' | ||
|
||
def load(self, **kwargs): | ||
"""Loads a given resource | ||
Loads a given resource provided a 'name' and an optional 'slot' | ||
parameter. The 'slot' parameter is not a required load parameter | ||
because it is provided as an optional way of constructing the | ||
correct 'name' of the vCMP resource. | ||
:param kwargs: | ||
:return: | ||
""" | ||
kwargs['transform_name'] = True | ||
kwargs = self._mutate_name(kwargs) | ||
return self._load(**kwargs) | ||
|
||
def exists(self, **kwargs): | ||
kwargs['transform_name'] = True | ||
kwargs = self._mutate_name(kwargs) | ||
return self._exists(**kwargs) | ||
|
||
def delete(self, **kwargs): | ||
kwargs['transform_name'] = True | ||
kwargs = self._mutate_name(kwargs) | ||
return self._delete(**kwargs) | ||
|
||
def modify(self, **kwargs): | ||
raise UnsupportedMethod( | ||
"%s does not support the modify method" % self.__class__.__name__ | ||
) | ||
|
||
def create(self, **kwargs): | ||
raise UnsupportedMethod( | ||
"%s does not support the create method" % self.__class__.__name__ | ||
) | ||
|
||
def update(self, **kwargs): | ||
raise UnsupportedMethod( | ||
"%s does not support the update method" % self.__class__.__name__ | ||
) | ||
|
||
def _check_load_parameters(self, **kwargs): | ||
"""Override method for one in resource.py to check partition | ||
The partition cannot be included as a parameter to load a guest. | ||
Raise an exception if a consumer gives the partition parameter. | ||
:raises: DisallowedReadParameter | ||
""" | ||
|
||
if 'partition' in kwargs: | ||
msg = "'partition' is not allowed as a load parameter. Vcmp " \ | ||
"guests are accessed by name." | ||
raise DisallowedReadParameter(msg) | ||
super(Virtual_Disk, self)._check_load_parameters(**kwargs) | ||
|
||
def _check_create_parameters(self, **kwargs): | ||
"""Override method for one in resource.py to check partition | ||
The partition cannot be included as a parameter to create a guest. | ||
Raise an exception if a consumer gives the partition parameter. | ||
:raises: DisallowedCreationParameter | ||
""" | ||
|
||
if 'partition' in kwargs: | ||
msg = "'partition' is not allowed as a create parameter. Vcmp " \ | ||
"guests are created with the 'name' at least." | ||
raise DisallowedCreationParameter(msg) | ||
super(Virtual_Disk, self)._check_create_parameters(**kwargs) | ||
|
||
def _mutate_name(self, kwargs): | ||
slot = kwargs.pop('slot', None) | ||
if slot is not None: | ||
try: | ||
kwargs['name'] = '{0}/{1}'.format(kwargs['name'], int(slot)) | ||
except ValueError: | ||
raise F5SDKError( | ||
"The provided 'slot' must be a number" | ||
) | ||
return kwargs |