Code development platform for open source projects from the European Union institutions

Skip to content
Snippets Groups Projects
Commit a30020ff authored by Laurent VENIER's avatar Laurent VENIER :speech_balloon:
Browse files

Merge branch 'ntt' into 'main'

Ntt

See merge request digit-c4/netbox-mapping!1
parents 4f95d3ad 20ee9690
No related branches found
No related tags found
1 merge request!1Ntt
Pipeline #53888 failed
from django.contrib.postgres.fields import ArrayField
from django.db import models
from netbox.models import NetBoxModel
from utilities.choices import ChoiceSet
from django.urls import reverse
from django.core.validators import URLValidator
class AuthenticationChoices(ChoiceSet):
key = 'Mapping.authentication'
DEFAULT_VALUE = 'none'
CHOICES = [
('none', 'None', 'dark'),
('ldap', 'Ldap', 'blue'),
('ecas', 'Ecas', 'blue'),
]
class Mapping(NetBoxModel):
source = models.CharField(
max_length=120,
blank=False,
verbose_name='Name',
validators=[URLValidator(message='It must be a url')],
)
target = models.CharField(
max_length=120,
blank=False,
verbose_name='Identifier',
validators=[URLValidator(message='It must be a url')],
)
authentication = models.CharField(
max_length=30,
choices=AuthenticationChoices,
default=AuthenticationChoices.DEFAULT_VALUE,
blank=False,
verbose_name='Auth',
)
testingpage = models.CharField(
max_length=120,
blank=False,
validators=[URLValidator(message='It must be a url')],
)
webdav = models.BooleanField(
default=False,
)
Comment = models.CharField(
max_length=500,
blank=True
)
class Meta:
ordering = ('source', 'target')
def __str__(self):
return f'{self.source}'
def get_absolute_url(self):
return reverse('plugins:netbox_rps_plugin:mapping', args=[self.pk])
def get_authentication_color(self):
return AuthenticationChoices.colors.get(self.authentication)
from extras.plugins import PluginMenuButton, PluginMenuItem, PluginMenu
from utilities.choices import ButtonColorChoices
mapping_butons = [
PluginMenuButton(
link='plugins:netbox_rps_plugin:mapping_add',
title='Add',
icon_class='mdi mdi-plus-thick',
color=ButtonColorChoices.GREEN
),
PluginMenuButton(
link='plugins:netbox_rps_plugin:mapping_add',
title='Import',
icon_class='mdi mdi-upload',
color=ButtonColorChoices.CYAN
),
]
mappingItem = PluginMenuItem(
link='plugins:netbox_rps_plugin:mapping_list',
link_text='Mappings',
buttons=mapping_butons
),
menu = (
PluginMenu(
label='Mappings',
groups=(
('MAPPINGS', mappingItem),
),
icon_class='mdi mdi-graph-outline'
)
)
from netbox.search import SearchIndex, register_search
from .models import Mapping
@register_search
class MappingIndex(SearchIndex):
model = Mapping
fields = (
('source', 120),
('target', 120),
('authentication', 30),
('Comment', 500),
)
import django_tables2 as tables
from netbox.tables import NetBoxTable, ChoiceFieldColumn
from .models import Mapping
class MappingTable(NetBoxTable):
authentication = ChoiceFieldColumn()
class Meta(NetBoxTable.Meta):
model = Mapping
fields = (
'pk', 'id', 'source', 'target', 'authentication', 'testingpage', 'webdav', 'Comment'
)
default_columns = (
'source', 'target', 'authentication', 'Comment'
)
{% extends 'generic/object.html' %}
{% load render_table from django_tables2 %}
{% block content %}
<div class="row mb-3">
<div class="col col-md-6">
<div class="card">
<h5 class="card-header">Access List</h5>
<div class="card-body">
<table class="table table-hover attr-table">
<tr>
<th scope="row">Name</th>
<td>{{ object.name }}</td>
</tr>
<tr>
<th scope="row">Default Action</th>
<td>{{ object.get_default_action_display }}</td>
</tr>
<tr>
<th scope="row">Rules</th>
<td>{{ object.rules.count }}</td>
</tr>
</table>
</div>
</div>
{% include 'inc/panels/custom_fields.html' %}
</div>
<div class="col col-md-6">
{% include 'inc/panels/tags.html' %}
{% include 'inc/panels/comments.html' %}
</div>
</div>
<div class="row">
<div class="col col-md-12">
<div class="card">
<h5 class="card-header">Rules</h5>
<div class="card-body table-responsive">
{% render_table rules_table %}
</div>
</div>
</div>
</div>
{% endblock content %}
{% extends 'generic/object.html' %}
{% block content %}
<div class="row mb-3">
<div class="col col-md-6">
<div class="card">
<h5 class="card-header">MAPPINGS</h5>
<div class="card-body">
<table class="table table-hover attr-table">
<tr>
<th scope="row">Name</th>
<td>{{ object.source }}</td>
</tr>
<tr>
<th scope="row">Comment</th>
<td>{{ object.Comment|placeholder }}</td>
</tr>
</table>
</div>
</div>
{% include 'inc/panels/custom_fields.html' %}
{% include 'inc/panels/tags.html' %}
</div>
<div class="col col-md-6">
<div class="card">
<h5 class="card-header">Details</h5>
<div class="card-body">
<table class="table table-hover attr-table">
<tr>
<th scope="row">Protocol</th>
<td>{{ object.get_protocol_display }}</td>
</tr>
<tr>
<th scope="row">Source Prefix</th>
<td>
{% if object.source_prefix %}
<a href="{{ object.source_prefix.get_absolute_url }}">{{ object.source_prefix }}</a>
{% else %}
{{ ''|placeholder }}
{% endif %}
</td>
</tr>
<tr>
<th scope="row">Source Ports</th>
<td>{{ object.source_ports|join:", "|placeholder }}</td>
</tr>
<tr>
<th scope="row">Destination Prefix</th>
<td>
{% if object.destination_prefix %}
<a href="{{ object.destination_prefix.get_absolute_url }}">{{ object.destination_prefix }}</a>
{% else %}
{{ ''|placeholder }}
{% endif %}
</td>
</tr>
<tr>
<th scope="row">Destination Ports</th>
<td>{{ object.destination_ports|join:", "|placeholder }}</td>
</tr>
<tr>
<th scope="row">Action</th>
<td>{{ object.get_action_display }}</td>
</tr>
</table>
</div>
</div>
</div>
</div>
{% endblock content %}
from django.urls import path
from netbox_rps_plugin import views, models
from netbox.views.generic import ObjectChangeLogView
urlpatterns = (
# Mapping
path('mappings/', views.MappingListView.as_view(), name='mapping_list'),
path('mappings/add/', views.MappingEditView.as_view(), name='mapping_add'),
path('mappings/<int:pk>/', views.MappingView.as_view(), name='mapping'),
path('mappings/<int:pk>/edit/', views.MappingEditView.as_view(), name='mapping_edit'),
path('mappings/<int:pk>/delete/', views.MappingDeleteView.as_view(), name='mapping_delete'),
path('mappings/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='mapping_changelog', kwargs={
'model': models.Mapping
}),
)
from netbox.views import generic
from netbox_rps_plugin import forms, tables, filtersets, models
class MappingView(generic.ObjectView):
queryset = models.Mapping.objects.all()
class MappingListView(generic.ObjectListView):
queryset = models.Mapping.objects.all()
table = tables.MappingTable
filterset = filtersets.MappingFilterSet
filterset_form = forms.MappingFilterForm
class MappingEditView(generic.ObjectEditView):
queryset = models.Mapping.objects.all()
form = forms.MappingForm
class MappingDeleteView(generic.ObjectDeleteView):
queryset = models.Mapping.objects.all()
# Testing the library
## Demo
```
TODO
```
## End to end
Deploy a full stack
```shell
$ terraform init
$ terraform apply -var="deploy_service=true"
```
wait `netbox` container to be ready (run `docker logs -f netbox` to watch the logs)
and prepare a python environment to execute the E2E tests suite
```shell
$ python3 -m venv venv
$ source venv/bin/activate
$ pip install -r tests/requirements.e2e.txt
$ python -m unittest discover tests/e2e
```
import unittest
import requests
class TestUnauthenticatedMappings(unittest.TestCase):
def test_mappings_get_unauthenticated(self):
r = requests.get('http://localhost:8000/api/plugins/rps/')
self.assertEqual(r.status_code, 403)
def test_mappings_get_unauthenticated(self):
r = requests.get('http://localhost:8000/api/plugins/rps/mapping/')
self.assertEqual(r.status_code, 403)
def test_mappings_post_unauthenticated(self):
r = requests.post('http://localhost:8000/api/plugins/rps/mapping/')
self.assertEqual(r.status_code, 403)
def test_mappings_patch_unauthenticated(self):
r = requests.patch('http://localhost:8000/api/plugins/rps/mapping/')
self.assertEqual(r.status_code, 403)
def test_mappings_delete_unauthenticated(self):
r = requests.delete('http://localhost:8000/api/plugins/rps/mapping/')
self.assertEqual(r.status_code, 403)
def test_mappings_put_unauthenticated(self):
r = requests.put('http://localhost:8000/api/plugins/rps/mapping')
self.assertEqual(r.status_code, 403)
if __name__ == '__main__':
unittest.main()
requests==2.30.0
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment