From 3eb31413129a158e422abeaf1aaf510c8532ade6 Mon Sep 17 00:00:00 2001 From: Denys Kalinin Date: Tue, 28 Apr 2020 14:39:52 +0300 Subject: [PATCH 01/12] Ignore absence of filter parameter --- docs/enricher.py | 13 +++++++------ docs/templates/includes/query_params.j2 | 2 ++ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/docs/enricher.py b/docs/enricher.py index 68bee78a..75ad05ca 100644 --- a/docs/enricher.py +++ b/docs/enricher.py @@ -28,17 +28,18 @@ def _add_operation_to_operations_spec(self, op_name, op_spec): def _generate_upsert_spec(self, operations, model_name, edit_operation, list_operation): op_spec = deepcopy(operations[edit_operation]) base_filter_spec = deepcopy( - operations[list_operation][OperationField.PARAMETERS][OperationParams.QUERY][QueryParams.FILTER]) + operations[list_operation][OperationField.PARAMETERS][OperationParams.QUERY].get(QueryParams.FILTER, None)) def property_for_filtering_is_present(model_spec, prop_name): """Check that required property is present in the model spec.""" return model_spec[PropName.PROPERTIES].get(prop_name) - if property_for_filtering_is_present(model_spec=self._api_spec[SpecProp.MODELS][model_name], - prop_name=PropName.NAME): - base_filter_spec[PropName.DESCRIPTION] += self.UPSERT_DEFAULT_FILTER_COMMENT - else: - base_filter_spec[PropName.REQUIRED] = True + if base_filter_spec: + if property_for_filtering_is_present(model_spec=self._api_spec[SpecProp.MODELS][model_name], + prop_name=PropName.NAME): + base_filter_spec[PropName.DESCRIPTION] += self.UPSERT_DEFAULT_FILTER_COMMENT + else: + base_filter_spec[PropName.REQUIRED] = True op_spec[OperationField.PARAMETERS][OperationParams.QUERY][QueryParams.FILTER] = base_filter_spec op_spec[OperationField.PARAMETERS][OperationParams.PATH].pop(PathParams.OBJ_ID, None) diff --git a/docs/templates/includes/query_params.j2 b/docs/templates/includes/query_params.j2 index 7b4a0ff7..afee0029 100644 --- a/docs/templates/includes/query_params.j2 +++ b/docs/templates/includes/query_params.j2 @@ -4,6 +4,8 @@ | Parameter | Required | Type | Description | | --------- | -------- | ---- | ----------- | {% for param_name, param_spec in query_params.items() %} +{% if param_spec %} | {{ param_name }} | {{ param_spec.required }} | {{ param_spec.type }} {{ param_spec.description | escape_md_symbols }} | +{% endif %} {% endfor %} {% endif %} \ No newline at end of file From 6cad4fa06fe8a6f687c272ffa7b3f044e327a673 Mon Sep 17 00:00:00 2001 From: Anton Nikulin Date: Tue, 28 Apr 2020 15:32:23 +0300 Subject: [PATCH 02/12] Release notes for 0.3.1 --- CHANGELOG.md | 4 ++++ Dockerfile | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e5e280b..168cc2e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # Changelog All notable changes to this project will be documented in this file. +## [v0.3.1] - 2020-04-28 +### Fixed +- Minor bugs to support FTD 6.6 + ## [v0.3.0] - 2019-10-23 ### Added - Update duplicate object lookup process according to API updated in newer versions of FDM diff --git a/Dockerfile b/Dockerfile index 19e3b0ee..535c7577 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ ARG PYTHON_VERSION=3.6 FROM python:${PYTHON_VERSION} -ARG FTD_ANSIBLE_VERSION=v0.3.0 +ARG FTD_ANSIBLE_VERSION=v0.3.1 ARG FTD_ANSIBLE_FOLDER=ftd-ansible RUN apt-get update && \ From 507c0c41ba58c249c9c977e507373bda3a2daca9 Mon Sep 17 00:00:00 2001 From: Denys Kalinin Date: Tue, 28 Apr 2020 15:32:34 +0300 Subject: [PATCH 03/12] Ignore filter spec at all if not present --- docs/enricher.py | 2 +- docs/templates/includes/query_params.j2 | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/enricher.py b/docs/enricher.py index 75ad05ca..5f32aa09 100644 --- a/docs/enricher.py +++ b/docs/enricher.py @@ -41,7 +41,7 @@ def property_for_filtering_is_present(model_spec, prop_name): else: base_filter_spec[PropName.REQUIRED] = True - op_spec[OperationField.PARAMETERS][OperationParams.QUERY][QueryParams.FILTER] = base_filter_spec + op_spec[OperationField.PARAMETERS][OperationParams.QUERY][QueryParams.FILTER] = base_filter_spec op_spec[OperationField.PARAMETERS][OperationParams.PATH].pop(PathParams.OBJ_ID, None) return op_spec diff --git a/docs/templates/includes/query_params.j2 b/docs/templates/includes/query_params.j2 index afee0029..7b4a0ff7 100644 --- a/docs/templates/includes/query_params.j2 +++ b/docs/templates/includes/query_params.j2 @@ -4,8 +4,6 @@ | Parameter | Required | Type | Description | | --------- | -------- | ---- | ----------- | {% for param_name, param_spec in query_params.items() %} -{% if param_spec %} | {{ param_name }} | {{ param_spec.required }} | {{ param_spec.type }} {{ param_spec.description | escape_md_symbols }} | -{% endif %} {% endfor %} {% endif %} \ No newline at end of file From ce9b082138289d91f1580d80ee7b12eb9e1bebea Mon Sep 17 00:00:00 2001 From: Denys Kalinin Date: Mon, 25 May 2020 16:33:19 +0300 Subject: [PATCH 04/12] Add config json file template for ftd-api docs --- docs/templates/static/ftd_api/config.json.j2 | 37 ++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 docs/templates/static/ftd_api/config.json.j2 diff --git a/docs/templates/static/ftd_api/config.json.j2 b/docs/templates/static/ftd_api/config.json.j2 new file mode 100644 index 00000000..5cfe2458 --- /dev/null +++ b/docs/templates/static/ftd_api/config.json.j2 @@ -0,0 +1,37 @@ +{ + "items": [ + { + "title": "Overview", + "items": [ + { + "title": "Introduction to Firepower Threat Defense REST API", + "content": "introduction/intro.md" + }, + { + "title": "Authenticating Your REST API Client Using OAuth", + "content": "introduction/auth.md" + }, + { + "title": "Deploying Configuration Changes", + "content": "introduction/deploy_config.md" + } + ] + }, + {% if error_codes %} + { + "title": "Error Codes", + "content": "error_codes.md" + }, + {% endif %} + { + "title": "Resources", + "type": "config", + "content": "resources/config.json" + }, + { + "title": "Models", + "type": "config", + "content": "models/config.json" + } + ] +} \ No newline at end of file From 0fb391682dc930448d8f8267e50667d6fc6fdafd Mon Sep 17 00:00:00 2001 From: Denys Kalinin Date: Mon, 25 May 2020 16:33:43 +0300 Subject: [PATCH 05/12] Move static files for ftd-ansible docs to relevant folder --- docs/templates/static/{ => ftd_ansible}/config.json | 0 docs/templates/static/{ => ftd_ansible}/examples.md.j2 | 0 docs/templates/static/{ => ftd_ansible}/installation_guide.md | 0 docs/templates/static/{ => ftd_ansible}/intro.md.j2 | 0 docs/templates/static/{ => ftd_ansible}/user_guide.md.j2 | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename docs/templates/static/{ => ftd_ansible}/config.json (100%) rename docs/templates/static/{ => ftd_ansible}/examples.md.j2 (100%) rename docs/templates/static/{ => ftd_ansible}/installation_guide.md (100%) rename docs/templates/static/{ => ftd_ansible}/intro.md.j2 (100%) rename docs/templates/static/{ => ftd_ansible}/user_guide.md.j2 (100%) diff --git a/docs/templates/static/config.json b/docs/templates/static/ftd_ansible/config.json similarity index 100% rename from docs/templates/static/config.json rename to docs/templates/static/ftd_ansible/config.json diff --git a/docs/templates/static/examples.md.j2 b/docs/templates/static/ftd_ansible/examples.md.j2 similarity index 100% rename from docs/templates/static/examples.md.j2 rename to docs/templates/static/ftd_ansible/examples.md.j2 diff --git a/docs/templates/static/installation_guide.md b/docs/templates/static/ftd_ansible/installation_guide.md similarity index 100% rename from docs/templates/static/installation_guide.md rename to docs/templates/static/ftd_ansible/installation_guide.md diff --git a/docs/templates/static/intro.md.j2 b/docs/templates/static/ftd_ansible/intro.md.j2 similarity index 100% rename from docs/templates/static/intro.md.j2 rename to docs/templates/static/ftd_ansible/intro.md.j2 diff --git a/docs/templates/static/user_guide.md.j2 b/docs/templates/static/ftd_ansible/user_guide.md.j2 similarity index 100% rename from docs/templates/static/user_guide.md.j2 rename to docs/templates/static/ftd_ansible/user_guide.md.j2 From 16d70b5db75b8b079ed0926e68c0cfbe84f82d5c Mon Sep 17 00:00:00 2001 From: Denys Kalinin Date: Mon, 25 May 2020 16:34:19 +0300 Subject: [PATCH 06/12] Make StaticDocGenerator generate root config.json file for ftd-api --- docs/build.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/build.py b/docs/build.py index ae525edf..544311e0 100644 --- a/docs/build.py +++ b/docs/build.py @@ -18,7 +18,8 @@ BASE_DIR_PATH = os.path.dirname(os.path.realpath(__file__)) DEFAULT_TEMPLATE_DIR = os.path.join(BASE_DIR_PATH, 'templates') -STATIC_TEMPLATE_DIR = os.path.join(DEFAULT_TEMPLATE_DIR, 'static') +FTD_ANSIBLE_STATIC_TEMPLATE_DIR = os.path.join(DEFAULT_TEMPLATE_DIR, 'static', 'ftd_ansible') +FTD_API_STATIC_TEMPLATE_DIR = os.path.join(DEFAULT_TEMPLATE_DIR, 'static', 'ftd_api') DEFAULT_SAMPLES_DIR = os.path.join(os.path.dirname(BASE_DIR_PATH), 'samples') DEFAULT_DIST_DIR = os.path.join(BASE_DIR_PATH, 'dist') DEFAULT_MODULE_DIR = os.path.join(os.path.dirname(BASE_DIR_PATH), 'library') @@ -202,7 +203,7 @@ def _generate_ansible_docs(args, api_spec, template_ctx): .generate_doc_files(args.dist, args.models) generator.ModuleDocGenerator(DEFAULT_TEMPLATE_DIR, template_ctx, DEFAULT_MODULE_DIR) \ .generate_doc_files(args.dist) - generator.StaticDocGenerator(DEFAULT_TEMPLATE_DIR, template_ctx, STATIC_TEMPLATE_DIR) \ + generator.StaticDocGenerator(DEFAULT_TEMPLATE_DIR, template_ctx, FTD_ANSIBLE_STATIC_TEMPLATE_DIR) \ .generate_doc_files(args.dist) @@ -216,6 +217,8 @@ def _generate_ftd_api_docs(args, api_spec, template_ctx, errors_codes): if errors_codes: generator.ErrorDocGenerator(DEFAULT_TEMPLATE_DIR, template_ctx) \ .generate_doc_files(args.dist, errors_codes) + generator.StaticDocGenerator(DEFAULT_TEMPLATE_DIR, template_ctx, FTD_API_STATIC_TEMPLATE_DIR) \ + .generate_doc_files(args.dist) def _generate_docs(args, api_client): @@ -230,6 +233,7 @@ def _generate_docs(args, api_client): _generate_ansible_docs(args, api_spec, template_ctx) elif args.doctype == DocType.ftd_api: error_codes = api_client.fetch_error_codes() + template_ctx['error_codes'] = bool(False) _generate_ftd_api_docs(args, api_spec, template_ctx, error_codes) From ebee3b57c718f6ea6397a9fac565ce982cf763f1 Mon Sep 17 00:00:00 2001 From: Denys Kalinin Date: Mon, 25 May 2020 18:59:23 +0300 Subject: [PATCH 07/12] Fix error codes variable value in context --- docs/build.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/build.py b/docs/build.py index 544311e0..0162a752 100644 --- a/docs/build.py +++ b/docs/build.py @@ -233,7 +233,7 @@ def _generate_docs(args, api_client): _generate_ansible_docs(args, api_spec, template_ctx) elif args.doctype == DocType.ftd_api: error_codes = api_client.fetch_error_codes() - template_ctx['error_codes'] = bool(False) + template_ctx['error_codes'] = bool(error_codes) _generate_ftd_api_docs(args, api_spec, template_ctx, error_codes) From d90f152eda8829acff310d3fde95d01d7e02b2f3 Mon Sep 17 00:00:00 2001 From: Denys Kalinin Date: Fri, 4 Jun 2021 13:23:54 +0300 Subject: [PATCH 08/12] Provide workaround for 7.0.0 devices docs generation --- docs/build.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/build.py b/docs/build.py index 0162a752..49b64fc4 100644 --- a/docs/build.py +++ b/docs/build.py @@ -208,6 +208,11 @@ def _generate_ansible_docs(args, api_spec, template_ctx): def _generate_ftd_api_docs(args, api_spec, template_ctx, errors_codes): + if template_ctx['ftd_version'] == '7.0.0': + # SSLGroupType has incorrect representation in 7.0.0 API spec, as it doesn't contain possible enum values. + # We need to add these enum values here to generate docs and represent possible values. + api_spec['models']['SSLGroupType']['enum'] = ["GROUP_14", "GROUP_15", "GROUP_19", "GROUP_20", "GROUP_21"] + generator.ResourceDocGenerator(DEFAULT_TEMPLATE_DIR, template_ctx, api_spec) \ .generate_doc_files(args.dist, args.models) generator.ModelDocGenerator(DEFAULT_TEMPLATE_DIR, template_ctx, api_spec) \ From 8050d06bbbb6191ef9bcfa2259cb060a721720b3 Mon Sep 17 00:00:00 2001 From: Adrian Costean Date: Wed, 25 May 2022 15:12:40 +0300 Subject: [PATCH 09/12] Replaced yaml.load() with yaml.full_load() --- docs/generator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/generator.py b/docs/generator.py index c75786e2..e6adb5ca 100644 --- a/docs/generator.py +++ b/docs/generator.py @@ -249,7 +249,7 @@ def generate_doc_files(self, dest_dir): module_name = os.path.splitext(module_filename)[0] module = importlib.import_module(module_name) - module_docs = yaml.load(module.DOCUMENTATION) + module_docs = yaml.full_load(module.DOCUMENTATION) module_spec = ModuleSpec( name=module_name, short_description=self._doc_to_text(module_docs.get('short_description')), From db566cb0643adbb72405b454ed09a3ca6ef550b1 Mon Sep 17 00:00:00 2001 From: Costean Adrian Date: Thu, 26 May 2022 23:01:51 +0300 Subject: [PATCH 10/12] Replaced all load() usages with full_load() --- docs/generator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/generator.py b/docs/generator.py index e6adb5ca..9e6c3e8c 100644 --- a/docs/generator.py +++ b/docs/generator.py @@ -270,7 +270,7 @@ def _doc_to_text(text): @staticmethod def _get_module_params(module): - docs = yaml.load(module.DOCUMENTATION) + docs = yaml.full_load(module.DOCUMENTATION) return {k: { 'description': ModuleDocGenerator._doc_to_text(v.get('description')), 'required': v.get('required', False), @@ -279,7 +279,7 @@ def _get_module_params(module): @staticmethod def _get_module_return_values(module): - return_params = yaml.load(module.RETURN) + return_params = yaml.full_load(module.RETURN) return {k: { 'description': ModuleDocGenerator._doc_to_text(v.get('description')), 'returned': v.get('returned', ''), From 859a2ac027a873a2e885237d1465bc1e07526e73 Mon Sep 17 00:00:00 2001 From: Costean Adrian Date: Mon, 30 May 2022 13:38:16 +0300 Subject: [PATCH 11/12] Fix dictionary issue with string objects --- docs/snippets_generation/body_generator.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/snippets_generation/body_generator.py b/docs/snippets_generation/body_generator.py index 1c1a2a7f..5bc0c270 100644 --- a/docs/snippets_generation/body_generator.py +++ b/docs/snippets_generation/body_generator.py @@ -54,9 +54,12 @@ def _generated_sample_by_model_spec(data_params, full_spec): } for key, value in data_params.items(): - value_type = value.get("type", "object") - result[key] = processing_map.get(value_type, _get_default_value)(value, full_spec) - + try: + value_type = value.get("type", "object") + result[key] = processing_map.get(value_type, _get_default_value)(value, full_spec) + except AttributeError: + # ignore errors for string values + pass return result From 882852c84f24d25db62d3e7d2cf283a157b22bfa Mon Sep 17 00:00:00 2001 From: Costean Adrian Date: Thu, 2 Jun 2022 03:42:48 +0300 Subject: [PATCH 12/12] Handle string values in data params for poorly defined APIs --- docs/snippets_generation/body_generator.py | 29 +++++++++++++--------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/docs/snippets_generation/body_generator.py b/docs/snippets_generation/body_generator.py index 5bc0c270..a023dd3e 100644 --- a/docs/snippets_generation/body_generator.py +++ b/docs/snippets_generation/body_generator.py @@ -1,13 +1,16 @@ def _get_default_value(value, *args): - if value.get("default"): - return value["default"] - elif value["type"] == "integer": - return 0 - elif value["type"] == "boolean": - return True - else: - return value["type"] - + try: + if value.get("default"): + return value["default"] + elif value["type"] == "integer": + return 0 + elif value["type"] == "boolean": + return True + else: + return value["type"] + except AttributeError: + if type(value) == str: + return '' def _get_model_name_from_reference(ref): return ref.replace("#/definitions/", "") @@ -56,10 +59,12 @@ def _generated_sample_by_model_spec(data_params, full_spec): for key, value in data_params.items(): try: value_type = value.get("type", "object") - result[key] = processing_map.get(value_type, _get_default_value)(value, full_spec) except AttributeError: - # ignore errors for string values - pass + # for values that don't support get method they will be handled in _get_default_values + # this usually indicates the model is not defined properly + value_type = value + + result[key] = processing_map.get(value_type, _get_default_value)(value, full_spec) return result