Skip to content

Commit e0adc19

Browse files
committed
update fieldspec name value based on nameReference map
1 parent 35c5542 commit e0adc19

File tree

7 files changed

+148
-118
lines changed

7 files changed

+148
-118
lines changed
Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,19 @@
11
# set-default-name
22

33
### Feature
4-
`set-default-name` does a simple task: cruelly updates the resource metadata name or name references if `metadata.name`
5-
match the fieldSpec list in `fieldspec/customName.go`.
4+
`set-default-name` sets two types of default name values:
65

7-
### Warning
8-
!!! Be careful when using this function.
6+
- It sets the `metadata.name` fields for white listed KRM resources.
7+
- It sets custom field specs to their referred `metadata.name` fields.
8+
9+
In case one, you use `ConfigMap` to set the name. The ConfigMap should
10+
contain a `.data.name` field and be provided as input resource. If the KRM
11+
resources are not listed, their `'metadata.name` won't be updated.
12+
The white list can be found in `./fieldspec/name.go`.
13+
14+
In case two, you can find the nameReferences whiteliest in `./fieldspec/nameref.go`
15+
A `nameReference` contains a GVK and a list of referrals. The GVK gives
16+
the resources' `metadata.data` to read, the `referral` lists the resource
17+
field spec to update. This is different from kustomize nameReference, which
18+
only updates referrals metadata.name field and requires the referrals and
19+
referror have the same `metadata.name`.

functions/go/gcp-set-default-name/builtin/backref.go

Lines changed: 0 additions & 94 deletions
This file was deleted.

functions/go/gcp-set-default-name/fieldspec/nameref.go

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,28 @@ package fieldspec
33
const (
44
NameReferenceFieldSpecs = `
55
nameReference:
6+
# Blueprint redis-bucket
67
- kind: RedisInstance
7-
group: redis.cnrm.cloud.google.com/v1beta1
8+
group: redis.cnrm.cloud.google.com
9+
version: v1beta1
810
fieldSpecs:
911
- path: spec/displayName
1012
kind: RedisInstance
11-
group: redis.cnrm.cloud.google.com/v1beta1
13+
group: redis.cnrm.cloud.google.com
14+
version: v1beta1
15+
16+
# Blueprint spanner
17+
- kind: SpannerInstance
18+
group: spanner.cnrm.cloud.google.com
19+
version: v1beta1
20+
fieldSpecs:
21+
- path: spec/displayName
22+
kind: SpannerInstance
23+
group: spanner.cnrm.cloud.google.com
24+
version: v1beta1
25+
- path: spec/instanceRef/name
26+
kind: SpannerDatabase
27+
group: spanner.cnrm.cloud.google.com
28+
version: v1beta1
1229
`
1330
)

functions/go/gcp-set-default-name/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
module github.com/GoogleContainerTools/kpt-functions-catalog/functions/go/set-project-id
1+
module github.com/GoogleContainerTools/kpt-functions-catalog/functions/go/gcp-set-default-name
22

