Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions docker/orthos/devel-server.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,21 @@ server_start() {
git switch "$OLD_BRANCH"
git stash pop
python3.11 manage.py migrate
# Load test machine fixtures for development
python3.11 manage.py loaddata orthos2/data/fixtures/tests/test_domain_orthos2test.json || true
python3.11 manage.py loaddata orthos2/data/fixtures/tests/test_machine_docker.json || true
DJANGO_SUPERUSER_PASSWORD="$ORTHOS2_SUPERUSER_PASSWORD" python3.11 manage.py createsuperuser --noinput --username admin --email admin@example.com
# Load test machine fixtures for development. Both fixtures use fixed
# keys/fqdns that collide with a previous run's data on the persistent dev
# DB, so skip loading them again if that data is already there.
python3.11 manage.py shell -c "
from orthos2.data.models import ServerConfig
exit(0 if ServerConfig.objects.filter(key='domain.validendings').exists() else 1)
" || python3.11 manage.py loaddata orthos2/data/fixtures/tests/test_domain_orthos2test.json
python3.11 manage.py shell -c "
from orthos2.data.models import Machine
exit(0 if Machine.objects.filter(fqdn='testmachine.orthos2.test').exists() else 1)
" || python3.11 manage.py loaddata orthos2/data/fixtures/tests/test_machine_docker.json
python3.11 manage.py shell -c "
from django.contrib.auth.models import User
exit(0 if User.objects.filter(username='admin').exists() else 1)
" || DJANGO_SUPERUSER_PASSWORD="$ORTHOS2_SUPERUSER_PASSWORD" python3.11 manage.py createsuperuser --noinput --username admin --email admin@example.com
python3.11 manage.py shell </code/docker/orthos/django-generate-admin-token
python3.11 manage.py runserver 0.0.0.0:8000
}
Expand Down
2 changes: 1 addition & 1 deletion docker/orthos/django-generate-admin-token
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ import pathlib
from django.contrib.auth.models import User
from rest_framework.authtoken.models import Token

token = Token.objects.create(user=User.objects.get(username="admin"))
token, _created = Token.objects.get_or_create(user=User.objects.get(username="admin"))
pathlib.Path("/var/lib/orthos2/admin-token").write_text(token.key)
9 changes: 9 additions & 0 deletions docker/orthos/setup_netbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,15 @@ def main():
token=settings.NETBOX_TOKEN,
)

# This script is re-run on every dev container restart against a persistent
# NetBox instance. Everything it creates is anchored to "orthos2-site", so
# its presence means a previous run already completed - skip re-running the
# ~50 POST calls below, which would otherwise fail with HTTP 400 (already
# exists) for most objects and silently no-op (return {}) for the rest.
if netbox.check_site("orthos2-site"):
print("NetBox dev fixtures already provisioned - skipping setup_netbox.py.")
return

# Create Custom Field Choice Set
try:
netbox.post_custom_field_choice_sets(
Expand Down
3 changes: 3 additions & 0 deletions mypy.ini
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,6 @@ django_settings_module = "orthos2.settings"
[mypy-ansible.*]
# See: https://github.com/ansible/ansible/issues/69424
ignore_missing_imports = True

[mypy-social_django.*]
ignore_missing_imports = True
1 change: 0 additions & 1 deletion orthos2/api/admin.py

This file was deleted.

1 change: 0 additions & 1 deletion orthos2/data/admin.py

This file was deleted.

12 changes: 12 additions & 0 deletions orthos2/frontend/forms/group.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
"""
This module contains the form used to create/edit a Group.
"""

from django import forms
from django.contrib.auth.models import Group


class GroupForm(forms.ModelForm): # type: ignore
class Meta: # type: ignore
model = Group
fields = ["name", "permissions"]
21 changes: 21 additions & 0 deletions orthos2/frontend/forms/useradmin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"""
This module contains the form used by superusers to create/edit any User account.
"""

from django import forms
from django.contrib.auth.models import User


class UserAdminForm(forms.ModelForm): # type: ignore
class Meta: # type: ignore
model = User
fields = [
"username",
"email",
"first_name",
"last_name",
"is_active",
"is_staff",
"is_superuser",
"groups",
]
67 changes: 67 additions & 0 deletions orthos2/frontend/templates/frontend/groups/detail/overview.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
{% extends 'frontend/base.html' %}
{% load static %}

{% block navbar %}
{% include 'frontend/snippet.navlinks.html' %}
{% endblock %}

{% block content %}
<div class="container-fluid">
<div class="row">
<div class="col-8">
<div class="title">
<h5>{{ group.name }}</h5>
</div>

<table class="table table-striped table-bordered small">
<thead class="thead-default">
<tr>
<th>Permissions</th>
</tr>
</thead>
<tbody>
{% for permission in group.permissions.all %}
<tr>
<td>{{ permission.content_type }} | {{ permission.name }}</td>
</tr>
{% empty %}
<tr>
<td class="text-muted">No permissions assigned</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>

<div class="col-2">
<div class="title">
<h5>Actions</h5>
</div>
<div class="btn-group-vertical d-flex">
<a
class="btn btn-warning btn-sm"
href="{% url 'frontend:edit_group' group.pk %}"
role="button"
>Edit Group</a
>
</div>
<br />
<div class="btn-group-vertical d-flex">
<a
class="btn btn-danger btn-sm"
href="{% url 'frontend:delete_group' group.pk %}"
role="button"
>Delete Group</a
>
</div>
</div>
</div>

<span style="font-size: 0.7em; font-family: Monospace;"
>Edit:
<a href="{% url 'frontend:edit_group' group.id %}"
>{% url 'frontend:edit_group' group.id %}</a
></span
>
</div>
{% endblock %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{% extends 'frontend/base.html' %}
{% load static %}

{% block navbar %}
{% include 'frontend/snippet.navlinks.html' %}
{% endblock %}

{% block content %}
<div class="container-fluid">
<form method="post">
{% csrf_token %}
<p>Are you sure you want to delete group "{{ object.name }}"?</p>
<input
class="btn btn-danger btn-sm"
type="submit"
value="Confirm deletion"
/>
</form>
</div>
{% endblock %}
62 changes: 62 additions & 0 deletions orthos2/frontend/templates/frontend/groups/groups.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{% extends 'frontend/base.html' %}
{% load static %}
{% load tags %}

{% block navbar %}
{% include 'frontend/snippet.navlinks.html' %}
{% endblock %}

{% block content %}
<div class="container-fluid" style="margin-bottom: 15px;">
<div class="row">
<div class="col-12 d-flex align-items-center">
<span class="hint">Found {{ paginator.count }} Group(s)</span>
<a class="nav-link ms-auto" href="{% url 'frontend:new_group' %}">
<button type="button" class="btn btn-success">+</button>
</a>
</div>
</div>
</div>
{% include 'frontend/snippet.paginator.html' %}

<div class="container-fluid">
{% if page_obj %}
<table class="table table-striped table-bordered table-fixed">
<thead class="thead-default">
<tr style="border: 1px solid #ddd;">
<th>Name</th>
<th>Permissions</th>
<th width="80px">&nbsp;</th>
</tr>
</thead>

<tbody>
{% for group in page_obj %}
<tr>
<td>
<a
href="{% url 'frontend:group_detail' group.pk %}"
class="text-muted"
>{{ group.name }}</a
>
</td>
<td>{{ group.permissions.count }}</td>
<td>
<a
href="{% url 'frontend:delete_group' group.pk %}"
class="btn btn-danger btn-sm"
>
Delete
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>

{% include 'frontend/snippet.paginator.html' %}
{% else %}
<div class="alert alert-info">No groups found!</div>
{% endif %}
</div>
{% endblock %}
43 changes: 43 additions & 0 deletions orthos2/frontend/templates/frontend/groups/new_group.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{% extends 'frontend/base.html' %}
{% load static %}

{% block navbar %}
{% include 'frontend/snippet.navlinks.html' %}
{% endblock %}

{% block content %}
<div class="container-fluid">
<div class="mb-3">
<form
class="pt-3"
method="post"
{% if action == 'new' %}
action="{% url 'frontend:new_group' %}"
{% elif action == 'edit' %}
action="{% url 'frontend:edit_group' object.id %}"
{% endif %}
>
{% csrf_token %}

{{ form.non_field_errors }}

{% for field in form %}
{{ field.errors }}
<div class="row" style="margin: 5px;">
<div class="col-3">
<label for="{{ field.id_for_label }}">{{ field.label }}:</label>
</div>
<div class="col-9">
{{ field }}
<small class="form-text text-muted">{{ field.help_text }}</small>
</div>
</div>
{% endfor %}

<button type="submit" class="btn btn-secondary btn-sm w-100">
Submit
</button>
</form>
</div>
</div>
{% endblock %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
{% extends 'frontend/base.html' %}
{% load static %}

{% block navbar %}
{% include 'frontend/snippet.navlinks.html' %}
{% endblock %}

{% block content %}
<div class="container-fluid">
<div class="title">
<h5>Associations</h5>
</div>
<table class="table table-striped table-bordered table-fixed small">
<thead class="thead-default">
<tr>
<th>Server URL</th>
<th>Handle</th>
<th>Assoc Type</th>
<th>Issued</th>
<th>Lifetime</th>
</tr>
</thead>
<tbody>
{% for association in associations %}
<tr>
<td>{{ association.server_url }}</td>
<td>{{ association.handle }}</td>
<td>{{ association.assoc_type }}</td>
<td>{{ association.issued }}</td>
<td>{{ association.lifetime }}</td>
</tr>
{% empty %}
<tr>
<td class="text-muted" colspan="5">No associations found.</td>
</tr>
{% endfor %}
</tbody>
</table>

<div class="title">
<h5>Nonces</h5>
</div>
<table class="table table-striped table-bordered table-fixed small">
<thead class="thead-default">
<tr>
<th>Server URL</th>
<th>Timestamp</th>
<th>Salt</th>
</tr>
</thead>
<tbody>
{% for nonce in nonces %}
<tr>
<td>{{ nonce.server_url }}</td>
<td>{{ nonce.timestamp }}</td>
<td>{{ nonce.salt }}</td>
</tr>
{% empty %}
<tr>
<td class="text-muted" colspan="3">No nonces found.</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}
Loading