コード例 #1
0
    def f(context):
        # Here it also can have long spinners
        with sel.ajax_timeout(90):
            toolbar.select('Lifecycle', tb_item)
        provider = context['provider']
        template_name = context['template_name']
        template_select_form.template_table._update_cache()
        template = template_select_form.template_table.find_row_by_cells({
            'Name':
            template_name,
            'Provider':
            provider if isinstance(provider, basestring) else provider.name
        })
        if template:
            sel.click(template)
            # In order to mitigate the sometimes very long spinner timeout, raise the timeout
            with sel.ajax_timeout(90):
                if current_version() < "5.4":
                    sel.click(submit_button)
                else:
                    sel.click(
                        form_buttons.FormButton("Continue", force_click=True))

        else:
            raise TemplateNotFound(
                'Unable to find template "{}" for provider "{}"'.format(
                    template_name, provider.key))
コード例 #2
0
def select_provision_image(template_name, provider):
    """
    Navigate to provision and select the template+click continue, leaving UI on provision form

    :param template_name: The image/template name to select
    :param provider: Provider where the image/template resides
    :return: none
    """
    logger.debug(
        'Selecting an image {} from provider {} for provisioning'.format(
            template_name, provider.name))
    navigate_to(Instance, 'Provision')
    template = image_select_form.template_table.find_row_by_cells({
        'Name':
        template_name,
        'Provider':
        provider.name
    })
    if template:
        sel.click(template)
        # In order to mitigate the sometimes very long spinner timeout, raise the timeout
        with sel.ajax_timeout(90):
            sel.click(form_buttons.FormButton("Continue", force_click=True))

    else:
        raise TemplateNotFound(
            'Unable to find template "{}" for provider "{}"'.format(
                template_name, provider.key))
コード例 #3
0
class CloudProvider(Pretty, CloudInfraProvider):
    """
    Abstract model of a cloud provider in cfme. See EC2Provider or OpenStackProvider.

    Args:
        name: Name of the provider.
        details: a details record (see EC2Details, OpenStackDetails inner class).
        credentials (:py:class:`Credential`): see Credential class.
        key: The CFME key of the provider in the yaml.

    Usage:

        myprov = EC2Provider(name='foo',
                             region='us-west-1',
                             credentials=Credential(principal='admin', secret='foobar'))
        myprov.create()

    """
    provider_types = {}
    in_version = (version.LOWEST, version.LATEST)
    category = "cloud"
    pretty_attrs = ['name', 'credentials', 'zone', 'key']
    STATS_TO_MATCH = ['num_template', 'num_vm']
    string_name = "Cloud"
    page_name = "clouds"
    templates_destination_name = "Images"
    quad_name = "cloud_prov"
    vm_name = "Instances"
    template_name = "Images"
    _properties_region = prop_region  # This will get resolved in common to a real form
    db_types = ["CloudManager"]
    # Specific Add button
    add_provider_button = deferred_verpick({
        version.LOWEST:
        form_buttons.FormButton("Add this Cloud Provider"),
        '5.5':
        form_buttons.add
    })
    save_button = deferred_verpick({
        version.LOWEST: form_buttons.save,
        '5.5': form_buttons.angular_save
    })

    def __init__(self,
                 name=None,
                 credentials=None,
                 zone=None,
                 key=None,
                 appliance=None):
        Navigatable.__init__(self, appliance=appliance)
        if not credentials:
            credentials = {}
        self.name = name
        self.credentials = credentials
        self.zone = zone
        self.key = key

    def _form_mapping(self, create=None, **kwargs):
        return {'name_text': kwargs.get('name')}
コード例 #4
0
ファイル: provider.py プロジェクト: vprusa/cfme_tests
class Provider(Pretty, CloudInfraProvider):
    """
    Abstract model of a cloud provider in cfme. See EC2Provider or OpenStackProvider.

    Args:
        name: Name of the provider.
        details: a details record (see EC2Details, OpenStackDetails inner class).
        credentials (Credential): see Credential inner class.
        key: The CFME key of the provider in the yaml.

    Usage:

        myprov = EC2Provider(name='foo',
                             region='us-west-1',
                             credentials=Provider.Credential(principal='admin', secret='foobar'))
        myprov.create()

    """
    pretty_attrs = ['name', 'credentials', 'zone', 'key']
    STATS_TO_MATCH = ['num_template', 'num_vm']
    string_name = "Cloud"
    page_name = "clouds"
    instances_page_name = "clouds_instances_by_provider"
    templates_page_name = "clouds_images_by_provider"
    quad_name = "cloud_prov"
    vm_name = "Instances"
    template_name = "Images"
    properties_form = properties_form
    # Specific Add button
    add_provider_button = deferred_verpick(
        {version.LOWEST: form_buttons.FormButton("Add this Cloud Provider"),
         '5.5': form_buttons.FormButton("Add")})
    save_button = deferred_verpick(
        {version.LOWEST: form_buttons.FormButton("Save Changes"),
         '5.5': form_buttons.FormButton("Save changes")})

    def __init__(self, name=None, credentials=None, zone=None, key=None):
        if not credentials:
            credentials = {}
        self.name = name
        self.credentials = credentials
        self.zone = zone
        self.key = key

    def _form_mapping(self, create=None, **kwargs):
        return {'name_text': kwargs.get('name')}
コード例 #5
0
class MiddlewareProvider(BaseProvider):
    in_version = ('5.7', version.LATEST)
    category = "middleware"
    page_name = 'middleware'
    string_name = 'Middleware'
    provider_types = {}
    STATS_TO_MATCH = []
    property_tuples = []
    detail_page_suffix = 'provider_detail'
    edit_page_suffix = 'provider_edit_detail'
    refresh_text = "Refresh items and relationships"
    quad_name = 'middleware'
    _properties_region = prop_region  # This will get resolved in common to a real form
    add_provider_button = form_buttons.FormButton("Add")
    save_button = form_buttons.FormButton("Save")
    taggable_type = 'ExtManagementSystem'
    db_types = ["MiddlewareManager"]
コード例 #6
0
        def set_relationship(self, server_name, server_id, click_cancel=False):
            self.navigate()
            option = "{} ({})".format(server_name, server_id)

            if click_cancel:
                fill(self.relationship_form, {'server_select': option},
                     action=self.relationship_form.cancel_button)
            else:
                fill(self.relationship_form, {'server_select': option})
                sel.click(form_buttons.FormButton(
                    "Save Changes", dimmed_alt="Save", force_click=True))
                flash.assert_success_message("Management Engine Relationship saved")
コード例 #7
0
    def step(self, *args, **kwargs):
        lcl_btn("Provision VMs")

        # choosing template and going further
        template_select_form.template_table._update_cache()
        template = template_select_form.template_table.find_row_by_cells({
            'Name': self.obj.template_name,
            'Provider': self.obj.provider.name
        })
        if template:
            sel.click(template)
            # In order to mitigate the sometimes very long spinner timeout, raise the timeout
            with sel.ajax_timeout(90):
                sel.click(form_buttons.FormButton("Continue", force_click=True))

        else:
            raise TemplateNotFound('Unable to find template "{}" for provider "{}"'.format(
                self.obj.template_name, self.obj.provider.key))
コード例 #8
0
        def set_relationship(self, server_name, server_id, click_cancel=False):
            self.navigate()
            option = "{} ({})".format(server_name, server_id)

            if click_cancel:
                fill(self.relationship_form, {'server_select': option},
                     action=self.relationship_form.cancel_button)
            else:
                fill(self.relationship_form, {'server_select': option},
                     action=self.relationship_form.save_button)
                # something weird going on where changing the select doesn't POST to undim save
                sel.wait_for_ajax()
                if self.relationship_form.save_button.is_dimmed:
                    logger.warning("Worked around dimmed save button")
                    sel.browser().execute_script(
                        "$j.ajax({type: 'POST', url: '/vm_infra/evm_relationship_field_changed',"
                        " data: {'server_id':'%s'}})" % (server_id))
                    sel.click(
                        form_buttons.FormButton("Save Changes",
                                                dimmed_alt="Save",
                                                force_click=True))
                flash.assert_success_message(
                    "Management Engine Relationship saved")
