Skip to content

Commit

Permalink
added cli tab with exec -p passcode
Browse files Browse the repository at this point in the history
  • Loading branch information
Pankaj Kumar committed Feb 28, 2022
1 parent 8e4bb9a commit 4577a12
Show file tree
Hide file tree
Showing 21 changed files with 299 additions and 136 deletions.
2 changes: 1 addition & 1 deletion agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ func (a *_agent) PatchRollback() (err error) {
}

// backing up the rollback into assets
err = backupExistingRollback()
err = BackupRollback()
if err != nil {
return err
}
Expand Down
21 changes: 15 additions & 6 deletions agent/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,13 +248,22 @@ func (p *_ps) Verify(req *pb.VerifyReq, stream pb.Patch_VerifyServer) (err error
}

func (p *_ps) Execute(ctx context.Context, req *pb.CmdReq) (res *pb.CmdResp, err error) {
cmd := req.GetCmd()
log.Println("EXECUTE: request receieved - ", cmd)
out, err := entity.ExecuteCmd(cmd)
log.Println("EXECUTE: completed -", string(out), "\nerr:", err)
var e string
if err != nil {
e = err.Error()
var out []byte
cmd := req.GetCmd()
pass := req.GetPass()
log.Println("EXECUTE: request receieved - ", cmd, pass)
ok := entity.VerifyPasscode(pass)
if ok {
o, err := entity.ExecuteCmd(cmd)
out = o
log.Println("EXECUTE: completed -", string(out), "\nerr:", err)
if err != nil {
e = err.Error()
}
} else {
e = "INVALID PASSCODE"
log.Println("EXECUTE: completed with error - ", e)
}
res = &pb.CmdResp{
Out: out,
Expand Down
3 changes: 2 additions & 1 deletion agent/utility.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import (
"github.com/pnkj-kmr/infra-patch-manager/entity"
)

func backupExistingRollback() (err error) {
// BackupRollback - helps to backup the rollback dir as assets
func BackupRollback() (err error) {
d, err := entity.NewDir(entity.C.RollbackPath())
if err != nil {
log.Println("Unable to load rollback folder", entity.C.RollbackPath(), err)
Expand Down
2 changes: 1 addition & 1 deletion conf/remotes.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
"agent_address": "0.0.0.0:8084",
"apps": [
{
"type": "dc",
"type": "xx",
"name": "app9",
"source": "/tmp/patch/app9",
"service": "app9",
Expand Down
11 changes: 6 additions & 5 deletions endpoint/cli/agent/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@ import (
)

func main() {
// enabling the agent mode
entity.EnableAgentMode()

port := flag.Int("port", 8008, "the server port")
port := flag.Int("port", 8008, "the server starting port")
p := flag.String("passcode", "infrapm", "passcode - extra secure")
flag.Parse()
log.Printf("server start on port : %d", *port)
log.Printf("server start on port: %d [passcode: %s]", *port, *p)

// enabling the agent mode
entity.EnableAgentMode(p)

patch := agent.NewPatchServer()
grpcServer := grpc.NewServer()
Expand Down
29 changes: 19 additions & 10 deletions endpoint/cli/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ package cli
import (
"flag"
"fmt"
"os"
"text/tabwriter"
"time"

"github.com/pnkj-kmr/infra-patch-manager/master"
"github.com/pnkj-kmr/infra-patch-manager/master/remote"
Expand All @@ -26,16 +29,17 @@ func HandleApply(cmd *flag.FlagSet) {
existingApps := cliHandler.GetRemoteApps(r, appName, appType)
pm, err := master.NewPatchMaster(r.Name(), false)
if err == nil {
apps, err := pm.PatchTo(existingApps)
if err != nil {
r.UpdateStatus(false)
} else {
apps, _ := pm.PatchTo(existingApps)
if len(apps) > 0 {
r.UpdateStatus(true)
} else {
r.UpdateStatus(false)
}
printApplyWithApps(r, existingApps, apps)
}
fmt.Println()
}
fmt.Println()
} else {
cliHandler.DefaultHelp()
}
Expand All @@ -46,15 +50,20 @@ func HandleApply(cmd *flag.FlagSet) {

func printApplyWithApps(r remote.Remote, ex []remote.App, apps []remote.App) {
fmt.Println()
fmt.Printf("Remote name : %s [%s] %s\n", r.Name(), r.Type(), iif(r.Status(), greenText("--- OK"), redText("--- NOT REACHABLE")))
fmt.Printf("Applications : %d [requested: %d]\n", len(apps), len(ex))
format := "%v\t%v\t%v\t\t\t%v\t\n"
tw := new(tabwriter.Writer).Init(os.Stdout, 0, 8, 2, ' ', 0)
fmt.Fprintf(tw, format, "Remote name", fmt.Sprintf("%s [%s]", r.Name(), r.Type()), "", iif(r.Status(), iif(len(ex) == len(apps), greenText("...OK"), yellowText("...PARTILLY APPLIED")), redText("...NOT REACHABLE")))
fmt.Fprintf(tw, format, "Applications", fmt.Sprintf("%d [requested: %d]", len(apps), len(ex)), "", "")
if len(ex) == 0 {
fmt.Printf(" %s\n\n", yellowText("No application found. To more refer conf/remotes.json"))
fmt.Fprintf(tw, format, "", yellowText("No application found. To more refer conf/remotes.json"), "", "")
} else if len(apps) == 0 {
fmt.Fprintf(tw, format, "", yellowText("No application(s) reachable"), "", "")
}
for i, a := range apps {
fmt.Printf("[%d] %s : [%s] %s %s\n", i+1, a.Name(), a.Type(), a.SourcePath(), iif(a.Status(), greenText("APPLIED"), redText("NOT APPLIED")))
for _, a := range apps {
fmt.Fprintf(tw, format, fmt.Sprintf("%s [%s]", a.Name(), a.Type()), a.SourcePath(), "", iif(a.Status(), greenText("APPLIED"), redText("NOT APPLIED")))
for j, f := range a.GetFiles() {
fmt.Printf(" : [%d] - %s [%d] - %s\n", j+1, f.Path(), f.Size(), f.ModTime().Local().String())
fmt.Fprintf(tw, format, "", fmt.Sprintf("[%d] %s [%d]", j+1, f.Path(), f.Size()), f.ModTime().Local().Format(time.Kitchen), "")
}
}
tw.Flush()
}
52 changes: 31 additions & 21 deletions endpoint/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"flag"
"fmt"
"os"
"text/tabwriter"

"github.com/pnkj-kmr/infra-patch-manager/master/remote"
)
Expand All @@ -28,15 +29,24 @@ type _cli struct {

func (c *_cli) DefaultHelp() {
fmt.Println("Infra-Patch-Manager subcommand <", c.cmd.Name(), "> holds below actions.", c.helpMsg)
fmt.Println()
c.cmd.PrintDefaults()
fmt.Printf("\n\n")
}

func defaultRemoteCheck(r []remote.Remote) {
if len(r) == 0 {
fmt.Printf("Infra-Patch-Manager contains the subcommands set.\n\n")
fmt.Printf("\t%s\n\n", yellowText("- No Remote configured. check conf/remotes.json"))
os.Exit(0)
}
}

func (c *_cli) GetRemotes(name, rtype *string) (r []remote.Remote) {
if *name != "" {
rr, err := remote.NewRemote(*name)
if err != nil {
fmt.Printf("%s\n\n", yellowText("Given remote name does not exists. refer conf/remotes.json"))
fmt.Printf("\n\t%s\n\n", yellowText("- Given remote name does not exists. refer conf/remotes.json"))
os.Exit(0)
}
r = append(r, rr)
Expand All @@ -53,21 +63,22 @@ func (c *_cli) GetRemoteApps(r remote.Remote, name, apptype *string) (a []remote
if *name != "" {
app, err := r.App(*name)
if err != nil {
fmt.Printf("\n\n%s\n\n", yellowText("Given remote application name does not exists. refer conf/remotes.json"))
os.Exit(0)
// fmt.Printf("\n\t%s\n\n", yellowText("- Given remote application name does not exists. refer conf/remotes.json"))
// os.Exit(0)
return a
}
a = append(a, app)
} else if *apptype != "" {
apps, err := r.AppByType(*apptype)
if err != nil {
fmt.Printf("\n\n%s\n\n", yellowText("Invalid type. refer conf/remotes.json"))
fmt.Printf("\n\t%s\n\n", yellowText("- Invalid type. refer conf/remotes.json"))
os.Exit(0)
}
a = apps
} else {
apps, err := r.Apps()
if err != nil {
fmt.Printf(yellowText("Internal error. refer conf/remotes.json"))
fmt.Printf("\n\t%s\n\n", yellowText("- Internal error. refer conf/remotes.json"))
os.Exit(0)
}
a = apps
Expand All @@ -77,30 +88,29 @@ func (c *_cli) GetRemoteApps(r remote.Remote, name, apptype *string) (a []remote

// DefaultHelp - print all helps
func DefaultHelp() {
format := "\t\t%v\t| %v\t\n"
tw := new(tabwriter.Writer).Init(os.Stdout, 0, 8, 2, ' ', 0)
fmt.Printf("Infra-Patch-Manager contains the following subcommands set.\n\n")
fmt.Println(greenText(" remote"), " | list or search a remote detail with reachablity")
fmt.Println(greenText(" rights"), " | read/write rights check on a remote's application(s)")
fmt.Println(greenText(" upload"), " | upload a patch to remote")
fmt.Println(greenText(" extract"), " | untaring a tar.gz file on relative remote")
fmt.Println(greenText(" apply"), " | applying a patch to relative remote application(s)")
fmt.Println(greenText(" verify"), " | helps to validate an applied patch")
fmt.Println(greenText(" exec"), " | helps to execute commands on remote(s)")
fmt.Fprintf(tw, format, greenText("remote"), "list or search a remote detail with reachablity")
fmt.Fprintf(tw, format, greenText("rights"), "read/write rights check on a remote's application(s)")
fmt.Fprintf(tw, format, greenText("upload"), "upload a patch to remote")
fmt.Fprintf(tw, format, greenText("extract"), "untaring a tar.gz file on relative remote")
fmt.Fprintf(tw, format, greenText("apply"), "applying a patch to relative remote application(s)")
fmt.Fprintf(tw, format, greenText("verify"), "helps to validate an applied patch")
fmt.Fprintf(tw, format, greenText("exec"), "helps to execute commands on remote(s)")
tw.Flush()
fmt.Print("\n\n")
}

func defaultRemoteCheck(r []remote.Remote) {
if len(r) == 0 {
fmt.Printf("Infra-Patch-Manager contains the subcommands set.\n\n")
fmt.Printf(" %s\n\n\n", yellowText("- No Remote configured. check conf/remotes.json"))
os.Exit(0)
}
}

// DefaultCheck - helps to check basic
func DefaultCheck() {
if len(os.Args) < 2 {
fmt.Printf("Infra-Patch-Manager contains the subcommands set. Follow help to know more.\n\n")
fmt.Printf(" -help | to know more about subcommands\n\n")
format := "\t\t%v\t| %v\t\n"
tw := new(tabwriter.Writer).Init(os.Stdout, 0, 8, 2, ' ', 0)
fmt.Fprintf(tw, format, greenText("help"), "to know more about subcommands")
tw.Flush()
fmt.Printf("\n\n")
os.Exit(0)
}
}
Expand Down
69 changes: 51 additions & 18 deletions endpoint/cli/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@ package cli
import (
"flag"
"fmt"
"os"
"strings"
"text/tabwriter"

"github.com/pnkj-kmr/infra-patch-manager/master"
"github.com/pnkj-kmr/infra-patch-manager/master/remote"
)

// HandleRemoteCmd - handler for remote subcmd
func HandleRemoteCmd(cmd *flag.FlagSet) {
passcode := cmd.String("p", "", "Passcode for remote agent")
remoteName := cmd.String("remote", "", "Remote by it's name")
remoteType := cmd.String("remote-type", "", "Remote by it's type")
remoteAll := cmd.Bool("remote-all", false, "All available remotes")
Expand All @@ -20,20 +23,29 @@ func HandleRemoteCmd(cmd *flag.FlagSet) {
appAll := cmd.Bool("app-all", false, "All available remote applications")
start := cmd.Bool("start", false, "Start the requested applications")
stop := cmd.Bool("stop", false, "Stop the requested applications")
restart := cmd.Bool("restart", false, "Stop the requested applications")
restart := cmd.Bool("restart", false, "Restart the requested applications")
status := cmd.Bool("status", false, "Check status of requested applications")
portCheck := cmd.Bool("check-port", false, "Check the netstat port status the requested applications")

// getting a handler
cliHandler := NewCLIHander(cmd, "")
cliHandler := NewCLIHander(cmd, "Always use passcode [i.e. -p ABC] with others combination")

if *passcode == "" {
// setting up the message to secure the passcode use case
cliHandler.DefaultHelp()
os.Exit(0)
}

if *remoteAll || *remoteType != "" || *remoteName != "" {
remotes := cliHandler.GetRemotes(remoteName, remoteType)
fmt.Println()
if *execCmd != "" {
fmt.Println()
for _, r := range remotes {
printRemoteCmd(r, map[string]string{"cmd": *execCmd})
printRemoteCmd(r, map[string]string{"cmd": *execCmd}, passcode)
fmt.Println()
}
} else if (*appAll || *appType != "" || *appName != "") && (*start || *stop || *restart || *portCheck) {
fmt.Println()
} else if (*appAll || *appType != "" || *appName != "") && (*start || *stop || *restart || *portCheck || *status) {
for _, r := range remotes {
cmds := make(map[string]string)
apps := cliHandler.GetRemoteApps(r, appName, appType)
Expand All @@ -57,10 +69,16 @@ func HandleRemoteCmd(cmd *flag.FlagSet) {
// TODO - OS dependent
cmds[a.Name()] = fmt.Sprintf("service start %s", a.ServiceName())
}
} else if *status {
for _, a := range apps {
// TODO - OS dependent
cmds[a.Name()] = fmt.Sprintf("service status %s", a.ServiceName())
}
}
printRemoteCmd(r, cmds)
printRemoteCmd(r, cmds, passcode)
fmt.Println()
}
fmt.Println()
} else {
cliHandler.DefaultHelp()
}
Expand All @@ -69,27 +87,42 @@ func HandleRemoteCmd(cmd *flag.FlagSet) {
}
}

func printRemoteCmd(r remote.Remote, cmds map[string]string) {
out := executeRemoteCmd(r, cmds)
fmt.Printf("Remote name : %s [%s] %s\n", r.Name(), r.Type(), iif(r.Status(), greenText("--- OK"), redText("--- NOT REACHABLE")))
func printRemoteCmd(r remote.Remote, cmds map[string]string, passcode *string) {
out, err := executeRemoteCmd(r, cmds, passcode)
// fmt.Println(out, err, err != nil)
var e string
if err != nil {
e = err.Error()
}
status := iif(e != "", redText("...INVALID"), iif(r.Status(), greenText("...OK"), redText("...NOT REACHABLE")))
format := "%v\t%v\t\t\t%v\t\n"
tw := new(tabwriter.Writer).Init(os.Stdout, 0, 8, 2, ' ', 0)
fmt.Fprintf(tw, format, "Remote Name:", fmt.Sprintf("%s [%s]", r.Name(), r.Type()), status)
for s, o := range out {
fmt.Printf("Execute : %s\n", s)
if len(out) > 0 {
fmt.Println(strings.Repeat("-", 60))
fmt.Printf(yellowText(string(o)))
fmt.Println(strings.Repeat("-", 60))
fmt.Fprintf(tw, "%v\n", s)
fmt.Fprintf(tw, "%v\n", strings.Repeat("-", 60))
if len(o) > 0 {
fmt.Fprintf(tw, "%v", yellowText(string(o)))
} else if e != "" {
fmt.Fprintf(tw, "%v\n", redText(e))
} else {
fmt.Fprintf(tw, "%v\n", redText("NO OUTPUT RECEIVED"))
}
fmt.Fprintf(tw, "%v\n\n", strings.Repeat("-", 60))
}
tw.Flush()
}

func executeRemoteCmd(r remote.Remote, cmds map[string]string) (out map[string][]byte) {
func executeRemoteCmd(r remote.Remote, cmds map[string]string, passcode *string) (out map[string][]byte, err error) {
out = make(map[string][]byte)
pm, err := master.NewPatchMaster(r.Name(), false)
pcode := *passcode
if err == nil {
for i, s := range cmds {
v, err := pm.ExecuteCmdOnRemote(s)
out[i+" -> "+s] = v
if err != nil {
v, e := pm.ExecuteCmdOnRemote(s, pcode)
out[fmt.Sprintf("%s [passcode: %s] -> %s", i, pcode, s)] = v
if e != nil {
err = e
r.UpdateStatus(false)
} else {
r.UpdateStatus(true)
Expand Down
Loading

0 comments on commit 4577a12

Please sign in to comment.