From f125432d77fea6e302da11dea2cbf089b0b86d79 Mon Sep 17 00:00:00 2001 From: Pawel Brzozowski Date: Fri, 6 Feb 2015 19:49:39 +0100 Subject: [PATCH] Added created field to all of the objects - added --timestamps switch to list command DocImpact: stackforge/fuel-devops - New switch required for job cleaner to work, this is required to fully track object creation time, adds switch --timestamps to shell command, no policy modifications. Partial-Bug: #1415024 Change-Id: I98529b08dd42a34be94046e9a2706fcf6a18c2da --- devops/migrations/0002_add_field_created.py | 185 ++++++++++++++++++++ devops/models/base.py | 3 + devops/shell.py | 12 +- 3 files changed, 198 insertions(+), 2 deletions(-) create mode 100644 devops/migrations/0002_add_field_created.py diff --git a/devops/migrations/0002_add_field_created.py b/devops/migrations/0002_add_field_created.py new file mode 100644 index 00000000..87557f7e --- /dev/null +++ b/devops/migrations/0002_add_field_created.py @@ -0,0 +1,185 @@ +# -*- coding: utf-8 -*- +# flake8: noqa +from south.utils import datetime_utils as datetime +from south.db import db +from south.v2 import SchemaMigration + + +class Migration(SchemaMigration): + def forwards(self, orm): + # Adding field 'Environment.created' + db.add_column('devops_environment', 'created', + self.gf('django.db.models.fields.DateTimeField')( + default=datetime.datetime.utcnow, + auto_now_add=True, blank=True), keep_default=False) + + # Adding field 'Node.created' + db.add_column('devops_node', 'created', + self.gf('django.db.models.fields.DateTimeField')( + default=datetime.datetime.utcnow, + auto_now_add=True, blank=True), keep_default=False) + + # Adding field 'Volume.created' + db.add_column('devops_volume', 'created', + self.gf('django.db.models.fields.DateTimeField')( + default=datetime.datetime.utcnow, + auto_now_add=True, blank=True), keep_default=False) + + # Adding field 'Network.created' + db.add_column('devops_network', 'created', + self.gf('django.db.models.fields.DateTimeField')( + default=datetime.datetime.utcnow, + auto_now_add=True, blank=True), keep_default=False) + + def backwards(self, orm): + # Deleting field 'Environment.created' + db.delete_column('devops_environment', 'created') + + # Deleting field 'Node.created' + db.delete_column('devops_node', 'created') + + # Deleting field 'Volume.created' + db.delete_column('devops_volume', 'created') + + # Deleting field 'Network.created' + db.delete_column('devops_network', 'created') + + models = { + u'devops.address': { + 'Meta': {'object_name': 'Address'}, + u'id': ( + 'django.db.models.fields.AutoField', [], + {'primary_key': 'True'}), + 'interface': ('django.db.models.fields.related.ForeignKey', [], + {'to': u"orm['devops.Interface']"}), + 'ip_address': ('django.db.models.fields.GenericIPAddressField', [], + {'max_length': '39'}) + }, + u'devops.diskdevice': { + 'Meta': {'object_name': 'DiskDevice'}, + 'bus': ('django.db.models.fields.CharField', + [], {'max_length': '255'} + ), + 'device': ('django.db.models.fields.CharField', [], + {'max_length': '255'}), + u'id': ('django.db.models.fields.AutoField', [], + {'primary_key': 'True'}), + 'node': ('django.db.models.fields.related.ForeignKey', [], + {'to': u"orm['devops.Node']"}), + 'target_dev': ('django.db.models.fields.CharField', [], + {'max_length': '255'}), + 'type': ('django.db.models.fields.CharField', [], + {'max_length': '255'}), + 'volume': ('django.db.models.fields.related.ForeignKey', [], + {'to': u"orm['devops.Volume']", 'null': 'True'}) + }, + u'devops.environment': { + 'Meta': {'object_name': 'Environment'}, + 'created': ('django.db.models.fields.DateTimeField', [], + {'default': 'datetime.datetime.utcnow', + 'auto_now_add': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], + {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], + {'unique': 'True', 'max_length': '255'}) + }, + u'devops.interface': { + 'Meta': {'object_name': 'Interface'}, + u'id': ('django.db.models.fields.AutoField', [], + {'primary_key': 'True'}), + 'mac_address': ('django.db.models.fields.CharField', [], + {'unique': 'True', 'max_length': '255'}), + 'model': ('django.db.models.fields.CharField', [], + {'max_length': '255'}), + 'network': ('django.db.models.fields.related.ForeignKey', [], + {'to': u"orm['devops.Network']"}), + 'node': ('django.db.models.fields.related.ForeignKey', [], + {'to': u"orm['devops.Node']"}), + 'type': ('django.db.models.fields.CharField', [], + {'max_length': '255'}) + }, + u'devops.network': { + 'Meta': {'unique_together': "(('name', 'environment'),)", + 'object_name': 'Network'}, + 'created': ('django.db.models.fields.DateTimeField', [], + {'default': 'datetime.datetime.utcnow', + 'auto_now_add': 'True', 'blank': 'True'}), + 'environment': ('django.db.models.fields.related.ForeignKey', [], + {'to': u"orm['devops.Environment']", + 'null': 'True'}), + 'forward': ('django.db.models.fields.CharField', [], + {'max_length': '255', 'null': 'True'}), + 'has_dhcp_server': ('django.db.models.fields.BooleanField', [], + {}), + 'has_pxe_server': ('django.db.models.fields.BooleanField', [], {}), + 'has_reserved_ips': ('django.db.models.fields.BooleanField', [], + {'default': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], + {'primary_key': 'True'}), + 'ip_network': ('django.db.models.fields.CharField', [], + {'unique': 'True', 'max_length': '255'}), + 'name': ('django.db.models.fields.CharField', [], + {'max_length': '255'}), + 'tftp_root_dir': ('django.db.models.fields.CharField', [], + {'max_length': '255'}), + 'uuid': ('django.db.models.fields.CharField', [], + {'max_length': '255'}) + }, + u'devops.node': { + 'Meta': {'unique_together': "(('name', 'environment'),)", + 'object_name': 'Node'}, + 'architecture': ('django.db.models.fields.CharField', [], + {'max_length': '255'}), + 'boot': ('django.db.models.fields.CharField', [], + {'default': "'[]'", 'max_length': '255'}), + 'created': ('django.db.models.fields.DateTimeField', [], + {'default': 'datetime.datetime.utcnow', + 'auto_now_add': 'True', 'blank': 'True'}), + 'environment': ('django.db.models.fields.related.ForeignKey', [], + {'to': u"orm['devops.Environment']", + 'null': 'True'}), + 'has_vnc': ('django.db.models.fields.BooleanField', [], + {'default': 'True'}), + 'hypervisor': ('django.db.models.fields.CharField', [], + {'max_length': '255'}), + u'id': ('django.db.models.fields.AutoField', [], + {'primary_key': 'True'}), + 'memory': ('django.db.models.fields.IntegerField', [], + {'default': '1024'}), + 'metadata': ('django.db.models.fields.CharField', [], + {'max_length': '255', 'null': 'True'}), + 'name': ('django.db.models.fields.CharField', [], + {'max_length': '255'}), + 'os_type': ('django.db.models.fields.CharField', [], + {'max_length': '255'}), + 'role': ('django.db.models.fields.CharField', [], + {'max_length': '255', 'null': 'True'}), + 'uuid': ('django.db.models.fields.CharField', [], + {'max_length': '255'}), + 'vcpu': ('django.db.models.fields.PositiveSmallIntegerField', [], + {'default': '1'}) + }, + u'devops.volume': { + 'Meta': {'unique_together': "(('name', 'environment'),)", + 'object_name': 'Volume'}, + 'backing_store': ('django.db.models.fields.related.ForeignKey', [], + {'to': u"orm['devops.Volume']", 'null': 'True'}), + 'capacity': ('django.db.models.fields.BigIntegerField', [], {}), + 'created': ('django.db.models.fields.DateTimeField', [], + {'default': 'datetime.datetime.utcnow', + 'auto_now_add': 'True', 'blank': 'True'}), + 'environment': ('django.db.models.fields.related.ForeignKey', [], + {'to': u"orm['devops.Environment']", + 'null': 'True'}), + 'format': ('django.db.models.fields.CharField', [], + {'max_length': '255'}), + u'id': ('django.db.models.fields.AutoField', [], + {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], + {'max_length': '255'}), + 'uuid': ('django.db.models.fields.CharField', [], + {'max_length': '255'}) + } + } + + complete_apps = ['devops'] diff --git a/devops/models/base.py b/devops/models/base.py index 08569c36..2236f4a1 100644 --- a/devops/models/base.py +++ b/devops/models/base.py @@ -12,6 +12,8 @@ # License for the specific language governing permissions and limitations # under the License. +from datetime import datetime + from django.conf import settings from django.db import models from django.utils.importlib import import_module @@ -33,6 +35,7 @@ def double_tuple(*args): class DriverModel(models.Model): _driver = None + created = models.DateTimeField(auto_now_add=True, default=datetime.utcnow) class Meta: abstract = True diff --git a/devops/shell.py b/devops/shell.py index 10dccced..ca88e6e8 100644 --- a/devops/shell.py +++ b/devops/shell.py @@ -30,7 +30,7 @@ class Shell(object): self.commands.get(self.params.command)(self) def do_list(self): - env_list = Environment.list().values('name') + env_list = Environment.list().values('name', 'created') for env in env_list: if self.params.list_ips: cur_env = Environment.get(name=env['name']) @@ -39,6 +39,9 @@ class Shell(object): admin_ip = (cur_env.get_node(name='admin'). get_ip_address_by_network_name('admin')) print('{0}\t{1}'.format(env['name'], admin_ip)) + elif self.params.timestamps: + created_text = env['created'].strftime('%Y-%m-%d_%H:%M:%S') + print('{0} {1}'.format(env['name'], created_text)) else: print(env['name']) @@ -170,6 +173,11 @@ class Shell(object): action='store_const', const=True, help='show admin node ip addresses', default=False) + timestamps_parser = argparse.ArgumentParser(add_help=False) + timestamps_parser.add_argument('--timestamps', dest='timestamps', + action='store_const', const=True, + help='show creation timestamps', + default=False) parser = argparse.ArgumentParser( description="Manage virtual environments. " "For addional help use command with -h/--help") @@ -177,7 +185,7 @@ class Shell(object): help='available commands', dest='command') subparsers.add_parser('list', - parents=[list_ips_parser], + parents=[list_ips_parser, timestamps_parser], help="Show virtual environments", description="Show virtual environments on host") subparsers.add_parser('show', parents=[name_parser],