--- - 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 }}"