Skip to content
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

[Feature] Helmfile KCL Plugin #519

Closed
Peefy opened this issue Apr 19, 2023 · 0 comments
Closed

[Feature] Helmfile KCL Plugin #519

Peefy opened this issue Apr 19, 2023 · 0 comments
Assignees
Labels

Comments

@Peefy
Copy link
Contributor

Peefy commented Apr 19, 2023

Background

KCL, which is specifically used for configuration writing and policy verification in cloud-native and Kubernetes scenarios. However, it is obviously not enough to use only one language for Kubernetes configuration management until we find Helmfile.

One of the core issues to be addressed by KCL is to enhance configuration tools and provide declarative configuration verification and editing capabilities, serving to a certain extent as a glue layer for Configuration as Data (CaC) and Configuration as Data (CaD). Besides, KCL is a Python-like domain language with enhancement schema models and multiple override strategies for transforming configuration data without out-of-band access to the host filesystem and networking.

For example, the following image shows how KCL can be applied to cloud-native configuration and policy scenarios to generate, mutate, and validate Kubernetes manifests.

image

Core Concepts of KCL

The core concepts of KCL are Config, Schema, Lambda, and Rule.

  • Config

image

  • Schema

image

  • Lambda

image

  • Rule

image

In KCL, lambda is designed to be "pure" (for example, it prohibits modifying features such as closure variables), which means that executing the same function multiple times will yield the same results, which naturally conforms to some design specifications of the KRM Function.

In addition, we have completed initial KCL plugin support for KPT, Helm, and Kustomize.

For these tools, KCL has the same KRM KCL user interface.

Design

KRM KCL Function

A KRM KCL function contains as follows

image

where:

  • input items: The input list of KRM resources to operate on.
  • output items: The output list obtained from adding, removing, or modifying items in the input.
  • functionConfig: An optional meta resource containing the arguments to this invocation of the function.
  • results: An optional meta resource emitted by the function for observability and debugging purposes.

KRM KCL Spec follows the KRM Function Spec

Function Config

# kcl-fn-config.yaml
apiVersion: krm.kcl.dev/v1alpha1
kind: KCLRun
metadata:
  name: set-annotation
spec:
  # EDIT THE SOURCE! 
  source: |
     # One line KCL transformer.
     [item | {metadata.annotations: {"managed-by" = "helmfile-kcl"}} for item in option("resource_list").items]

Besides, we can use a ConfigMap to store the KCL source. To use a ConfigMap as the functionConfig, the KCL script source must be specified in the data.source field. Additional parameters can be specified in the data field.

Here's an example:

apiVersion: v1
kind: ConfigMap
metadata:
  name: set-replicas
data:
  replicas: "5"
  source: |
    resources = option("resource_list")
    setReplicas = lambda items, replicas {
       [item | {
          spec.replicas = int(replicas)
       } if item.kind == "Deployment" and item.apiVersion == "apps/v1" else {} for item in items]
    }
    setReplicas(resources.items or [], resources.functionConfig.data.replicas)

In the example above, the script accesses the replicas parameters using option("resource_list").functionConfig.data.replicas.
To use a KCLRun as the functionConfig, the KCL source must be specified in the source field. Additional parameters can be specified in the params field. The params field supports any complex data structure as long as it can be represented in YAML.

apiVersion: krm.kcl.dev/v1alpha1
kind: KCLRun
metadata:
  name: conditionally-add-annotations
params:
  toMatch:
    config.kubernetes.io/local-config: "true"
  toAdd:
    configmanagement.gke.io/managed: disabled
spec:
  source: |
    resource = option("resource_list")
    items = resource.items
    params = resource.functionConfig.params
    toMatch = params.toMatch
    toAdd = params.toAdd
    [item | {
       # If all annotations are matched, patch more annotations
       if all key, value in toMatch {
            item.metadata.annotations[key] == value
       }:
           metadata.annotations: toAdd
    } for item in items]

Helmfile KCL Plugin User Interface

repositories:
- name: prometheus-community
  url: https://prometheus-community.github.io/helm-charts

releases:
- name: prom-norbac-ubuntu
  namespace: prometheus
  chart: prometheus-community/prometheus
  set:
  - name: rbac.create
    value: false
  transformers:
  # Use KRM KCL Plugin to mutate or validate Kubernetes manifests.
  - apiVersion: krm.kcl.dev/v1alpha1
    kind: KCLRun
    metadata:
      annotations:
        config.kubernetes.io/function: |
          container:
            image: docker.io/peefyxpf/kustomize-kcl:v0.1.1
    # EDIT THE SOURCE!
    # This should be your KCL code which preloads the `ResourceList` to `option("resource_list").
    spec:
      # code source
      source: |
        [resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "helmfile-kcl"}} for resource in option("resource_list").items]
      # source: path/to/file
      # source: oci://
      # source: git://

Besides, the source of KCL code can come from files, gits, and oci sources. Usually, users do not need to write too much KCL code. We provide many out-of-the-box models, including label/annotation mutation, sidecar injection, and so on

Helmfile KCL Plugin Implementation

TODO:

Reference

@Peefy Peefy added help wanted Extra attention is needed integration labels Apr 19, 2023
@Peefy Peefy added this to the v0.5.0 Release milestone Apr 26, 2023
@Peefy Peefy self-assigned this Apr 26, 2023
@Peefy Peefy added the long-term label Jul 6, 2023
@Peefy Peefy removed this from the v0.5.0 Release milestone Jul 6, 2023
@Peefy Peefy closed this as completed Nov 15, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant