From e6b5994a952b5d4c15bd14d678559c35928dccd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Mass=C3=A9?= Date: Fri, 24 Aug 2018 11:44:04 +0200 Subject: [PATCH] fix #5: implement OpenAPI Specifications validation --- .gitignore | 1 + README.md | 20 +++++++++++++++++ defaults/main.yml | 6 ++++++ tasks/main.yml | 4 ++++ tasks/steps/find_goswagger.yml | 22 +++++++++++++++++++ tasks/steps/install_goswagger.yml | 36 +++++++++++++++++++++++++++++++ tasks/steps/validate_openapi.yml | 17 +++++++++++++++ tests/api/echo-api-oidc.yaml | 2 ++ 8 files changed, 108 insertions(+) create mode 100644 tasks/steps/find_goswagger.yml create mode 100644 tasks/steps/install_goswagger.yml create mode 100644 tasks/steps/validate_openapi.yml diff --git a/.gitignore b/.gitignore index d653f84..f15c60a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *.retry inventory 3scale-inventory.* +bin diff --git a/README.md b/README.md index 86a6cfd..4ed7d14 100644 --- a/README.md +++ b/README.md @@ -457,6 +457,26 @@ when deploying the same API multiple times on the same 3scale instance. - **Default value:** none, no prefixing is performed. - **Examples:** `dev`, `test` or `prod` +### `threescale_cicd_validate_openapi` + +Validates the OpenAPI Specification file against the official schema. To do this, +the [go-swagger](https://goswagger.io/) tool is used. + +You can pre-install this tool somewhere in your `PATH`. Alternatively, you can +also point the complete path to the `swagger` command with the +`threescale_cicd_goswagger_command` extra variable. + +If the tool is missing, it will be automatically downloaded from GitHub and +installed in `{{ threescale_cicd_local_bin_path }}`. + +- **Syntax:** boolean (`yes`, `no`, `true`, `false`) +- **Required:** no +- **Default value:** `yes` +- **Examples:** + - `threescale_cicd_validate_openapi=no` + - `threescale_cicd_goswagger_command=/usr/local/bin/swagger` + - `threescale_cicd_local_bin_path=/tmp` + ### Miscellaneous variables Miscellaneous variables defined in [defaults/main.yml](defaults/main.yml) diff --git a/defaults/main.yml b/defaults/main.yml index b1fe5ed..40d6c45 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -17,6 +17,12 @@ threescale_cicd_application_plans: state: hidden name: Ansible Test Plan +# A folder where to download dependencies, when required +threescale_cicd_local_bin_path: '{{ playbook_dir }}/bin' + +# Enable the OpenAPI Specification validation +threescale_cicd_validate_openapi: yes + # APIcast public base URLs threescale_cicd_apicast_sandbox_endpoint: '{{ lookup(''template'', ''openapi/apicast_sandbox_endpoint.j2'') }}' threescale_cicd_apicast_production_endpoint: '{{ lookup(''template'', ''openapi/apicast_production_endpoint.j2'') }}' diff --git a/tasks/main.yml b/tasks/main.yml index 785f33b..f0528ca 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -3,6 +3,10 @@ # Make sure we have everything we need to run this playbook - import_tasks: steps/requirements.yml +# Validate the API definition against the Swagger 2.0 / OAS 3.0 +- include_tasks: steps/validate_openapi.yml + when: threescale_cicd_validate_openapi|bool + # Warn the user about those deprecated features - import_tasks: steps/variables_from_inventory.yml diff --git a/tasks/steps/find_goswagger.yml b/tasks/steps/find_goswagger.yml new file mode 100644 index 0000000..2d85ed4 --- /dev/null +++ b/tasks/steps/find_goswagger.yml @@ -0,0 +1,22 @@ +--- + +- name: Check if go-swagger is installed globally + command: swagger version + register: check_global_goswagger_version + changed_when: false + ignore_errors: yes + +- set_fact: + threescale_cicd_goswagger_command: 'swagger' + when: check_global_goswagger_version is success + +- name: Check if go-swagger is installed locally + command: '{{ threescale_cicd_local_bin_path }}/swagger version' + register: check_local_goswagger_version + changed_when: false + ignore_errors: yes + when: check_global_goswagger_version is failed + +- set_fact: + threescale_cicd_goswagger_command: '{{ threescale_cicd_local_bin_path }}/swagger' + when: check_local_goswagger_version is success and check_local_goswagger_version is not skipped diff --git a/tasks/steps/install_goswagger.yml b/tasks/steps/install_goswagger.yml new file mode 100644 index 0000000..450c255 --- /dev/null +++ b/tasks/steps/install_goswagger.yml @@ -0,0 +1,36 @@ +--- + +- name: Find the OS and architecture of the control node + setup: + gather_subset: '!all' + +- name: Find the latest version of go-swagger + uri: + url: https://api.github.com/repos/go-swagger/go-swagger/releases/latest + register: latest_goswagger_version + +- debug: + msg: 'Found go-swagger remotely, version {{ latest_goswagger_version.json.tag_name }}' + +- name: Create the folder to download go-swagger + file: + path: '{{ threescale_cicd_local_bin_path }}' + state: directory + +- name: Download go-swagger + get_url: + url: '{{ goswagger_download_url }}' + dest: '{{ threescale_cicd_local_bin_path }}/swagger' + mode: 0755 + vars: + goswagger_download_url: '{{ goswagger_asset.browser_download_url }}' + goswagger_asset: '{{ goswagger_assets|selectattr(''name'', ''equalto'', artifact_name)|first }}' + goswagger_assets: '{{ latest_goswagger_version.json.assets }}' + artifact_name: 'swagger_{{ ansible_system|lower }}_{{ swagger_architecture }}' + swagger_architecture: '{{ swagger_architecture_mapping[ansible_architecture] }}' + swagger_architecture_mapping: + x86_64: amd64 + armv7l: arm + +- set_fact: + threescale_cicd_goswagger_command: '{{ threescale_cicd_local_bin_path }}/swagger' diff --git a/tasks/steps/validate_openapi.yml b/tasks/steps/validate_openapi.yml new file mode 100644 index 0000000..1c12d6a --- /dev/null +++ b/tasks/steps/validate_openapi.yml @@ -0,0 +1,17 @@ +--- + +- debug: + msg: > + Will use go-swagger at '{{ threescale_cicd_goswagger_command }}' as instructed. + Auto-detection and download is DISABLED. + when: threescale_cicd_goswagger_command is defined + +- include_tasks: "steps/find_goswagger.yml" + when: threescale_cicd_goswagger_command is not defined + +- include_tasks: "steps/install_goswagger.yml" + when: threescale_cicd_goswagger_command is not defined + +- name: Validate the provided OpenAPI Specification file + command: '{{ threescale_cicd_goswagger_command }} validate {{ threescale_cicd_openapi_file }}' + changed_when: false diff --git a/tests/api/echo-api-oidc.yaml b/tests/api/echo-api-oidc.yaml index a215662..4cd12dc 100644 --- a/tests/api/echo-api-oidc.yaml +++ b/tests/api/echo-api-oidc.yaml @@ -35,3 +35,5 @@ securityDefinitions: flow: accessCode scopes: openid: Get an OpenID Connect token + authorizationUrl: http://dummy/placeholder + tokenUrl: http://dummy/placeholder