Is it possible to load data from filepaths within KCL? #804
Replies: 7 comments 7 replies
-
Make sense. I guess what you need is to write the configuration in blocks and merge the same fields? This is my personal solution: schema Selector:
path: str
selector: str
schema Selectors:
selectors: [Selector]
type SelectorKind = Selector | Selectors
schema Domains:
[...str]: SelectorKind
domain: Domains {
"example.com": {selectors += [{
path = "/config/dkim/keys/example.com/mail-ec/private.pem"
selector = "mail-ec"
}]}
}
domain: Domains {
"example.com": {selectors += [{
path = "/config/dkim/keys/example.com/mail-rsa/private.pem"
selector = "mail-rsa"
}]}
}
domain: Domains {
"example.org": {selectors += [{
path = "/config/dkim/keys/example.org/mail-rsa/private.pem"
selector = "mail-rsa"
}]}
} Of course, you can split the three domains into three files. Besides, we are considering supporting reading data from KCL files, but the initial reason for not supporting IO capability was due to security concerns. Issue is here: #313 |
Beta Was this translation helpful? Give feedback.
-
Ping @zong-zhe, we can complete the document on the differences between the |
Beta Was this translation helpful? Give feedback.
-
@polarathene May I ask what is your KCL version? I did not reproduce this issue in kcl v0.7.0-alpha.1 |
Beta Was this translation helpful? Give feedback.
-
The latest kcl docker image is |
Beta Was this translation helpful? Give feedback.
-
Hi @polarathene 😊 Appreciate the questions you've raised, as they are instrumental in our improvement. Here are some more detailed information, hope it can help you.
Firstly, the issue you pointed out is a mistake in our documentation https://kcl-lang.io/docs/reference/lang/tour#arguments-with-setting-files, which we will correct. The correct usage is :
And the blank output is the expected output. Let me provide more detailed information. The main reason you received a blank output from this command is because the behavior of this command is to
You can use many If merging them, it could cause these arguments to interact with each other, leading to many unpredictable results. Therefore, we have adopted the approach of That is, if you have manually entered a argument, and then later input the same argument in If you haven't entered a argument, then this argument is empty. If you then write this argument in Taking the command you provided above as an example.
the *k file path is also one of kcl's input arguments. You have manually entered the path And you have added the following path in kcl.yaml.
Because you have manually entered the path, the *.k file path argument is not empty, so the content in
I believe you have found the correct way to use them through your intelligence and thoughtful thinking. 👍
|
Beta Was this translation helpful? Give feedback.
-
@polarathene Additionally, this is a very constructive and thoughtful suggestion. 👍 We have decided to accept this requirement, and it will be supported. 😊 I've created an issue to track this feature #835. Additionally, the implementation for this feature is not difficult. If you're interested in KCL, we warmly welcome you to participate in the development of KCL. 😃 |
Beta Was this translation helpful? Give feedback.
-
@polarathene And sorry ❤️ , we did not notice the PR was locked. It gets locked automatically upon close.
|
Beta Was this translation helpful? Give feedback.
-
This may be a documentation issue. I'd like to source data from a variety files and merge that data into a dict.
I've seen:
.k
files.Below I share:
yq
all in the CLI + YAML data.From what I understand KCL is focused on config generation (JSON / YAML output), but it seems a bit limited with support to import data sources. Perhaps this is not a suitable use for KCL and the concern with loading dynamic data from files should be handled prior to using KCL?
I also noted some examples that implied ENV variables, but this was just naming an attribute with
env
/_env
and usingoption()
to read a key from-D
or-Y
inputs. It'd seem like a useful feature to have access to ENV, but this can be worked around like usingyq
to generate YAML that can supply it to-Y
option.Recently I was looking into generating some config for Rspamd
dkim_signing.conf
which has adomains
field/key, that can represent data as:or (A domain has
selectors
array property instead, with elements of thepath
+selector
map/object):UCL can be represented as JSON
UCL can alternatively be represented in JSON, which is useful since there doesn't appear to be support for generating UCL configs from code/schemas.
Thus I could generate JSON like this:
YAML snippets to unified JSON config via
yq
To accomplish that, when generating the DKIM keypair, I could add a
rspamd.yaml
snippet at the same location:Results in:
With these YAML files, I can then collect and process them into a single YAML document with
yq
:That produces this YAML (with the equivalent JSON output as shown earlier):
KCL
I was curious to try KCL, so I tried to adapt this.
.
is not valid in KCL identifiers. That can be post-processed later, so I just replaced.
with_
.kcl
command below.I thought I could pass a list of
.k
files and they'd merge, but it seems KCL is trying to be helpful with the module system due to different locations?So my workaround was to use
cat
with file redirection (this combines all the files into a single.k
input file passed tokcl
):The
start.k
andend.k
were part of another workaround.cat
trickery, the immutability prevented my original attempt of merging the commonexample_com
key as they were seen as conflicting IIRC._domain = {}
(start.k
) and using_domain |=
with my actual inputs to append to it mutably, withdomain = _domain
(end.k
) to finalize an output.A better approach?
The DKIM domain snippets aren't too useful in KCL it'd seem. Perhaps a better approach would be to have KCL define the
domains
object (dict), and some way to bring in that data?Looks like I'd need to generate the YAML document anyway to provide as input options to
kcl
? (like described here)I didn't see any way for the
.k
files to import dynamic data..k
files CLI example doesn't work as the file locations on disk seems to prevent the ability to collect/merge multiple inputs into a single.k
file (unless all files are siblings on disk)..k
schema / dict?option()
function seems to be the only viable way?Using
option()
approach, I could have a.k
file process the input, but without being able to load that data in, it kind of needs to already be in a prepared format 🤷♂️UPDATE: I managed to get this alternative approach working:
Additional KCL to handle both Selector kinds (assuming all input is of schema
Selectors
):I found that rather frustrating to get working, jumping through the reference docs a fair bit. I'm aware that KCL was originally Python based, which would explain why this type of data manipulation reminds me of Python 😭 (I do not find it a good UX personally, I'm biased more towards Rust)
Only missing functionality now would be to load the YAML data from a list of filepaths, and handling the merging. Interestingly, the dict keys could use
.
this way, probably because I'm not ever interacting with those directly in KCL? (or a feature as a string key, althoughI'm not sure how I'm meant to use that within KCLEDIT: via bracket notation)Input data via
options.yaml
:Applying it:
Feedback
You'll notice I used
|=
, I don't think the docs actually have any mention of this operator. Only some examples like|
operator for merging/union.This was a little confusing at first, I needed the
:
operator (also considered for union?), which looked useful due to thelabels
example. That handled merging the domain fields likeexample_com
.Then finally the
+=
for concatenating theselectors
array. Interestingly this works even withselectors
being defined for the first time, while|=
did not and required_domain = {}
to be declared first.Might be worth documenting
|=
? And better distinction between|
and:
operators 🤷♂️ I think I used them correctly, but looking over the docs I'm not quite sure how to explain their differences, they seem to serve a similar purpose for merging a value into an existing one?Beta Was this translation helpful? Give feedback.
All reactions