Ejemplo n.º 1
0
def write(ctx, namespace, encrypt, parameter, value):
    try:
        namespace = namespace or "service:" + re.sub('\W', '-', ctx.name)

        full_name = ctx.provider.ssm.write(namespace, parameter, value,
                                           encrypt)
    except Exception as e:
        logger.error(e.message)
        sys.exit(1)

    click.secho("Stored '{}' under key: '{}'".format(value, full_name),
                fg='green')
Ejemplo n.º 2
0
def invoke(ctx, function_name, source, mode, force, event, cleanup=False):
    try:
        sls = Serverless.from_context(ctx)
        sls.ensure_function(function_name)
        lambda_function = sls.get_function(function_name)

        with Virtualenv(lambda_function.global_id,
                        lambda_function.get_runtime(), cleanup) as venv:
            if venv.created or force:
                venv.pip.install_dependencies(
                    lambda_function.get_dependencies(True))
                venv.pip.install_dependencies(['memory-profiler==0.47'])

            context = ExecutionContext(venv, ctx.environment, lambda_function)

            click.secho(
                click.style('Execution details for ', fg='green') +
                click.style(lambda_function.name, fg='red'))

            click.secho(table('EXECUTION CONTEXT', context.details).table)
            click.secho(
                table('ENVIRONMENT VARIABLES',
                      context.environment_variables).table)

            emulator = Emulator(mode, source.read(), lambda_function)

            if event or True:
                display_section('EVENT', highlight_json(emulator.emulate()))

            click.echo('=' * click.get_terminal_size()[0] + '\n')

            result = context.execute(emulator.emulate())

            display_section('FUNCTION EXECUTION OUTPUT',
                            highlight_json(result.stdout))

            click.secho(
                table('COLLECTED EVENTS',
                      result.events, ['module', 'function', 'args'],
                      wraped_col=2).table)

            click.secho(table('METRICS', result.stats).table)

            if result.stderr:
                display_section('FUNCTION ERROR OUTPUT', result.stderr, 'red',
                                'red')
    except InvalidContextException:
        logger.error('Invalid context - check your serverless.yml file')
        sys.exit(1)
    except FunctionNotFoundException as e:
        logger.error(e.message)
        sys.exit(2)
Ejemplo n.º 3
0
def cli_prototype(ctx, working_dir, profile, project_name):
    working_dir = working_dir or ctx.working_dir
    try:
        current_ctx = click.get_current_context()

        if isinstance(current_ctx.command, GroupWithCommandOptions
                      ) and current_ctx.command.require_project(current_ctx):
            ensure_project_directory(working_dir)
        ctx.working_dir = working_dir
        ctx.name = project_name
    except NotProjectDirectoryException as e:
        logger.error(e.message)
        sys.exit(1)

    ctx.load(profile)
Ejemplo n.º 4
0
def events(ctx, function_name):
    try:
        sls = Serverless.from_context(ctx)
        sls.ensure_function(function_name)

        lambda_function = sls.get_function(function_name)
        for f in glob(join(lambda_function.function_dir, '.events', '*.json')):
            click.echo('- ' + basename(f).replace('.json', ''))

    except InvalidContextException:
        logger.error('Invalid context - check your serverless.yml file')
        sys.exit(1)
    except FunctionNotFoundException as e:
        logger.error(e.message)
        sys.exit(2)
Ejemplo n.º 5
0
def apply(ctx):
    """
    @type ctx: stylist.cli.Context
    """
    plan_path = None
    try:
        terraform = Terraform(ctx)
        plan_path = terraform.plan(True)

        _apply = click.prompt(style('Apply saved plan to "{}"? '.format(
            colourize(ctx.environment)),
                                    fg="green"),
                              type=Boolean(),
                              default=True)

        if _apply:
            terraform.apply(plan_path)
        else:
            click.secho("Aborted.", fg="yellow")
    except TerraformException as e:
        logger.error(e.message)
    finally:
        if plan_path:
            os.remove(plan_path)
Ejemplo n.º 6
0
def init(ctx, git_repository, path):
    """
    @@ignore_check@@
    """
    try:
        if git_repository == '.':
            path = os.getcwd()
        elif not path:
            path = os.path.join(
                os.getcwd(),
                git_repository.split('/')[-1].replace('.git', ''))

        ctx.working_dir = path

        if git_repository != '.':
            git.Git().clone(git_repository, path)

            click.secho('Git repository cloned to: "{}"'.format(path),
                        fg='green')

        if not os.path.exists(os.path.join(ctx.working_dir, '.stylist')):
            prefix = click.prompt(click.style('Prefix name for environments',
                                              fg='blue'),
                                  default='')

            try:
                os.makedirs(ctx.config_dir)
            except:
                pass

            with open(ctx.config_file, 'w+') as f:
                yaml.dump(
                    {
                        'stylist': {
                            'provider': {
                                'type': 'aws',
                                'prefix': str(prefix)
                            },
                            'stages': ['prod', 'uat', 'staging']
                        }
                    }, f)

            def deal_with_gitignore():
                gitignore_path = os.path.join(path, '.gitignore')
                mode = 'a' if os.path.isfile(gitignore_path) else 'w'

                with open(gitignore_path, mode) as f:
                    f.write(GIT_IGNORE)

                for to_add in ('.gitignore', '.stylist'):
                    call(['git', 'add', to_add])

            deal_with_gitignore()

            from stylist.commands.cmd_profile import select
            click.get_current_context().invoke(select, name='local')
    except Exception as e:
        logger.error(
            'Failed to create project - you may need clean it up manually. \n{}'
            .format(e))
        sys.exit(1)
Ejemplo n.º 7
0
    def configure_module(self, module_name, alias):
        maped_values = {
            'name': alias
        }

        values = {}
        current_vars = {}
        template = self.templates.get_template('internal/terraform/module.jinja2')

        module_dir = join(self.templates.destination, 'terraform_modules', module_name)

        if not isdir(module_dir):
            logger.error("Unable to locate '{}' module definition".format(module_name))
            sys.exit(1)

        full_module_name = module_name + '_' + alias

        module_file = join(self.terraform_dir, 'module.' + full_module_name + '.tf')
        if exists(module_file):
            regexp = ur'^\s*(?P<name>\w+)\s*=\s*"?(?P<value>.*?)"?$'

            try:
                with open(module_file, 'r') as f:
                    current_vars = {v.group('name'): v.group('value') for k, v in
                                    enumerate(re.finditer(regexp, f.read(), re.MULTILINE))}

                click.secho("Using existing definition from: '{}'\n".format(
                    module_file.replace(self.terraform_dir + '/', '')
                ), fg='blue')

            except Exception:
                pass

        module_variables = []

        for tf_file in glob(join(module_dir, '*.tf')):
            try:
                with open(tf_file, 'r') as f:
                    variables = hcl.load(f).get("variable")
                    module_variables += variables.keys()

                if not variables:
                    continue

                for name, config in variables.items():
                    if name in Terraform.STYLIST_VAR_NAMES:
                        continue

                    if name in maped_values:
                        values[name] = maped_values.get(name)
                    else:
                        prefix = "{feature}({module}) Enter value for: {variable}".format(
                            feature=style("Terraform", fg="blue"),
                            module=style(module_name, fg="green"),
                            variable=name
                        )

                        _val = prompt(prefix, default=current_vars.get(name, config.get("default")))

                        if _val and _val != config.get("default"):
                            values[name] = _val
            except Exception:
                pass

        rendered = template.render(
            module_name=module_name,
            full_module_name=full_module_name,
            vars=values,
            internal=filter(lambda x: unicode(x) in module_variables, Terraform.STYLIST_VAR_NAMES),
            source=self.templates.get_module_source(module_name),
            alias=alias
        )

        with open(module_file, 'w+') as f:
            f.write(rendered)

        click.secho("All done, module file updated: '{}'".format(
            module_file.replace(self.terraform_dir + '/', '')
        ), fg='green')
Ejemplo n.º 8
0
    def initschema(self, instance, db, schema):
        ssm = self.ctx.provider.ssm

        resource = 'master:{instance}'.format(instance=instance, db=db)
        params = ssm.get_short_parameters(resource)

        if not params:
            logger.error(
                "Unable to locate resource connection settings for: '{}'".
                format(resource))
            sys.exit(1)

        dsn = self._build_dsn(**params)
        conn = psycopg2.connect(dsn)
        conn.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)

        sqls = []
        passwd = random_password()

        with conn.cursor() as cur:
            role_name = 'service_' + schema

            sql = "SELECT 1 FROM pg_user WHERE usename = '{role_name}'".format(
                role_name=role_name)
            cur.execute(sql)

            if not cur.fetchone():
                sqls.append(
                    """CREATE ROLE {role_name} LOGIN PASSWORD '{role_password}'"""
                    .format(role_name=role_name, role_password=passwd))

                sqls.append("GRANT {role_name} TO {db}".format(
                    role_name=role_name, db=db))
                sqls.append("GRANT {role_name} TO {master_user}".format(
                    role_name=role_name, master_user=params['user']))

                sqls.append(
                    "ALTER USER {role_name} SET search_path to {schema};".
                    format(role_name=role_name, schema=schema))

        conn.close()

        resource = 'resource:{instance}/{db}'.format(instance=instance, db=db)
        params = ssm.get_short_parameters(resource)

        if not params:
            logger.error(
                "Unable to locate resource connection settings for: '{}'".
                format(resource))
            sys.exit(1)

        dsn = self._build_dsn(**params)
        conn = psycopg2.connect(dsn)
        conn.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)

        with conn.cursor() as cur:
            sql = "SELECT schema_name FROM information_schema.schemata WHERE schema_name = '{}';".format(
                schema)
            cur.execute(sql)
            if cur.fetchone():
                logger.error(
                    "There is already schema named: '{}' in db '{}'".format(
                        schema, db))
                sys.exit(1)

            sqls.append(
                'CREATE SCHEMA {schema} AUTHORIZATION {role_name}'.format(
                    schema=schema, role_name=role_name))

            from pygments import highlight
            from pygments.lexers import get_lexer_by_name
            from pygments.formatters import get_formatter_by_name

            queries = highlight("\n".join(sqls).replace(passwd, '*' * 8),
                                get_lexer_by_name('sql'),
                                get_formatter_by_name('console'))

            if not click.prompt("Execute: \n" + queries, type=Boolean()):
                click.secho("Aborted!", fg="yellow")

            for query in sqls:
                click.secho(query.replace(passwd, '*' * 8) + '.' * 5, nl=False)
                cur.execute(query)
                click.secho('OK', fg="green")

        namespace = 'service:'.format(instance=instance, db=db)
        ssm.write(namespace, 'db', db, True)
        ssm.write(namespace, 'host', params['host'], True)
        ssm.write(namespace, 'port', params['port'], True)
        ssm.write(namespace, 'user', db, True)
        ssm.write(namespace, 'password', passwd, True)