コード例 #1
0
class TestDriverHelper(TestCase):
    def setUp(self):
        self.helper = CloudshellDriverHelper()
        self.helper.cloudshell_data_retriever_service = Mock()
        self.helper.cloudshell_data_retriever_service.getVCenterConnectionDetails = Mock(
            return_value=True)
        self.helper.session_class = Mock()
        self.context = Mock()
        self.context.connectivity = Mock()
        self.context.connectivity.serverAddress = 'host'
        self.context.connectivity.adminAuthToken = 'token'
        self.context.reservation = Mock()
        self.context.reservation.domain = 'domain'

    def test_get_session(self):
        self.helper.get_session(self.context.connectivity.serverAddress,
                                self.context.connectivity.adminAuthToken,
                                self.context.reservation.domain)
        self.assertTrue(
            self.helper.session_class.called_with(
                self.context.connectivity.serverAddress,
                self.context.connectivity.adminAuthToken, 'admin', 'admin',
                self.context.reservation.domain))

    def test_get_connection_details(self):
        session = Mock()
        vcenter_data_model = Mock()
        res = self.helper.get_connection_details(session, vcenter_data_model,
                                                 self.context)
        self.assertTrue(res)
コード例 #2
0
class TestDriverHelper(TestCase):
    def setUp(self):
        self.helper = CloudshellDriverHelper()
        self.helper.cloudshell_data_retriever_service = Mock()
        self.helper.cloudshell_data_retriever_service.getVCenterConnectionDetails = Mock(return_value=True)
        self.helper.session_class = Mock()
        self.context = Mock()
        self.context.connectivity = Mock()
        self.context.connectivity.serverAddress = "host"
        self.context.connectivity.adminAuthToken = "token"
        self.context.reservation = Mock()
        self.context.reservation.domain = "domain"

    def test_get_session(self):
        self.helper.get_session(
            self.context.connectivity.serverAddress,
            self.context.connectivity.adminAuthToken,
            self.context.reservation.domain,
        )
        self.assertTrue(
            self.helper.session_class.called_with(
                self.context.connectivity.serverAddress,
                self.context.connectivity.adminAuthToken,
                "admin",
                "admin",
                self.context.reservation.domain,
            )
        )

    def test_get_connection_details(self):
        session = Mock()
        vcenter_data_model = Mock()
        res = self.helper.get_connection_details(session, vcenter_data_model, self.context)
        self.assertTrue(res)
コード例 #3
0
 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)
コード例 #4
0
 def setUp(self):
     self.helper = CloudshellDriverHelper()
     self.helper.cloudshell_data_retriever_service = Mock()
     self.helper.cloudshell_data_retriever_service.getVCenterConnectionDetails = Mock(
         return_value=True)
     self.helper.session_class = Mock()
     self.context = Mock()
     self.context.connectivity = Mock()
     self.context.connectivity.serverAddress = 'host'
     self.context.connectivity.adminAuthToken = 'token'
     self.context.reservation = Mock()
     self.context.reservation.domain = 'domain'
コード例 #5
0
 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)
コード例 #6
0
ファイル: driver.py プロジェクト: kalsky/vCenterShell
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))
        ]
コード例 #7
0
 def setUp(self):
     self.helper = CloudshellDriverHelper()
     self.helper.cloudshell_data_retriever_service = Mock()
     self.helper.cloudshell_data_retriever_service.getVCenterConnectionDetails = Mock(return_value=True)
     self.helper.session_class = Mock()
     self.context = Mock()
     self.context.connectivity = Mock()
     self.context.connectivity.serverAddress = "host"
     self.context.connectivity.adminAuthToken = "token"
     self.context.reservation = Mock()
     self.context.reservation.domain = "domain"
コード例 #8
0
ファイル: driver.py プロジェクト: QualiSystems/vCenterShell
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))]
コード例 #9
0
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
コード例 #10
0
ファイル: driver.py プロジェクト: QualiSystems/vCenterShell
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
コード例 #11
0
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
コード例 #12
0
    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)
コード例 #13
0
ファイル: driver.py プロジェクト: QualiSystems/vCenterShell
 def __init__(self):
     self.resource_model_parser = ResourceModelParser()
     self.cs_helper = CloudshellDriverHelper()
コード例 #14
0
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)

        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
コード例 #15
0
 def __init__(self):
     self.parser = ResourceModelParser()
     self.pv_service = pyVmomiService(SmartConnect, Disconnect, SynchronousTaskWaiter())
     self.cs_helper = CloudshellDriverHelper()
     self.context_based_logger_factory = ContextBasedLoggerFactory()
コード例 #16
0
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()
コード例 #17
0
class VCenterAutoModelDiscovery(object):
    def __init__(self):
        self.parser = ResourceModelParser()
        self.pv_service = pyVmomiService(SmartConnect, Disconnect)
        self.cs_helper = CloudshellDriverHelper()
        self.context_based_logger_factory = ContextBasedLoggerFactory()

    def validate_and_discover(self, context):
        """
        :type context: models.QualiDriverModels.AutoLoadCommandContext
        """
        logger = self.context_based_logger_factory.create_logger_for_context(
            logger_name='vCenterShell',
            context=context)

        logger.info('Autodiscovery started')

        session = self.cs_helper.get_session(context.connectivity.server_address,
                                             context.connectivity.admin_auth_token,
                                             DOMAIN)
        self._check_if_attribute_not_empty(context.resource, ADDRESS)
        resource = context.resource
        auto_attr = []
        si = self._check_if_vcenter_user_pass_valid(context, session, resource.attributes)
        if not si:
            error_message = 'Could not connect to the vCenter: {0}, with given credentials'\
                .format(context.resource.address)
            logger.error(error_message)
            raise ValueError(error_message)
        all_dc = self.pv_service.get_all_items_in_vcenter(si, vim.Datacenter)

        dc = self._validate_datacenter(si, all_dc, auto_attr, resource.attributes)

        all_items_in_dc = self.pv_service.get_all_items_in_vcenter(si, None, dc)

        dc_name = dc.name

        for key, value in resource.attributes.items():
            if key in [USER, PASSWORD, DEFAULT_DATACENTER, VM_CLUSTER]:
                continue
            validation_method = self._get_validation_method(key)
            validation_method(si, all_items_in_dc, auto_attr, dc_name, resource.attributes, key)

        logger.info('Autodiscovery completed')

        return AutoLoadDetails([], auto_attr)

    @staticmethod
    def _get_default_from_vc_by_type_and_name(items_in_vc, vim_type, name=None):
        items = []
        if not isinstance(vim_type, collections.Iterable):
            vim_type = [vim_type]
        for item in items_in_vc:
            if item.name == name:
                return item

            item_type = type(item)
            if [t for t in vim_type if item_type is t]:
                items.append(item)

        if len(items) == 1:
            return items[0]
        if len(items) > 1:
            return 'too many options'
        return 'not found'

    def _validate_datacenter(self, si, all_item_in_vc, auto_att, attributes):
        dc = self._validate_attribute(si, attributes, vim.Datacenter, DEFAULT_DATACENTER)
        if not dc:
            dc = self._get_default(all_item_in_vc, vim.Datacenter, DEFAULT_DATACENTER)
        auto_att.append(AutoLoadAttribute('', DEFAULT_DATACENTER, dc.name))
        return dc

    def _validate_attribute(self, si, attributes, vim_type, name, prefix=''):
        if name in attributes and attributes[name]:
            att_value = attributes[name]
            if prefix:
                att_value = '{0}/{1}'.format(prefix, att_value)

            obj = self.pv_service.get_folder(si, att_value)
            if not obj or isinstance(obj, str):
                raise ValueError('Could not find {0}'.format(name))
            if vim_type and not isinstance(obj, vim_type):
                raise ValueError('The given {0}: {1} is not of the correct type'.format(name, attributes[name]))
            return obj
        return False

    def _get_default(self, all_item_in_vc, vim_type, key):
        obj = self._get_default_from_vc_by_type_and_name(all_item_in_vc, vim_type)
        if isinstance(obj, str):
            if obj == 'too many options':
                raise ValueError('{0} must be selected'.format(key))

            raise ValueError('Could not find {0}'.format(key))

        return obj

    def _check_if_vcenter_user_pass_valid(self, context, session, attributes):
        self._check_if_attribute_not_empty(attributes, USER)
        self._check_if_attribute_not_empty(attributes, PASSWORD)
        connection_details = self._get_connection_details(session,
                                                          attributes[PASSWORD],
                                                          attributes[USER],
                                                          context.resource.address)
        try:
            si = self.pv_service.connect(connection_details.host,
                                         connection_details.username,
                                         connection_details.password,
                                         connection_details.port)
        except Exception:
            raise ValueError('could not connect to the vcenter: {0}, with the given credentials ({1})'.format(
                connection_details.host,
                connection_details.username))
        return si

    def _validate_default_dvswitch(self, si, all_items_in_vc, auto_att, dc_name, attributes, key):
        accepted_types = (vim.DistributedVirtualSwitch, vim.VmwareDistributedVirtualSwitch)
        d_switch = self._validate_attribute(si, attributes, accepted_types, key, dc_name)
        if not d_switch:
            d_switch = self._get_default(all_items_in_vc, accepted_types, key)
            d_name = self.get_full_name(dc_name, d_switch)
            # removing the upper folder
            d_name = d_name.replace('network/', '')
        else:
            d_name = attributes[key]
        auto_att.append(AutoLoadAttribute('', key, d_name))

    def _validate_vm_storage(self, si, all_items_in_vc, auto_att, dc_name, attributes, key):
        accepted_types = (vim.Datastore, vim.StoragePod)
        datastore = self._validate_attribute(si, attributes, accepted_types, key, dc_name)
        if not datastore:
            datastore = self._get_default(all_items_in_vc, accepted_types, key)
            d_name = self.get_full_name(dc_name, datastore)
            # removing the upper folder
            d_name = d_name.replace('datastore/', '')
        else:
            d_name = attributes[key]
        auto_att.append(AutoLoadAttribute('', key, d_name))

    def _validate_vm_location(self, si, all_items_in_vc, auto_att, dc_name, attributes, key):
        accepted_types = None
        folder = self._validate_attribute(si, attributes, accepted_types, key, dc_name)
        if not folder:
            raise ValueError('VM Folder cannot be empty')

        f_name = attributes[key]
        auto_att.append(AutoLoadAttribute('', key, f_name))

    def _validate_default_port_group_location(self, si, all_items_in_vc, auto_att, dc_name, attributes, key):
        if not attributes[key]:
            return
        self._validate_attribute(si, attributes, None, key, dc_name)

    def _validate_vm_cluster(self, si, all_items_in_vc, auto_att, dc_name, attributes, key):
        accepted_types = (vim.ClusterComputeResource, vim.HostSystem)
        cluster = self._validate_attribute(si, attributes, accepted_types, key, dc_name)
        if not cluster:
            cluster = self._get_default(all_items_in_vc, accepted_types, key)
            c_name = self.get_full_name(dc_name, cluster)
            # removing the upper folder
            c_name = c_name.replace('host/', '')
        else:
            c_name = attributes[key]
        auto_att.append(AutoLoadAttribute('', key, c_name))
        return cluster

    def _validate_vm_resource_pool(self, si, all_items_in_vc, auto_att, dc_name, attributes, key):
        cluster = self._validate_vm_cluster(si, all_items_in_vc, auto_att, dc_name, attributes, VM_CLUSTER)

        if key not in attributes or not attributes[key]:
            return
        pool_name = attributes[key]
        pool = self._find_resource_pool_by_path(pool_name, cluster)
        if pool:
            auto_att.append(AutoLoadAttribute('', key, pool_name))
            return

        raise ValueError('The given resource pool not found: {0}'.format(pool_name))

    def _find_resource_pool_by_path(self, name, root):
        paths = name.split('/')
        for path in paths:
            root = self._find_resource_pool(path, root)
            if not root:
                return None
        return root

    def _find_resource_pool(self, name, root):
        if hasattr(root, 'resourcePool'):
            resource_pool = root.resourcePool
            if hasattr(resource_pool, 'name') and resource_pool.name == name:
                return resource_pool

            if isinstance(resource_pool, collections.Iterable):
                for pool in resource_pool:
                    if pool.name == name:
                        return pool

            if hasattr(resource_pool, 'resourcePool'):
                return self._find_resource_pool(name, resource_pool)
        return None

    def _validate_holding_network(self, si, all_items_in_vc, auto_att, dc_name, attributes, key):
        holding_network = self._validate_attribute(si, attributes, vim.Network, key, dc_name)
        if not holding_network:
            raise ValueError('Holding Network cannot be empty')

        n_name = attributes[key]
        auto_att.append(AutoLoadAttribute('', key, n_name))

    def _validate_shutdown_method(self, si, all_items_in_vc, auto_att, dc_name, attributes, key):
        method = attributes[key]
        if self._is_in_array(key, method, SHUTDOWN_METHODS):
            auto_att.append(AutoLoadAttribute('', key, method))

    @staticmethod
    def _is_in_array(key, value, arr):
        if value in arr:
            return True
        raise ValueError('{0} can only be: {1} instead of: {2}'.format(key, arr, value))

    @staticmethod
    def _is_found(item, key):
        if not item:
            raise ValueError('The {0} could not be found in the given vCenter'.format(key))

    @staticmethod
    def _get_connection_details(session, password, user, address):
        password = session.DecryptPassword(password).Value
        return VCenterConnectionDetails(address, user, password)

    @staticmethod
    def _check_if_attribute_not_empty(attributes, name):
        if not ((hasattr(attributes, name) and getattr(attributes, name)) or
                    (isinstance(attributes, dict) and name in attributes and attributes[name])):
            raise ValueError('{0} cannot be empty'.format(name))

    @staticmethod
    def _validate_empty(si, all_items_in_vc, attributes, auto_attr, dc_name, key):
        return

    def _get_validation_method(self, name):
        if not name:
            return self._validate_empty
        name = name.lower()
        name = name.split(' ')
        name = '_'.join(name)
        method_name = '_validate_{0}'.format(name)
        return getattr(self, method_name, self._validate_empty)

    @staticmethod
    def get_full_name(dc_name, managed_object, name=''):
        if managed_object.name == dc_name:
            return name
        curr_path = managed_object.name
        if name:
            curr_path = '{0}/{1}'.format(managed_object.name, name)
        return VCenterAutoModelDiscovery.get_full_name(dc_name, managed_object.parent, curr_path)
コード例 #18
0
 def __init__(self):
     self.parser = ResourceModelParser()
     self.pv_service = pyVmomiService(SmartConnect, Disconnect)
     self.cs_helper = CloudshellDriverHelper()
     self.context_based_logger_factory = ContextBasedLoggerFactory()
コード例 #19
0
ファイル: driver.py プロジェクト: kalsky/vCenterShell
 def __init__(self):
     self.resource_model_parser = ResourceModelParser()
     self.cs_helper = CloudshellDriverHelper()
コード例 #20
0
class VCenterAutoModelDiscovery(object):
    def __init__(self):
        self.parser = ResourceModelParser()
        self.pv_service = pyVmomiService(SmartConnect, Disconnect, SynchronousTaskWaiter())
        self.cs_helper = CloudshellDriverHelper()
        self.context_based_logger_factory = ContextBasedLoggerFactory()

    def validate_and_discover(self, context):
        """
        :type context: models.QualiDriverModels.AutoLoadCommandContext
        """
        logger = self.context_based_logger_factory.create_logger_for_context(
            logger_name='vCenterShell',
            context=context)

        logger.info('Autodiscovery started')

        session = self.cs_helper.get_session(context.connectivity.server_address,
                                             context.connectivity.admin_auth_token,
                                             DOMAIN)
        self._check_if_attribute_not_empty(context.resource, ADDRESS)
        resource = context.resource
        auto_attr = []
        si = self._check_if_vcenter_user_pass_valid(context, session, resource.attributes)
        if not si:
            error_message = 'Could not connect to the vCenter: {0}, with given credentials'\
                .format(context.resource.address)
            logger.error(error_message)
            raise ValueError(error_message)
        all_dc = self.pv_service.get_all_items_in_vcenter(si, vim.Datacenter)

        dc = self._validate_datacenter(si, all_dc, auto_attr, resource.attributes)

        all_items_in_dc = self.pv_service.get_all_items_in_vcenter(si, None, dc)

        dc_name = dc.name

        for key, value in resource.attributes.items():
            if key in [USER, PASSWORD, DEFAULT_DATACENTER, VM_CLUSTER]:
                continue
            validation_method = self._get_validation_method(key)
            validation_method(si, all_items_in_dc, auto_attr, dc_name, resource.attributes, key)

        logger.info('Autodiscovery completed')

        return AutoLoadDetails([], auto_attr)

    @staticmethod
    def _get_default_from_vc_by_type_and_name(items_in_vc, vim_type, name=None):
        items = []
        if not isinstance(vim_type, collections.Iterable):
            vim_type = [vim_type]
        for item in items_in_vc:
            if item.name == name:
                return item

            item_type = type(item)
            if [t for t in vim_type if item_type is t]:
                items.append(item)

        if len(items) == 1:
            return items[0]
        if len(items) > 1:
            return 'too many options'
        return 'not found'

    def _validate_datacenter(self, si, all_item_in_vc, auto_att, attributes):
        dc = self._validate_attribute(si, attributes, vim.Datacenter, DEFAULT_DATACENTER)
        if not dc:
            dc = self._get_default(all_item_in_vc, vim.Datacenter, DEFAULT_DATACENTER)
        auto_att.append(AutoLoadAttribute('', DEFAULT_DATACENTER, dc.name))
        return dc

    def _validate_attribute(self, si, attributes, vim_type, name, prefix=''):
        if name in attributes and attributes[name]:
            att_value = attributes[name]
            if prefix:
                att_value = '{0}/{1}'.format(prefix, att_value)

            obj = self.pv_service.get_folder(si, att_value)
            if not obj or isinstance(obj, str):
                raise ValueError('Could not find {0}'.format(name))
            if vim_type and not isinstance(obj, vim_type):
                raise ValueError('The given {0}: {1} is not of the correct type'.format(name, attributes[name]))
            return obj
        return False

    def _get_default(self, all_item_in_vc, vim_type, key):
        obj = self._get_default_from_vc_by_type_and_name(all_item_in_vc, vim_type)
        if isinstance(obj, str):
            if obj == 'too many options':
                raise ValueError('{0} must be selected'.format(key))

            raise ValueError('Could not find {0}'.format(key))

        return obj

    def _check_if_vcenter_user_pass_valid(self, context, session, attributes):
        self._check_if_attribute_not_empty(attributes, USER)
        self._check_if_attribute_not_empty(attributes, PASSWORD)
        connection_details = self._get_connection_details(session,
                                                          attributes[PASSWORD],
                                                          attributes[USER],
                                                          context.resource.address)
        try:
            si = self.pv_service.connect(connection_details.host,
                                         connection_details.username,
                                         connection_details.password,
                                         connection_details.port)
        except Exception:
            raise ValueError('could not connect to the vcenter: {0}, with the given credentials ({1})'.format(
                connection_details.host,
                connection_details.username))
        return si

    def _validate_vm_storage(self, si, all_items_in_vc, auto_att, dc_name, attributes, key):
        accepted_types = (vim.Datastore, vim.StoragePod)
        datastore = self._validate_attribute(si, attributes, accepted_types, key, dc_name)
        if not datastore:
            datastore = self._get_default(all_items_in_vc, accepted_types, key)
            d_name = self.get_full_name(dc_name, datastore)
            # removing the upper folder
            d_name = d_name.replace('datastore/', '')
        else:
            d_name = attributes[key]
        auto_att.append(AutoLoadAttribute('', key, d_name))

    def _validate_vm_location(self, si, all_items_in_vc, auto_att, dc_name, attributes, key):
        accepted_types = None
        folder = self._validate_attribute(si, attributes, accepted_types, key, dc_name)
        if not folder:
            raise ValueError('VM Folder cannot be empty')

        f_name = attributes[key]
        auto_att.append(AutoLoadAttribute('', key, f_name))

    def _validate_vm_cluster(self, si, all_items_in_vc, auto_att, dc_name, attributes, key):
        accepted_types = (vim.ClusterComputeResource, vim.HostSystem)
        cluster = self._validate_attribute(si, attributes, accepted_types, key, dc_name)
        if not cluster:
            cluster = self._get_default(all_items_in_vc, accepted_types, key)
            c_name = self.get_full_name(dc_name, cluster)
            # removing the upper folder
            c_name = c_name.replace('host/', '')
        else:
            c_name = attributes[key]
        auto_att.append(AutoLoadAttribute('', key, c_name))
        return cluster

    def _validate_vm_resource_pool(self, si, all_items_in_vc, auto_att, dc_name, attributes, key):
        cluster = self._validate_vm_cluster(si, all_items_in_vc, auto_att, dc_name, attributes, VM_CLUSTER)

        if key not in attributes or not attributes[key]:
            return
        pool_name = attributes[key]
        pool = self._find_resource_pool_by_path(pool_name, cluster)
        if pool:
            auto_att.append(AutoLoadAttribute('', key, pool_name))
            return

        raise ValueError('The given resource pool not found: {0}'.format(pool_name))

    def _find_resource_pool_by_path(self, name, root):
        paths = name.split('/')
        for path in paths:
            root = self._find_resource_pool(path, root)
            if not root:
                return None
        return root

    def _find_resource_pool(self, name, root):
        if hasattr(root, 'resourcePool'):
            resource_pool = root.resourcePool
            if hasattr(resource_pool, 'name') and resource_pool.name == name:
                return resource_pool

            if isinstance(resource_pool, collections.Iterable):
                for pool in resource_pool:
                    if pool.name == name:
                        return pool

            if hasattr(resource_pool, 'resourcePool'):
                return self._find_resource_pool(name, resource_pool)
        return None

    def _validate_holding_network(self, si, all_items_in_vc, auto_att, dc_name, attributes, key):
        holding_network = self._validate_attribute(si, attributes, vim.Network, key, dc_name)
        if not holding_network:
            raise ValueError('Holding Network cannot be empty')

        n_name = attributes[key]
        auto_att.append(AutoLoadAttribute('', key, n_name))

    def _validate_shutdown_method(self, si, all_items_in_vc, auto_att, dc_name, attributes, key):
        method = attributes[key]
        if self._is_in_array(key, method, SHUTDOWN_METHODS):
            auto_att.append(AutoLoadAttribute('', key, method))

    @staticmethod
    def _is_in_array(key, value, arr):
        if value in arr:
            return True
        raise ValueError('{0} can only be: {1} instead of: {2}'.format(key, arr, value))

    @staticmethod
    def _is_found(item, key):
        if not item:
            raise ValueError('The {0} could not be found in the given vCenter'.format(key))

    @staticmethod
    def _get_connection_details(session, password, user, address):
        password = session.DecryptPassword(password).Value
        return VCenterConnectionDetails(address, user, password)

    @staticmethod
    def _check_if_attribute_not_empty(attributes, name):
        if not ((hasattr(attributes, name) and getattr(attributes, name)) or
                    (isinstance(attributes, dict) and name in attributes and attributes[name])):
            raise ValueError('{0} cannot be empty'.format(name))

    @staticmethod
    def _validate_empty(si, all_items_in_vc, attributes, auto_attr, dc_name, key):
        return

    def _get_validation_method(self, name):
        if not name:
            return self._validate_empty
        name = name.lower()
        name = name.split(' ')
        name = '_'.join(name)
        method_name = '_validate_{0}'.format(name)
        return getattr(self, method_name, self._validate_empty)

    @staticmethod
    def get_full_name(dc_name, managed_object, name=''):
        if managed_object.name == dc_name:
            return name
        curr_path = managed_object.name
        if name:
            curr_path = '{0}/{1}'.format(managed_object.name, name)
        return VCenterAutoModelDiscovery.get_full_name(dc_name, managed_object.parent, curr_path)