Exemple #1
0
def get_secure_backup(appliances=[],
                      credentials=[],
                      timeout=1200,
                      no_check_hostname=False,
                      out_dir='tmp',
                      CryptoCertificate="",
                      destination='local:/raid0',
                      include_iscsi=False,
                      include_raid=False,
                      remove=True,
                      quiesce_before=True,
                      unquiesce_after=True,
                      quiesce_timeout=60,
                      web=False):
    """Performs a secure backup of the specified domain.

Parameters:

* `-a, --appliances`: The hostname(s), ip address(es), environment name(s)
or alias(es) of the appliances you would like to affect. For details
on configuring environments please see the comments in
`environments.conf` located in `$MAST_HOME/etc/default`. For details
on configuring aliases, please see the comments in `hosts.conf` located in
`$MAST_HOME/etc/default`. To pass multiple arguments to this parameter,
use multiple entries of the form `[-a appliance1 [-a appliance2...]]`
* `-c, --credentials`: The credentials to use for authenticating to the
appliances. Should be either one set to use for all appliances
or one set for each appliance. Credentials should be in the form
`username:password`. To pass multiple credentials to this parameter, use
multiple entries of the form `[-c credential1 [-c credential2...]]`.
When referencing multiple appliances with multiple credentials,
there must be a one-to-one correspondence of credentials to appliances:
`[-a appliance1 [-a appliance2...]] [-c credential1 [-c credential2...]]`
If you would prefer to not use plain-text passwords,
you can use the output of `$ mast-system xor <username:password>`.
* `-t, --timeout`: The timeout in seconds to wait for a response from
an appliance for any single request. __NOTE__ Program execution may
halt if a timeout is reached.
* `-n, --no-check-hostname`: If specified SSL verification will be turned
off when sending commands to the appliances.
* `-o, --out-dir`: (NOT NEEDED IN WEB GUI) The directory (local) to store
the backup
* `-C, --CryptoCertificate`: The CryptoCertificate object to use to encrypt
the backup
* `-d, --destination`: The base location (on the appliance) to store
the backup
* `-i, --include-iscsi`: Whether to include the iscsi filesystem
* `-I, --include-raid`: Whether to include the RAID filesystem
* `-N, --no-remove`: If specified the backup will NOT be removed from
the DataPower
* `--no-quiesce-before`: If specified, the appliance will not be
quiesced before performing the secure backup
* `--no-unquiesce-after`: If specified, the appliance will not be
unquiesced after performing the secure backup
* `-q, --quiesce-timeout`: The timeout to wait before the appliance
attempts to quiesce
* `-w, --web`: __For Internel Use Only, will be removed in future versions.
DO NOT USE.__"""
    logger = make_logger("mast.backups")
    check_hostname = not no_check_hostname
    env = datapower.Environment(appliances,
                                credentials,
                                timeout,
                                check_hostname=check_hostname)

    output = ""

    if quiesce_before:
        resp = {}
        for appliance in env.appliances:
            logger.info("Quiescing {} in preparation of Secure Backup".format(
                appliance.hostname))
            resp[appliance.hostname] = appliance.QuiesceDP(
                timeout=quiesce_timeout)
            logger.debug("Response received {}".format(
                resp[appliance.hostname]))
            if web:
                output += util.render_boolean_results_table(
                    resp, suffix="Quiesce_appliance")
        sleep(quiesce_timeout)

    t = Timestamp()
    if destination.endswith("/"):
        destination = destination.rstrip("/")
    destination = '%s/%s' % (destination, t.timestamp)

    kwargs = {'Dir': destination, 'domain': 'default'}

    logger.info("Creating directory {} on {} to store Secure Backup".format(
        destination, str(env.appliances)))
    resp = env.perform_async_action('CreateDir', **kwargs)
    logger.debug("Responses received {}".format(str(resp)))

    if web:
        output += util.render_boolean_results_table(resp, suffix="CreateDir")

    include_raid = 'on' if include_raid else 'off'
    include_iscsi = 'on' if include_iscsi else 'off'

    kwargs = {
        'cert': CryptoCertificate,
        'destination': destination,
        'include_iscsi': include_iscsi,
        'include_raid': include_raid
    }
    logger.info("Attempting to perform a Secure Backup on {}".format(
        str(env.appliances)))
    resp = env.perform_async_action('SecureBackup', **kwargs)
    logger.debug("Responses received: {}".format(str(resp)))

    if web:
        output += util.render_boolean_results_table(resp,
                                                    suffix="SecureBackup")

    if web:
        results = {}
        remove_results = {}
    for appliance in env.appliances:
        directory = os.path.join(out_dir, appliance.hostname, "SecureBackup",
                                 t.timestamp)

        start = time()
        while not appliance.file_exists(
                '{}/backupmanifest.xml'.format(destination), 'default'):
            sleep(5)
            if time() - start > timeout:
                raise TimeoutError

        logger.info("Attempting to retrieve Secure Backup from {}".format(
            appliance.hostname))
        appliance.copy_directory(destination, directory)

        _directory = os.path.join(
            directory,
            destination.replace(":", "").replace("///", "/"))

        try:
            logger.info("Attempting to verify Secure Backup for {}".format(
                appliance.hostname))
            if appliance.verify_local_backup(_directory):
                logger.info("Secure Backup integrity verified for {}".format(
                    appliance.hostname))
                if web:
                    results[appliance.hostname] = "Succeeded"
                else:
                    print '\t', appliance.hostname, " - ", "Succeeded"
                if remove:
                    logger.info(
                        "Attempting to remove Secure Backup from appliance "
                        "{}".format(appliance.hostname))
                    _resp = appliance.RemoveDir(Dir=destination,
                                                domain='default')
                    logger.debug("Response received: {}".format(_resp))
                    if web:
                        remove_results[appliance.hostname] = _resp
            else:
                logger.warn("Secure Backup for {} Corrupt!".format(
                    appliance.hostname))
                if web:
                    results[appliance.hostname] = "Failed"
                else:
                    print '\t', appliance.hostname, " - ", "Failed"
                appliance.log_error('Verification of backup in %s failed' %
                                    (_directory))
        except:
            if web:
                results[appliance.hostname] = "Failed"
            logger.exception(
                "An unhandled exception occurred during execution.")
    if web:
        output += util.render_results_table(results,
                                            suffix="verify-SecureBackup")
        output += util.render_boolean_results_table(remove_results,
                                                    suffix="RemoveDir")

    if unquiesce_after:
        resp = {}
        for appliance in env.appliances:
            logger.info("Attempting to unquiesce {}".format(
                str(appliance.hostname)))
            resp[appliance.hostname] = appliance.UnquiesceDP()
            logger.debug("Response received: {}".format(
                resp[appliance.hostname]))
            if web:
                output += util.render_boolean_results_table(
                    resp, suffix="Unquiesce_appliance")

    if web:
        return output, util.render_history(env)
