|
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. |
Validação usando consultas JSON
Uma seção anterior mostra como escrever uma validação política usando tipos Go que descrevem objetos Kubernetes.
Há outra maneira de escrever a lógica de validação, extraindo os dados relevantes do documento JSON usando consultas ad-hoc.
Essa abordagem "semelhante ao jq" pode ser útil quando a política precisa olhar profundamente dentro de um objeto Kubernetes. É especialmente útil ao lidar com objetos internos opcionais.
Este documento reimplementa o código anterior usando consultas JSON em vez de deserializar a carga JSON em tipos Go.
A validate função
Você pode usar a política que acabou de criar e mudar sua validate função
para não usar os tipos Go que definem objetos Kubernetes.
Você pode em vez disso usar a gjson biblioteca para extrair dados do objeto JSON bruto.
Primeiramente, você precisa mudar a seção de requisitos. É assim que o código deve parecer:
import (
"encoding/json"
"fmt"
mapset "github.com/deckarep/golang-set/v2"
kubewarden "github.com/kubewarden/policy-sdk-go"
kubewarden_protocol "github.com/kubewarden/policy-sdk-go/protocol"
"github.com/tidwall/gjson"
)
Mude a validate função para parecer com:
validate função
func validate(payload []byte) ([]byte, error) {
// Create a ValidationRequest instance from the incoming payload
validationRequest := kubewarden_protocol.ValidationRequest{}
err := json.Unmarshal(payload, &validationRequest)
if err != nil {
return kubewarden.RejectRequest(
kubewarden.Message(err.Error()),
kubewarden.Code(400))
}
// Create a Settings instance from the ValidationRequest object
settings, err := NewSettingsFromValidationReq(&validationRequest)
if err != nil {
return kubewarden.RejectRequest(
kubewarden.Message(err.Error()),
kubewarden.Code(400))
}
// Access the **raw** JSON that describes the object
podJSON := validationRequest.Request.Object
// NOTE 1
data := gjson.GetBytes(
podJSON,
"metadata.labels")
var validationErr error
labels := mapset.NewThreadUnsafeSet[string]()
data.ForEach(func(key, value gjson.Result) bool {
// NOTE 2
label := key.String()
labels.Add(label)
// NOTE 3
validationErr = validateLabel(label, value.String(), &settings)
// keep iterating if there are no errors
return validationErr == nil
})
// NOTE 4
if validationErr != nil {
return kubewarden.RejectRequest(
kubewarden.Message(validationErr.Error()),
kubewarden.NoCode)
}
// NOTE 5
for requiredLabel := range settings.ConstrainedLabels {
if !labels.Contains(requiredLabel) {
return kubewarden.RejectRequest(
kubewarden.Message(fmt.Sprintf("Constrained label %s not found inside of Pod", requiredLabel)),
kubewarden.NoCode)
}
}
return kubewarden.AcceptRequest()
}
A primeira parte da validate função é semelhante à anterior.
As notas marcam as mudanças.
-
Você usa um
gjsonseletor para obter olabelmapa fornecido pelo objeto embutido na solicitação -
Você usa um
gjsonauxiliar para iterar sobre os resultados da consulta. Se a consulta não tiver resultados, o loop nunca ocorre. -
Você usa a função
validateLabelpara validar o rótulo e seu valor, como antes. Você também está adicionando os rótulos encontrados no Pod a ummapset.Setpreviamente definido. -
Se a validação produzir um erro, você retorna imediatamente com uma resposta de rejeição de validação.
-
Como antes, você itera sobre o
constrainedLabelspara verificar se todos estão especificados no Pod. O código foi levemente alterado para utilizar omapset.Setpreviamente preenchido.
Testando o código de validação
Os testes unitários e os testes de ponta a ponta não precisam de nenhuma alteração, você pode executá-los como antes:
make test
go test -v
=== RUN TestParseValidSettings
--- PASS: TestParseValidSettings (0.00s)
=== RUN TestParseSettingsWithInvalidRegexp
--- PASS: TestParseSettingsWithInvalidRegexp (0.00s)
=== RUN TestDetectValidSettings
--- PASS: TestDetectValidSettings (0.00s)
=== RUN TestDetectNotValidSettingsDueToBrokenRegexp
--- PASS: TestDetectNotValidSettingsDueToBrokenRegexp (0.00s)
=== RUN TestDetectNotValidSettingsDueToConflictingLabels
--- PASS: TestDetectNotValidSettingsDueToConflictingLabels (0.00s)
=== RUN TestValidateLabel
--- PASS: TestValidateLabel (0.00s)
PASS
ok github.com/kubewarden/go-policy-template 0.002s
make e2e-tests
bats e2e.bats
e2e.bats
✓ accept when no settings are provided
✓ accept because label is satisfying a constraint
✓ accept labels are not on deny list
✓ reject because label is on deny list
✓ reject because label is not satisfying a constraint
✓ reject because constrained label is missing
✓ fail settings validation because of conflicting labels
✓ fail settings validation because of invalid constraint
8 tests, 0 failures
Todos os testes estão funcionando como esperado.