Skip to content

Add set-project-id function #756

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
14 changes: 14 additions & 0 deletions functions/go/gcp-set-project-id/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
FROM golang:1.17-alpine3.13
ENV CGO_ENABLED=0
WORKDIR /go/src/

COPY go.mod go.sum ./

COPY . .
RUN go build -o /usr/local/bin/function ./

#############################################

FROM alpine:3.13
COPY --from=0 /usr/local/bin/function /usr/local/bin/function
ENTRYPOINT ["function"]
38 changes: 38 additions & 0 deletions functions/go/gcp-set-project-id/consts/annotation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package consts

// annotationFieldSpecs update the KRM resources' annotations whose field spec matches the path.
// This requires the annotation to already exist in the KRM resource, which is different from kustomize's
// commonAnnotations that creates the annotation if not exist.
const AnnotationFieldSpecs = `
annotations:
- path: metadata/annotations

- path: spec/template/metadata/annotations
version: v1
kind: ReplicationController

- path: spec/template/metadata/annotations
kind: Deployment

- path: spec/template/metadata/annotations
kind: ReplicaSet

- path: spec/template/metadata/annotations
kind: DaemonSet

- path: spec/template/metadata/annotations
kind: StatefulSet

- path: spec/template/metadata/annotations
group: batch
kind: Job

- path: spec/jobTemplate/metadata/annotations
group: batch
kind: CronJob

- path: spec/jobTemplate/spec/template/metadata/annotations
group: batch
kind: CronJob

`
96 changes: 96 additions & 0 deletions functions/go/gcp-set-project-id/consts/project.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package consts

// ProjectFieldSpecs contains the fieldSpec paths of Google Cloud ProjectID
const ProjectFieldSpecs = `
projectFieldSpec:
# Blueprint redis-bucket
- path: spec/authorizedNetworkRef/external
regexPattern: (?P<prefix>projects\/)(?P<projectID>\S+)(?P<suffix>\/global\/networks\/default)
group: redis.cnrm.cloud.google.com
version: v1beta1
kind: RedisInstance

# Blueprint cluster
- path: spec/resourceRef/external
group: iam.cnrm.cloud.google.com
version: v1beta1
kind: IAMPolicyMember

# Blueprint cluster
- path: spec/projectRef/external
group: gkehub.cnrm.cloud.google.com
version: v1beta1
kind: GKEHubFeatureMembership

- path: spec/googleServiceAccount
regexPattern: (?P<prefix>\S+@)(?P<projectID>\S+)(?P<suffix>\.iam\.gserviceaccount\.com)
group: core.cnrm.cloud.google.com
version: v1beta1
kind: ConfigConnectorContext

- path: spec/member
regexPattern: (?P<prefix>serviceAccount:\S+\.svc\.id\.goog\[cnrm-system\/cnrm-controller-manager-)(?P<projectID>\S+)(?P<suffix>\])
group: iam.cnrm.cloud.google.com
version: v1beta1
kind: IAMPolicyMember
`

/*
# Test-Only
- path: metadata/name
version: v1
group: apps
kind: Deployment
create: true
*/

