|
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. |
Escrevendo políticas brutas
Políticas brutas são políticas que podem avaliar documentos JSON arbitrários. Para mais informações sobre políticas brutas, consulte a página de políticas brutas.
Exemplos
Os seguintes exemplos devem parecer familiares se você completou a seção de validação deste tutorial.
|
Lembre-se de marcar a política como
|
Validação
Você quer escrever uma política que aceita uma solicitação no seguinte formato:
{
"request": {
"user": "alice",
"action": "delete",
"resource": "products"
}
}
e valida que:
-
userestá na lista de usuários válidos -
actionestá na lista de ações válidas -
resourceestá na lista de recursos válidos
Comece criando a política usando o modelo de política go.
Certifique-se de que tudo esteja em ordem com um make, make test e make e2e-tests.
Primeiramente, defina os tipos que representam a carga útil da solicitação.
Você precisa declarar um tipo RawValidationRequest personalizado (crie um arquivo request.go), contendo as estruturas RawValidationRequest e Settings, em vez de usar o tipo ValidationRequest fornecido pelo SDK:
// RawValidationRequest represents the request that is sent to the validate function by the Policy Server.
type RawValidationRequest struct {
Request Request `+json:"request"+`
// Raw policies can have settings.
Settings Settings `+json:"settings"+`
}
// Request represents the payload of the request.
type Request struct {
User string `+json:"user"+`
Action string `+json:"action"+`
Resource string `+json:"resource"+`
}
Então você precisa definir o tipo Settings e as funções Valid e validateSettings em settings.go:
A estrutura Settings e as funções Valid e validateSettings em settings.go.
// Settings represents the settings of the policy.
type Settings struct {
ValidUsers []string `+json:"validUsers"+`
ValidActions []string `+json:"validActions"+`
ValidResources []string `+json:"validResources"+`
}
// Valid returns true if the settings are valid.
func (s *Settings) Valid() (bool, error) {
if len(s.ValidUsers) == 0 {
return false, fmt.Errorf("validUsers cannot be empty")
}
if len(s.ValidActions) == 0 {
return false, fmt.Errorf("validActions cannot be empty")
}
if len(s.ValidResources) == 0 {
return false, fmt.Errorf("validResources cannot be empty")
}
return true, nil
}
// validateSettings validates the settings.
func validateSettings(payload []byte) ([]byte, error) {
logger.Info("validating settings")
settings := Settings{}
err := json.Unmarshal(payload, &settings)
if err != nil {
return kubewarden.RejectSettings(kubewarden.Message(fmt.Sprintf("Provided settings are not valid: %v", err)))
}
valid, err := settings.Valid()
if err != nil {
return kubewarden.RejectSettings(kubewarden.Message(fmt.Sprintf("Provided settings are not valid: %v", err)))
}
if valid {
return kubewarden.AcceptSettings()
}
logger.Warn("rejecting settings")
return kubewarden.RejectSettings(kubewarden.Message("Provided settings are not valid"))
}
Finalmente, você substitui a função validate (em validate.go):
A função validate em validate.go.
func validate(payload []byte) ([]byte, error) {
// Unmarshal the payload into a RawValidationRequest instance
validationRequest := RawValidationRequest{}
err := json.Unmarshal(payload, &validationRequest)
if err != nil {
// If the payload is not valid, reject the request
return kubewarden.RejectRequest(
kubewarden.Message(err.Error()),
kubewarden.Code(400))
}
request := validationRequest.Request
settings := validationRequest.Settings
// Validate the payload
if slices.Contains(settings.ValidUsers, request.User) &&
slices.Contains(settings.ValidActions, request.Action) &&
slices.Contains(settings.ValidResources, request.Resource) {
return kubewarden.AcceptRequest()
}
return kubewarden.RejectRequest(
kubewarden.Message("The request cannot be accepted."),
kubewarden.Code(400))
}
Você pode configurar um teste em e2e.bats:
e2e.bats
#!/usr/bin/env bats
@test "accept" {
run kwctl run annotated-policy.wasm -r test_data/request.json -s test_data/settings.json
# this prints the output when one the checks below fails
echo "output = ${output}"
# request allowed
[ "$status" -eq 0 ]
[ $(expr "$output" : '.*allowed.*true') -ne 0 ]
}
Então as saídas de make, make test e make e2e são:
Saídas
make && make test && make e2e-tests
docker run \
--rm \
-e GOFLAGS="-buildvcs=false" \
-v /home/jhk/projects/suse/tmp/fab-goraw:/src \
-w /src tinygo/tinygo:0.30.0 \
tinygo build -o policy.wasm -target=wasi -no-debug .
go test -v
=== RUN TestAcceptValidSettings
--- PASS: TestAcceptValidSettings (0.00s)
=== RUN TestRejectSettingsWithEmptyValidUsers
--- PASS: TestRejectSettingsWithEmptyValidUsers (0.00s)
=== RUN TestRejectSettingsWithEmptyValidActions
--- PASS: TestRejectSettingsWithEmptyValidActions (0.00s)
=== RUN TestRejectSettingsWithEmptyValidResources
--- PASS: TestRejectSettingsWithEmptyValidResources (0.00s)
=== RUN TestValidateRequestAccept
--- PASS: TestValidateRequestAccept (0.00s)
=== RUN TestValidateRequestReject
--- PASS: TestValidateRequestReject (0.00s)
PASS
ok github.com/kubewarden/go-policy-template 0.002s
kwctl annotate -m metadata.yml -u README.md -o annotated-policy.wasm policy.wasm
bats e2e.bats
e2e.bats
✓ accept
1 test, 0 failures
Mutação
Você precisa alterar o exemplo anterior para mutar a solicitação em vez de rejeitá-la.
As configurações devem conter o defaultUser, defaultAction e defaultRequest para usar para mutar a solicitação se o usuário, a ação ou o recurso não forem válidos.
Você precisa atualizar o tipo Settings com os novos campos:
// Settings defines the settings of the policy.
type Settings struct {
ValidUsers []string `+json:"validUsers"+`
ValidActions []string `+json:"validActions"+`
ValidResources []string `+json:"validResources"+`
DefaultUser string `+json:"defaultUser"+`
DefaultAction string `+json:"defaultAction"+`
DefaultResource string `+json:"defaultResource"+`
}
// Valid returns true if the settings are valid.
func (s *Settings) Valid() (bool, error) {
if len(s.ValidUsers) == 0 {
return false, fmt.Errorf("validUsers cannot be empty")
}
if len(s.ValidActions) == 0 {
return false, fmt.Errorf("validActions cannot be empty")
}
if len(s.ValidResources) == 0 {
return false, fmt.Errorf("validResources cannot be empty")
}
if s.DefaultUser == "" {
return false, fmt.Errorf("defaultUser cannot be empty")
}
if s.DefaultAction == "" {
return false, fmt.Errorf("defaultUser cannot be empty")
}
if s.DefaultResource == "" {
return false, fmt.Errorf("defaultResource cannot be empty")
}
return true, nil
}
Além disso, a função validate para introduzir a mutação:
func validate(payload []byte) ([]byte, error) {
// Unmarshal the payload into a RawValidationRequest instance
validationRequest := RawValidationRequest{}
err := json.Unmarshal(payload, &validationRequest)
if err != nil {
// If the payload is not valid, reject the request
return kubewarden.RejectRequest(
kubewarden.Message(err.Error()),
kubewarden.Code(400))
}
request := validationRequest.Request
settings := validationRequest.Settings
logger.Info("validating request")
// Accept the request without mutating it if it is valid
if slices.Contains(settings.ValidUsers, request.User) &&
slices.Contains(settings.ValidActions, request.Action) &&
slices.Contains(settings.ValidResources, request.Resource) {
return kubewarden.AcceptRequest()
}
logger.Info("mutating request")
// Mutate the request if it is not valid
if !slices.Contains(settings.ValidUsers, request.User) {
request.User = settings.DefaultUser
}
if !slices.Contains(settings.ValidActions, request.Action) {
request.Action = settings.DefaultAction
}
if !slices.Contains(settings.ValidResources, request.Resource) {
request.Resource = settings.DefaultResource
}
return kubewarden.MutateRequest(request)
}