Есть ли в клиентской библиотеке Kubernetes функция для проверки файлов json/yaml?
Я хотел бы знать, содержит ли библиотека client-go для Kubernetes функцию, которая проверяет наличие файла json / yaml. В идеале, он будет отлавливать ошибки, такие как имена, не соответствующие DNS-1123, или указанные неверные поля. Также было бы идеально, если бы был возвращен список ошибок, а не функция, возвращающаяся после первой обнаруженной ошибки.
Одна мысль, которую я пытался сделать, это выполнить exec для вызова kubectl --validate --dry-run
но это не полностью проверяет манифест (то есть, его можно пропустить, но потерпеть неудачу, когда вы на самом деле примените файл). Это также останавливается при первой ошибке. Плюс, это быстро обойдется, если у вас есть список манифестов, чтобы пройти.
Другой вариант, на который я посмотрел, был здесь Kubernetes GitHub Issue 193, но это не совсем подходящая функция и не выполняет те проверки, которые я ищу.
2 ответа
Клиентская библиотека для Kubernetes не содержит функций проверки для файлов конфигурации YAML/JSON.
Но взгляните на это, вы можете использовать его для проверки на стороне клиента, а также использовать его код в качестве примера реализации проверки.
Ты можешь взятьk8s.io/kubernetes/pkg/apis/apps/validation
иk8s.io/kubernetes/pkg/apis/core/validation
используя этот скрипт:
#!/bin/sh
set -euo pipefail
VERSION=${1#"v"}
if [ -z "$VERSION" ]; then
echo "Must specify version!"
exit 1
fi
MODS=($(
curl -sS https://raw.githubusercontent.com/kubernetes/kubernetes/v${VERSION}/go.mod |
sed -n 's|.*k8s.io/\(.*\) => ./staging/src/k8s.io/.*|k8s.io/\1|p'
))
for MOD in "${MODS[@]}"; do
V=$(
go mod download -json "${MOD}@kubernetes-${VERSION}" |
sed -n 's|.*"Version": "\(.*\)".*|\1|p'
)
go mod edit "-replace=${MOD}=${MOD}@${V}"
done
go get "k8s.io/kubernetes@v${VERSION}"
Затем вы можете написать такой тест для проверки манифеста с помощьюService
иDeployment
:
import (
"github.com/stretchr/testify/assert"
appsV1 "k8s.io/api/apps/v1"
coreV1 "k8s.io/api/core/v1"
"k8s.io/client-go/kubernetes/scheme"
kubernetesApps "k8s.io/kubernetes/pkg/apis/apps"
kubernetesAppsV1 "k8s.io/kubernetes/pkg/apis/apps/v1"
kubernetesAppsValidation "k8s.io/kubernetes/pkg/apis/apps/validation"
kubernetesCore "k8s.io/kubernetes/pkg/apis/core"
kubernetesCoreV1 "k8s.io/kubernetes/pkg/apis/core/v1"
kubernetesCoreValidation "k8s.io/kubernetes/pkg/apis/core/validation"
"strings"
"testing"
"text/template"
)
const RedisTemplate = `
---
apiVersion: v1
kind: Service
metadata:
name: redis
spec:
type: ClusterIP
internalTrafficPolicy: Cluster
sessionAffinity: None
ports:
- name: redis-port
protocol: TCP
port: 6379
targetPort: 6379
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
....
`
func Test_RedisManifest(t *testing.T) {
for _, m := range strings.Split(RedisTemplate, "---") {
if len(strings.Trim(m, "\n")) == 0 {
continue
}
obj, _, err := scheme.Codecs.UniversalDeserializer().Decode([]byte(m), nil, nil)
assert.NoError(t, err)
assert.NotEmptyf(t, obj.GetObjectKind().GroupVersionKind().Kind, "parsed k8s object kind is empty")
if service, ok := obj.(*coreV1.Service); ok {
kubernetesService := &kubernetesCore.Service{}
conversionErr := kubernetesCoreV1.Convert_v1_Service_To_core_Service(service, kubernetesService, nil)
assert.NoError(t, conversionErr)
kubernetesService.ObjectMeta.Namespace = "default"
validationErrs := kubernetesCoreValidation.ValidateService(kubernetesService)
assert.Empty(t, validationErrs)
}
if deployment, ok := obj.(*appsV1.Deployment); ok {
kubernetesDeployment := &kubernetesApps.Deployment{}
conversionErr := kubernetesAppsV1.Convert_v1_Deployment_To_apps_Deployment(deployment, kubernetesDeployment, nil)
assert.NoError(t, conversionErr)
kubernetesDeployment.ObjectMeta.Namespace = "default"
validationErrs := kubernetesAppsValidation.ValidateDeployment(kubernetesDeployment, kubernetesCoreValidation.PodValidationOptions{})
assert.Empty(t, validationErrs)
}
}
}
В этом подходе я вижу следующие недостатки:
- Прямой импорт не рекомендуется командой K8s.
- Прямой импорт
k8s.io/kubernetes
может создать проблемы в будущем. - Валдационные функции
ValidateService
иValidateDeployment
ожидают, что необязательные поля, такие какnamespace
,internalTrafficPolicy
,sessionAffinity
и многие другие должны иметь значения. Возможно, есть какие-то другие функции, которые могут заполнять необязательные поля значениями по умолчанию, но на данный момент я их не нашел.