Example #1
0
    def __init__(self, config_file=None, config_dict=None, cli_params=None):
        self.logger = get_logger()

        if isinstance(config_dict, dict):
            self.working_dir = None
        elif config_file:
            config_dict = self._read_config_file(config_file)
            self.working_dir = os.path.dirname(os.path.realpath(config_file))
        else:
            raise InvalidConfigException(
                "No config_file or valid config_dict provided")

        self.cli_params = self._parse_cli_parameters(cli_params)
        self.region = config_dict.get("region")

        self.default_service_role = config_dict.get("service-role")
        self.default_stack_policy_url = config_dict.get("stack-policy-url")
        self.default_timeout = config_dict.get("timeout", 600)
        self.default_tags = config_dict.get("tags", {})
        self.default_failure_action = config_dict.get("on_failure", "ROLLBACK")
        self.default_disable_rollback = config_dict.get(
            "disable_rollback", False)

        self.stacks = self._parse_stack_configs(config_dict)
        self._config_dict = config_dict

        self._validate()
Example #2
0
    def __init__(self,
                 config_file=None,
                 config_dict=None,
                 cli_params=None,
                 stack_name_suffix=None):
        self.logger = get_logger()

        if isinstance(config_dict, dict):
            self.stack_config_base_dir = None
        elif config_file:
            self.stack_config_base_dir = os.path.dirname(
                os.path.realpath(config_file))
            config_dict = FileLoader.get_yaml_or_json_file(
                config_file, working_dir=os.getcwd())
        else:
            raise InvalidConfigException(
                "You need to pass either config_file (path to a file) or config_dict (python dict) property"
            )

        self.cli_params = self._parse_cli_parameters(cli_params)
        self.region = config_dict.get("region")
        self.stack_name_suffix = stack_name_suffix

        self.default_service_role = config_dict.get("service-role")
        self.default_stack_policy_url = config_dict.get("stack-policy-url")
        self.default_timeout = config_dict.get("timeout", 600)
        self.default_tags = config_dict.get("tags", {})
        self.default_failure_action = config_dict.get("on_failure", "ROLLBACK")
        self.default_disable_rollback = config_dict.get(
            "disable_rollback", False)

        self._validate(config_dict)

        stacks = self._parse_stack_configs(config_dict)
        self.stacks = self._apply_stack_name_suffix(stacks, stack_name_suffix)
Example #3
0
 def __init__(self, config, dry_run=False):
     self.logger = get_logger(root=True)
     self.config = config
     self.cfn = CloudFormation(region=self.config.region, dry_run=dry_run)
     self.parameter_resolver = ParameterResolver(self.cfn,
                                                 region=self.config.region)
     self.cli_parameters = config.cli_params
Example #4
0
    def __init__(self, config_file=None, config_dict=None, cli_params=None):
        self.logger = get_logger()

        if isinstance(config_dict, dict):
            self.working_dir = None
        elif config_file:
            config_dict = self._read_config_file(config_file)
            self.working_dir = os.path.dirname(os.path.realpath(config_file))
        else:
            raise InvalidConfigException("No config_file or valid config_dict provided")

        self.cli_params = self._parse_cli_parameters(cli_params)
        self.region = config_dict.get("region")

        self.default_service_role = config_dict.get("service-role")
        self.default_stack_policy_url = config_dict.get("stack-policy-url")
        self.default_timeout = config_dict.get("timeout", 600)
        self.default_tags = config_dict.get("tags", {})
        self.default_failure_action = config_dict.get("on_failure", "ROLLBACK")
        self.default_disable_rollback = config_dict.get("disable_rollback", False)

        self.stacks = self._parse_stack_configs(config_dict)
        self._config_dict = config_dict

        self._validate()
Example #5
0
 def __init__(self, body_dict, name):
     self.logger = get_logger()
     self.name = name
     self.body_dict = body_dict
     self.template_format_version = body_dict.get('AWSTemplateFormatVersion', "2010-09-09")
     self.description = body_dict.get('Description', "")
     self.parameters = body_dict.get('Parameters', {})
     self.resources = body_dict.get('Resources', {})
     self.outputs = body_dict.get('Outputs', {})
     self.post_custom_resources = body_dict.get('PostCustomResources', {})
Example #6
0
    def __init__(self, region="eu-west-1"):
        logging.getLogger('boto').setLevel(logging.FATAL)
        self.logger = get_logger()

        self.conn = cloudformation.connect_to_region(region)
        if not self.conn:
            self.logger.error("Could not connect to cloudformation API in {0}. Invalid region?".format(region))
            raise Exception("Got None connection object")

        self.logger.debug("Connected to cloudformation API at {0} with access key id: {1}".format(
            region, self.conn.aws_access_key_id))
