Example #1
0
def tier_command(args):
    if args.name is None and args.action != 'info':
        print "Tier name is missing!"
        sys.exit(1)

    if args.action == 'info':
        conf = get_default_drift_config()
        if args.name is None:
            print "Tiers:"
            for tier in conf.get_table('tiers').find():
                print "\t{} state={}, is_live={}".format(
                    tier['tier_name'].ljust(21), tier['state'],
                    tier['is_live'])
        else:
            tier = conf.get_table('tiers').find({'tier_name': args.name})
            if not tier:
                print "No tier named {} found.".format(args.name)
                sys.exit(1)
            tier = tier[0]
            print "Tier {}:".format(tier['tier_name'])
            print json.dumps(tier, indent=4)

    elif args.action == 'add':
        with TSTransaction() as ts:
            tiers = ts.get_table('tiers')
            if tiers.find({'tier_name': args.name}):
                print "Tier {} already exists!".format(args.name)
                sys.exit(1)
            tiers.add({'tier_name': args.name})
    elif args.action == 'update':
        pass

    print "Done!"
Example #2
0
def info(organization_name):
    """Show organization info."""
    conf = get_default_drift_config()
    _header(conf)

    if organization_name is None:
        tabulate(
            ['organization_name', 'short_name', 'state', 'display_name'],
            conf.get_table('organizations').find(),
            indent='  ',
        )
    else:
        org = conf.get_table('organizations').find(
            {'organization_name': organization_name})
        if not org:
            org = conf.get_table('organizations').find(
                {'short_name': organization_name})
        if not org:
            click.secho(
                "No organization named {} found.".format(organization_name),
                fg='red',
                bold=True)
            sys.exit(1)
        org = org[0]
        click.echo("Organization {}:".format(org['organization_name']))
        click.echo(json.dumps(org, indent=4))
Example #3
0
def cache_command(args):
    if args.domain:
        os.environ['DRIFT_CONFIG_URL'] = args.domain
    ts = get_default_drift_config()
    print "Updating cache for '{}' - {}".format(
        ts.get_table('domain')['domain_name'], ts)

    for tier in ts.get_table('tiers').find():
        tier_name = tier['tier_name']
        if args.tier and args.tier.upper() != tier_name:
            continue
        click.secho("{}: ".format(tier_name), nl=False, bold=True)
        try:
            b = update_cache(ts, tier_name)
        except Exception as e:
            if "Timeout" not in str(e):
                raise
            click.secho("Updating failed. VPN down? {}".format(e),
                        fg='red',
                        bold=True)
        else:
            if b:
                click.secho("Cache updated on {}.".format(b))
            else:
                click.secho("No Redis resource defined for this tier.",
                            fg='red',
                            bold=True)
    '''
Example #4
0
def info(tenant_name):
    """Show tenant info."""
    conf = get_default_drift_config()
    _header(conf)

    if tenant_name is None:
        tabulate(
            [
                'organization_name', 'product_name', 'tenant_name',
                'reserved_at', 'reserved_by'
            ],
            conf.get_table('tenant-names').find(),
            indent='  ',
        )
    else:
        tenant = conf.get_table('tenants').find({'tenant_name': tenant_name})
        if not tenant:
            click.secho("No tenant named {} found.".format(tenant_name),
                        fg='red',
                        bold=True)
            sys.exit(1)

        click.secho("Tenant {s.BRIGHT}{}{s.NORMAL}:".format(
            tenant_name, **styles))
        click.echo(json.dumps(tenant, indent=4))
Example #5
0
def copy_command(args):
    print "Copy '%s' to '%s'" % (args.source_url, args.dest_url)
    if args.source_url == '.':
        ts = get_default_drift_config()
    else:
        ts = get_store_from_url(args.source_url)
    b = create_backend(args.dest_url)
    b.default_format = 'pickle' if args.pickle else 'json'
    b.save_table_store(ts)
    print "Done."
Example #6
0
def list_command(args):

    ts = get_default_drift_config()
    for product in ts.get_table('products').find():
        tenants = ts.get_table('tenant-names').find(
            {'product_name': product['product_name']})
        if tenants:
            print "\n[{}]".format(product['product_name'])
            for tenant in tenants:
                print "  ", tenant['tenant_name'],
                on_tiers = ts.get_table('tenants').find(
                    {'tenant_name': tenant['tenant_name']})
                if on_tiers:
                    tiers = set(t['tier_name'] for t in on_tiers)
                    print "-->", ", ".join(tiers)
                else:
                    print ""
Example #7
0
def add(product_name, edit):
    """Add a new product.\n
    PRODUCT_NAME is a 3-35 character long string containing only lower case letters digits and dashes.
    The product name must be prefixed with the organization short name and a dash.
    """
    if '-' not in product_name:
        click.secho(
            "Error: The product name must be prefixed with the organization "
            "short name and a dash.",
            fg='red',
            bold=True)
        sys.exit(1)

    short_name = product_name.split('-', 1)[0]
    conf = get_default_drift_config()
    org = conf.get_table('organizations').find({'short_name': short_name})
    if not org:
        click.secho(
            "No organization with short name {} found.".format(short_name),
            fg='red',
            bold=True)
        sys.exit(1)

    organization_name = org[0]['organization_name']

    with TSLocal() as ts:
        products = ts.get_table('products')
        entry = {
            'organization_name': organization_name,
            'product_name': product_name
        }

        if edit:
            edit = click.edit(json.dumps(entry, indent=4), editor='nano')
            if edit:
                entry = json.loads(edit)
        if products.find(entry):
            click.secho("Product {} already exists!".format(
                entry['product_name']),
                        fg='red',
                        bold=True)
            sys.exit(1)
        products.add(entry)

        _epilogue(ts)
Example #8
0
def info(tier_name):
    """Show tier info."""
    conf = get_default_drift_config()
    _header(conf)
    if tier_name is None:
        click.echo("Tiers:")
        tabulate(['tier_name', 'state', 'is_live'],
                 conf.get_table('tiers').find(),
                 indent='  ')
    else:
        tier = conf.get_table('tiers').find({'tier_name': tier_name})
        if not tier:
            click.secho("No tier named {} found.".format(tier_name),
                        fg='red',
                        bold=True)
            sys.exit(1)
        tier = tier[0]
        click.echo("Tier {}:".format(tier['tier_name']))
        click.echo(pretty(tier))
Example #9
0
def show_command(args):
    tier_name = get_tier_name()
    tenant_name = vars(args)['tenant-name']
    ts = get_default_drift_config()
    tenant_info = ts.get_table('tenant-names').get(
        {'tenant_name': tenant_name})
    if not tenant_info:
        print "Tenant '{}' not found.".format(tenant_name)
        sys.exit(1)

    tenant_info2 = ts.get_table('tenants').find({
        'tier_name': tier_name,
        'tenant_name': tenant_name
    })

    if not tenant_info2:
        print "The tenant '{}' is not defined for any deployable on tier '{}'.".format(
            tenant_name, tier_name)
        sys.exit(1)
Example #10
0
def make_celery(app):

    kombu.serialization.register('drift_celery_json',
                                 drift_celery_dumps,
                                 drift_celery_loads,
                                 content_type='application/x-myjson',
                                 content_encoding='utf-8')

    celery = Celery(app.import_name)

    ts = get_default_drift_config()
    tier_name = get_tier_name()
    tier_config = ts.get_table('tiers').get({'tier_name': tier_name})

    if os.environ.get('DRIFT_USE_LOCAL_SERVERS', False):
        broker_url = "redis://localhost:6379/15"
    else:
        broker_url = tier_config["celery_broker_url"]

    log.info("Celery broker from tier config: %s", broker_url)

    celery.conf.update(app.config)
    celery.conf["BROKER_URL"] = broker_url
    celery.conf["CELERY_RESULT_BACKEND"] = broker_url
    celery.conf["CELERY_TASK_SERIALIZER"] = "drift_celery_json"
    celery.conf["CELERY_RESULT_SERIALIZER"] = "drift_celery_json"
    celery.conf["CELERY_ACCEPT_CONTENT"] = ["drift_celery_json"]
    celery.conf["CELERY_ENABLE_UTC"] = True
    TaskBase = celery.Task

    class ContextTask(TaskBase):
        abstract = True

        def __call__(self, *args, **kwargs):
            with app.app_context():
                g.conf = get_config()
                return TaskBase.__call__(self, *args, **kwargs)

    celery.Task = ContextTask
    return celery
Example #11
0
def info(product_name):
    """Show product info."""
    conf = get_default_drift_config()
    _header(conf)

    if product_name is None:
        tabulate(
            ['organization_name', 'product_name', 'state', 'deployables'],
            conf.get_table('products').find(),
            indent='  ',
        )
    else:
        product = conf.get_table('products').find(
            {'product_name': product_name})
        if not product:
            click.secho("No product named {} found.".format(product_name),
                        fg='red',
                        bold=True)
            sys.exit(1)
        product = product[0]
        click.secho("Product {s.BRIGHT}{}{s.NORMAL}:".format(
            product['product_name'], **styles))
        click.echo(json.dumps(product, indent=4))
Example #12
0
def info():
    """Show deployable registration info."""
    click.secho("Registered Drift deployable plugins:")

    # setuptools distribution object:
    # http://setuptools.readthedocs.io/en/latest/pkg_resources.html#distribution-objects
    # 'activate', 'as_requirement', 'check_version_conflict', 'clone', 'egg_name', 'extras',
    # 'from_filename', 'from_location', 'get_entry_info', 'get_entry_map', 'has_version',
    # 'hashcmp', 'insert_on', 'key', 'load_entry_point', 'location', 'parsed_version',
    # 'platform', 'precedence', 'project_name', 'py_version', 'requires', 'version'

    # setuptools entry point object:
    # http://setuptools.readthedocs.io/en/latest/pkg_resources.html#entrypoint-objects
    # 'attrs', 'dist', 'extras', 'load', 'module_name', 'name', 'parse', 'parse_group',
    # 'parse_map', 'pattern', 'require', 'resolve'

    ts = get_default_drift_config()
    click.echo("List of Drift deployable plugins in ", nl=False)
    _header(ts)
    deployables = ts.get_table('deployable-names')

    click.secho("Deployables and api routes registered in config:\n",
                bold=True)

    def join_tables(master_table, *tables, **search_criteria):
        """
        Joins rows from 'tables' to the rows of 'master_table' and returns them
        as a single sequence.
        'search_criteria' is applied to the 'master_table'.
        """
        rows = master_table.find(search_criteria)
        for row in rows:
            row = row.copy()
            for table in tables:
                other = table.get(row)
                if other:
                    row.update(other)
            yield row

    tabulate(
        ['deployable_name', 'api', 'requires_api_key', 'display_name', 'tags'],
        list(
            join_tables(deployables, ts.get_table('routing'),
                        ts.get_table('deployable-names'))),
        indent='  ',
    )
    registered = [d['deployable_name'] for d in deployables.find()]

    click.secho("\nDeployables registered as plugins on this machine:\n",
                bold=True)
    for d in _enumerate_plugins('drift.plugin', 'register_deployable'):
        dist, meta, classifiers, tags = d['dist'], d['meta'], d[
            'classifiers'], d['tags']
        click.secho(dist.key, bold=True, nl=False)
        entry = deployables.get({'deployable_name': dist.key})
        if entry:
            click.secho("")
        else:
            click.secho(" (Plugin NOT registered in config DB!)", fg='red')

        if dist.key in registered:
            registered.remove(dist.key)

        assigned = ts.get_table('deployables').find(
            {'deployable_name': dist.key})
        if assigned:
            click.secho("\tTier assignment:")
            for assignment in assigned:
                if 'version' in assignment:
                    click.secho(
                        "\t\t{tier_name} [{version}]".format(**assignment),
                        nl=False)
                else:
                    click.secho("\t\t{tier_name}".format(**assignment),
                                nl=False)
                if assignment['is_active']:
                    click.secho("")
                else:
                    click.secho(" [inactive]", fg='white')

        click.secho("\tTags: {}".format(', '.join(tags)))
        click.secho("\tVersion: {}".format(dist.parsed_version))

        if meta:
            for key in ['Author', 'Summary']:
                if key in meta:
                    click.secho("\t{}:{}".format(key, meta[key]))
            for classifier in classifiers:
                if 'Programming Language' in classifier and classifier.count(
                        '::') == 1:
                    click.secho("\t{}".format(classifier))
        else:
            click.secho("\t(meta info missing)")
        click.secho("")

    if registered:
        click.secho(
            "Note! The following deployables are registered in the config, but are not "
            "registered as plugins on this machine:\n{}".format(
                ', '.join(registered)))

    click.secho("\nDeployables assigned to tiers:\n", bold=True)
    ta = {}
    for d in ts.get_table('deployables').find():
        ta.setdefault(d['tier_name'], []).append(d)
    for tier_name, dep in ta.items():
        click.secho("{}:".format(tier_name), bold=True)
        for d in dep:
            click.secho(d['deployable_name'],
                        fg='black' if d['is_active'] else 'red',
                        nl=False)
            click.secho(" ", nl=False)
        click.secho("\n")
Example #13
0
 def _get_table_store(self):
     ts = get_default_drift_config()
     return ts
Example #14
0
def get_ts():
    return get_default_drift_config()
Example #15
0
def _register_command(args):

    info = get_package_info()
    conf = get_drift_config()
    name = info['name']
    is_active = not args.inactive

    print "Registering/updating deployable: ", name
    _display_package_info()

    if not is_active:
        print "Marking the deployable as inactive!"

    with TSTransaction(commit_to_origin=not args.preview) as ts:
        # Insert or update name
        row = {'deployable_name': name, 'display_name': info['description']}
        if 'long-description' in info and info['long-description'] != "UNKNOWN":
            row['description'] = info['long-cdescription']
        ts.get_table('deployable-names').update(row)

        # Make deployable (in)active on all tiers
        deployables = ts.get_table('deployables')
        for tier in ts.get_table('tiers').find():
            row = {
                'tier_name': tier['tier_name'],
                'deployable_name': name,
                'is_active': is_active
            }
            deployables.update(row)

            # Now let's do some api-router specific stuff which is by no means my concern!
            if name == 'drift-base':
                api = 'drift'
            elif name == 'themachines-backend':
                api = 'themachines'
            elif name == 'themachines-admin':
                api = 'admin'
            elif name == 'kaleo-web':
                api = 'kaleo'
            elif name == 'kards-backend':
                api = 'kards'
            else:
                api = name

            row = {
                'tier_name': tier['tier_name'],
                'deployable_name': name,
                'api': api
            }
            ts.get_table('routing').update(row)

            # Now let's do some drift-base specific stuff which is by no means my concern!
            # Generate RSA key pairs
            from cryptography.hazmat.primitives.asymmetric import rsa
            from cryptography.hazmat.primitives import serialization
            from cryptography.hazmat.backends import default_backend

            private_key = rsa.generate_private_key(public_exponent=65537,
                                                   key_size=1024,
                                                   backend=default_backend())

            public_key = private_key.public_key()

            private_pem = private_key.private_bytes(
                encoding=serialization.Encoding.PEM,
                format=serialization.PrivateFormat.TraditionalOpenSSL,
                encryption_algorithm=serialization.NoEncryption())

            public_pem = public_key.public_bytes(
                encoding=serialization.Encoding.PEM,
                format=serialization.PublicFormat.SubjectPublicKeyInfo)

            now = datetime.datetime.utcnow()
            row = {
                'tier_name':
                tier['tier_name'],
                'deployable_name':
                name,
                'keys': [{
                    'issued':
                    now.isoformat() + "Z",
                    'expires':
                    (now + datetime.timedelta(days=365)).isoformat() + "Z",
                    'public_key':
                    public_pem,
                    'private_key':
                    private_pem,
                }]
            }
            ts.get_table('public-keys').update(row)

    if args.preview:
        print "Preview changes only, not committing to origin."

    # Display the diff
    _diff_ts(ts, get_default_drift_config())