|
Este documento foi traduzido usando tecnologia de tradução automática de máquina. Sempre trabalhamos para apresentar traduções precisas, mas não oferecemos nenhuma garantia em relação à integridade, precisão ou confiabilidade do conteúdo traduzido. Em caso de qualquer discrepância, a versão original em inglês prevalecerá e constituirá o texto official. |
|
Esta é uma documentação não divulgada para Admission Controller 1.34-dev. |
Criando uma nova política de mutação
Políticas de mutação são semelhantes às de validação, mas também têm a capacidade de mutar um objeto recebido.
Eles podem:
-
Rejeitar uma solicitação
-
Aceitar uma solicitação sem alterar o objeto recebido
-
Mutar o objeto recebido conforme necessário e aceitar a solicitação
Escrever uma política de mutação SUSE Security Admission Controller é descomplicado. Você usará a política de validação criada nas seções anteriores e, com algumas mudanças, transformá-la em uma política de mutação.
Sua política usa a mesma lógica de validação definida anteriormente, mas também adiciona uma anotação a todos os Pods que têm um nome válido.
Tentando criar um Pod assim:
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:latest
Leva à criação deste Pod:
apiVersion: v1
kind: Pod
metadata:
name: nginx
annotations:
kubewarden.policy.demo/inspected: true
spec:
containers:
- name: nginx
image: nginx:latest
Escreva o código de mutação
O código de mutação está na função validate.
Você deve alterar esta função para aprovar a solicitação usando mutate_request em vez de accept_request.
É assim que a função validate em lib.rs deve ficar:
fn validate(payload: &[u8]) -> CallResult {
let validation_request: ValidationRequest<Settings> = ValidationRequest::new(payload)?;
info!(LOG_DRAIN, "starting validation");
if validation_request.request.kind.kind != apicore::Pod::KIND {
warn!(LOG_DRAIN, "Policy validates Pods only. Accepting resource"; "kind" => &validation_request.request.kind.kind);
return kubewarden::accept_request();
}
match serde_json::from_value::<apicore::Pod>(validation_request.request.object) {
// NOTE 1
Ok(mut pod) => {
let pod_name = pod.metadata.name.clone().unwrap_or_default();
if validation_request
.settings
.invalid_names
.contains(&pod_name)
{
kubewarden::reject_request(
Some(format!("pod name {:?} is not accepted", pod_name)),
None,
None,
None,
)
} else {
// NOTE 2
let mut new_annotations = pod.metadata.annotations.clone().unwrap_or_default();
new_annotations.insert(
String::from("kubewarden.policy.demo/inspected"),
String::from("true"),
);
pod.metadata.annotations = Some(new_annotations);
// NOTE 3
let mutated_object = serde_json::to_value(pod)?;
kubewarden::mutate_request(mutated_object)
}
}
Err(_) => {
// We were forwarded a request we cannot unmarshal or
// understand, just accept it
kubewarden::accept_request()
}
}
}
Comparado ao código anterior, você fez três alterações:
-
Definimos o objeto
podcomo mutável, veja a palavra-chavemut. Isso é necessário porque iremos estender seu atributometadata.annotations. -
Este é o código que pega o
annotationsexistente, adiciona o novo e, finalmente, coloca o objetoannotationsatualizado de volta na instância originalpod. -
Serialize o objeto
podem umserde_json::Valuegenérico e, em seguida, retorne uma resposta de mutação.
Após fazer essas alterações, é hora de executar os testes unitários novamente:
$ cargo test
Compiling demo-a v0.1.0 (/home/jhk/projects/suse/tmp/demo)
Finished test [unoptimized + debuginfo] target(s) in 0.95s
Running unittests src/lib.rs (target/debug/deps/demo_a-634b88b0dcb6e707)
running 5 tests
test settings::tests::reject_settings_without_a_list_of_invalid_names ... ok
test settings::tests::accept_settings_with_a_list_of_invalid_names ... ok
test tests::accept_request_with_non_pod_resource ... ok
test tests::reject_pod_with_invalid_name ... ok
test tests::accept_pod_with_valid_name ... FAILED
failures:
---- tests::accept_pod_with_valid_name stdout ----
{"column":5,"file":"src/lib.rs","level":"info","line":34,"message":"starting validation","policy":"sample-policy"}
thread 'tests::accept_pod_with_valid_name' panicked at src/lib.rs:98:9:
Something mutated with test case: Pod creation with valid name
note: run with `+RUST_BACKTRACE=1+` environment variable to display a backtrace
failures:
tests::accept_pod_with_valid_name
test result: FAILED. 4 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Como você pode ver, o accept_pod_with_valid_name falha porque a resposta contém um objeto mutado.
Parece que nosso código está funcionando.
Atualize os testes unitários
Você pode atualizar o accept_pod_with_valid_name em lib.rs para ficar assim:
#[test]
fn accept_pod_with_valid_name() -> Result<(), ()> {
let mut invalid_names = HashSet::new();
invalid_names.insert(String::from("bad_name1"));
let settings = Settings { invalid_names };
let request_file = "test_data/pod_creation.json";
let tc = Testcase {
name: String::from("Pod creation with valid name"),
fixture_file: String::from(request_file),
expected_validation_result: true,
settings,
};
let res = tc.eval(validate).unwrap();
// NOTE 1
assert!(
res.mutated_object.is_some(),
"Expected accepted object to be mutated",
);
// NOTE 2
let final_pod =
serde_json::from_value::<apicore::Pod>(res.mutated_object.unwrap()).unwrap();
let final_annotations = final_pod.metadata.annotations.unwrap();
assert_eq!(
final_annotations.get_key_value("kubewarden.policy.demo/inspected"),
Some((
&String::from("kubewarden.policy.demo/inspected"),
&String::from("true")
)),
);
Ok(())
}
Comparado ao primeiro teste, há duas mudanças:
-
Altere a declaração
assert!para que a solicitação ainda seja aceita, mas também inclua um objeto mutado. -
Criou uma instância
Podcomeçando a partir do objeto mutado que faz parte da resposta. Afirme que o objeto Pod mutado tem ometadata.annotationscorreto.
Execute os testes novamente, desta vez todos devem passar:
$ cargo test
Compiling demo-a v0.1.0 (/home/jhk/projects/suse/tmp/demo)
Finished test [unoptimized + debuginfo] target(s) in 1.25s
Running unittests src/lib.rs (target/debug/deps/demo_a-634b88b0dcb6e707)
running 5 tests
test settings::tests::accept_settings_with_a_list_of_invalid_names ... ok
test settings::tests::reject_settings_without_a_list_of_invalid_names ... ok
test tests::accept_request_with_non_pod_resource ... ok
test tests::reject_pod_with_invalid_name ... ok
test tests::accept_pod_with_valid_name ... ok
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Como você pode ver, a criação de uma política de mutação é simples.