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')
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)
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)
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)
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)
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)
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')
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)