Skip to content

Commit 608fb39

Browse files
committed
Merge pull request #241 from QualiSystems/origin/feature/raz_a_153_setup_teardown
Origin/feature/raz a 153 setup teardown
2 parents d56c053 + a5c3f9c commit 608fb39

12 files changed

Lines changed: 218 additions & 2 deletions

File tree

environment_scripts/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+


environment_scripts/connect_all/__main__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from environment_scripts.service.environment import EnvironmentService
1+
from environment_scripts import EnvironmentService
22

33

44
def main():

environment_scripts/connect_bulk/__main__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from environment_scripts.service.environment import EnvironmentService
1+
from environment_scripts import EnvironmentService
22

33

44
def main():
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from environment_scripts.env_setup.setup_script import EnvironmentSetup
2+
3+
4+
def main():
5+
EnvironmentSetup().execute()
6+
7+
if __name__ == "__main__":
8+
main()
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
from multiprocessing.pool import ThreadPool
2+
3+
import cloudshell.api.cloudshell_scripts_helpers as helpers
4+
from cloudshell.api.cloudshell_api import *
5+
6+
from common.logger import getLogger
7+
8+
logger = getLogger("CloudShell Sandbox Setup")
9+
10+
11+
class EnvironmentSetup:
12+
def __init__(self):
13+
self.reservation_id = helpers.get_reservation_context_details().id
14+
15+
def execute(self):
16+
api = helpers.get_api_session()
17+
reservation_details = api.GetReservationDetails(self.reservation_id)
18+
19+
deploy_result = self._deploy_apps_in_reservation(api, reservation_details)
20+
if deploy_result is None:
21+
return
22+
23+
reservation_details = api.GetReservationDetails(self.reservation_id)
24+
self._connect_all_routes_in_reservation(api, reservation_details)
25+
26+
self._run_async_power_on_refresh_ip_install(api=api, deploy_result=deploy_result)
27+
28+
logger.info("Setup for reservation {0} completed".format(self.reservation_id))
29+
30+
def _deploy_apps_in_reservation(self, api, reservation_details):
31+
apps = reservation_details.ReservationDescription.Apps
32+
if not apps:
33+
logger.info("No apps found in reservation {0}".format(self.reservation_id))
34+
return None
35+
36+
app_names = map(lambda x: x.Name, apps)
37+
app_inputs = map(lambda x: DeployAppInput(x.Name, "Name", x.Name), apps)
38+
39+
logger.info(
40+
"Deploying apps for reservation {0}. App names: {1}".format(reservation_details, ", ".join(app_names)))
41+
42+
return api.ExecuteDeployAppCommandBulk(self.reservation_id, app_names, app_inputs)
43+
44+
def _connect_all_routes_in_reservation(self, api, reservation_details):
45+
connectors = reservation_details.ReservationDescription.Connectors
46+
endpoints = []
47+
for endpoint in connectors:
48+
endpoints.append(endpoint.Target)
49+
endpoints.append(endpoint.Source)
50+
51+
endpoint = [side for endpoint in connectors for side in [endpoint.Target, endpoint.Source]]
52+
53+
if not endpoints:
54+
logger.info("No routes to connect for reservation {0}".format(self.reservation_id))
55+
return
56+
57+
logger.info("Executing connect routes for reservation {0}".format(self.reservation_id))
58+
59+
return api.ConnectRoutesInReservation(self.reservation_id, endpoints, 'bi')
60+
61+
def _run_async_power_on_refresh_ip_install(self, api, deploy_result):
62+
if not deploy_result.ResultItems:
63+
logger.info("Nothing to power on. No deployed apps found in reservation {0}".format(self.reservation_id))
64+
return None
65+
66+
pool = ThreadPool(len(deploy_result.ResultItems))
67+
68+
for resultItem in deploy_result.ResultItems:
69+
if resultItem.Success:
70+
pool.apply_async(self._power_on_refresh_ip_install, (api, resultItem))
71+
else:
72+
logger.info("Failed to deploy app {0} in reservation {1}. Error: {2}."
73+
.format(resultItem.AppName, self.reservation_id, resultItem.Error))
74+
75+
pool.close()
76+
pool.join()
77+
78+
def _power_on_refresh_ip_install(self, api, deployed_app):
79+
deployed_app = deployed_app
80+
deployed_app_name = deployed_app.AppDeploymentyInfo.LogicalResourceName
81+
82+
try:
83+
logger.info("Executing 'Power On' on deployed app {0} in reservation {1}"
84+
.format(deployed_app_name, self.reservation_id))
85+
api.ExecuteResourceConnectedCommand(self.reservation_id, deployed_app_name, "PowerOn", "power")
86+
api.SetResourceLiveStatus(deployed_app_name, "Online", "Active")
87+
except Exception as exc:
88+
logger.error("Error powering on deployed app {0} in reservation {1}. Error: {2}"
89+
.format(deployed_app_name, self.reservation_id, str(exc)))
90+
return False
91+
92+
try:
93+
logger.info("Executing 'Refresh IP' on deployed app {0} in reservation {1}"
94+
.format(deployed_app_name, self.reservation_id))
95+
api.ExecuteResourceConnectedCommand(self.reservation_id, deployed_app_name, "remote_refresh_ip",
96+
"remote_connectivity")
97+
except Exception as exc:
98+
logger.error("Error refreshing IP on deployed app {0} in reservation {1}. Error: {2}"
99+
.format(deployed_app_name, self.reservation_id, str(exc)))
100+
return False
101+
102+
try:
103+
installation_info = deployed_app.AppInstallationInfo
104+
if installation_info:
105+
logger.info("Executing installation script {0} on deployed app {1} in reservation {2}"
106+
.format(installation_info.ScriptCommandName, deployed_app_name, self.reservation_id))
107+
108+
script_inputs = []
109+
for installation_script_input in installation_info.ScriptInputs:
110+
script_inputs.append(
111+
InputNameValue(installation_script_input.Name, installation_script_input.Value))
112+
113+
installation_result = api.ExecuteInstallAppCommand(self.reservation_id, deployed_app_name,
114+
installation_info.ScriptCommandName, script_inputs)
115+
logger.debug("Installation_result: " + installation_result.Output)
116+
except Exception as exc:
117+
logger.error("Error installing deployed app {0} in reservation {1}. Error: {2}"
118+
.format(deployed_app_name, self.reservation_id, str(exc)))
119+
return False
120+
121+
return True

