diff options
| author | John Estabrook <jestabro@vyos.io> | 2022-07-31 14:33:44 -0500 | 
|---|---|---|
| committer | John Estabrook <jestabro@vyos.io> | 2022-07-31 14:34:19 -0500 | 
| commit | 0e9115e34305d5a703a72557d0830e2d0ed385ac (patch) | |
| tree | 435eaecec06018e105aab2665451e5b24a66a9c7 | |
| parent | dbc8e243e13b370e74c6ab20b642c881b6377bd5 (diff) | |
| download | vyos-1x-0e9115e34305d5a703a72557d0830e2d0ed385ac.tar.gz vyos-1x-0e9115e34305d5a703a72557d0830e2d0ed385ac.zip | |
graphql: T4580: handle case of op-mode script name containing hyphens
| -rw-r--r-- | src/services/api/graphql/recipes/session.py | 18 | ||||
| -rwxr-xr-x | src/services/api/graphql/utils/schema_from_op_mode.py | 2 | ||||
| -rw-r--r-- | src/services/api/graphql/utils/util.py | 31 | 
3 files changed, 36 insertions, 15 deletions
| diff --git a/src/services/api/graphql/recipes/session.py b/src/services/api/graphql/recipes/session.py index 6b580af01..ac185beb7 100644 --- a/src/services/api/graphql/recipes/session.py +++ b/src/services/api/graphql/recipes/session.py @@ -40,7 +40,7 @@ class Session:          try:              with open(op_mode_include_file) as f: -                self._op_mode_list = f.read() +                self._op_mode_list = json.loads(f.read())          except Exception:              self._op_mode_list = None @@ -171,11 +171,11 @@ class Session:          # handle the case that the op-mode file contains underscores:          if op_mode_list is None:              raise FileNotFoundError(f"No op-mode file list at '{op_mode_include_file}'") -        (func_name, basename) = split_compound_op_mode_name(name, op_mode_list) -        if basename == '': -            raise FileNotFoundError(f"No op-mode file basename in string '{name}'") +        (func_name, scriptname) = split_compound_op_mode_name(name, op_mode_list) +        if scriptname == '': +            raise FileNotFoundError(f"No op-mode file named in string '{name}'") -        mod = load_op_mode_as_module(f'{basename}.py') +        mod = load_op_mode_as_module(f'{scriptname}')          func = getattr(mod, func_name)          if len(list(data)) > 0:              res = func(True, **data) @@ -193,11 +193,11 @@ class Session:          # handle the case that the op-mode file name contains underscores:          if op_mode_list is None:              raise FileNotFoundError(f"No op-mode file list at '{op_mode_include_file}'") -        (func_name, basename) = split_compound_op_mode_name(name, op_mode_list) -        if basename == '': -            raise FileNotFoundError(f"No op-mode file basename in string '{name}'") +        (func_name, scriptname) = split_compound_op_mode_name(name, op_mode_list) +        if scriptname == '': +            raise FileNotFoundError(f"No op-mode file named in string '{name}'") -        mod = load_op_mode_as_module(f'{basename}.py') +        mod = load_op_mode_as_module(f'{scriptname}')          func = getattr(mod, func_name)          if len(list(data)) > 0:              res = func(**data) diff --git a/src/services/api/graphql/utils/schema_from_op_mode.py b/src/services/api/graphql/utils/schema_from_op_mode.py index cdde5f187..d27586747 100755 --- a/src/services/api/graphql/utils/schema_from_op_mode.py +++ b/src/services/api/graphql/utils/schema_from_op_mode.py @@ -138,7 +138,7 @@ def generate_op_mode_definitions():          op_mode_files = json.load(f)      for file in op_mode_files: -        basename = os.path.splitext(file)[0] +        basename = os.path.splitext(file)[0].replace('-', '_')          module = load_as_module(basename, os.path.join(OP_MODE_PATH, file))          funcs = getmembers(module, isfunction) diff --git a/src/services/api/graphql/utils/util.py b/src/services/api/graphql/utils/util.py index e3dea31bf..073126853 100644 --- a/src/services/api/graphql/utils/util.py +++ b/src/services/api/graphql/utils/util.py @@ -27,7 +27,7 @@ def load_as_module(name: str, path: str):  def load_op_mode_as_module(name: str):      path = os.path.join(directories['op_mode'], name) -    name = os.path.splitext(name)[0] +    name = os.path.splitext(name)[0].replace('-', '_')      return load_as_module(name, path)  def is_op_mode_function_name(name): @@ -40,16 +40,37 @@ def is_show_function_name(name):          return True      return False +def _nth_split(delim: str, n: int, s: str): +    groups = s.split(delim) +    l = len(groups) +    if n > l-1 or n < 1: +        return (s, '') +    return (delim.join(groups[:n]), delim.join(groups[n:])) +  def _nth_rsplit(delim: str, n: int, s: str):      groups = s.split(delim)      l = len(groups) -    if n > l-1: -        return ('', s) +    if n > l-1 or n < 1: +        return (s, '')      return (delim.join(groups[:l-n]), delim.join(groups[l-n:])) +# Since we have mangled possible hyphens in the file name while constructing +# the snake case of the query/mutation name, we will need to recover the +# file name by searching with mangling: +def _filter_on_mangled(test): +    def func(elem): +        mangle = os.path.splitext(elem)[0].replace('-', '_') +        return test == mangle +    return func + +# Find longest name in concatenated string that matches the basename of an +# op-mode script. Should one prefer to concatenate in the reverse order +# (script_name + '_' + function_name), use _nth_rsplit.  def split_compound_op_mode_name(name: str, files: list):      for i in range(1, name.count('_') + 1): -        pair = _nth_rsplit('_', i, name) -        if pair[1] in files: +        pair = _nth_split('_', i, name) +        f = list(filter(_filter_on_mangled(pair[1]), files)) +        if f: +            pair = (pair[0], f[0])              return pair      return (name, '') | 
