Añadir políticas a la pasarela de GKE

Esta página se aplica a Apigee, pero no a Apigee Hybrid.

Consulta la documentación de Apigee Edge.

En esta página se describe cómo añadir políticas de tiempo de ejecución de Apigee y una política de inserción de tokens Google a la puerta de enlace de Google Kubernetes Engine (GKE) con el operador de gestión de APIs de Apigee para Kubernetes. Si añades un conjunto de políticas disponibles a la pasarela, podrás ampliar sus funciones más allá de la aplicación de productos de API para incluir reglas de negocio y de seguridad adicionales.

El operador de Apigee APIM para Kubernetes se puede usar para añadir las siguientes políticas a la pasarela:

Información general

En las siguientes secciones se describe cómo:

Antes de empezar

Para modificar tu GKE Gateway con el conjunto completo de políticas que se usa como ejemplo en esta guía, debes tener una cuenta de servicio con los roles necesarios para crear tokens en Apigee e implementar proxies y extensiones. Si decides no crear tokens, no tienes que añadir los roles adicionales a tu cuenta de servicio y puedes pasar a la siguiente sección. Google

Para crear una cuenta de servicio con los permisos necesarios, sigue estos pasos:

  1. Si has creado una cuenta de servicio llamada apigee-apim-gsa en la guía de instalación del operador de gestión de APIs de Apigee para Kubernetes, puedes saltarte este paso y pasar al siguiente. Si no lo has hecho, crea la cuenta de servicio:
    gcloud iam service-accounts create apigee-apim-gsa --project=$PROJECT_ID
  2. Asigna a la cuenta de servicio el rol necesario para crear tokens:
    gcloud projects add-iam-policy-binding $PROJECT_ID \
      --member "serviceAccount:apigee-apim-gsa@$PROJECT_ID.iam.gserviceaccount.com" \
      --role "roles/iam.serviceAccountTokenCreator"
  3. Concede a la cuenta de servicio apigee-apim-gsa el rol necesario para implementar proxies y extensiones:
    gcloud projects add-iam-policy-binding $PROJECT_ID \
      --member "serviceAccount:apigee-apim-gsa@$PROJECT_ID.iam.gserviceaccount.com" \
      --role "roles/iam.serviceAccountUser"

Modificar una pasarela de GKE con políticas

Puedes modificar tu GKE Gateway con una o varias políticas para ampliar su funcionalidad. En este ejemplo se aplica un archivo yaml a la pasarela que incluye las especificaciones de dos políticas de Apigee y una política de inyección de tokens Google .

Cada una de las políticas aplicadas a la pasarela mediante el siguiente archivo yaml desempeña un papel diferente al evaluar las solicitudes enviadas a la pasarela:

  • La política SpikeArrest controla la tasa máxima de mensajes definiendo una tasa máxima de solicitudes permitidas durante una unidad de tiempo. En este ejemplo, la frecuencia máxima se ha definido en cinco por minuto. Para obtener más información sobre cómo se usa la política de SpikeArrest para suavizar los picos repentinos de tráfico, consulta el artículo Política de SpikeArrest.
  • La política de JavaScript le permite añadir código JavaScript personalizado a las solicitudes de la pasarela. En este ejemplo, la política se usa para añadir un encabezado personalizado a la solicitud. Para obtener más información sobre cómo se usa la política de JavaScript para añadir código personalizado, consulta el artículo Política de JavaScript.
  • La política de inyección de tokens Google se usa para inyectar un token de acceso de autenticación Google en las solicitudes de la pasarela mediante la política AssignMessage. Apigee admite el uso de tokens de Google OAuth u OpenID Connect para autenticarse con servicios de Google . Para obtener más información sobre los tokens de autenticación, consulta el artículo Usar la autenticación de Google.

