Exemple #1
0
class Class(CopiableTreeNode, Updateable):
    """Represents a Class in the CFME ui.

    Providing a setup_schema dict, creates the Class with teh specified schema

    """

    form = Form(
        fields=[('name_text',
                 Input('name')), ('display_name_text', Input('display_name')
                                  ), ('description_text',
                                      Input('description')),
                ('inherits_from_select',
                 Select("//select[@name='inherits_from']"))])

    def __init__(self,
                 name=None,
                 display_name=None,
                 description=None,
                 inherits_from=None,
                 namespace=None,
                 setup_schema=None):
        self.name = name
        self.display_name = display_name
        self.description = description
        self.inherits_from = inherits_from
        self.namespace = namespace
        self.setup_schema = setup_schema

    @property
    def parent(self):
        return self.namespace

    @parent.setter
    def parent(self, p):
        self.namespace = p

    @property
    def name_in_tree(self):
        """The item is displayed differently with display_name"""
        if self.display_name:
            return "{} ({})".format(self.display_name, self.name)
        else:
            return self.name

    @property
    def name_in_table(self):
        """The item is displayed differently with display_name"""
        if self.display_name:
            return self.display_name
        else:
            return self.name

    def path_str(self):
        """Returns string path to this class, eg ns1/ns2/ThisClass"""
        path = self.path
        path[-1] = self.name  # override the display_name madness
        path = "/".join(path)
        if version.current_version() < "5.4":
            return path
        else:
            return "/" + path  # Starts with / from 5.4 onwards because of domains

    def create(self, cancel=False):
        if self.parent is not None and not self.parent.exists():
            self.parent.create()
        sel.force_navigate("automate_explorer_class_new",
                           context={"tree_item": self.namespace})
        fill(self.form, {
            'name_text':
            self.name,
            'description_text':
            self.description,
            'display_name_text':
            self.display_name,
            'inherits_from_select':
            self.inherits_from and self.inherits_from.path_str()
        },
             action=form_buttons.cancel if cancel else form_buttons.add)
        flash.assert_success_message('Automate Class "%s" was added' %
                                     self.path_str())
        if self.setup_schema:
            self.edit_schema(add_fields=self.setup_schema)

    def update(self, updates, cancel=False):
        sel.force_navigate("automate_explorer_edit",
                           context={
                               "tree_item": self.parent,
                               "table_item": self
                           })
        update_values = {
            'name_text':
            updates.get('name'),
            'description_text':
            updates.get('description'),
            'inherits_from_select':
            updates.get('inherits_from')
            and updates.get('inherits_from').path_str()
        }
        if "display_name" in updates:
            # We need to specifically override the display_name
            update_values["display_name_text"] = updates[
                "display_name"] or ""  # None -> emptystr
        fill(self.form,
             update_values,
             action=form_buttons.cancel if cancel else form_buttons.save)

    def delete(self, cancel=False):
        sel.force_navigate("automate_explorer_delete",
                           context={
                               'tree_item': self.parent,
                               'table_item': self
                           })
        sel.handle_alert(cancel)
        return flash.assert_no_errors()

    class SchemaField(Updateable):
        def __init__(self,
                     name=None,
                     type_=None,
                     data_type=None,
                     default_value=None,
                     display_name=None,
                     description=None,
                     sub=None,
                     collect=None,
                     message=None,
                     on_entry=None,
                     on_exit=None,
                     on_error=None,
                     max_retries=None,
                     max_time=None):
            self.name = name
            self.type_ = type_
            self.data_type = data_type
            self.default_value = default_value
            self.display_name = display_name
            self.description = description
            self.sub = sub
            self.collect = collect
            self.message = message
            self.on_entry = on_entry
            self.on_exit = on_exit
            self.on_error = on_error
            self.max_retries = max_retries
            self.max_time = max_time

        def get_form(self, blank=False):
            """Gets a form for a field that already exists (by its name). Or if
               blank=True, get the form for a new field.  Must be on
               the correct page before calling this.
            """
            idx = ""
            if blank:
                row_id = ""  # for new entries, id attribute has no trailing '_x'
            else:
                idx = sel.get_attribute(
                    "//input[starts-with(@id, 'fields_name') and @value='%s']"
                    % self.name, 'id').split("_")[2]
                row_id = "_" + idx

            def loc(fmt):
                if blank:
                    plural = ""
                else:
                    plural = "s"
                return fmt % (plural, row_id)

            def remove(loc):
                """Return a callable that clicks but still allows popup dismissal"""
                return lambda _: sel.click(loc, wait_ajax=False)

            return Form(fields=[
                ('name_text', Input(loc('field%s_name%s'))),
                ('type_select',
                 DHTMLSelect(loc("//div[@id='field%s_aetype_id%s']"))),
                ('data_type_select',
                 DHTMLSelect(loc("//div[@id='field%s_datatype_id%s']"))),
                ('default_value_text', Input(loc('field%s_default_value%s'))),
                ('display_name_text', Input(loc('field%s_display_name%s'))
                 ), ('description_text', Input(loc('field%s_description%s'))
                     ), ('sub_cb', Input(loc('field%s_substitution%s'))
                         ), ('collect_text', Input(loc('field%s_collect%s'))),
                ('message_text', Input(loc('field%s_message%s'))
                 ), ('on_entry_text', Input(loc('field%s_on_entry%s'))
                     ), ('on_exit_text', Input(loc('field%s_on_exit%s'))),
                ('max_retries_text', Input(loc('field%s_max_retries%s'))
                 ), ('max_time_text', Input(loc('field%s_max_time%s'))
                     ), ('add_entry_button', "//img[@alt='Add this entry']"),
                ('remove_entry_button',
                 remove("//a[contains(@title, 'delete this') "
                        "and contains(@href, 'arr_id=%s')]/img" % idx))
            ])

    schema_edit_page = Region(
        locators={'add_field_btn': "//img[@alt='Equal-green']"})

    def edit_schema(self, add_fields=None, remove_fields=None):
        sel.force_navigate("automate_explorer_schema_edit",
                           context={'tree_item': self})
        for remove_field in remove_fields or []:
            f = remove_field.get_form()
            fill(f, {}, action=f.remove_entry_button, action_always=True)
            sel.handle_alert()

        for add_field in add_fields or []:
            sel.click(self.schema_edit_page.add_field_btn)
            f = add_field.get_form(blank=True)
            fill(f, {
                'name_text': add_field.name,
                'type_select': add_field.type_,
                'data_type_select': add_field.data_type,
                'default_value_text': add_field.default_value,
                'description_text': add_field.description,
                'sub_cb': add_field.sub,
                'collect_text': add_field.collect,
                'message_text': add_field.message,
                'on_entry_text': add_field.on_entry,
                'on_exit_text': add_field.on_exit,
                'max_retries_text': add_field.max_retries,
                'max_time_text': add_field.max_time
            },
                 action=f.add_entry_button)

        sel.click(form_buttons.save)
        flash.assert_success_message(
            'Schema for Automate Class "%s" was saved' % self.name)
Exemple #2
0
 "Styling": [
     ("column_styles", ColumnStyleTable("styling_div")),
 ],
 "Filter": [
     ("filter", Expression()),
     ("filter_show_costs", select(id="cb_show_typ")),
     ("filter_owner", select(id="cb_owner_id")),
     ("filter_tag_cat", select(id="cb_tag_cat")),
     ("filter_tag_value", select(id="cb_tag_value")),
 ],
 "Summary": [
     ("sort",
      ShowingInputs(
          Form(fields=[
              ("by", select(id="chosen_sort1")),
              ("order", select(id="sort_order")),
              ("breaks", select(id="sort_group")),
          ]),
          Form(fields=[
              ("by", select(id="chosen_sort2")),
              ("limit", select(id="row_limit")),
          ]),
      )),
 ],
 "Charts": [
     ("chart_type", select(id="chosen_graph")),
     ("top_values", select(id="chosen_count")),
     ("sum_other", input(id="chosen_other")),
 ],
 "Timeline": [
     ("base_timeline_on", select(id="chosen_tl")),
Exemple #3
0
            lambda ctx: sel.click(Quadicon(ctx['provider'].name, None)), {
                'containers_provider_edit_detail':
                lambda _: cfg_btn('Edit this Containers Provider'),
                'containers_provider_timelines_detail':
                lambda _: mon_btn('Timelines'),
                'containers_provider_edit_tags_detail':
                lambda _: pol_btn('Edit Tags'),
                'containers_provider_topology_detail':
                lambda _: sel.click(InfoBlock('Overview', 'Topology'))
            }
        ]
    })

properties_form = Form(fields=[(
    'type_select',
    AngularSelect('server_emstype')), (
        'name_text',
        Input('name')), ('hostname_text',
                         Input('hostname')), ('port_text', Input('port'))])

properties_form_56 = TabStripForm(
    fields=[('type_select', AngularSelect('ems_type')),
            ('name_text', Input('name'))],
    tab_fields={
        "Default": [
            ('hostname_text', Input("default_hostname")),
            ('port_text', Input("default_api_port")),
            ('sec_protocol', AngularSelect("default_security_protocol")),
        ],
        "Hawkular": [('hawkular_hostname', Input("hawkular_hostname")),
                     ('hawkular_api_port', Input("hawkular_api_port"))],
    })
Exemple #4
0
from cfme.common.provider import CloudInfraProvider
from cfme.web_ui.menu import nav
from cfme.web_ui import Region, Quadicon, Form, Select, fill, paginator, AngularSelect, Radio
from cfme.web_ui import Input
from cfme.web_ui.tabstrip import TabStripForm
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_55 = Form(fields=[
    ('type_select', {
        version.LOWEST: Select('select#server_emstype'),
        '5.5': AngularSelect("emstype")
    }),
    ('azure_tenant_id', Input("azure_tenant_id")),
    ('name_text', Input("name")),
    ('azure_region_select', AngularSelect("provider_region")),
    ('hostname_text', Input("hostname")),
    ('ipaddress_text', Input("ipaddress"), {
        "removed_since": "5.4.0.0.15"
"""Provisioning-related forms and helper classes.

"""
from collections import OrderedDict

from cfme.fixtures import pytest_selenium as sel
from cfme.web_ui import Calendar, Form, Radio, Select, Table, Tree, form_buttons, tabstrip, toolbar
from cfme.web_ui.menu import nav

submit_button = form_buttons.FormButton("Submit")

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

provisioning_form = tabstrip.TabStripForm(
    fields=[('submit_button', submit_button),
            ('cancel_button', form_buttons.cancel)],
    tab_fields=OrderedDict([
        ('Request', [
            ('email', '//input[@name="requester__owner_email"]'),
            ('first_name', '//input[@id="requester__owner_first_name"]'),
            ('last_name', '//input[@id="requester__owner_last_name"]'),
            ('notes', '//textarea[@id="requester__request_notes"]'),
            ('manager_name', '//input[@id="requester__owner_manager"]'),
        ]),
        ('Purpose', [
            ('apply_tags', Tree('//div[@id="all_tags_treebox"]//table')),
        ]),
Exemple #6
0
class VM(BaseVM):
    TO_RETIRE = None

    retire_form = Form(fields=[
        ('date_retire',
            AngularCalendarInput("retirement_date",
                                 "//label[contains(normalize-space(.), 'Retirement Date')]")),
        ('warn', AngularSelect('retirementWarning'))
    ])

    def retire(self):
        self.load_details(refresh=True)
        lcl_btn(self.TO_RETIRE, invokes_alert=True)
        sel.handle_alert()
        flash.assert_success_message(
            'Retirement initiated for 1 VM and Instance from the {} Database'.format(version.pick({
                version.LOWEST: 'CFME',
                'upstream': 'ManageIQ'})))

    def power_control_from_provider(self):
        raise NotImplementedError("You have to implement power_control_from_provider!")

    def power_control_from_cfme(self, option, cancel=True, from_details=False):
        """Power controls a VM from within CFME

        Args:
            option: corresponds to option values under the power button
            cancel: Whether or not to cancel the power operation on confirmation
            from_details: Whether or not to perform action from instance details page

        Raises:
            OptionNotAvailable: option param is not visible or enabled
        """
        if (self.is_pwr_option_available_in_cfme(option=option, from_details=from_details)):
                pwr_btn(option, invokes_alert=True)
                sel.handle_alert(cancel=cancel, check_present=True)
                logger.info(
                    "Power control action of VM/instance %s, option %s, cancel %s executed",
                    self.name, option, str(cancel))
        else:
            raise OptionNotAvailable(option + " is not visible or enabled")

    def wait_candu_data_available(self, timeout=600):
        """Waits until C&U data are available for this VM/Instance

        Args:
            timeout: Timeout passed to :py:func:`utils.wait.wait_for`
        """
        self.load_details(refresh=True)
        wait_for(
            lambda: not toolbar.is_greyed('Monitoring', 'Utilization'),
            delay=10, handle_exception=True, num_sec=timeout,
            fail_func=lambda: toolbar.refresh())

    def wait_for_vm_state_change(self, desired_state=None, timeout=300, from_details=False,
                                 with_relationship_refresh=True, from_any_provider=False):
        """Wait for M to come to desired state.

        This function waits just the needed amount of time thanks to wait_for.

        Args:
            desired_state: on, off, suspended... for available states, see
                           :py:class:`EC2Instance` and :py:class:`OpenStackInstance`
            timeout: Specify amount of time (in seconds) to wait
            from_any_provider: Archived/Orphaned vms need this
        Raises:
            TimedOutError:
                When instance does not come up to desired state in specified period of time.
            InstanceNotFound:
                When unable to find the instance passed
        """
        detail_t = ("Power Management", "Power State")

        def _looking_for_state_change():
            if from_details:
                self.load_details(refresh=True)
                return self.get_detail(properties=detail_t) == desired_state
            else:
                return 'currentstate-' + desired_state in self.find_quadicon(
                    from_any_provider=from_any_provider).state

        return wait_for(
            _looking_for_state_change,
            num_sec=timeout,
            delay=30,
            fail_func=lambda: self.refresh_relationships(from_details=from_details,
                                                         from_any_provider=from_any_provider) if
            with_relationship_refresh else None)

    def is_pwr_option_available_in_cfme(self, option, from_details=False):
        """Checks to see if a power option is available on the VM

        Args:
            option: corresponds to option values under the power button,
                    see :py:class:`EC2Instance` and :py:class:`OpenStackInstance`
            from_details: Whether or not to perform action from instance details page
        """
        if from_details:
            self.load_details(refresh=True)
        else:
            self.find_quadicon(mark=True)
        try:
            return not toolbar.is_greyed('Power', option)
        except sel.NoSuchElementException:
            return False

    def delete_from_provider(self):
        logger.info("Begin delete_from_provider")
        if self.provider.mgmt.does_vm_exist(self.name):
            try:
                if self.provider.mgmt.is_vm_suspended(self.name) and self.provider.type != 'azure':
                    logger.debug("Powering up VM %s to shut it down correctly on %s.",
                                self.name, self.provider.key)
                    self.provider.mgmt.start_vm(self.name)
                    self.provider.mgmt.wait_vm_steady(self.name)
                    self.provider.mgmt.stop_vm(self.name)
                    self.provider.mgmt.wait_vm_steady(self.name)
            except exceptions.ActionNotSupported:
                # Action is not supported on mgmt system. Simply continue
                pass
            # One more check (for the suspended one)
            if self.provider.mgmt.does_vm_exist(self.name):
                try:
                    logger.info("Mgmt System delete_vm")
                    return self.provider.mgmt.delete_vm(self.name)
                except exceptions.VMInstanceNotFound:
                    # Does not exist already
                    return True
        else:
            return True

    def create_on_provider(self, timeout=900, find_in_cfme=False, **kwargs):
        """Create the VM on the provider

        Args:
            timeout: Number of seconds to wait for the VM to appear in CFME
                     Will not wait at all, if set to 0 (Defaults to ``900``)
        """
        deploy_template(self.provider.key, self.name, self.template_name, **kwargs)
        if find_in_cfme:
            self.provider.refresh_provider_relationships()
            self.wait_to_appear(timeout=timeout, load_details=False)

    def does_vm_exist_on_provider(self):
        """Check if VM exists on provider itself"""
        return self.provider.mgmt.does_vm_exist(self.name)

    def set_retirement_date(self, when, warn=None):
        """Sets the retirement date for this Vm object.

        It incorporates some magic to make it work reliably since the retirement form is not very
        pretty and it can't be just "done".

        Args:
            when: When to retire. :py:class:`str` in format mm/dd/yyyy of
                :py:class:`datetime.datetime` or :py:class:`utils.timeutil.parsetime`.
            warn: When to warn, fills the select in the form in case the ``when`` is specified.
        """
        # TODO: refactor for retirement nav destinations and widget form fill when child classes
        self.load_details()
        lcl_btn("Set Retirement Date")
        if callable(self.retire_form.date_retire):
            # It is the old functiton
            sel.wait_for_element("#miq_date_1")
        else:
            sel.wait_for_element(self.retire_form.date_retire)
        if when is None:
            try:
                wait_for(lambda: sel.is_displayed(retire_remove_button), num_sec=5, delay=0.2)
                sel.click(retire_remove_button)
                wait_for(lambda: not sel.is_displayed(retire_remove_button), num_sec=10, delay=0.2)
                sel.click(form_buttons.save)
            except TimedOutError:
                pass
        else:
            if sel.is_displayed(retire_remove_button):
                sel.click(retire_remove_button)
                wait_for(lambda: not sel.is_displayed(retire_remove_button), num_sec=15, delay=0.2)
            fill(self.retire_form.date_retire, when)
            wait_for(lambda: sel.is_displayed(retire_remove_button), num_sec=15, delay=0.2)
            if warn is not None:
                fill(self.retire_form.warn, warn)
            sel.click(form_buttons.save)

    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 will 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
        self.load_details(refresh=True)
        sel.click(InfoBlock("Properties", "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, min(10, len)))
            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_apply_btn = "//div[@id='accordion']/a[contains(normalize-space(text()), 'Apply')]"

        # Deselect other sections
        for other_section in drift_section.child_items():
            drift_section.check_node(other_section.text)
            drift_section.uncheck_node(other_section.text)

        # Activate the required section
        drift_section.check_node(section)
        sel.click(sec_apply_btn)

        if not tb.is_active("All attributes"):
            tb.select("All attributes")
        drift_grid = DriftGrid()
        if any(drift_grid.cell_indicates_change(row_text, i) for i in range(0, len(indexes))):
            return False
        return True
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',
             Input('snap_memory')), (
                 'create_button',
                 create_button), ('cancel_button', form_buttons.cancel)])

retirement_date_form = Form(
    fields=[('retirement_date_text', Calendar("miq_date_1")),
            ('retirement_warning_select',
             Select("//select[@id='retirement_warn']"))])

retire_remove_button = "//span[@id='remove_button']/a/img"
Exemple #8
0
    query = current_appliance.db.client.session.query(t_ems.id, t_ems.name, t_ems.type)
    if name:
        query = query.filter(t_ems.name == name)
    if type:
        query = query.filter(t_ems.type == type)
    return query


def _get_providers_page():
    navigate_to(MiddlewareProvider, 'All')


properties_form = Form(
    fields=[
        ('type_select', AngularSelect('emstype')),
        ('name_text', Input('name')),
        ('sec_protocol', AngularSelect('default_security_protocol', exact=True)),
        ('hostname_text', Input('default_hostname')),
        ('port_text', Input('default_api_port'))
    ])

properties_form_57 = Form(
    fields=[
        ('type_select', AngularSelect('emstype')),
        ('name_text', Input('name')),
        ('hostname_text', Input('default_hostname')),
        ('port_text', Input('default_api_port'))
    ])


prop_region = Region(
    locators={
    })

# Page specific locators
list_page = Region(title='Instances')

edit_page = Region(
    locators={
        'save_btn': "//img[@title='Save Changes']",
        'reset_btn': "//img[@title='Reset Changes']",
        'cancel_btn': "//img[@title='Cancel']",
    })

details_page = Region(infoblock_type='detail')

policy_page = Region(
    locators={
        'policy_tree': Tree('//div[@class="containerTableStyle"]/table')
    })

# Forms
edit_form = Form(fields=[
    ('custom_ident', "//*[@id='custom_1']"),
    ('description_tarea', "//textarea[@id='description']"),
    ('parent_sel', "//*[@id='chosen_parent']"),
    ('child_sel', Select("//select[@id='kids_chosen']", multi=True)),
    ('vm_sel', Select("//select[@id='choices_chosen']", multi=True)),
    ('add_btn', "//img[@alt='Move selected VMs to left']"),
    ('remove_btn', "//img[@alt='Move selected VMs to right']"),
    ('remove_all_btn', "//img[@alt='Move all VMs to right']"),
])
class User(Updateable, Pretty):
    user_form = Form(
        fields=[
            ('name_txt', Input('name')),
            ('userid_txt', Input('userid')),
            ('password_txt', Input('password')),
            ('password_verify_txt', Input('password2')),
            ('email_txt', Input('email')),
            ('user_group_select', Select("//*[@id='chosen_group']")),
        ])

    pretty_attrs = ['name', 'group']

    def __init__(self, name=None, credential=None, email=None,
                 group=None, cost_center=None, value_assign=None):
        self.name = name
        self.credential = credential
        self.email = email
        self.group = group
        self.cost_center = cost_center
        self.value_assign = value_assign

    def create(self):
        sel.force_navigate('cfg_accesscontrol_user_add')
        fill(self.user_form, {'name_txt': self.name,
                              'userid_txt': self.credential.principal,
                              'password_txt': self.credential.secret,
                              'password_verify_txt': self.credential.verify_secret,
                              'email_txt': self.email,
                              'user_group_select': getattr(self.group,
                                                           'description', None)},
             action=form_buttons.add)
        flash.assert_success_message('User "%s" was saved' % self.name)

    def update(self, updates):
        sel.force_navigate("cfg_accesscontrol_user_edit", context={"user": self})
        fill(self.user_form, {'name_txt': updates.get('name'),
                              'userid_txt': updates.get('credential').principal,
                              'password_txt': updates.get('credential').secret,
                              'password_verify_txt': updates.get('credential').verify_secret,
                              'email_txt': updates.get('email'),
                              'user_group_select': getattr(updates.get('group'),
                                                           'description', None)},
             action=form_buttons.save)
        flash.assert_success_message(
            'User "%s" was saved' % updates.get('name', self.name))

    def copy(self):
        sel.force_navigate("cfg_accesscontrol_user_ed", context={"user": self})
        tb.select('Configuration', 'Copy this User to a new User')
        new_user = User(name=self.name + "copy",
                        credential=cfme.Credential(principal='redhat', secret='redhat'))

        fill(self.user_form, {'name_txt': new_user.name,
                              'userid_txt': new_user.credential.principal,
                              'password_txt': new_user.credential.secret,
                              'password_verify_txt': new_user.credential.verify_secret},
             action=form_buttons.add)
        flash.assert_success_message('User "%s" was saved' % new_user.name)
        return new_user

    def delete(self):
        sel.force_navigate("cfg_accesscontrol_user_ed", context={"user": self})
        tb.select('Configuration', 'Delete this User', invokes_alert=True)
        sel.handle_alert()
        flash.assert_success_message('EVM User "%s": Delete successful' % self.name)

    def edit_tags(self, tag, value):
        sel.force_navigate("cfg_accesscontrol_user_ed", context={"user": self})
        pol_btn("Edit 'My Company' Tags for this User", invokes_alert=True)
        fill(edit_tags_form, {'select_tag': tag,
                              'select_value': value},
             action=form_buttons.save)
        flash.assert_success_message('Tag edits were successfully saved')

    def remove_tag(self, tag, value):
        sel.force_navigate("cfg_accesscontrol_user_ed", context={"user": self})
        pol_btn("Edit 'My Company' Tags for this User", invokes_alert=True)
        row = tag_table.find_row_by_cells({'category': tag, 'assigned_value': value},
            partial_check=True)
        sel.click(row[0])
        form_buttons.save()
        flash.assert_success_message('Tag edits were successfully saved')

    @property
    def description(self):
        return self.credential.principal
Exemple #11
0
    flash, form_buttons, menu, tabstrip, DHTMLSelect, Input, Tree, AngularSelect
from cfme.web_ui import toolbar as tb
from utils.update import Updateable
from utils.pretty import Pretty
from utils.version import current_version
from utils import version

cfg_btn = partial(tb.select, "Configuration")
accordion_tree = partial(accordion.tree, "Catalog Items")
policy_btn = partial(tb.select, "Policy")
dynamic_tree = Tree("//div[@id='basic_info_div']//ul[@class='dynatree-container']")

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

# Forms
basic_info_form = Form(
    fields=[
        ('name_text', Input("name")),
        ('description_text', Input("description")),
        ('display_checkbox', Input("display")),
        ('select_catalog', Select("//select[@id='catalog_id']")),
        ('select_dialog', Select("//select[@id='dialog_id']")),
        ('select_orch_template', Select("//select[@id='template_id']")),
        ('select_provider', Select("//select[@id='manager_id']")),
        ('field_entry_point', Input("fqname")),
Exemple #12
0
from functools import partial
from cfme import web_ui as ui
from cfme.exceptions import CandidateNotFound
from cfme.fixtures import pytest_selenium as sel
from cfme.web_ui import Form, accordion, fill, flash, form_buttons, menu, DHTMLSelect, AngularSelect
from cfme.web_ui import toolbar as tb
from utils.update import Updateable
from utils import deferred_verpick, version

cfg_btn = partial(tb.select, "Configuration")
buttons_tree = partial(accordion.tree, "Buttons", "Object Types")

button_group_form = Form(
    fields=[('btn_group_text',
             ui.Input('name')), (
                 'btn_group_hvr_text',
                 ui.Input('description')), (
                     'add_button',
                     form_buttons.add), ('save_button', form_buttons.save)])

button_form = Form(
    fields=[('btn_text',
             ui.Input('name')), ('btn_hvr_text', ui.Input('description')),
            ('select_dialog', ui.Select('select#dialog_id')
             ), ('system_process', ui.Select('select#instance_name')),
            ('request',
             ui.Input('object_request')), (
                 'add_button',
                 form_buttons.add), ('save_button', form_buttons.save)])

Exemple #13
0
class Instance(CopiableTreeNode, Updateable):
    """Represents a Instance in the CFME ui."""

    form = Form(fields=[(
        'name_text', "//input[contains(@name,'inst_name')]"
    ), ('display_name_text', "//input[contains(@name,'inst_display_name')]"
        ), ('description_text', "//input[contains(@name,'inst_description')]"
            ), ('values', InstanceFields())])

    def __init__(self,
                 name=None,
                 display_name=None,
                 description=None,
                 values=None,
                 cls=None):
        self.name = name
        self.description = description
        self.values = values
        self.display_name = display_name
        self.cls = cls

    @property
    def name_in_tree(self):
        """The item is displayed differently with display_name"""
        if self.display_name:
            return "{} ({})".format(self.display_name, self.name)
        else:
            return self.name

    @property
    def name_in_table(self):
        """The item is displayed differently with display_name"""
        if self.display_name:
            return self.display_name
        else:
            return self.name

    @property
    def parent(self):
        return self.cls

    @parent.setter
    def parent(self, p):
        self.cls = p

    def create(self, cancel=False):
        if self.parent is not None and not self.parent.exists():
            self.parent.create()
        sel.force_navigate("automate_explorer_instance_new",
                           context={'tree_item': self.cls})
        fill(self.form, {
            'name_text': self.name,
            'display_name_text': self.display_name,
            'description_text': self.description,
            'values': self.values
        },
             action=form_buttons.cancel if cancel else form_buttons.add)
        try:
            flash.assert_success_message('Automate Instance "%s" was added' %
                                         self.name)
        except Exception as e:
            if error.match("Name has already been taken", e):
                sel.click(form_buttons.cancel)
            raise

    def update(self, updates, cancel=False):
        sel.force_navigate("automate_explorer_instance_edit",
                           context={"tree_item": self})
        update_values = {
            'name_text': updates.get('name'),
            'description_text': updates.get('description'),
            'values': updates.get('values')
        }
        if "display_name" in updates:
            # We need to specifically override the display_name
            update_values["display_name_text"] = updates[
                "display_name"] or ""  # None -> emptystr
        fill(self.form,
             update_values,
             action=form_buttons.cancel if cancel else form_buttons.save)

    def delete(self, cancel=False):
        sel.force_navigate("automate_explorer_tree_path",
                           context={'tree_item': self})
        cfg_btn('Remove this Instance', invokes_alert=True)
        sel.handle_alert(cancel)
        return flash.assert_no_errors()
Exemple #14
0
class Method(CopiableTreeNode, Updateable):
    """Represents a Method in the CFME ui.  `Display Name` is not
       supported (it causes the name to be displayed differently in
       different places in the UI). """

    # TODO These locators need updating once the multiename Input class goes in

    form = Form(fields=[
        ('name_text', "//input[contains(@name,'method_name')]"),
        ('display_name_text',
         "//input[contains(@name,'method_display_name')]"),
        ('data_text',
         ScriptBox(
             ta_locator="//textarea[@id='method_data' or @id='cls_method_data']"
         ))
    ])

    def __init__(self,
                 name=None,
                 display_name=None,
                 location=None,
                 data=None,
                 cls=None):
        self.name = name
        # self.display_name = display_name
        self.location = location
        self.data = data
        self.cls = cls

    @property
    def parent(self):
        return self.cls

    @parent.setter
    def parent(self, p):
        self.cls = p

    def create(self, cancel=False):
        if self.parent is not None and not self.parent.exists():
            self.parent.create()
        sel.force_navigate("automate_explorer_method_new",
                           context={'tree_item': self.cls})
        fill(
            self.form,
            {
                'name_text': self.name,
                # 'display_name_text': self.display_name,
                'data_text': self.data
            },
            action=form_buttons.cancel if cancel else form_buttons.add)
        try:
            flash.assert_success_message('Automate Method "%s" was added' %
                                         self.name)
        except Exception as e:
            if error.match("Name has already been taken", e):
                sel.click(form_buttons.cancel)
            raise

    def update(self, updates, cancel=False):
        sel.force_navigate("automate_explorer_method_edit",
                           context={"tree_item": self})
        fill(self.form, {
            'name_text': updates.get('name'),
            'description_text': updates.get('description'),
            'data_text': updates.get('data')
        },
             action=form_buttons.cancel if cancel else form_buttons.save)

    def delete(self, cancel=False):
        sel.force_navigate("automate_explorer_tree_path",
                           context={'tree_item': self})
        cfg_btn('Remove this Method', invokes_alert=True)
        sel.handle_alert(cancel)
        return flash.assert_no_errors()
Exemple #15
0
class DatabaseBackupSchedule(Schedule):
    """ Configure/Configuration/Region/Schedules - Database Backup type

    Args:
        name: Schedule name
        description: Schedule description
        active: Whether the schedule should be active (default `True`)
        protocol: One of ``{'Samba', 'Network File System'}``
        run_type: Once, Hourly, Daily, ...
        run_every: If `run_type` is not Once, then you can specify how often it should be run
        time_zone: Time zone selection
        start_date: Specify start date (mm/dd/yyyy or datetime.datetime())
        start_hour: Starting hour
        start_min: Starting minute

    Usage:
        smb_schedule = DatabaseBackupSchedule(
            name="Bi-hourly Samba Database Backup",
            description="Everybody's favorite backup schedule",
            protocol="Samba",
            uri="samba.example.com/share_name",
            username="******",
            password="******",
            password_verify="secret",
            time_zone="UTC",
            start_date=datetime.datetime.utcnow(),
            run_type="Hourly",
            run_every="2 Hours"
        )
        smb_schedule.create()
        smb_schedule.delete()

        ... or ...

        nfs_schedule = DatabaseBackupSchedule(
            name="One-time NFS Database Backup",
            description="The other backup schedule",
            protocol="Network File System",
            uri="nfs.example.com/path/to/share",
            time_zone="Chihuahua",
            start_date="21/6/2014",
            start_hour="7",
            start_min="45"
        )
        nfs_schedule.create()
        nfs_schedule.delete()

    """
    form = Form(fields=[
        ("name", Input("name")),
        ("description", Input("description")),
        ("active", Input("enabled")),
        ("action", {
            version.LOWEST: Select("select#action_typ"),
            '5.5': AngularSelect('action_typ')
        }),
        ("log_protocol", {
            version.LOWEST: Select("select#log_protocol"),
            '5.5': AngularSelect('log_protocol')
        }),
        ("depot_name", Input("depot_name")),
        ("uri", Input("uri")),
        ("log_userid", Input("log_userid")),
        ("log_password", Input("log_password")),
        ("log_verify", Input("log_verify")),
        ("timer_type", {
            version.LOWEST: Select("select#timer_typ"),
            '5.5': AngularSelect('timer_typ')
        }),
        ("timer_hours", Select("select#timer_hours")),
        ("timer_days", Select("select#timer_days")),
        ("timer_weeks", Select("select#timer_weekss")),  # Not a typo!
        ("timer_months", Select("select#timer_months")),
        ("timer_value", AngularSelect('timer_value'), {
            "appeared_in": "5.5"
        }),
        ("time_zone", AngularSelect('time_zone')),
        ("start_date", Calendar("start_date")),
        ("start_hour", AngularSelect('start_hour')),
        ("start_min", AngularSelect('start_min')),
    ])

    def __init__(self,
                 name,
                 description,
                 active=True,
                 protocol=None,
                 depot_name=None,
                 uri=None,
                 username=None,
                 password=None,
                 password_verify=None,
                 run_type="Once",
                 run_every=None,
                 time_zone=None,
                 start_date=None,
                 start_hour=None,
                 start_min=None):

        assert protocol in {'Samba', 'Network File System'},\
            "Unknown protocol type '{}'".format(protocol)

        if protocol == 'Samba':
            self.details = dict(
                name=name,
                description=description,
                active=active,
                action='Database Backup',
                log_protocol=sel.ByValue(protocol),
                depot_name=depot_name,
                uri=uri,
                log_userid=username,
                log_password=password,
                log_verify=password_verify,
                time_zone=sel.ByValue(time_zone),
                start_date=start_date,
                start_hour=start_hour,
                start_min=start_min,
            )
        else:
            self.details = dict(
                name=name,
                description=description,
                active=active,
                action='Database Backup',
                log_protocol=sel.ByValue(protocol),
                depot_name=depot_name,
                uri=uri,
                time_zone=sel.ByValue(time_zone),
                start_date=start_date,
                start_hour=start_hour,
                start_min=start_min,
            )

        if run_type == "Once":
            self.details["timer_type"] = "Once"
        else:
            field = version.pick({
                version.LOWEST: self.tab[run_type],
                '5.5': 'timer_value'
            })
            self.details["timer_type"] = run_type
            self.details[field] = run_every

    def create(self, cancel=False, samba_validate=False):
        """ Create a new schedule from the informations stored in the object.

        Args:
            cancel: Whether to click on the cancel button to interrupt the creation.
            samba_validate: Samba-only option to click the `Validate` button to check
                            if entered samba credentials are valid or not
        """
        navigate_to(self, 'Add')

        fill(self.form, self.details)
        if samba_validate:
            sel.click(form_buttons.validate)
        if cancel:
            form_buttons.cancel()
        else:
            form_buttons.add()
            flash.assert_message_contain('Schedule "{}" was saved'.format(
                self.details['name']))

    def update(self, updates, cancel=False, samba_validate=False):
        """ Modify an existing schedule with informations from this instance.

        Args:
            updates: Dict with fields to be updated
            cancel: Whether to click on the cancel button to interrupt the editation.
            samba_validate: Samba-only option to click the `Validate` button to check
                            if entered samba credentials are valid or not
        """
        navigate_to(self, 'Edit')

        self.details.update(updates)
        fill(self.form, self.details)
        if samba_validate:
            sel.click(form_buttons.validate)
        if cancel:
            form_buttons.cancel()
        else:
            form_buttons.save()

    def delete(self):
        super(DatabaseBackupSchedule, self).delete()
        flash.assert_message_contain('Schedule "{}": Delete successful'.format(
            self.details['description']))

    @property
    def last_date(self):
        navigate_to(self, 'All')
        name = self.details["name"]
        row = records_table.find_row("Name", name)
        return row[6].text
Exemple #16
0
        if value is None:
            value = "<Nothing>"
        select = form.select_by_name(name)
        sel.select(select, value)


assign_form = Form(fields=[
    ("assign_to", Select_old("select#cbshow_typ")),
    # Enterprise
    ("enterprise",
     Select_old("select#enterprise__1")),  # Simple shotcut, might explode once
    # Tagged DS
    ("tag_category", Select_old("select#cbtag_cat")),
    # Docker Labels
    ("docker_labels", Select_old('select#cblabel_key')),
    # Common - selection table
    ("selections",
     AssignFormTable({
         LOWEST:
         ("//div[@id='cb_assignment_div']/fieldset/table[contains(@class, 'style1')]"
          "/tbody/tr/td/table"),
         "5.4":
         "//div[@id='cb_assignment_div']/table[contains(@class, 'table')]",
     })),
    ('save_button', form_buttons.save)
])


class ComputeRate(Updateable, Pretty, Navigatable):
    pretty_attrs = ['description']

    def __init__(
Exemple #17
0
from . import PolicyProfileAssignable, Taggable, SummaryMixin

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

retire_remove_button = "//span[@id='remove_button']/a/img|//a/img[contains(@src, '/clear')]"

set_ownership_form = Form(fields=[
    ('user_name', AngularSelect('user_name')),
    ('group_name', AngularSelect('group_name')),
    ('create_button', form_buttons.save),
    ('reset_button', form_buttons.reset),
    ('cancel_button', form_buttons.cancel)
])

drift_table = CheckboxTable("//th[normalize-space(.)='Timestamp']/ancestor::table[1]")
drift_section = BootstrapTreeview('all_sectionsbox')


def base_types(template=False):
    from pkg_resources import iter_entry_points
    search = "template" if template else "vm"
    return {
        ep.name: ep.resolve() for ep in iter_entry_points('manageiq.{}_categories'.format(search))
    }
Exemple #18
0
from utils.varmeth import variable

cfg_btn = partial(tb.select, 'Configuration')

pxe_server_table_exist = Table('//div[@id="records_div"]/table/tbody/tr/td')
pxe_details_page = Region(locators=dict(
    last_refreshed=InfoBlock("Basic Information", "Last Refreshed On"),
    pxe_image_type=InfoBlock("Basic Information", "Type")))

pxe_properties_form = Form(fields=[
    ('name_text', Input('name')),
    ('log_protocol', Select("//select[@id='log_protocol']")),
    ('userid_text', Input('log_userid')),
    ('password_text', Input('log_password')),
    ('verify_text', Input('log_verify')),
    ('validate_btn', "//a[@id='val']"),
    ('access_url_text', Input('access_url')),
    ('uri_text', Input('uri')),
    ('pxe_dir_text', Input('pxe_directory')),
    ('windows_dir_text', Input('windows_images_directory')),
    ('customize_dir_text', Input('customization_directory')),
    ('pxe_menu_text', Input('pxemenu_0')),
])

pxe_image_type_form = Form(fields=[('image_type',
                                    Select("//select[@id='image_typ']"))])

template_details_page = Region(
    infoblock_type='form')  # infoblock shoudl be type 'detail' #gofigure

template_properties_form = Form(
    fields=[('name_text',
Exemple #19
0
class BaseVM(Pretty, Updateable, PolicyProfileAssignable, Taggable, SummaryMixin, Navigatable):
    """Base VM and Template class that holds the largest common functionality between VMs,
    instances, templates and images.

    In order to inherit these, you have to implement the ``on_details`` method.
    """
    pretty_attrs = ['name', 'provider', 'template_name']

    # Forms
    edit_form = Form(
        fields=[
            ('custom_ident', Input("custom_1")),
            ('description_tarea', "//textarea[@id='description']"),
            ('parent_sel', {
                version.LOWEST: Select("//select[@name='chosen_parent']"),
                "5.5": AngularSelect("chosen_parent")}),
            ('child_sel', Select("//select[@id='kids_chosen']", multi=True)),
            ('vm_sel', Select("//select[@id='choices_chosen']", multi=True)),
            ('add_btn', "//img[@alt='Move selected VMs to left']"),
            ('remove_btn', "//img[@alt='Move selected VMs to right']"),
            ('remove_all_btn', "//img[@alt='Move all VMs to right']"),
        ])

    ###
    # Factory class methods
    #
    @classmethod
    def factory(cls, vm_name, provider, template_name=None, template=False):
        """Factory class method that determines the correct subclass for given provider.

        For reference how does that work, refer to the entrypoints in the setup.py

        Args:
            vm_name: Name of the VM/Instance as it appears in the UI
            provider: The provider object (not the string!)
            template_name: Source template name. Useful when the VM/Instance does not exist and you
                want to create it.
            template: Whether the generated object class should be VM/Instance or a template class.
        """
        try:
            return all_types(template)[provider.type](vm_name, provider, template_name)
        except KeyError:
            # Matching via provider type failed. Maybe we have some generic classes for infra/cloud?
            try:
                return all_types(template)[provider.category](vm_name, provider, template_name)
            except KeyError:
                raise UnknownProviderType(
                    'Unknown type of provider CRUD object: {}'
                    .format(provider.__class__.__name__))

    ###
    # To be set or implemented
    #
    ALL_LIST_LOCATION = None
    TO_OPEN_EDIT = None  # Name of the item in Configuration that puts you in the form
    QUADICON_TYPE = "vm"
    # Titles of the delete buttons in configuration
    REMOVE_SELECTED = {'5.6': 'Remove selected items',
                       '5.6.2.2': 'Remove selected items from the VMDB',
                       '5.7': 'Remove selected items'}
    REMOVE_SINGLE = {'5.6': 'Remove Virtual Machine',
                     '5.6.2.2': 'Remove from the VMDB',
                     '5.7': 'Remove Virtual Machine'}
    RETIRE_DATE_FMT = {version.LOWEST: parsetime.american_date_only_format,
                       '5.7': parsetime.american_minutes_with_utc}
    _param_name = ParamClassName('name')

    ###
    # Shared behaviour
    #
    def __init__(self, name, provider, template_name=None, appliance=None):
        super(BaseVM, self).__init__()
        Navigatable.__init__(self, appliance=appliance)
        if type(self) in {BaseVM, VM, Template}:
            raise NotImplementedError('This class cannot be instantiated.')
        self.name = name
        self.provider = provider
        self.template_name = template_name

    ###
    # Properties
    #
    @property
    def is_vm(self):
        return not isinstance(self, _TemplateMixin)

    @property
    def quadicon_type(self):
        return self.QUADICON_TYPE

    @property
    def paged_table(self):
        _paged_table_template = '//div[@id="list_grid"]/div[@class="{}"]/table/tbody'
        return version.pick({
            version.LOWEST: SplitPagedTable(header_data=(_paged_table_template.format("xhdr"), 1),
                                            body_data=(_paged_table_template.format("objbox"), 0)),
            "5.5": PagedTable('//table'),
        })

    ###
    # Methods
    #
    def check_compliance(self, timeout=240):
        """Initiates compliance check and waits for it to finish."""
        original_state = self.compliance_status
        cfg_btn("Refresh Relationships and Power States", invokes_alert=True)
        sel.handle_alert()
        flash.assert_no_errors()
        pol_btn("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)
        )
        return self.compliant

    @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
        """
        self.load_details(refresh=True)
        return InfoBlock("Compliance", "Status").title

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

        Returns:
            :py:class:`NoneType` if the VM was never verified, otherwise :py:class:`bool`
        """
        text = self.get_detail(properties=("Compliance", "Status")).strip().lower()
        if text == "never verified":
            return None
        elif text.startswith("non-compliant"):
            return False
        elif text.startswith("compliant"):
            return True
        else:
            raise ValueError("{} is not a known state for compliance".format(text))

    @property
    def console_handle(self):
        '''
        The basic algorithm for getting the consoles window handle is to get the
        appliances window handle and then iterate through the window_handles till we find
        one that is not the appliances window handle.   Once we find this check that it has
        a canvas widget with a specific ID
        '''
        browser = self.appliance.browser.widgetastic
        appliance_handle = browser.window_handle
        cur_handles = browser.selenium.window_handles
        logger.info("Current Window Handles:  {}".format(cur_handles))

        for handle in cur_handles:
            if handle != appliance_handle:
                # FIXME: Add code to verify the tab has the correct widget
                #      for a console tab.
                return handle

    def delete(self, cancel=False, from_details=False):
        """Deletes the VM/Instance from the VMDB.

        Args:
            cancel: Whether to cancel the action in the alert.
            from_details: Whether to use the details view or list view.
        """

        if from_details:
            self.load_details(refresh=True)
            cfg_btn(self.REMOVE_SINGLE, invokes_alert=True)
        else:
            self.find_quadicon(mark=True)
            cfg_btn(self.REMOVE_SELECTED, invokes_alert=True)
        sel.handle_alert(cancel=cancel)

    @property
    def exists(self):
        """Checks presence of the quadicon in the CFME."""
        try:
            self.find_quadicon()
            return True
        except VmOrInstanceNotFound:
            return False

    @property
    def ip_address(self):
        """Fetches IP Address of VM"""
        return self.provider.mgmt.get_ip_address(self.name)

    @property
    def is_retired(self):
        """"Check retirement status of vm"""
        self.summary.reload()
        if self.summary.lifecycle.retirement_date.text_value.lower() != 'never':
            try:
                return self.summary.lifecycle.retirement_state.text_value.lower() == 'retired'
            except AttributeError:
                return False
        else:
            return False

    def find_quadicon(
            self, do_not_navigate=False, mark=False, refresh=True, from_any_provider=False,
            use_search=True):
        """Find and return a quadicon belonging to a specific vm

        Args:
            from_any_provider: Whether to look for it anywhere (root of the tree). Useful when
                looking up archived or orphaned VMs

        Returns: :py:class:`cfme.web_ui.Quadicon` instance
        Raises: VmOrInstanceNotFound
        """
        from cfme.web_ui import paginator
        quadicon = Quadicon(self.name, self.quadicon_type)
        if not do_not_navigate:
            if from_any_provider:
                # TODO implement as navigate_to when cfme.infra.virtual_machines has destination
                navigate_to(self, 'All')
            else:
                navigate_to(self, 'AllForProvider', use_resetter=False)
            toolbar.select('Grid View')
        else:
            # Search requires navigation, we shouldn't use it then
            use_search = False
            if refresh:
                sel.refresh()
        if not paginator.page_controls_exist():
            if self.is_vm:
                raise VmOrInstanceNotFound("VM '{}' not found in UI!".format(self.name))
            else:
                raise TemplateNotFound("Template '{}' not found in UI!".format(self.name))

        paginator.results_per_page(1000)
        if use_search:
            try:
                if not search.has_quick_search_box():
                    # TODO rework search for archived/orphaned VMs
                    if from_any_provider:
                        navigate_to(self, 'All')
                    else:
                        navigate_to(self, 'AllForProvider', use_resetter=False)
                search.normal_search(self.name)
            except Exception as e:
                logger.warning("Failed to use search: %s", str(e))
        for page in paginator.pages():
            if sel.is_displayed(quadicon, move_to=True):
                if mark:
                    sel.check(quadicon.checkbox())
                return quadicon
        else:
            raise VmOrInstanceNotFound("VM '{}' not found in UI!".format(self.name))

    def get_detail(self, properties=None, icon_href=False):
        """Gets details from the details infoblock

        The function first ensures that we are on the detail page for the specific VM/Instance.

        Args:
            properties: An InfoBlock title, followed by the Key name, e.g. "Relationships", "Images"

        Returns:
            A string representing the contents of the InfoBlock's value.
        """
        self.load_details(refresh=True)
        if icon_href:
            return InfoBlock.icon_href(*properties)
        else:
            return InfoBlock.text(*properties)

    def open_console(self, console='VM Console', invokes_alert=False, cancel=False):
        """
        Initiates the opening of one of the console types supported by the Access
        button.   Presently we only support VM Console, which is the HTML5 Console.
        In case of VMware provider it could be VMRC, VNC/HTML5, WebMKS, but we only
        support VNC/HTML5.
        Possible values for 'console' could be 'VM Console' and 'Web Console', but Web
        Console is not supported as well.

        Args:
            console       - one of the supported console types given by the Access button.
            invokes_alert - If the particular console will invoke a CFME popup/alert
                            setting this to true will handle this.
            cancel        - Allows one to cancel the operation if the popup/alert occurs.
        """
        # TODO: implement vmrc vm console
        if console not in ['VM Console']:
            raise NotImplementedError('Not supported console type: {}'.format(console))

        view = navigate_to(self, 'Details')

        # Click console button given by type
        view.toolbar.access.item_select(console)

        # Get the consoles window handle, and then create a VMConsole object, and store
        # the VMConsole object aside.
        console_handle = self.console_handle

        if console_handle is None:
            raise TypeError("Console handle should not be None")

        appliance_handle = self.appliance.browser.widgetastic.window_handle
        logger.info("Creating VMConsole:")
        logger.info("   appliance_handle: {}".format(appliance_handle))
        logger.info("     console_handle: {}".format(console_handle))
        logger.info("               name: {}".format(self.name))

        self.vm_console = VMConsole(
            appliance_handle=appliance_handle,
            console_handle=console_handle,
            vm=self
        )

    def open_details(self, properties=None):
        """Clicks on details infoblock"""
        self.load_details(refresh=True)
        sel.click(InfoBlock(*properties))

    @classmethod
    def get_first_vm_title(cls, do_not_navigate=False, provider=None):
        """Get the title of first VM/Instance."""
        if not do_not_navigate:
            if provider is None:
                navigate_to(cls, 'All')
            else:
                provider.load_all_provider_vms()
        return Quadicon.get_first_quad_title()

    @property
    def last_analysed(self):
        """Returns the contents of the ``Last Analysed`` field in summary"""
        return self.get_detail(properties=('Lifecycle', 'Last Analyzed')).strip()

    def load_details(self, refresh=False):
        """Navigates to an VM's details page.

        Args:
            refresh: Refreshes the VM page if already there

        Raises:
            VmOrInstanceNotFound:
                When unable to find the VM passed
        """
        navigate_to(self, 'Details', use_resetter=False)
        if refresh:
            toolbar.refresh()

    def open_edit(self):
        """Loads up the edit page of the object."""
        self.load_details(refresh=True)
        cfg_btn(self.TO_OPEN_EDIT)

    def open_timelines(self):
        """Navigates to an VM's timeline page.

        Returns:
            :py:class:`TimelinesView` object
        """
        return navigate_to(self, 'Timelines')

    def rediscover(self):
        """Deletes the VM from the provider and lets it discover again"""
        self.delete(from_details=True)
        self.wait_for_delete()
        self.provider.refresh_provider_relationships()
        self.wait_to_appear()

    def rediscover_if_analysis_data_present(self):
        """Rediscovers the object if it has some analysis data present.

        Returns:
            Boolean if the rediscovery happened.
        """
        if self.last_analysed.lower() != 'never':
            self.rediscover()
            return True
        return False

    def refresh_relationships(self, from_details=False, cancel=False, from_any_provider=False):
        """Executes a refresh of relationships.

        Args:
            from_details: Whether or not to perform action from instance details page
            cancel: Whether or not to cancel the refresh relationships action
        """
        if from_details:
            self.load_details()
        else:
            self.find_quadicon(mark=True, from_any_provider=from_any_provider)
        cfg_btn('Refresh Relationships and Power States', invokes_alert=True)
        sel.handle_alert(cancel=cancel)

    @property
    def retirement_date(self):
        """Returns the retirement date of the selected machine, or 'Never'

        Returns:
            :py:class:`str` object
        """
        return self.get_detail(properties=("Lifecycle", "Retirement Date")).strip()

    def smartstate_scan(self, cancel=False, from_details=False):
        """Initiates fleecing from the UI.

        Args:
            cancel: Whether or not to cancel the refresh relationships action
            from_details: Whether or not to perform action from instance details page
        """
        if from_details:
            self.load_details(refresh=True)
        else:
            self.find_quadicon(mark=True)
        cfg_btn('Perform SmartState Analysis', invokes_alert=True)
        sel.handle_alert(cancel=cancel)

    def wait_to_disappear(self, timeout=600, load_details=True):
        """Wait for a VM to disappear within CFME

        Args:
            timeout: time (in seconds) to wait for it to appear
        """
        wait_for(
            lambda: self.exists,
            num_sec=timeout, delay=30, fail_func=sel.refresh, fail_condition=True,
            message="wait for vm to not exist")

    wait_for_delete = wait_to_disappear  # An alias for more fitting verbosity

    def wait_to_appear(self, timeout=600, load_details=True):
        """Wait for a VM to appear within CFME

        Args:
            timeout: time (in seconds) to wait for it to appear
            load_details: when found, should it load the vm details
        """
        wait_for(
            lambda: self.exists,
            num_sec=timeout, delay=30, fail_func=self.provider.refresh_provider_relationships,
            message="wait for vm to appear")
        if load_details:
            self.load_details()

    def set_ownership(self, user=None, group=None, click_cancel=False, click_reset=False):
        """Set ownership of the VM/Instance or Template/Image"""
        sel.click(self.find_quadicon(False, False, False, use_search=False))
        cfg_btn('Set Ownership')
        if click_reset:
            action = form_buttons.reset
            msg_assert = partial(
                flash.assert_message_match,
                'All changes have been reset'
            )
        elif click_cancel:
            action = form_buttons.cancel
            msg_assert = partial(
                flash.assert_success_message,
                'Set Ownership was cancelled by the user'
            )
        else:
            action = form_buttons.save
            msg_assert = partial(
                flash.assert_success_message,
                'Ownership saved for selected {}'.format(self.VM_TYPE)
            )
        fill(set_ownership_form, {'user_name': user, 'group_name': group},
             action=action)
        msg_assert()

    def unset_ownership(self):
        """Unset ownership of the VM/Instance or Template/Image"""
        # choose the vm code comes here
        sel.click(self.find_quadicon(False, False, False))
        cfg_btn('Set Ownership')
        fill(set_ownership_form, {'user_name': '<No Owner>',
            'group_name': 'EvmGroup-administrator'},
            action=form_buttons.save)
        flash.assert_success_message('Ownership saved for selected {}'.format(self.VM_TYPE))
Exemple #20
0
from cfme.web_ui import (
    accordion, Quadicon, Form, Input, fill, form_buttons, mixins, SplitTable, Table, Region,
    AngularSelect, Select
)
from utils import version, conf
from utils.log import logger
from utils.pretty import Pretty
from utils.update import Updateable
from utils.wait import wait_for


properties_form = Form(
    fields=[
        ('name_text', Input('name')),
        ('type_select', {
            version.LOWEST: Select("select#provtype"),
            '5.6': AngularSelect("provider_type")}),
        ('url_text', Input('url')),
        ('ssl_checkbox', Input('verify_ssl'))
    ])

credential_form = Form(
    fields=[
        ('principal_text', Input('log_userid')),
        ('secret_pass', Input('log_password')),
        ('verify_secret_pass', Input('log_verify')),
        ('validate_btn', form_buttons.validate)
    ])


CfgMgrSplitTable = lambda: SplitTable(
Exemple #21
0
class StorageManager(Updateable):
    """Represents the Storage / Storage Managers object. Allows interaction

    Args:
        name: Name of the Storage Namager as it appears in the UI.
        type: Type of the Storage Manager (eg. StorageManager.NETAPP_RS, ...)
        hostname: Host name of the machine.
        ip: IP Address of the machine.
        port: Port of the machine.
        credentials: :py:class:`dict` or :py:class:`StorageManager.Credential`
    """
    class Credential(Updateable):
        def __init__(self, username=None, password=None):
            self.username = username
            self.password = password

    form = Form(fields=[
        ("name", ui.Input("name")),
        ("type", ui.Select("select#sm_type")),
        ("hostname", ui.Input("hostname")),
        ("ip", ui.Input("ipaddress")),
        ("port", ui.Input("port")),
        ("credentials",
         Form(fields=[("username", ui.Input("userid")),
                      ("password",
                       MultiFill(ui.Input("password"), ui.Input("verify")))])),
    ])

    validate = form_buttons.FormButton(
        "Validate the credentials by logging into the Server")
    add = form_buttons.FormButton("Add this Storage Manager")

    ##
    # Types constants. Extend if needed :)
    NETAPP_RS = "NetApp Remote Service"

    def __init__(self,
                 name=None,
                 type=None,
                 hostname=None,
                 ip=None,
                 port=None,
                 credentials=None):
        self.name = name
        self.type = type
        self.hostname = hostname
        self.ip = ip
        self.port = port
        self.credentials = credentials

    def create(self, validate=True, cancel=False):
        sel.force_navigate("storage_manager_new")
        fill(self.form, self)
        if validate:
            sel.click(self.validate)
        if cancel:
            sel.click(form_buttons.cancel)
        else:
            sel.click(self.add)
        flash.assert_no_errors()

    def update(self, updates, validate=True, cancel=False):
        sel.force_navigate("storage_manager_edit",
                           context={"storage_manager": self})
        fill(self.form, updates)
        if validate:
            sel.click(self.validate)
        if cancel:
            sel.click(form_buttons.cancel)
        else:
            sel.click(form_buttons.save)
        flash.assert_no_errors()

    def delete(self, cancel=False):
        self.navigate()
        cfg_btn("Remove this Storage Manager from the VMDB",
                invokes_alert=True)
        sel.handle_alert(cancel)
        flash.assert_no_errors()

    def navigate(self):
        sel.force_navigate("storage_manager",
                           context={"storage_manager": self})

    def refresh_inventory(self):
        self.navigate()
        cfg_btn("Refresh Inventory", invokes_alert=True)
        sel.handle_alert(cancel=False)
        flash.assert_no_errors()

    def refresh_status(self):
        self.navigate()
        cfg_btn("Refresh Status", invokes_alert=True)
        sel.handle_alert(cancel=False)
        flash.assert_no_errors()

    def wait_until_updated(self, num_sec=300):
        def _wait_func():
            self.navigate()
            return InfoBlock("Properties",
                             "Last Update Status").text.strip().lower() == "ok"

        wait_for(_wait_func, num_sec=num_sec, delay=5)

    @property
    def exists(self):
        try:
            self.navigate()
            return True
        except StorageManagerNotFound:
            return False
Exemple #22
0
from functools import partial
from cfme.web_ui import toolbar as tb
from cfme import web_ui as ui
from xml.sax.saxutils import quoteattr
from cfme.exceptions import CFMEException
from utils.wait import wait_for

details_page = Region(infoblock_type='detail')
cfg_btn = partial(tb.select, "Configuration")
pol_btn = partial(tb.select, 'Policy')
output_table = SplitTable(
    ('//*[@id="list_grid"]//table[contains(@class, "hdr")]/tbody', 1),
    ('//*[@id="list_grid"]//table[contains(@class, "obj")]/tbody', 1))

edit_tags_form = Form(fields=[(
    "select_tag",
    ui.Select("select#tag_cat")), ("select_value",
                                   ui.Select("select#tag_add"))])

nav.add_branch('clouds_stacks', {
    'clouds_stack':
    lambda ctx: sel.click(Quadicon(ctx['stack'].name, 'stack'))
})


class Stack(Pretty):
    pretty_attrs = ['name']

    def __init__(self, name=None):
        self.name = name

    def delete(self):
Exemple #23
0
class ReportWidget(Widget):
    form = Form(fields=[
        ("title", Input("title")),
        ("description", Input("description")),
        ("active", Input("enabled")),
        ("filter",
         ShowingInputs(Select("//select[@id='filter_typ']"),
                       Select("//select[@id='subfilter_typ']"),
                       Select("//select[@id='repfilter_typ']"),
                       min_values=3)),  # Might be abstracted out too
        ("columns",
         ShowingInputs(Select("//select[@id='chosen_pivot1']"),
                       Select("//select[@id='chosen_pivot2']"),
                       Select("//select[@id='chosen_pivot3']"),
                       Select("//select[@id='chosen_pivot4']"),
                       min_values=1)),
        ("rows", Select("//select[@id='row_count']")),
        ("timer", Timer()),
        ("visibility", visibility_obj),
    ])
    TITLE = "Report"
    pretty_attrs = ['description', 'filter', 'visibility']
    DETAIL_PAGE = "reports_widgets_report"

    def __init__(self,
                 title,
                 description=None,
                 active=None,
                 filter=None,
                 columns=None,
                 rows=None,
                 timer=None,
                 visibility=None):
        self.title = title
        self.description = description
        self.active = active
        self.filter = filter
        self.columns = columns
        self.rows = rows
        self.timer = timer
        self.visibility = visibility

    def create(self, cancel=False):
        sel.force_navigate("reports_widgets_report_add")
        fill(self.form,
             self.__dict__,
             action=form_buttons.cancel if cancel else form_buttons.add)
        flash.assert_no_errors()

    def update(self, updates):
        sel.force_navigate("reports_widgets_report_edit",
                           context={"widget": self})
        fill(self.form, updates, action=form_buttons.save)
        flash.assert_no_errors()

    def delete(self, cancel=False):
        self.go_to_detail()
        toolbar.select("Configuration",
                       "Delete this Widget from the Database",
                       invokes_alert=True)
        sel.handle_alert(cancel)
        flash.assert_no_errors()
Exemple #24
0
from cfme.web_ui import accordion, menu, flash, Quadicon, Region, Form, fill, form_buttons
from cfme.web_ui import toolbar as tb
from utils.update import Updateable
from utils.wait import wait_for
from utils import version

lifecycle_btn = partial(tb.select, "Lifecycle")
reload_func = partial(tb.select, "Reload current display")
my_service_tree = partial(accordion.tree, "Services")
details_page = Region(infoblock_type='detail')
cfg_btn = partial(tb.select, "Configuration")
policy_btn = partial(tb.select, "Policy")
download_btn = partial(tb.select, "download_choice")

retirement_form = Form(fields=[('retirement_date', {
    version.LOWEST: ui.Calendar('miq_date_1'),
    '5.5': ui.Calendar('retirementDate')
}), ('retirement_warning', ui.Select("select#retirement_warn"))])

edit_service_form = Form(
    fields=[("name", ui.Input("name")), ("description",
                                         ui.Input("description"))])

set_ownership_form = Form(
    fields=[("select_owner", ui.Select("select#user_name")
             ), ("select_group", ui.Select("select#group_name"))])

edit_tags_form = Form(fields=[(
    "select_tag",
    ui.Select("select#tag_cat")), ("select_value",
                                   ui.Select("select#tag_add"))])
Exemple #25
0
def get_expression_as_text():
    """ Returns whole expression as represented visually.

    """
    return sel.text("//div[@id='exp_editor_div']/fieldset/div").encode(
        "utf-8").strip()


###
# Form handling
#
field_form = Form(fields=[
    ("type", AngularSelect("chosen_typ")),
    ("field", AngularSelect("chosen_field")),
    ("key", AngularSelect("chosen_key")),
    ("value", Input("chosen_value")),
    ("user_input", Input("user_input")),
])

field_date_form = Form(
    fields=[("dropdown_select", AngularSelect("chosen_from_1")
             ), ("input_select_date", Calendar("miq_date_1_0")
                 ), ("input_select_time", AngularSelect("miq_time_1_0"))])

count_form = Form(fields=[
    ("type", AngularSelect("chosen_typ")),
    ("count", AngularSelect("chosen_count")),
    ("key", AngularSelect("chosen_key", exact=True)),
    ("value", Input("chosen_value")),
    ("user_input", Input("user_input")),
Exemple #26
0
from cfme.utils.blockers import BZ
from cfme.utils.log import logger
from cfme.utils.pretty import Pretty
from cfme.utils.timeutil import parsetime
from cfme.utils.update import Updateable
from cfme.utils.wait import wait_for, TimedOutError

access_tree = partial(accordion.tree, "Access Control")
database_tree = partial(accordion.tree, "Database")
settings_tree = partial(accordion.tree, "Settings")
diagnostics_tree = partial(accordion.tree, "Diagnostics")

replication_worker = Form(fields=[
    ('database', Input("replication_worker_dbname")),
    ('port', Input("replication_worker_port")),
    ('username', Input("replication_worker_username")),
    ('password', Input("replication_worker_password")),
    ('password_verify', Input("replication_worker_verify")),
    ('host', Input("replication_worker_host")),
])

replication_process = UIRegion(
    locators={
        "status": InfoBlock("Replication Process", "Status"),
        "current_backlog": InfoBlock("Replication Process", "Current Backlog"),
    })

server_roles = Form(fields=[
    # TODO embedded_ansible is only present in CFME 5.8 (MIQ Fine+)
    ('embedded_ansible', CFMECheckbox("server_roles_embedded_ansible")),
    ('ems_metrics_coordinator',
     CFMECheckbox("server_roles_ems_metrics_coordinator")),
Exemple #27
0
from utils.wait import wait_for
from utils import deferred_verpick, version
from utils.pretty import Pretty

# Page specific locators
details_page = Region(infoblock_type='detail')

page_title_loc = '//div[@id="center_div" or @id="main-content"]//h1'

properties_form = Form(fields=[
    ('name_text', Input("name")),
    ('hostname_text', Input("hostname")),
    ('ipaddress_text', Input("ipaddress"), {
        "removed_since": "5.4.0.0.15"
    }),
    ('custom_ident_text', Input("custom")),
    ('host_platform', {
        version.LOWEST: Select('//select[@id="user_assigned_os"]'),
        '5.5': AngularSelect('user_assigned_os')
    }),
    ('ipmi_address_text', Input("ipmi_address")),
    ('mac_address_text', Input("mac_address")),
])

credential_form = Form(fields=[
    ('default_button', "//div[@id='auth_tabs']/ul/li/a[@href='#default']"),
    ('default_principal', Input("default_userid")),
    ('default_secret', Input("default_password")),
    ('default_verify_secret', Input("default_verify")),
    ('ipmi_button', "//div[@id='auth_tabs']/ul/li/a[@href='#ipmi']"),
    ('ipmi_principal', Input("ipmi_userid")),
    ('ipmi_secret', Input("ipmi_password")),
Exemple #28
0
class Schedule(Pretty, Navigatable):
    """ Configure/Configuration/Region/Schedules functionality

    Create, Update, Delete functionality.

    Args:
        name: Schedule's name.
        description: Schedule description.
        active: Whether the schedule should be active (default `True`)
        action: Action type
        filter_type: Filtering type
        filter_value: If a more specific `filter_type` is selected, here is the place to choose
            hostnames, machines and so ...
        run_type: Once, Hourly, Daily, ...
        run_every: If `run_type` is not Once, then you can specify how often it should be run.
        time_zone: Time zone selection.
        start_date: Specify start date (mm/dd/yyyy or datetime.datetime()).
        start_hour: Starting hour
        start_min: Starting minute.

    Usage:

        schedule = Schedule(
            "My very schedule",
            "Some description here.",
            action="Datastore Analysis",
            filter_type="All Datastores for Host",
            filter_value="datastore.intra.acme.com",
            run_type="Hourly",
            run_every="2 Hours"
        )
        schedule.create()
        schedule.disable()
        schedule.enable()
        schedule.delete()
        # Or
        Schedule.enable_by_names("One schedule", "Other schedule")
        # And so.

    Note: TODO: Maybe the row handling might go into Table class?

    """
    tab = {
        "Hourly": "timer_hours",
        "Daily": "timer_days",
        "Weekly": "timer_weeks",
        "Monthly": "timer_months"
    }

    form = Form(fields=[
        ("name", Input("name")),
        ("description", Input("description")),
        ("active", Input("enabled")),
        ("action", {
            version.LOWEST: Select("select#action_typ"),
            '5.5': AngularSelect('action_typ')
        }),
        ("filter_type", {
            version.LOWEST: Select("select#filter_typ"),
            '5.5': AngularSelect('filter_typ')
        }),
        ("filter_value", {
            version.LOWEST: Select("select#filter_value"),
            '5.5': AngularSelect('filter_value')
        }),
        ("timer_type", {
            version.LOWEST: Select("select#timer_typ"),
            '5.5': AngularSelect('timer_typ')
        }),
        ("timer_hours", Select("select#timer_hours")),
        ("timer_days", Select("select#timer_days")),
        ("timer_weeks", Select("select#timer_weekss")),  # Not a typo!
        ("timer_months", Select("select#timer_months")),
        ("timer_value", AngularSelect('timer_value'), {
            "appeared_in": "5.5"
        }),
        ("time_zone", {
            version.LOWEST: Select("select#time_zone"),
            '5.5': AngularSelect('time_zone')
        }),
        ("start_date", Calendar("miq_angular_date_1")),
        ("start_hour", {
            version.LOWEST: Select("select#start_hour"),
            '5.5': AngularSelect('start_hour')
        }),
        ("start_min", {
            version.LOWEST: Select("select#start_min"),
            '5.5': AngularSelect('start_min')
        }),
    ])

    pretty_attrs = [
        'name', 'description', 'run_type', 'run_every', 'start_date',
        'start_hour', 'start_min'
    ]

    def __init__(self,
                 name,
                 description,
                 active=True,
                 action=None,
                 filter_type=None,
                 filter_value=None,
                 run_type="Once",
                 run_every=None,
                 time_zone=None,
                 start_date=None,
                 start_hour=None,
                 start_min=None,
                 appliance=None):
        Navigatable.__init__(self, appliance=appliance)
        self.details = dict(
            name=name,
            description=description,
            active=active,
            action=action,
            filter_type=filter_type,
            filter_value=filter_value,
            time_zone=sel.ByValue(time_zone),
            start_date=start_date,
            start_hour=start_hour,
            start_min=start_min,
        )

        if run_type == "Once":
            self.details["timer_type"] = "Once"
        else:
            field = version.pick({
                version.LOWEST: self.tab[run_type],
                '5.5': 'timer_value'
            })
            self.details["timer_type"] = run_type
            self.details[field] = run_every

    def create(self, cancel=False):
        """ Create a new schedule from the informations stored in the object.

        Args:
            cancel: Whether to click on the cancel button to interrupt the creation.
        """
        navigate_to(self, 'Add')

        if cancel:
            action = form_buttons.cancel
        else:
            action = form_buttons.add
        fill(self.form, self.details, action=action)

    def update(self, updates, cancel=False):
        """ Modify an existing schedule with informations from this instance.

        Args:
            updates: Dict with fields to be updated
            cancel: Whether to click on the cancel button to interrupt the editation.

        """
        navigate_to(self, 'Edit')

        if cancel:
            action = form_buttons.cancel
        else:
            action = form_buttons.save
        self.details.update(updates)
        fill(self.form, self.details, action=action)

    def delete(self, cancel=False):
        """ Delete the schedule represented by this object.

        Calls the class method with the name of the schedule taken out from the object.

        Args:
            cancel: Whether to click on the cancel button in the pop-up.
        """
        navigate_to(self, 'Details')
        tb.select("Configuration",
                  "Delete this Schedule from the Database",
                  invokes_alert=True)
        sel.handle_alert(cancel)

    def enable(self):
        """ Enable the schedule via table checkbox and Configuration menu.

        """
        self.select()
        tb.select("Configuration", "Enable the selected Schedules")

    def disable(self):
        """ Enable the schedule via table checkbox and Configuration menu.

        """
        self.select()
        tb.select("Configuration", "Disable the selected Schedules")

    def select(self):
        """ Select the checkbox for current schedule

        """
        navigate_to(self, 'All')
        for row in records_table.rows():
            if row.name.strip() == self.details['name']:
                checkbox = row[0].find_element_by_xpath(
                    "//input[@type='checkbox']")
                if not checkbox.is_selected():
                    sel.click(checkbox)
                break
        else:
            raise ScheduleNotFound(
                "Schedule '{}' could not be found for selection!".format(
                    self.details['name']))
Exemple #29
0

def _get_servers_page(provider=None, server_group=None):
    if provider:  # if provider instance is provided navigate through provider's servers page
        navigate_to(provider, 'ProviderServers')
    elif server_group:
        # if server group instance is provided navigate through it's servers page
        navigate_to(server_group, 'ServerGroupServers')
    else:  # if None(provider) given navigate through all middleware servers page
        navigate_to(MiddlewareServer, 'All')


timeout_form = Form(fields=[(
    "timeout",
    Input("timeout", use_id=True)), (
        'suspend_button',
        FormButton("Suspend")), (
            'shutdown_button',
            FormButton("Shutdown")), ('cancel_button', FormButton("Cancel"))])


class MiddlewareServer(MiddlewareBase, Taggable, Container, Navigatable,
                       UtilizationMixin):
    """
    MiddlewareServer class provides actions and details on Server page.
    Class method available to get existing servers list

    Args:
        name: name of the server
        hostname: Host name of the server
        provider: Provider object (HawkularProvider)
Exemple #30
0
class Namespace(TreeNode, Updateable):
    form = Form(fields=[(
        'name',
        "//*[@id='ns_name']"), ('description', "//*[@id='ns_description']")])

    @classmethod
    def make_path(cls, *names, **kwargs):
        """
        Make a set of nested Namespace objects with the given path.

        Usage:
            #eg.
                n = Namespace.make_path("foo", "bar")
            #is equivalent to:
                n = Namespace(name="bar", parent=Namespace(name="foo"))
        """
        domain = kwargs.get('domain', None)
        parent = kwargs.get('parent', None)
        create_on_init = kwargs.get('create_on_init', False)

        names = list(names)
        parent = domain or parent
        ns = cls(name=names.pop(0), parent=parent)
        if create_on_init and not ns.exists():
            ns.create()
        if names:
            return cls.make_path(*names,
                                 parent=ns,
                                 create_on_init=create_on_init)
        else:
            return ns

    def __init__(self, name=None, description=None, parent=None, domain=None):
        self.name = name
        self.description = description
        self.parent = parent or (domain if isinstance(domain, Domain) else
                                 Domain.default)

    def create(self, cancel=False):
        if self.parent is not None and not self.parent.exists():
            self.parent.create()
        sel.force_navigate('automate_explorer_namespace_new',
                           context={'tree_item': self.parent})
        form_data = {'name': self.name, 'description': self.description}
        try:
            fill(self.form,
                 form_data,
                 action=form_buttons.cancel if cancel else form_buttons.add)
            flash.assert_success_message('Automate Namespace "%s" was added' %
                                         self.name)
        finally:
            # if there was a validation error we need to cancel out
            if sel.is_displayed(form_buttons.cancel):
                sel.click(form_buttons.cancel)

    def update(self, updates, cancel=False):
        sel.force_navigate('automate_explorer_edit',
                           context={
                               'tree_item': self.parent,
                               'table_item': self
                           })
        form_data = {
            'name': updates.get('name') or None,
            'description': updates.get('description') or None
        }
        fill(self.form,
             form_data,
             action=form_buttons.cancel if cancel else form_buttons.save)
        flash.assert_success_message('Automate Namespace "%s" was saved' %
                                     updates.get('name', self.name))

    def delete(self, cancel=False):
        sel.force_navigate("automate_explorer_table_select",
                           context={
                               'tree_item': self.parent,
                               'table_item': self
                           })
        dp_length = version.pick({version.LOWEST: 1, '5.3': 2})
        if len(self.path) > dp_length:
            cfg_btn('Remove selected Items', invokes_alert=True)
        else:
            cfg_btn('Remove Namespaces', invokes_alert=True)
        sel.handle_alert(cancel)
        del_msg = version.pick({
            version.LOWEST:
            'The selected Automate Namespaces were deleted',
            '5.3':
            'Automate Namespace "{}": Delete successful'.format(
                self.description)
        })
        flash.assert_success_message(del_msg)

    def __repr__(self):
        return "<%s.%s name=%s, path=%s>" % (__name__, self.__class__.__name__,
                                             self.name, self.path)