Documentation
¶
Index ¶
- Constants
- Variables
- func WithClientTrace(ctx context.Context, trace *ClientTrace) context.Context
- type ClientConfig
- type ClientTrace
- type HelloMessage
- type Notification
- type NotificationMessage
- type NotifyMessage
- type RPCError
- type RPCMessage
- type RPCReply
- type RPCReplyMessage
- type RPCRequest
- type Request
- type RequestHandler
- type Session
- func NewRPCSession(ctx context.Context, sshcfg *ssh.ClientConfig, target string) (s Session, err error)
- func NewRPCSessionWithConfig(ctx context.Context, sshcfg *ssh.ClientConfig, target string, ...) (s Session, err error)
- func NewSession(ctx context.Context, t Transport, cfg *ClientConfig) (Session, error)
- type SessionHandler
- type TestNCServer
- func (ncs *TestNCServer) Close()
- func (ncs *TestNCServer) Errorf(format string, args ...interface{})
- func (ncs *TestNCServer) FailNow()
- func (ncs *TestNCServer) LastHandler() *SessionHandler
- func (ncs *TestNCServer) SessionHandler(id uint64) *SessionHandler
- func (ncs *TestNCServer) WithCapabilities(caps []string) *TestNCServer
- func (ncs *TestNCServer) WithRequestHandler(rh RequestHandler) *TestNCServer
- type Transport
Constants ¶
const ( // CapBase10 defines capability value identifying 1.0 support CapBase10 = "urn:ietf:params:netconf:base:1.0" // CapBase11 defines capability value identifying 1.1 support CapBase11 = "urn:ietf:params:netconf:base:1.1" )
const ( TestUserName = "testUser" TestPassword = "testPassword" )
Defines credentials used for test sessions.
Variables ¶
var CloseRequestHandler = func(h *SessionHandler, req *rpcRequestMessage) {
h.ch.Close()
}
CloseRequestHandler closes the transport channel on request receipt.
var DefaultCapabilities = []string{ CapBase10, CapBase11, }
DefaultCapabilities sets the default capabilities of the client library
var DefaultLoggingHooks = &ClientTrace{ Error: func(context, target string, err error) { log.Printf("Error context:%s target:%s err:%v\n", context, target, err) }, }
DefaultLoggingHooks provides a default logging hook to report errors.
var DiagnosticLoggingHooks = &ClientTrace{ ConnectStart: func(clientConfig *ssh.ClientConfig, target string) { log.Printf("ConnectStart target:%s config:%v\n", target, clientConfig) }, ConnectDone: func(clientConfig *ssh.ClientConfig, target string, err error, d time.Duration) { log.Printf("ConnectDone target:%s config:%v err:%v took:%dns\n", target, clientConfig, err, d) }, ConnectionClosed: func(target string, err error) { log.Printf("ConnectionClosed target:%s err:%v\n", target, err) }, HelloDone: func(msg *HelloMessage) { log.Printf("HelloDone hello:%v\n", msg) }, ReadStart: func(p []byte) { log.Printf("ReadStart capacity:%d\n", len(p)) }, ReadDone: func(p []byte, c int, err error, d time.Duration) { log.Printf("ReadDone len:%d err:%v took:%dns\n", c, err, d) }, WriteStart: func(p []byte) { log.Printf("WriteStart len:%d\n", len(p)) }, WriteDone: func(p []byte, c int, err error, d time.Duration) { log.Printf("WriteDone len:%d err:%v took:%dns\n", c, err, d) }, Error: func(context, target string, err error) { log.Printf("Error context:%s target:%s err:%v\n", context, target, err) }, NotificationReceived: func(n *Notification) { log.Printf("NotificationReceived %s\n", n.XMLName.Local) }, NotificationDropped: func(n *Notification) { log.Printf("NotificationDropped %s\n", n.XMLName.Local) }, ExecuteStart: func(req Request, async bool) { log.Printf("ExecuteStart async:%v req:%s\n", async, req) }, ExecuteDone: func(req Request, async bool, res *RPCReply, err error, d time.Duration) { log.Printf("ExecuteDone async:%v req:%s err:%v took:%dns\n", async, req, err, d) }, }
DiagnosticLoggingHooks provides a set of default diagnostic hooks
var EchoRequestHandler = func(h *SessionHandler, req *rpcRequestMessage) { data := replyData{Data: req.Request.Body} reply := &RPCReplyMessage{Data: data, MessageID: req.MessageID} err := h.encode(reply) assert.NoError(h.t, err, "Failed to encode response") }
EchoRequestHandler responds to a request with a reply containing a data element holding the body of the request.
var FailingRequestHandler = func(h *SessionHandler, req *rpcRequestMessage) { reply := &RPCReplyMessage{ MessageID: req.MessageID, Errors: []RPCError{ {Severity: "error", Message: "oops"}}, } err := h.encode(reply) assert.NoError(h.t, err, "Failed to encode response") }
FailingRequestHandler replies to a request with an error.
var IgnoreRequestHandler = func(h *SessionHandler, req *rpcRequestMessage) {}
IgnoreRequestHandler does in nothing on receipt of a request.
var NoOpLoggingHooks = &ClientTrace{ ConnectStart: func(clientConfig *ssh.ClientConfig, target string) {}, ConnectDone: func(clientConfig *ssh.ClientConfig, target string, err error, d time.Duration) {}, ConnectionClosed: func(target string, err error) {}, HelloDone: func(msg *HelloMessage) {}, ReadStart: func(p []byte) {}, ReadDone: func(p []byte, c int, err error, d time.Duration) {}, WriteStart: func(p []byte) {}, WriteDone: func(p []byte, c int, err error, d time.Duration) {}, Error: func(context, target string, err error) {}, NotificationReceived: func(n *Notification) {}, NotificationDropped: func(n *Notification) {}, ExecuteStart: func(req Request, async bool) {}, ExecuteDone: func(req Request, async bool, res *RPCReply, err error, d time.Duration) {}, }
NoOpLoggingHooks provides set of hooks that do nothing.
Functions ¶
func WithClientTrace ¶
func WithClientTrace(ctx context.Context, trace *ClientTrace) context.Context
WithClientTrace returns a new context based on the provided parent ctx. Netconf client requests made with the returned context will use the provided trace hooks
Types ¶
type ClientConfig ¶
type ClientConfig struct {
// contains filtered or unexported fields
}
ClientConfig defines properties that configure netconf session behaviour.
type ClientTrace ¶
type ClientTrace struct {
// ConnectStart is called when starting to connect to a remote server.
ConnectStart func(clientConfig *ssh.ClientConfig, target string)
// ConnectDone is called when the transport connection attempt completes, with err indicating
// whether it was successful.
ConnectDone func(clientConfig *ssh.ClientConfig, target string, err error, d time.Duration)
// HelloDone is called when the hello message has been received from the server.
HelloDone func(msg *HelloMessage)
// ConnectionClosed is called after a transport connection has been closed, with
// err indicating any error condition.
ConnectionClosed func(target string, err error)
// ReadStart is called before a read from the underlying transport.
ReadStart func(buf []byte)
// ReadDone is called after a read from the underlying transport.
ReadDone func(buf []byte, c int, err error, d time.Duration)
// WriteStart is called before a write to the underlying transport.
WriteStart func(buf []byte)
// WriteDone is called after a write to the underlying transport.
WriteDone func(buf []byte, c int, err error, d time.Duration)
// Error is called after an error condition has been detected.
Error func(context, target string, err error)
// NotificationReceived is called when a notification has been received.
NotificationReceived func(m *Notification)
// NotificationDropped is called when a notification is dropped because the reader is not ready.
NotificationDropped func(m *Notification)
// ExecuteStart is called before the execution of an rpc request.
ExecuteStart func(req Request, async bool)
// ExecuteDone is called after the execution of an rpc request.
ExecuteDone func(req Request, async bool, res *RPCReply, err error, d time.Duration)
}
ClientTrace defines a structure for handling trace events
func ContextClientTrace ¶
func ContextClientTrace(ctx context.Context) *ClientTrace
ContextClientTrace returns the ClientTrace associated with the provided context. If none, it returns nil.
type HelloMessage ¶
type HelloMessage struct {
XMLName xml.Name `xml:"urn:ietf:params:xml:ns:netconf:base:1.0 hello"`
Capabilities []string `xml:"capabilities>capability"`
SessionID uint64 `xml:"session-id,omitempty"`
}
HelloMessage defines the message sent/received during session negotiation.
type Notification ¶
Notification defines a specific notification event.
type NotificationMessage ¶
type NotificationMessage struct {
XMLName xml.Name //`xml:"notification"`
EventTime string `xml:"eventTime"`
Event Notification `xml:",any"`
}
NotificationMessage defines the notification message sent from the server.
type NotifyMessage ¶ added in v0.1.1
type NotifyMessage struct {
XMLName xml.Name `xml:"urn:ietf:params:xml:ns:netconf:notification:1.0 notification"`
EventTime string `xml:"eventTime"`
Data string `xml:",innerxml"`
}
NotifyMessage defines the contents of a notification message that will be sent to a client session, where the element type of the notification event is unknown.
type RPCError ¶
type RPCError struct {
Type string `xml:"error-type"`
Tag string `xml:"error-tag"`
Severity string `xml:"error-severity"`
Path string `xml:"error-path"`
Message string `xml:"error-message"`
Info string `xml:",innerxml"`
}
RPCError defines an error reply to a RPC request
type RPCMessage ¶
type RPCMessage struct {
XMLName xml.Name `xml:"urn:ietf:params:xml:ns:netconf:base:1.0 rpc"`
MessageID string `xml:"message-id,attr"`
Methods []byte `xml:",innerxml"`
}
RPCMessage defines the an rpc request message
type RPCReply ¶
type RPCReply struct {
XMLName xml.Name `xml:"rpc-reply"`
Errors []RPCError `xml:"rpc-error,omitempty"`
Data string `xml:",innerxml"`
Ok bool `xml:",omitempty"`
RawReply string `xml:"-"`
MessageID string `xml:"message-id,attr"`
}
RPCReply defines the an rpc request message
type RPCReplyMessage ¶ added in v0.1.1
type RPCReplyMessage struct {
XMLName xml.Name `xml:"urn:ietf:params:xml:ns:netconf:base:1.0 rpc-reply"`
Errors []RPCError `xml:"rpc-error,omitempty"`
Data replyData `xml:"data"`
Ok bool `xml:",omitempty"`
RawReply string `xml:"-"`
MessageID string `xml:"message-id,attr"`
}
RPCReplyMessage and replyData represent an rpc-reply message that will be sent to a client session, where the element type of the reply body (i.e. the content of the data element) is unknown.
type RPCRequest ¶ added in v0.1.2
RPCRequest describes an RPC request.
type RequestHandler ¶ added in v0.1.1
type RequestHandler func(h *SessionHandler, req *rpcRequestMessage)
RequestHandler is a function type that will be invoked by the session handler to handle an RPC request.
type Session ¶
type Session interface {
// Execute executes an RPC request on the server and returns the reply.
Execute(req Request) (*RPCReply, error)
// ExecuteAsync submits an RPC request for execution on the server, arranging for the
// reply to be sent to the supplied channel.
ExecuteAsync(req Request, rchan chan *RPCReply) (err error)
// Subscribe issues an RPC request and returns the reply. If successful, notifications will
// be sent to the supplied channel.
Subscribe(req Request, nchan chan *Notification) (reply *RPCReply, err error)
// Close closes the session and releases any associated resources.
// The channel will be automatically closed if the underlying network connection is closed, for
// example if the remote server discoonects.
// When the session is closed, any outstanding execute requests and reads from a notification
// channel will return nil.
Close()
// ID delivers the server-allocated id of the session.
ID() uint64
// Capabilities delivers the server-supplied capabilities.
ServerCapabilities() []string
}
Session represents a Netconf Session
func NewRPCSession ¶
func NewRPCSession(ctx context.Context, sshcfg *ssh.ClientConfig, target string) (s Session, err error)
NewRPCSession connects to the target using the ssh configuration, and establishes a netconf session with default configuration.
func NewRPCSessionWithConfig ¶
func NewRPCSessionWithConfig(ctx context.Context, sshcfg *ssh.ClientConfig, target string, cfg *ClientConfig) (s Session, err error)
NewRPCSessionWithConfig connects to the target using the ssh configuration, and establishes a netconf session with the client configuration.
func NewSession ¶
NewSession creates a new Netconf session, using the supplied Transport.
type SessionHandler ¶ added in v0.1.2
type SessionHandler struct {
// The HelloMessage sent by the connecting client.
ClientHello *HelloMessage
Reqs []RPCRequest
// contains filtered or unexported fields
}
SessionHandler represents the server side of an active netconf SSH session.
func (*SessionHandler) Close ¶ added in v0.1.2
func (h *SessionHandler) Close()
Close initiates session tear-down by closing the underlying transport channel.
func (*SessionHandler) Handle ¶ added in v0.1.2
func (h *SessionHandler) Handle(t assert.TestingT, ch ssh.Channel)
Handle establishes a Netconf server session on a newly-connected SSH channel.
func (*SessionHandler) LastReq ¶ added in v0.1.2
func (h *SessionHandler) LastReq() *RPCRequest
LastReq delivers the last request received by the handler, or nil if no requests have been received.
func (*SessionHandler) ReqCount ¶ added in v0.1.2
func (h *SessionHandler) ReqCount() int
ReqCount delivers the number of requests received by the handler.
func (*SessionHandler) SendNotification ¶ added in v0.1.2
func (h *SessionHandler) SendNotification(body string) *SessionHandler
SendNotification sends a notification message with the supplied body to the client.
func (*SessionHandler) WaitStart ¶ added in v0.1.2
func (h *SessionHandler) WaitStart()
WaitStart waits until the session handler is ready.
type TestNCServer ¶ added in v0.1.1
TestNCServer represents a Netconf Server that can be used for 'on-board' testing. It encapsulates a transport connection to an SSH server, and a netconf session handler that will be invoked to handle netconf messages.
func NewTestNetconfServer ¶ added in v0.1.1
func NewTestNetconfServer(tctx assert.TestingT) *TestNCServer
NewTestNetconfServer creates a new TestNCServer that will accept Netconf localhost connections on an ephemeral port (available via Port(), with credentials defined by TestUserName and TestPassword. tctx will be used for handling failures; if the supplied value is nil, a default test context will be used. The behaviour of the Netconf session handler can be conifgured using the WithCapabilities and WithRequestHandler methods.
func (*TestNCServer) Close ¶ added in v0.1.1
func (ncs *TestNCServer) Close()
Close closes any active transport to the test server and prevents subsequent connections.
func (*TestNCServer) Errorf ¶ added in v0.1.1
func (ncs *TestNCServer) Errorf(format string, args ...interface{})
Errorf provides testing.T compatibility if a test context is not provided when the test server is created.
func (*TestNCServer) FailNow ¶ added in v0.1.1
func (ncs *TestNCServer) FailNow()
FailNow provides testing.T compatibility if a test context is not provided when the test server is created.
func (*TestNCServer) LastHandler ¶ added in v0.1.2
func (ncs *TestNCServer) LastHandler() *SessionHandler
LastHandler delivers the most recently instantiated session handler.
func (*TestNCServer) SessionHandler ¶ added in v0.1.2
func (ncs *TestNCServer) SessionHandler(id uint64) *SessionHandler
SessionHandler delivers the netconf session handler associated with the specified session id.
func (*TestNCServer) WithCapabilities ¶ added in v0.1.1
func (ncs *TestNCServer) WithCapabilities(caps []string) *TestNCServer
WithCapabilities define the capabilities that the server will advertise when a netconf client connects.
func (*TestNCServer) WithRequestHandler ¶ added in v0.1.1
func (ncs *TestNCServer) WithRequestHandler(rh RequestHandler) *TestNCServer
WithRequestHandler adds a request handler to the netconf session.
type Transport ¶
type Transport interface {
io.ReadWriteCloser
}
Transport interface defines what characteristics make up a NETCONF transport layer object.
func NewSSHTransport ¶
func NewSSHTransport(ctx context.Context, clientConfig *ssh.ClientConfig, target, subsystem string) (rt Transport, err error)
NewSSHTransport creates a new SSH transport, connecting to the target with the supplied client configuration and requesting the specified subsystem. nolint : gosec