X-Git-Url: https://gerrit.akraino.org/r/gitweb?a=blobdiff_plain;f=cmframework%2Fsrc%2Fcmframework%2Fapis%2Fcmclient.py;fp=cmframework%2Fsrc%2Fcmframework%2Fapis%2Fcmclient.py;h=d5ef98bd5d9d5c164d6dec3fb2fca7c6ede72f5a;hb=c389bdee7b3845b55f443dbf04c0ce4083a55886;hp=0000000000000000000000000000000000000000;hpb=5030f0c004701dd422c78c71c014ef60f48139fc;p=ta%2Fconfig-manager.git diff --git a/cmframework/src/cmframework/apis/cmclient.py b/cmframework/src/cmframework/apis/cmclient.py new file mode 100644 index 0000000..d5ef98b --- /dev/null +++ b/cmframework/src/cmframework/apis/cmclient.py @@ -0,0 +1,247 @@ +# Copyright 2019 Nokia + +# 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. +import re + +from functools import wraps +from cmframework import apis as cmapis + + +def handle_exceptions(func): + @wraps(func) + def wrapper(self, *arg, **kwargs): + try: + return func(self, *arg, **kwargs) + except cmapis.cmerror.CMError as exp: + raise + except Exception as exp: + raise cmapis.cmerror.CMError(str(exp)) + + return wrapper + + +class CMClient(object): + """ + Usage Example: + class VerboseLogger: + def __call__(self, msg): + print(msg) + + logger = VerboseLogger() + + client = CMClient(192.128.254.10, 51110, cmclient.CMClientImpl, logger) + try: + value = client.get_property('controller-1.ntp.servers') + except cmapis.cmerror.CMError as error: + print('Got exception %s' % str(error)) + """ + + @handle_exceptions + def __init__(self, server_ip='config-manager', server_port=61100, + client_lib_impl_module='cmframework.lib.CMClientImpl', verbose_logger=None): + """ initialize the client interface + + Arguments: + + server_ip: The configuration management server ip address. + + server_port: The configuration management server port number. + + client_lib_impl_module: The module implementing the client library. + + verbose_logger: The verbose logging callable. any callable which + takes a string as input argument can be used. + + Raise: + + CMError exception in-case of a failure. + """ + + import socket + try: + serverip = socket.gethostbyname(server_ip) + except Exception: # pylint: disable=broad-except + # use localhost in-case we cannot resolve the provided hostname + serverip = '127.0.0.1' + + self.server_ip = serverip + self.server_port = server_port + self.client_lib = None + self.verbose_logger = verbose_logger + + # Separate class path and module name + parts = client_lib_impl_module.rsplit('.', 1) + module_path = parts[0] + class_name = parts[1] + self.verbose_log('module_path = %s' % module_path) + self.verbose_log('class_name = %s' % class_name) + module = __import__(module_path, fromlist=[module_path]) + classobj = getattr(module, class_name) + self.client_lib = classobj(self.server_ip, self.server_port, verbose_logger) + + def verbose_log(self, msg): + if self.verbose_logger: + self.verbose_logger(msg) + + @handle_exceptions + def get_property(self, prop_name, snapshot_name=None): + """get the value assoicated with a property. + + This is the API used to read the value associated with a + configuration property. + + Arguments: + + prop_name: The property name + (optional) snapshot_name: The snapshot name + + Raise: + + CMError in-case of a failure. + """ + result = self.client_lib.get_property(prop_name, snapshot_name) + return result + + @handle_exceptions + def get_properties(self, prop_filter, snapshot_name=None): + """get a set of properties matching a filter. + + This is the API used to read a group of properties matching some + filter. + + Arguments: + + prop_filter: A valid python re describing the filter used when + matching the returned properties. + (optional) snapshot_name: The snapshot name + + Raise: + + CMError is raised in-case of a failure. + """ + self._check_filter(prop_filter) + result = self.client_lib.get_properties(prop_filter, snapshot_name) + return result + + @handle_exceptions + def set_property(self, prop_name, prop_value): + """set/update the value of a property. + + This is the API used to set/update the value associated with a + property. + + Arguments: + + prop_name: A string representing the property name. + + prop_value: A string representing the property value. + + Raise: + + CMError is raised in-case of failure. + """ + return self.client_lib.set_property(prop_name, prop_value) + + @handle_exceptions + def set_properties(self, props, overwrite=False): + """set/update a group of properties as a whole + + This API is used to set/update the values associated with a group of + properties as a whole, the change is either accepted as a whole or + rejected as a whole. + + Arguments: + + props: A dictionary containing the changed properties. + + overwrite: Replace the existing configuration dictionary with the new one. + + Raise: + + CMError is raised in-case of a failure. + """ + return self.client_lib.set_properties(props, overwrite) + + @handle_exceptions + def delete_property(self, prop_name): + """delete a property + + This is the API used to delete a configuration property. + + Arguments: + + prop_name: The name of the property to be deleted. + + Raise: + + CMError is raised in-case of a failure. + """ + return self.client_lib.delete_property(prop_name) + + @handle_exceptions + def delete_properties(self, arg): + """delete a group of properties as a whole + + This is the API used to delete a group of properties as whole, if the + deletion of one of the properties is rejected then the whole delete + operation will fail. + + Arguments: + + arg: This can be either a string representing the re used when + matching the properties to be deleted, or it can be a list of + properties names to be deleted. + + Raise: + + CMError is raised in-case of a failure. + """ + if isinstance(arg, str): + self._check_filter(arg) + return self.client_lib.delete_properties(arg) + + @handle_exceptions + def get_changes_states(self, change_uuid): + """get the config changes states + + This is the API used to get the changes states + + Arguments: + + arg: This can be either a valid change uuid or None. + + Raise: + + CMError is raised in-case of a failure. + """ + return self.client_lib.get_changes_states(change_uuid) + + @handle_exceptions + def wait_activation(self, change_uuid): + """wait for activation of config changes to finish + + This is the API used to wait for config changes to finish + + Arguments: + + arg: A valid change uuid. + + Raise: + + CMError is raised in-case of a failure. + """ + return self.client_lib.wait_activation(change_uuid) + + # pylint: disable=no-self-use + def _check_filter(self, prop_filter): + re.compile(prop_filter)