Skip to content

Commit 61fbd5a

Browse files
authored
Merge pull request #5166 from camilamacedo86/fix-domain
🐛 (fix): Fix plugin configuration tracking when wrapped in bundles with custom domains
2 parents 85e11a8 + d3a0558 commit 61fbd5a

File tree

22 files changed

+690
-81
lines changed

22 files changed

+690
-81
lines changed

pkg/cli/alpha/internal/generate.go

Lines changed: 101 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -243,12 +243,41 @@ func kubebuilderCreate(s store.Store) error {
243243
// Migrates the Grafana plugin.
244244
func migrateGrafanaPlugin(s store.Store, src, des string) error {
245245
var grafanaPlugin struct{}
246-
err := s.Config().DecodePluginConfig(plugin.KeyFor(grafanav1alpha.Plugin{}), grafanaPlugin)
247-
if errors.As(err, &config.PluginKeyNotFoundError{}) {
246+
key := plugin.GetPluginKeyForConfig(s.Config().GetPluginChain(), grafanav1alpha.Plugin{})
247+
canonicalKey := plugin.KeyFor(grafanav1alpha.Plugin{})
248+
found := true
249+
var err error
250+
251+
if err = s.Config().DecodePluginConfig(key, grafanaPlugin); err != nil {
252+
switch {
253+
case errors.As(err, &config.PluginKeyNotFoundError{}):
254+
found = false
255+
if key != canonicalKey {
256+
if err = s.Config().DecodePluginConfig(canonicalKey, grafanaPlugin); err != nil {
257+
switch {
258+
case errors.As(err, &config.PluginKeyNotFoundError{}):
259+
// still not found
260+
case errors.As(err, &config.UnsupportedFieldError{}):
261+
slog.Info("Project config version does not support plugin metadata, skipping Grafana migration")
262+
return nil
263+
default:
264+
return fmt.Errorf("failed to decode grafana plugin config: %w", err)
265+
}
266+
} else {
267+
found = true
268+
}
269+
}
270+
case errors.As(err, &config.UnsupportedFieldError{}):
271+
slog.Info("Project config version does not support plugin metadata, skipping Grafana migration")
272+
return nil
273+
default:
274+
return fmt.Errorf("failed to decode grafana plugin config: %w", err)
275+
}
276+
}
277+
278+
if !found {
248279
slog.Info("Grafana plugin not found, skipping migration")
249280
return nil
250-
} else if err != nil {
251-
return fmt.Errorf("failed to decode grafana plugin config: %w", err)
252281
}
253282

254283
if err = kubebuilderGrafanaEdit(); err != nil {
@@ -264,30 +293,89 @@ func migrateGrafanaPlugin(s store.Store, src, des string) error {
264293

265294
func migrateAutoUpdatePlugin(s store.Store) error {
266295
var autoUpdatePlugin struct{}
267-
err := s.Config().DecodePluginConfig(plugin.KeyFor(autoupdatev1alpha.Plugin{}), autoUpdatePlugin)
268-
if errors.As(err, &config.PluginKeyNotFoundError{}) {
296+
key := plugin.GetPluginKeyForConfig(s.Config().GetPluginChain(), autoupdatev1alpha.Plugin{})
297+
canonicalKey := plugin.KeyFor(autoupdatev1alpha.Plugin{})
298+
found := true
299+
var err error
300+
301+
if err = s.Config().DecodePluginConfig(key, autoUpdatePlugin); err != nil {
302+
switch {
303+
case errors.As(err, &config.PluginKeyNotFoundError{}):
304+
found = false
305+
if key != canonicalKey {
306+
if err = s.Config().DecodePluginConfig(canonicalKey, autoUpdatePlugin); err != nil {
307+
switch {
308+
case errors.As(err, &config.PluginKeyNotFoundError{}):
309+
// still not found
310+
case errors.As(err, &config.UnsupportedFieldError{}):
311+
slog.Info("Project config version does not support plugin metadata, skipping Auto Update migration")
312+
return nil
313+
default:
314+
return fmt.Errorf("failed to decode autoupdate plugin config: %w", err)
315+
}
316+
} else {
317+
found = true
318+
}
319+
}
320+
case errors.As(err, &config.UnsupportedFieldError{}):
321+
slog.Info("Project config version does not support plugin metadata, skipping Auto Update migration")
322+
return nil
323+
default:
324+
return fmt.Errorf("failed to decode autoupdate plugin config: %w", err)
325+
}
326+
}
327+
328+
if !found {
269329
slog.Info("Auto Update plugin not found, skipping migration")
270330
return nil
271-
} else if err != nil {
272-
return fmt.Errorf("failed to decode autoupdate plugin config: %w", err)
273331
}
274332

275333
args := []string{"edit", "--plugins", plugin.KeyFor(autoupdatev1alpha.Plugin{})}
276-
if err := util.RunCmd("kubebuilder edit", "kubebuilder", args...); err != nil {
334+
if err = util.RunCmd("kubebuilder edit", "kubebuilder", args...); err != nil {
277335
return fmt.Errorf("failed to run edit subcommand for Auto plugin: %w", err)
278336
}
279337
return nil
280338
}
281339

282340
// Migrates the Deploy Image plugin.
283341
func migrateDeployImagePlugin(s store.Store) error {
342+
key := plugin.GetPluginKeyForConfig(s.Config().GetPluginChain(), deployimagev1alpha1.Plugin{})
343+
canonicalKey := plugin.KeyFor(deployimagev1alpha1.Plugin{})
284344
var deployImagePlugin deployimagev1alpha1.PluginConfig
285-
err := s.Config().DecodePluginConfig(plugin.KeyFor(deployimagev1alpha1.Plugin{}), &deployImagePlugin)
286-
if errors.As(err, &config.PluginKeyNotFoundError{}) {
345+
found := true
346+
347+
var err error
348+
err = s.Config().DecodePluginConfig(key, &deployImagePlugin)
349+
if err != nil {
350+
switch {
351+
case errors.As(err, &config.PluginKeyNotFoundError{}):
352+
found = false
353+
if key != canonicalKey {
354+
if err = s.Config().DecodePluginConfig(canonicalKey, &deployImagePlugin); err != nil {
355+
switch {
356+
case errors.As(err, &config.PluginKeyNotFoundError{}):
357+
// still not found
358+
case errors.As(err, &config.UnsupportedFieldError{}):
359+
slog.Info("Project config version does not support plugin metadata, skipping Deploy Image migration")
360+
return nil
361+
default:
362+
return fmt.Errorf("failed to decode deploy-image plugin config: %w", err)
363+
}
364+
} else {
365+
found = true
366+
}
367+
}
368+
case errors.As(err, &config.UnsupportedFieldError{}):
369+
slog.Info("Project config version does not support plugin metadata, skipping Deploy Image migration")
370+
return nil
371+
default:
372+
return fmt.Errorf("failed to decode deploy-image plugin config: %w", err)
373+
}
374+
}
375+
376+
if !found {
287377
slog.Info("Deploy-image plugin not found, skipping migration")
288378
return nil
289-
} else if err != nil {
290-
return fmt.Errorf("failed to decode deploy-image plugin config: %w", err)
291379
}
292380

293381
for _, r := range deployImagePlugin.Resources {

pkg/cli/cli_test.go

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import (
3030
"sigs.k8s.io/kubebuilder/v4/pkg/config"
3131
cfgv3 "sigs.k8s.io/kubebuilder/v4/pkg/config/v3"
3232
"sigs.k8s.io/kubebuilder/v4/pkg/machinery"
33+
"sigs.k8s.io/kubebuilder/v4/pkg/model/resource"
3334
"sigs.k8s.io/kubebuilder/v4/pkg/model/stage"
3435
"sigs.k8s.io/kubebuilder/v4/pkg/plugin"
3536
golangv4 "sigs.k8s.io/kubebuilder/v4/pkg/plugins/golang/v4"
@@ -89,6 +90,56 @@ func (s *pluginChainCapturingSubcommand) SetPluginChain(chain []string) {
8990
s.pluginChain = append([]string(nil), chain...)
9091
}
9192

93+
type testCreateAPIPlugin struct {
94+
name string
95+
version plugin.Version
96+
subcommand *testCreateAPISubcommand
97+
projectVers []config.Version
98+
}
99+
100+
func newTestCreateAPIPlugin(name string, version plugin.Version) testCreateAPIPlugin {
101+
return testCreateAPIPlugin{
102+
name: name,
103+
version: version,
104+
subcommand: &testCreateAPISubcommand{},
105+
projectVers: []config.Version{{Number: 3}},
106+
}
107+
}
108+
109+
func (p testCreateAPIPlugin) Name() string { return p.name }
110+
func (p testCreateAPIPlugin) Version() plugin.Version { return p.version }
111+
func (p testCreateAPIPlugin) SupportedProjectVersions() []config.Version { return p.projectVers }
112+
func (p testCreateAPIPlugin) GetCreateAPISubcommand() plugin.CreateAPISubcommand {
113+
return p.subcommand
114+
}
115+
116+
type testCreateAPISubcommand struct{}
117+
118+
func (s *testCreateAPISubcommand) InjectResource(*resource.Resource) error {
119+
return nil
120+
}
121+
122+
func (s *testCreateAPISubcommand) Scaffold(machinery.Filesystem) error {
123+
return nil
124+
}
125+
126+
type fakeStore struct {
127+
cfg config.Config
128+
}
129+
130+
func (f *fakeStore) New(config.Version) error { return nil }
131+
func (f *fakeStore) Load() error { return nil }
132+
func (f *fakeStore) LoadFrom(string) error { return nil }
133+
func (f *fakeStore) Save() error { return nil }
134+
func (f *fakeStore) SaveTo(string) error { return nil }
135+
func (f *fakeStore) Config() config.Config { return f.cfg }
136+
137+
type captureSubcommand struct {
138+
lastChain []string
139+
}
140+
141+
func (c *captureSubcommand) Scaffold(machinery.Filesystem) error { return nil }
142+
92143
var _ = Describe("CLI", func() {
93144
var (
94145
c *CLI
@@ -103,6 +154,83 @@ var _ = Describe("CLI", func() {
103154
projectVersion = config.Version{Number: 3}
104155
})
105156

157+
Describe("filterSubcommands", func() {
158+
It("propagates bundle keys to wrapped subcommands", func() {
159+
bundleVersion := plugin.Version{Number: 1, Stage: stage.Alpha}
160+
161+
fooPlugin := newTestCreateAPIPlugin("deploy-image.go.kubebuilder.io", plugin.Version{Number: 1, Stage: stage.Alpha})
162+
barPlugin := newTestCreateAPIPlugin("deploy-image.go.kubebuilder.io", plugin.Version{Number: 1, Stage: stage.Alpha})
163+
164+
fooBundle, err := plugin.NewBundleWithOptions(
165+
plugin.WithName("deploy-image.foo.example.com"),
166+
plugin.WithVersion(bundleVersion),
167+
plugin.WithPlugins(fooPlugin),
168+
)
169+
Expect(err).NotTo(HaveOccurred())
170+
171+
barBundle, err := plugin.NewBundleWithOptions(
172+
plugin.WithName("deploy-image.bar.example.com"),
173+
plugin.WithVersion(bundleVersion),
174+
plugin.WithPlugins(barPlugin),
175+
)
176+
Expect(err).NotTo(HaveOccurred())
177+
178+
c.resolvedPlugins = []plugin.Plugin{fooBundle, barBundle}
179+
180+
tuples := c.filterSubcommands(
181+
func(p plugin.Plugin) bool {
182+
_, isCreateAPI := p.(plugin.CreateAPI)
183+
return isCreateAPI
184+
},
185+
func(p plugin.Plugin) plugin.Subcommand {
186+
return p.(plugin.CreateAPI).GetCreateAPISubcommand()
187+
},
188+
)
189+
190+
Expect(tuples).To(HaveLen(2))
191+
Expect(tuples[0].key).To(Equal("deploy-image.go.kubebuilder.io/v1-alpha"))
192+
Expect(tuples[0].configKey).To(Equal("deploy-image.foo.example.com/v1-alpha"))
193+
Expect(tuples[1].key).To(Equal("deploy-image.go.kubebuilder.io/v1-alpha"))
194+
Expect(tuples[1].configKey).To(Equal("deploy-image.bar.example.com/v1-alpha"))
195+
})
196+
})
197+
198+
Describe("executionHooksFactory", func() {
199+
It("temporarily reorders the plugin chain while invoking bundled subcommands", func() {
200+
cfg := cfgv3.New()
201+
Expect(cfg.SetPluginChain([]string{
202+
"deploy-image.foo.example.com/v1-alpha",
203+
"deploy-image.bar.example.com/v1-alpha",
204+
})).To(Succeed())
205+
206+
store := &fakeStore{cfg: cfg}
207+
first := &captureSubcommand{}
208+
second := &captureSubcommand{}
209+
210+
factory := executionHooksFactory{
211+
store: store,
212+
subcommands: []keySubcommandTuple{
213+
{configKey: "deploy-image.foo.example.com/v1-alpha", subcommand: first},
214+
{configKey: "deploy-image.bar.example.com/v1-alpha", subcommand: second},
215+
},
216+
errorMessage: "test",
217+
}
218+
219+
callErr := factory.forEach(func(sub plugin.Subcommand) error {
220+
cs := sub.(*captureSubcommand)
221+
cs.lastChain = append([]string(nil), store.Config().GetPluginChain()...)
222+
return nil
223+
}, "scaffold")
224+
Expect(callErr).NotTo(HaveOccurred())
225+
Expect(first.lastChain[0]).To(Equal("deploy-image.foo.example.com/v1-alpha"))
226+
Expect(second.lastChain[0]).To(Equal("deploy-image.bar.example.com/v1-alpha"))
227+
Expect(store.Config().GetPluginChain()).To(Equal([]string{
228+
"deploy-image.foo.example.com/v1-alpha",
229+
"deploy-image.bar.example.com/v1-alpha",
230+
}))
231+
})
232+
})
233+
106234
Context("buildCmd", func() {
107235
var projectFile string
108236

0 commit comments

Comments
 (0)