def list_probes(appliances=[],
                credentials=[],
                timeout=120,
                no_check_hostname=False,
                Domain=[],
                web=False):
    """Lists all enabled probes in all specified domains

Parameters:

* `-a, --appliances`: The hostname(s), ip address(es), environment name(s)
or alias(es) of the appliances you would like to affect. For details
on configuring environments please see the comments in
`environments.conf` located in `$MAST_HOME/etc/default`. For details
on configuring aliases, please see the comments in `hosts.conf` located in
`$MAST_HOME/etc/default`. To pass multiple arguments to this parameter,
use multiple entries of the form `[-a appliance1 [-a appliance2...]]`
* `-c, --credentials`: The credentials to use for authenticating to the
appliances. Should be either one set to use for all appliances
or one set for each appliance. Credentials should be in the form
`username:password`. To pass multiple credentials to this parameter, use
multiple entries of the form `[-c credential1 [-c credential2...]]`.
When referencing multiple appliances with multiple credentials,
there must be a one-to-one correspondence of credentials to appliances:
`[-a appliance1 [-a appliance2...]] [-c credential1 [-c credential2...]]`
If you would prefer to not use plain-text passwords,
you can use the output of `$ mast-system xor <username:password>`.
* `-t, --timeout`: The timeout in seconds to wait for a response from
an appliance for any single request. __NOTE__ Program execution may
halt if a timeout is reached.
* `-n, --no-check-hostname`: If specified SSL verification will be turned
off when sending commands to the appliances.
* `-D, --Domain`: One or more domains to inspect. To spcify multiple domains,
use multiple entries of the form `[-D domain1 [-D domain2...]]`
* `-w, --web`: __For Internel Use Only, will be removed in future versions.
DO NOT USE.__"""
    import urllib2
    check_hostname = not no_check_hostname
    env = datapower.Environment(
        appliances,
        credentials,
        timeout=timeout,
        check_hostname=check_hostname)
    results = {}
    for appliance in env.appliances:
        domains = Domain
        if "all-domains" in Domain:
            domains = appliance.domains
        for domain in domains:
            try:
                config = appliance.get_config(
                    _class="all-classes",
                    name="all-objects",
                    domain=domain,
                    persisted=False)
            except urllib2.HTTPError:
                config = appliance.get_config(domain=domain, persisted=False)
            for obj in config.xml.findall(datapower.CONFIG_XPATH):
                if obj.find("DebugMode") is not None:
                    if obj.find("DebugMode").text == "on":
                        k = "{}-{}".format(appliance.hostname, domain)
                        v = "{} - {}".format(obj.tag, obj.get("name"))
                        if k in results:
                            results[k].append(v)
                        else:
                            results[k] = [v]
    if web:
        for k, v in results.items():
            results[k] = "\n".join(v)
        return (
            util.render_results_table(results),
            util.render_history(env))
    else:
        for k, v in results.items():
            print k, "\n", "-" * len(k)
            for item in v:
                print "\t{}".format(item)
Exemple #3
0
def postdeploy(appliances=[],
               credentials=[],
               timeout=120,
               no_check_hostname=False,
               Domain="",
               unquiesce_domain=True,
               unquiesce_appliance=False,
               postdeploy_command=None,
               save_config=True,
               web=False):
    """This is a simple script which will allow you to unquiesce
your domain or appliances after you quiesce them for a deployment.
Also this will allow you to save the config.

Parameters:

* `-a, --appliances`: The hostname(s), ip address(es), environment name(s)
or alias(es) of the appliances you would like to affect. For details
on configuring environments please see the comments in
`environments.conf` located in `$MAST_HOME/etc/default`. For details
on configuring aliases, please see the comments in `hosts.conf` located in
`$MAST_HOME/etc/default`. To pass multiple arguments to this parameter,
use multiple entries of the form `[-a appliance1 [-a appliance2...]]`
* `-c, --credentials`: The credentials to use for authenticating to the
appliances. Should be either one set to use for all appliances
or one set for each appliance. Credentials should be in the form
`username:password`. To pass multiple credentials to this parameter, use
multiple entries of the form `[-c credential1 [-c credential2...]]`.
When referencing multiple appliances with multiple credentials,
there must be a one-to-one correspondence of credentials to appliances:
`[-a appliance1 [-a appliance2...]] [-c credential1 [-c credential2...]]`
If you would prefer to not use plain-text passwords,
you can use the output of `$ mast-system xor <username:password>`.
* `-t, --timeout`: The timeout in seconds to wait for a response from
an appliance for any single request. __NOTE__ Program execution may
halt if a timeout is reached.
* `-n, --no-check-hostname`: If specified SSL verification will be turned
off when sending commands to the appliances.
* `-D, --Domain`: The domain which will be unquiesced and persisted.
* `-N, --no-unquiesce-domain`: If specified, this script will not attempt
to unquiesce the domain
* `-u, --unquiesce-appliance`: If specified, this script will attempt to
unquiesce the appliance
* `-p, --postdeploy-command`: This command will be "shelled out"
to the machine running MAST after unquiescing and saving the configuration,
use this parameter to clean up VCS artifacts and/or perform check-outs
of your deployed services or similar operations
* `--no-save-config`: If specified, the configuration will not be saved in
the application domain
* `-w, --web`: __For Internel Use Only, will be removed in future versions.
DO NOT USE.__"""
    import mast.datapower.system as system
    check_hostname = not no_check_hostname
    logger = make_logger('mast.datapower.deployment')

    env = datapower.Environment(
        appliances,
        credentials,
        timeout,
        check_hostname=check_hostname)

    if web:
        output = ""
        history = ""
    for appliance in env.appliances:
        if unquiesce_appliance:
            appliance.log_info("Attempting to unquiesce appliance")

            _out = system.unquiesce_appliance(
                appliances=[appliance.hostname],
                credentials=[appliance.credentials],
                timeout=timeout,
                no_check_hostname=no_check_hostname,
                web=web)
            appliance.log_info(
                "Finished Unquiescing appliance")

            if web:
                output += _out[0]
                history += _out[1]
            else:
                print "Finished unquiescing appliance"

        if unquiesce_domain:
            appliance.log_info("Attempting to unquiesce domain")

            _out = system.unquiesce_domain(
                appliances=[appliance.hostname],
                credentials=[appliance.credentials],
                timeout=timeout,
                no_check_hostname=no_check_hostname,
                Domain=Domain,
                web=web)
            appliance.log_info(
                "Finished Unquiescing domain")

            if web:
                output += _out[0]
                history += _out[1]
            else:
                print "Finished unquiescing domain"

        if save_config:
            appliance.log_info(
                "Attempting to save configuration after deployment")

            _out = system.save_config(
                appliances=[appliance.hostname],
                credentials=[appliance.credentials],
                timeout=timeout,
                no_check_hostname=no_check_hostname,
                Domain=Domain,
                web=web)

            appliance.log_info(
                "Finished saving configuration after deployment")

            if web:
                output += _out[0]
                history += _out[1]
            else:
                print "Finished saving the configuration"

    if postdeploy_command:
        logger.info(
            "Post-Deployment command '{}' found. Executing at {}".format(
                postdeploy_command, str(Timestamp())))

        out, err = system_call(command=postdeploy_command)
        out = str(out)
        err = str(err)

        logger.info(
            "finished executing Post-Deployment command '{}' at {}., output: {}".format(
                postdeploy_command, str(Timestamp()), ";".join([out, err])))
        if web:
            results = {"postdeploy command": "{}\n\nout: {}\n\nerr: {}".format(postdeploy_command, out, err)}
            output += render_results_table(results)
        else:
            print "Finished running post-deploy command. output: {}".format(
                ";".join([out, err]))

    if web:
        return output, history
