Example #1
0
File: run.py Project: uho/cftpl
def create_or_update(config, password, run=True):
    stack = CFStack(config, password)
    print('Validating template... ', end='', file=sys.stderr)
    stack.validate()    # raises if defect
    print('successfull.', file=sys.stderr)
    if run:
        if stack.active:
            print("Updating Stack {}...".format(stack.name), end='', file=sys.stderr)
            stack.update()
            print(' done.')
        else:
            print("Creating Stack {}...".format(stack.name), end='', file=sys.stderr)
            stack.create()
        print(' done.', file=sys.stderr)
        print_stack_events(stack)
        return stack
    # IF WE'RE NOT ACTIVELY CREATING OR UPDATING A STACK, WE'RE SHOWING THE CONFIG INSTEAD:
    print("This is the configuration we'd use if this was for real:\n\n", file=sys.stderr)
    if not config['JSON_INDENT']:
        config['JSON_INDENT'] = 4
    template = CFTemplate(config)
    print(template.create_json())
    if config['FILES']:
        print("\n\nHere are all the files you can use:", file=sys.stderr)
        for name, path in config['FILES'].iteritems():
            print('\t"{}":\t"{}"'.format(name, path), file=sys.stderr)
    return None
Example #2
0
def create_or_update(config, password, run=True):
    stack = CFStack(config, password)
    print('Validating template... ', end='', file=sys.stderr)
    stack.validate()  # raises if defect
    print('successfull.', file=sys.stderr)
    if run:
        if stack.active:
            print("Updating Stack {}...".format(stack.name),
                  end='',
                  file=sys.stderr)
            stack.update()
            print(' done.')
        else:
            print("Creating Stack {}...".format(stack.name),
                  end='',
                  file=sys.stderr)
            stack.create()
        print(' done.', file=sys.stderr)
        print_stack_events(stack)
        return stack
    # IF WE'RE NOT ACTIVELY CREATING OR UPDATING A STACK, WE'RE SHOWING THE CONFIG INSTEAD:
    print("This is the configuration we'd use if this was for real:\n\n",
          file=sys.stderr)
    if not config['JSON_INDENT']:
        config['JSON_INDENT'] = 4
    template = CFTemplate(config)
    print(template.create_json())
    if config['FILES']:
        print("\n\nHere are all the files you can use:", file=sys.stderr)
        for name, path in config['FILES'].iteritems():
            print('\t"{}":\t"{}"'.format(name, path), file=sys.stderr)
    return None
Example #3
0
 def __init__(self, config, password=None):
     """
     A thin layer over boto.connect_cloudformation adding templates.
     config: the usual dict
     password_getter: an executable that yields the password or None to use AWS IAM.
     """
     self.conf = config
     self.password = password
     self.name = config['STACK_NAME']
     self.connection = self.__make_cloud_formation_connection()
     self.template = CFTemplate(self.conf)
Example #4
0
class CFStack(object):
    def __init__(self, config, password=None):
        """
        A thin layer over boto.connect_cloudformation adding templates.
        config: the usual dict
        password_getter: an executable that yields the password or None to use AWS IAM.
        """
        self.conf = config
        self.password = password
        self.name = config['STACK_NAME']
        self.connection = self.__make_cloud_formation_connection()
        self.template = CFTemplate(self.conf)

    def get_stack(self):
        temp = [x for x in self.list() if x.stack_name == self.name and
                                          x.stack_status != 'DELETE_COMPLETE']
        if len(temp) > 1:
            raise CFStackError('Confused, too many stacks found: {}'.format(", ".join([x.stack_id for x in temp])))
        if len(temp) == 1:
            return temp[0]
        return None

    def __getattr__(self, item):
        stack = self.get_stack()
        if hasattr(stack, item):
            return getattr(stack, item)

    def delete(self, stack_name_or_id=None):
        stack = stack_name_or_id or self.name
        return self.connection.delete_stack(stack)

    def list(self):
        return self.connection.list_stacks()

    def update(self):
        return self.connection.update_stack(self.name,
                                            template_body=self.template.create_json(),
                                            capabilities=self.conf['CAPABILITIES'],
                                            tags=self.conf['TAGS'])

    def create(self):
        return self.connection.create_stack(self.name,
                                            template_body=self.template.create_json(),
                                            capabilities=self.conf['CAPABILITIES'],
                                            tags=self.conf['TAGS'])

    @property
    def active(self):
        stack = self.get_stack()
        if stack and stack.stack_status.endswith('_COMPLETE'):
            return stack
        return False

    def get_stack_event(self):
        stack = self.get_stack()
        if stack:
            return self.connection.describe_stack_events(stack.stack_id)
        return None

    def get_stack_events(self, interval_wait_time=5):
        events = set()
        wait = 0
        while wait < 1000:  # make sure we're not running endlessly
            try:
                event_list = self.connection.describe_stack_events(self.name)
            except boto.exception.BotoServerError:
                yield 'DELETE_COMPLETE'
                break
            event_list.reverse()  # we'd like to see the most recent message last.
            for event in event_list:
                if event.event_id not in events:
                    yield event
                    events.add(event.event_id)
            wait += 1
            stack = self.get_stack()
            if stack.stack_status.endswith('_COMPLETE'):
                yield stack.stack_status
                break
            time.sleep(interval_wait_time)

    def price(self):
        return self.connection.estimate_template_cost(template_body=self.template.create_json())

    def validate(self):
        return self.connection.validate_template(template_body=self.template.create_json())

    def cancel_update(self):
        return self.connection.cancel_update_stack(self.name)

    def __make_cloud_formation_connection(self):
        cf_region = [x for x in boto.cloudformation.regions() if x.name == self.conf['ENDPOINT']]
        return boto.connect_cloudformation(self.conf['ACCOUNT'], aws_secret_access_key=self.password,
                                           region=cf_region[0])
Example #5
0
def display_yaml(config):
    print("This is the rendered template:\n\n", file=sys.stderr)
    template = CFTemplate(config)
    print(template.create())
    return None
Example #6
0
 def test_create_json(self):
     conf = CFTemplate(self.example_config)
     created = json.loads(conf.create_json())
     self.assertEqual(created, self.test_result)
Example #7
0
 def test_create_yaml(self):
     self.example_config['TEMPLATE'] = 'prod.yaml'
     conf = CFTemplate(self.example_config)
     created = json.loads(conf.create_json())
     self.assertEqual(created, self.test_result)
Example #8
0
 def test_create_fails(self):
     self.example_config['TEMPLATE_PATH'] = '/tmp'
     self.example_config['FILES'] = {}
     conf = CFTemplate(self.example_config)
     self.assertRaises(TemplateNotFound, conf.create)
Example #9
0
 def test_init_settings(self):
     testpath = '/tmp'
     self.example_config['TEMPLATE_PATH'] = testpath
     self.example_config['FILES'] = {}
     conf = CFTemplate(self.example_config)
     self.assertEqual(conf.config['TEMPLATE_PATH'], testpath)
Example #10
0
 def test_create_json(self):
     conf = CFTemplate(self.example_config)
     created = json.loads(conf.create_json())
     self.assertEqual(created, self.test_result)
Example #11
0
 def test_create_yaml(self):
     self.example_config["TEMPLATE"] = "prod.yaml"
     conf = CFTemplate(self.example_config)
     created = json.loads(conf.create_json())
     self.assertEqual(created, self.test_result)
Example #12
0
File: run.py Project: uho/cftpl
def display_yaml(config):
    print("This is the rendered template:\n\n", file=sys.stderr)
    template = CFTemplate(config)
    print(template.create())
    return None