この文書は自動機械翻訳技術を使用して翻訳されています。 正確な翻訳を提供するように努めておりますが、翻訳された内容の完全性、正確性、信頼性については一切保証いたしません。 相違がある場合は、元の英語版 英語 が優先され、正式なテキストとなります。

これは未公開の文書です Admission Controller 1.34-dev.

生のポリシー

生のポリシーは、任意のJSONドキュメントを評価できるポリシーです。 生のポリシーに関する詳細情報は、raw policiesページを参照してください。

以下の例は、このチュートリアルの検証ページを完了した場合、見覚えがあるはずです。

ポリシーを`raw`としてマークすることを忘れずに、`policyType`フィールドを`metadata.yml`設定で使用してください。 詳細情報については、メタデータ仕様を参照してください。

検証

次の形式のリクエストを受け入れるポリシーを作成しましょう:

{
  "request": {
    "user": "alice",
    "action": "delete",
    "resource": "products"
  }
}

そして、次のことを検証します:

  • `user`が有効なユーザーのリストに含まれていること

  • `action`が有効なアクションのリストに含まれていること

  • `resource`が有効なリソースのリストに含まれていること

まず、https://github.com/kubewarden/rust-policy-template[Rustポリシーテンプレート]を使用してポリシーの雛形を作成します。

最初に、リクエストのペイロードを表すタイプを定義します。 SDKが提供する`RawValidationRequest`タイプの代わりに、`Request`と`Settings`を含むカスタム`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)
}