scrapligo -- is a Go library focused on connecting to devices, specifically network devices (routers/switches/firewalls/etc.) via SSH and NETCONF.

Related tags

Network scrapligo
Overview

Go Report License: MIT


Source Code: https://github.com/scrapli/scrapligo

Examples: https://github.com/scrapli/scrapligo/tree/master/examples


scrapligo -- scrap(e c)li (but in go!) -- is a Go library focused on connecting to devices, specifically network devices (routers/switches/firewalls/etc.) via SSH and NETCONF.

NOTE this is a work in progress, use with caution!

Key Features:

  • Easy: It's easy to get going with scrapligo -- if you are familiar with go and/or scrapli you are already most of the way there! Check out the examples linked above to get started!
  • Fast: Do you like to go fast? Of course you do! All of scrapli is built with speed in mind, but this port of scrapli to go is of course even faster than its python sibling!
  • But wait, there's more!: Have NETCONF devices in your environment, but love the speed and simplicity of scrapli? You're in luck! NETCONF support is built right into scrapligo!

Running the Examples

You need Go 1.16+ installed. Clone the repo and go run any of the examples in the examples folder.

Executing a number of commands (from a file)

$  go run examples/base_driver/main.go
found prompt: 
csr1000v-1#


sent command 'show version', output received:
 Cisco IOS XE Software, Version 16.09.03
Cisco IOS Software [Fuji], Virtual XE Software (X86_64_LINUX_IOSD-UNIVERSALK9-M), Version 16.9.3, RELEASE SOFTWARE (fc2)
Technical Support: http://www.cisco.com/techsupport
Copyright (c) 1986-2019 by Cisco Systems, Inc.
Compiled Wed 20-Mar-19 07:56 by mcpre
...

Parsing a command output

For more details, check out Network automation options in Go with scrapligo.

$  go run examples/network_driver/textfsm/main.go
Hostname: csr1000v-1
SW Version: 16.9.3
Uptime: 18 minutes

Code Example

package main

import (
	"fmt"

	"github.com/scrapli/scrapligo/driver/base"
	"github.com/scrapli/scrapligo/driver/core"
)

func main() {
	d, err := core.NewCoreDriver(
		"localhost",
		"cisco_iosxe",
		base.WithPort(21022),
		base.WithAuthStrictKey(false),
		base.WithAuthUsername("vrnetlab"),
		base.WithAuthPassword("VR-netlab9"),
		base.WithAuthSecondary("VR-netlab9"),
	)

	if err != nil {
		fmt.Printf("failed to create driver; error: %+v\n", err)
		return
	}

	err = d.Open()
	if err != nil {
		fmt.Printf("failed to open driver; error: %+v\n", err)
		return
	}
	defer d.Close()

	// send some configs
	configs := []string{
		"interface loopback0",
		"interface loopback0 description tacocat",
		"no interface loopback0",
	}

	_, err = d.SendConfigs(configs)
	if err != nil {
		fmt.Printf("failed to send configs; error: %+v\n", err)
		return
	}
}

* gopher artwork by @egonelbre

