Coder Social home page Coder Social logo

vssh's Introduction

vSSH

Go library to handle tens of thousands SSH connections and execute the command(s) with higher-level API for building network device / server automation. Documentation and examples are available via godoc.

Test Status Go Report Card Coverage Status GoDoc PkgGoDev

Alt text

Features

  • Connect to multiple remote machines concurrently
  • Persistent SSH connection
  • DSL query based on the labels
  • Manage number of sessions per SSH connection
  • Limit amount of stdout and stderr data in bytes
  • Higher-level API for building automation

Sample query with label

labels := map[string]string {
  "POP" : "LAX",
  "OS" : "JUNOS",
}
// sets labels to a client
vs.AddClient(addr, config, vssh.SetLabels(labels))
// query with label
vs.RunWithLabel(ctx, cmd, timeout, "(POP == LAX || POP == DCA) && OS == JUNOS")

Basic example

vs := vssh.New().Start()
config := vssh.GetConfigUserPass("vssh", "vssh")
for _, addr := range []string{"54.193.17.197:22", "192.168.2.19:22"} {
  vs.AddClient(addr, config, vssh.SetMaxSessions(4))
}
vs.Wait()

ctx, cancel := context.WithCancel(context.Background())
defer cancel()

cmd:= "ping -c 4 192.168.55.10"
timeout, _ := time.ParseDuration("6s")
respChan := vs.Run(ctx, cmd, timeout)

for resp := range respChan {
  if err := resp.Err(); err != nil {
    log.Println(err)
      continue
    }

  outTxt, errTxt, _ := resp.GetText(vs)
  fmt.Println(outTxt, errTxt, resp.ExitStatus())
}

Stream example

vs := vssh.New().Start()
config, _ := vssh.GetConfigPEM("vssh", "mypem.pem")
vs.AddClient("54.193.17.197:22", config, vssh.SetMaxSessions(4))
vs.Wait()

ctx, cancel := context.WithCancel(context.Background())
defer cancel()

cmd:= "ping -c 4 192.168.55.10"
timeout, _ := time.ParseDuration("6s")
respChan := vs.Run(ctx, cmd, timeout)

resp := <- respChan
if err := resp.Err(); err != nil {
  log.Fatal(err)
}

stream := resp.GetStream()
defer stream.Close()

for stream.ScanStdout() {
  txt := stream.TextStdout()
  fmt.Println(txt)
}

Supported platform

  • Linux
  • Windows
  • Darwin
  • BSD
  • Solaris

License

Code is licensed under the Apache License, Version 2.0 (the "License"). Content is licensed under the CC BY 4.0 license. Terms available at https://creativecommons.org/licenses/by/4.0/.

Contribute

Welcomes any kind of contribution, please follow the next steps:

  • Fork the project on github.com.
  • Create a new branch.
  • Commit changes to the new branch.
  • Send a pull request.

vssh's People

Contributors

dmitris avatar mehrdadrad avatar mkontani avatar shashikreddy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vssh's Issues

Empty resp.ID()

Hello,
seems like if a response contains an error then resp.ID() produces an empty string.

for resp := range respChan {
  if err := resp.Err(); err != nil {
    log.Println(resp.ID())
    }
}

Provide direct access to ssh.Session.StdoutPipe

In situations where one needs to receive large amounts of binary data from a remote server, the only way to do so in vssh is for the remote server to send it in newline-terminated chunks <64k at a time.

In client.go, ssh.Session.StdoutPipe gets connected to a bufio.Scanner, which is not suitable for binary data since its default buffer is limited to 64k. Ideally there should be a way to directly export ssh.Session.StdoutPipe so that scanning and reading can be left up to the implementation that's using vssh.

Race conditions

Hello, i just found a couple of race conditions, seems like there could be more given that client write and read happens in multiple places so some access synchronization to this data structure would be needed.
Please see below:

WARNING: DATA RACE
Write at 0x00c0002024a0 by goroutine 46:
  github.com/yahoo/vssh.(*clientAttr).connect()
      go/pkg/mod/github.com/yahoo/[email protected]/client.go:360 +0x5f7
  github.com/yahoo/vssh.(*connect).run()
      go/pkg/mod/github.com/yahoo/[email protected]/client.go:393 +0x20b
  github.com/yahoo/vssh.(*VSSH).process.func1()
      go/pkg/mod/github.com/yahoo/[email protected]/vssh.go:223 +0x1f1

Previous read at 0x00c0002024a0 by main goroutine:
  github.com/yahoo/vssh.(*VSSH).Wait()
      go/pkg/mod/github.com/yahoo/[email protected]/vssh.go:425 +0xda

Goroutine 46 (running) created at:
  github.com/yahoo/vssh.(*VSSH).process()
      go/pkg/mod/github.com/yahoo/[email protected]/vssh.go:216 +0x64
==================
==================
WARNING: DATA RACE
Read at 0x00c000202690 by goroutine 1104:
  github.com/yahoo/vssh.(*query).run.func1()
      go/pkg/mod/github.com/yahoo/[email protected]/query.go:74 +0xfd

Previous write at 0x00c000202690 by goroutine 48:
  github.com/yahoo/vssh.(*clientAttr).connect()
      go/pkg/mod/github.com/yahoo/[email protected]/client.go:362 +0x69a
  github.com/yahoo/vssh.(*connect).run()
      go/pkg/mod/github.com/yahoo/[email protected]/client.go:393 +0x20b
  github.com/yahoo/vssh.(*VSSH).process.func1()
      go/pkg/mod/github.com/yahoo/[email protected]/vssh.go:223 +0x1f1

Goroutine 1104 (running) created at:
  github.com/yahoo/vssh.(*query).run()
      go/pkg/mod/github.com/yahoo/[email protected]/query.go:63 +0x120
  github.com/yahoo/vssh.(*VSSH).process.func1()
      go/pkg/mod/github.com/yahoo/[email protected]/vssh.go:226 +0x27e

Goroutine 48 (running) created at:
  github.com/yahoo/vssh.(*VSSH).process()
      go/pkg/mod/github.com/yahoo/[email protected]/vssh.go:216 +0x64

Bogus example in comment/README.md

The README.md file, and the vssh.go docstring available here both contain the following example:

vs.RunWithLabel(ctx, cmd, timeout, "POP == LAX || POP == DCA) && OS == JUNOS")

The expression there is malformed:

POP == LAX || POP == DCA) && OS == JUNOS

Notice the closing ), without an opening (.

SetInitNumProc compile error

With the following code

        vs := vssh.New()
        vs.SetInitNumProc(2)
        vs.Start()

I am getting the following output
command-line-arguments
./main.go:13:4: vs.SetInitNumProc undefined (type *vssh.VSSH has no field or method SetInitNumProc)

Run multiple commands in one SSH session

How can we run multiple commands one-by-one, check the response of the previous command and decide if the following command can be executed in the persistent SSH session?

Source ip/host?

In the following code provided in the examples, how to get the client ip/host which generated the outTxt

	// get the resp channel for each client
	for resp := range respChan {
		// in case of the connectivity issue to client
		if err := resp.Err(); err != nil {
			log.Println(err)
			continue
		}

		// get the returned data from client
		outTxt, errTxt, err := resp.GetText(vs)

Feature: feed private key from memory

Currently vssh.GetConfigPEM() function expects to read the key from a file on disk via:
key, err := ioutil.ReadFile(keyFile)
but when using vssh as a library it can be not very convenient to generate a new key, write it to disk and then read it from disk again in GetConfigPEM(). Instead it would be great to have the option to generate a private key and feed it directly from memory to either GetConfigPEM() or a similar function like GetConfigFoo(user string, block *pem.Block) or GetConfigFoo(user string, block []byte).
Let me know what are your thoughts :)

Race condition

Hello everyone,
there seems to be a race condition in the following places:

WARNING: DATA RACE
Read at 0x00c00130d650 by goroutine 43:
  github.com/yahoo/vssh.(*VSSH).reConnect()
      go/pkg/mod/github.com/yahoo/[email protected]/vssh.go:369 +0x128

Previous write at 0x00c00130d650 by goroutine 280:
  github.com/yahoo/vssh.(*clientAttr).setErr()
      go/pkg/mod/github.com/yahoo/[email protected]/client.go:314 +0x564
  github.com/yahoo/vssh.(*clientAttr).connect()
      go/pkg/mod/github.com/yahoo/[email protected]/client.go:366 +0x42d
  github.com/yahoo/vssh.(*connect).run()
      go/pkg/mod/github.com/yahoo/[email protected]/client.go:403 +0x228
  github.com/yahoo/vssh.(*VSSH).process.func1()
      go/pkg/mod/github.com/yahoo/[email protected]/vssh.go:223 +0x20e

Goroutine 43 (running) created at:
  github.com/yahoo/vssh.(*VSSH).Start()
      go/pkg/mod/github.com/yahoo/[email protected]/vssh.go:193 +0xbc

Goroutine 280 (running) created at:
  github.com/yahoo/vssh.(*VSSH).process()
      go/pkg/mod/github.com/yahoo/[email protected]/vssh.go:216 +0x64
==================
==================
WARNING: DATA RACE
Read at 0x00c00130d648 by goroutine 43:
  github.com/yahoo/vssh.(*VSSH).reConnect()
      go/pkg/mod/github.com/yahoo/[email protected]/vssh.go:369 +0x32c

Previous write at 0x00c00130d648 by goroutine 280:
  github.com/yahoo/vssh.(*clientAttr).setErr()
      go/pkg/mod/github.com/yahoo/[email protected]/client.go:311 +0x472
  github.com/yahoo/vssh.(*clientAttr).connect()
      go/pkg/mod/github.com/yahoo/[email protected]/client.go:366 +0x42d
  github.com/yahoo/vssh.(*connect).run()
      go/pkg/mod/github.com/yahoo/[email protected]/client.go:403 +0x228
  github.com/yahoo/vssh.(*VSSH).process.func1()
      go/pkg/mod/github.com/yahoo/[email protected]/vssh.go:223 +0x20e

Goroutine 43 (running) created at:
  github.com/yahoo/vssh.(*VSSH).Start()
      go/pkg/mod/github.com/yahoo/[email protected]/vssh.go:193 +0xbc


Goroutine 280 (running) created at:
  github.com/yahoo/vssh.(*VSSH).process()
      go/pkg/mod/github.com/yahoo/[email protected]/vssh.go:216 +0x64

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.