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