33
go 1.17
44

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package namereference
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/pkg/errors"
7+
"sigs.k8s.io/kustomize/api/filters/fieldspec"
8+
"sigs.k8s.io/kustomize/api/resmap"
9+
"sigs.k8s.io/kustomize/api/resource"
10+
"sigs.k8s.io/kustomize/api/types"
11+
"sigs.k8s.io/kustomize/kyaml/kio"
12+
"sigs.k8s.io/kustomize/kyaml/resid"
13+
"sigs.k8s.io/kustomize/kyaml/yaml"
14+
)
15+
16+
type UnlimitedNameRefFilter struct {
17+
Referrer *resource.Resource
18+
NameFieldToUpdate types.FieldSpec
19+
ReferralTarget resid.Gvk
20+
ReferralCandidates resmap.ResMap
21+
22+
}
23+
24+
func (f UnlimitedNameRefFilter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
25+
return kio.FilterAll(yaml.FilterFunc(f.run)).Filter(nodes)
26+
}
27+
28+
func (f UnlimitedNameRefFilter) run(node *yaml.RNode) (*yaml.RNode, error) {
29+
if node.GetNamespace() != f.Referrer.GetNamespace() {
30+
return nil, fmt.Errorf("not in the same namespace")
31+
}
32+
if err := node.PipeE(fieldspec.Filter{
33+
FieldSpec: f.NameFieldToUpdate,
34+
SetValue: f.updateName,
35+
}); err != nil {
36+
return nil, errors.Wrapf(
37+
err, "updating name reference in '%s' field of '%s'",
38+
f.NameFieldToUpdate.Path, f.Referrer.CurId().String())
39+
}
40+
return node, nil
41+
}
42+
43+
func (f UnlimitedNameRefFilter) updateName(node *yaml.RNode) error {
44+
if yaml.IsMissingOrNull(node) {
45+
return nil
46+
}
47+
candidates := f.ReferralCandidates.Resources()
48+
candidates = doSieve(candidates, previousIdSelectedByGvk(&f.ReferralTarget))
49+
candidates = doSieve(candidates, f.sameCurrentNamespaceAsReferrer())
50+
if len(candidates) == 0 {
51+
return nil
52+
}
53+
referral := candidates[0]
54+
return node.PipeE(yaml.FieldSetter{StringValue: referral.GetName()})
55+
}
56+
57+
type sieveFunc func(*resource.Resource) bool
58+
59+
func doSieve(list []*resource.Resource, fn sieveFunc) (s []*resource.Resource) {
60+
for _, r := range list {
61+
if fn(r) {
62+
s = append(s, r)
63+
}
64+
}
65+
return
66+
}
67+
68+
func previousIdSelectedByGvk(gvk *resid.Gvk) sieveFunc {
69+
return func(r *resource.Resource) bool {
70+
if r.OrgId().IsSelected(gvk) {
71+
return true
72+
}
73+
return false
74+
}
75+
}
76+
77+
func (f UnlimitedNameRefFilter) sameCurrentNamespaceAsReferrer() sieveFunc {
78+
referrerCurId := f.Referrer.CurId()
79+
if referrerCurId.IsClusterScoped() {
80+
// If the referrer is cluster-scoped, let anything through.
81+
return func(_ *resource.Resource) bool {return true}
82+
}
83+
return func(r *resource.Resource) bool {
84+
if r.CurId().IsClusterScoped() {
85+
// Allow cluster-scoped through.
86+
return true
87+
}
88+
if r.GetKind() == "ServiceAccount" {
89+
// Allow service accounts through, even though they
90+
// are in a namespace. A RoleBinding in another namespace
91+
// can reference them.
92+
return true
93+
}
94+
return referrerCurId.IsNsEquals(r.CurId())
95+
}
96+
}

functions/go/gcp-set-default-name/builtin/transformer.go renamed to functions/go/gcp-set-default-name/namereference/transformer.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,28 @@
1-
package builtin
1+
package namereference
22

33
import (
44
"log"
55

6-
"sigs.k8s.io/kustomize/api/filters/nameref"
76
"sigs.k8s.io/kustomize/api/resmap"
87
"sigs.k8s.io/kustomize/api/resource"
8+
"sigs.k8s.io/kustomize/api/types"
99
"sigs.k8s.io/kustomize/kyaml/resid"
1010
)
1111

1212
type nameReferenceTransformer struct {
1313
backRefs []NameBackReferences
1414
}
1515

16-
const doDebug = false
16+
type NameBackReferences struct {
17+
resid.Gvk `json:",inline,omitempty" yaml:",inline,omitempty"`
18+
Referrers types.FsSlice `json:"fieldSpecs,omitempty" yaml:"fieldSpecs,omitempty"`
19+
}
20+
21+
type NbrSlice []NameBackReferences
1722

1823
var _ resmap.Transformer = &nameReferenceTransformer{}
1924

20-
type filterMap map[*resource.Resource][]nameref.Filter
25+
type filterMap map[*resource.Resource][]UnlimitedNameRefFilter
2126

2227
func NewNameReferenceTransformer(
2328
br []NameBackReferences) resmap.Transformer {
@@ -39,23 +44,18 @@ func (t *nameReferenceTransformer) Transform(m resmap.ResMap) error {
3944
}
4045
}
4146
}
42-
4347
return nil
4448
}
4549

4650
func (t *nameReferenceTransformer) determineFilters(
4751
resources []*resource.Resource) (fMap filterMap) {
4852
// We cache the resource OrgId values because they don't change and otherwise are very visible in a memory pprof
49-
resourceOrgIds := make([]resid.ResId, len(resources))
50-
for i, resource := range resources {
51-
resourceOrgIds[i] = resource.OrgId()
52-
}
5353
fMap = make(filterMap)
5454
for _, backReference := range t.backRefs {
5555
for _, referrerSpec := range backReference.Referrers {
56-
for i, res := range resources {
57-
if resourceOrgIds[i].IsSelected(&referrerSpec.Gvk) {
58-
fMap[res] = append(fMap[res], nameref.Filter{
56+
for _, res := range resources {
57+
if res.OrgId().IsSelected(&referrerSpec.Gvk) {
58+
fMap[res] = append(fMap[res], UnlimitedNameRefFilter{
5959
NameFieldToUpdate: referrerSpec,
6060
ReferralTarget: backReference.Gvk,
6161
})

functions/go/gcp-set-default-name/transformer.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ package main
33
import (
44
"fmt"
55

6-
"github.com/GoogleContainerTools/kpt-functions-catalog/functions/go/set-project-id/builtin"
7-
"github.com/GoogleContainerTools/kpt-functions-catalog/functions/go/set-project-id/fieldspec"
6+
"github.com/GoogleContainerTools/kpt-functions-catalog/functions/go/gcp-set-default-name/fieldspec"
7+
"github.com/GoogleContainerTools/kpt-functions-catalog/functions/go/gcp-set-default-name/namereference"
88
"sigs.k8s.io/kustomize/api/filters/fsslice"
99
"sigs.k8s.io/kustomize/api/konfig/builtinpluginconsts"
1010
"sigs.k8s.io/kustomize/api/resmap"
@@ -55,7 +55,7 @@ func (p *CustomNameTransformer) Config(fnConfigNode *yaml.RNode) error {
5555
return err
5656
}
5757
nameRefs := append(builtinNameRefFs.NameReference, customNameRefFs.NameReference...)
58-
p.nameRefTransformer = builtin.NewNameReferenceTransformer(nameRefs)
58+
p.nameRefTransformer = namereference.NewNameReferenceTransformer(nameRefs)
5959
return nil
6060
}
6161

@@ -74,7 +74,7 @@ func (p *CustomNameTransformer) Transform(m resmap.ResMap) error {
7474
}
7575

7676
type NameBackRefs struct {
77-
NameReference builtin.NbrSlice `json:"nameReference,omitempty" yaml:"nameReference,omitempty"`
77+
NameReference namereference.NbrSlice `json:"nameReference,omitempty" yaml:"nameReference,omitempty"`
7878
}
7979

8080
var _ kio.Filter = CustomFieldSpecFilter{}
@@ -104,7 +104,7 @@ func (f CustomFieldSpecFilter) filter(node *yaml.RNode) (*yaml.RNode, error) {
104104
}
105105

106106
func (f CustomFieldSpecFilter) updateMetaNameFn(node *yaml.RNode) error {
107-
return node.PipeE(updater{metaName: f.MetaName,})
107+
return node.PipeE(updater{metaName: f.MetaName})
108108
}
109109

110110
type updater struct {

0 commit comments

Comments
 (0)