Răsfoiți Sursa

Add re-initialized migrations for v2.11.0

jeremystretch 4 ani în urmă
părinte
comite
c82470e4df

+ 103 - 0
netbox/circuits/migrations/0001_initial.py

@@ -0,0 +1,103 @@
+import dcim.fields
+import django.core.serializers.json
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    initial = True
+
+    dependencies = [
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='Circuit',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('cid', models.CharField(max_length=100)),
+                ('status', models.CharField(default='active', max_length=50)),
+                ('install_date', models.DateField(blank=True, null=True)),
+                ('commit_rate', models.PositiveIntegerField(blank=True, null=True)),
+                ('description', models.CharField(blank=True, max_length=200)),
+                ('comments', models.TextField(blank=True)),
+            ],
+            options={
+                'ordering': ['provider', 'cid'],
+            },
+        ),
+        migrations.CreateModel(
+            name='CircuitTermination',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('_cable_peer_id', models.PositiveIntegerField(blank=True, null=True)),
+                ('mark_connected', models.BooleanField(default=False)),
+                ('term_side', models.CharField(max_length=1)),
+                ('port_speed', models.PositiveIntegerField(blank=True, null=True)),
+                ('upstream_speed', models.PositiveIntegerField(blank=True, null=True)),
+                ('xconnect_id', models.CharField(blank=True, max_length=50)),
+                ('pp_info', models.CharField(blank=True, max_length=100)),
+                ('description', models.CharField(blank=True, max_length=200)),
+            ],
+            options={
+                'ordering': ['circuit', 'term_side'],
+            },
+        ),
+        migrations.CreateModel(
+            name='CircuitType',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=100, unique=True)),
+                ('slug', models.SlugField(max_length=100, unique=True)),
+                ('description', models.CharField(blank=True, max_length=200)),
+            ],
+            options={
+                'ordering': ['name'],
+            },
+        ),
+        migrations.CreateModel(
+            name='Provider',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=100, unique=True)),
+                ('slug', models.SlugField(max_length=100, unique=True)),
+                ('asn', dcim.fields.ASNField(blank=True, null=True)),
+                ('account', models.CharField(blank=True, max_length=30)),
+                ('portal_url', models.URLField(blank=True)),
+                ('noc_contact', models.TextField(blank=True)),
+                ('admin_contact', models.TextField(blank=True)),
+                ('comments', models.TextField(blank=True)),
+            ],
+            options={
+                'ordering': ['name'],
+            },
+        ),
+        migrations.CreateModel(
+            name='ProviderNetwork',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=100)),
+                ('description', models.CharField(blank=True, max_length=200)),
+                ('comments', models.TextField(blank=True)),
+                ('provider', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='networks', to='circuits.provider')),
+            ],
+            options={
+                'ordering': ('provider', 'name'),
+            },
+        ),
+    ]

+ 100 - 0
netbox/circuits/migrations/0002_initial.py

@@ -0,0 +1,100 @@
+from django.db import migrations, models
+import django.db.models.deletion
+import taggit.managers
+
+
+class Migration(migrations.Migration):
+
+    initial = True
+
+    dependencies = [
+        ('dcim', '0001_initial'),
+        ('contenttypes', '0002_remove_content_type_name'),
+        ('circuits', '0001_initial'),
+        ('extras', '0001_initial'),
+        ('tenancy', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='providernetwork',
+            name='tags',
+            field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'),
+        ),
+        migrations.AddField(
+            model_name='provider',
+            name='tags',
+            field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'),
+        ),
+        migrations.AddField(
+            model_name='circuittermination',
+            name='_cable_peer_type',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='contenttypes.contenttype'),
+        ),
+        migrations.AddField(
+            model_name='circuittermination',
+            name='cable',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'),
+        ),
+        migrations.AddField(
+            model_name='circuittermination',
+            name='circuit',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='terminations', to='circuits.circuit'),
+        ),
+        migrations.AddField(
+            model_name='circuittermination',
+            name='provider_network',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='circuit_terminations', to='circuits.providernetwork'),
+        ),
+        migrations.AddField(
+            model_name='circuittermination',
+            name='site',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='circuit_terminations', to='dcim.site'),
+        ),
+        migrations.AddField(
+            model_name='circuit',
+            name='provider',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='circuits', to='circuits.provider'),
+        ),
+        migrations.AddField(
+            model_name='circuit',
+            name='tags',
+            field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'),
+        ),
+        migrations.AddField(
+            model_name='circuit',
+            name='tenant',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='circuits', to='tenancy.tenant'),
+        ),
+        migrations.AddField(
+            model_name='circuit',
+            name='termination_a',
+            field=models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='circuits.circuittermination'),
+        ),
+        migrations.AddField(
+            model_name='circuit',
+            name='termination_z',
+            field=models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='circuits.circuittermination'),
+        ),
+        migrations.AddField(
+            model_name='circuit',
+            name='type',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='circuits', to='circuits.circuittype'),
+        ),
+        migrations.AddConstraint(
+            model_name='providernetwork',
+            constraint=models.UniqueConstraint(fields=('provider', 'name'), name='circuits_providernetwork_provider_name'),
+        ),
+        migrations.AlterUniqueTogether(
+            name='providernetwork',
+            unique_together={('provider', 'name')},
+        ),
+        migrations.AlterUniqueTogether(
+            name='circuittermination',
+            unique_together={('circuit', 'term_side')},
+        ),
+        migrations.AlterUniqueTogether(
+            name='circuit',
+            unique_together={('provider', 'cid')},
+        ),
+    ]

+ 659 - 0
netbox/dcim/migrations/0001_initial.py

@@ -0,0 +1,659 @@
+import dcim.fields
+import django.contrib.postgres.fields
+import django.core.serializers.json
+import django.core.validators
+from django.db import migrations, models
+import django.db.models.deletion
+import timezone_field.fields
+import utilities.fields
+import utilities.ordering
+import utilities.query_functions
+import utilities.validators
+
+
+class Migration(migrations.Migration):
+
+    initial = True
+
+    dependencies = [
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='Cable',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('termination_a_id', models.PositiveIntegerField()),
+                ('termination_b_id', models.PositiveIntegerField()),
+                ('type', models.CharField(blank=True, max_length=50)),
+                ('status', models.CharField(default='connected', max_length=50)),
+                ('label', models.CharField(blank=True, max_length=100)),
+                ('color', utilities.fields.ColorField(blank=True, max_length=6)),
+                ('length', models.PositiveSmallIntegerField(blank=True, null=True)),
+                ('length_unit', models.CharField(blank=True, max_length=50)),
+                ('_abs_length', models.DecimalField(blank=True, decimal_places=4, max_digits=10, null=True)),
+            ],
+            options={
+                'ordering': ['pk'],
+            },
+        ),
+        migrations.CreateModel(
+            name='CablePath',
+            fields=[
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('origin_id', models.PositiveIntegerField()),
+                ('destination_id', models.PositiveIntegerField(blank=True, null=True)),
+                ('path', dcim.fields.PathField(base_field=models.CharField(max_length=40), size=None)),
+                ('is_active', models.BooleanField(default=False)),
+                ('is_split', models.BooleanField(default=False)),
+            ],
+        ),
+        migrations.CreateModel(
+            name='ConsolePort',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=64)),
+                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)),
+                ('label', models.CharField(blank=True, max_length=64)),
+                ('description', models.CharField(blank=True, max_length=200)),
+                ('_cable_peer_id', models.PositiveIntegerField(blank=True, null=True)),
+                ('mark_connected', models.BooleanField(default=False)),
+                ('type', models.CharField(blank=True, max_length=50)),
+                ('speed', models.PositiveSmallIntegerField(blank=True, null=True)),
+            ],
+            options={
+                'ordering': ('device', '_name'),
+            },
+        ),
+        migrations.CreateModel(
+            name='ConsolePortTemplate',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=64)),
+                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)),
+                ('label', models.CharField(blank=True, max_length=64)),
+                ('description', models.CharField(blank=True, max_length=200)),
+                ('type', models.CharField(blank=True, max_length=50)),
+            ],
+            options={
+                'ordering': ('device_type', '_name'),
+            },
+        ),
+        migrations.CreateModel(
+            name='ConsoleServerPort',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=64)),
+                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)),
+                ('label', models.CharField(blank=True, max_length=64)),
+                ('description', models.CharField(blank=True, max_length=200)),
+                ('_cable_peer_id', models.PositiveIntegerField(blank=True, null=True)),
+                ('mark_connected', models.BooleanField(default=False)),
+                ('type', models.CharField(blank=True, max_length=50)),
+                ('speed', models.PositiveSmallIntegerField(blank=True, null=True)),
+            ],
+            options={
+                'ordering': ('device', '_name'),
+            },
+        ),
+        migrations.CreateModel(
+            name='ConsoleServerPortTemplate',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=64)),
+                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)),
+                ('label', models.CharField(blank=True, max_length=64)),
+                ('description', models.CharField(blank=True, max_length=200)),
+                ('type', models.CharField(blank=True, max_length=50)),
+            ],
+            options={
+                'ordering': ('device_type', '_name'),
+            },
+        ),
+        migrations.CreateModel(
+            name='Device',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('local_context_data', models.JSONField(blank=True, null=True)),
+                ('name', models.CharField(blank=True, max_length=64, null=True)),
+                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize, null=True)),
+                ('serial', models.CharField(blank=True, max_length=50)),
+                ('asset_tag', models.CharField(blank=True, max_length=50, null=True, unique=True)),
+                ('position', models.PositiveSmallIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)])),
+                ('face', models.CharField(blank=True, max_length=50)),
+                ('status', models.CharField(default='active', max_length=50)),
+                ('vc_position', models.PositiveSmallIntegerField(blank=True, null=True, validators=[django.core.validators.MaxValueValidator(255)])),
+                ('vc_priority', models.PositiveSmallIntegerField(blank=True, null=True, validators=[django.core.validators.MaxValueValidator(255)])),
+                ('comments', models.TextField(blank=True)),
+            ],
+            options={
+                'ordering': ('_name', 'pk'),
+            },
+        ),
+        migrations.CreateModel(
+            name='DeviceBay',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=64)),
+                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)),
+                ('label', models.CharField(blank=True, max_length=64)),
+                ('description', models.CharField(blank=True, max_length=200)),
+            ],
+            options={
+                'ordering': ('device', '_name'),
+            },
+        ),
+        migrations.CreateModel(
+            name='DeviceBayTemplate',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=64)),
+                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)),
+                ('label', models.CharField(blank=True, max_length=64)),
+                ('description', models.CharField(blank=True, max_length=200)),
+            ],
+            options={
+                'ordering': ('device_type', '_name'),
+            },
+        ),
+        migrations.CreateModel(
+            name='DeviceRole',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=100, unique=True)),
+                ('slug', models.SlugField(max_length=100, unique=True)),
+                ('color', utilities.fields.ColorField(default='9e9e9e', max_length=6)),
+                ('vm_role', models.BooleanField(default=True)),
+                ('description', models.CharField(blank=True, max_length=200)),
+            ],
+            options={
+                'ordering': ['name'],
+            },
+        ),
+        migrations.CreateModel(
+            name='DeviceType',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('model', models.CharField(max_length=100)),
+                ('slug', models.SlugField(max_length=100)),
+                ('part_number', models.CharField(blank=True, max_length=50)),
+                ('u_height', models.PositiveSmallIntegerField(default=1)),
+                ('is_full_depth', models.BooleanField(default=True)),
+                ('subdevice_role', models.CharField(blank=True, max_length=50)),
+                ('front_image', models.ImageField(blank=True, upload_to='devicetype-images')),
+                ('rear_image', models.ImageField(blank=True, upload_to='devicetype-images')),
+                ('comments', models.TextField(blank=True)),
+            ],
+            options={
+                'ordering': ['manufacturer', 'model'],
+            },
+        ),
+        migrations.CreateModel(
+            name='FrontPort',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=64)),
+                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)),
+                ('label', models.CharField(blank=True, max_length=64)),
+                ('description', models.CharField(blank=True, max_length=200)),
+                ('_cable_peer_id', models.PositiveIntegerField(blank=True, null=True)),
+                ('mark_connected', models.BooleanField(default=False)),
+                ('type', models.CharField(max_length=50)),
+                ('rear_port_position', models.PositiveSmallIntegerField(default=1, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(1024)])),
+            ],
+            options={
+                'ordering': ('device', '_name'),
+            },
+        ),
+        migrations.CreateModel(
+            name='FrontPortTemplate',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=64)),
+                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)),
+                ('label', models.CharField(blank=True, max_length=64)),
+                ('description', models.CharField(blank=True, max_length=200)),
+                ('type', models.CharField(max_length=50)),
+                ('rear_port_position', models.PositiveSmallIntegerField(default=1, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(1024)])),
+            ],
+            options={
+                'ordering': ('device_type', '_name'),
+            },
+        ),
+        migrations.CreateModel(
+            name='Interface',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=64)),
+                ('label', models.CharField(blank=True, max_length=64)),
+                ('description', models.CharField(blank=True, max_length=200)),
+                ('_cable_peer_id', models.PositiveIntegerField(blank=True, null=True)),
+                ('mark_connected', models.BooleanField(default=False)),
+                ('enabled', models.BooleanField(default=True)),
+                ('mac_address', dcim.fields.MACAddressField(blank=True, null=True)),
+                ('mtu', models.PositiveIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(65536)])),
+                ('mode', models.CharField(blank=True, max_length=50)),
+                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize_interface)),
+                ('type', models.CharField(max_length=50)),
+                ('mgmt_only', models.BooleanField(default=False)),
+            ],
+            options={
+                'ordering': ('device', utilities.query_functions.CollateAsChar('_name')),
+            },
+        ),
+        migrations.CreateModel(
+            name='InterfaceTemplate',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=64)),
+                ('label', models.CharField(blank=True, max_length=64)),
+                ('description', models.CharField(blank=True, max_length=200)),
+                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize_interface)),
+                ('type', models.CharField(max_length=50)),
+                ('mgmt_only', models.BooleanField(default=False)),
+            ],
+            options={
+                'ordering': ('device_type', '_name'),
+            },
+        ),
+        migrations.CreateModel(
+            name='InventoryItem',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=64)),
+                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)),
+                ('label', models.CharField(blank=True, max_length=64)),
+                ('description', models.CharField(blank=True, max_length=200)),
+                ('part_id', models.CharField(blank=True, max_length=50)),
+                ('serial', models.CharField(blank=True, max_length=50)),
+                ('asset_tag', models.CharField(blank=True, max_length=50, null=True, unique=True)),
+                ('discovered', models.BooleanField(default=False)),
+                ('lft', models.PositiveIntegerField(editable=False)),
+                ('rght', models.PositiveIntegerField(editable=False)),
+                ('tree_id', models.PositiveIntegerField(db_index=True, editable=False)),
+                ('level', models.PositiveIntegerField(editable=False)),
+            ],
+            options={
+                'ordering': ('device__id', 'parent__id', '_name'),
+            },
+        ),
+        migrations.CreateModel(
+            name='Location',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=100)),
+                ('slug', models.SlugField(max_length=100)),
+                ('description', models.CharField(blank=True, max_length=200)),
+                ('lft', models.PositiveIntegerField(editable=False)),
+                ('rght', models.PositiveIntegerField(editable=False)),
+                ('tree_id', models.PositiveIntegerField(db_index=True, editable=False)),
+                ('level', models.PositiveIntegerField(editable=False)),
+            ],
+            options={
+                'ordering': ['site', 'name'],
+            },
+        ),
+        migrations.CreateModel(
+            name='Manufacturer',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=100, unique=True)),
+                ('slug', models.SlugField(max_length=100, unique=True)),
+                ('description', models.CharField(blank=True, max_length=200)),
+            ],
+            options={
+                'ordering': ['name'],
+            },
+        ),
+        migrations.CreateModel(
+            name='Platform',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=100, unique=True)),
+                ('slug', models.SlugField(max_length=100, unique=True)),
+                ('napalm_driver', models.CharField(blank=True, max_length=50)),
+                ('napalm_args', models.JSONField(blank=True, null=True)),
+                ('description', models.CharField(blank=True, max_length=200)),
+            ],
+            options={
+                'ordering': ['name'],
+            },
+        ),
+        migrations.CreateModel(
+            name='PowerFeed',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('_cable_peer_id', models.PositiveIntegerField(blank=True, null=True)),
+                ('mark_connected', models.BooleanField(default=False)),
+                ('name', models.CharField(max_length=100)),
+                ('status', models.CharField(default='active', max_length=50)),
+                ('type', models.CharField(default='primary', max_length=50)),
+                ('supply', models.CharField(default='ac', max_length=50)),
+                ('phase', models.CharField(default='single-phase', max_length=50)),
+                ('voltage', models.SmallIntegerField(default=120, validators=[utilities.validators.ExclusionValidator([0])])),
+                ('amperage', models.PositiveSmallIntegerField(default=20, validators=[django.core.validators.MinValueValidator(1)])),
+                ('max_utilization', models.PositiveSmallIntegerField(default=80, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(100)])),
+                ('available_power', models.PositiveIntegerField(default=0, editable=False)),
+                ('comments', models.TextField(blank=True)),
+            ],
+            options={
+                'ordering': ['power_panel', 'name'],
+            },
+        ),
+        migrations.CreateModel(
+            name='PowerOutlet',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=64)),
+                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)),
+                ('label', models.CharField(blank=True, max_length=64)),
+                ('description', models.CharField(blank=True, max_length=200)),
+                ('_cable_peer_id', models.PositiveIntegerField(blank=True, null=True)),
+                ('mark_connected', models.BooleanField(default=False)),
+                ('type', models.CharField(blank=True, max_length=50)),
+                ('feed_leg', models.CharField(blank=True, max_length=50)),
+            ],
+            options={
+                'ordering': ('device', '_name'),
+            },
+        ),
+        migrations.CreateModel(
+            name='PowerOutletTemplate',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=64)),
+                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)),
+                ('label', models.CharField(blank=True, max_length=64)),
+                ('description', models.CharField(blank=True, max_length=200)),
+                ('type', models.CharField(blank=True, max_length=50)),
+                ('feed_leg', models.CharField(blank=True, max_length=50)),
+            ],
+            options={
+                'ordering': ('device_type', '_name'),
+            },
+        ),
+        migrations.CreateModel(
+            name='PowerPanel',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=100)),
+            ],
+            options={
+                'ordering': ['site', 'name'],
+            },
+        ),
+        migrations.CreateModel(
+            name='PowerPort',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=64)),
+                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)),
+                ('label', models.CharField(blank=True, max_length=64)),
+                ('description', models.CharField(blank=True, max_length=200)),
+                ('_cable_peer_id', models.PositiveIntegerField(blank=True, null=True)),
+                ('mark_connected', models.BooleanField(default=False)),
+                ('type', models.CharField(blank=True, max_length=50)),
+                ('maximum_draw', models.PositiveSmallIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)])),
+                ('allocated_draw', models.PositiveSmallIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)])),
+            ],
+            options={
+                'ordering': ('device', '_name'),
+            },
+        ),
+        migrations.CreateModel(
+            name='PowerPortTemplate',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=64)),
+                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)),
+                ('label', models.CharField(blank=True, max_length=64)),
+                ('description', models.CharField(blank=True, max_length=200)),
+                ('type', models.CharField(blank=True, max_length=50)),
+                ('maximum_draw', models.PositiveSmallIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)])),
+                ('allocated_draw', models.PositiveSmallIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1)])),
+            ],
+            options={
+                'ordering': ('device_type', '_name'),
+            },
+        ),
+        migrations.CreateModel(
+            name='Rack',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=100)),
+                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)),
+                ('facility_id', models.CharField(blank=True, max_length=50, null=True)),
+                ('status', models.CharField(default='active', max_length=50)),
+                ('serial', models.CharField(blank=True, max_length=50)),
+                ('asset_tag', models.CharField(blank=True, max_length=50, null=True, unique=True)),
+                ('type', models.CharField(blank=True, max_length=50)),
+                ('width', models.PositiveSmallIntegerField(default=19)),
+                ('u_height', models.PositiveSmallIntegerField(default=42, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(100)])),
+                ('desc_units', models.BooleanField(default=False)),
+                ('outer_width', models.PositiveSmallIntegerField(blank=True, null=True)),
+                ('outer_depth', models.PositiveSmallIntegerField(blank=True, null=True)),
+                ('outer_unit', models.CharField(blank=True, max_length=50)),
+                ('comments', models.TextField(blank=True)),
+            ],
+            options={
+                'ordering': ('site', 'location', '_name', 'pk'),
+            },
+        ),
+        migrations.CreateModel(
+            name='RackReservation',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('units', django.contrib.postgres.fields.ArrayField(base_field=models.PositiveSmallIntegerField(), size=None)),
+                ('description', models.CharField(max_length=200)),
+            ],
+            options={
+                'ordering': ['created', 'pk'],
+            },
+        ),
+        migrations.CreateModel(
+            name='RackRole',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=100, unique=True)),
+                ('slug', models.SlugField(max_length=100, unique=True)),
+                ('color', utilities.fields.ColorField(default='9e9e9e', max_length=6)),
+                ('description', models.CharField(blank=True, max_length=200)),
+            ],
+            options={
+                'ordering': ['name'],
+            },
+        ),
+        migrations.CreateModel(
+            name='RearPort',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=64)),
+                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)),
+                ('label', models.CharField(blank=True, max_length=64)),
+                ('description', models.CharField(blank=True, max_length=200)),
+                ('_cable_peer_id', models.PositiveIntegerField(blank=True, null=True)),
+                ('mark_connected', models.BooleanField(default=False)),
+                ('type', models.CharField(max_length=50)),
+                ('positions', models.PositiveSmallIntegerField(default=1, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(1024)])),
+            ],
+            options={
+                'ordering': ('device', '_name'),
+            },
+        ),
+        migrations.CreateModel(
+            name='RearPortTemplate',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=64)),
+                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)),
+                ('label', models.CharField(blank=True, max_length=64)),
+                ('description', models.CharField(blank=True, max_length=200)),
+                ('type', models.CharField(max_length=50)),
+                ('positions', models.PositiveSmallIntegerField(default=1, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(1024)])),
+            ],
+            options={
+                'ordering': ('device_type', '_name'),
+            },
+        ),
+        migrations.CreateModel(
+            name='Region',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=100, unique=True)),
+                ('slug', models.SlugField(max_length=100, unique=True)),
+                ('description', models.CharField(blank=True, max_length=200)),
+                ('lft', models.PositiveIntegerField(editable=False)),
+                ('rght', models.PositiveIntegerField(editable=False)),
+                ('tree_id', models.PositiveIntegerField(db_index=True, editable=False)),
+                ('level', models.PositiveIntegerField(editable=False)),
+            ],
+            options={
+                'abstract': False,
+            },
+        ),
+        migrations.CreateModel(
+            name='Site',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=100, unique=True)),
+                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)),
+                ('slug', models.SlugField(max_length=100, unique=True)),
+                ('status', models.CharField(default='active', max_length=50)),
+                ('facility', models.CharField(blank=True, max_length=50)),
+                ('asn', dcim.fields.ASNField(blank=True, null=True)),
+                ('time_zone', timezone_field.fields.TimeZoneField(blank=True)),
+                ('description', models.CharField(blank=True, max_length=200)),
+                ('physical_address', models.CharField(blank=True, max_length=200)),
+                ('shipping_address', models.CharField(blank=True, max_length=200)),
+                ('latitude', models.DecimalField(blank=True, decimal_places=6, max_digits=8, null=True)),
+                ('longitude', models.DecimalField(blank=True, decimal_places=6, max_digits=9, null=True)),
+                ('contact_name', models.CharField(blank=True, max_length=50)),
+                ('contact_phone', models.CharField(blank=True, max_length=20)),
+                ('contact_email', models.EmailField(blank=True, max_length=254)),
+                ('comments', models.TextField(blank=True)),
+            ],
+            options={
+                'ordering': ('_name',),
+            },
+        ),
+        migrations.CreateModel(
+            name='SiteGroup',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=100, unique=True)),
+                ('slug', models.SlugField(max_length=100, unique=True)),
+                ('description', models.CharField(blank=True, max_length=200)),
+                ('lft', models.PositiveIntegerField(editable=False)),
+                ('rght', models.PositiveIntegerField(editable=False)),
+                ('tree_id', models.PositiveIntegerField(db_index=True, editable=False)),
+                ('level', models.PositiveIntegerField(editable=False)),
+            ],
+            options={
+                'abstract': False,
+            },
+        ),
+        migrations.CreateModel(
+            name='VirtualChassis',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=64)),
+                ('domain', models.CharField(blank=True, max_length=30)),
+                ('master', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='vc_master_for', to='dcim.device')),
+            ],
+            options={
+                'verbose_name_plural': 'virtual chassis',
+                'ordering': ['name'],
+            },
+        ),
+    ]

