예제 #1
0
def get_password(vm_):
    '''
    Return the password to use
    '''
    return config.get_config_value(
        'password', vm_, __opts__, default=config.get_config_value(
            'passwd', vm_, __opts__, search_global=False
        ), search_global=False
    )
예제 #2
0
def get_conn():
    '''
    Return a conn object for the passed VM data
    '''
    vm_ = get_configured_provider()
    driver = get_driver(Provider.IBM)
    return driver(
        config.get_config_value('user', vm_, __opts__, search_global=False),
        config.get_config_value('password', vm_, __opts__, search_global=False)
    )
예제 #3
0
def master_client(cloud):
    vm_ = cloud.vm_profile('master')
    provider = cloud.provider_profile_full(vm_)

    username = config.get_config_value('ssh_username', vm_, cloud.opts)
    hostname = cloud.opts['cloudseed'].get('ip_address', None)

    if 'private_key' in provider or 'private_key' in vm_:
        private_key = config.get_config_value('private_key', vm_, cloud.opts)

        return client(hostname=hostname,
                      identity=private_key,
                      username=username)
예제 #4
0
def get_password(vm_):
    '''
    Return the password to use
    '''
    return config.get_config_value('password',
                                   vm_,
                                   __opts__,
                                   default=config.get_config_value(
                                       'passwd',
                                       vm_,
                                       __opts__,
                                       search_global=False),
                                   search_global=False)
예제 #5
0
def get_conn():
    '''
    Return a conn object for the passed VM data
    '''
    driver = get_driver(Provider.GOGRID)
    vm_ = get_configured_provider()
    return driver(
        config.get_config_value(
            'apikey', vm_, __opts__, search_global=False
        ),
        config.get_config_value(
            'sharedsecret', vm_, __opts__, search_global=False
        )
    )
예제 #6
0
def query(method='droplets', droplet_id=None, command=None, args=None):
    '''
    Make a web call to Digital Ocean
    '''
    path = 'https://api.digitalocean.com/{0}/'.format(method)

    if droplet_id:
        path = '{0}/'.format(droplet_id)

    if command:
        path += command

    if type(args) is not dict:
        args = {}

    args['client_id'] = config.get_config_value(
        'client_key', get_configured_provider(), __opts__, search_global=False
    )
    args['api_key'] = config.get_config_value(
        'api_key', get_configured_provider(), __opts__, search_global=False
    )

    path += '?%s'
    params = urllib.urlencode(args)
    request = urllib2.urlopen(path % params)
    if request.getcode() != 200:
        raise SaltCloudSystemExit(
            'An error occurred while querying Digital Ocean. HTTP Code: {0}  '
            'Error: {1!r}'.format(
                request.getcode(),
                request.read()
            )
        )

    log.debug(request.geturl())

    content = request.read()
    request.close()

    result = json.loads(content)
    if result.get('status', '').lower() == 'error':
        raise SaltCloudSystemExit(
            ''.join(
                '{0}: {1}\n'.format(k, '\n'.join(v)) for (k, v) in
                result.get('error_message', {}).items()
            )
        )

    return result
예제 #7
0
def master_client(cloud):
    vm_ = cloud.vm_profile('master')
    provider = cloud.provider_profile_full(vm_)

    username = config.get_config_value('ssh_username', vm_, cloud.opts)
    hostname = cloud.opts['cloudseed'].get('ip_address', None)

    if 'private_key' in provider or 'private_key' in vm_:
        private_key = config.get_config_value('private_key', vm_, cloud.opts)

        return client(
            hostname=hostname,
            identity=private_key,
            username=username
            )
예제 #8
0
def _toggle_term_protect(name, enabled):
    '''
    Toggle termination protection on a node
    '''
    # region is required for all boto queries
    region = get_location(None)

    # init botocore
    vm_ = get_configured_provider()
    session = botocore.session.get_session()
    session.set_credentials(
        access_key=config.get_config_value(
            'id', vm_, __opts__, search_global=False
        ),
        secret_key=config.get_config_value(
            'key', vm_, __opts__, search_global=False
        )
    )

    service = session.get_service('ec2')
    endpoint = service.get_endpoint(region)

    # get the instance-id for the supplied node name
    conn = get_conn(location=region)
    node = get_node(conn, name)

    params = {
        'instance_id': node.id,
        'attribute': 'disableApiTermination',
        'value': 'true' if enabled else 'false',
    }

    # get instance information
    operation = service.get_operation('modify-instance-attribute')
    http_response, response_data = operation.call(endpoint, **params)

    if http_response.status_code == 200:
        msg = 'Termination protection successfully {0} on {1}'.format(
            enabled and 'enabled' or 'disabled',
            name
        )
        log.info(msg)
        return msg

    # No proper HTTP response!?
    msg = 'Bad response from AWS: {0}'.format(http_response.status_code)
    log.error(msg)
    return msg
