def __init__(self): # self.cs_helper = CloudshellDriverHelper() self.model_parser = ResourceModelParser() self.ip_manager = VMIPManager() self.task_waiter = SynchronousTaskWaiter() self.pv_service = pyVmomiService(SmartConnect, Disconnect, self.task_waiter)
def __init__(self): super(PaloAltoStaticShellDriver, self).__init__() self._cli = None self.cs_helper = CloudshellDriverHelper() self.model_parser = ResourceModelParser() self.ip_manager = VMIPManager() self.task_waiter = SynchronousTaskWaiter() self.pv_service = pyVmomiService(SmartConnect, Disconnect, self.task_waiter)
def test_refresh_ip_choose_ipv4(self): nic1 = Mock() nic1.network = 'A Network' nic1.ipAddress = ['192.168.1.1'] nic2 = Mock() nic2.network = 'A Network' nic2.ipAddress = ['2001:0db8:0a0b:12f0:0000:0000:0000:0001'] guest = Mock() guest.toolsStatus = 'toolsOk' guest.net = [nic1, nic2] vm = Mock() vm.guest = guest pyvmomi_service = Mock() pyvmomi_service.find_by_uuid = Mock(return_value=vm) ip_regex = self._create_custom_param('ip_regex', '') refresh_ip_timeout = self._create_custom_param('refresh_ip_timeout', '10') resource_instance = create_autospec(ResourceInfo) resource_instance.ResourceModelName = 'Generic Deployed App' resource_instance.ResourceAttributes = { 'vm_uuis': '123', 'cloud_provider': 'vCenter' } resource_instance.VmDetails = create_autospec(ResourceInfoVmDetails) resource_instance.VmDetails.VmCustomParams = [ ip_regex, refresh_ip_timeout ] refresh_ip_command = RefreshIpCommand(pyvmomi_service, ResourceModelParser(), Mock()) session = Mock() session.UpdateResourceAddress = Mock(return_value=True) session.GetResourceDetails = Mock(return_value=resource_instance) si = Mock() center_resource_model = VMwarevCenterResourceModel() center_resource_model.default_datacenter = 'QualiSB' center_resource_model.holding_network = 'anetwork' cancellation_context = Mock() # Act refresh_ip_command.refresh_ip( si=si, session=session, vcenter_data_model=center_resource_model, vm_uuid='machine1', resource_name='default_network', cancellation_context=cancellation_context, logger=Mock()) # Assert self.assertTrue( session.UpdateResourceAddress.called_with('machine1', '192.168.1.1'))
def test_get_vcenter_data_model(self): # Arrange data_model_retriever = VCenterDataModelRetriever(ResourceModelParser()) api = Mock() vcenter_resource = create_autospec(ResourceContextDetails) vcenter_resource.model = 'VMWare vCenter' vcenter_resource.attrib = { 'user': '******', 'password': '******', 'default_dvswitch': '', 'holding_network': '', 'vm_cluster': '', 'vm_resource_pool': '', 'vm_storage': '', 'vm_location': '', 'shutdown_method': '', 'ovf_tool_path': '', 'execution_server_selector': '', 'reserved_networks': '', 'default_datacenter': '', 'promiscuous_mode': '', 'behavior_during_save': '', 'saved_sandbox_storage': '' } api.GetResourceDetails = Mock(return_value=vcenter_resource) # Act vcenter_data_model = data_model_retriever.get_vcenter_data_model( api, 'VMWare Center') # Assert self.assertEqual(vcenter_data_model.user, 'uzer')
def test_parse_resource_info_model(self): resource_model_parser = ResourceModelParser() resource_info = create_autospec(ResourceInfo) resource_info.ResourceModelName = 'VLAN Auto' resource_info.ResourceAttributes = {'Access Mode': 'Trunk', 'VLAN Id': '123', 'Allocation Ranges': '2-4094', 'Virtual Network': '', 'Isolation Level': 'Exclusive'} resource_model = resource_model_parser.convert_to_resource_model(resource_info, None) self.assertEqual(resource_model.access_mode, 'Trunk') self.assertEqual(resource_model.vlan_id, '123') self.assertEqual(resource_model.isolation_level, 'Exclusive') self.assertEqual(resource_model.allocation_ranges, '2-4094') self.assertEqual(resource_model.virtual_network, '') self.assertEqual(resource_model.virtual_network_attribute, 'Virtual Network')
def setUp(self): self.name = 'name' self.uuid = 'uuid' self.name_gen = Mock(return_value=self.name) self.pv_service = Mock() self.si = Mock() self.clone_parmas = Mock() self.clone_res = Mock() self.clone_res.error = None self.clone_res.vm = Mock() self.clone_res.vm.summary = Mock() self.clone_res.vm.summary.config = Mock() self.clone_res.vm.summary.config.uuid = self.uuid self.pv_service.CloneVmParameters = Mock( return_value=self.clone_parmas) self.pv_service.clone_vm = Mock(return_value=self.clone_res) self.image_deployer = Mock() self.image_deployer.deploy_image = Mock(return_value=True) self.vm = Mock() self.vm.config = Mock() self.vm.config.uuid = self.uuid self.pv_service.find_vm_by_name = Mock(return_value=self.vm) self.cs_helper = Mock() self.model_parser = ResourceModelParser() self.deployer = VirtualMachineDeployer(self.pv_service, self.name_gen, self.image_deployer, self.cs_helper, self.model_parser)
def test_get_vcenter_data_model_empty_vcenter_name(self): # Arrange data_model_retriever = VCenterDataModelRetriever(ResourceModelParser()) api = Mock() vcenter_resource = create_autospec(ResourceContextDetails) vcenter_resource.model = 'VMWare vCenter' vcenter_resource.attrib = { 'user': '******', 'password': '******', 'default_dvswitch': '', 'holding_network': '', 'vm_cluster': '', 'vm_resource_pool': '', 'vm_storage': '', 'vm_location': '', 'shutdown_method': '', 'ovf_tool_path': '', 'execution_server_selector': '', 'reserved_networks': '', 'default_datacenter': '', 'promiscuous_mode': '' } api.GetResourceDetails = Mock(return_value=vcenter_resource) # Act + Assert self.assertRaises(ValueError, data_model_retriever.get_vcenter_data_model, api, '')
def __init__(self): self.cs_helper = CloudshellDriverHelper() self.model_parser = ResourceModelParser() self.ip_manager = VMIPManager() self.task_waiter = SynchronousTaskWaiter() self.logger = get_qs_logger('VM AutoLoad') self.pv_service = pyVmomiService(SmartConnect, Disconnect, self.task_waiter)
def test_parse_resource__info_model_missing_attribute(self): resource_model_parser = ResourceModelParser() attributes = {'Access Mode': 'Trunk'} self.assertRaises(ValueError, resource_model_parser.convert_to_resource_model, attributes, VLANAutoResourceModel)
def test_parse_response_info(self): resource_info = create_autospec(ResourceInfo) resource_info.ResourceModelName = 'Generic Deployed App' vm_uuid_attribute = create_autospec(ResourceAttribute) vm_uuid_attribute.Name = 'VM_UUID' vm_uuid_attribute.Value = '422258cd-8b76-e375-8c3b-8e1bf86a4713' cloud_provider_attribute = create_autospec(ResourceAttribute) cloud_provider_attribute.Name = 'Cloud Provider' cloud_provider_attribute.Value = 'vCenter' resource_info.ResourceAttributes = [vm_uuid_attribute, cloud_provider_attribute] resource_model_parser = ResourceModelParser() resource_model = resource_model_parser.convert_to_resource_model(resource_info, None) self.assertEqual(resource_model.vm_uuid, '422258cd-8b76-e375-8c3b-8e1bf86a4713')
def test_refresh_ip_choose_ip_by_regex(self): nic1 = Mock() nic1.network = 'A Network' nic1.ipAddress = ['192.168.1.1'] nic2 = Mock() nic2.network = 'A Network' nic2.ipAddress = ['111.111.111.111'] guest = Mock() guest.toolsStatus = 'toolsOk' guest.net = [nic1, nic2] vm = Mock() vm.guest = guest pyvmomi_service = Mock() pyvmomi_service.find_by_uuid = Mock(return_value=vm) ip_regex = self._create_custom_param('ip_regex', '192\.168\..*') refresh_ip_timeout = self._create_custom_param('refresh_ip_timeout', '10') resource_model = create_autospec(GenericDeployedAppResourceModel) resource_model.fullname = 'Generic Deployed App' resource_model.vm_uuid = '123', resource_model.cloud_provider = 'vCenter' resource_model.vm_custom_params = [ip_regex, refresh_ip_timeout] refresh_ip_command = RefreshIpCommand(pyvmomi_service, ResourceModelParser(), Mock()) session = Mock() session.UpdateResourceAddress = Mock(return_value=True) session.GetResourceDetails = Mock(return_value=resource_model) si = Mock() center_resource_model = VMwarevCenterResourceModel() center_resource_model.default_datacenter = 'QualiSB' center_resource_model.holding_network = 'anetwork' cancellation_context = Mock() # Act refresh_ip_command.refresh_ip( si=si, session=session, vcenter_data_model=center_resource_model, resource_model=resource_model, cancellation_context=cancellation_context, logger=Mock(), app_request_json=Mock()) # Assert self.assertTrue( session.UpdateResourceAddress.called_with('machine1', '192.168.1.1'))
def test_resource_models(self): ns = { 'default': 'http://schemas.qualisystems.com/ResourceManagement/DataModelSchema.xsd' } #It didn't work with //..//..//.. so ?I used os.path.dirname X times datamodel_path = os.path.join( os.path.dirname( os.path.dirname( os.path.dirname(os.path.dirname( os.path.dirname(__file__))))), 'vCenterShellPackage/DataModel/datamodel.xml') tree = ET.parse(datamodel_path) root = tree.getroot() resource_models = root.findall('.//default:ResourceModel', ns) self.assertGreater(len(resource_models), 0) validation_errors = [] for resource_model in resource_models: model_name = ResourceModelParser().get_resource_model_class_name( resource_model.attrib['Name']) try: klass = ResourceModelParser().get_class( 'cloudshell.cp.vcenter.models.' + model_name) except ValueError as value_error: validation_errors.append( 'Failed to parse Model Name {0} with error {1}.'.format( model_name, value_error.message)) continue attribute_names = self.get_model_attributes(ns, resource_model) for attribute_name in attribute_names: if not hasattr(klass, attribute_name): validation_errors.append( 'attribute {0} is missing on class {1}'.format( attribute_name, model_name)) for validation_error in validation_errors: print validation_error self.assertSequenceEqual(validation_errors, [])
class DeployFromImage(ResourceDriverInterface): def cleanup(self): pass def __init__(self): self.cs_helper = CloudshellDriverHelper() self.resource_model_parser = ResourceModelParser() def initialize(self, context): pass def Deploy(self, context, Name=None): """ Deploys app from image :type context: models.QualiDriverModels.ResourceCommandContext """ session = self.cs_helper.get_session( context.connectivity.server_address, context.connectivity.admin_auth_token, context.reservation.domain) # get vCenter resource name, template name, template folder vcenter_image_resource_model = \ self.resource_model_parser.convert_to_resource_model(context.resource, vCenterVMFromImageResourceModel) vcenter_res = vcenter_image_resource_model.vcenter_name if not Name: Name = jsonpickle.decode( context.resource.app_context.app_request_json)['name'] deployment_info = self._get_deployment_info( vcenter_image_resource_model, Name) result = session.ExecuteCommand( context.reservation.reservation_id, vcenter_res, "Resource", "deploy_from_image", self._get_command_inputs_list(deployment_info), False) return result.Output def _get_deployment_info(self, image_model, name): """ :type image_model: vCenterVMFromImageResourceModel """ return DeployDataHolder({ 'app_name': name, 'image_params': image_model }) def _get_command_inputs_list(self, data_holder): return [ InputNameValue('deploy_data', jsonpickle.encode(data_holder, unpicklable=False)) ]
def test_parse_resource_info_model(self): resource_model_parser = ResourceModelParser() attributes = { 'Access Mode': 'Trunk', 'VLAN Id': '123', 'Allocation Ranges': '2-4094', 'Virtual Network': '', 'Isolation Level': 'Exclusive' } resource_model = resource_model_parser.convert_to_resource_model( attributes, VLANAutoResourceModel) self.assertEqual(resource_model.access_mode, 'Trunk') self.assertEqual(resource_model.vlan_id, '123') self.assertEqual(resource_model.isolation_level, 'Exclusive') self.assertEqual(resource_model.allocation_ranges, '2-4094') self.assertEqual(resource_model.virtual_network, '') self.assertEqual(resource_model.virtual_network_attribute, 'Virtual Network')
class DeployFromImage(ResourceDriverInterface): def cleanup(self): pass def __init__(self): self.cs_helper = CloudshellDriverHelper() self.resource_model_parser = ResourceModelParser() def initialize(self, context): pass def Deploy(self, context, Name=None): """ Deploys app from image :type context: models.QualiDriverModels.ResourceCommandContext """ session = self.cs_helper.get_session(context.connectivity.server_address, context.connectivity.admin_auth_token, context.reservation.domain) # get vCenter resource name, template name, template folder vcenter_image_resource_model = \ self.resource_model_parser.convert_to_resource_model(context.resource, vCenterVMFromImageResourceModel) vcenter_res = vcenter_image_resource_model.vcenter_name if not Name: Name = jsonpickle.decode(context.resource.app_context.app_request_json)['name'] deployment_info = self._get_deployment_info(vcenter_image_resource_model, Name) result = session.ExecuteCommand(context.reservation.reservation_id, vcenter_res, "Resource", "deploy_from_image", self._get_command_inputs_list(deployment_info), False) return result.Output def _get_deployment_info(self, image_model, name): """ :type image_model: vCenterVMFromImageResourceModel """ return DeployDataHolder({'app_name': name, 'image_params': image_model }) def _get_command_inputs_list(self, data_holder): return [InputNameValue('deploy_data', jsonpickle.encode(data_holder, unpicklable=False))]
def test_parse_resource_info_model_with_specified_type_by_string(self): resource_model_parser = ResourceModelParser() attributes = { 'Access Mode': 'Trunk', 'VLAN ID': '123', 'Allocation Ranges': '2-4094', 'Virtual Network': '', 'Isolation Level': 'Exclusive' } self.assertRaises(ValueError, resource_model_parser.convert_to_resource_model, attributes, 'VLANAutoResourceModel')
class DeployFromTemplateDriver(ResourceDriverInterface): def __init__(self): self.resource_model_parser = ResourceModelParser() self.cs_helper = CloudshellDriverHelper() def cleanup(self): pass def initialize(self, context): pass def Deploy(self, context, Name=None): """ Deploys app from template :type context: models.QualiDriverModels.ResourceCommandContext :param Name: Name of the Deployment :type Name: str :rtype: str """ session = self.cs_helper.get_session( context.connectivity.server_address, context.connectivity.admin_auth_token, context.reservation.domain) vcenter_template_resource_model = \ self.resource_model_parser.convert_to_resource_model(context.resource, vCenterVMFromTemplateResourceModel) if not Name: Name = jsonpickle.decode( context.resource.app_context.app_request_json)['name'] deploy_from_template_details = DeployFromTemplateDetails( vcenter_template_resource_model, Name) params = [ InputNameValue( 'deploy_data', jsonpickle.encode(deploy_from_template_details, unpicklable=False)) ] reservation_id = context.reservation.reservation_id result = session.ExecuteCommand( reservation_id, vcenter_template_resource_model.vcenter_name, "Resource", "deploy_from_template", params, False) return result.Output
class DeployCloneFromVMDriver(ResourceDriverInterface): def __init__(self): self.resource_model_parser = ResourceModelParser() self.cs_helper = CloudshellDriverHelper() def cleanup(self): pass def initialize(self, context): pass def Deploy(self, context, Name=None): """ Deploys app from template :type context: models.QualiDriverModels.ResourceCommandContext :param Name: Name of the Deployment :type Name: str :rtype: str """ session = self.cs_helper.get_session(context.connectivity.server_address, context.connectivity.admin_auth_token, context.reservation.domain) vcenter_template_resource_model = \ self.resource_model_parser.convert_to_resource_model(context.resource, VCenterDeployVMFromLinkedCloneResourceModel) if not Name: Name = jsonpickle.decode(context.resource.app_context.app_request_json)['name'] deploy_from_template_details = DeployFromTemplateDetails(vcenter_template_resource_model, Name) params = [InputNameValue('deploy_data', jsonpickle.encode(deploy_from_template_details, unpicklable=False))] reservation_id = context.reservation.reservation_id result = session.ExecuteCommand(reservation_id, vcenter_template_resource_model.vcenter_name, "Resource", "deploy_from_linked_clone", params, False) return result.Output
def setUp(self): self._si = None self.virtual_machine_path = 'SergiiT' self.virtual_machine_name = 'JustTestNeedToBeRemoved' self.vm_uuid = "422254d5-5226-946e-26fb-60c21898b731" self.vcenter_name = "QualiSB" self.dv_switch_path = 'QualiSB' self.network_path = 'QualiSB' self.dv_switch_name = 'dvSwitch-SergiiT' self.dv_port_group_name = 'aa-dvPortGroup3B' self.network = Mock() self.network.key = "network-key" self.network.config.distributedVirtualSwitch.uuid = "422254d5-5226-946e-26fb-60c21898b73f" self.py_vmomi_service = Mock() self.vm = Mock() self.vm.config.hardware = Mock() self.vnic = Mock(spec=vim.vm.device.VirtualEthernetCard) self.vnic.deviceInfo = Mock() self.vm.config.hardware.device = [self.vnic] self.py_vmomi_service.find_by_uuid = lambda a, b, c: self.vm self.py_vmomi_service.find_network_by_name = Mock( return_value=self.network) self.synchronous_task_waiter = Mock() self.synchronous_task_waiter.wait_for_task = Mock( return_value="TASK OK") self.si = Mock() resource_model_parser = ResourceModelParser() # vc_model_retriever = VCenterDataModelRetriever(helpers, resource_model_parser, cloudshell_data_retriever_service) # vc_data_model = vc_model_retriever.get_vcenter_data_model() vc_data_model = Mock() name_generator = generate_unique_name # vnic_to_network_mapper = VnicToNetworkMapper(name_generator, vc_data_model.default_network) vnic_to_network_mapper = VnicToNetworkMapper(name_generator) helpers = Mock() cs_retriever_service = Mock() session = Mock() resource_context = Mock() connection_details = Mock() helpers.get_resource_context_details = Mock( return_value=resource_context) helpers.get_api_session = Mock(return_value=session) cs_retriever_service.getVCenterConnectionDetails = Mock( return_value=connection_details) self.connection_details_retriever = ResourceConnectionDetailsRetriever( helpers) self.configurer = VirtualMachinePortGroupConfigurer( self.py_vmomi_service, self.synchronous_task_waiter, vnic_to_network_mapper, Mock(), Mock()) # pyvmomi_service, synchronous_task_waiter, vnic_to_network_mapper, vnic_common self.creator = DvPortGroupCreator(self.py_vmomi_service, self.synchronous_task_waiter) self.connector = VirtualSwitchToMachineConnector( self.creator, self.configurer)
class DeployAppOrchestrationDriver(object): def __init__(self): self.cs_helper = CloudshellDriverHelper() self.model_parser = ResourceModelParser() self.ip_manager = VMIPManager() self.task_waiter = SynchronousTaskWaiter() self.logger = get_qs_logger('VM AutoLoad') self.pv_service = pyVmomiService(SmartConnect, Disconnect, self.task_waiter) def get_inventory(self, context): """ Will locate vm in vcenter and fill its uuid :type context: cloudshell.shell.core.context.ResourceCommandContext """ vcenter_vm_name = context.resource.attributes['vCenter VM'] vcenter_vm_name = vcenter_vm_name.replace('\\', '/') vcenter_name = context.resource.attributes['vCenter Name'] self.logger.info('start autoloading vm_path: {0} on vcenter: {1}'.format(vcenter_vm_name, vcenter_name)) session = self.cs_helper.get_session(context.connectivity.server_address, context.connectivity.admin_auth_token, DOMAIN) vcenter_api_res = session.GetResourceDetails(vcenter_name) vcenter_resource = self.model_parser.convert_to_vcenter_model(vcenter_api_res) si = None try: self.logger.info('connecting to vcenter ({0})'.format(vcenter_api_res.Address)) si = self._get_connection_to_vcenter(self.pv_service, session, vcenter_resource, vcenter_api_res.Address) self.logger.info('loading vm uuid') vm_loader = VMLoader(self.pv_service) uuid = vm_loader.load_vm_uuid_by_name(si, vcenter_resource, vcenter_vm_name) self.logger.info('vm uuid: {0}'.format(uuid)) self.logger.info('loading the ip of the vm') ip = self._try_get_ip(self.pv_service, si, uuid, vcenter_resource) if ip: session.UpdateResourceAddress(context.resource.name, ip) except Exception as e: self.logger.error(e) raise finally: if si: self.pv_service.disconnect(si) return self._get_auto_load_response(uuid, vcenter_name, context.resource) def _get_auto_load_response(self, uuid, vcenter_name, resource): vm_details = self._get_vm_details(uuid, vcenter_name, resource) # return vm_details autoload_atts = [AutoLoadAttribute('', 'VmDetails', vm_details)] return AutoLoadDetails([], autoload_atts) def _try_get_ip(self, pv_service, si, uuid, vcenter_resource): ip = None try: vm = pv_service.get_vm_by_uuid(si, uuid) ip_res = self.ip_manager.get_ip(vm, vcenter_resource.holding_network, self.ip_manager.get_ip_match_function(None), cancellation_context=None, timeout=None, logger=self.logger) if ip_res.ip_address: ip = ip_res.ip_address except Exception as e: self.logger.debug('Error while trying to load VM({0}) IP'.format(uuid)) return ip @staticmethod def _get_vm_details(uuid, vcenter_name, resource): vm_details = ApiVmDetails() vm_details.UID = uuid vm_details.CloudProviderName = vcenter_name vm_details.VmCustomParams = [] str_vm_details = jsonpickle.encode(vm_details, unpicklable=False) return str_vm_details def _get_connection_to_vcenter(self, pv_service, session, vcenter_resource, address): password = self._decrypt_password(session, vcenter_resource.password) si = pv_service.connect(address, vcenter_resource.user, password, 443) return si @staticmethod def _decrypt_password(session, password): return session.DecryptPassword(password).Value
def __init__(self): """ Initialize the driver session, this function is called everytime a new instance of the driver is created in here the driver is going to be bootstrapped :param context: models.QualiDriverModels.InitCommandContext """ self.cs_helper = CloudshellDriverHelper() synchronous_task_waiter = SynchronousTaskWaiter() pv_service = pyVmomiService(connect=SmartConnect, disconnect=Disconnect, task_waiter=synchronous_task_waiter) self.resource_model_parser = ResourceModelParser() port_group_name_generator = DvPortGroupNameGenerator() vnic_to_network_mapper = VnicToNetworkMapper( quali_name_generator=port_group_name_generator) resource_remover = CloudshellResourceRemover() ovf_service = OvfImageDeployerService(self.resource_model_parser) self.vm_loader = VMLoader(pv_service) vm_deployer = VirtualMachineDeployer( pv_service=pv_service, name_generator=generate_unique_name, ovf_service=ovf_service, cs_helper=self.cs_helper, resource_model_parser=ResourceModelParser()) dv_port_group_creator = DvPortGroupCreator( pyvmomi_service=pv_service, synchronous_task_waiter=synchronous_task_waiter) virtual_machine_port_group_configurer = \ VirtualMachinePortGroupConfigurer(pyvmomi_service=pv_service, synchronous_task_waiter=synchronous_task_waiter, vnic_to_network_mapper=vnic_to_network_mapper, vnic_service=VNicService(), name_gen=port_group_name_generator) virtual_switch_to_machine_connector = VirtualSwitchToMachineConnector( dv_port_group_creator, virtual_machine_port_group_configurer) # Command Wrapper self.command_wrapper = CommandWrapper( pv_service=pv_service, cloud_shell_helper=self.cs_helper, resource_model_parser=self.resource_model_parser, context_based_logger_factory=ContextBasedLoggerFactory()) # Deploy Command self.deploy_command = DeployCommand(deployer=vm_deployer) # Virtual Switch Revoke self.virtual_switch_disconnect_command = \ VirtualSwitchToMachineDisconnectCommand( pyvmomi_service=pv_service, port_group_configurer=virtual_machine_port_group_configurer, resource_model_parser=self.resource_model_parser) # Virtual Switch Connect virtual_switch_connect_command = \ VirtualSwitchConnectCommand( pv_service=pv_service, virtual_switch_to_machine_connector=virtual_switch_to_machine_connector, dv_port_group_name_generator=DvPortGroupNameGenerator(), vlan_spec_factory=VlanSpecFactory(), vlan_id_range_parser=VLanIdRangeParser()) self.connection_orchestrator = ConnectionCommandOrchestrator( connector=virtual_switch_connect_command, disconnector=self.virtual_switch_disconnect_command, resource_model_parser=self.resource_model_parser) # Destroy VM Command self.destroy_virtual_machine_command = \ DestroyVirtualMachineCommand(pv_service=pv_service, resource_remover=resource_remover, disconnector=self.virtual_switch_disconnect_command) # Power Command self.vm_power_management_command = \ VirtualMachinePowerManagementCommand(pyvmomi_service=pv_service, synchronous_task_waiter=synchronous_task_waiter) ip_manager = VMIPManager() # Refresh IP command self.refresh_ip_command = RefreshIpCommand( pyvmomi_service=pv_service, resource_model_parser=ResourceModelParser(), ip_manager=ip_manager) # Save Snapshot self.snapshot_saver = SaveSnapshotCommand( pyvmomi_service=pv_service, task_waiter=synchronous_task_waiter) # Snapshot Restorer self.snapshot_restorer = SnapshotRestoreCommand( pyvmomi_service=pv_service, task_waiter=synchronous_task_waiter) self.snapshots_retriever = RetrieveSnapshotsCommand( pyvmomi_service=pv_service)
def __init__(self): self.resource_model_parser = ResourceModelParser() self.cs_helper = CloudshellDriverHelper()
class BreakingPointVChassisShellDriver(ResourceDriverInterface): DOMAIN = "Global" SHELL_NAME = "BP vChassis" def __init__(self): # self.cs_helper = CloudshellDriverHelper() self.model_parser = ResourceModelParser() self.ip_manager = VMIPManager() self.task_waiter = SynchronousTaskWaiter() self.pv_service = pyVmomiService(SmartConnect, Disconnect, self.task_waiter) def initialize(self, context): """ Initialize the driver session, this function is called everytime a new instance of the driver is created This is a good place to load and cache the driver configuration, initiate sessions etc. :param InitCommandContext context: the context the command runs on """ pass def cleanup(self): """ Destroy the driver session, this function is called everytime a driver instance is destroyed This is a good place to close any open sessions, finish writing to log files """ pass def get_inventory(self, context): """ Will locate vm in vcenter and fill its uuid :type context: cloudshell.shell.core.context.ResourceCommandContext """ logger = get_logger_with_thread_id(context) logger.info("Start Autoload process") vcenter_vm_name = context.resource.attributes["{}.vCenter VM".format(self.SHELL_NAME)] vcenter_vm_name = vcenter_vm_name.replace("\\", "/") vcenter_name = context.resource.attributes["{}.vCenter Name".format(self.SHELL_NAME)] logger.info("Start AutoLoading VM_path: {0} on vcenter: {1}".format(vcenter_vm_name, vcenter_name)) # session = self.cs_helper.get_session(context.connectivity.server_address, # context.connectivity.admin_auth_token, # self.DOMAIN) session = CloudShellAPISession(host=context.connectivity.server_address, token_id=context.connectivity.admin_auth_token, domain=self.DOMAIN) vcenter_api_res = session.GetResourceDetails(vcenter_name) vcenter_resource = self.model_parser.convert_to_vcenter_model(vcenter_api_res) si = None try: logger.info("Connecting to vcenter ({0})".format(vcenter_api_res.Address)) si = self._get_connection_to_vcenter(self.pv_service, session, vcenter_resource, vcenter_api_res.Address) logger.info("Loading VM UUID") vm_loader = VMLoader(self.pv_service) uuid = vm_loader.load_vm_uuid_by_name(si, vcenter_resource, vcenter_vm_name) logger.info("VM UUID: {0}".format(uuid)) logger.info("Loading the IP of the VM") ip = self._try_get_ip(self.pv_service, si, uuid, vcenter_resource, logger) if ip: session.UpdateResourceAddress(context.resource.name, ip) autoload_atts = [AutoLoadAttribute("", "VmDetails", self._get_vm_details(uuid, vcenter_name))] return AutoLoadDetails([], autoload_atts) except Exception: logger.exception("Get inventory command failed") raise finally: if si: self.pv_service.disconnect(si) def _try_get_ip(self, pv_service, si, uuid, vcenter_resource, logger): ip = None try: vm = pv_service.get_vm_by_uuid(si, uuid) ip_res = self.ip_manager.get_ip(vm, vcenter_resource.holding_network, self.ip_manager.get_ip_match_function(None), cancellation_context=None, timeout=None, logger=logger) if ip_res.ip_address: ip = ip_res.ip_address except Exception: logger.debug("Error while trying to load VM({0}) IP".format(uuid), exc_info=True) return ip @staticmethod def _get_vm_details(uuid, vcenter_name): vm_details = ApiVmDetails() vm_details.UID = uuid vm_details.CloudProviderName = vcenter_name vm_details.CloudProviderFullName = vcenter_name vm_details.VmCustomParams = [] str_vm_details = jsonpickle.encode(vm_details, unpicklable=False) return str_vm_details def _get_connection_to_vcenter(self, pv_service, session, vcenter_resource, address): password = self._decrypt_password(session, vcenter_resource.password) si = pv_service.connect(address, vcenter_resource.user, password, VCENTER_CONNECTION_PORT) return si @staticmethod def _decrypt_password(session, password): return session.DecryptPassword(password).Value
def __init__(self): self.resource_model_parser = ResourceModelParser() self.cs_helper = CloudshellDriverHelper()
def get_class_name_from_model_node(self, model_node): resource_model = model_node.attrib['Name'] return ResourceModelParser.get_resource_model_class_name(resource_model)
def get_attribute_name_from_attribute_node(self, attribute_node): return ResourceModelParser.get_property_name_from_attribute_name(attribute_node.attrib['Name'])
def get_class_name_from_model_node(self, model_node): resource_model = model_node.attrib['Name'] return ResourceModelParser.get_resource_model_class_name( resource_model)
class PaloAltoStaticShellDriver(ResourceDriverInterface, FirewallResourceDriverInterface, GlobalLock): SUPPORTED_OS = [r"Palo Alto"] SHELL_NAME = "PaloAlto Static vFirewall" PORT_MODEL = "GenericVPort" DOMAIN = "Global" def __init__(self): super(PaloAltoStaticShellDriver, self).__init__() self._cli = None self.cs_helper = CloudshellDriverHelper() self.model_parser = ResourceModelParser() self.ip_manager = VMIPManager() self.task_waiter = SynchronousTaskWaiter() self.pv_service = pyVmomiService(SmartConnect, Disconnect, self.task_waiter) def initialize(self, context): """ Initialize the driver session, this function is called everytime a new instance of the driver is created This is a good place to load and cache the driver configuration, initiate sessions etc. """ resource_config = create_firewall_resource_from_context( shell_name=self.SHELL_NAME, supported_os=self.SUPPORTED_OS, context=context) # session_pool_size = int(resource_config.sessions_concurrency_limit or 1) session_pool_size = int(resource_config.sessions_concurrency_limit) self._cli = get_cli(session_pool_size) return 'Finished initializing' def cleanup(self): """ Destroy the driver session, this function is called everytime a driver instance is destroyed This is a good place to close any open sessions, finish writing to log files """ pass def get_inventory(self, context): """ Will locate vm in vcenter and fill its uuid """ logger = get_logger_with_thread_id(context) logger.info("Start Autoload process") session = self.cs_helper.get_session( context.connectivity.server_address, context.connectivity.admin_auth_token, self.DOMAIN) vcenter_vblade = context.resource.attributes[ "{}.vFirewall vCenter VM".format(self.SHELL_NAME)].replace( "\\", "/") vcenter_name = context.resource.attributes["{}.vCenter Name".format( self.SHELL_NAME)] logger.info("Start AutoLoading VM_Path: {0} on vCenter: {1}".format( vcenter_vblade, vcenter_name)) vcenter_api_res = session.GetResourceDetails(vcenter_name) vcenter_resource = self.model_parser.convert_to_vcenter_model( vcenter_api_res) si = None try: logger.info("Connecting to vCenter ({0})".format( vcenter_api_res.Address)) si = self._get_connection_to_vcenter(self.pv_service, session, vcenter_resource, vcenter_api_res.Address) logger.info("Loading VMs UUID") vm_loader = VMLoader(self.pv_service) vfw_uuid = vm_loader.load_vm_uuid_by_name(si, vcenter_resource, vcenter_vblade) logger.info("PanOS vFirewall VM UUID: {0}".format(vfw_uuid)) logger.info("Loading the IP of the PanOS vFirewall VM") vfw_ip = self._try_get_ip(self.pv_service, si, vfw_uuid, vcenter_resource, logger) if vfw_ip: session.UpdateResourceAddress(context.resource.name, vfw_ip) else: raise Exception( "Determination of PanOS vFirewall IP address failed." "Please, verify that VM is up and running") vm = self.pv_service.get_vm_by_uuid(si, vfw_uuid) phys_interfaces = [] for device in vm.config.hardware.device: if isinstance(device, vim.vm.device.VirtualEthernetCard): phys_interfaces.append(device) resources = [] attributes = [] for port_number, phys_interface in enumerate(phys_interfaces): if port_number == 0: # First interface (port number 0) should be Management continue network_adapter_number = phys_interface.deviceInfo.label.lower( ).strip("network adapter ") unique_id = hash(phys_interface.macAddress) relative_address = "P{}".format(port_number) resources.append( AutoLoadResource(model="{}.{}".format( self.SHELL_NAME, self.PORT_MODEL), name="Port {}".format(port_number), relative_address=relative_address, unique_identifier=unique_id)) attributes.append( AutoLoadAttribute( attribute_name="{}.{}.MAC Address".format( self.SHELL_NAME, self.PORT_MODEL), attribute_value=phys_interface.macAddress, relative_address=relative_address)) attributes.append( AutoLoadAttribute( attribute_name="{}.{}.Requested vNIC Name".format( self.SHELL_NAME, self.PORT_MODEL), attribute_value=network_adapter_number, relative_address=relative_address)) attributes.append( AutoLoadAttribute( attribute_name="{}.{}.Logical Name".format( self.SHELL_NAME, self.PORT_MODEL), attribute_value="Interface {}".format(port_number), relative_address=relative_address)) attributes.append( AutoLoadAttribute("", "VmDetails", self._get_vm_details(vfw_uuid, vcenter_name))) autoload_details = AutoLoadDetails(resources=resources, attributes=attributes) except Exception: logger.exception("Get inventory command failed") raise finally: if si: self.pv_service.disconnect(si) return autoload_details def _try_get_ip(self, pv_service, si, uuid, vcenter_resource, logger): ip = None try: vm = pv_service.get_vm_by_uuid(si, uuid) ip_res = self.ip_manager.get_ip( vm, vcenter_resource.holding_network, self.ip_manager.get_ip_match_function(None), cancellation_context=None, timeout=None, logger=logger) if ip_res.ip_address: ip = ip_res.ip_address except Exception: logger.debug("Error while trying to load VM({0}) IP".format(uuid), exc_info=True) return ip @staticmethod def _get_vm_details(uuid, vcenter_name): vm_details = ApiVmDetails() vm_details.UID = uuid vm_details.CloudProviderName = vcenter_name vm_details.CloudProviderFullName = vcenter_name vm_details.VmCustomParams = [] str_vm_details = jsonpickle.encode(vm_details, unpicklable=False) return str_vm_details def _get_connection_to_vcenter(self, pv_service, session, vcenter_resource, address): password = self._decrypt_password(session, vcenter_resource.password) si = pv_service.connect(address, vcenter_resource.user, password, VCENTER_CONNECTION_PORT) return si @staticmethod def _decrypt_password(session, password): return session.DecryptPassword(password).Value def health_check(self, context): """Checks if the device is up and connectable :param ResourceCommandContext context: ResourceCommandContext object with all Resource Attributes inside :return: Success or fail message :rtype: str """ logger = get_logger_with_thread_id(context) api = get_api(context) logger.info("CONTEXT: {}".format(context)) logger.info("SHELL_NAME: {}".format(self.SHELL_NAME)) logger.info("SUPPORTED_OS: {}".format(self.SUPPORTED_OS)) resource_config = create_firewall_resource_from_context( shell_name=self.SHELL_NAME, supported_os=self.SUPPORTED_OS, context=context) logger.info("RESOURCE_CONFIG: {}".format(resource_config.__dict__)) cli_handler = CliHandler(self._cli, resource_config, logger, api) state_operations = StateRunner(logger, api, resource_config, cli_handler) return state_operations.health_check() def run_custom_command(self, context, custom_command): """Send custom command :param ResourceCommandContext context: ResourceCommandContext object with all Resource Attributes inside :return: result :rtype: str """ logger = get_logger_with_thread_id(context) api = get_api(context) resource_config = create_firewall_resource_from_context( shell_name=self.SHELL_NAME, supported_os=self.SUPPORTED_OS, context=context) cli_handler = CliHandler(self._cli, resource_config, logger, api) send_command_operations = RunCommandRunner(logger=logger, cli_handler=cli_handler) response = send_command_operations.run_custom_command( parse_custom_commands(command=custom_command)) return response def run_custom_config_command(self, context, custom_command): """Send custom command in configuration mode :param ResourceCommandContext context: ResourceCommandContext object with all Resource Attributes inside :return: result :rtype: str """ logger = get_logger_with_thread_id(context) api = get_api(context) resource_config = create_firewall_resource_from_context( shell_name=self.SHELL_NAME, supported_os=self.SUPPORTED_OS, context=context) cli_handler = CliHandler(self._cli, resource_config, logger, api) send_command_operations = RunCommandRunner(logger=logger, cli_handler=cli_handler) result_str = send_command_operations.run_custom_config_command( parse_custom_commands(command=custom_command)) return result_str @GlobalLock.lock def save(self, context, folder_path, configuration_type): """Save a configuration file to the provided destination :param ResourceCommandContext context: The context object for the command with resource and reservation info :param str folder_path: The path to the folder in which the configuration file will be saved :param str configuration_type: startup or running config :return The configuration file name :rtype: str """ logger = get_logger_with_thread_id(context) api = get_api(context) resource_config = create_firewall_resource_from_context( self.SHELL_NAME, self.SUPPORTED_OS, context) cli_handler = CliHandler(self._cli, resource_config, logger, api) configuration_type = configuration_type or 'running' configuration_operations = ConfigurationRunner(logger, resource_config, api, cli_handler) logger.info('Save started') response = configuration_operations.save(folder_path, configuration_type) logger.info('Save completed') return response @GlobalLock.lock def restore(self, context, path, configuration_type, restore_method): """Restores a configuration file :param ResourceCommandContext context: The context object for the command with resource and reservation info :param str path: The path to the configuration file, including the configuration file name :param str restore_method: Determines whether the restore should append or override the current configuration :param str configuration_type: Specify whether the file should update the startup or running config """ logger = get_logger_with_thread_id(context) api = get_api(context) resource_config = create_firewall_resource_from_context( self.SHELL_NAME, self.SUPPORTED_OS, context) cli_handler = CliHandler(self._cli, resource_config, logger, api) configuration_type = configuration_type or 'running' restore_method = restore_method or 'override' configuration_operations = ConfigurationRunner(logger, resource_config, api, cli_handler) logger.info('Restore started') configuration_operations.restore(path, configuration_type, restore_method) logger.info('Restore completed') def orchestration_save(self, context, mode, custom_params): """Saves the Shell state and returns a description of the saved artifacts and information This command is intended for API use only by sandbox orchestration scripts to implement a save and restore workflow :param ResourceCommandContext context: the context object containing resource and reservation info :param str mode: Snapshot save mode, can be one of two values 'shallow' (default) or 'deep' :param str custom_params: Set of custom parameters for the save operation :return: SavedResults serialized as JSON :rtype: OrchestrationSaveResult """ logger = get_logger_with_thread_id(context) api = get_api(context) resource_config = create_firewall_resource_from_context( self.SHELL_NAME, self.SUPPORTED_OS, context) cli_handler = CliHandler(self._cli, resource_config, logger, api) configuration_operations = ConfigurationRunner(logger, resource_config, api, cli_handler) logger.info('Orchestration save started') response = configuration_operations.orchestration_save( mode, custom_params) logger.info('Orchestration save completed') return response def orchestration_restore(self, context, saved_artifact_info, custom_params): """Restores a saved artifact previously saved by this Shell driver using the orchestration_save function :param ResourceCommandContext context: The context object for the command with resource and reservation info :param str saved_artifact_info: A JSON string representing the state to restore including saved artifacts and info :param str custom_params: Set of custom parameters for the restore operation """ logger = get_logger_with_thread_id(context) api = get_api(context) resource_config = create_firewall_resource_from_context( self.SHELL_NAME, self.SUPPORTED_OS, context) cli_handler = CliHandler(self._cli, resource_config, logger, api) configuration_operations = ConfigurationRunner(logger, resource_config, api, cli_handler) logger.info('Orchestration restore started') configuration_operations.orchestration_restore(saved_artifact_info, custom_params) logger.info('Orchestration restore completed') @GlobalLock.lock def load_firmware(self, context, path): """Upload and updates firmware on the resource :param ResourceCommandContext context: The context object for the command with resource and reservation info :param str path: path to tftp server where firmware file is stored """ logger = get_logger_with_thread_id(context) api = get_api(context) resource_config = create_firewall_resource_from_context( self.SHELL_NAME, self.SUPPORTED_OS, context) cli_handler = CliHandler(self._cli, resource_config, logger, api) logger.info('Start Load Firmware') firmware_operations = FirmwareRunner(logger, cli_handler) response = firmware_operations.load_firmware(path) logger.info('Finish Load Firmware: {}'.format(response)) def shutdown(self, context): """Sends a graceful shutdown to the device :param ResourceCommandContext context: The context object for the command with resource and reservation info """ logger = get_logger_with_thread_id(context) api = get_api(context) resource_config = create_firewall_resource_from_context( self.SHELL_NAME, self.SUPPORTED_OS, context) cli_handler = CliHandler(self._cli, resource_config, logger, api) state_operations = StateRunner(logger, api, resource_config, cli_handler) return state_operations.shutdown()
class CommandOrchestrator(object): def __init__(self): """ Initialize the driver session, this function is called everytime a new instance of the driver is created in here the driver is going to be bootstrapped """ synchronous_task_waiter = SynchronousTaskWaiter() cancellation_service = CommandCancellationService() pv_service = pyVmomiService(connect=SmartConnect, disconnect=Disconnect, task_waiter=synchronous_task_waiter) self.resource_model_parser = ResourceModelParser() port_group_name_generator = DvPortGroupNameGenerator() vnic_to_network_mapper = VnicToNetworkMapper( quali_name_generator=port_group_name_generator) resource_remover = CloudshellResourceRemover() ovf_service = OvfImageDeployerService(self.resource_model_parser) self.vm_loader = VMLoader(pv_service) ip_manager = VMIPManager() vm_details_provider = VmDetailsProvider(pyvmomi_service=pv_service, ip_manager=ip_manager) vm_deployer = VirtualMachineDeployer( pv_service=pv_service, name_generator=generate_unique_name, ovf_service=ovf_service, resource_model_parser=self.resource_model_parser, vm_details_provider=vm_details_provider) dv_port_group_creator = DvPortGroupCreator( pyvmomi_service=pv_service, synchronous_task_waiter=synchronous_task_waiter) virtual_machine_port_group_configurer = \ VirtualMachinePortGroupConfigurer(pyvmomi_service=pv_service, synchronous_task_waiter=synchronous_task_waiter, vnic_to_network_mapper=vnic_to_network_mapper, vnic_service=VNicService(), name_gen=port_group_name_generator) virtual_switch_to_machine_connector = VirtualSwitchToMachineConnector( dv_port_group_creator, virtual_machine_port_group_configurer) # Command Wrapper self.command_wrapper = CommandWrapper( pv_service=pv_service, resource_model_parser=self.resource_model_parser, context_based_logger_factory=ContextBasedLoggerFactory()) # Deploy Command self.deploy_command = DeployCommand(deployer=vm_deployer) # Virtual Switch Revoke self.virtual_switch_disconnect_command = \ VirtualSwitchToMachineDisconnectCommand( pyvmomi_service=pv_service, port_group_configurer=virtual_machine_port_group_configurer, resource_model_parser=self.resource_model_parser) # Virtual Switch Connect virtual_switch_connect_command = \ VirtualSwitchConnectCommand( pv_service=pv_service, virtual_switch_to_machine_connector=virtual_switch_to_machine_connector, dv_port_group_name_generator=DvPortGroupNameGenerator(), vlan_spec_factory=VlanSpecFactory(), vlan_id_range_parser=VLanIdRangeParser()) self.connection_orchestrator = ConnectionCommandOrchestrator( connector=virtual_switch_connect_command, disconnector=self.virtual_switch_disconnect_command, resource_model_parser=self.resource_model_parser) self.folder_manager = FolderManager( pv_service=pv_service, task_waiter=synchronous_task_waiter) # Destroy VM Command self.destroy_virtual_machine_command = \ DestroyVirtualMachineCommand(pv_service=pv_service, resource_remover=resource_remover, disconnector=self.virtual_switch_disconnect_command) # Power Command self.vm_power_management_command = \ VirtualMachinePowerManagementCommand(pyvmomi_service=pv_service, synchronous_task_waiter=synchronous_task_waiter) # Refresh IP command self.refresh_ip_command = RefreshIpCommand( pyvmomi_service=pv_service, resource_model_parser=self.resource_model_parser, ip_manager=ip_manager) # Get Vm Details command self.vm_details = VmDetailsCommand( pyvmomi_service=pv_service, vm_details_provider=vm_details_provider) # Save Snapshot self.snapshot_saver = SaveSnapshotCommand( pyvmomi_service=pv_service, task_waiter=synchronous_task_waiter) # Snapshot Restorer self.snapshot_restorer = SnapshotRestoreCommand( pyvmomi_service=pv_service, task_waiter=synchronous_task_waiter) self.snapshots_retriever = RetrieveSnapshotsCommand( pyvmomi_service=pv_service) self.save_app_command = SaveAppCommand( pyvmomi_service=pv_service, task_waiter=synchronous_task_waiter, deployer=vm_deployer, resource_model_parser=self.resource_model_parser, snapshot_saver=self.snapshot_saver, folder_manager=self.folder_manager, cancellation_service=cancellation_service, port_group_configurer=virtual_machine_port_group_configurer) self.delete_saved_sandbox_command = DeleteSavedSandboxCommand( pyvmomi_service=pv_service, task_waiter=synchronous_task_waiter, deployer=vm_deployer, resource_model_parser=self.resource_model_parser, snapshot_saver=self.snapshot_saver, folder_manager=self.folder_manager, cancellation_service=cancellation_service, port_group_configurer=virtual_machine_port_group_configurer) def connect_bulk(self, context, request): results = self.command_wrapper.execute_command_with_connection( context, self.connection_orchestrator.connect_bulk, request) driver_response = DriverResponse() driver_response.actionResults = results driver_response_root = DriverResponseRoot() driver_response_root.driverResponse = driver_response return set_command_result(result=driver_response_root, unpicklable=False) def save_sandbox(self, context, save_actions, cancellation_context): """ Save sandbox command, persists an artifact of existing VMs, from which new vms can be restored :param ResourceCommandContext context: :param list[SaveApp] save_actions: :param CancellationContext cancellation_context: :return: list[SaveAppResult] save_app_results """ connection = self.command_wrapper.execute_command_with_connection( context, self.save_app_command.save_app, save_actions, cancellation_context, ) save_app_results = connection return save_app_results def delete_saved_sandbox(self, context, delete_saved_apps, cancellation_context): """ Delete a saved sandbox, along with any vms associated with it :param ResourceCommandContext context: :param list[DeleteSavedApp] delete_saved_apps: :param CancellationContext cancellation_context: :return: list[SaveAppResult] save_app_results """ connection = self.command_wrapper.execute_command_with_connection( context, self.delete_saved_sandbox_command.delete_sandbox, delete_saved_apps, cancellation_context) delete_saved_apps_results = connection return delete_saved_apps_results def deploy_from_template(self, context, deploy_action, cancellation_context): """ Deploy From Template Command, will deploy vm from template :param CancellationContext cancellation_context: :param ResourceCommandContext context: the context of the command :param DeployApp deploy_action: :return DeployAppResult deploy results """ deploy_from_template_model = self.resource_model_parser.convert_to_resource_model( attributes=deploy_action.actionParams.deployment.attributes, resource_model_type=vCenterVMFromTemplateResourceModel) data_holder = DeployFromTemplateDetails( deploy_from_template_model, deploy_action.actionParams.appName) deploy_result_action = self.command_wrapper.execute_command_with_connection( context, self.deploy_command.execute_deploy_from_template, data_holder, cancellation_context, self.folder_manager) deploy_result_action.actionId = deploy_action.actionId return deploy_result_action def deploy_clone_from_vm(self, context, deploy_action, cancellation_context): """ Deploy Cloned VM From VM Command, will deploy vm from template :param CancellationContext cancellation_context: :param ResourceCommandContext context: the context of the command :param DeployApp deploy_action: :return DeployAppResult deploy results """ deploy_from_vm_model = self.resource_model_parser.convert_to_resource_model( attributes=deploy_action.actionParams.deployment.attributes, resource_model_type=vCenterCloneVMFromVMResourceModel) data_holder = DeployFromTemplateDetails( deploy_from_vm_model, deploy_action.actionParams.appName) deploy_result_action = self.command_wrapper.execute_command_with_connection( context, self.deploy_command.execute_deploy_clone_from_vm, data_holder, cancellation_context, self.folder_manager) deploy_result_action.actionId = deploy_action.actionId return deploy_result_action def deploy_from_linked_clone(self, context, deploy_action, cancellation_context): """ Deploy Cloned VM From VM Command, will deploy vm from template :param CancellationContext cancellation_context: :param ResourceCommandContext context: the context of the command :param DeployApp deploy_action: :return DeployAppResult deploy results """ linked_clone_from_vm_model = self.resource_model_parser.convert_to_resource_model( attributes=deploy_action.actionParams.deployment.attributes, resource_model_type=VCenterDeployVMFromLinkedCloneResourceModel) data_holder = DeployFromTemplateDetails( linked_clone_from_vm_model, deploy_action.actionParams.appName) if not linked_clone_from_vm_model.vcenter_vm_snapshot: raise ValueError( 'Please insert snapshot to deploy an app from a linked clone') deploy_result_action = self.command_wrapper.execute_command_with_connection( context, self.deploy_command.execute_deploy_from_linked_clone, data_holder, cancellation_context, self.folder_manager) deploy_result_action.actionId = deploy_action.actionId return deploy_result_action def deploy_from_image(self, context, deploy_action, cancellation_context): """ Deploy From Image Command, will deploy vm from ovf image :param CancellationContext cancellation_context: :param ResourceCommandContext context: the context of the command :param DeployApp deploy_action: :return str deploy results """ deploy_action.actionParams.deployment.attributes[ 'vCenter Name'] = context.resource.name deploy_from_image_model = self.resource_model_parser.convert_to_resource_model( attributes=deploy_action.actionParams.deployment.attributes, resource_model_type=vCenterVMFromImageResourceModel) data_holder = DeployFromImageDetails( deploy_from_image_model, deploy_action.actionParams.appName) # execute command deploy_result_action = self.command_wrapper.execute_command_with_connection( context, self.deploy_command.execute_deploy_from_image, data_holder, context.resource, cancellation_context, self.folder_manager) deploy_result_action.actionId = deploy_action.actionId return deploy_result_action # remote command def disconnect_all(self, context, ports): """ Disconnect All Command, will the assign all the vnics on the vm to the default network, which is sign to be disconnected :param models.QualiDriverModels.ResourceRemoteCommandContext context: the context the command runs on :param list[string] ports: the ports of the connection between the remote resource and the local resource, NOT IN USE!!! """ resource_details = self._parse_remote_model(context) # execute command res = self.command_wrapper.execute_command_with_connection( context, self.virtual_switch_disconnect_command.disconnect_all, resource_details.vm_uuid) return set_command_result(result=res, unpicklable=False) # remote command def disconnect(self, context, ports, network_name): """ Disconnect Command, will disconnect the a specific network that is assign to the vm, the command will assign the default network for all the vnics that is assigned to the given network :param models.QualiDriverModels.ResourceRemoteCommandContext context: the context the command runs on :param str network_name: the name of the network to disconnect from :param list[string] ports: the ports of the connection between the remote resource and the local resource, NOT IN USE!!! """ resource_details = self._parse_remote_model(context) # execute command res = self.command_wrapper.execute_command_with_connection( context, self.virtual_switch_disconnect_command.disconnect, resource_details.vm_uuid, network_name) return set_command_result(result=res, unpicklable=False) # remote command def DeleteInstance(self, context, ports): """ Destroy Vm Command, will only destroy the vm and will not remove the resource :param models.QualiDriverModels.ResourceRemoteCommandContext context: the context the command runs on :param list[string] ports: the ports of the connection between the remote resource and the local resource, NOT IN USE!!! """ resource_details = self._parse_remote_model(context) # execute command res = self.command_wrapper.execute_command_with_connection( context, self.destroy_virtual_machine_command.DeleteInstance, resource_details.vm_uuid, resource_details.fullname) return set_command_result(result=res, unpicklable=False) # remote command def refresh_ip(self, context, cancellation_context, ports): """ Refresh IP Command, will refresh the ip of the vm and will update it on the resource :param ResourceRemoteCommandContext context: the context the command runs on :param cancellation_context: :param list[string] ports: the ports of the connection between the remote resource and the local resource, NOT IN USE!!! """ resource_details = self._parse_remote_model(context) # execute command res = self.command_wrapper.execute_command_with_connection( context, self.refresh_ip_command.refresh_ip, resource_details, cancellation_context, context.remote_endpoints[0].app_context.app_request_json) return set_command_result(result=res, unpicklable=False) # remote command def power_off(self, context, ports): """ Powers off the remote vm :param models.QualiDriverModels.ResourceRemoteCommandContext context: the context the command runs on :param list[string] ports: the ports of the connection between the remote resource and the local resource, NOT IN USE!!! """ return self._power_command(context, ports, self.vm_power_management_command.power_off) # remote command def power_on(self, context, ports): """ Powers on the remote vm :param models.QualiDriverModels.ResourceRemoteCommandContext context: the context the command runs on :param list[string] ports: the ports of the connection between the remote resource and the local resource, NOT IN USE!!! """ return self._power_command(context, ports, self.vm_power_management_command.power_on) # remote command def power_cycle(self, context, ports, delay): """ preforms a restart to the vm :param models.QualiDriverModels.ResourceRemoteCommandContext context: the context the command runs on :param list[string] ports: the ports of the connection between the remote resource and the local resource, NOT IN USE!!! :param number delay: the time to wait between the power on and off """ self.power_off(context, ports) time.sleep(float(delay)) return self.power_on(context, ports) def _power_command(self, context, ports, command): resource_details = self._parse_remote_model(context) # execute command res = self.command_wrapper.execute_command_with_connection( context, command, resource_details.vm_uuid, resource_details.fullname) return set_command_result(result=res, unpicklable=False) def _parse_remote_model(self, context): """ parse the remote resource model and adds its full name :type context: models.QualiDriverModels.ResourceRemoteCommandContext """ if not context.remote_endpoints: raise Exception('no remote resources found in context: {0}', jsonpickle.encode(context, unpicklable=False)) resource = context.remote_endpoints[0] dictionary = jsonpickle.decode(resource.app_context.deployed_app_json) holder = DeployDataHolder(dictionary) app_resource_detail = GenericDeployedAppResourceModel() app_resource_detail.vm_uuid = holder.vmdetails.uid app_resource_detail.cloud_provider = context.resource.fullname app_resource_detail.fullname = resource.fullname if hasattr(holder.vmdetails, 'vmCustomParams'): app_resource_detail.vm_custom_params = holder.vmdetails.vmCustomParams return app_resource_detail def power_on_not_roemote(self, context, vm_uuid, resource_fullname): # get connection details res = self.command_wrapper.execute_command_with_connection( context, self.vm_power_management_command.power_on, vm_uuid, resource_fullname) return set_command_result(result=res, unpicklable=False) def get_vm_uuid_by_name(self, context, vm_name): res = self.command_wrapper.execute_command_with_connection( context, self.vm_loader.load_vm_uuid_by_name, vm_name) return set_command_result(result=res, unpicklable=False) def get_vm_details(self, context, cancellation_context, requests_json): requests = DeployDataHolder(jsonpickle.decode(requests_json)).items res = self.command_wrapper.execute_command_with_connection( context, self.vm_details.get_vm_details, context.resource, requests, cancellation_context) return set_command_result(result=res, unpicklable=False) def save_snapshot(self, context, snapshot_name, save_memory='No'): """ Saves virtual machine to a snapshot :param context: resource context of the vCenterShell :type context: models.QualiDriverModels.ResourceCommandContext :param snapshot_name: snapshot name to save to :type snapshot_name: str :param save_memory: Snapshot the virtual machine's memory. Lookup, Yes / No :type save_memory: str :return: """ resource_details = self._parse_remote_model(context) created_snapshot_path = self.command_wrapper.execute_command_with_connection( context, self.snapshot_saver.save_snapshot, resource_details.vm_uuid, snapshot_name, save_memory) return set_command_result(created_snapshot_path) def restore_snapshot(self, context, snapshot_name): """ Restores virtual machine from a snapshot :param context: resource context of the vCenterShell :type context: models.QualiDriverModels.ResourceCommandContext :param snapshot_name: snapshot name to save to :type snapshot_name: str :return: """ resource_details = self._parse_remote_model(context) self.command_wrapper.execute_command_with_connection( context, self.snapshot_restorer.restore_snapshot, resource_details.vm_uuid, resource_details.fullname, snapshot_name) def get_snapshots(self, context): """ Returns list of snapshots :param context: resource context of the vCenterShell :type context: models.QualiDriverModels.ResourceCommandContext :return: """ resource_details = self._parse_remote_model(context) res = self.command_wrapper.execute_command_with_connection( context, self.snapshots_retriever.get_snapshots, resource_details.vm_uuid) return set_command_result(result=res, unpicklable=False) def orchestration_save(self, context, mode="shallow", custom_params=None): """ Creates a snapshot with a unique name and returns SavedResults as JSON :param context: resource context of the vCenterShell :param mode: Snapshot save mode, default shallow. Currently not it use :param custom_params: Set of custom parameter to be supported in the future :return: SavedResults serialized as JSON :rtype: SavedResults """ resource_details = self._parse_remote_model(context) created_date = datetime.now() snapshot_name = created_date.strftime('%y_%m_%d %H_%M_%S_%f') created_snapshot_path = self.save_snapshot(context=context, snapshot_name=snapshot_name) created_snapshot_path = self._strip_double_quotes( created_snapshot_path) orchestration_saved_artifact = OrchestrationSavedArtifact() orchestration_saved_artifact.artifact_type = 'vcenter_snapshot' orchestration_saved_artifact.identifier = created_snapshot_path saved_artifacts_info = OrchestrationSavedArtifactsInfo( resource_name=resource_details.cloud_provider, created_date=created_date, restore_rules={'requires_same_resource': True}, saved_artifact=orchestration_saved_artifact) orchestration_save_result = OrchestrationSaveResult( saved_artifacts_info) return set_command_result(result=orchestration_save_result, unpicklable=False) @staticmethod def _strip_double_quotes(created_snapshot_path): if created_snapshot_path.startswith( '"') and created_snapshot_path.endswith('"'): created_snapshot_path = created_snapshot_path[1:-1] return created_snapshot_path def orchestration_restore(self, context, saved_details): """ :param context: :param saved_details: :return: """ saved_artifacts_info = get_result_from_command_output(saved_details) snapshot_name = saved_artifacts_info['saved_artifacts_info'][ 'saved_artifact']['identifier'] return self.restore_snapshot(context=context, snapshot_name=snapshot_name)
def __init__(self): self.parser = ResourceModelParser() self.pv_service = pyVmomiService(SmartConnect, Disconnect, SynchronousTaskWaiter()) self.context_based_logger_factory = ContextBasedLoggerFactory()
def get_attribute_name_from_attribute_node(self, attribute_node): return ResourceModelParser.get_property_name_from_attribute_name( attribute_node.attrib['Name'])
class DeployAppOrchestrationDriver(object): def __init__(self): self.model_parser = ResourceModelParser() self.ip_manager = VMIPManager() self.task_waiter = SynchronousTaskWaiter() self.logger = get_qs_logger('VM AutoLoad') self.pv_service = pyVmomiService(SmartConnect, Disconnect, self.task_waiter) def get_inventory(self, context): """ Will locate vm in vcenter and fill its uuid :type context: cloudshell.shell.core.context.ResourceCommandContext """ vcenter_vm_name = context.resource.attributes['vCenter VM'] vcenter_vm_name = vcenter_vm_name.replace('\\', '/') vcenter_name = context.resource.attributes['vCenter Name'] self.logger.info('start autoloading vm_path: {0} on vcenter: {1}'.format(vcenter_vm_name, vcenter_name)) with CloudShellSessionContext(context) as cloudshell_session: session = cloudshell_session vcenter_api_res = session.GetResourceDetails(vcenter_name) vcenter_resource = self.model_parser.convert_to_vcenter_model(vcenter_api_res) si = None try: self.logger.info('connecting to vcenter ({0})'.format(vcenter_api_res.Address)) si = self._get_connection_to_vcenter(self.pv_service, session, vcenter_resource, vcenter_api_res.Address) self.logger.info('loading vm uuid') vm_loader = VMLoader(self.pv_service) uuid = vm_loader.load_vm_uuid_by_name(si, vcenter_resource, vcenter_vm_name) self.logger.info('vm uuid: {0}'.format(uuid)) self.logger.info('loading the ip of the vm') ip = self._try_get_ip(self.pv_service, si, uuid, vcenter_resource) if ip: session.UpdateResourceAddress(context.resource.name, ip) except Exception: self.logger.exception("Get inventory command failed") raise finally: if si: self.pv_service.disconnect(si) return self._get_auto_load_response(uuid, vcenter_name, context.resource) def _get_auto_load_response(self, uuid, vcenter_name, resource): vm_details = self._get_vm_details(uuid, vcenter_name, resource) # return vm_details autoload_atts = [AutoLoadAttribute('', 'VmDetails', vm_details)] return AutoLoadDetails([], autoload_atts) def _try_get_ip(self, pv_service, si, uuid, vcenter_resource): ip = None try: vm = pv_service.get_vm_by_uuid(si, uuid) ip_res = self.ip_manager.get_ip(vm, vcenter_resource.holding_network, self.ip_manager.get_ip_match_function(None), cancellation_context=None, timeout=None, logger=self.logger) if ip_res.ip_address: ip = ip_res.ip_address except Exception: self.logger.debug('Error while trying to load VM({0}) IP'.format(uuid), exc_info=True) return ip @staticmethod def _get_vm_details(uuid, vcenter_name, resource): vm_details = ApiVmDetails() vm_details.UID = uuid vm_details.CloudProviderName = vcenter_name vm_details.VmCustomParams = [] str_vm_details = jsonpickle.encode(vm_details, unpicklable=False) return str_vm_details def _get_connection_to_vcenter(self, pv_service, session, vcenter_resource, address): password = self._decrypt_password(session, vcenter_resource.password) si = pv_service.connect(address, vcenter_resource.user, password, 443) return si @staticmethod def _decrypt_password(session, password): return session.DecryptPassword(password).Value
def __init__(self): self.model_parser = ResourceModelParser() self.ip_manager = VMIPManager() self.task_waiter = SynchronousTaskWaiter() self.logger = get_qs_logger('VM AutoLoad') self.pv_service = pyVmomiService(SmartConnect, Disconnect, self.task_waiter)
def test_parse_resource_info_model_class_does_not_exist(self): resource_model_parser = ResourceModelParser() self.assertRaises(ValueError, resource_model_parser.convert_to_resource_model, {}, None)
class BreakingPointVBladeShellDriver(ResourceDriverInterface): SHELL_NAME = "BP vBlade" PORT_MODEL = "GenericVPort" DOMAIN = "Global" IP_KEY = "ipAddress" ID_KEY = "id" def __init__(self): # self.cs_helper = CloudshellDriverHelper() self.model_parser = ResourceModelParser() self.ip_manager = VMIPManager() self.task_waiter = SynchronousTaskWaiter() self.pv_service = pyVmomiService(SmartConnect, Disconnect, self.task_waiter) def initialize(self, context): """ Initialize the driver session, this function is called everytime a new instance of the driver is created This is a good place to load and cache the driver configuration, initiate sessions etc. :param InitCommandContext context: the context the command runs on """ pass def cleanup(self): """ Destroy the driver session, this function is called everytime a driver instance is destroyed This is a good place to close any open sessions, finish writing to log files """ pass def get_inventory(self, context): """ Will locate vm in vcenter and fill its uuid :type context: cloudshell.shell.core.context.ResourceCommandContext """ logger = get_logger_with_thread_id(context) logger.info("Start Autoload process") # session = self.cs_helper.get_session(context.connectivity.server_address, # context.connectivity.admin_auth_token, # self.DOMAIN) session = CloudShellAPISession( host=context.connectivity.server_address, token_id=context.connectivity.admin_auth_token, domain=self.DOMAIN) vcenter_vblade = context.resource.attributes[ "{}.vBlade vCenter VM".format(self.SHELL_NAME)].replace("\\", "/") vcenter_vchassis = context.resource.attributes[ "{}.vChassis vCenter VM".format(self.SHELL_NAME)].replace( "\\", "/") username = context.resource.attributes["{}.User".format( self.SHELL_NAME)] password = self._decrypt_password( session, context.resource.attributes["{}.Password".format(self.SHELL_NAME)]) vcenter_name = context.resource.attributes["{}.vCenter Name".format( self.SHELL_NAME)] logger.info("Start AutoLoading VM_Path: {0} on vCenter: {1}".format( vcenter_vblade, vcenter_name)) vcenter_api_res = session.GetResourceDetails(vcenter_name) vcenter_resource = self.model_parser.convert_to_vcenter_model( vcenter_api_res) si = None try: logger.info("Connecting to vCenter ({0})".format( vcenter_api_res.Address)) si = self._get_connection_to_vcenter(self.pv_service, session, vcenter_resource, vcenter_api_res.Address) logger.info("Loading VMs UUID") vm_loader = VMLoader(self.pv_service) vchassis_uuid = vm_loader.load_vm_uuid_by_name( si, vcenter_resource, vcenter_vchassis) logger.info("vChassis VM UUID: {0}".format(vchassis_uuid)) logger.info("Loading the IP of the vChassis VM") vchassis_ip = self._try_get_ip(self.pv_service, si, vchassis_uuid, vcenter_resource, logger) if vchassis_ip: bp_api = BP_API(ip=vchassis_ip, username=username, password=password, logger=logger) bp_api.login() modules_position = { module[self.IP_KEY]: module[self.ID_KEY] for module in bp_api.get_modules() if module[self.IP_KEY] } bp_api.logout() logger.debug("Modules position: {}".format(modules_position)) else: raise Exception( "Determination of vChassis IP address failed. Please, verify that VM is up and running" ) vblade_uuid = vm_loader.load_vm_uuid_by_name( si, vcenter_resource, vcenter_vblade) logger.info("vBlade VM UUID: {0}".format(vblade_uuid)) logger.info("Loading the IP of the vBlade VM") vblade_ip = self._try_get_ip(self.pv_service, si, vblade_uuid, vcenter_resource, logger) if vblade_ip: module_id = modules_position.get(vblade_ip) if module_id is None: raise Exception( "Provided vBlade IP incorrect or vBlade isn't connect to vChassis" ) session.UpdateResourceAddress( context.resource.name, "{blade_ip}\{chassis_ip}\M{module_id}".format( blade_ip=vblade_ip, chassis_ip=vchassis_ip, module_id=module_id)) else: raise Exception( "Determination of vBlade IP address failed. Please, verify that VM is up and running" ) vm = self.pv_service.get_vm_by_uuid(si, vblade_uuid) phys_interfaces = [] for device in vm.config.hardware.device: if isinstance(device, vim.vm.device.VirtualEthernetCard): phys_interfaces.append(device) resources = [] attributes = [] for port_number, phys_interface in enumerate(phys_interfaces): if port_number == 0: # First interface (port number 0) should be Management continue network_adapter_number = phys_interface.deviceInfo.label.lower( ).strip("network adapter ") unique_id = hash(phys_interface.macAddress) relative_address = "P{}".format(port_number) resources.append( AutoLoadResource(model="{}.{}".format( self.SHELL_NAME, self.PORT_MODEL), name="Port {}".format(port_number), relative_address=relative_address, unique_identifier=unique_id)) attributes.append( AutoLoadAttribute( attribute_name="{}.{}.MAC Address".format( self.SHELL_NAME, self.PORT_MODEL), attribute_value=phys_interface.macAddress, relative_address=relative_address)) attributes.append( AutoLoadAttribute( attribute_name="{}.{}.Requested vNIC Name".format( self.SHELL_NAME, self.PORT_MODEL), attribute_value=network_adapter_number, relative_address=relative_address)) attributes.append( AutoLoadAttribute( attribute_name="{}.{}.Logical Name".format( self.SHELL_NAME, self.PORT_MODEL), attribute_value="Interface {}".format(port_number), relative_address=relative_address)) attributes.append( AutoLoadAttribute( "", "VmDetails", self._get_vm_details(vblade_uuid, vcenter_name))) autoload_details = AutoLoadDetails(resources=resources, attributes=attributes) except Exception: logger.exception("Get inventory command failed") raise finally: if si: self.pv_service.disconnect(si) return autoload_details def _try_get_ip(self, pv_service, si, uuid, vcenter_resource, logger): ip = None try: vm = pv_service.get_vm_by_uuid(si, uuid) ip_res = self.ip_manager.get_ip( vm, vcenter_resource.holding_network, self.ip_manager.get_ip_match_function(None), cancellation_context=None, timeout=None, logger=logger) if ip_res.ip_address: ip = ip_res.ip_address except Exception: logger.debug("Error while trying to load VM({0}) IP".format(uuid), exc_info=True) return ip @staticmethod def _get_vm_details(uuid, vcenter_name): vm_details = ApiVmDetails() vm_details.UID = uuid vm_details.CloudProviderName = vcenter_name vm_details.CloudProviderFullName = vcenter_name vm_details.VmCustomParams = [] str_vm_details = jsonpickle.encode(vm_details, unpicklable=False) return str_vm_details def _get_connection_to_vcenter(self, pv_service, session, vcenter_resource, address): password = self._decrypt_password(session, vcenter_resource.password) si = pv_service.connect(address, vcenter_resource.user, password, VCENTER_CONNECTION_PORT) return si @staticmethod def _decrypt_password(session, password): return session.DecryptPassword(password).Value