1
0
Fork 0
cisco-ios-apply/conf.go

94 lines
1.9 KiB
Go

package main
import (
"bufio"
"bytes"
"errors"
"fmt"
"io"
"time"
)
type Device interface {
ReadTimeout(time.Duration) ([]byte, error)
WriteLine([]byte) error
Close() error
}
var ErrorDeviceOperationNotSupported = errors.New("device operation not supported")
type ConfigurationLine interface {
Apply(Device) error
}
type ConfigurationDirective struct {
Name string
Argument string
}
type ConfigurationSimple []byte
func (d ConfigurationDirective) Apply(dev Device) error {
if d.Name == "sleep" {
seconds := 0
_, err := fmt.Sscanf(string(d.Argument), "%d", &seconds)
if err != nil {
return fmt.Errorf("bad sleep arguments: %w", err)
}
time.Sleep(time.Duration(seconds) * time.Second)
}
return nil
}
func (s ConfigurationSimple) Apply(dev Device) error {
err := dev.WriteLine([]byte(s))
if err != nil {
return err
}
response, err := dev.ReadTimeout(200 * time.Millisecond)
if errors.Is(err, ErrorDeviceOperationNotSupported) {
} else if err != nil {
return err
}
fmt.Printf("%s", response)
return nil
}
type ConfigurationReader bufio.Reader
func NewConfigurationReader(r io.Reader) *ConfigurationReader {
return (*ConfigurationReader)(bufio.NewReader(r))
}
func (c *ConfigurationReader) Read() (ConfigurationLine, error) {
line, err := (*bufio.Reader)(c).ReadBytes('\n')
if err != nil {
return nil, err
}
line = bytes.TrimSuffix(line, []byte{'\n'})
if len(line) > 1 && line[0] == '!' && line[1] == ' ' {
// Comment
return ConfigurationSimple(string(line)), nil
} else if len(line) > 0 && line[0] == '!' {
// Directive
line = line[1:]
firstSep := bytes.IndexByte(line, ' ')
if firstSep < 0 {
return ConfigurationDirective{
Name: string(line),
}, nil
}
directive := line[:firstSep]
rest := line[firstSep+1:]
return ConfigurationDirective{
Name: string(directive),
Argument: string(rest),
}, nil
} else {
return ConfigurationSimple(line), nil
}
}