Añade las políticas a la pasarela:

  1. Crea un archivo llamado apigee-policies.yaml en el espacio de nombres apim.
  2. Copia el contenido del siguiente archivo en el archivo que has creado:
    # apigee-policies.yaml
    apiVersion: apim.googleapis.com/v1
    kind: SpikeArrest
    metadata:
      name: spike-arrest
      namespace: apim
    spec:
      identifier:
        ref: request.header.name
      useEffectiveCount: true
      peakMessageRate:
        value: "5pm"
    ---
    apiVersion: apim.googleapis.com/v1
    kind: Javascript
    metadata:
      name: js-add-headers
      namespace: apim
    spec:
      timeLimit: 2000
      source: |
        var sum = 1+1;
        context.setVariable("request.header.first", 1);
        context.setVariable("request.header.second", 1);
        context.setVariable("request.header.sum", sum);
    ---
    apiVersion: apim.googleapis.com/v1
    kind: AssignMessage
    metadata:
      name: google-token-policy
      namespace: apim
    spec:
      setActions:
        - authentication:
            googleAccessToken:
              scopes:
                - 'https://www.googleapis.com/auth/cloud-platform'
      AssignTo:
        createNew: false
        type: request
    ---
    apiVersion: apim.googleapis.com/v1
    kind: KVM
    metadata:
      name: kvm-1
      namespace: apim
    spec:
      delete:
      - keys:
        - value: mykey
      exclusiveCache: true
      expiryTimeInSecs: 3600
      get:
      - assignTo: response.header.mykvm
        keys:
        - value: mykey
      initialEntries:
      - keys:
        - key1
        values:
        - val1
      - keys:
        - mykey
        values:
        - initvalue
      isEncrypted: false
      put:
      - keys:
        - value: mykey
        values:
        - value: request.header.mykvm
      scope: environment
    ---
    apiVersion: apim.googleapis.com/v1
    kind: OASValidation
    metadata:
      name: oas-validation-1
      namespace: apim
    spec:
      openApiSpec: |
        openapi: 3.0.4
        info:
          title: Sample API
          description: Optional multi/single line description.
          version: 0.1.9
        servers:
          - url: http://apigee-apim-operator-test.apigee.net
            description: Optional server description, our main host in httproute
        paths:
          /get:
            get:
              summary: just for test
              description: Optional extended description in CommonMark or HTML.
              parameters:
                - name: X-Request-Type
                  in: header
                  description: Must be 'internal' or 'external'.
                  required: true
                  schema:
                    type: string
                    enum:
                      - internal
                      - external
              responses:
                '200': # status code
                  description: A JSON object
                  content:
                    application/json:
                      schema:
                        type: object
                        properties:
                          headers:
                            type: object
      source: request
    ---
    apiVersion: apim.googleapis.com/v1
    kind: ServiceCallout
    metadata:
      name: service-callout-1
      namespace: apim
    spec:
      request:
        clearPayload: true
        variable: myRequest
        ignoreUnresolvedVariables: true
        removeActions:
          - payload: true
          - queryParams:
            - name: rq-param1
            - name: rq-param2
        copyActions:
          - version: true
          - verb: true
        addActions:
          - headers:
            - name: X-header1
              value: value1
            - name: X-header2
              value: value2
          - queryParams:
            - name: q-param1
              value: value1
            - name: q-param2
              value: value2
        setActions:
          - verb: PUT
          - formParams:
            - name: f-param1
              value: value1
            - name: f-param2
              value: value2
      response: calloutResponse
      timeout: 30000
      httpTargetConnection:
        URL: https://httpbin.org/put
        properties:
          - name: success.codes
            value: 1xx,2xx,3xx,400
          - name: supports.http11
            value: "true"
  3. Aplica el archivo yaml a la pasarela con el siguiente comando:
    kubectl -n apim apply -f apigee-policies.yaml

Crear un TemplateRule como plantilla de SharedFlow

En este paso, crearás un TemplateRule para aplicar las políticas que has añadido a la pasarela. Una regla de plantilla es una regla para SharedFlows creada por administradores de la organización para asegurarse de que los desarrolladores de servicios solo apliquen políticas aprobadas al tráfico de la pasarela. Una regla de plantilla asegura que los desarrolladores sepan qué políticas tienen a su disposición, qué políticas son obligatorias para casos prácticos específicos y qué políticas no pueden usar los desarrolladores de servicios.

Crear una regla de plantilla

Crea una regla de plantilla para aplicar el uso de la política AssignMessage:

  1. Crea un archivo yaml llamado template-rule.yaml en el espacio de nombres apim.
  2. Copia el contenido del siguiente archivo en el archivo que has creado:
    # template-rule.yaml
    apiVersion: apim.googleapis.com/v1
    kind: ApimTemplateRule
    metadata:
      name: template-rule
      namespace: apim
    spec:
      allowList: [SpikeArrest, Javascript, GenerateJWT, KVM, OASValidation, OAuthv2, ServiceCallout]
      requiredList: [AssignMessage]
      denyList: []

    En este ejemplo, la regla de plantilla indica a los desarrolladores que es obligatoria la política AssignMessage, que describe la política de inyección de tokens Google . También indica a los desarrolladores que pueden usar las políticas SpikeArrest, JavaScript, GenerateJWT, KVM, OASValidation, OAuthv2 y ServiceCallout en su gestión de APIs. No se ha especificado ninguna política en la lista de denegación.

Aplicar la regla de la plantilla

Aplica la regla de plantilla con el siguiente comando:

kubectl apply -f template-rule.yaml

Crea una plantilla de Apigee para usar la regla de plantilla

Crea una plantilla de Apigee para incluir la regla de plantilla que has creado en la sección anterior:

  1. Crea un archivo yaml llamado new-admin-template.yaml en el espacio de nombres apim.
  2. Copia el contenido del siguiente archivo en el archivo que has creado:
    # new-admin-template.yaml
    apiVersion: apim.googleapis.com/v1
    kind: ApimTemplate
    metadata:
      name: new-admin-template
      namespace: apim
    spec:
      apimTemplateRule:
        group: apim.googleapis.com
        kind: ApimTemplateRule
        name: template-rule
        namespace: apim
      templates:
      - mode: REQUEST
        flows:
        - name: preflow
          policies:
          - group: apim.googleapis.com
            kind: OASValidation
            name: oas-validation-1
            namespace: apim
          - group: apim.googleapis.com
            kind: SpikeArrest
            name: spike-arrest
            namespace: apim
        - name: ConditionalGetFlow
          policies:
          - group: apim.googleapis.com
            kind: Javascript
            name: js-add-headers
            namespace: apim
          condition: request.verb="GET"
        - name: postflow
          policies:
          - group: apim.googleapis.com
            kind: AssignMessage
            name: google-token-policy
            namespace: apim
          - group: apim.googleapis.com
            kind: ServiceCallout
            name: service-callout-1
            namespace: apim
      - mode: RESPONSE
        flows:
        - name: postflow
          policies:
          - group: apim.googleapis.com
            kind: KVM
            name: kvm-1
            namespace: apim
  3. Aplica la nueva plantilla con el siguiente comando:
    kubectl apply -f new-admin-template.yaml

Desplegar la política de Apigee Gateway

En este paso, aplicará un nuevo archivo a su Gateway que incluya las especificaciones de un ApigeeGatewayPolicy. Esta política se usa para implementar la plantilla de Apigee en la puerta de enlace.

Despliega la política de Apigee Gateway:

  1. Crea un archivo yaml llamado apigee-gateway-policy-withSA.yaml en el espacio de nombres apim.
  2. Copia el contenido del siguiente archivo en el archivo que has creado:
    # apigee-gateway-policy-withSA.yaml
    apiVersion: apim.googleapis.com/v1
    kind: ApigeeGatewayPolicy
    metadata:
      name: apim-template-injection
      namespace: apim
    spec:
      serviceAccount: apigee-apim-gsa@PROJECT_ID.iam.gserviceaccount.com
      ref:
        group: apim.googleapis.com
        kind: ApimTemplate
        name: new-admin-template
        namespace: apim
      targetRef:
        group: apim.googleapis.com
        kind: APIMExtensionPolicy
        name: global-ext-lb1-apim-policy
        namespace: apim
  3. Aplica la política:
    kubectl apply -f apigee-gateway-policy-withSA.yaml
  4. Verifica el estado de implementación de la nueva política de Gateway:
    kubectl -n apim get ApigeeGatewayPolicy

    Una vez implementada, la política STATUS debería mostrar CREATED.

Una vez que se haya implementado la nueva política de Gateway, espera dos minutos antes de enviar una solicitud a Gateway para que la política se propague al clúster.

Validar la aplicación de las políticas

Para confirmar que las políticas de Apigee Gateway funcionan correctamente, envía solicitudes a la pasarela tal como se describe en las siguientes secciones.

Cumplimiento de la política AssignMessage

Para confirmar que el token {company_name} se inserta en la solicitud mediante la política AssignMessage, envía una solicitud a la pasarela con el siguiente comando:

curl http://GATEWAY_IP_ADDRESS/get -H "Host: HOST_NAME" -H "x-api-key: API_KEY"

Donde:

  • GATEWAY_IP_ADDRESS es la dirección IP de la pasarela. Puedes obtener la dirección IP de la pasarela con el siguiente comando:
    kubectl get gateway GATEWAY_NAME
  • HOST_NAME es el nombre del host.
  • API_KEY es el valor de la clave de API.

Una respuesta correcta debe incluir un encabezado Authorization con el token de portador generado, como en el siguiente ejemplo:

{
  "args": {},
  "headers": {
    "Accept": "*/*",
    "Authorization": "Bearer ya29.c.c0ASRK0Gbw03y9cfvxL11DxaRYBQUU18SmUP4Vu63OckHI5cX7wJ4DmGMG2vbDDS69HXJHqMj-lak4tcqOsJGmE65crn2gNuJLanXidwM8",
    "First": "1.0",
    "Host": "apigee-apim-operator-test.apigee.net",
    "Second": "1.0",
    "Sum": "2",
    "User-Agent": "curl/8.7.1",
    "X-Api-Key": "McYcHGR3PTSGLXExvKADwQ1JJeCjgPDUvAakCl0rJKCFaX0Y",
    "X-Cloud-Trace-Context": "0fd3dadc2a3c328fa968d5f5f1434c29/18300783092696918345"
  },
  "origin": "34.54.108.129",
  "url": "apigee-apim-operator-test.apigee.net/get"
}

Aplicación de la política de SpikeArrest

Puedes probar la aplicación de la política SpikeArrest enviando una solicitud a la puerta de enlace diez veces en el plazo de un minuto.

Puedes ejecutar la siguiente secuencia de comandos para generar las solicitudes:

#!/bin/sh
for i in $(seq 1 11); do
    curl http://GATEWAY_IP_ADDRESS/get -H "Host: HOST_NAME" -H "x-api-key: API_KEY"
    sleep 1
done

Donde:

  • GATEWAY_IP_ADDRESS es la dirección IP de la pasarela. Puedes obtener la dirección IP de la pasarela con el siguiente comando, donde GATEWAY_NAME es el nombre de la pasarela:
    kubectl get gateways.gateway.networking.k8s.io GATEWAY_NAME -o=jsonpath="{.status.addresses[0].value}"
  • HOST_NAME es el nombre de host definido en HTTPRoute de la pasarela.
  • API_KEY es el valor de la clave de API que se ha obtenido en Configuración de pruebas.

La respuesta tendrá un aspecto similar al siguiente:

"fault":{"faultstring":"Spike arrest violation. Allowed rate : MessageRate{capacity=5, period=Minutes}","detail":{"errorcode":"policies.ratelimit.SpikeArrestViolation"}}}

Implementación de políticas de JavaScript

Para confirmar que la política de JavaScript funciona correctamente, envía una solicitud a la pasarela con el siguiente comando:

curl http://GATEWAY_IP_ADDRESS/get \
  -H "Host: HOST_NAME" \
  -H "x-api-key: API_KEY" \
  -H "X-Request-Type: external" -i

Donde:

  • GATEWAY_IP_ADDRESS es la dirección IP de la pasarela. Puedes obtener la dirección IP de la pasarela con el siguiente comando, donde GATEWAY_NAME es el nombre de la pasarela:
    kubectl get gateways.gateway.networking.k8s.io GATEWAY_NAME -o=jsonpath="{.status.addresses[0].value}"
  • HOST_NAME es el nombre de host definido en HTTPRoute de la pasarela.
  • API_KEY es el valor de la clave de API que se ha obtenido en Configuración de pruebas.

La política de JavaScript define tres encabezados de solicitud: First, Second y Sum, como se muestra en la respuesta:

HTTP/1.1 200 OK
...
{
  "args": {},
  "headers": {
    ...
    "First": "1.0",
    ...
    "Second": "1.0",
    "Sum": "2",
    ...
  },
  ...
}

Aplicación obligatoria de la política de OASValidation

Para confirmar que la política OASValidation funciona correctamente, envía una solicitud a la pasarela con el siguiente comando:

curl "http://GATEWAY_IP_ADDRESS/get"  \
  -H "Host: HOST_NAME" \
  -H "x-api-key: API_KEY" \
  -H "X-Request-Type: badvalue"

Donde:

  • GATEWAY_IP_ADDRESS es la dirección IP de la pasarela. Puedes obtener la dirección IP de la pasarela con el siguiente comando, donde GATEWAY_NAME es el nombre de la pasarela:
    kubectl get gateways.gateway.networking.k8s.io GATEWAY_NAME -o=jsonpath="{.status.addresses[0].value}"
  • HOST_NAME es el nombre de host definido en HTTPRoute de la pasarela.
  • API_KEY es el valor de la clave de API que se ha obtenido en Configuración de pruebas.

El comando incluye un valor no válido para el encabezado X-Request-Type. La solicitud fallará con una respuesta similar a la siguiente:

{"fault":{"faultstring":"OASValidation oas-validation-1 with resource \"oas:\/\/oas-validation-1.yaml\": failed with reason: \"[ERROR - Instance value (\"badvalue\") not found in enum (possible values: [\"internal\",\"external\"]): []]\"","detail":{"errorcode":"steps.oasvalidation.Failed"}}}

Si se envía la misma solicitud con un valor válido para el encabezado X-Request-Type, se completará correctamente. Por ejemplo:

curl "http://GATEWAY_IP_ADDRESS/get"  \
  -H "Host: HOST_NAME" \
  -H "x-api-key: API_KEY" \
  -H "X-Request-Type: external" -i

Donde:

  • GATEWAY_IP_ADDRESS es la dirección IP de la pasarela. Puedes obtener la dirección IP de la pasarela con el siguiente comando, donde GATEWAY_NAME es el nombre de la pasarela:
    kubectl get gateways.gateway.networking.k8s.io GATEWAY_NAME -o=jsonpath="{.status.addresses[0].value}"
  • HOST_NAME es el nombre de host definido en HTTPRoute de la pasarela.
  • API_KEY es el valor de la clave de API que se ha obtenido en Configuración de pruebas.

Cumplimiento de la política ServiceCallout

Para verificar que se aplica la política ServiceCallout, abre una sesión de depuración y envía algunas solicitudes válidas al proxy.

Para abrir una sesión de depuración, sigue estos pasos:

  1. En la Google Cloud consola, ve a la página Proxies de API.

    Ir a Proxies de API

  2. Selecciona el proxy global-ext-lb1-apim-policy que has desplegado en el entorno creado para el operador de gestión de APIs de Apigee para Kubernetes.
  3. Haz clic en la pestaña Depuración.
  4. En la ventana Sesión de depuración, haz clic en Iniciar sesión de depuración.
  5. En el panel Sesión de depuración, haga las siguientes selecciones:
    • Entorno: seleccione el entorno que ha creado para el operador de APIM en la lista de entornos disponibles.
    • Filtrar: selecciona Ninguno (todas las transacciones).
  6. Haz clic en Empezar.

Una vez que se haya iniciado la sesión, podrá enviar solicitudes válidas al proxy:

curl "GATEWAY_IP_ADDRESSget"  \
  -H "Host: HOST_NAME" \
  -H "x-api-key: API_KEY" \
  -H "X-Request-Type: external" -i

Donde:

  • GATEWAY_IP_ADDRESS es la dirección IP de la pasarela. Puedes obtener la dirección IP de la pasarela con el siguiente comando, donde GATEWAY_NAME es el nombre de la pasarela:
    kubectl get gateway GATEWAY_NAME
  • HOST_NAME es el nombre de host definido en HTTPRoute de la pasarela.
  • API_KEY es el valor de la clave de API que se ha obtenido en Configuración de pruebas.

Las transacciones de solicitud y respuesta se muestran en el panel Transacciones. Selecciona una transacción correcta de la lista para ver el flujo. Deberías ver que la política ServiceCallout se ha ejecutado correctamente.

Aplicación de la política de KVM

Cuando la política de KVM se ejecuta correctamente, inicializa el KVM con un valor inicial para la clave mykey. Cuando hay una transacción de respuesta, la política de KVM recupera el valor de mykey y lo almacena en el encabezado de respuesta mykvm. Cuando la política de KVM se vuelve a ejecutar, inserta el nuevo valor de mykey obtenido del encabezado de la solicitud mykvm.

Puede consultar los encabezados de cada transacción para confirmar que la política almacena un valor en el KVM en una transacción y recupera el mismo valor en la siguiente, como se muestra en el ejemplo siguiente.

Prueba la política de KVM:

  1. Envía una solicitud a la pasarela:
    curl -i "http://GATEWAY_IP_ADDRESS/get" \
      -H "Host: HOST_NAME" \
      -H "x-api-key: API_KEY" \
      -H "X-Request-Type: external" \
      -H "KVM_NAME: next-value1" -i

    Donde:

    • GATEWAY_IP_ADDRESS es la dirección IP de la pasarela. Puedes obtener la dirección IP de la pasarela con el siguiente comando, donde GATEWAY_NAME es el nombre de la pasarela:
      kubectl get gateway GATEWAY_NAME
    • HOST_NAME es el nombre de host definido en HTTPRoute de la pasarela.
    • API_KEY es el valor de la clave de API que se ha obtenido en Configuración de pruebas.
    • KVM_NAME es el nombre de la KVM.

  2. Comprueba los encabezados de respuesta para confirmar que la política de KVM se ha ejecutado correctamente y que se ha almacenado un valor inicial para mykvm. La respuesta debería ser similar a la siguiente:
    HTTP/1.1 200 OK
    access-control-allow-credentials: true
    access-control-allow-origin: *
    Content-Length: 517
    content-type: application/json
    date: ...
    server: gunicorn/19.9.0
    mykvm: initvalue
    via: 1.1 google
    {
      "args": {
      ...
      "url": "http://apigee-apim-operator-test.apigee.net/get"
      }
    }
  3. Envía otra solicitud a la pasarela:
    curl -i "http://GATEWAY_IP_ADDRESS/get" \
      -H "Host: HOST_NAME" \
      -H "x-api-key: API_KEY" \
      -H "mykvm: next"X-Request-Type: external" -H "mykvm: next-value2" -i

    La respuesta debería ser similar a la siguiente:

    HTTP/1.1 200 OK
    access-control-allow-credentials: true
    access-control-allow-origin: *
    Content-Length: 517
    content-type: application/json
    date: ...
    server: gunicorn/19.9.0
    mykvm: next-value2
    via: 1.1 google
    {
      "args": {
      ...
      "url": "http://apigee-apim-operator-test.apigee.net/get?rq-param2=rq-val1&x-param1=xval1"
      }
    }

    Puedes ver que la política de KVM se ha ejecutado correctamente porque el valor del encabezado mykvm se ha actualizado al valor del encabezado de solicitud mykvm.

  4. Enviar otra solicitud:
    curl -i "http://GATEWAY_IP_ADDRESS/get" \
      -H "Host: HOST_NAME" \
      -H "x-api-key: API_KEY" \
      -H "X-Request-Type: external" -H "mykvm: next-value3" -i

    La respuesta debería ser similar a la siguiente:

    HTTP/1.1 200 OK
    access-control-allow-credentials: true
    access-control-allow-origin: *
    Content-Length: 517
    content-type: application/json
    date: ...
    server: gunicorn/19.9.0
    mykvm: next-value2
    via: 1.1 google
    {
      "args": {
      ...
      "url": "http://apigee-apim-operator-test.apigee.net/get?rq-param2=rq-val1&x-param1=xval1"
      }
    }

    El valor del encabezado mykvm se vuelve a actualizar, lo que indica que el valor que se muestra en la respuesta son los valores almacenados en la transacción anterior.

Solucionar problemas

Si tienes problemas al añadir políticas a la GKE Gateway, consulta Solucionar problemas del operador de APIM para encontrar soluciones a errores habituales.

Siguientes pasos