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.36-dev.

Escribiendo la lógica de validación

Crítico: No escribas información de registro en STDOUT.

Escribir en STDOUT rompe las políticas. En su lugar, utiliza STDERR para el registro o la instalación de registro proporcionada por el SDK de SUSE Security Admission Controller. La salida de la directiva a STDOUT solo debe contener la respuesta de validación.

La lógica de validación va en el src/index.ts archivo.

Tu lógica de validación necesita:

  • Obtener la información relevante de la solicitud de validación entrante.

  • Devolver una respuesta basada en la entrada y la configuración de la directiva.

La solicitud entrante contiene un objeto JSON con el recurso de Kubernetes a validar. Puedes acceder a los datos de este objeto JSON a través de las funciones auxiliares del SDK de Admission Controller.

La validate función

La directiva proporcionada por la plantilla ya tiene una validate función en src/index.ts. Puedes usarla allí, añadiendo tu lógica para rechazar Pods con nombres de host denegados.

Así es como debería verse la función una vez completada:

/**
 * Validates the incoming request against policy settings.
 * Accepts or rejects the request based on denied hostnames.
 */
function validate(): void {
  try {
    // NOTE 1
    // Read the validation request payload
    const validationRequest = Validation.Validation.readValidationRequest();

    // NOTE 2
    // Extract policy settings from the validation request
    const settings: PolicySettings = validationRequest.settings || {};

    // NOTE 3
    // Extract the Kubernetes object (Pod) from the validation request
    const resource = getKubernetesResource(validationRequest);
    if (!resource) {
      writeOutput(Validation.Validation.rejectRequest('Failed to parse Kubernetes resource.'));
      return;
    }

    // Only process Pod resources
    if (resource.kind !== 'Pod') {
      writeOutput(Validation.Validation.acceptRequest());
      return;
    }

    // NOTE 4
    // Extract hostname from the Pod spec
    const hostname = getPodHostname(resource as Pod);
    const deniedHostnames = settings.denied_hostnames || [];

    // NOTE 5
    // Validate the hostname against the deny list
    if (!hostname) {
      writeOutput(Validation.Validation.acceptRequest());
      return;
    }

    if (deniedHostnames.includes(hostname)) {
      writeOutput(
        Validation.Validation.rejectRequest(
          `+Pod hostname '${hostname}' is not allowed. Denied hostnames: [${deniedHostnames.join(', ')}]+`
        ),
      );
    } else {
      writeOutput(Validation.Validation.acceptRequest());
    }
  } catch (err) {
    console.error('Validation error:', err);
    writeOutput(Validation.Validation.rejectRequest(`+Validation failed: ${err}+`));
  }
}

Lo que hace cada NOTA

  • NOTA 1: Lee la solicitud de validación entrante utilizando readValidationRequest().

  • NOTA 2: Extrae la configuración definida por el usuario de la solicitud de validación (por ejemplo, nombres de host denegados).

  • NOTA 3: Analiza el objeto de Kubernetes (se espera que sea un Pod) del payload de la solicitud.

  • NOTA 4: Extrae el campo de nombre de host de la sección de especificaciones del Pod.

  • NOTA 5: Compara el nombre de host con la lista de denegados y devuelve una respuesta adecuada.

Funciones auxiliares

La directiva utiliza varias funciones auxiliares para procesar la solicitud de validación:

getKubernetesResource

Esta función extrae el recurso de Kubernetes de la solicitud de validación:

/**
 * Safely parses and extracts the Kubernetes resource from the validation request.
 *
 * @param {ValidationRequest} validationRequest - The validation request object.
 * @returns {KubernetesResource | undefined} The parsed Kubernetes resource if available.
 */
function getKubernetesResource(validationRequest: ValidationRequest): KubernetesResource | undefined {
  try {
    let requestObject: string | KubernetesResource | undefined = validationRequest.request?.object;
    if (typeof requestObject === 'string') {
      requestObject = JSON.parse(requestObject) as unknown as KubernetesResource;
    } else if (requestObject === undefined) {
      return undefined;
    }
    return requestObject as KubernetesResource;
  } catch (error) {
    console.error('Error parsing Kubernetes resource:', error);
    return undefined;
  }
}

Esta función maneja el caso en que el objeto de Kubernetes es una cadena JSON o un objeto ya analizado.

getPodHostname

Esta función extrae el nombre de host de un recurso Pod:

/**
 * Extracts the hostname from a Pod resource.
 *
 * @param {Pod} pod - The Pod resource.
 * @returns {string | undefined} The hostname if set, otherwise undefined.
 */
import type { Pod } from 'kubernetes-types/core/v1';
function getPodHostname(pod: Pod): string | undefined {
  return pod.spec?.hostname;
}

Esta función extrae el nombre de host de la especificación del Pod.

Punto de entrada de la directiva

La directiva utiliza una declaración switch para manejar diferentes acciones:

const action = policyAction();
switch (action) {
  case 'validate':
    validate();
    break;
  case 'validate-settings':
    validateSettings();
    break;
  default:
    console.error('Unknown action:', action);
    writeOutput(new Validation.Validation.ValidationResponse(false, 'Unknown policy action'));
}

El Admission Controller complemento de Javy proporciona la policyAction() función que indica si la directiva debe validar un recurso o validar su configuración.