diff --git a/pkg/plugins/golang/deploy-image/v1alpha1/api.go b/pkg/plugins/golang/deploy-image/v1alpha1/api.go index 5e256343e5c..8245d7e7906 100644 --- a/pkg/plugins/golang/deploy-image/v1alpha1/api.go +++ b/pkg/plugins/golang/deploy-image/v1alpha1/api.go @@ -219,7 +219,7 @@ func (p *createAPISubcommand) Scaffold(fs machinery.Filesystem) error { } // Track the resources following a declarative approach - cfg := pluginConfig{} + cfg := PluginConfig{} if err := p.config.DecodePluginConfig(pluginKey, &cfg); errors.As(err, &config.UnsupportedFieldError{}) { // Config doesn't support per-plugin configuration, so we can't track them } else { @@ -233,7 +233,7 @@ func (p *createAPISubcommand) Scaffold(fs machinery.Filesystem) error { ContainerPort: p.imageContainerPort, RunAsUser: p.runAsUser, } - cfg.Resources = append(cfg.Resources, resourceData{ + cfg.Resources = append(cfg.Resources, ResourceData{ Group: p.resource.GVK.Group, Domain: p.resource.GVK.Domain, Version: p.resource.GVK.Version, diff --git a/pkg/plugins/golang/deploy-image/v1alpha1/plugin.go b/pkg/plugins/golang/deploy-image/v1alpha1/plugin.go index aadf4398712..8356de8335c 100644 --- a/pkg/plugins/golang/deploy-image/v1alpha1/plugin.go +++ b/pkg/plugins/golang/deploy-image/v1alpha1/plugin.go @@ -51,11 +51,11 @@ func (Plugin) SupportedProjectVersions() []config.Version { return supportedProj // GetCreateAPISubcommand will return the subcommand which is responsible for scaffolding apis func (p Plugin) GetCreateAPISubcommand() plugin.CreateAPISubcommand { return &p.createAPISubcommand } -type pluginConfig struct { - Resources []resourceData `json:"resources,omitempty"` +type PluginConfig struct { + Resources []ResourceData `json:"resources,omitempty"` } -type resourceData struct { +type ResourceData struct { Group string `json:"group,omitempty"` Domain string `json:"domain,omitempty"` Version string `json:"version"` diff --git a/pkg/rescaffold/migrate.go b/pkg/rescaffold/migrate.go index 8f336f752f2..5765c96691f 100644 --- a/pkg/rescaffold/migrate.go +++ b/pkg/rescaffold/migrate.go @@ -28,6 +28,7 @@ import ( "sigs.k8s.io/kubebuilder/v3/pkg/machinery" "sigs.k8s.io/kubebuilder/v3/pkg/model/resource" "sigs.k8s.io/kubebuilder/v3/pkg/plugin/util" + "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/deploy-image/v1alpha1" ) type MigrateOptions struct { @@ -66,7 +67,10 @@ func (opts *MigrateOptions) Rescaffold() error { } // plugin specific migration if err := migrateGrafanaPlugin(config, opts.InputDir, opts.OutputDir); err != nil { - log.Fatalf("Failed to run plugin migration %v", err) + log.Fatalf("Failed to run grafana plugin migration %v", err) + } + if err := migrateDeployImagePlugin(config); err != nil { + log.Fatalf("Failed to run deploy-image plugin migration %v", err) } return nil } @@ -172,6 +176,35 @@ func migrateGrafanaPlugin(store store.Store, src, des string) error { return kubebuilderGrafanaEdit() } +func migrateDeployImagePlugin(store store.Store) error { + deployImagePlugin := v1alpha1.PluginConfig{} + err := store.Config().DecodePluginConfig("deploy-image.go.kubebuilder.io/v1-alpha", &deployImagePlugin) + // If the deploy-image plugin is not found, we don't need to migrate + if err != nil { + if errors.As(err, &config.PluginKeyNotFoundError{}) { + log.Printf("deploy-image plugin is not found, skip the migration") + return nil + } + return fmt.Errorf("failed to decode deploy-image plugin config %v", err) + } + + for _, r := range deployImagePlugin.Resources { + if err = createAPIWithDeployImage(r); err != nil { + return err + } + } + return nil +} + +func createAPIWithDeployImage(resource v1alpha1.ResourceData) error { + var args []string + args = append(args, "create") + args = append(args, "api") + args = append(args, getGVKFlagsFromDeployImage(resource)...) + args = append(args, getDeployImageOptions(resource)...) + return util.RunCmd("kubebuilder create api", "kubebuilder", args...) +} + func getInitArgs(store store.Store) []string { var args []string plugins := store.Config().GetPluginChain() @@ -203,6 +236,38 @@ func getGVKFlags(resource resource.Resource) []string { return args } +func getGVKFlagsFromDeployImage(resource v1alpha1.ResourceData) []string { + var args []string + if len(resource.Group) > 0 { + args = append(args, "--group", resource.Group) + } + if len(resource.Version) > 0 { + args = append(args, "--version", resource.Version) + } + if len(resource.Kind) > 0 { + args = append(args, "--kind", resource.Kind) + } + return args +} + +func getDeployImageOptions(resource v1alpha1.ResourceData) []string { + var args []string + if len(resource.Options.Image) > 0 { + args = append(args, fmt.Sprintf("--image=%s", resource.Options.Image)) + } + if len(resource.Options.ContainerCommand) > 0 { + args = append(args, fmt.Sprintf("--image-container-command=%s", resource.Options.ContainerCommand)) + } + if len(resource.Options.ContainerPort) > 0 { + args = append(args, fmt.Sprintf("--image-container-port=%s", resource.Options.ContainerPort)) + } + if len(resource.Options.RunAsUser) > 0 { + args = append(args, fmt.Sprintf("--run-as-user=%s", resource.Options.RunAsUser)) + } + args = append(args, fmt.Sprintf("--plugins=\"%s\"", "deploy-image/v1-alpha")) + return args +} + func createAPI(resource resource.Resource) error { var args []string args = append(args, "create") diff --git a/test/e2e/alphagenerate/generate_test.go b/test/e2e/alphagenerate/generate_test.go index 9a9a202722e..5745cdad17b 100644 --- a/test/e2e/alphagenerate/generate_test.go +++ b/test/e2e/alphagenerate/generate_test.go @@ -123,6 +123,19 @@ func ReGenerateProject(kbc *utils.TestContext) { ) ExpectWithOffset(1, err).NotTo(HaveOccurred()) + By("create APIs with deploy-image plugin") + err = kbc.CreateAPI( + "--group", "crew", + "--version", "v1", + "--kind", "Memcached", + "--image=memcached:1.6.15-alpine", + "--image-container-command=memcached,-m=64,modern,-v", + "--image-container-port=11211", + "--run-as-user=1001", + "--plugins=\"deploy-image/v1-alpha\"", + ) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + By("Enable grafana plugin to an existing project") err = kbc.Edit( "--plugins", "grafana.kubebuilder.io/v1-alpha", @@ -197,7 +210,24 @@ func ReGenerateProject(kbc *utils.TestContext) { ExpectWithOffset(1, err).NotTo(HaveOccurred()) ExpectWithOffset(1, fileContainsExpr).To(BeTrue()) - By("checking if the project file was generated with the expected controller") + By("checking if the project file was generated with the expected deploy-image plugin fields") + var deployImagePlugin = "deploy-image.go.kubebuilder.io/v1-alpha" + fileContainsExpr, err = pluginutil.HasFileContentWith( + filepath.Join(kbc.Dir, "testdir2", "PROJECT"), deployImagePlugin) + Expect(err).NotTo(HaveOccurred()) + Expect(fileContainsExpr).To(BeTrue()) + var deployImagePluginFields = `kind: Memcached + options: + containerCommand: memcached,-m=64,modern,-v + containerPort: "11211" + image: memcached:1.6.15-alpine + runAsUser: "1001"` + fileContainsExpr, err = pluginutil.HasFileContentWith( + filepath.Join(kbc.Dir, "testdir2", "PROJECT"), deployImagePluginFields) + Expect(err).NotTo(HaveOccurred()) + Expect(fileContainsExpr).To(BeTrue()) + + By("checking if the project file was generated with the expected grafana plugin fields") var grafanaPlugin = "grafana.kubebuilder.io/v1-alpha" fileContainsExpr, err = pluginutil.HasFileContentWith( filepath.Join(kbc.Dir, "testdir2", "PROJECT"), grafanaPlugin)