Comments
  • GetConfig JunOS issue

    GetConfig JunOS issue

    Hello.

    Doing my first steps in Go while trying to implement Go agalogue of:

    from ncclient import manager
    
    with manager.connect(
        host="10.10.30.4",
        port=22,
        username="admin",
        password="Juniper",
    ) as m:
        r = m.get_config("running")
        print(r)
    

    which works perfectly fine.

    This is the code:

    package main
    
    import (
           "fmt"
    
           "github.com/scrapli/scrapligo/driver/base"
           "github.com/scrapli/scrapligo/netconf"
    )
    
    func getConfig(addr string) {
           d, _ := netconf.NewNetconfDriver(
                   addr,
                   base.WithPort(22),
                   base.WithAuthStrictKey(false),
                   base.WithAuthUsername("admin"),
                   base.WithAuthPassword("Juniper"),
           )
    
           err := d.Open()
           if err != nil {
                   fmt.Printf("failed to open driver; error: %+v\n", err)
                   return
           }
           defer d.Close()
    
           r, err := d.GetConfig("running")
           if err != nil {
                   fmt.Printf("failed to get config; error: %+v\n", err)
                   return
           }
    
           fmt.Printf("Get Config Response:\n%s\n", r.Result)
    }
    
    func getRPC(addr string, rpc string) {
           d, _ := netconf.NewNetconfDriver(
                   addr,
                   base.WithPort(22),
                   base.WithAuthStrictKey(false),
                   base.WithAuthUsername("admin"),
                   base.WithAuthPassword("Juniper"),
           )
    
           err := d.Open()
           if err != nil {
                   fmt.Printf("failed to open driver; error: %+v\n", err)
                   return
           }
           defer d.Close()
    
           r, err := d.RPC(netconf.WithNetconfFilter(rpc))
           if err != nil {
                   fmt.Printf("failed to get config; error: %+v\n", err)
                   return
           }
    
           fmt.Printf("Get Config Response:\n%s\n", r.Result)
    }
    
    
    func main() {
           getRPC("10.10.30.4", "<get-route-engine-information/>")
           getConfig("10.10.30.4")
    }
    

    RPC works but GetConfig doesn't:

    Get Config Response:
    <nc:rpc-reply xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:junos="http://xml.juniper.net/junos/19.2R0/junos" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
    <route-engine-information xmlns="http://xml.juniper.net/junos/19.2R0/junos-chassis">
    <route-engine>
    <slot>0</slot>
    <mastership-state>master</mastership-state>
    <mastership-priority>master (default)</mastership-priority>
    <status>OK</status>
    <memory-dram-size>2002 MB</memory-dram-size>
    <memory-installed-size>(2048 MB installed)</memory-installed-size>
    <memory-buffer-utilization>45</memory-buffer-utilization>
    <cpu-user>1</cpu-user>
    <cpu-background>0</cpu-background>
    <cpu-system>2</cpu-system>
    <cpu-interrupt>1</cpu-interrupt>
    <cpu-idle>96</cpu-idle>
    <cpu-user1>2</cpu-user1>
    <cpu-background1>0</cpu-background1>
    <cpu-system1>2</cpu-system1>
    <cpu-interrupt1>0</cpu-interrupt1>
    <cpu-idle1>95</cpu-idle1>
    <cpu-user2>2</cpu-user2>
    <cpu-background2>0</cpu-background2>
    <cpu-system2>2</cpu-system2>
    <cpu-interrupt2>1</cpu-interrupt2>
    <cpu-idle2>95</cpu-idle2>
    <cpu-user3>2</cpu-user3>
    <cpu-background3>0</cpu-background3>
    <cpu-system3>3</cpu-system3>
    <cpu-interrupt3>1</cpu-interrupt3>
    <cpu-idle3>84</cpu-idle3>
    <model>RE-VMX</model>
    <start-time junos:seconds="1651771969">2022-05-05 17:32:49 UTC</start-time>
    <up-time junos:seconds="2112">35 minutes, 12 seconds</up-time>
    <last-reboot-reason>Router rebooted after a normal shutdown.</last-reboot-reason>
    <load-average-one>0.44</load-average-one>
    <load-average-five>0.42</load-average-five>
    <load-average-fifteen>0.45</load-average-fifteen>
    </route-engine>
    </route-engine-information>
    </nc:rpc-reply>
    ]]>]]>
    
    Get Config Response:
    <nc:rpc-reply xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:junos="http://xml.juniper.net/junos/19.2R0/junos" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
    <nc:rpc-error>
    <nc:error-type>protocol</nc:error-type>
    <nc:error-tag>operation-failed</nc:error-tag>
    <nc:error-severity>error</nc:error-severity>
    <nc:error-message>syntax error, expecting &lt;candidate/&gt; or &lt;running/&gt;</nc:error-message>
    <nc:error-info>
    <nc:bad-element>running</nc:bad-element>
    </nc:error-info>
    </nc:rpc-error>
    <nc:rpc-error>
    <nc:error-type>protocol</nc:error-type>
    <nc:error-tag>operation-failed</nc:error-tag>
    <nc:error-severity>error</nc:error-severity>
    <nc:error-message>syntax error, expecting &lt;candidate/&gt; or &lt;running/&gt;</nc:error-message>
    <nc:error-info>
    <nc:bad-element>running</nc:bad-element>
    </nc:error-info>
    </nc:rpc-error>
    </nc:rpc-reply>
    ]]>]]>
    

    What am I doing wrong here?

    And there is one more thing: if I change port to 830 (works great from shell or ncclient) I get:

    failed to open driver; error: error reading from transport, cannot continue
    

    Could you pls shed some light on how to use that?! Thank you.

    opened by horseinthesky 47
  • ssh handshake failed: no common algorithm for key exchange

    ssh handshake failed: no common algorithm for key exchange

    Hey Carl,

    i'm trying to access an old Cisco C3560. I get the following error message. I´ve seen that there is no way to set the kexalgorithms.

    failed to open driver; error: ssh: handshake failed: ssh: no common algorithm for key exchange; client offered: [[email protected] ecdh-sha2-nistp256 ecdh-sha2-nistp384 ecdh-sha2-nistp521 diffie-hellman-group14-sha1], server offered: [diffie-hellman-group1-sha1]

    I´ve lookup in the ssh package, that you can set the kexalgorithms up: https://pkg.go.dev/golang.org/x/crypto/ssh#Config --> KeyExchanges []string

    Im more then happy to test a new build, if we can come up with a solution :)

    Regards, Romario

    opened by Bofrostmann07 12
  • data race in channel

    data race in channel

    When using scrapligo from goroutines, go detects a race:

    go run -race main.go
    ==================
    WARNING: DATA RACE
    Write at 0x000000a5f190 by goroutine 9:
      github.com/scrapli/scrapligo/channel.getAuthPatterns()
          /home/mk/go/pkg/mod/github.com/scrapli/[email protected]/channel/authenticate.go:21 +0x144
      github.com/scrapli/scrapligo/channel.(*Channel).authenticateSSH()
          /home/mk/go/pkg/mod/github.com/scrapli/[email protected]/channel/authenticate.go:34 +0x294
      github.com/scrapli/scrapligo/channel.(*Channel).AuthenticateSSH.func1()
          /home/mk/go/pkg/mod/github.com/scrapli/[email protected]/channel/authenticate.go:120 +0xc4
    
    Previous read at 0x000000a5f190 by goroutine 10:
      github.com/scrapli/scrapligo/channel.getAuthPatterns()
          /home/mk/go/pkg/mod/github.com/scrapli/[email protected]/channel/authenticate.go:20 +0x30
      github.com/scrapli/scrapligo/channel.(*Channel).authenticateSSH()
          /home/mk/go/pkg/mod/github.com/scrapli/[email protected]/channel/authenticate.go:34 +0x294
      github.com/scrapli/scrapligo/channel.(*Channel).AuthenticateSSH.func1()
          /home/mk/go/pkg/mod/github.com/scrapli/[email protected]/channel/authenticate.go:120 +0xc4
    
    Goroutine 9 (running) created at:
      github.com/scrapli/scrapligo/channel.(*Channel).AuthenticateSSH()
          /home/mk/go/pkg/mod/github.com/scrapli/scr[email protected]/channel/authenticate.go:119 +0x1ea
      github.com/scrapli/scrapligo/driver/base.(*Driver).Open()
          /home/mk/go/pkg/mod/github.com/scrapli/[email protected]/driver/base/base.go:74 +0x631
      github.com/scrapli/scrapligo/driver/network.(*Driver).Open()
          /home/mk/go/pkg/mod/github.com/scrapli/[email protected]/driver/network/network.go:82 +0x32
      main.getVersion()
          /home/mk/Network-Automation-with-Go/ch03/concurrency4/main.go:48 +0x544
      main.main·dwrap·4()
          /home/mk/Network-Automation-with-Go/ch03/concurrency4/main.go:114 +0x109
    
    

    Can I suggest replacing

    func getAuthPatterns() *authPatterns {
    	if authPatternsInstance == nil {
    		authPatternsInstance = &authPatterns{
    			telnetLoginPattern: regexp.MustCompile(`(?im)^(.*username:)|(.*login:)\s?$`),
    			passwordPattern:    regexp.MustCompile(`(?im)^(.*@.*)?password:\s?$`),
    			passphrasePattern:  regexp.MustCompile(`(?i)enter passphrase for key`),
    		}
    	}
    
    	return authPatternsInstance
    }
    

    with

    func init() {
    	if authPatternsInstance == nil {
    		authPatternsInstance = &authPatterns{
    			telnetLoginPattern: regexp.MustCompile(`(?im)^(.*username:)|(.*login:)\s?$`),
    			passwordPattern:    regexp.MustCompile(`(?im)^(.*@.*)?password:\s?$`),
    			passphrasePattern:  regexp.MustCompile(`(?i)enter passphrase for key`),
    		}
    	}
    
    }
    

    with these changes race is not detected.

    opened by networkop 11
  • CiscoIOSXE Authentication fails when login banner does not end with blank line

    CiscoIOSXE Authentication fails when login banner does not end with blank line

    When connecting to a Cisco IOSXE device (have not tested with others) that contains a login banner, where the login banner does not end on a blank line, the SSH Authentication times out as the passwordPattern in func GetAuthPatterns() is not matched

    Example with IOSv that ships with Cisco CML, out of the box, the default login banner configuration is this:

    banner login ^C
    **************************************************************************
    * IOSv is strictly limited to use for evaluation, demonstration and IOS  *
    * education. IOSv is provided as-is and is not supported by Cisco's      *
    * Technical Advisory Center. Any use or disclosure, in whole or in part, *
    * of the IOSv Software or Documentation to any third party for any       *
    * purposes is expressly prohibited except as otherwise authorized by     *
    * Cisco in writing.                                                      *
    **************************************************************************^C
    

    because the banner does not end on a blank line the password prompt appear in a format that does not match the regular expression for the passwordPattern defined in func GetAuthPatterns(): passwordPattern: regexp.MustCompile(`(?im)^(.*@.*)?password:\s?$`),

    removing the banner, or Changing the banner as follows does solve this problem:

    banner login ^C
    **************************************************************************
    * IOSv is strictly limited to use for evaluation, demonstration and IOS  *
    * education. IOSv is provided as-is and is not supported by Cisco's      *
    * Technical Advisory Center. Any use or disclosure, in whole or in part, *
    * of the IOSv Software or Documentation to any third party for any       *
    * purposes is expressly prohibited except as otherwise authorized by     *
    * Cisco in writing.                                                      *
    **************************************************************************
    ^C
    

    However, could this also be solved by changing the password prompt regex? Changing the pattern to: passwordPattern: regexp.MustCompile(`(?im)^(.*)?password:\s?$`), does solve the problem, but not sure if that will cause other issues (if there was use cases that required the .*@.* to match instead of just .*)?

    alternatively, is there the ability to pass a custom regex for this prompt in anywhere?

    opened by dpnetca 9
  • Incorrect chunk matching with netconf 1.1 (and ## in output)

    Incorrect chunk matching with netconf 1.1 (and ## in output)

    Hello,

    I have an issue while reading a device config, using a simple GetConfig("running"): the output returned by Result is truncated. Looking further, It's truncated here:

    <next-hops>
             <next-hop>
              <index
    

    The original data returned by the device is visible in the logs:

          <next-hops>
             <next-hop>
              <index>##10.222.18.65##</index>
    

    We can see that the output is truncated at the ## character.

    I think the issue lies with the record1dot1() function (since the router is using netconf 1.1), In particular,

    chunkSections := patterns.v1dot1Chunk.FindAllSubmatch(r.RawResult, -1)
    

    is cutting the final chunk at the <index> tag.

    I can see with the debugger that the final chunk has length 45100, but it's size should be 106234. This sets the r.Failed (which I didn't notice before investigating this issue).

    I therefore think that the v1dot1Chunk is wrong. A chunk on my device looks like this:

    #106234
      <netconf-yang xmlns="http://cisco.com/ns/yang/Cisco-IOS-XR-um-netconf-yang-cfg">
       <agent>
        <ssh/>
       </agent>
      </netconf-yang>
    

    and the pattern is v1dot1Chunk: regexp.MustCompile(`(?ms)(\d+)\n(.*?)#`),.

    I had success on this router by changing the pattern to (?ms)(\d+)\n(.*?)^#, but I don't know if it breaks other things.

    opened by netixx 7
  • Make scrapligo-netconf work with older nxos devices

    Make scrapligo-netconf work with older nxos devices

    Some nxos devices require 2 XML namespace attributes in the RPC element. ( see https://community.cisco.com/t5/network-management/netconf-get-config-error-wrong-document-namespaces-not-specified/td-p/3298323 ) It would be nice if we could define a second namespace while doing netconf operations with such devices.

    According to my testing, defining the namespace in the raw filter query does not work. After the request, I'll get back a default hello reply and the device closes the connection. Sometimes, there is an RPC namespace missing error msg.

    Request:

    2022/03/09 15:19:05 write::localhost::10022::write: 
    <?xml version="1.0" encoding="UTF-8"?>
    <rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
    <get>
    <filter type="subtree">
    <show xmlns="http://www.cisco.com/nxos:1.0:nfcli">
    <interface>
    </interface>
    </show>
    </filter>
    </get>
    </rpc>]]>]]>
    

    Reply

    2022/03/09 15:19:05 debug::localhost::10022::read: <?xml version="1.0" encoding="utf-8"?>
    <hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
         <capabilities>
             <capability>urn:ietf:params:netconf:base:1.0</capability>
         </capabilities>
    </hello>]]>]]>
    

    Reply with error msg

    022/03/09 15:19:03 debug::localhost::10022::read: <?xml version="1.0" encoding="ISO-8859-1"?>
    <rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
      <rpc-error>
        <error-type>rpc</error-type>
        <error-tag>missing-attribute</error-tag>
        <error-severity>error</error-severity>
        <error-message>Wrong document: namespaces not specified</error-message>
        <error-info>
          <bad-element>rpc</bad-element>
        </error-info>
      </rpc-error>
    </rpc-reply>
    ]]>]]>
    
    opened by tamasv 6
  • Extra prompt at the end of the output

    Extra prompt at the end of the output

    Hello,

    While testing a juniper device (finding the issue requiring to pass options.WithNetconfForceSelfClosingTags(),).

    I get the following r.Result (only the end, for brevity):

    </configuration>
    </nc:data>
    </nc:rpc-reply>
    ]]>]]>
    

    (note that there is not newline after the prompt)

    It seems to me that this shouldn't be the case. During my other tests, the output was only the XML. One of the difference between my previous tests is that this device only supports netconf 1.0 (I guess there is something different with the 1.0 code path).

    opened by netixx 5
  • defunct issue

    defunct issue

    here is my sample code :

    package main import ( "fmt" "github.com/scrapli/scrapligo/response" "github.com/scrapli/scrapligo/driver/options" "github.com/scrapli/scrapligo/platform" "time" )

    func main() { for { _, err := ExecCmd([]string{"sho run","show ver"}, "x.x.x.x", "cml20") if err != nil { panic("wrong") } time.Sleep(10 * time.Duration(time.Second)) }

    }

    func ExecCmd(cmdlist []string, deviceip string, devicename string) (response.MultiResponse, error) { p, err := platform.NewPlatform( // cisco_iosxe refers to the included cisco iosxe platform definition "cisco_iosxr", deviceip, options.WithPort(22), options.WithAuthNoStrictKey(), options.WithTimeoutOps(120time.Second), options.WithAuthUsername("admin"), options.WithAuthPassword("admin"), options.WithTermWidth(256), options.WithTermHeight(0), ) if err != nil { fmt.Printf("failed to create platform for %s(%s); error: %+v\n", devicename, deviceip, err) return nil, err } d, err := p.GetNetworkDriver() if err != nil { fmt.Printf("failed to fetch network driver for %s(%s) ; error: %+v\n", devicename, deviceip, err) return nil, err } err = d.Open() if err != nil { fmt.Printf("failed to open driver %s(%s); error: %+v\n", devicename, deviceip, err) return nil, err } defer d.Close() mr, err := d.SendCommands(cmdlist, options.WithTimeoutOps(120*time.Second)) return mr, err }


    I found lots of defunct processes, Every 1.0s: ps -ef | grep ssh | grep -v grep | grep -v sshd Mon Aug 8 04:40:00 2022 root 344 32616 0 04:39 ? 00:00:00 [ssh] root 428 32616 0 04:39 ? 00:00:00 [ssh] root 516 32616 0 04:39 ? 00:00:00 [ssh] root 601 32616 0 04:39 ? 00:00:00 [ssh] root 32622 32616 0 04:38 ? 00:00:00 [ssh] root 32692 32616 0 04:38 ? 00:00:00 [ssh] root 32740 32616 0 04:39 ? 00:00:00 [ssh]

    How can we avoid it?

    thanks.

    opened by lulianbing58 5
  • add sonic platform

    add sonic platform

    Im having a little look at adding sonic to the list of supported platforms so I can use Boxen to stand up Sonic relatively quickly on MacOs (and anywhere else). I really like the minimalist/streamlined code here and have largely scaffolded from the PanOS material because it looks so similar. No Go expert and welcome stewarding of my ability wherever its needed!

    opened by fire-ant 5
  • Junos Regex and config load fixes. Adds another example.

    Junos Regex and config load fixes. Adds another example.

    -Fixes a possible bug where LoadConfig always overrides current config. Now user can merge with the existing config instead of overriding.

    -Fixes junos shell and root-shell regex to adapt to the wider range of junos devices.

    Examples os shell prompts: start shell:

    • %
    • [vrf:foo] regress@EVOvFOOBAR_RE0-re0:~$

    start shell user root:

    • root@vMX1_RE:/var/home/regress #
    • [vrf:foo] root@EVOvFOOBAR_RE0-re0:~#

    Tested these regexes here: https://regex101.com/

    -Also added a LoadConfig example as it didn't exist in any of the examples.

    opened by nitinsoniism 5
  • Run examples with make in DevNet always-on device

    Run examples with make in DevNet always-on device

    What do you think if the examples run against the DevNet always-on IOS-XE device, so anyone can run the examples?

    I also added them to the Make file, so you can execute them from the root (all but the NETCONF one)

    $ make
    base-example                   Run Base example
    lint                           Run linters
    net-channellog-example         Run Network Channel Log example
    net-factory-example            Run Network Factory example
    net-interactive-example        Run Network Interactive example
    net-log-example                Run Network logging example
    net-onopen-example             Run Network On Open example
    net-simple-example             Run Network simple example
    test                           Test execution
    

    I added a note in the readme on how you would run the examples.

    $  make net-simple-example 
    found prompt: 
    csr1000v-1#
    
    
    sent command 'show version', output received:
     Cisco IOS XE Software, Version 16.09.03
    Cisco IOS Software [Fuji], Virtual XE Software (X86_64_LINUX_IOSD-UNIVERSALK9-M), Version 16.9.3, RELEASE SOFTWARE (fc2)
    Technical Support: http://www.cisco.com/techsupport
    Copyright (c) 1986-2019 by Cisco Systems, Inc.
    Compiled Wed 20-Mar-19 07:56 by mcpre
    ...
    

    PS: I added a bit more space between the outputs to make it more clear.

    opened by nleiva 5
  • forceSelfClosingTags may return empty data

    forceSelfClosingTags may return empty data

    Hello,

    While testing get-operationnal queries on a juniper device that uses netconf 1.0, I was getting timeouts... so I looked around in the debugger and found out that the forceSelfClosingTags (which needs to be used with juniper because of a bug), erases the query alltogether.

    See the following MWP (I copied the forceSelfClosingTags function and hard-coded the pattern):

    package main
    
    import (
    	"fmt"
    	"regexp"
    )
    
    func main() {
    	req := `
    	<?xml version="1.0" encoding="UTF-8"?><rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101"><get><filter type="subtree">
    	<routing-policy xmlns="http://openconfig.net/yang/routing-policy"></routing-policy>
    	</filter></get></rpc>]]>]]>
    	`
    	print("filter")
    	print(req)
    	print("self-close")
    	print(string(forceSelfClosingTags([]byte(req))))
    }
    
    func forceSelfClosingTags(b []byte) []byte {
    
    	emptyTagIdxs := regexp.MustCompile(`<(\w+)></\w+>`).FindAllSubmatchIndex(b, -1)
    
    	var nb []byte
    
    	for _, idx := range emptyTagIdxs {
    		// get everything in b up till the first of the submatch indexes (this is the start of an
    		// "empty" <thing></thing> tag), then get the name of the tag and put it in a self-closing
    		// tag.
    		nb = append(b[0:idx[0]], fmt.Sprintf("<%s/>", b[idx[2]:idx[3]])...) //nolint: gocritic
    
    		// finally, append everything *after* the submatch indexes
    		nb = append(nb, b[len(b)-(len(b)-idx[1]):]...)
    	}
    
    	return nb
    }
    

    and it's output:

    filter
            <?xml version="1.0" encoding="UTF-8"?><rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101"><get><filter type="subtree">
            <routing-policy xmlns="http://openconfig.net/yang/routing-policy"></routing-policy>
            </filter></get></rpc>]]>]]>
            self-close                                                                                                                                                                                          
    

    It seems to me that the pattern is too restrictive. A self-closing tag may contain any valid attributes.

    I've experimented with this replace function instead (with some success):

    func forceSelfClosingTags(b []byte) []byte {
    
    	cleanStr := regexp.MustCompile(`<([^>/]+?)>\s*</[\w-]+>`).ReplaceAllString(string(b), "<$1/>")
    
    	return []byte(cleanStr)
    }
    
    opened by netixx 3
