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
--- /dev/null
+#!/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()
"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
}
},
],
"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"
]
}
}
--- /dev/null
+################################################################################
+#
+# 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