From 10047730b96aa30a99169a374802fd5ed69e4e05 Mon Sep 17 00:00:00 2001
From: armingol <pablo.armingolrobles@telefonica.com>
Date: Thu, 30 May 2024 10:48:17 +0200
Subject: [PATCH] first version

---
 manifests/deviceservice.yaml                  |  2 +-
 manifests/serviceservice.yaml                 |  2 +-
 manifests/webuiservice.yaml                   |  2 +-
 my_deploy.sh                                  |  4 +--
 proto/context.proto                           | 11 ++++++--
 src/context/service/database/ConfigRule.py    |  3 +++
 src/context/service/database/Link.py          | 12 ++++-----
 .../database/models/ConfigRuleModel.py        |  5 ++--
 src/device/requirements.in                    |  2 +-
 .../drivers/openconfig/OpenConfigDriver.py    |  2 ++
 .../service_handler_api/SettingsHandler.py    | 25 +++++++++++++++++++
 src/webui/service/main/routes.py              |  2 +-
 12 files changed, 55 insertions(+), 17 deletions(-)

diff --git a/manifests/deviceservice.yaml b/manifests/deviceservice.yaml
index e49ba2399..3c9a941e0 100644
--- a/manifests/deviceservice.yaml
+++ b/manifests/deviceservice.yaml
@@ -39,7 +39,7 @@ spec:
             - containerPort: 9192
           env:
             - name: LOG_LEVEL
-              value: "INFO"
+              value: "DEBUG"
           startupProbe:
             exec:
               command: ["/bin/grpc_health_probe", "-addr=:2020"]
diff --git a/manifests/serviceservice.yaml b/manifests/serviceservice.yaml
index 1dd383d61..bcfb47ee3 100644
--- a/manifests/serviceservice.yaml
+++ b/manifests/serviceservice.yaml
@@ -36,7 +36,7 @@ spec:
             - containerPort: 9192
           env:
             - name: LOG_LEVEL
-              value: "INFO"
+              value: "DEBUG"
           readinessProbe:
             exec:
               command: ["/bin/grpc_health_probe", "-addr=:3030"]
diff --git a/manifests/webuiservice.yaml b/manifests/webuiservice.yaml
index a519aa4a2..d25f5f887 100644
--- a/manifests/webuiservice.yaml
+++ b/manifests/webuiservice.yaml
@@ -39,7 +39,7 @@ spec:
             - containerPort: 8004
           env:
             - name: LOG_LEVEL
-              value: "INFO"
+              value: "DEBUG"
             - name: WEBUISERVICE_SERVICE_BASEURL_HTTP
               value: "/webui/"
           readinessProbe:
diff --git a/my_deploy.sh b/my_deploy.sh
index 8417f6eae..89ede956e 100755
--- a/my_deploy.sh
+++ b/my_deploy.sh
@@ -106,7 +106,7 @@ export CRDB_DATABASE="tfs"
 export CRDB_DEPLOY_MODE="single"
 
 # Disable flag for dropping database, if it exists.
-export CRDB_DROP_DATABASE_IF_EXISTS=""
+export CRDB_DROP_DATABASE_IF_EXISTS="YES"
 
 # Disable flag for re-deploying CockroachDB from scratch.
 export CRDB_REDEPLOY=""
@@ -154,7 +154,7 @@ export QDB_TABLE_MONITORING_KPIS="tfs_monitoring_kpis"
 export QDB_TABLE_SLICE_GROUPS="tfs_slice_groups"
 
 # Disable flag for dropping tables if they exist.
-export QDB_DROP_TABLES_IF_EXIST=""
+export QDB_DROP_TABLES_IF_EXIST="YES"
 
 # Disable flag for re-deploying QuestDB from scratch.
 export QDB_REDEPLOY=""
