Bootstrap minions with salt-bootstrap

    version : develop
        Git tag of version to install

    script : https://bootstrap.saltstack.com
        URL containing the script to execute

    hosts
        Comma-separated hosts [example: hosts='host1.local,host2.local']. These
        hosts need to exist in the specified roster.

    script_args
        Any additional arguments that you want to pass to the script.

        .. versionadded:: 2016.11.0

    roster : flat
        The roster to use for Salt SSH. More information about roster files can
        be found in :ref:`Salt's Roster Documentation <ssh-roster>`.

        A full list of roster types, see the :ref:`builtin roster modules <all-salt.roster>`
        documentation.

        .. versionadded:: 2016.11.0

    ssh_user
        If ``user`` isn't found in the ``roster``, a default SSH user can be set here.
        Keep in mind that ``ssh_user`` will not override the roster ``user`` value if
        it is already defined.

        .. versionadded:: 2016.11.0

    ssh_password
        If ``passwd`` isn't found in the ``roster``, a default SSH password can be set
        here. Keep in mind that ``ssh_password`` will not override the roster ``passwd``
        value if it is already defined.

        .. versionadded:: 2016.11.0

    ssh_privkey
        If ``priv`` isn't found in the ``roster``, a default SSH private key can be set
        here. Keep in mind that ``ssh_password`` will not override the roster ``passwd``
        value if it is already defined.

        .. versionadded:: 2016.11.0

    tmp_dir : /tmp/.bootstrap
        The temporary directory to download the bootstrap script in. This
        directory will have ``-<uuid4>`` appended to it. For example:
        ``/tmp/.bootstrap-a19a728e-d40a-4801-aba9-d00655c143a7/``

        .. versionadded:: 2016.11.0

    http_backend : tornado
        The backend library to use to download the script. If you need to use
        a ``file:///`` URL, then you should set this to ``urllib2``.

        .. versionadded:: 2016.11.0


    CLI Example:

    .. code-block:: bash

        salt-run manage.bootstrap hosts='host1,host2'
        salt-run manage.bootstrap hosts='host1,host2' version='v0.17'
        salt-run manage.bootstrap hosts='host1,host2' version='v0.17' \
            script='https://bootstrap.saltstack.com/develop'

def bootstrap(version='develop',
              script=None,
              hosts='',
              script_args='',
              roster='flat',
              ssh_user=None,
              ssh_password=None,
              ssh_priv_key=None,
              tmp_dir='/tmp/.bootstrap',
              http_backend='tornado'):
    '''
    Bootstrap minions with salt-bootstrap

    version : develop
        Git tag of version to install

    script : https://bootstrap.saltstack.com
        URL containing the script to execute

    hosts
        Comma-separated hosts [example: hosts='host1.local,host2.local']. These
        hosts need to exist in the specified roster.

    script_args
        Any additional arguments that you want to pass to the script.

        .. versionadded:: 2016.11.0

    roster : flat
        The roster to use for Salt SSH. More information about roster files can
        be found in :ref:`Salt's Roster Documentation <ssh-roster>`.

        A full list of roster types, see the :ref:`builtin roster modules <all-salt.roster>`
        documentation.

        .. versionadded:: 2016.11.0

    ssh_user
        If ``user`` isn't found in the ``roster``, a default SSH user can be set here.
        Keep in mind that ``ssh_user`` will not override the roster ``user`` value if
        it is already defined.

        .. versionadded:: 2016.11.0

    ssh_password
        If ``passwd`` isn't found in the ``roster``, a default SSH password can be set
        here. Keep in mind that ``ssh_password`` will not override the roster ``passwd``
        value if it is already defined.

        .. versionadded:: 2016.11.0

    ssh_privkey
        If ``priv`` isn't found in the ``roster``, a default SSH private key can be set
        here. Keep in mind that ``ssh_password`` will not override the roster ``passwd``
        value if it is already defined.

        .. versionadded:: 2016.11.0

    tmp_dir : /tmp/.bootstrap
        The temporary directory to download the bootstrap script in. This
        directory will have ``-<uuid4>`` appended to it. For example:
        ``/tmp/.bootstrap-a19a728e-d40a-4801-aba9-d00655c143a7/``

        .. versionadded:: 2016.11.0

    http_backend : tornado
        The backend library to use to download the script. If you need to use
        a ``file:///`` URL, then you should set this to ``urllib2``.

        .. versionadded:: 2016.11.0


    CLI Example:

    .. code-block:: bash

        salt-run manage.bootstrap hosts='host1,host2'
        salt-run manage.bootstrap hosts='host1,host2' version='v0.17'
        salt-run manage.bootstrap hosts='host1,host2' version='v0.17' \
            script='https://bootstrap.saltstack.com/develop'

    '''
    if script is None:
        script = 'https://bootstrap.saltstack.com'

    client_opts = __opts__.copy()
    if roster is not None:
        client_opts['roster'] = roster

    if ssh_user is not None:
        client_opts['ssh_user'] = ssh_user

    if ssh_password is not None:
        client_opts['ssh_passwd'] = ssh_password

    if ssh_priv_key is not None:
        client_opts['ssh_priv'] = ssh_priv_key

    for host in hosts.split(','):
        client_opts['tgt'] = host
        client_opts['selected_target_option'] = 'glob'
        tmp_dir = '{0}-{1}/'.format(tmp_dir.rstrip('/'), uuid.uuid4())
        deploy_command = os.path.join(tmp_dir, 'deploy.sh')
        try:
            client_opts['argv'] = ['file.makedirs', tmp_dir, 'mode=0700']
            salt.client.ssh.SSH(client_opts).run()
            client_opts['argv'] = [
                'http.query',
                script,
                'backend={0}'.format(http_backend),
                'text_out={0}'.format(deploy_command)
            ]
            client = salt.client.ssh.SSH(client_opts).run()
            client_opts['argv'] = [
                'cmd.run',
                ' '.join(['sh', deploy_command, script_args]),
                'python_shell=False'
            ]
            salt.client.ssh.SSH(client_opts).run()
            client_opts['argv'] = ['file.remove', tmp_dir]
            salt.client.ssh.SSH(client_opts).run()
        except SaltSystemExit as exc:
            log.error(six.text_type(exc))