예제 #9
0
def securitygroup(vm_):
    '''
    Return the security group
    '''
    return config.get_config_value(
        'securitygroup', vm_, __opts__, search_global=False
    )
예제 #10
0
def keyname(vm_):
    '''
    Return the keyname
    '''
    return config.get_config_value(
        'keyname', vm_, __opts__, search_global=False
    )
예제 #11
0
def get_availability_zone(vm_):
    '''
    Return the availability zone to use
    '''
    avz = config.get_config_value(
        'availability_zone', vm_, __opts__, search_global=False
    )

    if avz is None:
        return None

    zones = list_availability_zones()

    # Validate user-specified AZ
    if avz not in zones.keys():
        raise SaltCloudException(
            'The specified availability zone isn\'t valid in this region: '
            '{0}\n'.format(
                avz
            )
        )

    # check specified AZ is available
    elif zones[avz] != 'available':
        raise SaltCloudException(
            'The specified availability zone isn\'t currently available: '
            '{0}\n'.format(
                avz
            )
        )

    return avz
예제 #12
0
def ssh_interface(vm_):
    '''
    Return the ssh_interface type to connect to. Either 'public_ips' (default)
    or 'private_ips'.
    '''
    return config.get_config_value(
        'ssh_interface', vm_, __opts__, default='public_ips',
        search_global=False
    )
예제 #13
0
def get_conn():
    '''
    Return a conn object for the passed VM data
    '''
    driver = get_driver(Provider.LINODE)
    return driver(
        config.get_config_value(
            'apikey', get_configured_provider(), __opts__, search_global=False
        )
    )
예제 #14
0
def get_location(conn, vm_):
    '''
    Return the node location to use
    '''
    locations = conn.list_locations()
    # Default to Dallas if not otherwise set
    loc = config.get_config_value('location', vm_, __opts__, default=2)
    for location in locations:
        if str(loc) in (str(location.id), str(location.name)):
            return location
예제 #15
0
def script(vm_):
    '''
    Return the script deployment object
    '''
    minion = saltcloud.utils.minion_conf_string(__opts__, vm_)
    script = saltcloud.utils.os_script(
        config.get_config_value('script', vm_, __opts__),
        vm_, __opts__, minion
    )
    return script
예제 #16
0
def get_conn():
    '''
    Return a conn object for the passed VM data
    '''
    driver = get_driver(Provider.HOSTVIRTUAL)
    return driver(
        config.get_config_value('apikey',
                                get_configured_provider(),
                                __opts__,
                                search_global=False))
예제 #17
0
def get_location(conn, vm_):
    '''
    Return the node location to use
    '''
    locations = conn.list_locations()
    # Default to Dallas if not otherwise set
    loc = config.get_config_value('location', vm_, __opts__, default=2)
    for location in locations:
        if str(loc) in (str(location.id), str(location.name)):
            return location
예제 #18
0
def bootstrap_minion(vm_):
    log.debug('Bootstrapping Minion %s', vm_)

    securitygroups = config.get_config_value('securitygroup', vm_, __opts__)

    marker = marker_security_group()

    create_securitygroup(name=vm_['name'], description='CloudseedApp')

    # merge security groups
    vm_['securitygroup'] = securitygroups + [vm_['name'], marker]
예제 #19
0
def get_size(vm_):
    '''
    Return the VM's size. Used by create_node().
    '''
    sizes = avail_sizes()
    vm_size = str(config.get_config_value(
        'size', vm_, __opts__, search_global=False
    ))
    for size in sizes:
        if vm_size in (sizes[size]['name'], sizes[size]['id']):
            return sizes[size]['id']
    raise SaltCloudNotFound('The specified size could not be found.')
예제 #20
0
def get_image(vm_):
    '''
    Return the image object to use
    '''
    images = avail_images()
    vm_image = config.get_config_value(
        'image', vm_, __opts__, search_global=False
    )
    for image in images:
        if str(vm_image) in (images[image]['name'], images[image]['id']):
            return images[image]['id']
    raise SaltCloudNotFound('The specified image could not be found.')
예제 #21
0
def get_location(conn, vm_):
    '''
    Return the location object to use
    '''
    locations = conn.list_locations()
    vm_location = config.get_config_value('location', vm_, __opts__)

    for img in locations:
        if vm_location and str(vm_location) in (str(img.id), str(img.name)):
            return img

    raise SaltCloudNotFound('The specified location could not be found.')
