Skip to content

Commit

Permalink
added import command
Browse files Browse the repository at this point in the history
  • Loading branch information
sbueringer committed Sep 15, 2018
1 parent d106d04 commit b63309c
Show file tree
Hide file tree
Showing 10 changed files with 179 additions and 3 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ clouds:
````

*Note*: The cloud/project_name is automatically discovered from the current kube context. E.g. a kube context named `i01p015-cluster-admin` leads to a cloud/project_name of `i01p015`.
*Note*: The clouds.yaml file can be created from `.rc` files via the `import-config` sub command.

# Usage

Expand Down
1 change: 1 addition & 0 deletions pkg/cmd/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"config_import.go",
"kubernetes.go",
"lb.go",
"openstack.go",
Expand Down
156 changes: 156 additions & 0 deletions pkg/cmd/config_import.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
package cmd

import (
"fmt"
"io/ioutil"
"os"
"path"
"regexp"
"strings"

"github.com/spf13/cobra"
"gopkg.in/yaml.v2"
"k8s.io/cli-runtime/pkg/genericclioptions"
)

type ImportConfigOptions struct {
configFlags *genericclioptions.ConfigFlags

fromDir string
openstackConfigFile string

genericclioptions.IOStreams
}

var (
importConfigExample = `
# import config
export OPENSTACK_CONFIG_FILE=~/clouds.yaml
%[1]s import-config --from-dir ~/openstack/tenants/
`
)

func NewCmdImportConfig(streams genericclioptions.IOStreams) *cobra.Command {
o := &ImportConfigOptions{
configFlags: genericclioptions.NewConfigFlags(),
IOStreams: streams,
}
cmd := &cobra.Command{
Use: "import-config",
Aliases: []string{"rc"},
Short: "Import config from OpenStack rc files.",
Example: fmt.Sprintf(importConfigExample, "kubectl os"),
SilenceUsage: true,
RunE: func(c *cobra.Command, args []string) error {
if err := o.Complete(c, args); err != nil {
return err
}
if err := o.Validate(); err != nil {
return err
}
if err := o.Run(); err != nil {
return err
}
return nil
},
}
cmd.Flags().StringVar(&o.fromDir, "from-dir", o.fromDir, "dir where the rc files are located")
o.configFlags.AddFlags(cmd.Flags())
return cmd
}

func (o *ImportConfigOptions) Complete(cmd *cobra.Command, args []string) error {
o.openstackConfigFile = os.Getenv("OPENSTACK_CONFIG_FILE")
return nil
}

func (o *ImportConfigOptions) Validate() error {
if o.fromDir == "" {
return fmt.Errorf("--from-dir is mandatory")
}
if o.openstackConfigFile == "" {
return fmt.Errorf("env var 'OPENSTACK_CONFIG_FILE' must be set")
}
return nil
}

func (o *ImportConfigOptions) Run() error {

files, err := ioutil.ReadDir(o.fromDir)
if err != nil {
return fmt.Errorf("error reading dir %s: %v", o.fromDir, err)
}

usernameRegEx := regexp.MustCompile("OS_USERNAME='(.*)'")
passwordRegEx := regexp.MustCompile("OS_PASSWORD='(.*)'")
tenantNameRegEx := regexp.MustCompile("OS_TENANT_NAME=['\"](.*)['\"]")
authUrlRegEx := regexp.MustCompile("OS_AUTH_URL='(.*)'")

clouds := clouds{}
clouds.Clouds = map[string]cloud{}
for _, f := range files {
if strings.HasSuffix(f.Name(), ".creds") {

fmt.Printf("Importing config from: %q\n", f.Name())

content, err := ioutil.ReadFile(path.Join(o.fromDir, f.Name()))
if err != nil {
return fmt.Errorf("error reading cred file %s: %v", path.Join(o.fromDir, f.Name()), err)
}

usernameMatch := usernameRegEx.FindSubmatch(content)
passwordMatch := passwordRegEx.FindSubmatch(content)
tenantNameMatch := tenantNameRegEx.FindSubmatch(content)
authUrlMatch := authUrlRegEx.FindSubmatch(content)

if len(usernameMatch) < 1 {
return fmt.Errorf("error matching username regex")
}
if len(passwordMatch) < 1 {
return fmt.Errorf("error matching username regex")
}
if len(tenantNameMatch) < 1 {
return fmt.Errorf("error matching username regex")
}
if len(authUrlMatch) < 1 {
return fmt.Errorf("error matching username regex")
}

clouds.Clouds[string(tenantNameMatch[1])] = cloud{
Auth: cloudAuth{
Username: string(usernameMatch[1]),
Password: string(passwordMatch[1]),
ProjectName: string(tenantNameMatch[1]),
AuthUrl: string(authUrlMatch[1]),
},
}
}
}

out, err := yaml.Marshal(clouds)
if err != nil {
return fmt.Errorf("error marshalling couds: %v", err)
}

fmt.Printf("Writing config to %s\n", o.openstackConfigFile)

err = ioutil.WriteFile(o.openstackConfigFile, out, os.ModePerm)
if err != nil {
return fmt.Errorf("error writing config file %s: %v", o.openstackConfigFile, err)
}
return nil
}

type clouds struct {
Clouds map[string]cloud `yaml:"clouds"`
}
type cloud struct {
Auth cloudAuth `yaml:"auth"`
}

type cloudAuth struct {
AuthUrl string `yaml:"auth_url"`
ProjectName string `yaml:"project_name"`
Username string `yaml:"username"`
Password string `yaml:"password"`
}
2 changes: 1 addition & 1 deletion pkg/cmd/lb.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ type LBOptions struct {
var (
lbExample = `
# list lb
%[1] lb
%[1]s lb
`
)

Expand Down
2 changes: 2 additions & 0 deletions pkg/cmd/os.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cmd

import (
"fmt"

"github.com/spf13/cobra"

"k8s.io/cli-runtime/pkg/genericclioptions"
Expand All @@ -24,5 +25,6 @@ func NewCmdOpenStack(streams genericclioptions.IOStreams) *cobra.Command {
cmd.AddCommand(NewCmdLB(streams))
cmd.AddCommand(NewCmdServer(streams))
cmd.AddCommand(NewCmdVolumes(streams))
cmd.AddCommand(NewCmdImportConfig(streams))
return cmd
}
2 changes: 1 addition & 1 deletion pkg/cmd/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ type ServerOptions struct {
var (
serverExample = `
# list server
%[1] server
%[1]s server
`
)

Expand Down
2 changes: 1 addition & 1 deletion pkg/cmd/volume.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ type VolumesOptions struct {
var (
volumesExample = `
# list volumes
%[1] volumes
%[1]s volumes
`
)

Expand Down
14 changes: 14 additions & 0 deletions pkg/util/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")

go_library(
name = "go_default_library",
srcs = ["util.go"],
importpath = "github.com/sbueringer/kubectl-openstack-plugin/pkg/util",
visibility = ["//visibility:public"],
)

go_test(
name = "go_default_test",
srcs = ["util_test.go"],
embed = [":go_default_library"],
)
1 change: 1 addition & 0 deletions pkg/util/util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package util
1 change: 1 addition & 0 deletions pkg/util/util_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package util

0 comments on commit b63309c

Please sign in to comment.