|
本文档采用自动化机器翻译技术翻译。 尽管我们力求提供准确的译文,但不对翻译内容的完整性、准确性或可靠性作出任何保证。 若出现任何内容不一致情况,请以原始 英文 版本为准,且原始英文版本为权威文本。 |
|
这是尚未发布的文档。 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}+`));
}
}
辅助函数
该策略使用多个辅助函数来处理验证请求:
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() 函数,指示策略是否应验证资源或验证其设置。