本文档采用自动化机器翻译技术翻译。 尽管我们力求提供准确的译文,但不对翻译内容的完整性、准确性或可靠性作出任何保证。 若出现任何内容不一致情况,请以原始 英文 版本为准,且原始英文版本为权威文本。

这是尚未发布的文档。 Admission Controller 1.36-dev.

编写验证逻辑

重要:不要将日志信息写入 STDOUT。

写入 STDOUT 会违反策略。相反,请使用 STDERR 进行日志记录或使用 SUSE Security Admission Controller SDK 提供的日志记录功能。策略输出到 STDOUT 只能包含验证响应。

验证逻辑应放在 src/index.ts 文件中。

您的验证逻辑需要:

  • 从传入的验证请求中获取相关信息。

  • 根据输入和策略设置返回响应。

传入的请求包含一个 JSON 对象,其中包含要验证的 Kubernetes 资源。 您可以通过 Admission Controller SDK 的辅助函数访问此 JSON 对象数据。

validate 函数

模板提供的策略在 src/index.ts 中已经有一个 validate 函数。 您可以在此处使用它,并添加逻辑以拒绝主机名被拒绝的 Pods。

完成后,函数应如下所示:

/**
 * 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}+`));
  }
}

每个注意事项的作用

  • 注意事项 1:使用 readValidationRequest() 读取传入的验证请求。

  • 注意事项 2:从验证请求中提取用户定义的设置(例如,被拒绝的主机名)。

  • 注意事项 3:从请求有效负载中解析 Kubernetes 对象(预期为 Pod)。

  • 注意事项 4:从 Pod 的规格部分提取主机名字段。

  • 注意事项 5:将主机名与被拒绝列表进行比较,并返回适当的响应。

辅助函数

该策略使用多个辅助函数来处理验证请求:

getKubernetesResource

此函数从验证请求中提取 Kubernetes 资源:

/**
 * 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;
  }
}

此函数处理 Kubernetes 对象为 JSON 字符串或已解析对象的情况。

getPodHostname

此函数从 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;
}

此函数从 Pod 的规格中提取主机名。

策略入口点

该策略使用 switch 语句来处理不同的操作:

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'));
}

Admission Controller Javy 插件提供 policyAction() 函数,指示策略是否应验证资源或验证其设置。