/* UNSUPPORTED Project FieldSpec due to substitution/partial-setter
- path: metadata/annotations[cnrm.cloud.google.com/project-id]
group: storage.cnrm.cloud.google.com
version: v1beta1
kind: StorageBucket
create: true

- path: spec/workloadIdentityConfig/identityNamespace
regexPattern: "(\s+)\.svc\.id\.goog"
group: container.cnrm.cloud.google.com
version: v1beta1
kind: ContainerCluster
create: true
- path: spec/networkRef/external
regexPattern: "projects/(\s+)/global/networks/default""
group: container.cnrm.cloud.google.com
version: v1beta1
kind: ContainerCluster
create: true

- path: spec/bindings[]/members[]/member
regexPattern: "^serviceAccount:\s+@(\s+).iam.gserviceaccount.com"
group: iam.cnrm.cloud.google.com
version: v1beta1
kind: IAMPartialPolicy
create: true
- path: spec/authority/issuer
regexPattern: "https://container.googleapis.com/v1/projects/(\s+)/locations/\s+/clusters/\s+"
group: gkehub.cnrm.cloud.google.com
version: v1beta1
kind: GKEHubMembership
- path: spec/endpoint/gkeCluster/resourceRef/external
regexPattern: "//container.googleapis.com/projects/(\s+)/locations/\s+/clusters/\s+"
group: gkehub.cnrm.cloud.google.com
version: v1beta1
kind: GKEHubMembership
create: true
- path: spec/projectRef/external
regexPattern: "//container.googleapis.com/projects/(\s+)/locations/\s+/clusters/\s+"
group: gkehub.cnrm.cloud.google.com
version: v1beta1
kind: GKEHubFeature
create: true
- path: spec/projectRef/configmanagement/configSync/git/gcpServiceAccountRef/external
regexPattern: "\s+@(\s+).iam.gserviceaccount.com"
group: gkehub.cnrm.cloud.google.com
version: v1beta1
kind: GKEHubFeatureMembership
create: true
*/
74 changes: 74 additions & 0 deletions functions/go/gcp-set-project-id/custom/filter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package custom

import (
"regexp"

"sigs.k8s.io/kustomize/api/filters/fieldspec"
"sigs.k8s.io/kustomize/api/filters/filtersutil"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/yaml"
)

var _ kio.Filter = Filter{}

type Filter struct {
ProjectID string
FsSlice []types.FieldSpec
}

func (f Filter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
_, err := kio.FilterAll(yaml.FilterFunc(
func(node *yaml.RNode) (*yaml.RNode, error) {
var fns []yaml.Filter
for _, fs := range f.FsSlice {

fn := fieldspec.Filter{
SetValue: f.updateProjectIDFn(fs.RegexPattern),
FieldSpec: fs,
}
fns = append(fns, fn)
}
return node.Pipe(fns...)
})).Filter(nodes)
return nodes, err
}

func (f Filter) updateProjectIDFn(regexPath string) filtersutil.SetFn {
return func(node *yaml.RNode) (err error) {
if regexPath == "" {
return node.PipeE(updater{ProjectID: f.ProjectID})
}
defer func() {
// recover from regex panic.
if recover() != nil {
// err = fmt.Errorf("invalid regex pattern %v", regexPath)
}
}()
re := regexp.MustCompile(regexPath)
match := re.FindStringSubmatch(node.YNode().Value)
namedGroup := make(map[string]string)
for i, name := range re.SubexpNames() {
if i != 0 && name != "" {
namedGroup[name] = match[i]
}
}
newProjectID := ""
if prefix, ok := namedGroup["prefix"]; ok {
newProjectID = newProjectID + prefix
}
newProjectID = newProjectID + f.ProjectID
if suffix, ok := namedGroup["suffix"]; ok {
newProjectID = newProjectID + suffix
}
return node.PipeE(updater{ProjectID: newProjectID})
}
}

type updater struct {
ProjectID string
}

func (u updater) Filter(rn *yaml.RNode) (*yaml.RNode, error) {
return rn.Pipe(yaml.FieldSetter{StringValue: u.ProjectID})
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
module github.com/GoogleContainerTools/kpt-functions-catalog/functions/go/set-project-id
module github.com/GoogleContainerTools/kpt-functions-catalog/functions/go/gcp-set-project-id

go 1.17

require (
github.com/GoogleContainerTools/kpt-functions-sdk/go v0.0.0-20210810181223-632b30549de6
sigs.k8s.io/kustomize/kyaml v0.11.0
sigs.k8s.io/kustomize/api v0.11.1
sigs.k8s.io/kustomize/kyaml v0.13.3
sigs.k8s.io/yaml v1.3.0
)

require (
Expand All @@ -20,13 +21,15 @@ require (
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/spf13/cobra v1.0.0 // indirect
github.com/spf13/cobra v1.2.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/stretchr/testify v1.7.0 // indirect
github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca // indirect
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e // indirect
golang.org/x/text v0.3.2 // indirect
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 // indirect
golang.org/x/text v0.3.5 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e // indirect
)

replace sigs.k8s.io/kustomize/api => ./thirdparty/kustomize/api
Loading