Documentation
¶
Overview ¶
Example (Ssh) ¶
package main import ( "context" "log" "time" "github.com/nemith/netconf" ncssh "github.com/nemith/netconf/transport/ssh" "golang.org/x/crypto/ssh" ) const sshAddr = "myrouter.example.com:830" func main() { config := &ssh.ClientConfig{ User: "admin", Auth: []ssh.AuthMethod{ ssh.Password("secret"), }, } ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() transport, err := ncssh.Dial(ctx, "tcp", sshAddr, config) if err != nil { panic(err) } defer transport.Close() session, err := netconf.Open(transport) if err != nil { panic(err) } // timeout for the call itself. ctx, cancel = context.WithTimeout(ctx, 5*time.Second) defer cancel() deviceConfig, err := session.GetConfig(ctx, "running") if err != nil { log.Fatalf("failed to get config: %v", err) } log.Printf("Config:\n%s\n", deviceConfig) if err := session.Close(context.Background()); err != nil { log.Print(err) } }
Output:
Example (Tls) ¶
package main import ( "context" "crypto/tls" "crypto/x509" _ "embed" "fmt" "log" "os" "time" "github.com/nemith/netconf" nctls "github.com/nemith/netconf/transport/tls" ) const tlsAddr = "myrouter.example.com:6513" func main() { caCert, err := os.ReadFile("ca.crt") if err != nil { log.Fatalf("failed to load ca cert: %v", err) } caCertPool := x509.NewCertPool() caCertPool.AppendCertsFromPEM(caCert) clientCert, err := os.ReadFile("client.crt") if err != nil { log.Fatalf("failed to load client cert: %v", err) } clientKey, err := os.ReadFile("client.key") if err != nil { log.Fatalf("failed to load client key: %v", err) } cert, err := tls.X509KeyPair(clientCert, clientKey) if err != nil { panic(err) } // tls transport configuration config := tls.Config{ InsecureSkipVerify: true, RootCAs: caCertPool, Certificates: []tls.Certificate{cert}, } // Add a connection establish timeout of 5 seconds. You can also accomplish // the same behavior with Timeout field of the ssh.ClientConfig. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() transport, err := nctls.Dial(ctx, "tcp", tlsAddr, &config) if err != nil { panic(err) } defer transport.Close() session, err := netconf.Open(transport) if err != nil { panic(err) } defer session.Close(context.Background()) // timeout for the call itself. ctx, cancel = context.WithTimeout(ctx, 5*time.Second) defer cancel() cfg, err := session.GetConfig(ctx, "running") if err != nil { panic(err) } fmt.Printf("Config: %s\n", cfg) if err := session.Close(context.Background()); err != nil { log.Print(err) } }
Output:
Index ¶
- Variables
- func ExpandCapability(s string) string
- func WithPersistID(id string) persistID
- type CancelCommitOption
- type CancelCommitReq
- type CommitOption
- type CommitReq
- type CopyConfigReq
- type CreateSubscriptionOption
- type CreateSubscriptionReq
- type Datastore
- type DeleteConfigReq
- type EditConfigOption
- type EditConfigReq
- type ErrSeverity
- type ErrTag
- type ErrType
- type ErrorStrategy
- type ExtantBool
- type GetConfigReply
- type GetConfigReq
- type KillSessionReq
- type LockReq
- type MergeStrategy
- type Notification
- type NotificationHandler
- type OKResp
- type RPCError
- type RPCErrors
- type RawXML
- type Reply
- type Session
- func (s *Session) Call(ctx context.Context, req any, resp any) error
- func (s *Session) CancelCommit(ctx context.Context, opts ...CancelCommitOption) error
- func (s *Session) ClientCapabilities() []string
- func (s *Session) Close(ctx context.Context) error
- func (s *Session) Commit(ctx context.Context, opts ...CommitOption) error
- func (s *Session) CopyConfig(ctx context.Context, source, target any) error
- func (s *Session) CreateSubscription(ctx context.Context, opts ...CreateSubscriptionOption) error
- func (s *Session) DeleteConfig(ctx context.Context, target Datastore) error
- func (s *Session) Do(ctx context.Context, req any) (*Reply, error)
- func (s *Session) EditConfig(ctx context.Context, target Datastore, config any, opts ...EditConfigOption) error
- func (s *Session) GetConfig(ctx context.Context, source Datastore) ([]byte, error)
- func (s *Session) KillSession(ctx context.Context, sessionID uint32) error
- func (s *Session) Lock(ctx context.Context, target Datastore) error
- func (s *Session) ServerCapabilities() []string
- func (s *Session) SessionID() uint64
- func (s *Session) Unlock(ctx context.Context, target Datastore) error
- func (s *Session) Validate(ctx context.Context, source any) error
- type SessionOption
- type TestStrategy
- type URL
- type ValidateReq
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var DefaultCapabilities = []string{
"urn:ietf:params:netconf:base:1.0",
"urn:ietf:params:netconf:base:1.1",
}
DefaultCapabilities are the capabilities sent by the client during the hello exchange by the server.
var ErrClosed = errors.New("closed connection")
Functions ¶
func ExpandCapability ¶
ExpandCapability will automatically add the standard capability prefix of `urn:ietf:params:netconf:capability` if not already present.
func WithPersistID ¶
func WithPersistID(id string) persistID
WithPersistID is used to confirm a previous commit set with a given identifier. This allows you to confirm a commit from (potentially) another sesssion.
Types ¶
type CancelCommitOption ¶
type CancelCommitOption interface {
// contains filtered or unexported methods
}
CancelCommitOption is a optional arguments to Session.CancelCommit method
type CancelCommitReq ¶ added in v0.0.2
type CommitOption ¶
type CommitOption interface {
// contains filtered or unexported methods
}
CommitOption is a optional arguments to Session.Commit method
func WithConfirmed ¶
func WithConfirmed() CommitOption
WithConfirmed will mark the commits as requiring confirmation or will rollback after the default timeout on the device (default should be 600s). The commit can be confirmed with another `<commit>` call without the confirmed option, extended by calling with `Commit` With `WithConfirmed` or `WithConfirmedTimeout` or canceling the commit with a `CommitCancel` call. This requires the device to support the `:confirmed-commit:1.1` capability.
func WithConfirmedTimeout ¶
func WithConfirmedTimeout(timeout time.Duration) CommitOption
WithConfirmedTimeout is like `WithConfirmed` but using the given timeout duration instead of the device's default.
func WithPersist ¶
func WithPersist(id string) CommitOption
WithPersist allows you to set a identifier to confirm a commit in another sessions. Confirming the commit requires setting the `WithPersistID` in the following `Commit` call matching the id set on the confirmed commit. Will mark the commit as confirmed if not already set.
type CopyConfigReq ¶ added in v0.0.2
type CreateSubscriptionOption ¶
type CreateSubscriptionOption interface {
// contains filtered or unexported methods
}
CreateSubscriptionOption is a optional arguments to Session.CreateSubscription method
func WithEndTimeOption ¶
func WithEndTimeOption(et time.Time) CreateSubscriptionOption
func WithStartTimeOption ¶
func WithStartTimeOption(st time.Time) CreateSubscriptionOption
func WithStreamOption ¶
func WithStreamOption(s string) CreateSubscriptionOption
type CreateSubscriptionReq ¶ added in v0.0.2
type CreateSubscriptionReq struct { XMLName xml.Name `xml:"urn:ietf:params:xml:ns:netconf:notification:1.0 create-subscription"` Stream string `xml:"stream,omitempty"` // TODO: Implement filter //Filter int64 `xml:"filter,omitempty"` StartTime string `xml:"startTime,omitempty"` EndTime string `xml:"endTime,omitempty"` }
type Datastore ¶
type Datastore string
const ( // Running configuration datastore. Required by RFC6241 Running Datastore = "running" // Candidate configuration configuration datastore. Supported with the // `:candidate` capability defined in RFC6241 section 8.3 Candidate Datastore = "candidate" // Startup configuration configuration datastore. Supported with the // `:startup` capability defined in RFC6241 section 8.7 Startup Datastore = "startup" // )
func (Datastore) MarshalXML ¶
type DeleteConfigReq ¶ added in v0.0.2
type EditConfigOption ¶
type EditConfigOption interface {
// contains filtered or unexported methods
}
EditOption is a optional arguments to Session.EditConfig method
func WithDefaultMergeStrategy ¶
func WithDefaultMergeStrategy(op MergeStrategy) EditConfigOption
WithDefaultMergeStrategy sets the default config merging strategy for the <edit-config> operation. Only [Merge], [Replace], and [None] are supported (the rest of the strategies are for defining as attributed in individual elements inside the `<config>` subtree).
func WithErrorStrategy ¶
func WithErrorStrategy(opt ErrorStrategy) EditConfigOption
WithErrorStrategy sets the `error-option` in the `<edit-config>` operation. This defines the behavior when errors are encountered applying the supplied config. See ErrorStrategy for the available options.
func WithTestStrategy ¶
func WithTestStrategy(op TestStrategy) EditConfigOption
WithTestStrategy sets the `test-option` in the `<edit-config>“ operation. This defines what testing should be done the supplied configuration. See the documentation on TestStrategy for details on each strategy.
type EditConfigReq ¶ added in v0.0.2
type EditConfigReq struct { XMLName xml.Name `xml:"edit-config"` Target Datastore `xml:"target"` DefaultMergeStrategy MergeStrategy `xml:"default-operation,omitempty"` TestStrategy TestStrategy `xml:"test-option,omitempty"` ErrorStrategy ErrorStrategy `xml:"error-option,omitempty"` // either of these two values Config any `xml:"config,omitempty"` URL string `xml:"url,omitempty"` }
type ErrSeverity ¶
type ErrSeverity string
const ( SevError ErrSeverity = "error" SevWarning ErrSeverity = "warning" )
type ErrTag ¶
type ErrTag string
const ( ErrInUse ErrTag = "in-use" ErrInvalidValue ErrTag = "invalid-value" ErrTooBig ErrTag = "too-big" ErrMissingAttribute ErrTag = "missing-attribute" ErrBadAttribute ErrTag = "bad-attribute" ErrUnknownAttribute ErrTag = "unknown-attribute" ErrMissingElement ErrTag = "missing-element" ErrBadElement ErrTag = "bad-element" ErrUnknownElement ErrTag = "unknown-element" ErrUnknownNamespace ErrTag = "unknown-namespace" ErrAccesDenied ErrTag = "access-denied" ErrLockDenied ErrTag = "lock-denied" ErrResourceDenied ErrTag = "resource-denied" ErrRollbackFailed ErrTag = "rollback-failed" ErrDataExists ErrTag = "data-exists" ErrDataMissing ErrTag = "data-missing" ErrOperationNotSupported ErrTag = "operation-not-supported" ErrOperationFailed ErrTag = "operation-failed" ErrPartialOperation ErrTag = "partial-operation" ErrMalformedMessage ErrTag = "malformed-message" )
type ErrorStrategy ¶
type ErrorStrategy string
ErrorStrategy defines the behavior when an error is encountered during a `<edit-config>` operation.
*Note*: in RFC6241 7.2 this is called the `error-option` parameter. Since the `option` term is already overloaded this was changed to `ErrorStrategy` for a cleaner API.
const ( // StopOnError will about the `<edit-config>` operation on the first error. StopOnError ErrorStrategy = "stop-on-error" // ContinueOnError will continue to parse the configuration data even if an // error is encountered. Errors are still recorded and reported in the // reply. ContinueOnError ErrorStrategy = "continue-on-error" // RollbackOnError will restore the configuration back to before the // `<edit-config>` operation took place. This requires the device to // support the `:rollback-on-error` capabilitiy. RollbackOnError ErrorStrategy = "rollback-on-error" )
type ExtantBool ¶
type ExtantBool bool
func (ExtantBool) MarshalXML ¶
func (b ExtantBool) MarshalXML(e *xml.Encoder, start xml.StartElement) error
func (*ExtantBool) UnmarshalXML ¶
func (b *ExtantBool) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error
type GetConfigReply ¶ added in v0.0.2
type GetConfigReq ¶ added in v0.0.2
type KillSessionReq ¶ added in v0.0.2
type MergeStrategy ¶
type MergeStrategy string
MergeStrategy defines the strategies for merging configuration in a `<edit-config> operation`.
*Note*: in RFC6241 7.2 this is called the `operation` attribute and `default-operation` parameter. Since the `operation` term is already overloaded this was changed to `MergeStrategy` for a cleaner API.
const ( // MergeConfig configuration elements are merged together at the level at // which this specified. Can be used for config elements as well as default // defined with [WithDefaultMergeStrategy] option. MergeConfig MergeStrategy = "merge" // ReplaceConfig defines that the incoming config change should replace the // existing config at the level which it is specified. This can be // specified on individual config elements or set as the default strategy set // with [WithDefaultMergeStrategy] option. ReplaceConfig MergeStrategy = "replace" // NoMergeStrategy is only used as a default strategy defined in // [WithDefaultMergeStrategy]. Elements must specific one of the other // strategies with the `operation` Attribute on elements in the `<config>` // subtree. Elements without the `operation` attribute are ignored. NoMergeStrategy MergeStrategy = "none" // CreateConfig allows a subtree element to be created only if it doesn't // already exist. // This strategy is only used as the `operation` attribute of // a `<config>` element and cannot be used as the default strategy. CreateConfig MergeStrategy = "create" // DeleteConfig will completely delete subtree from the config only if it // already exists. This strategy is only used as the `operation` attribute // of a `<config>` element and cannot be used as the default strategy. DeleteConfig MergeStrategy = "delete" // RemoveConfig will remove subtree from the config. If the subtree doesn't // exist in the datastore then it is silently skipped. This strategy is // only used as the `operation` attribute of a `<config>` element and cannot // be used as the default strategy. RemoveConfig MergeStrategy = "remove" )
type Notification ¶ added in v0.0.2
type Notification struct { XMLName xml.Name `xml:"urn:ietf:params:xml:ns:netconf:notification:1.0 notification"` EventTime time.Time `xml:"eventTime"` Body []byte `xml:",innerxml"` }
func (Notification) Decode ¶ added in v0.0.2
func (r Notification) Decode(v interface{}) error
Decode will decode the body of a noticiation into a value pointed to by v. This is a simple wrapper around xml.Unmarshal.
type NotificationHandler ¶
type NotificationHandler func(msg Notification)
NotificationHandler function allows to work with received notifications. A NotificationHandler function can be passed in as an option when calling Open method of Session object A typical use of the NofificationHandler function is to retrieve notifications once they are received so that they can be parsed and/or stored somewhere.
type OKResp ¶
type OKResp struct {
OK ExtantBool `xml:"ok"`
}
type RPCError ¶
type RPCError struct { Type ErrType `xml:"error-type"` Tag ErrTag `xml:"error-tag"` Severity ErrSeverity `xml:"error-severity"` AppTag string `xml:"error-app-tag,omitempty"` Path string `xml:"error-path,omitempty"` Message string `xml:"error-message,omitempty"` Info RawXML `xml:"error-info,omitempty"` }
type RPCErrors ¶
type RPCErrors []RPCError
func (RPCErrors) Filter ¶ added in v0.0.2
func (errs RPCErrors) Filter(severity ...ErrSeverity) RPCErrors
type RawXML ¶
type RawXML []byte
RawXML captures the raw xml for the given element. Used to process certain elements later.
func (*RawXML) MarshalXML ¶
MarshalXML implements xml.Marshaller. Raw XML is passed verbatim, errors and all.
func (*RawXML) UnmarshalXML ¶
type Reply ¶ added in v0.0.2
type Reply struct { XMLName xml.Name `xml:"urn:ietf:params:xml:ns:netconf:base:1.0 rpc-reply"` MessageID uint64 `xml:"message-id,attr"` Errors RPCErrors `xml:"rpc-error,omitempty"` Body []byte `xml:",innerxml"` }
Reply maps the xml value of <rpc-reply> in RFC6241
func (Reply) Decode ¶ added in v0.0.2
Decode will decode the body of a reply into a value pointed to by v. This is a simple wrapper around xml.Unmarshal.
func (Reply) Err ¶ added in v0.0.2
func (r Reply) Err(severity ...ErrSeverity) error
get all errors with severity of error
if err := reply.Err(ErrSevError); err != nil { /* ... */ }
or
if err := reply.Err(); err != nil { /* ... */ }
get all errors with severity of only warning
if err := reply.Err(ErrSevWarning); err != nil { /* ... */ }
get all errors
if err := reply.Err(ErrSevWarning, ErrSevError); err != nil { /* ... */ }
type Session ¶
type Session struct {
// contains filtered or unexported fields
}
Session is represents a netconf session to a one given device.
func Open ¶
func Open(transport transport.Transport, opts ...SessionOption) (*Session, error)
Open will create a new Session with th=e given transport and open it with the necessary hello messages.
func (*Session) Call ¶
Call issues a rpc message with `req` as the body and decodes the reponse into a pointer at `resp`. Any Call errors are presented as a go error.
func (*Session) CancelCommit ¶
func (s *Session) CancelCommit(ctx context.Context, opts ...CancelCommitOption) error
func (*Session) ClientCapabilities ¶
ClientCapabilities will return the capabilities initialized with the session.
func (*Session) Close ¶
Close will gracefully close the sessions first by sending a `close-session` operation to the remote and then closing the underlying transport
func (*Session) Commit ¶
func (s *Session) Commit(ctx context.Context, opts ...CommitOption) error
Commit will commit a canidate config to the running comming. This requires the device to support the `:canidate` capability.
func (*Session) CopyConfig ¶
CopyConfig issues the `<copy-config>` operation as defined in [RFC6241 7.3] for copying an entire config to/from a source and target datastore.
A `<config>` element defining a full config can be used as the source.
If a device supports the `:url` capability than a URL object can be used for the source or target datastore.
[RFC6241 7.3] https://www.rfc-editor.org/rfc/rfc6241.html#section-7.3
func (*Session) CreateSubscription ¶
func (s *Session) CreateSubscription(ctx context.Context, opts ...CreateSubscriptionOption) error
func (*Session) DeleteConfig ¶
func (*Session) Do ¶
Do issues a rpc call for the given NETCONF operation returning a Reply. RPC errors (i.e erros in the `<rpc-errors>` section of the `<rpc-reply>`) are converted into go errors automatically. Instead use `reply.Err()` or `reply.RPCErrors` to access the errors and/or warnings.
func (*Session) EditConfig ¶
func (s *Session) EditConfig(ctx context.Context, target Datastore, config any, opts ...EditConfigOption) error
EditConfig issues the `<edit-config>` operation defined in RFC6241 7.2 for updating an existing target config datastore.
func (*Session) GetConfig ¶
GetConfig implements the <get-config> rpc operation defined in RFC6241 7.1. `source` is the datastore to query.
func (*Session) KillSession ¶
func (*Session) ServerCapabilities ¶
ServerCapabilities will return the capabilities returned by the server in it's hello message.
type SessionOption ¶
type SessionOption interface {
// contains filtered or unexported methods
}
func WithCapability ¶
func WithCapability(capabilities ...string) SessionOption
func WithNotificationHandler ¶
func WithNotificationHandler(nh NotificationHandler) SessionOption
type TestStrategy ¶
type TestStrategy string
TestStrategy defines the beahvior for testing configuration before applying it in a `<edit-config>` operation.
*Note*: in RFC6241 7.2 this is called the `test-option` parameter. Since the `option` term is already overloaded this was changed to `TestStrategy` for a cleaner API.
const ( // TestThenSet will validate the configuration and only if is is valid then // apply the configuration to the datastore. TestThenSet TestStrategy = "test-then-set" // SetOnly will not do any testing before applying it. SetOnly TestStrategy = "set" // Test only will validation the incoming configuration and return the // results without modifying the underlying store. TestOnly TestStrategy = "test-only" )