def _execute_api(self, *args): """Instantiate and execute script called by API.""" # split arguments as needed args, kwargs = args method, endpoint = args endpoint_key = kwargs['endpoint_key'].split(':')[1] # identify what might be a query to the API. if '?' in endpoint: endpoint, query = endpoint.split('?') else: query = '' # Get endpoint doc api = self.meta_api.doc['paths'][endpoint_key][method] # Treat source to be a importable path. if '/' in api['source']: source = api['source'].split('/') elif '\\' in api['source']: source = api['source'].split('\\') else: source = api['source'].split() source = source[:-1] source = '/'.join(source) # Import it. sys.path.append(source) mio_commando = importlib.import_module(api['operation']) # Instanciate the Class. myoperation = getattr(mio_commando, api['operationId']) myoperation_inst = myoperation(self.cbacker, self.rbkcli_logger) #myoperation_inst = myoperation(self.cbacker) # Attribute the parameters to be passed to script. if kwargs['data'] == {}: data = {} else: data = json.loads(kwargs['data']) data = DotDict(data) pass_args = DotDict({ 'parameters': data, 'query': kwargs['params'], 'method': args[0], 'endpoint': args[1], 'target': self.target }) # Return class execution try: result = myoperation_inst.execute(pass_args) except AttributeError as error: msg = 'Error executing custom script, please debug it... ' + str( error) raise RbkcliException.ApiHandlerError(msg + '\n') return json.dumps(result, indent=2)
def call_back(self, args): """Perform same level of parsing (even CLI) as any other request.""" self.request, self.args = self.parseit(args) self.stct_request = self.structreit(self.args, self.request) result = DotDict() result.text = self.callit(self.stct_request) result.status_code = 200 result.text = json.dumps(result.text, indent=2) return self.formatter.outputfy(self.req, result)
def __init__(self, logger, conf_dict=None, workflow='command'): """Initialize the tools.""" self.logger = logger self.ssh_conn = False self.called_tools = [] self.workflow = workflow self.auth = DotDict({}) self.auth_dict = {} if conf_dict is None: conf_dict = {} self.conf_dict = conf_dict
def __init__(self, logger, auth, version, user_profile='admin'): """Initialize Rbkcli Executor.""" self._verify_api_version(version) self.local_tools = DotDict({}) self.local_tools.logger = logger self.local_tools.auth = auth self.local_tools.user_profile = user_profile self.version = version self.endpoints = {} self._assign_methods() self.filter_lists = DotDict({}) self.focus_list = []
def structreit(self, args, request): """Reestructure arguments provided.""" self.args = args self.request = {} requet_1 = {} for key in request.keys(): self.request[key] = request[key] requet_1[key] = request[key] # Structure the request to the needed format. stct_request = self.base_kit.parser.create_request_structure( requet_1, self.args) # Pass data to dot dictionary self.stct_request = DotDict() for key in stct_request.keys(): self.stct_request[key] = stct_request[key] # Normalizing request dictionary self.stct_request.endpoint = ' '.join(self.stct_request.api_endpoint) self.stct_request.formatt = 'raw' self.stct_request.param = self.stct_request.query self.stct_request.data = self.stct_request.parameter self.stct_request.structured = True return self.stct_request
def load_auth(self): """Load authentication.""" self.called_tools.append('load_auth') try: self.auth = self.load_file_auth() except RbkcliException.ToolsError: try: self.auth = self.load_env_auth() except RbkcliException.ToolsError: self.auth = DotDict({}) # Change the verification for target verification, auth verification # # To be performed before API execution. if not self._verify_target_consistency(self.auth): raise Exception('Verify auth code') return self.auth
def __init__(self, logger, user_profile, auth=None): """Initialize API requester.""" self.logger = logger self.auth = auth if auth is None: self.auth = {} self.url = '' self.api_result = requests.Response() self.user_profile = user_profile self.auth_prpt = DotDict() self.auth_prpt.type_ = '' self.auth_prpt.header = '' self.auth_prpt.primary_exception = ''
def __init__(self, user_profile='config', base_folder='', auth=None): """Initialize CLI helper.""" # Instantiate CLI target self.ops = [] self.ops_v = [] self.args = [] self.incomplete = '' self.result = [] self.rbk_target = None self.ctx = DotDict() self.ctx.user_profile = user_profile self.ctx.base_folder = base_folder self.auth = auth
def __init__(self, logger, user_profile, auth=None): """Initialize API requester.""" self.logger = logger self.auth = auth if auth is None: self.auth = {} self.url = '' self.api_result = requests.Response() self.user_profile = user_profile self.auth_prpt = DotDict() self.auth_prpt.type_ = '' self.auth_prpt.header = '' self.auth_prpt.primary_exception = '' self.python_version = sys.version.split("(")[0].strip() self.rbkcli_version = '1.0.0b4'
def _iteration_context(self, definitions, json_data): """Define the context to use during iteration.""" self.cursor = '' # Create dictionary to save all maps and make it accessible. self.map = DotDict({}) self.map.full = [] self.data_tag = False # Fix by unifying variables and removing redundant self.level = 0 # Json Keys that will be ignored while creating the map. # the following keys are a sort of metadata presented by the # documentation, so we use them to accurately build a valid # representation of any response. self.excluded_fields = [ 'properties', 'items', 'allOf', 'data', 'hasMore', 'total' ] self.exclude_properties = [ 'type', 'format', 'description', 'required', 'enum' ] # Get the schema of the response documentation only. try: json_dict = json_data['doc']['responses']['200']['schema'] except KeyError: json_dict = {} # Translate datatypes from documentation to python json module. self.type_dict = { 'string': 'str', 'unicode': 'str', 'boolean': 'bool', 'integer': 'int', 'empty': 'dict', 'object': 'dict', 'number': 'number', 'array': 'list' } # Iterate json data creating the map result = self._iterate_json(json_dict) # Create map variations from metadata gathered self._gen_all_maps() # Return the map structure. return result
def __init__(self, call_backer, rbkcli_logger): """Initialize external scripts integration class.""" self.rbkcli = call_backer self.rbkcli_logger = rbkcli_logger self.request = DotDict({ 'parameter': {}, 'filter': None, 'version': '', 'context': None, 'table': False, 'select': None, 'list': False, 'query': '', 'method': 'post', 'api_endpoint': [], 'loop': None, 'pretty_print': False, 'info': False, 'documentation': False })
class RubrikApiHandler: """Define methods to execute the APIs.""" def __init__(self, logger, auth, version, user_profile='admin'): """Initialize Rbkcli Executor.""" self._verify_api_version(version) self.local_tools = DotDict({}) self.local_tools.logger = logger self.local_tools.auth = auth self.local_tools.user_profile = user_profile self.version = version self.endpoints = {} self._assign_methods() self.filter_lists = DotDict({}) self.focus_list = [] def _verify_api_version(self, version): """Verify the provided API version.""" if version not in CONSTANTS.SUPPORTED_API_VERSIONS: msg = str('API version [' + version + '] does not match any ' 'accepted version.') error = 'ApiHandlerError # ' + msg self.local_tools.logger.error(msg) raise RbkcliException.ApiHandlerError(error) def _assign_methods(self): """Assign the correct import and execute method based in version.""" if self.version in ('v1', 'v2', 'internal'): self.import_api = self._download_api_doc self.execute_api = self.api_requester else: self.import_api = self._temp_import def _download_api_doc(self): """Download the swagger api-doc file from server.""" try: url = str('https://%s/docs/%s/api-docs' % (self.local_tools.auth.server, self.version)) tmp_tools = RbkcliTools(self.local_tools.logger) content = tmp_tools.download_file(url) content_dict = tmp_tools.yaml_load(content) self.endpoints = { 'paths': content_dict['paths'], 'definitions': content_dict['definitions'] } except RbkcliException.ToolsError as error: msg = '%s [%s]. %s' % ('ApiHandlerError # Unable to download API', self.version, error) self.local_tools.logger.error(msg) return self.endpoints def api_requester(self, *args, **kwargs): """Instantiate requester and request API.""" method, endpoint = args endpoint_key = kwargs['endpoint_key'] data = kwargs['data'] params = kwargs['params'] if self.focus_list != [] and endpoint_key not in self.focus_list: msg = str('Requested endpoint [' + endpoint_key + '] not found on' ' authorized endpoints list.') raise RbkcliException.ApiHandlerError(str(msg)) endpoint = '/%s/%s' % (self.version, endpoint) api_rs = ApiRequester(self.local_tools.logger, self.local_tools.user_profile, auth=self.local_tools.auth).demand(method, endpoint, data=data, params=params) return api_rs def gen_authorization_lists(self): """ Create custom lists of authorized based in the user profile. The focus list is used to verify if the API can be executed or not. """ filter_list = self._create_all_methods_list(string='REQUIRES SUPPORT' ' TOKEN') for user in CONSTANTS.USERS_PROFILE: self.filter_lists[user] = [] requires = '' if user == 'admin': requires = 'NA' for method in CONSTANTS.SUPPORTED_USER_METHODS[user]: for method_line in filter_list: if str(':%s:%s' % (method, requires)) in method_line: self.filter_lists[user].append(method_line) for user, filter_list in self.filter_lists.items(): filter_list.sort() self.focus_list = self.filter_lists[self.local_tools.user_profile] def _create_all_methods_list(self, field='summary', string='TOKEN'): """Generate simplified list of paths and methods.""" filter_list = [] string_ = string.replace(' ', '_') for endpoint, endpoint_data in self.endpoints['paths'].items(): for method, method_data in endpoint_data.items(): filter_list.append('%s:%s:%s:%s' % (self.version, endpoint, method, 'NA')) for doc_field, doc_field_data in method_data.items(): if field == doc_field and string in doc_field_data: filter_list.remove( '%s:%s:%s:%s' % (self.version, endpoint, method, 'NA')) filter_list.append( '%s:%s:%s:%s' % (self.version, endpoint, method, string_)) return filter_list def _temp_import(self): """Place holder import for unpredicted API versions.""" msg = 'ApiHandlerError # Api version not supported.' self.local_tools.logger.error(msg) return {}
def __init__(self, tools): """Initialize scripts customizer APIs class.""" self.tools = tools # Define the path to search. self.meta_api = DotDict() self.scripts_folder = CONSTANTS.BASE_FOLDER + '/scripts'
class RbkcliTools: """Define tools to be widely available throughout the code.""" def __init__(self, logger, conf_dict=None, workflow='command'): """Initialize the tools.""" self.logger = logger self.ssh_conn = False self.called_tools = [] self.workflow = workflow self.auth = DotDict({}) self.auth_dict = {} if conf_dict is None: conf_dict = {} self.conf_dict = conf_dict def load_yaml_file(self, yaml_file): """Open file as read, load yaml, returns dict.""" self.called_tools.append('load_yaml_file') try: with open(yaml_file, 'r') as file: dict_result = yaml.safe_load(file.read()) except FileNotFoundError as error: raise RbkcliException.ToolsError(error) return dict_result def load_json_file(self, json_file): """Open file as read, load json, returns dict.""" self.called_tools.append('load_json_file') try: with open(json_file, 'r') as file: dict_result = json.load(file) except FileNotFoundError as error: self.safe_create_folder(CONSTANTS.CONF_FOLDER) raise RbkcliException.ToolsError(error) except json.decoder.JSONDecodeError as error: raise RbkcliException.ToolsError(error) return dict_result def create_yaml_file(self, yml_dict, yml_file): """Open file as write, dump yaml dict to file.""" self.called_tools.append('create_yaml_file') try: with open(yml_file, 'w') as file: yaml.dump(yml_dict, file, default_flow_style=False) self.logger.debug('File created successfully: ' + yml_file) return True except FileNotFoundError as error: error = str(error) + '\n' msg = 'Exception is ' + error self.logger.error('IOToolsError # ' + msg) return False except Exception as error: error = str(error) + '\n' msg = 'Exception is ' + error self.logger.error('IOToolsError # ' + msg) raise RbkcliException.ToolsError(error) def create_json_file(self, json_dict, json_file): """Open file as write, dump json dict to file.""" self.called_tools.append('create_json_file') try: with open(json_file, 'w') as file: file.write(json.dumps(json_dict, indent=2, sort_keys=True)) self.logger.debug('IOTools # File created successfully: ' + json_file) return True except FileNotFoundError as error: error = str(error) + '\n' msg = 'Exception is ' + error self.logger.error('IOToolsError # ' + msg) return False except Exception as error: error = str(error) + '\n' msg = 'Exception is ' + str(error) self.logger.error('IOToolsError # ' + msg) raise RbkcliException.ToolsError(error) def safe_create_json_file(self, json_dict, json_file): """Open file as write, dump json dict to file.""" if os.path.isfile(json_file): return False else: if not self.create_json_file(json_dict, json_file): return False return True def create_simple_swagger_file(self, data, file): """Create a swagger file, version 2, providing minimum data.""" self.called_tools.append('create_simple_swagger_file') swagger_example = { 'basePath': data['base_path'], 'consumes': ['application/json'], 'info': { 'description': data['description'], 'title': data['title'], 'version': '1.0.0' }, 'paths': data['paths'], 'produces': ['application/json'], 'swagger': '2.0' } return self.create_yaml_file(swagger_example, file) def ssh_connection(self, server, username, password, port=22): """Create paramiko's SSH session with provided data.""" self.called_tools.append('ssh_connection') self.ssh_conn = paramiko.SSHClient() self.ssh_conn.set_missing_host_key_policy(paramiko.AutoAddPolicy()) self.ssh_conn.connect(server, port=port, username=username, password=password) return self.ssh_conn def ssh_cmd(self, cmd, ssh_conn=None): """Execute ssh command using Paramiko exec_command() method.""" self.called_tools.append('ssh_cmd') # If connection arg is not given use the instance ssh_con if ssh_conn == '': ssh_conn = self.ssh_conn # Declaring results = {} stdin, stdout, stderr = ssh_conn.exec_command(cmd) # Split session output in a dictionary name = ['stdin', 'stdout', 'stderr'] for item in enumerate([stdin, stdout, stderr]): try: results[name[item[0]]] = item[1].readlines() except IOError: results[name[item[0]]] = 'Warning ## cant read content' return results def ssh_cmd_shell(self, cmd, ssh_conn=None): """Execute ssh command using Paramiko invoke_shell() method.""" self.called_tools.append('ssh_cmd_shell') # Declaring results = [] ssh_session = ssh_conn.invoke_shell() time.sleep(1) for command in cmd: ssh_session.send(command + '\n') time.sleep(2.5) data = ssh_session.recv(10000) data = data.decode('utf-8') data = data.strip().split('\n') results = results + data ssh_conn.close() return results def load_env_auth(self): """Load authentication data from environment variables.""" self.called_tools.append('load_env_auth') try: self.auth.server = os.environ['rubrik_cdm_node_ip'] self.auth.username = os.environ['rubrik_cdm_username'] self.auth.password = os.environ['rubrik_cdm_password'] self.auth.token = os.environ['rubrik_cdm_token'] except KeyError as bad_key: if str(bad_key) != "\'rubrik_cdm_token\'" and str( bad_key) != "\'RUBRIK_CDM_TOKEN\'": msg = '%s%s%s' % ('Unable to load environmental variable for' ' authentication: ', bad_key, '. Are they defined?') self.logger.error('IOToolsError # ' + msg) raise RbkcliException.ToolsError(msg) else: # Log successful actions keys = '' for line in self.auth.keys(): keys = keys + ',' + line msg = '%s [%s]' % ('IOTools # Successfully loaded' ' environmental vars', keys.strip(',')) self.logger.debug(msg) return self.auth def load_conf_file(self, file='', conf_dict=None): """Load configuration data from json file.""" self.called_tools.append('load_conf_file') if conf_dict is None: conf_dict = {} try: if file == '': file = CONSTANTS.CONF_FOLDER + '/rbkcli.conf' msg = '%s [%s]' % ('IOTools # Successfully loaded configuration' ' file: ', file) if conf_dict == {} and self.conf_dict == {}: self.conf_dict = self.load_json_file(file) self.logger.debug(msg) elif isinstance(conf_dict, dict) and self.conf_dict == {}: self.conf_dict = conf_dict self.logger.debug(msg) else: msg = 'IOTools # Configuration file already loaded.' self.logger.debug(msg) CONSTANTS.CONF_DICT = self.conf_dict except RbkcliException.ToolsError: try: self.create_vanila_conf() self.load_conf_file() except RbkcliException.ToolsError: msg = 'Unable to load configuration file' self.logger.error('IOToolsError # ' + msg) raise RbkcliException.ToolsError(msg) return self.conf_dict def create_vanila_conf(self): """Create a default configuration file.""" self.called_tools.append('create_vanila_conf') conf_dict = { "config": { "storeToken": { "value": "False", "description": str("Caches the last successful token " "with environment data.") }, "logLevel": { "value": "debug", "description": str("Verbosity of the logs written to the" " file logs/rbkcli.log.") }, "useCredentialsFile": { "value": "False", "description": str("Tries to load credentials from auth" " file before looking for env vars.") }, "credentialsFile": { "value": "target.conf", "description": str("File where to load credentials from, " "before looking for env vars.") }, "whiteList": { "description": "", "value": [ 'v1:/session:post:NA', 'internal:/report/{id}/table:post:NA', 'internal:/managed_volume/{id}/begin_snapshot:post:NA', 'internal:/managed_volume/{id}/end_snapshot:post:NA', 'internal:/support/support_bundle:post:NA', 'rbkcli:/cmdlet/profile:get:NA', 'rbkcli:/cmdlet/profile:post:NA', 'rbkcli:/cmdlet/sync:post:NA', 'rbkcli:/cmdlet:delete:NA', 'rbkcli:/cmdlet:get:NA', 'rbkcli:/cmdlet:post:NA', 'rbkcli:/commands:get:NA', 'rbkcli:/jsonfy:get:NA', 'rbkcli:/script/sync:post:NA', 'rbkcli:/script:get:NA', 'scripts:/log/bundle:post:NA' ] }, "blackList": { "description": "", "value": [] }, "userProfile": { "description": str("String value which can be admin or " "support. A profile is a set of API" " endpoints that is available in the" " command line."), "value": "admin" } } } file = CONSTANTS.CONF_FOLDER + '/rbkcli.conf' try: self.safe_create_folder(CONSTANTS.CONF_FOLDER) self.create_json_file(conf_dict, file) msg = 'Successfully created new configuration file' self.logger.debug('IOTools # ' + msg) except Exception: msg = 'Unable to create new configuration file' self.logger.error('IOToolsError # ' + msg) raise RbkcliException.ToolsError(msg) def load_auth_file(self): """Load authentication data from json file.""" self.called_tools.append('load_auth_file') file = 'rbkcli.conf' try: if self.conf_dict == {}: self.load_conf_file() file = self.conf_dict['config']['credentialsFile']['value'] file = CONSTANTS.CONF_FOLDER + '/' + file self.auth_dict = self.load_json_file(file) except RbkcliException.ToolsError: msg = 'Unable to load auth file, [' + file + ']' self.logger.error('IOToolsError # ' + msg) raise RbkcliException.ToolsError(msg) def load_file_auth(self): """Load authentication data from json file.""" self.called_tools.append('load_file_auth') if self.conf_dict['config']['useCredentialsFile']['value'] == 'False': msg = 'CredentialsFile is disable, unable to read from file.' raise RbkcliException.ToolsError(msg) self.load_auth_file() auth_keys = ['server', 'token', 'username', 'password'] for key in auth_keys: self.load_auth_key(key) # Log successful actions keys = '' for line in self.auth.keys(): keys = keys + ',' + line msg = '%s [%s]' % ('IOTools # Successfully loaded file auth data', keys.strip(',')) self.logger.debug(msg) return self.auth def load_auth_key(self, key): """Load key by key confirming if consistency is kept.""" try: self.auth[key] = self.auth_dict[key] except KeyError as bad_key: if str(bad_key) == "\'token\'": if ('username' not in self.auth_dict.keys() and 'password' not in self.auth_dict.keys()): msg = '%s%s%s' % ('Unable to load authentication data from' ' configuration file: ', bad_key, '. Are all keys defined correctly?') self.logger.error('IOToolsError # ' + msg) raise RbkcliException.ToolsError(msg) elif (str(bad_key) != "\'password\'" or str(bad_key) != "\'username\'"): msg = '%s%s%s' % ('Unable to load authentication data from ' 'configuration file: ', bad_key, '. Are all keys defined correctly?') self.logger.error('IOToolsError # ' + msg) raise RbkcliException.ToolsError(msg) def load_auth(self): """Load authentication.""" self.called_tools.append('load_auth') try: self.auth = self.load_file_auth() except RbkcliException.ToolsError: try: self.auth = self.load_env_auth() except RbkcliException.ToolsError: self.auth = DotDict({}) # Change the verification for target verification, auth verification # # To be performed before API execution. if not self._verify_target_consistency(self.auth): raise Exception('Verify auth code') return self.auth def _verify_target_consistency(self, auth): """Verify if minimum auth params has been provided.""" self.auth = auth if 'server' in self.auth.keys(): self.auth.server = self._resolve_target(self.auth.server) if (self.auth.server == '' or not self.is_valid_ip_port(self.auth.server)): if self.workflow == 'command': msg = 'Invalid or missing Rubrik server' self.logger.error('AuthenticationError # ' + msg) self.auth.server = self._user_input( 'Rubrik server IP: ', self.is_valid_ip_port) else: if self.workflow == 'command': msg = 'Invalid or missing authentication parameters.' self.logger.error('AuthenticationError # ' + msg) self.auth.server = self._user_input('Rubrik server IP: ', self.is_valid_ip_port) elif self.workflow == 'complete': self.auth.server = '' return True def verify_auth_consistency(self, auth): """Verify if minimum auth params has been provided.""" self.auth = auth # To Fix Clean if 'token' in self.auth.keys(): if (self.auth.token == '' or not self.is_valid_uuid(self.auth.token)): msg = 'Invalid or missing Rubrik token' self.logger.error('AuthenticationError # ' + msg) self.auth.token = self._user_input('Rubrik API token: ', self.is_valid_uuid) else: pass if 'username' in self.auth.keys() and 'password' in self.auth.keys(): if self.auth.username != '' and self.auth.password != '': pass elif self.auth.username == '': msg = 'Invalid or missing username/password' self.logger.error('AuthenticationError # ' + msg) self.auth.username = self._user_input('Rubrik username: '******'': print('password:'******'': msg = 'Invalid or missing password format' self.logger.error('AuthenticationError # ' + msg) self.auth.password = self._user_input('Rubrik password: '******'Invalid or missing authentication parameters.' self.logger.error('AuthenticationError # ' + msg) return False return True def load_interactive_auth(self, auth): """Get auth values from user.""" self.auth = auth msg = 'Interactive authentication required.' self.logger.warning('AuthenticationWarning # ' + msg) # To Fix Clean self.auth.username = self._user_input('Rubrik username: '******'Rubrik password: '******'config']['useCredentialsFile']['value'] == 'True': self._update_auth_file() return self.auth def _update_auth_file(self): """Add server and username to auth file.""" auth_dict = { 'server': self.auth.server, 'username': self.auth.username, 'password': '' } file = self.conf_dict['config']['credentialsFile']['value'] file = CONSTANTS.CONF_FOLDER + '/' + file self.create_json_file(auth_dict, file) def json_load(self, json_str): """Load json data.""" self.called_tools.append('json_dump') # To Fix Clean try: json_dict = json.loads(json_str) except json.decoder.JSONDecodeError: json_dict = {} return json_dict def yaml_load(self, yaml_str): """Load yaml data.""" self.called_tools.append('json_dump') return yaml.safe_load(yaml_str) def json_dump(self, json_dict): """Dump json data.""" self.called_tools.append('json_dump') if not isinstance(json_dict, dict) and not isinstance(json_dict, list): json_dict = json.loads(json_dict) return json.dumps(json_dict, indent=2, sort_keys=True) def jsonfy(self, avar): """Load json data from string.""" avar_dict = {} if isinstance(avar, requests.models.Response): avar_dict = self.json_load(avar.text) elif isinstance(avar, dict) or isinstance(avar, list): avar_dict = avar else: avar_dict['result'] = str(avar) return self.json_dump(avar_dict) def cp_dict(self, existing_dict): """Copy dictionary completely.""" self.called_tools.append('cp_dict') return copy.deepcopy(existing_dict) def download_file(self, url): """Download file from provided url.""" self.called_tools.append('download_file') pool = urllib3.PoolManager(cert_reqs='CERT_NONE') try: with pool.request('GET', url, preload_content=False) as file: content = file.read() if content == b'Route not defined.': error = str('Wrong or nonexistent URL [' + url + '], route is ' 'not defined') msg = 'IOToolsError # ' + error self.logger.error(msg) raise RbkcliException.ToolsError(error) else: msg = str('IOTools # Successfully downloaded file [%s]' % url) self.logger.debug(msg) except urllib3.exceptions.MaxRetryError as error: msg = 'IOToolsError # ' + str(error) self.logger.error(msg) raise RbkcliException.ToolsError(str(error)) return content def safe_create_folder(self, folder_path): """Create folders that don't exist in a path provided.""" path = '' folder_path = folder_path.replace(CONSTANTS.BASE_FOLDER + "/", "") folders = folder_path.strip().split('/') try: for folder in folders: path = path + folder + '/' final_path = CONSTANTS.BASE_FOLDER + "/" + path if os.path.isdir(final_path): msg = str('IOTools # Found existing folder [' + final_path + '], not taking action.') self.logger.debug(msg) else: os.mkdir(final_path) msg = str('IOTools # Could not find folder [' + final_path + '], creating new.') if self.logger.status == 'created': self.logger.warning(msg) else: self.logger.debug(msg) return True except Exception as error: self.logger.error('IOToolsError # ' + str(error)) return False def is_valid_uuid1(self, uuid_to_test, version=4): """Copy dictionary completely.""" self.called_tools.append('is_valid_uuid') try: uuid_obj = UUID(uuid_to_test, version=version) except ValueError: return False return str(uuid_obj) == uuid_to_test def is_valid_uuid(self, uuid_to_test, version=4): """Copy dictionary completely.""" # Because of the creation of the universal ID rbkcli no longer # verifies id validity del uuid_to_test, version self.called_tools.append('is_valid_uuid') return True @staticmethod def is_valid_ip(ip): """Validate if provided IP is valid, takes IPv4/IPv6.""" try: # Python 2 compatibility try: ip = unicode(ip, "utf-8") except NameError: pass new_ip = ipaddress.ip_address(ip) del new_ip result = True except ValueError: result = False return result def is_valid_ip_port(self, ip_port): """Validate if provided IP is valid, takes IPv4/IPv6.""" if ':' in ip_port: ip, port = ip_port.split(':') try: if (self.is_valid_ip(ip) and 65535 > int(port) > 0): return True else: return False except ValueError: return False else: return self.is_valid_ip(ip_port) def _resolve_target(self, target_name): """Resolve target fqdn to IP.""" # Split port and fqdn if ':' in target_name: target_name = target_name.split(':') target_ip = target_name[0] port = ':' + target_name[1] else: port = '' target_ip = target_name try: target_ip = str(socket.gethostbyname(target_ip)) except socket.gaierror: msg = 'Unable to resolve FQDN [%s].' % target_ip self.logger.error('ToolsError # ' + msg) raise RbkcliException.ToolsError(msg) return target_ip + port @staticmethod def is_not_empty_str(value): """Test if string is not empty.""" return not value == '' @staticmethod def _user_input(msg, validator, inputer=input): """Validate user input.""" value = inputer(msg) while not validator(value): value = input(msg) return value @staticmethod def gen_uuid(): """Generate UUID version 4.""" return uuid4()
def _iteration_context(self, definitions, json_data): """Define the context to use during iteration.""" # Assign definitions to instance var. if definitions == []: definitions = {} self.definitions = definitions # Assign flag for returning the selected data. self.returning = True # Create the necessary var for map validated selection. self.cursor = '' self.level = 0 # Create dictionary to save all maps and make it accessible. self.map = DotDict({}) self.map.full = [] # Dictionary with selected keys. self.selected = {} # TEST self.unselected = {} self.type_dict = { 'str': 'str', 'unicode': 'str', 'bool': 'bool', 'int': 'int', 'dict': 'dict', 'number': 'number', 'list': 'list' } for key, value in definitions.items(): self.selected[key] = 'N/A' self.unselected[key] = '' # Iterate provided json data. self._iterate_json(json_data) # Once the iteration is based on the metadata_key that is matched # then, the ones that are not matched are never treated, so: # Created the unselected dictionary that stores the keys that were # never analyzed. # If after the iteration, there are unselected fields that are # supposed to be filtered, then result should not be returned. # Practical meaning here is, if a filter/selection was ordered but the # field which we are filtering does not exist in the json at hand, # the code will interpret it as a miss match and not add it to the # list of results. for key in self.unselected: if (definitions[key]['filter_eq'] != '' or definitions[key]['filter_aprox'] != '' or definitions[key]['filter_not'] != '' or definitions[key]['filter_not_aprox'] != ''): self.returning = False # From full map create simple keys map. self._gen_all_maps() # Use the flag to determine the return. if self.returning: return self.selected return {}