mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-14 10:30:59 +00:00
Allow exec and function transformers to generate resources
This commit is contained in:
@@ -15,6 +15,7 @@ import (
|
|||||||
"sigs.k8s.io/kustomize/api/konfig"
|
"sigs.k8s.io/kustomize/api/konfig"
|
||||||
"sigs.k8s.io/kustomize/api/resid"
|
"sigs.k8s.io/kustomize/api/resid"
|
||||||
"sigs.k8s.io/kustomize/api/resmap"
|
"sigs.k8s.io/kustomize/api/resmap"
|
||||||
|
"sigs.k8s.io/kustomize/api/resource"
|
||||||
"sigs.k8s.io/kustomize/api/types"
|
"sigs.k8s.io/kustomize/api/types"
|
||||||
"sigs.k8s.io/yaml"
|
"sigs.k8s.io/yaml"
|
||||||
)
|
)
|
||||||
@@ -147,34 +148,46 @@ func GetResMapWithIDAnnotation(rm resmap.ResMap) (resmap.ResMap, error) {
|
|||||||
// UpdateResMapValues updates the Resource value in the given ResMap
|
// UpdateResMapValues updates the Resource value in the given ResMap
|
||||||
// with the emitted Resource values in output.
|
// with the emitted Resource values in output.
|
||||||
func UpdateResMapValues(pluginName string, h *resmap.PluginHelpers, output []byte, rm resmap.ResMap) error {
|
func UpdateResMapValues(pluginName string, h *resmap.PluginHelpers, output []byte, rm resmap.ResMap) error {
|
||||||
outputRM, err := h.ResmapFactory().NewResMapFromBytes(output)
|
resFactory := h.ResmapFactory().RF()
|
||||||
|
resources, err := resFactory.SliceFromBytes(output)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, r := range outputRM.Resources() {
|
for _, r := range resources {
|
||||||
// for each emitted Resource, find the matching Resource in the original ResMap
|
// for each emitted Resource, find the matching Resource in the original ResMap
|
||||||
// using its id
|
// using its id
|
||||||
annotations := r.GetAnnotations()
|
annotations := r.GetAnnotations()
|
||||||
idString, ok := annotations[idAnnotation]
|
idString, ok := annotations[idAnnotation]
|
||||||
|
// Transformer-generated resource--add to resMap
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("the transformer %s should not remove annotation %s",
|
if err := rm.Append(r); err != nil {
|
||||||
pluginName, idAnnotation)
|
return err
|
||||||
|
}
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
id := resid.ResId{}
|
id := resid.ResId{}
|
||||||
err := yaml.Unmarshal([]byte(idString), &id)
|
err = yaml.Unmarshal([]byte(idString), &id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Outdated ID is likely a duplicated resource--add to resMap
|
||||||
|
if !id.Equals(r.CurId()) {
|
||||||
|
removeIDAnnotation(r)
|
||||||
|
if err := rm.Append(r); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Existing resource--update in resMap
|
||||||
|
|
||||||
res, err := rm.GetByCurrentId(id)
|
res, err := rm.GetByCurrentId(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to find unique match to %s", id.String())
|
return fmt.Errorf("unable to find unique match to %s", id.String())
|
||||||
}
|
}
|
||||||
// remove the annotation set by Kustomize to track the resource
|
removeIDAnnotation(r)
|
||||||
delete(annotations, idAnnotation)
|
|
||||||
if len(annotations) == 0 {
|
|
||||||
annotations = nil
|
|
||||||
}
|
|
||||||
r.SetAnnotations(annotations)
|
|
||||||
|
|
||||||
// update the resource value with the transformed object
|
// update the resource value with the transformed object
|
||||||
res.ResetPrimaryData(r)
|
res.ResetPrimaryData(r)
|
||||||
@@ -182,6 +195,16 @@ func UpdateResMapValues(pluginName string, h *resmap.PluginHelpers, output []byt
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func removeIDAnnotation(r *resource.Resource) {
|
||||||
|
// remove the annotation set by Kustomize to track the resource
|
||||||
|
annotations := r.GetAnnotations()
|
||||||
|
delete(annotations, idAnnotation)
|
||||||
|
if len(annotations) == 0 {
|
||||||
|
annotations = nil
|
||||||
|
}
|
||||||
|
r.SetAnnotations(annotations)
|
||||||
|
}
|
||||||
|
|
||||||
// UpdateResourceOptions updates the generator options for each resource in the
|
// UpdateResourceOptions updates the generator options for each resource in the
|
||||||
// given ResMap based on plugin provided annotations.
|
// given ResMap based on plugin provided annotations.
|
||||||
func UpdateResourceOptions(rm resmap.ResMap) (resmap.ResMap, error) {
|
func UpdateResourceOptions(rm resmap.ResMap) (resmap.ResMap, error) {
|
||||||
|
|||||||
@@ -38,12 +38,24 @@ data:
|
|||||||
kind: ConfigMap
|
kind: ConfigMap
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
|
config.kubernetes.io/path: configmap_some-cm.yaml
|
||||||
modified-by: mixer-instance
|
modified-by: mixer-instance
|
||||||
name: some-cm
|
name: some-cm
|
||||||
---
|
---
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
|
data:
|
||||||
|
foo: bar
|
||||||
kind: ConfigMap
|
kind: ConfigMap
|
||||||
metadata:
|
metadata:
|
||||||
|
annotations:
|
||||||
|
config.kubernetes.io/path: configmap_some-cm-copy.yaml
|
||||||
|
name: some-cm-copy
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
config.kubernetes.io/path: configmap_net-new.yaml
|
||||||
name: net-new
|
name: net-new
|
||||||
`)
|
`)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,27 @@
|
|||||||
def run(r, fc):
|
def run(r, fc):
|
||||||
|
add = []
|
||||||
|
remove = []
|
||||||
for resource in r:
|
for resource in r:
|
||||||
if resource.get("metadata") == None:
|
if resource.get("metadata") == None:
|
||||||
resource["metadata"] = {}
|
resource["metadata"] = {}
|
||||||
if resource["metadata"].get("annotations") == None:
|
if resource["metadata"].get("annotations") == None:
|
||||||
resource["metadata"]["annotations"] = {}
|
resource["metadata"]["annotations"] = {}
|
||||||
|
|
||||||
|
# Flag for deletion
|
||||||
|
if resource["metadata"]["name"] == "delete-me":
|
||||||
|
remove.append(resource)
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Deep-ish copy the resource
|
||||||
|
cp = dict(resource)
|
||||||
|
cp["metadata"] = dict(cp["metadata"])
|
||||||
|
cp["metadata"]["annotations"] = dict(cp["metadata"]["annotations"])
|
||||||
|
cp["metadata"]["name"] = resource["metadata"]["name"]+"-copy"
|
||||||
|
add.append(cp)
|
||||||
|
|
||||||
resource["metadata"]["annotations"]["modified-by"] = fc["metadata"]["name"]
|
resource["metadata"]["annotations"]["modified-by"] = fc["metadata"]["name"]
|
||||||
|
|
||||||
|
# Add something
|
||||||
new = {
|
new = {
|
||||||
"kind": "ConfigMap",
|
"kind": "ConfigMap",
|
||||||
"apiVersion": "v1",
|
"apiVersion": "v1",
|
||||||
@@ -13,6 +29,9 @@ def run(r, fc):
|
|||||||
"name": "net-new"
|
"name": "net-new"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
r.extend(add)
|
||||||
r.append(new)
|
r.append(new)
|
||||||
|
for resource in remove:
|
||||||
|
r.remove(resource)
|
||||||
|
|
||||||
run(ctx.resource_list["items"], ctx.resource_list["functionConfig"])
|
run(ctx.resource_list["items"], ctx.resource_list["functionConfig"])
|
||||||
|
|||||||
Reference in New Issue
Block a user