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

Skip to content
Snippets Groups Projects
Verified Commit c6217275 authored by Vincent SIMONIN's avatar Vincent SIMONIN
Browse files

:sparkles: New Mapping property Sorry Page

* Add mapping property "sorry_page". Must be an URL, default value is
  configurable (see next point)
* Add new plugin configuration "default_sorry_page" default to https://sorry.ec.europa.eu/
* Fixed mapping import form don't expose all mapping properties
parent 3d328bc3
No related branches found
No related tags found
1 merge request!50✨ New Mapping property Sorry Page
Pipeline #105295 failed
Showing with 218 additions and 11 deletions
......@@ -10,10 +10,13 @@ class NetBoxRpsConfig(PluginConfig):
name = "netbox_rps_plugin"
verbose_name = "NetBox RPS"
description = "A Netbox plugin to add RPS resources"
version = "0.11.0"
version = "0.12.0"
author = "Vincent Simonin"
author_email = "vincent.simonin@ext.ec.europa.eu"
base_url = "rps"
default_settings = {
"default_sorry_page": "https://sorry.ec.europa.eu/"
}
# pylint: disable=C0103
config = NetBoxRpsConfig
......@@ -123,6 +123,7 @@ class MappingSerializer(NetBoxModelSerializer):
"proxy_cache",
"proxy_read_timeout",
"client_max_body_size",
"sorry_page",
"custom_fields",
"created",
"last_updated",
......
......@@ -24,6 +24,7 @@ class MappingFilterSet(NetBoxModelFilterSet):
"proxy_cache",
"proxy_read_timeout",
"client_max_body_size",
"sorry_page"
)
# pylint: disable=W0613
......
......@@ -15,6 +15,7 @@ from .models import (
HttpHeader,
ApplyToChoices,
SamlConfig,
URL_MAX_SIZE,
)
......@@ -35,6 +36,7 @@ class MappingForm(NetBoxModelForm):
"proxy_cache",
"proxy_read_timeout",
"client_max_body_size",
"sorry_page",
"Comment",
"tags",
)
......@@ -43,14 +45,16 @@ class MappingForm(NetBoxModelForm):
"keepalive_requests": "Min value 100 requests, max 5000 requests, default 1000 requests.",
"keepalive_timeout": "In seconds. Min value 1, max 300, default 75.",
"proxy_read_timeout": "In seconds. Min value 1, max 300, default 60.",
"client_max_body_size": "In Mega Bytes. Min 1, max 255, default 1."
"client_max_body_size": "In Mega Bytes. Min 1, max 255, default 1.",
}
labels = {
"source": "Source",
"target": "Target",
"source": "Source URL",
"target": "Target URL",
"testingpage": "Testing Page URL",
"keepalive_timeout": "Keepalive timeout (s)",
"proxy_read_timeout": " Proxy read timeout (s)",
"client_max_body_size": "Client max body size (MB)"
"client_max_body_size": "Client max body size (MB)",
"sorry_page": "Sorry Page URL",
}
......@@ -59,10 +63,10 @@ class MappingFilterForm(NetBoxModelFilterSetForm):
model = Mapping
source = forms.CharField(
max_length=120, min_length=1, required=False, label="Source URL"
max_length=URL_MAX_SIZE, min_length=1, required=False, label="Source URL"
)
target = forms.CharField(
max_length=120, min_length=1, required=False, label="Target URL"
max_length=URL_MAX_SIZE, min_length=1, required=False, label="Target URL"
)
authentication = forms.MultipleChoiceField(
choices=AuthenticationChoices,
......@@ -80,22 +84,88 @@ class MappingFilterForm(NetBoxModelFilterSetForm):
gzip_proxied = webdav = forms.BooleanField(
required=False, widget=forms.Select(choices=BOOLEAN_WITH_BLANK_CHOICES)
)
keepalive_requests = forms.IntegerField(min_value=100, max_value=5000, required=False)
keepalive_requests = forms.IntegerField(
min_value=100, max_value=5000, required=False
)
keepalive_timeout = forms.IntegerField(min_value=1, max_value=300, required=False)
proxy_cache = forms.BooleanField(
required=False, widget=forms.Select(choices=BOOLEAN_WITH_BLANK_CHOICES)
)
proxy_read_timeout = forms.IntegerField(min_value=1, max_value=300, required=False)
client_max_body_size = forms.IntegerField(min_value=1, max_value=255, required=False)
client_max_body_size = forms.IntegerField(
min_value=1, max_value=255, required=False
)
sorry_page = forms.CharField(
max_length=URL_MAX_SIZE, min_length=1, required=False, label="Sorry Page URL"
)
tag = TagFilterField(model)
class MappingImportForm(NetBoxModelImportForm):
"""Mapping importation form definition class"""
authentication = forms.MultipleChoiceField(
choices=AuthenticationChoices,
required=False,
help_text='Authentication method. Can be "none", "ldap" and "ecas". Default to "none".',
)
keepalive_requests = forms.IntegerField(
min_value=100,
max_value=5000,
required=False,
help_text="Min value 100 requests, max 5000 requests, default 1000 requests.",
)
keepalive_timeout = forms.IntegerField(
min_value=1,
max_value=300,
required=False,
help_text="In seconds. Min value 1, max 300, default 75.",
)
proxy_read_timeout = forms.IntegerField(
min_value=1,
max_value=300,
required=False,
help_text="In seconds. Min value 1, max 300, default 60.",
)
client_max_body_size = forms.IntegerField(
min_value=1,
max_value=255,
required=False,
help_text="In Mega Bytes. Min 1, max 255, default 1.",
)
sorry_page = forms.CharField(
max_length=URL_MAX_SIZE,
min_length=1,
required=False,
help_text="Sorry Page URL",
)
class Meta:
model = Mapping
fields = ("source", "target", "authentication", "testingpage", "webdav")
fields = (
"source",
"target",
"authentication",
"testingpage",
"webdav",
"testingpage",
"Comment",
"gzip_proxied",
"keepalive_requests",
"keepalive_timeout",
"proxy_cache",
"proxy_read_timeout",
"client_max_body_size",
"sorry_page",
)
help_texts = {
"source": "Source URL",
"target": "Target URL",
"testingpage": "Testing page URL",
"webdav": 'Define if the mapping handle Webdav protocol. Default to "false"',
"gzip_proxied": 'Is gzip proxied. Default to "false"',
"proxy_cache": 'Is proxy cache activated. Default to "false"',
}
class HttpHeaderForm(NetBoxModelForm):
......
"""Migration File"""
# pylint: disable=C0103
from django.conf import settings
import django.core.validators
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
"""Migration Class"""
dependencies = [
("netbox_rps_plugin", "0008_new_mapping_attributes"),
]
operations = [
migrations.AddField(
model_name="mapping",
name="sorry_page",
field=models.CharField(
default=settings.PLUGINS_CONFIG["netbox_rps_plugin"]["default_sorry_page"],
max_length=2000,
validators=[
django.core.validators.URLValidator(message="It must be a url")
],
),
),
]
"""Models definitions"""
from django.conf import settings
from django.db import models
from django.urls import reverse
from django.core.validators import URLValidator, MaxValueValidator, MinValueValidator
......@@ -7,6 +8,7 @@ from netbox.models import NetBoxModel
from utilities.choices import ChoiceSet
URL_MAX_SIZE = 2000
DEFAULT_SORRY_PAGE = settings.PLUGINS_CONFIG["netbox_rps_plugin"]["default_sorry_page"]
class AuthenticationChoices(ChoiceSet):
......@@ -83,6 +85,13 @@ class Mapping(NetBoxModel):
client_max_body_size = models.IntegerField(
default=1, validators=[MinValueValidator(1), MaxValueValidator(255)]
)
sorry_page = models.CharField(
max_length=URL_MAX_SIZE,
blank=False,
verbose_name="Sorry Page",
validators=[URLValidator(message="It must be a url")],
default=DEFAULT_SORRY_PAGE,
)
class Meta:
ordering = ("source", "target")
......
......@@ -35,6 +35,7 @@ class MappingTable(NetBoxTable):
"proxy_read_timeout",
"client_max_body_size",
"httpheader_count",
"sorry_page",
"tags",
"created",
"last_updated",
......
......@@ -100,6 +100,10 @@
<th scope="row">Client max body size</th>
<td>{{ object.client_max_body_size }}&nbsp;MB</td>
</tr>
<tr>
<th scope="row">Sorry Page</th>
<td>{{ object.sorry_page }}&nbsp;MB</td>
</tr>
</table>
</div>
</div>
......
......@@ -2,7 +2,7 @@ from setuptools import find_packages, setup
setup(
name='netbox_rps_plugin',
version='0.11.0',
version='0.12.0',
description='A Netbox plugin to add RPS resources',
install_requires=[],
packages=find_packages(),
......
"""Test case for Mapping is unique"""
import unittest
import json
import os
import requests
# from netbox_rps_plugin import NetBoxRpsConfig
from .base import Base
HOST = os.getenv("HOST", default="localhost")
PORT = os.getenv("PORT", default="8080")
API_KEY = os.getenv("API_KEY", "only4testingpurpose")
class TestMappingSorryPage(Base):
"""Test case for Mapping Sorry Page property class"""
def test_that_mapping_sorry_page_default_value_is_set(self) -> None:
"""Test that mapping sorry page default value is set"""
response = requests.post(
url=f"http://{HOST}:{PORT}/api/plugins/rps/mapping/",
json={
"source": "https://truc8.com/api",
"target": "http://10.10.10.10:1888/api",
"authentication": "none",
"testingpage": None,
},
headers={"Authorization": f"Token {API_KEY}"},
timeout=5,
)
self.assertEqual(response.status_code, 201)
content = json.loads(response.content)
self.mapping_id = content["id"]
self.assertEqual(
content["sorry_page"],
"https://sorry.ec.europa.eu/",
)
def test_that_mapping_sorry_page_must_be_an_url(self) -> None:
"""Test that a mapping sorry page must be an URL"""
response = requests.post(
url=f"http://{HOST}:{PORT}/api/plugins/rps/mapping/",
json={
"source": "https://truc8.com/api",
"target": "http://10.10.10.10:1888/api",
"authentication": "none",
"testingpage": None,
"sorry_page": "not an URL"
},
headers={"Authorization": f"Token {API_KEY}"},
timeout=5,
)
self.assertEqual(response.status_code, 400)
response = requests.post(
url=f"http://{HOST}:{PORT}/api/plugins/rps/mapping/",
json={
"source": "https://truc8.com/api",
"target": "http://10.10.10.10:1888/api",
"authentication": "none",
"testingpage": None,
"sorry_page": "https://my.custom.sorry.page/500.html"
},
headers={"Authorization": f"Token {API_KEY}"},
timeout=5,
)
self.assertEqual(response.status_code, 201)
content = json.loads(response.content)
self.mapping_id = content["id"]
self.assertEqual(
content["sorry_page"],
"https://my.custom.sorry.page/500.html",
)
if __name__ == "__main__":
unittest.main()
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