diff --git a/proto/context.proto b/proto/context.proto
index 87f69132d..9cfe8fe07 100644
--- a/proto/context.proto
+++ b/proto/context.proto
@@ -300,6 +300,7 @@ enum ServiceTypeEnum {
   SERVICETYPE_TE = 4;
   SERVICETYPE_E2E = 5;
   SERVICETYPE_OPTICAL_CONNECTIVITY = 6;
+  SERVICETYPE_IPLINK = 7;
 }
 
 enum ServiceStatusEnum {
@@ -512,11 +513,17 @@ message ConfigRule_ACL {
   acl.AclRuleSet rule_set = 2;
 }
 
+message ConfigRule_IP_LIK {
+  EndPointId endpoint_id = 1;
+  string  subnet_ip = 2;
+}
+
 message ConfigRule {
   ConfigActionEnum action = 1;
   oneof config_rule {
-    ConfigRule_Custom custom = 2;
-    ConfigRule_ACL acl = 3;
+    ConfigRule_Custom custom  = 2;
+    ConfigRule_ACL acl        = 3;
+    ConfigRule_IP_LIK ip_link = 4;
   }
 }
 
diff --git a/src/context/service/database/ConfigRule.py b/src/context/service/database/ConfigRule.py
index 7d816b3e8..0f204c505 100644
--- a/src/context/service/database/ConfigRule.py
+++ b/src/context/service/database/ConfigRule.py
@@ -68,6 +68,9 @@ def compose_config_rules_data(
             _, _, endpoint_uuid = endpoint_get_uuid(config_rule.acl.endpoint_id, allow_random=False)
             rule_set_name = config_rule.acl.rule_set.name
             configrule_name = '{:s}:{:s}:{:s}:{:s}'.format(parent_kind, kind.value, endpoint_uuid, rule_set_name)
+        elif kind == ConfigRuleKindEnum.IP_LINK:
+            _, _, endpoint_uuid = endpoint_get_uuid(config_rule.ip_link.endpoint_id, allow_random=False)
+            configrule_name = '{:s}:{:s}:{:s}'.format(parent_kind, kind.value, endpoint_uuid)
         else:
             MSG = 'Name for ConfigRule({:s}) cannot be inferred '+\
                   '(device_uuid={:s}, service_uuid={:s}, slice_uuid={:s})'
diff --git a/src/context/service/database/Link.py b/src/context/service/database/Link.py
index 8aa2563e4..87ec27eb8 100644
--- a/src/context/service/database/Link.py
+++ b/src/context/service/database/Link.py
@@ -74,12 +74,12 @@ def link_set(db_engine : Engine, messagebroker : MessageBroker, request : Link)
     related_topologies : List[Dict] = list()
 
     # By default, always add link to default Context/Topology
-    _,topology_uuid = topology_get_uuid(TopologyId(), allow_random=False, allow_default=True)
-    related_topologies.append({
-        'topology_uuid': topology_uuid,
-        'link_uuid'    : link_uuid,
-    })
-    topology_uuids.add(topology_uuid)
+    # _,topology_uuid = topology_get_uuid(TopologyId(), allow_random=False, allow_default=True)
+    # related_topologies.append({
+    #     'topology_uuid': topology_uuid,
+    #     'link_uuid'    : link_uuid,
+    # })
+    # topology_uuids.add(topology_uuid)
 
     link_endpoints_data : List[Dict] = list()
     for i,endpoint_id in enumerate(request.link_endpoint_ids):
diff --git a/src/context/service/database/models/ConfigRuleModel.py b/src/context/service/database/models/ConfigRuleModel.py
index f57c90b82..73a667e6b 100644
--- a/src/context/service/database/models/ConfigRuleModel.py
+++ b/src/context/service/database/models/ConfigRuleModel.py
@@ -21,8 +21,9 @@ from ._Base import _Base
 
 # Enum values should match name of field in ConfigRule message
 class ConfigRuleKindEnum(enum.Enum):
-    CUSTOM = 'custom'
-    ACL    = 'acl'
+    CUSTOM  = 'custom'
+    ACL     = 'acl'
+    IP_LINK = 'ip_link'
 
 class DeviceConfigRuleModel(_Base):
     __tablename__ = 'device_configrule'
diff --git a/src/device/requirements.in b/src/device/requirements.in
index 73ea741d1..6f20b0de1 100644
--- a/src/device/requirements.in
+++ b/src/device/requirements.in
@@ -23,7 +23,7 @@ Flask==2.1.3
 Flask-HTTPAuth==4.5.0
 Flask-RESTful==0.3.9
 Jinja2==3.0.3
-ncclient==0.6.13
+ncclient==0.6.15
 p4runtime==1.3.0
 pandas==1.5.*
 paramiko==2.9.2
diff --git a/src/device/service/drivers/openconfig/OpenConfigDriver.py b/src/device/service/drivers/openconfig/OpenConfigDriver.py
index a592b5157..d6851e06d 100644
--- a/src/device/service/drivers/openconfig/OpenConfigDriver.py
+++ b/src/device/service/drivers/openconfig/OpenConfigDriver.py
@@ -209,6 +209,8 @@ def edit_config(
     commit_per_rule=False, target='running', default_operation='merge', test_option=None, error_option=None,
     format='xml' # pylint: disable=redefined-builtin
 ):
+    logger.debug('Reglas mandadas = {:s}'.format(str(resources)))
+
     str_method = 'DeleteConfig' if delete else 'SetConfig'
     results = []
     if "L2VSI" in resources[0][1] and netconf_handler.vendor == "CISCO":
diff --git a/src/service/service/service_handler_api/SettingsHandler.py b/src/service/service/service_handler_api/SettingsHandler.py
index 293de54aa..2afa4cbbf 100644
--- a/src/service/service/service_handler_api/SettingsHandler.py
+++ b/src/service/service/service_handler_api/SettingsHandler.py
@@ -47,6 +47,12 @@ class SettingsHandler:
             ACL_KEY_TEMPLATE = '/device[{:s}]/endpoint[{:s}]/index[{:d}]/acl_ruleset[{:s}]'
             key_or_path = ACL_KEY_TEMPLATE.format(device_uuid, endpoint_name,endpoint_index, acl_ruleset_name)
             value = grpc_message_to_json(config_rule.acl)
+        elif kind == 'ip_link':
+            device_uuid = config_rule.ip_link.device1
+            endpoint_uuid = config_rule.ip_link.interface
+            IP_LINK_KEY_TEMPLATE = '/device[{:s}]/endpoint[{:s}]/ip_link'
+            key_or_path = IP_LINK_KEY_TEMPLATE.format(device_uuid, endpoint_uuid,)
+            value = config_rule.ip_link
         else:
             MSG = 'Unsupported Kind({:s}) in ConfigRule({:s})'
             LOGGER.warning(MSG.format(str(kind), grpc_message_to_json_string(config_rule)))
@@ -100,6 +106,25 @@ class SettingsHandler:
                     if not 'index[{:d}]'.format(acl_index) in res_key: continue
                     acl_rules.append((res_key, res_value))
         return acl_rules
+    
+    def get_endpoint_ip_link(self, device : Device, endpoint : EndPoint) -> List [Tuple]:
+        endpoint_name = endpoint.name
+        device_keys   = device.device_id.device_uuid.uuid,       device.name
+        endpoint_keys = endpoint.endpoint_id.endpoint_uuid.uuid, endpoint.name
+        ip_links = []
+        for device_key in device_keys:
+            for endpoint_key in endpoint_keys:
+                endpoint_settings_uri = '/device[{:s}]/endpoint[{:s}]'.format(device_key, endpoint_key)
+                endpoint_settings = self.get(endpoint_settings_uri)
+                if endpoint_settings is None: continue  
+                IP_LINK_KEY_TEMPLATE = '/device[{:s}]/endpoint[{:s}]/'.format(device_key, endpoint_name)
+                
+                results = dump_subtree(endpoint_settings)
+                for res_key, res_value in results: 
+                    if not res_key.startswith(IP_LINK_KEY_TEMPLATE): continue
+                    if not "ip_link" in res_key: continue
+                    ip_links.append((res_key, res_value))
+        return None
 
     def set(self, key_or_path : Union[str, List[str]], value : Any) -> None:
         set_subnode_value(self.__resolver, self.__config, key_or_path, value)
diff --git a/src/webui/service/main/routes.py b/src/webui/service/main/routes.py
index 52944a31c..84c561737 100644
--- a/src/webui/service/main/routes.py
+++ b/src/webui/service/main/routes.py
@@ -48,7 +48,7 @@ def process_descriptors(descriptors):
     descriptor_loader = DescriptorLoader(descriptors, num_workers=DESCRIPTOR_LOADER_NUM_WORKERS)
     results = descriptor_loader.process()
     for message,level in compose_notifications(results):
-        if level == 'error': LOGGER.warning('ERROR message={:s}'.format(str(message)))
+        if level == 'error': LOGGER.warning('ERROR message servicio ={:s}, {:s}'.format(str(message), str(descriptors)))
         flash(message, level)
 
 @main.route('/', methods=['GET', 'POST'])
-- 
GitLab