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