Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compile patterns once #57

Merged
merged 4 commits into from
Nov 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions cfg/aristaeos.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"regexp"
"strings"
"sync"
"time"

"github.com/scrapli/scrapligo/logging"
Expand All @@ -18,16 +19,19 @@ type eosPatterns struct {
endPattern *regexp.Regexp
}

var eosPatternsInstance *eosPatterns //nolint:gochecknoglobals
var (
eosPatternsInstance *eosPatterns //nolint:gochecknoglobals
eosPatternsInstanceOnce sync.Once //nolint:gochecknoglobals
)

func getEOSPatterns() *eosPatterns {
if eosPatternsInstance == nil {
eosPatternsInstanceOnce.Do(func() {
eosPatternsInstance = &eosPatterns{
globalCommentLinePattern: regexp.MustCompile(`(?im)^! .*$`),
bannerPattern: regexp.MustCompile(`(?ims)^banner.*EOF$`),
endPattern: regexp.MustCompile(`end$`),
}
}
})

return eosPatternsInstance
}
Expand Down
14 changes: 9 additions & 5 deletions cfg/ciscoiosxe.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"regexp"
"strings"
"sync"

"github.com/scrapli/scrapligo/channel"

Expand All @@ -25,10 +26,13 @@ type iosxePatterns struct {
outputHeaderPattern *regexp.Regexp
}

var iosxePatternsInstance *iosxePatterns //nolint:gochecknoglobals
var (
iosxePatternsInstance *iosxePatterns //nolint:gochecknoglobals
iosxePatternsInstanceOnce sync.Once //nolint:gochecknoglobals
)

func getIOSXEPatterns() *iosxePatterns {
if iosxePatternsInstance == nil {
iosxePatternsInstanceOnce.Do(func() {
iosxePatternsInstance = &iosxePatterns{
bytesFreePattern: regexp.MustCompile(
`(?i)(?P<bytes_available>\d+)(?: bytes free)`,
Expand All @@ -38,7 +42,7 @@ func getIOSXEPatterns() *iosxePatterns {
// string in the config so we can remove anything in front of it
outputHeaderPattern: regexp.MustCompile(`(?im)(^version \d+\.\d+$)`),
}
}
})

return iosxePatternsInstance
}
Expand All @@ -54,8 +58,8 @@ type IOSXECfg struct {
replaceConfig bool
}

// NewIOSXECfg return a cfg instance setup for an Cisco IOSXE device.
func NewIOSXECfg(
// NewIOSXECfg return a cfg instance setup for a Cisco IOSXE device.
func NewIOSXECfg( //nolint:dupl
conn *network.Driver,
options ...Option,
) (*Cfg, error) {
Expand Down
10 changes: 7 additions & 3 deletions cfg/ciscoiosxr.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"regexp"
"strings"
"sync"

"github.com/scrapli/scrapligo/logging"

Expand All @@ -23,10 +24,13 @@ type iosxrPatterns struct {
endPattern *regexp.Regexp
}

var iosxrPatternsInstance *iosxrPatterns //nolint:gochecknoglobals
var (
iosxrPatternsInstance *iosxrPatterns //nolint:gochecknoglobals
iosxrPatternsInstanceOnce sync.Once //nolint:gochecknoglobals
)

func getIOSXRPatterns() *iosxrPatterns {
if iosxrPatternsInstance == nil {
iosxrPatternsInstanceOnce.Do(func() {
iosxrPatternsInstance = &iosxrPatterns{
bannerDelimPattern: regexp.MustCompile(
`(?im)(^banner\s(?:exec|incoming|login|motd|prompt-timeout|slip-ppp)\s(.))`,
Expand All @@ -51,7 +55,7 @@ func getIOSXRPatterns() *iosxrPatterns {
iosxrPatternsInstance.configChangePattern.String(),
),
)
}
})

return iosxrPatternsInstance
}
Expand Down
10 changes: 7 additions & 3 deletions cfg/cisconxos.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"regexp"
"strings"
"sync"
"time"

"github.com/scrapli/scrapligo/logging"
Expand All @@ -24,10 +25,13 @@ type nxosPatterns struct {
checkpointLinePattern *regexp.Regexp
}

var nxosPatternsInstance *nxosPatterns //nolint:gochecknoglobals
var (
nxosPatternsInstance *nxosPatterns //nolint:gochecknoglobals
nxosPatternsInstanceOnce sync.Once //nolint:gochecknoglobals
)

func getNXOSPatterns() *nxosPatterns {
if nxosPatternsInstance == nil {
nxosPatternsInstanceOnce.Do(func() {
nxosPatternsInstance = &nxosPatterns{
bytesFreePattern: regexp.MustCompile(
`(?i)(?P<bytes_available>\d+)(?: bytes free)`,
Expand All @@ -48,7 +52,7 @@ func getNXOSPatterns() *nxosPatterns {
nxosPatternsInstance.configChangePattern.String(),
),
)
}
})

return nxosPatternsInstance
}
Expand Down
10 changes: 7 additions & 3 deletions cfg/juniperjunos.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"regexp"
"strings"
"sync"

"github.com/scrapli/scrapligo/logging"

Expand All @@ -16,15 +17,18 @@ type junosPatterns struct {
editPattern *regexp.Regexp
}

var junosPatternsInstance *junosPatterns //nolint:gochecknoglobals
var (
junosPatternsInstance *junosPatterns //nolint:gochecknoglobals
junosPatternsInstanceOnce sync.Once //nolint:gochecknoglobals
)

func getJUNOSPatterns() *junosPatterns {
if junosPatternsInstance == nil {
junosPatternsInstanceOnce.Do(func() {
junosPatternsInstance = &junosPatterns{
outputHeaderPattern: regexp.MustCompile(`(?im)^## last commit.*$\nversion.*$`),
editPattern: regexp.MustCompile(`(?m)^\[edit\]$`),
}
}
})

return junosPatternsInstance
}
Expand Down
30 changes: 19 additions & 11 deletions channel/authenticate.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,41 @@ package channel
import (
"bytes"
"regexp"
"sync"
"time"

"github.com/scrapli/scrapligo/logging"
)

type authPatterns struct {
type AuthPatterns struct {
telnetLoginPattern *regexp.Regexp
passwordPattern *regexp.Regexp
passphrasePattern *regexp.Regexp
}

var authPatternsInstance *authPatterns //nolint:gochecknoglobals
var (
AuthPatternsInstance *AuthPatterns //nolint:gochecknoglobals
authPatternsInstanceOnce sync.Once //nolint:gochecknoglobals
)

func getAuthPatterns() *authPatterns {
if authPatternsInstance == nil {
authPatternsInstance = &authPatterns{
func GetAuthPatterns() *AuthPatterns {
authPatternsInstanceOnce.Do(func() {
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
return AuthPatternsInstance
}

func (c *Channel) authenticateSSH(authPassword, authPassphrase []byte) *channelResult {
func (c *Channel) authenticateSSH( //nolint:dupl
authPassword, authPassphrase []byte,
) *channelResult {
logging.LogDebug(c.FormatLogMessage("debug", "attempting in channel ssh authentication"))

patterns := getAuthPatterns()
patterns := GetAuthPatterns()
passwordPattern := patterns.passwordPattern
passphrasePattern := patterns.passphrasePattern

Expand Down Expand Up @@ -134,10 +140,12 @@ func (c *Channel) AuthenticateSSH(authPassword, authPassphrase string) ([]byte,
}
}

func (c *Channel) authenticateTelnet(authUsername, authPassword []byte) *channelResult {
func (c *Channel) authenticateTelnet( //nolint:dupl
authUsername, authPassword []byte,
) *channelResult {
logging.LogDebug(c.FormatLogMessage("debug", "attempting in channel telnet authentication"))

patterns := getAuthPatterns()
patterns := GetAuthPatterns()
usernamePattern := patterns.telnetLoginPattern
passwordPattern := patterns.passwordPattern

Expand Down
15 changes: 15 additions & 0 deletions channel/authenticate_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package channel_test

import (
"testing"

"github.com/scrapli/scrapligo/channel"
)

// TestGetAuthPatternsRace ensures that the global singleton-y auth patterns getter is goroutine
// safe.
func TestGetAuthPatternsRace(t *testing.T) {
for i := 1; i < 5; i++ {
go channel.GetAuthPatterns()
}
}
4 changes: 2 additions & 2 deletions transport/standard.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import (
"encoding/base64"
"fmt"
"io"
"io/ioutil"
"log"
"net"
"os"

"github.com/scrapli/scrapligo/logging"

Expand Down Expand Up @@ -133,7 +133,7 @@ func (t *Standard) openBase(baseArgs *BaseTransportArgs) error {
authMethods := make([]ssh.AuthMethod, 0)

if t.StandardTransportArgs.AuthPrivateKey != "" {
key, err := ioutil.ReadFile(t.StandardTransportArgs.AuthPrivateKey)
key, err := os.ReadFile(t.StandardTransportArgs.AuthPrivateKey)
if err != nil {
return err
}
Expand Down