diff --git a/NetworkMapper/ip/forms.py b/NetworkMapper/ip/forms.py
index 3c65759..9b1e2a1 100644
--- a/NetworkMapper/ip/forms.py
+++ b/NetworkMapper/ip/forms.py
@@ -1,6 +1,6 @@
from django import forms
-from .models import VLAN, WifiNetwork
+from .models import ClientDevice, VLAN, WifiNetwork
class VLANForm(forms.ModelForm):
class Meta:
@@ -12,3 +12,23 @@ class WifiForm(forms.ModelForm):
class Meta:
model = WifiNetwork
fields = ["ssid", "password"]
+
+
+class ClientDeviceForm(forms.ModelForm):
+
+ connection_type = forms.ChoiceField(choices=ClientDevice.CONNECTION_TYPES, widget=forms.Select(attrs={"class": "form-control"}))
+
+ class Meta:
+ model = ClientDevice
+ fields = ["name", "mac_address", "ip_address", "wifi", "vlan", "connection_type"]
+
+ def __init__(self, *args, vlan_options=None, wifi_options=None, **kwargs):
+ super(ClientDeviceForm, self).__init__(*args, **kwargs)
+
+ empty_choice = [("", "None")]
+
+ self.fields["vlan"].widget = forms.Select(choices=empty_choice + vlan_options, attrs={"class": "form-control"})
+ self.fields["vlan"].required = False
+
+ self.fields["wifi"].widget = forms.Select(choices=empty_choice + wifi_options, attrs={"class": "form-control"})
+ self.fields["wifi"].required = False
diff --git a/NetworkMapper/ip/migrations/0003_clientdevice.py b/NetworkMapper/ip/migrations/0003_clientdevice.py
new file mode 100644
index 0000000..b73c7b3
--- /dev/null
+++ b/NetworkMapper/ip/migrations/0003_clientdevice.py
@@ -0,0 +1,56 @@
+# Generated by Django 5.0.2 on 2024-02-27 21:51
+
+import django.db.models.deletion
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("ip", "0002_wifinetwork_remove_vlan_id_alter_vlan_vlan_id"),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name="ClientDevice",
+ fields=[
+ (
+ "id",
+ models.BigAutoField(
+ auto_created=True,
+ primary_key=True,
+ serialize=False,
+ verbose_name="ID",
+ ),
+ ),
+ ("name", models.CharField(max_length=100)),
+ ("mac_address", models.CharField(max_length=17, unique=True)),
+ (
+ "ip_address",
+ models.GenericIPAddressField(blank=True, null=True, unique=True),
+ ),
+ (
+ "connection_type",
+ models.CharField(
+ choices=[("ethernet", "Ethernet"), ("wifi", "WiFi")],
+ max_length=10,
+ ),
+ ),
+ (
+ "vlan",
+ models.ForeignKey(
+ on_delete=django.db.models.deletion.CASCADE, to="ip.vlan"
+ ),
+ ),
+ (
+ "wifi",
+ models.ForeignKey(
+ blank=True,
+ null=True,
+ on_delete=django.db.models.deletion.CASCADE,
+ to="ip.wifinetwork",
+ ),
+ ),
+ ],
+ ),
+ ]
diff --git a/NetworkMapper/ip/models/__init__.py b/NetworkMapper/ip/models/__init__.py
index 68d1217..bf01afd 100644
--- a/NetworkMapper/ip/models/__init__.py
+++ b/NetworkMapper/ip/models/__init__.py
@@ -1,2 +1,3 @@
+from .client_device import ClientDevice
from .vlan import VLAN
from .wifi import WifiNetwork
diff --git a/NetworkMapper/ip/models/client_device.py b/NetworkMapper/ip/models/client_device.py
new file mode 100644
index 0000000..6a3c845
--- /dev/null
+++ b/NetworkMapper/ip/models/client_device.py
@@ -0,0 +1,20 @@
+from django.db import models
+
+from .vlan import VLAN
+from .wifi import WifiNetwork
+
+class ClientDevice(models.Model):
+ CONNECTION_TYPES = (
+ ("ethernet", "Ethernet"),
+ ("wifi", "WiFi"),
+ )
+
+ name = models.CharField(max_length=100)
+ mac_address = models.CharField(max_length=17, unique=True)
+ ip_address = models.GenericIPAddressField(blank=True, null=True, unique=True)
+ vlan = models.ForeignKey(VLAN, on_delete=models.CASCADE)
+ wifi = models.ForeignKey(WifiNetwork, on_delete=models.CASCADE, blank=True, null=True)
+ connection_type = models.CharField(max_length=10, choices=CONNECTION_TYPES)
+
+ def __str__(self):
+ return self.name
diff --git a/NetworkMapper/ip/templates/ip/device/create.html b/NetworkMapper/ip/templates/ip/device/create.html
new file mode 100644
index 0000000..da56ffd
--- /dev/null
+++ b/NetworkMapper/ip/templates/ip/device/create.html
@@ -0,0 +1,21 @@
+
+
+
+
+
+ Create Device
+
+
+
+Create Device
+
+
+
+Back to Device List
+
+
+
diff --git a/NetworkMapper/ip/templates/ip/device/edit.html b/NetworkMapper/ip/templates/ip/device/edit.html
new file mode 100644
index 0000000..7429fc7
--- /dev/null
+++ b/NetworkMapper/ip/templates/ip/device/edit.html
@@ -0,0 +1,19 @@
+
+
+
+
+
+ Edit Device
+
+
+
+Edit Device - {{ device.name }}
+
+
+
+
+
diff --git a/NetworkMapper/ip/templates/ip/device/index.html b/NetworkMapper/ip/templates/ip/device/index.html
new file mode 100644
index 0000000..d9ff4f2
--- /dev/null
+++ b/NetworkMapper/ip/templates/ip/device/index.html
@@ -0,0 +1,46 @@
+
+
+
+
+
+ Device List
+
+
+
+Create Device
+
+Device List
+
+
+
+
+ Name |
+ MAC Address |
+ IP Address |
+ VLAN |
+ Wifi Network |
+ Connection |
+
+
+
+ {% for device in devices %}
+
+ {{ device.name }} |
+ {{ device.mac_address }} |
+ {{ device.ip_address }} |
+ {{ device.vlan }} |
+ {{ device.wifi.ssid }} |
+ {{ device.connection_type }} |
+
+ Edit
+ |
+
+ Delete
+ |
+
+ {% endfor %}
+
+
+
+
+
diff --git a/NetworkMapper/ip/urls.py b/NetworkMapper/ip/urls.py
index ba0fb2c..7b27b5b 100644
--- a/NetworkMapper/ip/urls.py
+++ b/NetworkMapper/ip/urls.py
@@ -11,4 +11,8 @@
path("wifi/create", views.wifi.create, name="wifi.create"),
path("wifi//edit", views.wifi.edit, name="wifi.edit"),
path("wifi//delete", views.wifi.delete, name="wifi.delete"),
+ path("device", views.device.index, name="device.index"),
+ path("device/create", views.device.create, name="device.create"),
+ path("device//edit", views.device.edit, name="device.edit"),
+ path("device//delete", views.device.delete, name="device.delete"),
]
diff --git a/NetworkMapper/ip/views/__init__.py b/NetworkMapper/ip/views/__init__.py
index 7efe8bd..59dea35 100644
--- a/NetworkMapper/ip/views/__init__.py
+++ b/NetworkMapper/ip/views/__init__.py
@@ -1 +1 @@
-from . import vlan, wifi
+from . import device, vlan, wifi
diff --git a/NetworkMapper/ip/views/device.py b/NetworkMapper/ip/views/device.py
new file mode 100644
index 0000000..bdcf3f3
--- /dev/null
+++ b/NetworkMapper/ip/views/device.py
@@ -0,0 +1,46 @@
+from django.shortcuts import get_object_or_404, redirect, render
+
+from ..forms import ClientDeviceForm
+from ..models import ClientDevice, VLAN, WifiNetwork
+
+def index(request):
+ devices = ClientDevice.objects.all()
+ return render(request, "ip/device/index.html", {"devices": devices})
+
+
+def create(request):
+ vlan_options = [(vlan.vlan_id, str(vlan)) for vlan in VLAN.objects.all()]
+ wifi_options = [(wifi.id, wifi.ssid) for wifi in WifiNetwork.objects.all()]
+
+ if request.method == "POST":
+ form = ClientDeviceForm(request.POST, vlan_options=vlan_options, wifi_options=wifi_options)
+ if form.is_valid():
+ form.save()
+ return redirect("device.index")
+ else:
+ form = ClientDeviceForm(vlan_options=vlan_options, wifi_options=wifi_options)
+
+ return render(request, "ip/device/create.html", {"form": form})
+
+
+def edit(request, id: int):
+ device = get_object_or_404(ClientDevice, id=id)
+
+ vlan_options = [(vlan.vlan_id, f"{vlan.vlan_id} - {vlan.name}") for vlan in VLAN.objects.all()]
+ wifi_options = [(wifi.id, wifi.ssid) for wifi in WifiNetwork.objects.all()]
+
+ if request.method == "POST":
+ form = ClientDeviceForm(request.POST, instance=device, vlan_options=vlan_options, wifi_options=wifi_options)
+ if form.is_valid():
+ form.save()
+ return redirect("device.index")
+ else:
+ form = ClientDeviceForm(instance=device, vlan_options=vlan_options, wifi_options=wifi_options)
+
+ return render(request, "ip/device/edit.html", {"form": form, "device": device})
+
+
+def delete(request, id: int):
+ device = get_object_or_404(ClientDevice, id=id)
+ device.delete()
+ return redirect("device.index")
diff --git a/NetworkMapper/ip/views/vlan.py b/NetworkMapper/ip/views/vlan.py
index c45182e..71084a5 100644
--- a/NetworkMapper/ip/views/vlan.py
+++ b/NetworkMapper/ip/views/vlan.py
@@ -13,7 +13,7 @@ def create(request):
form = VLANForm(request.POST)
if form.is_valid():
form.save()
- return redirect("vlan.index") # Redirect to the VLAN Index after successful creation
+ return redirect("vlan.index")
else:
form = VLANForm()
@@ -27,7 +27,7 @@ def edit(request, vlan_id: int):
form = VLANForm(request.POST, instance=vlan)
if form.is_valid():
form.save()
- return redirect("vlan.index") # Redirect to the VLAN Index after successful edit
+ return redirect("vlan.index")
else:
form = VLANForm(instance=vlan)
diff --git a/NetworkMapper/ip/views/wifi.py b/NetworkMapper/ip/views/wifi.py
index 648a611..89270c0 100644
--- a/NetworkMapper/ip/views/wifi.py
+++ b/NetworkMapper/ip/views/wifi.py
@@ -13,7 +13,7 @@ def create(request):
form = WifiForm(request.POST)
if form.is_valid():
form.save()
- return redirect("wifi.index") # Redirect to the VLAN Index after successful creation
+ return redirect("wifi.index")
else:
form = WifiForm()
@@ -27,7 +27,7 @@ def edit(request, id: int):
form = WifiForm(request.POST, instance=wifi)
if form.is_valid():
form.save()
- return redirect("wifi.index") # Redirect to the VLAN Index after successful edit
+ return redirect("wifi.index")
else:
form = WifiForm(instance=wifi)