Add vanilla ODL to topology-service. 51/7851/2
authorAlex Stancu <alexandru.stancu@highstreet-technologies.com>
Tue, 1 Mar 2022 09:49:17 +0000 (11:49 +0200)
committerAlex Stancu <alexandru.stancu@highstreet-technologies.com>
Tue, 1 Mar 2022 13:02:24 +0000 (15:02 +0200)
Issue-ID: SIM-93
Change-Id: I9f40828ec32682cc93ca4f2b89b2d1d8e8fd1d8a
Signed-off-by: Alex Stancu <alexandru.stancu@highstreet-technologies.com>
ntsimulator/deploy/smo-nts-ng-topology-server/Dockerfile
ntsimulator/deploy/smo-nts-ng-topology-server/callhomeConfig.py [new file with mode: 0755]
ntsimulator/deploy/smo-nts-ng-topology-server/config.json
ntsimulator/deploy/smo-nts-ng-topology-server/org.apache.karaf.features.cfg [new file with mode: 0644]

index 14a94c5..f854c42 100644 (file)
 FROM nexus3.o-ran-sc.org:10004/o-ran-sc/nts-ng-base:latest
 LABEL maintainer="alexandru.stancu@highstreet-technologies.com / adrian.lita@highstreet-technologies.com"
 