Example #7
0
    def package(cls, template_url, working_dir, template, region,
                package_bucket):
        logger = get_logger()

        if not package_bucket:
            return template

        if template_url.lower().startswith(
                "s3://") or template_url.lower().startswith("https://"):
            raise Exception(
                "SAM packaging is only supported for local templates (not S3/HTTPS)"
            )

        template_body_dict = template.get_template_body_dict()

        # Save template to a temporary file in the original template's
        # directory. Call `aws cloudformation package` to upload artifacts
        # to S3.
        aws_credentials = boto3.DEFAULT_SESSION.get_credentials()
        with tempfile.NamedTemporaryFile(
                mode="w",
                dir=os.path.dirname(os.path.join(working_dir, template_url)),
                suffix=".json") as src_fp:
            # Save the template. Ensure the buffer's flushed to disk before
            # calling `aws cloudformation package`.
            json.dump(template_body_dict, src_fp)
            src_fp.flush()

            # Open temporary file for the packaged template.
            # We'd previously used stdout, but the packaging process also
            # wrote status to stdout when the source artifact changed, causing
            # malformed JSON.
            with tempfile.NamedTemporaryFile(mode="r") as dst_fp:
                logger.info("Packaging {}".format(template_url))
                result = subprocess.check_call(
                    args=[
                        "aws", "cloudformation", "package", "--template-file",
                        src_fp.name, "--s3-bucket", package_bucket,
                        "--output-template-file", dst_fp.name, "--use-json"
                    ],
                    env=dict(os.environ,
                             AWS_REGION=region,
                             AWS_ACCESS_KEY_ID=aws_credentials.access_key,
                             AWS_SECRET_ACCESS_KEY=aws_credentials.secret_key,
                             AWS_SESSION_TOKEN=aws_credentials.token or ''),
                    stdout=subprocess.DEVNULL,
                    stderr=sys.stderr)

                result = dst_fp.read()

        template_body_dict = json.loads(result)
        template = CloudFormationTemplate(template_body_dict, template.name)
        return template
Example #8
0
    def __init__(self, region="eu-west-1"):
        logging.getLogger("boto").setLevel(logging.FATAL)
        self.logger = get_logger()

        self.conn = cloudformation.connect_to_region(region)
        if not self.conn:
            self.logger.error(
                "Could not connect to cloudformation API in {0}. Invalid region?"
                .format(region))
            raise Exception("Got None connection object")

        self.logger.debug(
            "Connected to cloudformation API at {0} with access key id: {1}".
            format(region, self.conn.aws_access_key_id))
Example #9
0
    def __init__(self,
                 config_file=None,
                 config_dict=None,
                 cli_params=None,
                 transform_context=None):
        self.logger = get_logger()

        import_path = None

        if transform_context:
            import_path = os.path.dirname(transform_context)

            with open(transform_context, 'r') as stream:
                transform_context = yaml.load(stream)
        else:
            transform_context = {}

        if isinstance(config_dict, dict):
            self.working_dir = None
        elif config_file:
            config_dict = self._read_config_file(config_file,
                                                 transform_context,
                                                 import_path)
            self.working_dir = os.path.dirname(os.path.realpath(config_file))
        else:
            raise InvalidConfigException(
                "No config_file or valid config_dict provided")

        self.cli_params = self._parse_cli_parameters(cli_params)
        self.region = config_dict.get("region")

        self.change_set = config_dict.get("change_set")
        self.default_service_role = config_dict.get("service-role")
        self.default_stack_policy_url = config_dict.get("stack-policy-url")
        self.default_timeout = config_dict.get("timeout", 600)
        self.default_tags = config_dict.get("tags", {})
        self.default_package_bucket = config_dict.get("package-bucket", None)
        self.default_failure_action = config_dict.get("on_failure", "ROLLBACK")
        self.default_disable_rollback = config_dict.get(
            "disable_rollback", False)

        self.stacks = self._parse_stack_configs(config_dict, transform_context)
        self._config_dict = config_dict

        self._validate()
Example #10
0
    def handle_sns_subscription(cls, resource_description, stack):
        logger = get_logger()
        queue_prefix = stack.name + '-' + resource_description['Properties']['QueueResourceName']
        topic_region = resource_description['Properties'].get('TopicRegion', stack.region)
        topic_arn = cls.extract_topic_arn(resource_description, stack.parameters)

        sqs_conn = sqs.connect_to_region(stack.region)
        sns_conn = sns.connect_to_region(topic_region)

        queues = sqs_conn.get_all_queues(prefix=queue_prefix)
        if len(queues) != 1:
            raise CfnSphereException(
                "Found {0} queues matching the prefix: {1}. Should be 1.".format(len(queues), queue_prefix))

        queue = queues[0]

        logger.info("Subscribing queue {0} to topic {1} in {2}".format(queue.name, topic_arn, topic_region))
        sns_conn.subscribe_sqs_queue(topic_arn, queue)
Example #11
0
    def handle_sns_subscription(cls, resource_description, stack):
        logger = get_logger()
        queue_prefix = stack.name + '-' + resource_description['Properties']['QueueResourceName']
        topic_region = resource_description['Properties'].get('TopicRegion', stack.region)
        topic_arn = cls.extract_topic_arn(resource_description, stack.parameters)

        sqs_conn = sqs.connect_to_region(stack.region)
        sns_conn = sns.connect_to_region(topic_region)

        queues = sqs_conn.get_all_queues(prefix=queue_prefix)
        if len(queues) != 1:
            raise CfnSphereException(
                "Found {0} queues matching the prefix: {1}. Should be 1.".format(len(queues), queue_prefix))

        queue = queues[0]

        logger.info("Subscribing queue {0} to topic {1} in {2}".format(queue.name, topic_arn, topic_region))
        sns_conn.subscribe_sqs_queue(topic_arn, queue)
Example #12
0
    def __init__(self, config_file=None, config_dict=None, cli_params=None):
        self.logger = get_logger()

        if isinstance(config_dict, dict):
            self.working_dir = None
        elif config_file:
            config_dict = self._read_config_file(config_file)
            self.working_dir = os.path.dirname(os.path.realpath(config_file))
        else:
            raise NoConfigException("No config_file or valid config_dict provided")

        self.cli_params = self._parse_cli_parameters(cli_params)
        self.region = config_dict.get('region')
        self.tags = config_dict.get('tags', {})
        self.tags = self._add_git_remote_url_tag(self.tags, self.working_dir)
        self.stacks = self._parse_stack_configs(config_dict)

        self._validate()
Example #13
0
 def __init__(self, config):
     self.logger = get_logger(root=True)
     self.config = config
     self.cfn = CloudFormation(region=self.config.region)
     self.parameter_resolver = ParameterResolver(region=self.config.region)
Example #14
0
import boto
import click

from boto.exception import NoAuthHandlerFound, BotoServerError

from cfn_sphere.template.transformer import CloudFormationTemplateTransformer
from cfn_sphere.aws.cfn import CloudFormation
from cfn_sphere.util import convert_file, get_logger, get_latest_version
from cfn_sphere.stack_configuration import Config
from cfn_sphere import StackActionHandler
from cfn_sphere.exceptions import CfnSphereException
from cfn_sphere.file_loader import FileLoader
from cfn_sphere import __version__

LOGGER = get_logger(root=True)
logging.getLogger('boto').setLevel(logging.FATAL)


def get_current_account_alias():
    try:
        return boto.connect_iam().get_account_alias().account_aliases[0]
    except NoAuthHandlerFound as e:
        click.echo("Authentication error! Please check credentials: {0}".format(e))
        sys.exit(1)
    except BotoServerError as e:
        if e.code == "ExpiredToken":
            click.echo(e.message)
        else:
            click.echo("AWS API Error: {0}".format(e))
Example #15
0
import boto3
import click
from botocore.exceptions import ClientError, BotoCoreError

from cfn_sphere import StackActionHandler
from cfn_sphere import __version__
from cfn_sphere.aws.cfn import CloudFormation
from cfn_sphere.aws.kms import KMS
from cfn_sphere.exceptions import CfnSphereException
from cfn_sphere.file_generator import FileGenerator
from cfn_sphere.file_loader import FileLoader
from cfn_sphere.stack_configuration import Config
from cfn_sphere.template.transformer import CloudFormationTemplateTransformer
from cfn_sphere.util import convert_file, get_logger, get_latest_version, kv_list_to_dict, get_resources_dir

LOGGER = get_logger(root=True)


def get_first_account_alias_or_account_id():
    try:
        return boto3.client('iam').list_account_aliases()["AccountAliases"][0]
    except IndexError:
        return boto3.client('sts').get_caller_identity()["Arn"].split(":")[4]
    except (BotoCoreError, ClientError) as e:
        LOGGER.error(e)
        sys.exit(1)
    except Exception as e:
        LOGGER.error("Unknown error occurred loading users account alias")
        LOGGER.exception(e)
        LOGGER.info(
            "Please report at https://github.com/cfn-sphere/cfn-sphere/issues!"
Example #16
0
 def __init__(self, region="eu-west-1"):
     self.logger = get_logger()
     self.cfn = CloudFormation(region)
     self.ec2 = Ec2Api(region)
     self.kms = KMS(region)
Example #17
0
 def __init__(self, cfn, region=DEFAULT_REGION):
     self.logger = get_logger()
     self.cfn = cfn
     self.ec2 = Ec2Api(region)
     self.kms = KMS(region)
     self.ssm = SSM(region)
Example #18
0
 def __init__(self, region="eu-west-1"):
     self.logger = get_logger()
     self.client = boto3.client('cloudformation', region_name=region)
     self.resource = boto3.resource('cloudformation', region_name=region)
Example #19
0
 def __init__(self, config):
     self.logger = get_logger(root=True)
     self.config = config
     self.region = config.region
     self.cfn = CloudFormation(region=self.region)
     self.parameter_resolver = ParameterResolver(region=self.region)
Example #20
0
 def __init__(self, region="eu-west-1"):
     self.logger = get_logger()
     self.client = boto3.client('cloudformation', region_name=region)
     self.resource = boto3.resource('cloudformation', region_name=region)
 def __init__(self, region="eu-west-1"):
     self.logger = get_logger()
     self.cfn = CloudFormation(region)
     self.ec2 = Ec2Api(region)
     self.kms = KMS(region)