+ 311 - 0
netbox/dcim/migrations/0002_initial.py

@@ -0,0 +1,311 @@
+from django.conf import settings
+from django.db import migrations, models
+import django.db.models.deletion
+import mptt.fields
+import taggit.managers
+
+
+class Migration(migrations.Migration):
+
+    initial = True
+
+    dependencies = [
+        ('dcim', '0001_initial'),
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+        ('contenttypes', '0002_remove_content_type_name'),
+        ('extras', '0001_initial'),
+        ('tenancy', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='virtualchassis',
+            name='tags',
+            field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'),
+        ),
+        migrations.AddField(
+            model_name='sitegroup',
+            name='parent',
+            field=mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='dcim.sitegroup'),
+        ),
+        migrations.AddField(
+            model_name='site',
+            name='group',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='sites', to='dcim.sitegroup'),
+        ),
+        migrations.AddField(
+            model_name='site',
+            name='region',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='sites', to='dcim.region'),
+        ),
+        migrations.AddField(
+            model_name='site',
+            name='tags',
+            field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'),
+        ),
+        migrations.AddField(
+            model_name='site',
+            name='tenant',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='sites', to='tenancy.tenant'),
+        ),
+        migrations.AddField(
+            model_name='region',
+            name='parent',
+            field=mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='dcim.region'),
+        ),
+        migrations.AddField(
+            model_name='rearporttemplate',
+            name='device_type',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='rearporttemplates', to='dcim.devicetype'),
+        ),
+        migrations.AddField(
+            model_name='rearport',
+            name='_cable_peer_type',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='contenttypes.contenttype'),
+        ),
+        migrations.AddField(
+            model_name='rearport',
+            name='cable',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'),
+        ),
+        migrations.AddField(
+            model_name='rearport',
+            name='device',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='rearports', to='dcim.device'),
+        ),
+        migrations.AddField(
+            model_name='rearport',
+            name='tags',
+            field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'),
+        ),
+        migrations.AddField(
+            model_name='rackreservation',
+            name='rack',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reservations', to='dcim.rack'),
+        ),
+        migrations.AddField(
+            model_name='rackreservation',
+            name='tags',
+            field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'),
+        ),
+        migrations.AddField(
+            model_name='rackreservation',
+            name='tenant',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='rackreservations', to='tenancy.tenant'),
+        ),
+        migrations.AddField(
+            model_name='rackreservation',
+            name='user',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL),
+        ),
+        migrations.AddField(
+            model_name='rack',
+            name='location',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='racks', to='dcim.location'),
+        ),
+        migrations.AddField(
+            model_name='rack',
+            name='role',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='racks', to='dcim.rackrole'),
+        ),
+        migrations.AddField(
+            model_name='rack',
+            name='site',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='racks', to='dcim.site'),
+        ),
+        migrations.AddField(
+            model_name='rack',
+            name='tags',
+            field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'),
+        ),
+        migrations.AddField(
+            model_name='rack',
+            name='tenant',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='racks', to='tenancy.tenant'),
+        ),
+        migrations.AddField(
+            model_name='powerporttemplate',
+            name='device_type',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='powerporttemplates', to='dcim.devicetype'),
+        ),
+        migrations.AddField(
+            model_name='powerport',
+            name='_cable_peer_type',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='contenttypes.contenttype'),
+        ),
+        migrations.AddField(
+            model_name='powerport',
+            name='_path',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='dcim.cablepath'),
+        ),
+        migrations.AddField(
+            model_name='powerport',
+            name='cable',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'),
+        ),
+        migrations.AddField(
+            model_name='powerport',
+            name='device',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='powerports', to='dcim.device'),
+        ),
+        migrations.AddField(
+            model_name='powerport',
+            name='tags',
+            field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'),
+        ),
+        migrations.AddField(
+            model_name='powerpanel',
+            name='location',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='dcim.location'),
+        ),
+        migrations.AddField(
+            model_name='powerpanel',
+            name='site',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='dcim.site'),
+        ),
+        migrations.AddField(
+            model_name='powerpanel',
+            name='tags',
+            field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'),
+        ),
+        migrations.AddField(
+            model_name='poweroutlettemplate',
+            name='device_type',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='poweroutlettemplates', to='dcim.devicetype'),
+        ),
+        migrations.AddField(
+            model_name='poweroutlettemplate',
+            name='power_port',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='poweroutlet_templates', to='dcim.powerporttemplate'),
+        ),
+        migrations.AddField(
+            model_name='poweroutlet',
+            name='_cable_peer_type',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='contenttypes.contenttype'),
+        ),
+        migrations.AddField(
+            model_name='poweroutlet',
+            name='_path',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='dcim.cablepath'),
+        ),
+        migrations.AddField(
+            model_name='poweroutlet',
+            name='cable',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'),
+        ),
+        migrations.AddField(
+            model_name='poweroutlet',
+            name='device',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='poweroutlets', to='dcim.device'),
+        ),
+        migrations.AddField(
+            model_name='poweroutlet',
+            name='power_port',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='poweroutlets', to='dcim.powerport'),
+        ),
+        migrations.AddField(
+            model_name='poweroutlet',
+            name='tags',
+            field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'),
+        ),
+        migrations.AddField(
+            model_name='powerfeed',
+            name='_cable_peer_type',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='contenttypes.contenttype'),
+        ),
+        migrations.AddField(
+            model_name='powerfeed',
+            name='_path',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='dcim.cablepath'),
+        ),
+        migrations.AddField(
+            model_name='powerfeed',
+            name='cable',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'),
+        ),
+        migrations.AddField(
+            model_name='powerfeed',
+            name='power_panel',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='powerfeeds', to='dcim.powerpanel'),
+        ),
+        migrations.AddField(
+            model_name='powerfeed',
+            name='rack',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='dcim.rack'),
+        ),
+        migrations.AddField(
+            model_name='powerfeed',
+            name='tags',
+            field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'),
+        ),
+        migrations.AddField(
+            model_name='platform',
+            name='manufacturer',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='platforms', to='dcim.manufacturer'),
+        ),
+        migrations.AddField(
+            model_name='location',
+            name='parent',
+            field=mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='dcim.location'),
+        ),
+        migrations.AddField(
+            model_name='location',
+            name='site',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='locations', to='dcim.site'),
+        ),
+        migrations.AddField(
+            model_name='inventoryitem',
+            name='device',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='inventoryitems', to='dcim.device'),
+        ),
+        migrations.AddField(
+            model_name='inventoryitem',
+            name='manufacturer',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='inventory_items', to='dcim.manufacturer'),
+        ),
+        migrations.AddField(
+            model_name='inventoryitem',
+            name='parent',
+            field=mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='child_items', to='dcim.inventoryitem'),
+        ),
+        migrations.AddField(
+            model_name='inventoryitem',
+            name='tags',
+            field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'),
+        ),
+        migrations.AddField(
+            model_name='interfacetemplate',
+            name='device_type',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='interfacetemplates', to='dcim.devicetype'),
+        ),
+        migrations.AddField(
+            model_name='interface',
+            name='_cable_peer_type',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='contenttypes.contenttype'),
+        ),
+        migrations.AddField(
+            model_name='interface',
+            name='_path',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='dcim.cablepath'),
+        ),
+        migrations.AddField(
+            model_name='interface',
+            name='cable',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'),
+        ),
+        migrations.AddField(
+            model_name='interface',
+            name='device',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='interfaces', to='dcim.device'),
+        ),
+        migrations.AddField(
+            model_name='interface',
+            name='lag',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='member_interfaces', to='dcim.interface'),
+        ),
+        migrations.AddField(
+            model_name='interface',
+            name='parent',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='child_interfaces', to='dcim.interface'),
+        ),
+    ]