Exemple #4
0
def get_normal_backup(appliances=[],
                      credentials=[],
                      timeout=120,
                      no_check_hostname=False,
                      Domain=[],
                      comment="",
                      out_dir='tmp',
                      individual=False,
                      web=False):
    """Performs a normal backup of the specified domain.

Parameters:

* `-a, --appliances`: The hostname(s), ip address(es), environment name(s)
or alias(es) of the appliances you would like to affect. For details
on configuring environments please see the comments in
`environments.conf` located in `$MAST_HOME/etc/default`. For details
on configuring aliases, please see the comments in `hosts.conf` located in
`$MAST_HOME/etc/default`. To pass multiple arguments to this parameter,
use multiple entries of the form `[-a appliance1 [-a appliance2...]]`
* `-c, --credentials`: The credentials to use for authenticating to the
appliances. Should be either one set to use for all appliances
or one set for each appliance. Credentials should be in the form
`username:password`. To pass multiple credentials to this parameter, use
multiple entries of the form `[-c credential1 [-c credential2...]]`.
When referencing multiple appliances with multiple credentials,
there must be a one-to-one correspondence of credentials to appliances:
`[-a appliance1 [-a appliance2...]] [-c credential1 [-c credential2...]]`
If you would prefer to not use plain-text passwords,
you can use the output of `$ mast-system xor <username:password>`.
* `-t, --timeout`: The timeout in seconds to wait for a response from
an appliance for any single request. __NOTE__ Program execution may
halt if a timeout is reached.
* `-n, --no-check-hostname`: If specified SSL verification will be turned
off when sending commands to the appliances.
* `-D, --Domain`: The domains to backup (all-domains will backup all domains)
To spcify multiple domains,
use multiple entries of the form `[-D domain1 [-D domain2...]]`
* `-C, --comment`: The comment to add to the backup
* `-o, --out-dir`: (NOT NEEDED IN WEB GUI) The directory (local) where you
would like to store the backup
* `-I, --individual`: If specified and all-domains is specified as --Domain
then backup each domain individually instead of "all-domains"
* `-w, --web`: __For Internel Use Only, will be removed in future versions.
DO NOT USE.__"""
    logger = make_logger("mast.backups")
    t = Timestamp()
    check_hostname = not no_check_hostname
    env = datapower.Environment(appliances,
                                credentials,
                                timeout,
                                check_hostname=check_hostname)

    if not Domain:
        raise ValueError(
            "Must provide one or more domains including 'all-domains'")

    if isinstance(Domain, basestring):
        Domain = [Domain]
    # Fixes duplicate domains issue
    Domain = list(set(Domain))

    results = {}
    if not individual:
        logger.info("Attempting to retrieve normal backup from "
                    "{} in {} domain".format(str(env.appliances), Domain))
        kwargs = {'domains': Domain, 'comment': comment}
        _results = env.perform_async_action('get_normal_backup', **kwargs)
        logger.debug("backups retrieved, check file for contents")

        for hostname, backup in _results.items():
            directory = os.path.join(out_dir, hostname, "NormalBackup",
                                     t.timestamp)
            os.makedirs(directory)
            filename = os.path.join(
                directory,
                '%s-%s-%s.zip' % (t.timestamp, hostname, "_".join(Domain)))

            logger.debug("Writing backup for {} to {}".format(
                hostname, filename))
            with open(filename, 'wb') as fout:
                fout.write(backup)

            if _verify_zip(filename):
                logger.info("backup for {} in {} domain verified".format(
                    hostname, str(Domain)))
                results[hostname + "-" + "_".join(Domain) +
                        "-normalBackup"] = "Verified"
            else:
                logger.info("backup for {} in {} domain corrupt".format(
                    hostname, str(Domain)))
                results[hostname + "-" + "_".join(Domain) +
                        "-normalBackup"] = "Corrupt"
    else:
        for domain in Domain:
            logger.info("Attempting to retrieve normal backup from "
                        "{} in {} domain".format(str(env.appliances), domain))
            kwargs = {'domains': domain, 'comment': comment}
            _results = env.perform_async_action('get_normal_backup', **kwargs)
            logger.debug("backups retrieved, check file for contents")

            for hostname, backup in _results.items():
                directory = os.path.join(out_dir, hostname, "NormalBackup",
                                         t.timestamp)
                if not os.path.exists(directory):
                    os.makedirs(directory)
                filename = os.path.join(
                    directory,
                    '%s-%s-%s.zip' % (t.timestamp, hostname, domain))

                logger.debug("Writing backup for {} to {}".format(
                    hostname, filename))
                with open(filename, 'wb') as fout:
                    fout.write(backup)

                if _verify_zip(filename):
                    logger.info("backup for {} in {} domain verified".format(
                        hostname, domain))
                    results[hostname + "-" + domain +
                            "-normalBackup"] = "Verified"
                else:
                    logger.info("backup for {} in {} domain corrupt".format(
                        hostname, domain))
                    results[hostname + "-" + domain +
                            "-normalBackup"] = "Corrupt"

    if web:
        return util.render_results_table(results), util.render_history(env)

    for k, v in results.items():
        print
        print k
        print '=' * len(k)
        print v
        print
Exemple #5
0
def del_password_map_alias(
    appliances=[],
    credentials=[],
    timeout=120,
    no_check_hostname=False,
    Domain="",
    alias_name="",
    save_config=True,
    web=False,
    ):
    """delete a password map alias on the specified appliances

Parameters:

* `-a, --appliances`: The hostname(s), ip address(es), environment name(s)
or alias(es) of the appliances you would like to affect. For details
on configuring environments please see the comments in
`environments.conf` located in `$MAST_HOME/etc/default`. For details
on configuring aliases, please see the comments in `hosts.conf` located in
`$MAST_HOME/etc/default`. To pass multiple arguments to this parameter,
use multiple entries of the form `[-a appliance1 [-a appliance2...]]`
* `-c, --credentials`: The credentials to use for authenticating to the
appliances. Should be either one set to use for all appliances
or one set for each appliance. Credentials should be in the form
`username:password`. To pass multiple credentials to this parameter, use
multiple entries of the form `[-c credential1 [-c credential2...]]`.
When referencing multiple appliances with multiple credentials,
there must be a one-to-one correspondence of credentials to appliances:
`[-a appliance1 [-a appliance2...]] [-c credential1 [-c credential2...]]`
If you would prefer to not use plain-text passwords,
you can use the output of `$ mast-system xor <username:password>`.
* `-t, --timeout`: The timeout in seconds to wait for a response from
an appliance for any single request. __NOTE__ Program execution may
halt if a timeout is reached.
* `-n, --no-check-hostname`: If specified SSL verification will be turned
off when sending commands to the appliances.
* `-A, --alias-name`: The name of the password map alias to delete
* `-N, --no-save-config`: If specified, the configuration of the domain will be
persisted
* `-w, --web`: __For Internel Use Only, will be removed in future versions.
DO NOT USE.__"""
    check_hostname = not no_check_hostname
    logger = make_logger('mast.datapower.deployment')

    env = datapower.Environment(
        appliances,
        credentials,
        timeout,
        check_hostname=check_hostname
    )

    if web:
        output = OrderedDict()
    for appliance in env.appliances:
        if not web:
            print(appliance.hostname)
            print("\tAttempting to remove Password Map Alias")
        response = appliance.DeletePasswordMap(
            domain=Domain,
            AliasName=alias_name,
        )
        logger.info(repr(response))
        if web:
            output["{}-{}".format(appliance.hostname, "DeletePasswordMapAlias")] = "\n".join(
                response.xml.find(
                    ".//{http://www.datapower.com/schemas/management}result"
                ).itertext()
            )
        else:
            print(
                "\t\t{}".format(
                    "\n\t\t".join(
                        response.xml.find(
                            ".//{http://www.datapower.com/schemas/management}result"
                        ).itertext()
                    ).strip()
                )
            )
        if save_config and response:
            if not web:
                print("\tSaving Configuration")
            response = appliance.SaveConfig(domain=Domain)
            logger.info(repr(response))
            if web:
                output["{}-{}".format(appliance.hostname, "SaveConfig")] = "\n".join(
                    response.xml.find(
                        ".//{http://www.datapower.com/schemas/management}result"
                    ).itertext()
                )
            else:
                print(
                    "\t\t{}".format(
                        "\n\t\t".join(
                            response.xml.find(
                                ".//{http://www.datapower.com/schemas/management}result"
                            ).itertext()
                        ).strip()
                    )
                )
    if web:
        return (
            render_results_table(output), 
            render_history(env),
        )        