コード例 #9
0
class ContainersProvider(BaseProvider, Pretty):
    PLURAL = 'Providers'
    provider_types = {}
    in_version = ('5.5', version.LATEST)
    category = "container"
    pretty_attrs = ['name', 'key', 'zone']
    STATS_TO_MATCH = [
        'num_project', 'num_service', 'num_replication_controller', 'num_pod',
        'num_node', 'num_image_registry', 'num_container'
    ]
    # TODO add 'num_volume'
    string_name = "Containers"
    page_name = "containers"
    detail_page_suffix = 'provider_detail'
    edit_page_suffix = 'provider_edit_detail'
    refresh_text = "Refresh items and relationships"
    quad_name = None
    db_types = ["ContainerManager"]
    _properties_region = prop_region  # This will get resolved in common to a real form
    add_provider_button = deferred_verpick({
        version.LOWEST:
        form_buttons.FormButton("Add this Containers Provider"),
        '5.6':
        form_buttons.add
    })
    save_button = deferred_verpick({
        version.LOWEST: form_buttons.save,
        '5.6': form_buttons.angular_save
    })

    def __init__(self,
                 name=None,
                 credentials=None,
                 key=None,
                 zone=None,
                 hawkular=None,
                 hostname=None,
                 api_port=None,
                 sec_protocol=None,
                 hawkular_sec_protocol=None,
                 hawkular_hostname=None,
                 hawkular_api_port=None,
                 provider_data=None,
                 appliance=None):
        Navigatable.__init__(self, appliance=appliance)
        if not credentials:
            credentials = {}
        self.name = name
        self.credentials = credentials
        self.key = key
        self.zone = zone
        self.hawkular = hawkular
        self.hostname = hostname
        self.api_port = api_port
        self.sec_protocol = sec_protocol
        self.hawkular_sec_protocol = hawkular_sec_protocol
        self.hawkular_hostname = hawkular_hostname
        self.hawkular_api_port = hawkular_api_port
        self.provider_data = provider_data

    def _on_detail_page(self):
        """ Returns ``True`` if on the providers detail page, ``False`` if not."""
        ensure_browser_open()
        return sel.is_displayed(
            '//div//h1[contains(., "{} (Summary)")]'.format(self.name))

    def load_details(self, refresh=False):
        navigate_to(self, 'Details')
        if refresh:
            tb.refresh()

    def get_detail(self, *ident):
        """ Gets details from the details infoblock

        Args:
            *ident: An InfoBlock title, followed by the Key name, e.g. "Relationships", "Images"
        Returns: A string representing the contents of the InfoBlock's value.
        """
        navigate_to(self, 'Details')
        return details_page.infoblock.text(*ident)

    @variable(alias='db')
    def num_project(self):
        return self._num_db_generic('container_projects')

    @num_project.variant('ui')
    def num_project_ui(self):
        return int(self.get_detail("Relationships", "Projects"))

    @variable(alias='db')
    def num_service(self):
        return self._num_db_generic('container_services')

    @num_service.variant('ui')
    def num_service_ui(self):
        if self.appliance.version < "5.7":
            name = "Services"
        else:
            name = "Container Services"
        return int(self.get_detail("Relationships", name))

    @variable(alias='db')
    def num_replication_controller(self):
        return self._num_db_generic('container_replicators')

    @num_replication_controller.variant('ui')
    def num_replication_controller_ui(self):
        return int(self.get_detail("Relationships", "Replicators"))

    @variable(alias='db')
    def num_container_group(self):
        return self._num_db_generic('container_groups')

    @num_container_group.variant('ui')
    def num_container_group_ui(self):
        return int(self.get_detail("Relationships", "Pods"))

    @variable(alias='db')
    def num_pod(self):
        # potato tomato
        return self.num_container_group()

    @num_pod.variant('ui')
    def num_pod_ui(self):
        # potato tomato
        return self.num_container_group(method='ui')

    @variable(alias='db')
    def num_node(self):
        return self._num_db_generic('container_nodes')

    @num_node.variant('ui')
    def num_node_ui(self):
        return int(self.get_detail("Relationships", "Nodes"))

    @variable(alias='db')
    def num_container(self):
        # Containers are linked to providers through container definitions and then through pods
        res = self.appliance.db.client.engine.execute(
            "SELECT count(*) "
            "FROM ext_management_systems, container_groups, container_definitions, containers "
            "WHERE containers.container_definition_id=container_definitions.id "
            "AND container_definitions.container_group_id=container_groups.id "
            "AND container_groups.ems_id=ext_management_systems.id "
            "AND ext_management_systems.name='{}'".format(self.name))
        return int(res.first()[0])

    @num_container.variant('ui')
    def num_container_ui(self):
        return int(self.get_detail("Relationships", "Containers"))

    @variable(alias='db')
    def num_image(self):
        return self._num_db_generic('container_images')

    @num_image.variant('ui')
    def num_image_ui(self):
        if self.appliance.version < "5.7":
            name = "Images"
        else:
            name = "Container Images"
        return int(self.get_detail("Relationships", name))

    @variable(alias='db')
    def num_image_registry(self):
        return self._num_db_generic('container_image_registries')

    @num_image_registry.variant('ui')
    def num_image_registry_ui(self):
        return int(self.get_detail("Relationships", "Image Registries"))

    def pods_per_ready_status(self):
        """Grabing the Container Statuses Summary of the pods from API"""
        #  TODO: Add later this logic to wrapanapi
        entities = self.mgmt.api.get('pod')[1]['items']
        out = {}
        for entity_j in entities:
            out[entity_j['metadata']['name']] = {
                condition['type']: eval_strings([condition['status']]).pop()
                for condition in entity_j['status'].get('conditions', [])
            }
        return out
コード例 #10
0
class Genealogy(object):
    """Class, representing genealogy of an infra object with possibility of data retrieval
    and comparison.

    Args:
        o: The :py:class:`Vm` or :py:class:`Template` object.
    """
    genealogy_tree = deferred_verpick({
        version.LOWEST:
        CheckboxTree("//div[@id='genealogy_treebox']/ul"),
        5.7:
        BootstrapTreeview('genealogy_treebox')
    })

    section_comparison_tree = CheckboxTree(
        "//div[@id='all_sections_treebox']/div/table")
    apply_button = form_buttons.FormButton("Apply sections")

    mode_mapping = {
        "exists": "Exists Mode",
        "details": "Details Mode",
    }

    attr_mapping = {
        "all": "All Attributes",
        "different": "Attributes with different values",
        "same": "Attributes with same values",
    }

    def __init__(self, o):
        self.o = o

    def navigate(self):
        self.o.load_details()
        sel.click(InfoBlock.element("Relationships", "Genealogy"))

    def compare(self, *objects, **kwargs):
        """Compares two or more objects in the genealogy.

        Args:
            *objects: :py:class:`Vm` or :py:class:`Template` or :py:class:`str` with name.

        Keywords:
            sections: Which sections to compare.
            attributes: `all`, `different` or `same`. Default: `all`.
            mode: `exists` or `details`. Default: `exists`."""
        sections = kwargs.get("sections")
        attributes = kwargs.get("attributes", "all").lower()
        mode = kwargs.get("mode", "exists").lower()
        assert len(objects) >= 2, "You must specify at least two objects"
        objects = map(lambda o: o.name
                      if isinstance(o, (Vm, Template)) else o, objects)
        self.navigate()
        for obj in objects:
            if not isinstance(obj, list):
                path = self.genealogy_tree.find_path_to(obj)
            self.genealogy_tree.check_node(*path)
        toolbar.select("Compare selected VMs")
        # COMPARE PAGE
        flash.assert_no_errors()
        if sections is not None:
            map(lambda path: self.section_comparison_tree.check_node(*path),
                sections)
            sel.click(self.apply_button)
            flash.assert_no_errors()
        # Set requested attributes sets
        toolbar.select(self.attr_mapping[attributes])
        # Set the requested mode
        toolbar.select(self.mode_mapping[mode])

    @property
    def tree(self):
        """Returns contents of the tree with genealogy"""
        self.navigate()
        return self.genealogy_tree.read_contents()

    @property
    def ancestors(self):
        """Returns list of ancestors of the represented object."""
        self.navigate()
        path = self.genealogy_tree.find_path_to(
            re.compile(r"^.*?\(Selected\)$"))
        if not path:
            raise ValueError("Something wrong happened, path not found!")
        processed_path = []
        for step in path[:-1]:
            # We will remove the (parent) and (Selected) suffixes
            processed_path.append(
                re.sub(r"\s*(?:\(Current\)|\(Parent\))$", "", step))
        return processed_path
