Просмотр исходного кода

#9816: Promote IKE & IPSec proposals and policies to primary models

Jeremy Stretch 2 лет назад
Родитель
Сommit
5b0b366b82

+ 4 - 0
docs/development/models.md

@@ -62,7 +62,11 @@ These are considered the "core" application models which are used to model netwo
 * [tenancy.Tenant](../models/tenancy/tenant.md)
 * [tenancy.Tenant](../models/tenancy/tenant.md)
 * [virtualization.Cluster](../models/virtualization/cluster.md)
 * [virtualization.Cluster](../models/virtualization/cluster.md)
 * [virtualization.VirtualMachine](../models/virtualization/virtualmachine.md)
 * [virtualization.VirtualMachine](../models/virtualization/virtualmachine.md)
+* [vpn.IKEPolicy](../models/vpn/ikepolicy.md)
+* [vpn.IKEProposal](../models/vpn/ikeproposal.md)
+* [vpn.IPSecPolicy](../models/vpn/ipsecpolicy.md)
 * [vpn.IPSecProfile](../models/vpn/ipsecprofile.md)
 * [vpn.IPSecProfile](../models/vpn/ipsecprofile.md)
+* [vpn.IPSecProposal](../models/vpn/ipsecproposal.md)
 * [vpn.L2VPN](../models/vpn/l2vpn.md)
 * [vpn.L2VPN](../models/vpn/l2vpn.md)
 * [vpn.Tunnel](../models/vpn/tunnel.md)
 * [vpn.Tunnel](../models/vpn/tunnel.md)
 * [wireless.WirelessLAN](../models/wireless/wirelesslan.md)
 * [wireless.WirelessLAN](../models/wireless/wirelesslan.md)

+ 1 - 0
netbox/templates/vpn/ikepolicy.html

@@ -48,6 +48,7 @@
     </div>
     </div>
     <div class="col col-md-6">
     <div class="col col-md-6">
       {% include 'inc/panels/custom_fields.html' %}
       {% include 'inc/panels/custom_fields.html' %}
+      {% include 'inc/panels/comments.html' %}
       {% include 'inc/panels/tags.html' %}
       {% include 'inc/panels/tags.html' %}
       {% plugin_right_page object %}
       {% plugin_right_page object %}
     </div>
     </div>

+ 1 - 0
netbox/templates/vpn/ikeproposal.html

@@ -51,6 +51,7 @@
     </div>
     </div>
     <div class="col col-md-6">
     <div class="col col-md-6">
       {% include 'inc/panels/custom_fields.html' %}
       {% include 'inc/panels/custom_fields.html' %}
+      {% include 'inc/panels/comments.html' %}
       {% include 'inc/panels/tags.html' %}
       {% include 'inc/panels/tags.html' %}
       {% plugin_right_page object %}
       {% plugin_right_page object %}
     </div>
     </div>

+ 1 - 0
netbox/templates/vpn/ipsecpolicy.html

@@ -35,6 +35,7 @@
     </div>
     </div>
     <div class="col col-md-6">
     <div class="col col-md-6">
       {% include 'inc/panels/custom_fields.html' %}
       {% include 'inc/panels/custom_fields.html' %}
+      {% include 'inc/panels/comments.html' %}
       {% include 'inc/panels/tags.html' %}
       {% include 'inc/panels/tags.html' %}
       {% plugin_right_page object %}
       {% plugin_right_page object %}
     </div>
     </div>

+ 1 - 0
netbox/templates/vpn/ipsecproposal.html

@@ -47,6 +47,7 @@
     </div>
     </div>
     <div class="col col-md-6">
     <div class="col col-md-6">
       {% include 'inc/panels/custom_fields.html' %}
       {% include 'inc/panels/custom_fields.html' %}
+      {% include 'inc/panels/comments.html' %}
       {% include 'inc/panels/tags.html' %}
       {% include 'inc/panels/tags.html' %}
       {% plugin_right_page object %}
       {% plugin_right_page object %}
     </div>
     </div>