+ 355 - 0
netbox/dcim/migrations/0003_initial.py

@@ -0,0 +1,355 @@
+from django.db import migrations, models
+import django.db.models.deletion
+import taggit.managers
+
+
+class Migration(migrations.Migration):
+
+    initial = True
+
+    dependencies = [
+        ('dcim', '0002_initial'),
+        ('virtualization', '0001_initial'),
+        ('contenttypes', '0002_remove_content_type_name'),
+        ('ipam', '0001_initial'),
+        ('tenancy', '0001_initial'),
+        ('extras', '0002_initial'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='interface',
+            name='tagged_vlans',
+            field=models.ManyToManyField(blank=True, related_name='interfaces_as_tagged', to='ipam.VLAN'),
+        ),
+        migrations.AddField(
+            model_name='interface',
+            name='tags',
+            field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'),
+        ),
+        migrations.AddField(
+            model_name='interface',
+            name='untagged_vlan',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='interfaces_as_untagged', to='ipam.vlan'),
+        ),
+        migrations.AddField(
+            model_name='frontporttemplate',
+            name='device_type',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='frontporttemplates', to='dcim.devicetype'),
+        ),
+        migrations.AddField(
+            model_name='frontporttemplate',
+            name='rear_port',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='frontport_templates', to='dcim.rearporttemplate'),
+        ),
+        migrations.AddField(
+            model_name='frontport',
+            name='_cable_peer_type',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='contenttypes.contenttype'),
+        ),
+        migrations.AddField(
+            model_name='frontport',
+            name='cable',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'),
+        ),
+        migrations.AddField(
+            model_name='frontport',
+            name='device',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='frontports', to='dcim.device'),
+        ),
+        migrations.AddField(
+            model_name='frontport',
+            name='rear_port',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='frontports', to='dcim.rearport'),
+        ),
+        migrations.AddField(
+            model_name='frontport',
+            name='tags',
+            field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'),
+        ),
+        migrations.AddField(
+            model_name='devicetype',
+            name='manufacturer',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='device_types', to='dcim.manufacturer'),
+        ),
+        migrations.AddField(
+            model_name='devicetype',
+            name='tags',
+            field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'),
+        ),
+        migrations.AddField(
+            model_name='devicebaytemplate',
+            name='device_type',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='devicebaytemplates', to='dcim.devicetype'),
+        ),
+        migrations.AddField(
+            model_name='devicebay',
+            name='device',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='devicebays', to='dcim.device'),
+        ),
+        migrations.AddField(
+            model_name='devicebay',
+            name='installed_device',
+            field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='parent_bay', to='dcim.device'),
+        ),
+        migrations.AddField(
+            model_name='devicebay',
+            name='tags',
+            field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'),
+        ),
+        migrations.AddField(
+            model_name='device',
+            name='cluster',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='devices', to='virtualization.cluster'),
+        ),
+        migrations.AddField(
+            model_name='device',
+            name='device_role',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='devices', to='dcim.devicerole'),
+        ),
+        migrations.AddField(
+            model_name='device',
+            name='device_type',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='instances', to='dcim.devicetype'),
+        ),
+        migrations.AddField(
+            model_name='device',
+            name='location',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='devices', to='dcim.location'),
+        ),
+        migrations.AddField(
+            model_name='device',
+            name='platform',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='devices', to='dcim.platform'),
+        ),
+        migrations.AddField(
+            model_name='device',
+            name='primary_ip4',
+            field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='primary_ip4_for', to='ipam.ipaddress'),
+        ),
+        migrations.AddField(
+            model_name='device',
+            name='primary_ip6',
+            field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='primary_ip6_for', to='ipam.ipaddress'),
+        ),
+        migrations.AddField(
+            model_name='device',
+            name='rack',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='devices', to='dcim.rack'),
+        ),
+        migrations.AddField(
+            model_name='device',
+            name='site',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='devices', to='dcim.site'),
+        ),
+        migrations.AddField(
+            model_name='device',
+            name='tags',
+            field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'),
+        ),
+        migrations.AddField(
+            model_name='device',
+            name='tenant',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='devices', to='tenancy.tenant'),
+        ),
+        migrations.AddField(
+            model_name='device',
+            name='virtual_chassis',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='members', to='dcim.virtualchassis'),
+        ),
+        migrations.AddField(
+            model_name='consoleserverporttemplate',
+            name='device_type',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='consoleserverporttemplates', to='dcim.devicetype'),
+        ),
+        migrations.AddField(
+            model_name='consoleserverport',
+            name='_cable_peer_type',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='contenttypes.contenttype'),
+        ),
+        migrations.AddField(
+            model_name='consoleserverport',
+            name='_path',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='dcim.cablepath'),
+        ),
+        migrations.AddField(
+            model_name='consoleserverport',
+            name='cable',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'),
+        ),
+        migrations.AddField(
+            model_name='consoleserverport',
+            name='device',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='consoleserverports', to='dcim.device'),
+        ),
+        migrations.AddField(
+            model_name='consoleserverport',
+            name='tags',
+            field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'),
+        ),
+        migrations.AddField(
+            model_name='consoleporttemplate',
+            name='device_type',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='consoleporttemplates', to='dcim.devicetype'),
+        ),
+        migrations.AddField(
+            model_name='consoleport',
+            name='_cable_peer_type',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='contenttypes.contenttype'),
+        ),
+        migrations.AddField(
+            model_name='consoleport',
+            name='_path',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='dcim.cablepath'),
+        ),
+        migrations.AddField(
+            model_name='consoleport',
+            name='cable',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='dcim.cable'),
+        ),
+        migrations.AddField(
+            model_name='consoleport',
+            name='device',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='consoleports', to='dcim.device'),
+        ),
+        migrations.AddField(
+            model_name='consoleport',
+            name='tags',
+            field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'),
+        ),
+        migrations.AddField(
+            model_name='cablepath',
+            name='destination_type',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='contenttypes.contenttype'),
+        ),
+        migrations.AddField(
+            model_name='cablepath',
+            name='origin_type',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='contenttypes.contenttype'),
+        ),
+        migrations.AddField(
+            model_name='cable',
+            name='_termination_a_device',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='dcim.device'),
+        ),
+        migrations.AddField(
+            model_name='cable',
+            name='_termination_b_device',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='dcim.device'),
+        ),
+        migrations.AddField(
+            model_name='cable',
+            name='tags',
+            field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'),
+        ),
+        migrations.AddField(
+            model_name='cable',
+            name='termination_a_type',
+            field=models.ForeignKey(limit_choices_to=models.Q(models.Q(models.Q(('app_label', 'circuits'), ('model__in', ('circuittermination',))), models.Q(('app_label', 'dcim'), ('model__in', ('consoleport', 'consoleserverport', 'frontport', 'interface', 'powerfeed', 'poweroutlet', 'powerport', 'rearport'))), _connector='OR')), on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.contenttype'),
+        ),
+        migrations.AddField(
+            model_name='cable',
+            name='termination_b_type',
+            field=models.ForeignKey(limit_choices_to=models.Q(models.Q(models.Q(('app_label', 'circuits'), ('model__in', ('circuittermination',))), models.Q(('app_label', 'dcim'), ('model__in', ('consoleport', 'consoleserverport', 'frontport', 'interface', 'powerfeed', 'poweroutlet', 'powerport', 'rearport'))), _connector='OR')), on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.contenttype'),
+        ),
+        migrations.AlterUniqueTogether(
+            name='rearporttemplate',
+            unique_together={('device_type', 'name')},
+        ),
+        migrations.AlterUniqueTogether(
+            name='rearport',
+            unique_together={('device', 'name')},
+        ),
+        migrations.AlterUniqueTogether(
+            name='rack',
+            unique_together={('location', 'facility_id'), ('location', 'name')},
+        ),
+        migrations.AlterUniqueTogether(
+            name='powerporttemplate',
+            unique_together={('device_type', 'name')},
+        ),
+        migrations.AlterUniqueTogether(
+            name='powerport',
+            unique_together={('device', 'name')},
+        ),
+        migrations.AlterUniqueTogether(
+            name='powerpanel',
+            unique_together={('site', 'name')},
+        ),
+        migrations.AlterUniqueTogether(
+            name='poweroutlettemplate',
+            unique_together={('device_type', 'name')},
+        ),
+        migrations.AlterUniqueTogether(
+            name='poweroutlet',
+            unique_together={('device', 'name')},
+        ),
+        migrations.AlterUniqueTogether(
+            name='powerfeed',
+            unique_together={('power_panel', 'name')},
+        ),
+        migrations.AlterUniqueTogether(
+            name='location',
+            unique_together={('site', 'name'), ('site', 'slug')},
+        ),
+        migrations.AlterUniqueTogether(
+            name='inventoryitem',
+            unique_together={('device', 'parent', 'name')},
+        ),
+        migrations.AlterUniqueTogether(
+            name='interfacetemplate',
+            unique_together={('device_type', 'name')},
+        ),
+        migrations.AlterUniqueTogether(
+            name='interface',
+            unique_together={('device', 'name')},
+        ),
+        migrations.AlterUniqueTogether(
+            name='frontporttemplate',
+            unique_together={('rear_port', 'rear_port_position'), ('device_type', 'name')},
+        ),
+        migrations.AlterUniqueTogether(
+            name='frontport',
+            unique_together={('device', 'name'), ('rear_port', 'rear_port_position')},
+        ),
+        migrations.AlterUniqueTogether(
+            name='devicetype',
+            unique_together={('manufacturer', 'model'), ('manufacturer', 'slug')},
+        ),
+        migrations.AlterUniqueTogether(
+            name='devicebaytemplate',
+            unique_together={('device_type', 'name')},
+        ),
+        migrations.AlterUniqueTogether(
+            name='devicebay',
+            unique_together={('device', 'name')},
+        ),
+        migrations.AlterUniqueTogether(
+            name='device',
+            unique_together={('rack', 'position', 'face'), ('virtual_chassis', 'vc_position'), ('site', 'tenant', 'name')},
+        ),
+        migrations.AlterUniqueTogether(
+            name='consoleserverporttemplate',
+            unique_together={('device_type', 'name')},
+        ),
+        migrations.AlterUniqueTogether(
+            name='consoleserverport',
+            unique_together={('device', 'name')},
+        ),
+        migrations.AlterUniqueTogether(
+            name='consoleporttemplate',
+            unique_together={('device_type', 'name')},
+        ),
+        migrations.AlterUniqueTogether(
+            name='consoleport',
+            unique_together={('device', 'name')},
+        ),
+        migrations.AlterUniqueTogether(
+            name='cablepath',
+            unique_together={('origin_type', 'origin_id')},
+        ),
+        migrations.AlterUniqueTogether(
+            name='cable',
+            unique_together={('termination_b_type', 'termination_b_id'), ('termination_a_type', 'termination_a_id')},
+        ),
+    ]

+ 231 - 0
netbox/extras/migrations/0001_initial.py

@@ -0,0 +1,231 @@
+from django.conf import settings
+import django.contrib.postgres.fields
+from django.db import migrations, models
+import django.db.models.deletion
+import extras.models.customfields
+import extras.utils
+import utilities.fields
+import utilities.validators
+
+
+class Migration(migrations.Migration):
+
+    initial = True
+
+    dependencies = [
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+        ('contenttypes', '0002_remove_content_type_name'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='Report',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False)),
+            ],
+            options={
+                'managed': False,
+            },
+        ),
+        migrations.CreateModel(
+            name='Script',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False)),
+            ],
+            options={
+                'managed': False,
+            },
+        ),
+        migrations.CreateModel(
+            name='ConfigContext',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=100, unique=True)),
+                ('weight', models.PositiveSmallIntegerField(default=1000)),
+                ('description', models.CharField(blank=True, max_length=200)),
+                ('is_active', models.BooleanField(default=True)),
+                ('data', models.JSONField()),
+            ],
+            options={
+                'ordering': ['weight', 'name'],
+            },
+        ),
+        migrations.CreateModel(
+            name='Tag',
+            fields=[
+                ('name', models.CharField(max_length=100, unique=True)),
+                ('slug', models.SlugField(max_length=100, unique=True)),
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('color', utilities.fields.ColorField(default='9e9e9e', max_length=6)),
+                ('description', models.CharField(blank=True, max_length=200)),
+            ],
+            options={
+                'ordering': ['name'],
+            },
+        ),
+        migrations.CreateModel(
+            name='Webhook',
+            fields=[
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=150, unique=True)),
+                ('type_create', models.BooleanField(default=False)),
+                ('type_update', models.BooleanField(default=False)),
+                ('type_delete', models.BooleanField(default=False)),
+                ('payload_url', models.CharField(max_length=500)),
+                ('enabled', models.BooleanField(default=True)),
+                ('http_method', models.CharField(default='POST', max_length=30)),
+                ('http_content_type', models.CharField(default='application/json', max_length=100)),
+                ('additional_headers', models.TextField(blank=True)),
+                ('body_template', models.TextField(blank=True)),
+                ('secret', models.CharField(blank=True, max_length=255)),
+                ('ssl_verification', models.BooleanField(default=True)),
+                ('ca_file_path', models.CharField(blank=True, max_length=4096, null=True)),
+                ('content_types', models.ManyToManyField(limit_choices_to=extras.utils.FeatureQuery('webhooks'), related_name='webhooks', to='contenttypes.ContentType')),
+            ],
+            options={
+                'ordering': ('name',),
+            },
+        ),
+        migrations.CreateModel(
+            name='TaggedItem',
+            fields=[
+                ('object_id', models.IntegerField(db_index=True)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='extras_taggeditem_tagged_items', to='contenttypes.contenttype')),
+                ('tag', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='extras_taggeditem_items', to='extras.tag')),
+            ],
+        ),
+        migrations.CreateModel(
+            name='ObjectChange',
+            fields=[
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('time', models.DateTimeField(auto_now_add=True, db_index=True)),
+                ('user_name', models.CharField(editable=False, max_length=150)),
+                ('request_id', models.UUIDField(editable=False)),
+                ('action', models.CharField(max_length=50)),
+                ('changed_object_id', models.PositiveIntegerField()),
+                ('related_object_id', models.PositiveIntegerField(blank=True, null=True)),
+                ('object_repr', models.CharField(editable=False, max_length=200)),
+                ('prechange_data', models.JSONField(blank=True, editable=False, null=True)),
+                ('postchange_data', models.JSONField(blank=True, editable=False, null=True)),
+                ('changed_object_type', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.contenttype')),
+                ('related_object_type', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.contenttype')),
+                ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='changes', to=settings.AUTH_USER_MODEL)),
+            ],
+            options={
+                'ordering': ['-time'],
+            },
+        ),
+        migrations.CreateModel(
+            name='JournalEntry',
+            fields=[
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('assigned_object_id', models.PositiveIntegerField()),
+                ('created', models.DateTimeField(auto_now_add=True)),
+                ('kind', models.CharField(default='info', max_length=30)),
+                ('comments', models.TextField()),
+                ('assigned_object_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype')),
+                ('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)),
+            ],
+            options={
+                'verbose_name_plural': 'journal entries',
+                'ordering': ('-created',),
+            },
+        ),
+        migrations.CreateModel(
+            name='JobResult',
+            fields=[
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=255)),
+                ('created', models.DateTimeField(auto_now_add=True)),
+                ('completed', models.DateTimeField(blank=True, null=True)),
+                ('status', models.CharField(default='pending', max_length=30)),
+                ('data', models.JSONField(blank=True, null=True)),
+                ('job_id', models.UUIDField(unique=True)),
+                ('obj_type', models.ForeignKey(limit_choices_to=extras.utils.FeatureQuery('job_results'), on_delete=django.db.models.deletion.CASCADE, related_name='job_results', to='contenttypes.contenttype')),
+                ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
+            ],
+            options={
+                'ordering': ['obj_type', 'name', '-created'],
+            },
+        ),
+        migrations.CreateModel(
+            name='ImageAttachment',
+            fields=[
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('object_id', models.PositiveIntegerField()),
+                ('image', models.ImageField(height_field='image_height', upload_to=extras.utils.image_upload, width_field='image_width')),
+                ('image_height', models.PositiveSmallIntegerField()),
+                ('image_width', models.PositiveSmallIntegerField()),
+                ('name', models.CharField(blank=True, max_length=50)),
+                ('created', models.DateTimeField(auto_now_add=True)),
+                ('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype')),
+            ],
+            options={
+                'ordering': ('name', 'pk'),
+            },
+        ),
+        migrations.CreateModel(
+            name='ExportTemplate',
+            fields=[
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=100)),
+                ('description', models.CharField(blank=True, max_length=200)),
+                ('template_code', models.TextField()),
+                ('mime_type', models.CharField(blank=True, max_length=50)),
+                ('file_extension', models.CharField(blank=True, max_length=15)),
+                ('as_attachment', models.BooleanField(default=True)),
+                ('content_type', models.ForeignKey(limit_choices_to=extras.utils.FeatureQuery('export_templates'), on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype')),
+            ],
+            options={
+                'ordering': ['content_type', 'name'],
+            },
+        ),
+        migrations.CreateModel(
+            name='CustomLink',
+            fields=[
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=100, unique=True)),
+                ('link_text', models.CharField(max_length=500)),
+                ('link_url', models.CharField(max_length=500)),
+                ('weight', models.PositiveSmallIntegerField(default=100)),
+                ('group_name', models.CharField(blank=True, max_length=50)),
+                ('button_class', models.CharField(default='default', max_length=30)),
+                ('new_window', models.BooleanField(default=False)),
+                ('content_type', models.ForeignKey(limit_choices_to=extras.utils.FeatureQuery('custom_links'), on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype')),
+            ],
+            options={
+                'ordering': ['group_name', 'weight', 'name'],
+            },
+        ),
+        migrations.CreateModel(
+            name='CustomField',
+            fields=[
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('type', models.CharField(default='text', max_length=50)),
+                ('name', models.CharField(max_length=50, unique=True)),
+                ('label', models.CharField(blank=True, max_length=50)),
+                ('description', models.CharField(blank=True, max_length=200)),
+                ('required', models.BooleanField(default=False)),
+                ('filter_logic', models.CharField(default='loose', max_length=50)),
+                ('default', models.JSONField(blank=True, null=True)),
+                ('weight', models.PositiveSmallIntegerField(default=100)),
+                ('validation_minimum', models.PositiveIntegerField(blank=True, null=True)),
+                ('validation_maximum', models.PositiveIntegerField(blank=True, null=True)),
+                ('validation_regex', models.CharField(blank=True, max_length=500, validators=[utilities.validators.validate_regex])),
+                ('choices', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=100), blank=True, null=True, size=None)),
+                ('content_types', models.ManyToManyField(limit_choices_to=extras.utils.FeatureQuery('custom_fields'), related_name='custom_fields', to='contenttypes.ContentType')),
+            ],
+            options={
+                'ordering': ['weight', 'name'],
+            },
+            managers=[
+                ('objects', extras.models.customfields.CustomFieldManager()),
+            ],
+        ),
+    ]