Exemple #6
0
def predeploy(
        appliances=[],
        credentials=[],
        timeout=120,
        no_check_hostname=False,
        out_dir="tmp",
        Domain="",
        comment="",
        predeploy_command=None,
        CryptoCertificate="",
        secure_backup_destination="local:/raid0",
        backup_default=True,
        backup_all=True,
        do_secure_backup=False,
        do_normal_backup=True,
        set_checkpoints=True,
        include_iscsi=False,
        include_raid=False,
        remove_secure_backup=True,
        default_checkpoint=True,
        remove_oldest_checkpoint=True,
        allow_shell=False,
        web=False):
    """Perform routine pre-deployment actions. Everything is optional, but if
you wish to perform an action, you must provide the necessary arguments.

Parameters:

* `-a, --appliances`: The hostname(s), ip address(es), environment name(s)
or alias(es) of the appliances you would like to affect. For details
on configuring environments please see the comments in
`environments.conf` located in `$MAST_HOME/etc/default`. For details
on configuring aliases, please see the comments in `hosts.conf` located in
`$MAST_HOME/etc/default`. To pass multiple arguments to this parameter,
use multiple entries of the form `[-a appliance1 [-a appliance2...]]`
* `-c, --credentials`: The credentials to use for authenticating to the
appliances. Should be either one set to use for all appliances
or one set for each appliance. Credentials should be in the form
`username:password`. To pass multiple credentials to this parameter, use
multiple entries of the form `[-c credential1 [-c credential2...]]`.
When referencing multiple appliances with multiple credentials,
there must be a one-to-one correspondence of credentials to appliances:
`[-a appliance1 [-a appliance2...]] [-c credential1 [-c credential2...]]`
If you would prefer to not use plain-text passwords,
you can use the output of `$ mast-system xor <username:password>`.
* `-t, --timeout`: The timeout in seconds to wait for a response from
an appliance for any single request. __NOTE__ Program execution may
halt if a timeout is reached.
* `-n, --no-check-hostname`: If specified SSL verification will be turned
off when sending commands to the appliances.
* `-o, --out-dir`: (Not needed in web GUI) The directory (local)
where you would like to store the artifacts generated by this
script
* `-D, --Domain`: This is the app domain to backup and the app domain
in which to set a checkpoint
* `-C, --comment`: This is shared among other actions. The comment is
used to build the name of the checkpoint.
* `-p, --predeploy-command`: This command will be "shelled out"
to the machine running MAST after performing the backups and checkpoints.
Use this parameter to pull from version control or similar
operations.
* `--CryptoCertificate`: The CryptoCertificate with which to
encrypt the secure backup
* `-s, --secure-backup-destination`: The destination (on the DataPower)
where the secure backup will be stored
* `-N, --no-backup-default`: Whether to also backup the default domain
* `--no-backup-all`: Whether to also backup all-domains
* `-d, --do-secure-backup`: Whether to retrieve a secure backup
* `--no-do-normal-backup`: Whether to retrieve normal backups
* `--no-set-checkpoints`: Whether to set checkpoints
* `-i, --include-iscsi`: Whether to include the iscsi volume in the
secure backup
* `-I, --include-raid`: Whether to include the raid volume in the
secure backup
* `--no-remove-secure-backup`: Whether to remove the secure backup
from the appliance after verifying your local copy.
* `--no-default-checkpoint`: Whether to create a checkpoint in the
default domain
* `--no-remove-oldest-checkpoint`: Whether to remove the oldest
checkpoint from the domain IF AND ONLY IF the maximum number
of checkpoints has been reached.
* `-A, --allow-shell`: Whether to allocate a shell for the execution of
the predeploy-command
* `-w, --web`: __For Internel Use Only, will be removed in future versions.
DO NOT USE.__

Here is what is possible (will be done in this order):

1. Secure Backup
    * The following parameters apply:
        * `-d, --do-secure-backup`
        * `-o, --out-dir`
        * `--CryptoCertificate`
        * `-s, --secure-backup-destination`
        * `-i, --include-iscsi`
        * `-I, --include-raid`
        * `--no-remove-secure-backup`
2. Normal Backups
    * The following parameters apply:
        * `--no-do-normal-backup`
        * `-o, --out-dir`
        * `-D, --Domain`
        * `-N, --no-backup-default`
        * `--no-backup-all`
        * `-C, --comment`
3. Checkpoints
    * The following parameters apply:
        * `--no-set-checkpoints`
        * `-D, --Domain`
        * `-C, --comment`
        * `--no-default-checkpoint`
        * `--no-remove-oldest-checkpoint`"""
    from mast.datapower.backups import set_checkpoint
    from mast.datapower.backups import get_normal_backup, get_secure_backup

    logger = make_logger('mast.datapower.deployment')
    check_hostname = not no_check_hostname
    env = datapower.Environment(
        appliances,
        credentials,
        timeout,
        check_hostname=check_hostname)

    if web:
        output = ""
        history = ""

    # Loop through appliances so we will only affect one appliance at a time
    for appliance in env.appliances:

        # Secure Backup
        if do_secure_backup:
            if not CryptoCertificate:
                # Fail if CryptoCertificate is not given
                logger.error(
                    "Cert must be specified in order "
                    "to perform a secure backup!")
                sys.exit(-1)

            logger.info("Starting Secure Backup for {}".format(
                appliance.hostname))

            _out = get_secure_backup(
                appliances=appliance.hostname,
                credentials=appliance.credentials,
                timeout=timeout,
                out_dir=out_dir,
                CryptoCertificate=CryptoCertificate,
                destination=secure_backup_destination,
                include_iscsi=include_iscsi,
                include_raid=include_raid,
                remove=remove_secure_backup,
                quiesce_before=False,
                unquiesce_after=False,
                no_check_hostname=no_check_hostname,
                web=web)

            if web:
                output += _out[0]
                history += _out[1]

            logger.info("Finished Secure Backup for {}".format(
                appliance.hostname))

        # Normal backups
        if do_normal_backup:
            logger.info(
                "Pre-Deployment backups started at {}".format(
                    str(Timestamp())))

            domains = [Domain]
            if backup_default:
                domains.append("default")
            if backup_all:
                domains.append("all-domains")

            _out = get_normal_backup(
                appliances=[appliance.hostname],
                credentials=credentials,
                timeout=timeout,
                no_check_hostname=no_check_hostname,
                Domain=domains,
                comment=comment,
                out_dir=out_dir,
                web=web)

            logger.info(
                "Pre-Deployment backups finished at {}".format(
                    str(Timestamp())))

            if web:
                output += _out[0]
                history += _out[1]

        # Checkpoints
        if set_checkpoints:
            logger.info(
                "Pre-Deployment checkpoints started at {}".format(
                    str(Timestamp())))

            domains = [Domain]
            if default_checkpoint:
                domains.append("default")

            _out = set_checkpoint(
                appliances=[appliance.hostname],
                credentials=credentials,
                timeout=timeout,
                no_check_hostname=no_check_hostname,
                Domain=domains,
                comment=comment,
                remove_oldest=remove_oldest_checkpoint,
                web=web)

            logger.info(
                "Pre-Deployment checkpoints finished at {}".format(
                    str(Timestamp())))

            if web:
                output += _out[0]
                history += _out[1]

    if predeploy_command:
        logger.info(
            "Pre-Deployment command '{}' found. Executing at {}".format(
                predeploy_command, str(Timestamp())))

        out, err = system_call(command=predeploy_command, shell=allow_shell)
        out = str(out)
        err = str(err)

        logger.info(
            "finished executing Pre-Deployment command '{}' at {}., output: {}".format(
                predeploy_command, str(Timestamp()), ";".join([out, err])))
        if web:
            from mast.plugin_utils.plugin_utils import render_results_table
            results = {"predeploy command": "{}\n\nout: {}\n\nerr: {}".format(predeploy_command, out, err)}
            output += render_results_table(results)
        else:
            print "Finished running pre-deploy command. output: {}".format(
                ";".join([out, err]))

    if web:
        return output, history
def list_probes(appliances=[],
                credentials=[],
                timeout=120,
                no_check_hostname=False,
                Domain=[],
                web=False):
    """Lists all enabled probes in all specified domains

Parameters:

* `-a, --appliances`: The hostname(s), ip address(es), environment name(s)
or alias(es) of the appliances you would like to affect. For details
on configuring environments please see the comments in
`environments.conf` located in `$MAST_HOME/etc/default`. For details
on configuring aliases, please see the comments in `hosts.conf` located in
`$MAST_HOME/etc/default`. To pass multiple arguments to this parameter,
use multiple entries of the form `[-a appliance1 [-a appliance2...]]`
* `-c, --credentials`: The credentials to use for authenticating to the
appliances. Should be either one set to use for all appliances
or one set for each appliance. Credentials should be in the form
`username:password`. To pass multiple credentials to this parameter, use
multiple entries of the form `[-c credential1 [-c credential2...]]`.
When referencing multiple appliances with multiple credentials,
there must be a one-to-one correspondence of credentials to appliances:
`[-a appliance1 [-a appliance2...]] [-c credential1 [-c credential2...]]`
If you would prefer to not use plain-text passwords,
you can use the output of `$ mast-system xor <username:password>`.
* `-t, --timeout`: The timeout in seconds to wait for a response from
an appliance for any single request. __NOTE__ Program execution may
halt if a timeout is reached.
* `-n, --no-check-hostname`: If specified SSL verification will be turned
off when sending commands to the appliances.
* `-D, --Domain`: One or more domains to inspect. To spcify multiple domains,
use multiple entries of the form `[-D domain1 [-D domain2...]]`
* `-w, --web`: __For Internel Use Only, will be removed in future versions.
DO NOT USE.__"""
    import urllib2
    check_hostname = not no_check_hostname
    env = datapower.Environment(
        appliances,
        credentials,
        timeout=timeout,
        check_hostname=check_hostname)
    results = {}
    for appliance in env.appliances:
        domains = Domain
        if "all-domains" in Domain:
            domains = appliance.domains
        for domain in domains:
            try:
                config = appliance.get_config(
                    _class="all-classes",
                    name="all-objects",
                    domain=domain,
                    persisted=False)
            except urllib2.HTTPError:
                config = appliance.get_config(domain=domain, persisted=False)
            for obj in config.xml.findall(datapower.CONFIG_XPATH):
                if obj.find("DebugMode") is not None:
                    if obj.find("DebugMode").text == "on":
                        k = "{}-{}".format(appliance.hostname, domain)
                        v = "{} - {}".format(obj.tag, obj.get("name"))
                        if k in results:
                            results[k].append(v)
                        else:
                            results[k] = [v]
    if web:
        for k, v in results.items():
            results[k] = "\n".join(v)
        return (
            util.render_results_table(results),
            util.render_history(env))
    else:
        for k, v in results.items():
            print k, "\n", "-" * len(k)
            for item in v:
                print "\t{}".format(item)
