Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func bootstrapCmdRun(cmd *cobra.Command, args []string) {
log.Fatalf("Unable to load context: %s", err.Error())
}

c, err := clients.New(ctx.Fqdn)
c, err := clients.New(ctx.Fqdn, clients.LocalExecutor{})
if err != nil {
log.Fatalf("Unable to load clients: %s", err.Error())
}
Expand Down
4 changes: 2 additions & 2 deletions cmd/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,6 @@ var contextCmdGet = &cobra.Command{
}

func init() {
createCmd.AddCommand(contextCmdCreate)
getCmd.AddCommand(contextCmdGet)
rootCmd.AddCommand(contextCmdCreate)
rootCmd.AddCommand(contextCmdGet)
}
48 changes: 45 additions & 3 deletions cmd/prepNode.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/platform9/pf9ctl/pkg/pmk"
"github.com/platform9/pf9ctl/pkg/pmk/clients"
"github.com/spf13/cobra"
"io/ioutil"
)

// prepNodeCmd represents the prepNode command
Expand All @@ -30,21 +31,27 @@ var (
func init() {
prepNodeCmd.Flags().StringVarP(&user, "user", "u", "", "ssh username for the nodes")
prepNodeCmd.Flags().StringVarP(&password, "password", "p", "", "ssh password for the nodes")
prepNodeCmd.Flags().StringVarP(&sshKey, "ssh-key", "s", "", "ssh key for connecting to the nodes")
prepNodeCmd.Flags().StringVarP(&sshKey, "ssh-key", "s", "", "ssh key file for connecting to the nodes")
prepNodeCmd.Flags().StringSliceVarP(&ips, "ips", "i", []string{}, "ips of host to be prepared")
prepNodeCmd.Flags().BoolVarP(&floatingIP, "floating-ip", "f", false, "")

rootCmd.AddCommand(prepNodeCmd)
}


func prepNodeRun(cmd *cobra.Command, args []string) {

ctx, err := pmk.LoadContext(constants.Pf9DBLoc)
if err != nil {
log.Fatalf("Unable to load the context: %s\n", err.Error())
}

c, err := clients.New(ctx.Fqdn)
// TODO: there seems to be a bug, we will need multiple executors one per ip, so at this moment
// it will only work with one remote host
executor, err := getExecutor()
if err != nil {
log.Fatalf("Error connecting to host %s",err.Error())
}
c, err := clients.New(ctx.Fqdn, executor)
if err != nil {
log.Fatalf("Unable to load clients needed for the Cmd. Error: %s", err.Error())
}
Expand All @@ -54,3 +61,38 @@ func prepNodeRun(cmd *cobra.Command, args []string) {
log.Fatalf("Unable to prep node: %s\n", err.Error())
}
}

// checkAndValidateRemote check if any of the command line
func checkAndValidateRemote() bool {
foundRemote := false
for _, ip := range ips {
if ip != "localhost" && ip != "127.0.0.1" && ip != "::1" {
// lets create a remote executor, but before that check if we got user and either of password or ssh-key
if user =="" || (sshKey == "" && password == "") {
log.Fatalf("please provider 'user' and one of 'password' or ''ssh-key'")
}
foundRemote = true
return foundRemote
}
}
log.Info("Using local exeuctor")
return foundRemote
}


// getExecutor creates the right Executor
func getExecutor() (clients.Executor, error) {
if checkAndValidateRemote() {
var pKey []byte
var err error
if sshKey != "" {
pKey, err = ioutil.ReadFile(sshKey)
if err != nil {
log.Fatalf("Unale to read the sshKey %s, %s", sshKey, err.Error())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would return an error here and not Fatalf ( FatalingF at top layer ). Wdyt ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I debated that, didn't see a point in doing that, but if you feel it is inconsistent, I can change it. Here is the reason why I did it this way.

  • This is part of the file that is supposed to be doing validation and preparation.
  • doing so in other places would be unnecessary, I will probably return and error with the same string and the function above will do a fatalf.
    if this check was in another file, I would have absolutely agreed with you.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok @abhimanyu-babbar I have refactored it little bit PTAL

}
}
return clients.NewRemoteExecutor(ips[0], 22, user, pKey, password)
}
log.Info("Using local exeuctor")
return clients.LocalExecutor{}, nil
}
13 changes: 9 additions & 4 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,15 @@ func Execute() {
}

func initializeBaseDirs() (err error) {
err = os.MkdirAll(constants.Pf9Dir, os.ModeDir)
err = os.MkdirAll(constants.Pf9DBDir, os.ModeDir)
err = os.MkdirAll(constants.Pf9LogDir, os.ModeDir)

err = os.MkdirAll(constants.Pf9Dir, 0700)
if err != nil {
return
}
err = os.MkdirAll(constants.Pf9DBDir, 0700)
if err != nil {
return
}
err = os.MkdirAll(constants.Pf9LogDir, 0700)
return
}

Expand Down
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ require (
github.com/google/uuid v1.1.2
github.com/hashicorp/go-retryablehttp v0.6.7
github.com/mitchellh/go-homedir v1.1.0
github.com/pkg/sftp v1.12.0
github.com/prometheus/common v0.4.0
github.com/segmentio/backo-go v0.0.0-20200129164019-23eae7c10bd3 // indirect
github.com/sethgrid/pester v1.1.0
github.com/spf13/cobra v1.0.0
github.com/spf13/viper v1.6.3
github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c // indirect
go.uber.org/zap v1.10.0
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a
gopkg.in/segmentio/analytics-go.v3 v3.1.0
)
12 changes: 12 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
Expand All @@ -88,6 +90,10 @@ github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/sftp v1.12.0 h1:/f3b24xrDhkhddlaobPe2JgBqfdt+gC/NYl0QY9IOuI=
github.com/pkg/sftp v1.12.0/go.mod h1:fUqqXB5vEgVCZ131L+9say31RAri6aF6KDViawhxKK8=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
Expand Down Expand Up @@ -133,6 +139,7 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
Expand All @@ -152,12 +159,14 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM=
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Expand All @@ -169,6 +178,8 @@ golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
Expand All @@ -195,4 +206,5 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
15 changes: 9 additions & 6 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,21 @@
package main

import (
"fmt"
"os"
//"fmt"
//"os"

"github.com/platform9/pf9ctl/cmd"
)

func main() {
// the program may run a machine different from the one where the installation is happening
// so removing this check. If this check needs to happen it should happen where the installation is
// happening
// Check if program is run using root privileges
if os.Geteuid() != 0 {
fmt.Println("This program requires root privileges. Please run the binary as a root user.")
os.Exit(1)
}
//if os.Geteuid() != 0 {
// fmt.Println("This program requires root privileges. Please run the binary as a root user.")
// os.Exit(1)
//}
// Read the context variables.
cmd.Execute()
}
3 changes: 2 additions & 1 deletion pkg/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import (
"path/filepath"
"time"
)

// Pkg structure is meant for other code to import it into their own
// code base, this MUST not be here
var (
homeDir, _ = os.UserHomeDir()
//Pf9Dir is the base pf9dir
Expand Down
4 changes: 2 additions & 2 deletions pkg/pmk/clients/clients.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ type Client struct {

// New creates the clients needed by the CLI
// to interact with the external services.
func New(fqdn string) (Client, error) {
func New(fqdn string, executor Executor) (Client, error) {
return Client{
Resmgr: NewResmgr(fqdn),
Keystone: NewKeystone(fqdn),
Qbert: NewQbert(fqdn),
Executor: ExecutorImpl{},
Executor: executor,
Segment: NewSegment(fqdn),
}, nil
}
49 changes: 45 additions & 4 deletions pkg/pmk/clients/executor.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,61 @@
package clients

import "os/exec"
import (
"os/exec"
"github.com/platform9/pf9ctl/pkg/ssh"
"github.com/platform9/pf9ctl/pkg/log"
"fmt"
)

// Executor interace abstracts us from local or remote execution
type Executor interface {
Run(name string, args ...string) error
RunWithStdout(name string, args ...string) (string, error)
}

type ExecutorImpl struct{}
// LocalExecutor as the name implies executes commands locally
type LocalExecutor struct{}

func (c ExecutorImpl) Run(name string, args ...string) error {
// Run runs a command locally returning just success or failure
func (c LocalExecutor) Run(name string, args ...string) error {
cmd := exec.Command(name, args...)
return cmd.Run()
}

func (c ExecutorImpl) RunWithStdout(name string, args ...string) (string, error) {
// RunWithStdout runs a command locally returning stdout and err
func (c LocalExecutor) RunWithStdout(name string, args ...string) (string, error) {
byt, err := exec.Command(name, args...).Output()
return string(byt), err
}

// RemoteExecutor as the name implies runs commands usign SSH on remote host
type RemoteExecutor struct{
Client ssh.Client
}

// Run runs a command locally returning just success or failure
func (r *RemoteExecutor) Run(name string, args ...string) error {
_,err := r.RunWithStdout(name, args...)
return err
}

// RunWithStdout runs a command locally returning stdout and err
func (r *RemoteExecutor) RunWithStdout(name string, args ...string) (string, error) {
cmd := name
for _, arg := range args {
cmd = fmt.Sprintf("%s \"%s\"", cmd, arg)
}
stdout, stderr, err := r.Client.RunCommand(cmd)
log.Debug("Running command ",cmd, "stdout:", string(stdout), "stderr:", string(stderr))
return string(stdout), err
}

// NewRemoteExecutor create an Executor interface to execute commands remotely
func NewRemoteExecutor(host string, port int, username string, privateKey []byte, password string) (Executor, error) {
client, err := ssh.NewClient(host, port, username, privateKey, password)
if err != nil {
return nil, err
}
re := &RemoteExecutor{Client: client}
return re, nil
}
2 changes: 1 addition & 1 deletion pkg/pmk/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func Bootstrap(ctx Context, c clients.Client, req clients.ClusterCreateRequest)
return fmt.Errorf("Unable to create cluster: %w", err)
}

cmd := `cat /etc/pf9/host_id.conf | grep ^host_id | cut -d = -f2 | cut -d ' ' -f2`
cmd := `\"cat /etc/pf9/host_id.conf | grep ^host_id | cut -d = -f2 | cut -d ' ' -f2\"`
output, err := c.Executor.RunWithStdout("bash", "-c", cmd)
if err != nil {
return fmt.Errorf("Unable to execute command: %w", err)
Expand Down
Loading