From bf3559604b2bcb027093e2d1afa68a8de8503c15 Mon Sep 17 00:00:00 2001
From: Mati Alfaro <mati@marvell.com>
Date: Thu, 29 Feb 2024 05:09:50 +0200
Subject: [PATCH] Add vlan validation in config interface ip add command
 (#3155)

---
 config/main.py          | 12 +++++++++++-
 tests/ip_config_test.py | 32 ++++++++++++++++++++++++++++++++
 2 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/config/main.py b/config/main.py
index f2113f255f..fc9c72f07e 100644
--- a/config/main.py
+++ b/config/main.py
@@ -4513,7 +4513,11 @@ def fec(ctx, interface_name, interface_fec, verbose):
 def ip(ctx):
     """Set IP interface attributes"""
     pass
-
+  
+def validate_vlan_exists(db,text):
+    data = db.get_table('VLAN')
+    keys = list(data.keys())
+    return text in keys
 #
 # 'add' subcommand
 #
@@ -4577,6 +4581,12 @@ def add(ctx, interface_name, ip_addr, gw):
     table_name = get_interface_table_name(interface_name)
     if table_name == "":
         ctx.fail("'interface_name' is not valid. Valid names [Ethernet/PortChannel/Vlan/Loopback]")
+    
+    if table_name == "VLAN_INTERFACE":
+        if not validate_vlan_exists(config_db, interface_name):
+            ctx.fail(f"Error: {interface_name} does not exist. Vlan must be created before adding an IP address")
+            return
+    
     interface_entry = config_db.get_entry(table_name, interface_name)
     if len(interface_entry) == 0:
         if table_name == "VLAN_SUB_INTERFACE":
diff --git a/tests/ip_config_test.py b/tests/ip_config_test.py
index 2f262a4a09..b227c76ff3 100644
--- a/tests/ip_config_test.py
+++ b/tests/ip_config_test.py
@@ -13,6 +13,7 @@
 import utilities_common.bgp_util as bgp_util
 
 ERROR_MSG = "Error: IP address is not valid"
+NOT_EXIST_VLAN_ERROR_MSG ="does not exist"
 
 INVALID_VRF_MSG ="""\
 Usage: bind [OPTIONS] <interface_name> <vrf_name>
@@ -43,6 +44,37 @@ def setup_class(cls):
     def mock_run_bgp_command():
         return ""
 
+    def test_add_vlan_interface_ipv4(self):
+        db = Db()
+        runner = CliRunner()
+        obj = {'config_db':db.cfgdb}
+
+        # config int ip add Vlan100 1.1.1.1/24  
+        result = runner.invoke(config.config.commands["interface"].commands["ip"].commands["add"], ["Vlan100", "1.1.1.1/24"], obj=obj)
+        print(result.exit_code, result.output)
+        assert result.exit_code != 0
+        assert NOT_EXIST_VLAN_ERROR_MSG in result.output
+
+        # create vlan 4093
+        result = runner.invoke(config.config.commands["vlan"].commands["add"], ["4093"], obj=db)
+        # config int ip add Vlan4093 1.1.1.1/24
+        result = runner.invoke(config.config.commands["interface"].commands["ip"].commands["add"], ["Vlan4093", "1.1.1.1/24"], obj=obj)
+        print(result.exit_code, result.output)
+        assert result.exit_code == 0
+
+        # config int ip add Vlan000000000000003 1.1.1.1/24
+        result = runner.invoke(config.config.commands["interface"].commands["ip"].commands["add"], ["Vlan000000000000003", "1.1.1.1/24"], obj=obj)
+        print(result.exit_code, result.output)
+        assert result.exit_code != 0
+        assert NOT_EXIST_VLAN_ERROR_MSG in result.output
+
+        # config int ip add Vlan1.2 1.1.1.1/24
+        result = runner.invoke(config.config.commands["interface"].commands["ip"].commands["add"], ["Vlan1.2", "1.1.1.1/24"], obj=obj)
+        print(result.exit_code, result.output)
+        assert result.exit_code != 0
+        assert NOT_EXIST_VLAN_ERROR_MSG in result.output
+
+
     def test_add_del_interface_valid_ipv4(self):
         db = Db()
         runner = CliRunner()