コード例 #11
0
ファイル: host.py プロジェクト: jdemon519/cfme_tests
class Host(Updateable, Pretty, Navigatable, PolicyProfileAssignable):
    """
    Model of an infrastructure host in cfme.

    Args:
        name: Name of the host.
        hostname: Hostname of the host.
        ip_address: The IP address as a string.
        custom_ident: The custom identifiter.
        host_platform: Included but appears unused in CFME at the moment.
        ipmi_address: The IPMI address.
        mac_address: The mac address of the system.
        credentials (:py:class:`Credential`): see Credential inner class.
        ipmi_credentials (:py:class:`Credential`): see Credential inner class.

    Usage:

        myhost = Host(name='vmware',
                      credentials=Provider.Credential(principal='admin', secret='foobar'))
        myhost.create()

    """
    pretty_attrs = ['name', 'hostname', 'ip_address', 'custom_ident']

    forced_saved = deferred_verpick({
        version.LOWEST:
        form_buttons.FormButton("Save Changes",
                                dimmed_alt="Save",
                                force_click=True),
        '5.5':
        form_buttons.FormButton("Save changes",
                                dimmed_alt="Save changes",
                                force_click=True)
    })

    def __init__(self,
                 name=None,
                 hostname=None,
                 ip_address=None,
                 custom_ident=None,
                 host_platform=None,
                 ipmi_address=None,
                 mac_address=None,
                 credentials=None,
                 ipmi_credentials=None,
                 interface_type='lan',
                 provider=None,
                 appliance=None):
        Navigatable.__init__(self, appliance=appliance)
        self.name = name
        self.quad_name = 'host'
        self.hostname = hostname
        self.ip_address = ip_address
        self.custom_ident = custom_ident
        self.host_platform = host_platform
        self.ipmi_address = ipmi_address
        self.mac_address = mac_address
        self.credentials = credentials
        self.ipmi_credentials = ipmi_credentials
        self.interface_type = interface_type
        self.db_id = None
        self.provider = provider

    def _form_mapping(self, create=None, **kwargs):
        return {
            'name_text': kwargs.get('name'),
            'hostname_text': kwargs.get('hostname'),
            'ipaddress_text': kwargs.get('ip_address'),
            'custom_ident_text': kwargs.get('custom_ident'),
            'host_platform': kwargs.get('host_platform'),
            'ipmi_address_text': kwargs.get('ipmi_address'),
            'mac_address_text': kwargs.get('mac_address')
        }

    class Credential(cfme.Credential, Updateable):
        """Provider credentials

           Args:
             **kwargs: If using IPMI type credential, ipmi = True"""
        def __init__(self, **kwargs):
            super(Host.Credential, self).__init__(**kwargs)
            self.ipmi = kwargs.get('ipmi')

    def _submit(self, cancel, submit_button):
        if cancel:
            sel.click(form_buttons.cancel)
            # sel.wait_for_element(page.configuration_btn)
        else:
            sel.click(submit_button)
            flash.assert_no_errors()

    def create(self, cancel=False, validate_credentials=False):
        """
        Creates a host in the UI

        Args:
           cancel (boolean): Whether to cancel out of the creation.  The cancel is done
               after all the information present in the Host has been filled in the UI.
           validate_credentials (boolean): Whether to validate credentials - if True and the
               credentials are invalid, an error will be raised.
        """
        navigate_to(self, 'Add')
        fill(properties_form, self._form_mapping(True, **self.__dict__))
        fill(credential_form, self.credentials, validate=validate_credentials)
        fill(credential_form,
             self.ipmi_credentials,
             validate=validate_credentials)
        self._submit(cancel, host_add_btn)

    def update(self, updates, cancel=False, validate_credentials=False):
        """
        Updates a host in the UI.  Better to use utils.update.update context
        manager than call this directly.

        Args:
           updates (dict): fields that are changing.
           cancel (boolean): whether to cancel out of the update.
        """

        navigate_to(self, 'Edit')
        change_stored_password()
        fill(credential_form,
             updates.get('credentials', None),
             validate=validate_credentials)

        logger.debug("Trying to save update for host with id: " +
                     str(self.get_db_id))
        self._submit(cancel, self.forced_saved)

    def delete(self, cancel=True):
        """
        Deletes a host from CFME

        Args:
            cancel: Whether to cancel the deletion, defaults to True
        """

        navigate_to(self, 'Details')
        if self.appliance.version >= '5.7':
            btn_name = "Remove item"
        else:
            btn_name = "Remove from the VMDB"
        cfg_btn(btn_name, invokes_alert=True)
        sel.handle_alert(cancel=cancel)

    def load_details(self, refresh=False):
        """To be compatible with the Taggable and PolicyProfileAssignable mixins."""
        navigate_to(self, 'Details')
        if refresh:
            sel.refresh()

    def execute_button(self, button_group, button, cancel=True):
        navigate_to(self, 'Details')
        host_btn = partial(tb.select, button_group)
        host_btn(button, invokes_alert=True)
        sel.click(form_buttons.submit)
        flash.assert_success_message("Order Request was Submitted")
        host_btn(button, invokes_alert=True)
        sel.click(form_buttons.cancel)
        flash.assert_success_message("Service Order was cancelled by the user")

    def power_on(self):
        navigate_to(self, 'Details')
        pow_btn('Power On', invokes_alert=True)
        sel.handle_alert()

    def power_off(self):
        navigate_to(self, 'Details')
        pow_btn('Power Off', invokes_alert=True)
        sel.handle_alert()

    def get_power_state(self):
        return self.get_detail('Properties', 'Power State')
        # return str(find_quadicon(self.name, do_not_navigate=True).state)
        # return state.split()[1]

    def refresh(self, cancel=False):
        tb.select("Configuration",
                  "Refresh Relationships and Power States",
                  invokes_alert=True)
        sel.handle_alert(cancel=cancel)

    # TODO remove provider_crud when issue #4137 fixed,host linked with provider
    def wait_for_host_state_change(self,
                                   desired_state,
                                   timeout=300,
                                   provider_crud=None):
        """Wait for Host to come to desired state.
        This function waits just the needed amount of time thanks to wait_for.
        Args:
            self: self
            desired_state: 'on' or 'off'
            timeout: Specify amount of time (in seconds) to wait until TimedOutError is raised
            provider_crud: provider object where vm resides on (optional)
        """
        def _looking_for_state_change():
            tb.refresh()
            return 'currentstate-' + desired_state in find_quadicon(
                self.name, do_not_navigate=False).state

        navigate_and_select_all_hosts(self.name, provider_crud)
        return wait_for(_looking_for_state_change, num_sec=timeout)

    def get_ipmi(self):
        return IPMI(hostname=self.ipmi_address,
                    username=self.ipmi_credentials.principal,
                    password=self.ipmi_credentials.secret,
                    interface_type=self.interface_type)

    def get_detail(self, *ident):
        """ Gets details from the details infoblock

        The function first ensures that we are on the detail page for the specific host.

        Args:
            *ident: An InfoBlock title, followed by the Key name, e.g. "Relationships", "Images"
        Returns: A string representing the contents of the InfoBlock's value.
        """
        navigate_to(self, 'Details')
        return details_page.infoblock.text(*ident)

    @property
    def exists(self):
        navigate_to(self, 'All')
        for page in paginator.pages():
            if sel.is_displayed(Quadicon(self.name, 'host')):
                return True
        else:
            return False

    @property
    def has_valid_credentials(self):
        """ Check if host has valid credentials saved

        Returns: ``True`` if credentials are saved and valid; ``False`` otherwise
        """
        navigate_to(self, 'All')
        quad = Quadicon(self.name, 'host')
        return 'checkmark' in quad.creds

    def get_datastores(self):
        """ Gets list of all datastores used by this host"""
        navigate_to(self, 'Details')
        list_acc.select('Relationships',
                        'Datastores',
                        by_title=False,
                        partial=True)
        return [q.name for q in Quadicon.all("datastore")]

    @property
    def get_db_id(self):
        if self.db_id is None:
            self.db_id = self.appliance.host_id(self.name)
            return self.db_id
        else:
            return self.db_id

    def run_smartstate_analysis(self):
        """ Runs smartstate analysis on this host

        Note:
            The host must have valid credentials already set up for this to work.
        """
        navigate_to(self, 'Details')
        tb.select('Configuration',
                  'Perform SmartState Analysis',
                  invokes_alert=True)
        sel.handle_alert()
        flash.assert_message_contain(
            '"{}": Analysis successfully initiated'.format(self.name))

    def check_compliance(self, timeout=240):
        """Initiates compliance check and waits for it to finish."""
        navigate_to(self, 'Details')
        original_state = self.compliance_status
        tb.select('Policy',
                  'Check Compliance of Last Known Configuration',
                  invokes_alert=True)
        sel.handle_alert()
        flash.assert_no_errors()
        wait_for(lambda: self.compliance_status != original_state,
                 num_sec=timeout,
                 delay=5,
                 message="compliance of {} checked".format(self.name))

    @property
    def compliance_status(self):
        """Returns the title of the compliance infoblock. The title contains datetime so it can be
        compared.

        Returns:
            :py:class:`NoneType` if no title is present (no compliance checks before), otherwise str
        """
        sel.refresh()
        return self.get_detail('Compliance', 'Status')

    @property
    def is_compliant(self):
        """Check if the Host is compliant

        Returns:
            :py:class:`bool`
        """
        text = self.compliance_status.strip().lower()
        if text.startswith("non-compliant"):
            return False
        elif text.startswith("compliant"):
            return True
        else:
            raise ValueError(
                "{} is not a known state for compliance".format(text))

    def equal_drift_results(self, row_text, section, *indexes):
        """ Compares drift analysis results of a row specified by it's title text

        Args:
            row_text: Title text of the row to compare
            section: Accordion section where the change happened; this section must be activated
            indexes: Indexes of results to compare starting with 0 for first row (latest result).
                     Compares all available drifts, if left empty (default).

        Note:
            There have to be at least 2 drift results available for this to work.

        Returns:
            ``True`` if equal, ``False`` otherwise.
        """
        # mark by indexes or mark all
        navigate_to(self, 'Details')
        list_acc.select(
            'Relationships',
            version.pick({
                version.LOWEST: 'Show host drift history',
                '5.4': 'Show Host drift history'
            }))
        if indexes:
            drift_table.select_rows_by_indexes(*indexes)
        else:
            # We can't compare more than 10 drift results at once
            # so when selecting all, we have to limit it to the latest 10
            if len(list(drift_table.rows())) > 10:
                drift_table.select_rows_by_indexes(*range(0, 10))
            else:
                drift_table.select_all()
        tb.select("Select up to 10 timestamps for Drift Analysis")

        # Make sure the section we need is active/open
        sec_loc_map = {
            'Properties': 'Properties',
            'Security': 'Security',
            'Configuration': 'Configuration',
            'My Company Tags': 'Categories'
        }
        active_sec_loc = "//div[@id='all_sections_treebox']//li[contains(@id, 'group_{}')]"\
            "/span[contains(@class, 'dynatree-selected')]".format(sec_loc_map[section])
        sec_checkbox_loc = "//div[@id='all_sections_treebox']//li[contains(@id, 'group_{}')]"\
            "//span[contains(@class, 'dynatree-checkbox')]".format(sec_loc_map[section])
        sec_apply_btn = "//div[@id='accordion']/a[contains(normalize-space(text()), 'Apply')]"

        # If the section is not active yet, activate it
        if not sel.is_displayed(active_sec_loc):
            sel.click(sec_checkbox_loc)
            sel.click(sec_apply_btn)

        if not tb.is_active("All attributes"):
            tb.select("All attributes")
        d_grid = DriftGrid()
        if any(
                d_grid.cell_indicates_change(row_text, i)
                for i in range(0, len(indexes))):
            return False
        return True

    def tag(self, tag, **kwargs):
        """Tags the system by given tag"""
        navigate_to(self, 'Details')
        mixins.add_tag(tag, **kwargs)

    def untag(self, tag):
        """Removes the selected tag off the system"""
        navigate_to(self, 'Details')
        mixins.remove_tag(tag)
コード例 #12
0
ファイル: hawkular.py プロジェクト: pavelzag/cfme_tests
class HawkularProvider(MiddlewareBase, TopologyMixin, BaseProvider):
    """
    HawkularProvider class holds provider data. Used to perform actions on hawkular provider page

    Args:
        name: Name of the provider
        hostname: Hostname/IP of the provider
        port: http/https port of hawkular provider
        credentials: see Credential inner class.
        key: The CFME key of the provider in the yaml.
        db_id: database row id of provider

    Usage:

        myprov = HawkularProvider(name='foo',
                            hostname='localhost',
                            port=8080,
                            credentials=Provider.Credential(principal='admin', secret='foobar')))
        myprov.create()
        myprov.num_deployment(method="ui")
    """
    STATS_TO_MATCH = ['num_server', 'num_deployment', 'num_datasource']
    property_tuples = [('name', 'name'), ('hostname', 'host_name'),
                       ('port', 'port'), ('provider_type', 'type')]
    type_tclass = "middleware"
    type_name = "hawkular"
    mgmt_class = Hawkular
    page_name = 'middleware'
    string_name = 'Middleware'
    detail_page_suffix = 'provider_detail'
    edit_page_suffix = 'provider_edit_detail'
    refresh_text = "Refresh items and relationships"
    quad_name = None
    _properties_form = properties_form
    add_provider_button = form_buttons.FormButton(
        "Add this Middleware Provider")
    save_button = form_buttons.FormButton("Save Changes")
    taggable_type = 'ExtManagementSystem'

    def __init__(self,
                 name=None,
                 hostname=None,
                 port=None,
                 credentials=None,
                 key=None,
                 **kwargs):
        self.name = name
        self.hostname = hostname
        self.port = port
        self.provider_type = 'Hawkular'
        if not credentials:
            credentials = {}
        self.credentials = credentials
        self.key = key
        self.db_id = kwargs['db_id'] if 'db_id' in kwargs else None

    def _form_mapping(self, create=None, **kwargs):
        return {
            'name_text': kwargs.get('name'),
            'type_select': create and 'Hawkular',
            'hostname_text': kwargs.get('hostname'),
            'port_text': kwargs.get('port')
        }

    @variable(alias='db')
    def num_deployment(self):
        return self._num_db_generic('middleware_deployments')

    @num_deployment.variant('ui')
    def num_deployment_ui(self, reload_data=True):
        if reload_data:
            self.summary.reload()
        return self.summary.relationships.middleware_deployments.value

    @variable(alias='db')
    def num_server(self):
        return self._num_db_generic('middleware_servers')

    @num_server.variant('ui')
    def num_server_ui(self, reload_data=True):
        if reload_data:
            self.summary.reload()
        return self.summary.relationships.middleware_servers.value

    @variable(alias='db')
    def num_datasource(self):
        return self._num_db_generic('middleware_datasources')

    @num_datasource.variant('ui')
    def num_datasource_ui(self, reload_data=True):
        if reload_data:
            self.summary.reload()
        return self.summary.relationships.middleware_datasources.value

    @variable(alias='ui')
    def is_refreshed(self, reload_data=True):
        if reload_data:
            self.summary.reload()
        if re.match('Success.*Minute.*Ago',
                    self.summary.status.last_refresh.text_value):
            return True
        else:
            return False

    @is_refreshed.variant('db')
    def is_refreshed_db(self):
        ems = cfmedb()['ext_management_systems']
        dates = cfmedb().session.query(
            ems.created_on,
            ems.updated_on).filter(ems.name == self.name).first()
        return dates.updated_on > dates.created_on

    @classmethod
    def download(cls, extension):
        _get_providers_page()
        download(extension)

    def load_details(self, refresh=False):
        """Call super class `load_details` and load `db_id` if not set"""
        BaseProvider.load_details(self, refresh=refresh)
        if not self.db_id or refresh:
            tmp_provider = _db_select_query(
                name=self.name,
                type='ManageIQ::Providers::Hawkular::MiddlewareManager').first(
                )
            self.db_id = tmp_provider.id

    def load_topology_page(self):
        self.summary.reload()
        self.summary.overview.topology.click()

    @staticmethod
    def configloader(prov_config, prov_key):
        credentials_key = prov_config['credentials']
        credentials = HawkularProvider.process_credential_yaml_key(
            credentials_key)
        return HawkularProvider(name=prov_config['name'],
                                key=prov_key,
                                hostname=prov_config['hostname'],
                                port=prov_config['port'],
                                credentials={'default': credentials})
コード例 #13
0
                                    Dropdown, Input as WInput)
from widgetastic_manageiq import TimelinesView
from widgetastic_manageiq.vm_reconfigure import DisksTable

# for provider specific vm/template page
QUADICON_TITLE_LOCATOR = (
    "//div[@id='quadicon']/../../../tr/td/a[contains(@href,'vm_infra/x_show')"
    " or contains(@href, '/show/')]")

cfg_btn = partial(toolbar.select, 'Configuration')
pol_btn = partial(toolbar.select, 'Policy')
lcl_btn = partial(toolbar.select, 'Lifecycle')
mon_btn = partial(toolbar.select, 'Monitoring')
pwr_btn = partial(toolbar.select, 'Power')

create_button = form_buttons.FormButton("Create")

manage_policies_tree = CheckboxTree("//div[@id='protect_treebox']/ul")

manage_policies_page = Region(locators={
    'save_button': form_buttons.save,
})

template_select_form = Form(fields=[('template_table',
                                     Table('//div[@id="pre_prov_div"]//table')
                                     ), ('cancel_button',
                                         form_buttons.cancel)])

snapshot_form = Form(
    fields=[('name', Input('name')), ('description', Input('description')),
            ('snapshot_memory',
コード例 #14
0
# -*- coding: utf-8 -*-

from cfme import web_ui as ui
from cfme.fixtures import pytest_selenium as sel
from cfme.web_ui import Region, accordion, fill, flash, form_buttons
from cfme.web_ui.menu import nav

nav.add_branch(
    "reports", {
        "import_export":
        lambda ctx: accordion.tree("Import/Export", "Import / Export"),
    })

form = Region(locators=dict(
    export_select=ui.Select("//select[@id='choices_chosen']", multi=True),
    export_button=form_buttons.FormButton("Download Report to YAML"),
    import_overwrite=ui.Input('overwrite'),
    import_file=ui.Input('upload_file'),
    import_submit=ui.Input('upload_atags')))

export_select = ui.Select("//select[@id='choices_chosen']", multi=True)
export_button = form_buttons.FormButton("Download Report to YAML")


def export_reports(*custom_report_names):
    sel.force_navigate("import_export")
    fill(form.export_select, custom_report_names)
    sel.click(form.export_button)


def import_reports(filename, overwrite=False):
コード例 #15
0
             Input('log_userid')), ('secret_pass', Input('log_password')),
            ('verify_secret_pass',
             Input('log_verify')), ('validate_btn', form_buttons.validate)])


def cfm_mgr_table():
    return Table("//div[@id='main_div']//div[@id='list_grid']/table")


page = Region(
    locators={
        'list_table_config_profiles': cfm_mgr_table(),
        'list_table_config_systems': cfm_mgr_table()
    })

add_manager_btn = form_buttons.FormButton('Add')
edit_manager_btn = form_buttons.FormButton('Save changes')
cfg_btn = partial(tb.select, 'Configuration')

match_page = partial(match_location,
                     controller='provider_foreman',
                     title='Red Hat Satellite Provider')


class ConfigManager(Updateable, Pretty, Navigatable):
    """
    This is base class for Configuration manager objects (Red Hat Satellite, Foreman, Ansible Tower)

    Args:
        name: Name of the config. manager
        url: URL, hostname or IP of the config. manager
コード例 #16
0
from cfme.fixtures import pytest_selenium as sel
from cfme.services import requests
from cfme.web_ui import fill, flash, form_buttons, tabstrip, toolbar
from cfme.web_ui.menu import nav
from utils import version
from utils.log import logger
from utils.version import current_version
from utils.wait import wait_for

# nav imports
import cfme.infrastructure.virtual_machines  # NOQA
import cfme.cloud.instance  # NOQA


instances_by_provider_tree = ui.Tree("ul.dynatree-container")
submit_button = form_buttons.FormButton("Submit")

template_select_form = ui.Form(
    fields=[
        ('template_table', ui.Table('//div[@id="pre_prov_div"]//table')),
        ('cancel_button', form_buttons.cancel)
    ]
)


def select_security_group(sg):
    """Workaround for select box that is immediately replaced by the same
       select box no matter what selenium clicks on (but works fine
       manually).  For now only selects one item even though it's a
       multiselect.
コード例 #17
0
class CopiableTreeNode(TreeNode):
    copy_form = Form(fields=[
        ("domain", {
            version.LOWEST: Select("select#domain"),
            "5.5": AngularSelect("domain")
        }),
        ("domain_text_only", {
            version.LOWEST:
            "//fieldset[p]//tr[./td[@class='key' and normalize-space(.)="
            "'To Domain']]/td[not(@class='key') and not(select)]",
            "5.5":
            "//label[contains(@class, 'control-label') and normalize-space(.)='To Domain']/"
            "../div/p"
        }), ("override", Input("override_source"))
    ])

    copy_button = form_buttons.FormButton("Copy")

    @property
    def class_name(self):
        """Used for gathering the object name from the class name. If the name is not same,
        you can set it manually. This exploits the fact that the classes are named exactly as it
        appears in the UI, so it will work unless someone changes ui/class name. Then you can set it
        manually, as it contains setter."""
        try:
            return self._class_name
        except AttributeError:
            return self.__class__.__name__

    @class_name.setter
    def class_name(self, value):
        self._class_name = value

    def _open_copy_dialog(self):
        sel.force_navigate("automate_explorer_tree_path",
                           context={"tree_item": self})
        cfg_btn("Copy this {}".format(self.class_name))

    # TODO: Make possible change `override` (did not do that because of pop-up tree)
    def copy_to(self, domain=None):
        self._open_copy_dialog()
        if isinstance(domain, Domain):
            domain_name = domain.name
        else:
            domain_name = str(domain)
        if sel.is_displayed(self.copy_form.domain):
            fill(self.copy_form, {"domain": domain_name, "override": True})
        else:
            # If there is only one domain, therefore the select is not present, only text
            domain_selected = sel.text(self.copy_form.domain_text_only).strip()
            if domain_selected != domain_name:
                raise ValueError(
                    "There is only one domain to select and that is {}".format(
                        domain_selected))
            fill(self.copy_form, {"override": True})
        sel.click(self.copy_button)
        flash.assert_message_match(
            "Copy selected Automate {} was saved".format(self.class_name))

        # Bunch'o functions that copy the chain to the domain and change domain's name
        def _change_path_in_namespace(o, new_domain_name):
            if isinstance(o, Domain):
                if isinstance(new_domain_name, Domain):
                    return new_domain_name
                new_domain = copy(o)
                new_domain.name = new_domain_name
                return new_domain
            else:
                new_obj = copy(o)
                if new_obj.parent is None:
                    # This should happen in the domain part of this func so Error here
                    raise Exception(
                        "It is not expected that {} has no parent!".format(
                            type(new_obj).__name__))
                new_obj.parent = _change_path_in_namespace(
                    new_obj.parent, new_domain_name)
                return new_obj

        def _change_parent_path_until_namespace(obj, new_domain_name):
            if isinstance(obj, Namespace):
                return _change_path_in_namespace(obj, new_domain_name)
            else:
                new_obj = copy(obj)
                if new_obj.parent is None:
                    # This should happen in the namespace func so Error here
                    raise Exception(
                        "It is not expected that {} has no parent!".format(
                            type(new_obj).__name__))
                new_obj.parent = _change_parent_path_until_namespace(
                    new_obj.parent, new_domain_name)
                return new_obj

        return _change_parent_path_until_namespace(self, domain)
