cdk8soperator

package module
v0.1.300 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 31, 2024 License: Apache-2.0 Imports: 7 Imported by: 0

README

cdk8s-operator

Create Kubernetes CRD Operators using CDK8s Constructs

This is a multi-language (jsii) library and a command-line tool that allows you to create Kubernetes operators for CRDs (Custom Resource Definitions) using CDK8s.

Getting Started

Let's create our first CRD served by a CDK8s construct using TypeScript.

Install CDK8s

Make sure your system has the required CDK8s prerequisites.

Install the CDK8s CLI globally through npm:

$ npm i -g cdk8s-cli
Installing...

# Verify installation
$ cdk8s --version
1.0.0-beta.3
Create a new CDK8s app

Now, let's create a new CDK8s typescript app:

mkdir hello-operator && cd hello-operator
git init
cdk8s init typescript-app
Install cdk8s-operator

Next, let's install this module as a dependency of our TypeScript project:

npm install cdk8s-operator
Construct

We will start by creating the construct that implements the abstraction. This is is just a normal CDK8s custom construct:

Let's create a construct called PodCollection which represents a collection of pods:

pod-collection.ts:

import { Pod } from 'cdk8s-plus-17';
import { Construct } from 'constructs';

export interface PodCollectionProps {
  /** Number of pods */
  readonly count: number;
  /** The docker image to deploy */
  readonly image: string;
}

export class PodCollection extends Construct {
  constructor(scope: Construct, id: string, props: PodCollectionProps) {
    super(scope, id);

    for (let i = 0; i < props.count; ++i) {
      new Pod(this, `pod-${i}`, {
        containers: [ { image: props.image } ]
      });
    }
  }
}
Operator App

Now, we will need to replace out main.ts file with an "operator app", which is a special kind of CDK8s app designed to be executed by the cdk8s-server CLI which is included in this module.

The Operator app construct can be used to create "CDK8s Operators" which are CDK8s apps that accept input from a file (or STDIN) with a Kubernetes manifest, instantiates a construct with the spec as its input and emits the resulting manifest to STDOUT.

Replace the contents of main.ts with the following. We initialize an Operator app and then register a provider which handles resources of API version samples.cdk8s.org/v1alpha1 and kind PodCollection.

main.ts:

import { Operator } from 'cdk8s-operator';
import { PodCollection } from './pod-collection';

const app = new Operator();

app.addProvider({
  apiVersion: 'samples.cdk8s.org/v1alpha1',
  kind: 'PodCollection',
  handler: {
    apply: (scope, id, props) => new PodCollection(scope, id, props)
  }
})

app.synth();

A single operator can handle any number of resource kinds. Simply call addProvider() for each apiVersion/kind.

Using Operators

To use this operator, create an input.json file, e.g:

input.json:

{
  "apiVersion": "samples.cdk8s.org/v1alpha1",
  "kind": "PodCollection",
  "metadata": {
    "name": "my-collection"
  },
  "spec": {
    "image": "paulbouwer/hello-kubernetes",
    "count": 5
  }
}

Compile your code:

# delete `main.test.ts` since it has some code that won't compile
$ rm -f main.test.*

# compile
$ npm run compile

And run:

$ node main.js input.json
STDOUT
apiVersion: "v1"
kind: "Pod"
metadata:
  name: "my-collection-pod-0-c8735c52"
spec:
  containers:
    - env: []
      image: "paulbouwer/hello-kubernetes"
      imagePullPolicy: "Always"
      name: "main"
      ports: []
      volumeMounts: []
  volumes: []
---
apiVersion: "v1"
kind: "Pod"
metadata:
  name: "my-collection-pod-1-c89f58d7"
spec:
  containers:
    - env: []
      image: "paulbouwer/hello-kubernetes"
      imagePullPolicy: "Always"
      name: "main"
      ports: []
      volumeMounts: []
  volumes: []
---
apiVersion: "v1"
kind: "Pod"
metadata:
  name: "my-collection-pod-2-c88d4268"
spec:
  containers:
    - env: []
      image: "paulbouwer/hello-kubernetes"
      imagePullPolicy: "Always"
      name: "main"
      ports: []
      volumeMounts: []
  volumes: []
---
apiVersion: "v1"
kind: "Pod"
metadata:
  name: "my-collection-pod-3-c86866b1"
spec:
  containers:
    - env: []
      image: "paulbouwer/hello-kubernetes"
      imagePullPolicy: "Always"
      name: "main"
      ports: []
      volumeMounts: []
  volumes: []
---
apiVersion: "v1"
kind: "Pod"
metadata:
  name: "my-collection-pod-4-c8b74b1d"
spec:
  containers:
    - env: []
      image: "paulbouwer/hello-kubernetes"
      imagePullPolicy: "Always"
      name: "main"
      ports: []
      volumeMounts: []
  volumes: []

cdk8s-server

This library is shipped with a program called cdk8s-server which can be used to host your operator inside an HTTP server. This server can be used as a sidecar container with a generic CRD operator (TBD).

