Made Nova flavor field name configurable

This commit is contained in:
Anuj Mathur 2013-10-10 19:22:46 +05:30
parent a85eb2bf07
commit 26567870da
17 changed files with 913 additions and 718 deletions

View File

@ -0,0 +1,244 @@
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding field 'InstanceReconcile.instance_flavor_id'
db.add_column(u'stacktach_instancereconcile', 'instance_flavor_id',
self.gf('django.db.models.fields.CharField')(db_index=True, max_length=100, null=True, blank=True),
keep_default=False)
# Adding field 'InstanceExists.instance_flavor_id'
db.add_column(u'stacktach_instanceexists', 'instance_flavor_id',
self.gf('django.db.models.fields.CharField')(db_index=True, max_length=100, null=True, blank=True),
keep_default=False)
# Adding field 'InstanceUsage.instance_flavor_id'
db.add_column(u'stacktach_instanceusage', 'instance_flavor_id',
self.gf('django.db.models.fields.CharField')(db_index=True, max_length=100, null=True, blank=True),
keep_default=False)
def backwards(self, orm):
# Deleting field 'InstanceReconcile.instance_flavor_id'
db.delete_column(u'stacktach_instancereconcile', 'instance_flavor_id')
# Deleting field 'InstanceExists.instance_flavor_id'
db.delete_column(u'stacktach_instanceexists', 'instance_flavor_id')
# Deleting field 'InstanceUsage.instance_flavor_id'
db.delete_column(u'stacktach_instanceusage', 'instance_flavor_id')
models = {
u'stacktach.deployment': {
'Meta': {'object_name': 'Deployment'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
u'stacktach.genericrawdata': {
'Meta': {'object_name': 'GenericRawData'},
'deployment': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['stacktach.Deployment']"}),
'event': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
'host': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '100', 'null': 'True', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'instance': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
'json': ('django.db.models.fields.TextField', [], {}),
'message_id': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
'publisher': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '100', 'null': 'True', 'blank': 'True'}),
'request_id': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
'routing_key': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
'service': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
'tenant': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
'when': ('django.db.models.fields.DecimalField', [], {'max_digits': '20', 'decimal_places': '6', 'db_index': 'True'})
},
u'stacktach.glancerawdata': {
'Meta': {'object_name': 'GlanceRawData'},
'deployment': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['stacktach.Deployment']"}),
'event': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
'host': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '100', 'null': 'True', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'image_type': ('django.db.models.fields.IntegerField', [], {'default': '0', 'null': 'True', 'db_index': 'True'}),
'instance': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
'json': ('django.db.models.fields.TextField', [], {}),
'owner': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255', 'null': 'True', 'blank': 'True'}),
'publisher': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '100', 'null': 'True', 'blank': 'True'}),
'request_id': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
'routing_key': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
'service': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
'status': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'db_index': 'True'}),
'uuid': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '36', 'null': 'True', 'blank': 'True'}),
'when': ('django.db.models.fields.DecimalField', [], {'max_digits': '20', 'decimal_places': '6', 'db_index': 'True'})
},
u'stacktach.imagedeletes': {
'Meta': {'object_name': 'ImageDeletes'},
'deleted_at': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '6', 'db_index': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'raw': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['stacktach.GlanceRawData']", 'null': 'True'}),
'uuid': ('django.db.models.fields.CharField', [], {'max_length': '50', 'db_index': 'True'})
},
u'stacktach.imageexists': {
'Meta': {'object_name': 'ImageExists'},
'audit_period_beginning': ('django.db.models.fields.DecimalField', [], {'max_digits': '20', 'decimal_places': '6', 'db_index': 'True'}),
'audit_period_ending': ('django.db.models.fields.DecimalField', [], {'max_digits': '20', 'decimal_places': '6', 'db_index': 'True'}),
'created_at': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '6', 'db_index': 'True'}),
'delete': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'to': u"orm['stacktach.ImageDeletes']"}),
'deleted_at': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '6', 'db_index': 'True'}),
'fail_reason': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'owner': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'db_index': 'True'}),
'raw': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': u"orm['stacktach.GlanceRawData']"}),
'send_status': ('django.db.models.fields.IntegerField', [], {'default': '0', 'db_index': 'True'}),
'size': ('django.db.models.fields.BigIntegerField', [], {'max_length': '20'}),
'status': ('django.db.models.fields.CharField', [], {'default': "'pending'", 'max_length': '50', 'db_index': 'True'}),
'usage': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'to': u"orm['stacktach.ImageUsage']"}),
'uuid': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'db_index': 'True'})
},
u'stacktach.imageusage': {
'Meta': {'object_name': 'ImageUsage'},
'created_at': ('django.db.models.fields.DecimalField', [], {'max_digits': '20', 'decimal_places': '6', 'db_index': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'last_raw': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['stacktach.GlanceRawData']", 'null': 'True'}),
'owner': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'db_index': 'True'}),
'size': ('django.db.models.fields.BigIntegerField', [], {'max_length': '20'}),
'uuid': ('django.db.models.fields.CharField', [], {'max_length': '50', 'db_index': 'True'})
},
u'stacktach.instancedeletes': {
'Meta': {'object_name': 'InstanceDeletes'},
'deleted_at': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '6', 'db_index': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'instance': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
'launched_at': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '6', 'db_index': 'True'}),
'raw': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['stacktach.RawData']", 'null': 'True'})
},
u'stacktach.instanceexists': {
'Meta': {'object_name': 'InstanceExists'},
'audit_period_beginning': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '6', 'db_index': 'True'}),
'audit_period_ending': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '6', 'db_index': 'True'}),
'bandwidth_public_out': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}),
'delete': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'to': u"orm['stacktach.InstanceDeletes']"}),
'deleted_at': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '6', 'db_index': 'True'}),
'fail_reason': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '300', 'null': 'True', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'instance': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
'instance_flavor_id': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '100', 'null': 'True', 'blank': 'True'}),
'instance_type_id': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
'launched_at': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '6', 'db_index': 'True'}),
'message_id': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
'os_architecture': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'os_distro': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'os_version': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'raw': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'to': u"orm['stacktach.RawData']"}),
'rax_options': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'send_status': ('django.db.models.fields.IntegerField', [], {'default': '0', 'null': 'True', 'db_index': 'True'}),
'status': ('django.db.models.fields.CharField', [], {'default': "'pending'", 'max_length': '50', 'db_index': 'True'}),
'tenant': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
'usage': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'to': u"orm['stacktach.InstanceUsage']"})
},
u'stacktach.instancereconcile': {
'Meta': {'object_name': 'InstanceReconcile'},
'deleted_at': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '6', 'db_index': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'instance': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
'instance_flavor_id': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '100', 'null': 'True', 'blank': 'True'}),
'instance_type_id': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
'launched_at': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '6', 'db_index': 'True'}),
'os_architecture': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'os_distro': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'os_version': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'rax_options': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'row_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'row_updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'source': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '150', 'null': 'True', 'blank': 'True'}),
'tenant': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'})
},
u'stacktach.instanceusage': {
'Meta': {'object_name': 'InstanceUsage'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'instance': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
'instance_flavor_id': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '100', 'null': 'True', 'blank': 'True'}),
'instance_type_id': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
'launched_at': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '6', 'db_index': 'True'}),
'os_architecture': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'os_distro': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'os_version': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'rax_options': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'request_id': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
'tenant': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'})
},
u'stacktach.jsonreport': {
'Meta': {'object_name': 'JsonReport'},
'created': ('django.db.models.fields.DecimalField', [], {'max_digits': '20', 'decimal_places': '6', 'db_index': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'json': ('django.db.models.fields.TextField', [], {}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'db_index': 'True'}),
'period_end': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}),
'period_start': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}),
'version': ('django.db.models.fields.IntegerField', [], {'default': '1'})
},
u'stacktach.lifecycle': {
'Meta': {'object_name': 'Lifecycle'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'instance': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
'last_raw': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['stacktach.RawData']", 'null': 'True'}),
'last_state': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
'last_task_state': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'})
},
u'stacktach.rawdata': {
'Meta': {'object_name': 'RawData'},
'deployment': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['stacktach.Deployment']"}),
'event': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
'host': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '100', 'null': 'True', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'image_type': ('django.db.models.fields.IntegerField', [], {'default': '0', 'null': 'True', 'db_index': 'True'}),
'instance': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
'json': ('django.db.models.fields.TextField', [], {}),
'old_state': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '20', 'null': 'True', 'blank': 'True'}),
'old_task': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '30', 'null': 'True', 'blank': 'True'}),
'publisher': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '100', 'null': 'True', 'blank': 'True'}),
'request_id': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
'routing_key': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
'service': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
'state': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '20', 'null': 'True', 'blank': 'True'}),
'task': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '30', 'null': 'True', 'blank': 'True'}),
'tenant': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
'when': ('django.db.models.fields.DecimalField', [], {'max_digits': '20', 'decimal_places': '6', 'db_index': 'True'})
},
u'stacktach.rawdataimagemeta': {
'Meta': {'object_name': 'RawDataImageMeta'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'os_architecture': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'os_distro': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'os_version': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'raw': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['stacktach.RawData']"}),
'rax_options': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'})
},
u'stacktach.requesttracker': {
'Meta': {'object_name': 'RequestTracker'},
'completed': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}),
'duration': ('django.db.models.fields.DecimalField', [], {'max_digits': '20', 'decimal_places': '6', 'db_index': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'last_timing': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['stacktach.Timing']", 'null': 'True'}),
'lifecycle': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['stacktach.Lifecycle']"}),
'request_id': ('django.db.models.fields.CharField', [], {'max_length': '50', 'db_index': 'True'}),
'start': ('django.db.models.fields.DecimalField', [], {'max_digits': '20', 'decimal_places': '6', 'db_index': 'True'})
},
u'stacktach.timing': {
'Meta': {'object_name': 'Timing'},
'diff': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '6', 'db_index': 'True'}),
'end_raw': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'to': u"orm['stacktach.RawData']"}),
'end_when': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '6'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'lifecycle': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['stacktach.Lifecycle']"}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'db_index': 'True'}),
'start_raw': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'to': u"orm['stacktach.RawData']"}),
'start_when': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '6'})
}
}
complete_apps = ['stacktach']

View File

@ -165,6 +165,8 @@ class InstanceUsage(models.Model):
null=True,
blank=True,
db_index=True)
instance_flavor_id = models.CharField(max_length=100, null=True,
blank=True, db_index=True)
tenant = models.CharField(max_length=50, null=True, blank=True,
db_index=True)
os_architecture = models.TextField(null=True, blank=True)
@ -227,6 +229,8 @@ class InstanceReconcile(models.Model):
null=True,
blank=True,
db_index=True)
instance_flavor_id = models.CharField(max_length=100, null=True,
blank=True, db_index=True)
tenant = models.CharField(max_length=50, null=True, blank=True,
db_index=True)
os_architecture = models.TextField(null=True, blank=True)
@ -293,6 +297,8 @@ class InstanceExists(models.Model):
os_version = models.TextField(null=True, blank=True)
rax_options = models.TextField(null=True, blank=True)
bandwidth_public_out = models.BigIntegerField(default=0)
instance_flavor_id = models.CharField(max_length=100, null=True,
blank=True, db_index=True)
def deployment(self):
return self.raw.deployment

View File

@ -229,6 +229,7 @@ class NovaNotification(Notification):
self.os_version = image_meta.get('org.openstack__1__os_version', '')
self.rax_options = image_meta.get('com.rackspace__1__options', '')
self.instance_type_id = self.payload.get('instance_type_id', None)
self.instance_flavor_id = self.payload.get('instance_flavor_id', None)
self.new_instance_type_id = \
self.payload.get('new_instance_type_id', None)
self.launched_at = self.payload.get('launched_at', None)

View File

@ -79,6 +79,7 @@ class Reconciler(object):
'launched_at': usage.launched_at,
'deleted_at': deleted_at,
'instance_type_id': usage.instance_type_id,
'instance_flavor_id': usage.instance_flavor_id,
'source': 'reconciler:%s' % src,
'tenant': usage.tenant,
'os_architecture': usage.os_architecture,
@ -93,6 +94,7 @@ class Reconciler(object):
if (exists.launched_at != instance['launched_at'] or
exists.instance_type_id != instance['instance_type_id'] or
exists.instance_flavor_id != instance['instance_flavor_id'] or
exists.tenant != instance['tenant'] or
exists.os_architecture != instance['os_architecture'] or
exists.os_distro != instance['os_distro'] or

View File

@ -4,7 +4,9 @@ from stacktach import utils as stackutils
from stacktach.reconciler import exceptions
from stacktach.reconciler.utils import empty_reconciler_instance
GET_INSTANCE_QUERY = "SELECT * FROM instances where uuid ='%s';"
GET_INSTANCE_QUERY = \
"SELECT i.*, it.flavorid FROM instances i INNER JOIN " \
"instance_types it on i.instance_type_id = it.id where i.uuid ='%s';"
METADATA_MAPPING = {
'image_org.openstack__1__architecture': 'os_architecture',
@ -51,6 +53,7 @@ class JSONBridgeClient(object):
'id': instance['uuid'],
'tenant': instance['project_id'],
'instance_type_id': str(instance['instance_type_id']),
'instance_flavor_id': str(instance['flavorid']),
})
if instance['launched_at'] is not None:

View File

@ -6,6 +6,7 @@ def empty_reconciler_instance():
'deleted': False,
'deleted_at': None,
'instance_type_id': None,
'instance_flavor_id': None,
'os_architecture': '',
'os_distro': '',
'os_version': '',

View File

@ -493,13 +493,15 @@ def do_list_usage_launches(request):
else:
launches = model_search(request, model, None)
results = [["UUID", "Launched At", "Instance Type Id"]]
results = [["UUID", "Launched At", "Instance Type Id",
"Instance Flavor Id"]]
for launch in launches:
launched = None
if launch.launched_at:
launched = str(dt.dt_from_decimal(launch.launched_at))
results.append([launch.instance, launched, launch.instance_type_id])
results.append([launch.instance, launched, launch.instance_type_id,
launch.instance_flavor_id])
return rsp(json.dumps(results))
@ -551,7 +553,7 @@ def do_list_usage_exists(request):
exists = model_search(request, model, None)
results = [["UUID", "Launched At", "Deleted At", "Instance Type Id",
"Message ID", "Status"]]
"Instance Flavor Id", "Message ID", "Status"]]
for exist in exists:
launched = None
@ -561,8 +563,8 @@ def do_list_usage_exists(request):
if exist.deleted_at:
deleted = str(dt.dt_from_decimal(exist.deleted_at))
results.append([exist.instance, launched, deleted,
exist.instance_type_id, exist.message_id,
exist.status])
exist.instance_type_id, exist.instance_flavor_id,
exist.message_id, exist.status])
return rsp(json.dumps(results))

