Documentation ¶
Index ¶
- Constants
- Variables
- func Marshal(v interface{}) ([]byte, error)
- func NewSession(clientConfig *ssh.ClientConfig, target string) (*Session, *HelloMessage, error)
- func Unmarshal(data []byte, v interface{}) error
- func XMLAttr(messageID string) []xml.Attr
- func XMLNameTag(namespace string) xml.Name
- type DeadlineError
- type DeadlineReader
- type Decoder
- type Encoder
- type ErrorInfo
- type ErrorSeverity
- type ErrorTag
- type ErrorType
- type HelloMessage
- type Method
- type Reply
- type ReplyError
- type ReplyReader
- type Session
- func (s *Session) Close() error
- func (s *Session) NewDeadlineReader(deadline time.Duration) io.Reader
- func (s *Session) NewDecoder() *Decoder
- func (s *Session) NewEncoder() *Encoder
- func (s *Session) NewReplyReader() *ReplyReader
- func (s *Session) NewTimeoutDecoder(timeout time.Duration) *Decoder
- func (s *Session) Read(p []byte) (n int, err error)
- func (s *Session) Write(p []byte) (n int, err error)
- type Uint
- type UnmarshalTextError
Constants ¶
const ( // MessageSeparator is explicitly invalid XML used to unambiguously separate NETCONF messages. MessageSeparator = `]]>]]>` // BaseNamespace is the most basic NETCONF namespace, and is the default namespace for all NETCONF methods. BaseNamespace = `urn:ietf:params:xml:ns:netconf:base:1.0` )
const DefaultHelloMessage = `` /* 200-byte string literal not displayed */
DefaultHelloMessage is this library's default hello sent to the server, when it is not sent manually by the client application.
Variables ¶
var GlobalCounter = NewUintCounterContext(context.Background())
GlobalCounter keeps a running count of every NETCONF RPC. It is incremented by the DefaultXMLAttr and DefaultRPCMethodWrapper functions.
GlobalCounter is safe for client applications to access, use, and increment.
Functions ¶
func Marshal ¶
Marshal returns the NETCONF encoding of v, including message separators and enclosing RPC tags.
If the argument's type is *Method, MarshalRPC just calls xml.Marshal internally to build the XML. Otherwise, it wraps its argument in the default *Method before calling xml.Marshal.
A NETCONF message separator and newline is always written to the end of the message.
func NewSession ¶
func NewSession(clientConfig *ssh.ClientConfig, target string) (*Session, *HelloMessage, error)
NewSession creates a new session ready for use with the NETCONF SSH subsystem. It uses the credentials given by the ssh.ClientConfig argument to connect to the target. Hello messages are negotiated, and the server's hello message is returned along with a newly allocated Session pointer.
func Unmarshal ¶
Unmarshal maps the NETCONF RPC reply XML into the given argument, discarding the terminating message separator.
func XMLAttr ¶
XMLAttr returns a slice of xml.Attr containing only one xml.Attr for the RPC's message-id.
func XMLNameTag ¶
XMLNameTag returns an xml.Name for an RPC's outer tag. It is appropriately named "rpc", with an attribute that has the given namespace.
Types ¶
type DeadlineError ¶
type DeadlineError struct { Op string BeginTime time.Time FailTime time.Time Deadline time.Duration }
DeadlineError is returned when a read or write deadline is reached.
func (*DeadlineError) Error ¶
func (te *DeadlineError) Error() string
Error implements the error interface.
type DeadlineReader ¶
type DeadlineReader struct {
// contains filtered or unexported fields
}
DeadlineReader is a decorator for an io.Reader that sets a deadline before every read. It can only be constructed by a ReplyReader's WithDeadline method.
func (*DeadlineReader) AsDecoder ¶
func (dr *DeadlineReader) AsDecoder() *Decoder
func (*DeadlineReader) Read ¶
func (dr *DeadlineReader) Read(b []byte) (n int, err error)
Read sets a deadline before every call to Read, and returns a DeadlineError if reading is not complete before the configured deadline expires. It is recommended that you close the session upon receipt of a DeadlineError, otherwise a subsequent read will return whatever the NETCONF server wrote to its stdout stream after the deadline expired.
type Decoder ¶
Decoder embeds an xml.Decoder, but overrides Decode with a custom implementation designed specifically to decode NETCONF RPC replies.
func NewDecoder ¶
NewDecoder buffers the given io.Reader, and wraps it in a Decoder.
func (*Decoder) Decode ¶
Decode wraps the interface{} parameter in a Reply object to capture all of the RPC Reply content. It also searches for errors in the Reply, and returns the first ReplyError found. as a standard error interface.
unmarshals a single NETCONF RPC reply message into the given interface{}.
A full RPC Reply can be obtained Parsing XML as a stream of tokens is still possible using the embedded xml.Decoder. However, Done should be called finished to discard the NETCONF message separator.
func (*Decoder) DecodeHello ¶
func (d *Decoder) DecodeHello(h *HelloMessage) error
DecodeHello handles hello/capabilities messages sent by the NETCONF server. It's a special decode case since the closing tags are named "hello" rather than "rpc-reply".
func (*Decoder) SkipSep ¶
SkipSep discarding everything from the underlying buffer until it encounters a NETCONF message separator, or an error.
Since the separator is explicitly designed to be invalid XML, failure to discard it before decoding will cause the standard decoder to fail with a syntax error.
Using this method is only necessary when manually decoding XML tokens as a stream, with DecodeToken, et al.
Calls to SkipSep may block if more bytes have to be read from the underlying net.Conn.
Most uses will call Decode, which calls SkipSep internally.
type Encoder ¶
Encoder embeds an xml.Encoder, but overrides Encode with a custom implementation designed specifically to encode NETCONF RPC requests.
func NewEncoder ¶
NewEncoder buffers the given io.Writer, and wraps it into a Encoder.
func (*Encoder) Encode ¶
Encode encodes a single NETCONF RPC, and marshals it into the underlying buffer. Then it writes the NETCONF message separator followed by a newline, and flushes the buffer.
Encoding XML as a stream of tokens is still possible using the underlying xml.Encoder. However, WriteSep must should be called after encoding an RPC.
func (*Encoder) EncodeHello ¶
func (e *Encoder) EncodeHello(h *HelloMessage) error
EncodeHello writes the given hello message to the underlying writer, writes a message separator, and flushes the buffer.
func (*Encoder) WriteSep ¶
WriteSep writes a message separator with a trailing newline to the underlying buffered io.Writer, and flushes the buffer before returning. Using this method is only necessary when manually encoding XML tokens as a stream with EncodeToken, et al.
Calls to WriteSep may block depending on the underlying net.Conn.
Most uses will call Encode, which calls WriteSep internally.
type ErrorInfo ¶
type ErrorInfo struct { BadAttribute string `xml:"bad-attribute"` // BadAttribute has the name(s) of the bad, missing, or unexpected attribute(s). BadElement string `xml:"bad-element"` // BadElement is the name of the element that should (or does) contain the missing (or bad) attribute. BadNamespace string `xml:"bad-namespace"` // BadNamespace contains the name of the unexpected namespace. OkElement []string `xml:"ok-element"` // OkElement is the parent element for which all children have completed the requested operation. ErrElement []string `xml:"err-element"` // ErrElement is the parent element for which all children have failed to complete the requested operation. NOPElement []string `xml:"noop-element"` // NOPElement is the parent element that identifies all children for which the requested operation was not attempted. }
ErrorInfo contains protocol or data model specific error content.
type ErrorSeverity ¶
type ErrorSeverity uint
ErrorSeverity identifies severity of the error as either warning, or error.
const ( ErrorSeverityZero ErrorSeverity = iota // ErrorSeverityZero represents an uninitialized ErrorSeverity value. ErrorSeverityError // ErrorSeverityError indicates the severity is on the error level. ErrorSeverityUnknown // ErrorSeverityUnknown means the ErrorSeverity could not be identified, and may indicate an internal error. ErrorSeverityWarning // ErrorSeverityWarning is not yet utilized, according to RFC 6241. )
func (ErrorSeverity) String ¶
func (es ErrorSeverity) String() string
String returns a string representing the ErrorSeverity. If the ErrorSeverity is not known for some erroneous reason, the String will return "unknown".
func (*ErrorSeverity) UnmarshalText ¶
func (es *ErrorSeverity) UnmarshalText(text []byte) error
UnmarshalText sets the receiver to the constant represented by the text argument given. If the text argument does not represent a known ErrorSeverity, it is set to the ErrorSeverityUnknown constant, and an UnmarshalTextError is returned.
type ErrorTag ¶
type ErrorTag uint64
ErrorTag identifies the error condition.
const ( ErrorTagZero ErrorTag = iota // ErrorTagZero is an uninitialized ErrorTag value. ErrorTagAccessDenied // ErrorTagAccessDenied indicates access was denied because authorization failed. ErrorTagBadAttribute // ErrorTagBadAttribute indicates an attribute value is not correct; e.g., wrong type, out of range, pattern mismatch. ErrorTagBadElement // ErrorTagBadElement indicates a bad element value was in the RPC. ErrorInfo's BadElement field will contain element's name. ErrorTagDataExists // ErrorTagDataExists indicates data could not be created because it already exists. ErrorTagDataMissing // ErrorTagDataMissing indicates data could not be deleted because it doesn't exist. ErrorTagInUse // ErrorTagInUse indicates the required resource is already in use. ErrorTagInvalidValue // ErrorTagInvalidValue indicates the RPC specifies an unacceptable value for one or more parameters. ErrorTagLockDenied // ErrorTagLockDenied indicates the requested lock is denied because it is held by another entity. ErrorTagMalformedMessage // ErrorTagMalformedMessage indicates a failure to parse the RPC correctly. ErrorTagMissingAttribute // ErrorTagMissingAttribute indicates an expected attribute is missing. ErrorTagMissingElement // ErrorTagMissingElement indicates an expected element is missing. ErrorInfo's BadElement field will contain the name of the missing element. ErrorTagOpFailed // ErrorTagOpFailed indicates failure for some reason not covered by other error conditions. ErrorTagOpNotSupported // ErrorTagOpNotSupported indicates RPC is not supported by the implementation. ErrorTagOpPartial // ErrorTagOpPartial indicates the RPC failed partially or was aborted, and cleanup was not performed. ErrorInfo's OkElement, ErrElement, and NOPElement identify elements that succeeded, failed, and were aborted respectively. ErrorTagResourceDenied // ErrorTagResourceDenied indicates insufficient resources. ErrorTagRollbackFailed // ErrorTagRollbackFailed indicates the rollback was not completed. ErrorTagTooBig // ErrorTagTooBig indicates the request or response is too large to handle. ErrorTagUnknown // ErrorTagUnknown probably indicates an internal error, because the error type could not be identified. ErrorTagUnknownAttribute // ErrorTagUnknownAttribute indicates an unexpected attribute is present. ErrorInfo's BadAttribute and BadElement field will contain more detail. ErrorTagUnknownElement // ErrorTagUnknownElement indicates an unexpected element. ErrorInfo's BadElement field will contain its name. ErrorTagUnknownNamespace // ErrorTagUnknownNamespace indicates an unexpected namespace is present. ErrorInfo's BadElement and BadNamespace fields will contain more detail. )
func (ErrorTag) Severity ¶
func (et ErrorTag) Severity() ErrorSeverity
Severity returns the severity of this ErrorTag.
func (*ErrorTag) UnmarshalText ¶
UnmarshalText sets the ErrorTag receiver to the constant represented by the text argument given. If the text argument does not represent a known ErrorTag, the ErrorTag is set to the ErrorTagUnknown constant, and an UnmarshalTextError is returned.
type ErrorType ¶
type ErrorType uint64
ErrorType defines the conceptual layer that the error occurred in.
const ( // ErrorTypeZero represents an uninitialized ErrorType value. ErrorTypeZero ErrorType = iota // ErrorTypeApplication indicates the error occurred on the Content layer. ErrorTypeApplication // ErrorTypeProtocol indicates the error occurred on the Operations layer, which defines a set of base protocol operations invoked as RPC methods. ErrorTypeProtocol // ErrorTypeRPC indicates the error occurred on the Messages layer: the transport-independent framing mechanism for encoding RPCs and notifications. ErrorTypeRPC // ErrorTypeTransport indicates the error occurred on the Secure Transport layer, which provides a communication path between the client and server. ErrorTypeTransport // ErrorTypeUnknown indicates an unexpected condition. ErrorTypeUnknown )
func (ErrorType) String ¶
String returns a string representation of the ErrorType. If the ErrorType is unknown, the ErrorTypeUnknown constant is returned.
func (*ErrorType) UnmarshalText ¶
UnmarshalText sets the ErrorType receiver to the constant represented by the text argument given. If the text argument does not represent a known ErrorType, it is set to the ErrorTypeUnknown constant, and an UnmarshalTextError is returned.
type HelloMessage ¶
type HelloMessage struct { XMLName xml.Name Capabilities []string `xml:"capabilities>capability"` SessionID uint `xml:"session-id,omitempty"` }
HelloMessage represents a capabilities exchange message.
func (*HelloMessage) Copy ¶
func (h *HelloMessage) Copy() *HelloMessage
Copy makes a deep copy of this HelloMessage.
type Method ¶
Method models the structure of a NETCONF method. It is useful for wrapping structs that don't encode the outer rpc tags.
Multiple methods can be encoded into one RPC.
func WrapMethod ¶
func WrapMethod(method ...interface{}) *Method
WrapMethod wraps the given methods' with outer rpc tags, and sets default values for namespace and message id attributes. It returns a pointer to a Method that can be directly marshaled into an RPC by Encoder.
type Reply ¶
type Reply struct { XMLName xml.Name `xml:"rpc-reply"` Attr []xml.Attr `xml:",attr"` Ok *struct{} `xml:"ok"` Error []ReplyError `xml:"rpc-error"` Data interface{} `xml:",any"` }
Reply models the structure of a NETCONF reply. It is useful for wrapping structs that don't decode the outer rpc-reply tags.
type ReplyError ¶
type ReplyError struct { Type ErrorType `xml:"error-type"` // Type is the conceptual layer that the error occurred. Tag ErrorTag `xml:"error-tag"` // Tag identifies the error condition. Severity ErrorSeverity `xml:"error-severity"` // Severity is the error severity: either error or warning. Info ErrorInfo `xml:"error-info"` // Info contains protocol or data-model-specific error content. Path string `xml:"error-path"` // Path is the absolute XPath expression identifying the element path to the node. Message string `xml:"error-message"` // Message is a human friendly description of the error. }
ReplyError encapsulates a NETCONF RPC error, and implements the error interface.
func (*ReplyError) Error ¶
func (e *ReplyError) Error() string
Error is the implementation of the error interface.
type ReplyReader ¶
type ReplyReader struct {
// contains filtered or unexported fields
}
ReplyReader reads exactly one RPC reply from the session, and discards the message separator. If multiple RPCs need to be read from the session, multiple ReplyReaders will be required. The io.EOF error is returned on every read after the NETCONF message separator is encountered. This is how ReplyReader is able to satisfy the strict interpretation of the io.Reader interface.
func NewReplyReader ¶
func NewReplyReader(session io.Reader) *ReplyReader
NewReplyReader assumes the given reader reads from a NETCONF session's stdout, and adapts its behavior to a standard io.Reader, allowing it to work with standard library methods and functions. It is intended to read exactly one RPC reply, however it can be reused after calling the Reset method.
func (*ReplyReader) Read ¶
func (rr *ReplyReader) Read(p []byte) (n int, err error)
Read implements the io.Reader interface by returning io.EOF whenever the standard NETCONF message separator is found in the byte stream.
func (*ReplyReader) Reset ¶
func (rr *ReplyReader) Reset()
Reset clears the internal error field, allowing this reader to be reused.
func (*ReplyReader) WithDeadline ¶
func (rr *ReplyReader) WithDeadline(deadline time.Duration) *DeadlineReader
WithDeadline decorates the ReplyReader with a DeadlineReader. The DeadlineReader sets its deadline before every call to Read.
type Session ¶
type Session struct {
// contains filtered or unexported fields
}
Session wraps an *ssh.Session providing additional NETCONF functionality. An initialized Session is a io.ReadWriteCloser, with the io.Reader connected to the ssh.Session's stdout, and the io.WriteCloser connected to the ssh.Sessions's stdin.
func (*Session) Close ¶
Close closes all session resources in the following order:
- stdin pipe
- SSH session
- SSH client
Errors are returned with priority matching the same order.
func (*Session) NewDeadlineReader ¶
NewDeadlineReader decorates the session's io.Reader with a new DeadlineReader.
The DeadlineReader only adds a deadline when reading from the stream. It does not handle higher level functionality, like a complete implementation of an io.Reader, or discarding NETCONF message separators.
func (*Session) NewDecoder ¶
NewDecoder returns a new Decoder object attached to the stdout pipe of the underlying SSH session.
func (*Session) NewEncoder ¶
NewEncoder returns a new Encoder object attached to the stdin pipe of the underlying SSH session.
func (*Session) NewReplyReader ¶
func (s *Session) NewReplyReader() *ReplyReader
NewReplyReader returns a ReplyReader that reads exactly one NETCONF RPC Reply from the session's stdout stream. The ReplyReader strictly satisfies io.Reader interface by reading from the stream until the NETCONF message separator "]]>]]>" is reached, and an io.EOF error is returned. The io.EOF error is also returned on all subsequent calls.
The ReplyReader does not close the underlying session. Multiple ReplyReaders are required to read multiple replies from the same session.
func (*Session) NewTimeoutDecoder ¶
NewTimeoutDecoder returns a new Decoder attached to the stdout pipe of the underlying SSH session. The Decoder's io.TrimReader is wrapped to set a read timeout on the underlying net.Conn before every read.
type Uint ¶
type Uint struct {
// contains filtered or unexported fields
}
Uint is a 64-bit unsigned integer variable that satisfies the expvar.Var interface.
func NewUintCounterContext ¶
NewUintCounterContext allocates the new unsigned integer counter with resources that can only be cancelled by a context.
type UnmarshalTextError ¶
type UnmarshalTextError struct { Type string // Type is the unknown value's type. Value string // Value is the what caused the failure. }
UnmarshalTextError is returned when UnmarshalText fails to parse the text it's given.
func (*UnmarshalTextError) Error ¶
func (ute *UnmarshalTextError) Error() string
Error is UnmarshalTextError's implementation of the error interface.