up snapshots from command line
This commit is contained in:
parent
72f242ad88
commit
e2f9855954
|
@ -132,7 +132,7 @@
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link{% if path == 'admin_people_list' %} active2{% endif %}" href="{# url 'idhub:admin_people_list' #}">
|
<a class="nav-link{% if path == 'admin_people_list' %} active2{% endif %}" href="{% url 'snapshot:list' %}">
|
||||||
{% trans 'Old snapshots' %}
|
{% trans 'Old snapshots' %}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
# Generated by Django 5.0.6 on 2024-07-11 13:58
|
||||||
|
|
||||||
|
import django.db.models.deletion
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("device", "0003_remove_component_type_remove_computer_type_and_more"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name="device",
|
||||||
|
name="dhid_bk",
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name="device",
|
||||||
|
name="phid_bk",
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="computer",
|
||||||
|
name="erasure_server",
|
||||||
|
field=models.BooleanField(default=False),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="device",
|
||||||
|
name="reliable",
|
||||||
|
field=models.BooleanField(default=True),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="component",
|
||||||
|
name="computer",
|
||||||
|
field=models.ForeignKey(
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
to="device.computer",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="computer",
|
||||||
|
name="system_uuid",
|
||||||
|
field=models.UUIDField(blank=True, null=True),
|
||||||
|
),
|
||||||
|
]
|
|
@ -33,12 +33,11 @@ class Device(models.Model):
|
||||||
production_date = models.DateTimeField(blank=True, null=True)
|
production_date = models.DateTimeField(blank=True, null=True)
|
||||||
variant = models.CharField(max_length=STR_SIZE, blank=True, null=True)
|
variant = models.CharField(max_length=STR_SIZE, blank=True, null=True)
|
||||||
devicehub_id = models.CharField(max_length=STR_SIZE, unique=True, blank=True, null=True)
|
devicehub_id = models.CharField(max_length=STR_SIZE, unique=True, blank=True, null=True)
|
||||||
dhid_bk = models.CharField(max_length=STR_SIZE, blank=True, null=True)
|
|
||||||
phid_bk = models.CharField(max_length=STR_SIZE, blank=True, null=True)
|
|
||||||
family = models.CharField(max_length=STR_SIZE, blank=True, null=True)
|
family = models.CharField(max_length=STR_SIZE, blank=True, null=True)
|
||||||
hid = models.CharField(max_length=STR_SIZE, blank=True, null=True)
|
hid = models.CharField(max_length=STR_SIZE, blank=True, null=True)
|
||||||
chid = models.CharField(max_length=STR_SIZE, blank=True, null=True)
|
chid = models.CharField(max_length=STR_SIZE, blank=True, null=True)
|
||||||
active = models.BooleanField(default=True)
|
active = models.BooleanField(default=True)
|
||||||
|
reliable = models.BooleanField(default=True)
|
||||||
owner = models.ForeignKey(User, on_delete=models.CASCADE)
|
owner = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||||
|
|
||||||
def has_physical_properties(self):
|
def has_physical_properties(self):
|
||||||
|
@ -80,13 +79,14 @@ class Computer(models.Model):
|
||||||
max_length=STR_SM_SIZE,
|
max_length=STR_SM_SIZE,
|
||||||
choices=Chassis
|
choices=Chassis
|
||||||
)
|
)
|
||||||
system_uuid = models.UUIDField()
|
system_uuid = models.UUIDField(blank=True, null=True)
|
||||||
sku = models.CharField(max_length=STR_SM_SIZE, blank=True, null=True)
|
sku = models.CharField(max_length=STR_SM_SIZE, blank=True, null=True)
|
||||||
|
erasure_server = models.BooleanField(default=False)
|
||||||
|
|
||||||
|
|
||||||
class Component(models.Model):
|
class Component(models.Model):
|
||||||
device = models.OneToOneField(Device, models.CASCADE, primary_key=True)
|
device = models.OneToOneField(Device, models.CASCADE, primary_key=True)
|
||||||
computer = models.OneToOneField(Computer, models.CASCADE, null=True)
|
computer = models.ForeignKey(Computer, on_delete=models.CASCADE, null=True)
|
||||||
|
|
||||||
|
|
||||||
class GraphicCard(models.Model):
|
class GraphicCard(models.Model):
|
||||||
|
|
|
@ -168,3 +168,5 @@ LOGGING = {
|
||||||
"level": "DEBUG",
|
"level": "DEBUG",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SNAPSHOT_PATH="/tmp/"
|
||||||
|
|
|
@ -21,6 +21,7 @@ urlpatterns = [
|
||||||
# path('api/', include('snapshot.urls')),
|
# path('api/', include('snapshot.urls')),
|
||||||
path("", include("login.urls")),
|
path("", include("login.urls")),
|
||||||
path("dashboard/", include("dashboard.urls")),
|
path("dashboard/", include("dashboard.urls")),
|
||||||
|
path("snapshot/", include("snapshot.urls")),
|
||||||
path("device/", include("device.urls")),
|
path("device/", include("device.urls")),
|
||||||
path("lot/", include("lot.urls")),
|
path("lot/", include("lot.urls")),
|
||||||
]
|
]
|
||||||
|
|
0
snapshot/management/__init__.py
Normal file
0
snapshot/management/__init__.py
Normal file
0
snapshot/management/commands/__init__.py
Normal file
0
snapshot/management/commands/__init__.py
Normal file
50
snapshot/management/commands/up_snapshots.py
Normal file
50
snapshot/management/commands/up_snapshots.py
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
|
||||||
|
import os
|
||||||
|
import json
|
||||||
|
|
||||||
|
from django.core.management.base import BaseCommand
|
||||||
|
from django.contrib.auth import get_user_model
|
||||||
|
from snapshot.parse import Build
|
||||||
|
|
||||||
|
|
||||||
|
User = get_user_model()
|
||||||
|
|
||||||
|
|
||||||
|
class Command(BaseCommand):
|
||||||
|
help = "Insert Snapshots"
|
||||||
|
snapshots = []
|
||||||
|
files = []
|
||||||
|
devices = []
|
||||||
|
|
||||||
|
def add_arguments(self, parser):
|
||||||
|
parser.add_argument('path', type=str, help='Path to snapshots')
|
||||||
|
parser.add_argument('email', type=str, help='Email of user')
|
||||||
|
|
||||||
|
|
||||||
|
def handle(self, *args, **kwargs):
|
||||||
|
path = kwargs['path']
|
||||||
|
email = kwargs['email']
|
||||||
|
self.user = User.objects.get(email=email)
|
||||||
|
|
||||||
|
if os.path.isfile(path):
|
||||||
|
self.open(path)
|
||||||
|
|
||||||
|
elif os.path.isdir(path):
|
||||||
|
self.read_directory(path)
|
||||||
|
|
||||||
|
self.parsing()
|
||||||
|
|
||||||
|
def read_directory(self, directory):
|
||||||
|
for filename in os.listdir(directory):
|
||||||
|
filepath = os.path.join(directory, filename)
|
||||||
|
if os.path.isfile(filepath):
|
||||||
|
self.open(filepath)
|
||||||
|
|
||||||
|
def open(self, filepath):
|
||||||
|
with open(filepath, 'r') as file:
|
||||||
|
content = json.loads(file.read())
|
||||||
|
self.snapshots.append(content)
|
||||||
|
|
||||||
|
def parsing(self):
|
||||||
|
for s in self.snapshots:
|
||||||
|
self.devices.append(Build(s, self.user))
|
18
snapshot/migrations/0002_alter_snapshot_uuid.py
Normal file
18
snapshot/migrations/0002_alter_snapshot_uuid.py
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 5.0.6 on 2024-07-11 14:16
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("snapshot", "0001_initial"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="snapshot",
|
||||||
|
name="uuid",
|
||||||
|
field=models.UUIDField(unique=True),
|
||||||
|
),
|
||||||
|
]
|
17
snapshot/migrations/0003_remove_snapshot_start_time.py
Normal file
17
snapshot/migrations/0003_remove_snapshot_start_time.py
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
# Generated by Django 5.0.6 on 2024-07-11 14:18
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("snapshot", "0002_alter_snapshot_uuid"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name="snapshot",
|
||||||
|
name="start_time",
|
||||||
|
),
|
||||||
|
]
|
|
@ -18,13 +18,12 @@ class Snapshot(models.Model):
|
||||||
|
|
||||||
created = models.DateTimeField(auto_now_add=True)
|
created = models.DateTimeField(auto_now_add=True)
|
||||||
software = models.CharField(max_length=STR_SM_SIZE, choices=SoftWare, default=SoftWare.WORKBENCH)
|
software = models.CharField(max_length=STR_SM_SIZE, choices=SoftWare, default=SoftWare.WORKBENCH)
|
||||||
uuid = models.UUIDField()
|
uuid = models.UUIDField(unique=True)
|
||||||
version = models.CharField(max_length=STR_SM_SIZE)
|
version = models.CharField(max_length=STR_SM_SIZE)
|
||||||
sid = models.CharField(max_length=STR_SM_SIZE)
|
sid = models.CharField(max_length=STR_SM_SIZE)
|
||||||
settings_version = models.CharField(max_length=STR_SM_SIZE)
|
settings_version = models.CharField(max_length=STR_SM_SIZE)
|
||||||
is_server_erase = models.BooleanField(default=False)
|
is_server_erase = models.BooleanField(default=False)
|
||||||
severity = models.SmallIntegerField(choices=Severity, default=Severity.Info)
|
severity = models.SmallIntegerField(choices=Severity, default=Severity.Info)
|
||||||
start_time = models.DateTimeField()
|
|
||||||
end_time = models.DateTimeField()
|
end_time = models.DateTimeField()
|
||||||
owner = models.ForeignKey(User, on_delete=models.CASCADE)
|
owner = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||||
computer = models.ForeignKey(Computer, on_delete=models.CASCADE)
|
computer = models.ForeignKey(Computer, on_delete=models.CASCADE)
|
||||||
|
|
|
@ -1,9 +1,119 @@
|
||||||
# from dmidecode import DMIParse
|
import os
|
||||||
|
import json
|
||||||
|
import shutil
|
||||||
|
import hashlib
|
||||||
|
|
||||||
|
from datetime import datetime
|
||||||
|
from django.conf import settings
|
||||||
|
from device.models import Device, Computer
|
||||||
|
from snapshot.models import Snapshot
|
||||||
|
|
||||||
|
|
||||||
class Parse:
|
HID = [
|
||||||
def __init__(self, snapshot_json):
|
"manufacturer",
|
||||||
|
"model",
|
||||||
|
"chassis",
|
||||||
|
"serialNumber",
|
||||||
|
"sku"
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class Build:
|
||||||
|
def __init__(self, snapshot_json, user):
|
||||||
self.json = snapshot_json
|
self.json = snapshot_json
|
||||||
|
self.user = user
|
||||||
|
self.hid = None
|
||||||
|
self.result = False
|
||||||
|
|
||||||
|
self.save_disk()
|
||||||
|
self.json_device = self.json["device"]
|
||||||
|
self.json_components = self.json["components"]
|
||||||
|
self.uuid = self.json["uuid"]
|
||||||
|
self.get_hid()
|
||||||
|
self.gen_computer()
|
||||||
|
self.gen_components()
|
||||||
|
self.gen_actions()
|
||||||
|
self.gen_snapshot()
|
||||||
|
|
||||||
|
self.result = True
|
||||||
|
self.move_json()
|
||||||
|
|
||||||
|
def save_disk(self):
|
||||||
|
snapshot_path = settings.SNAPSHOT_PATH
|
||||||
|
user = self.user.email
|
||||||
|
uuid = self.json.get("uuid", "")
|
||||||
|
now = datetime.now().strftime("%Y-%m-%d-%H-%M")
|
||||||
|
filename = f"{now}_{user}_{uuid}.json"
|
||||||
|
path_dir_base = os.path.join(snapshot_path, user)
|
||||||
|
path_upload = os.path.join(path_dir_base, 'upload')
|
||||||
|
path_name = os.path.join(path_upload, filename)
|
||||||
|
self.filename = path_name
|
||||||
|
self.path_dir_base = path_dir_base
|
||||||
|
|
||||||
|
if not os.path.isdir(path_dir_base):
|
||||||
|
os.system(f'mkdir -p {path_upload}')
|
||||||
|
|
||||||
|
with open(path_name, 'w') as file:
|
||||||
|
file.write(json.dumps(self.json))
|
||||||
|
|
||||||
|
def move_json(self):
|
||||||
|
if not self.result:
|
||||||
|
return
|
||||||
|
|
||||||
|
shutil.copy(self.filename, self.path_dir_base)
|
||||||
|
os.remove(self.filename)
|
||||||
|
|
||||||
|
def get_hid(self):
|
||||||
|
hid = ""
|
||||||
|
for f in HID:
|
||||||
|
hid += "-" + self.json_device[f]
|
||||||
|
self.hid = hid
|
||||||
|
|
||||||
|
def gen_computer(self):
|
||||||
|
self.device = Device.objects.filter(
|
||||||
|
hid=self.hid,
|
||||||
|
active=True,
|
||||||
|
reliable=True,
|
||||||
|
owner=self.user
|
||||||
|
).first()
|
||||||
|
|
||||||
|
if self.device:
|
||||||
|
return
|
||||||
|
|
||||||
|
chid = hashlib.sha3_256(self.hid.encode()).hexdigest()
|
||||||
|
self.device = Device.objects.create(
|
||||||
|
serial_number=self.json_device["serialNumber"],
|
||||||
|
manufacturer=self.json_device["manufacturer"],
|
||||||
|
version=self.json_device["version"],
|
||||||
|
model=self.json_device["model"],
|
||||||
|
type=self.json_device["type"],
|
||||||
|
hid=self.hid,
|
||||||
|
chid=chid,
|
||||||
|
owner=self.user
|
||||||
|
)
|
||||||
|
|
||||||
|
Computer.objects.create(
|
||||||
|
device=self.device,
|
||||||
|
sku=self.json_device["sku"],
|
||||||
|
chassis=self.json_device["chassis"]
|
||||||
|
)
|
||||||
|
|
||||||
|
def gen_snapshot(self):
|
||||||
|
self.snapshot = Snapshot.objects.create(
|
||||||
|
uuid = self.uuid,
|
||||||
|
version = self.json["version"],
|
||||||
|
computer = self.device.computer,
|
||||||
|
sid = self.json.get("sid", ""),
|
||||||
|
settings_version = self.json.get("settings_version", ""),
|
||||||
|
end_time = self.json.get("endTime"),
|
||||||
|
owner=self.user
|
||||||
|
)
|
||||||
|
|
||||||
|
def gen_components(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def gen_actions(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
# class ParseSnapshot:
|
# class ParseSnapshot:
|
||||||
|
|
40
snapshot/templates/snapshots.html
Normal file
40
snapshot/templates/snapshots.html
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<h3>{{ subtitle }}</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="dataTable-container">
|
||||||
|
<form method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col" data-sortable="">
|
||||||
|
<a class="dataTable-sorter" href="#">Title</a>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
{% for snap in snapshots %}
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<input type="checkbox" name="snapshots" value="{{ snap.id }}" />
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a href="{# url 'snapshot:details' snap.pk #}">{{ snap.uuid }} {{ snap.sid }} {{ snap.version }}</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a href="{% url 'device:details' snap.computer.device.pk %}">{{ snap.computer.device.manufacturer }} {{ snap.computer.device.model }}</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
|
@ -1,10 +1,18 @@
|
||||||
from django.urls import path, include
|
# from django.urls import path, include
|
||||||
from rest_framework.routers import DefaultRouter
|
# from rest_framework.routers import DefaultRouter
|
||||||
from snapshot.views import SnapshotViewSet
|
# from snapshot.views import SnapshotViewSet
|
||||||
|
|
||||||
router = DefaultRouter()
|
# router = DefaultRouter()
|
||||||
router.register(r'snapshots', SnapshotViewSet)
|
# router.register(r'snapshots', SnapshotViewSet)
|
||||||
|
|
||||||
|
# urlpatterns = [
|
||||||
|
# path('', include(router.urls)),
|
||||||
|
# ]
|
||||||
|
from django.urls import path
|
||||||
|
from snapshot import views
|
||||||
|
|
||||||
|
app_name = 'snapshot'
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('', include(router.urls)),
|
path("", views.ListSnapshotsView.as_view(), name="list"),
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
from django.views.generic.base import TemplateView
|
||||||
|
from dashboard.mixins import DashboardView
|
||||||
|
from snapshot.models import Snapshot
|
||||||
# from django.shortcuts import render
|
# from django.shortcuts import render
|
||||||
# from rest_framework import viewsets
|
# from rest_framework import viewsets
|
||||||
# from snapshot.models import Snapshot
|
|
||||||
# from snapshot.serializers import SnapshotSerializer
|
# from snapshot.serializers import SnapshotSerializer
|
||||||
|
|
||||||
|
|
||||||
|
@ -9,3 +12,16 @@
|
||||||
# serializer_class = SnapshotSerializer
|
# serializer_class = SnapshotSerializer
|
||||||
|
|
||||||
|
|
||||||
|
class ListSnapshotsView(DashboardView, TemplateView):
|
||||||
|
template_name = "snapshots.html"
|
||||||
|
section = "snapshots"
|
||||||
|
title = _("Snapshots")
|
||||||
|
breadcrumb = "Snapshots"
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
snapshots = Snapshot.objects.filter(owner=self.request.user)
|
||||||
|
context.update({
|
||||||
|
'snapshots': snapshots,
|
||||||
|
})
|
||||||
|
return context
|
||||||
|
|
Loading…
Reference in a new issue