kustomize
kustomize copied to clipboard
Patch with value fetched from a file
Is your feature request related to a problem? Please describe.
I meet multiple situations where I need to inject content of a source file (usually a K8S yaml spec files, sometimes files with other formats such as prometheus rule, grafana dashboard) into a K8S resource spec file. To leverage the native IDE tooling ( completion/documentation/syntax validation), I need the format of the source file to be preserved (e.g. a valid CR K8S spec files which matches its open api schema).
Currently, I use strategic patch or json patch to include sub-resources from distinct files, but this requires to modify their structure, and thus prevents usage of the native tooling the subresources files (typically openapi).
Did I miss a kustomize feature to fullfill this goal ?
Describe the solution you'd like
A way to copy content from a file into a k8s resource.
Here is an idea of a json patch fromFile extension to the copy operator
- op: copy
fromFile: ./network.yaml
from: /
path: /spec/resources[0]/base
Describe alternatives you've considered
- Using a KRM plugin, but this isn't supported in my context in FluxCD due to multi-tenancy security issues see https://github.com/fluxcd/kustomize-controller/issues/323
Additional context
I work with crossplane compositions which Composition CR which includes a nested array of arbitrary dynamically loaded CRs resources (eg NodePool, GKECluster, CloudSQLInstance, Release ...) which can not statically be defined in a single openapi schema. I need a way to split the Composition CR into manageable yaml files for each nested resource, while preserving ability within the IDE to leverage their openapi for completion/documentation/syntax validation.
See typical example from https://github.com/crossplane-contrib/provider-helm/blob/176aa6812860e95712ea7aecd541a564bc839b14/examples/in-composition/composition.yaml with such a long yaml
composition.yaml
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: wordpressclusters.example.crossplane.io
spec:
writeConnectionSecretsToNamespace: crossplane-system
compositeTypeRef:
apiVersion: example.crossplane.io/v1alpha1
kind: WordpressCluster
resources:
- base:
apiVersion: compute.gcp.crossplane.io/v1beta1
kind: Network
spec:
forProvider:
autoCreateSubnetworks: false
routingConfig:
routingMode: REGIONAL
- base:
apiVersion: container.gcp.crossplane.io/v1beta1
kind: GKECluster
spec:
forProvider:
addonsConfig:
kubernetesDashboard:
disabled: true
networkPolicyConfig:
disabled: false
databaseEncryption:
state: DECRYPTED
[...]
With a new feature, this could transform into
network.yaml (matching its open api schema):
apiVersion: compute.gcp.crossplane.io/v1beta1
kind: Network
spec:
forProvider:
autoCreateSubnetworks: false
routingConfig:
routingMode: REGIONAL
[...]
composition.yaml (matching its open api schema)
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
name: wordpressclusters.example.crossplane.io
spec:
writeConnectionSecretsToNamespace: crossplane-system
compositeTypeRef:
apiVersion: example.crossplane.io/v1alpha1
kind: WordpressCluster
resources: []
kustomization.yaml:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: crossplane
resources:
- composition.yaml
patchesJson6902:
- target: &composition
version: v1
group: apiextensions.crossplane.io
kind: Composition
name: wordpressclusters.example.crossplane.io
patch: |
- op: add
path: /spec/resources
value:
base: {}
- op: copy
fromFile: ./network.yaml
from: /
path: /spec/resources[0]/base
[....]
@gberche-orange: This issue is currently awaiting triage.
SIG CLI takes a lead on issue triage for this repo, but any Kubernetes member can accept issues by applying the triage/accepted label.
The triage/accepted label can be added by org members by writing /triage accepted in a comment.
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.
I think the configmap and secret generators are the only features that can source data from various specific file formats. Since Kustomize is oriented around structural edits, I don't see us adding a feature that loads arbitrary data into arbitrary resources.
However, the specific use case presented of embedding one k8s resource in another sounds adjacent to something the replacements transformer can do--it works by sourcing values from one resource and inserting them into specified locations in another. The resources in question would need to be in the normal resources field, though the config.kubernetes.io/local-config annotation could be used to strip them from the build output if needed.
The example below does not work, but if we were to support this use case, I think it would look something like it. @natasha41575 as the author of replacements, is this reasonable or out of scope?
replacements:
- source:
kind: Network
version: v1beta1
group: compute.gcp.crossplane.io
fieldPath: "." # the whole object--not supported
targets:
- select:
kind: Composition
group: apiextensions.crossplane.io
version: v1
name: wordpressclusters.example.crossplane.io
fieldPaths:
- "spec.resources.0" # targeting by index--not supported https://github.com/kubernetes-sigs/kustomize/issues/4507
options:
create: true
/triage under-consideration
Thanks @KnVerey, as a workaround, I'm using the carvel ytt YAML template engine which enables flexible inlining of arbitrary files into K8S resources. For example, see https://github.com/crossplane/crossplane/issues/3197#issuecomment-1191479570 with the inline of a json schema into a CRD definition, or https://github.com/crossplane/crossplane/issues/3197#issuecomment-1194624402 where fragments of K8S resource spec files gets inlined.
Note that w.r.t. use of the replacement transformer, in this carvel-based workaround the inlined fragments are not directly submitted as independent resources to the K8S api for the following rationales:
- some may not be expressed as K8S api objects (e.g. grafana dashboards json, or prometheus alerts, SQL statements, shell scripts ...)
- fragments that are expressed as K8S resources may not be syntaxically correct as standalone fragments, typically missing some fields (and hence would be rejected by K8S api validations)
- they may have undesireable side effects (typically fragments are inlined within templates that have broader scope)
Ah, I see. In that case, it sounds like the type of sources and edits you need are out of scope for Kustomize built-ins, so from Kustomize's perspective, a custom transformer would be the way to go: extensions docs.
/triage out-of-scope
The Kubernetes project currently lacks enough contributors to adequately respond to all issues and PRs.
This bot triages issues and PRs according to the following rules:
- After 90d of inactivity,
lifecycle/staleis applied - After 30d of inactivity since
lifecycle/stalewas applied,lifecycle/rottenis applied - After 30d of inactivity since
lifecycle/rottenwas applied, the issue is closed
You can:
- Mark this issue or PR as fresh with
/remove-lifecycle stale - Mark this issue or PR as rotten with
/lifecycle rotten - Close this issue or PR with
/close - Offer to help out with Issue Triage
Please send feedback to sig-contributor-experience at kubernetes/community.
/lifecycle stale
The Kubernetes project currently lacks enough active contributors to adequately respond to all issues and PRs.
This bot triages issues and PRs according to the following rules:
- After 90d of inactivity,
lifecycle/staleis applied - After 30d of inactivity since
lifecycle/stalewas applied,lifecycle/rottenis applied - After 30d of inactivity since
lifecycle/rottenwas applied, the issue is closed
You can:
- Mark this issue or PR as fresh with
/remove-lifecycle rotten - Close this issue or PR with
/close - Offer to help out with Issue Triage
Please send feedback to sig-contributor-experience at kubernetes/community.
/lifecycle rotten