From 8c05af813555d9e5922b7f18ec49ef636c75d59b Mon Sep 17 00:00:00 2001 From: Voomra Date: Tue, 4 Feb 2025 22:17:24 +0300 Subject: [PATCH] feat: openports --- cmd/openports.go | 29 +++++++++++ cmd/root.go | 3 +- internal/space_worker/openports.go | 77 ++++++++++++++++++++++++++++++ internal/types/ports.go | 30 ++++++++++++ 4 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 cmd/openports.go create mode 100644 internal/space_worker/openports.go create mode 100644 internal/types/ports.go diff --git a/cmd/openports.go b/cmd/openports.go new file mode 100644 index 0000000..edf7597 --- /dev/null +++ b/cmd/openports.go @@ -0,0 +1,29 @@ +package cmd + +import ( + "github.com/spf13/cobra" + "path/filepath" + sw "playbookctl/internal/space_worker" + "playbookctl/internal/utils/logger" +) + +func NewCommandOpenports() *cobra.Command { + openportsCmd := &cobra.Command{ + Use: "openports", + Short: "пробрасывает порты с сервера на локалку", + RunE: openportsRunE, + } + + openportsCmd.Flags().StringVar(&flagTargetHost, "target", "", "имя целевого хоста") + + return openportsCmd +} + +func openportsRunE(_ *cobra.Command, _ []string) error { + workDir, err := filepath.Abs(flagWorkdir) + if err != nil { + return err + } + spaceWorker := sw.NewSpaceWorker(logger.LogVerbose(flagVerbose), workDir) + return spaceWorker.Openports(flagTargetHost) +} diff --git a/cmd/root.go b/cmd/root.go index 0029677..a1d9494 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -21,7 +21,7 @@ var ( var rootCmd = &cobra.Command{ Use: "playbookctl", Short: "Ansible Playbook Dedic2 Control", - Version: "4.0.3", + Version: "4.1.0", RunE: func(cmd *cobra.Command, _ []string) error { return cmd.Help() }, @@ -42,6 +42,7 @@ func init() { rootCmd.AddCommand(NewCommandHosts()) rootCmd.AddCommand(NewCommandBackup()) rootCmd.AddCommand(NewCommandRestore()) + rootCmd.AddCommand(NewCommandOpenports()) } func Execute() { diff --git a/internal/space_worker/openports.go b/internal/space_worker/openports.go new file mode 100644 index 0000000..69ac684 --- /dev/null +++ b/internal/space_worker/openports.go @@ -0,0 +1,77 @@ +package space_worker + +import ( + "fmt" + "os" + "os/exec" + "playbookctl/internal/types" + "strconv" + "strings" +) + +func (app *SpaceWorker) Openports(targetHost string) error { + app.log.Debug(fmt.Sprintf("workDir: %s", app.workDir)) + + var ansibleHost string + if targetHost != "" { + ansibleHost = targetHost + } else { + var err error + ansibleHost, err = app.GetDefaultHost() + if err != nil { + return err + } + } + + app.log.Trace("try read hosts.yml") + hosts, err := types.ReadHosts(app.workDir) + if err != nil { + return err + } + + var sshTargetHost string + var sshTargetPort uint16 + var sshTargetUser string + for serverName, props := range *hosts { + if serverName == ansibleHost { + sshTargetHost = props.Host + sshTargetPort = props.Port + sshTargetUser = props.User + break + } + } + + //------------------------------------------------------------------------------------------------------------------ + + app.log.Trace("try read ports.yml") + portsDef, err := types.ReadPortsDef(app.workDir) + if err != nil { + return err + } + + message := []string{"Open SSH connection to"} + sshArgs := []string{"-N"} + for _, portDef := range *portsDef { + sshArgs = append(sshArgs, "-L", fmt.Sprintf("127.0.0.1:%d:127.0.0.1:%d", portDef.LocalPort, portDef.RemotePort)) + + if portDef.Url == "" { + message = append(message, fmt.Sprintf(" - %s (%d -> %d)", portDef.Name, portDef.LocalPort, portDef.RemotePort)) + } else { + message = append(message, fmt.Sprintf(" - %s (%d -> %d) :: %s", portDef.Name, portDef.LocalPort, portDef.RemotePort, portDef.Url)) + } + } + sshArgs = append(sshArgs, "-p", strconv.Itoa(int(sshTargetPort)), fmt.Sprintf("%s@%s", sshTargetUser, sshTargetHost)) + + app.log.Info(strings.Join(message, "\n")) + + command := exec.Command("/usr/bin/ssh", sshArgs...) + command.Dir = app.workDir + command.Stdin = os.Stdin + command.Stdout = os.Stdout + command.Stderr = os.Stderr + + app.log.Debug(fmt.Sprintf("ssh command line: %s", command.Args)) + err = command.Run() + + return err +} diff --git a/internal/types/ports.go b/internal/types/ports.go new file mode 100644 index 0000000..eed5617 --- /dev/null +++ b/internal/types/ports.go @@ -0,0 +1,30 @@ +package types + +import ( + "gopkg.in/yaml.v3" + "os" + "path/filepath" +) + +type PortDef struct { + Name string `yaml:"name"` + LocalPort uint16 `yaml:"local"` + RemotePort uint16 `yaml:"remote"` + Url string `yaml:"url"` +} + +func ReadPortsDef(workDir string) (*[]PortDef, error) { + var portsDef []PortDef + { + bb, err := os.ReadFile(filepath.Join(workDir, "ports.yml")) + if err != nil { + return nil, err + } + + if err := yaml.Unmarshal(bb, &portsDef); err != nil { + return nil, err + } + } + + return &portsDef, nil +}