Пример #1
0
 def jinja_txt(self, value):
     if not self.stack._deploying:
         return value
     context = self.stack.infra.context
     env = utils.jinja_env(context)
     t = env[0].from_string(value)
     return t.render(context.vars)
Пример #2
0
 def jinja_env_vars(self):
     if not self._deploying or \
             len(self.vars.keys()) <= 0:
         return
     context = self.infra.context
     env = utils.jinja_env(context)
     for k, v in self.vars.items():
         t = env[0].from_string(v)
         self.vars[k] = t.render(context.vars)
Пример #3
0
def test_infra():

    infra = stackformation.Infra("test")
    test_infra = infra.create_sub_infra("test")
    ec2_stack = test_infra.add_stack(ec2.EC2Stack('test'))
    env = utils.jinja_env(test_infra.context, True)

    return {
        'infra': infra,
        'test_infra': test_infra,
        'ec2_stack': ec2_stack,
        'env': env
    }
Пример #4
0
    def review(self, infra):

        review = {
            'dependent_stacks': [],
        }

        review['info'] = self.stack_info()

        # get stack dependencies
        deps = infra.get_dependent_stacks(self)  # noqa

        for k, v in deps.items():
            info = v.stack_info()
            v.load_stack_outputs(self.infra)
            outputs = v.get_outputs()
            params = {}
            if info and info.get('Parameters'):
                for p in info.get('Parameters'):
                    params.update({p['ParameterKey']: p['ParameterValue']})
            review['dependent_stacks'].append({
                'stack': v,
                'outputs': outputs,
                'stack_info': info,
                'parameters': params
            })

        context = self.infra.context

        env = utils.jinja_env(context)

        review['template'] = self.build_template()
        parameters = self.get_parameters()
        template_vars = self.render_template_components(env[0],
                                                        context)  # noqa

        self.before_deploy(context, parameters)

        review['parameters'] = self.fill_params(parameters, context)
        review['template_vars'] = template_vars

        return review
Пример #5
0
    def get_dependent_stacks(self, stack):

        results = {}

        params = list(stack.get_parameters().keys())

        env = utils.jinja_env({}, True)

        stack.render_template_components(env[0], Context())

        params += env[1]

        stacks = self.list_stacks()

        for stk in stacks:
            ops = stk.get_outputs().keys()
            for o in ops:
                if o in params:
                    results.update({stk.get_stack_name(): stk})

        return results
Пример #6
0
def test_ec2_stack(infra):

    ebs_stack = infra[6]
    eip_stack = infra[5]
    vpc_stack = infra[4]
    web_profile = infra[3]
    iam_stack = infra[2]
    prod_infra = infra[1]
    infra = infra[0]

    ec2_stack = prod_infra.add_stack(
        ec2.EC2Stack("Web", vpc_stack, web_profile))

    web_vol = ebs_stack.add_volume(ebs.EBSVolume("Web", 100))

    ec2_stack.add_volume(web_vol)

    ssh_sg = vpc_stack.add_security_group(vpc.SSHSecurityGroup("SSH"))

    ec2_stack.add_security_group(ssh_sg)

    ec2_stack.keypair("testkey")

    ec2_stack.ami = "ami-id"

    t = ec2_stack.build_template()

    inst = t.resources['WebEC2Instance'].to_dict()

    assert ec2_stack.output_instance() == "ProdTestWebEC2WebEC2Instance"

    assert inst['Properties']['KeyName'] == 'testkey'

    assert inst['Properties']['NetworkInterfaces'][0]['SubnetId'] == {
        'Ref': 'ProdTestVPCPublicSubnet0'
    }

    assert inst['Properties']['NetworkInterfaces'][0]['GroupSet'][0] == {
        'Ref': 'ProdTestVPCSSHSecurityGroup'
    }

    ec2_stack.private_subnet = True

    t = ec2_stack.build_template()

    inst = t.resources['WebEC2Instance'].to_dict()

    assert inst['Properties']['NetworkInterfaces'][0]['SubnetId'] == {
        'Ref': 'ProdTestVPCPrivateSubnet1'
    }

    web_eip = eip_stack.add_ip("WebEip")

    ec2_stack.add_user_data(user_data.EIPInfo(web_eip))

    env = utils.jinja_env(prod_infra.context, True)

    res = ec2_stack.render_template_components(env[0], prod_infra.context)

    assert env[1][0] == 'ProdTestTestEIPWebEipEIP'
    assert env[1][1] == 'ProdTestTestEIPWebEipAllocationId'

    params = ec2_stack.get_parameters()
    ec2_stack.before_deploy(prod_infra.context, params)

    assert prod_infra.get_var("WebUserData0") == res['WebUserData'][0]
Пример #7
0
    def start_deploy(self, infra, context):
        """

        """

        present = True

        # check if the stack has been deployed
        cf = infra.boto_session.client("cloudformation")

        try:
            cf.describe_stacks(StackName=self.get_remote_stack_name())
        except botocore.exceptions.ClientError as e:
            if e.response['Error']['Code'] == "ValidationError":
                present = False
            else:
                print(e.response['Error']['Code'])
                print("FATAL ERROR")
                exit(1)

        env = utils.jinja_env(context)

        self._deploying = True
        template = self.build_template()
        self._deploying = False
        parameters = self.get_parameters()
        template_vars = self.render_template_components(env[0],
                                                        context)  # noqa

        self.before_deploy(context, parameters)

        parameters = self.fill_params(parameters, context)

        dep_kw = {
            'StackName': self.get_remote_stack_name(),
            'Parameters': parameters,
            'Capabilities': ['CAPABILITY_IAM', 'CAPABILITY_NAMED_IAM']
        }

        # check template size constraint
        json_template = template.to_json()
        if len(json_template) < 5100:
            dep_kw['TemplateBody'] = json_template
        else:
            dep_kw['TemplateURL'] = self.upload_to_s3(
                infra, self.get_remote_stack_name(), json_template)
        # import json
        # print(json.dumps(dep_kw, indent=True))
        # exit(1)

        dep_kw['Tags'] = [{
            'Key': 'Stackformation',
            'Value': stackformation.__version__
        }]

        try:
            if present:
                cf.update_stack(**dep_kw)
                logger.info('{}UPDATING STACK:{} {}'.format(
                    utils.colors('b'), Style.RESET_ALL, self.get_stack_name()))
            else:
                cf.create_stack(**dep_kw)
                logger.info('{}CREATING STACK:{} {}'.format(
                    utils.colors('b', True), Style.RESET_ALL,
                    self.get_stack_name()))
        except botocore.exceptions.ClientError as e:
            err = e.response['Error']
            if (err['Code'] == "ValidationError"
                    and re.search("No updates", err['Message'])):  # noqa
                return False
            else:
                raise e

        return True