def get_secure_backup(appliances=[],
                      credentials=[],
                      timeout=1200,
                      no_check_hostname=False,
                      out_dir='tmp',
                      CryptoCertificate="",
                      destination='local:/raid0',
                      include_iscsi=False,
                      include_raid=False,
                      remove=True,
                      quiesce_before=True,
                      unquiesce_after=True,
                      quiesce_timeout=60,
                      web=False):
    """Performs a secure backup of the specified domain.

Parameters:

* `-a, --appliances`: The hostname(s), ip address(es), environment name(s)
or alias(es) of the appliances you would like to affect. For details
on configuring environments please see the comments in
`environments.conf` located in `$MAST_HOME/etc/default`. For details
on configuring aliases, please see the comments in `hosts.conf` located in
`$MAST_HOME/etc/default`. To pass multiple arguments to this parameter,
use multiple entries of the form `[-a appliance1 [-a appliance2...]]`
* `-c, --credentials`: The credentials to use for authenticating to the
appliances. Should be either one set to use for all appliances
or one set for each appliance. Credentials should be in the form
`username:password`. To pass multiple credentials to this parameter, use
multiple entries of the form `[-c credential1 [-c credential2...]]`.
When referencing multiple appliances with multiple credentials,
there must be a one-to-one correspondence of credentials to appliances:
`[-a appliance1 [-a appliance2...]] [-c credential1 [-c credential2...]]`
If you would prefer to not use plain-text passwords,
you can use the output of `$ mast-system xor <username:password>`.
* `-t, --timeout`: The timeout in seconds to wait for a response from
an appliance for any single request. __NOTE__ Program execution may
halt if a timeout is reached.
* `-n, --no-check-hostname`: If specified SSL verification will be turned
off when sending commands to the appliances.
* `-o, --out-dir`: (NOT NEEDED IN WEB GUI) The directory (local) to store
the backup
* `-C, --CryptoCertificate`: The CryptoCertificate object to use to encrypt
the backup
* `-d, --destination`: The base location (on the appliance) to store
the backup
* `-i, --include-iscsi`: Whether to include the iscsi filesystem
* `-I, --include-raid`: Whether to include the RAID filesystem
* `-N, --no-remove`: If specified the backup will NOT be removed from
the DataPower
* `--no-quiesce-before`: If specified, the appliance will not be
quiesced before performing the secure backup
* `--no-unquiesce-after`: If specified, the appliance will not be
unquiesced after performing the secure backup
* `-q, --quiesce-timeout`: The timeout to wait before the appliance
attempts to quiesce
* `-w, --web`: __For Internel Use Only, will be removed in future versions.
DO NOT USE.__"""
    logger = make_logger("mast.backups")
    check_hostname = not no_check_hostname
    env = datapower.Environment(
        appliances,
        credentials,
        timeout,
        check_hostname=check_hostname)

    output = ""

    if quiesce_before:
        resp = {}
        for appliance in env.appliances:
            logger.info(
                "Quiescing {} in preparation of Secure Backup".format(
                    appliance.hostname))
            resp[appliance.hostname] = appliance.QuiesceDP(
                timeout=quiesce_timeout)
            logger.debug(
                "Response received {}".format(resp[appliance.hostname]))
            if web:
                output += util.render_boolean_results_table(
                    resp, suffix="Quiesce_appliance")
        sleep(quiesce_timeout)

    t = Timestamp()
    if destination.endswith("/"):
        destination = destination.rstrip("/")
    destination = '%s/%s' % (destination, t.timestamp)

    kwargs = {'Dir': destination, 'domain': 'default'}

    logger.info(
        "Creating directory {} on {} to store Secure Backup".format(
            destination, str(env.appliances)))
    resp = env.perform_async_action('CreateDir', **kwargs)
    logger.debug("Responses received {}".format(str(resp)))

    if web:
        output += util.render_boolean_results_table(resp, suffix="CreateDir")

    include_raid = 'on' if include_raid else 'off'
    include_iscsi = 'on' if include_iscsi else 'off'

    kwargs = {
        'cert': CryptoCertificate,
        'destination': destination,
        'include_iscsi': include_iscsi,
        'include_raid': include_raid}
    logger.info(
        "Attempting to perform a Secure Backup on {}".format(
            str(env.appliances)))
    resp = env.perform_async_action('SecureBackup', **kwargs)
    logger.debug("Responses received: {}".format(str(resp)))

    if web:
        output += util.render_boolean_results_table(
            resp, suffix="SecureBackup")

    if web:
        results = {}
        remove_results = {}
    for appliance in env.appliances:
        directory = os.path.join(
            out_dir,
            appliance.hostname,
            "SecureBackup",
            t.timestamp)

        start = time()
        while not appliance.file_exists(
                '{}/backupmanifest.xml'.format(
                    destination),
                'default'):
                sleep(5)
                if time() - start > timeout:
                    raise TimeoutError

        logger.info(
            "Attempting to retrieve Secure Backup from {}".format(
                appliance.hostname))
        appliance.copy_directory(
            destination,
            directory)

        _directory = os.path.join(
            directory, destination.replace(":", "").replace("///", "/"))

        try:
            logger.info(
                "Attempting to verify Secure Backup for {}".format(
                    appliance.hostname))
            if appliance.verify_local_backup(_directory):
                logger.info(
                    "Secure Backup integrity verified for {}".format(
                        appliance.hostname))
                if web:
                    results[appliance.hostname] = "Succeeded"
                else:
                    print '\t', appliance.hostname, " - ", "Succeeded"
                if remove:
                    logger.info(
                        "Attempting to remove Secure Backup from appliance "
                        "{}".format(
                            appliance.hostname))
                    _resp = appliance.RemoveDir(
                        Dir=destination, domain='default')
                    logger.debug("Response received: {}".format(_resp))
                    if web:
                        remove_results[appliance.hostname] = _resp
            else:
                logger.warn(
                    "Secure Backup for {} Corrupt!".format(
                        appliance.hostname))
                if web:
                    results[appliance.hostname] = "Failed"
                else:
                    print '\t', appliance.hostname, " - ", "Failed"
                appliance.log_error(
                    'Verification of backup in %s failed' % (_directory))
        except:
            if web:
                results[appliance.hostname] = "Failed"
            logger.exception(
                "An unhandled exception occurred during execution.")
    if web:
        output += util.render_results_table(
            results, suffix="verify-SecureBackup")
        output += util.render_boolean_results_table(
            remove_results, suffix="RemoveDir")

    if unquiesce_after:
        resp = {}
        for appliance in env.appliances:
            logger.info(
                "Attempting to unquiesce {}".format(
                    str(appliance.hostname)))
            resp[appliance.hostname] = appliance.UnquiesceDP()
            logger.debug(
                "Response received: {}".format(
                    resp[appliance.hostname]))
            if web:
                output += util.render_boolean_results_table(
                    resp, suffix="Unquiesce_appliance")

    if web:
        return output, util.render_history(env)
def get_normal_backup(appliances=[],
                      credentials=[],
                      timeout=120,
                      no_check_hostname=False,
                      Domain=[],
                      comment="",
                      out_dir='tmp',
                      individual=False,
                      web=False):
    """Performs a normal backup of the specified domain.

Parameters:

* `-a, --appliances`: The hostname(s), ip address(es), environment name(s)
or alias(es) of the appliances you would like to affect. For details
on configuring environments please see the comments in
`environments.conf` located in `$MAST_HOME/etc/default`. For details
on configuring aliases, please see the comments in `hosts.conf` located in
`$MAST_HOME/etc/default`. To pass multiple arguments to this parameter,
use multiple entries of the form `[-a appliance1 [-a appliance2...]]`
* `-c, --credentials`: The credentials to use for authenticating to the
appliances. Should be either one set to use for all appliances
or one set for each appliance. Credentials should be in the form
`username:password`. To pass multiple credentials to this parameter, use
multiple entries of the form `[-c credential1 [-c credential2...]]`.
When referencing multiple appliances with multiple credentials,
there must be a one-to-one correspondence of credentials to appliances:
`[-a appliance1 [-a appliance2...]] [-c credential1 [-c credential2...]]`
If you would prefer to not use plain-text passwords,
you can use the output of `$ mast-system xor <username:password>`.
* `-t, --timeout`: The timeout in seconds to wait for a response from
an appliance for any single request. __NOTE__ Program execution may
halt if a timeout is reached.
* `-n, --no-check-hostname`: If specified SSL verification will be turned
off when sending commands to the appliances.
* `-D, --Domain`: The domains to backup (all-domains will backup all domains)
To spcify multiple domains,
use multiple entries of the form `[-D domain1 [-D domain2...]]`
* `-C, --comment`: The comment to add to the backup
* `-o, --out-dir`: (NOT NEEDED IN WEB GUI) The directory (local) where you
would like to store the backup
* `-I, --individual`: If specified and all-domains is specified as --Domain
then backup each domain individually instead of "all-domains"
* `-w, --web`: __For Internel Use Only, will be removed in future versions.
DO NOT USE.__"""
    logger = make_logger("mast.backups")
    t = Timestamp()
    check_hostname = not no_check_hostname
    env = datapower.Environment(
        appliances,
        credentials,
        timeout,
        check_hostname=check_hostname)
    
    if not Domain:
        raise ValueError("Must provide one or more domains including 'all-domains'")

    if isinstance(Domain, basestring):
        Domain = [Domain]
    # Fixes duplicate domains issue
    Domain = list(set(Domain))

    results = {}
    if not individual:
        logger.info(
            "Attempting to retrieve normal backup from "
            "{} in {} domain".format(str(env.appliances), Domain))
        kwargs = {'domains': Domain, 'comment': comment}
        _results = env.perform_async_action('get_normal_backup', **kwargs)
        logger.debug("backups retrieved, check file for contents")

        for hostname, backup in _results.items():
            directory = os.path.join(
                out_dir,
                hostname,
                "NormalBackup",
                t.timestamp)
            os.makedirs(directory)
            filename = os.path.join(
                directory,
                '%s-%s-%s.zip' % (
                    t.timestamp,
                    hostname,
                    "_".join(Domain)))

            logger.debug(
                "Writing backup for {} to {}".format(
                    hostname, filename))
            with open(filename, 'wb') as fout:
                fout.write(backup)

            if _verify_zip(filename):
                logger.info(
                    "backup for {} in {} domain verified".format(
                        hostname, str(Domain)))
                results[hostname + "-" + "_".join(Domain) + "-normalBackup"] = "Verified"
            else:
                logger.info(
                    "backup for {} in {} domain corrupt".format(
                        hostname, str(Domain)))
                results[hostname + "-" + "_".join(Domain) + "-normalBackup"] = "Corrupt"
    else:
        for domain in Domain:
            logger.info(
                "Attempting to retrieve normal backup from "
                "{} in {} domain".format(str(env.appliances), domain))
            kwargs = {'domains': domain, 'comment': comment}
            _results = env.perform_async_action('get_normal_backup', **kwargs)
            logger.debug("backups retrieved, check file for contents")

            for hostname, backup in _results.items():
                directory = os.path.join(
                    out_dir,
                    hostname,
                    "NormalBackup",
                    t.timestamp)
                if not os.path.exists(directory):
                    os.makedirs(directory)
                filename = os.path.join(
                    directory,
                    '%s-%s-%s.zip' % (
                        t.timestamp,
                        hostname,
                        domain))

                logger.debug(
                    "Writing backup for {} to {}".format(
                        hostname, filename))
                with open(filename, 'wb') as fout:
                    fout.write(backup)

                if _verify_zip(filename):
                    logger.info(
                        "backup for {} in {} domain verified".format(
                            hostname, domain))
                    results[hostname + "-" + domain + "-normalBackup"] = "Verified"
                else:
                    logger.info(
                        "backup for {} in {} domain corrupt".format(
                            hostname, domain))
                    results[hostname + "-" + domain + "-normalBackup"] = "Corrupt"

    if web:
        return util.render_results_table(results), util.render_history(env)

    for k, v in results.items():
        print
        print k
        print '=' * len(k)
        print v
        print
