Skip to content

Commit d8dcf32

Browse files
authored
Merge pull request #956 from QualiSystems/develop
Merge dev to master
2 parents f87ff5d + 89ef999 commit d8dcf32

File tree

58 files changed

+1968
-421
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+1968
-421
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ package/cloudshell/tests/config.ini
6767
*.tar.gz
6868
*.orig
6969
vCenterShell.zip
70-
vCenterShellPackage/
7170
debug.txt
7271
package/cloudshell/tests/utils/config.ini
7372

@@ -82,3 +81,4 @@ develop.cmd
8281
debug.xml
8382
debug_info.txt
8483

84+
/package/dist/

.travis.yml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,8 @@ env:
44
install:
55
- pip install -r external_requirements.txt
66
- pip install -r test_requirements.txt
7-
- pip install "cloudshell-core>=2.2.0,<2.3.0" --extra-index-url https://testpypi.python.org/simple
8-
- chmod 777 ./cloudshell_shell_core_install.sh
9-
- ./cloudshell_shell_core_install.sh
10-
- pip install "cloudshell-automation-api>=8.3.0.0,<8.3.1.0" --extra-index-url https://testpypi.python.org/simple
7+
- pip install "cloudshell-automation-api>=9.0.0.0,<9.0.1.0" --extra-index-url https://test.pypi.org/simple
8+
- pip install "cloudshell-cp-core>=1.0.0,<1.1.0" --extra-index-url https://test.pypi.org/simple
119
language: python
1210
notifications:
1311
webhools: "https://qualisystems.getbadges.io/api/app/webhook/63350e33-4119-49c3-8127-075aaa022926"

external_requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ lxml==3.8.0
22
requests==2.18.4
33
pyvmomi==6.5.0
44
jsonpickle==0.9.3
5-
enum==0.4.6
5+
enum==0.4.6
6+
retrying==1.3.3

package/__init__.py

Whitespace-only changes.

