https://github.com/metio/kdk
Infrastructure as code approach for Kubernetes
https://github.com/metio/kdk
java jshell k8s kubernetes repl yaml-generator
Last synced: 25 days ago
JSON representation
Infrastructure as code approach for Kubernetes
- Host: GitHub
- URL: https://github.com/metio/kdk
- Owner: metio
- License: cc0-1.0
- Created: 2020-05-16T23:03:29.000Z (about 6 years ago)
- Default Branch: master
- Last Pushed: 2022-12-14T20:45:30.000Z (over 3 years ago)
- Last Synced: 2025-08-10T04:23:41.964Z (11 months ago)
- Topics: java, jshell, k8s, kubernetes, repl, yaml-generator
- Language: Java
- Homepage:
- Size: 339 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Authors: AUTHORS/WAIVER
Awesome Lists containing this project
README
# k8s definition kit (kdk)
`kdk` is an infrastructure as code approach for Kubernetes inspired by [aws-cdk](https://docs.aws.amazon.com/cdk/latest/guide/home.html) and [cdk-clj](https://github.com/StediInc/cdk-clj). Think of it like a programmable [helm](https://helm.sh/) chart.
## Alternatives
- https://cdk8s.io/
- https://jkcfg.github.io/
## Usage
`kdk` requires at least Java 11 installed and supports 4 major use cases:
1. **construct** Kubernetes resources
2. **stack** Kubernetes resources
3. **validate** Kubernetes resources
4. **serialize** Kubernetes resources
### Construct
Use `kdk` to construct various k8s resources like this:
```
var service = Service.builder()
.metadata(...)
.spec(...)
.build();
```
Each supported k8s resource has a corresponding Java class with the same name that expose one or more builder methods. Use those methods to construct your stack.
### Stack
The `Stack` class does not exist in the k8s API and solely exists in `kdk` to wrap multiple resources together in one 'stack'.
```
var stack = Stack.builder()
.addServices(service)
.build();
```
Consider publishing your application stack, so that others can easily integrate your work in their project.
### Validate
In order to validate your construct, use the `Validate` class. It supports an easy to use API which can be customizationed in order to fit to your project. Several built-in validators are available, as well as presets which group these validators together.
```
var errors = Validate.validate(stack);
```
The above call will use the `recommended` preset. Use another one by specifying the validators as a second parameter:
```
var errors = Validate.validate(stack, Validators.all());
```
Besides `recommended`, there are `all`, `deprecated`, and `none` presets. Use `Validators.builder()` to construct your custom set of validation rules. Each validator is a function that transforms `TYPE` to `Stream Stream.of(ValidationError.of("some-error-code", deploymentSpec)))
.build());
```
If you rather want to start from a predefined preset and extend it with additional validators, use this:
```
Validators.from(Validators.recommended())
.withDeploymentSpec(deploymentSpec -> Stream.of(ValidationError.of("some-error-code", deploymentSpec)));
```
#### Validation Errors & Presets
| ID | Resource | Presets | Description | Fix |
|--------------------------------------------|------------|------------------|------------------------------------------|-------------------------------------------------|
| urn:kdk:error:secret:missing-metadata | Secret | all, recommended | Resource is missing the 'metadata' field | Add a 'metadata' field |
| urn:kdk:error:ingress:missing-metadata | Ingress | all, recommended | Resource is missing the 'metadata' field | Add a 'metadata' field |
| urn:kdk:error:service:missing-metadata | Service | all, recommended | Resource is missing the 'metadata' field | Add a 'metadata' field |
| urn:kdk:error:deployment:missing-metadata | Deployment | all, recommended | Resource is missing the 'metadata' field | Add a 'metadata' field |
| urn:kdk:error:job:missing-metadata | Job | all, recommended | Resource is missing the 'metadata' field | Add a 'metadata' field |
| urn:kdk:error:annotation:key-blank | Annotation | all, recommended | The 'key' field is blank | Change the 'key' field to something non-blank |
| urn:kdk:error:annotation:value-blank | Annotation | all, recommended | The 'value' field is blank | Change the 'value' field to something non-blank |
| urn:kdk:error:objectMeta:name-missing | ObjectMeta | all, recommended | The 'name' field is not set | Add a 'name' field |
| urn:kdk:error:objectMeta:namespace-missing | ObjectMeta | all | The 'namespace' field is not set | Add a 'namespace' field |
### Serialize
In order to serialize your construct to YAML, use the `Serialize` class.
```
var yaml = Serialize.asYaml(stack);
```
Use the generated YAML string and write it into a file or just output it to the console.
## Integration
There are several approaches to integrate `kdk` in your project.
### Static-Void-Main-Approach
Java applications can be started with `java `. The specified class has to declare a static method that returns noting (`void`), is called `main`, and accepts an array of strings as its input. The following code shows an example:
```java
package com.example;
import wtf.metio.kdk.construct.config.*;
import wtf.metio.kdk.construct.meta.*;
import wtf.metio.kdk.construct.service.*;
import wtf.metio.kdk.construct.workloads.*;
import wtf.metio.kdk.serialize.*;
import wtf.metio.kdk.stack.*;
import wtf.metio.kdk.validate.*;
public class ExampleApplication {
public static void main(String[] arguments) {
var name = "test";
var host = "example.tld";
var path = "/service";
var port = ServicePort.of(2002);
var label = Label.of("app", name);
var metadata = ObjectMeta.builder()
.name(name)
.namespace("example")
.addLabels(label)
.build();
var service = Service.of(
metadata,
ServiceSpec.of(port, Selector.of(label)));
var ingress = Ingress.of(
metadata,
IngressSpec.builder()
.addRules(IngressRule.of(host, HTTPIngressRuleValue.builder()
.addPaths(HTTPIngressPath.of(IngressBackend.of(name, port), path))
.build()))
.addTls(IngressTLS.of("tls-secret", host))
.build());
var stack = Stack.builder()
.addService(service)
.addIngress(ingress)
.build();
var errors = Validate.validate(stack);
if (errors.isEmpty()) {
var yaml = Serialize.asYaml(stack);
System.out.print(yaml);
}
}
}
```
### JShell-Approach
[JShell](https://docs.oracle.com/javase/9/jshell/introduction-jshell.htm) provides a [REPL](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop) for interactive Java development.
You will need both `kdk` and `snakeyml` (for serialization) on your classpath. You can use the [`jshell` artifact](https://codeberg.org/attachments/a8c30837-4afb-4cde-a5e0-c2bfca914782) which already includes all required files, and a bootstrap file to set up the classpath and load all `kdk` classes. Its [README](./kdk-construct/src/main/jshell/README.md) file explains how to start a new `jshell` session with `kdk`.
## License
To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide.
This software is distributed without any warranty.
You should have received a copy of the CC0 Public Domain Dedication along with this software.
If not, see http://creativecommons.org/publicdomain/zero/1.0/.
## Mirrors
`kdk` is mirrored across several git repositories.
Use any of the following to get a copy of the source.
- https://codeberg.org/metio.wtf/kdk
- https://github.com/metio/kdk (master only)
- https://gitlab.com/metio.wtf/kdk (master only)
- https://bitbucket.org/metio-wtf/kdk (master only)