def postdeploy(appliances=[],
               credentials=[],
               timeout=120,
               no_check_hostname=False,
               Domain="",
               unquiesce_domain=True,
               unquiesce_appliance=False,
               postdeploy_command=None,
               save_config=True,
               web=False):
    """This is a simple script which will allow you to unquiesce
your domain or appliances after you quiesce them for a deployment.
Also this will allow you to save the config.

Parameters:

* `-a, --appliances`: The hostname(s), ip address(es), environment name(s)
or alias(es) of the appliances you would like to affect. For details
on configuring environments please see the comments in
`environments.conf` located in `$MAST_HOME/etc/default`. For details
on configuring aliases, please see the comments in `hosts.conf` located in
`$MAST_HOME/etc/default`. To pass multiple arguments to this parameter,
use multiple entries of the form `[-a appliance1 [-a appliance2...]]`
* `-c, --credentials`: The credentials to use for authenticating to the
appliances. Should be either one set to use for all appliances
or one set for each appliance. Credentials should be in the form
`username:password`. To pass multiple credentials to this parameter, use
multiple entries of the form `[-c credential1 [-c credential2...]]`.
When referencing multiple appliances with multiple credentials,
there must be a one-to-one correspondence of credentials to appliances:
`[-a appliance1 [-a appliance2...]] [-c credential1 [-c credential2...]]`
If you would prefer to not use plain-text passwords,
you can use the output of `$ mast-system xor <username:password>`.
* `-t, --timeout`: The timeout in seconds to wait for a response from
an appliance for any single request. __NOTE__ Program execution may
halt if a timeout is reached.
* `-n, --no-check-hostname`: If specified SSL verification will be turned
off when sending commands to the appliances.
* `-D, --Domain`: The domain which will be unquiesced and persisted.
* `-N, --no-unquiesce-domain`: If specified, this script will not attempt
to unquiesce the domain
* `-u, --unquiesce-appliance`: If specified, this script will attempt to
unquiesce the appliance
* `-p, --postdeploy-command`: This command will be "shelled out"
to the machine running MAST after unquiescing and saving the configuration,
use this parameter to clean up VCS artifacts and/or perform check-outs
of your deployed services or similar operations
* `--no-save-config`: If specified, the configuration will not be saved in
the application domain
* `-w, --web`: __For Internel Use Only, will be removed in future versions.
DO NOT USE.__"""
    import mast.datapower.system as system
    check_hostname = not no_check_hostname
    logger = make_logger('mast.datapower.deployment')

    env = datapower.Environment(appliances,
                                credentials,
                                timeout,
                                check_hostname=check_hostname)

    if web:
        output = ""
        history = ""
    for appliance in env.appliances:
        if unquiesce_appliance:
            appliance.log_info("Attempting to unquiesce appliance")

            _out = system.unquiesce_appliance(
                appliances=[appliance.hostname],
                credentials=[appliance.credentials],
                timeout=timeout,
                no_check_hostname=no_check_hostname,
                web=web)
            appliance.log_info("Finished Unquiescing appliance")

            if web:
                output += _out[0]
                history += _out[1]
            else:
                print "Finished unquiescing appliance"

        if unquiesce_domain:
            appliance.log_info("Attempting to unquiesce domain")

            _out = system.unquiesce_domain(appliances=[appliance.hostname],
                                           credentials=[appliance.credentials],
                                           timeout=timeout,
                                           no_check_hostname=no_check_hostname,
                                           Domain=Domain,
                                           web=web)
            appliance.log_info("Finished Unquiescing domain")

            if web:
                output += _out[0]
                history += _out[1]
            else:
                print "Finished unquiescing domain"

        if save_config:
            appliance.log_info(
                "Attempting to save configuration after deployment")

            _out = system.save_config(appliances=[appliance.hostname],
                                      credentials=[appliance.credentials],
                                      timeout=timeout,
                                      no_check_hostname=no_check_hostname,
                                      Domain=Domain,
                                      web=web)

            appliance.log_info(
                "Finished saving configuration after deployment")

            if web:
                output += _out[0]
                history += _out[1]
            else:
                print "Finished saving the configuration"

    if postdeploy_command:
        logger.info(
            "Post-Deployment command '{}' found. Executing at {}".format(
                postdeploy_command, str(Timestamp())))

        out, err = system_call(command=postdeploy_command)
        out = str(out)
        err = str(err)

        logger.info(
            "finished executing Post-Deployment command '{}' at {}., output: {}"
            .format(postdeploy_command, str(Timestamp()), ";".join([out,
                                                                    err])))
        if web:
            from mast.plugin_utils.plugin_utils import render_results_table
            results = {
                "postdeploy command":
                "{}\n\nout: {}\n\nerr: {}".format(postdeploy_command, out, err)
            }
            output += render_results_table(results)
        else:
            print "Finished running post-deploy command. output: {}".format(
                ";".join([out, err]))

    if web:
        return output, history