View File

@ -33,150 +33,6 @@ REQUEST_ID_1 = 'testrequestid1'
REQUEST_ID_2 = 'testrequestid2'
REQUEST_ID_3 = 'testrequestid3'
def make_create_start_json(instance_type_id='1',
instance_id=INSTANCE_ID_1,
request_id=REQUEST_ID_1):
notification = ['monitor.info', {
'_context_request_id': request_id,
'event_type': views.INSTANCE_EVENT['create_start'],
'payload': {
'instance_id': instance_id,
'instance_type_id': instance_type_id,
}
}
]
return json.dumps(notification)
def make_create_end_json(launched_at, instance_type_id='1',
instance_id=INSTANCE_ID_1,
request_id=REQUEST_ID_1):
notification = ['monitor.info', {
'_context_request_id': request_id,
'event_type': views.INSTANCE_EVENT['create_end'],
'payload': {
'instance_id': instance_id,
'instance_type_id': instance_type_id,
'launched_at': launched_at
}
}
]
return json.dumps(notification)
def make_delete_end_json(launched_at, deleted_at,
instance_type_id='1', instance_id=INSTANCE_ID_1,
request_id=REQUEST_ID_2):
notification = ['monitor.info', {
'_context_request_id': request_id,
'event_type': views.INSTANCE_EVENT['create_end'],
'payload': {
'instance_id': instance_id,
'instance_type_id': instance_type_id,
'launched_at': launched_at,
'deleted_at': deleted_at
}
}
]
return json.dumps(notification)
def make_exists_json(launched_at, instance_type_id='1',
instance_id=INSTANCE_ID_1, deleted_at=None):
notification = ['monitor.info', {
'message_id': MESSAGE_ID_1,
'event_type': views.INSTANCE_EVENT['create_end'],
'payload': {
'instance_id': instance_id,
'instance_type_id': instance_type_id,
'launched_at': launched_at,
}
}
]
if deleted_at:
notification[1]['payload']['deleted_at'] = deleted_at
return json.dumps(notification)
def make_resize_finish_json(launched_at, instance_type_id='2',
instance_id=INSTANCE_ID_1,
request_id=REQUEST_ID_1):
notification = ['monitor.info', {
'_context_request_id': request_id,
'event_type': views.INSTANCE_EVENT['resize_finish_end'],
'payload': {
'instance_id': instance_id,
'instance_type_id': instance_type_id,
'launched_at': launched_at
}
}
]
return json.dumps(notification)
def make_resize_prep_start_json(instance_type_id='1',
instance_id=INSTANCE_ID_1,
request_id=REQUEST_ID_1):
notification = ['monitor.info', {
'_context_request_id': request_id,
'event_type': views.INSTANCE_EVENT['resize_prep_start'],
'payload': {
'instance_id': instance_id,
'instance_type_id': instance_type_id,
}
}
]
return json.dumps(notification)
def make_resize_prep_end_json(instance_type_id='1',
new_instance_type_id='2',
instance_id=INSTANCE_ID_1,
request_id=REQUEST_ID_1):
notification = ['monitor.info', {
'_context_request_id': request_id,
'event_type': views.INSTANCE_EVENT['resize_prep_start'],
'payload': {
'instance_id': instance_id,
'instance_type_id': instance_type_id,
'new_instance_type_id': new_instance_type_id,
}
}
]
return json.dumps(notification)
def make_resize_revert_start_json(instance_type_id='2',
instance_id=INSTANCE_ID_1,
request_id=REQUEST_ID_1):
notification = ['monitor.info', {
'_context_request_id': request_id,
'event_type': views.INSTANCE_EVENT['resize_revert_start'],
'payload': {
'instance_id': instance_id,
'instance_type_id': instance_type_id,
}
}
]
return json.dumps(notification)
def make_resize_revert_end_json(launched_at, instance_type_id='1',
instance_id=INSTANCE_ID_1,
request_id=REQUEST_ID_1):
notification = ['monitor.info', {
'_context_request_id': request_id,
'event_type': views.INSTANCE_EVENT['resize_finish_end'],
'payload': {
'instance_id': instance_id,
'instance_type_id': instance_type_id,
'launched_at': launched_at
}
}
]
return json.dumps(notification)
def create_raw(deployment, when, event, instance=INSTANCE_ID_1,
request_id=REQUEST_ID_1, state='active', old_task='',

View File

@ -176,6 +176,7 @@ def _process_usage_for_new_launch(raw, notification):
INSTANCE_EVENT['rebuild_start'],
INSTANCE_EVENT['rescue_start']]:
usage.instance_type_id = notification.instance_type_id
usage.instance_flavor_id = notification.instance_flavor_id
if raw.event in [INSTANCE_EVENT['rebuild_start'],
INSTANCE_EVENT['resize_prep_start'],
@ -215,8 +216,10 @@ def _process_usage_for_updates(raw, notification):
if raw.event == INSTANCE_EVENT['resize_revert_end']:
usage.instance_type_id = notification.instance_type_id
usage.instance_flavor_id = notification.instance_flavor_id
elif raw.event == INSTANCE_EVENT['resize_prep_end']:
usage.instance_type_id = notification.new_instance_type_id
usage.instance_flavor_id = notification.instance_flavor_id
usage.tenant = notification.tenant
usage.rax_options = notification.rax_options
@ -262,6 +265,7 @@ def _process_exists(raw, notification):
ending = utils.str_time_to_unix(notification.audit_period_ending)
values['audit_period_ending'] = ending
values['instance_type_id'] = notification.instance_type_id
values['instance_flavor_id'] = notification.instance_flavor_id
if usage:
values['usage'] = usage
values['raw'] = raw

File diff suppressed because it is too large Load Diff

View File

@ -31,7 +31,8 @@ from stacktach.reconciler import nova
from stacktach.reconciler import utils as rec_utils
from tests.unit import StacktachBaseTestCase
from tests.unit import utils
from tests.unit.utils import INSTANCE_ID_1
from tests.unit.utils import INSTANCE_ID_1, INSTANCE_TYPE_ID_1
from tests.unit.utils import INSTANCE_FLAVOR_ID_1
from tests.unit.utils import TENANT_ID_1
region_mapping = {
@ -90,7 +91,8 @@ class ReconcilerTestCase(StacktachBaseTestCase):
usage.instance = INSTANCE_ID_1
launched_at = beginning_d - (60*60)
usage.launched_at = launched_at
usage.instance_type_id = 1
usage.instance_type_id = INSTANCE_TYPE_ID_1
usage.instance_flavor_id = INSTANCE_FLAVOR_ID_1
usage.tenant = TENANT_ID_1
usage.os_architecture = DEFAULT_OS_ARCH
usage.os_distro = DEFAULT_OS_DISTRO
@ -108,7 +110,9 @@ class ReconcilerTestCase(StacktachBaseTestCase):
def _fake_reconciler_instance(self, uuid=INSTANCE_ID_1, launched_at=None,
deleted_at=None, deleted=False,
instance_type_id=1, tenant=TENANT_ID_1,
instance_type_id=INSTANCE_TYPE_ID_1,
instance_flavor_id=INSTANCE_FLAVOR_ID_1,
tenant=TENANT_ID_1,
os_arch=DEFAULT_OS_ARCH,
os_distro=DEFAULT_OS_DISTRO,
os_verison=DEFAULT_OS_VERSION,
@ -120,6 +124,7 @@ class ReconcilerTestCase(StacktachBaseTestCase):
'deleted_at': deleted_at,
'deleted': deleted,
'instance_type_id': instance_type_id,
'instance_flavor_id': instance_flavor_id,
'tenant': tenant,
'os_architecture': os_arch,
'os_distro': os_distro,
@ -194,6 +199,7 @@ class ReconcilerTestCase(StacktachBaseTestCase):
'launched_at': launch.launched_at,
'deleted_at': deleted_at,
'instance_type_id': launch.instance_type_id,
'instance_flavor_id': launch.instance_flavor_id,
'source': 'reconciler:mocked_client',
'tenant': TENANT_ID_1,
'os_architecture': DEFAULT_OS_ARCH,
@ -216,7 +222,7 @@ class ReconcilerTestCase(StacktachBaseTestCase):
launch = self.mox.CreateMockAnything()
launch.instance = INSTANCE_ID_1
launch.launched_at = beginning_d - (60*60)
launch.instance_type_id = 1
launch.instance_flavor_id = INSTANCE_FLAVOR_ID_1
models.InstanceUsage.objects.get(id=launch_id).AndReturn(launch)
deployment = self.mox.CreateMockAnything()
launch.deployment().AndReturn(deployment)
@ -233,9 +239,9 @@ class ReconcilerTestCase(StacktachBaseTestCase):
launch_id = 1
beginning_d = utils.decimal_utc()
launch = self.mox.CreateMockAnything()
launch.instance = INSTANCE_ID_1
launch.instance = INSTANCE_FLAVOR_ID_1
launch.launched_at = beginning_d - (60*60)
launch.instance_type_id = 1
launch.instance_flavor_id = 1
models.InstanceUsage.objects.get(id=launch_id).AndReturn(launch)
launch.deployment().AndReturn(None)
self.mox.ReplayAll()
@ -255,6 +261,7 @@ class ReconcilerTestCase(StacktachBaseTestCase):
'launched_at': exists.launched_at,
'deleted_at': exists.deleted_at,
'instance_type_id': exists.instance_type_id,
'instance_flavor_id': exists.instance_flavor_id,
'source': 'reconciler:mocked_client',
'tenant': TENANT_ID_1,
'os_architecture': DEFAULT_OS_ARCH,
@ -285,6 +292,7 @@ class ReconcilerTestCase(StacktachBaseTestCase):
'launched_at': exists.launched_at,
'deleted_at': exists.deleted_at,
'instance_type_id': exists.instance_type_id,
'instance_flavor_id': exists.instance_flavor_id,
'source': 'reconciler:mocked_client',
'tenant': TENANT_ID_1,
'os_architecture': DEFAULT_OS_ARCH,
@ -306,7 +314,7 @@ class ReconcilerTestCase(StacktachBaseTestCase):
exists.instance = INSTANCE_ID_1
launched_at = beginning_d - (60*60)
exists.launched_at = launched_at
exists.instance_type_id = 1
exists.instance_flavor_id = INSTANCE_FLAVOR_ID_1
exists.deleted_at = beginning_d
deployment = self.mox.CreateMockAnything()
exists.deployment().AndReturn(deployment)
@ -327,7 +335,7 @@ class ReconcilerTestCase(StacktachBaseTestCase):
exists.instance = INSTANCE_ID_1
launched_at = beginning_d - (60*60)
exists.launched_at = launched_at
exists.instance_type_id = 1
exists.instance_flavor_id = INSTANCE_FLAVOR_ID_1
exists.deleted_at = beginning_d
deployment = self.mox.CreateMockAnything()
exists.deployment().AndReturn(deployment)
@ -346,7 +354,7 @@ class ReconcilerTestCase(StacktachBaseTestCase):
exists.instance = INSTANCE_ID_1
launched_at = beginning_d - (60*60)
exists.launched_at = launched_at
exists.instance_type_id = 1
exists.instance_flavor_id = INSTANCE_FLAVOR_ID_1
exists.deleted_at = None
deployment = self.mox.CreateMockAnything()
exists.deployment().AndReturn(deployment)
@ -365,7 +373,7 @@ class ReconcilerTestCase(StacktachBaseTestCase):
exists.instance = INSTANCE_ID_1
launched_at = beginning_d - (60*60)
exists.launched_at = launched_at
exists.instance_type_id = 1
exists.instance_flavor_id = INSTANCE_FLAVOR_ID_1
exists.deleted_at = None
exists.deployment().AndReturn(None)
ex = exceptions.NotFound()
@ -465,14 +473,17 @@ class NovaJSONBridgeClientTestCase(StacktachBaseTestCase):
response.json().AndReturn(result)
def _fake_instance(self, uuid=INSTANCE_ID_1, launched_at=None,
terminated_at=None, deleted=0, instance_type_id=1,
project_id=TENANT_ID_1):
terminated_at=None, deleted=0,
instance_type_id=INSTANCE_TYPE_ID_1,
instance_flavor_id=INSTANCE_FLAVOR_ID_1,
project_id=TENANT_ID_1):
return {
'uuid': uuid,
'launched_at': launched_at,
'terminated_at': terminated_at,
'deleted': deleted,
'instance_type_id': instance_type_id,
'flavorid': instance_flavor_id,
'project_id': project_id
}
@ -488,8 +499,9 @@ class NovaJSONBridgeClientTestCase(StacktachBaseTestCase):
self.mox.ReplayAll()
instance = self.client.get_instance('RegionOne', INSTANCE_ID_1)
self.assertIsNotNone(instance)
self.assertEqual(instance['id'], INSTANCE_ID_1)
self.assertEqual(instance['instance_type_id'], '1')
self.assertEqual(instance['id'], INSTANCE_ID_1 )
self.assertEqual(instance['instance_type_id'], INSTANCE_TYPE_ID_1)
self.assertEqual(instance['instance_flavor_id'], INSTANCE_FLAVOR_ID_1)
launched_at_dec = stackutils.str_time_to_unix(launched_at)
self.assertEqual(instance['launched_at'], launched_at_dec)
terminated_at_dec = stackutils.str_time_to_unix(terminated_at)
@ -528,7 +540,7 @@ class NovaJSONBridgeClientTestCase(StacktachBaseTestCase):
get_metadata=True)
self.assertIsNotNone(instance)
self.assertEqual(instance['id'], INSTANCE_ID_1)
self.assertEqual(instance['instance_type_id'], '1')
self.assertEqual(instance['instance_flavor_id'], INSTANCE_FLAVOR_ID_1)
launched_at_dec = stackutils.str_time_to_unix(launched_at)
self.assertEqual(instance['launched_at'], launched_at_dec)
terminated_at_dec = stackutils.str_time_to_unix(terminated_at)

View File

@ -25,6 +25,7 @@ import mox
import utils
from utils import BANDWIDTH_PUBLIC_OUTBOUND
from utils import INSTANCE_FLAVOR_ID_1
from utils import INSTANCE_ID_1
from utils import OS_VERSION_1
from utils import OS_ARCH_1
@ -309,7 +310,7 @@ class StacktachUsageParsingTestCase(StacktachBaseTestCase):
msg = "'%s' does not have a process function mapping." % value
self.assertTrue(value in views.USAGE_PROCESS_MAPPING, msg)
def test_process_usage_for_new_launch_create_start(self):
def _create_mock_notification(self):
notification = self.mox.CreateMockAnything()
notification.launched_at = str(DUMMY_TIME)
notification.tenant = TENANT_ID_1
@ -320,6 +321,11 @@ class StacktachUsageParsingTestCase(StacktachBaseTestCase):
notification.instance = INSTANCE_ID_1
notification.request_id = REQUEST_ID_1
notification.instance_type_id = INSTANCE_TYPE_ID_1
return notification
def test_process_usage_for_new_launch_create_start(self):
notification = self._create_mock_notification()
notification.instance_flavor_id = INSTANCE_FLAVOR_ID_1
raw = self.mox.CreateMockAnything()
raw.event = 'compute.instance.create.start'
@ -339,20 +345,12 @@ class StacktachUsageParsingTestCase(StacktachBaseTestCase):
self.assertEquals(usage.os_version, OS_VERSION_1)
self.assertEquals(usage.os_distro, OS_DISTRO_1)
self.assertEquals(usage.rax_options, RAX_OPTIONS_1)
self.assertEquals(usage.instance_flavor_id, INSTANCE_FLAVOR_ID_1)
self.mox.VerifyAll()
def test_process_usage_for_new_launch_rescue_start(self):
notification = self.mox.CreateMockAnything()
notification.launched_at = str(DUMMY_TIME)
notification.tenant = TENANT_ID_1
notification.rax_options = RAX_OPTIONS_1
notification.os_architecture = OS_ARCH_1
notification.os_version = OS_VERSION_1
notification.os_distro = OS_DISTRO_1
notification.instance = INSTANCE_ID_1
notification.request_id = REQUEST_ID_1
notification.instance_type_id = INSTANCE_TYPE_ID_1
notification = self._create_mock_notification()
raw = self.mox.CreateMockAnything()
raw.event = 'compute.instance.rescue.start'
@ -376,17 +374,8 @@ class StacktachUsageParsingTestCase(StacktachBaseTestCase):
self.mox.VerifyAll()
def test_process_usage_for_new_launch_rebuild_start(self):
notification = self.mox.CreateMockAnything()
notification.launched_at = str(DUMMY_TIME)
notification.tenant = TENANT_ID_1
notification.rax_options = RAX_OPTIONS_1
notification.os_architecture = OS_ARCH_1
notification.os_version = OS_VERSION_1
notification.os_distro = OS_DISTRO_1
notification.instance = INSTANCE_ID_1
notification.request_id = REQUEST_ID_1
notification.instance_type_id = INSTANCE_TYPE_ID_1
notification = self._create_mock_notification()
notification.instance_flavor_id = INSTANCE_FLAVOR_ID_1
raw = self.mox.CreateMockAnything()
raw.event = 'compute.instance.rebuild.start'
usage = self.mox.CreateMockAnything()
@ -404,20 +393,12 @@ class StacktachUsageParsingTestCase(StacktachBaseTestCase):
self.assertEquals(usage.os_version, OS_VERSION_1)
self.assertEquals(usage.os_distro, OS_DISTRO_1)
self.assertEquals(usage.rax_options, RAX_OPTIONS_1)
self.assertEquals(usage.instance_flavor_id, INSTANCE_FLAVOR_ID_1)
self.mox.VerifyAll()
def test_process_usage_for_new_launch_rebuild_start_when_no_launched_at_in_db(self):
notification = self.mox.CreateMockAnything()
notification.launched_at = str(DUMMY_TIME)
notification.tenant = TENANT_ID_1
notification.rax_options = RAX_OPTIONS_1
notification.os_architecture = OS_ARCH_1
notification.os_version = OS_VERSION_1
notification.os_distro = OS_DISTRO_1
notification.instance = INSTANCE_ID_1
notification.request_id = REQUEST_ID_1
notification.instance_type_id = INSTANCE_TYPE_ID_1
notification = self._create_mock_notification()
notification.instance_flavor_id = INSTANCE_FLAVOR_ID_1
raw = self.mox.CreateMockAnything()
raw.event = 'compute.instance.rebuild.start'
@ -437,21 +418,12 @@ class StacktachUsageParsingTestCase(StacktachBaseTestCase):
self.assertEquals(usage.os_version, OS_VERSION_1)
self.assertEquals(usage.os_distro, OS_DISTRO_1)
self.assertEquals(usage.rax_options, RAX_OPTIONS_1)
self.assertEquals(usage.instance_flavor_id, INSTANCE_FLAVOR_ID_1)
self.mox.VerifyAll()
def test_process_usage_for_new_launch_resize_prep_start_when_no_launched_at_in_db(self):
notification = self.mox.CreateMockAnything()
notification.launched_at = str(DUMMY_TIME)
notification.tenant = TENANT_ID_1
notification.rax_options = RAX_OPTIONS_1
notification.os_architecture = OS_ARCH_1
notification.os_version = OS_VERSION_1
notification.os_distro = OS_DISTRO_1
notification.instance = INSTANCE_ID_1
notification.request_id = REQUEST_ID_1
notification.instance_type_id = INSTANCE_TYPE_ID_1
notification = self._create_mock_notification()
raw = self.mox.CreateMockAnything()
raw.event = 'compute.instance.resize.prep.start'
@ -477,17 +449,7 @@ class StacktachUsageParsingTestCase(StacktachBaseTestCase):
self.mox.VerifyAll()
def test_process_usage_for_new_launch_resize_revert_start_when_no_launched_at_in_db(self):
notification = self.mox.CreateMockAnything()
notification.launched_at = str(DUMMY_TIME)
notification.tenant = TENANT_ID_1
notification.rax_options = RAX_OPTIONS_1
notification.os_architecture = OS_ARCH_1
notification.os_version = OS_VERSION_1
notification.os_distro = OS_DISTRO_1
notification.instance = INSTANCE_ID_1
notification.request_id = REQUEST_ID_1
notification.instance_type_id = INSTANCE_TYPE_ID_1
notification = self._create_mock_notification()
raw = self.mox.CreateMockAnything()
raw.event = 'compute.instance.resize.revert.start'
@ -511,17 +473,7 @@ class StacktachUsageParsingTestCase(StacktachBaseTestCase):
self.mox.VerifyAll()
def test_process_usage_for_new_launch_resize_prep_start_when_launched_at_in_db(self):
notification = self.mox.CreateMockAnything()
notification.launched_at = str(DUMMY_TIME)
notification.tenant = TENANT_ID_1
notification.rax_options = RAX_OPTIONS_1
notification.os_architecture = OS_ARCH_1
notification.os_version = OS_VERSION_1
notification.os_distro = OS_DISTRO_1
notification.instance = INSTANCE_ID_1
notification.request_id = REQUEST_ID_1
notification.instance_type_id = INSTANCE_TYPE_ID_1
notification = self._create_mock_notification()
raw = self.mox.CreateMockAnything()
raw.event = 'compute.instance.resize.prep.start'
@ -546,17 +498,7 @@ class StacktachUsageParsingTestCase(StacktachBaseTestCase):
self.mox.VerifyAll()
def test_process_usage_for_new_launch_rescue_start_when_launched_at_in_db(self):
notification = self.mox.CreateMockAnything()
notification.launched_at = str(DUMMY_TIME)
notification.tenant = TENANT_ID_1
notification.rax_options = RAX_OPTIONS_1
notification.os_architecture = OS_ARCH_1
notification.os_version = OS_VERSION_1
notification.os_distro = OS_DISTRO_1
notification.instance = INSTANCE_ID_1
notification.request_id = REQUEST_ID_1
notification.instance_type_id = INSTANCE_TYPE_ID_1
notification = self._create_mock_notification()
raw = self.mox.CreateMockAnything()
raw.event = 'compute.instance.rescue.start'
@ -581,18 +523,8 @@ class StacktachUsageParsingTestCase(StacktachBaseTestCase):
self.mox.VerifyAll()
def test_process_usage_for_updates_create_end(self):
notification = self.mox.CreateMockAnything()
notification.launched_at = str(DUMMY_TIME)
notification.tenant = TENANT_ID_1
notification.rax_options = RAX_OPTIONS_1
notification.os_architecture = OS_ARCH_1
notification.os_version = OS_VERSION_1
notification.os_distro = OS_DISTRO_1
notification.instance = INSTANCE_ID_1
notification.request_id = REQUEST_ID_1
notification.instance_type_id = INSTANCE_TYPE_ID_1
notification.message = None
notification = self._create_mock_notification()
notification.message = 'Success'
raw = self.mox.CreateMockAnything()
raw.event = 'compute.instance.create.end'
@ -616,18 +548,7 @@ class StacktachUsageParsingTestCase(StacktachBaseTestCase):
self.mox.VerifyAll()
def test_process_usage_for_updates_rescue_end(self):
notification = self.mox.CreateMockAnything()
notification.launched_at = str(DUMMY_TIME)
notification.tenant = TENANT_ID_1
notification.rax_options = RAX_OPTIONS_1
notification.os_architecture = OS_ARCH_1
notification.os_version = OS_VERSION_1
notification.os_distro = OS_DISTRO_1
notification.instance = INSTANCE_ID_1
notification.request_id = REQUEST_ID_1
notification.instance_type_id = INSTANCE_TYPE_ID_1
notification.message = None
notification = self._create_mock_notification()
raw = self.mox.CreateMockAnything()
raw.event = 'compute.instance.rescue.end'
@ -651,18 +572,8 @@ class StacktachUsageParsingTestCase(StacktachBaseTestCase):
self.mox.VerifyAll()
def test_process_usage_for_updates_create_end_success_message(self):
notification = self.mox.CreateMockAnything()
notification.launched_at = str(DUMMY_TIME)
notification.tenant = TENANT_ID_1
notification.rax_options = RAX_OPTIONS_1
notification.os_architecture = OS_ARCH_1
notification.os_version = OS_VERSION_1
notification.os_distro = OS_DISTRO_1
notification.instance = INSTANCE_ID_1
notification.request_id = REQUEST_ID_1
notification.instance_type_id = INSTANCE_TYPE_ID_1
notification = self._create_mock_notification()
notification.message = 'Success'
raw = self.mox.CreateMockAnything()
raw.event = 'compute.instance.create.end'
@ -675,7 +586,6 @@ class StacktachUsageParsingTestCase(StacktachBaseTestCase):
self.mox.ReplayAll()
views._process_usage_for_updates(raw, notification)
self.assertEqual(usage.launched_at, utils.decimal_utc(DUMMY_TIME))
self.assertEqual(usage.tenant, TENANT_ID_1)
self.assertEquals(usage.os_architecture, OS_ARCH_1)
@ -698,18 +608,7 @@ class StacktachUsageParsingTestCase(StacktachBaseTestCase):
self.mox.VerifyAll()
def test_process_usage_for_updates_revert_end(self):
notification = self.mox.CreateMockAnything()
notification.launched_at = str(DUMMY_TIME)
notification.tenant = TENANT_ID_1
notification.rax_options = RAX_OPTIONS_1
notification.os_architecture = OS_ARCH_1
notification.os_version = OS_VERSION_1
notification.os_distro = OS_DISTRO_1
notification.instance = INSTANCE_ID_1
notification.request_id = REQUEST_ID_1
notification.instance_type_id = INSTANCE_TYPE_ID_1
notification.message = None
notification = self._create_mock_notification()
raw = self.mox.CreateMockAnything()
raw.event = 'compute.instance.resize.revert.end'
@ -733,19 +632,13 @@ class StacktachUsageParsingTestCase(StacktachBaseTestCase):
self.mox.VerifyAll()
def test_process_usage_for_updates_prep_end(self):
notification = self.mox.CreateMockAnything()
notification.launched_at = str(DUMMY_TIME)
notification.tenant = TENANT_ID_1
notification.rax_options = RAX_OPTIONS_1
notification.os_architecture = OS_ARCH_1
notification.os_version = OS_VERSION_1
notification.os_distro = OS_DISTRO_1
notification.instance = INSTANCE_ID_1
notification.request_id = REQUEST_ID_1
def _create_notification_with_new_instance_type_id(self):
notification = self._create_mock_notification()
notification.new_instance_type_id = INSTANCE_TYPE_ID_2
notification.message = None
return notification
def test_process_usage_for_updates_prep_end(self):
notification = self._create_notification_with_new_instance_type_id()
raw = self.mox.CreateMockAnything()
raw.event = 'compute.instance.resize.prep.end'
@ -821,15 +714,11 @@ class StacktachUsageParsingTestCase(StacktachBaseTestCase):
self.assertEqual(delete.deleted_at, delete_decimal)
self.mox.VerifyAll()
def test_process_exists(self):
def _create_exists_notification(self, audit_beginning, current_time,
launch_time, deleted_time):
notification = self.mox.CreateMockAnything()
current_time = datetime.datetime.utcnow()
launch_time = current_time - datetime.timedelta(hours=23)
launch_decimal = utils.decimal_utc(launch_time)
audit_beginning = current_time - datetime.timedelta(hours=20)
audit_beginning_decimal = utils.decimal_utc(audit_beginning)
audit_ending_decimal = utils.decimal_utc(current_time)
notification.launched_at = str(launch_time)
notification.deleted_at = str(deleted_time)
notification.audit_period_beginning = str(audit_beginning)
notification.audit_period_ending = str(current_time)
notification.tenant = TENANT_ID_1
@ -838,16 +727,27 @@ class StacktachUsageParsingTestCase(StacktachBaseTestCase):
notification.os_distro = OS_DISTRO_1
notification.rax_options = RAX_OPTIONS_1
notification.instance = INSTANCE_ID_1
notification.deleted_at = ''
notification.instance_type_id = INSTANCE_TYPE_ID_1
notification.instance_flavor_id = INSTANCE_FLAVOR_ID_1
notification.message_id = MESSAGE_ID_1
notification.bandwidth_public_out = BANDWIDTH_PUBLIC_OUTBOUND
return notification
def test_process_exists(self):
current_time = datetime.datetime.utcnow()
launch_time = current_time - datetime.timedelta(hours=23)
launch_decimal = utils.decimal_utc(launch_time)
audit_beginning = current_time - datetime.timedelta(hours=20)
audit_beginning_decimal = utils.decimal_utc(audit_beginning)
audit_ending_decimal = utils.decimal_utc(current_time)
notification = self._create_exists_notification(
audit_beginning, current_time, launch_time, deleted_time='')
raw = self.mox.CreateMockAnything()
usage = self.mox.CreateMockAnything()
launched_range = (launch_decimal, launch_decimal+1)
views.STACKDB.get_instance_usage(instance=INSTANCE_ID_1,
launched_at__range=launched_range)\
.AndReturn(usage)
views.STACKDB.get_instance_usage(
instance=INSTANCE_ID_1,
launched_at__range=launched_range).AndReturn(usage)
exists_values = {
'message_id': MESSAGE_ID_1,
'instance': INSTANCE_ID_1,
@ -855,6 +755,7 @@ class StacktachUsageParsingTestCase(StacktachBaseTestCase):
'audit_period_beginning': audit_beginning_decimal,
'audit_period_ending': audit_ending_decimal,
'instance_type_id': INSTANCE_TYPE_ID_1,
'instance_flavor_id': INSTANCE_FLAVOR_ID_1,
'usage': usage,
'raw': raw,
'tenant': TENANT_ID_1,
@ -884,7 +785,6 @@ class StacktachUsageParsingTestCase(StacktachBaseTestCase):
self.mox.VerifyAll()
def test_process_exists_with_deleted_at(self):
notification = self.mox.CreateMockAnything()
current_time = datetime.datetime.utcnow()
launch_time = current_time - datetime.timedelta(hours=23)
launch_decimal = utils.decimal_utc(launch_time)
@ -893,20 +793,8 @@ class StacktachUsageParsingTestCase(StacktachBaseTestCase):
audit_beginning = current_time - datetime.timedelta(hours=20)
audit_beginning_decimal = utils.decimal_utc(audit_beginning)
audit_ending_decimal = utils.decimal_utc(current_time)
notification.launched_at = str(launch_time)
notification.audit_period_beginning = str(audit_beginning)
notification.audit_period_ending = str(current_time)
notification.tenant = TENANT_ID_1
notification.os_architecture = OS_ARCH_1
notification.os_version = OS_VERSION_1
notification.os_distro = OS_DISTRO_1
notification.rax_options = RAX_OPTIONS_1
notification.instance = INSTANCE_ID_1
notification.instance_type_id = INSTANCE_TYPE_ID_1
notification.message_id = MESSAGE_ID_1
notification.deleted_at = str(delete_time)
notification.bandwidth_public_out = BANDWIDTH_PUBLIC_OUTBOUND
notification = self._create_exists_notification(
audit_beginning, current_time, launch_time, delete_time)
raw = self.mox.CreateMockAnything()
usage = self.mox.CreateMockAnything()
launched_range = (launch_decimal, launch_decimal+1)
@ -925,6 +813,7 @@ class StacktachUsageParsingTestCase(StacktachBaseTestCase):
'audit_period_beginning': audit_beginning_decimal,
'audit_period_ending': audit_ending_decimal,
'instance_type_id': INSTANCE_TYPE_ID_1,
'instance_flavor_id': INSTANCE_FLAVOR_ID_1,
'usage': usage,
'delete': delete,
'raw': raw,

View File

@ -29,7 +29,8 @@ from stacktach import datetime_to_decimal as dt
from stacktach import models
from stacktach import stacky_server
import utils
from utils import INSTANCE_ID_1
from utils import INSTANCE_ID_1, INSTANCE_TYPE_ID_1
from utils import INSTANCE_FLAVOR_ID_1
from utils import INSTANCE_ID_2
from utils import REQUEST_ID_1
@ -1062,7 +1063,8 @@ class StackyServerTestCase(StacktachBaseTestCase):
usage = self.mox.CreateMockAnything()
usage.instance = INSTANCE_ID_1
usage.launched_at = utils.decimal_utc()
usage.instance_type_id = 1
usage.instance_type_id = INSTANCE_TYPE_ID_1
usage.instance_flavor_id = INSTANCE_FLAVOR_ID_1
results[None:50].AndReturn(results)
results.__iter__().AndReturn([usage].__iter__())
self.mox.ReplayAll()
@ -1072,11 +1074,13 @@ class StackyServerTestCase(StacktachBaseTestCase):
resp_json = json.loads(resp.content)
self.assertEqual(len(resp_json), 2)
self.assertEqual(resp_json[0], ["UUID", "Launched At",
"Instance Type Id"])
"Instance Type Id",
"Instance Flavor Id"])
self.assertEqual(resp_json[1][0], INSTANCE_ID_1)
time_str = dt.dt_from_decimal(usage.launched_at)
self.assertEqual(resp_json[1][1], str(time_str))
self.assertEqual(resp_json[1][2], 1)
self.assertEqual(resp_json[1][2], INSTANCE_TYPE_ID_1)
self.assertEqual(resp_json[1][3], INSTANCE_FLAVOR_ID_1)
self.mox.VerifyAll()
@ -1089,7 +1093,8 @@ class StackyServerTestCase(StacktachBaseTestCase):
usage = self.mox.CreateMockAnything()
usage.instance = INSTANCE_ID_1
usage.launched_at = utils.decimal_utc()
usage.instance_type_id = 1
usage.instance_type_id = INSTANCE_TYPE_ID_1
usage.instance_flavor_id = INSTANCE_FLAVOR_ID_1
results[None:50].AndReturn(results)
results.__iter__().AndReturn([usage].__iter__())
self.mox.ReplayAll()
@ -1099,11 +1104,13 @@ class StackyServerTestCase(StacktachBaseTestCase):
resp_json = json.loads(resp.content)
self.assertEqual(len(resp_json), 2)
self.assertEqual(resp_json[0], ["UUID", "Launched At",
"Instance Type Id"])
"Instance Type Id",
"Instance Flavor Id"])
self.assertEqual(resp_json[1][0], INSTANCE_ID_1)
time_str = dt.dt_from_decimal(usage.launched_at)
self.assertEqual(resp_json[1][1], str(time_str))
self.assertEqual(resp_json[1][2], 1)
self.assertEqual(resp_json[1][2], INSTANCE_TYPE_ID_1)
self.assertEqual(resp_json[1][3], INSTANCE_FLAVOR_ID_1)
self.mox.VerifyAll()
@ -1199,7 +1206,8 @@ class StackyServerTestCase(StacktachBaseTestCase):
usage.instance = INSTANCE_ID_1
usage.launched_at = utils.decimal_utc()
usage.deleted_at = usage.launched_at + 10
usage.instance_type_id = 1
usage.instance_type_id = INSTANCE_TYPE_ID_1
usage.instance_flavor_id = INSTANCE_FLAVOR_ID_1
usage.message_id = 'someid'
usage.status = 'pending'
results[None:50].AndReturn(results)
@ -1211,13 +1219,18 @@ class StackyServerTestCase(StacktachBaseTestCase):
resp_json = json.loads(resp.content)
self.assertEqual(len(resp_json), 2)
self.assertEqual(resp_json[0], ["UUID", "Launched At", "Deleted At",
"Instance Type Id", "Message ID",
"Instance Type Id",
"Instance Flavor Id", "Message ID",
"Status"])
self.assertEqual(resp_json[1][0], INSTANCE_ID_1)
launch_time_str = dt.dt_from_decimal(usage.launched_at)
self.assertEqual(resp_json[1][1], str(launch_time_str))
delete_time_str = dt.dt_from_decimal(usage.deleted_at)
self.assertEqual(resp_json[1][2], str(delete_time_str))
self.assertEqual(resp_json[1][3], INSTANCE_TYPE_ID_1)
self.assertEqual(resp_json[1][4], INSTANCE_FLAVOR_ID_1)
self.assertEqual(resp_json[1][5], 'someid')
self.assertEqual(resp_json[1][6], 'pending')
self.mox.VerifyAll()
def test_do_list_usage_exists_with_instance(self):
@ -1230,7 +1243,8 @@ class StackyServerTestCase(StacktachBaseTestCase):
usage.instance = INSTANCE_ID_1
usage.launched_at = utils.decimal_utc()
usage.deleted_at = usage.launched_at + 10
usage.instance_type_id = 1
usage.instance_type_id = INSTANCE_TYPE_ID_1
usage.instance_flavor_id = INSTANCE_FLAVOR_ID_1
usage.message_id = 'someid'
usage.status = 'pending'
results[None:50].AndReturn(results)
@ -1242,13 +1256,18 @@ class StackyServerTestCase(StacktachBaseTestCase):
resp_json = json.loads(resp.content)
self.assertEqual(len(resp_json), 2)
self.assertEqual(resp_json[0], ["UUID", "Launched At", "Deleted At",
"Instance Type Id", "Message ID",
"Instance Type Id",
"Instance Flavor Id", "Message ID",
"Status"])
self.assertEqual(resp_json[1][0], INSTANCE_ID_1)
launch_time_str = dt.dt_from_decimal(usage.launched_at)
self.assertEqual(resp_json[1][1], str(launch_time_str))
delete_time_str = dt.dt_from_decimal(usage.deleted_at)
self.assertEqual(resp_json[1][2], str(delete_time_str))
self.assertEqual(resp_json[1][3], INSTANCE_TYPE_ID_1)
self.assertEqual(resp_json[1][4], INSTANCE_FLAVOR_ID_1)
self.assertEqual(resp_json[1][5], 'someid')
self.assertEqual(resp_json[1][6], 'pending')
self.mox.VerifyAll()
def test_do_list_usage_exists_bad_instance(self):

View File

@ -30,6 +30,9 @@ IMAGE_UUID_1 = "12345678-6352-4dbc-8271-96cc54bf14cd"
INSTANCE_ID_1 = "08f685d9-6352-4dbc-8271-96cc54bf14cd"
INSTANCE_ID_2 = "515adf96-41d3-b86d-5467-e584edc61dab"
INSTANCE_FLAVOR_ID_1 = "performance1-120"
INSTANCE_FLAVOR_ID_2 = "performance2-120"
INSTANCE_TYPE_ID_1 = "12345"
INSTANCE_TYPE_ID_2 = '54321'
@ -68,7 +71,7 @@ USERID = 'rabbit'
PASSWORD = 'password'
NOVA_VERIFIER_EVENT_TYPE = 'compute.instance.exists.verified.old'
GLANCE_VERIFIER_EVENT_TYPE = 'image.exists.verified.old'
FLAVOR_FIELD_NAME = 'flavor_field_name'
def decimal_utc(t = datetime.datetime.utcnow()):
return dt.dt_to_decimal(t)
@ -156,7 +159,7 @@ def create_tracker(mox, request_id, lifecycle, start, last_timing=None,
class FakeVerifierConfig(object):
def __init__(self, host, port, virtual_host, userid, password, tick_time,
settle_time, settle_units, durable_queue, topics, notifs,
nova_event_type, glance_event_type):
nova_event_type, glance_event_type, flavor_field_name):
self.host = lambda: host
self.port = lambda: port
self.virtual_host = lambda: virtual_host
@ -172,6 +175,7 @@ class FakeVerifierConfig(object):
self.validation_level = lambda: 'all'
self.nova_event_type = lambda: nova_event_type
self.glance_event_type = lambda: glance_event_type
self.flavor_field_name = lambda: flavor_field_name
def make_verifier_config(notifs):
@ -180,5 +184,6 @@ def make_verifier_config(notifs):
PASSWORD, TICK_TIME, SETTLE_TIME,
SETTLE_UNITS, True, topics, notifs,
NOVA_VERIFIER_EVENT_TYPE,
GLANCE_VERIFIER_EVENT_TYPE)
GLANCE_VERIFIER_EVENT_TYPE,
FLAVOR_FIELD_NAME)
return config

