Este documento ha sido traducido utilizando tecnología de traducción automática. Si bien nos esforzamos por proporcionar traducciones precisas, no ofrecemos garantías sobre la integridad, precisión o confiabilidad del contenido traducido. En caso de discrepancia, la versión original en inglés prevalecerá y constituirá el texto autorizado.

Esta es documentación inédita para Admission Controller 1.34-dev.

Validando directivas

El servidor de directivas SUSE Security Admission Controller recibe:

  • Kubernetes AdmissionReview objetos del servidor API de Kubernetes. Luego reenvía el valor de su atributo request, de tipo AdmissionRequest, a la directiva para su evaluación.

O bien:

  • Un atributo JSON request que contiene el documento de solicitud en formato libre, en caso de una directiva bruta. Consulta la sección Directivas brutas para más detalles.

La directiva evalúa el request y establece si debe aceptarlo o no. Cuando ocurre el rechazo de la solicitud, la directiva puede proporcionar el mensaje de explicación y un código de error para mostrar al usuario final.

Por convención, del proyecto policy-server, el invitado debe exponer una función llamada validate, a través del SDK de invitado waPC, para que el policy-server (anfitrión waPC) pueda invocarla.

La función validate recibe un objeto JSON ValidationRequest y devuelve un objeto JSON ValidationResponse.

El objeto ValidationRequest

El ValidationRequest es un objeto JSON recibido por la función validate. Se ve así:

{
  "request": <AdmissionReview.request data> | <RawReviewRequest.request data>,
  "settings": {
    # your policy configuration
  }
}

La clave settings apunta a un documento JSON en formato libre que contiene las configuraciones específicas de la directiva. El capítulo anterior se centró en directivas y configuraciones.

Un ejemplo

Dada la siguiente directiva de Kubernetes AdmissionReview:

Expande para ver AdmissionReview
{
  "apiVersion": "admission.k8s.io/v1",
  "kind": "AdmissionReview",
  "request": {
    # Random uid uniquely identifying this admission call
    "uid": "705ab4f5-6393-11e8-b7cc-42010a800002",

    # Fully-qualified group/version/kind of the incoming object
    "kind": {"group":"autoscaling","version":"v1","kind":"Scale"},
    # Fully-qualified group/version/kind of the resource being modified
    "resource": {"group":"apps","version":"v1","resource":"deployments"},
    # subresource, if the request is to a subresource
    "subResource": "scale",

    # Fully-qualified group/version/kind of the incoming object in the original request to the API server.
    # This only differs from `+kind+` if the webhook specified `+matchPolicy: Equivalent+` and the
    # original request to the API server was converted to a version the webhook registered for.
    "requestKind": {"group":"autoscaling","version":"v1","kind":"Scale"},
    # Fully-qualified group/version/kind of the resource being modified in the original request to the API server.
    # This only differs from `+resource+` if the webhook specified `+matchPolicy: Equivalent+` and the
    # original request to the API server was converted to a version the webhook registered for.
    "requestResource": {"group":"apps","version":"v1","resource":"deployments"},
    # subresource, if the request is to a subresource
    # This only differs from `+subResource+` if the webhook specified `+matchPolicy: Equivalent+` and the
    # original request to the API server was converted to a version the webhook registered for.
    "requestSubResource": "scale",

    # Name of the resource being modified
    "name": "my-deployment",
    # Namespace of the resource being modified, if the resource is namespaced (or is a Namespace object)
    "namespace": "my-namespace",

    # operation can be CREATE, UPDATE, DELETE, or CONNECT
    "operation": "UPDATE",

    "userInfo": {
      # Username of the authenticated user making the request to the API server
      "username": "admin",
      # UID of the authenticated user making the request to the API server
      "uid": "014fbff9a07c",
      # Group memberships of the authenticated user making the request to the API server
      "groups": ["system:authenticated","my-admin-group"],
      # Arbitrary extra info associated with the user making the request to the API server.
      # This is populated by the API server authentication layer and should be included
      # if any SubjectAccessReview checks are performed by the webhook.
      "extra": {
        "some-key":["some-value1", "some-value2"]
      }
    },

    # object is the new object being admitted.
    # It is null for DELETE operations.
    "object": {"apiVersion":"autoscaling/v1","kind":"Scale",...},
    # oldObject is the existing object.
    # It is null for CREATE and CONNECT operations.
    "oldObject": {"apiVersion":"autoscaling/v1","kind":"Scale",...},
    # options contains the options for the operation being admitted, like meta.k8s.io/v1 CreateOptions, UpdateOptions, or DeleteOptions.
    # It is null for CONNECT operations.
    "options": {"apiVersion":"meta.k8s.io/v1","kind":"UpdateOptions",...},

    # dryRun indicates the API request is running in dry run mode and will not be persisted.
    # Webhooks with side effects should avoid actuating those side effects when dryRun is true.
    # See http://k8s.io/docs/reference/using-api/api-concepts/#make-a-dry-run-request for more details.
    "dryRun": false
  }
}

