Skip to content

Commit

Permalink
feat: add resourcedistribution generator
Browse files Browse the repository at this point in the history
Signed-off-by: dong <dong4325@126.com>
  • Loading branch information
dong4325 committed Sep 25, 2022
1 parent aedda20 commit f8663b1
Show file tree
Hide file tree
Showing 10 changed files with 2,220 additions and 0 deletions.
20 changes: 20 additions & 0 deletions cmd/resourcedistributiongenerator/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
BINARY="resourcedistributiongenerator"

.PHONY: test fmt vet build clean

default: build

test:
go test -v ./...

fmt:
go fmt ./...

vet:
go vet ./...

build:
go build -v -o ${BINARY}

clean:
@if [ -f ${BINARY} ] ; then rm ${BINARY} ; fi
218 changes: 218 additions & 0 deletions cmd/resourcedistributiongenerator/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
# ResourceDistribution Generator

> To use this plug-in, you need to install Kustomize first. Please refer to the [Kustomize documentation](https://kubectl.docs.kubernetes.io/installation/kustomize/) for installation
When using Kustomize to manage applications, the generator provided with Kustomize can directly read files as data content to create Configmap or Secret, avoiding various format errors that are easy to occur during manual replication. The ResourceDistribution Generator is a third-party plug-in for Kustomize that can be used to create a ResourceDistribution by reading files as data content.

The application reads a Kubernetes object of type ResourceList, as shown below. functionConfig is a Kubernetes object used to pass build parameters to the application. Items is a list of Kubernetes objects, the content is the ResourceDistribution object generated by this application, and finally kustomize will fill this field into the output resource list.

```yaml
apiVersion: config.kubernetes.io/v1
kind: ResourceList
items:
...
functionConfig:
...
```
## Download ResourceDistribution generaotor
[This page](https://github.com/openkruise/kruise-tools/releases) provides the path to download binary files for common versions. Currently `Linux`, `Darwin` (OS X), `Windows` provide `X86_64` and `ARM64 `. If you use some other system or architecture, you must download the [source code](https://github.com/openkruise/kruise-tools/blob/master/cmd/resourcedistributiongenerator) and perform `Go Build` or `make` to build the binary

```bash
go build -o resourcedistributiongenerator main.go
```

## API Description

ResourceDistributionGenerator is the Exec KRM functions plugin of kusomize. It is mainly composed of `resource` and `targets` fields. After the build, it will generate `resource` and `targets` content corresponding to ResourceDistribution. The `name` in `metadata` is used to set the name of the generated resourceDistribution. The annotation `config.kubernetes.io/function` needs to write the path of this plugin in the file system. If a relative path is used, it needs to be relative to A kustomization file that references the configuration file.

```yaml
apiVersion: apps.kruise.io/v1alpha1
kind: ResourceDistributionGenerator
metadata:
name: rdname
annotations:
config.kubernetes.io/function: |
exec:
path: ./plugins/resourcedistributiongenerator
resource:
... ...
targets:
... ...
```

## Resource Field

The contents of the `resource` field are used to generate the distributed resources. The `literals`, `files`, and `envs` fields are used in the same way as in [Configmap or Secret](https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/configmapgenerator/) Generator.

- `resourceKind`: Specify the resource kind to distribute, Secret or ConfigMap;
- `resourceName`: Set the name of the distribution resource, that is, the name of the Secret or ConfigMap;
- `literals`: create data content using key/value pairs in the given literals;
- `files`: create data content with the given file name and content;
- `envs`: create data content using key/value pairs in the file;

A correctly configured resource field is as follows:

```yaml
apiVersion: apps.kruise.io/v1alpha1
kind: ResourceDistributionGenerator
metadata:
... ...
resource:
resourceKind: ConfigMap
resourceName: cmname
files:
- file.properties
literals:
- JAVA_HOME=/opt/java/jdk
targets:
... ...
```

## Targets Field

The usage of the `targets` field is basically the same as that of the `targets` field in ResourceDistribution. Note that the contents of the `includedNamespaces` and `excludedNamespaces` fields are directly the names of the namespaces.

A correctly configured targets field is as follows:

```yaml
apiVersion: apps.kruise.io/v1alpha1
kind: ResourceDistributionGenerator
metadata:
... ...
resource:
... ...
targets:
allNamespaces: true
excludedNamespaces:
- ns-2
includedNamespaces:
- ns-1
namespaceLabelSelector:
matchLabels:
group: "test"
```

## Options and ResourceOptions Field

The `options` and `resourceOptions` fields are used to set annotations or labels for the generated ResourceDistribution and the Resource (ie ConfigMap or Secret) in it, respectively.

A correctly configured `options` and `resourceOptions` fields is as follows:

```yaml
apiVersion: apps.kruise.io/v1alpha1
kind: ResourceDistributionGenerator
metadata:
... ...
resource:
... ...
resourceOptions:
annotations:
dashboard: "1"
labels:
environment: "dev"
targets:
... ...
options:
annotations:
type: "slave"
labels:
version: "stable"
```

## A Complete Use Case

1. Create an empty directory demo. Create a configuration file named rdGenerator.yaml in the demo directory with the following content. Put the downloaded ResourceDistributionGenerator plugin into the `demo/plugins/` path.

```yaml
apiVersion: apps.kruise.io/v1alpha1
kind: ResourceDistributionGenerator
metadata:
name: rdname
annotations:
config.kubernetes.io/function: |
exec:
path: ./plugins/resourcedistributiongenerator
resource:
resourceKind: ConfigMap
resourceName: cmname
files:
- application.properties
literals:
- JAVA_HOME=/opt/java/jdk
resourceOptions:
annotations:
dashboard: "1"
options:
labels:
app.kubernetes.io/name: "app1"
targets:
includedNamespaces:
- ns-1
namespaceLabelSelector:
matchLabels:
group: "test"
```

2. Create the application.properties file in the demo directory with the following contents.

```properties
FOO=Bar
```

3. Create a kustomization file in the demo directory that references the plugin configuration.

```yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
... ...
generators:
- rdGenerator.yaml
```

4. Use the `kustomize build --enable-alpha-plugins --enable-exec demo` command to build your application, the effect is as follows

```yaml
...
apiVersion: apps.kruise.io/v1alpha1
kind: ResourceDistribution
metadata:
labels:
app.kubernetes.io/name: app1
name: rdname
spec:
resource:
apiVersion: v1
data:
JAVA_HOME: /opt/java/jdk
application.properties: |
FOO=Bar
kind: ConfigMap
metadata:
annotations:
dashboard: "1"
name: cmname
targets:
includedNamespaces:
list:
- name: ns-1
namespaceLabelSelector:
matchLabels:
group: test
```

## Use the ResourceDistribution Generator in ArgoCD

To use the Kustomize plug-in in ArgoCD, you need to add build options for Kustomize that allow third-party plug-ins. Find the configMap named argocd-cm and add the following to the `data` field `kustomize.buildOptions : --enable-alpha-plugins --enable-exec` to add build options for third-party plugins to the default version of kustomize. See [ArgoCD](https://argo-cd.readthedocs.io/en/stable/user-guide/kustomize/#kustomize-build-optionsparameters) for more information.

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
....
data:
kustomize.buildOptions: --enable-alpha-plugins --enable-exec
```

91 changes: 91 additions & 0 deletions cmd/resourcedistributiongenerator/generator/alias.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
Copyright 2022 The Kruise Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package generator

const tmpl = `
apiVersion: apps.kruise.io/v1alpha1
kind: ResourceDistribution
spec:
resource:
apiVersion: v1
`

// Field names
const (
kindField = "kind"
nameField = "name"
listField = "list"
allNamespacesField = "allNamespaces"
immutableField = "immutable"
typeField = "type"
matchExpressionsField = "matchExpressions"
keyField = "key"
operatorField = "operator"
valuesField = "values"
)

var metadataLabelsPath = []string{"metadata", "labels"}
var metadataAnnotationsPath = []string{"metadata", "annotations"}
var resourcePath = []string{"spec", "resource"}
var metadataPath = []string{"spec", "resource", "metadata"}
var resourceLabelsPath = []string{"spec", "resource", "metadata", "labels"}
var resourceAnnotationsPath = []string{"spec", "resource", "metadata", "annotations"}
var targetsPath = []string{"spec", "targets"}
var includedNamespacesPath = []string{"spec", "targets", "includedNamespaces"}
var excludedNamespacesPath = []string{"spec", "targets", "excludedNamespaces"}
var NamespaceLabelSelectorPath = []string{"spec", "targets", "namespaceLabelSelector"}
var MatchLabelsPath = []string{"spec", "targets", "namespaceLabelSelector", "matchLabels"}

const TestData = `
apiVersion: config.kubernetes.io/v1
kind: ResourceList
items:
functionConfig:
apiVersion: apps.kruise.io/v1alpha1
kind: ResourceDistributionGenerator
metadata:
name: rdname
resource:
resourceKind: ConfigMap
resourceName: cmname
literals:
- JAVA_HOME=/opt/java/jdk
resourceOptions:
annotations:
dashboard: "1"
immutable: true
labels:
rsla: rs
options:
labels:
app.kubernetes.io/name: "app1"
annotations:
an: rdan
targets:
allNamespaces: true
includedNamespaces:
- ns-1
namespaceLabelSelector:
matchLabels:
group: "test"
matchExpressions:
- key: exc
operator: NotIn
values:
- abc
- e
`
Loading

0 comments on commit f8663b1

Please sign in to comment.