예제 #1
0
def setup_provider(provider, original_provider_key):
    original_provider = get_from_config(original_provider_key)
    if original_provider.exists:
        # Delete original provider's hosts first
        for host in original_provider.hosts:
            if host.exists:
                host.delete(cancel=False)
        # Get rid of the original provider, it would make a mess.
        original_provider.delete(cancel=False)
        wait_for_provider_delete(provider)
    provider.create()
    provider.refresh_provider_relationships()
    try:
        wait_for(
            lambda: any([
                provider.num_vm() > 0,
                provider.num_template() > 0,
                provider.num_datastore() > 0,
                provider.num_host() > 0,
            ]), num_sec=400, delay=5)
    except:
        provider.delete(cancel=False)
        raise
    yield
    for host in provider.hosts:
        if host.exists:
            host.delete(cancel=False)
    provider.delete(cancel=False)
    wait_for_provider_delete(provider)
예제 #2
0
def is_provider_setup(provider_key):
    """Checks whether provider is already existing in CFME

    Args:
        provider_key: YAML key of the provider

    Returns:
        :py:class:`bool` of existence
    """
    if provider_key in list_cloud_providers():
        from cfme.cloud.provider import get_from_config
        # provider = setup_infrastructure_provider(provider_key, validate, check_existing)
    elif provider_key in list_infra_providers():
        from cfme.infrastructure.provider import get_from_config
    else:
        raise UnknownProvider(provider_key)

    return get_from_config(provider_key).exists
예제 #3
0
def setup_provider(provider_key, validate=True, check_existing=True):
    """Add the named provider to CFME

    Args:
        provider_key: Provider key name from cfme_data
        validate: Whether or not to block until the provider stats in CFME
            match the stats gleaned from the backend management system
            (default: ``True``)
        check_existing: Check if this provider already exists, skip if it does

    Returns:
        An instance of :py:class:`cfme.cloud.provider.Provider` or
        :py:class:`cfme.infrastructure.provider.Provider` for the named provider, as appropriate.

    """
    if provider_key in list_cloud_providers():
        from cfme.cloud.provider import get_from_config
        # provider = setup_infrastructure_provider(provider_key, validate, check_existing)
    elif provider_key in list_infra_providers():
        from cfme.infrastructure.provider import get_from_config
    else:
        raise UnknownProvider(provider_key)

    provider = get_from_config(provider_key)
    if check_existing and provider.exists:
        # no need to create provider if the provider exists
        # pass so we don't skip the validate step
        pass
    else:
        logger.info('Setting up provider: %s' % provider.key)
        provider.create(validate_credentials=True)

    if validate:
        provider.validate()

    return provider
예제 #4
0
def setup_for_event_testing(ssh_client, db, listener_info, providers):
    # FIX THE ENV ERROR IF PRESENT
    if ssh_client.run_command("ruby -v")[0] != 0:
        success = ssh_client.run_command("echo 'source /etc/default/evm' >> .bashrc")[0] == 0
        assert success, "Issuing the patch command was unsuccessful"
        # Verify it works
        assert ssh_client.run_command("ruby -v")[0] == 0, "Patch failed"

    # IMPORT AUTOMATE NAMESPACE
    qe_automate_namespace_xml = "qe_event_handler.xml"
    qe_automate_namespace_script = "qe_event_handler.rb"
    local_automate_script = local(__file__)\
        .new(basename="../data/%s" % qe_automate_namespace_script)\
        .strpath
    local_automate_file = local(__file__)\
        .new(basename="../data/%s" % qe_automate_namespace_xml)\
        .strpath
    tmp_automate_file = "/tmp/%s" % qe_automate_namespace_xml

    # Change the information
    with open(local_automate_file, "r") as input_xml, \
            open(tmp_automate_file, "w") as output_xml:
        tree = etree.parse(input_xml)
        root = tree.getroot()

        def set_text(xpath, text):
            field = root.xpath(xpath)
            assert len(field) == 1
            field[0].text = text
        set_text("//MiqAeSchema/MiqAeField[@name='url']",
                 re.sub(r"^http://([^/]+)/?$", "\\1", listener_info.host))
        set_text("//MiqAeSchema/MiqAeField[@name='port']", str(listener_info.port))

        # Put the custom script from an external file
        with open(local_automate_script, "r") as script:
            set_text("//MiqAeMethod[@name='relay_events']",
                     etree.CDATA(script.read()))

        et = etree.ElementTree(root)
        et.write(output_xml)

    # copy xml file to appliance
    # but before that, let's check whether it's there because we may have already applied this file
    if ssh_client.run_command("ls /root/%s" % qe_automate_namespace_xml)[0] != 0:
        ssh_client.put_file(tmp_automate_file, '/root/')

        # We have to convert it first for new version
        convert_cmd = version.pick({
            "default": None,

            "5.3.0.0":
            "evm:automate:convert DOMAIN=Default FILE=/root/{} ZIP_FILE=/root/{}.zip".format(
                qe_automate_namespace_xml, qe_automate_namespace_xml),
        })
        if convert_cmd is not None:
            logger.info("Converting namespace for use on newer appliance...")
            return_code, stdout = ssh_client.run_rake_command(convert_cmd)
            if return_code != 0:
                logger.error("Namespace conversion was unsuccessful")
                logger.error(stdout)
                # We didn't successfully do that so remove the file to know
                # that it's needed to do it again when run again
                ssh_client.run_command("rm -f /root/%s*" % qe_automate_namespace_xml)
                raise AutomateImportError(stdout)

        # run rake cmd on appliance to import automate namespace
        rake_cmd = version.pick({
            "default": "evm:automate:import FILE=/root/{}".format(qe_automate_namespace_xml),

            "5.3.0.0":
            "evm:automate:import ZIP_FILE=/root/{}.zip DOMAIN=Default OVERWRITE=true "
            "PREVIEW=false".format(qe_automate_namespace_xml),
        })
        logger.info("Importing the QE Automation namespace ...")
        return_code, stdout = ssh_client.run_rake_command(rake_cmd)
        if return_code != 0:
            logger.error("Namespace import was unsuccessful")
            logger.error(stdout)
            # We didn't successfully do that so remove the file to know
            # that it's needed to do it again when run again
            ssh_client.run_command("rm -f /root/%s*" % qe_automate_namespace_xml)
            raise AutomateImportError(stdout)

    # CREATE AUTOMATE INSTANCE HOOK
    if db is None or db.session.query(db['miq_ae_instances'].name)\
            .filter(db['miq_ae_instances'].name == "RelayEvents").count() == 0:
        # Check presence
        instance = Instance(
            name="RelayEvents",
            display_name="RelayEvents",
            description="relationship hook to link to custom QE events relay namespace",
            values={
                "rel2": {
                    "value": "/QE/Automation/APIMethods/relay_events?event=$evm.object['event']"
                }
            },
            cls=Class(name="Automation Requests (Request)", namespace=Namespace("System"))
        )
        instance.create()

    # IMPORT POLICIES
    policy_yaml = "profile_relay_events.yaml"
    policy_path = local(__file__).new(basename="../data/%s" % policy_yaml)
    if not is_imported("Automate event policies"):
        import_file(policy_path.strpath)

    # ASSIGN POLICY PROFILES
    for provider in providers:
        prov_obj = get_from_config(provider)
        prov_obj.assign_policy_profiles("Automate event policies")
        flash.assert_no_errors()
