Move kubernetes client processes into plugins
This commit is contained in:
parent
35ed575fbc
commit
df6b11515b
cmd
internal/test
pkg/plugin
plugins/internal
24
cmd/root.go
24
cmd/root.go
@ -7,7 +7,6 @@ import (
|
||||
"os"
|
||||
|
||||
"github.com/ian-howell/airshipctl/pkg/environment"
|
||||
"github.com/ian-howell/airshipctl/pkg/kube"
|
||||
"github.com/ian-howell/airshipctl/pkg/log"
|
||||
"github.com/ian-howell/airshipctl/pkg/plugin"
|
||||
|
||||
@ -18,7 +17,7 @@ var settings environment.AirshipCTLSettings
|
||||
|
||||
// NewRootCmd creates the root `airshipctl` command. All other commands are
|
||||
// subcommands branching from this one
|
||||
func NewRootCmd(out io.Writer, client *kube.Client, args []string) (*cobra.Command, error) {
|
||||
func NewRootCmd(out io.Writer, args []string) (*cobra.Command, error) {
|
||||
rootCmd := &cobra.Command{
|
||||
Use: "airshipctl",
|
||||
Short: "airshipctl is a unified entrypoint to various airship components",
|
||||
@ -26,30 +25,27 @@ func NewRootCmd(out io.Writer, client *kube.Client, args []string) (*cobra.Comma
|
||||
rootCmd.SetOutput(out)
|
||||
|
||||
// Settings flags - This section should probably be moved to pkg/environment
|
||||
rootCmd.PersistentFlags().StringVar(&settings.KubeConfigFilePath, "kubeconfig", "", "path to kubeconfig")
|
||||
rootCmd.PersistentFlags().BoolVar(&settings.Debug, "debug", false, "enable verbose output")
|
||||
|
||||
rootCmd.AddCommand(NewVersionCommand(out))
|
||||
|
||||
workflowPlugin := "plugins/internal/workflow.so"
|
||||
if _, err := os.Stat(workflowPlugin); err == nil {
|
||||
rootCmd.AddCommand(plugin.CreateCommandFromPlugin(workflowPlugin, out, args))
|
||||
}
|
||||
|
||||
if err := rootCmd.PersistentFlags().Parse(args); err != nil {
|
||||
return nil, errors.New("could not parse flags: " + err.Error())
|
||||
}
|
||||
|
||||
log.Init(&settings, out)
|
||||
|
||||
rootCmd.AddCommand(NewVersionCommand(out, client))
|
||||
|
||||
workflowPlugin := "plugins/internal/workflow.so"
|
||||
if _, err := os.Stat(workflowPlugin); err == nil {
|
||||
rootCmd.AddCommand(plugin.CreateCommandFromPlugin(workflowPlugin, out, settings.KubeConfigFilePath))
|
||||
}
|
||||
|
||||
return rootCmd, nil
|
||||
}
|
||||
|
||||
// Execute runs the base airshipctl command
|
||||
func Execute(out io.Writer) {
|
||||
// TODO(howell): Fix this unused error
|
||||
client, _ := kube.NewForConfig(settings.KubeConfigFilePath)
|
||||
|
||||
rootCmd, err := NewRootCmd(out, client, os.Args[1:])
|
||||
rootCmd, err := NewRootCmd(out, os.Args[1:])
|
||||
osExitIfError(out, err)
|
||||
osExitIfError(out, rootCmd.Execute())
|
||||
}
|
||||
|
10
cmd/testdata/TestRootGoldenOutput/default.golden
vendored
10
cmd/testdata/TestRootGoldenOutput/default.golden
vendored
@ -5,14 +5,10 @@ Usage:
|
||||
|
||||
Available Commands:
|
||||
help Help about any command
|
||||
version Show the version number of airshipctl and its underlying tools
|
||||
version Show the version number of airshipctl
|
||||
|
||||
Flags:
|
||||
--debug enable verbose output
|
||||
-h, --help help for airshipctl
|
||||
--kubeconfig string path to kubeconfig
|
||||
|
||||
Additional help topics:
|
||||
airshipctl workflow access to workflows
|
||||
--debug enable verbose output
|
||||
-h, --help help for airshipctl
|
||||
|
||||
Use "airshipctl [command] --help" for more information about a command.
|
||||
|
@ -1,2 +1 @@
|
||||
client: v0.1.0
|
||||
kubernetes server: v0.0.0-master+$Format:%h$
|
||||
airshipctl: v0.1.0
|
||||
|
@ -6,34 +6,18 @@ import (
|
||||
"text/tabwriter"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
kube "github.com/ian-howell/airshipctl/pkg/kube"
|
||||
)
|
||||
|
||||
const versionLong = `Show the versions for the airshipctl tool and its components.
|
||||
This includes the following components, in order:
|
||||
* airshipctl client
|
||||
* kubernetes cluster
|
||||
`
|
||||
|
||||
// NewVersionCommand prints out the versions of airshipctl and its underlying tools
|
||||
func NewVersionCommand(out io.Writer, client *kube.Client) *cobra.Command {
|
||||
func NewVersionCommand(out io.Writer) *cobra.Command {
|
||||
versionCmd := &cobra.Command{
|
||||
Use: "version",
|
||||
Short: "Show the version number of airshipctl and its underlying tools",
|
||||
Long: versionLong,
|
||||
Short: "Show the version number of airshipctl",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
clientV := clientVersion()
|
||||
kubeV, err := kubeVersion(client)
|
||||
if err != nil {
|
||||
fmt.Fprintf(out, "Could not get kubernetes version")
|
||||
return
|
||||
}
|
||||
|
||||
w := tabwriter.NewWriter(out, 0, 0, 1, ' ', 0)
|
||||
defer w.Flush()
|
||||
fmt.Fprintf(w, "%s:\t%s\n", "client", clientV)
|
||||
fmt.Fprintf(w, "%s:\t%s\n", "kubernetes server", kubeV)
|
||||
fmt.Fprintf(w, "%s:\t%s\n", "airshipctl", clientV)
|
||||
},
|
||||
}
|
||||
return versionCmd
|
||||
@ -43,14 +27,3 @@ func clientVersion() string {
|
||||
// TODO(howell): There's gotta be a smarter way to do this
|
||||
return "v0.1.0"
|
||||
}
|
||||
|
||||
func kubeVersion(client *kube.Client) (string, error) {
|
||||
if client == nil {
|
||||
return "could not connect to a kubernetes cluster", nil
|
||||
}
|
||||
version, err := client.Discovery().ServerVersion()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return version.String(), nil
|
||||
}
|
||||
|
@ -10,8 +10,6 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/ian-howell/airshipctl/cmd"
|
||||
"github.com/ian-howell/airshipctl/pkg/kube"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
)
|
||||
|
||||
// UpdateGolden writes out the golden files with the latest values, rather than failing the test.
|
||||
@ -42,10 +40,9 @@ func RunCmdTests(t *testing.T, tests []CmdTest) {
|
||||
|
||||
func executeCmd(t *testing.T, command string) []byte {
|
||||
var actual bytes.Buffer
|
||||
client := &kube.Client{Interface: fake.NewSimpleClientset()}
|
||||
// TODO(howell): switch to shellwords (or similar)
|
||||
args := strings.Fields(command)
|
||||
rootCmd, err := cmd.NewRootCmd(&actual, client, args)
|
||||
rootCmd, err := cmd.NewRootCmd(&actual, args)
|
||||
if err != nil {
|
||||
t.Fatalf(err.Error())
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func CreateCommandFromPlugin(pluginPath string, out io.Writer, configPath string) *cobra.Command {
|
||||
func CreateCommandFromPlugin(pluginPath string, out io.Writer, args []string) *cobra.Command {
|
||||
//TODO(howell): Remove these panics
|
||||
plug, err := plugin.Open(pluginPath)
|
||||
if err != nil {
|
||||
@ -17,9 +17,9 @@ func CreateCommandFromPlugin(pluginPath string, out io.Writer, configPath string
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
command, ok := cmdSym.(func(io.Writer, string) *cobra.Command)
|
||||
command, ok := cmdSym.(func(io.Writer, []string) *cobra.Command)
|
||||
if !ok {
|
||||
panic("NewCommand does not meet the interface.")
|
||||
}
|
||||
return command(out, configPath)
|
||||
return command(out, args)
|
||||
}
|
||||
|
@ -13,46 +13,55 @@ import (
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
)
|
||||
|
||||
func NewCommand(out io.Writer, configPath string) *cobra.Command {
|
||||
//nolint:unused
|
||||
var kubeConfigFilePath string
|
||||
|
||||
//nolint:deadcode,unused
|
||||
func NewCommand(out io.Writer, args []string) *cobra.Command {
|
||||
workflowRootCmd := &cobra.Command{
|
||||
Use: "workflow",
|
||||
Short: "access to workflows",
|
||||
Aliases: []string{"workflows", "wf"},
|
||||
}
|
||||
|
||||
workflowRootCmd.AddCommand(NewWorkflowListCommand(out, configPath))
|
||||
workflowRootCmd.PersistentFlags().StringVar(&kubeConfigFilePath, "kubeconfig", "", "path to kubeconfig")
|
||||
workflowRootCmd.AddCommand(NewWorkflowListCommand(out, args))
|
||||
|
||||
return workflowRootCmd
|
||||
}
|
||||
|
||||
func NewWorkflowListCommand(out io.Writer, configPath string) *cobra.Command {
|
||||
//nolint:unused
|
||||
func NewWorkflowListCommand(out io.Writer, args []string) *cobra.Command {
|
||||
|
||||
config, err := clientcmd.BuildConfigFromFlags("", configPath)
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
v1alpha1.AddToScheme(scheme.Scheme)
|
||||
|
||||
crdConfig := *config
|
||||
crdConfig.ContentConfig.GroupVersion = &v1alpha1.SchemeGroupVersion
|
||||
crdConfig.APIPath = "/apis"
|
||||
crdConfig.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: scheme.Codecs}
|
||||
crdConfig.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||
|
||||
exampleRestClient, err := rest.UnversionedRESTClientFor(&crdConfig)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// TODO(howell): This is only used to appease the linter. It will be used later
|
||||
_ = args
|
||||
|
||||
workflowRootCmd := &cobra.Command{
|
||||
Use: "list",
|
||||
Short: "list workflows",
|
||||
Aliases: []string{"ls"},
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
wflist := v1alpha1.WorkflowList{}
|
||||
if kubeConfigFilePath == "" {
|
||||
kubeConfigFilePath = clientcmd.RecommendedHomeFile
|
||||
}
|
||||
config, err := clientcmd.BuildConfigFromFlags("", kubeConfigFilePath)
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
err := exampleRestClient.
|
||||
crdConfig := *config
|
||||
crdConfig.ContentConfig.GroupVersion = &v1alpha1.SchemeGroupVersion
|
||||
crdConfig.APIPath = "/apis"
|
||||
crdConfig.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: scheme.Codecs}
|
||||
crdConfig.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||
|
||||
exampleRestClient, err := rest.UnversionedRESTClientFor(&crdConfig)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
wflist := v1alpha1.WorkflowList{}
|
||||
err = exampleRestClient.
|
||||
Get().
|
||||
Resource("workflows").
|
||||
Do().
|
||||
|
Loading…
x
Reference in New Issue
Block a user