netbox-authorized-keys 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- netbox_authorized_keys-1.0.0/PKG-INFO +6 -0
- netbox_authorized_keys-1.0.0/README.md +42 -0
- netbox_authorized_keys-1.0.0/netbox_authorized_keys/__init__.py +19 -0
- netbox_authorized_keys-1.0.0/netbox_authorized_keys/api/__init__.py +2 -0
- netbox_authorized_keys-1.0.0/netbox_authorized_keys/api/serializers.py +59 -0
- netbox_authorized_keys-1.0.0/netbox_authorized_keys/api/urls.py +14 -0
- netbox_authorized_keys-1.0.0/netbox_authorized_keys/api/views.py +27 -0
- netbox_authorized_keys-1.0.0/netbox_authorized_keys/filtersets/__init__.py +1 -0
- netbox_authorized_keys-1.0.0/netbox_authorized_keys/filtersets/authorizedkey.py +63 -0
- netbox_authorized_keys-1.0.0/netbox_authorized_keys/forms/__init__.py +1 -0
- netbox_authorized_keys-1.0.0/netbox_authorized_keys/forms/authorizedkey.py +79 -0
- netbox_authorized_keys-1.0.0/netbox_authorized_keys/migrations/0001_initial.py +160 -0
- netbox_authorized_keys-1.0.0/netbox_authorized_keys/migrations/0002_authorizedkey_full_name_and_more.py +33 -0
- netbox_authorized_keys-1.0.0/netbox_authorized_keys/migrations/__init__.py +0 -0
- netbox_authorized_keys-1.0.0/netbox_authorized_keys/models/__init__.py +1 -0
- netbox_authorized_keys-1.0.0/netbox_authorized_keys/models/authorizedkey.py +116 -0
- netbox_authorized_keys-1.0.0/netbox_authorized_keys/navigation.py +28 -0
- netbox_authorized_keys-1.0.0/netbox_authorized_keys/tables/__init__.py +1 -0
- netbox_authorized_keys-1.0.0/netbox_authorized_keys/tables/authorizedkey.py +50 -0
- netbox_authorized_keys-1.0.0/netbox_authorized_keys/template_content.py +58 -0
- netbox_authorized_keys-1.0.0/netbox_authorized_keys/urls.py +27 -0
- netbox_authorized_keys-1.0.0/netbox_authorized_keys/version.py +5 -0
- netbox_authorized_keys-1.0.0/netbox_authorized_keys/views/__init__.py +1 -0
- netbox_authorized_keys-1.0.0/netbox_authorized_keys/views/authorizedkey.py +62 -0
- netbox_authorized_keys-1.0.0/netbox_authorized_keys.egg-info/PKG-INFO +6 -0
- netbox_authorized_keys-1.0.0/netbox_authorized_keys.egg-info/SOURCES.txt +29 -0
- netbox_authorized_keys-1.0.0/netbox_authorized_keys.egg-info/dependency_links.txt +1 -0
- netbox_authorized_keys-1.0.0/netbox_authorized_keys.egg-info/not-zip-safe +1 -0
- netbox_authorized_keys-1.0.0/netbox_authorized_keys.egg-info/top_level.txt +1 -0
- netbox_authorized_keys-1.0.0/setup.cfg +4 -0
- netbox_authorized_keys-1.0.0/setup.py +44 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# NetBox Authorized Keys Plugin
|
|
2
|
+
|
|
3
|
+
NetBox Authorized Keys is a plugin for NetBox that allows you to store and manage SSH authorized keys.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Store SSH authorized keys
|
|
8
|
+
- Assign keys to devices or virtual machines
|
|
9
|
+
- Manage keys through the NetBox UI
|
|
10
|
+
- API support for managing keys
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
1. Clone the repository:
|
|
15
|
+
```sh
|
|
16
|
+
git clone https://github.com/yourusername/netbox_authorized_keys.git
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
2. Navigate to the project directory:
|
|
20
|
+
```sh
|
|
21
|
+
cd netbox_authorized_keys
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
3. Install the plugin:
|
|
25
|
+
```sh
|
|
26
|
+
pip install .
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
4. Add the plugin to your NetBox configuration:
|
|
30
|
+
```python
|
|
31
|
+
PLUGINS = ["netbox_authorized_keys"]
|
|
32
|
+
PLUGINS_CONFIG = {
|
|
33
|
+
"netbox_authorized_keys": {
|
|
34
|
+
# Add any plugin-specific configuration here
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
5. Run the migrations:
|
|
40
|
+
```sh
|
|
41
|
+
python manage.py migrate
|
|
42
|
+
```
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""Top-level package for NetBox cesnet_services Plugin."""
|
|
2
|
+
|
|
3
|
+
__author__ = """Jan Krupa"""
|
|
4
|
+
__email__ = "jan.krupa@cesnet.cz"
|
|
5
|
+
__version__ = "0.0.1"
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
from netbox.plugins import PluginConfig
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class NetBoxAuthorizeKeysConfig(PluginConfig):
|
|
12
|
+
name = "netbox_authorized_keys"
|
|
13
|
+
verbose_name = "NetBox Authorized key Plugin"
|
|
14
|
+
description = ""
|
|
15
|
+
version = __version__
|
|
16
|
+
base_url = "authorized-keys"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
config = NetBoxAuthorizeKeysConfig
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
from dcim.api.serializers_.devices import DeviceSerializer
|
|
2
|
+
from dcim.models import Device
|
|
3
|
+
from netbox.api.fields import SerializedPKRelatedField
|
|
4
|
+
from netbox.api.serializers import NetBoxModelSerializer
|
|
5
|
+
from rest_framework import serializers
|
|
6
|
+
from virtualization.api.serializers_.virtualmachines import VirtualMachineSerializer
|
|
7
|
+
from virtualization.models import VirtualMachine
|
|
8
|
+
|
|
9
|
+
from netbox_authorized_keys.models import AuthorizedKey, AuthorizedKeyDevice, AuthorizedKeyVirtualMachine
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class AuthorizedKeySerializer(NetBoxModelSerializer):
|
|
13
|
+
url = serializers.HyperlinkedIdentityField(view_name="plugins-api:netbox_authorized_keys-api:authorizedkey-detail")
|
|
14
|
+
devices = SerializedPKRelatedField(
|
|
15
|
+
queryset=Device.objects.all(), serializer=DeviceSerializer, nested=True, required=False, many=True
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
virtual_machines = SerializedPKRelatedField(
|
|
19
|
+
queryset=VirtualMachine.objects.all(),
|
|
20
|
+
serializer=VirtualMachineSerializer,
|
|
21
|
+
nested=True,
|
|
22
|
+
required=False,
|
|
23
|
+
many=True,
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
class Meta:
|
|
27
|
+
model = AuthorizedKey
|
|
28
|
+
fields = [
|
|
29
|
+
"id",
|
|
30
|
+
"display",
|
|
31
|
+
"url",
|
|
32
|
+
"public_key",
|
|
33
|
+
"username",
|
|
34
|
+
"full_name",
|
|
35
|
+
"description",
|
|
36
|
+
"comments",
|
|
37
|
+
"devices",
|
|
38
|
+
"virtual_machines",
|
|
39
|
+
"tags",
|
|
40
|
+
]
|
|
41
|
+
brief_fields = ("id", "url", "display")
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class AuthorizedKeyDeviceSerializer(NetBoxModelSerializer):
|
|
45
|
+
authorized_key = AuthorizedKeySerializer(nested=True)
|
|
46
|
+
device = DeviceSerializer(nested=True)
|
|
47
|
+
|
|
48
|
+
class Meta:
|
|
49
|
+
model = AuthorizedKeyDevice
|
|
50
|
+
fields = ["id", "authorized_key", "device"]
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class AuthorizedKeyVirtualMachineSerializer(NetBoxModelSerializer):
|
|
54
|
+
authorized_key = AuthorizedKeySerializer(nested=True)
|
|
55
|
+
virtual_machine = VirtualMachineSerializer(nested=True)
|
|
56
|
+
|
|
57
|
+
class Meta:
|
|
58
|
+
model = AuthorizedKeyVirtualMachine
|
|
59
|
+
fields = ["id", "authorized_key", "virtual_machine"]
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from rest_framework.routers import DefaultRouter
|
|
2
|
+
|
|
3
|
+
from netbox_authorized_keys.api.views import (
|
|
4
|
+
AuthorizedKeyDeviceViewSet,
|
|
5
|
+
AuthorizedKeyViewSet,
|
|
6
|
+
AuthorizedKeyVirtualMachineViewSet,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
router = DefaultRouter()
|
|
10
|
+
router.register(r"authorized-keys", AuthorizedKeyViewSet)
|
|
11
|
+
router.register(r"devices", AuthorizedKeyDeviceViewSet)
|
|
12
|
+
router.register(r"virtual-machines", AuthorizedKeyVirtualMachineViewSet)
|
|
13
|
+
|
|
14
|
+
urlpatterns = router.urls
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from netbox.api.viewsets import NetBoxModelViewSet
|
|
2
|
+
|
|
3
|
+
from netbox_authorized_keys.api.serializers import (
|
|
4
|
+
AuthorizedKeyDeviceSerializer,
|
|
5
|
+
AuthorizedKeySerializer,
|
|
6
|
+
AuthorizedKeyVirtualMachineSerializer,
|
|
7
|
+
)
|
|
8
|
+
from netbox_authorized_keys.models import AuthorizedKey, AuthorizedKeyDevice, AuthorizedKeyVirtualMachine
|
|
9
|
+
from netbox_authorized_keys.filtersets import AuthorizedKeyFilterSet, AuthorizedKeyDeviceFilterSet, AuthorizedKeyVirtualMachineFilterSet
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class AuthorizedKeyViewSet(NetBoxModelViewSet):
|
|
13
|
+
queryset = AuthorizedKey.objects.all()
|
|
14
|
+
serializer_class = AuthorizedKeySerializer
|
|
15
|
+
filterset_class = AuthorizedKeyFilterSet
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class AuthorizedKeyDeviceViewSet(NetBoxModelViewSet):
|
|
19
|
+
queryset = AuthorizedKeyDevice.objects.all()
|
|
20
|
+
serializer_class = AuthorizedKeyDeviceSerializer
|
|
21
|
+
filterset_class = AuthorizedKeyDeviceFilterSet
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class AuthorizedKeyVirtualMachineViewSet(NetBoxModelViewSet):
|
|
25
|
+
queryset = AuthorizedKeyVirtualMachine.objects.all()
|
|
26
|
+
serializer_class = AuthorizedKeyVirtualMachineSerializer
|
|
27
|
+
filterset_class = AuthorizedKeyVirtualMachineFilterSet
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .authorizedkey import *
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import django_filters
|
|
2
|
+
from dcim.models import Device
|
|
3
|
+
from django.db.models import Q
|
|
4
|
+
from extras.filters import TagFilter
|
|
5
|
+
from netbox.filtersets import BaseFilterSet, NetBoxModelFilterSet
|
|
6
|
+
from virtualization.models import VirtualMachine
|
|
7
|
+
|
|
8
|
+
from netbox_authorized_keys.models import AuthorizedKey, AuthorizedKeyDevice, AuthorizedKeyVirtualMachine
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class AuthorizedKeyFilterSet(NetBoxModelFilterSet):
|
|
12
|
+
q = django_filters.CharFilter(method="search", label="Search")
|
|
13
|
+
public_key = django_filters.CharFilter()
|
|
14
|
+
username = django_filters.CharFilter()
|
|
15
|
+
full_name = django_filters.CharFilter()
|
|
16
|
+
description = django_filters.CharFilter()
|
|
17
|
+
tag = TagFilter()
|
|
18
|
+
|
|
19
|
+
devices = django_filters.ModelMultipleChoiceFilter(
|
|
20
|
+
field_name="devices", queryset=Device.objects.all(), label="Devices"
|
|
21
|
+
)
|
|
22
|
+
virtual_machines = django_filters.ModelMultipleChoiceFilter(
|
|
23
|
+
field_name="virtual_machines", queryset=VirtualMachine.objects.all(), label="Virtual Machines"
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
class Meta:
|
|
27
|
+
model = AuthorizedKey
|
|
28
|
+
fields = ["id", "public_key", "username", "full_name", "description", "comments", "devices", "virtual_machines"]
|
|
29
|
+
|
|
30
|
+
def search(self, queryset, name, value):
|
|
31
|
+
if not value.strip():
|
|
32
|
+
return queryset
|
|
33
|
+
|
|
34
|
+
filters = Q(username__icontains=value) | Q(full_name__icontains=value) | Q(description__icontains=value) | Q(comments__icontains=value)
|
|
35
|
+
return queryset.filter(filters)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class AuthorizedKeyDeviceFilterSet(BaseFilterSet):
|
|
39
|
+
authorized_key = django_filters.ModelMultipleChoiceFilter(
|
|
40
|
+
field_name="authorized_key", queryset=AuthorizedKey.objects.all(), label="Authorized Key"
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
device = django_filters.ModelMultipleChoiceFilter(
|
|
44
|
+
field_name="device", queryset=Device.objects.all(), label="Device"
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
class Meta:
|
|
48
|
+
model = AuthorizedKeyDevice
|
|
49
|
+
fields = ["id", "authorized_key", "device"]
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class AuthorizedKeyVirtualMachineFilterSet(BaseFilterSet):
|
|
53
|
+
authorized_key = django_filters.ModelMultipleChoiceFilter(
|
|
54
|
+
field_name="authorized_key", queryset=AuthorizedKey.objects.all(), label="Authorized Key"
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
virtual_machine = django_filters.ModelMultipleChoiceFilter(
|
|
58
|
+
field_name="virtual_machine", queryset=VirtualMachine.objects.all(), label="Virtual Machine"
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
class Meta:
|
|
62
|
+
model = AuthorizedKeyVirtualMachine
|
|
63
|
+
fields = ["id", "authorized_key", "virtual_machine"]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .authorizedkey import *
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
from dcim.models import Device
|
|
2
|
+
from django import forms
|
|
3
|
+
from django.utils.translation import gettext_lazy as _
|
|
4
|
+
from netbox.forms import NetBoxModelFilterSetForm, NetBoxModelForm
|
|
5
|
+
from utilities.forms.fields import (
|
|
6
|
+
CommentField,
|
|
7
|
+
DynamicModelMultipleChoiceField,
|
|
8
|
+
TagFilterField,
|
|
9
|
+
)
|
|
10
|
+
from utilities.forms.rendering import FieldSet
|
|
11
|
+
from virtualization.models import VirtualMachine
|
|
12
|
+
|
|
13
|
+
from netbox_authorized_keys.models import AuthorizedKey, AuthorizedKeyDevice, AuthorizedKeyVirtualMachine
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class AuthorizedKeyForm(NetBoxModelForm):
|
|
17
|
+
public_key = forms.CharField(
|
|
18
|
+
label=_("Public Key"), widget=forms.Textarea, required=True, help_text=_("Enter the public key (unique)")
|
|
19
|
+
)
|
|
20
|
+
username = forms.CharField(label=_("Username"), required=True)
|
|
21
|
+
full_name = forms.CharField(label=_("Full Name"), required=False, help_text=_("Owner's Full Name"))
|
|
22
|
+
|
|
23
|
+
devices = DynamicModelMultipleChoiceField(queryset=Device.objects.all(), label=_("Devices"), required=False)
|
|
24
|
+
virtual_machines = DynamicModelMultipleChoiceField(
|
|
25
|
+
queryset=VirtualMachine.objects.all(), label=_("Virtual Machines"), required=False
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
fieldsets = (
|
|
29
|
+
FieldSet("public_key", "username", "full_name", "description", name=_("Base")),
|
|
30
|
+
FieldSet("devices", "virtual_machines", name=_("Host Assignment")),
|
|
31
|
+
FieldSet("tags", name=_("Misc")),
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
class Meta:
|
|
35
|
+
comments = CommentField()
|
|
36
|
+
model = AuthorizedKey
|
|
37
|
+
fields = [
|
|
38
|
+
"public_key",
|
|
39
|
+
"username",
|
|
40
|
+
"full_name",
|
|
41
|
+
"description",
|
|
42
|
+
"devices",
|
|
43
|
+
"virtual_machines",
|
|
44
|
+
"comments",
|
|
45
|
+
"tags",
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class AuthorizedKeyFilterForm(NetBoxModelFilterSetForm):
|
|
50
|
+
model = AuthorizedKey
|
|
51
|
+
public_key = forms.CharField(required=False, widget=forms.widgets.Textarea(attrs={"placeholder": _("Public Key")}))
|
|
52
|
+
username = forms.CharField(required=False)
|
|
53
|
+
full_name = forms.CharField(required=False)
|
|
54
|
+
description = forms.CharField(required=False)
|
|
55
|
+
|
|
56
|
+
devices = DynamicModelMultipleChoiceField(queryset=Device.objects.all(), label=_("Devices"), required=False)
|
|
57
|
+
virtual_machines = DynamicModelMultipleChoiceField(
|
|
58
|
+
queryset=VirtualMachine.objects.all(), label=_("Virtual Machines"), required=False
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
tag = TagFilterField(model)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class AuthorizedKeyDeviceFilterForm(NetBoxModelFilterSetForm):
|
|
65
|
+
model = AuthorizedKeyDevice
|
|
66
|
+
authorized_key = DynamicModelMultipleChoiceField(
|
|
67
|
+
queryset=AuthorizedKey.objects.all(), label=_("Authorized Key"), required=False
|
|
68
|
+
)
|
|
69
|
+
device = DynamicModelMultipleChoiceField(queryset=Device.objects.all(), label=_("Device"), required=False)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class AuthorizedKeyVirtualMachineFilterForm(NetBoxModelFilterSetForm):
|
|
73
|
+
model = AuthorizedKeyVirtualMachine
|
|
74
|
+
authorized_key = DynamicModelMultipleChoiceField(
|
|
75
|
+
queryset=AuthorizedKey.objects.all(), label=_("Authorized Key"), required=False
|
|
76
|
+
)
|
|
77
|
+
virtual_machine = DynamicModelMultipleChoiceField(
|
|
78
|
+
queryset=VirtualMachine.objects.all(), label=_("Virtual Machine"), required=False
|
|
79
|
+
)
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# Generated by Django 5.0.9 on 2024-11-25 13:28
|
|
2
|
+
|
|
3
|
+
import django.db.models.deletion
|
|
4
|
+
import taggit.managers
|
|
5
|
+
import utilities.json
|
|
6
|
+
from django.db import migrations, models
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Migration(migrations.Migration):
|
|
10
|
+
|
|
11
|
+
initial = True
|
|
12
|
+
|
|
13
|
+
dependencies = [
|
|
14
|
+
("dcim", "0191_module_bay_rebuild"),
|
|
15
|
+
("extras", "0121_customfield_related_object_filter"),
|
|
16
|
+
("virtualization", "0040_convert_disk_size"),
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
operations = [
|
|
20
|
+
migrations.CreateModel(
|
|
21
|
+
name="AuthorizedKey",
|
|
22
|
+
fields=[
|
|
23
|
+
(
|
|
24
|
+
"id",
|
|
25
|
+
models.BigAutoField(
|
|
26
|
+
auto_created=True, primary_key=True, serialize=False
|
|
27
|
+
),
|
|
28
|
+
),
|
|
29
|
+
("created", models.DateTimeField(auto_now_add=True, null=True)),
|
|
30
|
+
("last_updated", models.DateTimeField(auto_now=True, null=True)),
|
|
31
|
+
(
|
|
32
|
+
"custom_field_data",
|
|
33
|
+
models.JSONField(
|
|
34
|
+
blank=True,
|
|
35
|
+
default=dict,
|
|
36
|
+
encoder=utilities.json.CustomFieldJSONEncoder,
|
|
37
|
+
),
|
|
38
|
+
),
|
|
39
|
+
("public_key", models.TextField()),
|
|
40
|
+
("username", models.CharField(blank=True, default="", max_length=200)),
|
|
41
|
+
(
|
|
42
|
+
"description",
|
|
43
|
+
models.CharField(blank=True, default="", max_length=200),
|
|
44
|
+
),
|
|
45
|
+
("comments", models.TextField(blank=True, default="")),
|
|
46
|
+
(
|
|
47
|
+
"tags",
|
|
48
|
+
taggit.managers.TaggableManager(
|
|
49
|
+
through="extras.TaggedItem", to="extras.Tag"
|
|
50
|
+
),
|
|
51
|
+
),
|
|
52
|
+
],
|
|
53
|
+
options={
|
|
54
|
+
"abstract": False,
|
|
55
|
+
},
|
|
56
|
+
),
|
|
57
|
+
migrations.CreateModel(
|
|
58
|
+
name="AuthorizedKeyDevice",
|
|
59
|
+
fields=[
|
|
60
|
+
(
|
|
61
|
+
"id",
|
|
62
|
+
models.BigAutoField(
|
|
63
|
+
auto_created=True, primary_key=True, serialize=False
|
|
64
|
+
),
|
|
65
|
+
),
|
|
66
|
+
(
|
|
67
|
+
"custom_field_data",
|
|
68
|
+
models.JSONField(
|
|
69
|
+
blank=True,
|
|
70
|
+
default=dict,
|
|
71
|
+
encoder=utilities.json.CustomFieldJSONEncoder,
|
|
72
|
+
),
|
|
73
|
+
),
|
|
74
|
+
(
|
|
75
|
+
"authorized_key",
|
|
76
|
+
models.ForeignKey(
|
|
77
|
+
on_delete=django.db.models.deletion.CASCADE,
|
|
78
|
+
to="netbox_authorized_keys.authorizedkey",
|
|
79
|
+
),
|
|
80
|
+
),
|
|
81
|
+
(
|
|
82
|
+
"device",
|
|
83
|
+
models.ForeignKey(
|
|
84
|
+
on_delete=django.db.models.deletion.CASCADE, to="dcim.device"
|
|
85
|
+
),
|
|
86
|
+
),
|
|
87
|
+
(
|
|
88
|
+
"tags",
|
|
89
|
+
taggit.managers.TaggableManager(
|
|
90
|
+
through="extras.TaggedItem", to="extras.Tag"
|
|
91
|
+
),
|
|
92
|
+
),
|
|
93
|
+
],
|
|
94
|
+
options={
|
|
95
|
+
"unique_together": {("authorized_key", "device")},
|
|
96
|
+
},
|
|
97
|
+
),
|
|
98
|
+
migrations.AddField(
|
|
99
|
+
model_name="authorizedkey",
|
|
100
|
+
name="devices",
|
|
101
|
+
field=models.ManyToManyField(
|
|
102
|
+
blank=True,
|
|
103
|
+
related_name="authorized_keys",
|
|
104
|
+
through="netbox_authorized_keys.AuthorizedKeyDevice",
|
|
105
|
+
to="dcim.device",
|
|
106
|
+
),
|
|
107
|
+
),
|
|
108
|
+
migrations.CreateModel(
|
|
109
|
+
name="AuthorizedKeyVirtualMachine",
|
|
110
|
+
fields=[
|
|
111
|
+
(
|
|
112
|
+
"id",
|
|
113
|
+
models.BigAutoField(
|
|
114
|
+
auto_created=True, primary_key=True, serialize=False
|
|
115
|
+
),
|
|
116
|
+
),
|
|
117
|
+
(
|
|
118
|
+
"custom_field_data",
|
|
119
|
+
models.JSONField(
|
|
120
|
+
blank=True,
|
|
121
|
+
default=dict,
|
|
122
|
+
encoder=utilities.json.CustomFieldJSONEncoder,
|
|
123
|
+
),
|
|
124
|
+
),
|
|
125
|
+
(
|
|
126
|
+
"authorized_key",
|
|
127
|
+
models.ForeignKey(
|
|
128
|
+
on_delete=django.db.models.deletion.CASCADE,
|
|
129
|
+
to="netbox_authorized_keys.authorizedkey",
|
|
130
|
+
),
|
|
131
|
+
),
|
|
132
|
+
(
|
|
133
|
+
"tags",
|
|
134
|
+
taggit.managers.TaggableManager(
|
|
135
|
+
through="extras.TaggedItem", to="extras.Tag"
|
|
136
|
+
),
|
|
137
|
+
),
|
|
138
|
+
(
|
|
139
|
+
"virtual_machine",
|
|
140
|
+
models.ForeignKey(
|
|
141
|
+
on_delete=django.db.models.deletion.CASCADE,
|
|
142
|
+
to="virtualization.virtualmachine",
|
|
143
|
+
),
|
|
144
|
+
),
|
|
145
|
+
],
|
|
146
|
+
options={
|
|
147
|
+
"unique_together": {("authorized_key", "virtual_machine")},
|
|
148
|
+
},
|
|
149
|
+
),
|
|
150
|
+
migrations.AddField(
|
|
151
|
+
model_name="authorizedkey",
|
|
152
|
+
name="virtual_machines",
|
|
153
|
+
field=models.ManyToManyField(
|
|
154
|
+
blank=True,
|
|
155
|
+
related_name="authorized_keys",
|
|
156
|
+
through="netbox_authorized_keys.AuthorizedKeyVirtualMachine",
|
|
157
|
+
to="virtualization.virtualmachine",
|
|
158
|
+
),
|
|
159
|
+
),
|
|
160
|
+
]
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Generated by Django 5.0.9 on 2024-11-26 08:06
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
("netbox_authorized_keys", "0001_initial"),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.AddField(
|
|
14
|
+
model_name="authorizedkey",
|
|
15
|
+
name="full_name",
|
|
16
|
+
field=models.CharField(blank=True, max_length=200),
|
|
17
|
+
),
|
|
18
|
+
migrations.AlterField(
|
|
19
|
+
model_name="authorizedkey",
|
|
20
|
+
name="description",
|
|
21
|
+
field=models.CharField(blank=True, default="", max_length=255),
|
|
22
|
+
),
|
|
23
|
+
migrations.AlterField(
|
|
24
|
+
model_name="authorizedkey",
|
|
25
|
+
name="public_key",
|
|
26
|
+
field=models.TextField(unique=True),
|
|
27
|
+
),
|
|
28
|
+
migrations.AlterField(
|
|
29
|
+
model_name="authorizedkey",
|
|
30
|
+
name="username",
|
|
31
|
+
field=models.CharField(max_length=200),
|
|
32
|
+
),
|
|
33
|
+
]
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .authorizedkey import *
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
from django.db import models
|
|
2
|
+
from django.urls import reverse
|
|
3
|
+
from django.utils.translation import gettext_lazy as _
|
|
4
|
+
from netbox.models import NetBoxModel
|
|
5
|
+
from netbox.models.features import (
|
|
6
|
+
BookmarksMixin,
|
|
7
|
+
# ChangeLoggingMixin,
|
|
8
|
+
CloningMixin,
|
|
9
|
+
CustomFieldsMixin,
|
|
10
|
+
CustomLinksMixin,
|
|
11
|
+
CustomValidationMixin,
|
|
12
|
+
EventRulesMixin,
|
|
13
|
+
ExportTemplatesMixin,
|
|
14
|
+
JournalingMixin,
|
|
15
|
+
NotificationsMixin,
|
|
16
|
+
TagsMixin,
|
|
17
|
+
)
|
|
18
|
+
from utilities.querysets import RestrictedQuerySet
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class AuthorizedKey(NetBoxModel):
|
|
22
|
+
public_key = models.TextField(verbose_name=_("Public Key"), null=False, blank=False, unique=True)
|
|
23
|
+
username = models.CharField(max_length=200, blank=False, null=False, verbose_name=_("Username"))
|
|
24
|
+
full_name = models.CharField(max_length=200, blank=True, null=False, verbose_name=_("Full Name"))
|
|
25
|
+
|
|
26
|
+
description = models.CharField(max_length=255, verbose_name=_("description"), blank=True, default="", null=False)
|
|
27
|
+
comments = models.TextField(blank=True, default="", null=False, verbose_name=_("Comments"))
|
|
28
|
+
|
|
29
|
+
devices = models.ManyToManyField(
|
|
30
|
+
to="dcim.device",
|
|
31
|
+
related_name="authorized_keys",
|
|
32
|
+
blank=True,
|
|
33
|
+
through="netbox_authorized_keys.AuthorizedKeyDevice",
|
|
34
|
+
verbose_name=_("Devices"),
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
virtual_machines = models.ManyToManyField(
|
|
38
|
+
to="virtualization.virtualmachine",
|
|
39
|
+
related_name="authorized_keys",
|
|
40
|
+
blank=True,
|
|
41
|
+
through="netbox_authorized_keys.AuthorizedKeyVirtualMachine",
|
|
42
|
+
verbose_name=_("Virtual Machines"),
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
objects = RestrictedQuerySet.as_manager()
|
|
46
|
+
|
|
47
|
+
def __str__(self):
|
|
48
|
+
if self.username and self.full_name and self.description:
|
|
49
|
+
return f"{self.username} - {self.full_name} - {self.description}"
|
|
50
|
+
elif self.username and self.full_name:
|
|
51
|
+
return f"{self.username} - {self.full_name}"
|
|
52
|
+
elif self.username and self.description:
|
|
53
|
+
return f"{self.username} - {self.description}"
|
|
54
|
+
|
|
55
|
+
return self.username
|
|
56
|
+
|
|
57
|
+
def get_absolute_url(self):
|
|
58
|
+
return reverse("plugins:netbox_authorized_keys:authorizedkey", args=[self.pk])
|
|
59
|
+
|
|
60
|
+
def serialize_object(self, *, exclude=None):
|
|
61
|
+
data = super().serialize_object(exclude=exclude or [])
|
|
62
|
+
data["devices"] = list(self.devices.values_list("pk", flat=True))
|
|
63
|
+
data["virtual_machines"] = list(self.virtual_machines.values_list("pk", flat=True))
|
|
64
|
+
return data
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class AuthorizedKeyDevice(
|
|
68
|
+
BookmarksMixin,
|
|
69
|
+
# ChangeLoggingMixin,
|
|
70
|
+
CloningMixin,
|
|
71
|
+
CustomFieldsMixin,
|
|
72
|
+
CustomLinksMixin,
|
|
73
|
+
CustomValidationMixin,
|
|
74
|
+
ExportTemplatesMixin,
|
|
75
|
+
JournalingMixin,
|
|
76
|
+
NotificationsMixin,
|
|
77
|
+
TagsMixin,
|
|
78
|
+
EventRulesMixin,
|
|
79
|
+
models.Model,
|
|
80
|
+
):
|
|
81
|
+
authorized_key = models.ForeignKey(to="netbox_authorized_keys.AuthorizedKey", on_delete=models.CASCADE)
|
|
82
|
+
device = models.ForeignKey(to="dcim.Device", on_delete=models.CASCADE)
|
|
83
|
+
|
|
84
|
+
objects = RestrictedQuerySet.as_manager()
|
|
85
|
+
|
|
86
|
+
class Meta:
|
|
87
|
+
unique_together = ("authorized_key", "device")
|
|
88
|
+
|
|
89
|
+
def __str__(self):
|
|
90
|
+
return f"{self.authorized_key} - {self.device}"
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
class AuthorizedKeyVirtualMachine(
|
|
94
|
+
BookmarksMixin,
|
|
95
|
+
# ChangeLoggingMixin,
|
|
96
|
+
CloningMixin,
|
|
97
|
+
CustomFieldsMixin,
|
|
98
|
+
CustomLinksMixin,
|
|
99
|
+
CustomValidationMixin,
|
|
100
|
+
ExportTemplatesMixin,
|
|
101
|
+
JournalingMixin,
|
|
102
|
+
NotificationsMixin,
|
|
103
|
+
TagsMixin,
|
|
104
|
+
EventRulesMixin,
|
|
105
|
+
models.Model,
|
|
106
|
+
):
|
|
107
|
+
authorized_key = models.ForeignKey(to="netbox_authorized_keys.AuthorizedKey", on_delete=models.CASCADE)
|
|
108
|
+
virtual_machine = models.ForeignKey(to="virtualization.VirtualMachine", on_delete=models.CASCADE)
|
|
109
|
+
|
|
110
|
+
objects = RestrictedQuerySet.as_manager()
|
|
111
|
+
|
|
112
|
+
class Meta:
|
|
113
|
+
unique_together = ("authorized_key", "virtual_machine")
|
|
114
|
+
|
|
115
|
+
def __str__(self):
|
|
116
|
+
return f"{self.authorized_key} - {self.virtual_machine}"
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from netbox.plugins import PluginMenu, PluginMenuItem
|
|
2
|
+
|
|
3
|
+
menu = PluginMenu(
|
|
4
|
+
label="Authorized Keys",
|
|
5
|
+
icon_class="mdi mdi-key",
|
|
6
|
+
groups=(
|
|
7
|
+
(
|
|
8
|
+
"SSH Public Keys",
|
|
9
|
+
(
|
|
10
|
+
PluginMenuItem(
|
|
11
|
+
link="plugins:netbox_authorized_keys:authorizedkey_list",
|
|
12
|
+
link_text="Authorized Keys",
|
|
13
|
+
permissions=["netbox_authorized_keys.view_authorizedkey"],
|
|
14
|
+
),
|
|
15
|
+
PluginMenuItem(
|
|
16
|
+
link="plugins:netbox_authorized_keys:authorizedkeydevice_list",
|
|
17
|
+
link_text="Devices",
|
|
18
|
+
permissions=["netbox_authorized_keys.view_authorizedkey"],
|
|
19
|
+
),
|
|
20
|
+
PluginMenuItem(
|
|
21
|
+
link="plugins:netbox_authorized_keys:authorizedkeyvirtualmachine_list",
|
|
22
|
+
link_text="Virtual Machines",
|
|
23
|
+
permissions=["netbox_authorized_keys.view_authorizedkey"],
|
|
24
|
+
),
|
|
25
|
+
),
|
|
26
|
+
),
|
|
27
|
+
),
|
|
28
|
+
)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .authorizedkey import *
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import django_tables2 as tables
|
|
2
|
+
from django.utils.html import format_html
|
|
3
|
+
from netbox.tables import NetBoxTable, columns
|
|
4
|
+
|
|
5
|
+
from netbox_authorized_keys.models import AuthorizedKey, AuthorizedKeyDevice, AuthorizedKeyVirtualMachine
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class AuthorizedKeyTable(NetBoxTable):
|
|
9
|
+
id = tables.Column(linkify=True, verbose_name="ID")
|
|
10
|
+
public_key = tables.Column(verbose_name="Public Key")
|
|
11
|
+
|
|
12
|
+
class Meta(NetBoxTable.Meta):
|
|
13
|
+
model = AuthorizedKey
|
|
14
|
+
fields = ("id", "public_key", "username", "full_name", "description", "comments", "tags")
|
|
15
|
+
default_columns = ("id", "username", "full_name", "description")
|
|
16
|
+
|
|
17
|
+
def render_public_key(self, value):
|
|
18
|
+
if len(value) > 23:
|
|
19
|
+
truncated_value = f"{value[:10]}...{value[-10:]}"
|
|
20
|
+
else:
|
|
21
|
+
truncated_value = value
|
|
22
|
+
return format_html('<span title="{}">{}</span>', value, truncated_value)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class AuthorizedKeyDeviceTable(NetBoxTable):
|
|
26
|
+
id = tables.Column(linkify=False, verbose_name="ID")
|
|
27
|
+
|
|
28
|
+
authorized_key = tables.Column(linkify=True)
|
|
29
|
+
device = tables.Column(linkify=True)
|
|
30
|
+
actions = columns.ActionsColumn(
|
|
31
|
+
actions=(),
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
class Meta(NetBoxTable.Meta):
|
|
35
|
+
model = AuthorizedKeyDevice
|
|
36
|
+
fields = ("authorized_key", "device")
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class AuthorizedKeyVirtualMachineTable(NetBoxTable):
|
|
40
|
+
id = tables.Column(linkify=False, verbose_name="ID")
|
|
41
|
+
|
|
42
|
+
authorized_key = tables.Column(linkify=True)
|
|
43
|
+
virtual_machine = tables.Column(linkify=True)
|
|
44
|
+
actions = columns.ActionsColumn(
|
|
45
|
+
actions=(),
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
class Meta(NetBoxTable.Meta):
|
|
49
|
+
model = AuthorizedKeyVirtualMachine
|
|
50
|
+
fields = ("authorized_key", "virtual_machine")
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
from dcim.models import Device
|
|
2
|
+
from netbox.views import generic
|
|
3
|
+
from utilities.views import ViewTab, register_model_view
|
|
4
|
+
from virtualization.models import VirtualMachine
|
|
5
|
+
|
|
6
|
+
from netbox_authorized_keys.filtersets import AuthorizedKeyFilterSet
|
|
7
|
+
from netbox_authorized_keys.models import AuthorizedKey
|
|
8
|
+
from netbox_authorized_keys.tables import AuthorizedKeyTable
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def create_authorized_key_tab_view(model):
|
|
12
|
+
view_name = f"{model._meta.model_name}-authorized-keys"
|
|
13
|
+
view_path = f"{model._meta.model_name}-authorized-keys"
|
|
14
|
+
|
|
15
|
+
class AuthorizedKeyTabView(generic.ObjectChildrenView):
|
|
16
|
+
child_model = AuthorizedKey
|
|
17
|
+
filterset = AuthorizedKeyFilterSet
|
|
18
|
+
template_name = "generic/object_children.html"
|
|
19
|
+
table = AuthorizedKeyTable
|
|
20
|
+
queryset = model.objects.all()
|
|
21
|
+
|
|
22
|
+
if model == Device:
|
|
23
|
+
tab = ViewTab(
|
|
24
|
+
label="Authorized Keys",
|
|
25
|
+
badge=lambda obj: AuthorizedKey.objects.filter(devices=obj.id).count(),
|
|
26
|
+
permission="netbox_authorized_keys.view_authorizedkey",
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
def get_children(self, request, parent):
|
|
30
|
+
children = self.child_model.objects.filter(devices=parent.id).restrict(request.user, "view")
|
|
31
|
+
return children
|
|
32
|
+
|
|
33
|
+
def get_table(self, data, request, bulk_actions=True):
|
|
34
|
+
table = super().get_table(data, request, bulk_actions)
|
|
35
|
+
table.exclude = "actions"
|
|
36
|
+
return table
|
|
37
|
+
|
|
38
|
+
elif model == VirtualMachine:
|
|
39
|
+
tab = ViewTab(
|
|
40
|
+
label="Authorized Keys",
|
|
41
|
+
badge=lambda obj: AuthorizedKey.objects.filter(virtual_machines=obj.id).count(),
|
|
42
|
+
permission="netbox_authorized_keys.view_authorizedkey",
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
def get_children(self, request, parent):
|
|
46
|
+
children = self.child_model.objects.filter(virtual_machines=parent.id).restrict(request.user, "view")
|
|
47
|
+
return children
|
|
48
|
+
|
|
49
|
+
def get_table(self, data, request, bulk_actions=True):
|
|
50
|
+
table = super().get_table(data, request, bulk_actions)
|
|
51
|
+
table.exclude = "actions"
|
|
52
|
+
return table
|
|
53
|
+
|
|
54
|
+
register_model_view(model, name=view_name, path=view_path)(AuthorizedKeyTabView)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
for model in [Device, VirtualMachine]:
|
|
58
|
+
create_authorized_key_tab_view(model)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from django.urls import path
|
|
2
|
+
from netbox.views.generic import ObjectChangeLogView
|
|
3
|
+
|
|
4
|
+
from netbox_authorized_keys import models, views
|
|
5
|
+
|
|
6
|
+
urlpatterns = [
|
|
7
|
+
# Authorized Keys
|
|
8
|
+
path("authorized-keys/", views.AuthorizedKeyListView.as_view(), name="authorizedkey_list"),
|
|
9
|
+
path("authorized-keys/add/", views.AuthorizedKeyEditView.as_view(), name="authorizedkey_add"),
|
|
10
|
+
path("authorized-keys/<int:pk>/", views.AuthorizedKeyView.as_view(), name="authorizedkey"),
|
|
11
|
+
path("authorized-keys/<int:pk>/edit/", views.AuthorizedKeyEditView.as_view(), name="authorizedkey_edit"),
|
|
12
|
+
path("authorized-keys/<int:pk>/delete/", views.AuthorizedKeyDeleteView.as_view(), name="authorizedkey_delete"),
|
|
13
|
+
path(
|
|
14
|
+
"authorized-keys/<int:pk>/changelog/",
|
|
15
|
+
ObjectChangeLogView.as_view(),
|
|
16
|
+
name="authorizedkey_changelog",
|
|
17
|
+
kwargs={"model": models.AuthorizedKey},
|
|
18
|
+
),
|
|
19
|
+
# Authorized Key Devices
|
|
20
|
+
path("authorized-keys/devices/", views.AuthorizedKeyDeviceListView.as_view(), name="authorizedkeydevice_list"),
|
|
21
|
+
# Authorized Key Virtual Machines
|
|
22
|
+
path(
|
|
23
|
+
"authorized-keys/virtual-machines/",
|
|
24
|
+
views.AuthorizedKeyVirtualMachineListView.as_view(),
|
|
25
|
+
name="authorizedkeyvirtualmachine_list",
|
|
26
|
+
),
|
|
27
|
+
]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .authorizedkey import *
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
from dcim.models import Device
|
|
2
|
+
from netbox.views import generic
|
|
3
|
+
from virtualization.models import VirtualMachine
|
|
4
|
+
|
|
5
|
+
from netbox_authorized_keys.filtersets import (
|
|
6
|
+
AuthorizedKeyDeviceFilterSet,
|
|
7
|
+
AuthorizedKeyFilterSet,
|
|
8
|
+
AuthorizedKeyVirtualMachineFilterSet,
|
|
9
|
+
)
|
|
10
|
+
from netbox_authorized_keys.forms import (
|
|
11
|
+
AuthorizedKeyDeviceFilterForm,
|
|
12
|
+
AuthorizedKeyFilterForm,
|
|
13
|
+
AuthorizedKeyForm,
|
|
14
|
+
AuthorizedKeyVirtualMachineFilterForm,
|
|
15
|
+
)
|
|
16
|
+
from netbox_authorized_keys.models import AuthorizedKey, AuthorizedKeyDevice, AuthorizedKeyVirtualMachine
|
|
17
|
+
from netbox_authorized_keys.tables import AuthorizedKeyDeviceTable, AuthorizedKeyTable, AuthorizedKeyVirtualMachineTable
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class AuthorizedKeyListView(generic.ObjectListView):
|
|
21
|
+
queryset = AuthorizedKey.objects.all()
|
|
22
|
+
table = AuthorizedKeyTable
|
|
23
|
+
filterset = AuthorizedKeyFilterSet
|
|
24
|
+
filterset_form = AuthorizedKeyFilterForm
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class AuthorizedKeyView(generic.ObjectView):
|
|
28
|
+
queryset = AuthorizedKey.objects.all()
|
|
29
|
+
|
|
30
|
+
def get_extra_context(self, request, instance):
|
|
31
|
+
device_ids = list(Device.objects.filter(authorized_keys=instance).values_list("id", flat=True))
|
|
32
|
+
virtual_machine_ids = list(VirtualMachine.objects.filter(authorized_keys=instance).values_list("id", flat=True))
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
"device_ids": device_ids,
|
|
36
|
+
"virtual_machine_ids": virtual_machine_ids,
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class AuthorizedKeyEditView(generic.ObjectEditView):
|
|
41
|
+
queryset = AuthorizedKey.objects.all()
|
|
42
|
+
form = AuthorizedKeyForm
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class AuthorizedKeyDeleteView(generic.ObjectDeleteView):
|
|
46
|
+
queryset = AuthorizedKey.objects.all()
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
# Authorized Key Devices
|
|
50
|
+
class AuthorizedKeyDeviceListView(generic.ObjectListView):
|
|
51
|
+
queryset = AuthorizedKeyDevice.objects.all()
|
|
52
|
+
table = AuthorizedKeyDeviceTable
|
|
53
|
+
filterset = AuthorizedKeyDeviceFilterSet
|
|
54
|
+
filterset_form = AuthorizedKeyDeviceFilterForm
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
# Authorized Key Virtual Machines
|
|
58
|
+
class AuthorizedKeyVirtualMachineListView(generic.ObjectListView):
|
|
59
|
+
queryset = AuthorizedKeyVirtualMachine.objects.all()
|
|
60
|
+
table = AuthorizedKeyVirtualMachineTable
|
|
61
|
+
filterset = AuthorizedKeyVirtualMachineFilterSet
|
|
62
|
+
filterset_form = AuthorizedKeyVirtualMachineFilterForm
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
setup.py
|
|
3
|
+
netbox_authorized_keys/__init__.py
|
|
4
|
+
netbox_authorized_keys/navigation.py
|
|
5
|
+
netbox_authorized_keys/template_content.py
|
|
6
|
+
netbox_authorized_keys/urls.py
|
|
7
|
+
netbox_authorized_keys/version.py
|
|
8
|
+
netbox_authorized_keys.egg-info/PKG-INFO
|
|
9
|
+
netbox_authorized_keys.egg-info/SOURCES.txt
|
|
10
|
+
netbox_authorized_keys.egg-info/dependency_links.txt
|
|
11
|
+
netbox_authorized_keys.egg-info/not-zip-safe
|
|
12
|
+
netbox_authorized_keys.egg-info/top_level.txt
|
|
13
|
+
netbox_authorized_keys/api/__init__.py
|
|
14
|
+
netbox_authorized_keys/api/serializers.py
|
|
15
|
+
netbox_authorized_keys/api/urls.py
|
|
16
|
+
netbox_authorized_keys/api/views.py
|
|
17
|
+
netbox_authorized_keys/filtersets/__init__.py
|
|
18
|
+
netbox_authorized_keys/filtersets/authorizedkey.py
|
|
19
|
+
netbox_authorized_keys/forms/__init__.py
|
|
20
|
+
netbox_authorized_keys/forms/authorizedkey.py
|
|
21
|
+
netbox_authorized_keys/migrations/0001_initial.py
|
|
22
|
+
netbox_authorized_keys/migrations/0002_authorizedkey_full_name_and_more.py
|
|
23
|
+
netbox_authorized_keys/migrations/__init__.py
|
|
24
|
+
netbox_authorized_keys/models/__init__.py
|
|
25
|
+
netbox_authorized_keys/models/authorizedkey.py
|
|
26
|
+
netbox_authorized_keys/tables/__init__.py
|
|
27
|
+
netbox_authorized_keys/tables/authorizedkey.py
|
|
28
|
+
netbox_authorized_keys/views/__init__.py
|
|
29
|
+
netbox_authorized_keys/views/authorizedkey.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
netbox_authorized_keys
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import codecs
|
|
2
|
+
import os.path
|
|
3
|
+
|
|
4
|
+
from setuptools import find_packages, setup
|
|
5
|
+
|
|
6
|
+
with open("README.md", "r") as fh:
|
|
7
|
+
long_description = fh.read()
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def read(rel_path):
|
|
11
|
+
here = os.path.abspath(os.path.dirname(__file__))
|
|
12
|
+
with codecs.open(os.path.join(here, rel_path), "r") as fp:
|
|
13
|
+
return fp.read()
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def get_config_param(rel_path, variable_name):
|
|
17
|
+
for line in read(rel_path).splitlines():
|
|
18
|
+
if line.startswith(variable_name):
|
|
19
|
+
delim = '"' if '"' in line else "'"
|
|
20
|
+
return line.split(delim)[1]
|
|
21
|
+
else:
|
|
22
|
+
raise RuntimeError(f"Unable to find {variable_name} string.")
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def get_version(rel_path):
|
|
26
|
+
for line in read(rel_path).splitlines():
|
|
27
|
+
if line.startswith("__version__"):
|
|
28
|
+
delim = '"' if '"' in line else "'"
|
|
29
|
+
return line.split(delim)[1]
|
|
30
|
+
else:
|
|
31
|
+
raise RuntimeError("Unable to find version string.")
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
setup(
|
|
35
|
+
name=get_config_param("netbox_authorized_keys/version.py", "__name__"),
|
|
36
|
+
version=get_version("netbox_authorized_keys/version.py"),
|
|
37
|
+
description=get_config_param("netbox_authorized_keys/version.py", "__description__"),
|
|
38
|
+
author=get_config_param("netbox_authorized_keys/version.py", "__author__"),
|
|
39
|
+
license="MIT",
|
|
40
|
+
install_requires=[],
|
|
41
|
+
packages=find_packages(),
|
|
42
|
+
include_package_data=True,
|
|
43
|
+
zip_safe=False,
|
|
44
|
+
)
|