-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Resolve Vars at a directory level #1738
Conversation
Thanks for your pull request. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). 📝 Please follow instructions at https://git.k8s.io/community/CLA.md#the-contributor-license-agreement to sign the CLA. It may take a couple minutes for the CLA signature to be fully registered; after that, please reply here with a new comment and we'll verify. Thanks.
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 understand the commands that are listed here. |
Welcome @bearium! |
afe9d2d
to
691dff3
Compare
@Liujingfang1 Could you take a look at this? The current "only at the end" var substitution is very hard to work with. This pull request changes the behaviour to substitute the variable at the build level where its defined and bound (instead of at the end). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like braking kustomize. The value computed by kustomise is wrong. base-myServerPod does not exist anywhere, so kustomize is silently taking the wrong decision. Current behavior of kustomize is much better.
Kustomize isn’t taking any decisions. If you want the current behaviour you simply bind the variables at the top level kubernetes build as it does now “under the covers”. |
Additionally, the current functionality does work with transformer resources that consume variables like secretGenerator. @jbrette As a compromise, we could add an additional attribute level called "subsitituteImmediately" at the variable level, which uses the behaviour in this PR, otherwise default to the current "at the end" value substitution currently used. |
Var now has a flag immediateSubstitution which if set to true, will use the new implementation, else use the old way. |
@jbrette This behaviour is now behind a flag, current is default. |
@Liujingfang1 @monopole Do see a problem with adopting this flag? I feel that providing this optional behaviour change for vars can help with a host of use cases that require substitutions to occur at the level they are declared. |
Thanks for your patience @bkuschel. @Liujingfang1 is OOO and back early December. Perhaps @monopole could review, otherwise I'll make sure she reviews this when she returns. |
@bearium Thank you for being patient with us. I took a look at the change and here is my thought.
|
Is there any update on when this might be merged in? This seems like the best solution to a problem that I've had ever since I started using Kustomize. I'm currently just using @bearium 's branch which works well but I'm having to patch it in to lots of third party tools to replace Kustomize which is cumbersome. |
@Liujingfang1 I love the approach with the replacement transformer and it would be great to retire this PR in favour of that but there is one use case that isn't addressed there that is covered by the VAR implementation; the ability to replace substrings. Here are some examples: This is an ingress resource that needs a URL for auth-url because of an implementation details needs the full namespace qualified domain. Service also have a "prefix" which groups resources in a namespace by application (using the application name as prefix) apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: component
annotations:
nginx.ingress.kubernetes.io/auth-url: http://$(PREFIX)-edge-auth.$(NAMESPACE).svc.cluster.local:8080/v1/auth Sometimes configMaps need non-trivial replacements as well: apiVersion: v1
kind: ConfigMap
metadata:
name: messaging-configs
data:
natsUri: "nats://$(PREFIX)-messaging-nats-client:4222"
natsStreamingClusterId: "$(PREFIX)-messaging-nats-streaming-cluster"
someConfigFIle: |-
bunch:
ofstuff: "$(SOMETHING)"
aURL: "http://$(PREFIX)-some service.$(NAMESPACE).svc.cluster.local:8080/v1" There are also circumstances with CRDs where kubernetes (server side) variable expansion cannot be relied upon, opening up a host of circumstances where compound substitutions needs to occur within one value. |
db268a6
to
31ab9f4
Compare
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: bearium The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
@bkuschel We did consider the use case for replacing sub string when proposing the replacement POC but decided to not support this. Here is the reason. The replacement transformation can be applied more than once. It should have the same effect as being applied only once. Replacing a sub string by some marks like "$()" or by regexp matching doesn't guarantee this. On the other side, users can always format the value for the whole string outside of the k8s resource files. For example in kustomization.yaml file.
|
The drawback of this is that potentially, especially in a microservice architecture, a replacement would need to be created for each field that would have namespace/prefix embedded in it. So changing a namespace or prefix (very typical scenarios) could require non-trivial changes to replacement values across multiple kustomization.yaml files. I'll play back and example we are currently dealing with related to PREFIX to demonstrate the problem with current (similar) mechanisms. Knowing that current VAR substitution happens at the very end, we qualify all resources with To do this we are using the PrefixTransformer with additional nameReferences to cover additional fields not defaulted. In the top level kustomization.yaml file, we use VAR substitution to substitute $(PREFIX) with a var reference to an entry in a ConfigMap. To do this with replacements, we would still need to use the prefix transformer (as we would not be able to do this with replacementTransformer; partial string again). Additionally, we would need to create a replacement for all the other fields that could potentially have PREFIX embedded in them. The problem with PREFIX (and NAMESPACE to a lesser extent) is that it is used everywhere a service needs to communicate with another service using a URL; to modify a configuration with a URL reference to another service, prepended with the prefix. If it were possible to stipulated, by decree, that URLs to other services be specified in a consistent way as environmental variable references to configMap across the board (the simplest scenario), at a minimum we would need a value replacement for each service name for each dependent service unless we break up the URLS into constituent parts, so that the substitution could be done be a fieldref. ex: replacements:
- source:
# value should be the format of http://$(PREFIX)-edge-auth.$(NAMESPACE).svc.cluster.local:8080/v1/auth
value: http://pre-edge-auth.ns.svc.cluster.local:8080/v1/auth
target:
objref:
kind: Ingress
fieldrefs:
- metadata.annotations[nginx.ingress.kubernetes.io/auth-url]
- source:
# This would require a substitution per service name
value: http://myprefix-servicename:1234/
target:
objref:
kind: ConfigMap
fieldrefs:
- data.servicenameUrl
- source:
# This would not, you could get away with one for all
value: myprefix
target:
objref:
kind: ConfigMap
fieldrefs:
- data.servicenUrlPrefix In this case you'd have a minimum of two, reducing this simple scenario futher to 1 would require a re-work the nginx-ingress-controller, which for us is out of the question. as it's third party component and are not interested in maintaining a hacked up version supporting a prefix field. Again, this is the simplest scenario for the PREFIX case. So basically, the consequence of more rigidity around replacement in yaml values, is stricter adherence to a resource schema/model, which seems to somewhat compromise one of the stronger cases for kustomize (last-mild modification). |
Issues go stale after 90d of inactivity. If this issue is safe to close now please do so with Send feedback to sig-testing, kubernetes/test-infra and/or fejta. |
Stale issues rot after 30d of inactivity. If this issue is safe to close now please do so with Send feedback to sig-testing, kubernetes/test-infra and/or fejta. |
Rotten issues close after 30d of inactivity. Send feedback to sig-testing, kubernetes/test-infra and/or fejta. |
@fejta-bot: Closed this PR. In response to this:
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. |
fixes: #506
Adds functionality to resolve vars at a directory level, resolved vars will not propagate up and cause collisions, unresolved vars still propagate upwards/downwards.
Prefixes resolve at the time of var substitution and if referenced var changes at higher level already substituted var will not change.