Fixes and improvements
This commit is contained in:
parent
9545b0ec1f
commit
4d2e3174db
8 changed files with 66 additions and 18 deletions
12
client.sh
Executable file
12
client.sh
Executable file
|
@ -0,0 +1,12 @@
|
|||
SECRET="SECRET"
|
||||
|
||||
sleep 10
|
||||
|
||||
wget -O- https://admin360.kumi.host/hosts --post-data "secret=$SECRET"
|
||||
|
||||
while [ True ]; do
|
||||
IP=$(ifconfig br0 | awk '/inet /{print substr($2,1)}');
|
||||
sleep 60;
|
||||
wget -O- https://admin360.kumi.host/heartbeat --post-data "secret=$SECRET&ip=$IP";
|
||||
done
|
||||
|
|
@ -6,15 +6,15 @@ def getRandom():
|
|||
return str(uuid.uuid4().hex)
|
||||
|
||||
class Organization(models.Model):
|
||||
name = models.CharField(max_length=300)
|
||||
name = models.CharField("Organization Name", max_length=300)
|
||||
users = models.ManyToManyField(settings.AUTH_USER_MODEL)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class Network(models.Model):
|
||||
extip = models.CharField(max_length=15)
|
||||
intip = models.CharField(max_length=15)
|
||||
extip = models.CharField("External/Public IP", max_length=15)
|
||||
intip = models.CharField("Internal/Private IP", max_length=15)
|
||||
organizations = models.ManyToManyField(Organization)
|
||||
|
||||
def __str__(self):
|
||||
|
|
|
@ -60,6 +60,12 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
<div class="container">
|
||||
<span class="text-muted">© <a style="color: rgb(108, 117, 125);" href="https://kumi.systems/">Kumi Systems e.U.</a></span>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
</div>
|
||||
<div class="form-group">
|
||||
<label for="name">Device Name</label>
|
||||
<input type="text" class="form-control" name="name" id="name" placeholder="Enter Device Name (Optional)"></input>
|
||||
<input type="text" class="form-control" name="name" id="name" placeholder="Enter Device Name (Optional)" value="{{ device.name }}"></input>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="subnet">Assigned Network</label>
|
||||
|
@ -19,8 +19,10 @@
|
|||
<option {% if choice.intip == device.network.intip %} selected {% endif %} value="{{ choice.intip }}">{{ choice.intip}} ({{ choice.extip }})</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<small id="subnetHelp" class="form-text text-muted">A network change will require a (manual) reboot of the device to be applied.</small>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Apply Changes</button>
|
||||
<button type="submit" class="btn btn-success">Apply Changes</button>
|
||||
<a class="btn btn-danger" href="/" role="button">Cancel</a>
|
||||
</form>
|
||||
|
||||
{% endblock %}
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
<td>{{ device.network }}</td>
|
||||
<td>{% if device.curip %}{{ device.curip }} (at {{ device.lasttime }}){% endif %}</td>
|
||||
<td>{{ device.secret }}</td>
|
||||
<td><a href="/devices/{{ device.id }}"><i class="fas fa-edit"></i></a></td>
|
||||
<td><a href="/devices/{{ device.id }}/edit"><i class="fas fa-edit"></i></a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
|
|
|
@ -4,8 +4,9 @@ from . import views
|
|||
|
||||
urlpatterns = [
|
||||
path('', views.index, name='index'),
|
||||
path('devices', views.devices, name='devices'),
|
||||
path('devices/', views.devices, name='devices'),
|
||||
path('hosts', views.hosts, name='hosts'),
|
||||
path('devices/<int:device_id>', views.editdevice, name='editdevice'),
|
||||
path('devices/<int:device_id>/edit/', views.editdevice, name='editdevice'),
|
||||
path('devices/<int:device_id>/ping/', views.ping, name="ping"),
|
||||
path('heartbeat', views.heartbeat, name='heartbeat')
|
||||
]
|
||||
|
|
|
@ -6,6 +6,9 @@ from django.views.decorators.csrf import csrf_exempt
|
|||
from django.utils import timezone
|
||||
from .models import Device, Organization, Network
|
||||
|
||||
import os
|
||||
import socket
|
||||
|
||||
def index(request):
|
||||
if request.user.is_authenticated:
|
||||
return redirect("/devices")
|
||||
|
@ -20,20 +23,48 @@ def heartbeat(request):
|
|||
device.save()
|
||||
return HttpResponse("")
|
||||
|
||||
@csrf_exempt
|
||||
def hosts(request):
|
||||
device = get_object_or_404(Device, secret=request.POST.get("secret", ""))
|
||||
return render(request, "manager/hosts", {"device": device})
|
||||
|
||||
def ping(request, device_id):
|
||||
if request.user.is_authenticated:
|
||||
device = None
|
||||
for organization in Organization.objects.filter(users=request.user):
|
||||
device = device or Device.objects.filter(id=device_id, organization=organization)
|
||||
|
||||
if not device:
|
||||
return HttpResponse("-1")
|
||||
|
||||
try:
|
||||
socket.inet_aton(device[0].curip)
|
||||
return HttpResponse(str(int(not os.WEXITSTATUS(os.system("ping -c1 -w1 " + device[0].curip + " > /dev/null 2>&1"))))) # This monster is not long enough yet.
|
||||
|
||||
except:
|
||||
return HttpResponse("-3")
|
||||
|
||||
else:
|
||||
return HttpResponse("-2")
|
||||
|
||||
|
||||
|
||||
def devices(request):
|
||||
if request.user.is_authenticated:
|
||||
user = request.user
|
||||
organization = Organization.objects.filter(users__username=request.user.username)[0]
|
||||
devices = Device.objects.filter(organization=organization.id)
|
||||
devices = set()
|
||||
orga = None
|
||||
|
||||
for organization in Organization.objects.filter(users=user):
|
||||
orga = orga or organization
|
||||
for device in Device.objects.filter(organization=organization):
|
||||
devices.add(device)
|
||||
|
||||
return render(request, "manager/index.html",
|
||||
{
|
||||
"title": "Device Administration",
|
||||
"user": user,
|
||||
"organization": organization,
|
||||
"organization": orga,
|
||||
"devices": devices
|
||||
}
|
||||
)
|
||||
|
@ -44,9 +75,9 @@ def editdevice(request, device_id):
|
|||
if request.user.is_authenticated:
|
||||
device = None
|
||||
subnets = set()
|
||||
for organization in Organization.objects.filter(users__id=request.user.id):
|
||||
device = device or Device.objects.filter(id=device_id, organization=organization.id)
|
||||
for subnet in Network.objects.filter(organizations=organization.id):
|
||||
for organization in Organization.objects.filter(users=request.user):
|
||||
device = device or Device.objects.filter(id=device_id, organization=organization)
|
||||
for subnet in Network.objects.filter(organizations=organization):
|
||||
subnets.add(subnet)
|
||||
|
||||
if not device:
|
||||
|
|
|
@ -3,10 +3,6 @@ import os
|
|||
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
||||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
|
||||
# Quick-start development settings - unsuitable for production
|
||||
# See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/
|
||||
|
||||
# SECURITY WARNING: keep the secret key used in production secret!
|
||||
SECRET_KEY = '=go8&h#^kh6ksr11e2z-@4qqd6t%63$x#-!s#l_yhw@oyanrys'
|
||||
|
||||
|
|
Loading…
Reference in a new issue