+RUN apt-get update && apt-get install -y --no-install-recommends \
+    # Opendaylight download
+    wget \
+    # Java 11
+    default-jdk \
+    python3 \
+    && rm -rf /var/lib/apt/lists/* && \
+    mkdir /opt/opendaylight
+
+WORKDIR /opt
+
+ARG ODL_VERSION=15.1.0
+
+RUN wget --no-check-certificate https://nexus.opendaylight.org/content/repositories/opendaylight.release/org/opendaylight/integration/opendaylight/$ODL_VERSION/opendaylight-$ODL_VERSION.tar.gz
+
+RUN tar -xvzf opendaylight-${ODL_VERSION}.tar.gz -C opendaylight --strip-components 1 && \
+    rm -rf opendaylight-${ODL_VERSION}.tar.gz
+
 # ntsim-ng configuration and deployment
 COPY ./yang /opt/dev/deploy/yang
 COPY ./data /opt/dev/deploy/data
 COPY ./config.json /opt/dev/ntsim-ng/config/config.json
+COPY ./org.apache.karaf.features.cfg /opt/opendaylight/etc/org.apache.karaf.features.cfg
 
 # ntsim-ng init docker
 RUN /opt/dev/ntsim-ng/ntsim-ng --container-init -w /opt/dev/ntsim-ng
 
+COPY ./callhomeConfig.py /opt/dev/workspace/callhomeConfig.py
+
 # finishing container build
 ARG BUILD_DATE
 LABEL build-date=$BUILD_DATE
 
 # add exposed ports
-EXPOSE 830-929
-EXPOSE 21-22
+EXPOSE 8181
 
 ENV NTS_FUNCTION_TYPE=NTS_FUNCTION_TYPE_TOPOLOGY_SERVER
+ENV NTS_NF_STANDALONE_START_FEATURES="datastore-populate netconf-call-home"
+ENV SDN_CONTROLLER_IP="127.0.0.1"
+ENV SDN_CONTROLLER_PROTOCOL="http"
+ENV SDN_CONTROLLER_PORT="8181"
+ENV SDN_CONTROLLER_CALLHOME_IP="127.0.0.1"
+ENV SDN_CONTROLLER_CALLHOME_PORT="6666"
+ENV SDN_CONTROLLER_USERNAME="admin"
+ENV SDN_CONTROLLER_PASSWORD="admin"
+ENV ODL_HOME=/opt/opendaylight
 
 # run
 WORKDIR /opt/dev/workspace
diff --git a/ntsimulator/deploy/smo-nts-ng-topology-server/callhomeConfig.py b/ntsimulator/deploy/smo-nts-ng-topology-server/callhomeConfig.py
new file mode 100755 (executable)
index 0000000..531faf9
--- /dev/null
@@ -0,0 +1,100 @@
+#!/usr/bin/python3
+
+################################################################################
+# Copyright 2022 highstreet technologies GmbH
+#
+# Licensed under the Apache License, Version 2.0 (the 'License');
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an 'AS IS' BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+################################################################################
+# Script for adding this running NTS Topology Server to the allowed-devices list of the
+# local OpenDaylight instance, for enabling NETCONF CallHome
+
+import http.client
+import time
+import base64
+import os
+
+TIMEOUT=1000
+INTERVAL=30
+
+# default ODL credentials
+username = os.getenv("SDN_CONTROLLER_USERNAME")
+password = os.getenv("SDN_CONTROLLER_PASSWORD")
+cred_string = username + ":" + password
+
+certreadyCmd="GET"
+certreadyUrl="/rests/data/odl-netconf-callhome-server:netconf-callhome-server"
+timePassed=0
+
+headers = {'Authorization':'Basic %s' % base64.b64encode(cred_string.encode()).decode(),
+           'Accept':"application/json",
+           'Content-type':"application/yang-data+json"}
+
+# ODL NETCONF CallHome allowed devices URL
+callhomeConfigUrl = "/rests/data/odl-netconf-callhome-server:netconf-callhome-server/allowed-devices/device=o-ran-sc-topology-service"
+# ODL NETCONF CallHome allowed devices payload; private key will be replaced with the one generated on the device at runtime
+callhomeConfigPayload = "{\"odl-netconf-callhome-server:device\":[{\"odl-netconf-callhome-server:unique-id\":\"o-ran-sc-topology-service\", \"odl-netconf-callhome-server:ssh-client-params\": {\"odl-netconf-callhome-server:host-key\":\"@priv_key@\",\"odl-netconf-callhome-server:credentials\":{\"odl-netconf-callhome-server:username\":\"netconf\",\"odl-netconf-callhome-server:passwords\":[\"netconf!\"]}}}]}"
+
+
+# checking if RESTCONF and NETCONF CallHome feature are functional in ODL
+def makeHealthcheckCall(headers, timePassed):
+    connected = False
+    # WAIT 10 minutes maximum and test every 30 seconds if HealthCheck API is returning 200
+    while timePassed < TIMEOUT:
+        try:
+            conn = http.client.HTTPConnection("127.0.0.1",8181)
+            req = conn.request(certreadyCmd, certreadyUrl,headers=headers)
+            res = conn.getresponse()
+            res.read()
+            httpStatus = res.status
+            if httpStatus == 200:
+                print("Healthcheck Passed in %d seconds." %timePassed)
+                connected = True
+                break
+            else:
+                print("Sleep: %d seconds before testing if Healthcheck worked. Total wait time up now is: %d seconds. Timeout is: %d seconds. Problem code was: %d" %(INTERVAL, timePassed, TIMEOUT, httpStatus))
+        except:
+            print("Cannot execute REST call. Sleep: %d seconds before testing if Healthcheck worked. Total wait time up now is: %d seconds. Timeout is: %d seconds." %(INTERVAL, timePassed, TIMEOUT))
+        timePassed = timeIncrement(timePassed)
+
+    if timePassed > TIMEOUT:
+        print("TIME OUT: Healthcheck not passed in  %d seconds... Could cause problems for testing activities..." %TIMEOUT)
+
+    return connected
+
+
+def timeIncrement(timePassed):
+    time.sleep(INTERVAL)
+    timePassed = timePassed + INTERVAL
+    return timePassed
+
+# add current NTS in allowed devices list for NETCONF CallHome
+def configureNetconfCallhome():
+    connected = makeHealthcheckCall(headers, timePassed)
+    if connected:
+        with open('/home/netconf/.ssh/melacon.server.key.pub', 'r') as file:
+            data = file.read().rstrip()
+            words = data.split()
+            publicKey = words[1]
+            payload = callhomeConfigPayload.replace("@priv_key@", publicKey)
+            conn = http.client.HTTPConnection("localhost",8181)
+            req = conn.request("PUT", callhomeConfigUrl,headers=headers, body=payload)
+            res = conn.getresponse()
+            res.read()
+            httpStatus = res.status
+            if httpStatus >= 200 and httpStatus < 300:
+                print("Successfully enabled CallHome for device with key=%s" % publicKey)
+            else:
+                print("Could not allow device...")
+
+print("Starting NETCONF Callhome configuration...")
+configureNetconfCallhome()
index 6a8587e..3889585 100644 (file)
         "ntsim-network-function": {
             "path": "/opt/dev/ntsim-ng/ntsim-ng",
             "args": ["-w/opt/dev/ntsim-ng", "-f"],
+            "autorestart": true,
+            "nomanual": false
+        },
+
+        "opendaylight": {
+            "path": "/opt/opendaylight/bin/karaf",
+            "args": ["server"],
+            "autorestart": true
+        },
+
+        "callhome-config": {
+            "path": "/opt/dev/workspace/callhomeConfig.py",
+            "autorestart": false,
             "nomanual": false
         }
     },
@@ -47,7 +60,7 @@
         ],
 
         "debug-max-string-size" : 50,
-        
+
         "default-list-instances": 1,
         "custom-list-instances" : []
     },
         "random-generation-enabled": false,
 
         "pre-generated-operational-data": [
-            
+            "/opt/dev/deploy/data/tapi-common-operational.json"
         ],
         "pre-generated-running-data": [
-            
+            "/opt/dev/deploy/data/tapi-common-running.json"
         ]
     }
 }
diff --git a/ntsimulator/deploy/smo-nts-ng-topology-server/org.apache.karaf.features.cfg b/ntsimulator/deploy/smo-nts-ng-topology-server/org.apache.karaf.features.cfg
new file mode 100644 (file)
index 0000000..5e49e98
--- /dev/null
@@ -0,0 +1,77 @@
+################################################################################
+#
+#    Licensed to the Apache Software Foundation (ASF) under one or more
+#    contributor license agreements.  See the NOTICE file distributed with
+#    this work for additional information regarding copyright ownership.
+#    The ASF licenses this file to You under the Apache License, Version 2.0
+#    (the "License"); you may not use this file except in compliance with
+#    the License.  You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS,
+#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#    See the License for the specific language governing permissions and
+#    limitations under the License.
+#
+################################################################################
+
+#
+# Comma separated list of features repositories to register by default
+#
+featuresRepositories = file:${karaf.home}/etc/9b118133-44f9-4486-bf63-d3677814ed0d.xml
+
+#
+# Comma separated list of features to install at startup
+#
+featuresBoot = 938e1513-0628-4b0b-86ce-5db3d990508f, \
+odl-netconf-connector-all, \
+odl-restconf-nb-rfc8040, \
+odl-mdsal-apidocs, \
+odl-netconf-callhome-ssh
+
+#
+# Resource repositories (OBR) that the features resolver can use
+# to resolve requirements/capabilities
+#
+# The format of the resourceRepositories is 
+# resourceRepositories=[xml:url|json:url],...
+# for Instance:
+#
+#resourceRepositories=xml:http://host/path/to/index.xml
+# or
+#resourceRepositories=json:http://host/path/to/index.json
+#
+
+#
+# Defines if the boot features are started in asynchronous mode (in a dedicated thread)
+#
+featuresBootAsynchronous=false
+
+#
+# Service requirements enforcement
+#
+# By default, the feature resolver checks the service requirements/capabilities of
+# bundles for new features (xml schema >= 1.3.0) in order to automatically installs
+# the required bundles.
+# The following flag can have those values:
+#   - disable: service requirements are completely ignored
+#   - default: service requirements are ignored for old features
+#   - enforce: service requirements are always verified
+#
+#serviceRequirements=default
+
+#
+# Store cfg file for config element in feature
+#
+#configCfgStore=true
+
+#
+# Configuration of features processing mechanism (overrides, blacklisting, modification of features)
+# XML file defines instructions related to features processing
+# versions.properties may declare properties to resolve placeholders in XML file
+# both files are relative to ${karaf.etc}
+#
+#featureProcessing=org.apache.karaf.features.xml
+#featureProcessingVersions=versions.properties