Commit generated code for image and namespace transformers.

This commit is contained in:
Jeffrey Regan
2019-06-19 18:52:24 -07:00
parent c437d99c5f
commit 3325852aab
2 changed files with 110 additions and 19 deletions

View File

@@ -59,30 +59,28 @@ func (p *ImageTagTransformerPlugin) mutateImage(in interface{}) (interface{}, er
return nil, fmt.Errorf("image path is not of type string but %T", in) return nil, fmt.Errorf("image path is not of type string but %T", in)
} }
nTag := p.ImageTag if !isImageMatched(original, p.ImageTag.Name) {
if !isImageMatched(original, nTag.Name) {
return original, nil return original, nil
} }
name, tag := split(original) name, tag := split(original)
if nTag.NewName != "" { if p.ImageTag.NewName != "" {
name = nTag.NewName name = p.ImageTag.NewName
} }
if nTag.NewTag != "" { if p.ImageTag.NewTag != "" {
tag = ":" + nTag.NewTag tag = ":" + p.ImageTag.NewTag
} }
if nTag.Digest != "" { if p.ImageTag.Digest != "" {
tag = "@" + nTag.Digest tag = "@" + p.ImageTag.Digest
} }
return name + tag, nil return name + tag, nil
} }
/* // findAndReplaceImage replaces the image name and
findAndReplaceImage replaces the image name and tags inside one object // tags inside one object.
It searches the object for container session // It searches the object for container session
then loops though all images inside containers session, // then loops though all images inside containers
finds matched ones and update the image name and tag name // session, finds matched ones and update the
*/ // image name and tag name
func (p *ImageTagTransformerPlugin) findAndReplaceImage(obj map[string]interface{}) error { func (p *ImageTagTransformerPlugin) findAndReplaceImage(obj map[string]interface{}) error {
paths := []string{"containers", "initContainers"} paths := []string{"containers", "initContainers"}
updated := false updated := false
@@ -104,7 +102,8 @@ func (p *ImageTagTransformerPlugin) findAndReplaceImage(obj map[string]interface
func (p *ImageTagTransformerPlugin) updateContainers(in interface{}) (interface{}, error) { func (p *ImageTagTransformerPlugin) updateContainers(in interface{}) (interface{}, error) {
containers, ok := in.([]interface{}) containers, ok := in.([]interface{})
if !ok { if !ok {
return nil, fmt.Errorf("containers path is not of type []interface{} but %T", in) return nil, fmt.Errorf(
"containers path is not of type []interface{} but %T", in)
} }
for i := range containers { for i := range containers {
container := containers[i].(map[string]interface{}) container := containers[i].(map[string]interface{})
@@ -112,7 +111,6 @@ func (p *ImageTagTransformerPlugin) updateContainers(in interface{}) (interface{
if !found { if !found {
continue continue
} }
imageName := containerImage.(string) imageName := containerImage.(string)
if isImageMatched(imageName, p.ImageTag.Name) { if isImageMatched(imageName, p.ImageTag.Name) {
newImage, err := p.mutateImage(imageName) newImage, err := p.mutateImage(imageName)

View File

@@ -2,8 +2,11 @@
package builtin package builtin
import ( import (
"sigs.k8s.io/kustomize/pkg/gvk"
"sigs.k8s.io/kustomize/pkg/ifc" "sigs.k8s.io/kustomize/pkg/ifc"
"sigs.k8s.io/kustomize/pkg/resid"
"sigs.k8s.io/kustomize/pkg/resmap" "sigs.k8s.io/kustomize/pkg/resmap"
"sigs.k8s.io/kustomize/pkg/resource"
"sigs.k8s.io/kustomize/pkg/transformers" "sigs.k8s.io/kustomize/pkg/transformers"
"sigs.k8s.io/kustomize/pkg/transformers/config" "sigs.k8s.io/kustomize/pkg/transformers/config"
"sigs.k8s.io/yaml" "sigs.k8s.io/yaml"
@@ -28,6 +31,96 @@ func (p *NamespaceTransformerPlugin) Config(
} }
func (p *NamespaceTransformerPlugin) Transform(m resmap.ResMap) error { func (p *NamespaceTransformerPlugin) Transform(m resmap.ResMap) error {
return transformers.NewNamespaceTransformer( if len(p.Namespace) == 0 {
p.Namespace, p.FieldSpecs).Transform(m) return nil
}
for _, r := range m.Resources() {
id := r.OrgId()
fs, ok := p.isSelected(id)
if !ok {
continue
}
if len(r.Map()) == 0 {
// Don't mutate empty objects?
continue
}
if doIt(id, fs) {
if err := p.changeNamespace(r, fs); err != nil {
return err
}
}
}
p.updateClusterRoleBinding(m)
return nil
}
const metaNamespace = "metadata/namespace"
// Special casing metadata.namespace since
// all objects have it, even "ClusterKind" objects
// that don't exist in a namespace (the Namespace
// object itself doesn't live in a namespace).
func doIt(id resid.ResId, fs *config.FieldSpec) bool {
return fs.Path != metaNamespace ||
(fs.Path == metaNamespace && !id.IsClusterKind())
}
func (p *NamespaceTransformerPlugin) changeNamespace(
r *resource.Resource, fs *config.FieldSpec) error {
return transformers.MutateField(
r.Map(), fs.PathSlice(), fs.CreateIfNotPresent,
func(_ interface{}) (interface{}, error) {
return p.Namespace, nil
})
}
func (p *NamespaceTransformerPlugin) isSelected(
id resid.ResId) (*config.FieldSpec, bool) {
for _, fs := range p.FieldSpecs {
if id.IsSelected(&fs.Gvk) {
return &fs, true
}
}
return nil, false
}
func (p *NamespaceTransformerPlugin) updateClusterRoleBinding(m resmap.ResMap) {
srvAccount := gvk.Gvk{Version: "v1", Kind: "ServiceAccount"}
saMap := map[string]bool{}
for _, id := range m.AllIds() {
if id.Gvk.Equals(srvAccount) {
saMap[id.Name] = true
}
}
for _, res := range m.Resources() {
if res.OrgId().Kind != "ClusterRoleBinding" &&
res.OrgId().Kind != "RoleBinding" {
continue
}
objMap := res.Map()
subjects, ok := objMap["subjects"].([]interface{})
if subjects == nil || !ok {
continue
}
for i := range subjects {
subject := subjects[i].(map[string]interface{})
kind, foundK := subject["kind"]
name, foundN := subject["name"]
if !foundK || !foundN || kind.(string) != srvAccount.Kind {
continue
}
// a ServiceAccount named “default” exists in every active namespace
if name.(string) == "default" || saMap[name.(string)] {
subject := subjects[i].(map[string]interface{})
transformers.MutateField(
subject, []string{"namespace"},
true, func(_ interface{}) (interface{}, error) {
return p.Namespace, nil
})
subjects[i] = subject
}
}
objMap["subjects"] = subjects
}
} }