Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CES-68] Added configuration for APIM migration to itn #312

Merged
merged 3 commits into from
Nov 18, 2024

Conversation

mamu0
Copy link
Contributor

@mamu0 mamu0 commented Nov 4, 2024

List of Changes

Added new APIM configuration file with API and product pointing to itn APIM.

Motivation and Context

In view of the migration of the APIM in italynorth, this PR was created which contains the creation of all the resources that will point to the new APIM, it will be applied before making the backup and restore on the new APIM in ITN, so as to generate all the necessary APIs and products.
Subsequently, all the commented code will be uncommented in a specific PR and the imports of all those resources will be made.
Once the migration is finished, the files and resources relating to the weu APIM v2 will be deleted.

How Has This Been Tested?

Screenshots (if appropriate):

Checklist:

  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.

Copy link

changeset-bot bot commented Nov 4, 2024

⚠️ No Changeset found

Latest commit: e23f75c

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link
Contributor

📖 Terraform Plan ('infra/resources/prod') - success

Terraform Plan
data:
                            schema:
                              type: object
                              properties:
                                document:
                                  type: string
                                  format: binary
                                signature_fields:
                                  type: array
                                  items:
                                    $ref: "#/components/schemas/SignatureField"
                              required:
                                - document
                            encoding:
                              document:
                                contentType: application/pdf
                      responses:
                        "200":
                          description: the validation result
                          content:
                            application/json:
                              schema:
                                $ref: "#/components/schemas/DocumentValidationResult"
                        "400":
                          $ref: "#/components/responses/BadRequest"
                        "401":
                          $ref: "#/components/responses/Unauthorized"
                        "403":
                          $ref: "#/components/responses/Forbidden"
                        "429":
                          $ref: "#/components/responses/TooManyRequests"
                        default:
                          $ref: "#/components/responses/Unexpected"
                
                components:
                  securitySchemes:
                    SubscriptionKey:
                      type: apiKey
                      name: Ocp-Apim-Subscription-Key
                      in: header
                      description: The API key obtained through the developer portal
                
                  responses:
                    NotFound:
                      description: The specified resource was not found
                      content:
                        application/json:
                          schema:
                            $ref: "#/components/schemas/ProblemDetail"
                
                    BadRequest:
                      description: Validation error on body
                      content:
                        application/json:
                          schema:
                            $ref: "#/components/schemas/ProblemDetail"
                
                    Forbidden:
                      description: You don't have enough privileges to perform this action
                      content:
                        application/json:
                          schema:
                            $ref: "#/components/schemas/ProblemDetail"
                
                    Unauthorized:
                      description: Unauthorized
                      content:
                        application/json:
                          schema:
                            $ref: "#/components/schemas/ProblemDetail"
                
                    UnprocessableContent:
                      description: Unprocessable Content
                      content:
                        application/json:
                          schema:
                            $ref: "#/components/schemas/ProblemDetail"
                
                    TooManyRequests:
                      description: Too Many Requests
                      content:
                        application/json:
                          schema:
                            $ref: "#/components/schemas/ProblemDetail"
                
                    Unexpected:
                      description: Unexpected error
                      content:
                        application/json:
                          schema:
                            $ref: "#/components/schemas/ProblemDetail"
                
                  schemas:
                    ProblemDetail:
                      type: object
                      properties:
                        type:
                          type: string
                          format: uri
                          description: |-
                            An absolute URI that identifies the problem type. When dereferenced,
                            it SHOULD provide human-readable documentation for the problem type
                            (e.g., using HTML).
                          default: about:blank
                          example: https://example.com/problem/constraint-violation
                        title:
                          type: string
                          description: >-
                            A short, summary of the problem type. Written in english and
                            readable
                
                            for engineers (usually not suited for non technical stakeholders and
                
                            not localized); example: Service Unavailable
                        status:
                          type: integer
                          format: int32
                          description: >-
                            The HTTP status code generated by the origin server for this
                            occurrence of the problem.
                          minimum: 100
                          maximum: 600
                          exclusiveMaximum: true
                          example: 200
                        detail:
                          type: string
                          description: |-
                            A human readable explanation specific to this occurrence of the
                            problem.
                          example: There was an error processing the request
                        instance:
                          type: string
                          format: uri
                          description: >-
                            An absolute URI that identifies the specific occurrence of the
                            problem. It may or may not yield further information if
                            dereferenced.
                
                    Clause:
                      type: object
                      properties:
                        title:
                          type: string
                          minLength: 5
                          maxLength: 80
                        type:
                          type: string
                          enum: ["REQUIRED", "UNFAIR", "OPTIONAL"]
                      required:
                        - title
                        - type
                
                    ExistingSignatureFieldAttrs:
                      type: object
                      properties:
                        unique_name:
                          type: string
                      required:
                        - unique_name
                
                    SignatureFieldToBeCreatedAttrs:
                      type: object
                      properties:
                        coordinates:
                          type: object
                          properties:
                            x: { type: number }
                            y: { type: number }
                          required: [x, y]
                        page:
                          type: number
                          minimum: 0
                        size:
                          type: object
                          properties:
                            w: { type: number, minimum: 0 }
                            h: { type: number, minimum: 0 }
                          required: [w, h]
                      required:
                        - coordinates
                        - page
                        - size
                
                    SignatureFieldAttrs:
                      oneOf:
                        - $ref: "#/components/schemas/ExistingSignatureFieldAttrs"
                        - $ref: "#/components/schemas/SignatureFieldToBeCreatedAttrs"
                
                    SignatureField:
                      type: object
                      properties:
                        attrs:
                          $ref: "#/components/schemas/SignatureFieldAttrs"
                        clause:
                          $ref: "#/components/schemas/Clause"
                      required:
                        - attrs
                        - clause
                
                    DocumentMetadata:
                      type: object
                      properties:
                        title:
                          type: string
                          minLength: 3
                          maxLength: 60
                        signature_fields:
                          type: array
                          items:
                            $ref: "#/components/schemas/SignatureField"
                      required:
                        - title
                
                    DocumentMetadataList:
                      type: array
                      items:
                        $ref: "#/components/schemas/DocumentMetadata"
                      minLength: 1
                
                    DossierSupportEmail:
                      type: string
                      description: Issuer's support email for a specific dossier.
                      format: email
                      example: demo@example.com
                
                    DossierTitle:
                      type: string
                      minLength: 3
                
                    CreateDossierBody:
                      type: object
                      properties:
                        title:
                          $ref: "#/components/schemas/DossierTitle"
                        support_email:
                          $ref: "#/components/schemas/DossierSupportEmail"
                        documents_metadata:
                          $ref: "#/components/schemas/DocumentMetadataList"
                      required:
                        - title
                        - documents_metadata
                
                    SetSignatureRequestStatusBody:
                      type: string
                      x-extensible-enum:
                        - READY
                        - CANCELLED
                
                    DossierDetailView:
                      type: object
                      properties:
                        id:
                          $ref: "#/components/schemas/Id"
                        title:
                          $ref: "#/components/schemas/DossierTitle"
                        support_email:
                          $ref: "#/components/schemas/DossierSupportEmail"
                        documents_metadata:
                          $ref: "#/components/schemas/DocumentMetadataList"
                        created_at:
                          $ref: "#/components/schemas/Timestamp"
                        updated_at:
                          $ref: "#/components/schemas/Timestamp"
                      required:
                        - id
                        - title
                        - documents_metadata
                        - created_at
                        - updated_at
                
                    Timestamp:
                      type: string
                      format: UTCISODateFromString
                      description: A date-time field in ISO-8601 format and UTC timezone.
                      x-import: "@pagopa/ts-commons/lib/dates"
                      example: "2018-10-13T00:00:00.000Z"
                
                    Id:
                      type: string
                      description: Entity Id
                      format: NonEmptyString
                      example: 01ARZ3NDEKTSV4RRFFQ69G5FAV
                      x-import: "@pagopa/ts-commons/lib/strings"
                
                    FiscalCode:
                      type: string
                      description: User's fiscal code.
                      format: FiscalCode
                      x-import: "@pagopa/ts-commons/lib/strings"
                      example: SPNDNL80R13C555X
                
                    GetSignerByFiscalCodeBody:
                      type: object
                      properties:
                        fiscal_code:
                          $ref: "#/components/schemas/FiscalCode"
                      required:
                        - fiscal_code
                
                    SignerDetailView:
                      type: object
                      properties:
                        id:
                          $ref: "#/components/schemas/Id"
                      required:
                        - id
                
                    CreateSignatureRequestBody:
                      type: object
                      properties:
                        dossier_id:
                          $ref: "#/components/schemas/Id"
                        signer_id:
                          $ref: "#/components/schemas/Id"
                        expires_at:
                          $ref: "#/components/schemas/Timestamp"
                      required:
                        - dossier_id
                        - signer_id
                
                    Document:
                      type: object
                      properties:
                        id:
                          $ref: "#/components/schemas/Id"
                        metadata:
                          $ref: "#/components/schemas/DocumentMetadata"
                        created_at:
                          $ref: "#/components/schemas/Timestamp"
                        updated_at:
                          $ref: "#/components/schemas/Timestamp"
                      required:
                        - id
                        - metadata
                        - created_at
                        - updated_at
                
                    DocumentToBeUploaded:
                      allOf:
                        - $ref: "#/components/schemas/Document"
                        - type: object
                          properties:
                            status:
                              type: string
                              enum:
                                - WAIT_FOR_UPLOAD
                          required:
                            - status
                
                    DocumentToBeValidated:
                      allOf:
                        - $ref: "#/components/schemas/Document"
                        - type: object
                          properties:
                            status:
                              type: string
                              enum:
                                - WAIT_FOR_VALIDATION
                            uploaded_at:
                              $ref: "#/components/schemas/Timestamp"
                          required:
                            - status
                            - uploaded_at
                
                      allOf:
                        - $ref: "#/components/schemas/Document"
                        - type: object
                          properties:
                            status:
                              type: string
                              enum:
                                - READY
                            uploaded_at:
                              $ref: "#/components/schemas/Timestamp"
                            url:
                              type: string
                              format: uri
                          required:
                            - status
                            - uploaded_at
                            - url
                
                    DocumentRejected:
                      allOf:
                        - $ref: "#/components/schemas/Document"
                        - type: object
                          properties:
                            status:
                              type: string
                              enum:
                                - REJECTED
                            uploaded_at:
                              $ref: "#/components/schemas/Timestamp"
                            rejected_at:
                              $ref: "#/components/schemas/Timestamp"
                            reject_reason:
                              type: string
                          required:
                            - status
                            - uploaded_at
                            - rejected_at
                            - reject_reason
                
                    DocumentDetailView:
                      oneOf:
                        - $ref: "#/components/schemas/DocumentToBeUploaded"
                        - $ref: "#/components/schemas/DocumentToBeValidated"
                        - $ref: "#/components/schemas/DocumentRejected"
                
                    SignatureRequestStatus:
                      type: string
                      x-extensible-enum:
                        - DRAFT
                        - READY
                        - WAIT_FOR_SIGNATURE
                        - SIGNED
                        - REJECTED
                        - CANCELLED
                
                    SignatureRequestDetailView:
                      type: object
                      properties:
                        id:
                          $ref: "#/components/schemas/Id"
                        status:
                          $ref: "#/components/schemas/SignatureRequestStatus"
                        dossier_id:
                          $ref: "#/components/schemas/Id"
                        signer_id:
                          $ref: "#/components/schemas/Id"
                        expires_at:
                          $ref: "#/components/schemas/Timestamp"
                        documents:
                          type: array
                          items:
                            $ref: "#/components/schemas/DocumentDetailView"
                        notification:
                          $ref: "#/components/schemas/NotificationDetailView"
                        created_at:
                          $ref: "#/components/schemas/Timestamp"
                        updated_at:
                          $ref: "#/components/schemas/Timestamp"
                        signed_at:
                          $ref: "#/components/schemas/Timestamp"
                        rejected_at:
                          $ref: "#/components/schemas/Timestamp"
                        reject_reason:
                          type: string
                        qr_code_url:
                          type: string
                          format: uri
                      required:
                        - id
                        - status
                        - dossier_id
                        - signer_id
                        - expires_at
                        - documents
                        - created_at
                        - updated_at
                
                    SignatureRequestListView:
                      type: object
                      properties:
                        id:
                          $ref: "#/components/schemas/Id"
                        signer_id:
                          $ref: "#/components/schemas/Id"
                        dossier_id:
                          $ref: "#/components/schemas/Id"
                        status:
                          $ref: "#/components/schemas/SignatureRequestStatus"
                        created_at:
                          $ref: "#/components/schemas/Timestamp"
                        updated_at:
                          $ref: "#/components/schemas/Timestamp"
                        expires_at:
                          $ref: "#/components/schemas/Timestamp"
                      required:
                        - id
                        - signer_id
                        - dossier_id
                        - status
                        - created_at
                        - updated_at
                        - expires_at
                
                    SignatureRequestList:
                      type: object
                      properties:
                        items:
                          type: array
                          items:
                            $ref: "#/components/schemas/SignatureRequestListView"
                        continuation_token:
                          type: string
                      required:
                        - items
                
                    UploadUrl:
                      type: string
                      format: uri
                
                    NotificationDetailView:
                      type: object
                      properties:
                        io_message_id:
                          type: string
                      required:
                        - io_message_id
                
                    DocumentValidationResult:
                      type: object
                      properties:
                        is_valid:
                          type: boolean
                        violations:
                          type: array
                          items:
                            type: string
                      required:
                        - is_valid
            EOT
        }
    }

  # module.apim_itn_io_sign_issuer_api_v1.azurerm_api_management_api_policy.this[0] will be created
  + resource "azurerm_api_management_api_policy" "this" {
      + api_management_name = "io-p-itn-apim-01"
      + api_name            = "io-p-sign-issuer-api"
      + id                  = (known after apply)
      + resource_group_name = "io-p-itn-common-rg-01"
      + xml_content         = <<-EOT
            <policies>
                <inbound>
                    <base />
                    <set-backend-service id="apim-generated-policy" base-url="{{io-fn-sign-issuer-url}}/api/v1/sign" />
                    <set-header name="x-functions-key" exists-action="override">
                        <value>{{io-fn-sign-issuer-key}}</value>
                    </set-header>
                    <set-header name="x-subscription-id" exists-action="override">
                        <value>@(context.Subscription.Id)</value>
                    </set-header>
                    <cors>
                        <allowed-origins>
                            <origin>*</origin>
                        </allowed-origins>
                        <allowed-methods>
                            <method>*</method>
                        </allowed-methods>
                        <allowed-headers>
                            <header>*</header>
                        </allowed-headers>
                        <expose-headers>
                            <header>*</header>
                        </expose-headers>
                    </cors>
                </inbound>
                <outbound>
                    <base />
                </outbound>
                <backend>
                    <base />
                </backend>
                <on-error>
                    <base />
                </on-error>
            </policies>
        EOT
    }

  # module.apim_itn_io_sign_issuer_api_v1.azurerm_api_management_product_api.this["io-sign-api"] will be created
  + resource "azurerm_api_management_product_api" "this" {
      + api_management_name = "io-p-itn-apim-01"
      + api_name            = "io-p-sign-issuer-api"
      + id                  = (known after apply)
      + product_id          = "io-sign-api"
      + resource_group_name = "io-p-itn-common-rg-01"
    }

  # module.apim_itn_io_sign_product.azurerm_api_management_product.this will be created
  + resource "azurerm_api_management_product" "this" {
      + api_management_name   = "io-p-itn-apim-01"
      + approval_required     = false
      + description           = "Product for IO sign"
      + display_name          = "IO SIGN API"
      + id                    = (known after apply)
      + product_id            = "io-sign-api"
      + published             = true
      + resource_group_name   = "io-p-itn-common-rg-01"
      + subscription_required = true
    }

  # module.apim_itn_io_sign_product.azurerm_api_management_product_policy.this[0] will be created
  + resource "azurerm_api_management_product_policy" "this" {
      + api_management_name = "io-p-itn-apim-01"
      + id                  = (known after apply)
      + product_id          = "io-sign-api"
      + resource_group_name = "io-p-itn-common-rg-01"
      + xml_content         = <<-EOT
            <policies>
                <inbound>
                    <choose>
                        <!-- When called from the outside -->
                        <when condition="@(context.Request.Headers.ContainsKey("X-Forwarded-For"))">
                            <cache-lookup-value key="@(context.Subscription.Id+"_whitelist")" variable-name="issuerWhitelist" />
                            <choose>
                                <!-- Check if the IP whitelist is in cache -->
                                <when condition="@(!context.Variables.ContainsKey("issuerWhitelist"))">
                                    <!--
                                        Executes a query on CosmosDb via REST API to obtain the list of whitelisted IPs for single issuer (subscriptionId).
                                        The connection to cosmosdb is explained here: https://learn.microsoft.com/en-us/rest/api/cosmos-db/access-control-on-cosmosdb-resources
                                    -->
                                    <set-variable name="requestDateString" value="@(DateTime.UtcNow.ToString("r"))" />
                                    <send-request mode="new" response-variable-name="response" timeout="1" ignore-error="false">
                                        <set-url>https://{{io-sign-cosmosdb-name}}.documents.azure.com/dbs/{{io-sign-backoffice-database-name}}/colls/{{io-sign-backoffice-api-keys-collection-name}}/docs</set-url>
                                        <set-method>POST</set-method>
                                        <set-header name="Authorization" exists-action="override">
                                            <value>@{
                                                var verb = "post";
                                                var resourceType = "docs";
                                                var resourceLink = "dbs/{{io-sign-backoffice-database-name}}/colls/{{io-sign-backoffice-api-keys-collection-name}}";
                                                var key = "{{io-sign-cosmosdb-key}}";
                                                var keyType = "master";
                                                var tokenVersion = "1.0";
                                                var date = context.Variables.GetValueOrDefault<string>("requestDateString");
            
                                                var hmacSha256 = new System.Security.Cryptography.HMACSHA256 { Key = Convert.FromBase64String(key) };
            
                                                string payLoad = string.Format("{0}\n{1}\n{2}\n{3}\n{4}\n",
                                                        verb.ToLowerInvariant(),
                                                        resourceType.ToLowerInvariant(),
                                                        resourceLink,
                                                        date.ToLowerInvariant(),
                                                        ""
                                                );
            
                                                byte[] hashPayLoad = hmacSha256.ComputeHash(System.Text.Encoding.UTF8.GetBytes(payLoad));
                                                string signature = Convert.ToBase64String(hashPayLoad);
            
                                                return System.Uri.EscapeDataString(String.Format("type={0}&ver={1}&sig={2}",
                                                    keyType,
                                                    tokenVersion,
                                                    signature));
                                                }</value>
                                        </set-header>
                                        <set-header name="Content-Type" exists-action="override">
                                            <value>application/query+json</value>
                                        </set-header>
                                        <set-header name="x-ms-documentdb-isquery" exists-action="override">
                                            <value>True</value>
                                        </set-header>
                                        <set-header name="x-ms-documentdb-query-enablecrosspartition" exists-action="override">
                                            <value>True</value>
                                        </set-header>
                                        <set-header name="x-ms-date" exists-action="override">
                                            <value>@(context.Variables.GetValueOrDefault<string>("requestDateString"))</value>
                                        </set-header>
                                        <set-header name="x-ms-version" exists-action="override">
                                            <value>2018-12-31</value>
                                        </set-header>
                                        <set-body>@("{\"query\": \"SELECT w.cidrs FROM whitelist w WHERE w.id = @id\", " +
                                                        "\"parameters\": [{ \"name\": \"@id\", \"value\": \"" + context.Subscription.Id + "\"}]}")</set-body>
                                    </send-request>
                                    <!-- Save response in issuerWhitelist var -->
                                    <set-variable name="issuerWhitelist" value="@(((IResponse)context.Variables["response"]).Body.As<JObject>())" />
                                    <!-- Cache the query result for 60s to reduce the number of calls to cosmosDb -->
                                    <cache-store-value key="@(context.Subscription.Id+"_whitelist")" value="@((JObject)context.Variables["issuerWhitelist"])" duration="60" />
                                </when>
                            </choose>
                            <!-- Set a temporary header -->
                            <set-header name="X-Allowed" exists-action="override">
                                <!--
                                    Get the client ip from the X-Forwarded-For header and check if it is in the issuer's whitelist.
                                    In the positive case it place "true" in the "X-Allowed" header otherwise "false"
                                -->
                                <value>@{
                                    int HostToNetworkOrder(int host) {
                                        return (((int)HostToNetworkOrderShort((short)host) & 0xFFFF) << 16)
                                            | ((int)HostToNetworkOrderShort((short)(host >> 16)) & 0xFFFF);
                                    }
                                    short HostToNetworkOrderShort(short host) {
                                        return (short)((((int)host & 0xFF) << 8) | (int)((host >> 8) & 0xFF));
                                    }
            
                                    bool IsPrivate(string ipAddress)
                                    {
                                        int[] ipParts = ipAddress.Split(new String[] { "." }, StringSplitOptions.RemoveEmptyEntries)
                                                                .Select(s => int.Parse(s)).ToArray();
                                        // in private ip range
                                        if (ipParts[0] == 127 ||
                                            ipParts[0] == 10 ||
                                            (ipParts[0] == 192 && ipParts[1] == 168) ||
                                            (ipParts[0] == 172 && (ipParts[1] >= 16 && ipParts[1] <= 31))) {
                                            return true;
                                        }
            
                                        // IP Address is probably public.
                                        // This doesn't catch some VPN ranges like OpenVPN and Hamachi.
                                        return false;
                                    }
            
                                    /*
                                     * If a request goes through multiple proxies, the IP addresses of each successive proxy is listed.
                                     * This means that, given well-behaved client and proxies, the rightmost IP address is the IP address of the most recent proxy.
                                     * For this reason we take the last IP in the list that is not a reserved IP
                                    */
                                    string GetRightmostIp(string[] ipAddressList){
                                        for(int i = ipAddressList.Count()-1; i>=0; i--)
                                        {
                                            string ip = ipAddressList[i];
                                            string ipAddress = String.Concat(ip.Where(c => !Char.IsWhiteSpace(c)));
                                            if(!IsPrivate(ipAddress)){
                                                return ipAddress;
                                            }
                                        }
                                        return "127.0.0.1";
                                    }
            
                                    string forwardedFor = context.Request.Headers.GetValueOrDefault("x-forwarded-for","");
                                    if (!string.IsNullOrEmpty(forwardedFor)) {
                                        string[] ipAddressList = forwardedFor.Split(',');
                                        string ipAddress = GetRightmostIp(ipAddressList);
            
                                        string[] tokens = ipAddress.Split(':');
                                        if(tokens.Length == 2) {
                                            ipAddress = tokens[0];
                                        }
            
                                        var queryResponse = context.Variables.GetValueOrDefault<JObject>("issuerWhitelist");
                                        if (queryResponse != null && queryResponse.ContainsKey("Documents"))
                                        {
                                            JArray documents = (JArray) queryResponse["Documents"];
                                            if (documents.Count > 0){
                                                JObject firstDocument = (JObject) documents[0];
                                                if(firstDocument.ContainsKey("cidrs")){
                                                    JArray whiteListCidrs = (JArray)firstDocument["cidrs"];
                                                    foreach (var cidr in whiteListCidrs) {
                                                        string cidrAddress = (string)cidr;
                                                        // Avoid checking in this case because all IPs are enabled
                                                        if(cidrAddress=="0.0.0.0/0"){
                                                            return "true";
                                                        }
            
                                                        string[] cidrParts = cidrAddress.Split('/');
                                                        string[] inputIPParts = ipAddress.Split('.');
                                                        string[] cidrIPArray = cidrParts[0].Split('.');
            
                                                        if (inputIPParts.Length == 4 && cidrIPArray.Length == 4) {
                                                            byte[] inputIPBytes = new byte[] {Convert.ToByte(int.Parse(inputIPParts[0])),
                                                                Convert.ToByte(int.Parse(inputIPParts[1])),
                                                                Convert.ToByte(int.Parse(inputIPParts[2])),
                                                                Convert.ToByte(int.Parse(inputIPParts[3])), };
                                                            byte[] cidrIPBytes = new byte[] {Convert.ToByte(int.Parse(cidrIPArray[0])),
                                                                Convert.ToByte(int.Parse(cidrIPArray[1])),
                                                                Convert.ToByte(int.Parse(cidrIPArray[2])),
                                                                Convert.ToByte(int.Parse(cidrIPArray[3])), };
            
                                                            int cidrAddr = BitConverter.ToInt32(inputIPBytes,0);
                                                            int ipAddr = BitConverter.ToInt32(cidrIPBytes,0);
            
                                                            var host = int.Parse(cidrParts[1]);
                                                            host = -1 << (32-host);
                                                            var mask = HostToNetworkOrder(host);
            
                                                            if (((ipAddr & mask) == (cidrAddr & mask))) {
                                                                return "true";
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                    return "false";
                                }</value>
                            </set-header>
                            <check-header name="X-Allowed" failed-check-httpcode="403" failed-check-error-message="Forbidden" ignore-case="true">
                                <value>true</value>
                            </check-header>
                            <!-- Delete temporary header -->
                            <set-header name="X-Allowed" exists-action="delete" />
                            <rate-limit-by-key calls="150" renewal-period="5" counter-key="@(context.Subscription.Id)" retry-after-header-name="x-rate-limit-retry-after" remaining-calls-header-name="x-rate-limit-remaining" />
                        </when>
                        <otherwise>
                            <!-- Allow direct call only from internal -->
                            <ip-filter action="allow">
                                <address-range from="172.16.2.1" to="172.16.2.254" />
                            </ip-filter>
                        </otherwise>
                    </choose>
                    <base />
                </inbound>
                <backend>
                    <base />
                </backend>
                <outbound>
                    <base />
                </outbound>
                <on-error>
                    <base />
                </on-error>
            </policies>
        EOT
    }

  # module.apim_itn_io_sign_support_api_v1.azurerm_api_management_api.this will be created
  + resource "azurerm_api_management_api" "this" {
      + api_management_name   = "io-p-itn-apim-01"
      + api_type              = "http"
      + description           = "IO Sign - Support API"
      + display_name          = "IO Sign - Support API"
      + id                    = (known after apply)
      + is_current            = (known after apply)
      + is_online             = (known after apply)
      + name                  = "io-p-sign-support-api"
      + path                  = "api/v1/sign/support"
      + protocols             = [
          + "https",
        ]
      + resource_group_name   = "io-p-itn-common-rg-01"
      + revision              = "1"
      + service_url           = (known after apply)
      + soap_pass_through     = (known after apply)
      + subscription_required = true
      + version               = (known after apply)
      + version_set_id        = (known after apply)

      + import {
          + content_format = "openapi"
          + content_value  = <<-EOT
                openapi: 3.0.3
                info:
                  title: Firma con IO - Support API
                  version: 1.0.0
                servers:
                  - url: https://api.io.pagopa.it/api/v1/sign/support
                    description: production
                  - url: http://localhost:7071/api/v1/sign/support
                    description: local
                paths:
                  /signature-requests/{id}:
                    post:
                      operationId: getSignatureRequestById
                      tags:
                        - signature request
                      summary: Find Signature Request by Id
                      requestBody:
                        $ref: "#/components/requestBodies/GetSignatureRequestById"
                      parameters:
                        - in: path
                          name: id
                          description: the signature request id
                          required: true
                          schema:
                            $ref: "#/components/schemas/Id"
                      responses:
                        200:
                          description: the signature request
                          content:
                            application/json:
                              schema:
                                $ref: "#/components/schemas/SignatureRequest"
                        400:
                          $ref: "#/components/responses/ValidationProblem"
                        401:
                          $ref: "#/components/responses/HttpUnauthorized"
                        404:
                          $ref: "#/components/responses/HttpNotFound"
                        500:
                          $ref: "#/components/responses/HttpInternalServerError"
                
                components:
                  requestBodies:
                    GetSignatureRequestById:
                      required: true
                      content:
                        application/json:
                          schema:
                            $ref: "#/components/schemas/RequireFiscalCodeOrVatNumber"
                
                  responses:
                    HttpNotFound:
                      description: The specified resource was not found
                      content:
                        application/json:
                          schema:
                            type: object
                            properties:
                              title:
                                type: string
                                enum: ["Not found"]
                              status:
                                type: number
                                enum: [404]
                            required:
                              - title
                              - status
                
                    HttpInternalServerError:
                      description: Internal Server Error
                      content:
                        application/json:
                          schema:
                            type: object
                            properties:
                              title:
                                type: string
                                enum: ["Internal Server Error"]
                              status:
                                type: number
                                enum: [500]
                              detail:
                                type: string
                            required:
                              - title
                              - status
                
                    HttpUnauthorized:
                      description: Internal Server Error
                      content:
                        application/json:
                          schema:
                            type: object
                            properties:
                              title:
                                type: string
                                enum: ["Unauthorized"]
                              status:
                                type: number
                                enum: [401]
                              detail:
                                type: string
                                enum:
                                  ["You must provide a valid API key to access this resource."]
                            required:
                              - title
                              - status
                              - detail
                
                    ValidationProblem:
                      description: Error on request validation
                      content:
                        application/json:
                          schema:
                            type: object
                            properties:
                              type:
                                type: string
                                enum: ["/problems/validation-error"]
                              title:
                                type: string
                              detail:
                                type: string
                              status:
                                type: number
                                enum: [400]
                              violations:
                                type: array
                                items:
                                  type: string
                            required:
                              - type
                              - title
                              - detail
                              - status
                
                  schemas:
                    FiscalCode:
                      type: string
                      description: User's fiscal code.
                      format: FiscalCode
                      x-import: "@pagopa/ts-commons/lib/strings"
                      example: SPNDNL80R13C555X
                
                    Id:
                      type: string
                      description: Entity Id
                      format: NonEmptyString
                      example: 01ARZ3NDEKTSV4RRFFQ69G5FAV
                      x-import: "@pagopa/ts-commons/lib/strings"
                
                    Timestamp:
                      type: string
                      format: UTCISODateFromString
                      description: A date-time field in ISO-8601 format and UTC timezone.
                      x-import: "@pagopa/ts-commons/lib/dates"
                      example: "2018-10-13T00:00:00.000Z"
                
                    RequireFiscalCodeOrVatNumber:
                      oneOf:
                        - type: object
                          properties:
                            fiscal_code:
                              $ref: "#/components/schemas/FiscalCode"
                          required:
                            - fiscal_code
                        - type: object
                          properties:
                            vat_number:
                              type: string
                          required:
                            - vat_number
                
                    Clause:
                      type: object
                      properties:
                        title:
                          type: string
                          minLength: 5
                          maxLength: 80
                        type:
                          type: string
                          enum: ["REQUIRED", "UNFAIR", "OPTIONAL"]
                      required:
                        - title
                        - type
                
                    ExistingSignatureFieldAttrs:
                      type: object
                      properties:
                        unique_name:
                          type: string
                      required:
                        - unique_name
                
                    SignatureFieldToBeCreatedAttrs:
                      type: object
                      properties:
                        coordinates:
                          type: object
                          properties:
                            x: { type: number }
                            y: { type: number }
                          required: [x, y]
                        page:
                          type: number
                          minimum: 0
                        size:
                          type: object
                          properties:
                            w: { type: number, minimum: 0 }
                            h: { type: number, minimum: 0 }
                          required: [w, h]
                      required:
                        - coordinates
                        - page
                        - size
                
                    SignatureFieldAttrs:
                      oneOf:
                        - $ref: "#/components/schemas/ExistingSignatureFieldAttrs"
                        - $ref: "#/components/schemas/SignatureFieldToBeCreatedAttrs"
                
                    SignatureField:
                      type: object
                      properties:
                        attrs:
                          $ref: "#/components/schemas/SignatureFieldAttrs"
                        clause:
                          $ref: "#/components/schemas/Clause"
                      required:
                        - attrs
                        - clause
                
                    DocumentMetadata:
                      type: object
                      properties:
                        title:
                          type: string
                          minLength: 3
                          maxLength: 60
                        signature_fields:
                          type: array
                          items:
                            $ref: "#/components/schemas/SignatureField"
                      required:
                        - title
                
                    Document:
                      type: object
                      properties:
                        id:
                          $ref: "#/components/schemas/Id"
                        metadata:
                          $ref: "#/components/schemas/DocumentMetadata"
                        status:
                          type: string
                          enum:
                            - WAIT_FOR_UPLOAD
                            - WAIT_FOR_VALIDATION
                            - READY
                            - REJECTED
                        created_at:
                          $ref: "#/components/schemas/Timestamp"
                        url:
                          type: string
                          format: url
                        uploaded_at:
                          $ref: "#/components/schemas/Timestamp"
                        updated_at:
                          $ref: "#/components/schemas/Timestamp"
                        rejected_at:
                          $ref: "#/components/schemas/Timestamp"
                        reject_reason:
                          type: string
                      required:
                        - id
                        - metadata
                        - created_at
                        - status
                
                    Notification:
                      type: object
                      properties:
                        io_message_id:
                          $ref: "#/components/schemas/Id"
                      required:
                        - io_message_id
                
                    SignatureRequest:
                      type: object
                      properties:
                        id:
                          $ref: "#/components/schemas/Id"
                        issuer_id:
                          $ref: "#/components/schemas/Id"
                        signer_id:
                          $ref: "#/components/schemas/Id"
                        dossier_id:
                          $ref: "#/components/schemas/Id"
                        status:
                          type: string
                          enum:
                            - DRAFT
                            - READY
                            - WAIT_FOR_SIGNATURE
                            - WAIT_FOR_QTSP
                            - SIGNED
                            - REJECTED
                        created_at:
                          $ref: "#/components/schemas/Timestamp"
                        updated_at:
                          $ref: "#/components/schemas/Timestamp"
                        expires_at:
                          $ref: "#/components/schemas/Timestamp"
                        rejected_at:
                          $ref: "#/components/schemas/Timestamp"
                        signed_at:
                          $ref: "#/components/schemas/Timestamp"
                        reject_reason:
                          type: string
                        documents:
                          type: array
                          items:
                            $ref: "#/components/schemas/Document"
                        notification:
                          $ref: "#/components/schemas/Notification"
                      required:
                        - id
                        - issuer_id
                        - signer_id
                        - dossier_id
                        - status
                        - created_at
                        - updated_at
                        - expires_at
            EOT
        }
    }

  # module.apim_itn_io_sign_support_api_v1.azurerm_api_management_api_policy.this[0] will be created
  + resource "azurerm_api_management_api_policy" "this" {
      + api_management_name = "io-p-itn-apim-01"
      + api_name            = "io-p-sign-support-api"
      + id                  = (known after apply)
      + resource_group_name = "io-p-itn-common-rg-01"
      + xml_content         = <<-EOT
            <policies>
                <inbound>
                    <base />
                    <set-backend-service id="apim-generated-policy" base-url="{{io-fn-sign-support-url}}/api/v1/sign/support" />
                    <set-header name="x-functions-key" exists-action="override">
                        <value>{{io-fn-sign-support-key}}</value>
                    </set-header>
                    <set-header name="x-subscription-id" exists-action="override">
                        <value>@(context.Subscription.Id)</value>
                    </set-header>
                    <cors>
                        <allowed-origins>
                            <origin>*</origin>
                        </allowed-origins>
                        <allowed-methods>
                            <method>*</method>
                        </allowed-methods>
                        <allowed-headers>
                            <header>*</header>
                        </allowed-headers>
                        <expose-headers>
                            <header>*</header>
                        </expose-headers>
                    </cors>
                </inbound>
                <outbound>
                    <base />
                </outbound>
                <backend>
                    <base />
                </backend>
                <on-error>
                    <base />
                </on-error>
            </policies>
        EOT
    }

  # module.apim_itn_io_sign_support_api_v1.azurerm_api_management_product_api.this["io-sign-support-api"] will be created
  + resource "azurerm_api_management_product_api" "this" {
      + api_management_name = "io-p-itn-apim-01"
      + api_name            = "io-p-sign-support-api"
      + id                  = (known after apply)
      + product_id          = "io-sign-support-api"
      + resource_group_name = "io-p-itn-common-rg-01"
    }

  # module.apim_itn_io_sign_support_product.azurerm_api_management_product.this will be created
  + resource "azurerm_api_management_product" "this" {
      + api_management_name   = "io-p-itn-apim-01"
      + approval_required     = false
      + description           = "Support Product for IO SIGN"
      + display_name          = "IO SIGN SUPPORT Product"
      + id                    = (known after apply)
      + product_id            = "io-sign-support-api"
      + published             = true
      + resource_group_name   = "io-p-itn-common-rg-01"
      + subscription_required = true
    }

  # module.apim_itn_io_sign_support_product.azurerm_api_management_product_policy.this[0] will be created
  + resource "azurerm_api_management_product_policy" "this" {
      + api_management_name = "io-p-itn-apim-01"
      + id                  = (known after apply)
      + product_id          = "io-sign-support-api"
      + resource_group_name = "io-p-itn-common-rg-01"
      + xml_content         = <<-EOT
            <policies>
                <inbound>
                    <base />
                </inbound>
                <backend>
                    <base />
                </backend>
                <outbound>
                    <base />
                </outbound>
                <on-error>
                    <base />
                </on-error>
            </policies>
        EOT
    }

Plan: 31 to add, 0 to change, 0 to destroy.

Warning: Argument is deprecated

  with module.cosmosdb_account.azurerm_cosmosdb_account.this,
  on .terraform/modules/cosmosdb_account/cosmosdb_account/main.tf line 7, in resource "azurerm_cosmosdb_account" "this":
   7:   enable_free_tier          = var.enable_free_tier

This property has been superseded by `free_tier_enabled` and will be removed
in v4.0 of the AzureRM Provider

(and 23 more similar warnings elsewhere)

Warning: Deprecated attribute

  on .terraform/modules/cosmosdb_account/cosmosdb_account/output.tf line 54, in output "connection_strings":
  54:   value     = azurerm_cosmosdb_account.this.connection_strings

The attribute "connection_strings" is deprecated. Refer to the provider
documentation for details.

(and one more similar warning elsewhere)

─────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't
guarantee to take exactly these actions if you run "terraform apply" now.

@mamu0 mamu0 merged commit 9388d1b into main Nov 18, 2024
5 of 6 checks passed
@mamu0 mamu0 deleted the CES-68-define-resources-for-itn-apim branch November 18, 2024 14:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants