mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-05-17 18:25:26 +00:00
Add support for using common base
This commit is contained in:
@@ -292,7 +292,7 @@ func (a *Application) resolveRefVars(m resmap.ResMap) (map[string]string, error)
|
||||
}
|
||||
for _, v := range vars {
|
||||
id := resource.NewResId(v.ObjRef.GroupVersionKind(), v.ObjRef.Name)
|
||||
if r, found := m[id]; found {
|
||||
if r, found := m.DemandOneMatchForId(id); found {
|
||||
s, err := r.GetFieldValue(v.FieldRef.FieldPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to resolve referred var: %+v", v)
|
||||
|
||||
@@ -91,7 +91,7 @@ var svc = schema.GroupVersionKind{Version: "v1", Kind: "Service"}
|
||||
|
||||
func TestResources1(t *testing.T) {
|
||||
expected := resmap.ResMap{
|
||||
resource.NewResId(deploy, "dply1"): resource.NewResourceFromMap(
|
||||
resource.NewResIdWithPrefix(deploy, "dply1", "foo-"): resource.NewResourceFromMap(
|
||||
map[string]interface{}{
|
||||
"apiVersion": "apps/v1",
|
||||
"kind": "Deployment",
|
||||
@@ -123,7 +123,7 @@ func TestResources1(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}),
|
||||
resource.NewResId(cmap, "literalConfigMap"): resource.NewResourceFromMap(
|
||||
resource.NewResIdWithPrefix(cmap, "literalConfigMap", "foo-"): resource.NewResourceFromMap(
|
||||
map[string]interface{}{
|
||||
"apiVersion": "v1",
|
||||
"kind": "ConfigMap",
|
||||
@@ -143,7 +143,7 @@ func TestResources1(t *testing.T) {
|
||||
"DB_PASSWORD": "somepw",
|
||||
},
|
||||
}).SetBehavior(resource.BehaviorCreate),
|
||||
resource.NewResId(secret, "secret"): resource.NewResourceFromMap(
|
||||
resource.NewResIdWithPrefix(secret, "secret", "foo-"): resource.NewResourceFromMap(
|
||||
map[string]interface{}{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Secret",
|
||||
@@ -164,7 +164,7 @@ func TestResources1(t *testing.T) {
|
||||
"DB_PASSWORD": base64.StdEncoding.EncodeToString([]byte("somepw")),
|
||||
},
|
||||
}).SetBehavior(resource.BehaviorCreate),
|
||||
resource.NewResId(ns, "ns1"): resource.NewResourceFromMap(
|
||||
resource.NewResIdWithPrefix(ns, "ns1", "foo-"): resource.NewResourceFromMap(
|
||||
map[string]interface{}{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Namespace",
|
||||
@@ -289,7 +289,7 @@ func makeLoader2(t *testing.T) loader.Loader {
|
||||
// perhaps it's not worth supporting the command.
|
||||
func TestRawResources2(t *testing.T) {
|
||||
expected := resmap.ResMap{
|
||||
resource.NewResId(deploy, "dply1"): resource.NewResourceFromMap(
|
||||
resource.NewResIdWithPrefix(deploy, "dply1", "foo-"): resource.NewResourceFromMap(
|
||||
map[string]interface{}{
|
||||
"apiVersion": "apps/v1",
|
||||
"kind": "Deployment",
|
||||
|
||||
@@ -56,7 +56,7 @@ func writeYamlToNewDir(in resmap.ResMap, prefix string) (*directory, error) {
|
||||
}
|
||||
|
||||
for id, obj := range in {
|
||||
f, err := dir.newFile(id.String())
|
||||
f, err := dir.newFile(id.GvknString())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -37,6 +37,26 @@ import (
|
||||
// ResMap is a map from ResId to Resource.
|
||||
type ResMap map[resource.ResId]*resource.Resource
|
||||
|
||||
// FindByGVKN find the matched ResIds by Group/Version/Kind and Name
|
||||
func (m ResMap) FindByGVKN(inputId resource.ResId) []resource.ResId {
|
||||
var result []resource.ResId
|
||||
for id := range m {
|
||||
if id.GvknEquals(inputId) {
|
||||
result = append(result, id)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// DemandOneMatchForId find the matched resource by Group/Version/Kind and Name
|
||||
func (m ResMap) DemandOneMatchForId(inputId resource.ResId) (*resource.Resource, bool) {
|
||||
result := m.FindByGVKN(inputId)
|
||||
if len(result) == 1 {
|
||||
return m[result[0]], true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// EncodeAsYaml encodes a ResMap to YAML; encoded objects separated by `---`.
|
||||
func (m ResMap) EncodeAsYaml() ([]byte, error) {
|
||||
var ids []resource.ResId
|
||||
@@ -217,10 +237,12 @@ func MergeWithoutOverride(maps ...ResMap) (ResMap, error) {
|
||||
// must be BehaviorMerge or BehaviorReplace. If X is not in the map, then it's
|
||||
// behavior cannot be merge or replace.
|
||||
func MergeWithOverride(maps ...ResMap) (ResMap, error) {
|
||||
result := ResMap{}
|
||||
for _, m := range maps {
|
||||
result := maps[0]
|
||||
for _, m := range maps[1:] {
|
||||
for id, r := range m {
|
||||
if _, found := result[id]; found {
|
||||
matchedId := result.FindByGVKN(id)
|
||||
if len(matchedId) == 1 {
|
||||
id = matchedId[0]
|
||||
switch r.Behavior() {
|
||||
case resource.BehaviorReplace:
|
||||
glog.V(4).Infof("Replace %v with %v", result[id].Object, r.Object)
|
||||
@@ -236,13 +258,15 @@ func MergeWithOverride(maps ...ResMap) (ResMap, error) {
|
||||
default:
|
||||
return nil, fmt.Errorf("id %#v exists; must merge or replace", id)
|
||||
}
|
||||
} else {
|
||||
} else if len(matchedId) == 0 {
|
||||
switch r.Behavior() {
|
||||
case resource.BehaviorMerge, resource.BehaviorReplace:
|
||||
return nil, fmt.Errorf("id %#v does not exist; cannot merge or replace", id)
|
||||
default:
|
||||
result[id] = r
|
||||
}
|
||||
} else {
|
||||
return nil, fmt.Errorf("Merge conflict, found multiple objects %v the Resmap %v can merge into", matchedId, id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,18 +28,49 @@ type ResId struct {
|
||||
gvk schema.GroupVersionKind
|
||||
// original name of the resource before transformation.
|
||||
name string
|
||||
// namePrefix of the resource
|
||||
// an untransformed resource has no prefix, fully transformed resource has an arbitrary number of prefixes
|
||||
// concatenated together.
|
||||
prefix string
|
||||
}
|
||||
|
||||
// NewResIdWithPrefix creates new resource identifier with a prefix
|
||||
func NewResIdWithPrefix(g schema.GroupVersionKind, n, p string) ResId {
|
||||
return ResId{gvk: g, name: n, prefix: p}
|
||||
}
|
||||
|
||||
// NewResId creates new resource identifier
|
||||
func NewResId(g schema.GroupVersionKind, n string) ResId {
|
||||
return ResId{gvk: g, name: n}
|
||||
return NewResIdWithPrefix(g, n, "")
|
||||
}
|
||||
|
||||
// String of ResId based on GVK, name and prefix
|
||||
func (n ResId) String() string {
|
||||
//var fields []string
|
||||
//for _, s := range []string{n.gvk.Group, n.gvk.Version, n.gvk.Kind, n.prefix, n.name} {
|
||||
// if s != "" {
|
||||
// fields = append(fields, s)
|
||||
// }
|
||||
//}
|
||||
//return strings.Join(fields, "_") + ".yaml"
|
||||
fields := []string{n.gvk.Group, n.gvk.Version, n.gvk.Kind, n.prefix, n.name}
|
||||
return strings.Join(fields, "_") + ".yaml"
|
||||
}
|
||||
|
||||
// GvknString of ResId based on GVK and name
|
||||
func (n ResId) GvknString() string {
|
||||
if n.gvk.Group == "" {
|
||||
return strings.Join([]string{n.gvk.Version, n.gvk.Kind, n.name}, "_") + ".yaml"
|
||||
}
|
||||
return strings.Join([]string{n.gvk.Group, n.gvk.Version, n.gvk.Kind, n.name}, "_") + ".yaml"
|
||||
|
||||
}
|
||||
|
||||
// GvknEquals return if two ResId have the same Group/Version/Kind and name
|
||||
// The comparison excludes prefix
|
||||
func (n ResId) GvknEquals(id ResId) bool {
|
||||
return n.gvk.Group == id.gvk.Group && n.gvk.Version == id.gvk.Version &&
|
||||
n.gvk.Kind == id.gvk.Kind && n.name == id.name
|
||||
}
|
||||
|
||||
// Gvk returns Group/Version/Kind of the resource.
|
||||
@@ -51,3 +82,13 @@ func (n ResId) Gvk() schema.GroupVersionKind {
|
||||
func (n ResId) Name() string {
|
||||
return n.name
|
||||
}
|
||||
|
||||
// Prefix returns name prefix.
|
||||
func (n ResId) Prefix() string {
|
||||
return n.prefix
|
||||
}
|
||||
|
||||
// CopyWithNewPrefix make a new copy from current ResId and append a new prefix
|
||||
func (n ResId) CopyWithNewPrefix(p string) ResId {
|
||||
return ResId{gvk: n.gvk, name: n.name, prefix: p + n.prefix}
|
||||
}
|
||||
|
||||
@@ -55,10 +55,15 @@ func (pt *patchTransformer) Transform(baseResourceMap resmap.ResMap) error {
|
||||
for _, patch := range patches {
|
||||
// Merge patches with base resource.
|
||||
id := patch.Id()
|
||||
base, found := baseResourceMap[id]
|
||||
if !found {
|
||||
matchedIds := baseResourceMap.FindByGVKN(id)
|
||||
if len(matchedIds) == 0 {
|
||||
return fmt.Errorf("failed to find an object with %#v to apply the patch", id.Gvk())
|
||||
}
|
||||
if len(matchedIds) > 1 {
|
||||
return fmt.Errorf("Found multiple objects %#v that the patch %#v can apply", matchedIds, id)
|
||||
}
|
||||
id = matchedIds[0]
|
||||
base := baseResourceMap[id]
|
||||
merged := map[string]interface{}{}
|
||||
versionedObj, err := scheme.Scheme.New(id.Gvk())
|
||||
baseName := base.GetName()
|
||||
|
||||
@@ -69,13 +69,17 @@ func (o *namePrefixTransformer) Transform(m resmap.ResMap) error {
|
||||
mf := resmap.ResMap{}
|
||||
|
||||
for id := range m {
|
||||
mf[id] = m[id]
|
||||
found := false
|
||||
for _, path := range o.skipPathConfigs {
|
||||
if selectByGVK(id.Gvk(), path.GroupVersionKind) {
|
||||
delete(mf, id)
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
mf[id] = m[id]
|
||||
delete(m, id)
|
||||
}
|
||||
}
|
||||
|
||||
for id := range mf {
|
||||
@@ -88,6 +92,8 @@ func (o *namePrefixTransformer) Transform(m resmap.ResMap) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
newId := id.CopyWithNewPrefix(o.prefix)
|
||||
m[newId] = mf[id]
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -53,7 +53,7 @@ func TestPrefixNameRun(t *testing.T) {
|
||||
}),
|
||||
}
|
||||
expected := resmap.ResMap{
|
||||
resource.NewResId(cmap, "cm1"): resource.NewResourceFromMap(
|
||||
resource.NewResIdWithPrefix(cmap, "cm1", "someprefix-"): resource.NewResourceFromMap(
|
||||
map[string]interface{}{
|
||||
"apiVersion": "v1",
|
||||
"kind": "ConfigMap",
|
||||
@@ -61,7 +61,7 @@ func TestPrefixNameRun(t *testing.T) {
|
||||
"name": "someprefix-cm1",
|
||||
},
|
||||
}),
|
||||
resource.NewResId(cmap, "cm2"): resource.NewResourceFromMap(
|
||||
resource.NewResIdWithPrefix(cmap, "cm2", "someprefix-"): resource.NewResourceFromMap(
|
||||
map[string]interface{}{
|
||||
"apiVersion": "v1",
|
||||
"kind": "ConfigMap",
|
||||
|
||||
Reference in New Issue
Block a user