Пример #1
0
    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
Пример #2
0
    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
Пример #3
0
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)
Пример #4
0
 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)
Пример #5
0
    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()
Пример #6
0
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)
Пример #7
0
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
Пример #8
0
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