View File

@ -29,8 +29,12 @@ except ImportError:
pass
config = None
with open(config_filename, "r") as f:
config = json.load(f)
def load():
global config
with open(config_filename, "r") as f:
config = json.load(f)
def enable_notifications():
@ -99,3 +103,7 @@ def nova_event_type():
def glance_event_type():
return config.get('glance_event_type', 'image.exists.verified.old')
def flavor_field_name():
return config['flavor_field_name']

View File

@ -31,6 +31,7 @@ if os.path.exists(os.path.join(POSSIBLE_TOPDIR, 'stacktach')):
sys.path.insert(0, POSSIBLE_TOPDIR)
from verifier import base_verifier
from verifier import config
from verifier import NullFieldException
from stacktach import models
from stacktach import datetime_to_decimal as dt
@ -43,14 +44,17 @@ LOG = stacklog.get_logger('verifier')
def _verify_field_mismatch(exists, launch):
flavor_field_name = config.flavor_field_name()
if not base_verifier._verify_date_field(
launch.launched_at, exists.launched_at, same_second=True):
raise FieldMismatch('launched_at', exists.launched_at,
launch.launched_at)
if launch.instance_type_id != exists.instance_type_id:
raise FieldMismatch('instance_type_id', exists.instance_type_id,
launch.instance_type_id)
if getattr(launch, flavor_field_name) != \
getattr(exists, flavor_field_name):
raise FieldMismatch(flavor_field_name,
getattr(exists, flavor_field_name),
getattr(launch, flavor_field_name))
if launch.tenant != exists.tenant:
raise FieldMismatch('tenant', exists.tenant,
@ -146,10 +150,13 @@ def _verify_for_delete(exist, delete=None,
def _verify_basic_validity(exist):
fields = {exist.tenant: 'tenant',
exist.launched_at: 'launched_at',
exist.instance_type_id: 'instance_type_id'}
for (field_value, field_name) in fields.items():
flavor_field_name = config.flavor_field_name()
fields = {
'tenant': exist.tenant,
'launched_at': exist.launched_at,
flavor_field_name: getattr(exist, flavor_field_name)
}
for (field_name, field_value) in fields.items():
if field_value is None:
raise NullFieldException(field_name, exist.id)
base_verifier._is_hex_owner_id('tenant', exist.tenant, exist.id)
@ -242,7 +249,6 @@ def _verify(exist, validation_level):
try:
if not exist.launched_at:
raise VerificationException("Exists without a launched_at")
_verify_validity(exist, validation_level)
_verify_for_launch(exist)
_verify_for_delete(exist)

View File

@ -80,6 +80,7 @@ if __name__ == '__main__':
verifier.run()
verifier_config.load()
for exchange in verifier_config.topics().keys():
process = Process(target=make_and_start_verifier, args=(exchange,))
process.start()