From 3701b7200261f32aeb44c89f1df623f60b0d8a76 Mon Sep 17 00:00:00 2001 From: El Mehdi Rami Date: Mon, 6 Feb 2023 01:29:05 +0100 Subject: [PATCH] feat: add plugin entrypoint --- plugin/v1/api.go | 4 +- plugin/v1/cmd/cmd.go | 85 ++++++++++++++++++++++++++++++++++ plugin/v1/exec/main.go | 25 ++++++++++ plugin/v1/scaffolds/api-new.go | 33 +++++++++++++ plugin/v1/scaffolds/init.go | 33 +++++++++++++ 5 files changed, 178 insertions(+), 2 deletions(-) create mode 100644 plugin/v1/cmd/cmd.go create mode 100644 plugin/v1/exec/main.go create mode 100644 plugin/v1/scaffolds/api-new.go create mode 100644 plugin/v1/scaffolds/init.go diff --git a/plugin/v1/api.go b/plugin/v1/api.go index c4efdb42..86f35b79 100644 --- a/plugin/v1/api.go +++ b/plugin/v1/api.go @@ -20,12 +20,12 @@ import ( "errors" "fmt" + "sigs.k8s.io/kubebuilder-declarative-pattern/plugin/v1/scaffolds" "sigs.k8s.io/kubebuilder/v3/pkg/config" "sigs.k8s.io/kubebuilder/v3/pkg/machinery" "sigs.k8s.io/kubebuilder/v3/pkg/model/resource" "sigs.k8s.io/kubebuilder/v3/pkg/plugin" "sigs.k8s.io/kubebuilder/v3/pkg/plugin/util" - "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/declarative/v1/scaffolds" goPluginV2 "sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v2" ) @@ -111,7 +111,7 @@ func (p *createAPISubcommand) Scaffold(fs machinery.Filesystem) error { 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 { - // Fail unless they key wasn't found, which just means it is the first resource tracked + // Fail unless the key wasn't found, which just means it is the first resource tracked if err != nil && !errors.As(err, &config.PluginKeyNotFoundError{}) { return err } diff --git a/plugin/v1/cmd/cmd.go b/plugin/v1/cmd/cmd.go new file mode 100644 index 00000000..93e97cbb --- /dev/null +++ b/plugin/v1/cmd/cmd.go @@ -0,0 +1,85 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cmd + +import ( + "bufio" + "encoding/json" + "fmt" + "io" + "log" + "os" + + "sigs.k8s.io/kubebuilder/v3/pkg/plugin/external" +) + +const ( + commandInit = "init" + commandCreateApi = "create api" +) + +func returnError(err error) { + response := external.PluginResponse{ + Error: true, + ErrorMsgs: []string{err.Error()}, + } + + output, err := json.Marshal(response) + if err != nil { + log.Fatalf("encountered error serializing output: %s | output: %s", err.Error(), output) + } + fmt.Printf("%s", output) +} + +// Run will run the steps defined by the plugin +func Run() { + // Kubebuilder makes requests to external plugin by writing STDIN. + reader := bufio.NewReader(os.Stdin) + + input, err := io.ReadAll(reader) + if err != nil { + returnError(fmt.Errorf("encountered error reading from STDIN: %+v", err)) + } + + // Parsing request sent by kubebuilder into a PluginRequest instance. + pluginRequest := &external.PluginRequest{} + + if err = json.Unmarshal(input, pluginRequest); err != nil { + returnError(err) + } + + // Run logic based on the command executed by Kubebuilder. + var response external.PluginResponse + switch pluginRequest.Command { + case commandInit: + // handle init command + case commandCreateApi: + // handle create api command + default: + response = external.PluginResponse{ + Error: true, + ErrorMsgs: []string{"unknown subcommand:" + pluginRequest.Command}, + } + } + + output, err := json.Marshal(response) + if err != nil { + returnError(err) + } + + fmt.Printf("%s", output) +} diff --git a/plugin/v1/exec/main.go b/plugin/v1/exec/main.go new file mode 100644 index 00000000..289ab298 --- /dev/null +++ b/plugin/v1/exec/main.go @@ -0,0 +1,25 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "sigs.k8s.io/kubebuilder-declarative-pattern/plugin/v1/cmd" +) + +func main() { + cmd.Run() +} diff --git a/plugin/v1/scaffolds/api-new.go b/plugin/v1/scaffolds/api-new.go new file mode 100644 index 00000000..801895d3 --- /dev/null +++ b/plugin/v1/scaffolds/api-new.go @@ -0,0 +1,33 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package scaffolds + +import ( + "sigs.k8s.io/kubebuilder/v3/pkg/plugin/external" +) + +// ApiCmd handles all the logic for the `create api` subcommand +func ApiCmd(pr *external.PluginRequest) external.PluginResponse { + pluginResponse := external.PluginResponse{ + Command: "init", + Universe: pr.Universe, + } + + // TODO(@em-r): add logic for handling `create api` command + + return pluginResponse +} diff --git a/plugin/v1/scaffolds/init.go b/plugin/v1/scaffolds/init.go new file mode 100644 index 00000000..d03a9da6 --- /dev/null +++ b/plugin/v1/scaffolds/init.go @@ -0,0 +1,33 @@ +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package scaffolds + +import ( + "sigs.k8s.io/kubebuilder/v3/pkg/plugin/external" +) + +// InitCmd handles all the logic for the `init` subcommand +func InitCmd(pr *external.PluginRequest) external.PluginResponse { + pluginResponse := external.PluginResponse{ + Command: "init", + Universe: pr.Universe, + } + + // TODO(@em-r): add logic for handling `init` command + + return pluginResponse +}