Integrate Kubernetes Models into KCL

The KCL Programming Language
Dev Genius
Published in
5 min readDec 5, 2022

--

What is KCL

KCL (Kusion Configuration Language) is an open-source constraint-based record and functional language. KCL improves the writing of a large number of complex configurations through mature programming language technology and practice, and is committed to building better modularity, scalability and stability around configuration, simpler logic writing, fast automation and good ecological extensionality.

More documents about KCL are at the last blog https://medium.com/p/f03ee820c7a4 and the KCL website https://github.com/KusionStack/KCLVM

From Kubernetes

1. Kubernetes OpenAPI Spec

Starting from Kubernetes 1.4, the alpha support for the OpenAPI specification (known as Swagger 2.0 before it was donated to the OpenAPI Initiative) was introduced, and the API descriptions follow the OpenAPI Spec 2.0. And since Kubernetes 1.5, Kubernetes supports directly extracting models from source code and then generating the OpenAPI spec file to automatically keep the specifications and documents up to date with the operation and models.

In addition, Kubernetes CRD uses [OpenAPI V3.0 validation](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#validation) to describe a custom schema (in addition to the built-in attributes apiVersion, Kind, and metadata), that APIServer uses to validate the CR during the resource creation and update phases.

2. KCL OpenAPI Support

The kcl-openapi tool supports extracting and generating KCL schemas from Kubernetes OpenAPI/CRD. the KCL OpenAPI Spec defines the mapping between the OpenAPI specification and the KCL language features. For a quick start with the tool, see KCL OpenAPI tool

3. Migrate From Kubernetes To KCL

The entirely OpenAPI definition of the Kubernetes built-in model is stored in the Kubernetes OpenAPI-Spec File. Taking this file as input, the KCL OpenAPI tool can generate all model schemas of the corresponding version. In the following sections, we will introduce how to migrate from Kubernetes to KCL with a deployment release scenario as an example. Assume that your project is using [Kubernetes Deployment] (https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) to define Deployment configuration, Migrating to KCL requires only the following steps:

3.1 Write Config Based On The Models

We provide an out-of-the-box kusion_models package for you to quickly start. It contains a well-designed frontend model called Server schema. You can declare their configurations by initializing the Server schema. For the description and usage of the schema and its attributes, please refer to the Server schema documentation.

3.2 Build Your Custom Frontend Models

The existing KCL Models may not meet your specific business requirements, then you can also design your custom frontend model package. In the kusion_kubernetes directory (https://github.com/KusionStack/konfig/tree/main/base/pkg/kusion_kubernetes), there's a copy of the generated Kubernetes 1.22 models and you can design your custom models based on it. And you can also develop your custom scripts to migrate your configuration data as what kube2kcl tool does.

3.2.1 Convert Kubernetes Deployment Into KCL Schema

We already have a copy of generated Kubernetes 1.22 models under the base/pkg/kusion_kubernetes directory in the Konfig repository. You can skip this step and use the existing models, or you can generate other versions of that if needed.

Now let’s generate a v1.23 version of Kubernetes models. From Kubernetes v1.23 OpenAPI Spec, we can find the definition of the apps/v1.Deployment model, and here is a partial excerpt:

{
"definitions": {
"io.k8s.api.apps.v1.Deployment": {
"description": "Deployment enables declarative updates for Pods and ReplicaSets.",
"properties": {
"apiVersion": {
"description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
"type": "string"
},
"kind": {
"description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"type": "string"
},
"metadata": {
"$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta",
"description": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata"
},
"spec": {
"$ref": "#/definitions/io.k8s.api.apps.v1.DeploymentSpec",
"description": "Specification of the desired behavior of the Deployment."
},
"status": {
"$ref": "#/definitions/io.k8s.api.apps.v1.DeploymentStatus",
"description": "Most recently observed status of the Deployment."
}
},
"type": "object",
"x-kubernetes-group-version-kind": [
{
"group": "apps",
"kind": "Deployment",
"version": "v1"
}
]
}
},
"info": {
"title": "Kubernetes",
"version": "unversioned"
},
"paths": {},
"swagger": "2.0"
}

You can save the above spec as deployment.json and run kcl-openapi generate model -f deployment.json, and the KCL Schemas will be generated and output to your current workspace. Other Kubernetes models can also be saved in that spec file and can be generated similarly.

3.2.2 Design Custom Frontend Models

Since the Kubernetes built-in models are atomistic and kind of complex to beginners, we recommend taking the native model of Kubernetes as the backend output model and designing a batch of frontend models which could become a more abstract, friendlier and simpler interface to the user. You can refer to the design pattern in the Server Schema in the Konfig repo.

3.2.3 Migrate The Configuration Data

You can develop your custom scripts to migrate your configuration data automatically. KCL will later provide writing scaffolding and writing guidelines for this script.

4. Migrate From Kubernetes CRD

If you developed CRDs, you can generate the KCL version of the CRD schemas and declare CRs based on that.

  • Generate KCL Schema from CRD
kcl-openapi generate model --crd --skip-validation -f <your_crd.yaml>

5. CRD to KCL Example

  • Command
kcl-openapi generate model --crd -f ${your_CRD.yaml} -t ${the_kcl_files_output_di} --skip-validation
  • test_crontab_CRD.yaml:
# Deprecated in v1.16 in favor of apiextensions.k8s.io/v1
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
# name must match the spec fields below, and be in the form: <plural>.<group>
name: crontabs.stable.example.com
spec:
# group name to use for REST API: /apis/<group>/<version>
group: stable.example.com
# list of versions supported by this CustomResourceDefinition
versions:
- name: v1
# Each version can be enabled/disabled by Served flag.
served: true
# One and only one version must be marked as the storage version.
storage: true
# either Namespaced or Cluster
scope: Namespaced
names:
# plural name to be used in the URL: /apis/<group>/<version>/<plural>
plural: crontabs
# singular name to be used as an alias on the CLI and for display
singular: crontab
# kind is normally the CamelCased singular type. Your resource manifests use this.
kind: CronTab
# shortNames allow shorter string to match your resource on the CLI
shortNames:
- ct
preserveUnknownFields: false
validation:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
cronSpec:
type: string
image:
type: string
replicas:
type: integer
  • Command
kcl-openapi generate model -f test_crontab_CRD.yaml -t ~/ --skip-validation --crd
  • Output `~/models/stable_example_com_v1_cron_tab.k`
"""
This file was generated by the KCL auto-gen tool. DO NOT EDIT.
Editing this file might prove futile when you re-run the KCL auto-gen generate command.
"""
import kusion_kubernetes.apimachinery.apis

schema CronTab:
"""stable example com v1 cron tab
Attributes
----------
__settings__ : {str:str}, default is {"output_type": "STANDALONE"}, optional
existence of this attribute indicates that the model will be treated standalone by KCLVM.
apiVersion : str, default is "stable.example.com/v1", required
APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
kind : str, default is "CronTab", required
Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
metadata : apis.ObjectMeta, default is Undefined, optional
metadata
spec : StableExampleComV1CronTabSpec, default is Undefined, optional
spec
"""

apiVersion: "stable.example.com/v1" = "stable.example.com/v1"
kind: "CronTab" = "CronTab"
metadata?: apis.ObjectMeta
spec?: StableExampleComV1CronTabSpec

schema StableExampleComV1CronTabSpec:
"""stable example com v1 cron tab spec
Attributes
----------
cronSpec : str, default is Undefined, optional
cron spec
image : str, default is Undefined, optional
image
replicas : int, default is Undefined, optional
replicas
"""

cronSpec?: str
image?: str
replicas?: int

Next

For more information, please visit (if U like it, U can star it, thx 😊):

Welcome to join our community for communication:

--

--