예제 #5
0
 def __init__(self, name=None, provider_key=None):
     self.name = name
     if provider_key:
         self.provider = provider.get_from_config(provider_key)
     else:
         self.provider = None
예제 #6
0
def setup_a_provider(
        prov_class=None, prov_type=None, validate=True, check_existing=True, delete_failure=False):
    """Sets up a random provider

    Args:
        prov_type: "infra" or "cloud"
        delete_failure: Deletes the provider if the provider exists and the validation fails. Then
            it re-adds the provider.

    """
    if prov_class == "infra":
        from cfme.infrastructure.provider import get_from_config, wait_for_provider_delete
        potential_providers = list_infra_providers()
        if prov_type:
            providers = []
            for provider in potential_providers:
                if providers_data[provider]['type'] == prov_type:
                    providers.append(provider)
        else:
            providers = potential_providers
    elif prov_class == "cloud":
        from cfme.cloud.provider import get_from_config, wait_for_provider_delete
        potential_providers = list_cloud_providers()
        if prov_type:
            providers = []
            for provider in potential_providers:
                if providers_data[provider]['type'] == prov_type:
                    providers.append(provider)
        else:
            providers = potential_providers
    else:
        from cfme.infrastructure.provider import get_from_config, wait_for_provider_delete
        providers = list_infra_providers()

    result = None

    # If there is a provider that we want to specifically avoid ...
    # If there is only a single provider, then do not do any filtering
    # Specify `do_not_prefer` in provider's yaml to make it an object of avoidance.
    if len(providers) > 1:
        filtered_providers = [
            provider
            for provider
            in providers
            if not providers_data[provider].get("do_not_prefer", False)]
        if filtered_providers:
            # If our filtering yielded any providers, use them, otherwise do not bother with that
            providers = filtered_providers

    # If there is already a suitable provider, don't try to setup a new one.
    already_existing = filter(is_provider_setup, providers)
    if already_existing:
        chosen = random.choice(already_existing)
        try:
            return setup_provider(  # This will run a refresh too
                chosen, validate=validate, check_existing=check_existing)
        except Exception as e:
            if not delete_failure:
                raise
            logger.exception(e)
            logger.warning("Deleting and re-adding the provider {}.".format(chosen))
            prov_object = get_from_config(chosen)
            prov_object.delete(cancel=False)
            wait_for_provider_delete(prov_object)
            logger.info("Provider {} deleted, now going for re-add.".format(chosen))
            # And try again
            return setup_provider(  # This will run a refresh too
                chosen, validate=validate, check_existing=check_existing)

    # Shuffle the order to spread the load across providers
    random.shuffle(providers)
    # We need to setup a new one
    for provider in providers:
        try:
            result = setup_provider(provider, validate=validate, check_existing=check_existing)
            break
        except Exception as e:
            logger.exception(e)
            continue
    else:
        raise Exception("No providers could be set up matching the params")
    return result
예제 #7
0
 def __init__(self, name=None, provider_key=None):
     self.name = name
     if provider_key:
         self.provider = provider.get_from_config(provider_key)
     else:
         self.provider = None