-
Notifications
You must be signed in to change notification settings - Fork 0
/
session.go
108 lines (88 loc) · 2.71 KB
/
session.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
// session contains functionality needed to download YANG/YIN
// schema as defined in ietf-netconf-monitoring.
package main
import (
"encoding/xml"
"fmt"
"strings"
"github.com/Juniper/go-netconf/netconf"
)
const YIN string = "yin"
const YANG string = "yang"
type Session struct {
handle *netconf.Session
}
// Get a NETCONF session to the target device.
func newSession(host string, username string, password string) (session *Session, err error) {
// Connect to target device.
var s *netconf.Session
s, err = netconf.DialSSH(host, netconf.SSHConfigPassword(username, password))
if err != nil {
return nil, err
}
session = &Session{}
session.handle = s
return session, nil
}
// Close is used to close and end a transport session
func (s *Session) Close() error {
return s.handle.Close()
}
// Retrieve list of available schema from device.
func (s *Session) getSchemaList(format string) (result []SchemaType, err error) {
var buffer *DataType = &DataType{}
// Get the schema list
var reply *netconf.RPCReply
reply, err = s.handle.Exec(netconf.RawMethod(GetSchemaList))
if err != nil {
fmt.Printf("%v", reply.Errors)
return nil, err
}
fmt.Printf("%v", reply.Data)
// Unmarshal the XML into our had built type structures.
err = xml.Unmarshal([]byte(reply.Data), buffer)
if err != nil {
fmt.Printf("%v", reply.Errors)
return nil, err
}
// For each schema returned in the list we want to retrieve the YANG instance from the device.
var in []SchemaType = buffer.NetconfState.Schemas.SchemaList
for i := 0; i < len(in); i++ {
var list []string = strings.Split(in[i].Format, ":")
if len(list) > 1 {
in[i].Format = list[1]
} else {
in[i].Format = list[0]
}
if strings.Contains(in[i].Format, format) &&
strings.Compare(in[i].Location, "NETCONF") == 0 {
result = append(result, in[i])
}
}
return result, nil
}
// Retrieve an individual schema instance from device.
func (s *Session) getSchema(schema SchemaType) (source *SourceType, err error) {
// Build the NETCONF get message for the schema document.
var request string
request = fmt.Sprintf(GetSchemaInstance, schema.Identifier, schema.Version, schema.Format)
var reply *netconf.RPCReply
reply, err = s.handle.Exec(netconf.RawMethod(request))
if err != nil {
fmt.Printf("%v", reply.Errors)
return nil, err
}
// Unmarshal the document.
source = &SourceType{}
err = xml.Unmarshal([]byte(reply.Data), source)
if err != nil {
return nil, err
}
// YIN is an XML document so our simple SourceType "chardata" will not work so manually parse.
if schema.Format == YIN {
s1 := strings.Index(reply.Data, "<module")
s2 := strings.Index(reply.Data[s1:], "</data>")
source.Data = xml.Header + reply.Data[s1:s1 + s2]
}
return source, nil
}