Skip to content

Commit 51057c2

Browse files
committed
Add GCP support for service account modules with read and write bucket access management
1 parent 039e37e commit 51057c2

File tree

4 files changed

+113
-0
lines changed

4 files changed

+113
-0
lines changed

modules/helm_chart/module.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
name: helm_chart
22
type: helm_chart
3+
provider: helm
34
version: 1.0.0
45
resources:
56
- helm_release.local_chart

pkg/augment/augment.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ type Context struct {
2323
type Augmentation struct {
2424
IamPolicy map[string]interface{}
2525
KubernetesTrusts []map[string]interface{}
26+
ReadBuckets []string
27+
WriteBuckets []string
2628
SourceModule config.Module
2729
}
2830

@@ -102,6 +104,13 @@ func mergeAugmentation(existing, next Augmentation) Augmentation {
102104
merged.KubernetesTrusts = append(merged.KubernetesTrusts, next.KubernetesTrusts...)
103105
}
104106

107+
if len(next.ReadBuckets) > 0 {
108+
merged.ReadBuckets = append(merged.ReadBuckets, next.ReadBuckets...)
109+
}
110+
if len(next.WriteBuckets) > 0 {
111+
merged.WriteBuckets = append(merged.WriteBuckets, next.WriteBuckets...)
112+
}
113+
105114
if merged.SourceModule.ID == "" {
106115
merged.SourceModule = next.SourceModule
107116
}

pkg/augment/gcp.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package augment
2+
3+
import "pltf/pkg/config"
4+
5+
func init() {
6+
RegisterProviderBuilder("gcp", buildGCP)
7+
RegisterProviderBuilder("google", buildGCP)
8+
}
9+
10+
// buildGCP generates GCS access inputs for GCP service account modules.
11+
func buildGCP(ctx Context) map[string]Augmentation {
12+
result := map[string]Augmentation{}
13+
roleIndex := indexModulesByID(ctx.Modules)
14+
15+
for _, mod := range ctx.Modules {
16+
if !isGcpServiceAccountModule(mod) {
17+
continue
18+
}
19+
20+
bindings := collectBindings(ctx.Modules, mod.ID)
21+
if len(bindings) == 0 {
22+
continue
23+
}
24+
25+
var readBuckets []string
26+
var writeBuckets []string
27+
for _, b := range bindings {
28+
if b.moduleType != "gcp_gcs" {
29+
continue
30+
}
31+
bucketRef := refForModuleOutputInterpolated(ctx, b.moduleID, "bucket_name")
32+
switch b.accessLevel {
33+
case "read":
34+
readBuckets = append(readBuckets, bucketRef)
35+
case "write":
36+
writeBuckets = append(writeBuckets, bucketRef)
37+
case "readwrite", "rw", "admin":
38+
writeBuckets = append(writeBuckets, bucketRef)
39+
}
40+
}
41+
42+
if len(readBuckets) == 0 && len(writeBuckets) == 0 {
43+
continue
44+
}
45+
46+
result[mod.ID] = Augmentation{
47+
ReadBuckets: readBuckets,
48+
WriteBuckets: writeBuckets,
49+
SourceModule: roleIndex[mod.ID],
50+
}
51+
}
52+
53+
return result
54+
}
55+
56+
func isGcpServiceAccountModule(m config.Module) bool {
57+
switch m.Type {
58+
case "gcp_service_account", "gcp_k8s_service":
59+
return true
60+
default:
61+
return false
62+
}
63+
}

pkg/generate/generator.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1128,9 +1128,49 @@ func (g *Generator) applyAugmentations(m config.Module) config.Module {
11281128
m.Inputs["kubernetes_trusts"] = list
11291129
}
11301130

1131+
if len(aug.ReadBuckets) > 0 {
1132+
m.Inputs["read_buckets"] = mergeStringInputs(m.Inputs["read_buckets"], aug.ReadBuckets)
1133+
}
1134+
if len(aug.WriteBuckets) > 0 {
1135+
m.Inputs["write_buckets"] = mergeStringInputs(m.Inputs["write_buckets"], aug.WriteBuckets)
1136+
}
1137+
11311138
return m
11321139
}
11331140

1141+
func mergeStringInputs(existing interface{}, extra []string) []string {
1142+
var out []string
1143+
seen := map[string]struct{}{}
1144+
add := func(val string) {
1145+
if strings.TrimSpace(val) == "" {
1146+
return
1147+
}
1148+
if _, ok := seen[val]; ok {
1149+
return
1150+
}
1151+
seen[val] = struct{}{}
1152+
out = append(out, val)
1153+
}
1154+
1155+
switch v := existing.(type) {
1156+
case []string:
1157+
for _, item := range v {
1158+
add(item)
1159+
}
1160+
case []interface{}:
1161+
for _, item := range v {
1162+
if s, ok := item.(string); ok {
1163+
add(s)
1164+
}
1165+
}
1166+
}
1167+
1168+
for _, item := range extra {
1169+
add(item)
1170+
}
1171+
return out
1172+
}
1173+
11341174
func (g *Generator) replaceIntrinsicPlaceholders(val string, replaceEnvLayer bool) string {
11351175
// Normalize legacy {foo} style to ${foo} so the rest of the pipeline can treat them as expressions.
11361176
val = normalizeCurlyPlaceholders(val)

0 commit comments

Comments
 (0)