コード例 #18
0
ファイル: settings.py プロジェクト: jawatts/integration_tests
class Visual(Updateable, Navigatable):

    pretty_attrs = ['name']

    item_form = Form(
        fields=[
            ('grid_view', AngularSelect('perpage_grid')),
            ('tile_view', AngularSelect("perpage_tile")),
            ('list_view', AngularSelect("perpage_list")),
            ('reports', AngularSelect("perpage_reports")),
        ])

    startpage_form = Form(
        fields=[
            ('login_page', AngularSelect("start_page"))])

    quadicons_form = Form(
        fields=[
            ('infra_provider_quad', CFMECheckbox("quadicons_ems")),
            ('cloud_provider_quad', CFMECheckbox("quadicons_ems_cloud")),
            ('host_quad', CFMECheckbox("quadicons_host")),
            ('datastore_quad', CFMECheckbox("quadicons_storage")),
            ('datastoreitem_quad', Input("quadicons_storageitem")),
            ('vm_quad', CFMECheckbox("quadicons_vm")),
            ('vmitem_quad', Input("quadicons_vmitem")),
            ('template_quad', CFMECheckbox("quadicons_miq_template")),
        ])

    display_form = Form(
        fields=[
            ('chart_theme', AngularSelect("display_reporttheme")),
            ('time_zone', AngularSelect("display_timezone")),
        ])

    save_button = form_buttons.FormButton("Add this Time Profile")

    @property
    def grid_view_limit(self):
        navigate_to(self, 'All')
        return int(re.findall("\d+", self.item_form.grid_view.first_selected_option_text)[0])

    @grid_view_limit.setter
    def grid_view_limit(self, value):
        navigate_to(self, 'All')
        fill(self.item_form.grid_view, str(value))
        sel.click(form_buttons.save)

    @property
    def tile_view_limit(self):
        navigate_to(self, 'All')
        return int(re.findall("\d+", self.item_form.tile_view.first_selected_option_text)[0])

    @tile_view_limit.setter
    def tile_view_limit(self, value):
        navigate_to(self, 'All')
        fill(self.item_form.tile_view, str(value))
        sel.click(form_buttons.save)

    @property
    def list_view_limit(self):
        navigate_to(self, 'All')
        return int(re.findall("\d+", self.item_form.list_view.first_selected_option_text)[0])

    @list_view_limit.setter
    def list_view_limit(self, value):
        navigate_to(self, 'All')
        fill(self.item_form.list_view, str(value))
        sel.click(form_buttons.save)

    @property
    def report_view_limit(self):
        navigate_to(self, 'All')
        return int(re.findall("\d+", self.item_form.reports.first_selected_option_text)[0])

    @report_view_limit.setter
    def report_view_limit(self, value):
        navigate_to(self, 'All')
        fill(self.item_form.reports, str(value))
        sel.click(form_buttons.save)

    @property
    def login_page(self):
        navigate_to(self, 'All')
        return self.startpage_form.login_page.first_selected_option_text

    @login_page.setter
    def login_page(self, value):
        navigate_to(self, 'All')
        fill(self.startpage_form.login_page, str(value))
        sel.click(form_buttons.save)

    @property
    def infra_provider_quad(self):
        navigate_to(self, 'All')
        return self.infra_provider_quad

    @infra_provider_quad.setter
    def infra_provider_quad(self, value):
        navigate_to(self, 'All')
        fill(self.quadicons_form.infra_provider_quad, value)
        sel.click(form_buttons.save)

    @property
    def host_quad(self):
        navigate_to(self, 'All')
        return self.host_quad

    @host_quad.setter
    def host_quad(self, value):
        navigate_to(self, 'All')
        fill(self.quadicons_form.host_quad, value)
        sel.click(form_buttons.save)

    @property
    def datastore_quad(self):
        navigate_to(self, 'All')
        return self.datastore_quad

    @datastore_quad.setter
    def datastore_quad(self, value):
        navigate_to(self, 'All')
        fill(self.quadicons_form.datastore_quad, value)
        sel.click(form_buttons.save)

    @property
    def vm_quad(self):
        navigate_to(self, 'All')
        return self.vm_quad

    @vm_quad.setter
    def vm_quad(self, value):
        navigate_to(self, 'All')
        fill(self.quadicons_form.vm_quad, value)
        sel.click(form_buttons.save)

    @property
    def template_quad(self):
        navigate_to(self, 'All')
        return self.template_quad

    @template_quad.setter
    def template_quad(self, value):
        navigate_to(self, 'All')
        fill(self.quadicons_form.template_quad, value)
        sel.click(form_buttons.save)

    def check_image_exists(self):
        name = Quadicon.get_first_quad_title()
        quad = Quadicon(name, None)
        return quad.check_for_single_quadrant_icon

    @property
    def cloud_provider_quad(self):
        navigate_to(self, 'All')
        return self.cloud_provider_quad

    @cloud_provider_quad.setter
    def cloud_provider_quad(self, value):
        navigate_to(self, 'All')
        fill(self.quadicons_form.cloud_provider_quad, value)
        sel.click(form_buttons.save)

    @property
    def timezone(self):
        navigate_to(self, 'All')
        return self.display_form.time_zone.first_selected_option_text

    @timezone.setter
    def timezone(self, value):
        navigate_to(self, 'All')
        fill(self.display_form.time_zone, str(value))
        sel.click(form_buttons.save)
コード例 #19
0
ファイル: settings.py プロジェクト: vrutkovs/cfme_tests
class Timeprofile(Updateable):
    timeprofile_form = Form(fields=[
        ("description", Input("description")),
        ("scope", {
            version.LOWEST: Select("select#profile_type"),
            "5.5": AngularSelect("profile_type")
        }),
        ("timezone", {
            version.LOWEST: Select("select#profile_tz"),
            "5.5": AngularSelect("profile_tz")
        }),
        ("days", Input("all_days")),
        ("hours", Input("all_hours")),
    ])

    save_button = form_buttons.FormButton("Add this Time Profile")

    def __init__(self,
                 description=None,
                 scope=None,
                 days=None,
                 hours=None,
                 timezone=None):
        self.description = description
        self.scope = scope
        self.days = days
        self.hours = hours
        self.timezone = timezone

    def create(self):
        sel.force_navigate('timeprofile_new')
        fill(self.timeprofile_form, {
            'description': self.description,
            'scope': self.scope,
            'days': self.days,
            'hours': self.hours,
            'timezone': self.timezone,
        },
             action=self.save_button)
        flash.assert_success_message('Time Profile "{}" was added'.format(
            self.description))

    def update(self, updates):
        sel.force_navigate("timeprofile_edit", context={"timeprofile": self})
        fill(self.timeprofile_form, {
            'description': updates.get('description'),
            'scope': updates.get('scope'),
            'timezone': updates.get('timezone')
        },
             action=form_buttons.save)
        flash.assert_success_message('Time Profile "{}" was saved'.format(
            updates.get('description', self.description)))

    def copy(self):
        sel.force_navigate("my_settings_time_profiles")
        row = timeprofile_table.find_row_by_cells(
            {'description': self.description})
        sel.check(sel.element(".//input[@type='checkbox']", root=row[0]))
        cfg_btn('Copy selected Time Profile')
        new_timeprofile = Timeprofile(description=self.description + "copy",
                                      scope=self.scope)
        fill(self.timeprofile_form, {
            'description': new_timeprofile.description,
            'scope': new_timeprofile.scope
        },
             action=self.save_button)
        flash.assert_success_message('Time Profile "{}" was added'.format(
            new_timeprofile.description))
        return new_timeprofile

    def delete(self):
        sel.force_navigate("my_settings_time_profiles")
        row = timeprofile_table.find_row_by_cells(
            {'description': self.description})
        sel.check(sel.element(".//input[@type='checkbox']", root=row[0]))
        cfg_btn('Delete selected Time Profiles', invokes_alert=True)
        sel.handle_alert()
        flash.assert_success_message(
            'Time Profile "{}": Delete successful'.format(self.description))
コード例 #20
0
ファイル: settings.py プロジェクト: jawatts/integration_tests
class Timeprofile(Updateable, Navigatable):
    timeprofile_form = Form(
        fields=[
            ("description", Input("description")),
            ("scope", AngularSelect("profile_type")),
            ("timezone", AngularSelect("profile_tz")),
            ("days", CFMECheckbox("all_days")),
            ("hours", CFMECheckbox("all_hours")),
        ]
    )
    save_edit_button = deferred_verpick({'5.7': form_buttons.FormButton('Save changes'),
                                         '5.8': form_buttons.FormButton('Save')})
    save_button = deferred_verpick({
        version.LOWEST: form_buttons.FormButton("Add this Time Profile"),
        '5.7': form_buttons.FormButton('Add'),
        '5.8': form_buttons.FormButton('Save')
    })

    def __init__(self, description=None, scope=None, days=None, hours=None, timezone=None,
            appliance=None):
        Navigatable.__init__(self, appliance=appliance)
        self.description = description
        self.scope = scope
        self.days = days
        self.hours = hours
        self.timezone = timezone

    def create(self, cancel=False):
        navigate_to(self, 'Add')
        fill(self.timeprofile_form, {'description': self.description,
                                     'scope': self.scope,
                                     'days': self.days,
                                     'hours': self.hours,
                                     'timezone': self.timezone,
                                     })
        if not cancel:
            sel.click(self.save_button)
            end = "saved" if self.appliance.version > '5.7' else "added"
            flash.assert_success_message('Time Profile "{}" was {}'
                                         .format(self.description, end))

    def update(self, updates):
        navigate_to(self, 'Edit')
        fill(self.timeprofile_form, {'description': updates.get('description'),
                                     'scope': updates.get('scope'),
                                     'timezone': updates.get('timezone')},
             action={version.LOWEST: form_buttons.save,
                     '5.7': self.save_edit_button})
        flash.assert_success_message(
            'Time Profile "{}" was saved'.format(updates.get('description', self.description)))

    def copy(self):
        navigate_to(self, 'All')
        row = timeprofile_table.find_row_by_cells({'description': self.description})
        sel.check(sel.element(".//input[@type='checkbox']", root=row[0]))
        cfg_btn('Copy selected Time Profile')
        new_timeprofile = Timeprofile(description=self.description + "copy",
                         scope=self.scope)
        fill(self.timeprofile_form, {'description': new_timeprofile.description,
                              'scope': new_timeprofile.scope},
             action=self.save_button)
        end = "saved" if self.appliance.version > '5.7' else "added"
        flash.assert_success_message('Time Profile "{}" was {}'
                                     .format(new_timeprofile.description, end))
        return new_timeprofile

    def delete(self):
        navigate_to(self, 'All')
        row = timeprofile_table.find_row_by_cells({'description': self.description})
        sel.check(sel.element(".//input[@type='checkbox']", root=row[0]))
        cfg_btn('Delete selected Time Profiles', invokes_alert=True)
        sel.handle_alert()
        flash.assert_success_message(
            'Time Profile "{}": Delete successful'.format(self.description))
コード例 #21
0
ファイル: provider.py プロジェクト: vprusa/cfme_tests
from cfme.web_ui import Input
from utils.log import logger
from utils.providers import setup_provider_by_name
from utils.wait import wait_for
from utils import version, deferred_verpick
from utils.pretty import Pretty


# Forms
discover_form = Form(
    fields=[
        ('discover_select', AngularSelect("discover_type_selected"), {"appeared_in": "5.5"}),
        ('username', "#userid"),
        ('password', "#password"),
        ('password_verify', "#verify"),
        ('start_button', form_buttons.FormButton("Start the Host Discovery"))
    ])