$ PORT=8080 npx cdk8s-server
Listening on 8080
- App command: node main.js
- Request body should include a single k8s resource in JSON format
- Request will be piped through STDIN to "node main.js"
- Response is the STDOUT and expected to be a multi-resource yaml manifest

Now, you can send input.json over HTTP:

$ curl -d @input.json http://localhost:8080
MANIFEST...

License

Apache 2.0

Documentation

Overview

Create Kubernetes CRD Operators using CDK8s Constructs

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewOperator_Override

func NewOperator_Override(o Operator, props *OperatorProps)

func NewServer_Override

func NewServer_Override(s Server, props *ServerProps)

func Operator_IsConstruct

func Operator_IsConstruct(x interface{}) *bool

Checks if `x` is a construct.

Use this method instead of `instanceof` to properly detect `Construct` instances, even when the construct library is symlinked.

Explanation: in JavaScript, multiple copies of the `constructs` library on disk are seen as independent, completely different libraries. As a consequence, the class `Construct` in each copy of the `constructs` library is seen as a different class, and an instance of one class will not test as `instanceof` the other class. `npm install` will not create installations like this, but users may manually symlink construct libraries together or use a monorepo tool: in those cases, multiple copies of the `constructs` library can be accidentally installed, and `instanceof` will behave unpredictably. It is safest to avoid using `instanceof`, and using this type-testing method instead.

Returns: true if `x` is an object created from a class which extends `Construct`.

func Operator_Of added in v0.1.259

func Operator_Of(c constructs.IConstruct) cdk8s.App

Types

type CustomResourceProvider

type CustomResourceProvider struct {
	// API version of the custom resource.
	// Default: "v1".
	//
	ApiVersion *string `field:"required" json:"apiVersion" yaml:"apiVersion"`
	// The construct handler.
	Handler ICustomResourceProviderHandler `field:"required" json:"handler" yaml:"handler"`
	// Kind of this custom resource.
	Kind *string `field:"required" json:"kind" yaml:"kind"`
}

type ICustomResourceProviderHandler

type ICustomResourceProviderHandler interface {
	Apply(scope constructs.Construct, id *string, spec interface{}) constructs.Construct
}

The handler for this custom resource provider.

type Operator

type Operator interface {
	cdk8s.App
	// Returns all the charts in this app, sorted topologically.
	Charts() *[]cdk8s.Chart
	// The tree node.
	Node() constructs.Node
	// The output directory into which manifests will be synthesized.
	Outdir() *string
	// The file extension to use for rendered YAML files.
	// Default: .k8s.yaml
	//
	OutputFileExtension() *string
	// Resolvers used by this app.
	//
	// This includes both custom resolvers
	// passed by the `resolvers` property, as well as built-in resolvers.
	Resolvers() *[]cdk8s.IResolver
	// How to divide the YAML output into files.
	// Default: YamlOutputType.FILE_PER_CHART
	//
	YamlOutputType() cdk8s.YamlOutputType
	// Adds a custom resource provider to this operator.
	AddProvider(provider *CustomResourceProvider)
	// Reads a Kubernetes manifest in JSON format from STDIN or the file specified as the first positional command-line argument.
	//
	// This manifest is expected to
	// include a single Kubernetes resource. Then, we match `apiVersion` and
	// `kind` to one of the registered providers and if we do, we invoke
	// `apply()`, passing it the `spec` of the input manifest and a chart as a
	// scope. The chart is then synthesized and the output manifest is written to
	// STDOUT.
	Synth()
	// Synthesizes the app into a YAML string.
	//
	// Returns: A string with all YAML objects across all charts in this app.
	SynthYaml() *string
	// Returns a string representation of this construct.
	ToString() *string
}

A CDK8s app which allows implementing Kubernetes operators using CDK8s constructs.

func NewOperator

func NewOperator(props *OperatorProps) Operator

type OperatorProps

type OperatorProps struct {
	// A Kubernetes JSON manifest with a single resource that is matched against one of the providers within this operator.
	// Default: - first position command-line argument or "/dev/stdin".
	//
	InputFile *string `field:"optional" json:"inputFile" yaml:"inputFile"`
	// Where to write the synthesized output.
	// Default: "/dev/stdout".
	//
	OutputFile *string `field:"optional" json:"outputFile" yaml:"outputFile"`
}

type Server

type Server interface {
	// Stop server.
	Close()
	// Starts HTTP server.
	Listen(port *float64) *float64
}

func NewServer

func NewServer(props *ServerProps) Server

type ServerProps

type ServerProps struct {
	// The command to execute in order to synthesize the CDK app.
	AppCommand *string `field:"required" json:"appCommand" yaml:"appCommand"`
}

Directories

Path Synopsis
Package jsii contains the functionaility needed for jsii packages to initialize their dependencies and themselves.
Package jsii contains the functionaility needed for jsii packages to initialize their dependencies and themselves.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL