예제 #1
0
def heroku_deploy():
    if not heroku_remote_exists():
        # check if heroku toolbelt is available
        heroku_bin = local('which heroku', capture=True)
        if not heroku_bin:
            install_heroku_toolbelt()

        # log in to heroku
        selected_account = heroku_select_account()
        local('heroku login --account %s' % selected_account)

        # select or create an app
        app_name = heroku_select_or_create_app(selected_account)

        # add redis ?
        add_redis = prompt(_white("Type 'y' to add Redis To Go to your Heroku application "
                                  "(to use an external service, update your settings file): ")) or None
        if add_redis.lower() == 'y':
            heroku_add_redis(app=app_name, account=selected_account)

        check_git()
        # add git remote
        local('git remote add heroku heroku.com:%s.git' % app_name)

        print(_green("You are ready to commit any changes and deploy to heroku by typing: %s" %
                     _white("git push heroku <name_of_branch>")))
        return None
    print(_green("Looks like there is already a heroku remote set up. Huzzah!"))
예제 #2
0
파일: cheflab.py 프로젝트: kodelint/cheflab
def destory_config(conf):
    import os
    for vm in conf:
        sendWarning("Removing stale Keys for: " + _white(vm["name"]))
        dest = "provisioner/conf/keys/" + vm["name"] + ".pem"
        os.remove(dest)

    cfg = "provisioner/conf/cache/cheflab-hosts.cfg"
    sendWarning("Removing stale hosts file : " + _white(cfg))
    os.remove(cfg)
예제 #3
0
def deploy():
    if not exists('/home/%s' % env.user):
        sudo('mkdir /home/%s' % env.user)
        sudo('chown %s:%s /home/%s' % (env.user, env.user, env.user))
    puppet_properties = {}
    properties = get_puppet_properties()
    puppet_properties.update((k, v) for k, v in properties.iteritems() if v)
    puppet_properties['couchdb_hostname'] = env.host
    '''
    if the desired couchdb database path DNE, create it
    '''
    if 'database_dir' in puppet_properties:
        if not exists(puppet_properties['database_dir']):
            sudo('mkdir -p %s' % puppet_properties['database_dir'])
    '''
    ensure puppet is installed before running module
    '''
    install_puppet()
    '''
    ensure puppet repo is up-to-date on host then apply couch module
    '''
    update_puppet_repo()
    apply_couch_module(puppet_properties)
    # update_hosts()
    '''
    adding a small sleep to ensure couchdb is running before setting up dbs and replicating
    '''
    run('sleep 10')
    couchdb_flush()
    couchdb_replicate(properties['couchdb_masterless_mode'],
                      properties['slave_mode'])
    '''
    new relic setup - ask operator if s/he wants to set up new relic monitoring
    '''
    newrelic = bool(
        prompt(_white(
            'Set up New Relic monitoring %s ' % _green('[y/N]:')))) or False
    if newrelic:
        newrelic_key = None
        while not newrelic_key:
            newrelic_key = prompt(
                _white(
                    'Enter your New Relic license key -- required: ')) or None

    if newrelic and newrelic_key:
        newrelic_setup(newrelic, newrelic_key)
    '''
    if this is the first time it has run, amend rc.local with appropriate commands
    '''
    if not exists('/etc/puppet/.couchdb.deployed'):
        amend_rc_local(properties['couchdb_masterless_mode'])
    '''
    add a blank hidden file to let us know this deploy has already run
    '''
    sudo('touch /etc/puppet/.couchdb.deployed')
예제 #4
0
def heroku_select_or_create_app(account_name):
    account_applications = local('heroku apps --account %s' % account_name, capture=True)
    app = prompt(_white("Type the name of the application you wish to use, or press "
                        "Enter to create a new one:\n\t%s%s\nSelection: " %
                        (_yellow('* '), _yellow('\n\t* '.join(account_applications.split('\n')))))) or None
    if app:
        if app in account_applications:
            return app

    app = prompt(_white("Type the name of the app you would like to create: "))
    local('heroku apps:create %s --account %s' % (app, account_name))
    return app
예제 #5
0
def heroku_select_account():
    # select heroku account
    accounts = local('heroku accounts', capture=True) or None
    if accounts:
        return prompt(_white("Type the name of the Heroku account you would like to use:\n\t%s%s\n" %
                             (_yellow('* '), _yellow('\n\t* '.join(accounts.split('\n'))))))

    else:
        add_account = prompt(_white("No heroku toolbelt account was found. Would you like to add one? [n] ")) or None
        if add_account:
            account_name = prompt(_white("Type the name of the account you would like to add"))
            local('heroku accounts:add %s' % account_name)
            return account_name