예제 #22
0
    def action(*args, **kwargs):
        cloud = env.cloud()
        vm_ = cloud.vm_profile('master')
        ip_address = cloud.opts['cloudseed']['ip_address']

        private_key = config.get_config_value('private_key', vm_, cloud.opts)
        username = config.get_config_value('ssh_username', vm_, cloud.opts)
        password = config.get_config_value('password', vm_, cloud.opts)

        socket = ssh.agent_zmq_tunnel(socket_type=zmq.REQ,
                                      host=ip_address,
                                      port='5556',
                                      private_key=private_key,
                                      username=username,
                                      password=password)

        socket.send_json(fun(*args, **kwargs))
        response = socket.recv_json()

        if 'data' in response:
            return response['data']
예제 #23
0
def get_conn():
    '''
    Return a conn object for the passed VM data
    '''
    vm_ = get_configured_provider()
    driver = get_driver(Provider.OPENSTACK)
    authinfo = {
        'ex_force_auth_url': config.get_config_value(
            'identity_url', vm_, __opts__, search_global=False
        ),
        'ex_force_service_name': config.get_config_value(
            'compute_name', vm_, __opts__, search_global=False
        ),
        'ex_force_service_region': config.get_config_value(
            'compute_region', vm_, __opts__, search_global=False
        ),
        'ex_tenant_name': config.get_config_value(
            'tenant', vm_, __opts__, search_global=False
        ),
        'ex_force_service_name': config.get_config_value(
            'compute_name', vm_, __opts__, search_global=False
        )
    }

    password = config.get_config_value(
        'password', vm_, __opts__, search_global=False
    )
    if password is not None:
        authinfo['ex_force_auth_version'] = '2.0_password'
        log.debug('OpenStack authenticating using password')
        return driver(
            config.get_config_value(
                'user', vm_, __opts__, search_global=False
            ),
            password,
            **authinfo
        )

    authinfo['ex_force_auth_version'] = '2.0_apikey'
    log.debug('OpenStack authenticating using apikey')
    return driver(
        config.get_config_value('user', vm_, __opts__, search_global=False),
        config.get_config_value('apikey', vm_, __opts__, search_global=False),
        **authinfo
    )
예제 #24
0
def get_image(conn, vm_):
    '''
    Return the image object to use
    '''
    images = conn.list_images()

    vm_image = config.get_config_value('image', vm_, __opts__)

    for img in images:
        if vm_image and str(vm_image) in (str(img.id), str(img.name)):
            return img

    raise SaltCloudNotFound('The specified image could not be found.')
예제 #25
0
    def action(*args, **kwargs):
        cloud = env.cloud()
        vm_ = cloud.vm_profile('master')
        ip_address = cloud.opts['cloudseed']['ip_address']

        private_key = config.get_config_value('private_key', vm_, cloud.opts)
        username = config.get_config_value('ssh_username', vm_, cloud.opts)
        password = config.get_config_value('password', vm_, cloud.opts)

        socket = ssh.agent_zmq_tunnel(
            socket_type=zmq.REQ,
            host=ip_address,
            port='5556',
            private_key=private_key,
            username=username,
            password=password)

        socket.send_json(fun(*args, **kwargs))
        response = socket.recv_json()

        if 'data' in response:
            return response['data']
예제 #26
0
def get_size(conn, vm_):
    '''
    Return the VM's size object
    '''
    sizes = conn.list_sizes()
    vm_size = config.get_config_value('size', vm_, __opts__)
    if not vm_size:
        return sizes[0]

    for size in sizes:
        if vm_size and str(vm_size) in (str(size.id), str(size.name)):
            return size
    raise SaltCloudNotFound('The specified size could not be found.')
예제 #27
0
def ssh_pub(vm_):
    '''
    Deploy the primary ssh authentication key
    '''
    ssh = config.get_config_value('ssh_auth', vm_, __opts__)
    if not ssh:
        return None

    ssh = os.path.expanduser(ssh)
    if os.path.isfile(ssh):
        return None

    return SSHKeyDeployment(open(ssh).read())
예제 #28
0
def get_location(vm_):
    '''
    Return the VM's location
    '''
    locations = avail_locations()
    vm_location = str(config.get_config_value(
        'location', vm_, __opts__, search_global=False
    ))

    for location in locations:
        if vm_location in (locations[location]['name'],
                           locations[location]['id']):
            return locations[location]['id']
    raise SaltCloudNotFound('The specified location could not be found.')
예제 #29
0
def bootstrap_minion(vm_):
    log.debug('Bootstrapping Minion %s', vm_)

    securitygroups = config.get_config_value(
        'securitygroup',
         vm_,
         __opts__)

    marker = marker_security_group()

    create_securitygroup(
            name=vm_['name'],
            description='CloudseedApp')

    # merge security groups
    vm_['securitygroup'] = securitygroups + [vm_['name'], marker]
예제 #30
0
def destroy(name, call=None):
    '''
    Destroy a node. Will check termination protection and warn if enabled.

    CLI Example::

        salt-cloud --destroy mymachine
    '''
    instance_id = _get_node(name)['instanceId']
    protected = show_term_protect(
        name=name,
        instance_id=instance_id,
        call='action',
        quiet=True
    )

    if protected == 'true':
        raise SaltCloudSystemExit(
            'This instance has been protected from being destroyed. '
            'Use the following command to disable protection:\n\n'
            'salt-cloud -a disable_term_protect {0}'.format(
                name
            )
        )

    ret = {}

    if config.get_config_value('rename_on_destroy',
                               get_configured_provider(),
                               __opts__, search_global=False) is True:
        newname = '{0}-DEL{1}'.format(name, uuid.uuid4().hex)
        rename(name, kwargs={'newname': newname}, call='action')
        log.info(
            'Machine will be identified as {0} until it has been '
            'cleaned up.'.format(
                newname
            )
        )
        ret['newname'] = newname

    params = {'Action': 'TerminateInstances',
              'InstanceId.1': instance_id}
    result = query(params)
    log.info(result)

    ret.update(result[0])
    return ret
예제 #31
0
def get_location(vm_=None):
    '''
    Return the EC2 region to use, in this order:
        - CLI parameter
        - Cloud profile setting
        - Global salt-cloud config
    '''
    return __opts__.get(
        'location',
        config.get_config_value(
            'location',
            vm_ or get_configured_provider(),
            __opts__,
            default=DEFAULT_LOCATION,
            #search_global=False
        )
    )
예제 #32
0
def preferred_ip(vm_, ips):
    '''
    Return the preferred Internet protocol. Either 'ipv4' (default) or 'ipv6'.
    '''
    proto = config.get_config_value(
        'protocol', vm_, __opts__, default='ipv4', search_global=False
    )
    family = socket.AF_INET
    if proto == 'ipv6':
        family = socket.AF_INET6
    for ip in ips:
        try:
            socket.inet_pton(family, ip)
            return ip
        except:
            continue
    return False
예제 #33
0
def ssh_username(vm_):
    '''
    Return the ssh_username. Defaults to a built-in list of users for trying.
    '''
    usernames = config.get_config_value(
        'ssh_username', vm_, __opts__
    )

    if not isinstance(usernames, list):
        usernames = [usernames]

    # get rid of None's or empty names
    usernames = filter(lambda x: x, usernames)

    # Add common usernames to the list to be tested
    for name in ('ec2-user', 'ubuntu', 'admin', 'bitnami', 'root'):
        if name not in usernames:
            usernames.append(name)
    return usernames
