parallexe

package module
v0.0.0-...-1738110 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 18, 2023 License: Apache-2.0 Imports: 13 Imported by: 0

README

Parallexe

Parallexe executes scripts in parallel on remote servers. It simplifies management by allowing users to execute commands described in a markdown file or directly from code.

Installation

go get github.com/parallexe/parallexe

Usage

Code
package main

import (
	"log"
	"github.com/parallexe/parallexe"
)

func main() {
	hostConfigs := []parallexe.HostConfig{
		{
			Host:   "53.0.0.1",
			Groups: []string{"prod"},
			SshConfig: &parallexe.SshConfig{
				User:           "root",
				PrivateKeyPath: "/home/user/.ssh/id_rsa",
			},
		},
		{
			Host:   "53.0.0.2",
			Groups: []string{"uat"},
			SshConfig: &parallexe.SshConfig{
				User:           "root",
				PrivateKeyPath: "/home/user/.ssh/id_rsa",
			},
		},
	}

	pexe, err := parallexe.New(hostConfigs)
	if err != nil {
		panic(err)
	}
	defer p.Close()

	responses, err := pexe.Exec("ls -l", nil)
	if err != nil {
		panic(err)
	}
	log.Print(responses.GetStdoutLines())
	
	// Send file.tpl to /tmp/file.txt on hosts and compile go template
	_, err := pexe.Send("./file.tpl", "/tmp/file.txt", &parallexe.SendConfig{
		CompileTemplate: true,
		ExecVariables:   &parallexe.ExecVariables{
			Variables: parallexe.KeyValueVariable{
				"var1": "value1",
			},
		},
	})
}
Command line

COMING SOON

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CommandResponse

type CommandResponse struct {
	Stdout string
	// Contains the error returns by the command
	Stderr string
	// Contains network error (ssh connection, ...)
	Error   error
	Code    int
	Success bool
}

type CommandResponses

type CommandResponses struct {
	HostResponses map[string]*CommandResponse
}

func (*CommandResponses) GetStderrLines

func (r *CommandResponses) GetStderrLines() map[string][]string

func (*CommandResponses) GetStdoutLines

func (r *CommandResponses) GetStdoutLines() map[string][]string

type CommandStatus

type CommandStatus string
const (
	CommandStatusDone CommandStatus = "done"
	CommandStatusSkip CommandStatus = "skip"
)

type ExecConfig

type ExecConfig struct {
	Hosts  []string
	Groups []string
}

type ExecVariables

type ExecVariables struct {
	// Variables will be injected for all hosts
	Variables KeyValueVariable
	// GroupVariables will be injected for corresponding group and will override Variables
	GroupVariables map[string]KeyValueVariable
	// HostVariables will be injected in template and will override GroupVariables
	HostVariables map[string]KeyValueVariable
}

type HostConfig

type HostConfig struct {
	SshConfig *SshConfig
	Host      string
	Groups    []string
}

type HostConnection

type HostConnection struct {
	HostConfig HostConfig
	Client     *ssh.Client
}

HostConnection contains the SSH Client and the HostConfig. It is used internally to filter connections against what HostConfig contains

type KeyValueVariable

type KeyValueVariable map[string]interface{}

type LineInFileConfig

type LineInFileConfig struct {
	// ExecConfig allows to filter hosts and groups
	ExecConfig *ExecConfig
	Absent     bool
}

type MultiCommandResponses

type MultiCommandResponses struct {
	Status        CommandStatus
	Command       string
	HostResponses map[string]*CommandResponse
}

type Parallexe

type Parallexe struct {
	HostConnections []HostConnection
}

func New

func New(configs []HostConfig) (*Parallexe, error)

New creates a new Parallexe client with a list of HostConfig It returns an error if at least one host is not reachable If Host is localhost or 127.0.0.1, it will create a HostConnection with Client nil

func (*Parallexe) AddHost

func (p *Parallexe) AddHost(hostConfig HostConfig) error

AddHost adds a new host to the Parallexe client

func (*Parallexe) Close

func (p *Parallexe) Close() error

Close closes all SSH connections in all HostConnections

func (*Parallexe) Exec

func (p *Parallexe) Exec(command string, execConfig *ExecConfig) (*CommandResponses, error)

Exec executes a command on a list of hosts

func (*Parallexe) LineInFile

func (p *Parallexe) LineInFile(path string, line string, config *LineInFileConfig) (*CommandResponses, error)

LineInFile checks if a line is present in a file. If absent is true, the line will be removed from the file if it exists or nothing will be done. If absent is false, if file does not exist, it will be created with the line.

Example (Add)
pexe, err := New([]HostConfig{{Host: "localhost"}})
if err != nil {
	panic(err)
}
defer pexe.Close()

// Create tmp file
file, err := os.CreateTemp("", "testfile")
if err != nil {
	panic(err)
}
defer os.Remove(file.Name())