+ 83 - 0
netbox/extras/migrations/0002_initial.py

@@ -0,0 +1,83 @@
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    initial = True
+
+    dependencies = [
+        ('dcim', '0002_initial'),
+        ('extras', '0001_initial'),
+        ('virtualization', '0001_initial'),
+        ('tenancy', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='configcontext',
+            name='cluster_groups',
+            field=models.ManyToManyField(blank=True, related_name='_extras_configcontext_cluster_groups_+', to='virtualization.ClusterGroup'),
+        ),
+        migrations.AddField(
+            model_name='configcontext',
+            name='clusters',
+            field=models.ManyToManyField(blank=True, related_name='_extras_configcontext_clusters_+', to='virtualization.Cluster'),
+        ),
+        migrations.AddField(
+            model_name='configcontext',
+            name='device_types',
+            field=models.ManyToManyField(blank=True, related_name='_extras_configcontext_device_types_+', to='dcim.DeviceType'),
+        ),
+        migrations.AddField(
+            model_name='configcontext',
+            name='platforms',
+            field=models.ManyToManyField(blank=True, related_name='_extras_configcontext_platforms_+', to='dcim.Platform'),
+        ),
+        migrations.AddField(
+            model_name='configcontext',
+            name='regions',
+            field=models.ManyToManyField(blank=True, related_name='_extras_configcontext_regions_+', to='dcim.Region'),
+        ),
+        migrations.AddField(
+            model_name='configcontext',
+            name='roles',
+            field=models.ManyToManyField(blank=True, related_name='_extras_configcontext_roles_+', to='dcim.DeviceRole'),
+        ),
+        migrations.AddField(
+            model_name='configcontext',
+            name='site_groups',
+            field=models.ManyToManyField(blank=True, related_name='_extras_configcontext_site_groups_+', to='dcim.SiteGroup'),
+        ),
+        migrations.AddField(
+            model_name='configcontext',
+            name='sites',
+            field=models.ManyToManyField(blank=True, related_name='_extras_configcontext_sites_+', to='dcim.Site'),
+        ),
+        migrations.AddField(
+            model_name='configcontext',
+            name='tags',
+            field=models.ManyToManyField(blank=True, related_name='_extras_configcontext_tags_+', to='extras.Tag'),
+        ),
+        migrations.AddField(
+            model_name='configcontext',
+            name='tenant_groups',
+            field=models.ManyToManyField(blank=True, related_name='_extras_configcontext_tenant_groups_+', to='tenancy.TenantGroup'),
+        ),
+        migrations.AddField(
+            model_name='configcontext',
+            name='tenants',
+            field=models.ManyToManyField(blank=True, related_name='_extras_configcontext_tenants_+', to='tenancy.Tenant'),
+        ),
+        migrations.AlterUniqueTogether(
+            name='webhook',
+            unique_together={('payload_url', 'type_create', 'type_update', 'type_delete')},
+        ),
+        migrations.AlterIndexTogether(
+            name='taggeditem',
+            index_together={('content_type', 'object_id')},
+        ),
+        migrations.AlterUniqueTogether(
+            name='exporttemplate',
+            unique_together={('content_type', 'name')},
+        ),
+    ]