+ 7 - 6
netbox/vpn/api/serializers.py

@@ -107,7 +107,8 @@ class IKEProposalSerializer(NetBoxModelSerializer):
         model = IKEProposal
         model = IKEProposal
         fields = (
         fields = (
             'id', 'url', 'display', 'name', 'description', 'authentication_method', 'encryption_algorithm',
             'id', 'url', 'display', 'name', 'description', 'authentication_method', 'encryption_algorithm',
-            'authentication_algorithm', 'group', 'sa_lifetime', 'tags', 'custom_fields', 'created', 'last_updated',
+            'authentication_algorithm', 'group', 'sa_lifetime', 'comments', 'tags', 'custom_fields', 'created',
+            'last_updated',
         )
         )
 
 
 
 
@@ -131,8 +132,8 @@ class IKEPolicySerializer(NetBoxModelSerializer):
     class Meta:
     class Meta:
         model = IKEPolicy
         model = IKEPolicy
         fields = (
         fields = (
-            'id', 'url', 'display', 'name', 'description', 'version', 'mode', 'proposals', 'preshared_key', 'tags',
-            'custom_fields', 'created', 'last_updated',
+            'id', 'url', 'display', 'name', 'description', 'version', 'mode', 'proposals', 'preshared_key', 'comments',
+            'tags', 'custom_fields', 'created', 'last_updated',
         )
         )
 
 
 
 
@@ -151,7 +152,7 @@ class IPSecProposalSerializer(NetBoxModelSerializer):
         model = IPSecProposal
         model = IPSecProposal
         fields = (
         fields = (
             'id', 'url', 'display', 'name', 'description', 'encryption_algorithm', 'authentication_algorithm',
             'id', 'url', 'display', 'name', 'description', 'encryption_algorithm', 'authentication_algorithm',
-            'sa_lifetime_seconds', 'sa_lifetime_data', 'tags', 'custom_fields', 'created', 'last_updated',
+            'sa_lifetime_seconds', 'sa_lifetime_data', 'comments', 'tags', 'custom_fields', 'created', 'last_updated',
         )
         )
 
 
 
 
@@ -173,8 +174,8 @@ class IPSecPolicySerializer(NetBoxModelSerializer):
     class Meta:
     class Meta:
         model = IPSecPolicy
         model = IPSecPolicy
         fields = (
         fields = (
-            'id', 'url', 'display', 'name', 'description', 'proposals', 'pfs_group', 'tags', 'custom_fields', 'created',
-            'last_updated',
+            'id', 'url', 'display', 'name', 'description', 'proposals', 'pfs_group', 'comments', 'tags',
+            'custom_fields', 'created', 'last_updated',
         )
         )
 
 
 
 

+ 8 - 4
netbox/vpn/filtersets.py

@@ -128,7 +128,8 @@ class IKEProposalFilterSet(NetBoxModelFilterSet):
             return queryset
             return queryset
         return queryset.filter(
         return queryset.filter(
             Q(name__icontains=value) |
             Q(name__icontains=value) |
-            Q(description__icontains=value)
+            Q(description__icontains=value) |
+            Q(comments__icontains=value)
         )
         )
 
 
 
 
@@ -155,7 +156,8 @@ class IKEPolicyFilterSet(NetBoxModelFilterSet):
             return queryset
             return queryset
         return queryset.filter(
         return queryset.filter(
             Q(name__icontains=value) |
             Q(name__icontains=value) |
-            Q(description__icontains=value)
+            Q(description__icontains=value) |
+            Q(comments__icontains=value)
         )
         )
 
 
 
 
@@ -176,7 +178,8 @@ class IPSecProposalFilterSet(NetBoxModelFilterSet):
             return queryset
             return queryset
         return queryset.filter(
         return queryset.filter(
             Q(name__icontains=value) |
             Q(name__icontains=value) |
-            Q(description__icontains=value)
+            Q(description__icontains=value) |
+            Q(comments__icontains=value)
         )
         )
 
 
 
 
