1 package main
2
3 import (
4 "flag"
5 "fmt"
6 "os"
7 "path/filepath"
8 "strings"
9
10 "github.com/google/go-containerregistry/pkg/name"
11 "sigs.k8s.io/kustomize/api/filters/imagetag"
12 "sigs.k8s.io/kustomize/api/krusty"
13 "sigs.k8s.io/kustomize/api/resmap"
14 "sigs.k8s.io/kustomize/api/types"
15 "sigs.k8s.io/kustomize/kyaml/kio"
16
17 "edge-infra.dev/pkg/k8s/eyaml/fieldspecs"
18 "edge-infra.dev/pkg/k8s/kustomize"
19 )
20
21 var (
22 inKustomizationPath string
23 outManifestsPath string
24 )
25
26 func init() {
27 flag.StringVar(&inKustomizationPath, "src-kustomization", "", "path to source kustomization.yaml")
28 flag.StringVar(&outManifestsPath, "out-manifests", "", "path to generated manifests")
29 }
30
31 func main() {
32 flag.Parse()
33
34 imageFilters := []kio.Filter{}
35
36
37
38 for _, arg := range flag.Args() {
39
40 pair := strings.Split(arg, "=")
41 oldRef := pair[0]
42 pushRefPath := pair[1]
43
44 parsedRef, err := parseRef(pushRefPath)
45 if err != nil {
46 fmt.Printf("%s\n", err)
47 os.Exit(1)
48 }
49
50
51 reg := parsedRef.Context().RegistryStr()
52 repo := parsedRef.Context().RepositoryStr()
53 digest := parsedRef.Identifier()
54
55 newName := filepath.Join(reg, repo)
56
57 f := imagetag.Filter{
58 ImageTag: types.Image{
59 Name: oldRef,
60 NewName: newName,
61 Digest: digest,
62 },
63 FsSlice: fieldspecs.Images,
64 }
65 imageFilters = append(imageFilters, f)
66 }
67
68
69 res, err := krustomize()
70 if err != nil {
71 fmt.Printf("%s\n", err)
72 os.Exit(1)
73 }
74
75
76 resyaml, err := filter(res, imageFilters)
77 if err != nil {
78 fmt.Printf("%s\n", err)
79 os.Exit(1)
80 }
81
82
83 err = os.WriteFile(outManifestsPath, resyaml, 0644)
84 if err != nil {
85 fmt.Printf("failed to write output manifests: %s\n", err)
86 os.Exit(1)
87 }
88 }
89
90
91 func parseRef(path string) (name.Reference, error) {
92 pushRef, err := os.ReadFile(path)
93 if err != nil {
94 return nil, fmt.Errorf("failed to read OCIPushInfo ref file: %w", err)
95 }
96
97 parsedRef, err := name.ParseReference(strings.TrimSpace(string(pushRef)))
98 if err != nil {
99 return nil, fmt.Errorf("failed to parse reference from ref file: %w", err)
100 }
101
102 return parsedRef, nil
103 }
104
105
106 func krustomize() (resmap.ResMap, error) {
107
108
109 cwd, err := os.Getwd()
110 if err != nil {
111 return nil, fmt.Errorf("failed to get current working dir: %w", err)
112 }
113 kfs := &kustomize.FS{FS: os.DirFS(cwd)}
114
115 krustomizer := krusty.MakeKustomizer(
116 &krusty.Options{
117 LoadRestrictions: types.LoadRestrictionsNone,
118 PluginConfig: types.DisabledPluginConfig(),
119 Reorder: krusty.ReorderOptionLegacy,
120 },
121 )
122
123
124 resmap, err := krustomizer.Run(kfs, filepath.Dir(inKustomizationPath))
125 if err != nil {
126 fmt.Printf("failed to krustomize: %s\n", err)
127 os.Exit(1)
128 }
129
130 return resmap, nil
131 }
132
133
134 func filter(resmap resmap.ResMap, imageFilters []kio.Filter) ([]byte, error) {
135 for _, fltr := range imageFilters {
136 err := resmap.ApplyFilter(fltr)
137 if err != nil {
138 return nil, fmt.Errorf("resmap filter execution failed: %w", err)
139 }
140 }
141
142 resyaml, err := resmap.AsYaml()
143 if err != nil {
144 return nil, fmt.Errorf("failed to convert resmap to yaml: %w", err)
145 }
146
147 return resyaml, nil
148 }
149
View as plain text