+ 206 - 0
netbox/ipam/migrations/0001_initial.py

@@ -0,0 +1,206 @@
+import django.contrib.postgres.fields
+import django.core.serializers.json
+import django.core.validators
+from django.db import migrations, models
+import django.db.models.deletion
+import django.db.models.expressions
+import ipam.fields
+import taggit.managers
+
+
+class Migration(migrations.Migration):
+
+    initial = True
+
+    dependencies = [
+        ('contenttypes', '0002_remove_content_type_name'),
+        ('dcim', '0002_initial'),
+        ('extras', '0001_initial'),
+        ('tenancy', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='Aggregate',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('prefix', ipam.fields.IPNetworkField()),
+                ('date_added', models.DateField(blank=True, null=True)),
+                ('description', models.CharField(blank=True, max_length=200)),
+            ],
+            options={
+                'ordering': ('prefix', 'pk'),
+            },
+        ),
+        migrations.CreateModel(
+            name='IPAddress',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('address', ipam.fields.IPAddressField()),
+                ('status', models.CharField(default='active', max_length=50)),
+                ('role', models.CharField(blank=True, max_length=50)),
+                ('assigned_object_id', models.PositiveIntegerField(blank=True, null=True)),
+                ('dns_name', models.CharField(blank=True, max_length=255, validators=[django.core.validators.RegexValidator(code='invalid', message='Only alphanumeric characters, hyphens, periods, and underscores are allowed in DNS names', regex='^[0-9A-Za-z._-]+$')])),
+                ('description', models.CharField(blank=True, max_length=200)),
+            ],
+            options={
+                'verbose_name': 'IP address',
+                'verbose_name_plural': 'IP addresses',
+                'ordering': ('address', 'pk'),
+            },
+        ),
+        migrations.CreateModel(
+            name='Prefix',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('prefix', ipam.fields.IPNetworkField()),
+                ('status', models.CharField(default='active', max_length=50)),
+                ('is_pool', models.BooleanField(default=False)),
+                ('description', models.CharField(blank=True, max_length=200)),
+            ],
+            options={
+                'verbose_name_plural': 'prefixes',
+                'ordering': (django.db.models.expressions.OrderBy(django.db.models.expressions.F('vrf'), nulls_first=True), 'prefix', 'pk'),
+            },
+        ),
+        migrations.CreateModel(
+            name='RIR',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=100, unique=True)),
+                ('slug', models.SlugField(max_length=100, unique=True)),
+                ('is_private', models.BooleanField(default=False)),
+                ('description', models.CharField(blank=True, max_length=200)),
+            ],
+            options={
+                'verbose_name': 'RIR',
+                'verbose_name_plural': 'RIRs',
+                'ordering': ['name'],
+            },
+        ),
+        migrations.CreateModel(
+            name='Role',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=100, unique=True)),
+                ('slug', models.SlugField(max_length=100, unique=True)),
+                ('weight', models.PositiveSmallIntegerField(default=1000)),
+                ('description', models.CharField(blank=True, max_length=200)),
+            ],
+            options={
+                'ordering': ['weight', 'name'],
+            },
+        ),
+        migrations.CreateModel(
+            name='RouteTarget',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=21, unique=True)),
+                ('description', models.CharField(blank=True, max_length=200)),
+            ],
+            options={
+                'ordering': ['name'],
+            },
+        ),
+        migrations.CreateModel(
+            name='VRF',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=100)),
+                ('rd', models.CharField(blank=True, max_length=21, null=True, unique=True)),
+                ('enforce_unique', models.BooleanField(default=True)),
+                ('description', models.CharField(blank=True, max_length=200)),
+                ('export_targets', models.ManyToManyField(blank=True, related_name='exporting_vrfs', to='ipam.RouteTarget')),
+                ('import_targets', models.ManyToManyField(blank=True, related_name='importing_vrfs', to='ipam.RouteTarget')),
+                ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')),
+                ('tenant', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='vrfs', to='tenancy.tenant')),
+            ],
+            options={
+                'verbose_name': 'VRF',
+                'verbose_name_plural': 'VRFs',
+                'ordering': ('name', 'rd', 'pk'),
+            },
+        ),
+        migrations.CreateModel(
+            name='VLANGroup',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=100)),
+                ('slug', models.SlugField(max_length=100)),
+                ('scope_id', models.PositiveBigIntegerField(blank=True, null=True)),
+                ('description', models.CharField(blank=True, max_length=200)),
+                ('scope_type', models.ForeignKey(blank=True, limit_choices_to=models.Q(('model__in', ('region', 'sitegroup', 'site', 'location', 'rack', 'clustergroup', 'cluster'))), null=True, on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype')),
+            ],
+            options={
+                'verbose_name': 'VLAN group',
+                'verbose_name_plural': 'VLAN groups',
+                'ordering': ('name', 'pk'),
+            },
+        ),
+        migrations.CreateModel(
+            name='VLAN',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('vid', models.PositiveSmallIntegerField(validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(4094)])),
+                ('name', models.CharField(max_length=64)),
+                ('status', models.CharField(default='active', max_length=50)),
+                ('description', models.CharField(blank=True, max_length=200)),
+                ('group', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='vlans', to='ipam.vlangroup')),
+                ('role', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='vlans', to='ipam.role')),
+                ('site', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='vlans', to='dcim.site')),
+                ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')),
+                ('tenant', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='vlans', to='tenancy.tenant')),
+            ],
+            options={
+                'verbose_name': 'VLAN',
+                'verbose_name_plural': 'VLANs',
+                'ordering': ('site', 'group', 'vid', 'pk'),
+            },
+        ),
+        migrations.CreateModel(
+            name='Service',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=100)),
+                ('protocol', models.CharField(max_length=50)),
+                ('ports', django.contrib.postgres.fields.ArrayField(base_field=models.PositiveIntegerField(validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(65535)]), size=None)),
+                ('description', models.CharField(blank=True, max_length=200)),
+                ('device', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='services', to='dcim.device')),
+                ('ipaddresses', models.ManyToManyField(blank=True, related_name='services', to='ipam.IPAddress')),
+                ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')),
+            ],
+            options={
+                'ordering': ('protocol', 'ports', 'pk'),
+            },
+        ),
+    ]

+ 113 - 0
netbox/ipam/migrations/0002_initial.py

@@ -0,0 +1,113 @@
+from django.db import migrations, models
+import django.db.models.deletion
+import taggit.managers
+
+
+class Migration(migrations.Migration):
+
+    initial = True
+
+    dependencies = [
+        ('dcim', '0003_initial'),
+        ('virtualization', '0001_initial'),
+        ('contenttypes', '0002_remove_content_type_name'),
+        ('ipam', '0001_initial'),
+        ('extras', '0002_initial'),
+        ('tenancy', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='service',
+            name='virtual_machine',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='services', to='virtualization.virtualmachine'),
+        ),
+        migrations.AddField(
+            model_name='routetarget',
+            name='tags',
+            field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'),
+        ),
+        migrations.AddField(
+            model_name='routetarget',
+            name='tenant',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='route_targets', to='tenancy.tenant'),
+        ),
+        migrations.AddField(
+            model_name='prefix',
+            name='role',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='prefixes', to='ipam.role'),
+        ),
+        migrations.AddField(
+            model_name='prefix',
+            name='site',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='prefixes', to='dcim.site'),
+        ),
+        migrations.AddField(
+            model_name='prefix',
+            name='tags',
+            field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'),
+        ),
+        migrations.AddField(
+            model_name='prefix',
+            name='tenant',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='prefixes', to='tenancy.tenant'),
+        ),
+        migrations.AddField(
+            model_name='prefix',
+            name='vlan',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='prefixes', to='ipam.vlan'),
+        ),
+        migrations.AddField(
+            model_name='prefix',
+            name='vrf',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='prefixes', to='ipam.vrf'),
+        ),
+        migrations.AddField(
+            model_name='ipaddress',
+            name='assigned_object_type',
+            field=models.ForeignKey(blank=True, limit_choices_to=models.Q(models.Q(models.Q(('app_label', 'dcim'), ('model', 'interface')), models.Q(('app_label', 'virtualization'), ('model', 'vminterface')), _connector='OR')), null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.contenttype'),
+        ),
+        migrations.AddField(
+            model_name='ipaddress',
+            name='nat_inside',
+            field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='nat_outside', to='ipam.ipaddress'),
+        ),
+        migrations.AddField(
+            model_name='ipaddress',
+            name='tags',
+            field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'),
+        ),
+        migrations.AddField(
+            model_name='ipaddress',
+            name='tenant',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='ip_addresses', to='tenancy.tenant'),
+        ),
+        migrations.AddField(
+            model_name='ipaddress',
+            name='vrf',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='ip_addresses', to='ipam.vrf'),
+        ),
+        migrations.AddField(
+            model_name='aggregate',
+            name='rir',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='aggregates', to='ipam.rir'),
+        ),
+        migrations.AddField(
+            model_name='aggregate',
+            name='tags',
+            field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'),
+        ),
+        migrations.AddField(
+            model_name='aggregate',
+            name='tenant',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='aggregates', to='tenancy.tenant'),
+        ),
+        migrations.AlterUniqueTogether(
+            name='vlangroup',
+            unique_together={('scope_type', 'scope_id', 'name'), ('scope_type', 'scope_id', 'slug')},
+        ),
+        migrations.AlterUniqueTogether(
+            name='vlan',
+            unique_together={('group', 'vid'), ('group', 'name')},
+        ),
+    ]

