summaryrefslogtreecommitdiff
path: root/src/caas
diff options
context:
space:
mode:
authorckonstanski <kostcarl@isu.edu>2026-07-30 18:17:14 -0600
committerckonstanski <kostcarl@isu.edu>2026-07-30 18:17:14 -0600
commit640ff61422bc0ee3966941b93d9889ddbbd38d77 (patch)
treeabf1c08f5d38ee53ec8b29dc4f425722517505e6 /src/caas
parent22dae02a86c1fce71091bfa5289cf99abba1b217 (diff)
more filesHEADmaster
Diffstat (limited to 'src/caas')
-rw-r--r--src/caas/forms.py110
-rw-r--r--src/caas/migrations/0001_initial.py100
-rw-r--r--src/caas/migrations/0002_auto_20200706_2113.py260
-rw-r--r--src/caas/migrations/0003_auto_20200706_2113.py35
-rw-r--r--src/caas/migrations/0004_delete_wrbatch.py16
-rw-r--r--src/caas/migrations/0005_auto_20200710_2235.py20
-rw-r--r--src/caas/migrations/0006_wrbatch.py43
-rw-r--r--src/caas/migrations/0007_auto_20200711_1126.py20
-rw-r--r--src/caas/migrations/0008_auto_20200711_1127.py20
-rw-r--r--src/caas/migrations/0009_auto_20200715_1630.py18
-rw-r--r--src/caas/migrations/0010_auto_20200720_1413.py20
-rw-r--r--src/caas/migrations/0011_auto_20200720_1525.py20
-rw-r--r--src/caas/migrations/0012_auto_20200721_1540.py20
-rw-r--r--src/caas/migrations/0013_auto_20200728_2359.py31
-rw-r--r--src/caas/migrations/0014_auto_20200803_1931.py20
-rw-r--r--src/caas/migrations/0015_auto_20200804_1404.py20
-rw-r--r--src/caas/migrations/0016_auto_20200804_1559.py20
-rw-r--r--src/caas/migrations/0017_cluster_is_central_controller.py18
-rw-r--r--src/caas/migrations/0018_auto_20200925_1855.py30
-rw-r--r--src/caas/migrations/0019_cluster_is_maint_window.py18
-rw-r--r--src/caas/migrations/0020_auto_20201001_1142.py20
-rw-r--r--src/caas/migrations/0021_auto_20201001_1232.py22
-rw-r--r--src/caas/migrations/0022_auto_20201001_1232.py20
-rw-r--r--src/caas/migrations/0023_auto_20201019_1631.py20
-rw-r--r--src/caas/migrations/0024_auto_20201023_1556.py20
-rw-r--r--src/caas/migrations/0025_auto_20201102_1545.py20
-rw-r--r--src/caas/migrations/0026_auto_20201110_0932.py29
-rw-r--r--src/caas/migrations/0027_auto_20201211_2103.py23
-rw-r--r--src/caas/migrations/0028_auto_20201212_1001.py20
-rw-r--r--src/caas/migrations/0029_auto_20201215_0832.py21
-rw-r--r--src/caas/migrations/0030_auto_20201215_0835.py20
-rw-r--r--src/caas/migrations/0031_auto_20201215_1430.py20
-rw-r--r--src/caas/models.py433
-rw-r--r--src/caas/services/ansibleservice.py52
-rw-r--r--src/caas/services/bmcservice.py50
-rw-r--r--src/caas/services/ciqservice.py193
-rw-r--r--src/caas/services/dnsservice.py60
-rw-r--r--src/caas/services/firmwareservice.py87
-rw-r--r--src/caas/services/helpers.py136
-rw-r--r--src/caas/services/httpclient.py18
-rw-r--r--src/caas/services/icingapollservice.py47
-rw-r--r--src/caas/services/icingaservice.py46
-rw-r--r--src/caas/services/jinja/bmc_host_vars.j213
-rw-r--r--src/caas/services/jinja/bmc_inventory.j26
-rw-r--r--src/caas/services/jinja/dns_host_vars.j212
-rw-r--r--src/caas/services/jinja/dns_inventory.j26
-rw-r--r--src/caas/services/jinja/firmware_host_vars.j213
-rw-r--r--src/caas/services/jinja/firmware_inventory.j27
-rw-r--r--src/caas/services/jinja/icinga_host_vars.j238
-rw-r--r--src/caas/services/jinja/icinga_inventory.j26
-rw-r--r--src/caas/services/jinja/icinga_poll_host_vars.j211
-rw-r--r--src/caas/services/jinja/icinga_poll_inventory.j26
-rw-r--r--src/caas/services/jinja/wr_host_vars.j274
-rw-r--r--src/caas/services/jinja/wr_inventory.j211
-rw-r--r--src/caas/services/macaddressservice.py38
-rw-r--r--src/caas/services/nicfirmwareupgradenowservice.py68
-rw-r--r--src/caas/services/nicfirmwareversionservice.py37
-rw-r--r--src/caas/services/passwordservice.py180
-rw-r--r--src/caas/services/patchservice.py106
-rw-r--r--src/caas/services/playbookreportservice.py147
-rw-r--r--src/caas/services/subcloudservice.py12
-rw-r--r--src/caas/services/wrinstallnowservice.py107
-rw-r--r--src/caas/services/wrservice.py75
-rw-r--r--src/caas/templates/adminpassword.xml12
-rw-r--r--src/caas/templates/autoremediate.xml12
-rw-r--r--src/caas/templates/ciq.xml13
-rw-r--r--src/caas/templates/ciq_success.xml4
-rw-r--r--src/caas/templates/dns.xml12
-rw-r--r--src/caas/templates/macaddress.xml12
-rw-r--r--src/caas/templates/mockwrremediate.xml12
-rw-r--r--src/caas/templates/nicfirmwareupgrade.xml12
-rw-r--r--src/caas/templates/nicfirmwareupgradenow.xml12
-rw-r--r--src/caas/templates/nicfirmwareversion.xml12
-rw-r--r--src/caas/templates/passwords.xml13
-rw-r--r--src/caas/templates/passwords_success.xml4
-rw-r--r--src/caas/templates/playbookreport.xml13
-rw-r--r--src/caas/templates/pushbutton.xml12
-rw-r--r--src/caas/templates/queuecustom.xml12
-rw-r--r--src/caas/templates/serialnumber.xml12
-rw-r--r--src/caas/templates/site.xml26
-rw-r--r--src/caas/templates/subcloud.xml58
-rw-r--r--src/caas/templates/wrinstall.xml12
-rw-r--r--src/caas/templates/wrinstallnow.xml12
-rw-r--r--src/caas/templates/wrremediate.xml12
-rw-r--r--src/caas/urls.py28
-rw-r--r--src/caas/views.py713
86 files changed, 4173 insertions, 76 deletions
diff --git a/src/caas/forms.py b/src/caas/forms.py
new file mode 100644
index 0000000..d485ee6
--- /dev/null
+++ b/src/caas/forms.py
@@ -0,0 +1,110 @@
+from django import forms
+
+
+class CiqUploadForm(forms.Form):
+ filehandle = forms.FileField(label = "CIQ (in CSV format with header rows deleted)")
+ assign_parent = forms.BooleanField(label = "Assign subclouds to central controllers?", required = False)
+
+
+class CiqUpload2Form(forms.Form):
+ filehandle = forms.FileField(label = "CIQ (in CSV format, servers over CC capacity will be not be assigned parents, servers with parents won't be affected)")
+
+
+class CiqAssignOrphanSubcloudsForm(forms.Form):
+ filehandle = forms.FileField(label = "CIQ (in CSV format, servers without parents will be assigned to new controllers if any)")
+
+
+class PasswordUploadForm(forms.Form):
+ filehandle = forms.FileField(label = "Password CSV (with header rows deleted)")
+
+
+class SerialNumberForm(forms.Form):
+ vendor = forms.CharField(label = "Vendor")
+ serial_number = forms.CharField(label = "Serial number")
+ ilo_host_address = forms.CharField(label = "BMC IP address")
+
+
+class AutoremediateForm(forms.Form):
+ ilo_host_address_list = forms.CharField(label = "BMC IP addresses separated by space")
+
+
+class DnsForm(forms.Form):
+ ilo_host_address = forms.CharField(label = "BMC IP address")
+
+
+class QueueCustomForm(forms.Form):
+ key = forms.CharField(label = "key")
+ playbook_key = forms.CharField(label = "playbook_key")
+ target = forms.CharField(label = "target")
+ cluster_name = forms.CharField(label = "cluster-name (optional)")
+
+
+class MacAddressForm(forms.Form):
+ ilo_host_address = forms.CharField(label = "BMC IP address")
+ pxe_mac_address = forms.CharField(label = "BMC MAC address")
+ intel_nic_firmware_version = forms.CharField(label = "Intel NIC firmware version")
+
+
+class AdminPasswordForm(forms.Form):
+ ilo_host_address = forms.CharField(label = "BMC IP address")
+ icinga_poll_status = forms.CharField(label = "Icinga poll status")
+
+
+class NicFirmwareVersionForm(forms.Form):
+ ilo_host_address = forms.CharField(label = "BMC IP address")
+ nic_firmware_version = forms.CharField(label = "NIC firmware version")
+
+
+class NicFirmwareUpgradeForm(forms.Form):
+ ilo_host_address_list = forms.CharField(label = "BMC IP addresses separated by space")
+
+
+class NicFirmwareUpgradeNowForm(forms.Form):
+ ilo_host_address = forms.CharField(label = "BMC IP address")
+ icinga_poll_status = forms.CharField(label = "Icinga poll status")
+
+
+class WrInstallForm(forms.Form):
+ ilo_host_address_list = forms.CharField(label = "BMC IP addresses separated by space")
+
+
+class WrInstallNowForm(forms.Form):
+ ilo_host_address = forms.CharField(label = "BMC IP address")
+ icinga_poll_status = forms.CharField(label = "Icinga poll status")
+
+
+class PushButtonForm(forms.Form):
+ pass
+
+
+class WrRemediateForm(forms.Form):
+ cluster_name_list = forms.CharField(label = "Cluster names separated by space")
+ playbook = forms.ChoiceField(label = "Playbook dict key in settings.py",
+ choices = (("wr", "wr"),
+ ("wr_remediate", "wr_remediate"),
+ ("wr_wipedisk", "wr_wipedisk"),
+ ("wr_ptp", "wr_ptp"),
+ ("wr_ptp_config", "wr_ptp_config"),
+ ("wr_unlock", "wr_unlock"),
+ ("wr_reboot", "wr_reboot"),
+ ("wr_wrap", "wr_wrap")))
+
+
+class WrRebootForm(forms.Form):
+ namespace_name_list = forms.CharField(label = "Namespace names separated by space")
+
+
+#created Oct30 2020 for Raj reboot testing delete later - Soda
+class MockWrRebootForm(forms.Form):
+ namespace_name_list = forms.CharField(label = "Mock namespace names separated by space")
+
+
+class PlaybookReportForm(forms.Form):
+ git = forms.CharField(label = "git remote")
+ playbook = forms.CharField(label = "Playbook dict key in settings.py")
+ target = forms.CharField(label = "Target")
+ failed = forms.CharField(label = "Failed count (0 or 1)")
+
+
+class SubcloudForm(forms.Form):
+ fuze_id = forms.CharField(label = "FUZE ID")
diff --git a/src/caas/migrations/0001_initial.py b/src/caas/migrations/0001_initial.py
index 409c48f..d524cf3 100644
--- a/src/caas/migrations/0001_initial.py
+++ b/src/caas/migrations/0001_initial.py
@@ -1,7 +1,6 @@
-# Generated by Django 3.0.5 on 2020-05-04 16:28
+# Generated by Django 3.0.8 on 2020-07-07 03:12
from django.db import migrations, models
-import django.db.models.deletion
class Migration(migrations.Migration):
@@ -13,62 +12,81 @@ class Migration(migrations.Migration):
operations = [
migrations.CreateModel(
- name='VcpfeLocation',
+ name='FirmwareBatch',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('fuze_spm_site_id', models.CharField(max_length=16)),
- ('fuze_spm_site_name', models.CharField(max_length=255)),
- ('fuze_spm_market', models.CharField(max_length=255)),
- ('fuze_spm_submarket', models.CharField(max_length=255)),
- ('fuze_spm_site_type', models.CharField(choices=[('DRAN', 'DRAN'), ('CRAN', 'CRAN')], max_length=4)),
- ('central_controller_sap_clli', models.CharField(max_length=255)),
- ('vcu_sap_clli', models.CharField(max_length=255)),
- ('csr_hostname', models.CharField(max_length=255)),
- ('f1c_f1u_subnet', models.CharField(max_length=255)),
- ('f1c_f1u_default_gateway', models.CharField(max_length=255)),
- ('oam_subnet', models.CharField(max_length=255)),
- ('oam_default_gateway', models.CharField(max_length=255)),
- ('mgmt_subnet', models.CharField(max_length=255)),
- ('mgmt_default_gateway', models.CharField(max_length=255)),
- ('ilo_subnet', models.CharField(max_length=255)),
- ('ilo_default_gateway', models.CharField(max_length=255)),
- ('fhgw_subnet', models.CharField(max_length=255)),
- ('fhgw_default_gateway', models.CharField(max_length=255)),
+ ('ilo_host_address', models.CharField(blank=True, max_length=255, null=True)),
+ ('ilo_hostname', models.CharField(blank=True, max_length=255, null=True)),
+ ('bmc_username', models.CharField(blank=True, max_length=255, null=True)),
+ ('bmc_password', models.CharField(blank=True, max_length=255, null=True)),
],
+ options={
+ 'db_table': 'caas_firmwarebatch',
+ 'managed': False,
+ },
),
migrations.CreateModel(
- name='Vlan',
+ name='IcingaBmc',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('host_vlan', models.PositiveSmallIntegerField()),
- ('oam_vlan', models.PositiveSmallIntegerField()),
- ('mgmt_vlan', models.PositiveSmallIntegerField()),
+ ('ilo_hostname', models.CharField(blank=True, max_length=255, null=True)),
+ ('ilo_host_address', models.CharField(blank=True, max_length=255, null=True)),
+ ('csr_hostname', models.CharField(blank=True, max_length=255, null=True)),
+ ('oam_default_gateway', models.CharField(blank=True, max_length=255, null=True)),
+ ('latitude', models.CharField(blank=True, max_length=255, null=True)),
+ ('longitude', models.CharField(blank=True, max_length=255, null=True)),
+ ('serial_number', models.CharField(blank=True, max_length=255, null=True)),
+ ('vendor_name', models.CharField(blank=True, max_length=255, null=True)),
+ ('bmc_password_admin_default', models.CharField(blank=True, max_length=255, null=True)),
+ ('bmc_password_admin', models.CharField(blank=True, max_length=255, null=True)),
+ ('bmc_username', models.CharField(blank=True, max_length=255, null=True)),
+ ('bmc_password', models.CharField(blank=True, max_length=255, null=True)),
],
+ options={
+ 'db_table': 'caas_icingabmc',
+ 'managed': False,
+ },
),
migrations.CreateModel(
- name='VcpfeServer',
+ name='IcingaRouter',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('server_number', models.PositiveSmallIntegerField()),
- ('server_hostname', models.CharField(max_length=255)),
- ('cluster_name', models.CharField(max_length=255)),
- ('f1u_address', models.CharField(max_length=255)),
- ('f1c_address', models.CharField(max_length=255)),
- ('oam_host_address', models.CharField(max_length=255)),
- ('oam_vip_address', models.CharField(max_length=255)),
- ('mgmt_address_range_start', models.CharField(max_length=255)),
- ('mgmt_address_range_end', models.CharField(max_length=255)),
- ('ilo_host_address', models.CharField(max_length=255)),
- ('fhgw_host_address', models.CharField(max_length=255)),
- ('vlan_id', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='caas.Vlan')),
+ ('csr_hostname', models.CharField(blank=True, max_length=255, null=True)),
+ ('oam_default_gateway', models.CharField(blank=True, max_length=255, null=True)),
],
+ options={
+ 'db_table': 'caas_icingarouter',
+ 'managed': False,
+ },
),
migrations.CreateModel(
- name='Namespace',
+ name='WrBatch',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('namespace_name', models.CharField(max_length=255)),
- ('server_id', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='caas.VcpfeServer')),
+ ('cluster_id', models.IntegerField()),
+ ('parent_oam_vip_hostname', models.CharField(blank=True, max_length=255, null=True)),
+ ('parent_oam_vip_address', models.CharField(blank=True, max_length=255, null=True)),
+ ('pxe_mac_address', models.CharField(blank=True, max_length=255, null=True)),
+ ('ilo_host_address', models.CharField(blank=True, max_length=255, null=True)),
+ ('oam_hostname', models.CharField(blank=True, max_length=255, null=True)),
+ ('oam_host_address', models.CharField(blank=True, max_length=255, null=True)),
+ ('oam_vip_address', models.CharField(blank=True, max_length=255, null=True)),
+ ('oam_default_gateway', models.CharField(blank=True, max_length=255, null=True)),
+ ('mgmt_address_range_start', models.CharField(blank=True, max_length=255, null=True)),
+ ('mgmt_address_range_end', models.CharField(blank=True, max_length=255, null=True)),
+ ('mgmt_default_gateway', models.CharField(blank=True, max_length=255, null=True)),
+ ('mgmt_subnet', models.CharField(blank=True, max_length=255, null=True)),
+ ('host_vlan', models.PositiveSmallIntegerField()),
+ ('oam_vlan', models.PositiveSmallIntegerField()),
+ ('mgmt_vlan', models.PositiveSmallIntegerField()),
+ ('cluster_name', models.CharField(blank=True, max_length=255, null=True)),
+ ('vendor_name', models.CharField(blank=True, max_length=255, null=True)),
+ ('bmc_username', models.CharField(blank=True, max_length=255, null=True)),
+ ('bmc_password', models.CharField(blank=True, max_length=255, null=True)),
],
+ options={
+ 'db_table': 'caas_wrbatch',
+ 'managed': False,
+ },
),
]
diff --git a/src/caas/migrations/0002_auto_20200706_2113.py b/src/caas/migrations/0002_auto_20200706_2113.py
new file mode 100644
index 0000000..553a4e4
--- /dev/null
+++ b/src/caas/migrations/0002_auto_20200706_2113.py
@@ -0,0 +1,260 @@
+# Generated by Django 3.0.8 on 2020-07-07 03:13
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('caas', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Blade',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('serial_number', models.CharField(blank=True, max_length=255, null=True)),
+ ],
+ ),
+ migrations.CreateModel(
+ name='CellSiteRouter',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('csr_hostname', models.CharField(blank=True, max_length=255, null=True)),
+ ('oam_subnet', models.CharField(blank=True, max_length=255, null=True)),
+ ('oam_default_gateway', models.CharField(blank=True, max_length=255, null=True)),
+ ('mgmt_subnet', models.CharField(blank=True, max_length=255, null=True)),
+ ('mgmt_default_gateway', models.CharField(blank=True, max_length=255, null=True)),
+ ('ilo_subnet', models.CharField(blank=True, max_length=255, null=True)),
+ ('ilo_default_gateway', models.CharField(blank=True, max_length=255, null=True)),
+ ],
+ ),
+ migrations.CreateModel(
+ name='Chassis',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('serial_number', models.CharField(blank=True, max_length=255, null=True)),
+ ],
+ ),
+ migrations.CreateModel(
+ name='Cluster',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('cluster_name', models.CharField(max_length=255)),
+ ('oam_vip_hostname', models.CharField(blank=True, max_length=255, null=True)),
+ ('oam_vip_address', models.CharField(blank=True, max_length=255, null=True)),
+ ('mgmt_address_range_start', models.CharField(blank=True, max_length=255, null=True)),
+ ('mgmt_address_range_end', models.CharField(blank=True, max_length=255, null=True)),
+ ],
+ ),
+ migrations.CreateModel(
+ name='Credential',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('bmc_password_admin_default', models.CharField(blank=True, max_length=255, null=True)),
+ ('bmc_password_admin', models.CharField(blank=True, max_length=255, null=True)),
+ ('bmc_username', models.CharField(blank=True, max_length=255, null=True)),
+ ('bmc_password', models.CharField(blank=True, max_length=255, null=True)),
+ ],
+ ),
+ migrations.CreateModel(
+ name='FirmwareUpgradeSchedule',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('date_scheduled', models.DateTimeField(blank=True, null=True)),
+ ('date_completed', models.DateTimeField(blank=True, null=True)),
+ ('date_last_failed', models.DateTimeField(blank=True, null=True)),
+ ('kirke_ticket_number', models.CharField(blank=True, max_length=255, null=True)),
+ ('kirke_ticket_status', models.CharField(blank=True, max_length=255, null=True)),
+ ('kirke_ticket_completed', models.DateTimeField(blank=True, null=True)),
+ ],
+ ),
+ migrations.CreateModel(
+ name='Location',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('fuze_spm_site_id', models.CharField(max_length=16)),
+ ('fuze_spm_site_name', models.CharField(max_length=255)),
+ ('fuze_spm_market', models.CharField(max_length=255)),
+ ('fuze_spm_submarket', models.CharField(max_length=255)),
+ ('fuze_spm_site_type', models.CharField(choices=[('DRAN', 'DRAN'), ('CRAN', 'CRAN')], max_length=4)),
+ ('latitude', models.DecimalField(blank=True, decimal_places=9, max_digits=12, null=True)),
+ ('longitude', models.DecimalField(blank=True, decimal_places=9, max_digits=12, null=True)),
+ ],
+ ),
+ migrations.CreateModel(
+ name='Namespace',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('namespace_name', models.CharField(max_length=255)),
+ ],
+ ),
+ migrations.CreateModel(
+ name='SapClli',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('clli', models.CharField(blank=True, max_length=255, null=True)),
+ ],
+ ),
+ migrations.CreateModel(
+ name='Server',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('server_number', models.PositiveSmallIntegerField(blank=True, null=True)),
+ ('oam_hostname', models.CharField(blank=True, max_length=255, null=True)),
+ ('oam_host_address', models.CharField(blank=True, max_length=255, null=True)),
+ ('ilo_hostname', models.CharField(max_length=255)),
+ ('ilo_host_address', models.CharField(blank=True, max_length=255, null=True)),
+ ('pxe_mac_address', models.CharField(blank=True, max_length=255, null=True)),
+ ('csr_vdu_port_number', models.CharField(blank=True, max_length=255, null=True)),
+ ('csr_oam_port_number', models.CharField(blank=True, max_length=255, null=True)),
+ ('csr_mgmt_port_number', models.CharField(blank=True, max_length=255, null=True)),
+ ('csr_nfs_port_number', models.CharField(blank=True, max_length=255, null=True)),
+ ('intel_nic_firmware_version', models.CharField(blank=True, max_length=255, null=True)),
+ ],
+ ),
+ migrations.CreateModel(
+ name='Vendor',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('vendor_name', models.CharField(blank=True, max_length=255, null=True)),
+ ],
+ ),
+ migrations.CreateModel(
+ name='Vlan',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('host_vlan', models.PositiveSmallIntegerField()),
+ ('oam_vlan', models.PositiveSmallIntegerField()),
+ ('mgmt_vlan', models.PositiveSmallIntegerField()),
+ ('nfs_vlan', models.PositiveSmallIntegerField(blank=True, null=True)),
+ ],
+ ),
+ migrations.CreateModel(
+ name='WrInstallSchedule',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('date_scheduled', models.DateTimeField(blank=True, null=True)),
+ ('date_completed', models.DateTimeField(blank=True, null=True)),
+ ('date_last_failed', models.DateTimeField(blank=True, null=True)),
+ ('kirke_ticket_number', models.CharField(blank=True, max_length=255, null=True)),
+ ('kirke_ticket_status', models.CharField(blank=True, max_length=255, null=True)),
+ ('kirke_ticket_completed', models.DateTimeField(blank=True, null=True)),
+ ('cluster', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='caas.Cluster')),
+ ],
+ ),
+ migrations.AddConstraint(
+ model_name='vlan',
+ constraint=models.UniqueConstraint(fields=('host_vlan', 'oam_vlan', 'mgmt_vlan', 'nfs_vlan'), name='unique_vlan'),
+ ),
+ migrations.AddConstraint(
+ model_name='vendor',
+ constraint=models.UniqueConstraint(fields=('vendor_name',), name='unique_vendor'),
+ ),
+ migrations.AddField(
+ model_name='server',
+ name='blade',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='caas.Blade'),
+ ),
+ migrations.AddField(
+ model_name='server',
+ name='cluster',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='caas.Cluster'),
+ ),
+ migrations.AddConstraint(
+ model_name='sapclli',
+ constraint=models.UniqueConstraint(fields=('clli',), name='unique_sapclli'),
+ ),
+ migrations.AddConstraint(
+ model_name='namespace',
+ constraint=models.UniqueConstraint(fields=('namespace_name',), name='unique_namespace'),
+ ),
+ migrations.AddConstraint(
+ model_name='location',
+ constraint=models.UniqueConstraint(fields=('fuze_spm_site_id', 'fuze_spm_site_name', 'fuze_spm_market', 'fuze_spm_submarket', 'fuze_spm_site_type'), name='unique_location'),
+ ),
+ migrations.AddField(
+ model_name='firmwareupgradeschedule',
+ name='server',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='caas.Server'),
+ ),
+ migrations.AddConstraint(
+ model_name='credential',
+ constraint=models.UniqueConstraint(fields=('bmc_password_admin_default', 'bmc_password_admin', 'bmc_username', 'bmc_password'), name='unique_credential'),
+ ),
+ migrations.AddField(
+ model_name='cluster',
+ name='csr',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='caas.CellSiteRouter'),
+ ),
+ migrations.AddField(
+ model_name='cluster',
+ name='location',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='caas.Location'),
+ ),
+ migrations.AddField(
+ model_name='cluster',
+ name='namespace',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='caas.Namespace'),
+ ),
+ migrations.AddField(
+ model_name='cluster',
+ name='parent_cluster',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='caas.Cluster'),
+ ),
+ migrations.AddField(
+ model_name='cluster',
+ name='sap_clli',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='caas.SapClli'),
+ ),
+ migrations.AddField(
+ model_name='cluster',
+ name='vlan',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='caas.Vlan'),
+ ),
+ migrations.AddConstraint(
+ model_name='chassis',
+ constraint=models.UniqueConstraint(fields=('serial_number',), name='unique_chassis'),
+ ),
+ migrations.AddConstraint(
+ model_name='cellsiterouter',
+ constraint=models.UniqueConstraint(fields=('csr_hostname',), name='unique_cellsiterouter'),
+ ),
+ migrations.AddField(
+ model_name='blade',
+ name='chassis',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='caas.Chassis'),
+ ),
+ migrations.AddField(
+ model_name='blade',
+ name='credential',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='caas.Credential'),
+ ),
+ migrations.AddField(
+ model_name='blade',
+ name='vendor',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='caas.Vendor'),
+ ),
+ migrations.AddConstraint(
+ model_name='wrinstallschedule',
+ constraint=models.UniqueConstraint(fields=('cluster_id',), name='unique_wrinstallschedule'),
+ ),
+ migrations.AddConstraint(
+ model_name='server',
+ constraint=models.UniqueConstraint(fields=('ilo_host_address',), name='unique_server_byiloaddress'),
+ ),
+ migrations.AddConstraint(
+ model_name='firmwareupgradeschedule',
+ constraint=models.UniqueConstraint(fields=('server_id',), name='unique_firmwareupgradeschedule'),
+ ),
+ migrations.AddConstraint(
+ model_name='cluster',
+ constraint=models.UniqueConstraint(fields=('cluster_name',), name='unique_cluster'),
+ ),
+ migrations.AddConstraint(
+ model_name='blade',
+ constraint=models.UniqueConstraint(fields=('serial_number',), name='unique_blade'),
+ ),
+ ]
diff --git a/src/caas/migrations/0003_auto_20200706_2113.py b/src/caas/migrations/0003_auto_20200706_2113.py
new file mode 100644
index 0000000..fb3c69d
--- /dev/null
+++ b/src/caas/migrations/0003_auto_20200706_2113.py
@@ -0,0 +1,35 @@
+# Generated by Django 3.0.8 on 2020-07-07 03:13
+
+from django.db import migrations
+import django_db_views.migration_functions
+import django_db_views.operations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('caas', '0002_auto_20200706_2113'),
+ ]
+
+ operations = [
+ django_db_views.operations.ViewRunPython(
+ code=django_db_views.migration_functions.ForwardViewMigration('select s.id,\n s.ilo_hostname,\n s.ilo_host_address,\n l.id as location_id,\n csr.oam_default_gateway,\n l.latitude,\n l.longitude,\n csr.csr_hostname,\n b.serial_number,\n v.vendor_name,\n cr.bmc_password_admin_default,\n cr.bmc_password_admin,\n cr.bmc_username,\n cr.bmc_password\nfrom caas_server s\ninner join caas_cluster c\n on s.cluster_id = c.id\ninner join caas_location l\n on c.location_id = l.id\ninner join caas_cellsiterouter csr\n on c.csr_id = csr.id\nleft outer join caas_blade b\n on s.blade_id = b.id\nleft outer join caas_vendor v\n on b.vendor_id = v.id\nleft outer join caas_credential cr\n on b.credential_id = cr.id\nwhere c.parent_cluster_id is not null', 'caas_icingabmc'),
+ reverse_code=django_db_views.migration_functions.BackwardViewMigration('', 'caas_icingabmc'),
+ atomic=False,
+ ),
+ django_db_views.operations.ViewRunPython(
+ code=django_db_views.migration_functions.ForwardViewMigration('select location_id as id,\n csr_hostname,\n oam_default_gateway\nfrom caas_icingabmc\ngroup by location_id,\n csr_hostname,\n oam_default_gateway', 'caas_icingarouter'),
+ reverse_code=django_db_views.migration_functions.BackwardViewMigration('', 'caas_icingarouter'),
+ atomic=False,
+ ),
+ django_db_views.operations.ViewRunPython(
+ code=django_db_views.migration_functions.ForwardViewMigration('select s.id,\n s.ilo_hostname,\n s.ilo_host_address,\n cr.bmc_username,\n cr.bmc_password\nfrom caas_server s\ninner join caas_cluster c\n on s.cluster_id = c.id\nleft outer join caas_blade b\n on s.blade_id = b.id\nleft outer join caas_credential cr\n on b.credential_id = cr.id\nwhere c.parent_cluster_id is not null', 'caas_firmwarebatch'),
+ reverse_code=django_db_views.migration_functions.BackwardViewMigration('', 'caas_firmwarebatch'),
+ atomic=False,
+ ),
+ django_db_views.operations.ViewRunPython(
+ code=django_db_views.migration_functions.ForwardViewMigration("select s.id,\n c.id as cluster_id,\n cp.oam_vip_hostname as parent_oam_vip_hostname,\n cp.oam_vip_address as parent_oam_vip_address,\n s.pxe_mac_address,\n s.ilo_host_address,\n s.oam_hostname,\n s.oam_host_address,\n c.oam_vip_address,\n csr.oam_default_gateway,\n c.mgmt_address_range_start,\n c.mgmt_address_range_end,\n csr.mgmt_default_gateway,\n csr.mgmt_subnet,\n vl.host_vlan,\n vl.oam_vlan,\n vl.mgmt_vlan,\n c.cluster_name,\n v.vendor_name,\n cr.bmc_username,\n cr.bmc_password\nfrom caas_server s\ninner join caas_cluster c\n on s.cluster_id = c.id\nleft outer join caas_cluster cp\n on c.parent_cluster_id = cp.id\ninner join caas_cellsiterouter csr\n on c.csr_id = csr.id\ninner join caas_location l\n on c.location_id = l.id\ninner join caas_vlan vl\n on c.vlan_id = vl.id\nleft outer join caas_blade b\n on s.blade_id = b.id\nleft outer join caas_vendor v\n on b.vendor_id = v.id\nleft outer join caas_credential cr\n on b.credential_id = cr.id\nwhere c.parent_cluster_id is not null\n and s.intel_nic_firmware_version = '1.2585.0'", 'caas_wrbatch'),
+ reverse_code=django_db_views.migration_functions.BackwardViewMigration('', 'caas_wrbatch'),
+ atomic=False,
+ ),
+ ]
diff --git a/src/caas/migrations/0004_delete_wrbatch.py b/src/caas/migrations/0004_delete_wrbatch.py
new file mode 100644
index 0000000..a3e0e4d
--- /dev/null
+++ b/src/caas/migrations/0004_delete_wrbatch.py
@@ -0,0 +1,16 @@
+# Generated by Django 3.0.8 on 2020-07-11 04:34
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('caas', '0003_auto_20200706_2113'),
+ ]
+
+ operations = [
+ migrations.DeleteModel(
+ name='WrBatch',
+ ),
+ ]
diff --git a/src/caas/migrations/0005_auto_20200710_2235.py b/src/caas/migrations/0005_auto_20200710_2235.py
new file mode 100644
index 0000000..8ca77db
--- /dev/null
+++ b/src/caas/migrations/0005_auto_20200710_2235.py
@@ -0,0 +1,20 @@
+# Generated by Django 3.0.8 on 2020-07-11 04:35
+
+from django.db import migrations
+import django_db_views.migration_functions
+import django_db_views.operations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('caas', '0004_delete_wrbatch'),
+ ]
+
+ operations = [
+ django_db_views.operations.ViewRunPython(
+ code=django_db_views.migration_functions.ForwardViewMigration('select s.id,\n s.ilo_hostname,\n s.ilo_host_address,\n s.intel_nic_firmware_version,\n cr.bmc_username,\n cr.bmc_password\nfrom caas_server s\ninner join caas_cluster c\n on s.cluster_id = c.id\nleft outer join caas_blade b\n on s.blade_id = b.id\nleft outer join caas_credential cr\n on b.credential_id = cr.id\nwhere c.parent_cluster_id is not null', 'caas_firmwarebatch'),
+ reverse_code=django_db_views.migration_functions.BackwardViewMigration('select s.id,\n s.ilo_hostname,\n s.ilo_host_address,\n cr.bmc_username,\n cr.bmc_password\nfrom caas_server s\ninner join caas_cluster c\n on s.cluster_id = c.id\nleft outer join caas_blade b\n on s.blade_id = b.id\nleft outer join caas_credential cr\n on b.credential_id = cr.id\nwhere c.parent_cluster_id is not null', 'caas_firmwarebatch'),
+ atomic=False,
+ ),
+ ]
diff --git a/src/caas/migrations/0006_wrbatch.py b/src/caas/migrations/0006_wrbatch.py
new file mode 100644
index 0000000..52cb599
--- /dev/null
+++ b/src/caas/migrations/0006_wrbatch.py
@@ -0,0 +1,43 @@
+# Generated by Django 3.0.8 on 2020-07-11 04:50
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('caas', '0005_auto_20200710_2235'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='WrBatch',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('cluster_id', models.IntegerField()),
+ ('parent_oam_vip_hostname', models.CharField(blank=True, max_length=255, null=True)),
+ ('parent_oam_vip_address', models.CharField(blank=True, max_length=255, null=True)),
+ ('pxe_mac_address', models.CharField(blank=True, max_length=255, null=True)),
+ ('ilo_host_address', models.CharField(blank=True, max_length=255, null=True)),
+ ('oam_hostname', models.CharField(blank=True, max_length=255, null=True)),
+ ('oam_host_address', models.CharField(blank=True, max_length=255, null=True)),
+ ('oam_vip_address', models.CharField(blank=True, max_length=255, null=True)),
+ ('oam_default_gateway', models.CharField(blank=True, max_length=255, null=True)),
+ ('mgmt_address_range_start', models.CharField(blank=True, max_length=255, null=True)),
+ ('mgmt_address_range_end', models.CharField(blank=True, max_length=255, null=True)),
+ ('mgmt_default_gateway', models.CharField(blank=True, max_length=255, null=True)),
+ ('mgmt_subnet', models.CharField(blank=True, max_length=255, null=True)),
+ ('host_vlan', models.PositiveSmallIntegerField()),
+ ('oam_vlan', models.PositiveSmallIntegerField()),
+ ('mgmt_vlan', models.PositiveSmallIntegerField()),
+ ('cluster_name', models.CharField(blank=True, max_length=255, null=True)),
+ ('vendor_name', models.CharField(blank=True, max_length=255, null=True)),
+ ('bmc_username', models.CharField(blank=True, max_length=255, null=True)),
+ ('bmc_password', models.CharField(blank=True, max_length=255, null=True)),
+ ],
+ options={
+ 'db_table': 'caas_wrbatch',
+ 'managed': False,
+ },
+ ),
+ ]
diff --git a/src/caas/migrations/0007_auto_20200711_1126.py b/src/caas/migrations/0007_auto_20200711_1126.py
new file mode 100644
index 0000000..a8911d6
--- /dev/null
+++ b/src/caas/migrations/0007_auto_20200711_1126.py
@@ -0,0 +1,20 @@
+# Generated by Django 3.0.8 on 2020-07-11 17:26
+
+from django.db import migrations
+import django_db_views.migration_functions
+import django_db_views.operations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('caas', '0006_wrbatch'),
+ ]
+
+ operations = [
+ django_db_views.operations.ViewRunPython(
+ code=django_db_views.migration_functions.ForwardViewMigration('select s.id,\n c.id as cluster_id,\n cp.oam_vip_hostname as parent_oam_vip_hostname,\n cp.oam_vip_address as parent_oam_vip_address,\n s.pxe_mac_address,\n s.ilo_host_address,\n s.oam_hostname,\n s.oam_host_address,\n c.oam_vip_address,\n csr.oam_default_gateway,\n c.mgmt_address_range_start,\n c.mgmt_address_range_end,\n csr.mgmt_default_gateway,\n csr.mgmt_subnet,\n vl.host_vlan,\n vl.oam_vlan,\n vl.mgmt_vlan,\n c.cluster_name,\n v.vendor_name,\n cr.bmc_username,\n cr.bmc_password\nfrom caas_server s\ninner join caas_cluster c\n on s.cluster_id = c.id\nleft outer join caas_cluster cp\n on c.parent_cluster_id = cp.id\ninner join caas_cellsiterouter csr\n on c.csr_id = csr.id\ninner join caas_location l\n on c.location_id = l.id\ninner join caas_vlan vl\n on c.vlan_id = vl.id\nleft outer join caas_blade b\n on s.blade_id = b.id\nleft outer join caas_vendor v\n on b.vendor_id = v.id\nleft outer join caas_credential cr\n on b.credential_id = cr.id\nwhere c.parent_cluster_id is not null', 'caas_wrbatch'),
+ reverse_code=django_db_views.migration_functions.BackwardViewMigration("select s.id,\n c.id as cluster_id,\n cp.oam_vip_hostname as parent_oam_vip_hostname,\n cp.oam_vip_address as parent_oam_vip_address,\n s.pxe_mac_address,\n s.ilo_host_address,\n s.oam_hostname,\n s.oam_host_address,\n c.oam_vip_address,\n csr.oam_default_gateway,\n c.mgmt_address_range_start,\n c.mgmt_address_range_end,\n csr.mgmt_default_gateway,\n csr.mgmt_subnet,\n vl.host_vlan,\n vl.oam_vlan,\n vl.mgmt_vlan,\n c.cluster_name,\n v.vendor_name,\n cr.bmc_username,\n cr.bmc_password\nfrom caas_server s\ninner join caas_cluster c\n on s.cluster_id = c.id\nleft outer join caas_cluster cp\n on c.parent_cluster_id = cp.id\ninner join caas_cellsiterouter csr\n on c.csr_id = csr.id\ninner join caas_location l\n on c.location_id = l.id\ninner join caas_vlan vl\n on c.vlan_id = vl.id\nleft outer join caas_blade b\n on s.blade_id = b.id\nleft outer join caas_vendor v\n on b.vendor_id = v.id\nleft outer join caas_credential cr\n on b.credential_id = cr.id\nwhere c.parent_cluster_id is not null\n and s.intel_nic_firmware_version = '1.2585.0'", 'caas_wrbatch'),
+ atomic=False,
+ ),
+ ]
diff --git a/src/caas/migrations/0008_auto_20200711_1127.py b/src/caas/migrations/0008_auto_20200711_1127.py
new file mode 100644
index 0000000..8808699
--- /dev/null
+++ b/src/caas/migrations/0008_auto_20200711_1127.py
@@ -0,0 +1,20 @@
+# Generated by Django 3.0.8 on 2020-07-11 17:27
+
+from django.db import migrations
+import django_db_views.migration_functions
+import django_db_views.operations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('caas', '0007_auto_20200711_1126'),
+ ]
+
+ operations = [
+ django_db_views.operations.ViewRunPython(
+ code=django_db_views.migration_functions.ForwardViewMigration('select s.id,\n c.id as cluster_id,\n cp.oam_vip_hostname as parent_oam_vip_hostname,\n cp.oam_vip_address as parent_oam_vip_address,\n s.pxe_mac_address,\n s.ilo_host_address,\n s.oam_hostname,\n s.oam_host_address,\n s.intel_nic_firmware_version,\n c.oam_vip_address,\n csr.oam_default_gateway,\n c.mgmt_address_range_start,\n c.mgmt_address_range_end,\n csr.mgmt_default_gateway,\n csr.mgmt_subnet,\n vl.host_vlan,\n vl.oam_vlan,\n vl.mgmt_vlan,\n c.cluster_name,\n v.vendor_name,\n cr.bmc_username,\n cr.bmc_password\nfrom caas_server s\ninner join caas_cluster c\n on s.cluster_id = c.id\nleft outer join caas_cluster cp\n on c.parent_cluster_id = cp.id\ninner join caas_cellsiterouter csr\n on c.csr_id = csr.id\ninner join caas_location l\n on c.location_id = l.id\ninner join caas_vlan vl\n on c.vlan_id = vl.id\nleft outer join caas_blade b\n on s.blade_id = b.id\nleft outer join caas_vendor v\n on b.vendor_id = v.id\nleft outer join caas_credential cr\n on b.credential_id = cr.id\nwhere c.parent_cluster_id is not null', 'caas_wrbatch'),
+ reverse_code=django_db_views.migration_functions.BackwardViewMigration('select s.id,\n c.id as cluster_id,\n cp.oam_vip_hostname as parent_oam_vip_hostname,\n cp.oam_vip_address as parent_oam_vip_address,\n s.pxe_mac_address,\n s.ilo_host_address,\n s.oam_hostname,\n s.oam_host_address,\n c.oam_vip_address,\n csr.oam_default_gateway,\n c.mgmt_address_range_start,\n c.mgmt_address_range_end,\n csr.mgmt_default_gateway,\n csr.mgmt_subnet,\n vl.host_vlan,\n vl.oam_vlan,\n vl.mgmt_vlan,\n c.cluster_name,\n v.vendor_name,\n cr.bmc_username,\n cr.bmc_password\nfrom caas_server s\ninner join caas_cluster c\n on s.cluster_id = c.id\nleft outer join caas_cluster cp\n on c.parent_cluster_id = cp.id\ninner join caas_cellsiterouter csr\n on c.csr_id = csr.id\ninner join caas_location l\n on c.location_id = l.id\ninner join caas_vlan vl\n on c.vlan_id = vl.id\nleft outer join caas_blade b\n on s.blade_id = b.id\nleft outer join caas_vendor v\n on b.vendor_id = v.id\nleft outer join caas_credential cr\n on b.credential_id = cr.id\nwhere c.parent_cluster_id is not null', 'caas_wrbatch'),
+ atomic=False,
+ ),
+ ]
diff --git a/src/caas/migrations/0009_auto_20200715_1630.py b/src/caas/migrations/0009_auto_20200715_1630.py
new file mode 100644
index 0000000..204b615
--- /dev/null
+++ b/src/caas/migrations/0009_auto_20200715_1630.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.0.8 on 2020-07-15 22:30
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('caas', '0008_auto_20200711_1127'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='location',
+ name='fuze_spm_site_type',
+ field=models.CharField(choices=[('SAP', 'SAP'), ('DRAN', 'DRAN'), ('CRAN', 'CRAN')], max_length=4),
+ ),
+ ]
diff --git a/src/caas/migrations/0010_auto_20200720_1413.py b/src/caas/migrations/0010_auto_20200720_1413.py
new file mode 100644
index 0000000..544b7f3
--- /dev/null
+++ b/src/caas/migrations/0010_auto_20200720_1413.py
@@ -0,0 +1,20 @@
+# Generated by Django 3.0.8 on 2020-07-20 20:13
+
+from django.db import migrations
+import django_db_views.migration_functions
+import django_db_views.operations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('caas', '0009_auto_20200715_1630'),
+ ]
+
+ operations = [
+ django_db_views.operations.ViewRunPython(
+ code=django_db_views.migration_functions.ForwardViewMigration('select s.id,\n c.id as cluster_id,\n cp.oam_vip_hostname as parent_oam_vip_hostname,\n cp.oam_vip_address as parent_oam_vip_address,\n cp.mgmt_address_range_start as parent_mgmt_address_range_start,\n cp.mgmt_address_range_end as parent_mgmt_address_range_end,\n s.pxe_mac_address,\n s.ilo_host_address,\n s.oam_hostname,\n s.oam_host_address,\n s.intel_nic_firmware_version,\n c.oam_vip_address,\n csr.oam_default_gateway,\n c.mgmt_address_range_start,\n c.mgmt_address_range_end,\n csr.mgmt_default_gateway,\n csr.mgmt_subnet,\n vl.host_vlan,\n vl.oam_vlan,\n vl.mgmt_vlan,\n c.cluster_name,\n v.vendor_name,\n cr.bmc_username,\n cr.bmc_password\nfrom caas_server s\ninner join caas_cluster c\n on s.cluster_id = c.id\nleft outer join caas_cluster cp\n on c.parent_cluster_id = cp.id\ninner join caas_cellsiterouter csr\n on c.csr_id = csr.id\ninner join caas_location l\n on c.location_id = l.id\ninner join caas_vlan vl\n on c.vlan_id = vl.id\nleft outer join caas_blade b\n on s.blade_id = b.id\nleft outer join caas_vendor v\n on b.vendor_id = v.id\nleft outer join caas_credential cr\n on b.credential_id = cr.id\nwhere c.parent_cluster_id is not null', 'caas_wrbatch'),
+ reverse_code=django_db_views.migration_functions.BackwardViewMigration('select s.id,\n c.id as cluster_id,\n cp.oam_vip_hostname as parent_oam_vip_hostname,\n cp.oam_vip_address as parent_oam_vip_address,\n s.pxe_mac_address,\n s.ilo_host_address,\n s.oam_hostname,\n s.oam_host_address,\n s.intel_nic_firmware_version,\n c.oam_vip_address,\n csr.oam_default_gateway,\n c.mgmt_address_range_start,\n c.mgmt_address_range_end,\n csr.mgmt_default_gateway,\n csr.mgmt_subnet,\n vl.host_vlan,\n vl.oam_vlan,\n vl.mgmt_vlan,\n c.cluster_name,\n v.vendor_name,\n cr.bmc_username,\n cr.bmc_password\nfrom caas_server s\ninner join caas_cluster c\n on s.cluster_id = c.id\nleft outer join caas_cluster cp\n on c.parent_cluster_id = cp.id\ninner join caas_cellsiterouter csr\n on c.csr_id = csr.id\ninner join caas_location l\n on c.location_id = l.id\ninner join caas_vlan vl\n on c.vlan_id = vl.id\nleft outer join caas_blade b\n on s.blade_id = b.id\nleft outer join caas_vendor v\n on b.vendor_id = v.id\nleft outer join caas_credential cr\n on b.credential_id = cr.id\nwhere c.parent_cluster_id is not null', 'caas_wrbatch'),
+ atomic=False,
+ ),
+ ]
diff --git a/src/caas/migrations/0011_auto_20200720_1525.py b/src/caas/migrations/0011_auto_20200720_1525.py
new file mode 100644
index 0000000..158bdb1
--- /dev/null
+++ b/src/caas/migrations/0011_auto_20200720_1525.py
@@ -0,0 +1,20 @@
+# Generated by Django 3.0.8 on 2020-07-20 21:25
+
+from django.db import migrations
+import django_db_views.migration_functions
+import django_db_views.operations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('caas', '0010_auto_20200720_1413'),
+ ]
+
+ operations = [
+ django_db_views.operations.ViewRunPython(
+ code=django_db_views.migration_functions.ForwardViewMigration('select s.id,\n c.id as cluster_id,\n cp.oam_vip_hostname as parent_oam_vip_hostname,\n cp.oam_vip_address as parent_oam_vip_address,\n cp.mgmt_address_range_start as parent_mgmt_address_range_start,\n cp.mgmt_address_range_end as parent_mgmt_address_range_end,\n csrp.mgmt_default_gateway as parent_mgmt_default_gateway,\n s.pxe_mac_address,\n s.ilo_host_address,\n s.oam_hostname,\n s.oam_host_address,\n s.intel_nic_firmware_version,\n c.oam_vip_address,\n csr.oam_default_gateway,\n c.mgmt_address_range_start,\n c.mgmt_address_range_end,\n csr.mgmt_default_gateway,\n csr.mgmt_subnet,\n vl.host_vlan,\n vl.oam_vlan,\n vl.mgmt_vlan,\n c.cluster_name,\n v.vendor_name,\n cr.bmc_username,\n cr.bmc_password\nfrom caas_server s\ninner join caas_cluster c\n on s.cluster_id = c.id\nleft outer join caas_cluster cp\n on c.parent_cluster_id = cp.id\ninner join caas_cellsiterouter csr\n on c.csr_id = csr.id\ninner join caas_cellsiterouter csrp\n on cp.csr_id = csrp.id\ninner join caas_location l\n on c.location_id = l.id\ninner join caas_vlan vl\n on c.vlan_id = vl.id\nleft outer join caas_blade b\n on s.blade_id = b.id\nleft outer join caas_vendor v\n on b.vendor_id = v.id\nleft outer join caas_credential cr\n on b.credential_id = cr.id\nwhere c.parent_cluster_id is not null', 'caas_wrbatch'),
+ reverse_code=django_db_views.migration_functions.BackwardViewMigration('select s.id,\n c.id as cluster_id,\n cp.oam_vip_hostname as parent_oam_vip_hostname,\n cp.oam_vip_address as parent_oam_vip_address,\n cp.mgmt_address_range_start as parent_mgmt_address_range_start,\n cp.mgmt_address_range_end as parent_mgmt_address_range_end,\n s.pxe_mac_address,\n s.ilo_host_address,\n s.oam_hostname,\n s.oam_host_address,\n s.intel_nic_firmware_version,\n c.oam_vip_address,\n csr.oam_default_gateway,\n c.mgmt_address_range_start,\n c.mgmt_address_range_end,\n csr.mgmt_default_gateway,\n csr.mgmt_subnet,\n vl.host_vlan,\n vl.oam_vlan,\n vl.mgmt_vlan,\n c.cluster_name,\n v.vendor_name,\n cr.bmc_username,\n cr.bmc_password\nfrom caas_server s\ninner join caas_cluster c\n on s.cluster_id = c.id\nleft outer join caas_cluster cp\n on c.parent_cluster_id = cp.id\ninner join caas_cellsiterouter csr\n on c.csr_id = csr.id\ninner join caas_location l\n on c.location_id = l.id\ninner join caas_vlan vl\n on c.vlan_id = vl.id\nleft outer join caas_blade b\n on s.blade_id = b.id\nleft outer join caas_vendor v\n on b.vendor_id = v.id\nleft outer join caas_credential cr\n on b.credential_id = cr.id\nwhere c.parent_cluster_id is not null', 'caas_wrbatch'),
+ atomic=False,
+ ),
+ ]
diff --git a/src/caas/migrations/0012_auto_20200721_1540.py b/src/caas/migrations/0012_auto_20200721_1540.py
new file mode 100644
index 0000000..dc5169b
--- /dev/null
+++ b/src/caas/migrations/0012_auto_20200721_1540.py
@@ -0,0 +1,20 @@
+# Generated by Django 3.0.8 on 2020-07-21 21:40
+
+from django.db import migrations
+import django_db_views.migration_functions
+import django_db_views.operations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('caas', '0011_auto_20200720_1525'),
+ ]
+
+ operations = [
+ django_db_views.operations.ViewRunPython(
+ code=django_db_views.migration_functions.ForwardViewMigration('select s.id,\n c.id as cluster_id,\n cp.oam_vip_hostname as parent_oam_vip_hostname,\n cp.oam_vip_address as parent_oam_vip_address,\n cp.mgmt_address_range_start as parent_mgmt_address_range_start,\n cp.mgmt_address_range_end as parent_mgmt_address_range_end,\n csrp.mgmt_default_gateway as parent_mgmt_default_gateway,\n s.pxe_mac_address,\n s.ilo_host_address,\n s.oam_hostname,\n s.oam_host_address,\n s.intel_nic_firmware_version,\n c.oam_vip_address,\n csr.oam_default_gateway,\n c.mgmt_address_range_start,\n c.mgmt_address_range_end,\n csr.mgmt_default_gateway,\n csr.mgmt_subnet,\n vl.host_vlan,\n vl.oam_vlan,\n vl.mgmt_vlan,\n c.cluster_name,\n cp.cluster_name as parent_cluster_name,\n v.vendor_name,\n cr.bmc_username,\n cr.bmc_password\nfrom caas_server s\ninner join caas_cluster c\n on s.cluster_id = c.id\nleft outer join caas_cluster cp\n on c.parent_cluster_id = cp.id\ninner join caas_cellsiterouter csr\n on c.csr_id = csr.id\ninner join caas_cellsiterouter csrp\n on cp.csr_id = csrp.id\ninner join caas_location l\n on c.location_id = l.id\ninner join caas_vlan vl\n on c.vlan_id = vl.id\nleft outer join caas_blade b\n on s.blade_id = b.id\nleft outer join caas_vendor v\n on b.vendor_id = v.id\nleft outer join caas_credential cr\n on b.credential_id = cr.id\nwhere c.parent_cluster_id is not null', 'caas_wrbatch'),
+ reverse_code=django_db_views.migration_functions.BackwardViewMigration('select s.id,\n c.id as cluster_id,\n cp.oam_vip_hostname as parent_oam_vip_hostname,\n cp.oam_vip_address as parent_oam_vip_address,\n cp.mgmt_address_range_start as parent_mgmt_address_range_start,\n cp.mgmt_address_range_end as parent_mgmt_address_range_end,\n csrp.mgmt_default_gateway as parent_mgmt_default_gateway,\n s.pxe_mac_address,\n s.ilo_host_address,\n s.oam_hostname,\n s.oam_host_address,\n s.intel_nic_firmware_version,\n c.oam_vip_address,\n csr.oam_default_gateway,\n c.mgmt_address_range_start,\n c.mgmt_address_range_end,\n csr.mgmt_default_gateway,\n csr.mgmt_subnet,\n vl.host_vlan,\n vl.oam_vlan,\n vl.mgmt_vlan,\n c.cluster_name,\n v.vendor_name,\n cr.bmc_username,\n cr.bmc_password\nfrom caas_server s\ninner join caas_cluster c\n on s.cluster_id = c.id\nleft outer join caas_cluster cp\n on c.parent_cluster_id = cp.id\ninner join caas_cellsiterouter csr\n on c.csr_id = csr.id\ninner join caas_cellsiterouter csrp\n on cp.csr_id = csrp.id\ninner join caas_location l\n on c.location_id = l.id\ninner join caas_vlan vl\n on c.vlan_id = vl.id\nleft outer join caas_blade b\n on s.blade_id = b.id\nleft outer join caas_vendor v\n on b.vendor_id = v.id\nleft outer join caas_credential cr\n on b.credential_id = cr.id\nwhere c.parent_cluster_id is not null', 'caas_wrbatch'),
+ atomic=False,
+ ),
+ ]
diff --git a/src/caas/migrations/0013_auto_20200728_2359.py b/src/caas/migrations/0013_auto_20200728_2359.py
new file mode 100644
index 0000000..83e8998
--- /dev/null
+++ b/src/caas/migrations/0013_auto_20200728_2359.py
@@ -0,0 +1,31 @@
+# Generated by Django 3.0.8 on 2020-07-29 05:59
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('caas', '0012_auto_20200721_1540'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='PatchSchedule',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('date_scheduled', models.DateTimeField(blank=True, null=True)),
+ ('date_completed', models.DateTimeField(blank=True, null=True)),
+ ('date_last_failed', models.DateTimeField(blank=True, null=True)),
+ ('kirke_ticket_number', models.CharField(blank=True, max_length=255, null=True)),
+ ('kirke_ticket_status', models.CharField(blank=True, max_length=255, null=True)),
+ ('kirke_ticket_completed', models.DateTimeField(blank=True, null=True)),
+ ('cluster', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='caas.Cluster')),
+ ],
+ ),
+ migrations.AddConstraint(
+ model_name='patchschedule',
+ constraint=models.UniqueConstraint(fields=('cluster_id',), name='unique_patchschedule'),
+ ),
+ ]
diff --git a/src/caas/migrations/0014_auto_20200803_1931.py b/src/caas/migrations/0014_auto_20200803_1931.py
new file mode 100644
index 0000000..793d1c3
--- /dev/null
+++ b/src/caas/migrations/0014_auto_20200803_1931.py
@@ -0,0 +1,20 @@
+# Generated by Django 3.0.8 on 2020-08-04 01:31
+
+from django.db import migrations
+import django_db_views.migration_functions
+import django_db_views.operations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('caas', '0013_auto_20200728_2359'),
+ ]
+
+ operations = [
+ django_db_views.operations.ViewRunPython(
+ code=django_db_views.migration_functions.ForwardViewMigration('select s.id,\n c.id as cluster_id,\n l.fuze_spm_site_id,\n cp.oam_vip_hostname as parent_oam_vip_hostname,\n cp.oam_vip_address as parent_oam_vip_address,\n cp.mgmt_address_range_start as parent_mgmt_address_range_start,\n cp.mgmt_address_range_end as parent_mgmt_address_range_end,\n csrp.mgmt_default_gateway as parent_mgmt_default_gateway,\n s.pxe_mac_address,\n s.ilo_host_address,\n s.oam_hostname,\n s.oam_host_address,\n s.intel_nic_firmware_version,\n c.oam_vip_address,\n csr.oam_default_gateway,\n c.mgmt_address_range_start,\n c.mgmt_address_range_end,\n csr.mgmt_default_gateway,\n csr.mgmt_subnet,\n vl.host_vlan,\n vl.oam_vlan,\n vl.mgmt_vlan,\n c.cluster_name,\n cp.cluster_name as parent_cluster_name,\n v.vendor_name,\n cr.bmc_username,\n cr.bmc_password\nfrom caas_server s\ninner join caas_cluster c\n on s.cluster_id = c.id\nleft outer join caas_cluster cp\n on c.parent_cluster_id = cp.id\ninner join caas_cellsiterouter csr\n on c.csr_id = csr.id\ninner join caas_cellsiterouter csrp\n on cp.csr_id = csrp.id\ninner join caas_location l\n on c.location_id = l.id\ninner join caas_vlan vl\n on c.vlan_id = vl.id\nleft outer join caas_blade b\n on s.blade_id = b.id\nleft outer join caas_vendor v\n on b.vendor_id = v.id\nleft outer join caas_credential cr\n on b.credential_id = cr.id\nwhere c.parent_cluster_id is not null', 'caas_wrbatch'),
+ reverse_code=django_db_views.migration_functions.BackwardViewMigration('select s.id,\n c.id as cluster_id,\n cp.oam_vip_hostname as parent_oam_vip_hostname,\n cp.oam_vip_address as parent_oam_vip_address,\n cp.mgmt_address_range_start as parent_mgmt_address_range_start,\n cp.mgmt_address_range_end as parent_mgmt_address_range_end,\n csrp.mgmt_default_gateway as parent_mgmt_default_gateway,\n s.pxe_mac_address,\n s.ilo_host_address,\n s.oam_hostname,\n s.oam_host_address,\n s.intel_nic_firmware_version,\n c.oam_vip_address,\n csr.oam_default_gateway,\n c.mgmt_address_range_start,\n c.mgmt_address_range_end,\n csr.mgmt_default_gateway,\n csr.mgmt_subnet,\n vl.host_vlan,\n vl.oam_vlan,\n vl.mgmt_vlan,\n c.cluster_name,\n cp.cluster_name as parent_cluster_name,\n v.vendor_name,\n cr.bmc_username,\n cr.bmc_password\nfrom caas_server s\ninner join caas_cluster c\n on s.cluster_id = c.id\nleft outer join caas_cluster cp\n on c.parent_cluster_id = cp.id\ninner join caas_cellsiterouter csr\n on c.csr_id = csr.id\ninner join caas_cellsiterouter csrp\n on cp.csr_id = csrp.id\ninner join caas_location l\n on c.location_id = l.id\ninner join caas_vlan vl\n on c.vlan_id = vl.id\nleft outer join caas_blade b\n on s.blade_id = b.id\nleft outer join caas_vendor v\n on b.vendor_id = v.id\nleft outer join caas_credential cr\n on b.credential_id = cr.id\nwhere c.parent_cluster_id is not null', 'caas_wrbatch'),
+ atomic=False,
+ ),
+ ]
diff --git a/src/caas/migrations/0015_auto_20200804_1404.py b/src/caas/migrations/0015_auto_20200804_1404.py
new file mode 100644
index 0000000..11c1150
--- /dev/null
+++ b/src/caas/migrations/0015_auto_20200804_1404.py
@@ -0,0 +1,20 @@
+# Generated by Django 3.1 on 2020-08-04 20:04
+
+from django.db import migrations
+import django_db_views.migration_functions
+import django_db_views.operations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('caas', '0014_auto_20200803_1931'),
+ ]
+
+ operations = [
+ django_db_views.operations.ViewRunPython(
+ code=django_db_views.migration_functions.ForwardViewMigration('select s.id,\n c.id as cluster_id,\n l.fuze_spm_site_id,\n cp.oam_vip_hostname as parent_oam_vip_hostname,\n cp.oam_vip_address as parent_oam_vip_address,\n cp.mgmt_address_range_start as parent_mgmt_address_range_start,\n cp.mgmt_address_range_end as parent_mgmt_address_range_end,\n csrp.mgmt_default_gateway as parent_mgmt_default_gateway,\n csrp.mgmt_subnet as parent_mgmt_subnet,\n s.pxe_mac_address,\n s.ilo_host_address,\n s.oam_hostname,\n s.oam_host_address,\n s.intel_nic_firmware_version,\n c.oam_vip_address,\n csr.oam_default_gateway,\n c.mgmt_address_range_start,\n c.mgmt_address_range_end,\n csr.mgmt_default_gateway,\n csr.mgmt_subnet,\n vl.host_vlan,\n vl.oam_vlan,\n vl.mgmt_vlan,\n c.cluster_name,\n cp.cluster_name as parent_cluster_name,\n v.vendor_name,\n cr.bmc_username,\n cr.bmc_password\nfrom caas_server s\ninner join caas_cluster c\n on s.cluster_id = c.id\nleft outer join caas_cluster cp\n on c.parent_cluster_id = cp.id\ninner join caas_cellsiterouter csr\n on c.csr_id = csr.id\ninner join caas_cellsiterouter csrp\n on cp.csr_id = csrp.id\ninner join caas_location l\n on c.location_id = l.id\ninner join caas_vlan vl\n on c.vlan_id = vl.id\nleft outer join caas_blade b\n on s.blade_id = b.id\nleft outer join caas_vendor v\n on b.vendor_id = v.id\nleft outer join caas_credential cr\n on b.credential_id = cr.id\nwhere c.parent_cluster_id is not null', 'caas_wrbatch'),
+ reverse_code=django_db_views.migration_functions.BackwardViewMigration('select s.id,\n c.id as cluster_id,\n l.fuze_spm_site_id,\n cp.oam_vip_hostname as parent_oam_vip_hostname,\n cp.oam_vip_address as parent_oam_vip_address,\n cp.mgmt_address_range_start as parent_mgmt_address_range_start,\n cp.mgmt_address_range_end as parent_mgmt_address_range_end,\n csrp.mgmt_default_gateway as parent_mgmt_default_gateway,\n s.pxe_mac_address,\n s.ilo_host_address,\n s.oam_hostname,\n s.oam_host_address,\n s.intel_nic_firmware_version,\n c.oam_vip_address,\n csr.oam_default_gateway,\n c.mgmt_address_range_start,\n c.mgmt_address_range_end,\n csr.mgmt_default_gateway,\n csr.mgmt_subnet,\n vl.host_vlan,\n vl.oam_vlan,\n vl.mgmt_vlan,\n c.cluster_name,\n cp.cluster_name as parent_cluster_name,\n v.vendor_name,\n cr.bmc_username,\n cr.bmc_password\nfrom caas_server s\ninner join caas_cluster c\n on s.cluster_id = c.id\nleft outer join caas_cluster cp\n on c.parent_cluster_id = cp.id\ninner join caas_cellsiterouter csr\n on c.csr_id = csr.id\ninner join caas_cellsiterouter csrp\n on cp.csr_id = csrp.id\ninner join caas_location l\n on c.location_id = l.id\ninner join caas_vlan vl\n on c.vlan_id = vl.id\nleft outer join caas_blade b\n on s.blade_id = b.id\nleft outer join caas_vendor v\n on b.vendor_id = v.id\nleft outer join caas_credential cr\n on b.credential_id = cr.id\nwhere c.parent_cluster_id is not null', 'caas_wrbatch'),
+ atomic=False,
+ ),
+ ]
diff --git a/src/caas/migrations/0016_auto_20200804_1559.py b/src/caas/migrations/0016_auto_20200804_1559.py
new file mode 100644
index 0000000..64fd575
--- /dev/null
+++ b/src/caas/migrations/0016_auto_20200804_1559.py
@@ -0,0 +1,20 @@
+# Generated by Django 3.1 on 2020-08-04 21:59
+
+from django.db import migrations
+import django_db_views.migration_functions
+import django_db_views.operations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('caas', '0015_auto_20200804_1404'),
+ ]
+
+ operations = [
+ django_db_views.operations.ViewRunPython(
+ code=django_db_views.migration_functions.ForwardViewMigration('select s.id,\n c.id as cluster_id,\n l.fuze_spm_site_id,\n cp.oam_vip_hostname as parent_oam_vip_hostname,\n cp.oam_vip_address as parent_oam_vip_address,\n cp.mgmt_address_range_start as parent_mgmt_address_range_start,\n cp.mgmt_address_range_end as parent_mgmt_address_range_end,\n csrp.mgmt_default_gateway as parent_mgmt_default_gateway,\n csrp.mgmt_subnet as parent_mgmt_subnet,\n s.pxe_mac_address,\n s.ilo_host_address,\n s.oam_hostname,\n s.oam_host_address,\n c.oam_vip_address,\n csr.oam_default_gateway,\n c.mgmt_address_range_start,\n c.mgmt_address_range_end,\n csr.mgmt_default_gateway,\n csr.mgmt_subnet,\n vl.host_vlan,\n vl.oam_vlan,\n vl.mgmt_vlan,\n c.cluster_name,\n cp.cluster_name as parent_cluster_name,\n v.vendor_name,\n s.intel_nic_firmware_version,\n cr.bmc_username,\n cr.bmc_password\nfrom caas_server s\ninner join caas_cluster c\n on s.cluster_id = c.id\nleft outer join caas_cluster cp\n on c.parent_cluster_id = cp.id\ninner join caas_cellsiterouter csr\n on c.csr_id = csr.id\ninner join caas_cellsiterouter csrp\n on cp.csr_id = csrp.id\ninner join caas_location l\n on c.location_id = l.id\ninner join caas_vlan vl\n on c.vlan_id = vl.id\nleft outer join caas_blade b\n on s.blade_id = b.id\nleft outer join caas_vendor v\n on b.vendor_id = v.id\nleft outer join caas_credential cr\n on b.credential_id = cr.id\nwhere c.parent_cluster_id is not null', 'caas_wrbatch'),
+ reverse_code=django_db_views.migration_functions.BackwardViewMigration('select s.id,\n c.id as cluster_id,\n l.fuze_spm_site_id,\n cp.oam_vip_hostname as parent_oam_vip_hostname,\n cp.oam_vip_address as parent_oam_vip_address,\n cp.mgmt_address_range_start as parent_mgmt_address_range_start,\n cp.mgmt_address_range_end as parent_mgmt_address_range_end,\n csrp.mgmt_default_gateway as parent_mgmt_default_gateway,\n csrp.mgmt_subnet as parent_mgmt_subnet,\n s.pxe_mac_address,\n s.ilo_host_address,\n s.oam_hostname,\n s.oam_host_address,\n s.intel_nic_firmware_version,\n c.oam_vip_address,\n csr.oam_default_gateway,\n c.mgmt_address_range_start,\n c.mgmt_address_range_end,\n csr.mgmt_default_gateway,\n csr.mgmt_subnet,\n vl.host_vlan,\n vl.oam_vlan,\n vl.mgmt_vlan,\n c.cluster_name,\n cp.cluster_name as parent_cluster_name,\n v.vendor_name,\n cr.bmc_username,\n cr.bmc_password\nfrom caas_server s\ninner join caas_cluster c\n on s.cluster_id = c.id\nleft outer join caas_cluster cp\n on c.parent_cluster_id = cp.id\ninner join caas_cellsiterouter csr\n on c.csr_id = csr.id\ninner join caas_cellsiterouter csrp\n on cp.csr_id = csrp.id\ninner join caas_location l\n on c.location_id = l.id\ninner join caas_vlan vl\n on c.vlan_id = vl.id\nleft outer join caas_blade b\n on s.blade_id = b.id\nleft outer join caas_vendor v\n on b.vendor_id = v.id\nleft outer join caas_credential cr\n on b.credential_id = cr.id\nwhere c.parent_cluster_id is not null', 'caas_wrbatch'),
+ atomic=False,
+ ),
+ ]
diff --git a/src/caas/migrations/0017_cluster_is_central_controller.py b/src/caas/migrations/0017_cluster_is_central_controller.py
new file mode 100644
index 0000000..d2e500d
--- /dev/null
+++ b/src/caas/migrations/0017_cluster_is_central_controller.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.0.8 on 2020-09-24 17:37
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('caas', '0016_auto_20200804_1559'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='cluster',
+ name='is_central_controller',
+ field=models.SmallIntegerField(blank=True, default=0, null=True),
+ ),
+ ]
diff --git a/src/caas/migrations/0018_auto_20200925_1855.py b/src/caas/migrations/0018_auto_20200925_1855.py
new file mode 100644
index 0000000..e8bc107
--- /dev/null
+++ b/src/caas/migrations/0018_auto_20200925_1855.py
@@ -0,0 +1,30 @@
+# Generated by Django 3.0.8 on 2020-09-25 18:55
+
+from django.db import migrations
+import django_db_views.migration_functions
+import django_db_views.operations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('caas', '0017_cluster_is_central_controller'),
+ ]
+
+ operations = [
+ django_db_views.operations.ViewRunPython(
+ code=django_db_views.migration_functions.ForwardViewMigration('select l.id as id,\n csr.csr_hostname as csr_hostname,\n csr.oam_default_gateway as oam_default_gateway\nfrom caas_server s\ninner join caas_cluster c\n on s.cluster_id = c.id\ninner join caas_location l\n on c.location_id = l.id\ninner join caas_cellsiterouter csr\n on c.csr_id = csr.id\nleft outer join caas_blade b\n on s.blade_id = b.id\nleft outer join caas_vendor v\n on b.vendor_id = v.id\nleft outer join caas_credential cr\n on b.credential_id = cr.id\nwhere c.is_central_controller=0\ngroup by l.id,\n csr.csr_hostname,\n csr.oam_default_gateway', 'caas_icingarouter'),
+ reverse_code=django_db_views.migration_functions.BackwardViewMigration('select location_id as id,\n csr_hostname,\n oam_default_gateway\nfrom caas_icingabmc\ngroup by location_id,\n csr_hostname,\n oam_default_gateway', 'caas_icingarouter'),
+ atomic=False,
+ ),
+ django_db_views.operations.ViewRunPython(
+ code=django_db_views.migration_functions.ForwardViewMigration('select s.id,\n s.ilo_hostname,\n s.ilo_host_address,\n l.id as location_id,\n csr.oam_default_gateway,\n l.latitude,\n l.longitude,\n csr.csr_hostname,\n b.serial_number,\n v.vendor_name,\n cr.bmc_password_admin_default,\n cr.bmc_password_admin,\n cr.bmc_username,\n cr.bmc_password\nfrom caas_server s\ninner join caas_cluster c\n on s.cluster_id = c.id\ninner join caas_location l\n on c.location_id = l.id\ninner join caas_cellsiterouter csr\n on c.csr_id = csr.id\nleft outer join caas_blade b\n on s.blade_id = b.id\nleft outer join caas_vendor v\n on b.vendor_id = v.id\nleft outer join caas_credential cr\n on b.credential_id = cr.id\nwhere c.is_central_controller=0', 'caas_icingabmc'),
+ reverse_code=django_db_views.migration_functions.BackwardViewMigration('select s.id,\n s.ilo_hostname,\n s.ilo_host_address,\n l.id as location_id,\n csr.oam_default_gateway,\n l.latitude,\n l.longitude,\n csr.csr_hostname,\n b.serial_number,\n v.vendor_name,\n cr.bmc_password_admin_default,\n cr.bmc_password_admin,\n cr.bmc_username,\n cr.bmc_password\nfrom caas_server s\ninner join caas_cluster c\n on s.cluster_id = c.id\ninner join caas_location l\n on c.location_id = l.id\ninner join caas_cellsiterouter csr\n on c.csr_id = csr.id\nleft outer join caas_blade b\n on s.blade_id = b.id\nleft outer join caas_vendor v\n on b.vendor_id = v.id\nleft outer join caas_credential cr\n on b.credential_id = cr.id\nwhere c.parent_cluster_id is not null', 'caas_icingabmc'),
+ atomic=False,
+ ),
+ django_db_views.operations.ViewRunPython(
+ code=django_db_views.migration_functions.ForwardViewMigration('select s.id,\n s.ilo_hostname,\n s.ilo_host_address,\n s.intel_nic_firmware_version,\n cr.bmc_username,\n cr.bmc_password\nfrom caas_server s\ninner join caas_cluster c\n on s.cluster_id = c.id\nleft outer join caas_blade b\n on s.blade_id = b.id\nleft outer join caas_credential cr\n on b.credential_id = cr.id\nwhere c.is_central_controller=0', 'caas_firmwarebatch'),
+ reverse_code=django_db_views.migration_functions.BackwardViewMigration('select s.id,\n s.ilo_hostname,\n s.ilo_host_address,\n s.intel_nic_firmware_version,\n cr.bmc_username,\n cr.bmc_password\nfrom caas_server s\ninner join caas_cluster c\n on s.cluster_id = c.id\nleft outer join caas_blade b\n on s.blade_id = b.id\nleft outer join caas_credential cr\n on b.credential_id = cr.id\nwhere c.parent_cluster_id is not null', 'caas_firmwarebatch'),
+ atomic=False,
+ ),
+ ]
diff --git a/src/caas/migrations/0019_cluster_is_maint_window.py b/src/caas/migrations/0019_cluster_is_maint_window.py
new file mode 100644
index 0000000..cd297c5
--- /dev/null
+++ b/src/caas/migrations/0019_cluster_is_maint_window.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.1.2 on 2020-10-01 17:42
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('caas', '0018_auto_20200925_1855'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='cluster',
+ name='is_maint_window',
+ field=models.SmallIntegerField(blank=True, default=0, null=True),
+ ),
+ ]
diff --git a/src/caas/migrations/0020_auto_20201001_1142.py b/src/caas/migrations/0020_auto_20201001_1142.py
new file mode 100644
index 0000000..3e238eb
--- /dev/null
+++ b/src/caas/migrations/0020_auto_20201001_1142.py
@@ -0,0 +1,20 @@
+# Generated by Django 3.1.2 on 2020-10-01 17:42
+
+from django.db import migrations
+import django_db_views.migration_functions
+import django_db_views.operations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('caas', '0019_cluster_is_maint_window'),
+ ]
+
+ operations = [
+ django_db_views.operations.ViewRunPython(
+ code=django_db_views.migration_functions.ForwardViewMigration('select s.id,\n c.id as cluster_id,\n l.fuze_spm_site_id,\n cp.oam_vip_hostname as parent_oam_vip_hostname,\n cp.oam_vip_address as parent_oam_vip_address,\n cp.mgmt_address_range_start as parent_mgmt_address_range_start,\n cp.mgmt_address_range_end as parent_mgmt_address_range_end,\n csrp.mgmt_default_gateway as parent_mgmt_default_gateway,\n csrp.mgmt_subnet as parent_mgmt_subnet,\n s.pxe_mac_address,\n s.ilo_host_address,\n s.oam_hostname,\n s.oam_host_address,\n c.oam_vip_address,\n csr.oam_default_gateway,\n c.mgmt_address_range_start,\n c.mgmt_address_range_end,\n csr.mgmt_default_gateway,\n csr.mgmt_subnet,\n vl.host_vlan,\n vl.oam_vlan,\n vl.mgmt_vlan,\n c.cluster_name,\n cp.cluster_name as parent_cluster_name,\n v.vendor_name,\n s.intel_nic_firmware_version,\n c.is_maint_window,\n cr.bmc_username,\n cr.bmc_password\nfrom caas_server s\ninner join caas_cluster c\n on s.cluster_id = c.id\nleft outer join caas_cluster cp\n on c.parent_cluster_id = cp.id\ninner join caas_cellsiterouter csr\n on c.csr_id = csr.id\ninner join caas_cellsiterouter csrp\n on cp.csr_id = csrp.id\ninner join caas_location l\n on c.location_id = l.id\ninner join caas_vlan vl\n on c.vlan_id = vl.id\nleft outer join caas_blade b\n on s.blade_id = b.id\nleft outer join caas_vendor v\n on b.vendor_id = v.id\nleft outer join caas_credential cr\n on b.credential_id = cr.id\nwhere c.parent_cluster_id is not null', 'caas_wrbatch'),
+ reverse_code=django_db_views.migration_functions.BackwardViewMigration('select s.id,\n c.id as cluster_id,\n l.fuze_spm_site_id,\n cp.oam_vip_hostname as parent_oam_vip_hostname,\n cp.oam_vip_address as parent_oam_vip_address,\n cp.mgmt_address_range_start as parent_mgmt_address_range_start,\n cp.mgmt_address_range_end as parent_mgmt_address_range_end,\n csrp.mgmt_default_gateway as parent_mgmt_default_gateway,\n csrp.mgmt_subnet as parent_mgmt_subnet,\n s.pxe_mac_address,\n s.ilo_host_address,\n s.oam_hostname,\n s.oam_host_address,\n c.oam_vip_address,\n csr.oam_default_gateway,\n c.mgmt_address_range_start,\n c.mgmt_address_range_end,\n csr.mgmt_default_gateway,\n csr.mgmt_subnet,\n vl.host_vlan,\n vl.oam_vlan,\n vl.mgmt_vlan,\n c.cluster_name,\n cp.cluster_name as parent_cluster_name,\n v.vendor_name,\n s.intel_nic_firmware_version,\n cr.bmc_username,\n cr.bmc_password\nfrom caas_server s\ninner join caas_cluster c\n on s.cluster_id = c.id\nleft outer join caas_cluster cp\n on c.parent_cluster_id = cp.id\ninner join caas_cellsiterouter csr\n on c.csr_id = csr.id\ninner join caas_cellsiterouter csrp\n on cp.csr_id = csrp.id\ninner join caas_location l\n on c.location_id = l.id\ninner join caas_vlan vl\n on c.vlan_id = vl.id\nleft outer join caas_blade b\n on s.blade_id = b.id\nleft outer join caas_vendor v\n on b.vendor_id = v.id\nleft outer join caas_credential cr\n on b.credential_id = cr.id\nwhere c.parent_cluster_id is not null', 'caas_wrbatch'),
+ atomic=False,
+ ),
+ ]
diff --git a/src/caas/migrations/0021_auto_20201001_1232.py b/src/caas/migrations/0021_auto_20201001_1232.py
new file mode 100644
index 0000000..bb59147
--- /dev/null
+++ b/src/caas/migrations/0021_auto_20201001_1232.py
@@ -0,0 +1,22 @@
+# Generated by Django 3.1.2 on 2020-10-01 18:32
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('caas', '0020_auto_20201001_1142'),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name='cluster',
+ name='is_maint_window',
+ ),
+ migrations.AddField(
+ model_name='location',
+ name='maint_window_p',
+ field=models.BooleanField(blank=True, default=False, null=True),
+ ),
+ ]
diff --git a/src/caas/migrations/0022_auto_20201001_1232.py b/src/caas/migrations/0022_auto_20201001_1232.py
new file mode 100644
index 0000000..c18cf10
--- /dev/null
+++ b/src/caas/migrations/0022_auto_20201001_1232.py
@@ -0,0 +1,20 @@
+# Generated by Django 3.1.2 on 2020-10-01 18:32
+
+from django.db import migrations
+import django_db_views.migration_functions
+import django_db_views.operations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('caas', '0021_auto_20201001_1232'),
+ ]
+
+ operations = [
+ django_db_views.operations.ViewRunPython(
+ code=django_db_views.migration_functions.ForwardViewMigration('select s.id,\n c.id as cluster_id,\n l.fuze_spm_site_id,\n cp.oam_vip_hostname as parent_oam_vip_hostname,\n cp.oam_vip_address as parent_oam_vip_address,\n cp.mgmt_address_range_start as parent_mgmt_address_range_start,\n cp.mgmt_address_range_end as parent_mgmt_address_range_end,\n csrp.mgmt_default_gateway as parent_mgmt_default_gateway,\n csrp.mgmt_subnet as parent_mgmt_subnet,\n s.pxe_mac_address,\n s.ilo_host_address,\n s.oam_hostname,\n s.oam_host_address,\n c.oam_vip_address,\n csr.oam_default_gateway,\n c.mgmt_address_range_start,\n c.mgmt_address_range_end,\n csr.mgmt_default_gateway,\n csr.mgmt_subnet,\n vl.host_vlan,\n vl.oam_vlan,\n vl.mgmt_vlan,\n c.cluster_name,\n cp.cluster_name as parent_cluster_name,\n v.vendor_name,\n s.intel_nic_firmware_version,\n l.maint_window_p,\n cr.bmc_username,\n cr.bmc_password\nfrom caas_server s\ninner join caas_cluster c\n on s.cluster_id = c.id\nleft outer join caas_cluster cp\n on c.parent_cluster_id = cp.id\ninner join caas_cellsiterouter csr\n on c.csr_id = csr.id\ninner join caas_cellsiterouter csrp\n on cp.csr_id = csrp.id\ninner join caas_location l\n on c.location_id = l.id\ninner join caas_vlan vl\n on c.vlan_id = vl.id\nleft outer join caas_blade b\n on s.blade_id = b.id\nleft outer join caas_vendor v\n on b.vendor_id = v.id\nleft outer join caas_credential cr\n on b.credential_id = cr.id\nwhere c.parent_cluster_id is not null', 'caas_wrbatch'),
+ reverse_code=django_db_views.migration_functions.BackwardViewMigration('select s.id,\n c.id as cluster_id,\n l.fuze_spm_site_id,\n cp.oam_vip_hostname as parent_oam_vip_hostname,\n cp.oam_vip_address as parent_oam_vip_address,\n cp.mgmt_address_range_start as parent_mgmt_address_range_start,\n cp.mgmt_address_range_end as parent_mgmt_address_range_end,\n csrp.mgmt_default_gateway as parent_mgmt_default_gateway,\n csrp.mgmt_subnet as parent_mgmt_subnet,\n s.pxe_mac_address,\n s.ilo_host_address,\n s.oam_hostname,\n s.oam_host_address,\n c.oam_vip_address,\n csr.oam_default_gateway,\n c.mgmt_address_range_start,\n c.mgmt_address_range_end,\n csr.mgmt_default_gateway,\n csr.mgmt_subnet,\n vl.host_vlan,\n vl.oam_vlan,\n vl.mgmt_vlan,\n c.cluster_name,\n cp.cluster_name as parent_cluster_name,\n v.vendor_name,\n s.intel_nic_firmware_version,\n c.is_maint_window,\n cr.bmc_username,\n cr.bmc_password\nfrom caas_server s\ninner join caas_cluster c\n on s.cluster_id = c.id\nleft outer join caas_cluster cp\n on c.parent_cluster_id = cp.id\ninner join caas_cellsiterouter csr\n on c.csr_id = csr.id\ninner join caas_cellsiterouter csrp\n on cp.csr_id = csrp.id\ninner join caas_location l\n on c.location_id = l.id\ninner join caas_vlan vl\n on c.vlan_id = vl.id\nleft outer join caas_blade b\n on s.blade_id = b.id\nleft outer join caas_vendor v\n on b.vendor_id = v.id\nleft outer join caas_credential cr\n on b.credential_id = cr.id\nwhere c.parent_cluster_id is not null', 'caas_wrbatch'),
+ atomic=False,
+ ),
+ ]
diff --git a/src/caas/migrations/0023_auto_20201019_1631.py b/src/caas/migrations/0023_auto_20201019_1631.py
new file mode 100644
index 0000000..557884b
--- /dev/null
+++ b/src/caas/migrations/0023_auto_20201019_1631.py
@@ -0,0 +1,20 @@
+# Generated by Django 3.1.2 on 2020-10-19 22:31
+
+from django.db import migrations
+import django_db_views.migration_functions
+import django_db_views.operations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('caas', '0022_auto_20201001_1232'),
+ ]
+
+ operations = [
+ django_db_views.operations.ViewRunPython(
+ code=django_db_views.migration_functions.ForwardViewMigration('select s.id,\n s.ilo_hostname,\n s.ilo_host_address,\n l.id as location_id,\n csr.oam_default_gateway,\n l.latitude,\n l.longitude,\n csr.csr_hostname,\n b.serial_number,\n v.vendor_name,\n cr.bmc_password_admin_default,\n cr.bmc_password_admin,\n cr.bmc_username,\n cr.bmc_password,\n ws.date_completed\nfrom caas_server s\ninner join caas_cluster c\n on s.cluster_id = c.id\ninner join caas_location l\n on c.location_id = l.id\ninner join caas_cellsiterouter csr\n on c.csr_id = csr.id\nleft outer join caas_blade b\n on s.blade_id = b.id\nleft outer join caas_vendor v\n on b.vendor_id = v.id\nleft outer join caas_credential cr\n on b.credential_id = cr.id\nleft outer join caas_wrinstallschedule ws\n on c.id = ws.cluster_id\nwhere c.is_central_controller = 0', 'caas_icingabmc'),
+ reverse_code=django_db_views.migration_functions.BackwardViewMigration('select s.id,\n s.ilo_hostname,\n s.ilo_host_address,\n l.id as location_id,\n csr.oam_default_gateway,\n l.latitude,\n l.longitude,\n csr.csr_hostname,\n b.serial_number,\n v.vendor_name,\n cr.bmc_password_admin_default,\n cr.bmc_password_admin,\n cr.bmc_username,\n cr.bmc_password\nfrom caas_server s\ninner join caas_cluster c\n on s.cluster_id = c.id\ninner join caas_location l\n on c.location_id = l.id\ninner join caas_cellsiterouter csr\n on c.csr_id = csr.id\nleft outer join caas_blade b\n on s.blade_id = b.id\nleft outer join caas_vendor v\n on b.vendor_id = v.id\nleft outer join caas_credential cr\n on b.credential_id = cr.id\nwhere c.is_central_controller=0', 'caas_icingabmc'),
+ atomic=False,
+ ),
+ ]
diff --git a/src/caas/migrations/0024_auto_20201023_1556.py b/src/caas/migrations/0024_auto_20201023_1556.py
new file mode 100644
index 0000000..e6cb4a9
--- /dev/null
+++ b/src/caas/migrations/0024_auto_20201023_1556.py
@@ -0,0 +1,20 @@
+# Generated by Django 3.1.2 on 2020-10-23 21:56
+
+from django.db import migrations
+import django_db_views.migration_functions
+import django_db_views.operations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('caas', '0023_auto_20201019_1631'),
+ ]
+
+ operations = [
+ django_db_views.operations.ViewRunPython(
+ code=django_db_views.migration_functions.ForwardViewMigration('select s.id,\n c.id as cluster_id,\n l.fuze_spm_site_id,\n cp.oam_vip_hostname as parent_oam_vip_hostname,\n cp.oam_vip_address as parent_oam_vip_address,\n cp.mgmt_address_range_start as parent_mgmt_address_range_start,\n cp.mgmt_address_range_end as parent_mgmt_address_range_end,\n csrp.mgmt_default_gateway as parent_mgmt_default_gateway,\n csrp.mgmt_subnet as parent_mgmt_subnet,\n s.pxe_mac_address,\n s.ilo_host_address,\n s.oam_hostname,\n s.oam_host_address,\n c.oam_vip_address,\n csr.oam_default_gateway,\n c.mgmt_address_range_start,\n c.mgmt_address_range_end,\n csr.mgmt_default_gateway,\n csr.mgmt_subnet,\n vl.host_vlan,\n vl.oam_vlan,\n vl.mgmt_vlan,\n c.cluster_name,\n cp.cluster_name as parent_cluster_name,\n v.vendor_name,\n s.intel_nic_firmware_version,\n l.maint_window_p,\n n.id as namespace_id,\n n.namespace_name,\n cr.bmc_username,\n cr.bmc_password\nfrom caas_server s\ninner join caas_cluster c\n on s.cluster_id = c.id\nleft outer join caas_cluster cp\n on c.parent_cluster_id = cp.id\ninner join caas_cellsiterouter csr\n on c.csr_id = csr.id\ninner join caas_cellsiterouter csrp\n on cp.csr_id = csrp.id\ninner join caas_location l\n on c.location_id = l.id\ninner join caas_vlan vl\n on c.vlan_id = vl.id\ninner join caas_namespace n\n on c.namespace_id = n.id\nleft outer join caas_blade b\n on s.blade_id = b.id\nleft outer join caas_vendor v\n on b.vendor_id = v.id\nleft outer join caas_credential cr\n on b.credential_id = cr.id\nwhere c.parent_cluster_id is not null', 'caas_wrbatch'),
+ reverse_code=django_db_views.migration_functions.BackwardViewMigration('select s.id,\n c.id as cluster_id,\n l.fuze_spm_site_id,\n cp.oam_vip_hostname as parent_oam_vip_hostname,\n cp.oam_vip_address as parent_oam_vip_address,\n cp.mgmt_address_range_start as parent_mgmt_address_range_start,\n cp.mgmt_address_range_end as parent_mgmt_address_range_end,\n csrp.mgmt_default_gateway as parent_mgmt_default_gateway,\n csrp.mgmt_subnet as parent_mgmt_subnet,\n s.pxe_mac_address,\n s.ilo_host_address,\n s.oam_hostname,\n s.oam_host_address,\n c.oam_vip_address,\n csr.oam_default_gateway,\n c.mgmt_address_range_start,\n c.mgmt_address_range_end,\n csr.mgmt_default_gateway,\n csr.mgmt_subnet,\n vl.host_vlan,\n vl.oam_vlan,\n vl.mgmt_vlan,\n c.cluster_name,\n cp.cluster_name as parent_cluster_name,\n v.vendor_name,\n s.intel_nic_firmware_version,\n l.maint_window_p,\n cr.bmc_username,\n cr.bmc_password\nfrom caas_server s\ninner join caas_cluster c\n on s.cluster_id = c.id\nleft outer join caas_cluster cp\n on c.parent_cluster_id = cp.id\ninner join caas_cellsiterouter csr\n on c.csr_id = csr.id\ninner join caas_cellsiterouter csrp\n on cp.csr_id = csrp.id\ninner join caas_location l\n on c.location_id = l.id\ninner join caas_vlan vl\n on c.vlan_id = vl.id\nleft outer join caas_blade b\n on s.blade_id = b.id\nleft outer join caas_vendor v\n on b.vendor_id = v.id\nleft outer join caas_credential cr\n on b.credential_id = cr.id\nwhere c.parent_cluster_id is not null', 'caas_wrbatch'),
+ atomic=False,
+ ),
+ ]
diff --git a/src/caas/migrations/0025_auto_20201102_1545.py b/src/caas/migrations/0025_auto_20201102_1545.py
new file mode 100644
index 0000000..b37f422
--- /dev/null
+++ b/src/caas/migrations/0025_auto_20201102_1545.py
@@ -0,0 +1,20 @@
+# Generated by Django 3.1.3 on 2020-11-02 22:45
+
+from django.db import migrations
+import django_db_views.migration_functions
+import django_db_views.operations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('caas', '0024_auto_20201023_1556'),
+ ]
+
+ operations = [
+ django_db_views.operations.ViewRunPython(
+ code=django_db_views.migration_functions.ForwardViewMigration('select s.id,\n c.id as cluster_id,\n l.fuze_spm_site_id,\n cp.oam_vip_hostname as parent_oam_vip_hostname,\n cp.oam_vip_address as parent_oam_vip_address,\n cp.mgmt_address_range_start as parent_mgmt_address_range_start,\n cp.mgmt_address_range_end as parent_mgmt_address_range_end,\n csrp.mgmt_default_gateway as parent_mgmt_default_gateway,\n csrp.mgmt_subnet as parent_mgmt_subnet,\n s.pxe_mac_address,\n s.ilo_hostname,\n s.ilo_host_address,\n s.oam_hostname,\n s.oam_host_address,\n c.oam_vip_address,\n csr.oam_default_gateway,\n c.mgmt_address_range_start,\n c.mgmt_address_range_end,\n csr.mgmt_default_gateway,\n csr.mgmt_subnet,\n vl.host_vlan,\n vl.oam_vlan,\n vl.mgmt_vlan,\n c.cluster_name,\n cp.cluster_name as parent_cluster_name,\n v.vendor_name,\n s.intel_nic_firmware_version,\n l.maint_window_p,\n n.id as namespace_id,\n n.namespace_name,\n cr.bmc_username,\n cr.bmc_password\nfrom caas_server s\ninner join caas_cluster c\n on s.cluster_id = c.id\nleft outer join caas_cluster cp\n on c.parent_cluster_id = cp.id\ninner join caas_cellsiterouter csr\n on c.csr_id = csr.id\ninner join caas_cellsiterouter csrp\n on cp.csr_id = csrp.id\ninner join caas_location l\n on c.location_id = l.id\ninner join caas_vlan vl\n on c.vlan_id = vl.id\ninner join caas_namespace n\n on c.namespace_id = n.id\nleft outer join caas_blade b\n on s.blade_id = b.id\nleft outer join caas_vendor v\n on b.vendor_id = v.id\nleft outer join caas_credential cr\n on b.credential_id = cr.id\nwhere c.parent_cluster_id is not null', 'caas_wrbatch'),
+ reverse_code=django_db_views.migration_functions.BackwardViewMigration('select s.id,\n c.id as cluster_id,\n l.fuze_spm_site_id,\n cp.oam_vip_hostname as parent_oam_vip_hostname,\n cp.oam_vip_address as parent_oam_vip_address,\n cp.mgmt_address_range_start as parent_mgmt_address_range_start,\n cp.mgmt_address_range_end as parent_mgmt_address_range_end,\n csrp.mgmt_default_gateway as parent_mgmt_default_gateway,\n csrp.mgmt_subnet as parent_mgmt_subnet,\n s.pxe_mac_address,\n s.ilo_host_address,\n s.oam_hostname,\n s.oam_host_address,\n c.oam_vip_address,\n csr.oam_default_gateway,\n c.mgmt_address_range_start,\n c.mgmt_address_range_end,\n csr.mgmt_default_gateway,\n csr.mgmt_subnet,\n vl.host_vlan,\n vl.oam_vlan,\n vl.mgmt_vlan,\n c.cluster_name,\n cp.cluster_name as parent_cluster_name,\n v.vendor_name,\n s.intel_nic_firmware_version,\n l.maint_window_p,\n n.id as namespace_id,\n n.namespace_name,\n cr.bmc_username,\n cr.bmc_password\nfrom caas_server s\ninner join caas_cluster c\n on s.cluster_id = c.id\nleft outer join caas_cluster cp\n on c.parent_cluster_id = cp.id\ninner join caas_cellsiterouter csr\n on c.csr_id = csr.id\ninner join caas_cellsiterouter csrp\n on cp.csr_id = csrp.id\ninner join caas_location l\n on c.location_id = l.id\ninner join caas_vlan vl\n on c.vlan_id = vl.id\ninner join caas_namespace n\n on c.namespace_id = n.id\nleft outer join caas_blade b\n on s.blade_id = b.id\nleft outer join caas_vendor v\n on b.vendor_id = v.id\nleft outer join caas_credential cr\n on b.credential_id = cr.id\nwhere c.parent_cluster_id is not null', 'caas_wrbatch'),
+ atomic=False,
+ ),
+ ]
diff --git a/src/caas/migrations/0026_auto_20201110_0932.py b/src/caas/migrations/0026_auto_20201110_0932.py
new file mode 100644
index 0000000..3956e28
--- /dev/null
+++ b/src/caas/migrations/0026_auto_20201110_0932.py
@@ -0,0 +1,29 @@
+# Generated by Django 3.1.3 on 2020-11-10 16:32
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('caas', '0025_auto_20201102_1545'),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name='server',
+ name='csr_mgmt_port_number',
+ ),
+ migrations.RemoveField(
+ model_name='server',
+ name='csr_nfs_port_number',
+ ),
+ migrations.RemoveField(
+ model_name='server',
+ name='csr_oam_port_number',
+ ),
+ migrations.RemoveField(
+ model_name='server',
+ name='csr_vdu_port_number',
+ ),
+ ]
diff --git a/src/caas/migrations/0027_auto_20201211_2103.py b/src/caas/migrations/0027_auto_20201211_2103.py
new file mode 100644
index 0000000..751411b
--- /dev/null
+++ b/src/caas/migrations/0027_auto_20201211_2103.py
@@ -0,0 +1,23 @@
+# Generated by Django 3.1.4 on 2020-12-12 04:03
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('caas', '0026_auto_20201110_0932'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='cluster',
+ name='mgmt_default_gateway',
+ field=models.CharField(blank=True, max_length=255, null=True),
+ ),
+ migrations.AddField(
+ model_name='cluster',
+ name='mgmt_subnet',
+ field=models.CharField(blank=True, max_length=255, null=True),
+ ),
+ ]
diff --git a/src/caas/migrations/0028_auto_20201212_1001.py b/src/caas/migrations/0028_auto_20201212_1001.py
new file mode 100644
index 0000000..cf6c1d0
--- /dev/null
+++ b/src/caas/migrations/0028_auto_20201212_1001.py
@@ -0,0 +1,20 @@
+# Generated by Django 3.1.4 on 2020-12-12 17:01
+
+from django.db import migrations
+import django_db_views.migration_functions
+import django_db_views.operations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('caas', '0027_auto_20201211_2103'),
+ ]
+
+ operations = [
+ django_db_views.operations.ViewRunPython(
+ code=django_db_views.migration_functions.ForwardViewMigration('select s.id,\n c.id as cluster_id,\n l.fuze_spm_site_id,\n cp.oam_vip_hostname as parent_oam_vip_hostname,\n cp.oam_vip_address as parent_oam_vip_address,\n cp.mgmt_address_range_start as parent_mgmt_address_range_start,\n cp.mgmt_address_range_end as parent_mgmt_address_range_end,\n csrp.mgmt_default_gateway as parent_mgmt_default_gateway,\n csrp.mgmt_subnet as parent_mgmt_subnet,\n s.pxe_mac_address,\n s.ilo_hostname,\n s.ilo_host_address,\n s.oam_hostname,\n s.oam_host_address,\n c.oam_vip_address,\n csr.oam_default_gateway,\n c.mgmt_address_range_start,\n c.mgmt_address_range_end,\n c.mgmt_default_gateway,\n c.mgmt_subnet,\n vl.host_vlan,\n vl.oam_vlan,\n vl.mgmt_vlan,\n c.cluster_name,\n cp.cluster_name as parent_cluster_name,\n v.vendor_name,\n s.intel_nic_firmware_version,\n l.maint_window_p,\n n.id as namespace_id,\n n.namespace_name,\n cr.bmc_username,\n cr.bmc_password\nfrom caas_server s\ninner join caas_cluster c\n on s.cluster_id = c.id\nleft outer join caas_cluster cp\n on c.parent_cluster_id = cp.id\ninner join caas_cellsiterouter csr\n on c.csr_id = csr.id\ninner join caas_cellsiterouter csrp\n on cp.csr_id = csrp.id\ninner join caas_location l\n on c.location_id = l.id\ninner join caas_vlan vl\n on c.vlan_id = vl.id\ninner join caas_namespace n\n on c.namespace_id = n.id\nleft outer join caas_blade b\n on s.blade_id = b.id\nleft outer join caas_vendor v\n on b.vendor_id = v.id\nleft outer join caas_credential cr\n on b.credential_id = cr.id\nwhere c.parent_cluster_id is not null', 'caas_wrbatch'),
+ reverse_code=django_db_views.migration_functions.BackwardViewMigration('select s.id,\n c.id as cluster_id,\n l.fuze_spm_site_id,\n cp.oam_vip_hostname as parent_oam_vip_hostname,\n cp.oam_vip_address as parent_oam_vip_address,\n cp.mgmt_address_range_start as parent_mgmt_address_range_start,\n cp.mgmt_address_range_end as parent_mgmt_address_range_end,\n csrp.mgmt_default_gateway as parent_mgmt_default_gateway,\n csrp.mgmt_subnet as parent_mgmt_subnet,\n s.pxe_mac_address,\n s.ilo_hostname,\n s.ilo_host_address,\n s.oam_hostname,\n s.oam_host_address,\n c.oam_vip_address,\n csr.oam_default_gateway,\n c.mgmt_address_range_start,\n c.mgmt_address_range_end,\n csr.mgmt_default_gateway,\n csr.mgmt_subnet,\n vl.host_vlan,\n vl.oam_vlan,\n vl.mgmt_vlan,\n c.cluster_name,\n cp.cluster_name as parent_cluster_name,\n v.vendor_name,\n s.intel_nic_firmware_version,\n l.maint_window_p,\n n.id as namespace_id,\n n.namespace_name,\n cr.bmc_username,\n cr.bmc_password\nfrom caas_server s\ninner join caas_cluster c\n on s.cluster_id = c.id\nleft outer join caas_cluster cp\n on c.parent_cluster_id = cp.id\ninner join caas_cellsiterouter csr\n on c.csr_id = csr.id\ninner join caas_cellsiterouter csrp\n on cp.csr_id = csrp.id\ninner join caas_location l\n on c.location_id = l.id\ninner join caas_vlan vl\n on c.vlan_id = vl.id\ninner join caas_namespace n\n on c.namespace_id = n.id\nleft outer join caas_blade b\n on s.blade_id = b.id\nleft outer join caas_vendor v\n on b.vendor_id = v.id\nleft outer join caas_credential cr\n on b.credential_id = cr.id\nwhere c.parent_cluster_id is not null', 'caas_wrbatch'),
+ atomic=False,
+ ),
+ ]
diff --git a/src/caas/migrations/0029_auto_20201215_0832.py b/src/caas/migrations/0029_auto_20201215_0832.py
new file mode 100644
index 0000000..49adea4
--- /dev/null
+++ b/src/caas/migrations/0029_auto_20201215_0832.py
@@ -0,0 +1,21 @@
+# Generated by Django 3.1.4 on 2020-12-15 15:32
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('caas', '0028_auto_20201212_1001'),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name='cellsiterouter',
+ name='mgmt_default_gateway',
+ ),
+ migrations.RemoveField(
+ model_name='cellsiterouter',
+ name='mgmt_subnet',
+ ),
+ ]
diff --git a/src/caas/migrations/0030_auto_20201215_0835.py b/src/caas/migrations/0030_auto_20201215_0835.py
new file mode 100644
index 0000000..c8ee59d
--- /dev/null
+++ b/src/caas/migrations/0030_auto_20201215_0835.py
@@ -0,0 +1,20 @@
+# Generated by Django 3.1.4 on 2020-12-15 15:35
+
+from django.db import migrations
+import django_db_views.migration_functions
+import django_db_views.operations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('caas', '0029_auto_20201215_0832'),
+ ]
+
+ operations = [
+ django_db_views.operations.ViewRunPython(
+ code=django_db_views.migration_functions.ForwardViewMigration('select s.id,\n c.id as cluster_id,\n l.fuze_spm_site_id,\n cp.oam_vip_hostname as parent_oam_vip_hostname,\n cp.oam_vip_address as parent_oam_vip_address,\n cp.mgmt_address_range_start as parent_mgmt_address_range_start,\n cp.mgmt_address_range_end as parent_mgmt_address_range_end,\n c.mgmt_default_gateway as parent_mgmt_default_gateway,\n c.mgmt_subnet as parent_mgmt_subnet,\n s.pxe_mac_address,\n s.ilo_hostname,\n s.ilo_host_address,\n s.oam_hostname,\n s.oam_host_address,\n c.oam_vip_address,\n csr.oam_default_gateway,\n c.mgmt_address_range_start,\n c.mgmt_address_range_end,\n c.mgmt_default_gateway,\n c.mgmt_subnet,\n vl.host_vlan,\n vl.oam_vlan,\n vl.mgmt_vlan,\n c.cluster_name,\n cp.cluster_name as parent_cluster_name,\n v.vendor_name,\n s.intel_nic_firmware_version,\n l.maint_window_p,\n n.id as namespace_id,\n n.namespace_name,\n cr.bmc_username,\n cr.bmc_password\nfrom caas_server s\ninner join caas_cluster c\n on s.cluster_id = c.id\nleft outer join caas_cluster cp\n on c.parent_cluster_id = cp.id\ninner join caas_cellsiterouter csr\n on c.csr_id = csr.id\ninner join caas_cellsiterouter csrp\n on cp.csr_id = csrp.id\ninner join caas_location l\n on c.location_id = l.id\ninner join caas_vlan vl\n on c.vlan_id = vl.id\ninner join caas_namespace n\n on c.namespace_id = n.id\nleft outer join caas_blade b\n on s.blade_id = b.id\nleft outer join caas_vendor v\n on b.vendor_id = v.id\nleft outer join caas_credential cr\n on b.credential_id = cr.id\nwhere c.parent_cluster_id is not null', 'caas_wrbatch'),
+ reverse_code=django_db_views.migration_functions.BackwardViewMigration('select s.id,\n c.id as cluster_id,\n l.fuze_spm_site_id,\n cp.oam_vip_hostname as parent_oam_vip_hostname,\n cp.oam_vip_address as parent_oam_vip_address,\n cp.mgmt_address_range_start as parent_mgmt_address_range_start,\n cp.mgmt_address_range_end as parent_mgmt_address_range_end,\n csrp.mgmt_default_gateway as parent_mgmt_default_gateway,\n csrp.mgmt_subnet as parent_mgmt_subnet,\n s.pxe_mac_address,\n s.ilo_hostname,\n s.ilo_host_address,\n s.oam_hostname,\n s.oam_host_address,\n c.oam_vip_address,\n csr.oam_default_gateway,\n c.mgmt_address_range_start,\n c.mgmt_address_range_end,\n c.mgmt_default_gateway,\n c.mgmt_subnet,\n vl.host_vlan,\n vl.oam_vlan,\n vl.mgmt_vlan,\n c.cluster_name,\n cp.cluster_name as parent_cluster_name,\n v.vendor_name,\n s.intel_nic_firmware_version,\n l.maint_window_p,\n n.id as namespace_id,\n n.namespace_name,\n cr.bmc_username,\n cr.bmc_password\nfrom caas_server s\ninner join caas_cluster c\n on s.cluster_id = c.id\nleft outer join caas_cluster cp\n on c.parent_cluster_id = cp.id\ninner join caas_cellsiterouter csr\n on c.csr_id = csr.id\ninner join caas_cellsiterouter csrp\n on cp.csr_id = csrp.id\ninner join caas_location l\n on c.location_id = l.id\ninner join caas_vlan vl\n on c.vlan_id = vl.id\ninner join caas_namespace n\n on c.namespace_id = n.id\nleft outer join caas_blade b\n on s.blade_id = b.id\nleft outer join caas_vendor v\n on b.vendor_id = v.id\nleft outer join caas_credential cr\n on b.credential_id = cr.id\nwhere c.parent_cluster_id is not null', 'caas_wrbatch'),
+ atomic=False,
+ ),
+ ]
diff --git a/src/caas/migrations/0031_auto_20201215_1430.py b/src/caas/migrations/0031_auto_20201215_1430.py
new file mode 100644
index 0000000..5f31f82
--- /dev/null
+++ b/src/caas/migrations/0031_auto_20201215_1430.py
@@ -0,0 +1,20 @@
+# Generated by Django 3.1.4 on 2020-12-15 21:30
+
+from django.db import migrations
+import django_db_views.migration_functions
+import django_db_views.operations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('caas', '0030_auto_20201215_0835'),
+ ]
+
+ operations = [
+ django_db_views.operations.ViewRunPython(
+ code=django_db_views.migration_functions.ForwardViewMigration('select s.id,\n c.id as cluster_id,\n l.fuze_spm_site_id,\n cp.oam_vip_hostname as parent_oam_vip_hostname,\n cp.oam_vip_address as parent_oam_vip_address,\n cp.mgmt_address_range_start as parent_mgmt_address_range_start,\n cp.mgmt_address_range_end as parent_mgmt_address_range_end,\n cp.mgmt_default_gateway as parent_mgmt_default_gateway,\n cp.mgmt_subnet as parent_mgmt_subnet,\n s.pxe_mac_address,\n s.ilo_hostname,\n s.ilo_host_address,\n s.oam_hostname,\n s.oam_host_address,\n c.oam_vip_address,\n csr.oam_default_gateway,\n c.mgmt_address_range_start,\n c.mgmt_address_range_end,\n c.mgmt_default_gateway,\n c.mgmt_subnet,\n vl.host_vlan,\n vl.oam_vlan,\n vl.mgmt_vlan,\n c.cluster_name,\n cp.cluster_name as parent_cluster_name,\n v.vendor_name,\n s.intel_nic_firmware_version,\n l.maint_window_p,\n n.id as namespace_id,\n n.namespace_name,\n cr.bmc_username,\n cr.bmc_password\nfrom caas_server s\ninner join caas_cluster c\n on s.cluster_id = c.id\nleft outer join caas_cluster cp\n on c.parent_cluster_id = cp.id\ninner join caas_cellsiterouter csr\n on c.csr_id = csr.id\ninner join caas_cellsiterouter csrp\n on cp.csr_id = csrp.id\ninner join caas_location l\n on c.location_id = l.id\ninner join caas_vlan vl\n on c.vlan_id = vl.id\ninner join caas_namespace n\n on c.namespace_id = n.id\nleft outer join caas_blade b\n on s.blade_id = b.id\nleft outer join caas_vendor v\n on b.vendor_id = v.id\nleft outer join caas_credential cr\n on b.credential_id = cr.id\nwhere c.parent_cluster_id is not null', 'caas_wrbatch'),
+ reverse_code=django_db_views.migration_functions.BackwardViewMigration('select s.id,\n c.id as cluster_id,\n l.fuze_spm_site_id,\n cp.oam_vip_hostname as parent_oam_vip_hostname,\n cp.oam_vip_address as parent_oam_vip_address,\n cp.mgmt_address_range_start as parent_mgmt_address_range_start,\n cp.mgmt_address_range_end as parent_mgmt_address_range_end,\n c.mgmt_default_gateway as parent_mgmt_default_gateway,\n c.mgmt_subnet as parent_mgmt_subnet,\n s.pxe_mac_address,\n s.ilo_hostname,\n s.ilo_host_address,\n s.oam_hostname,\n s.oam_host_address,\n c.oam_vip_address,\n csr.oam_default_gateway,\n c.mgmt_address_range_start,\n c.mgmt_address_range_end,\n c.mgmt_default_gateway,\n c.mgmt_subnet,\n vl.host_vlan,\n vl.oam_vlan,\n vl.mgmt_vlan,\n c.cluster_name,\n cp.cluster_name as parent_cluster_name,\n v.vendor_name,\n s.intel_nic_firmware_version,\n l.maint_window_p,\n n.id as namespace_id,\n n.namespace_name,\n cr.bmc_username,\n cr.bmc_password\nfrom caas_server s\ninner join caas_cluster c\n on s.cluster_id = c.id\nleft outer join caas_cluster cp\n on c.parent_cluster_id = cp.id\ninner join caas_cellsiterouter csr\n on c.csr_id = csr.id\ninner join caas_cellsiterouter csrp\n on cp.csr_id = csrp.id\ninner join caas_location l\n on c.location_id = l.id\ninner join caas_vlan vl\n on c.vlan_id = vl.id\ninner join caas_namespace n\n on c.namespace_id = n.id\nleft outer join caas_blade b\n on s.blade_id = b.id\nleft outer join caas_vendor v\n on b.vendor_id = v.id\nleft outer join caas_credential cr\n on b.credential_id = cr.id\nwhere c.parent_cluster_id is not null', 'caas_wrbatch'),
+ atomic=False,
+ ),
+ ]
diff --git a/src/caas/models.py b/src/caas/models.py
index 6ad754f..8c7e4da 100644
--- a/src/caas/models.py
+++ b/src/caas/models.py
@@ -1,59 +1,426 @@
from django.db import models
+from django_db_views.db_view import DBView
+
class Vlan(models.Model):
host_vlan = models.PositiveSmallIntegerField()
oam_vlan = models.PositiveSmallIntegerField()
mgmt_vlan = models.PositiveSmallIntegerField()
+ nfs_vlan = models.PositiveSmallIntegerField(blank=True, null=True)
def __str__(self):
- return "host_vlan: %s , oam_vlan: %s , mgmt_vlan: %s" % (self.host_vlan, self.oam_vlan, self.mgmt_vlan)
+ return "pk: %s , host_vlan: %s , oam_vlan: %s , mgmt_vlan: %s , nfs_vlan: %s" % (self.pk, self.host_vlan, self.oam_vlan, self.mgmt_vlan, self.nfs_vlan)
+
+ class Meta:
+ constraints = [models.UniqueConstraint(fields=["host_vlan", "oam_vlan", "mgmt_vlan", "nfs_vlan"], name="unique_vlan")]
class Namespace(models.Model):
namespace_name = models.CharField(max_length=255)
- server_id = models.ForeignKey('VcpfeServer', on_delete=models.SET_NULL, blank=True, null=True)
-
+
+ def __str__(self):
+ return "pk: %s , namespace_name: %s" % (self.pk, self.namespace_name)
+
+ class Meta:
+ constraints = [models.UniqueConstraint(fields=["namespace_name"], name="unique_namespace")]
+
+
+class SapClli(models.Model):
+ clli = models.CharField(max_length=255, blank=True, null=True)
+
def __str__(self):
- return "namespace_name: %s , server_id : %s" % (self.namespace_name, self.server_id)
+ return "pk: %s , clli: %s" % (self.pk, self.clli)
+ class Meta:
+ constraints = [models.UniqueConstraint(fields=["clli"], name="unique_sapclli")]
-class VcpfeLocation(models.Model):
+
+class Location(models.Model):
fuze_spm_site_id = models.CharField(max_length=16)
fuze_spm_site_name = models.CharField(max_length=255)
fuze_spm_market = models.CharField(max_length=255)
fuze_spm_submarket = models.CharField(max_length=255)
- fuze_spm_site_type = models.CharField(max_length=4, choices=[('DRAN', 'DRAN'), ('CRAN', 'CRAN')])
- central_controller_sap_clli = models.CharField(max_length=255)
- vcu_sap_clli = models.CharField(max_length=255)
- csr_hostname = models.CharField(max_length=255)
- f1c_f1u_subnet = models.CharField(max_length=255)
- f1c_f1u_default_gateway = models.CharField(max_length=255)
- oam_subnet = models.CharField(max_length=255)
- oam_default_gateway = models.CharField(max_length=255)
- mgmt_subnet = models.CharField(max_length=255)
- mgmt_default_gateway = models.CharField(max_length=255)
- ilo_subnet = models.CharField(max_length=255)
- ilo_default_gateway = models.CharField(max_length=255)
- fhgw_subnet = models.CharField(max_length=255)
- fhgw_default_gateway = models.CharField(max_length=255)
+ fuze_spm_site_type = models.CharField(max_length=4, choices=[("SAP", "SAP"), ("DRAN", "DRAN"), ("CRAN", "CRAN")])
+ latitude = models.DecimalField(max_digits=12, decimal_places=9, blank=True, null=True)
+ longitude = models.DecimalField(max_digits=12, decimal_places=9, blank=True, null=True)
+ maint_window_p = models.BooleanField(default=False, blank=True, null=True)
+
+ def __str__(self):
+ return "pk: %s , fuze_spm_site_id: %s , fuze_spm_site_name: %s , fuze_spm_market: %s , fuze_spm_submarket: %s , fuze_spm_site_type: %s" % (self.pk, self.fuze_spm_site_id, self.fuze_spm_site_name, self.fuze_spm_market, self.fuze_spm_submarket, self.fuze_spm_site_type)
+
+ class Meta:
+ constraints = [models.UniqueConstraint(fields=["fuze_spm_site_id",
+ "fuze_spm_site_name",
+ "fuze_spm_market",
+ "fuze_spm_submarket",
+ "fuze_spm_site_type"],
+ name="unique_location")]
+
+
+class CellSiteRouter(models.Model):
+ csr_hostname = models.CharField(max_length=255, blank=True, null=True)
+ oam_subnet = models.CharField(max_length=255, blank=True, null=True)
+ oam_default_gateway = models.CharField(max_length=255, blank=True, null=True)
+ ilo_subnet = models.CharField(max_length=255, blank=True, null=True)
+ ilo_default_gateway = models.CharField(max_length=255, blank=True, null=True)
def __str__(self):
- return "%s : %s : %s : %s : %s" % (self.fuze_spm_site_id, self.fuze_spm_site_name, self.fuze_spm_market, self.fuze_spm_submarket, self.fuze_spm_site_type)
+ return "pk: %s , csr_hostname: %s" % (self.pk, self.csr_hostname)
+
+ class Meta:
+ constraints = [models.UniqueConstraint(fields=["csr_hostname"], name="unique_cellsiterouter")]
-class VcpfeServer(models.Model):
- server_number = models.PositiveSmallIntegerField()
- server_hostname = models.CharField(max_length=255)
+class Cluster(models.Model):
cluster_name = models.CharField(max_length=255)
- f1u_address = models.CharField(max_length=255)
- f1c_address = models.CharField(max_length=255)
- oam_host_address = models.CharField(max_length=255)
- oam_vip_address = models.CharField(max_length=255)
- mgmt_address_range_start = models.CharField(max_length=255)
- mgmt_address_range_end = models.CharField(max_length=255)
- ilo_host_address = models.CharField(max_length=255)
- fhgw_host_address = models.CharField(max_length=255)
- vlan_id = models.ForeignKey('Vlan', on_delete=models.SET_NULL, blank=True, null=True)
+ oam_vip_hostname = models.CharField(max_length=255, blank=True, null=True)
+ oam_vip_address = models.CharField(max_length=255, blank=True, null=True)
+ mgmt_subnet = models.CharField(max_length=255, blank=True, null=True)
+ mgmt_default_gateway = models.CharField(max_length=255, blank=True, null=True)
+ mgmt_address_range_start = models.CharField(max_length=255, blank=True, null=True)
+ mgmt_address_range_end = models.CharField(max_length=255, blank=True, null=True)
+ is_central_controller = models.SmallIntegerField(default=0, blank=True, null=True)
+ sap_clli = models.ForeignKey("SapClli", on_delete=models.SET_NULL, blank=True, null=True)
+ parent_cluster = models.ForeignKey("Cluster", on_delete=models.SET_NULL, blank=True, null=True)
+ location = models.ForeignKey("Location", on_delete=models.SET_NULL, blank=True, null=True)
+ vlan = models.ForeignKey("Vlan", on_delete=models.SET_NULL, blank=True, null=True)
+ csr = models.ForeignKey("CellSiteRouter", on_delete=models.SET_NULL, blank=True, null=True)
+ namespace = models.ForeignKey("Namespace", on_delete=models.SET_NULL, blank=True, null=True)
+
+ def __str__(self):
+ return "pk: %s , cluster_name: %s" % (self.pk, self.cluster_name)
+
+ class Meta:
+ constraints = [models.UniqueConstraint(fields=["cluster_name"], name="unique_cluster")]
+
+
+class Server(models.Model):
+ server_number = models.PositiveSmallIntegerField(blank=True, null=True)
+ oam_hostname = models.CharField(max_length=255, blank=True, null=True)
+ oam_host_address = models.CharField(max_length=255, blank=True, null=True)
+ ilo_hostname = models.CharField(max_length=255)
+ ilo_host_address = models.CharField(max_length=255, blank=True, null=True)
+ pxe_mac_address = models.CharField(max_length=255, blank=True, null=True)
+ intel_nic_firmware_version = models.CharField(max_length=255, blank=True, null=True)
+ cluster = models.ForeignKey("Cluster", on_delete=models.SET_NULL, blank=True, null=True)
+ blade = models.ForeignKey("Blade", on_delete=models.SET_NULL, blank=True, null=True)
+
+ def __str__(self):
+ return "pk: %s , ilo_hostname: %s , cluster_id: %s" % (self.pk, self.ilo_hostname, self.cluster_id)
+
+ class Meta:
+ constraints = [models.UniqueConstraint(fields=["ilo_hostname"], name="unique_server_byhostname")]
+ constraints = [models.UniqueConstraint(fields=["ilo_host_address"], name="unique_server_byiloaddress")]
+
+
+class Credential(models.Model):
+ bmc_password_admin_default = models.CharField(max_length=255, blank=True, null=True)
+ bmc_password_admin = models.CharField(max_length=255, blank=True, null=True)
+ bmc_username = models.CharField(max_length=255, blank=True, null=True)
+ bmc_password = models.CharField(max_length=255, blank=True, null=True)
+
+ def __str__(self):
+ return "pk: %s , bmc_password_admin_default: %s , bmc_password_admin: %s , bmc_username: %s , bmc_password: %s" % (self.pk, self.bmc_password_admin_default, self.bmc_password_admin, self.bmc_username, self.bmc_password)
+
+ class Meta:
+ constraints = [models.UniqueConstraint(fields=["bmc_password_admin_default", "bmc_password_admin", "bmc_username", "bmc_password"], name="unique_credential")]
+
+
+class Chassis(models.Model):
+ serial_number = models.CharField(max_length=255, blank=True, null=True)
+
+ def __str__(self):
+ return "pk: %s , serial_number: %s" % (self.pk, self.serial_number)
+
+ class Meta:
+ constraints = [models.UniqueConstraint(fields=["serial_number"], name="unique_chassis")]
+
+
+class Blade(models.Model):
+ serial_number = models.CharField(max_length=255, blank=True, null=True)
+ credential = models.ForeignKey("Credential", on_delete=models.SET_NULL, blank=True, null=True)
+ chassis = models.ForeignKey("Chassis", on_delete=models.SET_NULL, blank=True, null=True)
+ vendor = models.ForeignKey("Vendor", on_delete=models.SET_NULL, blank=True, null=True)
+
+ def __str__(self):
+ return "pk: %s , serial_number: %s , chassis_id: %s , vendor_id: %s" % (self.pk, self.serial_number, self.chassis_id, self.vendor_id)
+
+ class Meta:
+ constraints = [models.UniqueConstraint(fields=["serial_number"], name="unique_blade")]
+
+
+class Vendor(models.Model):
+ vendor_name = models.CharField(max_length=255, blank=True, null=True)
def __str__(self):
- return "%s : %s : %s" % (self.server_hostname, self.cluster_name, self.namespace_name)
+ return "pk: %s , vendor_name: %s" % (self.pk, self.vendor_name)
+
+ class Meta:
+ constraints = [models.UniqueConstraint(fields=["vendor_name"], name="unique_vendor")]
+
+
+class FirmwareUpgradeSchedule(models.Model):
+ date_scheduled = models.DateTimeField(blank=True, null=True)
+ date_completed = models.DateTimeField(blank=True, null=True)
+ date_last_failed = models.DateTimeField(blank=True, null=True)
+ kirke_ticket_number = models.CharField(max_length=255, blank=True, null=True)
+ kirke_ticket_status = models.CharField(max_length=255, blank=True, null=True)
+ kirke_ticket_completed = models.DateTimeField(blank=True, null=True)
+ server = models.ForeignKey("Server", on_delete=models.SET_NULL, blank=True, null=True)
+
+ def __str__(self):
+ return "pk: %s , date_scheduled: %s , kirke_ticket_number: %s , server_id: %s" % (self.pk, self.date_scheduled, self.kirke_ticket_number, self.server_id)
+
+ class Meta:
+ constraints = [models.UniqueConstraint(fields=["server_id"], name="unique_firmwareupgradeschedule")]
+
+
+class WrInstallSchedule(models.Model):
+ date_scheduled = models.DateTimeField(blank=True, null=True)
+ date_completed = models.DateTimeField(blank=True, null=True)
+ date_last_failed = models.DateTimeField(blank=True, null=True)
+ kirke_ticket_number = models.CharField(max_length=255, blank=True, null=True)
+ kirke_ticket_status = models.CharField(max_length=255, blank=True, null=True)
+ kirke_ticket_completed = models.DateTimeField(blank=True, null=True)
+ cluster = models.ForeignKey("Cluster", on_delete=models.SET_NULL, blank=True, null=True)
+
+ def __str__(self):
+ return "pk: %s , date_scheduled: %s , kirke_ticket_number: %s , cluster_id: %s, date_completed: %s" % (self.pk, self.date_scheduled, self.kirke_ticket_number, self.cluster_id, self.date_completed)
+
+ class Meta:
+ constraints = [models.UniqueConstraint(fields=["cluster_id"], name="unique_wrinstallschedule")]
+
+
+class PatchSchedule(models.Model):
+ date_scheduled = models.DateTimeField(blank=True, null=True)
+ date_completed = models.DateTimeField(blank=True, null=True)
+ date_last_failed = models.DateTimeField(blank=True, null=True)
+ kirke_ticket_number = models.CharField(max_length=255, blank=True, null=True)
+ kirke_ticket_status = models.CharField(max_length=255, blank=True, null=True)
+ kirke_ticket_completed = models.DateTimeField(blank=True, null=True)
+ cluster = models.ForeignKey("Cluster", on_delete=models.SET_NULL, blank=True, null=True)
+
+ def __str__(self):
+ return "pk: %s , date_scheduled: %s , kirke_ticket_number: %s , cluster_id: %s" % (self.pk, self.date_scheduled, self.kirke_ticket_number, self.cluster_id)
+
+ class Meta:
+ constraints = [models.UniqueConstraint(fields=["cluster_id"], name="unique_patchschedule")]
+
+
+class IcingaBmc(DBView):
+ ilo_hostname = models.CharField(max_length=255, blank=True, null=True)
+ ilo_host_address = models.CharField(max_length=255, blank=True, null=True)
+ location = models.ForeignKey("Location", on_delete=models.DO_NOTHING, blank=True, null=True)
+ csr_hostname = models.CharField(max_length=255, blank=True, null=True)
+ oam_default_gateway = models.CharField(max_length=255, blank=True, null=True)
+ latitude = models.CharField(max_length=255, blank=True, null=True)
+ longitude = models.CharField(max_length=255, blank=True, null=True)
+ serial_number = models.CharField(max_length=255, blank=True, null=True)
+ vendor_name = models.CharField(max_length=255, blank=True, null=True)
+ bmc_password_admin_default = models.CharField(max_length=255, blank=True, null=True)
+ bmc_password_admin = models.CharField(max_length=255, blank=True, null=True)
+ bmc_username = models.CharField(max_length=255, blank=True, null=True)
+ bmc_password = models.CharField(max_length=255, blank=True, null=True)
+ date_completed = models.DateTimeField(blank=True, null=True)
+ view_definition = """
+select s.id,
+ s.ilo_hostname,
+ s.ilo_host_address,
+ l.id as location_id,
+ csr.oam_default_gateway,
+ l.latitude,
+ l.longitude,
+ csr.csr_hostname,
+ b.serial_number,
+ v.vendor_name,
+ cr.bmc_password_admin_default,
+ cr.bmc_password_admin,
+ cr.bmc_username,
+ cr.bmc_password,
+ ws.date_completed
+from caas_server s
+inner join caas_cluster c
+ on s.cluster_id = c.id
+inner join caas_location l
+ on c.location_id = l.id
+inner join caas_cellsiterouter csr
+ on c.csr_id = csr.id
+left outer join caas_blade b
+ on s.blade_id = b.id
+left outer join caas_vendor v
+ on b.vendor_id = v.id
+left outer join caas_credential cr
+ on b.credential_id = cr.id
+left outer join caas_wrinstallschedule ws
+ on c.id = ws.cluster_id
+where c.is_central_controller = 0;
+"""
+
+ def __str__(self):
+ return "pk: %s , ilo_hostname: %s , ilo_host_address: %s , csr_hostname: %s , oam_default_gateway: %s, latitude: %s , longitude: %s , bmc_password_admin_default: %s , bmc_password_admin: %s , bmc_username: %s , bmc_password: %s" % (self.pk, self.ilo_hostname, self.ilo_host_address, self.csr_hostname, self.oam_default_gateway, self.latitude, self.longitude, self.bmc_password_admin_default, self.bmc_password_admin, self.bmc_username, self.bmc_password, self.date_completed)
+
+ class Meta:
+ managed = False
+ db_table = "caas_icingabmc"
+
+
+class IcingaRouter(DBView):
+ csr_hostname = models.CharField(max_length=255, blank=True, null=True)
+ oam_default_gateway = models.CharField(max_length=255, blank=True, null=True)
+ view_definition = """
+select l.id as id,
+ csr.csr_hostname as csr_hostname,
+ csr.oam_default_gateway as oam_default_gateway
+from caas_server s
+inner join caas_cluster c
+ on s.cluster_id = c.id
+inner join caas_location l
+ on c.location_id = l.id
+inner join caas_cellsiterouter csr
+ on c.csr_id = csr.id
+left outer join caas_blade b
+ on s.blade_id = b.id
+left outer join caas_vendor v
+ on b.vendor_id = v.id
+left outer join caas_credential cr
+ on b.credential_id = cr.id
+where c.is_central_controller=0
+group by l.id,
+ csr.csr_hostname,
+ csr.oam_default_gateway;
+"""
+
+ def __str__(self):
+ return "pk: %s , csr_hostname: %s , oam_default_gateway: %s" % (self.pk, self.csr_hostname, self.oam_default_gateway)
+
+ class Meta:
+ managed = False
+ db_table = "caas_icingarouter"
+
+
+class FirmwareBatch(DBView):
+ ilo_host_address = models.CharField(max_length=255, blank=True, null=True)
+ ilo_hostname = models.CharField(max_length=255, blank=True, null=True)
+ intel_nic_firmware_version = models.CharField(max_length=255, blank=True, null=True)
+ bmc_username = models.CharField(max_length=255, blank=True, null=True)
+ bmc_password = models.CharField(max_length=255, blank=True, null=True)
+ view_definition = """
+select s.id,
+ s.ilo_hostname,
+ s.ilo_host_address,
+ s.intel_nic_firmware_version,
+ cr.bmc_username,
+ cr.bmc_password
+from caas_server s
+inner join caas_cluster c
+ on s.cluster_id = c.id
+left outer join caas_blade b
+ on s.blade_id = b.id
+left outer join caas_credential cr
+ on b.credential_id = cr.id
+where c.is_central_controller=0;
+"""
+
+ def __str__(self):
+ return "pk: %s , ilo_host_address: %s" % (self.pk, self.ilo_host_address)
+
+ class Meta:
+ managed = False
+ db_table = "caas_firmwarebatch"
+
+
+class WrBatch(DBView):
+ cluster_id = models.IntegerField()
+ fuze_spm_site_id = models.CharField(max_length=16)
+ parent_oam_vip_hostname = models.CharField(max_length=255, blank=True, null=True)
+ parent_oam_vip_address = models.CharField(max_length=255, blank=True, null=True)
+ parent_mgmt_address_range_start = models.CharField(max_length=255, blank=True, null=True)
+ parent_mgmt_address_range_end = models.CharField(max_length=255, blank=True, null=True)
+ parent_mgmt_default_gateway = models.CharField(max_length=255, blank=True, null=True)
+ parent_mgmt_subnet = models.CharField(max_length=255, blank=True, null=True)
+ pxe_mac_address = models.CharField(max_length=255, blank=True, null=True)
+ ilo_hostname = models.CharField(max_length=255, blank=True, null=True)
+ ilo_host_address = models.CharField(max_length=255, blank=True, null=True)
+ oam_hostname = models.CharField(max_length=255, blank=True, null=True)
+ oam_host_address = models.CharField(max_length=255, blank=True, null=True)
+ oam_vip_address = models.CharField(max_length=255, blank=True, null=True)
+ oam_default_gateway = models.CharField(max_length=255, blank=True, null=True)
+ mgmt_address_range_start = models.CharField(max_length=255, blank=True, null=True)
+ mgmt_address_range_end = models.CharField(max_length=255, blank=True, null=True)
+ mgmt_default_gateway = models.CharField(max_length=255, blank=True, null=True)
+ mgmt_subnet = models.CharField(max_length=255, blank=True, null=True)
+ host_vlan = models.PositiveSmallIntegerField()
+ oam_vlan = models.PositiveSmallIntegerField()
+ mgmt_vlan = models.PositiveSmallIntegerField()
+ cluster_name = models.CharField(max_length=255, blank=True, null=True)
+ parent_cluster_name = models.CharField(max_length=255, blank=True, null=True)
+ vendor_name = models.CharField(max_length=255, blank=True, null=True)
+ intel_nic_firmware_version = models.CharField(max_length=255, blank=True, null=True)
+ maint_window_p = models.BooleanField(default=False, blank=True, null=True)
+ namespace_id = models.IntegerField()
+ namespace_name = models.CharField(max_length=255, blank=True, null=True)
+ bmc_username = models.CharField(max_length=255, blank=True, null=True)
+ bmc_password = models.CharField(max_length=255, blank=True, null=True)
+ view_definition = """
+select s.id,
+ c.id as cluster_id,
+ l.fuze_spm_site_id,
+ cp.oam_vip_hostname as parent_oam_vip_hostname,
+ cp.oam_vip_address as parent_oam_vip_address,
+ cp.mgmt_address_range_start as parent_mgmt_address_range_start,
+ cp.mgmt_address_range_end as parent_mgmt_address_range_end,
+ cp.mgmt_default_gateway as parent_mgmt_default_gateway,
+ cp.mgmt_subnet as parent_mgmt_subnet,
+ s.pxe_mac_address,
+ s.ilo_hostname,
+ s.ilo_host_address,
+ s.oam_hostname,
+ s.oam_host_address,
+ c.oam_vip_address,
+ csr.oam_default_gateway,
+ c.mgmt_address_range_start,
+ c.mgmt_address_range_end,
+ c.mgmt_default_gateway,
+ c.mgmt_subnet,
+ vl.host_vlan,
+ vl.oam_vlan,
+ vl.mgmt_vlan,
+ c.cluster_name,
+ cp.cluster_name as parent_cluster_name,
+ v.vendor_name,
+ s.intel_nic_firmware_version,
+ l.maint_window_p,
+ n.id as namespace_id,
+ n.namespace_name,
+ cr.bmc_username,
+ cr.bmc_password
+from caas_server s
+inner join caas_cluster c
+ on s.cluster_id = c.id
+left outer join caas_cluster cp
+ on c.parent_cluster_id = cp.id
+inner join caas_cellsiterouter csr
+ on c.csr_id = csr.id
+inner join caas_cellsiterouter csrp
+ on cp.csr_id = csrp.id
+inner join caas_location l
+ on c.location_id = l.id
+inner join caas_vlan vl
+ on c.vlan_id = vl.id
+inner join caas_namespace n
+ on c.namespace_id = n.id
+left outer join caas_blade b
+ on s.blade_id = b.id
+left outer join caas_vendor v
+ on b.vendor_id = v.id
+left outer join caas_credential cr
+ on b.credential_id = cr.id
+where c.parent_cluster_id is not null;
+"""
+
+ def __str__(self):
+ return "pk: %s , ilo_host_address: %s , cluster_name : %s" % (self.pk, self.ilo_host_address, self.cluster_name)
+
+ class Meta:
+ managed = False
+ db_table = "caas_wrbatch"
diff --git a/src/caas/services/ansibleservice.py b/src/caas/services/ansibleservice.py
new file mode 100644
index 0000000..148bcf4
--- /dev/null
+++ b/src/caas/services/ansibleservice.py
@@ -0,0 +1,52 @@
+from django.conf import settings
+import json
+import zmq
+import logging
+
+
+logger = logging.getLogger("caas")
+
+
+"""
+Superclass for classes that manage ansible playbooks, for example
+icinga and wr-installer.
+"""
+class AnsibleService():
+ def __init__(self, ansible_queue, target, git, branch, playbook, zmq, maint_window_p = False):
+ self.ansible_queue = ansible_queue
+ self.target = target
+ self.git = git
+ self.branch = branch
+ self.playbook = playbook
+ self.zmq = zmq
+ self.maint_window_p = maint_window_p
+
+ def run_playbook(self, inventory, inventory_content, hostvars, hostvars_content, extra_args = {}):
+ payload = [{"git": self.git,
+ "playbook": self.playbook,
+ "maintWindowP": self.maint_window_p,
+ "inventory": inventory,
+ "inventoryContent": inventory_content,
+ "hostvars": hostvars,
+ "hostvarsContent": hostvars_content}]
+ payload[0].update(extra_args)
+ payload_json = json.dumps(payload)
+ context = zmq.Context()
+ retries = 10
+ while True:
+ socket = context.socket(zmq.REQ)
+ if settings.ZEROMQ_IPV6:
+ socket.setsockopt(zmq.IPV6, 1)
+ # logger.debug("sending playbook: %s" % payload_json)
+ socket.connect(self.zmq)
+ socket.send_string(payload_json)
+ logger.debug("sent playbook")
+ if (socket.poll(5000) & zmq.POLLIN) != 0:
+ return socket.recv()
+ retries -= 1
+ socket.setsockopt(zmq.LINGER, 0)
+ socket.close()
+ if retries == 0:
+ errmsg = "Failed to send zmq message to ansible-queue: %s" % payload_json
+ logger.error(errmsg)
+ raise Exception(errmsg)
diff --git a/src/caas/services/bmcservice.py b/src/caas/services/bmcservice.py
new file mode 100644
index 0000000..43fdb51
--- /dev/null
+++ b/src/caas/services/bmcservice.py
@@ -0,0 +1,50 @@
+from .helpers import Jinja
+from .ansibleservice import AnsibleService
+from ..models import IcingaBmc
+from django.conf import settings
+import logging
+
+
+logger = logging.getLogger("caas")
+
+
+class BmcService(AnsibleService):
+ def __init__(self, target, git, branch, playbook, zmq):
+ super().__init__("bmc", target, git, branch, playbook, zmq)
+
+ def deploy(self):
+ logger.debug("%s Enter" % self.target)
+ try:
+ bmc_kwargs = {"ilo_host_address": self.target}
+ bmc = IcingaBmc.objects.get(**bmc_kwargs)
+ except IcingaBmc.DoesNotExist:
+ errmsg = "%s FAILED: while running BMC playbook: failed to look up BMC" % self.target
+ logger.error(errmsg)
+ return -1
+ # The ansible target is the hostname, but until now we only had the ilo IP.
+ self.target = bmc.ilo_hostname
+ # host_vars file
+ hostvars_config = {"bmc_ip": bmc.ilo_host_address,
+ "bmc_password_admin_default": bmc.bmc_password_admin_default,
+ "bmc_password_admin": bmc.bmc_password_admin,
+ "bmc_username": bmc.bmc_username,
+ "bmc_password": bmc.bmc_password,
+ "dns_nameservers": (" ").join(settings.DNS_SERVERS),
+ "syslog_server": settings.SYSLOG_SERVER,
+ "syslog_server_port": settings.SYSLOG_SERVER_PORT,
+ "ntp_servers": (" ").join(settings.NTP_SERVERS),
+ "middleware_endpoint": settings.CAAS_MIDDLEWARE_ENDPOINT,
+ "middleware_username": settings.CAAS_MIDDLEWARE_USERNAME,
+ "middleware_password": settings.CAAS_MIDDLEWARE_PASSWORD}
+ hostvars_content = Jinja.render("bmc_host_vars.j2", **hostvars_config)
+ hostvars = self.target
+ # inventory file
+ inventory_config = {"vendor_name": bmc.vendor_name,
+ "target": self.target}
+ inventory_content = Jinja.render("bmc_inventory.j2", **inventory_config)
+ inventory = "%s.yaml" % self.target
+ logger.debug("%s Sending playbook to queue" % self.target)
+ self.run_playbook(inventory, inventory_content, hostvars, hostvars_content)
+ logger.debug("%s Sent playbook to queue" % self.target)
+ return 0
+
diff --git a/src/caas/services/ciqservice.py b/src/caas/services/ciqservice.py
new file mode 100644
index 0000000..a97e9e0
--- /dev/null
+++ b/src/caas/services/ciqservice.py
@@ -0,0 +1,193 @@
+import csv
+import ipaddress
+from io import TextIOWrapper
+from django.db import connections
+from django.conf import settings
+from .helpers import Address, RawQuery
+from ..models import Vlan, Namespace, CellSiteRouter, SapClli, Location, Cluster, Server
+
+
+"""
+Derive IPs from rules defined in the LLD:
+https://oneconfluence.verizon.com/display/NTD/VRAN+2.0+Far+Edge?preview=/554294908/592448982/vRAN%202.0%20on%20VCP%20Far%20Edge_WebScale%20Transport%20LLD%20v2.3.pdf
+"""
+class CiqService():
+ @staticmethod
+ def import_ciq_data(filehandle, assign_parent = False):
+ with connections["default"].cursor() as cursor:
+ f = TextIOWrapper(filehandle, encoding = "ascii", errors = "replace")
+ csv_reader = csv.reader(f, delimiter = ",")
+ for row in csv_reader:
+ # Fetch data from CSV row
+ fuze_spm_site_id = row[1]
+ fuze_spm_site_name = row[3]
+ fuze_spm_market = row[4]
+ fuze_spm_submarket = row[5]
+ fuze_spm_site_type = row[6]
+ central_controller_sap_clli = row[7]
+ server_number = int(row[9])
+ ilo_hostname = row[10].lower()
+ cluster_name = row[11].lower()
+ namespace_name = row[12].lower()
+ host_vlan = int(row[13])
+ oam_vlan = int(row[14])
+ mgmt_vlan = int(row[15])
+ csr_hostname = row[17]
+ ilo_host_address = ipaddress.IPv6Address(row[23])
+ ilo_default_gateway = ipaddress.IPv6Address(row[24])
+ mgmt_default_gateway = ipaddress.IPv6Address(row[25])
+ oam_default_gateway = ipaddress.IPv6Address(row[26])
+ central_controller_p = bool(row[28])
+
+ # Use the minimum uniquely identifying data to load existing matching records if available
+
+ # location
+ location_kwargs = {"fuze_spm_site_id": fuze_spm_site_id}
+ location, location_created = Location.objects.get_or_create(**location_kwargs)
+ location.fuze_spm_site_name = fuze_spm_site_name
+ location.fuze_spm_market = fuze_spm_market
+ location.fuze_spm_submarket = fuze_spm_submarket
+ location.fuze_spm_site_type = fuze_spm_site_type
+
+ # vlan
+ vlan_kwargs = {"host_vlan": host_vlan,
+ "oam_vlan": oam_vlan,
+ "mgmt_vlan": mgmt_vlan}
+ vlan, vlan_created = Vlan.objects.get_or_create(**vlan_kwargs)
+
+ # csr
+ csr_kwargs = {"csr_hostname": csr_hostname}
+ csr, csr_created = CellSiteRouter.objects.get_or_create(**csr_kwargs)
+
+ # sap_clli
+ sap_clli_kwargs = {"clli": central_controller_sap_clli}
+ sap_clli, sap_clli_created = SapClli.objects.get_or_create(**sap_clli_kwargs)
+
+ # cluster
+ cluster_kwargs = {"cluster_name": cluster_name}
+ cluster, cluster_created = Cluster.objects.get_or_create(**cluster_kwargs)
+
+ # namespaces
+ namespace_kwargs = {"namespace_name": namespace_name}
+ namespace, namespace_created = Namespace.objects.get_or_create(**namespace_kwargs)
+
+ # server
+ server_kwargs = {"ilo_hostname": ilo_hostname}
+ server, server_created = Server.objects.get_or_create(**server_kwargs)
+
+ parent_cluster = None
+
+ if not central_controller_p:
+ # find least-used parent central controller cluster
+ parent_clusters_kwargs = {"sap_clli_id__exact": sap_clli.pk,
+ "parent_cluster_id__isnull": True,
+ "is_central_controller": 1}
+ parent_clusters = Cluster.objects.filter(**parent_clusters_kwargs)
+ subcloud_counts = {}
+
+ for parent in parent_clusters:
+ num_children = RawQuery.query_single_value(cursor, """
+select count(*) as num_children
+from caas_cluster
+where parent_cluster_id = %s and is_central_controller = 0""" % parent.pk, "num_children")
+
+ if num_children < settings.WR_MAX_CHILD_CLUSTERS:
+ subcloud_counts[parent.pk] = [num_children, parent]
+
+ if len(subcloud_counts) != 0:
+ parent_cluster = min(subcloud_counts.items(), key=lambda x: x[1][0])[1][1]
+
+ # Derive subnets from gateways
+ oam_subnet = Address.add_40a(Address.gateway_to_subnet(oam_default_gateway))
+ mgmt_subnet = Address.add_40a(Address.gateway_to_subnet(mgmt_default_gateway))
+ ilo_subnet = Address.add_40a(Address.gateway_to_subnet(ilo_default_gateway))
+
+ # oam vip
+ need_ip = False
+
+ if csr.oam_subnet == str(oam_subnet) and csr.oam_default_gateway == str(oam_default_gateway):
+ if cluster.oam_vip_address is None:
+ need_ip = True
+ else:
+ csr.oam_subnet = str(oam_subnet)
+ csr.oam_default_gateway = str(oam_default_gateway)
+ need_ip = True
+ if need_ip:
+ oam_vip_address_max = RawQuery.query_single_value(cursor, """
+with oam_ips as (
+ select csr.id as csr_id,
+ c.oam_vip_address
+ from caas_server s
+ inner join caas_cluster c
+ on s.cluster_id = c.id
+ inner join caas_cellsiterouter csr
+ on c.csr_id = csr.id
+)
+select max(oam_vip_address) as max
+from oam_ips
+where csr_id = %s""" % csr.id, "max")
+ if oam_vip_address_max:
+ oam_vip_address_max = str(Address.next_address(oam_vip_address_max, oam_subnet, 0x10))
+ else:
+ oam_vip_address_max = str(Address.next_address(oam_vip_address_max, oam_subnet, 0xf400))
+ cluster.oam_vip_address = oam_vip_address_max
+ # oam host
+ need_ip = False
+ if csr.oam_subnet == str(oam_subnet) and csr.oam_default_gateway == str(oam_default_gateway):
+ if server.oam_host_address is None:
+ need_ip = True
+ else:
+ csr.oam_subnet = str(oam_subnet)
+ csr.oam_default_gateway = str(oam_default_gateway)
+ need_ip = True
+ if need_ip:
+ oam_host_address_max = RawQuery.query_single_value(cursor, """
+with oam_ips as (
+ select csr.id as csr_id,
+ s.oam_host_address
+ from caas_server s
+ inner join caas_cluster c
+ on s.cluster_id = c.id
+ inner join caas_cellsiterouter csr
+ on c.csr_id = csr.id
+)
+select max(oam_host_address) as max
+from oam_ips
+where csr_id = %s""" % csr.id, "max")
+ if oam_host_address_max:
+ oam_host_address_max = str(Address.next_address(oam_host_address_max, oam_subnet, 0x1))
+ else:
+ oam_host_address_max = str(Address.next_address(oam_host_address_max, oam_subnet, 0x400))
+ server.oam_host_address = oam_host_address_max
+
+ # mgmt
+ cluster.mgmt_subnet = str(mgmt_subnet)
+ cluster.mgmt_default_gateway = str(mgmt_default_gateway)
+ cluster.mgmt_address_range_start = str(mgmt_subnet)
+ cluster.mgmt_address_range_end = str(Address.address_add(cluster.mgmt_address_range_start, 0xf))
+
+ # don't step on central controllers TODO: separate central and remote CIQ ingestion
+ csr.ilo_subnet = str(ilo_subnet)
+ csr.ilo_default_gateway = str(ilo_default_gateway)
+ server.server_number = server_number
+ server.ilo_host_address = str(ilo_host_address)
+ else:
+ cluster.is_central_controller = 1
+
+ # foreign-key relationships
+ cluster.sap_clli = sap_clli
+ if assign_parent is True and cluster.parent_cluster is None:
+ cluster.parent_cluster = parent_cluster
+ cluster.location = location
+ cluster.vlan = vlan
+ cluster.csr = csr
+ cluster.namespace = namespace
+ server.cluster = cluster
+ # upsert
+ vlan.save()
+ namespace.save()
+ csr.save()
+ sap_clli.save()
+ location.save()
+ cluster.save()
+ server.save()
diff --git a/src/caas/services/dnsservice.py b/src/caas/services/dnsservice.py
new file mode 100644
index 0000000..bd8c388
--- /dev/null
+++ b/src/caas/services/dnsservice.py
@@ -0,0 +1,60 @@
+from django.conf import settings
+from .helpers import Jinja, Hostname
+from .ansibleservice import AnsibleService
+from ..models import Server, Cluster
+import logging
+
+
+logger = logging.getLogger("caas")
+
+
+class DnsService(AnsibleService):
+ def __init__(self, target, git, branch, playbook, zmq):
+ super().__init__("dns", target, git, branch, playbook, zmq)
+
+ def deploy(self):
+ logger.debug("%s Enter" % self.target)
+ try:
+ server_kwargs = {"ilo_host_address": self.target}
+ server = Server.objects.get(**server_kwargs)
+ except Server.DoesNotExist:
+ errmsg = "%s FAILED: while running DNS playbook: failed to look up server" % self.target
+ logger.error(errmsg)
+ return -1
+ try:
+ cluster_kwargs = {"id": server.cluster.pk}
+ cluster = Cluster.objects.get(**cluster_kwargs)
+ except Cluster.DoesNotExist:
+ errmsg = "%s FAILED: while running DNS playbook: failed to look up cluster" % self.target
+ logger.error(errmsg)
+ return -1
+ server.oam_hostname = Hostname.make_oam_hostname(server.ilo_hostname)
+ if cluster.oam_vip_hostname is None:
+ cluster.oam_vip_hostname = Hostname.make_vip_hostname(server.ilo_hostname, cluster.cluster_name)
+ cluster.save()
+ server.save()
+ # The ansible target is the ilo hostname, but until now we only had the ilo IP.
+ self.target = server.ilo_hostname
+ # host_vars file
+ hostvars_config = {"ilo_hostname": server.ilo_hostname,
+ "ilo_host_address": server.ilo_host_address,
+ "oam_hostname": server.oam_hostname,
+ "oam_host_address": server.oam_host_address,
+ "oam_vip_hostname": cluster.oam_vip_hostname,
+ "oam_vip_address": cluster.oam_vip_address,
+ "cluster_name": cluster.cluster_name,
+ "dns_admin_endpoint": settings.DNS_ADMIN_ENDPOINT,
+ "dns_domain": settings.DNS_DOMAIN,
+ "infoblox_username": settings.INFOBLOX_USERNAME,
+ "infoblox_password": settings.INFOBLOX_PASSWORD}
+ hostvars_content = Jinja.render("dns_host_vars.j2", **hostvars_config)
+ hostvars = server.ilo_hostname
+ # inventory file
+ inventory_config = {"target": self.target}
+ inventory_content = Jinja.render("dns_inventory.j2", **inventory_config)
+ inventory = "%s.yaml" % self.target
+ logger.debug("%s Sending playbook to queue" % self.target)
+ self.run_playbook(inventory, inventory_content, hostvars, hostvars_content)
+ logger.debug("%s Sent playbook to queue" % self.target)
+ return 0
+
diff --git a/src/caas/services/firmwareservice.py b/src/caas/services/firmwareservice.py
new file mode 100644
index 0000000..97bfecc
--- /dev/null
+++ b/src/caas/services/firmwareservice.py
@@ -0,0 +1,87 @@
+import datetime
+from .helpers import Jinja
+from .ansibleservice import AnsibleService
+from ..models import FirmwareUpgradeSchedule, FirmwareBatch
+from django.conf import settings
+import logging
+
+
+logger = logging.getLogger("caas")
+
+
+"""
+Expected versions. The bottom one is OK; the top one is too old.
+firmware-version: 6.00 0x800036cb 1.1747.0
+firmware-version: 7.20 0x80007fdf 1.2585.0
+"""
+class FirmwareService(AnsibleService):
+ """
+ target == ilo_host_address
+ """
+ def __init__(self, target, git, branch, playbook, zmq):
+ super().__init__("nic", target, git, branch, playbook, zmq)
+
+ def schedule_upgrade(self):
+ logger.debug("%s Enter schedule_upgrade" % self.target)
+ try:
+ firmwarebatch_kwargs = {"ilo_host_address": self.target}
+ firmwarebatch = FirmwareBatch.objects.get(**firmwarebatch_kwargs)
+ except FirmwareBatch.DoesNotExist:
+ errmsg = "%s FAILED: while checking Intel NIC firmware version: cannot find server" % self.target
+ logger.error(errmsg)
+ return -1
+ if firmwarebatch.intel_nic_firmware_version != settings.INTEL_NIC_FIRMWARE_VERSION:
+ firmware_kwargs = {"server_id": firmwarebatch.pk}
+ firmware, firmware_created = FirmwareUpgradeSchedule.objects.get_or_create(**firmware_kwargs)
+ if firmware.date_scheduled == None:
+ firmware.date_scheduled = datetime.datetime.now()
+ if firmware.kirke_ticket_number == None:
+ # TODO bealer: create KIRKE ticket
+ pass
+ firmware.save()
+ return 0
+
+ def deploy(self):
+ logger.debug("%s Enter deploy" % self.target)
+ kirke_inprocess_kwargs = {"kirke_ticket_number__isnull": False,
+ "kirke_ticket_completed__isnull": True}
+ kirke_inprocess = FirmwareUpgradeSchedule.objects.filter(**kirke_inprocess_kwargs)
+ for rec in kirke_inprocess:
+ # TODO bealer: query KIRKE and update status
+ rec.save()
+ firmware_schedule_kwargs = {"kirke_ticket_completed__isnull": False,
+ "date_completed__isnull": True}
+ firmware_schedule_ready = FirmwareUpgradeSchedule.objects.filter(**firmware_schedule_kwargs)
+ for sched in firmware_schedule_ready:
+ try:
+ firmwarebatch_kwargs = {"pk": sched.server.pk}
+ firmwarebatch = FirmwareBatch.objects.get(**firmwarebatch_kwargs)
+ except FirmwareBatch.DoesNotExist:
+ errmsg = "%s FAILED: while running firmware batch playbook: failed to look up batch" % self.target
+ logger.error(errmsg)
+ return -1
+ self.target = firmwarebatch.ilo_hostname
+ # host_vars file
+ hostvars_config = {"ilo_host_address": firmwarebatch.ilo_host_address,
+ "wr_bmc_username": firmwarebatch.bmc_username,
+ "wr_bmc_password": firmwarebatch.bmc_password,
+ "wr_webdav_firmwarebatch": settings.WR_WEBDAV_SERVER,
+ "wr_webdav_server": settings.WR_WEBDAV_SERVER,
+ "wr_webdav_username": settings.WR_WEBDAV_USERNAME,
+ "wr_webdav_password": settings.WR_WEBDAV_PASSWORD,
+ "middleware_endpoint": settings.CAAS_MIDDLEWARE_ENDPOINT,
+ "middleware_username": settings.CAAS_MIDDLEWARE_USERNAME,
+ "middleware_password": settings.CAAS_MIDDLEWARE_PASSWORD,
+ "wr_registry_server": settings.WR_REGISTRY_SERVER,
+ "firmware_iso": settings.FIRMWARE_ISO}
+ hostvars_content = Jinja.render("firmware_host_vars.j2", **hostvars_config)
+ hostvars = self.target
+ # inventory file
+ inventory_config = {"target": firmwarebatch.ilo_hostname,
+ "ilo_host_address": firmwarebatch.ilo_host_address}
+ inventory_content = Jinja.render("firmware_inventory.j2", **inventory_config)
+ inventory = "%s.yaml" % self.target
+ logger.debug("%s Sending playbook to queue" % self.target)
+ self.run_playbook(inventory, inventory_content, hostvars, hostvars_content, extra_args = {"autoremediate": firmwarebatch.ilo_host_address})
+ logger.debug("%s Sent playbook to queue" % self.target)
+ return 0
diff --git a/src/caas/services/helpers.py b/src/caas/services/helpers.py
new file mode 100644
index 0000000..9145d1f
--- /dev/null
+++ b/src/caas/services/helpers.py
@@ -0,0 +1,136 @@
+import ipaddress
+import jinja2
+import os
+import subprocess
+
+
+class Shell():
+ @staticmethod
+ def run_shell_command(cmd):
+ p = subprocess.Popen([cmd],
+ shell=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ env={})
+ out, err = p.communicate()
+ if p.returncode != 0:
+ raise Exception("Error running shell command:\n%s\n%s" % (out, err))
+ return out, err
+
+
+class Jinja():
+ @staticmethod
+ def render(template_name, **kwargs):
+ cwd = os.path.dirname(os.path.abspath(__file__))
+ loader = jinja2.FileSystemLoader([".", "/"])
+ extensions = ["jinja2.ext.with_", "jinja2.ext.loopcontrols"]
+ environment = jinja2.Environment(trim_blocks = True,
+ lstrip_blocks = True,
+ extensions = extensions,
+ loader = loader)
+ template_names = ["%s/jinja/%s" % (cwd, template_name)]
+ template = environment.select_template(template_names)
+ return template.render(kwargs)
+
+
+class RawQuery():
+ @staticmethod
+ def dict_fetchall(cursor):
+ rows = cursor.fetchall()
+ if len(rows) == 0:
+ return None
+ else:
+ columns = [col[0] for col in cursor.description]
+ return [dict(zip(columns, row)) for row in rows]
+
+ @staticmethod
+ def query_single_value(cursor, query, column_name):
+ cursor.execute(query)
+ rows = RawQuery.dict_fetchall(cursor)
+ if rows == {}:
+ return None
+ else:
+ return rows[0][column_name]
+
+
+class Address():
+ @staticmethod
+ def coalesce(ip, default):
+ if ip is None:
+ return default
+ else:
+ return ip
+
+ @staticmethod
+ def get_quads(addr):
+ return list(filter(lambda x: x, str(addr).split("/")[0].split(":")))
+
+ @staticmethod
+ def address_add(ip, index):
+ return ipaddress.IPv6Address(ip) + index
+
+ """
+ Assumes a 5-quad 'subnet' as import input. Adds the 6th quad which is always 40a.
+ """
+ @staticmethod
+ def add_40a(subnet):
+ return Address.address_add(subnet, 0x040a00000000)
+
+ @staticmethod
+ def next_address(ip, subnet, block_begin_hex):
+ beginning_address = Address.coalesce(ip, Address.address_add(subnet, block_begin_hex))
+ if ip is None:
+ return beginning_address
+ else:
+ return Address.address_add(beginning_address, 0x1)
+
+ @staticmethod
+ def add_cidr(subnet, cidr = 64):
+ subnet_quads = Address.get_quads(subnet)
+ return "%s::/%s" % (":".join(subnet_quads), cidr)
+
+ @staticmethod
+ def remove_cidr(subnet):
+ return ipaddress.IPv6Address(str(subnet).split("/")[0])
+
+ @staticmethod
+ def gateway_to_subnet(gateway, numquads = 5):
+ # The subnet is always the first 5 quads of the gateway.
+ # TODO: make sure this holds true in MTCE and labs as well as production.
+ quads = Address.get_quads(gateway)
+ return ipaddress.IPv6Address("%s::" % ":".join(quads[:numquads]))
+
+ @staticmethod
+ def gateway_to_subnet_new(gateway):
+ quads = Address.get_quads(gateway)
+ return ipaddress.IPv6Address("%s:40a::" % ":".join(quads[:5]))
+
+ @staticmethod
+ def subnet_to_4_quads(subnet):
+ quads = Address.get_quads(gateway)
+ return ipaddress.IPv6Address("%s::" % ":".join(quads[:4]))
+
+ @staticmethod
+ def strip_brackets(ip):
+ return ip.replace("[", "").replace("]", "")
+
+
+class Hostname():
+ @staticmethod
+ def make_oam_hostname(ilo_hostname):
+ return ilo_hostname.replace("-pe0", "-pe2")
+
+ """
+ Note: this method does not deal with the index at the end of the
+ hostname. Doing so would require database access. This is the
+ responsibility of the service classes. See dnsservice.py
+ """
+ @staticmethod
+ def make_vip_hostname(ilo_hostname, cluster_name):
+ index = int(cluster_name[-3:])
+ return "%s-%s" % (ilo_hostname.replace("-pe0", "-pe1")[:-4], f"{index + 0:03}")
+
+ @staticmethod
+ def increment_hostname(hostname):
+ index = int(hostname[-3:])
+ return "%s-%s" % (hostname[:-4], f"{index + 1:03}")
diff --git a/src/caas/services/httpclient.py b/src/caas/services/httpclient.py
new file mode 100644
index 0000000..ad8270b
--- /dev/null
+++ b/src/caas/services/httpclient.py
@@ -0,0 +1,18 @@
+import requests
+from requests.packages.urllib3.exceptions import InsecureRequestWarning
+from requests.auth import HTTPBasicAuth
+
+
+class HttpClient(object):
+ def __init__(self):
+ requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
+ self.session = requests.Session()
+
+ def post(self, url, username, password, data = None, headers = {}, timeout = 60):
+ resp = self.session.post(url = url,
+ auth = HTTPBasicAuth(username, password),
+ json = data,
+ headers = headers,
+ timeout = timeout,
+ verify = False)
+ return resp
diff --git a/src/caas/services/icingapollservice.py b/src/caas/services/icingapollservice.py
new file mode 100644
index 0000000..d1796d0
--- /dev/null
+++ b/src/caas/services/icingapollservice.py
@@ -0,0 +1,47 @@
+from .helpers import Jinja
+from .ansibleservice import AnsibleService
+from ..models import IcingaBmc
+from django.conf import settings
+import logging
+
+
+logger = logging.getLogger("caas")
+
+
+class IcingaPollService(AnsibleService):
+ def __init__(self, target, git, branch, playbook, zmq, url):
+ super().__init__("icinga_poll", target, git, branch, playbook, zmq)
+ self.url = url
+
+ def deploy(self):
+ logger.debug("%s Enter" % self.target)
+ try:
+ icinga_poll_kwargs = {"ilo_host_address": self.target}
+ icinga_poll = IcingaBmc.objects.get(**icinga_poll_kwargs)
+ except IcingaBmc.DoesNotExist:
+ logger.error("%s FAILED: while running icinga_poll playbook: failed to look up BMC" % self.target)
+ return -1
+
+ self.target = icinga_poll.ilo_hostname
+ # host_vars file
+ hostvars_config = {"bmc_ip": icinga_poll.ilo_host_address,
+ "bmc_username": icinga_poll.bmc_username,
+ "bmc_password": icinga_poll.bmc_password,
+ "icinga_api_url": settings.ICINGA_API_URL,
+ "icinga_api_username": settings.ICINGA_API_USERNAME,
+ "icinga_api_password": settings.ICINGA_API_PASSWORD,
+ "middleware_endpoint": settings.CAAS_MIDDLEWARE_ENDPOINT,
+ "middleware_username": settings.CAAS_MIDDLEWARE_USERNAME,
+ "middleware_password": settings.CAAS_MIDDLEWARE_PASSWORD,
+ "middleware_url": self.url}
+ hostvars_content = Jinja.render("icinga_poll_host_vars.j2", **hostvars_config)
+ hostvars = self.target
+ # inventory file
+ inventory_config = {"vendor_name": icinga_poll.vendor_name, "target": self.target}
+ inventory_content = Jinja.render("icinga_poll_inventory.j2", **inventory_config)
+ inventory = "%s.yaml" % self.target
+ logger.debug("%s Sending playbook to queue" % self.target)
+ self.run_playbook(inventory, inventory_content, hostvars, hostvars_content)
+ logger.debug("%s Sent playbook to queue" % self.target)
+ return 0
+
diff --git a/src/caas/services/icingaservice.py b/src/caas/services/icingaservice.py
new file mode 100644
index 0000000..4d1ff67
--- /dev/null
+++ b/src/caas/services/icingaservice.py
@@ -0,0 +1,46 @@
+from .helpers import Jinja
+from .ansibleservice import AnsibleService
+from .macaddressservice import MacAddressService
+from ..models import IcingaBmc, IcingaRouter
+from django.conf import settings
+import logging
+
+
+logger = logging.getLogger("caas")
+
+
+class IcingaService(AnsibleService):
+ def __init__(self, target, git, branch, playbook, zmq):
+ super().__init__("icinga", target, git, branch, playbook, zmq)
+
+ def deploy(self, mockciq = False):
+ logger.debug("%s Enter" % self.target)
+ # host_vars file
+ hostvars_config = {"icinga_routers": [], "icinga_bmcs": []}
+ for router in IcingaRouter.objects.all():
+ hostvars_config["icinga_routers"].append({"name": router.csr_hostname,
+ "address6": router.oam_default_gateway})
+ server_kwargs = {"date_completed": None}
+ servers = IcingaBmc.objects.filter(**server_kwargs)
+ for server in servers:
+ hostvars_config["icinga_bmcs"].append({"name": server.ilo_hostname,
+ "address6": server.ilo_host_address,
+ "preauth": True if mockciq or server.bmc_password_admin_default is None or MacAddressService.get_server_mac_address(server.ilo_host_address) is None else False,
+ "bmc_password_admin_default": server.bmc_password_admin_default,
+ "bmc_password_admin": server.bmc_password_admin,
+ "bmc_username": server.bmc_username,
+ "bmc_password": server.bmc_password,
+ "middleware_endpoint": settings.CAAS_MIDDLEWARE_ENDPOINT,
+ "middleware_username": settings.CAAS_MIDDLEWARE_USERNAME,
+ "middleware_password": settings.CAAS_MIDDLEWARE_PASSWORD})
+
+ hostvars_content = Jinja.render("icinga_host_vars.j2", **hostvars_config)
+ hostvars = self.target
+ # inventory file
+ inventory_config = {"target": self.target}
+ inventory_content = Jinja.render("icinga_inventory.j2", **inventory_config)
+ inventory = "%s.yaml" % self.target
+ logger.debug("%s Sending playbook to queue" % self.target)
+ self.run_playbook(inventory, inventory_content, hostvars, hostvars_content)
+ logger.debug("%s Sent playbook to queue" % self.target)
+ return 0
diff --git a/src/caas/services/jinja/bmc_host_vars.j2 b/src/caas/services/jinja/bmc_host_vars.j2
new file mode 100644
index 0000000..eb56bdd
--- /dev/null
+++ b/src/caas/services/jinja/bmc_host_vars.j2
@@ -0,0 +1,13 @@
+---
+bmc_ip: "{{ bmc_ip }}"
+bmc_password_admin_default: "{{ bmc_password_admin_default }}"
+bmc_password_admin: "{{ bmc_password_admin }}"
+bmc_username: "{{ bmc_username }}"
+bmc_password: "{{ bmc_password }}"
+dns_nameservers: "{{ dns_nameservers }}"
+syslog_server: "{{ syslog_server }}"
+syslog_server_port: "{{ syslog_server_port }}"
+ntp_servers: "{{ ntp_servers }}"
+middleware_endpoint: "{{ middleware_endpoint }}"
+middleware_username: "{{ middleware_username }}"
+middleware_password: "{{ middleware_password }}"
diff --git a/src/caas/services/jinja/bmc_inventory.j2 b/src/caas/services/jinja/bmc_inventory.j2
new file mode 100644
index 0000000..6ef8ca2
--- /dev/null
+++ b/src/caas/services/jinja/bmc_inventory.j2
@@ -0,0 +1,6 @@
+---
+all:
+ children:
+ {{ vendor_name }}:
+ hosts:
+ {{ target }}
diff --git a/src/caas/services/jinja/dns_host_vars.j2 b/src/caas/services/jinja/dns_host_vars.j2
new file mode 100644
index 0000000..2e66a8f
--- /dev/null
+++ b/src/caas/services/jinja/dns_host_vars.j2
@@ -0,0 +1,12 @@
+---
+ilo_hostname: "{{ ilo_hostname }}"
+ilo_host_address: "{{ ilo_host_address }}"
+oam_hostname: "{{ oam_hostname }}"
+oam_host_address: "{{ oam_host_address }}"
+oam_vip_hostname: "{{ oam_vip_hostname }}"
+oam_vip_address: "{{ oam_vip_address }}"
+cluster_name: "{{ cluster_name }}"
+dns_admin_endpoint: "{{ dns_admin_endpoint }}"
+dns_domain: "{{ dns_domain }}"
+infoblox_username: "{{ infoblox_username }}"
+infoblox_password: "{{ infoblox_password }}"
diff --git a/src/caas/services/jinja/dns_inventory.j2 b/src/caas/services/jinja/dns_inventory.j2
new file mode 100644
index 0000000..c003afe
--- /dev/null
+++ b/src/caas/services/jinja/dns_inventory.j2
@@ -0,0 +1,6 @@
+---
+all:
+ children:
+ target:
+ hosts:
+ {{ target }}
diff --git a/src/caas/services/jinja/firmware_host_vars.j2 b/src/caas/services/jinja/firmware_host_vars.j2
new file mode 100644
index 0000000..c029def
--- /dev/null
+++ b/src/caas/services/jinja/firmware_host_vars.j2
@@ -0,0 +1,13 @@
+---
+wr_distribution_zip: "WRCP-2006.20.03.zip"
+ilo_host_address: "{{ ilo_host_address }}"
+wr_bmc_username: "{{ wr_bmc_username }}"
+wr_bmc_password: "{{ wr_bmc_password }}"
+wr_webdav_server: "{{ wr_webdav_server }}"
+wr_webdav_username: "{{ wr_webdav_username }}"
+wr_webdav_password: "{{ wr_webdav_password }}"
+middleware_endpoint: "{{ middleware_endpoint }}"
+middleware_username: "{{ middleware_username }}"
+middleware_password: "{{ middleware_password }}"
+wr_registry_server: "{{ wr_registry_server }}"
+firmware_iso: "{{ firmware_iso }}"
diff --git a/src/caas/services/jinja/firmware_inventory.j2 b/src/caas/services/jinja/firmware_inventory.j2
new file mode 100644
index 0000000..b7d566c
--- /dev/null
+++ b/src/caas/services/jinja/firmware_inventory.j2
@@ -0,0 +1,7 @@
+---
+all:
+ children:
+ target:
+ hosts:
+ {{ target }}:
+ ansible_host: {{ ilo_host_address }}
diff --git a/src/caas/services/jinja/icinga_host_vars.j2 b/src/caas/services/jinja/icinga_host_vars.j2
new file mode 100644
index 0000000..c25b0ec
--- /dev/null
+++ b/src/caas/services/jinja/icinga_host_vars.j2
@@ -0,0 +1,38 @@
+---
+icinga_routers:
+{% for router in icinga_routers %}
+ - name: "{{ router.name }}"
+ address6: "{{ router.address6 }}"
+ group: "icingaadmins"
+{% endfor %}
+
+icinga_bmcs:
+{% for bmc in icinga_bmcs %}
+ - name: "{{ bmc.name }}"
+ address6: "{{ bmc.address6 }}"
+ group: "icingaadmins"
+{% if bmc.preauth %}
+ preauth: True
+{% endif %}
+{% if bmc.bmc_password_admin_default is not none %}
+ bmc_username_admin_default: "Administrator"
+ bmc_password_admin_default: "{{ bmc.bmc_password_admin_default }}"
+{% endif %}
+{% if bmc.bmc_password_admin is not none %}
+ bmc_username_admin: "Administrator"
+ bmc_password_admin: "{{ bmc.bmc_password_admin }}"
+{% endif %}
+{% if bmc.bmc_username is not none and bmc.bmc_password is not none %}
+ bmc_username: "{{ bmc.bmc_username }}"
+ bmc_password: "{{ bmc.bmc_password }}"
+{% endif %}
+{% if bmc.middleware_endpoint is not none %}
+ middleware_endpoint: "{{ bmc.middleware_endpoint }}"
+{% endif %}
+{% if bmc.middleware_username is not none %}
+ middleware_username: "{{ bmc.middleware_username }}"
+{% endif %}
+{% if bmc.middleware_password is not none %}
+ middleware_password: "{{ bmc.middleware_password }}"
+{% endif %}
+{% endfor %}
diff --git a/src/caas/services/jinja/icinga_inventory.j2 b/src/caas/services/jinja/icinga_inventory.j2
new file mode 100644
index 0000000..c003afe
--- /dev/null
+++ b/src/caas/services/jinja/icinga_inventory.j2
@@ -0,0 +1,6 @@
+---
+all:
+ children:
+ target:
+ hosts:
+ {{ target }}
diff --git a/src/caas/services/jinja/icinga_poll_host_vars.j2 b/src/caas/services/jinja/icinga_poll_host_vars.j2
new file mode 100644
index 0000000..e2aaac7
--- /dev/null
+++ b/src/caas/services/jinja/icinga_poll_host_vars.j2
@@ -0,0 +1,11 @@
+---
+bmc_ip: "{{ bmc_ip }}"
+bmc_username: "{{ bmc_username }}"
+bmc_password: "{{ bmc_password }}"
+icinga_api_url: "{{ icinga_api_url }}"
+icinga_api_username: "{{ icinga_api_username }}"
+icinga_api_password: "{{ icinga_api_password }}"
+middleware_endpoint: "{{ middleware_endpoint }}"
+middleware_username: "{{ middleware_username }}"
+middleware_password: "{{ middleware_password }}"
+middleware_url: "{{ middleware_url }}"
diff --git a/src/caas/services/jinja/icinga_poll_inventory.j2 b/src/caas/services/jinja/icinga_poll_inventory.j2
new file mode 100644
index 0000000..6ef8ca2
--- /dev/null
+++ b/src/caas/services/jinja/icinga_poll_inventory.j2
@@ -0,0 +1,6 @@
+---
+all:
+ children:
+ {{ vendor_name }}:
+ hosts:
+ {{ target }}
diff --git a/src/caas/services/jinja/wr_host_vars.j2 b/src/caas/services/jinja/wr_host_vars.j2
new file mode 100644
index 0000000..15a6f4d
--- /dev/null
+++ b/src/caas/services/jinja/wr_host_vars.j2
@@ -0,0 +1,74 @@
+---
+wr_vendor_name: "{{ wr_vendor_name }}"
+wr_region_name: "{{ wr_region_name }}"
+wr_location: "{{ wr_region_name }}"
+wr_bmc_username: "{{ wr_bmc_username }}"
+wr_bmc_password: "{{ wr_bmc_password }}"
+wr_bmc_controller_0_address: "{{ wr_bmc_controller_0_address }}"
+{% if wr_bmc_controller_1_address %}
+wr_bmc_controller_1_address: "{{ wr_bmc_controller_1_address }}"
+{% endif %}
+wr_mgmt_controller_0_mac: "{{ wr_mgmt_controller_0_mac }}"
+{% if wr_bmc_controller_1_mac %}
+wr_mgmt_controller_1_mac: "{{ wr_mgmt_controller_1_mac }}"
+{% endif %}
+wr_oam_floating_address: "{{ wr_oam_floating_address }}/64"
+wr_oam_node_0_address: "{{ wr_oam_node_0_address }}/64"
+{% if wr_oam_node_1_address %}
+wr_oam_node_1_address: "{{ wr_oam_node_1_address }}/64"
+{% endif %}
+wr_oam_gateway_address: "{{ wr_oam_gateway_address }}"
+wr_mgmt_start_address: "{{ wr_mgmt_start_address }}"
+wr_mgmt_end_address: "{{ wr_mgmt_end_address }}"
+wr_mgmt_gateway_address: "{{ wr_mgmt_gateway_address }}"
+wr_mgmt_subnet: "{{ wr_mgmt_subnet }}/64"
+wr_central_mgmt_start_address: "{{ wr_central_mgmt_start_address }}"
+wr_central_mgmt_default_gateway: "{{ wr_central_mgmt_default_gateway }}"
+wr_central_mgmt_subnet: "{{ wr_central_mgmt_subnet }}"
+wr_host_vlan: {{ wr_host_vlan }}
+wr_oam_vlan: {{ wr_oam_vlan }}
+wr_mgmt_vlan: {{ wr_mgmt_vlan }}
+wr_cluster_pod_subnet: "fd00:4888::/64"
+wr_cluster_host_subnet: "fd00:4888:0:1::/64"
+wr_cluster_service_subnet: "fd00:4888:0:2::/112"
+wr_mgmt_multicast_subnet: "ff05::18:1:0/124"
+{% if wr_dns_servers %}
+wr_dns_servers:
+{% for server in wr_dns_servers %}
+ - "{{ server }}"
+{% endfor %}
+{% endif %}
+{% if wr_ntp_servers %}
+wr_ntp_servers:
+{% for server in wr_ntp_servers %}
+ - "{{ server }}"
+{% endfor %}
+{% endif %}
+wr_no_check_cert: True
+wr_registry_server: "{{ wr_registry_server }}"
+wr_registry_username: "{{ wr_registry_username }}"
+wr_registry_password: "{{ wr_registry_password }}"
+wr_webdav_server: "{{ wr_webdav_server }}"
+wr_webdav_username: "{{ wr_webdav_username }}"
+wr_webdav_password: "{{ wr_webdav_password }}"
+wr_middleware_endpoint: "{{ wr_middleware_endpoint }}"
+wr_middleware_username: "{{ wr_middleware_username }}"
+wr_middleware_password: "{{ wr_middleware_password }}"
+{% if wr_docker_http_proxy %}
+wr_docker_http_proxy: "{{ wr_docker_http_proxy }}"
+{% endif %}
+{% if wr_docker_https_proxy %}
+wr_docker_https_proxy: "{{ wr_docker_https_proxy }}"
+{% endif %}
+{% if wr_docker_no_proxy %}
+wr_docker_no_proxy: {{ wr_docker_no_proxy }}
+{% endif %}
+wr_oam_nic_0: ens3f0
+wr_oam_nic_1: ens3f1
+wr_nic_main: ens3f0
+wr_no_check_cert: True
+
+wr_ssl_ca_cert: |
+{% filter indent(width=2) %}
+ {{ wr_ssl_ca_cert }}
+{% endfilter %}
diff --git a/src/caas/services/jinja/wr_inventory.j2 b/src/caas/services/jinja/wr_inventory.j2
new file mode 100644
index 0000000..814d692
--- /dev/null
+++ b/src/caas/services/jinja/wr_inventory.j2
@@ -0,0 +1,11 @@
+---
+all:
+ children:
+ central:
+ hosts:
+ {{ central_target }}:
+ ansible_host: {{ central_target_ip }}
+ remote:
+ hosts:
+ {{ remote_target }}:
+ ansible_host: {{ remote_target_ip }}
diff --git a/src/caas/services/macaddressservice.py b/src/caas/services/macaddressservice.py
new file mode 100644
index 0000000..745f5fa
--- /dev/null
+++ b/src/caas/services/macaddressservice.py
@@ -0,0 +1,38 @@
+from ..models import Server
+from .helpers import Address
+import logging
+
+
+logger = logging.getLogger("caas")
+
+
+class MacAddressService():
+ @staticmethod
+ def set_server_mac_address(ilo_host_address, pxe_mac_address, intel_nic_firmware_version):
+ try:
+ server_kwargs = {"ilo_host_address": Address.strip_brackets(ilo_host_address)}
+ server = Server.objects.get(**server_kwargs)
+ except Server.DoesNotExist:
+ logger.error("%s FAILED: while setting server MAC address: failed to retrieve server" % ilo_host_address)
+ return -1
+ changed_p = False
+ if server.pxe_mac_address != pxe_mac_address:
+ server.pxe_mac_address = pxe_mac_address
+ changed_p = True
+ if server.intel_nic_firmware_version != intel_nic_firmware_version:
+ server.intel_nic_firmware_version = intel_nic_firmware_version
+ changed_p = True
+ if changed_p:
+ server.save()
+ return 0
+
+ @staticmethod
+ def get_server_mac_address(ilo_host_address):
+ try:
+ server_kwargs = {"ilo_host_address": Address.strip_brackets(ilo_host_address)}
+ server = Server.objects.get(**server_kwargs)
+ except Server.DoesNotExist:
+ logger.error("%s FAILED: while getting server MAC address: failed to retrieve server" % ilo_host_address)
+ return None
+
+ return server.pxe_mac_address
diff --git a/src/caas/services/nicfirmwareupgradenowservice.py b/src/caas/services/nicfirmwareupgradenowservice.py
new file mode 100644
index 0000000..d31fd74
--- /dev/null
+++ b/src/caas/services/nicfirmwareupgradenowservice.py
@@ -0,0 +1,68 @@
+from .helpers import Jinja
+from .ansibleservice import AnsibleService
+from .firmwareservice import FirmwareService
+from .wrinstallnowservice import WrInstallNowService
+from ..models import FirmwareBatch, WrBatch, WrInstallSchedule, FirmwareUpgradeSchedule
+from django.conf import settings
+import logging
+import datetime
+
+
+logger = logging.getLogger("caas")
+
+
+class NicFirmwareUpgradeNowService(AnsibleService):
+ def __init__(self, target, git, branch, playbook, zmq):
+ super().__init__("nic", target, git, branch, playbook, zmq)
+
+ def deploy(self):
+ try:
+ firmwarebatch_kwargs = {"ilo_host_address": self.target}
+ firmwarebatch = FirmwareBatch.objects.get(**firmwarebatch_kwargs)
+ except FirmwareBatch.DoesNotExist:
+ errmsg = "FAILED: while checking Intel NIC firmware version: cannot find server with ilo_host_address: %s" % self.target
+ logger.error(errmsg)
+ return -1
+ completed = datetime.datetime.utcnow()
+ if firmwarebatch.intel_nic_firmware_version == settings.INTEL_NIC_FIRMWARE_VERSION:
+ try:
+ wrbatch_kwargs = {"ilo_host_address": firmwarebatch.ilo_host_address}
+ wrbatch = WrBatch.objects.get(**wrbatch_kwargs)
+ except WrBatch.DoesNotExist:
+ logger.error("FAILED: while scheduling Wind River installation: cannot find wrbatch with identifier: %s" % icingabmc.ilo_host_address)
+ raise
+ try:
+ wr_kwargs = {"cluster_id": wrbatch.cluster_id}
+ wr = WrInstallSchedule.objects.get(**wr_kwargs)
+ except WrInstallSchedule.DoesNotExist:
+ return "FAILED: while performing Wind River playbook callback: cannot find WrInstallSchedule associated with the cluster with cluster_id: %s" % cluster.pk
+ # never run an installation on top of a finished subcloud
+ if wr.kirke_ticket_number is None:
+ if wr.kirke_ticket_completed is None:
+ wr.kirke_ticket_completed = completed
+ wr.date_completed = None
+ wr.kirke_ticket_number = None
+ wr.save()
+ wrinstallnow = WrInstallNowService("wr",
+ firmwarebatch.ilo_host_address,
+ settings.ANSIBLE["wr"]["git"],
+ settings.ANSIBLE["wr"]["branch"],
+ settings.ANSIBLE["wr"]["playbook"],
+ settings.ANSIBLE["wr"]["zmq"])
+ wrinstallnow.deploy()
+ else:
+ try:
+ nic_kwargs = {"server_id": firmwarebatch.pk}
+ nic = FirmwareUpgradeSchedule.objects.get(**nic_kwargs)
+ except FirmwareUpgradeSchedule.DoesNotExist:
+ logger.error("FAILED: while deploying Wind River installation: cannot find FirmwareUpgradeSchedule with ID: %s" % icingabmc.pk)
+ raise
+ if nic.kirke_ticket_completed is None:
+ nic.kirke_ticket_completed = completed
+ nic.date_completed = None
+ nic.kirke_ticket_number = None
+ nic.save()
+ firmwareservice = FirmwareService(firmwarebatch.ilo_host_address, self.git, self.branch, self.playbook, self.zmq)
+ firmwareservice.deploy()
+ # The playbook callback will trigger the wr install
+ return 0
diff --git a/src/caas/services/nicfirmwareversionservice.py b/src/caas/services/nicfirmwareversionservice.py
new file mode 100644
index 0000000..b8a9d43
--- /dev/null
+++ b/src/caas/services/nicfirmwareversionservice.py
@@ -0,0 +1,37 @@
+import datetime
+from .helpers import Address
+from ..models import FirmwareUpgradeSchedule, Server
+from django.conf import settings
+import logging
+
+
+logger = logging.getLogger("caas")
+
+class NicFirmwareVersionService():
+ @staticmethod
+ def set_server_nic_firmware_version(ilo_host_address, intel_nic_firmware_version):
+ try:
+ server_kwargs = {"ilo_host_address": ilo_host_address}
+ server = Server.objects.get(**server_kwargs)
+ except Server.DoesNotExist:
+ errmsg = "FAILED: while upgrading Intel NIC firmware: cannot find server with ilo_host_address: %s" % ilo_host_address
+ logger.error(errmsg)
+ return -1
+
+ try:
+ firmware_kwargs = {"server_id": server.pk}
+ firmware = FirmwareUpgradeSchedule.objects.get(**firmware_kwargs)
+ except FirmwareUpgradeSchedule.DoesNotExist:
+ errmsg = "FAILED: while upgrading Intel NIC firmware: cannot find FirmwareUpgradeSchedule associated with the server with ilo_hostname: %s" % server.ilo_hostname
+ logger.error(errmsg)
+ return -1
+
+ if intel_nic_firmware_version == settings.INTEL_NIC_FIRMWARE_VERSION:
+ firmware.date_completed = datetime.datetime.now()
+ else:
+ firmware.date_last_failed = datetime.datetime.now()
+
+ server.intel_nic_firmware_version = intel_nic_firmware_version
+ server.save()
+ firmware.save()
+ return 0
diff --git a/src/caas/services/passwordservice.py b/src/caas/services/passwordservice.py
new file mode 100644
index 0000000..ab666c8
--- /dev/null
+++ b/src/caas/services/passwordservice.py
@@ -0,0 +1,180 @@
+import csv
+import hashlib
+import os
+from io import TextIOWrapper
+from django.conf import settings
+from ..models import Cluster, Server, Credential, Chassis, Blade, Vendor
+import logging
+
+logger = logging.getLogger("caas")
+
+class PasswordService():
+ @staticmethod
+ def import_password_data(filehandle):
+ f = TextIOWrapper(filehandle, encoding = "ascii", errors = "replace")
+ csv_reader = csv.reader(f, delimiter=",")
+ for row in csv_reader:
+ serial_number_chassis = "ILO%s" % row[1]
+ serial_number_blade = "ILO%s" % row[2]
+ password = row[3]
+ credential_kwargs = {"bmc_password_admin_default": password,
+ "bmc_password_admin__isnull": True,
+ "bmc_username__isnull": True,
+ "bmc_password__isnull": True}
+ credential, credential_created = Credential.objects.get_or_create(**credential_kwargs)
+ chassis_kwargs = {"serial_number": serial_number_chassis}
+ chassis, chassis_created = Chassis.objects.get_or_create(**chassis_kwargs)
+ blade_kwargs = {"serial_number": serial_number_blade}
+ blade, blade_created = Blade.objects.get_or_create(**blade_kwargs)
+ blade.credential = credential
+ blade.chassis = chassis
+ credential.save()
+ chassis.save()
+ blade.save()
+
+ @staticmethod
+ def get_server_link_data(ilo_host_address):
+ try:
+ server_kwargs = {"ilo_host_address": ilo_host_address}
+ server = Server.objects.get(**server_kwargs)
+ except Server.DoesNotExist:
+ logger.error("FAILED: while linking server to blade: failed to look up server ilo_host_address=%s" % ilo_host_address)
+ return None
+ try:
+ blade_kwargs = {"id": server.blade.pk}
+ blade = Blade.objects.get(**blade_kwargs)
+ except Blade.DoesNotExist:
+ logger.error("FAILED: while linking server to blade: failed to look up blade ilo_host_address=%s" % ilo_host_address)
+ return None
+ try:
+ vendor_kwargs = {"id": blade.vendor.pk}
+ vendor = Vendor.objects.get(**vendor_kwargs)
+ except Vendor.DoesNotExist:
+ logger.error("FAILED: while linking server to blade: failed to look up vendor ilo_host_address=%s" % ilo_host_address)
+ return None
+ return {"vendor": vendor.vendor_name,
+ "serial_number": blade.serial_number,
+ "ilo_host_address": server.ilo_host_address}
+
+ @staticmethod
+ def link_server_to_blade(vendor_name, serial_number, ilo_host_address):
+ try:
+ server_kwargs = {"ilo_host_address": ilo_host_address}
+ server = Server.objects.get(**server_kwargs)
+ except Server.DoesNotExist:
+ logger.error("FAILED: while linking server to blade: failed to look up server! ilo_host_address=%s" % ilo_host_address)
+ return None
+ try:
+ blade_kwargs = {"serial_number": serial_number}
+ blade = Blade.objects.get(**blade_kwargs)
+ except Blade.DoesNotExist:
+ logger.error("FAILED: while linking server to blade: failed to look up blade! ilo_host_address=%s" % ilo_host_address)
+ return None
+ try:
+ vendor_kwargs = {"vendor_name": vendor_name}
+ vendor = Vendor.objects.get(**vendor_kwargs)
+ except Vendor.DoesNotExist:
+ logger.error("FAILED: while linking server to blade: failed to look up vendor! ilo_host_address=%s" % ilo_host_address)
+ return None
+ server.blade = blade
+ blade.vendor = vendor
+ server.save()
+ blade.save()
+ return server
+
+ @staticmethod
+ def is_server_linked_to_blade(ilo_host_address):
+ try:
+ server_kwargs = {"ilo_host_address": ilo_host_address}
+ server = Server.objects.get(**server_kwargs)
+ except Server.DoesNotExist:
+ return True # server doesn't exist, no action should be triggered
+
+ if server.blade is None or server.pxe_mac_address is None:
+ return False # server is not yet linked with blade
+ else:
+ return True # server is already linked with blade
+
+ @staticmethod
+ def generate_unique_password():
+ m = hashlib.sha1()
+ m.update(os.urandom(16))
+ return m.hexdigest()[:20]
+
+ @staticmethod
+ def create_bmc_admin_password(serial_number):
+ try:
+ blade_kwargs = {"serial_number": serial_number}
+ blade = Blade.objects.get(**blade_kwargs)
+ except Blade.DoesNotExist:
+ logger.error("FAILED: while creating BMC account: failed to look up blade for serial %s" % serial_number)
+ return -1
+ if blade.credential is None:
+ logger.error("FAILED: while creating BMC account: failed to look up credential for serial %s" % serial_number)
+ return -1
+ if blade.credential.bmc_password is None:
+ # We don't want to update this Credential because it will affect
+ # every Blade that is tied to it. We need to create a new
+ # Credential and link the Blade to the new Credential.
+ admin_password = PasswordService.generate_unique_password()
+ ospctl_password = PasswordService.generate_unique_password()
+ credential_kwargs = {"bmc_password_admin_default": blade.credential.bmc_password_admin_default}
+ credential, credential_created = Credential.objects.get_or_create(**credential_kwargs)
+ blade.credential = credential
+ credential.bmc_password_admin = admin_password
+ credential.bmc_username = settings.BMC_USERNAME
+ credential.bmc_password = ospctl_password
+ blade.save()
+ credential.save()
+ logger.debug("OK: passwords created for serial %s" % serial_number)
+ return 0
+ logger.debug("OK: no-op for serial %s" % serial_number)
+ return 0
+
+ @staticmethod
+ def central_server_p(ilo_host_address):
+ try:
+ server_kwargs = {"ilo_host_address": ilo_host_address}
+ server = Server.objects.get(**server_kwargs)
+ except Server.DoesNotExist:
+ logger.error("FAILED: while determining if the server with ilo_host_address %s is a central server: server not found." % ilo_host_address)
+ return True
+ try:
+ cluster_kwargs = {"id": server.cluster.pk}
+ cluster = Cluster.objects.get(**cluster_kwargs)
+ except Cluster.DoesNotExist:
+ logger.error("FAILED: while determining if the server with ilo_host_address %s is a central server: cluster not found." % ilo_host_address)
+ return True
+ return False if cluster.is_central_controller==0 else True
+
+ @staticmethod
+ def fix_creds():
+ bad_creds = Credential.objects.raw("""
+with dupes (bmc_password_admin_default, zahl) as (
+ select bmc_password_admin_default,
+ count(bmc_password_admin_default) as zahl
+ from caas_credential
+ group by bmc_password_admin_default
+)
+select c.id,
+ c.bmc_password_admin_default,
+ c.bmc_password_admin,
+ c.bmc_username,
+ c.bmc_password
+from caas_credential c
+left outer join dupes d
+ on c.bmc_password_admin_default = d.bmc_password_admin_default
+where d.zahl > 1
+ and bmc_password is null""")
+ for bad_cred in bad_creds:
+ good_cred_kwargs = {"bmc_password_admin_default": bad_cred.bmc_password_admin_default,
+ "bmc_password__isnull": False}
+ good_cred = Credential.objects.get(**good_cred_kwargs)
+ try:
+ blade_kwargs = {"credential_id": bad_cred.id}
+ blade = Blade.objects.get(**blade_kwargs)
+ blade.credential_id = good_cred.pk
+ blade.save()
+ bad_cred.delete()
+ except Blade.DoesNotExist:
+ pass
diff --git a/src/caas/services/patchservice.py b/src/caas/services/patchservice.py
new file mode 100644
index 0000000..c986051
--- /dev/null
+++ b/src/caas/services/patchservice.py
@@ -0,0 +1,106 @@
+import datetime
+from ..models import Cluster, WrInstallSchedule, PatchSchedule, WrBatch
+from django.conf import settings
+from .helpers import Jinja
+from .ansibleservice import AnsibleService
+
+
+class PatchService(AnsibleService):
+ """
+ target == ilo_host_address, later becomes cluster_name
+ """
+ def __init__(self, target, git, branch, playbook, zmq):
+ super().__init__("patch", target, git, branch, playbook, zmq)
+
+ def schedule_install(self):
+ pass
+ # try:
+ # patchbatch_kwargs = {"ilo_host_address": self.target}
+ # # repurpose WrBatch
+ # patchbatch = WrBatch.objects.get(**patchbatch_kwargs)
+ # except WrBatch.DoesNotExist:
+ # return "FAILED: while scheduling Wind River installation: cannot find wrbatch with ilo_host_address: %s" % self.target
+ # try:
+ # cluster_kwargs = {"pk": patchbatch.cluster_id}
+ # cluster = Cluster.objects.get(**cluster_kwargs)
+ # except Cluster.DoesNotExist:
+ # return "FAILED: while scheduling Wind River installation: cannot find cluster associated with wrbatch with ilo_host_address: %s" % patchbatch.ilo_host_address
+ # patch_kwargs = {"cluster_id": cluster.pk}
+ # patch, patch_created = PatchSchedule.objects.get_or_create(**patch_kwargs)
+ # if patch.date_scheduled is None:
+ # patch.date_scheduled = datetime.datetime.now()
+ # if patch.kirke_ticket_number is None:
+ # # TODO bealer: create KIRKE ticket
+ # pass
+ # patch.save()
+ # # one playbook per cluster
+ # self.target = cluster.cluster_name
+ # with tempfile.TemporaryDirectory() as tempdir:
+ # builddir = "%s/%s" % (tempdir, self.repo_name)
+ # self.clone_repo(builddir)
+ # # host_vars file
+ # patch_config = {"wr_vendor_name": patchbatch.vendor_name,
+ # "wr_region_name": cluster.cluster_name,
+ # "wr_central_p": False if patchbatch.parent_oam_vip_hostname else True,
+ # "wr_bmc_controller_0_address": patchbatch.ilo_host_address,
+ # "wr_mgmt_controller_0_mac": patchbatch.pxe_mac_address,
+ # "wr_oam_floating_address": patchbatch.oam_vip_address,
+ # "wr_oam_node_0_address": patchbatch.oam_host_address,
+ # "wr_oam_gateway_address": patchbatch.oam_default_gateway,
+ # "wr_mgmt_start_address": patchbatch.mgmt_address_range_start,
+ # "wr_mgmt_end_address": patchbatch.mgmt_address_range_end,
+ # "wr_mgmt_gateway_address": patchbatch.mgmt_default_gateway,
+ # "wr_mgmt_subnet": patchbatch.mgmt_subnet,
+ # "wr_central_mgmt_start_address": patchbatch.parent_mgmt_address_range_start,
+ # "wr_central_mgmt_default_gateway": patchbatch.parent_mgmt_default_gateway,
+ # "wr_host_vlan": patchbatch.host_vlan,
+ # "wr_oam_vlan": patchbatch.oam_vlan,
+ # "wr_mgmt_vlan": patchbatch.mgmt_vlan,
+ # "wr_bmc_username": patchbatch.bmc_username,
+ # "wr_bmc_password": patchbatch.bmc_password,
+ # "wr_dns_servers": settings.DNS_SERVERS,
+ # "wr_ntp_servers": settings.NTP_SERVERS,
+ # "wr_registry_server": settings.WR_REGISTRY_SERVER,
+ # "wr_registry_username": settings.WR_REGISTRY_USERNAME,
+ # "wr_registry_password": settings.WR_REGISTRY_PASSWORD,
+ # "wr_webdav_server": settings.WR_WEBDAV_SERVER,
+ # "wr_webdav_username": settings.WR_WEBDAV_USERNAME,
+ # "wr_webdav_password": settings.WR_WEBDAV_PASSWORD,
+ # "wr_docker_http_proxy": settings.WR_DOCKER_HTTP_PROXY,
+ # "wr_docker_https_proxy": settings.WR_DOCKER_HTTPS_PROXY,
+ # "wr_docker_no_proxy": settings.WR_DOCKER_NO_PROXY,
+ # "wr_ssl_ca_cert": settings.WR_SSL_CA_CERT}
+ # content = Jinja.render("patch_host_vars.j2", **patch_config)
+ # filename = "%s/host_vars/%s" % (builddir, patchbatch.oam_hostname)
+ # with AnsibleVaultFile(filename) as f:
+ # f.write(content)
+ # # inventory file
+ # patch_config = {"central_target": patchbatch.parent_cluster_name,
+ # "central_target_ip": patchbatch.parent_oam_vip_address,
+ # "remote_target": patchbatch.oam_hostname,
+ # "remote_target_ip": patchbatch.oam_vip_address}
+ # content = Jinja.render("patch_inventory.j2", **patch_config)
+ # filename = "%s/inventory/%s.yaml" % (builddir, cluster.cluster_name)
+ # with open(filename, "w") as f:
+ # f.write(content)
+ # self.push()
+
+ def deploy(self):
+ pass
+ # kirke_inprocess = PatchSchedule.objects.filter(kirke_ticket_number__isnull = False,
+ # kirke_ticket_completed__isnull = True)
+ # for rec in kirke_inprocess:
+ # # TODO bealer: query KIRKE and update status
+ # rec.save()
+ # patch_schedule_kwargs = {"kirke_ticket_completed__isnull": False,
+ # "date_completed__isnull": True}
+ # patch_schedule_ready = PatchSchedule.objects.filter(**patch_schedule_kwargs)
+ # for sched in patch_schedule_ready:
+ # try:
+ # patchbatch_kwargs = {"cluster_id": sched.cluster.pk,
+ # "intel_nic_firmware_version": settings.INTEL_NIC_FIRMWARE_VERSION}
+ # patchbatch = WrBatch.objects.filter(**patchbatch_kwargs)
+ # except WrBatch.DoesNotExist:
+ # return "FAILED: while running PATCH batch playbook: failed to look up wrbatch"
+ # self.target = patchbatch.cluster_name
+ # self.run_playbook()
diff --git a/src/caas/services/playbookreportservice.py b/src/caas/services/playbookreportservice.py
new file mode 100644
index 0000000..73abdfa
--- /dev/null
+++ b/src/caas/services/playbookreportservice.py
@@ -0,0 +1,147 @@
+import datetime
+from django.conf import settings
+from ..models import FirmwareUpgradeSchedule, WrInstallSchedule, Location, Cluster, Server, IcingaBmc, WrBatch
+from .wrinstallnowservice import WrInstallNowService
+from .icingapollservice import IcingaPollService
+from .bmcservice import BmcService
+from .httpclient import HttpClient
+import logging
+
+
+logger = logging.getLogger("caas")
+
+
+class PlaybookReportService():
+ def __init__(self, git, playbook, target, failed):
+ self.git = git
+ self.playbook = playbook
+ self.target = target
+ self.failed = failed
+
+ def process(self):
+ if ".yaml" in self.playbook:
+ ansible_config = {k: v for (k, v) in settings.ANSIBLE.items() if self.playbook in v.values() and v["git"] == self.git}
+ else:
+ ansible_config = {k: v for (k, v) in settings.ANSIBLE.items() if k == self.playbook and v["git"] == self.git}
+ key = [k for k in ansible_config.keys()][0]
+ if key == "wr":
+ self.target = self.target.split(".yaml")[0]
+ try:
+ cluster_kwargs = {"cluster_name": self.target}
+ cluster = Cluster.objects.get(**cluster_kwargs)
+ except Server.DoesNotExist:
+ return "FAILED: while performing Wind River playbook callback: cannot find cluster with cluster_name: %s" % self.target
+ try:
+ wr_kwargs = {"cluster_id": cluster.pk}
+ wr = WrInstallSchedule.objects.get(**wr_kwargs)
+ except WrInstallSchedule.DoesNotExist:
+ return "FAILED: while performing Wind River playbook callback: cannot find WrInstallSchedule associated with the cluster with cluster_name: %s" % cluster.cluster_name
+ completed = datetime.datetime.utcnow()
+ if wr.kirke_ticket_completed is None:
+ wr.kirke_ticket_completed = completed
+ if self.failed == "0":
+ wr.date_completed = completed
+ wr.kirke_ticket_number = None # Still needs manual check/remediation
+ # # Change default BMC password
+ # server_kwargs = {"cluster_id": cluster.pk}
+ # servers = Server.objects.filter(**server_kwargs)
+ # for server in servers:
+ # bmc = BmcService(server.ilo_host_address,
+ # settings.ANSIBLE["bmc"]["git"],
+ # settings.ANSIBLE["bmc"]["branch"],
+ # settings.ANSIBLE["bmc"]["playbook_adminpassword"],
+ # settings.ANSIBLE["bmc"]["zmq"])
+ # bmc.deploy()
+ # Orchstration callback
+ try:
+ location_kwargs = {"pk": cluster.location_id}
+ location = Location.objects.get(**location_kwargs)
+ except Location.DoesNotExist:
+ return "FAILED: while performing Wind River playbook callback: cannot find Location associated with the cluster with cluster_name: %s" % cluster.cluster_name
+ payload = {"cluster_status": [{
+ "name": cluster.cluster_name,
+ "description": location.fuze_spm_site_name,
+ "location": location.fuze_spm_site_id,
+ "software_version": settings.WR_VERSION,
+ "availability": "ONLINE",
+ "deploy_status": "COMPLETE",
+ "created_at": completed.strftime("%Y-%m-%d %H:%M:%S"),
+ "updated_at": completed.strftime("%Y-%m-%d %H:%M:%S")}]}
+ httpclient = HttpClient()
+ resp = httpclient.post(url = "%s/orchestration/caas-status" % settings.CAAS_MIDDLEWARE_ENDPOINT,
+ username = settings.CAAS_MIDDLEWARE_USERNAME,
+ password = settings.CAAS_MIDDLEWARE_PASSWORD,
+ data = payload)
+ if resp.status_code >= 300:
+ return "Error calling orchestration endpoint. Status code: %s , message: %s" % (resp.status_code, resp.text)
+ else:
+ wr.date_completed = None
+ wr.kirke_ticket_number = None
+ wr.date_last_failed = completed
+ wr.save()
+ elif key == "nic":
+ self.target = self.target.split(".yaml")[0]
+ try:
+ icingabmc_kwargs = {"ilo_hostname": self.target}
+ icingabmc = IcingaBmc.objects.get(**icingabmc_kwargs)
+ except IcingaBmc.DoesNotExist:
+ logger.error("FAILED: while deploying Wind River installation: cannot find IcingaBmc with identifier: %s" % self.target)
+ raise
+ try:
+ nic_kwargs = {"server_id": icingabmc.pk}
+ nic = FirmwareUpgradeSchedule.objects.get(**nic_kwargs)
+ except FirmwareUpgradeSchedule.DoesNotExist:
+ logger.error("FAILED: while deploying Wind River installation: cannot find FirmwareUpgradeSchedule with ID: %s" % icingabmc.pk)
+ raise
+ completed = datetime.datetime.utcnow()
+ if nic.kirke_ticket_completed is None:
+ nic.kirke_ticket_completed = completed
+ if self.failed == "0":
+ try:
+ wrbatch_kwargs = {"ilo_host_address": icingabmc.ilo_host_address}
+ wrbatch = WrBatch.objects.get(**wrbatch_kwargs)
+ except WrBatch.DoesNotExist:
+ logger.error("FAILED: while scheduling Wind River installation: cannot find wrbatch with identifier: %s" % icingabmc.ilo_host_address)
+ raise
+ # never run an installation on top of a finished subcloud
+ try:
+ wr_kwargs = {"cluster_id": wrbatch.cluster_id}
+ wr = WrInstallSchedule.objects.get(**wr_kwargs)
+ except WrInstallSchedule.DoesNotExist:
+ return "FAILED: while performing Wind River playbook callback: cannot find WrInstallSchedule associated with the cluster with cluster_name: %s" % cluster.cluster_name
+ if wr.kirke_ticket_number is None:
+ nic.date_completed = completed
+ nic.kirke_ticket_number = nic.pk
+ wrinstallnow = WrInstallNowService("wr",
+ wrbatch.ilo_host_address,
+ settings.ANSIBLE["wr"]["git"],
+ settings.ANSIBLE["wr"]["branch"],
+ settings.ANSIBLE["wr"]["playbook"],
+ settings.ANSIBLE["wr"]["zmq"])
+ wrinstallnow.deploy()
+ else:
+ nic.date_completed = None
+ nic.kirke_ticket_number = None
+ nic.date_last_failed = completed
+ nic.save()
+ elif key == "bmc":
+ self.target = self.target.split(".yaml")[0]
+ if self.failed == "0":
+ try:
+ icingabmc_kwargs = {"ilo_hostname": self.target}
+ icingabmc = IcingaBmc.objects.get(**icingabmc_kwargs)
+ except IcingaBmc.DoesNotExist:
+ logger.error("FAILED: while deploying Wind River installation: cannot find IcingaBmc with identifier: %s" % self.target)
+ raise
+ icinga_poll = IcingaPollService(icingabmc.ilo_host_address,
+ settings.ANSIBLE["icinga_poll"]["git"],
+ settings.ANSIBLE["icinga_poll"]["branch"],
+ settings.ANSIBLE["icinga_poll"]["playbook"],
+ settings.ANSIBLE["icinga_poll"]["zmq"],
+ "adminpassword")
+ rc = icinga_poll.deploy()
+ return {"git": self.git,
+ "playbook": self.playbook,
+ "target": self.target,
+ "failed": self.failed,
+ "key": key}
diff --git a/src/caas/services/subcloudservice.py b/src/caas/services/subcloudservice.py
new file mode 100644
index 0000000..5095bbb
--- /dev/null
+++ b/src/caas/services/subcloudservice.py
@@ -0,0 +1,12 @@
+from ..models import WrBatch
+import logging
+
+
+logger = logging.getLogger("caas")
+
+
+class SubcloudService():
+ @staticmethod
+ def find_subclouds(fuze_id):
+ wrbatch_kwargs = {"fuze_spm_site_id": fuze_id}
+ return WrBatch.objects.filter(**wrbatch_kwargs)
diff --git a/src/caas/services/wrinstallnowservice.py b/src/caas/services/wrinstallnowservice.py
new file mode 100644
index 0000000..4db0ec4
--- /dev/null
+++ b/src/caas/services/wrinstallnowservice.py
@@ -0,0 +1,107 @@
+import tempfile
+import datetime
+from ..models import Cluster, WrInstallSchedule, WrBatch, Namespace
+from django.conf import settings
+from .helpers import Address, Jinja
+from .ansibleservice import AnsibleService
+import logging
+
+
+logger = logging.getLogger("caas")
+
+
+class WrInstallNowService(AnsibleService):
+ """
+ target == ilo_host_address, later becomes cluster_name
+ """
+ def __init__(self, ansible_queue, target, git, branch, playbook, zmq):
+ super().__init__(ansible_queue, target, git, branch, playbook, zmq)
+
+ def get_wrbatch(self):
+ if self.ansible_queue == "wr":
+ wrbatch_kwargs = {"ilo_host_address": self.target}
+ elif self.ansible_queue in ("wr_remediate", "wr_wipedisk", "wr_ptp", "wr_ptp_config", "wr_unlock", "wr_wrap"):
+ wrbatch_kwargs = {"cluster_name": self.target}
+ elif self.ansible_queue == "wr_reboot":
+ wrbatch_kwargs = {"namespace_name": self.target}
+ try:
+ wrbatch = WrBatch.objects.get(**wrbatch_kwargs)
+ except WrBatch.DoesNotExist:
+ logger.error("FAILED: while scheduling Wind River installation: cannot find wrbatch with identifier: %s" % self.target)
+ raise
+ return wrbatch
+
+ def deploy(self):
+ logger.debug("%s Enter" % self.target)
+ wrbatch = self.get_wrbatch()
+ self.do_deploy(wrbatch)
+
+ def remediate(self):
+ logger.debug("%s Enter" % self.target)
+ wrbatch = self.get_wrbatch()
+ self.do_deploy(wrbatch)
+
+ def do_deploy(self, wrbatch):
+ try:
+ cluster_kwargs = {"pk": wrbatch.cluster_id}
+ cluster = Cluster.objects.get(**cluster_kwargs)
+ except Cluster.DoesNotExist:
+ logger.error("FAILED: while scheduling Wind River installation: cannot find cluster associated with wrbatch with identifier: %s" % wrbatch.ilo_host_address)
+ raise
+
+ # one playbook per cluster
+ self.target = cluster.cluster_name
+ self.maint_window_p = wrbatch.maint_window_p
+ # host_vars file
+ hostvars_config = {"wr_vendor_name": wrbatch.vendor_name,
+ "wr_region_name": cluster.cluster_name,
+ "wr_bmc_controller_0_address": wrbatch.ilo_host_address,
+ "wr_mgmt_controller_0_mac": wrbatch.pxe_mac_address,
+ "wr_oam_floating_address": wrbatch.oam_vip_address,
+ "wr_oam_node_0_address": wrbatch.oam_host_address,
+ "wr_oam_gateway_address": wrbatch.oam_default_gateway,
+ "wr_mgmt_start_address": wrbatch.mgmt_address_range_start,
+ "wr_mgmt_end_address": wrbatch.mgmt_address_range_end,
+ "wr_mgmt_gateway_address": wrbatch.mgmt_default_gateway,
+ "wr_mgmt_subnet": Address.gateway_to_subnet(wrbatch.mgmt_subnet, numquads = 4),
+ "wr_central_mgmt_start_address": wrbatch.parent_mgmt_address_range_start,
+ "wr_central_mgmt_default_gateway": wrbatch.parent_mgmt_default_gateway,
+ "wr_central_mgmt_subnet": Address.gateway_to_subnet(wrbatch.parent_mgmt_subnet, numquads = 4),
+ "wr_host_vlan": wrbatch.host_vlan,
+ "wr_oam_vlan": wrbatch.oam_vlan,
+ "wr_mgmt_vlan": wrbatch.mgmt_vlan,
+ "wr_bmc_username": wrbatch.bmc_username,
+ "wr_bmc_password": wrbatch.bmc_password,
+ "wr_dns_servers": settings.DNS_SERVERS,
+ "wr_ntp_servers": settings.NTP_SERVERS,
+ "wr_registry_server": settings.WR_REGISTRY_SERVER,
+ "wr_registry_username": settings.WR_REGISTRY_USERNAME,
+ "wr_registry_password": settings.WR_REGISTRY_PASSWORD,
+ "wr_webdav_server": settings.WR_WEBDAV_SERVER,
+ "wr_webdav_username": settings.WR_WEBDAV_USERNAME,
+ "wr_webdav_password": settings.WR_WEBDAV_PASSWORD,
+ "wr_middleware_endpoint": settings.CAAS_MIDDLEWARE_ENDPOINT,
+ "wr_middleware_username": settings.CAAS_MIDDLEWARE_USERNAME,
+ "wr_middleware_password": settings.CAAS_MIDDLEWARE_PASSWORD,
+ "wr_docker_http_proxy": settings.WR_DOCKER_HTTP_PROXY,
+ "wr_docker_https_proxy": settings.WR_DOCKER_HTTPS_PROXY,
+ "wr_docker_no_proxy": settings.WR_DOCKER_NO_PROXY,
+ "wr_ssl_ca_cert": settings.WR_SSL_CA_CERT}
+ # revisit for NVPA-279
+ # if len(servers) > 1:
+ # wr_config["wr_bmc_controller_1_address"] = servers[1].ilo_host_address
+ # wr_config["wr_mgmt_controller_1_mac"] = servers[1].pxe_mac_address
+ # wr_config["wr_oam_node_1_address"] = servers[1].oam_host_address
+ hostvars_content = Jinja.render("wr_host_vars.j2", **hostvars_config)
+ hostvars = wrbatch.oam_hostname
+ # inventory file
+ inventory_config = {"central_target": wrbatch.parent_cluster_name,
+ "central_target_ip": wrbatch.parent_oam_vip_address,
+ "remote_target": wrbatch.oam_hostname,
+ "remote_target_ip": wrbatch.oam_vip_address}
+ inventory_content = Jinja.render("wr_inventory.j2", **inventory_config)
+ inventory = "%s.yaml" % self.target
+ logger.debug("%s Sending playbook to queue" % self.target)
+ self.run_playbook(inventory, inventory_content, hostvars, hostvars_content, extra_args = {"clusterName": wrbatch.parent_cluster_name})
+ logger.debug("%s Sent playbook to queue" % self.target)
+ return 0
diff --git a/src/caas/services/wrservice.py b/src/caas/services/wrservice.py
new file mode 100644
index 0000000..51b3c02
--- /dev/null
+++ b/src/caas/services/wrservice.py
@@ -0,0 +1,75 @@
+import datetime
+from ..models import Cluster, WrInstallSchedule, WrBatch
+from django.conf import settings
+from .helpers import Address, Jinja
+from .ansibleservice import AnsibleService
+from .icingapollservice import IcingaPollService
+import logging
+
+
+logger = logging.getLogger("caas")
+
+
+class WrService(AnsibleService):
+ """
+ target == ilo_host_address, later becomes cluster_name
+ """
+ def __init__(self, target, git, branch, playbook, zmq):
+ super().__init__("wr", target, git, branch, playbook, zmq)
+
+ def schedule_install(self):
+ logger.debug("%s Enter schedule_install" % self.target)
+ try:
+ wrbatch_kwargs = {"ilo_host_address": self.target}
+ wrbatch = WrBatch.objects.get(**wrbatch_kwargs)
+ except WrBatch.DoesNotExist:
+ logger.error("FAILED: while scheduling Wind River installation: cannot find wrbatch with ilo_host_address: %s" % self.target)
+ raise
+ try:
+ cluster_kwargs = {"pk": wrbatch.cluster_id}
+ cluster = Cluster.objects.get(**cluster_kwargs)
+ except Cluster.DoesNotExist:
+ logger.error("FAILED: while scheduling Wind River installation: cannot find cluster associated with wrbatch with ilo_host_address: %s" % wrbatch.ilo_host_address)
+ raise
+ wr_kwargs = {"cluster_id": cluster.pk}
+ wr, wr_created = WrInstallSchedule.objects.get_or_create(**wr_kwargs)
+ if wr.date_scheduled is None:
+ wr.date_scheduled = datetime.datetime.now()
+ if wr.kirke_ticket_number is None:
+ # TODO bealer: create KIRKE ticket
+ pass
+ wr.save()
+
+ def deploy(self):
+ kirke_inprocess_kwargs = {"kirke_ticket_number__isnull": False,
+ "kirke_ticket_completed__isnull": True}
+ kirke_inprocess = WrInstallSchedule.objects.filter(**kirke_inprocess_kwargs)
+
+ for rec in kirke_inprocess:
+ # TODO bealer: query KIRKE and update status
+ rec.save()
+
+ wr_schedule_kwargs = {"kirke_ticket_completed__isnull": False,
+ "date_completed__isnull": True}
+ wr_schedule_ready = WrInstallSchedule.objects.filter(**wr_schedule_kwargs)
+
+ for sched in wr_schedule_ready:
+ try:
+ wrbatch_kwargs = {"cluster_id": sched.cluster.pk,
+ "intel_nic_firmware_version": settings.INTEL_NIC_FIRMWARE_VERSION}
+ wrbatch_results = WrBatch.objects.filter(**wrbatch_kwargs)
+
+ except WrBatch.DoesNotExist:
+ logger.error("FAILED: while running WR batch playbook: failed to look up wrbatch")
+ raise
+
+ # check hardware before wr isntall
+ wrbatch = wrbatch_results[0]
+ icingapoll = IcingaPollService(wrbatch.ilo_host_address,
+ settings.ANSIBLE["icinga_poll"]["git"],
+ settings.ANSIBLE["icinga_poll"]["branch"],
+ settings.ANSIBLE["icinga_poll"]["playbook"],
+ settings.ANSIBLE["icinga_poll"]["zmq"],
+ "wrinstallnow")
+ icingapoll.deploy()
+
diff --git a/src/caas/templates/adminpassword.xml b/src/caas/templates/adminpassword.xml
new file mode 100644
index 0000000..b362a25
--- /dev/null
+++ b/src/caas/templates/adminpassword.xml
@@ -0,0 +1,12 @@
+{% extends "site.xml" %}
+{% block content %}
+{% load crispy_forms_tags %}
+<form name="admin_password_form"
+ id="admin_password_form"
+ method="POST"
+ action=""
+ enctype="multipart/form-data">
+{{ form|crispy }}
+<input type="submit" class="btn btn-success" value="Change BMC administrator password"/>
+</form>
+{% endblock %}
diff --git a/src/caas/templates/autoremediate.xml b/src/caas/templates/autoremediate.xml
new file mode 100644
index 0000000..31a87ac
--- /dev/null
+++ b/src/caas/templates/autoremediate.xml
@@ -0,0 +1,12 @@
+{% extends "site.xml" %}
+{% block content %}
+{% load crispy_forms_tags %}
+<form name="autoremediate_form"
+ id="autoremediate_form"
+ method="POST"
+ action=""
+ enctype="multipart/form-data">
+{{ form|crispy }}
+<input type="submit" class="btn btn-success" value="Autoremediate server"/>
+</form>
+{% endblock %}
diff --git a/src/caas/templates/ciq.xml b/src/caas/templates/ciq.xml
new file mode 100644
index 0000000..baf97f1
--- /dev/null
+++ b/src/caas/templates/ciq.xml
@@ -0,0 +1,13 @@
+{% extends "site.xml" %}
+{% block content %}
+{% load crispy_forms_tags %}
+<form name="ciq_upload_form"
+ id="ciq_upload_form"
+ method="POST"
+ action=""
+ enctype="multipart/form-data">
+{% csrf_token %}
+{{ form|crispy }}
+<input type="submit" class="btn btn-success" value="Upload and import CIQ"/>
+</form>
+{% endblock %}
diff --git a/src/caas/templates/ciq_success.xml b/src/caas/templates/ciq_success.xml
new file mode 100644
index 0000000..831a75c
--- /dev/null
+++ b/src/caas/templates/ciq_success.xml
@@ -0,0 +1,4 @@
+{% extends "site.xml" %}
+{% block content %}
+CIQ import was a success!
+{% endblock %}
diff --git a/src/caas/templates/dns.xml b/src/caas/templates/dns.xml
new file mode 100644
index 0000000..1c57337
--- /dev/null
+++ b/src/caas/templates/dns.xml
@@ -0,0 +1,12 @@
+{% extends "site.xml" %}
+{% block content %}
+{% load crispy_forms_tags %}
+<form name="dns_form"
+ id="dns_form"
+ method="POST"
+ action=""
+ enctype="multipart/form-data">
+{{ form|crispy }}
+<input type="submit" class="btn btn-success" value="Update DNS records"/>
+</form>
+{% endblock %}
diff --git a/src/caas/templates/macaddress.xml b/src/caas/templates/macaddress.xml
new file mode 100644
index 0000000..3aded91
--- /dev/null
+++ b/src/caas/templates/macaddress.xml
@@ -0,0 +1,12 @@
+{% extends "site.xml" %}
+{% block content %}
+{% load crispy_forms_tags %}
+<form name="mac_address_form"
+ id="mac_address_form"
+ method="POST"
+ action=""
+ enctype="multipart/form-data">
+{{ form|crispy }}
+<input type="submit" class="btn btn-success" value="Upload BMC IP and MAC address"/>
+</form>
+{% endblock %}
diff --git a/src/caas/templates/mockwrremediate.xml b/src/caas/templates/mockwrremediate.xml
new file mode 100644
index 0000000..0d8f26b
--- /dev/null
+++ b/src/caas/templates/mockwrremediate.xml
@@ -0,0 +1,12 @@
+{% extends "site.xml" %}
+{% block content %}
+{% load crispy_forms_tags %}
+<form name="mockwr_remediate_form"
+ id="mockwr_remediate_form"
+ method="POST"
+ action=""
+ enctype="multipart/form-data">
+{{ form|crispy }}
+<input type="submit" class="btn btn-success" value="Mock Remediate Wind River CaaS subcloud"/>
+</form>
+{% endblock %}
diff --git a/src/caas/templates/nicfirmwareupgrade.xml b/src/caas/templates/nicfirmwareupgrade.xml
new file mode 100644
index 0000000..146e641
--- /dev/null
+++ b/src/caas/templates/nicfirmwareupgrade.xml
@@ -0,0 +1,12 @@
+{% extends "site.xml" %}
+{% block content %}
+{% load crispy_forms_tags %}
+<form name="nic_firmware_upgrade_form"
+ id="nic_firmware_upgrade_form"
+ method="POST"
+ action=""
+ enctype="multipart/form-data">
+{{ form|crispy }}
+<input type="submit" class="btn btn-success" value="Check hardware and upgrade NIC firmware"/>
+</form>
+{% endblock %}
diff --git a/src/caas/templates/nicfirmwareupgradenow.xml b/src/caas/templates/nicfirmwareupgradenow.xml
new file mode 100644
index 0000000..9cf3511
--- /dev/null
+++ b/src/caas/templates/nicfirmwareupgradenow.xml
@@ -0,0 +1,12 @@
+{% extends "site.xml" %}
+{% block content %}
+{% load crispy_forms_tags %}
+<form name="nic_firmware_upgrade_now_form"
+ id="nic_firmware_upgrade_now_form"
+ method="POST"
+ action=""
+ enctype="multipart/form-data">
+{{ form|crispy }}
+<input type="submit" class="btn btn-success" value="Upgrade NIC firmware now"/>
+</form>
+{% endblock %}
diff --git a/src/caas/templates/nicfirmwareversion.xml b/src/caas/templates/nicfirmwareversion.xml
new file mode 100644
index 0000000..8d4cdf2
--- /dev/null
+++ b/src/caas/templates/nicfirmwareversion.xml
@@ -0,0 +1,12 @@
+{% extends "site.xml" %}
+{% block content %}
+{% load crispy_forms_tags %}
+<form name="firmware_version_form"
+ id="firmware_version_form"
+ method="POST"
+ action=""
+ enctype="multipart/form-data">
+{{ form|crispy }}
+<input type="submit" class="btn btn-success" value="Upload BMC IP and NIC firmware version"/>
+</form>
+{% endblock %}
diff --git a/src/caas/templates/passwords.xml b/src/caas/templates/passwords.xml
new file mode 100644
index 0000000..99d465e
--- /dev/null
+++ b/src/caas/templates/passwords.xml
@@ -0,0 +1,13 @@
+{% extends "site.xml" %}
+{% block content %}
+{% load crispy_forms_tags %}
+<form name="password_upload_form"
+ id="password_upload_form"
+ method="POST"
+ action=""
+ enctype="multipart/form-data">
+{% csrf_token %}
+{{ form|crispy }}
+<input type="submit" class="btn btn-success" value="Upload and import serial numbers and passwords"/>
+</form>
+{% endblock %}
diff --git a/src/caas/templates/passwords_success.xml b/src/caas/templates/passwords_success.xml
new file mode 100644
index 0000000..01be059
--- /dev/null
+++ b/src/caas/templates/passwords_success.xml
@@ -0,0 +1,4 @@
+{% extends "site.xml" %}
+{% block content %}
+Serial number and password import was a success!
+{% endblock %}
diff --git a/src/caas/templates/playbookreport.xml b/src/caas/templates/playbookreport.xml
new file mode 100644
index 0000000..c768b46
--- /dev/null
+++ b/src/caas/templates/playbookreport.xml
@@ -0,0 +1,13 @@
+{% extends "site.xml" %}
+{% block content %}
+{% load crispy_forms_tags %}
+<form name="playbook_report_form"
+ id="playbook_report_form"
+ method="POST"
+ action=""
+ enctype="multipart/form-data">
+{% csrf_token %}
+{{ form|crispy }}
+<input type="submit" class="btn btn-success" value="Post playbook status"/>
+</form>
+{% endblock %}
diff --git a/src/caas/templates/pushbutton.xml b/src/caas/templates/pushbutton.xml
new file mode 100644
index 0000000..bc51019
--- /dev/null
+++ b/src/caas/templates/pushbutton.xml
@@ -0,0 +1,12 @@
+{% extends "site.xml" %}
+{% block content %}
+{% load crispy_forms_tags %}
+<form name="push_button_form"
+ id="push_button_form"
+ method="POST"
+ action=""
+ enctype="multipart/form-data">
+{{ form|crispy }}
+<input type="submit" class="btn btn-success" value="Make it so"/>
+</form>
+{% endblock %}
diff --git a/src/caas/templates/queuecustom.xml b/src/caas/templates/queuecustom.xml
new file mode 100644
index 0000000..0cd5f58
--- /dev/null
+++ b/src/caas/templates/queuecustom.xml
@@ -0,0 +1,12 @@
+{% extends "site.xml" %}
+{% block content %}
+{% load crispy_forms_tags %}
+<form name="queue_custom_form"
+ id="queue_custom_form"
+ method="POST"
+ action=""
+ enctype="multipart/form-data">
+{{ form|crispy }}
+<input type="submit" class="btn btn-success" value="Send job to ansible-queue"/>
+</form>
+{% endblock %}
diff --git a/src/caas/templates/serialnumber.xml b/src/caas/templates/serialnumber.xml
new file mode 100644
index 0000000..233cdfc
--- /dev/null
+++ b/src/caas/templates/serialnumber.xml
@@ -0,0 +1,12 @@
+{% extends "site.xml" %}
+{% block content %}
+{% load crispy_forms_tags %}
+<form name="serial_number_form"
+ id="serial_number_form"
+ method="POST"
+ action=""
+ enctype="multipart/form-data">
+{{ form|crispy }}
+<input type="submit" class="btn btn-success" value="Upload vendor, BMC IP and serial number"/>
+</form>
+{% endblock %}
diff --git a/src/caas/templates/site.xml b/src/caas/templates/site.xml
new file mode 100644
index 0000000..7c46498
--- /dev/null
+++ b/src/caas/templates/site.xml
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta name="viewport" content="width=device-width, initial-scale=1"></meta>
+ <meta charset="utf-8"></meta>
+ <title>Far-Edge Ops Middleware</title>
+ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"></link>
+ <script type="text/javascript" src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
+ <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
+ <script type="text/javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
+ </head>
+ <body>
+ <div class="container-fluid">
+ <div class="row" style="padding: 20px">
+ <div class="col">
+ <div class="page-header">
+ <h2 align="center">Far-Edge Ops Middleware</h2>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div id="content">
+ {% block content %}{% endblock %}
+ </div>
+ </body>
+</html>
diff --git a/src/caas/templates/subcloud.xml b/src/caas/templates/subcloud.xml
new file mode 100644
index 0000000..fec8cfb
--- /dev/null
+++ b/src/caas/templates/subcloud.xml
@@ -0,0 +1,58 @@
+{% extends "site.xml" %}
+{% block content %}
+{% load crispy_forms_tags %}
+<form name="subcloud_form"
+ id="subcloud_form"
+ method="POST"
+ action=""
+ enctype="multipart/form-data">
+{{ form|crispy }}
+<input type="submit" class="btn btn-success" value="Find subcloud"/>
+</form>
+{% for subcloud in subclouds %}
+<div>
+ <pre>
+ fqdn: {{ subcloud.cluster_name }}.{{ fqdn }}
+ server_id: {{ subcloud.id }}
+ cluster_id: {{ subcloud.cluster_id }}
+ fuze_spm_site_id: {{ subcloud.fuze_spm_site_id }}
+ parent_oam_vip_hostname: {{ subcloud.parent_oam_vip_hostname }}
+ parent_oam_vip_address: {{ subcloud.parent_oam_vip_address }}
+ parent_mgmt_address_range_start: {{ subcloud.parent_mgmt_address_range_start }}
+ parent_mgmt_address_range_end: {{ subcloud.parent_mgmt_address_range_end }}
+ parent_mgmt_default_gateway: {{ subcloud.parent_mgmt_default_gateway }}
+ parent_mgmt_subnet: {{ subcloud.parent_mgmt_subnet }}
+ pxe_mac_address: {{ subcloud.pxe_mac_address }}
+ ilo_hostname: {{ subcloud.ilo_hostname }}
+ ilo_host_address: {{ subcloud.ilo_host_address }}
+ oam_hostname: {{ subcloud.oam_hostname }}
+ oam_host_address: {{ subcloud.oam_host_address }}
+ oam_vip_address: {{ subcloud.oam_vip_address }}
+ oam_default_gateway: {{ subcloud.oam_default_gateway }}
+ mgmt_address_range_start: {{ subcloud.mgmt_address_range_start }}
+ mgmt_address_range_end: {{ subcloud.mgmt_address_range_end }}
+ mgmt_default_gateway: {{ subcloud.mgmt_default_gateway }}
+ mgmt_subnet: {{ subcloud.mgmt_subnet }}
+ host_vlan: {{ subcloud.host_vlan }}
+ oam_vlan: {{ subcloud.oam_vlan }}
+ mgmt_vlan: {{ subcloud.mgmt_vlan }}
+ cluster_name: {{ subcloud.cluster_name }}
+ parent_cluster_name: {{ subcloud.parent_cluster_name }}
+ vendor_name: {{ subcloud.vendor_name }}
+ intel_nic_firmware_version: {{ subcloud.intel_nic_firmware_version }}
+ maint_window_p: {{ subcloud.maint_window_p }}
+ namespace_id: {{ subcloud.namespace_id }}
+ namespace_name: {{ subcloud.namespace_name }}
+ bmc_username: {{ subcloud.bmc_username }}
+ bmc_password: {{ subcloud.bmc_password }}
+ wrinstallschedule_id: {{ subcloud.wrinstallschedule_id }}
+ date_scheduled: {{ subcloud.date_scheduled }}
+ date_completed: {{ subcloud.date_completed }}
+ date_last_failed: {{ subcloud.date_last_failed }}
+ kirke_ticket_number: {{ subcloud.kirke_ticket_number }}
+ kirke_ticket_status: {{ subcloud.kirke_ticket_status }}
+ kirke_ticket_completed: {{ subcloud.kirke_ticket_completed }}
+ </pre>
+</div>
+{% endfor %}
+{% endblock %}
diff --git a/src/caas/templates/wrinstall.xml b/src/caas/templates/wrinstall.xml
new file mode 100644
index 0000000..f77e37f
--- /dev/null
+++ b/src/caas/templates/wrinstall.xml
@@ -0,0 +1,12 @@
+{% extends "site.xml" %}
+{% block content %}
+{% load crispy_forms_tags %}
+<form name="wr_install_form"
+ id="wr_install_form"
+ method="POST"
+ action=""
+ enctype="multipart/form-data">
+{{ form|crispy }}
+<input type="submit" class="btn btn-success" value="Check hardware and install Wind River CaaS"/>
+</form>
+{% endblock %}
diff --git a/src/caas/templates/wrinstallnow.xml b/src/caas/templates/wrinstallnow.xml
new file mode 100644
index 0000000..50fe961
--- /dev/null
+++ b/src/caas/templates/wrinstallnow.xml
@@ -0,0 +1,12 @@
+{% extends "site.xml" %}
+{% block content %}
+{% load crispy_forms_tags %}
+<form name="wr_install_now_form"
+ id="wr_install_now_form"
+ method="POST"
+ action=""
+ enctype="multipart/form-data">
+{{ form|crispy }}
+<input type="submit" class="btn btn-success" value="Install Wind River CaaS now"/>
+</form>
+{% endblock %}
diff --git a/src/caas/templates/wrremediate.xml b/src/caas/templates/wrremediate.xml
new file mode 100644
index 0000000..9509ae1
--- /dev/null
+++ b/src/caas/templates/wrremediate.xml
@@ -0,0 +1,12 @@
+{% extends "site.xml" %}
+{% block content %}
+{% load crispy_forms_tags %}
+<form name="wr_remediate_form"
+ id="wr_remediate_form"
+ method="POST"
+ action=""
+ enctype="multipart/form-data">
+{{ form|crispy }}
+<input type="submit" class="btn btn-success" value="Remediate Wind River CaaS subcloud"/>
+</form>
+{% endblock %}
diff --git a/src/caas/urls.py b/src/caas/urls.py
index 97d2641..6d9b02d 100644
--- a/src/caas/urls.py
+++ b/src/caas/urls.py
@@ -2,5 +2,31 @@ from django.urls import path
from . import views
urlpatterns = [
- path('', views.index, name='index')
+ # path("accounts/", include("django.contrib.auth.urls")),
+ path("", views.index, name="index"),
+ path("count/<int:count>/", views.count, name="count"),
+ path("ciq/", views.ciq, name="ciq"),
+ path("ciq/success/", views.ciq_success, name="ciq_success"),
+ path("mockciq/", views.mockciq, name="mockciq"),
+ path("passwords/", views.passwords, name="passwords"),
+ path("passwords/success/", views.passwords_success, name="passwords_success"),
+ path("serialnumber/", views.serialnumber, name="serialnumber"),
+ path("autoremediate/", views.autoremediate, name="autoremediate"),
+ path("dns/", views.dns, name="dns"),
+ # path("queuecustom/", views.queuecustom, name="queuecustom"),
+ path("macaddress/", views.macaddress, name="macaddress"),
+ path("adminpassword/", views.adminpassword, name="adminpassword"),
+ path("nicfirmwareversion/", views.nicfirmwareversion, name="nicfirmwareversion"),
+ path("nicfirmwareupgradebatch/", views.nicfirmwareupgradebatch, name="nicfirmwareupgradebatch"),
+ path("nicfirmwareupgrade/", views.nicfirmwareupgrade, name="nicfirmwareupgrade"),
+ path("nicfirmwareupgradenow/", views.nicfirmwareupgradenow, name="nicfirmwareupgradenow"),
+ path("nightlybatch/", views.nightlybatch, name="nightlybatch"),
+ path("wrinstall/", views.wrinstall, name="wrinstall"),
+ path("wrinstallnow/", views.wrinstallnow, name="wrinstallnow"),
+ path("wrfix/", views.wrfix, name="wrfix"),
+ path("reboot/", views.reboot, name="reboot"),
+ path("mockreboot/", views.mockreboot, name="mockreboot"),
+ path("playbookreport/", views.playbookreport, name="playbookreport"),
+ path("subcloud/", views.subcloud, name="subcloud"),
+ # path("fixcreds/", views.fixcreds, name="fixcreds"),
]
diff --git a/src/caas/views.py b/src/caas/views.py
index 91ea44a..049d9e4 100644
--- a/src/caas/views.py
+++ b/src/caas/views.py
@@ -1,3 +1,714 @@
from django.shortcuts import render
+from django.conf import settings
+from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
+from django.views.decorators.csrf import csrf_exempt
+from .forms import CiqUploadForm, CiqUpload2Form, CiqAssignOrphanSubcloudsForm, \
+ PasswordUploadForm, SerialNumberForm, DnsForm, \
+ MacAddressForm, AdminPasswordForm, NicFirmwareVersionForm, PushButtonForm, \
+ PlaybookReportForm, \
+ NicFirmwareUpgradeForm, NicFirmwareUpgradeNowForm, \
+ WrInstallForm, WrInstallNowForm, \
+ AutoremediateForm, WrRemediateForm, \
+ WrRebootForm, MockWrRebootForm, SubcloudForm
+ # QueueCustomForm, \
+from .services.ciqservice import CiqService
+from .services.passwordservice import PasswordService
+from .services.icingaservice import IcingaService
+from .services.bmcservice import BmcService
+from .services.macaddressservice import MacAddressService
+from .services.dnsservice import DnsService
+from .services.firmwareservice import FirmwareService
+from .services.wrservice import WrService
+from .services.patchservice import PatchService
+from .services.playbookreportservice import PlaybookReportService
+from .services.icingapollservice import IcingaPollService
+from .services.nicfirmwareversionservice import NicFirmwareVersionService
+from .services.nicfirmwareupgradenowservice import NicFirmwareUpgradeNowService
+from .services.wrinstallnowservice import WrInstallNowService
+from .services.subcloudservice import SubcloudService
+import logging
-# Create your views here.
+
+logger = logging.getLogger("caas")
+
+
+def index(request):
+ return HttpResponse("Hello world")
+
+
+def count(request, count):
+ data = {
+ "name": "Vitor",
+ "location": "Finland",
+ "is_active": True,
+ "count": count
+ }
+ return JsonResponse(data)
+
+
+@csrf_exempt
+def passwords(request):
+ if request.method == "POST":
+ form = PasswordUploadForm(request.POST, request.FILES)
+ if form.is_valid():
+ PasswordService.import_password_data(request.FILES["filehandle"])
+ return HttpResponseRedirect("success/")
+ else:
+ form = PasswordUploadForm()
+ context = {
+ "title": "Far-Edge Ops Middleware",
+ "form": form
+ }
+ return render(request, "passwords.xml", context)
+
+
+def passwords_success(request):
+ return render(request, "passwords_success.xml")
+
+
+@csrf_exempt
+def ciq(request):
+ if request.method == "POST":
+ form = CiqUploadForm(request.POST, request.FILES)
+ if form.is_valid():
+ CiqService.import_ciq_data(request.FILES["filehandle"], form.cleaned_data["assign_parent"])
+ # TODO: opstracker for lat, long, etc
+ icinga = IcingaService(settings.ANSIBLE["icinga"]["target"],
+ settings.ANSIBLE["icinga"]["git"],
+ settings.ANSIBLE["icinga"]["branch"],
+ settings.ANSIBLE["icinga"]["playbook"],
+ settings.ANSIBLE["icinga"]["zmq"])
+ icinga.deploy()
+ return HttpResponseRedirect("success/")
+ else:
+ form = CiqUploadForm()
+ context = {
+ "title": "Far-Edge Ops Middleware",
+ "form": form
+ }
+ return render(request, "ciq.xml", context)
+
+
+@csrf_exempt
+def mockciq(request):
+ if request.method == "POST":
+ form = PushButtonForm(request.POST)
+ if form.is_valid():
+ icinga = IcingaService(settings.ANSIBLE["icinga"]["target"],
+ settings.ANSIBLE["icinga"]["git"],
+ settings.ANSIBLE["icinga"]["branch"],
+ settings.ANSIBLE["icinga"]["playbook"],
+ settings.ANSIBLE["icinga"]["zmq"])
+ icinga.deploy(mockciq = settings.MOCKCIQ)
+ return JsonResponse({"status": "OK"})
+ else:
+ form = PushButtonForm()
+ context = {
+ "title": "Far-Edge Ops Middleware",
+ "form": form
+ }
+ return render(request, "pushbutton.xml", context)
+
+
+def ciq_success(request):
+ return render(request, "ciq_success.xml")
+
+
+@csrf_exempt
+def serialnumber(request):
+ if request.method == "POST":
+ logger.debug("POST received")
+ form = SerialNumberForm(request.POST)
+ if form.is_valid():
+ logger.debug("%s POST received" % form.cleaned_data["ilo_host_address"])
+ if not PasswordService.is_server_linked_to_blade(ilo_host_address = form.cleaned_data["ilo_host_address"]):
+ if not settings.MOCKCIQ:
+ link_status = PasswordService.link_server_to_blade(vendor_name = form.cleaned_data["vendor"],
+ serial_number = form.cleaned_data["serial_number"],
+ ilo_host_address = form.cleaned_data["ilo_host_address"])
+ if link_status is None:
+ logger.error("%s Error linking server to blade!" % form.cleaned_data["ilo_host_address"])
+ return JsonResponse({"status": "Error linking server to blade!"})
+
+ PasswordService.create_bmc_admin_password(serial_number = form.cleaned_data["serial_number"])
+ dns = DnsService(form.cleaned_data["ilo_host_address"],
+ settings.ANSIBLE["dns"]["git"],
+ settings.ANSIBLE["dns"]["branch"],
+ settings.ANSIBLE["dns"]["playbook"],
+ settings.ANSIBLE["dns"]["zmq"])
+ rc = dns.deploy()
+ if rc != 0:
+ errmsg = "%s dns deploy failed" % form.cleaned_data["ilo_host_address"]
+ logger.error(errmsg)
+ return JsonResponse({"status": errmsg})
+
+ # don't run bmc automation against central controllers
+ if not PasswordService.central_server_p(form.cleaned_data["ilo_host_address"]):
+ if settings.ENABLE_BMC:
+ bmc = BmcService(form.cleaned_data["ilo_host_address"],
+ settings.ANSIBLE["bmc"]["git"],
+ settings.ANSIBLE["bmc"]["branch"],
+ settings.ANSIBLE["bmc"]["playbook"],
+ settings.ANSIBLE["bmc"]["zmq"])
+ rc = bmc.deploy()
+ if rc != 0:
+ logger.error("%s bmc deploy failed" % form.cleaned_data["ilo_host_address"])
+ return JsonResponse({"status": "%s bmc deploy failed!" % form.cleaned_data["ilo_host_address"]})
+ else:
+ icingapoll = IcingaPollService(form.cleaned_data["ilo_host_address"],
+ settings.ANSIBLE["icinga_poll"]["git"],
+ settings.ANSIBLE["icinga_poll"]["branch"],
+ settings.ANSIBLE["icinga_poll"]["playbook"],
+ settings.ANSIBLE["icinga_poll"]["zmq"],
+ "adminpassword")
+ rc = icingapoll.deploy()
+ if rc != 0:
+ logger.error("%s icingapoll deploy failed" % form.cleaned_data["ilo_host_address"])
+ return JsonResponse({"status": "%s icingapoll deploy failed!" % form.cleaned_data["ilo_host_address"]})
+ else:
+ logger.debug("%s server already linked to blade" % form.cleaned_data["ilo_host_address"])
+
+ return JsonResponse({"status": "OK"})
+ else:
+ errmsg = "%s Error linking server to blade: invalid form" % form.cleaned_data["ilo_host_address"]
+ logger.error(errmsg)
+ raise Exception(errmsg)
+ else:
+ form = SerialNumberForm()
+ context = {
+ "title": "Far-Edge Ops Middleware",
+ "form": form
+ }
+ return render(request, "serialnumber.xml", context)
+
+
+@csrf_exempt
+def autoremediate(request):
+ if request.method == "POST":
+ form = AutoremediateForm(request.POST)
+ if form.is_valid():
+ ilo_host_address_list = form.cleaned_data["ilo_host_address_list"]
+ for ilo_host_address in list(ilo_host_address_list.split()):
+ linking_data = PasswordService.get_server_link_data(ilo_host_address)
+ if linking_data is None:
+ logger.error("Error PasswordService.get_server_link_data! ilo_host_address=%s" % ilo_host_address)
+ continue
+
+ PasswordService.create_bmc_admin_password(serial_number = linking_data["serial_number"])
+ dns = DnsService(linking_data["ilo_host_address"],
+ settings.ANSIBLE["dns"]["git"],
+ settings.ANSIBLE["dns"]["branch"],
+ settings.ANSIBLE["dns"]["playbook"],
+ settings.ANSIBLE["dns"]["zmq"])
+ rc = dns.deploy()
+ if rc != 0:
+ errmsg = "%s dns deploy failed" % form.cleaned_data["ilo_host_address"]
+ logger.error(errmsg)
+ return JsonResponse({"status": errmsg})
+
+ # don't run bmc automation against central controllers
+ if not PasswordService.central_server_p(ilo_host_address):
+ if settings.ENABLE_BMC:
+ bmc = BmcService(linking_data["ilo_host_address"],
+ settings.ANSIBLE["bmc"]["git"],
+ settings.ANSIBLE["bmc"]["branch"],
+ settings.ANSIBLE["bmc"]["playbook"],
+ settings.ANSIBLE["bmc"]["zmq"])
+ rc = bmc.deploy()
+ if rc != 0:
+ logger.error("%s bmc deploy failed" % form.cleaned_data["ilo_host_address"])
+ return JsonResponse({"status": "%s bmc deploy failed!" % form.cleaned_data["ilo_host_address"]})
+ else:
+ icingapoll = IcingaPollService(linking_data["ilo_host_address"],
+ settings.ANSIBLE["icinga_poll"]["git"],
+ settings.ANSIBLE["icinga_poll"]["branch"],
+ settings.ANSIBLE["icinga_poll"]["playbook"],
+ settings.ANSIBLE["icinga_poll"]["zmq"],
+ "adminpassword")
+ rc = icingapoll.deploy()
+ if rc != 0:
+ logger.error("%s dicingapollns deploy failed" % form.cleaned_data["ilo_host_address"])
+ return JsonResponse({"status": "%s icingapoll deploy failed!" % form.cleaned_data["ilo_host_address"]})
+
+ return JsonResponse({"status": "OK"})
+ else:
+ raise Exception("Error linking server to blade: invalid form")
+ else:
+ form = AutoremediateForm()
+ context = {
+ "title": "Far-Edge Ops Middleware",
+ "form": form
+ }
+ return render(request, "autoremediate.xml", context)
+
+
+@csrf_exempt
+def dns(request):
+ if request.method == "POST":
+ form = DnsForm(request.POST)
+ if form.is_valid():
+ dns = DnsService(form.cleaned_data["ilo_host_address"],
+ settings.ANSIBLE["dns"]["git"],
+ settings.ANSIBLE["dns"]["branch"],
+ settings.ANSIBLE["dns"]["playbook"],
+ settings.ANSIBLE["dns"]["zmq"])
+ rc = dns.deploy()
+ if rc != 0:
+ errmsg = "%s dns deploy failed" % form.cleaned_data["ilo_host_address"]
+ logger.error(errmsg)
+ return JsonResponse({"status": errmsg})
+ return JsonResponse({"status": "OK"})
+ else:
+ raise Exception("Error processing DNS: form input is invalid.")
+ else:
+ form = DnsForm()
+ context = {
+ "title": "Far-Edge Ops Middleware",
+ "form": form
+ }
+ return render(request, "dns.xml", context)
+
+
+# @csrf_exempt
+# def queuecustom(request):
+# if request.method == "POST":
+# form = QueueCustomForm(request.POST)
+# if form.is_valid():
+# key = form.cleaned_data["key"]
+# playbook_key = form.cleaned_data["playbook_key"]
+# ansible = AnsibleService(key,
+# form.cleaned_data["target"],
+# settings.ANSIBLE[key]["git"],
+# settings.ANSIBLE[key]["branch"],
+# settings.ANSIBLE[key][playbook_key],
+# settings.ANSIBLE[key]["zmq"])
+# if len(form.cleaned_data["cluster_name"]) > 0:
+# extra_args = {"cluster-name": form.cleaned_data["cluster_name"]}
+# else:
+# extra_args = {}
+# ansible.run_playbook(extra_args = extra_args)
+# return JsonResponse({"status": "OK"})
+# else:
+# raise Exception("Error processing queuecustom: form input is invalid.")
+# else:
+# form = QueueCustomForm()
+# context = {
+# "title": "Far-Edge Ops Middleware",
+# "form": form
+# }
+# return render(request, "queuecustom.xml", context)
+
+
+@csrf_exempt
+def macaddress(request):
+ if request.method == "POST":
+ form = MacAddressForm(request.POST)
+ if form.is_valid():
+ MacAddressService.set_server_mac_address(ilo_host_address = form.cleaned_data["ilo_host_address"],
+ pxe_mac_address = form.cleaned_data["pxe_mac_address"],
+ intel_nic_firmware_version = form.cleaned_data["intel_nic_firmware_version"])
+
+ icinga = IcingaService(settings.ANSIBLE["icinga"]["target"],
+ settings.ANSIBLE["icinga"]["git"],
+ settings.ANSIBLE["icinga"]["branch"],
+ settings.ANSIBLE["icinga"]["playbook"],
+ settings.ANSIBLE["icinga"]["zmq"])
+ rc = icinga.deploy()
+ if rc != 0:
+ logger.error("%s icinga deploy failed" % form.cleaned_data["ilo_host_address"])
+ return JsonResponse({"status": "%s icinga deploy failed!" % form.cleaned_data["ilo_host_address"]})
+ return JsonResponse({"status": "OK"})
+ else:
+ raise Exception("Error processing macaddress: form input is invalid.")
+ else:
+ form = MacAddressForm()
+ context = {
+ "title": "Far-Edge Ops Middleware",
+ "form": form
+ }
+ return render(request, "macaddress.xml", context)
+
+
+@csrf_exempt
+def adminpassword(request):
+ if request.method == "POST":
+ form = AdminPasswordForm(request.POST)
+ if form.is_valid():
+ ilo_host_address = form.cleaned_data["ilo_host_address"]
+ icinga_poll_status = form.cleaned_data["icinga_poll_status"]
+ if icinga_poll_status == "OK":
+ firmware = FirmwareService(ilo_host_address,
+ settings.ANSIBLE["nic"]["git"],
+ settings.ANSIBLE["nic"]["branch"],
+ settings.ANSIBLE["nic"]["playbook"],
+ settings.ANSIBLE["nic"]["zmq"])
+ firmware.schedule_upgrade()
+ nicfirmwareupgradenow = NicFirmwareUpgradeNowService(ilo_host_address,
+ settings.ANSIBLE["nic"]["git"],
+ settings.ANSIBLE["nic"]["branch"],
+ settings.ANSIBLE["nic"]["playbook"],
+ settings.ANSIBLE["nic"]["zmq"])
+ nicfirmwareupgradenow.deploy()
+ wr = WrService(ilo_host_address,
+ settings.ANSIBLE["wr"]["git"],
+ settings.ANSIBLE["wr"]["branch"],
+ settings.ANSIBLE["wr"]["playbook"],
+ settings.ANSIBLE["wr"]["zmq"])
+ wr.schedule_install()
+ # The firmware pipeline will launch the wr install
+ return JsonResponse({"status": "OK"})
+ else:
+ return JsonResponse({"status": "NO-OP: icinga_poll status NOT_OK"})
+ else:
+ raise Exception("Error changing BMC administrator password: form is invalid")
+ else:
+ form = AdminPasswordForm()
+ context = {
+ "title": "Far-Edge Ops Middleware",
+ "form": form
+ }
+ return render(request, "adminpassword.xml", context)
+
+
+@csrf_exempt
+def nicfirmwareversion(request):
+ if request.method == "POST":
+ form = NicFirmwareVersionForm(request.POST)
+ if form.is_valid():
+ NicFirmwareVersionService.set_server_nic_firmware_version(ilo_host_address = form.cleaned_data["ilo_host_address"],
+ intel_nic_firmware_version = form.cleaned_data["nic_firmware_version"])
+ return JsonResponse({"status": "OK"})
+ else:
+ raise Exception("Error processing macaddress: form input is invalid.")
+ else:
+ form = NicFirmwareVersionForm()
+ context = {
+ "title": "Far-Edge Ops Middleware",
+ "form": form
+ }
+ return render(request, "nicfirmwareversion.xml", context)
+
+
+@csrf_exempt
+def nicfirmwareupgrade(request):
+ if request.method == "POST":
+ form = NicFirmwareUpgradeForm(request.POST)
+ if form.is_valid():
+ ilo_host_address_list = form.cleaned_data["ilo_host_address_list"]
+ for ilo_host_address in list(ilo_host_address_list.split()):
+ icingapoll = IcingaPollService(ilo_host_address,
+ settings.ANSIBLE["icinga_poll"]["git"],
+ settings.ANSIBLE["icinga_poll"]["branch"],
+ settings.ANSIBLE["icinga_poll"]["playbook"],
+ settings.ANSIBLE["icinga_poll"]["zmq"],
+ "nicfirmwareupgradenow")
+ icingapoll.deploy()
+ return JsonResponse({"status": "OK"})
+ else:
+ raise Exception("Error processing nicfirmwareupgrade: form input is invalid.")
+ else:
+ form = NicFirmwareUpgradeForm()
+ context = {
+ "title": "Far-Edge Ops Middleware",
+ "form": form
+ }
+ return render(request, "nicfirmwareupgrade.xml", context)
+
+
+@csrf_exempt
+def nicfirmwareupgradenow(request):
+ if request.method == "POST":
+ form = NicFirmwareUpgradeNowForm(request.POST)
+ if form.is_valid():
+ ilo_host_address = form.cleaned_data["ilo_host_address"]
+ icinga_poll_status = form.cleaned_data["icinga_poll_status"]
+ if icinga_poll_status == "OK":
+ firmware = FirmwareService(ilo_host_address,
+ settings.ANSIBLE["nic"]["git"],
+ settings.ANSIBLE["nic"]["branch"],
+ settings.ANSIBLE["nic"]["playbook"],
+ settings.ANSIBLE["nic"]["zmq"])
+ firmware.schedule_upgrade()
+
+ wr = WrService(ilo_host_address,
+ settings.ANSIBLE["wr"]["git"],
+ settings.ANSIBLE["wr"]["branch"],
+ settings.ANSIBLE["wr"]["playbook"],
+ settings.ANSIBLE["wr"]["zmq"])
+ wr.schedule_install()
+
+ nicfirmwareupgradenow = NicFirmwareUpgradeNowService(ilo_host_address,
+ settings.ANSIBLE["nic"]["git"],
+ settings.ANSIBLE["nic"]["branch"],
+ settings.ANSIBLE["nic"]["playbook"],
+ settings.ANSIBLE["nic"]["zmq"])
+ nicfirmwareupgradenow.deploy()
+ return JsonResponse({"status": "OK"})
+ else:
+ return JsonResponse({"status": "OK"})
+ else:
+ raise Exception("Error processing nicfirmwareupgradenow: form input is invalid.")
+ else:
+ form = NicFirmwareUpgradeNowForm()
+ context = {
+ "title": "Far-Edge Ops Middleware",
+ "form": form
+ }
+ return render(request, "nicfirmwareupgradenow.xml", context)
+
+@csrf_exempt
+def wrinstall(request):
+ if request.method == "POST":
+ form = WrInstallForm(request.POST)
+ if form.is_valid():
+ ilo_host_address_list = form.cleaned_data["ilo_host_address_list"]
+ for ilo_host_address in list(ilo_host_address_list.split()):
+ icingapoll = IcingaPollService(ilo_host_address,
+ settings.ANSIBLE["icinga_poll"]["git"],
+ settings.ANSIBLE["icinga_poll"]["branch"],
+ settings.ANSIBLE["icinga_poll"]["playbook"],
+ settings.ANSIBLE["icinga_poll"]["zmq"],
+ "wrinstallnow")
+ icingapoll.deploy()
+ return JsonResponse({"status": "OK"})
+ else:
+ raise Exception("Error processing wrinstall: form input is invalid.")
+ else:
+ form = WrInstallForm()
+ context = {
+ "title": "Far-Edge Ops Middleware",
+ "form": form
+ }
+ return render(request, "wrinstall.xml", context)
+
+@csrf_exempt
+def wrinstallnow(request):
+ if request.method == "POST":
+ form = WrInstallNowForm(request.POST)
+ if form.is_valid():
+ ilo_host_address = form.cleaned_data["ilo_host_address"]
+ icinga_poll_status = form.cleaned_data["icinga_poll_status"]
+ if icinga_poll_status == "OK":
+ wrinstallnow = WrInstallNowService("wr",
+ ilo_host_address,
+ settings.ANSIBLE["wr"]["git"],
+ settings.ANSIBLE["wr"]["branch"],
+ settings.ANSIBLE["wr"]["playbook"],
+ settings.ANSIBLE["wr"]["zmq"])
+ wrinstallnow.deploy()
+ return JsonResponse({"status": "OK"})
+ else:
+ return JsonResponse({"status": "OK"})
+ else:
+ raise Exception("Error processing wrinstallnow: form input is invalid.")
+ else:
+ form = WrInstallNowForm()
+ context = {
+ "title": "Far-Edge Ops Middleware",
+ "form": form
+ }
+ return render(request, "wrinstallnow.xml", context)
+
+
+@csrf_exempt
+def nicfirmwareupgradebatch(request):
+ if request.method == "POST":
+ form = PushButtonForm(request.POST)
+ if form.is_valid():
+ firmware = FirmwareService(None,
+ settings.ANSIBLE["nic"]["git"],
+ settings.ANSIBLE["nic"]["branch"],
+ settings.ANSIBLE["nic"]["playbook"],
+ settings.ANSIBLE["nic"]["zmq"])
+ firmware.deploy()
+ return JsonResponse({"status": "OK"})
+ else:
+ raise Exception("Error running nightly batch: somehow a form that takes no inputs is invalid")
+ else:
+ form = PushButtonForm()
+ context = {
+ "title": "Far-Edge Ops Middleware",
+ "form": form
+ }
+ return render(request, "pushbutton.xml", context)
+
+
+@csrf_exempt
+def nightlybatch(request):
+ if request.method == "POST":
+ form = PushButtonForm(request.POST)
+ if form.is_valid():
+ wr = WrService(None,
+ settings.ANSIBLE["wr"]["git"],
+ settings.ANSIBLE["wr"]["branch"],
+ settings.ANSIBLE["wr"]["playbook"],
+ settings.ANSIBLE["wr"]["zmq"])
+ wr.deploy()
+ return JsonResponse({"status": "OK"})
+ else:
+ raise Exception("Error running nightly batch: somehow a form that takes no inputs is invalid")
+ else:
+ form = PushButtonForm()
+ context = {
+ "title": "Far-Edge Ops Middleware",
+ "form": form
+ }
+ return render(request, "pushbutton.xml", context)
+
+
+@csrf_exempt
+def nightlypatch(request):
+ if request.method == "POST":
+ form = PushButtonForm(request.POST)
+ if form.is_valid():
+ patch = PatchService(None,
+ settings.ANSIBLE["patch"]["git"],
+ settings.ANSIBLE["patch"]["branch"],
+ settings.ANSIBLE["patch"]["playbook"],
+ settings.ANSIBLE["patch"]["zmq"])
+ patch.deploy()
+ return JsonResponse({"status": "OK"})
+ else:
+ raise Exception("Error running nightly patch: somehow a form that takes no inputs is invalid")
+ else:
+ form = PushButtonForm()
+ context = {
+ "title": "Far-Edge Ops Middleware",
+ "form": form
+ }
+ return render(request, "pushbutton.xml", context)
+
+
+@csrf_exempt
+def wrfix(request):
+ if request.method == "POST":
+ form = WrRemediateForm(request.POST)
+ if form.is_valid():
+ playbook = form.cleaned_data["playbook"]
+ cluster_name_list = form.cleaned_data["cluster_name_list"]
+ for cluster_name in list(cluster_name_list.split()):
+ wrinstallnow = WrInstallNowService(playbook,
+ cluster_name,
+ settings.ANSIBLE[playbook]["git"],
+ settings.ANSIBLE[playbook]["branch"],
+ settings.ANSIBLE[playbook]["playbook"],
+ settings.ANSIBLE[playbook]["zmq"])
+ wrinstallnow.remediate()
+ return JsonResponse({"status": "OK"})
+ else:
+ raise Exception("Error running playbook: the form is invalid")
+ else:
+ form = WrRemediateForm()
+ context = {
+ "title": "Far-Edge Ops Middleware",
+ "form": form
+ }
+ return render(request, "wrremediate.xml", context)
+
+
+@csrf_exempt
+def reboot(request):
+ if request.method == "POST":
+ form = WrRebootForm(request.POST)
+ if form.is_valid():
+ namespace_name_list = form.cleaned_data["namespace_name_list"]
+ for namespace_name in list(namespace_name_list.split()):
+ wrinstallnow = WrInstallNowService("wr_reboot",
+ namespace_name,
+ settings.ANSIBLE["wr_reboot"]["git"],
+ settings.ANSIBLE["wr_reboot"]["branch"],
+ settings.ANSIBLE["wr_reboot"]["playbook"],
+ settings.ANSIBLE["wr_reboot"]["zmq"])
+ wrinstallnow.remediate()
+ return JsonResponse({"status": "OK"})
+ else:
+ raise Exception("Error running reboot: the form is invalid")
+ else:
+ form = WrRebootForm()
+ context = {
+ "title": "Far-Edge Ops Middleware",
+ "form": form
+ }
+ return render(request, "wrremediate.xml", context)
+
+#created Oct30 2020 for Raj reboot testing delete later - Soda
+@csrf_exempt
+def mockreboot(request):
+ if request.method == "POST":
+ form = MockWrRebootForm(request.POST)
+ if form.is_valid():
+ namespace_name_list = form.cleaned_data["namespace_name_list"]
+ for namespace_name in list(namespace_name_list.split()):
+ print(namespace_name)
+ return JsonResponse({"status": "OK"})
+ else:
+ raise Exception("Error running Mock reboot: the form is invalid")
+ else:
+ form = MockWrRebootForm()
+ context = {
+ "title": "Mock Reboot Far-Edge Ops Middleware",
+ "form": form
+ }
+ return render(request, "mockwrremediate.xml", context)
+
+@csrf_exempt
+def playbookreport(request):
+ if request.method == "POST":
+ form = PlaybookReportForm(request.POST)
+ if form.is_valid():
+ report_kwargs = {"git": form.cleaned_data["git"],
+ "playbook": form.cleaned_data["playbook"],
+ "target": form.cleaned_data["target"],
+ "failed": form.cleaned_data["failed"]}
+ service = PlaybookReportService(**report_kwargs)
+ status = service.process()
+ return JsonResponse({"status": status})
+ else:
+ raise Exception("Error receiving playbook report: form input is invalid.")
+ else:
+ form = PlaybookReportForm()
+ context = {
+ "title": "Far-Edge Ops Middleware",
+ "form": form
+ }
+ return render(request, "playbookreport.xml", context)
+
+
+@csrf_exempt
+def subcloud(request):
+ subclouds = None
+ if request.method == "POST":
+ form = SubcloudForm(request.POST)
+ if form.is_valid():
+ subclouds = SubcloudService.find_subclouds(form.cleaned_data["fuze_id"])
+ else:
+ raise Exception("Error finding subcloud: form input is invalid.")
+ else:
+ form = SubcloudForm()
+ context = {
+ "title": "Far-Edge Ops Middleware",
+ "form": form,
+ "subclouds": subclouds,
+ "fqdn": settings.DNS_DOMAIN
+ }
+ return render(request, "subcloud.xml", context)
+
+
+# @csrf_exempt
+# def fixcreds(request):
+# if request.method == "POST":
+# form = PushButtonForm(request.POST)
+# if form.is_valid():
+# PasswordService.fix_creds()
+# return JsonResponse({"status": "OK"})
+# else:
+# form = PushButtonForm()
+# context = {
+# "title": "Far-Edge Ops Middleware",
+# "form": form
+# }
+# return render(request, "pushbutton.xml", context)
+
+
+# def fixcreds_success(request):
+# return render(request, "ciq_success.xml")