@@ -200,7 +203,8 @@ class IPSecPolicyFilterSet(NetBoxModelFilterSet):
             return queryset
             return queryset
         return queryset.filter(
         return queryset.filter(
             Q(name__icontains=value) |
             Q(name__icontains=value) |
-            Q(description__icontains=value)
+            Q(description__icontains=value) |
+            Q(comments__icontains=value)
         )
         )
 
 
 
 

+ 4 - 4
netbox/vpn/forms/bulk_import.py

@@ -147,7 +147,7 @@ class IKEProposalImportForm(NetBoxModelImportForm):
         model = IKEProposal
         model = IKEProposal
         fields = (
         fields = (
             'name', 'description', 'authentication_method', 'encryption_algorithm', 'authentication_algorithm',
             'name', 'description', 'authentication_method', 'encryption_algorithm', 'authentication_algorithm',
-            'group', 'sa_lifetime', 'tags',
+            'group', 'sa_lifetime', 'comments', 'tags',
         )
         )
 
 
 
 
@@ -169,7 +169,7 @@ class IKEPolicyImportForm(NetBoxModelImportForm):
     class Meta:
     class Meta:
         model = IKEPolicy
         model = IKEPolicy
         fields = (
         fields = (
-            'name', 'description', 'version', 'mode', 'proposals', 'preshared_key', 'tags',
+            'name', 'description', 'version', 'mode', 'proposals', 'preshared_key', 'comments', 'tags',
         )
         )
 
 
 
 
@@ -187,7 +187,7 @@ class IPSecProposalImportForm(NetBoxModelImportForm):
         model = IPSecProposal
         model = IPSecProposal
         fields = (
         fields = (
             'name', 'description', 'encryption_algorithm', 'authentication_algorithm', 'sa_lifetime_seconds',
             'name', 'description', 'encryption_algorithm', 'authentication_algorithm', 'sa_lifetime_seconds',
-            'sa_lifetime_data', 'tags',
+            'sa_lifetime_data', 'comments', 'tags',
         )
         )
 
 
 
 
@@ -205,7 +205,7 @@ class IPSecPolicyImportForm(NetBoxModelImportForm):
     class Meta:
     class Meta:
         model = IPSecPolicy
         model = IPSecPolicy
         fields = (
         fields = (
-            'name', 'description', 'proposals', 'pfs_group', 'tags',
+            'name', 'description', 'proposals', 'pfs_group', 'comments', 'tags',
         )
         )
 
 
 
 

+ 4 - 4
netbox/vpn/forms/model_forms.py

@@ -280,7 +280,7 @@ class IKEProposalForm(NetBoxModelForm):
         model = IKEProposal
         model = IKEProposal
         fields = [
         fields = [
             'name', 'description', 'authentication_method', 'encryption_algorithm', 'authentication_algorithm', 'group',
             'name', 'description', 'authentication_method', 'encryption_algorithm', 'authentication_algorithm', 'group',
-            'sa_lifetime', 'tags',
+            'sa_lifetime', 'comments', 'tags',
         ]
         ]
 
 
 
 
@@ -298,7 +298,7 @@ class IKEPolicyForm(NetBoxModelForm):
     class Meta:
     class Meta:
         model = IKEPolicy
         model = IKEPolicy
         fields = [
         fields = [
-            'name', 'description', 'version', 'mode', 'proposals', 'preshared_key', 'tags',
+            'name', 'description', 'version', 'mode', 'proposals', 'preshared_key', 'comments', 'tags',
         ]
         ]
 
 
 
 