Releases(v1.1.4)
  • v1.1.4(Nov 13, 2022)

    What's Changed

    • Support supplying private key with system transport by @netixx in https://github.com/scrapli/scrapligo/pull/104
    • fix: fixes nc1.0 not stripping delim, update junos golden test output… by @carlmontanari in https://github.com/scrapli/scrapligo/pull/102
    • Fix transport close() to also close the underlying client by @mayuresh82 in https://github.com/scrapli/scrapligo/pull/108
    • Fix goroutine leak in channel.read when transport is closed by @mayuresh82 in https://github.com/scrapli/scrapligo/pull/109
    • Add tacacs+ configure prompt in cisco assets platform. by @dmmjy9 in https://github.com/scrapli/scrapligo/pull/111
    • updates to NETCONF error checking & adding subscription example by @0x2142 in https://github.com/scrapli/scrapligo/pull/110

    New Contributors

    • @netixx made their first contribution in https://github.com/scrapli/scrapligo/pull/104
    • @mayuresh82 made their first contribution in https://github.com/scrapli/scrapligo/pull/108
    • @dmmjy9 made their first contribution in https://github.com/scrapli/scrapligo/pull/111
    • @0x2142 made their first contribution in https://github.com/scrapli/scrapligo/pull/110

    Full Changelog: https://github.com/scrapli/scrapligo/compare/v1.1.3...v1.1.4

    Source code(tar.gz)
    Source code(zip)
  • v1.1.3(Oct 4, 2022)

    What's Changed

    • propagate multiresponse failed status to the combined response of SendConfig by @hellt in https://github.com/scrapli/scrapligo/pull/101

    Full Changelog: https://github.com/scrapli/scrapligo/compare/v1.1.2...v1.1.3

    Source code(tar.gz)
    Source code(zip)
  • v1.1.2(Jul 25, 2022)

    What's Changed

    • Add Netconf WithFilter by @no-such-anthony in https://github.com/scrapli/scrapligo/pull/86
    • ensure platform failedwhencontains is set by @carlmontanari in https://github.com/scrapli/scrapligo/pull/90
    • Updated srl prompts by @hellt in https://github.com/scrapli/scrapligo/pull/91

    New Contributors

    • @no-such-anthony made their first contribution in https://github.com/scrapli/scrapligo/pull/86

    Full Changelog: https://github.com/scrapli/scrapligo/compare/v1.1.1...v1.1.2

    Source code(tar.gz)
    Source code(zip)
  • v1.1.1(Jul 15, 2022)

    What's Changed

    • Channel close bugfix by @carlmontanari in https://github.com/scrapli/scrapligo/pull/85

    Full Changelog: https://github.com/scrapli/scrapligo/compare/v1.1.0...v1.1.1

    Source code(tar.gz)
    Source code(zip)
  • v1.1.0(Jul 10, 2022)

    What's Changed

    • include dot char in a hostname patter for junos by @hellt in https://github.com/scrapli/scrapligo/pull/84
    • Platform type and win by @carlmontanari in https://github.com/scrapli/scrapligo/pull/83

    Full Changelog: https://github.com/scrapli/scrapligo/compare/v1.0.3...v1.1.0

    Source code(tar.gz)
    Source code(zip)
  • v1.0.3(Jul 6, 2022)

    What's Changed

    • master->main by @hellt in https://github.com/scrapli/scrapligo/pull/81
    • build tags and some tidying to allow windows use in commando by @carlmontanari in https://github.com/scrapli/scrapligo/pull/82

    Full Changelog: https://github.com/scrapli/scrapligo/compare/v1.0.2...v1.0.3

    Source code(tar.gz)
    Source code(zip)
  • v1.0.2(Jul 5, 2022)

    What's Changed

    • accept yaml bytes or string filepath/url by @carlmontanari in https://github.com/scrapli/scrapligo/pull/80

    Full Changelog: https://github.com/scrapli/scrapligo/compare/v1.0.1...v1.0.2

    Source code(tar.gz)
    Source code(zip)
  • v1.0.1(Jul 2, 2022)

    What's Changed

    • add open args override and open bin options for system transport by @carlmontanari in https://github.com/scrapli/scrapligo/pull/79

    Full Changelog: https://github.com/scrapli/scrapligo/compare/v1.0.0...v1.0.1

    Source code(tar.gz)
    Source code(zip)
  • v1.0.0(Jul 2, 2022)

    What's Changed

    • force self closing tag option by @carlmontanari in https://github.com/scrapli/scrapligo/pull/76
    • V1.0.0 beta by @carlmontanari in https://github.com/scrapli/scrapligo/pull/78
      • Far too much to list on this PR as it was basically a near re-write! Things have stayed similar but hopefully are a bit more idiomatic and generally nicer (though still not super idiomatic in many respects as we are still trying to stay similar to the python roots). Please see the "whats changed" section of the readme (bottom of the page) for the list of major changes.

    Full Changelog: https://github.com/scrapli/scrapligo/compare/v0.1.3...v1.0.0

    Source code(tar.gz)
    Source code(zip)
  • v0.1.3(May 6, 2022)

    What's Changed

    • Make TextFsmParse recognise URLs by @networkop in https://github.com/scrapli/scrapligo/pull/63
    • In channel auth pattern options by @carlmontanari in https://github.com/scrapli/scrapligo/pull/66
    • improve escalate auth handling, redact passwords from channel log by @carlmontanari in https://github.com/scrapli/scrapligo/pull/75

    New Contributors

    • @networkop made their first contribution in https://github.com/scrapli/scrapligo/pull/63

    Full Changelog: https://github.com/scrapli/scrapligo/compare/v0.1.2...v0.1.3

    Source code(tar.gz)
    Source code(zip)
  • v0.1.2(Dec 22, 2021)

    • Added "bare" RPC netconf operation #54
    • Fix regex pattern possible race condition #56 #57 (thank you @networkop and @hellt)
    • Added Palo Alto PanOS support #58
    • Fixed build for Windows (🤮 ) #55
    • Added ReadWithCallbacks method to driver #60
    Source code(tar.gz)
    Source code(zip)
  • v0.1.1(Sep 23, 2021)

    • Fixed netconf auth failure not reporting error
    • Added option to set cfg CandidateConfigFIle name (thank you to @nitinsoniism )
    • Handle privilege escalation for secondary auth better
    • Fixed netconf capabilities exchange to not break if server has namespaces (thank you to @hellt )
    Source code(tar.gz)
    Source code(zip)
  • v0.1.0(Aug 31, 2021)

