diff options
| author | John Estabrook <jestabro@vyos.io> | 2022-10-23 11:07:46 -0500 | 
|---|---|---|
| committer | John Estabrook <jestabro@vyos.io> | 2022-10-25 10:35:48 -0500 | 
| commit | af56ddf4615974c6b5f5886520d6abb0781cea80 (patch) | |
| tree | 3615850297850c792f5804621d4d83652c8023f5 | |
| parent | f76a6f68b08fce1feee2dbbb84658b8eede09655 (diff) | |
| download | vyos-1x-af56ddf4615974c6b5f5886520d6abb0781cea80.tar.gz vyos-1x-af56ddf4615974c6b5f5886520d6abb0781cea80.zip | |
graphql: T4574: read config and generate schema with/without key auth
4 files changed, 144 insertions, 9 deletions
| diff --git a/src/services/api/graphql/generate/schema_from_composite.py b/src/services/api/graphql/generate/schema_from_composite.py index 7187047a0..61a08cb2f 100755 --- a/src/services/api/graphql/generate/schema_from_composite.py +++ b/src/services/api/graphql/generate/schema_from_composite.py @@ -29,22 +29,50 @@ if __package__ is None or __package__ == '':      sys.path.append("/usr/libexec/vyos/services/api")      from graphql.libs.op_mode import snake_to_pascal_case, map_type_name      from composite_function import queries, mutations +    from vyos.config import Config +    from vyos.configdict import dict_merge +    from vyos.xml import defaults  else:      from .. libs.op_mode import snake_to_pascal_case, map_type_name      from . composite_function import queries, mutations +    from .. import state  SCHEMA_PATH = directories['api_schema'] -schema_data: dict = {'schema_name': '', +if __package__ is None or __package__ == '': +    # allow running stand-alone +    conf = Config() +    base = ['service', 'https', 'api'] +    graphql_dict = conf.get_config_dict(base, key_mangling=('-', '_'), +                                          no_tag_node_value_mangle=True, +                                          get_first_key=True) +    if 'graphql' not in graphql_dict: +        exit("graphql is not configured") + +    graphql_dict = dict_merge(defaults(base), graphql_dict) +    auth_type = graphql_dict['graphql']['authentication']['type'] +else: +    auth_type = state.settings['app'].state.vyos_auth_type + +schema_data: dict = {'auth_type': auth_type, +                     'schema_name': '',                       'schema_fields': []}  query_template  = """ +{%- if auth_type == 'key' %}  input {{ schema_name }}Input {      key: String!      {%- for field_entry in schema_fields %}      {{ field_entry }}      {%- endfor %}  } +{%- elif schema_fields %} +input {{ schema_name }}Input { +    {%- for field_entry in schema_fields %} +    {{ field_entry }} +    {%- endfor %} +} +{%- endif %}  type {{ schema_name }} {      result: Generic @@ -57,17 +85,29 @@ type {{ schema_name }}Result {  }  extend type Query { +{%- if auth_type == 'key' or schema_fields %}      {{ schema_name }}(data: {{ schema_name }}Input) : {{ schema_name }}Result @compositequery +{%- else %} +    {{ schema_name }} : {{ schema_name }}Result @compositequery +{%- endif %}  }  """  mutation_template  = """ +{%- if auth_type == 'key' %}  input {{ schema_name }}Input {      key: String!      {%- for field_entry in schema_fields %}      {{ field_entry }}      {%- endfor %}  } +{%- elif schema_fields %} +input {{ schema_name }}Input { +    {%- for field_entry in schema_fields %} +    {{ field_entry }} +    {%- endfor %} +} +{%- endif %}  type {{ schema_name }} {      result: Generic @@ -80,7 +120,11 @@ type {{ schema_name }}Result {  }  extend type Mutation { +{%- if auth_type == 'key' or schema_fields %}      {{ schema_name }}(data: {{ schema_name }}Input) : {{ schema_name }}Result @compositemutation +{%- else %} +    {{ schema_name }} : {{ schema_name }}Result @compositemutation +{%- endif %}  }  """ diff --git a/src/services/api/graphql/generate/schema_from_config_session.py b/src/services/api/graphql/generate/schema_from_config_session.py index cf69cbafd..49bf2440e 100755 --- a/src/services/api/graphql/generate/schema_from_config_session.py +++ b/src/services/api/graphql/generate/schema_from_config_session.py @@ -29,22 +29,50 @@ if __package__ is None or __package__ == '':      sys.path.append("/usr/libexec/vyos/services/api")      from graphql.libs.op_mode import snake_to_pascal_case, map_type_name      from config_session_function import queries, mutations +    from vyos.config import Config +    from vyos.configdict import dict_merge +    from vyos.xml import defaults  else:      from .. libs.op_mode import snake_to_pascal_case, map_type_name      from . config_session_function import queries, mutations +    from .. import state  SCHEMA_PATH = directories['api_schema'] -schema_data: dict = {'schema_name': '', +if __package__ is None or __package__ == '': +    # allow running stand-alone +    conf = Config() +    base = ['service', 'https', 'api'] +    graphql_dict = conf.get_config_dict(base, key_mangling=('-', '_'), +                                          no_tag_node_value_mangle=True, +                                          get_first_key=True) +    if 'graphql' not in graphql_dict: +        exit("graphql is not configured") + +    graphql_dict = dict_merge(defaults(base), graphql_dict) +    auth_type = graphql_dict['graphql']['authentication']['type'] +else: +    auth_type = state.settings['app'].state.vyos_auth_type + +schema_data: dict = {'auth_type': auth_type, +                     'schema_name': '',                       'schema_fields': []}  query_template  = """ +{%- if auth_type == 'key' %}  input {{ schema_name }}Input {      key: String!      {%- for field_entry in schema_fields %}      {{ field_entry }}      {%- endfor %}  } +{%- elif schema_fields %} +input {{ schema_name }}Input { +    {%- for field_entry in schema_fields %} +    {{ field_entry }} +    {%- endfor %} +} +{%- endif %}  type {{ schema_name }} {      result: Generic @@ -57,17 +85,29 @@ type {{ schema_name }}Result {  }  extend type Query { +{%- if auth_type == 'key' or schema_fields %}      {{ schema_name }}(data: {{ schema_name }}Input) : {{ schema_name }}Result @configsessionquery +{%- else %} +    {{ schema_name }} : {{ schema_name }}Result @configsessionquery +{%- endif %}  }  """  mutation_template  = """ +{%- if auth_type == 'key' %}  input {{ schema_name }}Input {      key: String!      {%- for field_entry in schema_fields %}      {{ field_entry }}      {%- endfor %}  } +{%- elif schema_fields %} +input {{ schema_name }}Input { +    {%- for field_entry in schema_fields %} +    {{ field_entry }} +    {%- endfor %} +} +{%- endif %}  type {{ schema_name }} {      result: Generic @@ -80,7 +120,11 @@ type {{ schema_name }}Result {  }  extend type Mutation { +{%- if auth_type == 'key' or schema_fields %}      {{ schema_name }}(data: {{ schema_name }}Input) : {{ schema_name }}Result @configsessionmutation +{%- else %} +    {{ schema_name }} : {{ schema_name }}Result @configsessionmutation +{%- endif %}  }  """ diff --git a/src/services/api/graphql/generate/schema_from_op_mode.py b/src/services/api/graphql/generate/schema_from_op_mode.py index a88816b34..1fd198a37 100755 --- a/src/services/api/graphql/generate/schema_from_op_mode.py +++ b/src/services/api/graphql/generate/schema_from_op_mode.py @@ -29,9 +29,13 @@ if __package__ is None or __package__ == '':      sys.path.append("/usr/libexec/vyos/services/api")      from graphql.libs.op_mode import load_as_module, is_op_mode_function_name, is_show_function_name      from graphql.libs.op_mode import snake_to_pascal_case, map_type_name +    from vyos.config import Config +    from vyos.configdict import dict_merge +    from vyos.xml import defaults  else:      from .. libs.op_mode import load_as_module, is_op_mode_function_name, is_show_function_name      from .. libs.op_mode import snake_to_pascal_case, map_type_name +    from .. import state  OP_MODE_PATH = directories['op_mode']  SCHEMA_PATH = directories['api_schema'] @@ -40,16 +44,40 @@ DATA_DIR = directories['data']  op_mode_include_file = os.path.join(DATA_DIR, 'op-mode-standardized.json')  op_mode_error_schema = 'op_mode_error.graphql' -schema_data: dict = {'schema_name': '', +if __package__ is None or __package__ == '': +    # allow running stand-alone +    conf = Config() +    base = ['service', 'https', 'api'] +    graphql_dict = conf.get_config_dict(base, key_mangling=('-', '_'), +                                          no_tag_node_value_mangle=True, +                                          get_first_key=True) +    if 'graphql' not in graphql_dict: +        exit("graphql is not configured") + +    graphql_dict = dict_merge(defaults(base), graphql_dict) +    auth_type = graphql_dict['graphql']['authentication']['type'] +else: +    auth_type = state.settings['app'].state.vyos_auth_type + +schema_data: dict = {'auth_type': auth_type, +                     'schema_name': '',                       'schema_fields': []}  query_template  = """ +{%- if auth_type == 'key' %}  input {{ schema_name }}Input {      key: String!      {%- for field_entry in schema_fields %}      {{ field_entry }}      {%- endfor %}  } +{%- elif schema_fields %} +input {{ schema_name }}Input { +    {%- for field_entry in schema_fields %} +    {{ field_entry }} +    {%- endfor %} +} +{%- endif %}  type {{ schema_name }} {      result: Generic @@ -63,17 +91,29 @@ type {{ schema_name }}Result {  }  extend type Query { +{%- if auth_type == 'key' or schema_fields %}      {{ schema_name }}(data: {{ schema_name }}Input) : {{ schema_name }}Result @genopquery +{%- else %} +    {{ schema_name }} : {{ schema_name }}Result @genopquery +{%- endif %}  }  """  mutation_template  = """ +{%- if auth_type == 'key' %}  input {{ schema_name }}Input {      key: String!      {%- for field_entry in schema_fields %}      {{ field_entry }}      {%- endfor %}  } +{%- elif schema_fields %} +input {{ schema_name }}Input { +    {%- for field_entry in schema_fields %} +    {{ field_entry }} +    {%- endfor %} +} +{%- endif %}  type {{ schema_name }} {      result: Generic @@ -87,7 +127,11 @@ type {{ schema_name }}Result {  }  extend type Mutation { +{%- if auth_type == 'key' or schema_fields %}      {{ schema_name }}(data: {{ schema_name }}Input) : {{ schema_name }}Result @genopmutation +{%- else %} +    {{ schema_name }} : {{ schema_name }}Result @genopquery +{%- endif %}  }  """ diff --git a/src/services/vyos-http-api-server b/src/services/vyos-http-api-server index 632c1e87d..7a35546e5 100755 --- a/src/services/vyos-http-api-server +++ b/src/services/vyos-http-api-server @@ -647,11 +647,11 @@ def reset_op(data: ResetModel):  ###  def graphql_init(fast_api_app): -    from api.graphql.bindings import generate_schema -      api.graphql.state.init()      api.graphql.state.settings['app'] = app +    # import after initializaion of state +    from api.graphql.bindings import generate_schema      schema = generate_schema()      in_spec = app.state.vyos_introspection @@ -690,10 +690,13 @@ if __name__ == '__main__':      app.state.vyos_origins = server_config.get('cors', {}).get('allow_origin', [])      if 'graphql' in server_config:          app.state.vyos_graphql = True -        if isinstance(server_config['graphql'], dict) and 'introspection' in server_config['graphql']: -            app.state.vyos_introspection = True -        else: -            app.state.vyos_introspection = False +        if isinstance(server_config['graphql'], dict): +            if 'introspection' in server_config['graphql']: +                app.state.vyos_introspection = True +            else: +                app.state.vyos_introspection = False +            # default value is merged in conf_mode http-api.py, if not set +            app.state.vyos_auth_type = server_config['graphql']['authentication']['type']      else:          app.state.vyos_graphql = False | 
