|
Este documento ha sido traducido utilizando tecnología de traducción automática. Si bien nos esforzamos por proporcionar traducciones precisas, no ofrecemos garantías sobre la integridad, precisión o confiabilidad del contenido traducido. En caso de discrepancia, la versión original en inglés prevalecerá y constituirá el texto autorizado. |
|
Esta es documentación inédita para Admission Controller 1.34-dev. |
Validación utilizando consultas JSON
Una sección anterior muestra cómo escribir una
validación
directiva utilizando tipos de Go que describen objetos de Kubernetes.
Hay otra forma de escribir la lógica de validación, extrayendo los datos relevantes del documento JSON utilizando consultas ad-hoc.
Este enfoque "similar a jq" puede ser útil cuando la directiva tiene que mirar profundamente dentro de un objeto de Kubernetes. Es especialmente útil al tratar con objetos internos opcionales.
Este documento reimplementa el código anterior utilizando consultas JSON en lugar de deserializar la carga JSON en tipos de Go.
La validate función
Puedes utilizar la directiva que acabas de crear y cambiar su validate función para no usar los tipos de Go que definen objetos de Kubernetes.
Puedes en su lugar utilizar la gjson biblioteca para extraer datos del objeto JSON crudo.
Primero, necesitas cambiar la sección de requisitos. Así es como debería verse el código:
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"
)
Cambia la validate función para que se parezca a:
validate función
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()
}
La primera parte de la validate función es similar a antes.
Las notas marcan los cambios.
-
Utilizas un
gjsonselector para obtener ellabelmapa proporcionado por el objeto incrustado en la solicitud -
Utilizas un
gjsonhelper para iterar sobre los resultados de la consulta. Si la consulta no tiene resultados, el bucle nunca se lleva a cabo. -
Utilizas la
validateLabelfunción para validar la etiqueta y su valor, como antes. También estás añadiendo las etiquetas encontradas en el Pod a unmapset.Setpreviamente definido. -
Si la validación produce un error, devuelves inmediatamente una respuesta de rechazo de validación.
-
Como antes, iteras sobre el
constrainedLabelspara comprobar que todos están especificados en el Pod. El código ha sido ligeramente modificado para hacer uso delmapset.Setpreviamente poblado.
Probando el código de validación
Las pruebas unitarias y las pruebas de extremo a extremo no necesitan ningún cambio, puedes ejecutarlas 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
Todas las pruebas están funcionando como se esperaba.