-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add resourcedistribution generator
Signed-off-by: dong <dong4325@126.com>
- Loading branch information
Showing
10 changed files
with
2,220 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
``` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
` |
Oops, something went wrong.