El objeto ValidationRequest se vería así:

Expande para ver el ValidationRequest
{
  "request": {
    # Random uid uniquely identifying this admission call
    "uid": "705ab4f5-6393-11e8-b7cc-42010a800002",

    # Fully-qualified group/version/kind of the incoming object
    "kind": {"group":"autoscaling","version":"v1","kind":"Scale"},
    # Fully-qualified group/version/kind of the resource being modified
    "resource": {"group":"apps","version":"v1","resource":"deployments"},
    # subresource, if the request is to a subresource
    "subResource": "scale",

    # Fully-qualified group/version/kind of the incoming object in the original request to the API server.
    # This only differs from `+kind+` if the webhook specified `+matchPolicy: Equivalent+` and the
    # original request to the API server was converted to a version the webhook registered for.
    "requestKind": {"group":"autoscaling","version":"v1","kind":"Scale"},
    # Fully-qualified group/version/kind of the resource being modified in the original request to the API server.
    # This only differs from `+resource+` if the webhook specified `+matchPolicy: Equivalent+` and the
    # original request to the API server was converted to a version the webhook registered for.
    "requestResource": {"group":"apps","version":"v1","resource":"deployments"},
    # subresource, if the request is to a subresource
    # This only differs from `+subResource+` if the webhook specified `+matchPolicy: Equivalent+` and the
    # original request to the API server was converted to a version the webhook registered for.
    "requestSubResource": "scale",

    # Name of the resource being modified
    "name": "my-deployment",
    # Namespace of the resource being modified, if the resource is namespaced (or is a Namespace object)
    "namespace": "my-namespace",

    # operation can be CREATE, UPDATE, DELETE, or CONNECT
    "operation": "UPDATE",

    "userInfo": {
      # Username of the authenticated user making the request to the API server
      "username": "admin",
      # UID of the authenticated user making the request to the API server
      "uid": "014fbff9a07c",
      # Group memberships of the authenticated user making the request to the API server
      "groups": ["system:authenticated","my-admin-group"],
      # Arbitrary extra info associated with the user making the request to the API server.
      # This is populated by the API server authentication layer and should be included
      # if any SubjectAccessReview checks are performed by the webhook.
      "extra": {
        "some-key":["some-value1", "some-value2"]
      }
    },

    # object is the new object being admitted.
    # It is null for DELETE operations.
    "object": {"apiVersion":"autoscaling/v1","kind":"Scale",...},
    # oldObject is the existing object.
    # It is null for CREATE and CONNECT operations.
    "oldObject": {"apiVersion":"autoscaling/v1","kind":"Scale",...},
    # options contains the options for the operation being admitted, like meta.k8s.io/v1 CreateOptions, UpdateOptions, or DeleteOptions.
    # It is null for CONNECT operations.
    "options": {"apiVersion":"meta.k8s.io/v1","kind":"UpdateOptions",...},

    # dryRun indicates the API request is running in dry run mode and will not be persisted.
    # Webhooks with side effects should avoid actuating those side effects when dryRun is true.
    # See http://k8s.io/docs/reference/using-api/api-concepts/#make-a-dry-run-request for more details.
    "dryRun": false
  },
  "settings": {
    # policy settings
  }
}

El objeto ValidationResponse

La función validate devuelve el resultado de su validación utilizando un objeto ValidationResponse.

El ValidationResponse tiene esta estructura:

{
  # mandatory
  "accepted": <boolean>,

  # optional, ignored if accepted - recommended for rejections
  "message": <string>,

  # optional, ignored if accepted
  "code": <integer>,

  # optional, used by mutation policies
  "mutated_object": <string>
}

Puedes especificar estos atributos message y code cuando la solicitud no es aceptada. El message es un error textual de formato libre y code representa un código de error HTTP.

El servidor API de Kubernetes ignora los valores message y code en la aceptación de la solicitud.

En caso de denegación de la solicitud y si el message o el code están presentes, entonces el servidor API de Kubernetes devuelve esta información. La información es parte del cuerpo del error, y el servidor se la devuelve al cliente API de Kubernetes que emitió la solicitud rechazada.

El mutated_object es un campo opcional utilizado solo por directivas de mutación. Este es el tema del próximo capítulo.