package/cloudshell/cp/vcenter/commands/destroy_vm.py renamed to package/cloudshell/cp/vcenter/commands/DeleteInstance.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def destroy(self, si, logger, session, vcenter_data_model, vm_uuid, vm_name, res
4444
self.resource_remover.remove_resource(session=session, resource_full_name=vm_name)
4545
return result
4646

47-
def destroy_vm_only(self, si, logger, session, vcenter_data_model, vm_uuid, vm_name):
47+
def DeleteInstance(self, si, logger, session, vcenter_data_model, vm_uuid, vm_name):
4848
"""
4949
:param logger:
5050
:param CloudShellAPISession session:

package/cloudshell/cp/vcenter/commands/command_orchestrator.py

Lines changed: 126 additions & 65 deletions
Large diffs are not rendered by default.
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import copy
2+
from itertools import groupby
3+
4+
from cloudshell.cp.core.models import ActionResultBase
5+
6+
from cloudshell.cp.vcenter.common.utilites.savers.artifact_saver import ArtifactHandler, UnsupportedArtifactHandler
7+
from cloudshell.cp.vcenter.common.vcenter.task_waiter import SynchronousTaskWaiter
8+
from cloudshell.cp.vcenter.common.vcenter.vmomi_service import pyVmomiService
9+
10+
import os
11+
from multiprocessing.pool import ThreadPool
12+
13+
14+
class DeleteSavedSandboxCommand:
15+
def __init__(self, pyvmomi_service, task_waiter, deployer, resource_model_parser, snapshot_saver, folder_manager,
16+
cancellation_service, port_group_configurer):
17+
"""
18+
:param pyvmomi_service:
19+
:type pyvmomi_service: pyVmomiService
20+
:param task_waiter: Waits for the task to be completed
21+
:param folder_manager: cloudshell.cp.vcenter.common.vcenter.folder_manager.FolderManager
22+
:type task_waiter: SynchronousTaskWaiter
23+
"""
24+
self.pyvmomi_service = pyvmomi_service
25+
self.task_waiter = task_waiter
26+
self.deployer = deployer
27+
self.resource_model_parser = resource_model_parser
28+
self.snapshot_saver = snapshot_saver
29+
self.folder_manager = folder_manager
30+
DELETE_SAVED_APPS_THREAD_POOL_SIZE = int(os.getenv('DeleteSavedAppsThreadPoolSize', 10))
31+
self._pool = ThreadPool(DELETE_SAVED_APPS_THREAD_POOL_SIZE)
32+
self.cs = cancellation_service
33+
self.pg = port_group_configurer
34+
35+
def delete_sandbox(self, si, logger, vcenter_data_model, delete_sandbox_actions, cancellation_context):
36+
"""
37+
Deletes a saved sandbox's artifacts
38+
39+
:param vcenter_data_model: VMwarevCenterResourceModel
40+
:param vim.ServiceInstance si: py_vmomi service instance
41+
:type si: vim.ServiceInstance
42+
:param logger: Logger
43+
:type logger: cloudshell.core.logger.qs_logger.get_qs_logger
44+
:param list[SaveApp] delete_sandbox_actions:
45+
:param cancellation_context:
46+
"""
47+
results = []
48+
49+
logger.info('Deleting saved sandbox command starting on ' + vcenter_data_model.default_datacenter)
50+
51+
if not delete_sandbox_actions:
52+
raise Exception('Failed to delete saved sandbox, missing data in request.')
53+
54+
actions_grouped_by_save_types = groupby(delete_sandbox_actions, lambda x: x.actionParams.saveDeploymentModel)
55+
artifactHandlersToActions = {ArtifactHandler.factory(k,
56+
self.pyvmomi_service,
57+
vcenter_data_model,
58+
si,
59+
logger,
60+
self.deployer,
61+
None,
62+
self.resource_model_parser,
63+
self.snapshot_saver,
64+
self.task_waiter,
65+
self.folder_manager,
66+
self.pg,
67+
self.cs): list(g)
68+
for k, g in actions_grouped_by_save_types}
69+
70+
self._validate_save_deployment_models(artifactHandlersToActions, delete_sandbox_actions, results)
71+
72+
error_results = [r for r in results if not r.success]
73+
if not error_results:
74+
results = self._execute_delete_saved_sandbox(artifactHandlersToActions,
75+
cancellation_context,
76+
logger,
77+
results)
78+
79+
return results
80+
81+
def _validate_save_deployment_models(self, artifactHandlersToActions, delete_sandbox_actions, results):
82+
unsupported_save_deployment_models = [a.unsupported_save_type for a in artifactHandlersToActions.keys() if
83+
isinstance(a, UnsupportedArtifactHandler)]
84+
if unsupported_save_deployment_models:
85+
for action in delete_sandbox_actions:
86+
unsupported_msg = 'Unsupported save deployment models: {0}'.format(
87+
', '.join(unsupported_save_deployment_models))
88+
results.append(
89+
ActionResultBase(type='DeleteSavedAppResult',
90+
actionId=action.actionId,
91+
success=False,
92+
infoMessage=unsupported_msg,
93+
errorMessage=unsupported_msg)
94+
)
95+
96+
def _execute_delete_saved_sandbox(self, artifactHandlersToActions, cancellation_context, logger, results):
97+
for artifactHandler in artifactHandlersToActions.keys():
98+
delete_sandbox_results = artifactHandler.delete(artifactHandlersToActions[artifactHandler],
99+
cancellation_context,
100+
self._pool)
101+
results.extend(delete_sandbox_results)
102+
return results
103+
Lines changed: 54 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1-
from cloudshell.cp.vcenter.models.DeployFromTemplateDetails import DeployFromTemplateDetails
1+
from cloudshell.cp.vcenter.models.DeployFromImageDetails import DeployFromImageDetails
2+
3+
from cloudshell.cp.vcenter.common.vcenter.vm_location import VMLocation
4+
from cloudshell.cp.vcenter.models.DeployFromTemplateDetails import DeployFromTemplateDetails
5+
from os.path import normpath
6+
7+
DEPLOYED_APPS = 'Deployed Apps'
8+
29

310

411
class DeployCommand(object):
@@ -11,35 +18,67 @@ def __init__(self, deployer):
1118
"""
1219
self.deployer = deployer
1320

14-
def execute_deploy_from_linked_clone(self, si, logger, vcenter_data_model, reservation_id, deployment_params):
21+
def execute_deploy_from_linked_clone(self, si, logger, vcenter_data_model, reservation_id, deployment_params, cancellation_context, folder_manager):
1522
"""
1623
Calls the deployer to deploy vm from snapshot
24+
:param cancellation_context:
1725
:param str reservation_id:
1826
:param si:
1927
:param logger:
2028
:type deployment_params: DeployFromLinkedClone
2129
:param vcenter_data_model:
2230
:return:
2331
"""
32+
self._prepare_deployed_apps_folder(deployment_params, si, logger, folder_manager, vcenter_data_model)
33+
2434
deploy_result = self.deployer.deploy_from_linked_clone(si, logger, deployment_params, vcenter_data_model,
25-
reservation_id)
35+
reservation_id, cancellation_context)
2636
return deploy_result
2737

28-
def execute_deploy_clone_from_vm(self, si, logger, vcenter_data_model, reservation_id, deployment_params):
38+
def execute_deploy_clone_from_vm(self, si, logger, vcenter_data_model, reservation_id, deployment_params, cancellation_context, folder_manager):
2939
"""
3040
Calls the deployer to deploy vm from another vm
41+
:param cancellation_context:
3142
:param str reservation_id:
3243
:param si:
3344
:param logger:
3445
:type deployment_params: DeployFromTemplateDetails
3546
:param vcenter_data_model:
3647
:return:
3748
"""
49+
self._prepare_deployed_apps_folder(deployment_params, si, logger, folder_manager, vcenter_data_model)
3850
deploy_result = self.deployer.deploy_clone_from_vm(si, logger, deployment_params, vcenter_data_model,
39-
reservation_id)
51+
reservation_id, cancellation_context)
4052
return deploy_result
4153

42-
def execute_deploy_from_template(self, si, logger, vcenter_data_model, reservation_id, deployment_params):
54+
def _prepare_deployed_apps_folder(self, data_holder, si, logger, folder_manager, vcenter_resource_model):
55+
if isinstance(data_holder, DeployFromImageDetails):
56+
self._update_deploy_from_image_vm_location(data_holder, folder_manager, logger, si, vcenter_resource_model)
57+
else:
58+
self._update_deploy_from_template_vm_location(data_holder, folder_manager, logger, si,
59+
vcenter_resource_model)
60+
61+
def _update_deploy_from_template_vm_location(self, data_holder, folder_manager, logger, si, vcenter_resource_model):
62+
vm_location = data_holder.template_resource_model.vm_location or vcenter_resource_model.vm_location
63+
folder_path = VMLocation.combine([vcenter_resource_model.default_datacenter, vm_location])
64+
folder_manager.get_or_create_vcenter_folder(si,
65+
logger,
66+
folder_path,
67+
DEPLOYED_APPS)
68+
data_holder.template_resource_model.vm_location = VMLocation.combine([vm_location, DEPLOYED_APPS])
69+
logger.info('VM will be deployed to {0}'.format(data_holder.template_resource_model.vm_location))
70+
71+
def _update_deploy_from_image_vm_location(self, data_holder, folder_manager, logger, si, vcenter_resource_model):
72+
vm_location = data_holder.image_params.vm_location or vcenter_resource_model.vm_location
73+
folder_path = VMLocation.combine([vcenter_resource_model.default_datacenter, vm_location])
74+
folder_manager.get_or_create_vcenter_folder(si,
75+
logger,
76+
folder_path,
77+
DEPLOYED_APPS)
78+
data_holder.image_params.vm_location = VMLocation.combine([vm_location, DEPLOYED_APPS])
79+
logger.info('VM will be deployed to {0}'.format(data_holder.image_params.vm_location))
80+
81+
def execute_deploy_from_template(self, si, logger, vcenter_data_model, reservation_id, deployment_params, cancellation_context, folder_manager):
4382
"""
4483
4584
:param str reservation_id:
@@ -49,14 +88,17 @@ def execute_deploy_from_template(self, si, logger, vcenter_data_model, reservati
4988
:param vcenter_data_model:
5089
:return:
5190
"""
91+
self._prepare_deployed_apps_folder(deployment_params, si, logger, folder_manager, vcenter_data_model)
92+
5293
deploy_result = self.deployer.deploy_from_template(si, logger, deployment_params, vcenter_data_model,
53-
reservation_id)
94+
reservation_id, cancellation_context)
5495
return deploy_result
5596

5697
def execute_deploy_from_image(self, si, logger, session, vcenter_data_model, reservation_id, deployment_params,
57-
resource_context):
98+
resource_context, cancellation_context, folder_manager):
5899
"""
59100
101+
:param cancellation_context:
60102
:param str reservation_id:
61103
:param si:
62104
:param logger:
@@ -66,11 +108,14 @@ def execute_deploy_from_image(self, si, logger, session, vcenter_data_model, res
66108
:param resource_context:
67109
:return:
68110
"""
111+
self._prepare_deployed_apps_folder(deployment_params, si, logger, folder_manager, vcenter_data_model)
112+
69113
deploy_result = self.deployer.deploy_from_image(si=si,
70114
logger=logger,
71115
session=session,
72116
vcenter_data_model=vcenter_data_model,
73117
data_holder=deployment_params,
74118
resource_context=resource_context,
75-
reservation_id=reservation_id)
119+
reservation_id=reservation_id,
120+
cancellation_context=cancellation_context)
76121
return deploy_result

package/cloudshell/cp/vcenter/commands/power_manager_vm.py

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,7 @@ def power_off(self, si, logger, session, vcenter_data_model, vm_uuid, resource_f
5050

5151
vm.ShutdownGuest()
5252
task_result = 'vm powered off'
53-
54-
# Set live status - deployment done
55-
if resource_fullname:
56-
session.SetResourceLiveStatus(resource_fullname, "Offline", "Powered Off")
57-
53+
5854
return task_result
5955

6056
def power_on(self, si, logger, session, vm_uuid, resource_fullname):
@@ -80,8 +76,4 @@ def power_on(self, si, logger, session, vm_uuid, resource_fullname):
8076
logger=logger,
8177
action_name='Power On')
8278

83-
# Set live status - deployment done
84-
if resource_fullname:
85-
session.SetResourceLiveStatus(resource_fullname, "Online", "Active")
86-
8779
return task_result

package/cloudshell/cp/vcenter/commands/restore_snapshot.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,9 @@ def restore_snapshot(self, si, logger, session, vm_uuid, resource_fullname, snap
3535
logger.info("Revert snapshot")
3636

3737
snapshot = SnapshotRestoreCommand._get_snapshot(vm=vm, snapshot_name=snapshot_name)
38-
3938
session.SetResourceLiveStatus(resource_fullname, "Offline", "Powered Off")
40-
4139
task = snapshot.RevertToSnapshot_Task()
40+
4241
return self.task_waiter.wait_for_task(task=task, logger=logger, action_name='Revert Snapshot')
4342

4443
@staticmethod

0 commit comments

Comments
 (0)