properties_form = Form(
    fields=[
        ('type_select', {version.LOWEST: Select('select#server_emstype'),
            '5.5': AngularSelect("emstype")}),
        ('name_text', Input("name")),
        ('hostname_text', Input("hostname")),
        ('ipaddress_text', Input("ipaddress"), {"removed_since": "5.4.0.0.15"}),
        ('amazon_region_select', {version.LOWEST: Select("select#provider_region"),
            "5.5": AngularSelect("provider_region")}),
        ('api_port', Input(
            {
                version.LOWEST: "port",
                "5.5": "api_port",
コード例 #22
0
ファイル: provider.py プロジェクト: richardfontana/cfme_tests
import cfme.fixtures.pytest_selenium as sel
from cfme.web_ui import form_buttons
from cfme.web_ui import toolbar as tb
from cfme.common.provider import BaseProvider
from cfme.web_ui.menu import nav
from cfme.web_ui import Region, Quadicon, Form, Select, fill, paginator
from cfme.web_ui import Input
from utils.log import logger
from utils.update import Updateable
from utils.wait import wait_for
from utils import version
from utils.pretty import Pretty

# Specific Add button
add_provider_button = form_buttons.FormButton("Add this Cloud Provider")

# Forms
discover_form = Form(
    fields=[('username',
             "#userid"), ('password',
                          "#password"), ('password_verify', "#verify"),
            ('start_button',
             form_buttons.FormButton("Start the Host Discovery"))])

properties_form = Form(fields=[
    ('type_select', Select("select#server_emstype")),
    ('name_text', Input("name")),
    ('hostname_text', Input("hostname")),
    ('ipaddress_text', Input("ipaddress"), {
        "removed_since": "5.4.0.0.15"
コード例 #23
0
ファイル: provisioning.py プロジェクト: jdemon519/cfme_tests
from widgetastic_patternfly import Tab, BootstrapSelect, Input, BootstrapTreeview
from widgetastic_manageiq import VersionPick, Version, CheckboxSelect, Table, Calendar

from cfme import web_ui as ui
from cfme import BaseLoggedInPage
from cfme.fixtures import pytest_selenium as sel
from cfme.infrastructure.virtual_machines import Vm
from cfme.services import requests
from cfme.web_ui import AngularSelect, fill, flash, form_buttons, tabstrip
from utils import version
from utils import normalize_text
from utils.appliance.implementations.ui import navigate_to
from utils.log import logger
from utils.wait import wait_for

submit_button = form_buttons.FormButton("Submit")


def select_security_group(sg):
    """TODO: Not even sure this is needed any more, but removal of it is not part of this PR"""
    sel.wait_for_ajax()
    sel.sleep(1)


class ProvisioningForm(BaseLoggedInPage):
    @View.nested
    class request(Tab):  # noqa
        TAB_NAME = 'Request'
        email = Input(name='requester__owner_email')
        first_name = Input(name='requester__owner_first_name')
        last_name = Input(name='requester__owner_last_name')
コード例 #24
0
class Host(Updateable, Pretty):
    """
    Model of an infrastructure host in cfme.

    Args:
        name: Name of the host.
        hostname: Hostname of the host.
        ip_address: The IP address as a string.
        custom_ident: The custom identifiter.
        host_platform: Included but appears unused in CFME at the moment.
        ipmi_address: The IPMI address.
        mac_address: The mac address of the system.
        credentials (Credential): see Credential inner class.
        ipmi_credentials (Credential): see Credential inner class.

    Usage:

        myhost = Host(name='vmware',
                      credentials=Provider.Credential(principal='admin', secret='foobar'))
        myhost.create()

    """
    pretty_attrs = ['name', 'hostname', 'ip_address', 'custom_ident']

    forced_saved = deferred_verpick(
        {version.LOWEST: form_buttons.FormButton(
            "Save Changes", dimmed_alt="Save", force_click=True),
         '5.5': form_buttons.FormButton(
            "Save changes", dimmed_alt="Save changes", force_click=True)})

    def __init__(self, name=None, hostname=None, ip_address=None, custom_ident=None,
                 host_platform=None, ipmi_address=None, mac_address=None, credentials=None,
                 ipmi_credentials=None, interface_type='lan'):
        self.name = name
        self.hostname = hostname
        self.ip_address = ip_address
        self.custom_ident = custom_ident
        self.host_platform = host_platform
        self.ipmi_address = ipmi_address
        self.mac_address = mac_address
        self.credentials = credentials
        self.ipmi_credentials = ipmi_credentials
        self.interface_type = interface_type
        self.db_id = None

    def _form_mapping(self, create=None, **kwargs):
        return {'name_text': kwargs.get('name'),
                'hostname_text': kwargs.get('hostname'),
                'ipaddress_text': kwargs.get('ip_address'),
                'custom_ident_text': kwargs.get('custom_ident'),
                'host_platform': kwargs.get('host_platform'),
                'ipmi_address_text': kwargs.get('ipmi_address'),
                'mac_address_text': kwargs.get('mac_address')}

    class Credential(cfme.Credential, Updateable):
        """Provider credentials

           Args:
             **kwargs: If using IPMI type credential, ipmi = True"""

        def __init__(self, **kwargs):
            super(Host.Credential, self).__init__(**kwargs)
            self.ipmi = kwargs.get('ipmi')

    def _submit(self, cancel, submit_button):
        if cancel:
            sel.click(form_buttons.cancel)
            # sel.wait_for_element(page.configuration_btn)
        else:
            sel.click(submit_button)
            flash.assert_no_errors()

    def create(self, cancel=False, validate_credentials=False):
        """
        Creates a host in the UI

        Args:
           cancel (boolean): Whether to cancel out of the creation.  The cancel is done
               after all the information present in the Host has been filled in the UI.
           validate_credentials (boolean): Whether to validate credentials - if True and the
               credentials are invalid, an error will be raised.
        """
        sel.force_navigate('infrastructure_host_new')
        fill(properties_form, self._form_mapping(True, **self.__dict__))
        fill(credential_form, self.credentials, validate=validate_credentials)
        fill(credential_form, self.ipmi_credentials, validate=validate_credentials)
        self._submit(cancel, host_add_btn)

    def update(self, updates, cancel=False, validate_credentials=False):
        """
        Updates a host in the UI.  Better to use utils.update.update context
        manager than call this directly.

        Args:
           updates (dict): fields that are changing.
           cancel (boolean): whether to cancel out of the update.
        """

        sel.force_navigate('infrastructure_host_edit', context={'host': self})
        change_stored_password()
        fill(credential_form, updates.get('credentials', None), validate=validate_credentials)

        # Workaround for issue with form_button staying dimmed.
        try:
            logger.debug("Trying to save update for host with id: " + str(self.get_db_id))
            self._submit(cancel, self.forced_saved)
            logger.debug("save worked, no exception")
        except Exception as e:
            logger.debug("exception detected: " + str(e))
            sel.browser().execute_script(
                "$j.ajax({type: 'POST', url: '/host/form_field_changed/%s',"
                " data: {'default_userid':'%s'}})" %
                (str(sel.current_url().split('/')[5]), updates.get('credentials', None).principal))
            sel.browser().execute_script(
                "$j.ajax({type: 'POST', url: '/host/form_field_changed/%s',"
                " data: {'default_password':'******'}})" %
                (str(sel.current_url().split('/')[5]), updates.get('credentials', None).secret))
            sel.browser().execute_script(
                "$j.ajax({type: 'POST', url: '/host/form_field_changed/%s',"
                " data: {'default_verify':'%s'}})" %
                (str(sel.current_url().split('/')[5]),
                    updates.get('credentials', None).verify_secret))
            self._submit(cancel, self.forced_saved)

    def delete(self, cancel=True):
        """
        Deletes a host from CFME

        Args:
            cancel: Whether to cancel the deletion, defaults to True
        """

        sel.force_navigate('infrastructure_host', context={'host': self})
        cfg_btn('Remove from the VMDB', invokes_alert=True)
        sel.handle_alert(cancel=cancel)

    def execute_button(self, button_group, button, cancel=True):
        sel.force_navigate('infrastructure_host', context={'host': self})
        host_btn = partial(tb.select, button_group)
        host_btn(button, invokes_alert=True)
        sel.click(form_buttons.submit)
        flash.assert_success_message("Order Request was Submitted")
        host_btn(button, invokes_alert=True)
        sel.click(form_buttons.cancel)
        flash.assert_success_message("Service Order was cancelled by the user")

    def power_on(self):
        sel.force_navigate('infrastructure_host', context={'host': self})
        pow_btn('Power On')
        sel.handle_alert()

    def power_off(self):
        sel.force_navigate('infrastructure_host', context={'host': self})
        pow_btn('Power Off')
        sel.handle_alert()

    def get_ipmi(self):
        return IPMI(hostname=self.ipmi_address, username=self.ipmi_credentials.principal,
                    password=self.ipmi_credentials.secret, interface_type=self.interface_type)

    def get_detail(self, *ident):
        """ Gets details from the details infoblock

        The function first ensures that we are on the detail page for the specific host.

        Args:
            *ident: An InfoBlock title, followed by the Key name, e.g. "Relationships", "Images"
        Returns: A string representing the contents of the InfoBlock's value.
        """
        if not self._on_detail_page():
            sel.force_navigate('infrastructure_host', context={'host': self})
        return details_page.infoblock.text(*ident)

    def _on_detail_page(self):
        """ Returns ``True`` if on the hosts detail page, ``False`` if not."""
        return sel.is_displayed('//div[@class="dhtmlxInfoBarLabel-2"][contains(., "%s")]'
                                % self.name)

    @property
    def exists(self):
        sel.force_navigate('infrastructure_hosts')
        for page in paginator.pages():
            if sel.is_displayed(Quadicon(self.name, 'host')):
                return True
        else:
            return False

    @property
    def has_valid_credentials(self):
        """ Check if host has valid credentials saved

        Returns: ``True`` if credentials are saved and valid; ``False`` otherwise
        """
        sel.force_navigate('infrastructure_hosts')
        quad = Quadicon(self.name, 'host')
        return quad.creds == 'checkmark'

    def _assign_unassign_policy_profiles(self, assign, *policy_profile_names):
        """DRY function for managing policy profiles.

        See :py:func:`assign_policy_profiles` and :py:func:`assign_policy_profiles`

        Args:
            assign: Wheter to assign or unassign.
            policy_profile_names: :py:class:`str` with Policy Profile names.
        """
        sel.force_navigate('infrastructure_host_policy_assignment', context={'host': self})
        for policy_profile in policy_profile_names:
            if assign:
                manage_policies_tree.check_node(policy_profile)
            else:
                manage_policies_tree.uncheck_node(policy_profile)
        sel.click(form_buttons.save)

    def assign_policy_profiles(self, *policy_profile_names):
        """ Assign Policy Profiles to this Host.

        Args:
            policy_profile_names: :py:class:`str` with Policy Profile names. After Control/Explorer
                coverage goes in, PolicyProfile objects will be also passable.
        """
        self._assign_unassign_policy_profiles(True, *policy_profile_names)

    def unassign_policy_profiles(self, *policy_profile_names):
        """ Unssign Policy Profiles to this Host.

        Args:
            policy_profile_names: :py:class:`str` with Policy Profile names. After Control/Explorer
                coverage goes in, PolicyProfile objects will be also passable.
        """
        self._assign_unassign_policy_profiles(False, *policy_profile_names)

    def get_datastores(self):
        """ Gets list of all datastores used by this host"""
        sel.force_navigate('infrastructure_host', context={'host': self})
        list_acc.select('Relationships', version.pick({version.LOWEST: 'Show Datastores',
                                                       '5.3': 'Show all Datastores'}))

        datastores = set([])
        for page in paginator.pages():
            for title in sel.elements(
                    "//div[@id='quadicon']/../../../tr/td/a[contains(@href,'storage/show')]"):
                datastores.add(sel.get_attribute(title, "title"))
        return datastores

    @property
    def get_db_id(self):
        if self.db_id is None:
            self.db_id = get_host_id(self.name)
            return self.db_id
        else:
            return self.db_id

    def run_smartstate_analysis(self):
        """ Runs smartstate analysis on this host

        Note:
            The host must have valid credentials already set up for this to work.
        """
        sel.force_navigate('infrastructure_host', context={'host': self})
        tb.select('Configuration', 'Perform SmartState Analysis', invokes_alert=True)
        sel.handle_alert()
        flash.assert_message_contain('"{}": Analysis successfully initiated'.format(self.name))

    def equal_drift_results(self, row_text, section, *indexes):
        """ Compares drift analysis results of a row specified by it's title text

        Args:
            row_text: Title text of the row to compare
            section: Accordion section where the change happened; this section must be activated
            indexes: Indexes of results to compare starting with 0 for first row (latest result).
                     Compares all available drifts, if left empty (default).

        Note:
            There have to be at least 2 drift results available for this to work.

        Returns:
            ``True`` if equal, ``False`` otherwise.
        """
        # mark by indexes or mark all
        sel.force_navigate('infrastructure_host', context={'host': self})
        list_acc.select('Relationships',
            version.pick({
                version.LOWEST: 'Show host drift history',
                '5.4': 'Show Host drift history'}))
        if indexes:
            drift_table.select_rows_by_indexes(*indexes)
        else:
            # We can't compare more than 10 drift results at once
            # so when selecting all, we have to limit it to the latest 10
            if len(list(drift_table.rows())) > 10:
                drift_table.select_rows_by_indexes(*range(0, 10))
            else:
                drift_table.select_all()
        tb.select("Select up to 10 timestamps for Drift Analysis")

        # Make sure the section we need is active/open
        sec_loc_map = {
            'Properties': 'Properties',
            'Security': 'Security',
            'Configuration': 'Configuration',
            'My Company Tags': 'Categories'}
        active_sec_loc = "//div[@id='all_sections_treebox']//li[contains(@id, 'group_{}')]"\
            "/span[contains(@class, 'dynatree-selected')]".format(sec_loc_map[section])
        sec_checkbox_loc = "//div[@id='all_sections_treebox']//li[contains(@id, 'group_{}')]"\
            "//span[contains(@class, 'dynatree-checkbox')]".format(sec_loc_map[section])
        sec_apply_btn = "//div[@id='accordion']/a[contains(normalize-space(text()), 'Apply')]"

        # If the section is not active yet, activate it
        if not sel.is_displayed(active_sec_loc):
            sel.click(sec_checkbox_loc)
            sel.click(sec_apply_btn)

        if not tb.is_active("All attributes"):
            tb.select("All attributes")
        d_grid = DriftGrid()
        if any(d_grid.cell_indicates_change(row_text, i) for i in range(0, len(indexes))):
            return False
        return True

    def tag(self, tag, **kwargs):
        """Tags the system by given tag"""
        sel.force_navigate('infrastructure_host', context={'host': self})
        mixins.add_tag(tag, **kwargs)

    def untag(self, tag):
        """Removes the selected tag off the system"""
        sel.force_navigate('infrastructure_host', context={'host': self})
        mixins.remove_tag(tag)
コード例 #25
0
class Provider(BaseProvider, Pretty):
    pretty_attrs = ['name', 'key', 'zone']
    STATS_TO_MATCH = [
        'num_project', 'num_service', 'num_replication_controller', 'num_pod',
        'num_node', 'num_container', 'num_image'
    ]
    # TODO add 'num_image_registry' and 'num_volume'
    string_name = "Containers"
    page_name = "containers"
    detail_page_suffix = 'provider_detail'
    edit_page_suffix = 'provider_edit_detail'
    refresh_text = "Refresh items and relationships"
    quad_name = None
    _properties_region = prop_region  # This will get resolved in common to a real form
    add_provider_button = deferred_verpick({
        version.LOWEST:
        form_buttons.FormButton("Add this Containers Provider"),
        '5.6':
        form_buttons.add
    })
    save_button = deferred_verpick({
        version.LOWEST: form_buttons.save,
        '5.6': form_buttons.angular_save
    })

    def __init__(self,
                 name=None,
                 credentials=None,
                 key=None,
                 zone=None,
                 hostname=None,
                 port=None,
                 provider_data=None):
        if not credentials:
            credentials = {}
        self.name = name
        self.credentials = credentials
        self.key = key
        self.zone = zone
        self.hostname = hostname
        self.port = port
        self.provider_data = provider_data

    def _on_detail_page(self):
        """ Returns ``True`` if on the providers detail page, ``False`` if not."""
        ensure_browser_open()
        return sel.is_displayed(
            '//div//h1[contains(., "{} (Summary)")]'.format(self.name))

    def load_details(self, refresh=False):
        if not self._on_detail_page():
            self.navigate(detail=True)
        elif refresh:
            tb.refresh()

    def navigate(self, detail=True):
        if detail is True:
            if not self._on_detail_page():
                sel.force_navigate('containers_provider_detail',
                                   context={'provider': self})
        else:
            sel.force_navigate('containers_provider',
                               context={'provider': self})

    def get_detail(self, *ident):
        """ Gets details from the details infoblock

        Args:
            *ident: An InfoBlock title, followed by the Key name, e.g. "Relationships", "Images"
        Returns: A string representing the contents of the InfoBlock's value.
        """
        self.navigate(detail=True)
        return details_page.infoblock.text(*ident)

    @variable(alias='db')
    def num_project(self):
        return self._num_db_generic('container_projects')

    @num_project.variant('ui')
    def num_project_ui(self):
        return int(self.get_detail("Relationships", "Projects"))

    @variable(alias='db')
    def num_service(self):
        return self._num_db_generic('container_services')

    @num_service.variant('ui')
    def num_service_ui(self):
        return int(self.get_detail("Relationships", "Services"))

    @variable(alias='db')
    def num_replication_controller(self):
        return self._num_db_generic('container_replicators')

    @num_replication_controller.variant('ui')
    def num_replication_controller_ui(self):
        return int(self.get_detail("Relationships", "Replicators"))

    @variable(alias='db')
    def num_container_group(self):
        return self._num_db_generic('container_groups')

    @num_container_group.variant('ui')
    def num_container_group_ui(self):
        return int(self.get_detail("Relationships", "Pods"))

    @variable(alias='db')
    def num_pod(self):
        # potato tomato
        return self.num_container_group()

    @num_pod.variant('ui')
    def num_pod_ui(self):
        # potato tomato
        return self.num_container_group(method='ui')

    @variable(alias='db')
    def num_node(self):
        return self._num_db_generic('container_nodes')

    @num_node.variant('ui')
    def num_node_ui(self):
        return int(self.get_detail("Relationships", "Nodes"))

    @variable(alias='db')
    def num_container(self):
        # Containers are linked to providers through container definitions and then through pods
        res = cfmedb().engine.execute(
            "SELECT count(*) "
            "FROM ext_management_systems, container_groups, container_definitions, containers "
            "WHERE containers.container_definition_id=container_definitions.id "
            "AND container_definitions.container_group_id=container_groups.id "
            "AND container_groups.ems_id=ext_management_systems.id "
            "AND ext_management_systems.name='{}'".format(self.name))
        return int(res.first()[0])

    @num_container.variant('ui')
    def num_container_ui(self):
        return int(self.get_detail("Relationships", "Containers"))

    @variable(alias='db')
    def num_image(self):
        return self._num_db_generic('container_images')

    @num_image.variant('ui')
    def num_image_ui(self):
        return int(self.get_detail("Relationships", "Images"))

    @variable(alias='db')
    def num_image_registry(self):
        return self._num_db_generic('container_image_registries')

    @num_image_registry.variant('ui')
    def num_image_registry_ui(self):
        return int(self.get_detail("Relationships", "Image Registries"))
コード例 #26
0
ファイル: provider.py プロジェクト: vprusa/cfme_tests
class Provider(Pretty, CloudInfraProvider):
    """
    Abstract model of an infrastructure provider in cfme. See VMwareProvider or RHEVMProvider.

    Args:
        name: Name of the provider.
        details: a details record (see VMwareDetails, RHEVMDetails inner class).
        credentials (Credential): see Credential inner class.
        key: The CFME key of the provider in the yaml.
        candu: C&U credentials if this is a RHEVMDetails class.

    Usage:

        myprov = VMwareProvider(name='foo',
                             region='us-west-1',
                             credentials=Provider.Credential(principal='admin', secret='foobar'))
        myprov.create()

    """
    pretty_attrs = ['name', 'key', 'zone']
    STATS_TO_MATCH = [
        'num_template', 'num_vm', 'num_datastore', 'num_host', 'num_cluster'
    ]
    string_name = "Infrastructure"
    page_name = "infrastructure"
    instances_page_name = "infra_vm_and_templates"
    templates_page_name = "infra_vm_and_templates"
    quad_name = "infra_prov"
    properties_form = properties_form
    add_provider_button = form_buttons.FormButton(
        "Add this Infrastructure Provider")
    save_button = form_buttons.FormButton("Save Changes")

    def __init__(self,
                 name=None,
                 credentials=None,
                 key=None,
                 zone=None,
                 provider_data=None):
        if not credentials:
            credentials = {}
        self.name = name
        self.credentials = credentials
        self.key = key
        self.provider_data = provider_data
        self.zone = zone
        self.vm_name = version.pick({
            version.LOWEST: "VMs",
            '5.5': "VMs and Instances"
        })
        self.template_name = "Templates"

    def _form_mapping(self, create=None, **kwargs):
        return {'name_text': kwargs.get('name')}

    @variable(alias='db')
    def num_datastore(self):
        storage_table_name = version.pick({
            version.LOWEST: 'hosts_storages',
            '5.5.0.8': 'host_storages'
        })
        """ Returns the providers number of templates, as shown on the Details page."""

        results = list(cfmedb().engine.execute(
            'SELECT DISTINCT storages.name, hosts.ems_id '
            'FROM ext_management_systems, hosts, storages, {} '
            'WHERE hosts.id={}.host_id AND '
            'storages.id={}.storage_id AND '
            'hosts.ems_id=ext_management_systems.id AND '
            'ext_management_systems.name=\'{}\''.format(
                storage_table_name, storage_table_name, storage_table_name,
                self.name)))
        return len(results)

    @num_datastore.variant('ui')
    def num_datastore_ui(self):
        return int(self.get_detail("Relationships", "Datastores"))

    @variable(alias='rest')
    def num_host(self):
        provider = rest_api().collections.providers.find_by(name=self.name)[0]
        num_host = 0
        for host in rest_api().collections.hosts:
            if host['ems_id'] == provider.id:
                num_host += 1
        return num_host

    @num_host.variant('db')
    def num_host_db(self):
        ext_management_systems = cfmedb()["ext_management_systems"]
        hosts = cfmedb()["hosts"]
        hostlist = list(cfmedb().session.query(hosts.name).join(
            ext_management_systems,
            hosts.ems_id == ext_management_systems.id).filter(
                ext_management_systems.name == self.name))
        return len(hostlist)

    @num_host.variant('ui')
    def num_host_ui(self):
        return int(self.get_detail("Relationships", "host.png", use_icon=True))

    @variable(alias='rest')
    def num_cluster(self):
        provider = rest_api().collections.providers.find_by(name=self.name)[0]
        num_cluster = 0
        for cluster in rest_api().collections.clusters:
            if cluster['ems_id'] == provider.id:
                num_cluster += 1
        return num_cluster

    @num_cluster.variant('db')
    def num_cluster_db(self):
        """ Returns the providers number of templates, as shown on the Details page."""
        ext_management_systems = cfmedb()["ext_management_systems"]
        clusters = cfmedb()["ems_clusters"]
        clulist = list(cfmedb().session.query(clusters.name).join(
            ext_management_systems,
            clusters.ems_id == ext_management_systems.id).filter(
                ext_management_systems.name == self.name))
        return len(clulist)

    @num_cluster.variant('ui')
    def num_cluster_ui(self):
        return int(
            self.get_detail("Relationships", "cluster.png", use_icon=True))

    def discover(self):
        """
        Begins provider discovery from a provider instance

        Usage:
            discover_from_config(utils.providers.get_crud('rhevm'))
        """
        vmware = isinstance(self, VMwareProvider)
        rhevm = isinstance(self, RHEVMProvider)
        scvmm = isinstance(self, SCVMMProvider)
        discover(rhevm,
                 vmware,
                 scvmm,
                 cancel=False,
                 start_ip=self.start_ip,
                 end_ip=self.end_ip)

    @property
    def hosts(self):
        """Returns list of :py:class:`cfme.infrastructure.host.Host` that should belong to this
        provider according to the YAML
        """
        result = []
        for host in self.get_yaml_data().get("hosts", []):
            creds = conf.credentials.get(host["credentials"], {})
            cred = Host.Credential(
                principal=creds["username"],
                secret=creds["password"],
                verify_secret=creds["password"],
            )
            result.append(Host(name=host["name"], credentials=cred))
        return result
コード例 #27
0
class HawkularProvider(MiddlewareBase, BaseProvider):
    """
    HawkularProvider class holds provider data. Used to perform actions on hawkular provider page

    Args:
        name: Name of the provider
        hostname: Hostname/IP of the provider
        port: http/https port of hawkular provider
        credentials: see Credential inner class.
        key: The CFME key of the provider in the yaml.

    Usage:

        myprov = HawkularProvider(name='foo',
                            hostname='localhost',
                            port=8080,
                            credentials=Provider.Credential(principal='admin', secret='foobar')))
        myprov.create()
        myprov.num_deployment(method="ui")
    """
    STATS_TO_MATCH = ['num_server', 'num_deployment', 'num_datasource']
    property_tuples = [('name', 'name'), ('hostname', 'host_name'),
                       ('port', 'port'), ('provider_type', 'type')]

    page_name = 'middleware'
    string_name = 'Middleware'
    detail_page_suffix = 'provider_detail'
    edit_page_suffix = 'provider_edit_detail'
    refresh_text = "Refresh items and relationships"
    quad_name = None
    _properties_form = properties_form
    add_provider_button = form_buttons.FormButton(
        "Add this Middleware Provider")
    save_button = form_buttons.FormButton("Save Changes")

    def __init__(self,
                 name=None,
                 hostname=None,
                 port=None,
                 credentials=None,
                 key=None):
        self.name = name
        self.hostname = hostname
        self.port = port
        self.provider_type = 'Hawkular'
        if not credentials:
            credentials = {}
        self.credentials = credentials
        self.key = key

    def _form_mapping(self, create=None, **kwargs):
        return {
            'name_text': kwargs.get('name'),
            'type_select': create and 'Hawkular',
            'hostname_text': kwargs.get('hostname'),
            'port_text': kwargs.get('port')
        }

    @variable(alias='db')
    def num_deployment(self):
        return self._num_db_generic('middleware_deployments')

    @num_deployment.variant('ui')
    def num_deployment_ui(self, reload_data=True):
        if reload_data:
            self.summary.reload()
        return self.summary.relationships.middleware_deployments.value

    @variable(alias='db')
    def num_server(self):
        return self._num_db_generic('middleware_servers')

    @num_server.variant('ui')
    def num_server_ui(self, reload_data=True):
        if reload_data:
            self.summary.reload()
        return self.summary.relationships.middleware_servers.value

    @variable(alias='db')
    def num_datasource(self):
        return self._num_db_generic('middleware_datasources')

    @num_datasource.variant('ui')
    def num_datasource_ui(self, reload_data=True):
        if reload_data:
            self.summary.reload()
        return self.summary.relationships.middleware_datasources.value

    @variable(alias='ui')
    def is_refreshed(self, reload_data=True):
        if reload_data:
            self.summary.reload()
        if re.match('Success.*Minute.*Ago',
                    self.summary.status.last_refresh.text_value):
            return True
        else:
            return False

    @is_refreshed.variant('db')
    def is_refreshed_db(self):
        ems = cfmedb()['ext_management_systems']
        dates = cfmedb().session.query(
            ems.created_on,
            ems.updated_on).filter(ems.name == self.name).first()
        return dates.updated_on > dates.created_on
コード例 #28
0
import pytest

from textwrap import dedent

from cfme.automate.buttons import ButtonGroup, Button
from cfme.automate.explorer import Namespace, Class, Instance, Domain, Method
from cfme.automate.service_dialogs import ServiceDialog
from cfme.common.vm import VM
from cfme.web_ui import fill, flash, form_buttons, toolbar, Input
from utils import testgen
from utils.blockers import BZ
from utils.log import logger
from utils.providers import setup_provider
from utils.wait import wait_for

submit = form_buttons.FormButton("Submit")
pytestmark = [
    pytest.mark.meta(server_roles="+automate"),
    pytest.mark.ignore_stream("upstream", "5.2")
]


def pytest_generate_tests(metafunc):
    argnames, argvalues, idlist = testgen.provider_by_type(
        metafunc, ['virtualcenter'], 'provisioning')
    metafunc.parametrize(argnames, argvalues, ids=idlist, scope='module')


@pytest.yield_fixture(scope="module")
def domain(request):
    domain = Domain(name=fauxfactory.gen_alphanumeric(), enabled=True)
コード例 #29
0
ファイル: access_control.py プロジェクト: vprusa/cfme_tests
class Tenant(Updateable, Pretty):
    """ Class representing CFME tenants in the UI.
    * Kudos to mfalesni *

    The behaviour is shared with Project, which is the same except it cannot create more nested
    tenants/projects.

    Args:
        name: Name of the tenant
        description: Description of the tenant
        parent_tenant: Parent tenant, can be None, can be passed as string or object
    """
    save_changes = form_buttons.FormButton("Save changes")
    tenant_form = Form(
        fields=[('name', Input('name')), ('description',
                                          Input('description'))])
    pretty_attrs = ["name", "description"]

    @classmethod
    def get_root_tenant(cls):
        return cls(name="My Company", _default=True)

    def __init__(self,
                 name=None,
                 description=None,
                 parent_tenant=None,
                 _default=False):
        self.name = name
        self.description = description
        self.parent_tenant = parent_tenant
        self._default = _default

    @property
    def parent_tenant(self):
        if self._default:
            return None
        if self._parent_tenant:
            return self._parent_tenant
        return self.get_root_tenant()

    @parent_tenant.setter
    def parent_tenant(self, tenant):
        if tenant is not None and isinstance(tenant, Project):
            # If we try to
            raise ValueError("Project cannot be a parent object.")
        if isinstance(tenant, basestring):
            # If parent tenant is passed as string,
            # we assume that tenant name was passed instead of object
            tenant = Tenant(tenant)
        self._parent_tenant = tenant

    def __eq__(self, other):
        if not isinstance(other, type(self)):
            return False
        else:
            return self.name == other.name

    @property
    def exists(self):
        try:
            sel.force_navigate("cfg_tenant_project", context={"tenant": self})
        except CandidateNotFound:
            return False
        else:
            return True

    @property
    def tree_path(self):
        if self._default:
            return [self.name]
        else:
            return self.parent_tenant.tree_path + [self.name]

    @property
    def parent_path(self):
        return self.tree_path[:-1]

    def create(self, cancel=False):
        sel.force_navigate("cfg_tenant_project_create",
                           context={"tenant": self})
        fill(self.tenant_form, self, action=form_buttons.add)
        if type(self) is Tenant:
            flash.assert_success_message('Tenant "{}" was saved'.format(
                self.name))
        elif type(self) is Project:
            flash.assert_success_message('Project "{}" was saved'.format(
                self.name))
        else:
            raise TypeError(
                'No Tenant or Project class passed to create method{}'.format(
                    type(self).__name__))

    def update(self, updates):
        sel.force_navigate("cfg_tenant_project_edit", context={"tenant": self})
        # Workaround - without this, update was failing sometimes
        sel.wait_for_ajax()
        # Workaround - form is appearing after short delay
        sel.wait_for_element(self.tenant_form.description)
        fill(self.tenant_form, updates, action=self.save_changes)
        flash.assert_success_message('Project "{}" was saved'.format(
            updates.get('name', self.name)))

    def delete(self, cancel=False):
        sel.force_navigate("cfg_tenant_project", context={"tenant": self})
        tb_select("Delete this item", invokes_alert=True)
        sel.handle_alert(cancel=cancel)
        flash.assert_success_message('Tenant "{}": Delete successful'.format(
            self.description))
コード例 #30
0
ファイル: menus.py プロジェクト: vrutkovs/cfme_tests
})

manager = FolderManager("//div[@id='folder_lists']/table")
report_select = MultiBoxSelect(
    "//select[@id='available_reports']",
    "//select[@id='selected_reports']",
    "//a[@title='Move selected reports right']/img",
    "//a[@title='Move selected reports left']/img",
)

buttons = Region(locators=dict(
    commit="//a[@title='Commit report management changes']/img",
    discard="//a[@title='Discard report management changes']/img",
))

default_button = form_buttons.FormButton("Reset All menus to CFME defaults")


def get_folders(group):
    """Returns list of folders for given user group.

    Args:
        group: User group to check.
    """
    sel.force_navigate("report_menus_group", context={"group": group})
    reports_tree.click_path("Top Level")
    return manager.fields


def get_subfolders(group, folder):
    """Returns list of sub-folders for given user group and folder.