environment_scripts/env_teardown/__init__.py

Whitespace-only changes.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from environment_scripts.env_teardown.teardown_script import EnvironmentTeardown
2+
3+
4+
def main():
5+
EnvironmentTeardown().execute()
6+
7+
if __name__ == "__main__":
8+
main()
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
from multiprocessing.pool import ThreadPool
2+
3+
import cloudshell.api.cloudshell_scripts_helpers as helpers
4+
from cloudshell.api.cloudshell_api import *
5+
6+
from common.logger import getLogger
7+
8+
logger = getLogger("CloudShell Sandbox Teardown")
9+
10+
11+
class EnvironmentTeardown:
12+
def __init__(self):
13+
self.reservation_id = helpers.get_reservation_context_details().id
14+
15+
def execute(self):
16+
api = helpers.get_api_session()
17+
reservation_details = api.GetReservationDetails(self.reservation_id)
18+
19+
self._disconnect_all_routes_in_reservation(api, reservation_details)
20+
self._power_off_all_vm_resources(api, reservation_details)
21+
22+
logger.info("Teardown for reservation {0} completed".format(self.reservation_id))
23+
24+
def _disconnect_all_routes_in_reservation(self, api, reservation_details):
25+
connectors = reservation_details.ReservationDescription.Connectors
26+
endpoints = []
27+
for endpoint in connectors:
28+
endpoints.append(endpoint.Target)
29+
endpoints.append(endpoint.Source)
30+
31+
if len(endpoints) == 0:
32+
logger.info("No routes to disconnect for reservation {0}".format(self.reservation_id))
33+
return
34+
35+
logger.info("Executing disconnect routes for reservation {0}".format(self.reservation_id))
36+
37+
return api.DisconnectRoutesInReservation(self.reservation_id, endpoints)
38+
39+
def _power_off_all_vm_resources(self, api, reservation_details):
40+
resources = reservation_details.ReservationDescription.Resources
41+
42+
pool = ThreadPool()
43+
44+
for resource in resources:
45+
resource_details = api.GetResourceDetails(resource.Name)
46+
if resource_details.VmDetails:
47+
pool.apply_async(self._power_off_resource, (api, resource_details.Name))
48+
49+
pool.close()
50+
pool.join()
51+
52+
def _power_off_resource(self, api, resource_name):
53+
try:
54+
logger.info("Executing 'Power Off' on deployed app {0} in reservation {1}"
55+
.format(resource_name, self.reservation_id))
56+
api.ExecuteResourceConnectedCommand(self.reservation_id, resource_name, "PowerOff", "power")
57+
return True
58+
except Exception as exc:
59+
logger.error("Error powering off deployed app {0} in reservation {1}. Error: {2}"
60+
.format(resource_name, self.reservation_id, str(exc)))
61+
return False

vCenterShellPackage/DataModel/datamodel.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,5 +657,11 @@
657657
<ns0:ScriptDescriptor Name="Connect All" Version="1.0.0">
658658
<ns0:ScriptInputs />
659659
</ns0:ScriptDescriptor>
660+
<ns0:ScriptDescriptor Name="Setup" Version="1.0.0">
661+
<ns0:ScriptInputs />
662+
</ns0:ScriptDescriptor>
663+
<ns0:ScriptDescriptor Name="Teardown" Version="1.0.0">
664+
<ns0:ScriptInputs />
665+
</ns0:ScriptDescriptor>
660666
</ns0:ScriptDescriptors>
661667
</ns0:DataModelInfo>

0 commit comments

Comments
 (0)