// Write content in tmp file
file.WriteString("toto")

// Add line in tmp file
_, err = pexe.LineInFile(file.Name(), "tata", &LineInFileConfig{
	ExecConfig: nil,
	Absent:     false,
})
if err != nil {
	panic(err)
}

// Check if tmp file contains "tata"
content, err := os.ReadFile(file.Name())
if err != nil {
	panic(err)
}

fmt.Println(strings.Contains(string(content), "toto\ntata"))
Output:

true
Example (Remove)
pexe, err := New([]HostConfig{{Host: "localhost"}})
if err != nil {
	panic(err)
}
defer pexe.Close()

// Create tmp file
file, err := os.CreateTemp("", "testfile")
if err != nil {
	panic(err)
}
defer os.Remove(file.Name())

// Write content in tmp file
file.WriteString("toto\ntata")

// Remove line in tmp file
_, err = pexe.LineInFile(file.Name(), "tata", &LineInFileConfig{
	ExecConfig: nil,
	Absent:     true,
})
if err != nil {
	panic(err)
}

// Check if tmp file contains "tata"
content, err := os.ReadFile(file.Name())
if err != nil {
	panic(err)
}

fmt.Println(strings.Contains(string(content), "tata"))
Output:

false

func (*Parallexe) MultiExec

func (p *Parallexe) MultiExec(commands []string, execConfig *ExecConfig) ([]*MultiCommandResponses, error)

MultiExec executes a list of commands on a list of hosts. It returns a list of MultiCommandResponses, each one containing the command and the responses for each host. If a command fails on a host, the next commands will not be executed on any host. Commands not executed on any host will have a status CommandStatusSkip.

func (*Parallexe) Send

func (p *Parallexe) Send(sourcePath string, destPath string, config *SendConfig) (*CommandResponses, error)

Send sends a source file to a destination on remote hosts. The source file can be a template that will be rendered before sending.

Example (Copy)
pexe, err := New([]HostConfig{{Host: "localhost"}})
if err != nil {
	panic(err)
}
defer pexe.Close()

file, err := os.CreateTemp("", "testfile")
if err != nil {
	panic(err)
}
defer os.Remove(file.Name())
file.WriteString("toto\n")

// Check if file is correctly sent
destCopyFile := fmt.Sprintf("%s/%s", os.TempDir(), "destFile")
defer os.Remove(destCopyFile)

_, err = pexe.Send(file.Name(), destCopyFile, &SendConfig{
	ExecConfig:      nil,
	CompileTemplate: false,
	IgnoreIfExists:  false,
})
if err != nil {
	panic(err)
}

content, err := os.ReadFile(destCopyFile)
if err != nil {
	panic(err)
}

fmt.Println(string(content))
Output:

toto
Example (Template)
pexe, err := New([]HostConfig{{Host: "localhost"}})
if err != nil {
	panic(err)
}
defer pexe.Close()

file, err := os.CreateTemp("", "testfile")
if err != nil {
	panic(err)
}
defer os.Remove(file.Name())
file.WriteString("{{ .Name }}\n")

// Check if file is correctly sent
destCopyFile := fmt.Sprintf("%s/%s", os.TempDir(), "destFile")
defer os.Remove(destCopyFile)

_, err = pexe.Send(file.Name(), destCopyFile, &SendConfig{
	ExecConfig:      nil,
	CompileTemplate: true,
	ExecVariables:   &ExecVariables{Variables: KeyValueVariable{"Name": "tutu"}},
})
if err != nil {
	panic(err)
}

content, err := os.ReadFile(destCopyFile)
if err != nil {
	panic(err)
}

fmt.Println(string(content))
Output:

tutu

type SendConfig

type SendConfig struct {
	// ExecConfig allows to filter hosts and groups
	ExecConfig *ExecConfig
	// CompileTemplate If sourcePath is a go template, Parallexe will compile this template for each host before sending it
	CompileTemplate bool
	// ExecVariables contains the runtime variables for compiling the templates when sending them.
	// These variables allow you to customize the rendering of templates for each host.
	// Variables can be overridden by host group specific variables and host specific variables.
	ExecVariables *ExecVariables
	// Owner is the owner of the destination file
	Owner string
	//	Group is the group of the destination file
	Mode string
	// IgnoreIfExists indicates whether the upload should be ignored if the destination file already exists on the remote host.
	// If this value is set to true, the upload will not be performed and no error will be returned if the file already exists.
	// If this value is set to false, the upload will be performed even if the file already exists, causing it to be overwritten.
	// The default value is false.
	IgnoreIfExists bool
}

type SshConfig

type SshConfig struct {
	User           string
	Password       string
	PrivateKeyPath string
	PrivateKey     []byte
}

SshConfig contains all needed configuration to SSH access to a specific host

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL