Fix TLS issues. Fix VES faultNotification issues. 64/1564/1
authorAlex Stancu <alexandru.stancu@highstreet-technologies.com>
Wed, 13 Nov 2019 12:40:21 +0000 (14:40 +0200)
committerAlex Stancu <alexandru.stancu@highstreet-technologies.com>
Wed, 13 Nov 2019 12:40:21 +0000 (14:40 +0200)
Signed-off-by: Alex Stancu <alexandru.stancu@highstreet-technologies.com>
Change-Id: I7e9835dbb0168558f3cb6b867a57da0a37e1c168

ntsimulator/README.md
ntsimulator/deploy/supervisord.conf
ntsimulator/scripts/tls/enable_ssh_key.sh
ntsimulator/scripts/tls/enable_tls.sh
ntsimulator/src/ntsimulator-manager/simulator-operations.c
ntsimulator/src/o-ran-notifications/o-ran-notifications.c
ntsimulator/src/utils/utils.c
ntsimulator/yang/sysrepo-configuration-load.sh

index ddadd00..a1c8d01 100644 (file)
@@ -1,2 +1,248 @@
-# ntsimulator
-Network Topology Simulator
+# Network Topology Simulator (NTS)
+
+The Network Topology Simulator is a framework that allows simulating devices that expose a management interface through a NETCONF/YANG interface.
+
+## Description
+
+### Overview
+
+The NETCONF/YANG management interface is simulated, and any YANG models can be loaded by the framework to be exposed. Random data is generated based on the specific models, such that each simulated device presents different data on its management interface.
+
+The NTS Manager can be used to specify the simulation details and to manage the simulation environment at runtime.
+
+The NTS framework is based on several open-source projects:
+* [Netopeer2](https://github.com/CESNET/Netopeer2) 
+* [libnetconf2](https://github.com/CESNET/libnetconf2) 
+* [libyang](https://github.com/CESNET/libyang)
+* [sysrepo](https://github.com/sysrepo/sysrepo) - all of these are used for the implementation of the NETCONF Server, both in the NTS Manager and in each simulated device
+* [cJSON](https://github.com/DaveGamble/cJSON) - used to create the JSON payloads for talking with the simulation framework
+* [pyang](https://github.com/mbj4668/pyang) - used to create random data from the YANG models that are exposed
+
+Each simulated device is represented as a docker container, where the NETCONF Server is running. The creation and deletion of docker containers associated with simulated devices is handled by the NTS Manager. The NTS Manager is also running as a docker container and exposes a NETCONF/YANG interface to control the simulation.
+
+### NTS Manager
+
+The purpose of the NTS Manager is to ease the utilization of the NTS framework. It enables the user to interact with the simulation framework through a NETCONF/YANG interface. The user has the ability to modify the simulation parameters at runtime and to see the status of the current state of the NTS. The NETCONF/YANG interface will be detailed below.
+
+```
+module: network-topology-simulator
+  +--rw simulator-config
+  |  +--rw simulated-devices?      uint32
+  |  +--rw mounted-devices?        uint32
+  |  +--rw notification-config
+  |  |  +--rw fault-notification-delay-period?   uint32
+  |  |  +--rw ves-heartbeat-period?              uint32
+  |  |  +--rw is-netconf-available?              boolean
+  |  |  +--rw is-ves-available?                  boolean
+  |  +--rw controller-details
+  |  |  +--rw controller-ip?         inet:ip-address
+  |  |  +--rw controller-port?       inet:port-number
+  |  |  +--rw controller-username?   string
+  |  |  +--rw controller-password?   string
+  |  +--rw ves-endpoint-details
+  |     +--rw ves-endpoint-ip?            inet:ip-address
+  |     +--rw ves-endpoint-port?          inet:port-number
+  |     +--rw ves-endpoint-auth-method?   authentication-method-type
+  |     +--rw ves-endpoint-username?      string
+  |     +--rw ves-endpoint-password?      string
+  |     +--rw ves-endpoint-certificate?   string
+  |     +--rw ves-registration?           boolean
+  +--ro simulator-status
+     +--ro simulation-usage-details
+     |  +--ro running-simulated-devices?   uint32
+     |  +--ro running-mounted-devices?     uint32
+     |  +--ro base-netconf-port?           uint32
+     |  +--ro cpu-usage?                   percent
+     |  +--ro mem-usage?                   uint32
+     +--ro simulated-devices-list* [uuid]
+        +--ro uuid                 string
+        +--ro device-ip?           string
+        +--ro device-port*         uint32
+        +--ro is-mounted?          boolean
+        +--ro operational-state?   operational-state-type
+
+  rpcs:
+    +---x restart-simulation
+    +---x add-key-pair-to-odl
+```
+
+#### Detailed information about the YANG attributes
+
+##### Configuration
+
+* **simulated-devices** - represents the number of simulated devices. The default value is 0, meaning that when the NTS is started, there are no simulated devices. When this value is increased to **n**, the NTS Manager starts docker containers in order to reach **n** simulated devices. If the value is decreased to **k**, the NTS Manager will remove docker containers, until the number of simulated devices reaches **k**;
+* **mounted-devices** - represents the number of devices to be mounted to an ODL based SDN Controller. The same phylosophy as in the case of the previous leaf applies. If this number is increased, the number of ODL mountpoints increases. Else, the simulated devices are being unmounted from ODL. The number of mounted devices cannot exceed the number of simulated devices. The details about the ODL controller where to mount/unmount are given by the **controller-details** container; **Please note that this cannot be set to a value > 0 if the *ves-registration* leaf is set to 'True'**; For each simulated device, 10 NETCONF endpoints will be mounted (7 SSH + 3 TLS). See **NETCONF Endpoints** section for more details.
+*  **notification-config** - this container groups the configuration about fault notification generation of each simulated device;
+* **fault-notification-delay-period** - the amount of seconds between two generated fault notifications. For example, if this has a value of *10*, each simulated device will generate a **random** fault notification every *10* seconds;
+* **ves-heartbeat-period** - the amount of seconds between VES heartbeat messages that can be generated by each simulated device. The details about the VES connection endpoint are given in the **ves-endpoint-details** container;
+* **is-netconf-available** - if set to 'True', NETCONF notifications will be sent when a random fault notification is generated, The NETCONF notification that is being sent is currently *o-ran-fm:alarm-notif*; if set to 'False', NETCONF notifications are not being sent out;
+* **is-ves-available** - if set to 'True', VES *faultNotification* messages will be sent when a random fault notification is generated; if set to 'False', VES *faultNotification* messages are not generated;
+* **controller-details** - this container groups the configuration related to the ODL based SDN controller that the simulated devices can connect to;
+* **controller-ip** - the IP address of the ODL based SDN controller where the simulated devices can be mounted. Only IPv4 is supported currently;
+* **controller-port** - the port of the ODL based SDN controller;
+* **controller-username** - the username to be used when connecting to the ODL based SDN controller;
+* **controller-password** - the password to be used when connecting to the ODL based SDN controller;
+* **ves-endpoint-details** - this container groups the configuration related to the VES endpoint where the VES messages are targeted;
+* **ves-endpoint-ip** - the IP address of the VES endpoint where VES messages are targeted;
+* **ves-endpoint-port** - the port address of the VES endpoint where VES messages are targeted;
+* **ves-endpoint-auth-method** - the authentication method to be used when sending the VES message to the VES endpoint. Possible values are:
+  + *no-auth* - no authentication;
+  + *cert-only* - certificate only authentication; in this case the certificate to be used for the communication must be configured;
+  + *basic-auth* - classic username/password authentication; in this case both the username and password need to be configured;
+  + *cert-basic-auth* - authentication that uses both username/password and a certificate; all three values need to be configured in this case;
+* **ves-endpoint-username** - the username to be used when authenticating to the VES endpoint;
+* **ves-endpoint-password** - the password to be used when authenticating to the VES endpoint;
+* **ves-endpoint-certificate** - the certificate to be used when authenticating to the VES endpoint;
+* **ves-registration** - if this is set to 'True' **when simulated devices are starting**, each simulated device will send out *pnfRegistration* VES messages to the configured VES endpoint; if this is set to 'False', *pnfRegistration* VES messages will not be sent out. **Please note that this cannot be set to 'True' is simulated devices are already mounted to ODL based SDN controller (mounted-devices leaf > 0)**; For each simulated device, 10 pnfRegistration VES messages will be sent out (7 SSH + 3 TLS). See **NETCONF Endpoints** section for more details.
+
+##### Status
+
+* **simulation-usage-details** - this container groups the information about the current simulator status;
+* **running-simulated-devices** - the current number of running simulated devices;
+* **running-mounted-devices** - the current number of running simulated devices that have been mounted to the ODL based SDN controller; For each simulated device, 10 NETCONF endpoints will be mounted (7 SSH + 3 TLS). See **NETCONF Endpoints** section for more details.
+* **base-netconf-port** - the port that was used as a base when craeting simulated devices;
+* **cpu-usage** - the percentage of the CPU used currently by the simulation framework;
+* **mem-usage** - the amount of RAM used (in MB) currently by the simulation framework;
+* **simulated-devices-list** - this list contains the details about each simulated devices that is currently running;
+* **uuid** - the Universally Unique ID of the simulated device;
+* **device-ip** - the IP address of the simulated device;
+* **device-port** - the port of the simulated device, where the NETCONF connection is exposed;
+* **is-mounted** - boolean to show whether the device is currently mounted to an ODL based SDN controller;
+* **operational-state** - the operational state of the current simulated device; it can be either *not-specified*, *created*, *running* or *exited*.
+
+##### RPCs
+
+* **add-key-pair-to-odl** - this RPC can be used to trigger the loading of a *keystore* entry in an ODL based SDN controller such that the controller can connect to the simulated devices via **TLS**. A private key, an associated certificate and a trusted certificate are loaded in the *keystore* entry in ODL. The certificate associated with the private key to be used by ODL in the TLS communication is signed by the same CA as the certificates used by the simulated devices, easing the TLS configuration in both the NETCONF Server and the ODL.
+* **restart-simulation** - this RPC is not yet implemented.
+
+### Simulated Device
+
+Each simulated device is represented as a docker container, inside which the NETCONF Server runs. The simulated device exposes the YANG models which are found inside the **yang** folder. A custom version of the *pyang* utility is used to generate random data for each of the YANG modules found inside the **yang** folder.
+
+#### NETCONF Endpoints
+
+Each simulated device exposes **10 NETCONF endpoints**, on 10 consecutive ports. The first simulated device uses the 10 ports starting from the **NETCONF_BASE** environment variable used when starting the NTST Manager, while the nextt one uses the next 10 ports and so on and so forth. E.g. if the **NETCONF_BASE=50000** the first simulated device will expose ports from *50000* to *50009*, the second simulated device will expose ports from *50010* to *50019* etc.
+
+The first 7 connections exposed by a simulated device are **SSH** based. A NETCONF client can connect to the exposed endpoint using one of the SSH ports (e.g. 50000 to 50006) and the **username/password**: *netconf/netconf*.
+
+The last 3 connections exposed by a simulated device are **TLS** based. A NETCONF client can connect to the exposed endpoint using one of the TLS ports (e.g. 50007 to 50009), using a valid certificate and the **username**: *netconf*. 
+
+## Usage
+
+### Building the images
+
+The `docker-build-manager.sh` script can be used to built the docker image associated with the NTS Manager. This will create a docker image named *ntsim_manager*, which will be used to start the simulation framework. Inside the docker image, port 830 will wait for connections for the NETCONF/YANG management interface.
+
+The `docker-build-model.sh` script can be used to build the docker image associated with a simulated device. Currently, this will create a docker image named *ntsim_oran*, which will be used by the manager to start the docker containers for each simulated device.
+
+### Starting the NTS Manager
+
+The NTS Manager can be started using the `docker-compose.yml` file that is provided inside tthe **scripts** folder. Further, the parameters present in this file are explained.
+
+```yaml
+version: '3'
+services:
+  ntsimulator:
+    image: "ntsim_manager:latest"
+    container_name: NTS_Manager
+    ports:
+     - "172.17.0.1:8300:830"
+    volumes:
+     - "/var/run/docker.sock:/var/run/docker.sock"
+     - "/path/to/simulator/folder/ntsimulator/scripts:/opt/dev/scripts"
+     - "/usr/bin/docker:/usr/bin/docker"
+    labels:
+      "NTS-manager": ""
+    environment:
+      NTS_IP: "172.17.0.1"
+      NETCONF_BASE: 50000
+      DOCKER_ENGINE_VERSION: "1.40"
+      MODELS_IMAGE: "ntsim_oran"
+```
+
+
+* Port mapping:
+    * `"172.17.0.1:8300:830"` - this maps the *830* port from inside the docker container of the NTS Manager to the port *8300* from the host, and binds it to the docker IP address *172.17.0.1*:
+    
+* Volumes - these map 3 important things:
+    * the docker socket from the host is mapped inside the docker container:
+        `/var/run/docker.sock:/var/run/docker.sock` - **please do not modify the path inside the container!**;
+    * the **scripts** folder from the cloned repository needs to be mapped inside the container:
+        `/path/to/simulator/folder/ntsimulator/scripts:/opt/dev/scripts` - **please do not modify the path inside the container!**;
+    * the path to the docker executable needs to be mapped inside the container:
+        `/usr/bin/docker:/usr/bin/docker` - **please do not modify the path inside the container!**;
+        
+* Labels - this associates the *NTS-manager* label to the docker container where the NTS runs;
+* Environment variables:
+    * **NTS_IP** - this should point to an IP address **from the host**, through which the simulated devices will be accessed;
+    * **NETCONF_BASE** - this is the starting port used to expose NETCONF endpoints. Starting from this, each device will use 10 consecutive ports for its endpoints;
+    * **DOCKER_ENGINE_VERSION** - this is the version of the *docker engine* installed currently on the host. This can be verified using `docker version` command in the host, and looking to the `API version:      #.##` variable from the Server details.
+    * **MODELS_IMAGE** - this represents the name of the docker image that represents the simulated device. The NTS Manager will start containers using this image, when starting simulated devices.
+    
+After modifying the `docker-compose.yml` file with values specific to your host, the NTS Manager can be started by running the command `docker-compose up` from the **scripts** folder.
+
+After the NTS Manager is started, it will wait for connections on its NETCONF/YANG management interface. One can connect to this using a NETCONF Client. The **username/password** for connecting are: *netconf/netconf*.
+
+Example of `docker ps` command result, after the NTS Manager was started:
+
+```
+7ff723b7f794        ntsim_manager:latest   "sh -c '/usr/bin/sup…"   5 days ago          Up 5 days           172.17.0.1:8300->830/tcp       NTS_Manager
+```
+
+### Using the NTST Manager
+
+When the NTS Manager is started, its default configuration looks like this:
+
+```xml
+<simulator-config xmlns="urn:onf:params:xml:ns:yang:network-topology-simulator">
+       <simulated-devices>0</simulated-devices>
+       <mounted-devices>0</mounted-devices>
+       <notification-config>
+               <fault-notification-delay-period>0</fault-notification-delay-period>
+               <ves-heartbeat-period>0</ves-heartbeat-period>
+               <is-netconf-available>true</is-netconf-available>
+               <is-ves-available>true</is-ves-available>
+       </notification-config>
+       <controller-details>
+               <controller-ip>172.17.0.1</controller-ip>
+               <controller-port>8181</controller-port>
+               <controller-username>admin</controller-username>
+               <controller-password>admin</controller-password>
+       </controller-details>
+       <ves-endpoint-details>
+               <ves-endpoint-ip>172.17.0.1</ves-endpoint-ip>
+               <ves-endpoint-port>30007</ves-endpoint-port>
+               <ves-endpoint-auth-method>no-auth</ves-endpoint-auth-method>
+               <ves-registration>false</ves-registration>
+       </ves-endpoint-details>
+</simulator-config>
+```
+
+This configuration can be altered by connecting to the NTS Manager with a NETCONF Client.
+
+### Starting a simulated device
+
+Example of starting **one** simulated device:
+
+If the leaf `<simulated-devices>1</simulated-devices>` will be set to a value of **1**, the NTS Manager will start a new docker container. We can verify that this was successfull by running the `docker ps` command. The results will look like this:
+
+```
+c18eb7a362f5        ntsim_oran             "sh -c '/usr/bin/sup…"   4 days ago          Up 4 days           172.17.0.1:50000->830/tcp, 172.17.0.1:50001->831/tcp, 172.17.0.1:50002->832/tcp, 172.17.0.1:50003->833/tcp, 172.17.0.1:50004->834/tcp, 172.17.0.1:50005->835/tcp, 172.17.0.1:50006->836/tcp, 172.17.0.1:50007->837/tcp, 172.17.0.1:50008->838/tcp, 172.17.0.1:50009->839/tcp   reverent_bhabha
+```
+
+We can see that the simulated device has 10 NETCONF Endpoints listening for connections. The first 7 (50000 to 50006) are SSH connections, while the last 3 (50007 to 50009) are TLS connections.
+
+
+## Troubleshooting
+
+### No simulated devices are starting
+
+If, after setting the leaf `<simulated-devices>1</simulated-devices>` to a value greater that 0, no new containers are created, please make sure that the image name specified in the **MODELS_IMAGE** environment variable when starting the NTS Manager is present in the host. You can verify that using the `docker images` command.
+
+Example of a result of such a command:
+
+```
+ntsim_oran       latest           57b065de4458     4 days ago     785MB
+```
+
+This means that `MODELS_IMAGE: "ntsim_oran:latest"` can be used as an environment variable when starting the NTS Manager.
\ No newline at end of file
index e136beb..b4a9098 100644 (file)
@@ -21,30 +21,38 @@ autorestart=true
 redirect_stderr=true
 priority=3
 
+[program:enable-ssh]
+directory=/home/netconf/.ssh
+command=/home/netconf/.ssh/enable_ssh_key.sh
+startsecs=0
+autorestart=false
+redirect_stderr=false
+priority=4
+
+[program:enable-tls]
+directory=/home/netconf/.ssh
+command=/home/netconf/.ssh/enable_tls.sh
+startsecs=0
+autorestart=false
+redirect_stderr=false
+priority=5
+
 [program:sysrepo-config-load]
 directory=/opt/dev/yang
 command=/opt/dev/yang/sysrepo-configuration-load.sh
 autorestart=false
 redirect_stderr=true
 startretries=1
-priority=5
+priority=6
 
 [program:o-ran-notifications]
 command=/usr/local/bin/o-ran-notifications
 autorestart=true
 redirect_stderr=true
-priority=6
+priority=7
 
 [program:ves-heartbeat]
 command=/usr/local/bin/ves-heartbeat
 autorestart=true
 redirect_stderr=true
-priority=7
-
-[program:enable-tls]
-directory=/home/netconf/.ssh
-command=/home/netconf/.ssh/enable_tls.sh
-startsecs=0
-autorestart=false
-redirect_stderr=false
-priority=101
\ No newline at end of file
+priority=8
\ No newline at end of file
index 5ed2868..4a3d43a 100755 (executable)
@@ -10,7 +10,7 @@ echo '<key-data>'"$SSH_PUB_KEY"'</key-data></authorized-key></user></authenticat
 sysrepocfg --merge=load_auth_pubkey.xml --format=xml ietf-system
 rm load_auth_pubkey.xml
 
-ssh-keyscan -p 830 localhost >> ~/.ssh/known_hosts
+ssh-keyscan -p 830 127.0.0.1 >> ~/.ssh/known_hosts
 
 echo 'Done'
 exit 0
\ No newline at end of file
index a6314bf..fc846e1 100755 (executable)
@@ -1,6 +1,6 @@
 #! /bin/bash
 
-sleep 5
+sleep 10
 
 openssl genrsa -out melacon.server.key 2048
 
@@ -16,7 +16,7 @@ echo '<private-key>'"$MELACON_SERVER_KEY"'</private-key></load-private-key></pri
 netopeer2-cli <<END
 auth pref publickey 1000
 auth keys add /home/netconf/.ssh/id_dsa.pub /home/netconf/.ssh/id_dsa
-connect --login netconf
+connect --host 127.0.0.1 --login netconf
 user-rpc --content=load_private_key.xml
 disconnect
 END
index 872513a..29f8147 100644 (file)
@@ -418,7 +418,7 @@ static int send_mount_device_instance_ssh(char *url, char *credentials, char *de
 
        curl_easy_setopt(curl_odl, CURLOPT_URL, url_for_curl);
 
-       char post_data_xml[1000];
+       char post_data_xml[1500];
 
        sprintf(post_data_xml,
                        "<node xmlns=\"urn:TBD:params:xml:ns:yang:network-topology\">"
@@ -429,6 +429,11 @@ static int send_mount_device_instance_ssh(char *url, char *credentials, char *de
                        "<password xmlns=\"urn:opendaylight:netconf-node-topology\">%s</password>"
                        "<tcp-only xmlns=\"urn:opendaylight:netconf-node-topology\">false</tcp-only>"
                        "<keepalive-delay xmlns=\"urn:opendaylight:netconf-node-topology\">120</keepalive-delay>"
+                       "<reconnect-on-changed-schema xmlns=\"urn:opendaylight:netconf-node-topology\">false</reconnect-on-changed-schema>"
+                       "<sleep-factor xmlns=\"urn:opendaylight:netconf-node-topology\">1.5</sleep-factor>"
+                       "<connection-timeout-millis xmlns=\"urn:opendaylight:netconf-node-topology\">20000</connection-timeout-millis>"
+                       "<max-connection-attempts xmlns=\"urn:opendaylight:netconf-node-topology\">100</max-connection-attempts>"
+                       "<between-attempts-timeout-millis xmlns=\"urn:opendaylight:netconf-node-topology\">2000</between-attempts-timeout-millis>"
                        "</node>",
                        device_name, device_port, getenv("NTS_IP"), device_port, "netconf", "netconf");
 
@@ -471,7 +476,7 @@ static int send_mount_device_instance_tls(char *url, char *credentials, char *de
 
        curl_easy_setopt(curl_odl, CURLOPT_URL, url_for_curl);
 
-       char post_data_xml[1000];
+       char post_data_xml[1500];
 
        sprintf(post_data_xml,
                        "<node xmlns=\"urn:TBD:params:xml:ns:yang:network-topology\">"
@@ -487,6 +492,11 @@ static int send_mount_device_instance_tls(char *url, char *credentials, char *de
                        "<port xmlns=\"urn:opendaylight:netconf-node-topology\">%d</port>"
                        "<tcp-only xmlns=\"urn:opendaylight:netconf-node-topology\">false</tcp-only>"
                        "<keepalive-delay xmlns=\"urn:opendaylight:netconf-node-topology\">120</keepalive-delay>"
+                       "<reconnect-on-changed-schema xmlns=\"urn:opendaylight:netconf-node-topology\">false</reconnect-on-changed-schema>"
+                       "<sleep-factor xmlns=\"urn:opendaylight:netconf-node-topology\">1.5</sleep-factor>"
+                       "<connection-timeout-millis xmlns=\"urn:opendaylight:netconf-node-topology\">20000</connection-timeout-millis>"
+                       "<max-connection-attempts xmlns=\"urn:opendaylight:netconf-node-topology\">100</max-connection-attempts>"
+                       "<between-attempts-timeout-millis xmlns=\"urn:opendaylight:netconf-node-topology\">2000</between-attempts-timeout-millis>"
                        "</node>",
                        device_name, device_port, getenv("NTS_IP"), "netconf", device_port);
 
index 49a6931..747bec9 100644 (file)
@@ -29,22 +29,22 @@ struct faultAlarms
 {
        int             faultId;
        char*           faultSource;
-       int             cleared;
+       int             cleared[10];
        char*           faultSeverity;
        char*           faultText;
        char*           affectedObjects[AFFECTED_OBJECTS_MAX_NUMBER];
 };
 struct faultAlarms oran_fault_alarms[ORAN_FAULT_ALARMS_NUMBER] = {
-               {.faultId = 1, .faultSource = "jknsdfnui", .affectedObjects = {"akddconoj", "asodmnjvf", "roiemfkmods"}, .cleared = 1, .faultSeverity = "MAJOR", .faultText = "sdnjosopnojnsd"},
-               {.faultId = 2, .faultSource = "onascokjnasc", .affectedObjects = {"sdouvncsjdfv13", "asjdn13ejlncd4"}, .cleared = 1, .faultSeverity = "WARNING", .faultText = "4pionfcsofn42on"},
-               {.faultId = 3, .faultSource = "asonxpkn", .affectedObjects = {"0j4fiwef320fd", "sdlvkmsdv-9023"}, .cleared = 1, .faultSeverity = "CRITICAL", .faultText = "sdjnonj32onjsa23"},
-               {.faultId = 4, .faultSource = "asnjcpkd", .affectedObjects = {"0j4fiwef320fd", "sdlvkmsdv-9023", "laksmdklmdas21"}, .cleared = 1, .faultSeverity = "MINOR", .faultText = "asdjln12osa453"},
-               {.faultId = 5, .faultSource = "dskmfl", .affectedObjects = {"sdkm31wdlk"}, .cleared = 1, .faultSeverity = "MAJOR", .faultText = "dknovrf34ekl"},
-               {.faultId = 6, .faultSource = "dsllkje232kl", .affectedObjects = {"sFKOM24KLMerw"}, .cleared = 1, .faultSeverity = "MAJOR", .faultText = "frpkm24k lsd  kmewfpm"},
-               {.faultId = 7, .faultSource = "fvkdlsfjnwej23kloe", .affectedObjects = {"fvkm24km", "sdfk23d", "kmdfkmo32", "wekl2332"}, .cleared = 1, .faultSeverity = "WARNING", .faultText = "dsm 2d 32j sdfmr32"},
-               {.faultId = 8, .faultSource = "dkom32", .affectedObjects = {"kmsdfkpm23ds", "sdmkp32"}, .cleared = 1, .faultSeverity = "CRITICAL", .faultText = "dsonj32 don32 mdson32pk654"},
-               {.faultId = 9, .faultSource = "weflm3", .affectedObjects = {"klklm32kl3", "dsfln234poewj23-", "spmd32k"}, .cleared = 1, .faultSeverity = "MINOR", .faultText = "dsflknjwej32"},
-               {.faultId = 10, .faultSource = "fweiunvfrem32", .affectedObjects = {"sfkm23klsdf2343"}, .cleared = 1, .faultSeverity = "MAJOR", .faultText = "dfskjnl4j dsfknl2 fodn54 65k"}
+               {.faultId = 1, .faultSource = "jknsdfnui", .affectedObjects = {"akddconoj", "asodmnjvf", "roiemfkmods"}, .cleared = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, .faultSeverity = "MAJOR", .faultText = "sdnjosopnojnsd"},
+               {.faultId = 2, .faultSource = "onascokjnasc", .affectedObjects = {"sdouvncsjdfv13", "asjdn13ejlncd4"}, .cleared = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, .faultSeverity = "WARNING", .faultText = "4pionfcsofn42on"},
+               {.faultId = 3, .faultSource = "asonxpkn", .affectedObjects = {"0j4fiwef320fd", "sdlvkmsdv-9023"}, .cleared = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, .faultSeverity = "CRITICAL", .faultText = "sdjnonj32onjsa23"},
+               {.faultId = 4, .faultSource = "asnjcpkd", .affectedObjects = {"0j4fiwef320fd", "sdlvkmsdv-9023", "laksmdklmdas21"}, .cleared = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, .faultSeverity = "MINOR", .faultText = "asdjln12osa453"},
+               {.faultId = 5, .faultSource = "dskmfl", .affectedObjects = {"sdkm31wdlk"}, .cleared = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, .faultSeverity = "MAJOR", .faultText = "dknovrf34ekl"},
+               {.faultId = 6, .faultSource = "dsllkje232kl", .affectedObjects = {"sFKOM24KLMerw"}, .cleared = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, .faultSeverity = "MAJOR", .faultText = "frpkm24k lsd     kmewfpm"},
+               {.faultId = 7, .faultSource = "fvkdlsfjnwej23kloe", .affectedObjects = {"fvkm24km", "sdfk23d", "kmdfkmo32", "wekl2332"}, .cleared = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, .faultSeverity = "WARNING", .faultText = "dsm 2d 32j sdfmr32"},
+               {.faultId = 8, .faultSource = "dkom32", .affectedObjects = {"kmsdfkpm23ds", "sdmkp32"}, .cleared = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, .faultSeverity = "CRITICAL", .faultText = "dsonj32 don32 mdson32pk654"},
+               {.faultId = 9, .faultSource = "weflm3", .affectedObjects = {"klklm32kl3", "dsfln234poewj23-", "spmd32k"}, .cleared = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, .faultSeverity = "MINOR", .faultText = "dsflknjwej32"},
+               {.faultId = 10, .faultSource = "fweiunvfrem32", .affectedObjects = {"sfkm23klsdf2343"}, .cleared = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, .faultSeverity = "MAJOR", .faultText = "dfskjnl4j dsfknl2 fodn54 65k"}
 };
 
 static         CURL *curl;
@@ -71,10 +71,12 @@ static int cleanup_curl()
        return SR_ERR_OK;
 }
 
-static int send_fault_ves_message(char *alarm_condition, char *alarm_object, char *severity, char *date_time, char *specific_problem)
+static int send_fault_ves_message(char *alarm_condition, char *alarm_object, char *severity, char *date_time, char *specific_problem, int port)
 {
+       int rc = SR_ERR_OK;
        CURLcode res;
        static sequence_id = 0;
+       int netconf_port_base = 0;
 
        prepare_ves_message_curl(curl);
 
@@ -89,8 +91,23 @@ static int send_fault_ves_message(char *alarm_condition, char *alarm_object, cha
        cJSON_AddItemToObject(postDataJson, "event", event);
 
        char *hostname = getenv("HOSTNAME");
+       char *netconf_base_string = getenv("NETCONF_BASE");
 
-       cJSON *commonEventHeader = vesCreateCommonEventHeader("fault", "O_RAN_COMPONENT_Alarms", hostname, sequence_id++);
+       if (netconf_base_string != NULL)
+       {
+               rc = sscanf(netconf_base_string, "%d", &netconf_port_base);
+               if (rc != 1)
+               {
+                       printf("Could not find the NETCONF base port, aborting the PNF registration...\n");
+                       return 1;
+               }
+               netconf_port_base += port;
+       }
+
+       char source_name[100];
+       sprintf(source_name, "%s_%d", hostname, netconf_port_base);
+
+       cJSON *commonEventHeader = vesCreateCommonEventHeader("fault", "O_RAN_COMPONENT_Alarms", source_name, sequence_id++);
        if (commonEventHeader == NULL)
        {
                printf("Could not create JSON object: commonEventHeader\n");
@@ -189,13 +206,16 @@ static int send_dummy_notif(sr_session_ctx_t *sess)
 
     int ran = (int) random_at_most(ORAN_FAULT_ALARMS_NUMBER - 1);
 
-    if (oran_fault_alarms[ran].cleared == 1)
+    //TODO we hardcode here the number of ports for each device, 10
+    int random_port = (int) random_at_most(9);
+
+    if (oran_fault_alarms[ran].cleared[random_port] == 1)
     {
-       oran_fault_alarms[ran].cleared = 0;
+       oran_fault_alarms[ran].cleared[random_port] = 0;
     }
     else
     {
-       oran_fault_alarms[ran].cleared = 1;
+       oran_fault_alarms[ran].cleared[random_port] = 1;
     }
 
        sr_val_t *vnotif;
@@ -221,7 +241,7 @@ static int send_dummy_notif(sr_session_ctx_t *sess)
 
        sr_val_build_xpath(&vnotif[current_num_of_values - 1], "%s", "/o-ran-fm:alarm-notif/is-cleared");
        vnotif[current_num_of_values - 1].type = SR_BOOL_T;
-       vnotif[current_num_of_values - 1].data.bool_val = oran_fault_alarms[ran].cleared;
+       vnotif[current_num_of_values - 1].data.bool_val = oran_fault_alarms[ran].cleared[random_port];
 
        CREATE_NEW_VALUE(rc, vnotif, current_num_of_values);
 
@@ -267,7 +287,7 @@ static int send_dummy_notif(sr_session_ctx_t *sess)
                char faultId[10];
                sprintf(faultId, "%d", oran_fault_alarms[ran].faultId);
                rc = send_fault_ves_message(faultId, oran_fault_alarms[ran].faultSource,
-                               (oran_fault_alarms[ran].cleared) ? "NORMAL" : oran_fault_alarms[ran].faultSeverity, dateAndTime, oran_fault_alarms[ran].faultText);
+                               (oran_fault_alarms[ran].cleared[random_port]) ? "NORMAL" : oran_fault_alarms[ran].faultSeverity, dateAndTime, oran_fault_alarms[ran].faultText, random_port);
                if (rc != SR_ERR_OK)
                {
                        printf("Could not send Fault VES message\n");
index 745718b..c41e432 100644 (file)
@@ -192,9 +192,6 @@ cJSON*      vesCreateCommonEventHeader(char *domain, char *event_type, char *source_n
        char dateAndTime[50];
        getCurrentDateAndTime(dateAndTime);
 
-    char hostname[100];
-    sprintf(hostname, "%s", getenv("HOSTNAME"));
-
        long int useconds = getMicrosecondsSinceEpoch;
 
        cJSON *commonEventHeader = cJSON_CreateObject();
@@ -211,7 +208,7 @@ cJSON*      vesCreateCommonEventHeader(char *domain, char *event_type, char *source_n
        }
 
        char eventId[200];
-       sprintf(eventId, "%s_%s", hostname, dateAndTime);
+       sprintf(eventId, "%s_%s", source_name, dateAndTime);
 
        if (cJSON_AddStringToObject(commonEventHeader, "eventId", eventId) == NULL)
        {
@@ -252,7 +249,7 @@ cJSON*      vesCreateCommonEventHeader(char *domain, char *event_type, char *source_n
                return NULL;
        }
 
-       if (cJSON_AddStringToObject(commonEventHeader, "reportingEntityName", hostname) == NULL)
+       if (cJSON_AddStringToObject(commonEventHeader, "reportingEntityName", source_name) == NULL)
        {
                printf("Could not create JSON object: reportingEntityName\n");
                return NULL;
index bf8f93b..d9d88df 100755 (executable)
@@ -1,25 +1,23 @@
 #!/bin/bash
 
-sleep 5
+sleep 20
 
 echo "Loading data into sysrepo..."
 
-SSH_PUB_KEY="$(cat /home/netconf/.ssh/id_dsa.pub| awk '{print $2}')"
+#SSH_PUB_KEY="$(cat /home/netconf/.ssh/id_dsa.pub| awk '{print $2}')"
 
-echo '<system xmlns="urn:ietf:params:xml:ns:yang:ietf-system"><authentication><user><name>netconf</name><authorized-key><name>ssh_key</name><algorithm>ssh-dss</algorithm>' >> load_auth_pubkey.xml
-echo '<key-data>'"$SSH_PUB_KEY"'</key-data></authorized-key></user></authentication></system>' >> load_auth_pubkey.xml
+#echo '<system xmlns="urn:ietf:params:xml:ns:yang:ietf-system"><authentication><user><name>netconf</name><authorized-key><name>ssh_key</name><algorithm>ssh-dss</algorithm>' >> load_auth_pubkey.xml
+#echo '<key-data>'"$SSH_PUB_KEY"'</key-data></authorized-key></user></authentication></system>' >> load_auth_pubkey.xml
 
-sysrepocfg --merge=load_auth_pubkey.xml --format=xml ietf-system
-rm load_auth_pubkey.xml
-
-ssh-keyscan -p 830 localhost >> ~/.ssh/known_hosts
+#sysrepocfg --merge=load_auth_pubkey.xml --format=xml ietf-system
+#rm load_auth_pubkey.xml
+#
+#ssh-keyscan -p 830 localhost >> ~/.ssh/known_hosts
 
 pyang -f sample-xml-skeleton --sample-xml-list-entries 3 *.yang
 
 result=$(netopeer2-cli <<-END
-       auth pref publickey 1000
-       auth keys add /home/netconf/.ssh/id_dsa.pub /home/netconf/.ssh/id_dsa
-       connect --login netconf
+       connect --host 127.0.0.1 --login netconf
        user-rpc --content=/opt/dev/yang/edit_config_operation.xml
        disconnect
 END
@@ -30,7 +28,7 @@ do
   pyang -f sample-xml-skeleton --sample-xml-list-entries 2 *.yang
   
   result=$(netopeer2-cli <<-END
-       connect --login netconf
+       connect --host 127.0.0.1 --login netconf
        user-rpc --content=edit_config_operation.xml
        disconnect
 END