예제 #34
0
def create(vm_):
    '''
    Create a single VM from a data dict
    '''
    log.info('Creating Cloud VM {0}'.format(vm_['name']))
    saltcloud.utils.check_name(vm_['name'], 'a-zA-Z0-9._-')
    conn = get_conn()
    kwargs = {
        'name': vm_['name']
    }

    try:
        kwargs['image'] = get_image(conn, vm_)
    except Exception as exc:
        log.error(
            'Error creating {0} on OPENSTACK\n\n'
            'Could not find image {1}: {2}\n'.format(
                vm_['name'], vm_['image'], exc
            ),
            # Show the traceback if the debug logging level is enabled
            exc_info=log.isEnabledFor(logging.DEBUG)
        )
        return False

    try:
        kwargs['size'] = get_size(conn, vm_)
    except Exception as exc:
        log.error(
            'Error creating {0} on OPENSTACK\n\n'
            'Could not find size {1}: {2}\n'.format(
                vm_['name'], vm_['size'], exc
            ),
            # Show the traceback if the debug logging level is enabled
            exc_info=log.isEnabledFor(logging.DEBUG)
        )
        return False

    kwargs['ex_keyname'] = config.get_config_value(
        'ssh_key_name', vm_, __opts__, search_global=False
    )

    security_groups = config.get_config_value(
        'security_groups', vm_, __opts__, search_global=False
    )
    if security_groups is not None:
        vm_groups = security_groups.split(',')
        avail_groups = conn.ex_list_security_groups()
        group_list = []

        for vg in vm_groups:
            if vg in [ag.name for ag in avail_groups]:
                group_list.append(vg)
            else:
                raise SaltCloudNotFound(
                    'No such security group: \'{0}\''.format(
                        group
                    )
                )

        kwargs['ex_security_groups'] = [
            g for g in avail_groups if g.name in group_list
        ]

    try:
        data = conn.create_node(**kwargs)
    except Exception as exc:
        log.error(
            'Error creating {0} on OPENSTACK\n\n'
            'The following exception was thrown by libcloud when trying to '
            'run the initial deployment: {1}\n'.format(
                vm_['name'], exc
            ),
            # Show the traceback if the debug logging level is enabled
            exc_info=log.isEnabledFor(logging.DEBUG)
        )
        return False

    not_ready = True
    nr_total = 50
    nr_count = nr_total
    while not_ready:
        log.debug('Looking for IP addresses')
        nodelist = list_nodes(conn)
        private = nodelist[vm_['name']]['private_ips']
        public = nodelist[vm_['name']]['public_ips']
        running = nodelist[vm_['name']]['state'] == node_state(
            NodeState.RUNNING
        )
        if running and private and not public:
            log.warn(
                'Private IPs returned, but not public... Checking for '
                'misidentified IPs'
            )
            for private_ip in private:
                private_ip = preferred_ip(vm_, [private_ip])
                if saltcloud.utils.is_public_ip(private_ip):
                    log.warn('{0} is a public ip'.format(private_ip))
                    data.public_ips.append(private_ip)
                    not_ready = False
                else:
                    log.warn('{0} is a private ip'.format(private_ip))
                    ignore_ip = ignore_ip_addr(vm_, private_ip)
                    if private_ip not in data.private_ips and not ignore_ip:
                        data.private_ips.append(private_ip)
            if ssh_interface(vm_) == 'private_ips' and data.private_ips:
                break

        if running and public:
            data.public_ips = public
            not_ready = False

        nr_count -= 1
        if nr_count == 0:
            log.warn('Timed out waiting for a public ip, continuing anyway')
            break
        time.sleep(nr_total - nr_count + 5)

    if ssh_interface(vm_) == 'private_ips':
        ip_address = preferred_ip(vm_, data.private_ips)
    else:
        ip_address = preferred_ip(vm_, data.public_ips)
    log.debug('Using IP address {0}'.format(ip_address))

    if not ip_address:
        raise SaltCloudException('A valid IP address was not found')

    deploy_kwargs = {
        'host': ip_address,
        'name': vm_['name'],
        'sock_dir': __opts__['sock_dir'],
        'start_action': __opts__['start_action'],
        'minion_pem': vm_['priv_key'],
        'minion_pub': vm_['pub_key'],
        'keep_tmp': __opts__['keep_tmp'],
        'script_args': config.get_config_value(
            'script_args', vm_, __opts__
        )
    }

    deploy_kwargs['minion_conf'] = saltcloud.utils.minion_conf_string(
        __opts__,
        vm_
    )

    ssh_username = config.get_config_value(
        'ssh_username', vm_, __opts__, default='root'
    )
    if ssh_username != 'root':
        deploy_kwargs['deploy_command'] = '/tmp/deploy.sh'
        deploy_kwargs['username'] = ssh_username
        deploy_kwargs['tty'] = True

    log.debug('Using {0} as SSH username'.format(ssh_username))

    ssh_key_file = config.get_config_value(
        'ssh_key_file', vm_, __opts__, search_global=False
    )
    if ssh_key_file is not None:
        deploy_kwargs['key_filename'] = ssh_key_file
        log.debug(
            'Using {0} as SSH key file'.format(ssh_key_file)
        )
    elif 'password' in data.extra:
        deploy_kwargs['password'] = data.extra['password']
        log.debug('Logging into SSH using password')

    ret = {}
    sudo = config.get_config_value(
        'sudo', vm_, __opts__, default=(ssh_username != 'root')
    )
    if sudo is not None:
        deploy_kwargs['sudo'] = sudo
        log.debug('Running root commands using sudo')

    if config.get_config_value('deploy', vm_, __opts__) is True:
        deploy_script = script(vm_)
        deploy_kwargs['script'] = deploy_script.script

        # Deploy salt-master files, if necessary
        if config.get_config_value('make_master', vm_, __opts__) is True:
            deploy_kwargs['make_master'] = True
            deploy_kwargs['master_pub'] = vm_['master_pub']
            deploy_kwargs['master_pem'] = vm_['master_pem']
            master_conf = saltcloud.utils.master_conf_string(__opts__, vm_)
            if master_conf:
                deploy_kwargs['master_conf'] = master_conf

            if 'syndic_master' in master_conf:
                deploy_kwargs['make_syndic'] = True

        deployed = saltcloud.utils.deploy_script(**deploy_kwargs)
        if deployed:
            log.info('Salt installed on {0}'.format(vm_['name']))
            if __opts__.get('show_deploy_args', False) is True:
                ret['deploy_kwargs'] = deploy_kwargs
        else:
            log.error(
                'Failed to start Salt on Cloud VM {0}'.format(
                    vm_['name']
                )
            )

    log.info(
        'Created Cloud VM {0} with the following values:'.format(
            vm_['name']
        )
    )
    for key, val in data.__dict__.items():
        ret[key] = val
        log.info('  {0}: {1}'.format(key, val))

    return ret
예제 #35
0
def create(vm_):
    '''
    Create a single VM from a data dict
    '''
    log.info('Creating Cloud VM {0}'.format(vm_['name']))
    conn = get_conn()
    kwargs = {
        'name': vm_['name'],
        'image': get_image(conn, vm_),
        'size': get_size(conn, vm_),
        'location': get_location(conn, vm_),
        'auth': NodeAuthPassword(get_password(vm_))
    }
    try:
        data = conn.create_node(**kwargs)
    except Exception as exc:
        log.error(
            'Error creating {0} on LINODE\n\n'
            'The following exception was thrown by libcloud when trying to '
            'run the initial deployment: \n{1}'.format(
                vm_['name'], exc.message
            ),
            # Show the traceback if the debug logging level is enabled
            exc_info=log.isEnabledFor(logging.DEBUG)
        )
        return False

    ret = {}
    if config.get_config_value('deploy', vm_, __opts__) is True:
        deploy_script = script(vm_)
        deploy_kwargs = {
            'host': data.public_ips[0],
            'username': '******',
            'password': get_password(vm_),
            'script': deploy_script.script,
            'name': vm_['name'],
            'deploy_command': '/tmp/deploy.sh',
            'start_action': __opts__['start_action'],
            'sock_dir': __opts__['sock_dir'],
            'conf_file': __opts__['conf_file'],
            'minion_pem': vm_['priv_key'],
            'minion_pub': vm_['pub_key'],
            'keep_tmp': __opts__['keep_tmp'],
            'script_args': config.get_config_value(
                'script_args', vm_, __opts__
            )
        }

        deploy_kwargs['minion_conf'] = saltcloud.utils.minion_conf_string(
            __opts__,
            vm_
        )

        # Deploy salt-master files, if necessary
        if config.get_config_value('make_master', vm_, __opts__) is True:
            deploy_kwargs['make_master'] = True
            deploy_kwargs['master_pub'] = vm_['master_pub']
            deploy_kwargs['master_pem'] = vm_['master_pem']
            master_conf = saltcloud.utils.master_conf_string(__opts__, vm_)
            if master_conf:
                deploy_kwargs['master_conf'] = master_conf

            if 'syndic_master' in master_conf:
                deploy_kwargs['make_syndic'] = True

        deployed = saltcloud.utils.deploy_script(**deploy_kwargs)
        if deployed:
            log.info('Salt installed on {0}'.format(vm_['name']))
            if __opts__.get('show_deploy_args', False) is True:
                ret['deploy_kwargs'] = deploy_kwargs
        else:
            log.error(
                'Failed to start Salt on Cloud VM {0}'.format(
                    vm_['name']
                )
            )

    log.info(
        'Created Cloud VM {0} with the following values:'.format(
            vm_['name']
        )
    )
    for key, val in data.__dict__.items():
        ret[key] = val
        log.info('  {0}: {1}'.format(key, val))

    return ret
예제 #36
0
def create(vm_):
    '''
    Provision a single machine
    '''
    if config.get_config_value('deploy', vm_, __opts__) is False:
        return {
            'Error': {
                'No Deploy': '\'deploy\' is not enabled. Not deploying.'
            }
        }

    ret = {}

    log.info('Provisioning existing machine {0}'.format(vm_['name']))

    ssh_username = config.get_config_value('ssh_username', vm_, __opts__)
    deploy_script = script(vm_)
    deploy_kwargs = {
        'host': vm_['ssh_host'],
        'username': ssh_username,
        'script': deploy_script,
        'name': vm_['name'],
        'deploy_command': '/tmp/deploy.sh',
        'start_action': __opts__['start_action'],
        'sock_dir': __opts__['sock_dir'],
        'conf_file': __opts__['conf_file'],
        'minion_pem': vm_['priv_key'],
        'minion_pub': vm_['pub_key'],
        'keep_tmp': __opts__['keep_tmp'],
        'sudo': config.get_config_value(
            'sudo', vm_, __opts__, default=(ssh_username != 'root')
        ),
        'password': config.get_config_value(
            'password', vm_, __opts__, search_global=False
        ),
        'ssh_keyfile': config.get_config_value(
            'ssh_keyfile', vm_, __opts__, search_global=False
        ),
        'script_args': config.get_config_value(
            'script_args', vm_, __opts__
        ),
        'minion_conf': saltcloud.utils.minion_conf_string(__opts__, vm_)
    }

    # Deploy salt-master files, if necessary
    if config.get_config_value('make_master', vm_, __opts__) is True:
        deploy_kwargs['make_master'] = True
        deploy_kwargs['master_pub'] = vm_['master_pub']
        deploy_kwargs['master_pem'] = vm_['master_pem']
        master_conf = saltcloud.utils.master_conf_string(__opts__, vm_)
        if master_conf:
            deploy_kwargs['master_conf'] = master_conf

        if 'syndic_master' in master_conf:
            deploy_kwargs['make_syndic'] = True

    deployed = saltcloud.utils.deploy_script(**deploy_kwargs)
    if deployed:
        ret['deployed'] = deployed
        log.info('Salt installed on {0}'.format(vm_['name']))
        if __opts__.get('show_deploy_args', False) is True:
            ret['deploy_kwargs'] = deploy_kwargs
        return ret

    log.error('Failed to start Salt on host {0}'.format(vm_['name']))
    return {
        'Error': {
            'Not Deployed': 'Failed to start Salt on host {0}'.format(
                vm_['name']
            )
        }
    }
예제 #37
0
def create(vm_):
    '''
    Create a single VM from a data dict
    '''
    saltcloud.utils.fire_event(
        'event',
        'starting create',
        'salt/cloud/{0}/creating'.format(vm_['name']),
        {
            'name': vm_['name'],
            'profile': vm_['profile'],
            'provider': vm_['provider'],
        },
    )

    log.info('Creating Cloud VM {0}'.format(vm_['name']))
    conn = get_conn()
    kwargs = {
        'name': vm_['name'],
        'image': get_image(conn, vm_),
        'size': get_size(conn, vm_),
        'location': get_location(conn, vm_),
        'auth': NodeAuthPassword(get_password(vm_))
    }

    saltcloud.utils.fire_event(
        'event',
        'requesting instance',
        'salt/cloud/{0}/requesting'.format(vm_['name']),
        {
            'kwargs': {
                'name': kwargs['name'],
                'image': kwargs['image'].name,
                'size': kwargs['size'].name,
                'location': kwargs['location'].name
            }
        },
    )

    try:
        # pop off the first 3 since f*****g hv driver
        # doesn't use kwargs for these 3...
        # whereas auth and location are...
        name = kwargs.pop('name')
        image = kwargs.pop('image')
        size = kwargs.pop('size')
        data = conn.create_node(name, image, size, **kwargs)
    except Exception as exc:
        log.error(
            'Error creating {0} on HOSTVIRTUAL\n\n'
            'The following exception was thrown by libcloud when trying to '
            'run the initial deployment: \n{1}'.format(vm_['name'],
                                                       exc.message),
            # Show the traceback if the debug logging level is enabled
            exc_info=log.isEnabledFor(logging.DEBUG))
        return False

    ssh_username = config.get_config_value('ssh_username',
                                           vm_,
                                           __opts__,
                                           default='root')

    ret = {}
    if config.get_config_value('deploy', vm_, __opts__) is True:
        deploy_script = script(vm_)
        deploy_kwargs = {
            'host':
            data.public_ips[0],
            'username':
            ssh_username,
            'password':
            get_password(vm_),
            'script':
            deploy_script.script,
            'name':
            vm_['name'],
            'tmp_dir':
            config.get_config_value('tmp_dir',
                                    vm_,
                                    __opts__,
                                    default='/tmp/.saltcloud'),
            'deploy_command':
            config.get_config_value(
                'deploy_command',
                vm_,
                __opts__,
                default='/tmp/.saltcloud/deploy.sh',
            ),
            'start_action':
            __opts__['start_action'],
            'parallel':
            __opts__['parallel'],
            'sock_dir':
            __opts__['sock_dir'],
            'conf_file':
            __opts__['conf_file'],
            'minion_pem':
            vm_['priv_key'],
            'minion_pub':
            vm_['pub_key'],
            'keep_tmp':
            __opts__['keep_tmp'],
            'preseed_minion_keys':
            vm_.get('preseed_minion_keys', None),
            'sudo':
            config.get_config_value('sudo',
                                    vm_,
                                    __opts__,
                                    default=(ssh_username != 'root')),
            'sudo_password':
            config.get_config_value('sudo_password',
                                    vm_,
                                    __opts__,
                                    default=None),
            'tty':
            config.get_config_value('tty', vm_, __opts__, default=False),
            'display_ssh_output':
            config.get_config_value('display_ssh_output',
                                    vm_,
                                    __opts__,
                                    default=True),
            'script_args':
            config.get_config_value('script_args', vm_, __opts__),
            'script_env':
            config.get_config_value('script_env', vm_, __opts__),
            'minion_conf':
            saltcloud.utils.minion_config(__opts__, vm_)
        }

        # Deploy salt-master files, if necessary
        if config.get_config_value('make_master', vm_, __opts__) is True:
            deploy_kwargs['make_master'] = True
            deploy_kwargs['master_pub'] = vm_['master_pub']
            deploy_kwargs['master_pem'] = vm_['master_pem']
            master_conf = saltcloud.utils.master_config(__opts__, vm_)
            deploy_kwargs['master_conf'] = master_conf

            if master_conf.get('syndic_master', None):
                deploy_kwargs['make_syndic'] = True

        deploy_kwargs['make_minion'] = config.get_config_value('make_minion',
                                                               vm_,
                                                               __opts__,
                                                               default=True)

        # Store what was used to the deploy the VM
        event_kwargs = copy.deepcopy(deploy_kwargs)
        del (event_kwargs['minion_pem'])
        del (event_kwargs['minion_pub'])
        del (event_kwargs['sudo_password'])
        if 'password' in event_kwargs:
            del (event_kwargs['password'])
        ret['deploy_kwargs'] = event_kwargs

        saltcloud.utils.fire_event(
            'event',
            'executing deploy script',
            'salt/cloud/{0}/deploying'.format(vm_['name']),
            {'kwargs': event_kwargs},
        )

        deployed = False
        deployed = saltcloud.utils.deploy_script(**deploy_kwargs)

        if deployed:
            log.info('Salt installed on {0}'.format(vm_['name']))
        else:
            log.error('Failed to start Salt on Cloud VM {0}'.format(
                vm_['name']))

    log.info('Created Cloud VM {0[name]!r}'.format(vm_))
    log.debug('{0[name]!r} VM creation details:\n{1}'.format(
        vm_, pprint.pformat(data.__dict__)))

    ret.update(data.__dict__)

    saltcloud.utils.fire_event(
        'event',
        'created instance',
        'salt/cloud/{0}/created'.format(vm_['name']),
        {
            'name': vm_['name'],
            'profile': vm_['profile'],
            'provider': vm_['provider'],
        },
    )

    return ret
예제 #38
0
def run(argv):
    args = docopt(__doc__, argv=argv)

    # TODO We can capture all this loading and error handling
    # in 1 function
    try:
        with open('cloudseed/current/salt/cloud.profiles') as f:
            profiles = yaml.load(f.read())
    except IOError:
        print('No Cloud Profiles Found')
        return

    try:
        with open('cloudseed/current/salt/cloud.providers') as f:
            providers = yaml.load(f.read())
    except IOError:
        print('No Cloud Providers Found')
        return

    try:
        with open('cloudseed/current/salt/cloudseed') as f:
            conf = yaml.load(f.read())
    except IOError:
        print('Have you bootstrapped?')
        return

    profile = profiles.get('master', None)

    if not profile:
        # TODO Add Error Messaging
        return

    prefix = os.path.join(env.current_env_path(), 'salt')
    cloud_config = os.path.join(prefix, 'cloud')
    cloud_providers = os.path.join(prefix, 'cloud.providers')
    cloud_profiles = os.path.join(prefix, 'cloud.profiles')
    master_config = os.path.join(prefix, 'master')

    cloudseed_args = [
        '--cloud-config', cloud_config, '--providers-config', cloud_providers,
        '--profiles', cloud_profiles, '--master-config', master_config
    ]

    cli = saltcloud.cli.SaltCloud()
    cli.parse_args(args=cloudseed_args)

    cloud = cloudseed.cloud.Cloud(cli.config)
    vm_ = cloud.vm_profile('master')

    provider = config.get_config_value('provider', vm_, cloud.opts)

    if not provider:
        # TODO Add Error Messaging
        return

    username = config.get_config_value('ssh_username', vm_, cloud.opts)
    identity = config.get_config_value('private_key', vm_, cloud.opts)
    host = conf.get('ip_address', False)

    if username and identity and host:
        identity = os.path.abspath(identity)
        #sys.stdout.write('Connecting to environment \'%s\'\n' % current_env)
        ssh.connect(host=host, username=username, identity=identity)