An Ansible module that enables Continuous Delivery with Red Hat 3scale API Management Platform (3scale AMP)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

197 lines
11 KiB

---
- name: Parse the OpenAPI file (YAML format)
set_fact:
threescale_cicd_openapi_file_content: '{{ lookup(''file'', threescale_cicd_openapi_file) |from_yaml }}'
when: "threescale_cicd_openapi_file_format|upper == 'YAML'"
- name: Parse the OpenAPI file (JSON format)
set_fact:
threescale_cicd_openapi_file_content: '{{ lookup(''file'', threescale_cicd_openapi_file) |from_json }}'
when: "threescale_cicd_openapi_file_format|upper == 'JSON'"
- name: Extract the OpenAPI format version
set_fact:
threescale_cicd_openapi_file_version: '{{ threescale_cicd_openapi_file_content|json_query(''swagger'') }}'
- name: Check the OpenAPI format version
assert:
that:
- "threescale_cicd_openapi_file_version == '2.0'"
msg: "Currently only the OpenAPI/Swagger 2.0 is handled. If needed, fill an issue or submit a pull request!"
# TODO rewrite this in a more "Ansible compatible" way
- name: Extract API Methods
set_fact:
threescale_cicd_api_name: '{{ threescale_cicd_openapi_file_content.info.title|default("API") }}'
threescale_cicd_api_description: '{{ threescale_cicd_openapi_file_content.info.description|default("") }}'
threescale_cicd_api_version: '{{ threescale_cicd_openapi_file_content.info.version|default("0.0.1") }}'
threescale_cicd_api_basepath: '{{ threescale_cicd_openapi_file_content.basePath|default("") }}'
threescale_cicd_api_operations: >-
{% set operations = {} -%}
{% if 'paths' in threescale_cicd_openapi_file_content -%}
{% for path, verbs in threescale_cicd_openapi_file_content['paths'].items() -%}
{% if path.startswith('/') -%}
{% for verb, method_description in verbs.items() -%}
{% if verb != '$ref' and verb != 'parameters' -%}
{% if 'operationId' in method_description -%}
{% set operation_id = method_description['operationId'] -%}
{% else -%}
{% set operation_id = verb.upper() + path -%}
{% endif -%}
{% set operation_id = operation_id|regex_replace('[^0-9a-zA-Z_]+', '_') -%}
{% set operation = { operation_id: { 'path': path, 'verb': verb } } -%}
{% if 'summary' in method_description -%}
{% if operation[operation_id].update({ 'friendly_name': method_description.summary }) -%}{% endif -%}
{% endif -%}
{% if 'description' in method_description -%}
{% if operation[operation_id].update({ 'description': method_description.description }) -%}{% endif -%}
{% endif -%}
{% if operations.update(operation) -%}{% endif -%}
{% endif -%}
{% endfor -%}
{% endif -%}
{% endfor -%}
{% endif -%}
{{ operations }}
- name: Extract components from the version number
set_fact:
threescale_cicd_api_version_components: '{{ threescale_cicd_api_version.split(".") }}'
- name: Find the major version
set_fact:
threescale_cicd_api_version_major: '{{ threescale_cicd_api_version_components|first }}'
- name: Compute the system_name suffix to append to the generated system_name
set_fact:
threescale_cicd_api_system_name_suffix: '{{ (threescale_cicd_api_system_name is not defined)|ternary("_" ~ (threescale_cicd_api_version_major|regex_replace(''[^a-zA-Z0-9_]+'', ''_'')), "") }}'
- name: Compute the system_name prefix to prepend to the generated system_name
set_fact:
threescale_cicd_api_system_name_prefix: '{{ (threescale_cicd_api_system_name is not defined and threescale_cicd_api_environment_name is defined)|ternary((threescale_cicd_api_environment_name|default("")|regex_replace(''[^a-zA-Z0-9_]+'', ''_'')) ~ "_", "") }}'
- name: Extract the wanted system_name from OpenAPI
set_fact:
threescale_cicd_api_system_name: '{{ threescale_cicd_openapi_file_content.info[''x-threescale-system-name'']|regex_replace(''[^a-zA-Z0-9_]+'', ''_'')|lower }}'
when: 'threescale_cicd_api_system_name is not defined and ''x-threescale-system-name'' in threescale_cicd_openapi_file_content.info'
- name: Generate a system_name from the API title
set_fact:
threescale_cicd_api_system_name: '{{ threescale_cicd_openapi_file_content.info[''title'']|default(''api'')|regex_replace(''[^a-zA-Z0-9_]+'', ''_'')|lower }}'
when: 'threescale_cicd_api_system_name is not defined'
- name: Append the major version to the system_name
set_fact:
threescale_cicd_api_system_name: '{{ threescale_cicd_api_system_name }}{{ threescale_cicd_api_system_name_suffix }}'
- name: Set the threescale_cicd_apicast_{sandbox,production}_endpoint variable from the wildcard domain
set_fact:
threescale_cicd_apicast_sandbox_endpoint: '{{ threescale_cicd_default_apicast_scheme }}://{{ threescale_cicd_api_system_name|regex_replace(''[^a-zA-Z0-9-]+'', ''-'')|lower }}{{ threescale_cicd_default_staging_suffix }}.{{ threescale_cicd_wildcard_domain }}'
threescale_cicd_apicast_production_endpoint: '{{ threescale_cicd_default_apicast_scheme }}://{{ threescale_cicd_api_system_name|regex_replace(''[^a-zA-Z0-9-]+'', ''-'')|lower }}{{ threescale_cicd_default_production_suffix }}.{{ threescale_cicd_wildcard_domain }}'
when: 'threescale_cicd_wildcard_domain is defined'
- name: Prefix the system_name with the environment
set_fact:
threescale_cicd_api_system_name: '{{ threescale_cicd_api_system_name_prefix }}{{ threescale_cicd_api_system_name }}'
- name: Append the full version to the API title
set_fact:
threescale_cicd_api_name: '{{ threescale_cicd_api_name }} (v{{ threescale_cicd_api_version }})'
when: 'threescale_cicd_api_environment_name is not defined'
- name: Append the full version and the environment to the API title
set_fact:
threescale_cicd_api_name: '{{ threescale_cicd_api_name }} ({{ threescale_cicd_api_environment_name|upper }}, v{{ threescale_cicd_api_version }})'
when: 'threescale_cicd_api_environment_name is defined'
- name: Extract the security definitions and requirements from OpenAPI
set_fact:
threescale_cicd_api_security_requirements: '{{ threescale_cicd_openapi_file_content.security|default([]) }}'
threescale_cicd_api_security_definitions: '{{ threescale_cicd_openapi_file_content.securityDefinitions|default({}) }}'
- name: Make sure there is one and exactly one security requirement
assert:
that:
- 'threescale_cicd_api_security_requirements|length == 1'
msg: 'You have {{ threescale_cicd_api_security_requirements|length }} global security requirements. There must be one and only one security requirement.'
- name: Find the security requirement to use
set_fact:
threescale_cicd_api_security_scheme_name: '{{ threescale_cicd_api_security_requirements[0].keys()[0] }}'
- name: Make sure the requested security definition exists
assert:
that:
- 'threescale_cicd_api_security_scheme_name in threescale_cicd_api_security_definitions'
- name: Find the security definition to use
set_fact:
threescale_cicd_api_security_scheme: '{{ threescale_cicd_api_security_definitions[threescale_cicd_api_security_scheme_name] }}'
- name: Make sure the security scheme is consistent with 3scale
assert:
that:
- 'threescale_cicd_api_security_scheme.type == ''apiKey'' or (threescale_cicd_api_security_scheme.type == ''oauth2'' and threescale_cicd_sso_issuer_endpoint is defined)'
- name: Find the correct backend_version to use
set_fact:
threescale_cicd_api_backend_version: '1'
when: 'threescale_cicd_api_security_scheme.type == ''apiKey'''
- name: Find the correct backend_version to use
set_fact:
threescale_cicd_api_backend_version: 'oidc'
when: 'threescale_cicd_api_security_scheme.type == ''oauth2'''
- name: Extract the backend hostname from OpenAPI
set_fact:
threescale_cicd_api_backend_hostname: '{{ threescale_cicd_openapi_file_content.host }}'
when: 'threescale_cicd_api_backend_hostname is not defined and ''host'' in threescale_cicd_openapi_file_content'
- name: Extract the backend scheme from OpenAPI
set_fact:
threescale_cicd_api_backend_scheme: '{{ threescale_cicd_openapi_file_content.schemes|default(["http"])|first }}'
when: 'threescale_cicd_api_backend_scheme is not defined'
- name: Compute the private base url from the OpenAPI file
set_fact:
threescale_cicd_private_base_url: '{{ threescale_cicd_api_backend_scheme ~ ''://'' ~ threescale_cicd_api_backend_hostname }}'
when: threescale_cicd_api_backend_hostname is defined and threescale_cicd_private_base_url is not defined
- assert:
that:
- 'threescale_cicd_private_base_url is defined'
msg: 'Either the private base url or the tuple backend hostname/scheme must be declared as extra variables (either threescale_cicd_private_base_url or threescale_cicd_api_backend_scheme / threescale_cicd_api_backend_hostname)'
- name: Find the smoke-test flagged operation
set_fact:
threescale_cicd_openapi_smoketest_operation: '{{ threescale_cicd_openapi_file_content|json_query(''paths.*.get[? "x-threescale-smoketests-operation" ].operationId|[0]'') }}'
when: 'threescale_cicd_openapi_smoketest_operation is not defined'
- assert:
that:
# Operation must exists
- 'threescale_cicd_openapi_smoketest_operation in threescale_cicd_api_operations'
# Must be a GET
- 'threescale_cicd_api_operations[threescale_cicd_openapi_smoketest_operation].verb == ''get'''
# Must NOT have a placeholder in the path
- 'threescale_cicd_api_operations[threescale_cicd_openapi_smoketest_operation].path.find("{") == -1'
msg: "The smoketest operation {{ threescale_cicd_openapi_smoketest_operation }} must be a GET and cannot have a placeholder in its path."
when: 'threescale_cicd_openapi_smoketest_operation is defined and threescale_cicd_openapi_smoketest_operation|length > 0'
- set_fact:
threescale_cicd_openapi_smoketest_operation: '{{ threescale_cicd_openapi_smoketest_operation|regex_replace(''[^0-9a-zA-Z_]+'', ''_'') }}'
when: 'threescale_cicd_openapi_smoketest_operation is defined and threescale_cicd_openapi_smoketest_operation|length > 0'
- set_fact:
threescale_cicd_openapi_smoketest_path: '{{ threescale_cicd_api_basepath }}{{ threescale_cicd_api_operations[threescale_cicd_openapi_smoketest_operation].path }}'
when: 'threescale_cicd_openapi_smoketest_operation is defined and threescale_cicd_openapi_smoketest_operation|length > 0'
- name: Compute the service system_name
set_fact:
threescale_cicd_api_system_name: '{{ threescale_cicd_api_environment_name ~ "_" ~ threescale_cicd_api_system_name }}'
when: 'threescale_cicd_api_environment_name is defined'
- debug:
msg: "Will work on service with system_name = {{ threescale_cicd_api_system_name }}"