Skip to content

Commit

Permalink
Merge pull request #29 from QualiSystemsLab/setup-teardown_vm-w-Resou…
Browse files Browse the repository at this point in the history
…rceBase

Setup teardown vm w resource base
  • Loading branch information
kalsky committed Jun 7, 2017
2 parents 1242466 + b97ab17 commit 1625b14
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 122 deletions.
6 changes: 6 additions & 0 deletions sandbox_scripts/QualiEnvironmentUtils/QualiUtils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,9 @@ def __init__(self, name, message):

def __str__(self):
return 'CloudShell error at ' + self.name + '. Error is: ' + self.message

class rsc_run_result_struct:
def __init__(self, resource_name):
self.run_result = True
self.resource_name = resource_name
self.message = ""
107 changes: 52 additions & 55 deletions sandbox_scripts/environment/setup/setup_VM.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
from sandbox_scripts.helpers.Networking.save_restore_mgr import SaveRestoreManager
from sandbox_scripts.QualiEnvironmentUtils.Sandbox import SandboxBase
from sandbox_scripts.QualiEnvironmentUtils.Resource import ResourceBase
from cloudshell.core.logger.qs_logger import get_qs_logger
from cloudshell.helpers.scripts import cloudshell_scripts_helpers as helpers
from sandbox_scripts.QualiEnvironmentUtils.QualiUtils import QualiError
from multiprocessing.pool import ThreadPool
from threading import Lock
from sandbox_scripts.QualiEnvironmentUtils.QualiUtils import rsc_run_result_struct


class EnvironmentSetupVM(object):
Expand All @@ -14,26 +15,26 @@ def __init__(self):
self.logger = get_qs_logger(log_file_prefix="CloudShell Sandbox Setup",
log_group=self.reservation_id,
log_category='Setup')
self.is_snapshot = False
self.sandbox = None

# ---------------------------
# ---------------------------
def execute(self):
self.sandbox = SandboxBase(self.reservation_id, self.logger)

self.sandbox.report_info('Beginning VMs power on')

#TODO: don't use networking save and restore to figure if it's a snapshot setup
self.is_snapshot = False
save_n_restore_mgr = SaveRestoreManager(self.sandbox)
if save_n_restore_mgr.get_storage_manager():
if save_n_restore_mgr.is_snapshot():
self.is_snapshot = True

self.sandbox.report_info('Beginning VMs power on')
self._run_async_power_on_refresh_ip()

# ---------------------------
# ---------------------------
def _run_async_power_on_refresh_ip(self):
# filter out resources not created in this reservation

resources = self.sandbox.get_details().ReservationDescription.Resources
# Get only VM resources
resources = self.sandbox.get_root_vm_resources()

if len(resources) == 0:
self.sandbox.report_info(message='No VMs to power on ', write_to_output_window=True)
Expand All @@ -51,79 +52,79 @@ def _run_async_power_on_refresh_ip(self):

pool.close()
pool.join()

err_msg = ""
for async_result in async_results:
res = async_result.get()
if not res[0]:
raise QualiError("Reservation is Active with Errors - " + res[1])

""":type : rsc_run_result_struct"""
if not res.run_result:
err_msg += "\n" + res.message
if err_msg:
self.sandbox.report_error("Reservation is Active with Errors - " + err_msg,raise_error=True)

# ---------------------------
# ---------------------------
def _power_on_refresh_ip(self, lock, message_status, resource):
"""
:param Lock lock:
:param (dict of str: Boolean) message_status:
:param ReservedResourceInfo resource:
:param ResourceBase resource:
:return:
"""

deployed_app_name = resource.Name

resource_details = self.sandbox.api_session.GetResourceDetails(deployed_app_name)
vm_details = resource_details.VmDetails

if vm_details is None or hasattr(vm_details, "UID") is False or vm_details.UID is None:
self.logger.debug("Skipping resource '{0}' - not an app, not powering on".format(deployed_app_name))
return True, ""

#deployed_app_name = resource.name
run_result = rsc_run_result_struct(resource.name)
power_on = "true"
wait_for_ip = "true"

if resource.ResourceModelName.lower() == "vcenter static vm":
self.logger.debug("Resource {0} is a static app".format(deployed_app_name))
if resource.model.lower() == "vcenter static vm":
self.logger.debug("Resource {0} is a static app".format(resource.name))
wait_for_ip = "false"
elif not self.is_snapshot:
return True, ""

try:
self._power_on(deployed_app_name, power_on, lock, message_status)
self._power_on(resource, power_on, lock, message_status)
except Exception as exc:
self.logger.error("Error powering on deployed app '{0}' in reservation '{1}'. Error: {2}"
.format(deployed_app_name, self.reservation_id, str(exc)))
return False, "Error powering on deployed app '{0}'".format(deployed_app_name)

self.sandbox.report_error("Error powering on deployed app '{0}' in reservation '{1}'. Error: {2}"
.format(deployed_app_name, self.reservation_id, str(exc)),raise_error=False)
run_result.message = str("Error powering on deployed app '{0}'").format(resource.name)
run_result.run_result = False
return run_result
try:
if wait_for_ip.lower() == "true":
self._wait_for_ip(deployed_app_name, lock, message_status)
self._wait_for_ip(resource, lock, message_status)
else:
self.logger.info("Wait For IP is off for deployed app '{0}' in reservation '{1}'"
.format(deployed_app_name, self.reservation_id))
self.sandbox.report_info("Wait For IP is off for deployed app '{0}' in reservation '{1}'"
.format(resource.name, self.reservation_id))
except Exception as exc:
self.logger.error("Error refreshing IP on deployed app '{0}' in reservation '{1}'. Error: {2}"
.format(deployed_app_name, self.reservation_id, str(exc)))
return False, "Error refreshing IP deployed app '{0}'. Error: {1}".format(deployed_app_name, exc.message)
self.sandbox.report_error("Error refreshing IP on deployed app '{0}' in reservation '{1}'. Error: {2}"
.format(resource.name, self.reservation_id, str(exc)),raise_error=False)
run_result.message = str("Error refreshing IP deployed app '{0}'. Error: {1}").format(resource.name, exc.message)
run_result.run_result = False

return True, ""

return run_result

def _wait_for_ip(self, deployed_app_name, lock, message_status):
# ---------------------------
# ---------------------------
def _wait_for_ip(self, resource, lock, message_status):
if not message_status['wait_for_ip']:
with lock:
if not message_status['wait_for_ip']:
message_status['wait_for_ip'] = True
self.sandbox.report_info(message='Waiting for apps IP addresses, this may take a while...',
write_to_output_window=True)

self.logger.info("Executing 'Refresh IP' on deployed app '{0}' in reservation '{1}'"
.format(deployed_app_name, self.reservation_id))

self.sandbox.report_info("Executing 'Refresh IP' on deployed app '{0}' in reservation '{1}'"
.format(resource.name, self.reservation_id))
with lock:
self.sandbox.api_session.ExecuteResourceConnectedCommand(self.reservation_id, deployed_app_name,
"remote_refresh_ip",
resource.execute_connected_command(self.reservation_id,"remote_refresh_ip",
"remote_connectivity")



def _power_on(self, deployed_app_name, power_on, lock, message_status):
# ---------------------------
# ---------------------------
def _power_on(self, resource, power_on, lock, message_status):

if power_on.lower() == "true":
with lock:
Expand All @@ -132,16 +133,12 @@ def _power_on(self, deployed_app_name, power_on, lock, message_status):
self.sandbox.report_info('Apps are powering on... ')

self.sandbox.report_info(message="Executing 'Power On' on deployed app '{0}' "
.format(deployed_app_name),
.format(resource.name),
log_message="Executing 'Power On' on deployed app '{0}' in reservation '{1}'"
.format(deployed_app_name, self.reservation_id),
.format(resource.name, self.reservation_id),
write_to_output_window=True)

self.sandbox.api_session.ExecuteResourceConnectedCommand(self.reservation_id, deployed_app_name,
"PowerOn", "power")


resource.execute_connected_command(self.reservation_id,"PowerOn", "power")
else:
self.logger.info("Auto Power On is off for deployed app {0} in reservation {1}"
.format(deployed_app_name, self.reservation_id))
self.sandbox.report_info("Auto Power On is off for deployed app {0} in reservation {1}"
.format(resource.name, self.reservation_id))

34 changes: 19 additions & 15 deletions sandbox_scripts/environment/setup/tests/test_setup_VM.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,9 @@ def resource_details_mock_side_effect(name):

self.setup_script.execute()

report_info_calls = [call('Beginning VMs power on')]
report_info_calls = [call('Beginning VMs power on'),call(message='No VMs to power on ', write_to_output_window=True)]
mock_sandboxbase.return_value.report_info.assert_has_calls(report_info_calls)

logger_debug_calls = [call("Skipping resource 'r1' - not an app, not powering on"),
call("Skipping resource 'r2' - not an app, not powering on")]
self.setup_script.logger.debug.assert_has_calls(logger_debug_calls, any_order=True)

@patch('cloudshell.helpers.scripts.cloudshell_scripts_helpers.get_api_session')
@patch('sandbox_scripts.environment.setup.setup_VM.SandboxBase')
Expand All @@ -108,6 +105,11 @@ def resource_details_mock_side_effect(name):

mock_sandboxbase.return_value.api_session.GetResourceDetails.side_effect = resource_details_mock_side_effect

resourcebase1 = Mock()
resourcebase1.name = 'r2'
resourcebase1.model = 'vcenter static vm'
mock_sandboxbase.return_value.get_root_vm_resources.return_value = [resourcebase1]

mock_save.return_value.is_snapshot.return_value = False

self.setup_script.execute()
Expand All @@ -116,18 +118,16 @@ def resource_details_mock_side_effect(name):
call('Apps are powering on... '),
call(log_message="Executing 'Power On' on deployed app 'r2' in reservation "
"'5487c6ce-d0b3-43e9-8ee7-e27af8406905'",
message="Executing 'Power On' on deployed app 'r2' ", write_to_output_window=True)]
message="Executing 'Power On' on deployed app 'r2' ", write_to_output_window=True),
call("Wait For IP is off for deployed app 'r2' in reservation "
"'5487c6ce-d0b3-43e9-8ee7-e27af8406905'")]
mock_sandboxbase.return_value.report_info.assert_has_calls(report_info_calls)

logger_debug_calls = [call("Resource r2 is a static app")]
self.setup_script.logger.debug.assert_has_calls(logger_debug_calls)

logger_info_calls = [call("Wait For IP is off for deployed app 'r2' in reservation "
"'5487c6ce-d0b3-43e9-8ee7-e27af8406905'")]
self.setup_script.logger.info.assert_has_calls(logger_info_calls)

api_calls = [call('5487c6ce-d0b3-43e9-8ee7-e27af8406905', 'r2', 'PowerOn', 'power')]
mock_sandboxbase.return_value.api_session.ExecuteResourceConnectedCommand.assert_has_calls(api_calls)
api_calls = [call.execute_connected_command(u'5487c6ce-d0b3-43e9-8ee7-e27af8406905', 'PowerOn', 'power')]
resourcebase1.assert_has_calls(api_calls)


@patch('cloudshell.helpers.scripts.cloudshell_scripts_helpers.get_api_session')
Expand All @@ -154,6 +154,11 @@ def resource_details_mock_side_effect(name):

mock_sandboxbase.return_value.api_session.GetResourceDetails.side_effect = resource_details_mock_side_effect

resourcebase1 = Mock()
resourcebase1.name = 'r2'
resourcebase1.model = 'deployed app'
mock_sandboxbase.return_value.get_root_vm_resources.return_value = [resourcebase1]

mock_save.return_value.is_snapshot.return_value = True

self.setup_script.execute()
Expand All @@ -167,10 +172,9 @@ def resource_details_mock_side_effect(name):
write_to_output_window=True)]
mock_sandboxbase.return_value.report_info.assert_has_calls(report_info_calls)

api_calls = [call('5487c6ce-d0b3-43e9-8ee7-e27af8406905', 'r2', 'PowerOn', 'power'),
call('5487c6ce-d0b3-43e9-8ee7-e27af8406905', 'r2', 'remote_refresh_ip', 'remote_connectivity')]
mock_sandboxbase.return_value.api_session.ExecuteResourceConnectedCommand.assert_has_calls(api_calls)

api_calls = [call.execute_connected_command(u'5487c6ce-d0b3-43e9-8ee7-e27af8406905', 'PowerOn', 'power'),
call.execute_connected_command(u'5487c6ce-d0b3-43e9-8ee7-e27af8406905', 'remote_refresh_ip', 'remote_connectivity')]
resourcebase1.assert_has_calls(api_calls)

if __name__ == '__main__':
unittest.main()
Loading

0 comments on commit 1625b14

Please sign in to comment.