From f921b1721a7d968d30ac04faf879d7111b1eb90d Mon Sep 17 00:00:00 2001
From: Pim van Pelt <pim@ipng.nl>
Date: Thu, 17 Mar 2022 00:15:18 +0000
Subject: [PATCH] Expand autocreated LCP namelen to all possible (dot1q, qin*)
 scenarios. Allow manually set LCP to be 15char in length

---
 schema.yaml                       |  8 ++++----
 unittest/error-schema-field2.yaml |  4 +++-
 unittest/error-subinterface3.yaml | 15 +++++++++++++--
 validator/interface.py            |  3 +++
 4 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/schema.yaml b/schema.yaml
index 538f359..debd364 100644
--- a/schema.yaml
+++ b/schema.yaml
@@ -13,13 +13,13 @@ vxlan:
 bridgedomain:
   description: str(exclude='\'"',len=64,required=False)
   mtu: int(min=128,max=9216,required=False)
-  lcp: str(max=8,matches='[a-z]+[a-z0-9-]{,7}',required=False)
+  lcp: str(max=15,matches='[a-z]+[a-z0-9-]{,7}',required=False)
   addresses: list(ip_interface(),min=1,max=6,required=False)
   interfaces: list(str())
 ---
 loopback:
   description: str(exclude='\'"',len=64,required=False)
-  lcp: str(max=8,matches='[a-z]+[a-z0-9-]{,7}',required=False)
+  lcp: str(max=15,matches='[a-z]+[a-z0-9-]{,7}',required=False)
   mtu: int(min=128,max=9216,required=False)
   addresses: list(ip_interface(),min=1,max=6,required=False)
 ---
@@ -30,7 +30,7 @@ bondethernet:
 interface:
   description: str(exclude='\'"',len=64,required=False)
   mac: mac(required=False)
-  lcp: str(max=8,matches='[a-z]+[a-z0-9-]{,7}',required=False)
+  lcp: str(max=15,matches='[a-z]+[a-z0-9-]{,7}',required=False)
   mtu: int(min=128,max=9216,required=False)
   addresses: list(ip_interface(),min=1,max=6,required=False)
   sub-interfaces: map(include('sub-interface'),key=int(min=1,max=4294967295),required=False)
@@ -38,7 +38,7 @@ interface:
 ---
 sub-interface:
   description: str(exclude='\'"',len=64,required=False)
-  lcp: str(max=8,matches='[a-z]+[a-z0-9-]{,7}',required=False)
+  lcp: str(max=15,matches='[a-z]+[a-z0-9-]{,7}',required=False)
   mtu: int(min=128,max=9216,required=False)
   addresses: list(ip_interface(),required=False)
   encapsulation: include('encapsulation',required=False)
diff --git a/unittest/error-schema-field2.yaml b/unittest/error-schema-field2.yaml
index e0d1fa3..e774f70 100644
--- a/unittest/error-schema-field2.yaml
+++ b/unittest/error-schema-field2.yaml
@@ -4,7 +4,8 @@ test:
     expected:
      - "yamale: .* is not a "
      - "yamale: .*: Unexpected element"
-    count: 12
+     - "Length of .* is greater than 15"
+    count: 13
 ---
 interfaces:
   GigabitEthernet1/0/0:
@@ -20,6 +21,7 @@ interfaces:
 
   GigabitEthernet1/0/1:
     mtu: 1500
+    lcp: "a234567890123456"
     sub-interfaces:
       "string":
         description: "the sub-int key should be an int"
diff --git a/unittest/error-subinterface3.yaml b/unittest/error-subinterface3.yaml
index 19be078..cb93df4 100644
--- a/unittest/error-subinterface3.yaml
+++ b/unittest/error-subinterface3.yaml
@@ -2,12 +2,23 @@ test:
   description: "The length of the LCP name is too long"
   errors:
     expected:
-     - "Length .* is greater than 8"
+    - "sub-interface .* has LCP with too long name .*"
+    count: 2
 ---
 interfaces:
   GigabitEthernet1/0/0:
-    lcp: "e01234567"
+    lcp: "e23456789012"
     sub-interfaces:
       100:
         description: "VLAN 100"
+  GigabitEthernet1/0/1:
+    lcp: "e2345678"
+    sub-interfaces:
+      100:
+        description: "VLAN 100"
+      101:
+        description: "QinQ 101"
+        encapsulation:
+          dot1q: 100
+          inner-dot1q: 100
 
diff --git a/validator/interface.py b/validator/interface.py
index 9c1ae3a..d151768 100644
--- a/validator/interface.py
+++ b/validator/interface.py
@@ -334,6 +334,9 @@ def validate_interfaces(yaml):
         if iface_lcp and not lcp.is_unique(yaml, iface_lcp):
             msgs.append("interface %s does not have a unique LCP name %s" % (ifname, iface_lcp))
             result = False
+        if iface_lcp and len(iface_lcp)>15:
+            msgs.append("interface %s has LCP with too long name %s" % (fname, iface_lcp))
+            result = False
 
         if 'addresses' in iface:
             for a in iface['addresses']: