def set_hri(self, v, save=False): def parse_str(s): d = s if isinstance(s, list) else s.strip().split() interval = None f = None for i, x in enumerate(d): if x == 'interval': try: interval = float(d[i + 1]) if len(d) > i + 2: raise Exception except: raise ValueError('Invalid interval') f = ' '.join(d[:i]) break if not f: f = ' '.join(s) if isinstance(s, list) else s return interval, f try: interval, f = parse_str(v) except Exception as e: raise FunctionFailed(e) if interval: try: if not self.set_prop('interval', interval): raise Exception except: raise FunctionFailed('Unable to set cycle interval') try: name, args, kwargs = parse_func_str(f) except Exception as e: raise FunctionFailed(e) if not self.set_prop('macro', name): raise FunctionFailed('Unable to set cycle macro') if not self.set_prop('macro_args', args): raise FunctionFailed('Unable to set cycle macro args') if not self.set_prop('macro_kwargs', kwargs): raise FunctionFailed('Unable to set cycle macro kwargs') if save: self.save() return True
def set_hri(self, v, save=False): def parse_str(s): d = s if isinstance(s, list) else s.strip().split() every = None f = None for i, x in enumerate(d): if x == 'every': f = ' '.join(d[:i]) every = ' '.join(d[i + 1:]) break if not f: f = ' '.join(s) if isinstance(s, list) else s return every, f try: every, f = parse_str(v) except Exception as e: raise FunctionFailed(e) if every: try: if not self.set_prop('every', every): raise Exception except: raise FunctionFailed('Unable to set job schedule') try: name, args, kwargs = parse_func_str(f) except Exception as e: raise FunctionFailed(e) if not self.set_prop('macro', name): raise FunctionFailed('Unable to set job macro') if not self.set_prop('macro_args', args): raise FunctionFailed('Unable to set job macro args') if not self.set_prop('macro_kwargs', kwargs): raise FunctionFailed('Unable to set job macro kwargs') if save: self.save() return True
def append_macro_function(file_name, rebuild=True): def parse_arg(fndoc): x = re.split('[\ \t]+', d, 2) argname = x[1] if len(x) > 2: argdescr = x[2] else: argdescr = '' result = {'description': argdescr} if argname.find('=') != -1: argname, argval = argname.split('=', 1) try: argval = float(argval) if argval == int(argval): argval = int(argval) except: pass result['default'] = argval result['var'] = argname return result try: with open(file_name) as fd: raw = fd.read() fname = os.path.basename(file_name[:-3]) if raw.startswith('# FBD'): l = raw.split('\n') jcode = '' for i in range(3, len(l)): if l[i].startswith('"""'): break jcode += l[i] j = rapidjson.loads(jcode) tp = 'fbd-json' else: tp = 'py' code, src_code = raw, raw if tp == 'py': code += '\nimport inspect\nfndoc = inspect.getdoc({})\n'.format( fname, fname) code += 'fnsrc = inspect.getsource({})\n'.format(fname) d = {} c = compile(code, file_name, 'exec') exec(c, d) if tp == 'py': src = '' x = 0 indent = 4 for s in d['fnsrc'].split('\n'): if x >= 2: if src: src += '\n' src += s[indent:] st = s.strip() if st.startswith('\'\'\'') or st.startswith('"""'): if not x: indent = len(s) - len(st) x += 1 elif tp == 'fbd-json': src = j result = { 'name': fname, 'var_in': [], 'var_out': [], 'src': src, 'editable': True, 'group': 'custom', 'description': '', 'type': tp } if tp == 'py': doc = d['fndoc'] if doc: for d in doc.split('\n'): d = d.strip() if d.startswith('@var_in'): result['var_in'].append(parse_arg(d)) if d.startswith('@var_out'): result['var_out'].append(parse_arg(d)) if d.startswith('@description'): try: result['description'] = re.split('[\ \t]+', d, 1)[1] except: pass elif tp == 'fbd-json': result['description'] = j.get('description', '') for x in j.get('input', []): result['var_in'].append({ 'var': x.get('var'), 'description': x.get('description', '') }) for x in j.get('output', []): result['var_out'].append({ 'var': x.get('var'), 'description': x.get('description', '') }) macro_functions[fname] = result macro_function_codes[fname] = src_code if rebuild: rebuild_mfcode() return True except Exception as e: raise FunctionFailed(e)
def set_prop(self, prop, value=None, save=False): with key_lock: if not self.dynamic or self.master: raise FunctionFailed( 'Master and static keys can not be changed') if prop == 'key': if value is None or value == '' or value.find( ':') != -1 or value.find('|') != -1: return False if self.key != value: if value in keys: raise ResourceAlreadyExists('API key') regenerate_key(self.key_id, k=value, save=False) self.set_modified(save) return True elif prop == 'dynamic': return False elif prop == 'sysfunc': val = val_to_boolean(value) if val is None: return False if self.sysfunc != val: self.sysfunc = val self.set_modified(save) return True elif prop == 'items': if isinstance(value, list): val = value else: if value: val = value.split(',') else: val = [] if self.item_ids != val: self.item_ids = val self.set_modified(save) return True elif prop == 'groups': if isinstance(value, list): val = value else: if value: val = value.split(',') else: val = [] if self.groups != val: self.groups = val self.set_modified(save) return True elif prop == 'items_ro': if isinstance(value, list): val = value else: if value: val = value.split(',') else: val = [] if self.item_ids_ro != val: self.item_ids_ro = val self.set_modified(save) return True elif prop == 'groups_ro': if isinstance(value, list): val = value else: if value: val = value.split(',') else: val = [] if self.groups_ro != val: self.groups_ro = val self.set_modified(save) return True elif prop == 'items_deny': if isinstance(value, list): val = value else: if value: val = value.split(',') else: val = [] if self.item_ids_deny != val: self.item_ids_deny = val self.set_modified(save) return True elif prop == 'groups_deny': if isinstance(value, list): val = value else: if value: val = value.split(',') else: val = [] if self.groups_deny != val: self.groups_deny = val self.set_modified(save) return True elif prop == 'allow': if isinstance(value, list): val = value else: if value: val = value.split(',') else: val = [] for v in val: if v not in all_allows: return False if self.allow != val: self.allow = val self.set_modified(save) return True elif prop == 'hosts_allow': if isinstance(value, list): val = value else: if value: val = value.split(',') else: val = ['0.0.0.0/0'] val = [IPNetwork(h) for h in val] if self.hosts_allow != val: self.hosts_allow = val self.set_modified(save) return True elif prop == 'hosts_assign': if isinstance(value, list): val = value else: if value: val = value.split(',') else: val = [] val = [IPNetwork(h) for h in val] if self.hosts_assign != val: self.hosts_assign = val self.set_modified(save) return True elif prop == 'pvt': if isinstance(value, list): val = value else: if value: val = value.split(',') else: val = [] if self.pvt_files != val: self.pvt_files = val self.set_modified(save) return True elif prop == 'rpvt': if isinstance(value, list): val = value else: if value: val = value.split(',') else: val = [] if self.rpvt_uris != val: self.rpvt_uris = val self.set_modified(save) return True elif prop == 'cdata': val = [] if value is None else value if isinstance(val, str): val = val.split(',') res = [] for v in val: if v not in res: res.append(str(v)) if self.cdata != res: self.cdata = res self.set_modified(save) return True raise ResourceNotFound('property ' + prop)
def run(self, macro, argv=None, kwargs=None, wait=0, uuid=None, priority=None): """ execute another macro Execute a macro with the specified arguments. Args: macro: macro id Optional: args: macro arguments, array or space separated kwargs: macro keyword arguments, name=value, comma separated or dict wait: wait for the completion for the specified number of seconds uuid: action UUID (will be auto generated if none specified) priority: queue priority (default is 100, lower is better) Returns: Serialized macro action object (dict) Raises: ResourceNotFound: macro is not found @var_out exitcode Exit code @var_out status Action status @var_out out Macro "out" variable """ _argv = [] if isinstance(argv, str): try: _argv = shlex.split(argv) except: _argv = argv.split(' ') elif isinstance(argv, float) or isinstance(argv, int): _argv = [argv] elif isinstance(argv, list): _argv = argv if isinstance(kwargs, str): try: kw = dict_from_str(kwargs) except: kw = {} elif isinstance(kwargs, dict): kw = kwargs else: kw = {} a = eva.lm.controller.exec_macro(macro=oid_to_id(macro, 'lmacro'), argv=_argv, kwargs=kw, priority=priority, action_uuid=uuid, wait=wait) if not a: raise ResourceNotFound elif a.is_status_dead(): raise FunctionFailed('queue error') else: return a.serialize()
def destroy_item(item): try: if isinstance(item, str): i = get_item(item) if not i: raise ResourceNotFound else: i = item if not eva.core.config.enterprise_layout: del items_by_id[i.item_id] del items_by_full_id[i.full_id] del items_by_group[i.group][i.item_id] if i.item_type == 'unit': if not eva.core.config.enterprise_layout: del units_by_id[i.item_id] del units_by_full_id[i.full_id] del units_by_group[i.group][i.item_id] if not units_by_group[i.group]: del units_by_group[i.group] if i.item_type == 'sensor': if not eva.core.config.enterprise_layout: del sensors_by_id[i.item_id] del sensors_by_full_id[i.full_id] del sensors_by_group[i.group][i.item_id] if not sensors_by_group[i.group]: del sensors_by_group[i.group] if i.item_type == 'mu': if not eva.core.config.enterprise_layout: del mu_by_id[i.item_id] del mu_by_full_id[i.full_id] del mu_by_group[i.group][i.item_id] if not mu_by_group[i.group]: del mu_by_group[i.group] if not items_by_group[i.group]: del items_by_group[i.group] i.destroy() if eva.core.config.auto_save: if i.config_file_exists: try: eva.registry.key_delete(i.get_rkn()) except: logging.error('Can not remove %s config' % i.full_id) eva.core.log_traceback() if eva.core.config.state_to_registry: try: eva.registry.key_delete(i.get_rskn()) except: logging.error('Can not remove %s state key' % i.full_id) eva.core.log_traceback() else: if i.config_file_exists: configs_to_remove.add(i.get_rkn()) if eva.core.config.state_to_registry: configs_to_remove.add(i.get_rskn()) logging.info('%s destroyed' % i.full_id) return True except ResourceNotFound: raise except Exception as e: eva.core.log_traceback() raise FunctionFailed(e)
def load_driver(lpi_id, lpi_mod_id, phi_id, lpi_cfg=None, start=True, config_validated=False, _o=None, set_modified=True): if get_phi(phi_id) is None: raise ResourceNotFound( 'Unable to load LPI, unknown PHI: {}'.format(phi_id)) if not lpi_id: raise InvalidParameter('LPI id not specified') if not re.match("^[A-Za-z0-9_-]*$", lpi_id): raise InvalidParameter( 'LPI {} id contains forbidden symbols'.format(lpi_id)) if _o is None: # import module try: lpi_mod = import_x(_get_lpi_module_fname(lpi_mod_id)) _api = lpi_mod.__api__ _author = lpi_mod.__author__ _version = lpi_mod.__version__ _description = lpi_mod.__description__ _license = lpi_mod.__license__ _logic = lpi_mod.__logic__ logging.info('LPI loaded %s v%s, author: %s, license: %s' % (lpi_mod_id, _version, _author, _license)) logging.debug('%s: %s' % (lpi_mod_id, _description)) if _logic == 'abstract': logging.error( 'Unable to activate LPI %s: ' % lpi_mod_id + \ 'abstract module' ) return False if _api > __api__: logging.error( 'Unable to activate LPI %s: ' % lpi_mod_id + \ 'controller driver API version is %s, ' % __api__ + \ 'LPI driver API version is %s' % _api) return False except Exception as e: raise FunctionFailed('unable to load LPI mod {}: {}'.format( lpi_mod_id, e)) else: lpi_mod = _o.__xmod__ lpi = lpi_mod.LPI(lpi_cfg=lpi_cfg, phi_id=phi_id, config_validated=config_validated, _xmod=lpi_mod) if not lpi.ready: raise FunctionFailed('unable to init LPI mod %s' % lpi_mod_id) lpi.lpi_id = lpi_id lpi.driver_id = phi_id + '.' + lpi_id lpi.oid = 'driver:uc/%s/%s' % (eva.core.config.system_name, lpi.driver_id) if lpi.driver_id in drivers: try: drivers[lpi.driver_id]._stop() except: eva.core.log_traceback() drivers[lpi.driver_id] = lpi if set_modified: _d.driver_modified.add(lpi.driver_id) if start: try: lpi._start() except: eva.core.log_traceback() return lpi
def load_phi(phi_id, phi_mod_id, phi_cfg=None, start=True, config_validated=False, _o=None, set_modified=True): if not phi_id: raise InvalidParameter('PHI id not specified') if not re.match("^[A-Za-z0-9_-]*$", phi_id): raise InvalidParameter('PHI %s id contains forbidden symbols' % phi_id) if _o is None: # import module try: phi_mod = import_x(_get_phi_module_fname(phi_mod_id)) _api = phi_mod.__api__ _author = phi_mod.__author__ _version = phi_mod.__version__ _description = phi_mod.__description__ _license = phi_mod.__license__ _equipment = phi_mod.__equipment__ logging.info('PHI loaded %s v%s, author: %s, license: %s' % (phi_mod_id, _version, _author, _license)) logging.debug('%s: %s' % (phi_mod_id, _description)) if _equipment == 'abstract': logging.error( 'Unable to activate PHI %s: ' % phi_mod_id + \ 'abstract module' ) raise FunctionFailed('PHI module is abstract') if _api > __api__: logging.error( 'Unable to activate PHI %s: ' % phi_mod_id + \ 'controller driver API version is %s, ' % __api__ + \ 'PHI driver API version is %s' % _api) raise FunctionFailed('unsupported driver API version') except Exception as e: raise FunctionFailed('unable to load PHI mod {}: {}'.format( phi_mod_id, e)) else: phi_mod = _o.__xmod__ phi = phi_mod.PHI(phi_cfg=phi_cfg, config_validated=config_validated, _xmod=phi_mod) if not phi.ready: raise FunctionFailed('unable to init PHI mod %s' % phi_mod_id) phi.phi_id = phi_id phi.oid = 'phi:uc/%s/%s' % (eva.core.config.system_name, phi_id) if phi_id in phis: try: phis[phi_id]._stop_processors() phis[phi_id]._stop() except: eva.core.log_traceback() phis[phi_id] = phi if set_modified: _d.phi_modified.add(phi_id) if not phi_id in items_by_phi: items_by_phi[phi_id] = set() if start: try: phi._start() phi._start_processors() except: eva.core.log_traceback() ld = phi.get_default_lpi() if ld: load_driver('default', ld, phi_id, start=True) return phi