def predeploy(appliances=[],
              credentials=[],
              timeout=120,
              no_check_hostname=False,
              out_dir="tmp",
              Domain="",
              comment="",
              predeploy_command=None,
              CryptoCertificate="",
              secure_backup_destination="local:/raid0",
              backup_default=True,
              backup_all=True,
              do_secure_backup=False,
              do_normal_backup=True,
              set_checkpoints=True,
              include_iscsi=False,
              include_raid=False,
              remove_secure_backup=True,
              default_checkpoint=True,
              remove_oldest_checkpoint=True,
              allow_shell=False,
              web=False):
    """Perform routine pre-deployment actions. Everything is optional, but if
you wish to perform an action, you must provide the necessary arguments.

Parameters:

* `-a, --appliances`: The hostname(s), ip address(es), environment name(s)
or alias(es) of the appliances you would like to affect. For details
on configuring environments please see the comments in
`environments.conf` located in `$MAST_HOME/etc/default`. For details
on configuring aliases, please see the comments in `hosts.conf` located in
`$MAST_HOME/etc/default`. To pass multiple arguments to this parameter,
use multiple entries of the form `[-a appliance1 [-a appliance2...]]`
* `-c, --credentials`: The credentials to use for authenticating to the
appliances. Should be either one set to use for all appliances
or one set for each appliance. Credentials should be in the form
`username:password`. To pass multiple credentials to this parameter, use
multiple entries of the form `[-c credential1 [-c credential2...]]`.
When referencing multiple appliances with multiple credentials,
there must be a one-to-one correspondence of credentials to appliances:
`[-a appliance1 [-a appliance2...]] [-c credential1 [-c credential2...]]`
If you would prefer to not use plain-text passwords,
you can use the output of `$ mast-system xor <username:password>`.
* `-t, --timeout`: The timeout in seconds to wait for a response from
an appliance for any single request. __NOTE__ Program execution may
halt if a timeout is reached.
* `-n, --no-check-hostname`: If specified SSL verification will be turned
off when sending commands to the appliances.
* `-o, --out-dir`: (Not needed in web GUI) The directory (local)
where you would like to store the artifacts generated by this
script
* `-D, --Domain`: This is the app domain to backup and the app domain
in which to set a checkpoint
* `-C, --comment`: This is shared among other actions. The comment is
used to build the name of the checkpoint.
* `-p, --predeploy-command`: This command will be "shelled out"
to the machine running MAST after performing the backups and checkpoints.
Use this parameter to pull from version control or similar
operations.
* `--CryptoCertificate`: The CryptoCertificate with which to
encrypt the secure backup
* `-s, --secure-backup-destination`: The destination (on the DataPower)
where the secure backup will be stored
* `-N, --no-backup-default`: Whether to also backup the default domain
* `--no-backup-all`: Whether to also backup all-domains
* `-d, --do-secure-backup`: Whether to retrieve a secure backup
* `--no-do-normal-backup`: Whether to retrieve normal backups
* `--no-set-checkpoints`: Whether to set checkpoints
* `-i, --include-iscsi`: Whether to include the iscsi volume in the
secure backup
* `-I, --include-raid`: Whether to include the raid volume in the
secure backup
* `--no-remove-secure-backup`: Whether to remove the secure backup
from the appliance after verifying your local copy.
* `--no-default-checkpoint`: Whether to create a checkpoint in the
default domain
* `--no-remove-oldest-checkpoint`: Whether to remove the oldest
checkpoint from the domain IF AND ONLY IF the maximum number
of checkpoints has been reached.
* `-A, --allow-shell`: Whether to allocate a shell for the execution of
the predeploy-command
* `-w, --web`: __For Internel Use Only, will be removed in future versions.
DO NOT USE.__

Here is what is possible (will be done in this order):

1. Secure Backup
    * The following parameters apply:
        * `-d, --do-secure-backup`
        * `-o, --out-dir`
        * `--CryptoCertificate`
        * `-s, --secure-backup-destination`
        * `-i, --include-iscsi`
        * `-I, --include-raid`
        * `--no-remove-secure-backup`
2. Normal Backups
    * The following parameters apply:
        * `--no-do-normal-backup`
        * `-o, --out-dir`
        * `-D, --Domain`
        * `-N, --no-backup-default`
        * `--no-backup-all`
        * `-C, --comment`
3. Checkpoints
    * The following parameters apply:
        * `--no-set-checkpoints`
        * `-D, --Domain`
        * `-C, --comment`
        * `--no-default-checkpoint`
        * `--no-remove-oldest-checkpoint`"""
    from mast.datapower.backups import set_checkpoint
    from mast.datapower.backups import get_normal_backup, get_secure_backup

    logger = make_logger('mast.datapower.deployment')
    check_hostname = not no_check_hostname
    env = datapower.Environment(appliances,
                                credentials,
                                timeout,
                                check_hostname=check_hostname)

    if web:
        output = ""
        history = ""

    # Loop through appliances so we will only affect one appliance at a time
    for appliance in env.appliances:

        # Secure Backup
        if do_secure_backup:
            if not CryptoCertificate:
                # Fail if CryptoCertificate is not given
                logger.error("Cert must be specified in order "
                             "to perform a secure backup!")
                sys.exit(-1)

            logger.info("Starting Secure Backup for {}".format(
                appliance.hostname))

            _out = get_secure_backup(appliances=appliance.hostname,
                                     credentials=appliance.credentials,
                                     timeout=timeout,
                                     out_dir=out_dir,
                                     CryptoCertificate=CryptoCertificate,
                                     destination=secure_backup_destination,
                                     include_iscsi=include_iscsi,
                                     include_raid=include_raid,
                                     remove=remove_secure_backup,
                                     quiesce_before=False,
                                     unquiesce_after=False,
                                     no_check_hostname=no_check_hostname,
                                     web=web)

            if web:
                output += _out[0]
                history += _out[1]

            logger.info("Finished Secure Backup for {}".format(
                appliance.hostname))

        # Normal backups
        if do_normal_backup:
            logger.info("Pre-Deployment backups started at {}".format(
                str(Timestamp())))

            domains = [Domain]
            if backup_default:
                domains.append("default")
            if backup_all:
                domains.append("all-domains")

            _out = get_normal_backup(appliances=[appliance.hostname],
                                     credentials=credentials,
                                     timeout=timeout,
                                     no_check_hostname=no_check_hostname,
                                     Domain=domains,
                                     comment=comment,
                                     out_dir=out_dir,
                                     web=web)

            logger.info("Pre-Deployment backups finished at {}".format(
                str(Timestamp())))

            if web:
                output += _out[0]
                history += _out[1]

        # Checkpoints
        if set_checkpoints:
            logger.info("Pre-Deployment checkpoints started at {}".format(
                str(Timestamp())))

            domains = [Domain]
            if default_checkpoint:
                domains.append("default")

            _out = set_checkpoint(appliances=[appliance.hostname],
                                  credentials=credentials,
                                  timeout=timeout,
                                  no_check_hostname=no_check_hostname,
                                  Domain=domains,
                                  comment=comment,
                                  remove_oldest=remove_oldest_checkpoint,
                                  web=web)

            logger.info("Pre-Deployment checkpoints finished at {}".format(
                str(Timestamp())))

            if web:
                output += _out[0]
                history += _out[1]

    if predeploy_command:
        logger.info(
            "Pre-Deployment command '{}' found. Executing at {}".format(
                predeploy_command, str(Timestamp())))

        out, err = system_call(command=predeploy_command, shell=allow_shell)
        out = str(out)
        err = str(err)

        logger.info(
            "finished executing Pre-Deployment command '{}' at {}., output: {}"
            .format(predeploy_command, str(Timestamp()), ";".join([out, err])))
        if web:
            from mast.plugin_utils.plugin_utils import render_results_table
            results = {
                "predeploy command":
                "{}\n\nout: {}\n\nerr: {}".format(predeploy_command, out, err)
            }
            output += render_results_table(results)
        else:
            print "Finished running pre-deploy command. output: {}".format(
                ";".join([out, err]))

    if web:
        return output, history