package main import ( "bytes" "encoding/json" "flag" "fmt" "github.com/Juniper/go-netconf/netconf" xj "github.com/basgys/goxml2json" "golang.org/x/crypto/ssh" "io/ioutil" "log" "os" "strings" "time" ) var ( host = flag.String("host", "localhost", "Hostname") username = flag.String("username", "netconf", "Username") passwd = flag.String("password", "netconf", "Password") source = flag.String("source", "running", "Source datastore") target = flag.String("target", "running", "Target datastore") subtree = flag.String("subtree", "ric", "Subtree or module to select") namespace = flag.String("namespace", "urn:o-ran:ric:xapp-desc:1.0", "XML namespace") file = flag.String("file", "", "Configuration file") action = flag.String("action", "get", "Netconf command: get or edit") timeout = flag.Int("timeout", 30, "Timeout") getStateXml = "" getConfigXml = "<%s/><%s/>" editConfigXml = "<%s/>%s" ) func main() { defer func() { // catch or finally if err := recover(); err != nil { //catch fmt.Fprintf(os.Stderr, "Something went wrong: %v\n", err) os.Exit(1) } }() if flag.Parse(); flag.Parsed() == false { log.Fatal("Syntax error!") return } session := startSSHSession() if session == nil { return } defer session.Close() switch *action { case "get": getStatus(session, getStateXml) case "get-config": getConfig(session, getConfigXml) case "edit": editConfig(session) } } func getStatus(session *netconf.Session, cmdXml string) { cmd := netconf.RawMethod(fmt.Sprintf(cmdXml, *namespace)) reply, err := session.Exec(cmd) if err != nil { log.Fatal(err) return } displayReply(reply.RawReply) } func getConfig(session *netconf.Session, cmdXml string) { cmd := netconf.RawMethod(fmt.Sprintf(cmdXml, *source, *subtree)) reply, err := session.Exec(cmd) if err != nil { log.Fatal(err) return } displayReply(reply.RawReply) } func editConfig(session *netconf.Session) { if *file == "" { log.Fatal("Configuration file missing!") return } if data, err := ioutil.ReadFile(*file); err == nil { cmd := netconf.RawMethod(fmt.Sprintf(editConfigXml, *target, data)) reply, err := session.Exec(cmd) if err != nil { log.Fatal(err) return } displayReply(reply.RawReply) } } func startSSHSession() *netconf.Session { sshConfig := &ssh.ClientConfig{ User: *username, Auth: []ssh.AuthMethod{ssh.Password(*passwd)}, HostKeyCallback: ssh.InsecureIgnoreHostKey(), Timeout: time.Duration(*timeout) * time.Second, } session, err := netconf.DialSSH(*host, sshConfig) if err != nil { log.Fatal(err) return nil } return session } func prettyPrint(b string) string { var out bytes.Buffer if err := json.Indent(&out, []byte(b), "", " "); err == nil { return string(out.Bytes()) } return "" } func displayReply(rawReply string) { xml := strings.NewReader(rawReply) json, err := xj.Convert(xml) if err != nil { log.Fatal("Something went sore ... XML is invalid!") } fmt.Println(prettyPrint(json.String())) }