summaryrefslogtreecommitdiff
path: root/src/automationstatus
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/automationstatus
parent22dae02a86c1fce71091bfa5289cf99abba1b217 (diff)
more filesHEADmaster
Diffstat (limited to 'src/automationstatus')
-rw-r--r--src/automationstatus/README.md26
-rw-r--r--src/automationstatus/__init__.py0
-rw-r--r--src/automationstatus/admin.py3
-rw-r--r--src/automationstatus/apps.py5
-rw-r--r--src/automationstatus/crons.py151
-rw-r--r--src/automationstatus/migrations/0001_initial.py25
-rw-r--r--src/automationstatus/migrations/0002_auto_20200908_1720.py23
-rw-r--r--src/automationstatus/migrations/0003_deploymentworkflow_summary.py39
-rw-r--r--src/automationstatus/migrations/0004_auto_20201020_0232.py20
-rw-r--r--src/automationstatus/migrations/0005_auto_20201020_0253.py18
-rw-r--r--src/automationstatus/migrations/0006_auto_20201020_1416.py18
-rw-r--r--src/automationstatus/migrations/0007_auto_20201026_0129.py33
-rw-r--r--src/automationstatus/migrations/0008_auto_20201030_1654.py48
-rw-r--r--src/automationstatus/migrations/0009_orchestrationworkflow.py28
-rw-r--r--src/automationstatus/migrations/__init__.py0
-rw-r--r--src/automationstatus/models.py67
-rw-r--r--src/automationstatus/serializers.py9
-rw-r--r--src/automationstatus/tests.py3
-rw-r--r--src/automationstatus/urls.py14
-rw-r--r--src/automationstatus/views.py19
20 files changed, 549 insertions, 0 deletions
diff --git a/src/automationstatus/README.md b/src/automationstatus/README.md
new file mode 100644
index 0000000..3adf86a
--- /dev/null
+++ b/src/automationstatus/README.md
@@ -0,0 +1,26 @@
+## How to use the automation status API
+
+The automation status API is a REST api for playbooks to report startus as they are running.
+
+URL: /automationstatus/playbook/
+
+## Sending a status updates
+
+POST: /automationstatus/playbook/
+
+Body:
+{
+ "ilo_host_address": "2001:4888:2a10:30c2:101:40a:0:e001",
+ "playbook_name": "test_playbook123",
+ "status": "test_status223"
+}
+
+## Retrieve updates
+
+GET: /automationstatus/playbook/
+
+GET: /automationstatus/playbook/1
+
+
+
+
diff --git a/src/automationstatus/__init__.py b/src/automationstatus/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/automationstatus/__init__.py
diff --git a/src/automationstatus/admin.py b/src/automationstatus/admin.py
new file mode 100644
index 0000000..8c38f3f
--- /dev/null
+++ b/src/automationstatus/admin.py
@@ -0,0 +1,3 @@
+from django.contrib import admin
+
+# Register your models here.
diff --git a/src/automationstatus/apps.py b/src/automationstatus/apps.py
new file mode 100644
index 0000000..0df5294
--- /dev/null
+++ b/src/automationstatus/apps.py
@@ -0,0 +1,5 @@
+from django.apps import AppConfig
+
+
+class AutomationStatusConfig(AppConfig):
+ name = 'automationstatus'
diff --git a/src/automationstatus/crons.py b/src/automationstatus/crons.py
new file mode 100644
index 0000000..da1d59d
--- /dev/null
+++ b/src/automationstatus/crons.py
@@ -0,0 +1,151 @@
+from .models import DeploymentWorkflow, Summary
+from .models import OrchestrationWorkflow
+from datetime import datetime
+from django.apps import apps
+from django.db import connection
+from django.core import serializers
+from django.utils import timezone
+
+
+def count():
+ queryset = DeploymentWorkflow.objects.all()
+
+ in_progress_clusters = 0
+ failed_clusters = 0
+ completed_clusters = 0
+ ingested = 0
+ online = 0
+ bmc = 0
+ firmware_scheduled = 0
+ firmware_upgraded = 0
+ wr_scheduled = 0
+ wr_installed = 0
+
+ for workflow in queryset:
+ if workflow.wr_installed:
+ completed_clusters = completed_clusters + 1
+ else:
+ in_progress_clusters = in_progress_clusters + 1
+ # summary.failed = failed_clusters
+
+ if workflow.ingested:
+ ingested = ingested + 1
+
+ if workflow.online:
+ online = online + 1
+
+ if workflow.bmc:
+ bmc = bmc + 1
+
+ if workflow.firmware_scheduled and not workflow.firmware_upgraded:
+ firmware_scheduled = firmware_scheduled + 1
+
+ if workflow.firmware_upgraded:
+ firmware_upgraded = firmware_upgraded + 1
+
+ if workflow.wr_scheduled and not workflow.wr_installed:
+ wr_scheduled = wr_scheduled + 1
+
+ if workflow.wr_installed:
+ wr_installed = wr_installed + 1
+
+
+ summary = Summary()
+ summary.clusters = len(queryset)
+ summary.in_progress = in_progress_clusters
+ summary.completed = completed_clusters
+ summary.ingested = ingested
+ summary.online = online
+ summary.bmc = bmc
+ summary.firmware_scheduled = firmware_scheduled
+ summary.firmware_upgraded = firmware_upgraded
+ summary.wr_scheduled = wr_scheduled
+ summary.wr_installed = wr_installed
+ summary.created_at = timezone.now()
+ print(summary)
+ try:
+ summary.save()
+ except Exception as e:
+ print(e)
+
+
+def summary():
+ print("**** running cron: summary **** : {}".format(datetime.now()))
+ servers = apps.get_model('caas', 'Server')
+ query_set = servers.objects.select_related('cluster').select_related('blade')
+ for server in query_set:
+ # Set server id and date
+ status = DeploymentWorkflow()
+ status.cluster = server.cluster
+ status.created_at = timezone.now()
+ # CIQ ingestion
+ status.ingested = True
+ # Server online check
+ status.online = True if server.blade_id else False
+ #BMC done check
+ if server.pxe_mac_address and server.intel_nic_firmware_version:
+ status.bmc = True
+ # Check Firmware schedule and installation status
+ # Get server list from
+ Server = apps.get_model('caas', 'Server')
+ server = Server.objects.get(cluster=server.cluster)
+ FirmwareUpgradeSchedule = apps.get_model('caas', 'FirmwareUpgradeSchedule')
+ try:
+ firmware_schedule = FirmwareUpgradeSchedule.objects.get(server=server)
+ # Firmware installation Scheduled and completiong check
+ status.firmware_scheduled = True if firmware_schedule.date_scheduled else False
+ status.firmware_upgraded = True if firmware_schedule.date_completed else False
+ except FirmwareUpgradeSchedule.DoesNotExist:
+ status.firmware_schedule = False
+ status.firmware_upgraded = False
+ except Exception as e:
+ print(e)
+
+ # Check WindRiver schedule and installation status
+ WrInstallSchedule = apps.get_model('caas', 'WrInstallSchedule')
+ try:
+ wr_schedule = WrInstallSchedule.objects.select_related('cluster').get(cluster=server.cluster)
+ # WindRiver installation Scheduled and completiong check
+ status.wr_scheduled = True if wr_schedule.date_scheduled else False
+ status.wr_installed = True if wr_schedule.date_completed else False
+ except WrInstallSchedule.DoesNotExist:
+ status.wr_scheduled = False
+ status.wr_installed = False
+ except Exception as e:
+ print(e)
+ # Save status object
+ status.save()
+ count()
+
+def orchestration_summary():
+ print("**** running cron: orchestration_summary **** : {}".format(datetime.now()))
+ regions = apps.get_model('orchestration', 'remoteregionsetup')
+ status = OrchestrationWorkflow()
+
+ # Namespace count and Timestamp
+ status.namespaces = regions.objects.count()
+ status.created_at = timezone.now()
+
+ # Service accounts
+ status.orch_service_account = regions.objects.filter(serviceaccount__in=['orchestration-sa', 'SVC-FE-Atlas']).count()
+ status.edge_eng_service_account = regions.objects.filter(serviceaccount='SVC-Edge-Eng').count() + regions.objects.filter(serviceaccount__contains='application-sa-').count()
+ status.samsung_service_account = regions.objects.filter(serviceaccount='samsung-sa').count()
+
+ # Orchestration Kubeconfigs
+ status.orch_kubeconfig = regions.objects.filter(serviceaccount__in=['orchestration-sa', 'SVC-FE-Atlas']).exclude(kubeconfig='').count()
+
+ # Edge engineering Kubeconfigs
+ status.edge_eng_kubeconfig = regions.objects.filter(serviceaccount='SVC-Edge-Eng').exclude(kubeconfig='').count()
+ status.edge_eng_kubeconfig += regions.objects.filter(serviceaccount__contains='application-sa-').exclude(kubeconfig='').count()
+
+ # Samsung Kubeconfigs
+ status.samsung_kubeconfig= regions.objects.filter(serviceaccount__in=['orchestration-sa', 'SVC-FE-Atlas']).exclude(kubeconfig='').count()
+
+ # Uncomment and use once Dev completes tracking on his side
+ # Setting to 0 for now
+ status.data_network_setup = 0
+
+ status.save()
+
+
+
diff --git a/src/automationstatus/migrations/0001_initial.py b/src/automationstatus/migrations/0001_initial.py
new file mode 100644
index 0000000..fe2cd95
--- /dev/null
+++ b/src/automationstatus/migrations/0001_initial.py
@@ -0,0 +1,25 @@
+# Generated by Django 3.1.1 on 2020-09-08 04:15
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ initial = True
+
+ dependencies = [
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='AutomationStatus',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('playbook_name', models.CharField(blank=True, max_length=255)),
+ ('status', models.CharField(blank=True, max_length=50)),
+ ('ilo_host_address', models.CharField(blank=True, max_length=255)),
+ ('cluster_name', models.CharField(blank=True, max_length=255)),
+ ('created_at', models.DateTimeField(auto_now_add=True)),
+ ],
+ ),
+ ]
diff --git a/src/automationstatus/migrations/0002_auto_20200908_1720.py b/src/automationstatus/migrations/0002_auto_20200908_1720.py
new file mode 100644
index 0000000..12a4044
--- /dev/null
+++ b/src/automationstatus/migrations/0002_auto_20200908_1720.py
@@ -0,0 +1,23 @@
+# Generated by Django 3.1.1 on 2020-09-08 17:20
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('automationstatus', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='automationstatus',
+ name='fuze_spm_site_id',
+ field=models.CharField(blank=True, max_length=255),
+ ),
+ migrations.AddField(
+ model_name='automationstatus',
+ name='fuze_spm_site_name',
+ field=models.CharField(blank=True, max_length=255),
+ ),
+ ]
diff --git a/src/automationstatus/migrations/0003_deploymentworkflow_summary.py b/src/automationstatus/migrations/0003_deploymentworkflow_summary.py
new file mode 100644
index 0000000..1fc490f
--- /dev/null
+++ b/src/automationstatus/migrations/0003_deploymentworkflow_summary.py
@@ -0,0 +1,39 @@
+# Generated by Django 3.1.1 on 2020-10-20 01:53
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('caas', '0022_auto_20201001_1232'),
+ ('automationstatus', '0002_auto_20200908_1720'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='DeploymentWorkflow',
+ fields=[
+ ('cluster', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, primary_key=True, serialize=False, to='caas.cluster')),
+ ('ingested', models.BooleanField(blank=True, default=False, null=True)),
+ ('online', models.BooleanField(blank=True, default=False, null=True)),
+ ('bmc', models.BooleanField(blank=True, default=False, null=True)),
+ ('firmware_wr_scheduling', models.BooleanField(blank=True, default=False, null=True)),
+ ('firmware_upgraded', models.BooleanField(blank=True, default=False, null=True)),
+ ('wr_installed', models.BooleanField(blank=True, default=False, null=True)),
+ ('created_at', models.DateTimeField(auto_now_add=True)),
+ ],
+ ),
+ migrations.CreateModel(
+ name='Summary',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('servers', models.PositiveIntegerField()),
+ ('in_progress', models.PositiveIntegerField()),
+ ('completed', models.PositiveIntegerField()),
+ ('failed', models.PositiveIntegerField()),
+ ('created_at', models.DateTimeField(auto_now_add=True)),
+ ],
+ ),
+ ]
diff --git a/src/automationstatus/migrations/0004_auto_20201020_0232.py b/src/automationstatus/migrations/0004_auto_20201020_0232.py
new file mode 100644
index 0000000..410f8ac
--- /dev/null
+++ b/src/automationstatus/migrations/0004_auto_20201020_0232.py
@@ -0,0 +1,20 @@
+# Generated by Django 3.1.1 on 2020-10-20 02:32
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('caas', '0022_auto_20201001_1232'),
+ ('automationstatus', '0003_deploymentworkflow_summary'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='deploymentworkflow',
+ name='cluster',
+ field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, primary_key=True, serialize=False, to='caas.cluster'),
+ ),
+ ]
diff --git a/src/automationstatus/migrations/0005_auto_20201020_0253.py b/src/automationstatus/migrations/0005_auto_20201020_0253.py
new file mode 100644
index 0000000..0ca406f
--- /dev/null
+++ b/src/automationstatus/migrations/0005_auto_20201020_0253.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.1.1 on 2020-10-20 02:53
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('automationstatus', '0004_auto_20201020_0232'),
+ ]
+
+ operations = [
+ migrations.RenameField(
+ model_name='summary',
+ old_name='servers',
+ new_name='clusters',
+ ),
+ ]
diff --git a/src/automationstatus/migrations/0006_auto_20201020_1416.py b/src/automationstatus/migrations/0006_auto_20201020_1416.py
new file mode 100644
index 0000000..2e4804b
--- /dev/null
+++ b/src/automationstatus/migrations/0006_auto_20201020_1416.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.1.1 on 2020-10-20 14:16
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('automationstatus', '0005_auto_20201020_0253'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='deploymentworkflow',
+ name='created_at',
+ field=models.DateTimeField(blank=True, null=True),
+ ),
+ ]
diff --git a/src/automationstatus/migrations/0007_auto_20201026_0129.py b/src/automationstatus/migrations/0007_auto_20201026_0129.py
new file mode 100644
index 0000000..dd7f547
--- /dev/null
+++ b/src/automationstatus/migrations/0007_auto_20201026_0129.py
@@ -0,0 +1,33 @@
+# Generated by Django 3.1.1 on 2020-10-26 01:29
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('automationstatus', '0006_auto_20201020_1416'),
+ ]
+
+ operations = [
+ migrations.RenameField(
+ model_name='deploymentworkflow',
+ old_name='firmware_wr_scheduling',
+ new_name='firmware_scheduled',
+ ),
+ migrations.AddField(
+ model_name='deploymentworkflow',
+ name='wr_scheduled',
+ field=models.BooleanField(blank=True, default=False, null=True),
+ ),
+ migrations.AlterField(
+ model_name='summary',
+ name='created_at',
+ field=models.DateTimeField(blank=True, null=True),
+ ),
+ migrations.AlterField(
+ model_name='summary',
+ name='failed',
+ field=models.PositiveIntegerField(default=0, null=True),
+ ),
+ ]
diff --git a/src/automationstatus/migrations/0008_auto_20201030_1654.py b/src/automationstatus/migrations/0008_auto_20201030_1654.py
new file mode 100644
index 0000000..d775f5d
--- /dev/null
+++ b/src/automationstatus/migrations/0008_auto_20201030_1654.py
@@ -0,0 +1,48 @@
+# Generated by Django 3.1.1 on 2020-10-30 16:54
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('automationstatus', '0007_auto_20201026_0129'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='summary',
+ name='bmc',
+ field=models.PositiveIntegerField(default=0, null=True),
+ ),
+ migrations.AddField(
+ model_name='summary',
+ name='firmware_scheduled',
+ field=models.PositiveIntegerField(default=0, null=True),
+ ),
+ migrations.AddField(
+ model_name='summary',
+ name='firmware_upgraded',
+ field=models.PositiveIntegerField(default=0, null=True),
+ ),
+ migrations.AddField(
+ model_name='summary',
+ name='ingested',
+ field=models.PositiveIntegerField(default=0, null=True),
+ ),
+ migrations.AddField(
+ model_name='summary',
+ name='online',
+ field=models.PositiveIntegerField(default=0, null=True),
+ ),
+ migrations.AddField(
+ model_name='summary',
+ name='wr_installed',
+ field=models.PositiveIntegerField(default=0, null=True),
+ ),
+ migrations.AddField(
+ model_name='summary',
+ name='wr_scheduled',
+ field=models.PositiveIntegerField(default=0, null=True),
+ ),
+ ]
diff --git a/src/automationstatus/migrations/0009_orchestrationworkflow.py b/src/automationstatus/migrations/0009_orchestrationworkflow.py
new file mode 100644
index 0000000..78aa2b4
--- /dev/null
+++ b/src/automationstatus/migrations/0009_orchestrationworkflow.py
@@ -0,0 +1,28 @@
+# Generated by Django 3.1.2 on 2020-12-09 19:58
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('automationstatus', '0008_auto_20201030_1654'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='OrchestrationWorkflow',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('namespaces', models.PositiveIntegerField()),
+ ('orch_service_account', models.PositiveIntegerField()),
+ ('edge_eng_service_account', models.PositiveIntegerField()),
+ ('samsung_service_account', models.PositiveIntegerField()),
+ ('orch_kubeconfig', models.PositiveIntegerField()),
+ ('edge_eng_kubeconfig', models.PositiveIntegerField()),
+ ('samsung_kubeconfig', models.PositiveIntegerField()),
+ ('data_network_setup', models.PositiveIntegerField()),
+ ('created_at', models.DateTimeField(blank=True, null=True)),
+ ],
+ ),
+ ]
diff --git a/src/automationstatus/migrations/__init__.py b/src/automationstatus/migrations/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/automationstatus/migrations/__init__.py
diff --git a/src/automationstatus/models.py b/src/automationstatus/models.py
new file mode 100644
index 0000000..9e249c6
--- /dev/null
+++ b/src/automationstatus/models.py
@@ -0,0 +1,67 @@
+from django.db import models
+from caas.models import Cluster
+
+class AutomationStatus(models.Model):
+ playbook_name = models.CharField(max_length=255, blank=True, null=False)
+ status = models.CharField(max_length=50, blank=True, null=False)
+ ilo_host_address = models.CharField(max_length=255, blank=True, null=False)
+ cluster_name = models.CharField(max_length=255, blank=True, null=False)
+ fuze_spm_site_name = models.CharField(max_length=255, blank=True, null=False)
+ fuze_spm_site_id = models.CharField(max_length=255, blank=True, null=False)
+ created_at = models.DateTimeField(auto_now_add=True)
+
+ def __str__(self):
+ str = "pk: %s, playbook_name: %s, status: %s, cluster_name: %s, cluster_name: %s, fuze_spm_site_name: %s, fuze_spm_site_id: %s"
+ return str % (self.pk, self.playbook_name, self.status, self.cluster_name, self.fuze_spm_site_name, self.fuze_spm_site_id, self.created_at)
+
+
+class Summary(models.Model):
+ clusters = models.PositiveIntegerField(null=False)
+ in_progress = models.PositiveIntegerField(null=False)
+ completed = models.PositiveIntegerField(null=False)
+ ingested = models.PositiveIntegerField(default=0, null=True)
+ online = models.PositiveIntegerField(default=0, null=True)
+ bmc = models.PositiveIntegerField(default=0, null=True)
+ firmware_scheduled = models.PositiveIntegerField(default=0, null=True)
+ firmware_upgraded = models.PositiveIntegerField(default=0, null=True)
+ wr_scheduled = models.PositiveIntegerField(default=0, null=True)
+ wr_installed = models.PositiveIntegerField(default=0, null=True)
+ failed = models.PositiveIntegerField(default=0, null=True)
+ created_at = models.DateTimeField(blank=True, null=True)
+
+ def __str__(self):
+ str = "pk: %s, clusters: %s, in_progress: %s, completed: %s, failed: %s, created_at: %s"
+ return str % (self.pk, self.clusters, self.in_progress, self.completed, self.failed, self.created_at)
+
+
+class DeploymentWorkflow(models.Model):
+ cluster = models.OneToOneField("caas.Cluster", on_delete=models.CASCADE, primary_key=True)
+ ingested = models.BooleanField(blank=True, default=False, null=True)
+ online = models.BooleanField(blank=True, default=False, null=True)
+ bmc = models.BooleanField(blank=True, default=False, null=True)
+ firmware_scheduled = models.BooleanField(blank=True, default=False, null=True)
+ firmware_upgraded = models.BooleanField(blank=True, default=False, null=True)
+ wr_scheduled = models.BooleanField(blank=True, default=False, null=True)
+ wr_installed = models.BooleanField(blank=True, default=False, null=True)
+ created_at = models.DateTimeField(blank=True, null=True)
+
+ def __str__(self):
+ str = "pk: %s, cluster: %s, ingested: %s, online: %s, bmc: %s, firmware_upgraded: %s, wr_installed: %s, created_at: %s"
+ return str % (self.pk, self.cluster, self.ingested, self.online, self.bmc, self.firmware_upgraded, self.wr_installed, self.created_at)
+
+
+class OrchestrationWorkflow(models.Model):
+ # cluster = models.OneToOneField("caas.Cluster", on_delete=models.CASCADE, primary_key=True)
+ namespaces = models.PositiveIntegerField(null=False)
+ orch_service_account = models.PositiveIntegerField(null=False)
+ edge_eng_service_account = models.PositiveIntegerField(null=False)
+ samsung_service_account = models.PositiveIntegerField(null=False)
+ orch_kubeconfig = models.PositiveIntegerField(null=False)
+ edge_eng_kubeconfig = models.PositiveIntegerField(null=False)
+ samsung_kubeconfig= models.PositiveIntegerField(null=False)
+ data_network_setup = models.PositiveIntegerField(null=False) # Update once Dev completes tracking
+ created_at = models.DateTimeField(blank=True, null=True)
+
+ def __str__(self):
+ str = "pk: %s, namespaces: %s, created_at: %s"
+ return str % (self.pk, self.namespaces, self.created_at) \ No newline at end of file
diff --git a/src/automationstatus/serializers.py b/src/automationstatus/serializers.py
new file mode 100644
index 0000000..0afdf8c
--- /dev/null
+++ b/src/automationstatus/serializers.py
@@ -0,0 +1,9 @@
+from rest_framework import serializers
+
+from .models import AutomationStatus
+
+class AutomationStatusSerializer(serializers.HyperlinkedModelSerializer):
+ class Meta:
+ model = AutomationStatus
+ fields = ('pk', 'ilo_host_address', 'playbook_name', 'status', 'cluster_name', 'fuze_spm_site_name', 'fuze_spm_site_id', 'created_at')
+
diff --git a/src/automationstatus/tests.py b/src/automationstatus/tests.py
new file mode 100644
index 0000000..7ce503c
--- /dev/null
+++ b/src/automationstatus/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/src/automationstatus/urls.py b/src/automationstatus/urls.py
new file mode 100644
index 0000000..5976610
--- /dev/null
+++ b/src/automationstatus/urls.py
@@ -0,0 +1,14 @@
+from django.urls import include, path
+from rest_framework import routers
+from . import views
+
+router = routers.DefaultRouter()
+router.register(r'playbook', views.AutomationStatusViewSet)
+router.register(r'playbook/(?P<playbook_name>\d+)', views.AutomationStatusViewSet)
+
+# Wire up our API using automatic URL routing.
+# Additionally, we include login URLs for the browsable API.
+urlpatterns = [
+ path('', include(router.urls)),
+ path('', include('rest_framework.urls', namespace='rest_framework'))
+] \ No newline at end of file
diff --git a/src/automationstatus/views.py b/src/automationstatus/views.py
new file mode 100644
index 0000000..df75868
--- /dev/null
+++ b/src/automationstatus/views.py
@@ -0,0 +1,19 @@
+from rest_framework import viewsets
+from caas.models import Cluster, Location, Server
+from .models import AutomationStatus
+from .serializers import AutomationStatusSerializer
+
+class AutomationStatusViewSet(viewsets.ModelViewSet):
+ queryset = AutomationStatus.objects.all().order_by('created_at')
+ serializer_class = AutomationStatusSerializer
+
+ def perform_create(self, serializer):
+ # Lookup cluster name based on the ilo_host_address
+ server = Server.objects.get(ilo_host_address=self.request.data['ilo_host_address'])
+ cluster = Cluster.objects.get(id=server.cluster_id)
+ fuze_id = cluster.location_id
+ location = Location.objects.get(id=fuze_id)
+ serializer.save(
+ cluster_name=cluster.cluster_name,
+ fuze_spm_site_name=location.fuze_spm_site_name,
+ fuze_spm_site_id=location.fuze_spm_site_id)