summaryrefslogtreecommitdiffstats
path: root/components
diff options
context:
space:
mode:
authorottero <rodrigo.ottero@est.tech>2019-03-27 19:13:28 +0000
committerottero <rodrigo.ottero@est.tech>2019-03-27 19:13:28 +0000
commitdb81568e983ffb8f6827fadf5354ef5133e217de (patch)
treeef707da03ad324d9d236353b8b4beca581b43128 /components
parent10164a7ab851859bfd548e32b4fe3c0610f3d614 (diff)
Creating a reusable Restconf client
The code in RestconfConfigDeploy.py that was responsible for making the Restconf connections was extracted to another script, making it reusa- ble by other blueprints Change-Id: Ib7d8870f29c76b120ccd3e3e5ba7e13765414269 Issue-ID: CCSDK-926 Signed-off-by: ottero <rodrigo.ottero@est.tech>
Diffstat (limited to 'components')
-rw-r--r--components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Scripts/python/RestconfConfigDeploy.py99
-rw-r--r--components/scripts/python/ccsdk_restconf/__init__.py0
-rw-r--r--components/scripts/python/ccsdk_restconf/restconf_client.py74
3 files changed, 96 insertions, 77 deletions
diff --git a/components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Scripts/python/RestconfConfigDeploy.py b/components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Scripts/python/RestconfConfigDeploy.py
index 01e2ec477..78a38a225 100644
--- a/components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Scripts/python/RestconfConfigDeploy.py
+++ b/components/model-catalog/blueprint-model/test-blueprint/capability_restconf/Scripts/python/RestconfConfigDeploy.py
@@ -14,30 +14,40 @@
# limitations under the License.
# ============LICENSE_END=========================================================
-from time import sleep
-
from org.onap.ccsdk.cds.blueprintsprocessor.functions.restconf.executor import \
RestconfComponentFunction
from java.lang import Exception as JavaException
+from restconf_client import RestconfClient
+
class RestconfConfigDeploy(RestconfComponentFunction):
log = globals()["log"]
- odl_status_check_limit = 10
- odl_status_check_pause = 1
- odl_status_check_url = "restconf/operational/network-topology:network-topology/topology/topology-netconf/node/"
- base_odl_url = "restconf/config/network-topology:network-topology/topology/topology-netconf/node/"
- server_identifier = "sdncodl"
configlet_template_name = "config-assign"
- configlet_odl_resource = "/yang-ext:mount/mynetconf:netconflist"
+ configlet_resource_path = "/yang-ext:mount/mynetconf:netconflist"
+ restconf_server_identifier = "sdncodl"
def process(self, execution_request):
self.log.info("Started execution of process method")
try:
+ restconf_client = RestconfClient(self.log, self)
pnf_id, resolution_key = self.retrieve_parameters(execution_request)
- self.interact_with_odl(pnf_id, resolution_key)
+ web_client_service = self.restClientService(self.restconf_server_identifier)
+
+ try:
+ mount_payload = self.resolveAndGenerateMessage("config-deploy-mapping", "config-deploy-template")
+ restconf_client.mount_device(web_client_service, pnf_id, mount_payload)
+
+ configlet = self.resolveFromDatabase(resolution_key, self.configlet_template_name)
+ restconf_client.configure_device(web_client_service, pnf_id, self.configlet_resource_path, configlet)
+ except Exception, err:
+ self.log.error("an error occurred while configuring device {}", err)
+ raise err
+ finally:
+ restconf_client.unmount_device(web_client_service, pnf_id)
+
except JavaException, err:
self.log.error("Java Exception in the script", err)
raise err
@@ -54,74 +64,9 @@ class RestconfConfigDeploy(RestconfComponentFunction):
self.log.info("pnf-id: {}", pnf_id)
return pnf_id, resolution_key
- def interact_with_odl(self, pnf_id, resolution_key):
- try:
- self.mount(pnf_id)
- self.log_current_configlet(pnf_id)
- self.apply_configuration(pnf_id, resolution_key, self.configlet_template_name)
- except Exception, err:
- self.log.error("an error occurred while configuring device {}", err)
- raise err
- finally:
- self.log.info("unmounting device {}", pnf_id)
- self.unmount(pnf_id)
-
- def mount(self, pnf_id):
- self.log.info("mounting device {}", pnf_id)
- mount_payload = self.resolveAndGenerateMessage("config-deploy-mapping", "config-deploy-template")
- self.log.info("mount payload: \n {}", mount_payload)
- headers = {"Content-Type": "application/xml"} # defining custom header
- url = self.base_odl_url + str(pnf_id)
- self.log.info("sending mount request, url: {}", url)
- web_client_service = self.restClientService(self.server_identifier)
- web_client_service.exchangeResource("PUT", url, mount_payload, headers)
- self.wait_for_odl_to_mount(pnf_id)
-
- def wait_for_odl_to_mount(self, pnf_id):
- counter = 0
- url = self.odl_status_check_url + pnf_id
- self.log.info("url for ODL status check: {}", url)
- web_client_service = self.restClientService(self.server_identifier)
- expected_result = '"netconf-node-topology:connection-status":"connected"'
- while counter < self.odl_status_check_limit:
- result = web_client_service.exchangeResource("GET", url, "")
- self.log.info("ODL status check result: {}", result)
- if expected_result in result:
- self.log.info("PNF was mounted successfully on ODL")
- return None
- sleep(1)
- counter += 1
- raise JavaException("PNF was not mounted on ODL, aborting configuration procedure")
-
- def log_current_configlet(self, pnf_id):
- self.log.info("retrieving configuration for device {}", pnf_id)
- url = self.base_odl_url + pnf_id + self.configlet_odl_resource
- self.log.info("sending GET request, url: {}", url)
- web_client_service = self.restClientService(self.server_identifier)
- result = web_client_service.exchangeResource("GET", url, "")
- self.log.info("Current configuration: {}", result)
-
- def apply_configuration(self, pnf_id, resolution_key, template_name):
- self.log.info("configuring device {}", pnf_id)
- self.log.info("Retrieving configlet from database (resolution-key: {}, template_name: {}",
- resolution_key, template_name)
- configlet = self.resolveFromDatabase(resolution_key, template_name)
- self.log.info("Configlet: {}", configlet)
- headers = { "Content-Type": "application/yang.patch+json" } # defining custom header
- url = self.base_odl_url + pnf_id + self.configlet_odl_resource
- self.log.info("sending patch request, url: {}", url)
- web_client_service = self.restClientService(self.server_identifier)
- result = web_client_service.exchangeResource("PATCH", url, configlet, headers)
- self.log.info("Configuration application result: {}", result)
-
- def unmount(self, pnf_id):
- url = self.base_odl_url + str(pnf_id)
- self.log.info("sending unmount request, url: {}", url)
- web_client_service = self.restClientService(self.server_identifier)
- web_client_service.exchangeResource("DELETE", url, "")
-
def recover(self, runtime_exception, execution_request):
self.log.info("Recover function called!")
- self.log.error(runtime_exception.getMessage())
+ self.log.info("Execution request", execution_request)
+ self.log.error("Exception", runtime_exception)
print self.bluePrintRuntimeService.getBluePrintError().addError(runtime_exception.getMessage())
- return None \ No newline at end of file
+ return None
diff --git a/components/scripts/python/ccsdk_restconf/__init__.py b/components/scripts/python/ccsdk_restconf/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/components/scripts/python/ccsdk_restconf/__init__.py
diff --git a/components/scripts/python/ccsdk_restconf/restconf_client.py b/components/scripts/python/ccsdk_restconf/restconf_client.py
new file mode 100644
index 000000000..43e885a5b
--- /dev/null
+++ b/components/scripts/python/ccsdk_restconf/restconf_client.py
@@ -0,0 +1,74 @@
+#
+# ============LICENSE_START=======================================================
+# Copyright (C) 2019 Nordix Foundation.
+# ================================================================================
+# 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.
+#
+# SPDX-License-Identifier: Apache-2.0
+# ============LICENSE_END=========================================================
+#
+from time import sleep
+
+
+class RestconfClient:
+
+ __odl_status_check_limit = 10
+ __odl_status_check_pause = 1
+ __odl_status_check_url = "restconf/operational/network-topology:network-topology/topology/topology-netconf/node/"
+ __base_odl_url = "restconf/config/network-topology:network-topology/topology/topology-netconf/node/"
+
+ def __init__(self, log, restconf_component_function):
+ self.__log = log
+ self.__component_function = restconf_component_function
+
+ def mount_device(self, web_client_service, pnf_id, mount_payload):
+ self.__log.debug("mounting device {}", pnf_id)
+ headers = {"Content-Type": "application/xml"}
+ url = self.__base_odl_url + pnf_id
+ self.__log.debug("sending mount request, url: {}", url)
+ web_client_service.exchangeResource("PUT", url, mount_payload, headers)
+ self.__wait_for_odl_to_mount(web_client_service, pnf_id)
+
+ def __wait_for_odl_to_mount(self, web_client_service, pnf_id):
+ counter = 0
+ url = self.__odl_status_check_url + pnf_id
+ self.__log.info("url for ODL status check: {}", url)
+ expected_result = '"netconf-node-topology:connection-status":"connected"'
+ while counter < self.__odl_status_check_limit:
+ result = web_client_service.exchangeResource("GET", url, "")
+ if expected_result in result:
+ self.__log.info("PNF was mounted successfully on ODL")
+ return None
+ sleep(self.__odl_status_check_pause)
+ counter += 1
+ raise Exception("PNF was not mounted on ODL, aborting configuration procedure")
+
+ def configure_device(self, web_client_service, pnf_id, configlet_resource_path, configlet_to_apply):
+ self.log_current_configlet(web_client_service, pnf_id, configlet_resource_path)
+ self.__log.info("configuring device: {}, Configlet: {}", pnf_id, configlet_to_apply)
+ headers = {"Content-Type": "application/yang.patch+json"}
+ url = self.__base_odl_url + pnf_id + configlet_resource_path
+ self.__log.debug("sending patch request, url: {}", url)
+ result = web_client_service.exchangeResource("PATCH", url, configlet_to_apply, headers)
+ self.__log.info("Configuration application result: {}", result)
+
+ def log_current_configlet(self, web_client_service, pnf_id, configlet_resource_path):
+ url = self.__base_odl_url + pnf_id + configlet_resource_path
+ self.__log.debug("sending GET request, url: {}", url)
+ result = web_client_service.exchangeResource("GET", url, "")
+ self.__log.info("Current configuration: {}", result)
+
+ def unmount_device(self, web_client_service, pnf_id):
+ url = self.__base_odl_url + str(pnf_id)
+ self.__log.debug("sending unmount request, url: {}", url)
+ web_client_service.exchangeResource("DELETE", url, "")