@@ -315,7 +315,7 @@ class IPSecProposalForm(NetBoxModelForm):
         model = IPSecProposal
         model = IPSecProposal
         fields = [
         fields = [
             'name', 'description', 'encryption_algorithm', 'authentication_algorithm', 'sa_lifetime_seconds',
             'name', 'description', 'encryption_algorithm', 'authentication_algorithm', 'sa_lifetime_seconds',
-            'sa_lifetime_data', 'tags',
+            'sa_lifetime_data', 'comments', 'tags',
         ]
         ]
 
 
 
 
@@ -333,7 +333,7 @@ class IPSecPolicyForm(NetBoxModelForm):
     class Meta:
     class Meta:
         model = IPSecPolicy
         model = IPSecPolicy
         fields = [
         fields = [
-            'name', 'description', 'proposals', 'pfs_group', 'tags',
+            'name', 'description', 'proposals', 'pfs_group', 'comments', 'tags',
         ]
         ]
 
 
 
 

+ 8 - 4
netbox/vpn/migrations/0001_initial.py

@@ -23,8 +23,9 @@ class Migration(migrations.Migration):
                 ('created', models.DateTimeField(auto_now_add=True, null=True)),
                 ('created', models.DateTimeField(auto_now_add=True, null=True)),
                 ('last_updated', models.DateTimeField(auto_now=True, null=True)),
                 ('last_updated', models.DateTimeField(auto_now=True, null=True)),
                 ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)),
                 ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)),
-                ('name', models.CharField(max_length=100, unique=True)),
                 ('description', models.CharField(blank=True, max_length=200)),
                 ('description', models.CharField(blank=True, max_length=200)),
+                ('comments', models.TextField(blank=True)),
+                ('name', models.CharField(max_length=100, unique=True)),
                 ('version', models.PositiveSmallIntegerField(default=2)),
                 ('version', models.PositiveSmallIntegerField(default=2)),
                 ('mode', models.CharField()),
                 ('mode', models.CharField()),
                 ('preshared_key', models.TextField(blank=True)),
                 ('preshared_key', models.TextField(blank=True)),
@@ -42,8 +43,9 @@ class Migration(migrations.Migration):
                 ('created', models.DateTimeField(auto_now_add=True, null=True)),
                 ('created', models.DateTimeField(auto_now_add=True, null=True)),
                 ('last_updated', models.DateTimeField(auto_now=True, null=True)),
                 ('last_updated', models.DateTimeField(auto_now=True, null=True)),
                 ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)),
                 ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)),
-                ('name', models.CharField(max_length=100, unique=True)),
                 ('description', models.CharField(blank=True, max_length=200)),
                 ('description', models.CharField(blank=True, max_length=200)),
+                ('comments', models.TextField(blank=True)),
+                ('name', models.CharField(max_length=100, unique=True)),
                 ('pfs_group', models.PositiveSmallIntegerField(blank=True, null=True)),
                 ('pfs_group', models.PositiveSmallIntegerField(blank=True, null=True)),
             ],
             ],
             options={
             options={
@@ -123,8 +125,9 @@ class Migration(migrations.Migration):
                 ('created', models.DateTimeField(auto_now_add=True, null=True)),
                 ('created', models.DateTimeField(auto_now_add=True, null=True)),
                 ('last_updated', models.DateTimeField(auto_now=True, null=True)),
                 ('last_updated', models.DateTimeField(auto_now=True, null=True)),
                 ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)),
                 ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)),
-                ('name', models.CharField(max_length=100, unique=True)),
                 ('description', models.CharField(blank=True, max_length=200)),
                 ('description', models.CharField(blank=True, max_length=200)),
+                ('comments', models.TextField(blank=True)),
+                ('name', models.CharField(max_length=100, unique=True)),
                 ('encryption_algorithm', models.CharField()),
                 ('encryption_algorithm', models.CharField()),
                 ('authentication_algorithm', models.CharField()),
                 ('authentication_algorithm', models.CharField()),
                 ('sa_lifetime_seconds', models.PositiveIntegerField(blank=True, null=True)),
                 ('sa_lifetime_seconds', models.PositiveIntegerField(blank=True, null=True)),
@@ -154,8 +157,9 @@ class Migration(migrations.Migration):
                 ('created', models.DateTimeField(auto_now_add=True, null=True)),
                 ('created', models.DateTimeField(auto_now_add=True, null=True)),
                 ('last_updated', models.DateTimeField(auto_now=True, null=True)),
                 ('last_updated', models.DateTimeField(auto_now=True, null=True)),
                 ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)),
                 ('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)),
-                ('name', models.CharField(max_length=100, unique=True)),
                 ('description', models.CharField(blank=True, max_length=200)),
                 ('description', models.CharField(blank=True, max_length=200)),
+                ('comments', models.TextField(blank=True)),
+                ('name', models.CharField(max_length=100, unique=True)),
                 ('authentication_method', models.CharField()),
                 ('authentication_method', models.CharField()),
                 ('encryption_algorithm', models.CharField()),
                 ('encryption_algorithm', models.CharField()),
                 ('authentication_algorithm', models.CharField()),
                 ('authentication_algorithm', models.CharField()),

+ 5 - 25
netbox/vpn/models/crypto.py

@@ -2,7 +2,7 @@ from django.db import models
 from django.urls import reverse
 from django.urls import reverse
 from django.utils.translation import gettext_lazy as _
 from django.utils.translation import gettext_lazy as _
 
 
-from netbox.models import NetBoxModel, PrimaryModel
+from netbox.models import PrimaryModel
 from vpn.choices import *
 from vpn.choices import *
 
 
 __all__ = (
 __all__ = (
@@ -18,17 +18,12 @@ __all__ = (
 # IKE
 # IKE
 #
 #
 
 
-class IKEProposal(NetBoxModel):
+class IKEProposal(PrimaryModel):
     name = models.CharField(
     name = models.CharField(
         verbose_name=_('name'),
         verbose_name=_('name'),
         max_length=100,
         max_length=100,
         unique=True
         unique=True
     )
     )
-    description = models.CharField(
-        verbose_name=_('description'),
-        max_length=200,
-        blank=True
-    )
     authentication_method = models.CharField(
     authentication_method = models.CharField(
         verbose_name=('authentication method'),
         verbose_name=('authentication method'),
         choices=AuthenticationMethodChoices
         choices=AuthenticationMethodChoices
@@ -69,17 +64,12 @@ class IKEProposal(NetBoxModel):
         return reverse('vpn:ikeproposal', args=[self.pk])
         return reverse('vpn:ikeproposal', args=[self.pk])
 
 
 
 
-class IKEPolicy(NetBoxModel):
+class IKEPolicy(PrimaryModel):
     name = models.CharField(
     name = models.CharField(
         verbose_name=_('name'),
         verbose_name=_('name'),
         max_length=100,
         max_length=100,
         unique=True
         unique=True
     )
     )
-    description = models.CharField(
-        verbose_name=_('description'),
-        max_length=200,
-        blank=True
-    )
     version = models.PositiveSmallIntegerField(
     version = models.PositiveSmallIntegerField(
         verbose_name=_('version'),
         verbose_name=_('version'),
         choices=IKEVersionChoices,
         choices=IKEVersionChoices,
@@ -122,17 +112,12 @@ class IKEPolicy(NetBoxModel):
 # IPSec
 # IPSec
 #
 #
 
 
-class IPSecProposal(NetBoxModel):
+class IPSecProposal(PrimaryModel):
     name = models.CharField(
     name = models.CharField(
         verbose_name=_('name'),
         verbose_name=_('name'),
         max_length=100,
         max_length=100,
         unique=True
         unique=True
     )
     )
-    description = models.CharField(
-        verbose_name=_('description'),
-        max_length=200,
-        blank=True
-    )
     encryption_algorithm = models.CharField(
     encryption_algorithm = models.CharField(
         verbose_name=_('encryption'),
         verbose_name=_('encryption'),
         choices=EncryptionAlgorithmChoices
         choices=EncryptionAlgorithmChoices
@@ -170,17 +155,12 @@ class IPSecProposal(NetBoxModel):
         return reverse('vpn:ipsecproposal', args=[self.pk])
         return reverse('vpn:ipsecproposal', args=[self.pk])
 
 
 
 
-class IPSecPolicy(NetBoxModel):
+class IPSecPolicy(PrimaryModel):
     name = models.CharField(
     name = models.CharField(
         verbose_name=_('name'),
         verbose_name=_('name'),
         max_length=100,
         max_length=100,
         unique=True
         unique=True
     )
     )
-    description = models.CharField(
-        verbose_name=_('description'),
-        max_length=200,
-        blank=True
-    )
     proposals = models.ManyToManyField(
     proposals = models.ManyToManyField(
         to='vpn.IPSecProposal',
         to='vpn.IPSecProposal',
         related_name='ipsec_policies',
         related_name='ipsec_policies',

+ 4 - 0
netbox/vpn/search.py

@@ -20,6 +20,7 @@ class IKEProposalIndex(SearchIndex):
     fields = (
     fields = (
         ('name', 100),
         ('name', 100),
         ('description', 500),
         ('description', 500),
+        ('comments', 5000),
     )
     )
     display_attrs = ('description',)
     display_attrs = ('description',)
 
 
@@ -30,6 +31,7 @@ class IKEPolicyIndex(SearchIndex):
     fields = (
     fields = (
         ('name', 100),
         ('name', 100),
         ('description', 500),
         ('description', 500),
+        ('comments', 5000),
     )
     )
     display_attrs = ('description',)
     display_attrs = ('description',)
 
 
@@ -40,6 +42,7 @@ class IPSecProposalIndex(SearchIndex):
     fields = (
     fields = (
         ('name', 100),
         ('name', 100),
         ('description', 500),
         ('description', 500),
+        ('comments', 5000),
     )
     )
     display_attrs = ('description',)
     display_attrs = ('description',)
 
 
@@ -50,6 +53,7 @@ class IPSecPolicyIndex(SearchIndex):
     fields = (
     fields = (
         ('name', 100),
         ('name', 100),
         ('description', 500),
         ('description', 500),
+        ('comments', 5000),
     )
     )
     display_attrs = ('description',)
     display_attrs = ('description',)
 
 

+ 17 - 5
netbox/vpn/tables/crypto.py

@@ -33,6 +33,9 @@ class IKEProposalTable(NetBoxTable):
     sa_lifetime = tables.Column(
     sa_lifetime = tables.Column(
         verbose_name=_('SA Lifetime')
         verbose_name=_('SA Lifetime')
     )
     )
+    comments = columns.MarkdownColumn(
+        verbose_name=_('Comments'),
+    )
     tags = columns.TagColumn(
     tags = columns.TagColumn(
         url_name='vpn:ikeproposal_list'
         url_name='vpn:ikeproposal_list'
     )
     )
@@ -41,7 +44,7 @@ class IKEProposalTable(NetBoxTable):
         model = IKEProposal
         model = IKEProposal
         fields = (
         fields = (
             'pk', 'id', 'name', 'authentication_method', 'encryption_algorithm', 'authentication_algorithm',
             'pk', 'id', 'name', 'authentication_method', 'encryption_algorithm', 'authentication_algorithm',
-            'group', 'sa_lifetime', 'description', 'tags', 'created', 'last_updated',
+            'group', 'sa_lifetime', 'description', 'comments', 'tags', 'created', 'last_updated',
         )
         )
         default_columns = (
         default_columns = (
             'pk', 'name', 'authentication_method', 'encryption_algorithm', 'authentication_algorithm', 'group',
             'pk', 'name', 'authentication_method', 'encryption_algorithm', 'authentication_algorithm', 'group',
@@ -67,6 +70,9 @@ class IKEPolicyTable(NetBoxTable):
     preshared_key = tables.Column(
     preshared_key = tables.Column(
         verbose_name=_('Pre-shared Key')
         verbose_name=_('Pre-shared Key')
     )
     )
+    comments = columns.MarkdownColumn(
+        verbose_name=_('Comments'),
+    )
     tags = columns.TagColumn(
     tags = columns.TagColumn(
         url_name='vpn:ikepolicy_list'
         url_name='vpn:ikepolicy_list'
     )
     )
@@ -74,8 +80,8 @@ class IKEPolicyTable(NetBoxTable):
     class Meta(NetBoxTable.Meta):
     class Meta(NetBoxTable.Meta):
         model = IKEPolicy
         model = IKEPolicy
         fields = (
         fields = (
-            'pk', 'id', 'name', 'version', 'mode', 'proposals', 'preshared_key', 'description', 'tags', 'created',
-            'last_updated',
+            'pk', 'id', 'name', 'version', 'mode', 'proposals', 'preshared_key', 'description', 'comments', 'tags',
+            'created', 'last_updated',
         )
         )
         default_columns = (
         default_columns = (
             'pk', 'name', 'version', 'mode', 'proposals', 'description',
             'pk', 'name', 'version', 'mode', 'proposals', 'description',
@@ -99,6 +105,9 @@ class IPSecProposalTable(NetBoxTable):
     sa_lifetime_data = tables.Column(
     sa_lifetime_data = tables.Column(
         verbose_name=_('SA Lifetime (KB)')
         verbose_name=_('SA Lifetime (KB)')
     )
     )
+    comments = columns.MarkdownColumn(
+        verbose_name=_('Comments'),
+    )
     tags = columns.TagColumn(
     tags = columns.TagColumn(
         url_name='vpn:ipsecproposal_list'
         url_name='vpn:ipsecproposal_list'
     )
     )
@@ -107,7 +116,7 @@ class IPSecProposalTable(NetBoxTable):
         model = IPSecProposal
         model = IPSecProposal
         fields = (
         fields = (
             'pk', 'id', 'name', 'encryption_algorithm', 'authentication_algorithm', 'sa_lifetime_seconds',
             'pk', 'id', 'name', 'encryption_algorithm', 'authentication_algorithm', 'sa_lifetime_seconds',
-            'sa_lifetime_data', 'description', 'tags', 'created', 'last_updated',
+            'sa_lifetime_data', 'description', 'comments', 'tags', 'created', 'last_updated',
         )
         )
         default_columns = (
         default_columns = (
             'pk', 'name', 'encryption_algorithm', 'authentication_algorithm', 'sa_lifetime_seconds',
             'pk', 'name', 'encryption_algorithm', 'authentication_algorithm', 'sa_lifetime_seconds',
@@ -127,6 +136,9 @@ class IPSecPolicyTable(NetBoxTable):
     pfs_group = tables.Column(
     pfs_group = tables.Column(
         verbose_name=_('PFS Group')
         verbose_name=_('PFS Group')
     )
     )
+    comments = columns.MarkdownColumn(
+        verbose_name=_('Comments'),
+    )
     tags = columns.TagColumn(
     tags = columns.TagColumn(
         url_name='vpn:ipsecpolicy_list'
         url_name='vpn:ipsecpolicy_list'
     )
     )
@@ -134,7 +146,7 @@ class IPSecPolicyTable(NetBoxTable):
     class Meta(NetBoxTable.Meta):
     class Meta(NetBoxTable.Meta):
         model = IPSecPolicy
         model = IPSecPolicy
         fields = (
         fields = (
-            'pk', 'id', 'name', 'proposals', 'pfs_group', 'description', 'tags', 'created', 'last_updated',
+            'pk', 'id', 'name', 'proposals', 'pfs_group', 'description', 'comments', 'tags', 'created', 'last_updated',
         )
         )
         default_columns = (
         default_columns = (
             'pk', 'name', 'proposals', 'pfs_group', 'description',
             'pk', 'name', 'proposals', 'pfs_group', 'description',