Skip to content

Commit

Permalink
Allow exec and function transformers to generate resources
Browse files Browse the repository at this point in the history
  • Loading branch information
KnVerey committed Feb 4, 2021
1 parent f927cf0 commit 97a2b15
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 11 deletions.
45 changes: 34 additions & 11 deletions api/internal/plugins/utils/utils.go
Expand Up @@ -15,6 +15,7 @@ import (
"sigs.k8s.io/kustomize/api/konfig"
"sigs.k8s.io/kustomize/api/resid"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/yaml"
)
Expand Down Expand Up @@ -147,41 +148,63 @@ func GetResMapWithIDAnnotation(rm resmap.ResMap) (resmap.ResMap, error) {
// UpdateResMapValues updates the Resource value in the given ResMap
// with the emitted Resource values in output.
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 {
return err
}
for _, r := range outputRM.Resources() {
for _, r := range resources {
// for each emitted Resource, find the matching Resource in the original ResMap
// using its id
annotations := r.GetAnnotations()
idString, ok := annotations[idAnnotation]
// Transformer-generated resource--add to resMap
if !ok {
return fmt.Errorf("the transformer %s should not remove annotation %s",
pluginName, idAnnotation)
if err := rm.Append(r); err != nil {
return err
}
continue
}

id := resid.ResId{}
err := yaml.Unmarshal([]byte(idString), &id)
err = yaml.Unmarshal([]byte(idString), &id)
if err != nil {
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)
if err != nil {
return fmt.Errorf("unable to find unique match to %s", id.String())
}
// remove the annotation set by Kustomize to track the resource
delete(annotations, idAnnotation)
if len(annotations) == 0 {
annotations = nil
}
r.SetAnnotations(annotations)
removeIDAnnotation(r)

// update the resource value with the transformed object
res.ResetPrimaryData(r)
}
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
// given ResMap based on plugin provided annotations.
func UpdateResourceOptions(rm resmap.ResMap) (resmap.ResMap, error) {
Expand Down
12 changes: 12 additions & 0 deletions plugin/someteam.example.com/v1/starlarkmixer/StarlarkMixer_test.go
Expand Up @@ -38,12 +38,24 @@ data:
kind: ConfigMap
metadata:
annotations:
config.kubernetes.io/path: configmap_some-cm.yaml
modified-by: mixer-instance
name: some-cm
---
apiVersion: v1
data:
foo: bar
kind: ConfigMap
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
`)
}
19 changes: 19 additions & 0 deletions plugin/someteam.example.com/v1/starlarkmixer/mixer.star
@@ -1,18 +1,37 @@
def run(r, fc):
add = []
remove = []
for resource in r:
if resource.get("metadata") == None:
resource["metadata"] = {}
if resource["metadata"].get("annotations") == None:
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"]

# Add something
new = {
"kind": "ConfigMap",
"apiVersion": "v1",
"metadata": {
"name": "net-new"
}
}
r.extend(add)
r.append(new)
for resource in remove:
r.remove(resource)

run(ctx.resource_list["items"], ctx.resource_list["functionConfig"])

0 comments on commit 97a2b15

Please sign in to comment.