예제 #6
0
파일: cheflab.py 프로젝트: kodelint/cheflab
def get_keys(conf):
    from shutil import copy
    for vm in conf:
        sendInfo("Getting Keys for: " + _white(vm["name"]))
        src = "boxes/machines/" + vm["name"] + "/virtualbox/private_key"
        dest = "provisioner/conf/keys/" + vm["name"] + ".pem"
        copy(src, dest)
예제 #7
0
def heroku_add_redis(app=None, account=None):
    redis_host = None
    redis_port = 6379
    redis_password = None
    redis_db = 0

    if not account:
        account = heroku_select_account()
    if not app:
        app = heroku_select_or_create_app(account)

    redis_exists = local('heroku addons --app %s --account %s' % (app, account), capture=True)
    if not 'redistogo' in redis_exists:
        local('heroku addons:add --app %s --account %s redistogo:nano' % (app, account))

    open_redis_details = prompt(_white("Would you like to open the addon's details in your browser now? [n] ")) or False
    if open_redis_details:
        prompted = prompt(_yellow("Once the redis details open, you will be prompted to enter some details. "
                                  "You can type 'q' at any time to cancel updating your application's Redis details."
                                  "Press Enter to open the Redis details page."))
        if prompted != 'q':
            local('heroku addons:open --app %s --account %s redistogo:nano' % (app, account))
            prompted = prompt(_white("From the 'General' section, paste the name of the redis instance (like 'angelfish-9357')")) or None
        if prompted and prompted != 'q':
            host, redis_port = prompted.strip().split('-')
            redis_host = '%s.redistogo.com' % host
            prompted = prompt(_white("From the security section, paste the Redis password: "******"Which environment is this for?\n\t1. Staging\n\t2. Production\nSelection: "))
    profile = 'staging'
    if '2' in is_staging:
        profile = 'prod'
    settings_file = [i for i in os.listdir('./') if re.search('settings', i) and not re.search(r'.*\.pyc$', i)][0]
    settings_path = os.path.join('./', settings_file)

    f = open(settings_path, 'r')
    settings_lines = [
        i.replace('<%s.redis_host>' % profile, redis_host)
            .replace('<%s.redis_port>' % profile, str(redis_port))
            .replace('<%s.redis_password>' % profile, redis_password) for i in f.readlines()]

    f = open('%s' % settings_path, 'w')
    for line in settings_lines:
        f.write(line)
    f.close()
예제 #8
0
def get_puppet_properties():
    properties = {}

    print(_white('Enter setup information. Defaults in %s. ' %
                 _green('green')))
    prompt(
        _white(
            'To keep default, simply press enter when prompted. \nAll optional unless noted. Press enter to continue.'
        ))
    properties['bind'] = prompt(
        _white('CouchDB bind address %s ' % _green('[0.0.0.0]:'))) or '0.0.0.0'

    properties['database_dir'] = prompt(
        _white('CouchDB database dir %s ' %
               _green('[/usr/local/var/lib/couchdb]:'))) or None
    '''
    admin user info 
    '''
    properties['admin_user'] = prompt(
        _white('CouchDB admin user %s ' % _green('[None]:'))) or None
    if properties['admin_user']:
        properties['admin_password'] = None
        while not properties['admin_password']:
            properties['admin_password'] = prompt(
                _white(
                    'CouchDb admin password %s ' % _green('[None] :'))) or None
    '''
    masterless/slave setup
    '''
    properties['couchdb_masterless_mode'] = bool(
        prompt(
            _yellow('Run as part of a masterless cluster %s ' %
                    _green('[y/N]:')))) or False
    if not properties['couchdb_masterless_mode']:
        properties['slave_mode'] = bool(
            prompt(
                _yellow('Run as a slave to another master %s ' %
                        _green('[y/N]:')))) or False
    else:
        properties['slave_mode'] = False
    if properties['couchdb_masterless_mode'] or properties['slave_mode']:
        properties['couchdb_master_hostname'] = None
        properties['couchdb_master_ip'] = None
        while not properties['couchdb_master_hostname']:
            properties['couchdb_master_hostname'] = prompt(
                _white(
                    'Hostname of CouchDB master server -- required: ')) or None
        while not properties['couchdb_master_ip']:
            properties['couchdb_master_ip'] = prompt(
                _white('IP Address of CouchDB master server -- required: ')
            ) or None

    return properties
예제 #9
0
파일: cheflab.py 프로젝트: kodelint/cheflab
def generate_hostsfile(conf):
    import os.path
    cheflabfile = "provisioner/conf/cache/cheflab-hosts.cfg"
    sendInfo("Generating hosts file")
    s = []
    if os.path.isfile(cheflabfile):
        with open(cheflabfile) as f:
            for line in f:
                s.append(line.strip().split("\t"))

        for vm, index in zip(conf, s):
            fqdn = vm["name"] + ".cheflab.dev"
            if fqdn == index[1]:
                pass
            else:
                sendInfo("Adding host entry for: " + _white(fqdn))
                write_file(cheflabfile, vm["ip"], fqdn, vm["name"])
    else:
        for vm in conf:
            fqdn = vm["name"] + ".cheflab.dev"
            sendInfo("Adding host entry for: " + _white(fqdn))
            write_file(cheflabfile, vm["ip"], fqdn, vm["name"])
예제 #10
0
def import_container(container_name=None):
    """
    import a container by name. If no container name is specified, import all containers
    :param container_name: (optional) the container to import
    """
    import_containers = [x for x in CONTAINERS if x['name'] != 'base']

    if container_name:
        import_containers = [x for x in import_containers if x['name'] == container_name]

    for c in import_containers:
        container = Container(env.environment, c)
        print(_white("==> Importing %s container from S3" % container.name))
        local('sudo curl %s | sudo docker import - %s/%s' % (container.s3_path,
                                                             env.environment.lower(),
                                                             container.name))
예제 #11
0
def create_virtualenv_local(virtual_env_path=env.local_virtual_env_path):
    """ * create a local virtualenv environment.
    Usage:
        create_virtual_local:path_to_env
        create_virtual_local
    Options:
        path_toenv: Optional. Will default to one directory up from fabfile named 'env'.
                    Effectively the path ['../'].
    """

    if not os.path.isdir(virtual_env_path):
        with settings(warn_only=True):
            result = local("virtualenv --no-site-packages --distribute %s" % virtual_env_path)
        if result.failed and not confirm(_white("Installing virtualenv failed. Continue anyway?"), default=False):
            abort(_red("Aborting local staging."))
    
    print(_green("Virtualenv installed and detected."))
예제 #12
0
def config():
    ENVIRONMENT = os.environ.get("COUCHENV", "development")
    if ENVIRONMENT in ['prod', 'production']:
        config_file_path = './config/production.json'
    elif ENVIRONMENT in ['test', 'staging']:
        config_file_path = './config/staging.json'
    elif ENVIRONMENT in ['dev', 'development']:
        config_file_path = './config/dev.json'
    elif ENVIORNMENT in ['local']:
        config_file_path = './config/local.json'
    else:
        abort(
            _red(
                'No COUCHENV or config file defined. Either define COUCHENV=[prod|test|dev] or call fab config:/path/to/config/file spinup:[ID]'
            ))

    opts = {}
    with open(config_file_path) as data_file:
        '''
        load in template data from data file
        '''
        opts = json.load(data_file)

    opts['environment'] = ENVIRONMENT.upper()
    '''
    ensure required properties are present in config file
    '''
    if all(k in opts for k in ('user', 'ssh_keyfile', 'project_name',
                               'aws_access_key_id', 'aws_secret_access_key',
                               'aws_ami', 'aws_keypair_name', 'aws_ec2_region',
                               'aws_instance_type', 'aws_security_group')):
        return opts
    else:
        print(
            _red(
                'One or more required fields are missing. Ensure that the following properties are included in your config file:\n'
            ))
        print(
            _white(
                '%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s' %
                ('user', 'ssh_keyfile', 'project_name', 'aws_access_key_id',
                 'aws_secret_access_key', 'aws_ami', 'aws_keypair_name',
                 'aws_ec2_region', 'aws_instance_type', 'aws_security_group')))
        abort('Aborting.')
예제 #13
0
def create_virtualenv_local(virtual_env_path=env.local_virtual_env_path):
    """ * create a local virtualenv environment.
    Usage:
        create_virtual_local:path_to_env
        create_virtual_local
    Options:
        path_toenv: Optional. Will default to one directory up from fabfile named 'env'.
                    Effectively the path ['../'].
    """

    if not os.path.isdir(virtual_env_path):
        with settings(warn_only=True):
            result = local("virtualenv --no-site-packages --distribute %s" %
                           virtual_env_path)
        if result.failed and not confirm(
                _white("Installing virtualenv failed. Continue anyway?"),
                default=False):
            abort(_red("Aborting local staging."))

    print(_green("Virtualenv installed and detected."))
예제 #14
0
def install_heroku_toolbelt():
    is_installed = False
    install = prompt(_white("Heroku Toolbelt is not installed. Would you like to install it? [n] ")) or None
    if install:
        if re.search('darwin', sys.platform):
            # install with brew if available
            brew = local('which brew', capture=True)
            if brew:
                local('brew install heroku-toolbelt')
                is_installed = True
            else:
                abort(_red("Attempted to install heroku-toolbelt with brew, but brew was not found. "
                           "Please install homebrew and try again, or install the heroku-toolbelt manually "
                           "from https://toolbelt.heroku.com"))

        elif re.search('linux', sys.platform):
            # install with wget if ubuntu
            is_ubuntu = local('uname -v', capture=True)
            if re.search('ubuntu', is_ubuntu.lower()):
                sudo('wget -qO- https://toolbelt.heroku.com/install-ubuntu.sh | sh')
                is_installed = True

    if is_installed:
        print(_green("Heroku Toolbelt successfully installed"))
예제 #15
0
def spinup(suffix):
    '''
    if no suffix was defined for the new instance, generate one at random
    '''
    if not suffix:
        suffix = b2a_hex(os.urandom(4))
    '''
    get environment options and create an ec2 connection
    '''
    opts = config()
    env.user = opts['user']
    host_name = '%s-CouchDB-%s' % (opts['environment'], suffix)
    ec2 = EC2(opts['aws_ec2_region'], opts['aws_access_key_id'],
              opts['aws_secret_access_key'])

    print(_green("Started..."))
    print(_yellow("...Creating EC2 instance..."))
    '''
    check if user has defined specific placement zone
    '''
    desired_availability_zone = None
    if 'aws_ec2_availability_zone' in opts:
        desired_availability_zone = opts['aws_ec2_availability_zone']
    '''
    clone the defined ami to a new instance
    '''
    reservation = ec2.conn.run_instances(
        opts['aws_ami'],
        placement=desired_availability_zone,
        key_name=opts['aws_keypair_name'],
        instance_type=opts['aws_instance_type'],
        security_groups=opts['aws_security_group'])
    instance = reservation.instances[0]
    '''
    update progress
    '''
    while instance.state != 'running':
        print(_yellow("Instance state: %s" % instance.state))
        sleep(1)
        instance.update()
    '''
    tag the new instance
    '''
    ec2.conn.create_tags([instance.id], {'Name': '%s' % host_name})
    if opts['project_name']:
        ec2.conn.create_tags([instance.id], {'Project': opts['project_name']})
    '''
    update progress
    '''
    print(_yellow("Launched: %s, %s" % (instance.dns_name, host_name)))
    print(_green("Instance state: %s" % instance.state))
    print(_green("Public dns: %s" % instance.public_dns_name))
    '''
    if you want to add the new instance to a load balancer, you can do that.
    '''
    add_to_lb = prompt(
        _white(
            "Add new EC2 instance to an ELB %s" % _green('[y/N]: '))) or None
    if add_to_lb:
        add_to_lb = prompt(
            _white(
                "Adding this to the ELB will automatically enable the availability zone for your EC2 instance if not already enabled for this ELB. Proceed %s "
                % _green('[y/N]: ')))
        if add_to_lb:
            load_balancer_name = None

            if 'aws_elb_load_balancer' not in opts:
                while not load_balancer_name:
                    load_balancer_name = prompt(
                        _white('Load Balancer Name --required: ')) or None
            else:
                load_balancer_name = opts['aws_elb_load_balancer']
            '''
            if no desired_availability_zone was defined in the config, set it now to the instance's placement group
            '''
            if not desired_availability_zone:
                desired_availability_zone = instance.placement

            add_to_load_balancer(ec2, load_balancer_name, instance.id,
                                 desired_availability_zone)
    '''
    update local ssh config so new instance is ssh-ready
    '''
    local('echo "\nHost %s" >> ~/.ssh/config' % host_name)
    local('echo "HostName %s" >> ~/.ssh/config' % instance.dns_name)
    local('echo "User %s" >> ~/.ssh/config' % env.user)
    '''
    run couchdb deploy
    '''
    print(_yellow("Deploying CouchDB Puppet Module..."))
    env.host_string = instance.dns_name
    deploy()