def update(self, data):
        """Updates the object information based on live data, if there were any changes made. Any changes will be
        automatically applied to the object, but will not be automatically persisted. You must manually call
        `db.session.add(instance)` on the object.

        Args:
            data (:obj:): AWS API Resource object fetched from AWS API

        Returns:
            True if there were any changes to the object, else false
        """
        # If the instance was terminated, remove it
        if data.state['Name'] == 'terminated':
            self.delete(auto_commit=False)
            return True

        updated = self.set_property('launch_date', to_utc_date(data.launch_time).isoformat())
        updated |= self.set_property('state', data.state['Name'])
        updated |= self.set_property('instance_type', data.instance_type)
        updated |= self.set_property('public_ip', data.public_ip_address or None)
        updated |= self.set_property('public_dns', data.public_dns_name or None)

        tags = {x['Key']: x['Value'] for x in data.tags or {}}
        existing_tags = {x.key: x for x in self.tags}

        # Check for new tags
        for key, value in list(tags.items()):
            updated |= self.set_tag(key, value)

        # Check for updated or removed tags
        for key in list(existing_tags.keys()):
            if key not in tags:
                updated |= self.delete_tag(key)

        return updated
Exemple #2
0
    def update_instances(self):
        """Update list of EC2 Instances for the account / region

        Returns:
            `None`
        """
        self.log.debug('Updating EC2Instances for {}/{}'.format(
            self.account.account_name, self.region))
        ec2 = self.session.resource('ec2', region_name=self.region)

        try:
            existing_instances = EC2Instance.get_all(self.account, self.region)
            instances = {}
            api_instances = {x.id: x for x in ec2.instances.all()}

            try:
                for instance_id, data in api_instances.items():
                    if data.instance_id in existing_instances:
                        instance = existing_instances[instance_id]

                        if data.state['Name'] not in ('terminated',
                                                      'shutting-down'):
                            instances[instance_id] = instance

                            # Add object to transaction if it changed
                            if instance.update(data):
                                self.log.debug(
                                    'Updating info for instance {} in {}/{}'.
                                    format(instance.resource.resource_id,
                                           self.account.account_name,
                                           self.region))
                                db.session.add(instance.resource)
                    else:
                        # New instance, if its not in state=terminated
                        if data.state['Name'] in ('terminated',
                                                  'shutting-down'):
                            continue

                        tags = {
                            tag['Key']: tag['Value']
                            for tag in data.tags or {}
                        }
                        properties = {
                            'launch_date':
                            to_utc_date(data.launch_time).isoformat(),
                            'state':
                            data.state['Name'],
                            'instance_type':
                            data.instance_type,
                            'public_ip':
                            getattr(data, 'public_ip_address', None),
                            'public_dns':
                            getattr(data, 'public_dns_address', None),
                            'created':
                            isoformat(datetime.now())
                        }

                        instance = EC2Instance.create(
                            data.instance_id,
                            account_id=self.account.account_id,
                            location=self.region,
                            properties=properties,
                            tags=tags)

                        instances[instance.resource.resource_id] = instance
                        self.log.debug('Added new EC2Instance {}/{}/{}'.format(
                            self.account.account_name, self.region,
                            instance.resource.resource_id))

                # Check for deleted instances
                ik = set(list(instances.keys()))
                eik = set(list(existing_instances.keys()))

                for instanceID in eik - ik:
                    db.session.delete(existing_instances[instanceID].resource)
                    self.log.debug('Deleted EC2Instance {}/{}/{}'.format(
                        self.account.account_name, self.region, instanceID))

                db.session.commit()
            except:
                db.session.rollback()
                raise
        finally:
            del ec2