eb5062e0ffbe1c7de269a5b5cc7052a72c55c864
[ric-plt/o1.git] / agent / cli / o1-cli.go
1 package main
2
3 import (
4         "bytes"
5         "encoding/json"
6         "flag"
7         "fmt"
8         "github.com/Juniper/go-netconf/netconf"
9         xj "github.com/basgys/goxml2json"
10         "golang.org/x/crypto/ssh"
11         "io/ioutil"
12         "log"
13         "strings"
14         "time"
15 )
16
17 var (
18         host     = flag.String("host", "localhost", "Hostname")
19         username = flag.String("username", "netconf", "Username")
20         passwd   = flag.String("password", "netconf", "Password")
21         source   = flag.String("source", "running", "Source datastore")
22         target   = flag.String("target", "running", "Target datastore")
23         subtree  = flag.String("subtree", "netconf-server", "Subtree or module to select")
24         file     = flag.String("file", "", "Configuration file")
25         action   = flag.String("action", "get", "Netconf command: get or edit")
26         timeout  = flag.Int("timeout", 30, "Timeout")
27
28         getConfigXml  = "<get-config><source><%s/></source><filter type=\"subtree\"><%s/></filter></get-config>"
29         editConfigXml = "<edit-config><target><%s/></target><config>%s</config></edit-config>"
30 )
31
32 func main() {
33         if flag.Parse(); flag.Parsed() == false {
34                 log.Fatal("Syntax error!")
35                 return
36         }
37
38         switch *action {
39         case "get":
40                 getConfig()
41         case "edit":
42                 editConfig()
43         }
44 }
45
46 func getConfig() {
47         session := startSSHSession()
48         if session == nil {
49                 return
50         }
51         defer session.Close()
52
53         cmd := netconf.RawMethod(fmt.Sprintf(getConfigXml, *source, *subtree))
54         reply, err := session.Exec(cmd)
55         if err != nil {
56                 log.Fatal(err)
57                 return
58         }
59         displayReply(reply.RawReply)
60 }
61
62 func editConfig() {
63         if *file == "" {
64                 log.Fatal("Configuration file missing!")
65                 return
66         }
67
68         session := startSSHSession()
69         if session == nil {
70                 return
71         }
72         defer session.Close()
73
74         if data, err := ioutil.ReadFile(*file); err == nil {
75                 cmd := netconf.RawMethod(fmt.Sprintf(editConfigXml, *target, data))
76                 reply, err := session.Exec(cmd)
77                 if err != nil {
78                         log.Fatal(err)
79                         return
80                 }
81                 displayReply(reply.RawReply)
82         }
83 }
84
85 func startSSHSession() *netconf.Session {
86         sshConfig := &ssh.ClientConfig{
87                 User:            *username,
88                 Auth:            []ssh.AuthMethod{ssh.Password(*passwd)},
89                 HostKeyCallback: ssh.InsecureIgnoreHostKey(),
90                 Timeout:         time.Duration(*timeout) * time.Second,
91         }
92
93         session, err := netconf.DialSSH(*host, sshConfig)
94         if err != nil {
95                 log.Fatal(err)
96                 return nil
97         }
98         return session
99 }
100
101 func prettyPrint(b string) string {
102         var out bytes.Buffer
103         if err := json.Indent(&out, []byte(b), "", "  "); err == nil {
104                 return string(out.Bytes())
105         }
106         return ""
107 }
108
109 func displayReply(rawReply string) {
110         xml := strings.NewReader(rawReply)
111         json, err := xj.Convert(xml)
112         if err != nil {
113                 log.Fatal("Something went sore ... XML is invalid!")
114         }
115         fmt.Println(prettyPrint(json.String()))
116 }