Owner
null
Capdns is a network capture utility designed specifically for DNS traffic. This utility is based on tcpdump.

Capdns is a network capture utility designed specifically for DNS traffic. This utility is based on tcpdump. Some of its features include: Unde

Infvie Envoy 10 Feb 26, 2022
Gsshrun - Running commands via ssh on the server/hosting (if ssh support) specified in the connection file

Gsshrun - Running commands via ssh on the server/hosting (if ssh support) specified in the connection file

Məhəmməd 2 Sep 8, 2022
NETCONF client implementation in go.

❗ Red Hat does not provide commercial support for the content of these repos #########################################################################

Community of OpenShift Telco Experiments 14 Dec 26, 2022
A memory-safe SSH server, focused on listening only on VPN networks such as Tailscale

Features Is tested to work with SCP Integrates well with systemd Quickstart Download binary for your architecture. We only support Linux. If you don't

function61.com 2 Jun 10, 2022
Helps you to send ssh commands to target machine in your local network from outside via gRPC

rpc-ssh In case, you don't want to make your ssh port accessible from outside local network. This repository helps you to send ssh commands to target

Berkay Akyazı 2 Nov 16, 2022
TFTP and HTTP server specifically designed to serve iPXE ROMs and scripts.

pixie TFTP and HTTP server specifically designed to serve iPXE ROMs and scripts. pixie comes embedded with the following ROMs provided by the iPXE pro

