|
本文档采用自动化机器翻译技术翻译。 尽管我们力求提供准确的译文,但不对翻译内容的完整性、准确性或可靠性作出任何保证。 若出现任何内容不一致情况,请以原始 英文 版本为准,且原始英文版本为权威文本。 |
|
这是尚未发布的文档。 Admission Controller 1.34-dev. |
原始策略
原始策略是可以评估任意 JSON 文档的策略。 有关原始策略的更多信息,请参阅 raw policies 页面。
示例
如果您完成了本教程的 validation 页面,以下示例应该很熟悉。
|
请记得在 |
Validation
让我们编写一个接受以下格式请求的策略:
{
"request": {
"user": "alice",
"action": "delete",
"resource": "products"
}
}
并验证:
-
user在有效用户列表中 -
action在有效操作列表中 -
resource在有效资源列表中
首先使用 rust policy template 来搭建策略。
首先,我们定义表示请求有效负载的类型。
我们将声明一个自定义 RawValidationRequest 类型,该类型包含 Request 和 Settings,而不是使用 SDK 提供的 ValidationRequest 类型:
/// RawValidationRequest represents the request that is sent to the validate function by the Policy Server.
#[derive(Deserialize)]
pub(crate) struct RawValidationRequest {
pub(crate) request: Request,
pub(crate) settings: Settings,
}
#[derive(Serialize, Deserialize)]
/// Request represents the payload of the request.
pub(crate) struct Request {
pub(crate) user: String,
pub(crate) resource: String,
pub(crate) action: String,
}
然后我们需要定义 Settings 类型并实现 Validatable 特性:
/// Settings represents the settings of the policy.
#[derive(Serialize, Deserialize, Default, Debug)]
#[serde(default, rename_all = "camelCase")]
pub(crate) struct Settings {
pub(crate) valid_users: Vec<String>,
pub(crate) valid_actions: Vec<String>,
pub(crate) valid_resources: Vec<String>,
}
impl kubewarden::settings::Validatable for Settings {
fn validate(&self) -> Result<(), String> {
info!(LOG_DRAIN, "starting settings validation");
if self.valid_users.is_empty() {
return Err("validUsers cannot be empty".to_string());
}
if self.valid_actions.is_empty() {
return Err("validActions cannot be empty".to_string());
}
if self.valid_resources.is_empty() {
return Err("validResources cannot be empty".to_string());
}
Ok(())
}
}
最后,我们定义 validate 函数:
fn validate(payload: &[u8]) -> CallResult {
let validation_request: RawValidationRequest =
if let Ok(validation_request) = serde_json::from_slice(payload) {
validation_request
} else {
return kubewarden::reject_request(
Some("cannot unmarshal request".to_string()),
None,
None,
None,
);
};
info!(LOG_DRAIN, "starting validation");
let request = validation_request.request;
let settings = validation_request.settings;
if settings.valid_users.contains(&request.user)
&& settings.valid_actions.contains(&request.action)
&& settings.valid_resources.contains(&request.resource)
{
info!(LOG_DRAIN, "accepting resource");
kubewarden::accept_request()
} else {
kubewarden::reject_request(
Some("this request is not accepted".to_string()),
None,
None,
None,
)
}
}
变更
让我们修改之前的示例,以便变更请求而不是拒绝它。
在这种情况下,设置将包含`defaultUser`、defaultAction`和`defaultRequest,如果用户、操作或资源无效,将用于变更请求。
我们需要用新字段更新`Settings`类型:
/// Settings represents the settings of the policy.
#[derive(Serialize, Deserialize, Default, Debug)]
#[serde(default, rename_all = "camelCase")]
pub(crate) struct Settings {
pub(crate) valid_users: Vec<String>,
pub(crate) valid_actions: Vec<String>,
pub(crate) valid_resources: Vec<String>,
pub(crate) default_user: String,
pub(crate) default_action: String,
pub(crate) default_resource: String,
}
impl kubewarden::settings::Validatable for Settings {
fn validate(&self) -> Result<(), String> {
info!(LOG_DRAIN, "starting settings validation");
if self.valid_users.is_empty() {
return Err("validUsers cannot be empty".to_string());
}
if self.valid_actions.is_empty() {
return Err("validActions cannot be empty".to_string());
}
if self.valid_resources.is_empty() {
return Err("validResources cannot be empty".to_string());
}
if self.default_user.is_empty() {
return Err("defaultUser cannot be empty".to_string());
}
if self.default_action.is_empty() {
return Err("defaultAction cannot be empty".to_string());
}
if self.default_resource.is_empty() {
return Err("defaultResource cannot be empty".to_string());
}
Ok(())
}
}
以及 validate 函数以引入变更:
fn validate(payload: &[u8]) -> CallResult {
let validation_request: RawValidationRequest =
if let Ok(validation_request) = serde_json::from_slice(payload) {
validation_request
} else {
return kubewarden::reject_request(
Some("cannot unmarshal request".to_string()),
None,
None,
None,
);
};
info!(LOG_DRAIN, "starting validation");
let request = validation_request.request;
let settings = validation_request.settings;
if settings.valid_users.contains(&request.user)
&& settings.valid_actions.contains(&request.action)
&& settings.valid_resources.contains(&request.resource)
{
info!(LOG_DRAIN, "accepting request");
return kubewarden::accept_request();
}
info!(LOG_DRAIN, "mutating request");
let mut request = request;
if !settings.valid_users.contains(&request.user) {
request.user = settings.default_user;
}
if !settings.valid_actions.contains(&request.action) {
request.action = settings.default_action;
}
if !settings.valid_resources.contains(&request.resource) {
request.resource = settings.default_resource;
}
let mutated_request = serde_json::to_value(request)?;
kubewarden::mutate_request(mutated_request)
}