def describe_change_set(ctx, path, change_set_name, verbose): """ Describes the change set. \f :param path: Path to execute the command on. :type path: str :param change_set_name: Name of the Change Set to use. :type change_set_name: str :param verbose: A flag to display verbose output. :type verbose: bool """ context = SceptreContext( command_path=path, project_path=ctx.obj.get("project_path"), user_variables=ctx.obj.get("user_variables"), options=ctx.obj.get("options"), output_format=ctx.obj.get("output_format"), no_colour=ctx.obj.get("no_colour"), ignore_dependencies=ctx.obj.get("ignore_dependencies")) plan = SceptrePlan(context) responses = plan.describe_change_set(change_set_name) for response in responses.values(): description = response if not verbose: description = simplify_change_set_description(description) write(description, context.output_format, context.no_colour)
def list_outputs(ctx, path, export): """ List outputs for stack. \f :param path: Path to execute the command on. :type path: str :param export: Specify the export formatting. :type export: str """ context = SceptreContext( command_path=path, project_path=ctx.obj.get("project_path", None), user_variables=ctx.obj.get("user_variables", {}), options=ctx.obj.get("options", {}), output_format=ctx.obj.get("output_format"), ignore_dependencies=ctx.obj.get("ignore_dependencies")) plan = SceptrePlan(context) responses = [ response for response in plan.describe_outputs().values() if response ] if export == "envvar": for response in responses: for stack in response.values(): for output in stack: write( "export SCEPTRE_{0}='{1}'".format( output.get("OutputKey"), output.get("OutputValue")), 'text') else: write(responses, context.output_format)
def estimate_cost_command(ctx, path): """ Prints a URI to STOUT that provides an estimated cost based on the resources in the stack. This command will also attempt to open a web browser with the returned URI. \f :param path: Path to execute the command on. :type path: str """ context = SceptreContext( command_path=path, project_path=ctx.obj.get("project_path"), user_variables=ctx.obj.get("user_variables"), options=ctx.obj.get("options"), output_format=ctx.obj.get("output_format"), ignore_dependencies=ctx.obj.get("ignore_dependencies")) plan = SceptrePlan(context) responses = plan.estimate_cost() for stack, response in responses.items(): if response['ResponseMetadata']['HTTPStatusCode'] == 200: del response['ResponseMetadata'] click.echo("View the estimated cost for {} at:".format(stack.name)) response = response["Url"] webbrowser.open(response, new=2) write(response + "\n", 'text')
def validate_command(ctx, path): """ Validates the template used for stack in PATH. \f :param path: Path to execute the command on. :type path: str """ context = SceptreContext( command_path=path, project_path=ctx.obj.get("project_path"), user_variables=ctx.obj.get("user_variables"), options=ctx.obj.get("options"), output_format=ctx.obj.get("output_format"), ignore_dependencies=ctx.obj.get("ignore_dependencies")) plan = SceptrePlan(context) responses = plan.validate() for stack, response in responses.items(): if response['ResponseMetadata']['HTTPStatusCode'] == 200: del response['ResponseMetadata'] click.echo("Template {} is valid. Template details:\n".format( stack.name)) write(response, context.output_format)
def update_command(ctx, path, change_set, verbose, yes): """ Updates a stack for a given config PATH. Or perform an update via change-set when the change-set flag is set. \f :param path: Path to execute the command on. :type path: str :param change_set: Whether a change set should be created. :type change_set: bool :param verbose: A flag to print a verbose output. :type verbose: bool :param yes: A flag to answer 'yes' to all CLI questions. :type yes: bool """ context = SceptreContext( command_path=path, project_path=ctx.obj.get("project_path"), user_variables=ctx.obj.get("user_variables"), options=ctx.obj.get("options"), output_format=ctx.obj.get("output_format"), ignore_dependencies=ctx.obj.get("ignore_dependencies")) plan = SceptrePlan(context) if change_set: change_set_name = "-".join(["change-set", uuid1().hex]) plan.create_change_set(change_set_name) try: # Wait for change set to be created statuses = plan.wait_for_cs_completion(change_set_name) # Exit if change set fails to create for status in list(statuses.values()): if status != StackChangeSetStatus.READY: exit(1) # Describe changes descriptions = plan.describe_change_set(change_set_name) for description in list(descriptions.values()): if not verbose: description = simplify_change_set_description(description) write(description, context.output_format) # Execute change set if happy with changes if yes or click.confirm("Proceed with stack update?"): plan.execute_change_set(change_set_name) except Exception as e: raise e finally: # Clean up by deleting change set plan.delete_change_set(change_set_name) else: confirmation("update", yes, command_path=path) responses = plan.update() exit(stack_status_exit_code(responses.values()))
def generate_command(ctx, path): """ Prints the template used for stack in PATH. \f :param path: Path to execute the command on. :type path: str """ context = SceptreContext( command_path=path, project_path=ctx.obj.get("project_path"), user_variables=ctx.obj.get("user_variables"), options=ctx.obj.get("options"), output_format=ctx.obj.get("output_format"), ignore_dependencies=ctx.obj.get("ignore_dependencies")) plan = SceptrePlan(context) responses = plan.generate() output = [template for template in responses.values()] write(output, context.output_format)
def describe_policy(ctx, path): """ Displays the stack policy used. \f :param path: Path to execute the command on. :type path: str """ context = SceptreContext( command_path=path, project_path=ctx.obj.get("project_path"), user_variables=ctx.obj.get("user_variables"), options=ctx.obj.get("options"), output_format=ctx.obj.get("output_format"), no_colour=ctx.obj.get("no_colour"), ignore_dependencies=ctx.obj.get("ignore_dependencies")) plan = SceptrePlan(context) responses = plan.get_policy() for response in responses.values(): write(response, context.output_format, context.no_colour)
def list_resources(ctx, path): """ List resources for stack or stack_group. \f :param path: Path to execute the command on. :type path: str """ context = SceptreContext( command_path=path, project_path=ctx.obj.get("project_path"), user_variables=ctx.obj.get("user_variables"), options=ctx.obj.get("options"), output_format=ctx.obj.get("output_format"), ignore_dependencies=ctx.obj.get("ignore_dependencies")) plan = SceptrePlan(context) responses = [ response for response in plan.describe_resources().values() if response ] write(responses, context.output_format)
def status_command(ctx, path): """ Prints the stack status or the status of the stacks within a stack_group for a given config PATH. \f :param path: Path to execute the command on. :type path: str """ context = SceptreContext( command_path=path, project_path=ctx.obj.get("project_path"), user_variables=ctx.obj.get("user_variables"), options=ctx.obj.get("options"), no_colour=ctx.obj.get("no_colour"), output_format=ctx.obj.get("output_format"), ignore_dependencies=ctx.obj.get("ignore_dependencies")) plan = SceptrePlan(context) responses = plan.get_status() message = "\n".join("{}: {}".format(stack.name, status) for stack, status in responses.items()) write(message, no_colour=context.no_colour)
def test_write_status_without_colour(self, mock_echo): write("stack: CREATE_COMPLETE", no_colour=True) mock_echo.assert_called_once_with( '{\n "stack": "CREATE_COMPLETE"\n}')
def test_write_status_with_colour(self, mock_echo): write("stack: CREATE_COMPLETE", no_colour=False) mock_echo.assert_called_once_with( '{\n "stack": "\x1b[32mCREATE_COMPLETE\x1b[0m"\n}')
def test_write_formats(self, mock_echo, output_format, no_colour, expected_output): write({"stack": "CREATE_COMPLETE"}, output_format, no_colour) mock_echo.assert_called_once_with(expected_output)