Adrian L Lange 18 Dec 31, 2022
A Go library for connecting to HandlerSocket (github.com/ahiguti/HandlerSocket-Plugin-for-MySQL)

handlersocket-go Go library for connecting to HandlerSocket Mysql plugin. See github.com/ahiguti/HandlerSocket-Plugin-for-MySQL/ Installation $ go get

Brian Ketelsen 47 Jan 19, 2021
🤘 The native golang ssh client to execute your commands over ssh connection. 🚀🚀

Golang SSH Client. Fast and easy golang ssh client module. Goph is a lightweight Go SSH client focusing on simplicity! Installation ❘ Features ❘ Usage

Mohamed El Bahja 1.2k Dec 24, 2022
Extended ssh-agent which supports git commit signing over ssh

ssh-agentx ssh-agentx Rationale Requirements Configuration ssh-agentx Configuration ssh-gpg-signer Linux Windows Signing commits after configuration T

Wim 10 Jun 29, 2022
Golang `net/rpc` over SSH using installed SSH program

Golang net/rpc over SSH using installed SSH program This package implements a helper functions to launch an RPC client and server. It uses the install

null 1 Nov 16, 2022
one simple git ssh server (just for learning git over ssh )

wriet one simple git ssh server use golang write one simple git ssh server how to running starting service docker-compose up -d add authorized_keys i

rong fengliang 2 Mar 5, 2022
Control your legacy Reciva based internet radios (Crane, Grace Digital, Tangent, etc.) via REST api or web browser.

reciva-web-remote Control your legacy Reciva based internet radios (Crane, Grace Digital, Tangent, etc.) via REST api or web browser. Usage This progr

null 6 May 3, 2022
Docker4ssh: Docker containers and more via ssh

docker4ssh - docker containers and more via ssh docker4ssh is an ssh server that

null 6 Jun 2, 2022
`kawipiko` -- blazingly fast static HTTP server -- focused on low latency and high concurrency, by leveraging Go, `fasthttp` and the CDB embedded database

kawipiko -- blazingly fast static HTTP server kawipiko is a lightweight static HTTP server written in Go; focused on serving static content as fast an

Volution 318 Jan 3, 2023
Connect your devices into a single private WireGuard®-based mesh network.

Wiretrustee A WireGuard®-based mesh network that connects your devices into a single private network. Why using Wiretrustee? Connect multiple devices

null 4k Dec 31, 2022
Tool for monitoring network devices (mainly using SNMP) - monitoring check plugin

Thola Description A tool for monitoring network devices written in Go. It features a check mode which complies with the monitoring plugins development

inexio 265 Dec 29, 2022
Prometheus exporter for counting connected devices to a network using nmap

nmapprom Prometheus exporter for counting the hosts connected to a network using nmap · Report Bug · Request Feature Table of Contents About The Proje

Oisín Aylward 3 Oct 17, 2021
Chisel is a fast TCP/UDP tunnel, transported over HTTP, secured via SSH.

Chisel is a fast TCP/UDP tunnel, transported over HTTP, secured via SSH. Single executable including both client and server. Written in Go (golang). Chisel is mainly useful for passing through firewalls, though it can also be used to provide a secure endpoint into your network.

Jaime Pillora 8.4k Jan 1, 2023
Netpoll is a high-performance non-blocking I/O networking framework, which focused on RPC scenarios, developed by ByteDance.

Netpoll is a high-performance non-blocking I/O networking framework, which focused on RPC scenarios, developed by ByteDance. RPC is usually heavy on processing logic and therefore cannot handle I/O serially. But Go's standard library net designed blocking I/O API, so that the RPC framework can only follow the One Conn One Goroutine design.

CloudWeGo 3.3k Jan 2, 2023