Я использую Jsonnet для рендеринга объектов Kubernetes. Я хотел бы использовать миксин для применения нескольких подключений томов к развертыванию.
Пример того, что я пробовал (k — каузальная библиотека):
config: {
mountConfig: [
first: {
mountPath: '/path/to/first',
subPath: 'first',
data: {},
},
second: {
mountPath: '/path/to/second',
subPath: 'second',
data: {},
},
],
}
configMap: configMap.new('config')
+ configMap.withData(
{ [config.mountPath]: config.data }
for config in $.mountConfig
),
deployment: deployment.new(
name='dep1',
replicas='2',
containers=[container.new('name', 'image')]
)
+ k.util.configMapVolumeMount($.configMap, config.mountPath, config.subPath)
for mount in $.config.mountConfig
Вышеупомянутое создает одну карту конфигурации с ключом для каждого файла конфигурации, а затем пытается смонтировать карту конфигурации несколько раз для каждого файла конфигурации, определенного в карте конфигурации.
Очевидно, это неполный пример, я не могу понять синтаксис, чтобы сделать + mixin for something in somethings.

Обработка Afaicf subPath для одного configMap более задействована в kausal.libsonnet библиотеках, поскольку вызовы k.util.configMapVolumeMount() в конечном итоге будут добавлять запись configmap в модуль volumes[] много раз.
Я думаю, что приведенный ниже фрагмент решает ваш вопрос, учтите, что есть и другие исправления синтаксиса (помимо механики реализации).
// foo.jsonnet
local k = import 'jsonnet-libs/ksonnet-util/kausal.libsonnet',
deployment = k.apps.v1.deployment,
container = k.core.v1.container,
configMap = k.core.v1.configMap,
volumeMount = k.core.v1.volumeMount;
local config = {
mountConfig: [
{
mountPath: '/path/to/first',
subPath: 'first',
data: 'Data ONE', // NOTE: must be a string
},
{
mountPath: '/path/to/second',
subPath: 'second',
data: 'Data TWO', // NOTE: must be a string
},
],
};
{
configMap:
configMap.new('config')
+ configMap.withData({
[e.subPath]: e.data
for e in config.mountConfig
}),
deployment:
local configVolName = $.configMap.metadata.name + '-volume';
deployment.new(
name='dep1',
replicas=2,
containers=[
container.new('name', 'image')
+ container.withVolumeMountsMixin([
volumeMount.new(configVolName, e.mountPath)
+ volumeMount.withSubPath(e.subPath)
for e in config.mountConfig
]),
]
)
+ deployment.spec.template.spec.withVolumesMixin([
k.core.v1.volume.fromConfigMap(configVolName, $.configMap.metadata.name),
]),
}
## Initialize jsonnet-bundler
$ jb init
## Add jsonnet libs
$ jb install https://github.com/grafana/jsonnet-libs
GET https://github.com/grafana/jsonnet-libs/archive/5f8a166911d56d0402fd52cbbce47cadfee0e466.tar.gz 200
## Add Kube 1.27 underlying libs, see https://tanka.dev/known-issues
$ jb install github.com/jsonnet-libs/k8s-libsonnet/1.27@main
GET https://github.com/jsonnet-libs/k8s-libsonnet/archive/6ecbb7709baf27f44b2e48f3529741ae6754ae6a.tar.gz 200
$ mkdir -p lib; echo "import 'github.com/jsonnet-libs/k8s-libsonnet/1.27/main.libsonnet'" > lib/k.libsonnet
## Spit-out cm+deployment JSON, need to massage it a bit for `kubectl` to slurp it in
$ jsonnet -J lib -J vendor foo.jsonnet |jq -S '.[]' |kubectl apply --dry-run=server -f-
configmap/config created (server dry run)
deployment.apps/dep1 created (server dry run)
Результат jsonnet -J lib -J vendor foo.jsonnet| yq -y .
configMap:
apiVersion: v1
data:
first: Data ONE
second: Data TWO
kind: ConfigMap
metadata:
name: config
deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: dep1
spec:
minReadySeconds: 10
replicas: 2
revisionHistoryLimit: 10
selector:
matchLabels:
name: dep1
template:
metadata:
labels:
name: dep1
spec:
containers:
- image: image
imagePullPolicy: IfNotPresent
name: name
volumeMounts:
- mountPath: /path/to/first
name: config-volume
subPath: first
- mountPath: /path/to/second
name: config-volume
subPath: second
volumes:
- configMap:
name: config
name: config-volume
Бог есть, работает отлично.