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
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