+ 55 - 0
netbox/tenancy/migrations/0001_initial.py

@@ -0,0 +1,55 @@
+import django.core.serializers.json
+from django.db import migrations, models
+import django.db.models.deletion
+import mptt.fields
+import taggit.managers
+
+
+class Migration(migrations.Migration):
+
+    initial = True
+
+    dependencies = [
+        ('extras', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='TenantGroup',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=100, unique=True)),
+                ('slug', models.SlugField(max_length=100, unique=True)),
+                ('description', models.CharField(blank=True, max_length=200)),
+                ('lft', models.PositiveIntegerField(editable=False)),
+                ('rght', models.PositiveIntegerField(editable=False)),
+                ('tree_id', models.PositiveIntegerField(db_index=True, editable=False)),
+                ('level', models.PositiveIntegerField(editable=False)),
+                ('parent', mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='tenancy.tenantgroup')),
+            ],
+            options={
+                'ordering': ['name'],
+            },
+        ),
+        migrations.CreateModel(
+            name='Tenant',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=100, unique=True)),
+                ('slug', models.SlugField(max_length=100, unique=True)),
+                ('description', models.CharField(blank=True, max_length=200)),
+                ('comments', models.TextField(blank=True)),
+                ('group', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='tenants', to='tenancy.tenantgroup')),
+                ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')),
+            ],
+            options={
+                'ordering': ['group', 'name'],
+            },
+        ),
+    ]

+ 93 - 0
netbox/users/migrations/0001_initial.py

@@ -0,0 +1,93 @@
+from django.conf import settings
+import django.contrib.auth.models
+import django.contrib.postgres.fields
+import django.core.validators
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    initial = True
+
+    dependencies = [
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+        ('contenttypes', '0002_remove_content_type_name'),
+        ('auth', '0012_alter_user_first_name_max_length'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='AdminGroup',
+            fields=[
+            ],
+            options={
+                'verbose_name': 'Group',
+                'proxy': True,
+                'indexes': [],
+                'constraints': [],
+            },
+            bases=('auth.group',),
+            managers=[
+                ('objects', django.contrib.auth.models.GroupManager()),
+            ],
+        ),
+        migrations.CreateModel(
+            name='AdminUser',
+            fields=[
+            ],
+            options={
+                'verbose_name': 'User',
+                'proxy': True,
+                'indexes': [],
+                'constraints': [],
+            },
+            bases=('auth.user',),
+            managers=[
+                ('objects', django.contrib.auth.models.UserManager()),
+            ],
+        ),
+        migrations.CreateModel(
+            name='UserConfig',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False)),
+                ('data', models.JSONField(default=dict)),
+                ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='config', to=settings.AUTH_USER_MODEL)),
+            ],
+            options={
+                'verbose_name': 'User Preferences',
+                'verbose_name_plural': 'User Preferences',
+                'ordering': ['user'],
+            },
+        ),
+        migrations.CreateModel(
+            name='Token',
+            fields=[
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('created', models.DateTimeField(auto_now_add=True)),
+                ('expires', models.DateTimeField(blank=True, null=True)),
+                ('key', models.CharField(max_length=40, unique=True, validators=[django.core.validators.MinLengthValidator(40)])),
+                ('write_enabled', models.BooleanField(default=True)),
+                ('description', models.CharField(blank=True, max_length=200)),
+                ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tokens', to=settings.AUTH_USER_MODEL)),
+            ],
+        ),
+        migrations.CreateModel(
+            name='ObjectPermission',
+            fields=[
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=100)),
+                ('description', models.CharField(blank=True, max_length=200)),
+                ('enabled', models.BooleanField(default=True)),
+                ('actions', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=30), size=None)),
+                ('constraints', models.JSONField(blank=True, null=True)),
+                ('groups', models.ManyToManyField(blank=True, related_name='object_permissions', to='auth.Group')),
+                ('object_types', models.ManyToManyField(limit_choices_to=models.Q(models.Q(models.Q(('app_label__in', ['admin', 'auth', 'contenttypes', 'sessions', 'taggit', 'users']), _negated=True), models.Q(('app_label', 'auth'), ('model__in', ['group', 'user'])), models.Q(('app_label', 'users'), ('model__in', ['objectpermission', 'token'])), _connector='OR')), related_name='object_permissions', to='contenttypes.ContentType')),
+                ('users', models.ManyToManyField(blank=True, related_name='object_permissions', to=settings.AUTH_USER_MODEL)),
+            ],
+            options={
+                'verbose_name': 'permission',
+                'ordering': ['name'],
+            },
+        ),
+    ]

+ 146 - 0
netbox/virtualization/migrations/0001_initial.py

@@ -0,0 +1,146 @@
+import dcim.fields
+import django.core.serializers.json
+import django.core.validators
+from django.db import migrations, models
+import django.db.models.deletion
+import taggit.managers
+import utilities.fields
+import utilities.ordering
+import utilities.query_functions
+
+
+class Migration(migrations.Migration):
+
+    initial = True
+
+    dependencies = [
+        ('dcim', '0002_initial'),
+        ('ipam', '0001_initial'),
+        ('extras', '0001_initial'),
+        ('tenancy', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='Cluster',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=100, unique=True)),
+                ('comments', models.TextField(blank=True)),
+            ],
+            options={
+                'ordering': ['name'],
+            },
+        ),
+        migrations.CreateModel(
+            name='ClusterGroup',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=100, unique=True)),
+                ('slug', models.SlugField(max_length=100, unique=True)),
+                ('description', models.CharField(blank=True, max_length=200)),
+            ],
+            options={
+                'ordering': ['name'],
+            },
+        ),
+        migrations.CreateModel(
+            name='ClusterType',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('name', models.CharField(max_length=100, unique=True)),
+                ('slug', models.SlugField(max_length=100, unique=True)),
+                ('description', models.CharField(blank=True, max_length=200)),
+            ],
+            options={
+                'ordering': ['name'],
+            },
+        ),
+        migrations.CreateModel(
+            name='VirtualMachine',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('local_context_data', models.JSONField(blank=True, null=True)),
+                ('name', models.CharField(max_length=64)),
+                ('status', models.CharField(default='active', max_length=50)),
+                ('vcpus', models.DecimalField(blank=True, decimal_places=2, max_digits=6, null=True, validators=[django.core.validators.MinValueValidator(0.01)])),
+                ('memory', models.PositiveIntegerField(blank=True, null=True)),
+                ('disk', models.PositiveIntegerField(blank=True, null=True)),
+                ('comments', models.TextField(blank=True)),
+                ('cluster', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='virtual_machines', to='virtualization.cluster')),
+                ('platform', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='virtual_machines', to='dcim.platform')),
+                ('primary_ip4', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='ipam.ipaddress')),
+                ('primary_ip6', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='ipam.ipaddress')),
+                ('role', models.ForeignKey(blank=True, limit_choices_to={'vm_role': True}, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='virtual_machines', to='dcim.devicerole')),
+                ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')),
+                ('tenant', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='virtual_machines', to='tenancy.tenant')),
+            ],
+            options={
+                'ordering': ('name', 'pk'),
+                'unique_together': {('cluster', 'tenant', 'name')},
+            },
+        ),
+        migrations.AddField(
+            model_name='cluster',
+            name='group',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='clusters', to='virtualization.clustergroup'),
+        ),
+        migrations.AddField(
+            model_name='cluster',
+            name='site',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='clusters', to='dcim.site'),
+        ),
+        migrations.AddField(
+            model_name='cluster',
+            name='tags',
+            field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'),
+        ),
+        migrations.AddField(
+            model_name='cluster',
+            name='tenant',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='clusters', to='tenancy.tenant'),
+        ),
+        migrations.AddField(
+            model_name='cluster',
+            name='type',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='clusters', to='virtualization.clustertype'),
+        ),
+        migrations.CreateModel(
+            name='VMInterface',
+            fields=[
+                ('created', models.DateField(auto_now_add=True, null=True)),
+                ('last_updated', models.DateTimeField(auto_now=True, null=True)),
+                ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
+                ('id', models.BigAutoField(primary_key=True, serialize=False)),
+                ('enabled', models.BooleanField(default=True)),
+                ('mac_address', dcim.fields.MACAddressField(blank=True, null=True)),
+                ('mtu', models.PositiveIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(65536)])),
+                ('mode', models.CharField(blank=True, max_length=50)),
+                ('name', models.CharField(max_length=64)),
+                ('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize_interface)),
+                ('description', models.CharField(blank=True, max_length=200)),
+                ('parent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='child_interfaces', to='virtualization.vminterface')),
+                ('tagged_vlans', models.ManyToManyField(blank=True, related_name='vminterfaces_as_tagged', to='ipam.VLAN')),
+                ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')),
+                ('untagged_vlan', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='vminterfaces_as_untagged', to='ipam.vlan')),
+                ('virtual_machine', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='interfaces', to='virtualization.virtualmachine')),
+            ],
+            options={
+                'verbose_name': 'interface',
+                'ordering': ('virtual_machine', utilities.query_functions.CollateAsChar('_name')),
+                'unique_together': {('virtual_machine', 'name')},
+            },
+        ),
+    ]