-
-
Notifications
You must be signed in to change notification settings - Fork 205
feat: add cuelang input type #1322
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
Merged
+272
−2
Merged
Changes from 11 commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
1edc233
feat: mvp cuelang implementation
lorenzofelletti 2dfdceb
style: fmt
lorenzofelletti 2dbab1c
feat: enhance Cuelang input type with configurable input and output c…
lorenzofelletti 7b0fc6d
feat: update Cuelang input type to allow configurable output filename
e0ce61b
test: add cuelang testing
e4d80c6
docs: init CUE type doc
08847bf
test: fix cuelang test
477b2cc
docs: enhance CUE Lang input type documentation
76679a3
Merge branch 'master' into feat/cuelang
ademariag 18c20ed
ci: add installation step for CUE testing dependencies
2e14939
fix: update testing dependencies installation to include CUE and addi…
e42f28f
fix: update CUE installation URL to use the correct release path
lorenzofelletti File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
# CUE Lang Input Type | ||
|
||
The CUE Lang input type allows you to use [CUE](https://cuelang.org/) to manage, validate, and generate manifests within Kapitan. | ||
|
||
## Configuration | ||
|
||
The CLUE Lang input type supports the following configuration options: | ||
|
||
```yaml | ||
kapitan: | ||
compile: | ||
- output_path: cute | ||
input_type: cuelang | ||
input_fill_path: "input:" # Optional: the CUE path in which to inject the input value (default at root) | ||
# Note: the ':' is not a typo, run `cue help flags` for more information | ||
yield_path: output # Optional: the CUE field path to yield in the output (default is the whole CUE output) | ||
input_paths: | ||
- templates/cue | ||
input: # Optional: the input value | ||
some_input: true | ||
``` | ||
|
||
### Configuration Options | ||
|
||
| Option | Type | Description | | ||
|-----------------|--------|-----------------------------------------------------------------------------| | ||
| `output_path` | string | Path where compiled manifests will be written | | ||
| `input_type` | string | Must be set to `cuelang` | | ||
| `input_fill_path` | string | Optional: CUE path in which to inject the input value (default at root) | | ||
| `yield_path` | string | Optional: CUE field path to yield in the output (default is the whole CUE output) | | ||
| `input_paths` | list | List of paths to CUE module | | ||
| `input` | object | Optional: the input value to be used in the CUE templates | | ||
|
||
## Examples | ||
|
||
### Basic Usage | ||
|
||
> Note: You must have a valid CUE module in the specified `input_path`. | ||
> The module takes a numerator and denominator, and calculates the result. | ||
|
||
`templates/cue/main.cue`: | ||
```cue | ||
package main | ||
|
||
numerator: int | ||
denominator: int & != 0 | ||
|
||
result: numerator / denominator | ||
``` | ||
|
||
The following is a valid configuration for the CUE input type: | ||
```yaml | ||
# inventory/targets/cue-example.yaml | ||
parameters: | ||
kapitan: | ||
compile: | ||
- output_path: cute | ||
input_type: cuelang | ||
input_paths: | ||
- templates/cue | ||
input: | ||
numerator: 10 | ||
denominator: 2 | ||
``` | ||
|
||
The output will be: | ||
```yaml | ||
# cute/main.yaml | ||
numerator: 10 | ||
denominator: 2 | ||
result: 5 | ||
``` | ||
|
||
## Troubleshooting | ||
|
||
If you encounter issues with the CUE Lang input type, you may try compiling the CUE module manually using the `cue export` command and checking for errors. | ||
You can use the `-l` flag to pass the input value directly to the CUE module: | ||
```bash | ||
cue export templates/cue/main.cue -l input.yaml # put numerator and denominator in input.yaml' | ||
``` | ||
|
||
## Related | ||
|
||
- [CUE Lang Documentation](https://cuelang.org/docs/) | ||
- [Kapitan Input Types](../input_types/introduction.md) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import logging | ||
import os | ||
import shutil | ||
import subprocess | ||
import tempfile | ||
|
||
import yaml | ||
|
||
from kapitan.errors import KustomizeTemplateError | ||
from kapitan.inputs.base import InputType | ||
from kapitan.inventory.model.input_types import KapitanInputTypeCuelangConfig | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class Cuelang(InputType): | ||
"""CUE-Lang implementation.""" | ||
|
||
def __init__(self, compile_path: str, search_paths: list, ref_controller, target_name: str, args): | ||
"""Initialize the CUE-Lang implementation. | ||
|
||
Args: | ||
compile_path: Base path for compiled output | ||
search_paths: List of paths to search for input files | ||
ref_controller: Reference controller for handling refs | ||
target_name: Name of the target being compiled | ||
args: Additional arguments passed to the tool | ||
""" | ||
super().__init__(compile_path, search_paths, ref_controller, target_name, args) | ||
self.cue_path = args.cue_path if hasattr(args, "cue_path") else "cue" | ||
|
||
def compile_file(self, config: KapitanInputTypeCuelangConfig, input_path: str, compile_path: str) -> None: | ||
temp_dir = tempfile.mkdtemp() | ||
abs_input_path = os.path.abspath(input_path) | ||
|
||
# Copy the input directory to the temporary directory | ||
input_dir_name = os.path.basename(abs_input_path) | ||
temp_input_dir = os.path.join(temp_dir, input_dir_name) | ||
shutil.copytree(abs_input_path, temp_input_dir) | ||
|
||
# Write the input data to file | ||
input_file_path = os.path.join(temp_input_dir, "input.yaml") | ||
with open(input_file_path, "w") as f: | ||
yaml.dump(config.input, f) | ||
|
||
# Prepare the command to run CUE export | ||
cmd = [ | ||
self.cue_path, | ||
"export", | ||
".", | ||
] | ||
# if specified where to inject the input, add it to the command | ||
if config.input_fill_path: | ||
cmd += ["-l", config.input_fill_path] | ||
cmd += ["input.yaml", "--out", "yaml"] | ||
# if specified where the output is yielded, add it to the command | ||
if config.output_yield_path: | ||
cmd += ["--expression", config.output_yield_path] | ||
|
||
output_filename = config.output_filename if config.output_filename else "output.yaml" | ||
output_file = os.path.join(compile_path, output_filename) | ||
with open(output_file, "w") as f: | ||
result = subprocess.run(cmd, stdout=f, stderr=subprocess.PIPE, text=True, cwd=temp_input_dir) | ||
if result.returncode != 0: | ||
err = f"Failed to run CUE export: {result.stderr}" | ||
raise KustomizeTemplateError(err) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
module: "com.example.module" | ||
language: { | ||
version: "v0.13.0" | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package main | ||
|
||
input: { | ||
numerator: int | ||
denominator: int & !=0 | ||
} | ||
|
||
output: { | ||
result: input.numerator / input.denominator | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
"""Tests for CueLang input type.""" | ||
|
||
import os | ||
import shutil | ||
import tempfile | ||
import unittest | ||
|
||
import yaml | ||
|
||
from kapitan.inputs.cuelang import Cuelang | ||
from kapitan.inventory.model.input_types import KapitanInputTypeCuelangConfig | ||
|
||
|
||
class CuelangInputTest(unittest.TestCase): | ||
"""Test cases for Cuelang input type.""" | ||
|
||
def setUp(self): | ||
"""Set up the test environment.""" | ||
self.compile_path = tempfile.mkdtemp() | ||
self.search_paths = [] | ||
self.ref_controller = None | ||
self.target_name = "test_target" | ||
self.args = type("Args", (), {"cue_path": "cue"})() | ||
self.cuelang = Cuelang( | ||
compile_path=self.compile_path, | ||
search_paths=self.search_paths, | ||
ref_controller=self.ref_controller, | ||
target_name=self.target_name, | ||
args=self.args, | ||
) | ||
|
||
def tearDown(self): | ||
"""Clean up the test environment.""" | ||
shutil.rmtree(self.compile_path, ignore_errors=True) | ||
|
||
def test_compile_file(self): | ||
"""Compile a CUE-Lang template.""" | ||
temp_dir = tempfile.mkdtemp() | ||
|
||
try: | ||
shutil.copytree("tests/test_cue/module1", temp_dir, dirs_exist_ok=True) | ||
|
||
config = KapitanInputTypeCuelangConfig( | ||
input_paths=[temp_dir], | ||
output_path=self.compile_path, | ||
input_fill_path="input:", | ||
input={ | ||
"numerator": 10, | ||
"denominator": 2, | ||
}, | ||
output_yield_path="output", | ||
) | ||
|
||
cue_input = Cuelang( | ||
compile_path=self.compile_path, | ||
search_paths=self.search_paths, | ||
ref_controller=self.ref_controller, | ||
target_name=self.target_name, | ||
args=self.args, | ||
) | ||
|
||
cue_input.compile_file(config, temp_dir, self.compile_path) | ||
|
||
output_file = os.path.join(self.compile_path, "output.yaml") | ||
self.assertTrue(os.path.exists(output_file), "Output file was not created.") | ||
|
||
with open(output_file, "r") as f: | ||
output = yaml.safe_load(f) | ||
self.assertEqual(output, {"result": 5}, "Output does not match expected result.") | ||
finally: | ||
shutil.rmtree(temp_dir) | ||
|
||
|
||
if __name__ == "__main__": | ||
unittest.main() |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.