Commit 11e34d43 authored by zdc's avatar zdc

move to JSON api, clear code

* now all operations work through JSON API
* deleted not needed anymore code
* deleted http/template import
* changed html page
parent 6b87ce1d
......@@ -45,7 +45,7 @@ user = "lookis"
password = ""
command_01 = "ping count=5"
command_01_name = "ping"
command_02 = "tool traceroute count=1"
command_02 = "tool traceroute count=1 max-hops=30"
command_02_name = "traceroute"
command_03 = "ip route print where"
command_03_name = "show route"
......
......@@ -3,7 +3,6 @@ package main
import (
"flag"
"fmt"
"html/template"
"encoding/json"
"log"
"net"
......@@ -30,23 +29,20 @@ type Router struct {
RouterCommands []RouterCommands
}
// declare variables for page template
type DataOut struct {
RoutersList []Router
OutputHeader, OutputBody string
// declare variables for JSON interface
type JsonIn struct {
Router, Action, Argument string
}
// fill error details
func PrepareError (RoutersRaw []Router, HeaderRaw, BodyRaw string) DataOut {
log.Printf("Error! %s: \"%s\"", HeaderRaw, BodyRaw)
output := DataOut{ RoutersList: RoutersRaw, OutputHeader: HeaderRaw, OutputBody: BodyRaw }
return output
type JsonOut struct {
Status, Result string
}
// fill normal output
func PrepareOutput (RoutersRaw []Router, HeaderRaw, BodyRaw string) DataOut {
output := DataOut{ RoutersList: RoutersRaw, OutputHeader: HeaderRaw, OutputBody: BodyRaw }
// fill response in JSON
func PrepareJson (StatusRaw, ResultRaw string) JsonOut {
if StatusRaw == "Error" {
log.Printf("Error! \"%s\"", ResultRaw)
}
output := JsonOut{ Status: "<strong>"+StatusRaw+"</strong>", Result: "<pre>"+ResultRaw+"</pre>" }
return output
}
......@@ -77,9 +73,9 @@ func GetCommand (router, command string) (string, bool) {
}
// connect to router and run command
func SSHRun (router_ip, port, username, password, command, argument, suffix string) DataOut {
func SSHRun (router_ip, port, username, password, command, argument, suffix string) JsonOut {
var rawoutput []byte
var output DataOut
var output JsonOut
var allok bool = true
// setting auth options
......@@ -93,7 +89,7 @@ func SSHRun (router_ip, port, username, password, command, argument, suffix stri
// connect to router
connection, err := ssh.Dial("tcp", router_ip+":"+port, sshConfig)
if err != nil {
output = PrepareError (RouterList, "Unable to connect", router_ip)
output = PrepareJson ("Error", "Unable to connect: "+router_ip)
allok = false
}
......@@ -101,7 +97,7 @@ func SSHRun (router_ip, port, username, password, command, argument, suffix stri
// create ssh session
session, err := connection.NewSession()
if err != nil {
output = PrepareError (RouterList, "Connection failed", "failed to create session")
output = PrepareJson ("Error", "Connection failed: failed to create session")
allok = false
connection.Close()
} else {
......@@ -109,11 +105,11 @@ func SSHRun (router_ip, port, username, password, command, argument, suffix stri
// run command and save output
rawoutput, err = session.Output(command+" "+argument+suffix)
if err != nil {
output = PrepareError (RouterList, "Cannot execute command", command+" "+argument+suffix)
output = PrepareJson ("Error", "Cannot execute command: "+command+" "+argument+suffix)
allok = false
connection.Close()
} else {
output = PrepareOutput (RouterList, "Result", ByteToString(rawoutput))
output = PrepareJson ("Result", ByteToString(rawoutput))
connection.Close()
}
}
......@@ -132,6 +128,22 @@ func GetRouterName (RouterId string) string {
return RouterName
}
// check router in request
func CheckRouter (RouterId string) bool {
var RouterStatus bool
for i := range RouterList {
if RouterList[i].RouterId == RouterId {
RouterStatus = true
break
} else {
RouterStatus = false
}
}
return RouterStatus
}
// get command list for router from config file
func GetRouterCommands (RouterId string) []RouterCommands {
var CommandList []RouterCommands
......@@ -178,74 +190,89 @@ func ParseRoutersFromConfig () []Router {
return routers
}
// show page and base logic
// show page
func ShowPage (w http.ResponseWriter, r *http.Request) {
// select html template
t, _ := template.ParseFiles(datapath+"/page_main.gtpl")
// check HTTP method
if r.Method == "POST" {
if r.Method == "GET" {
http.ServeFile(w, r, datapath+"/page_main.gtpl")
} else {
w.Write([]byte("Not allowed!"))
}
}
// show JSON with routers and commands
func ShowJSON (w http.ResponseWriter, r *http.Request) {
// check method
switch r.Method {
// if GET, then show router list with commands
case "GET":
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
jsonout, _ := json.MarshalIndent(ParseRoutersFromConfig(), "", "\t")
w.Write(jsonout)
// if POST, process request and show answer
case "POST":
var Command, argument, suffix string
var router_ip, port, username, password string
var output DataOut
var allok bool = true
var CommandState bool
var input_router, input_action, input_argument string
var output JsonOut
var routerState, CommandState bool
var jsonrequest JsonIn
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
// decode JSON to variable jsonrequest
jsonbody := json.NewDecoder(r.Body)
err := jsonbody.Decode(&jsonrequest)
if err != nil {
PrepareJson ("Error", "Cannot decode JSON")
goto ShowOutput
}
// get POST data
input_router := r.PostFormValue("router")
input_action := r.PostFormValue("action")
input_argument := r.PostFormValue("argument")
input_router = jsonrequest.Router
input_action = jsonrequest.Action
input_argument = jsonrequest.Argument
// check for selected router exist
if viper.IsSet(input_router+".address") == false {
output = PrepareError (RouterList, "Bad router id", input_router)
allok = false
} else {
routerState = CheckRouter(input_router)
if routerState == true {
// setting router variables from config file
router_ip = viper.GetString(input_router+".address")
port = viper.GetString(input_router+".port")
username = viper.GetString(input_router+".user")
password = viper.GetString(input_router+".password")
} else {
output = PrepareJson ("Error", "Bad router id: "+input_router)
goto ShowOutput
}
// check and get command for selected action
Command, CommandState = GetCommand(input_router, input_action)
if CommandState == false {
output = PrepareError (RouterList, "Bad command", input_action)
allok = false
output = PrepareJson ("Error", "Bad command: "+input_action)
goto ShowOutput
}
// check for argument
if net.ParseIP(input_argument) == nil {
output = PrepareError (RouterList, "Bad argument", input_argument)
allok = false
output = PrepareJson ("Error", "Bad argument: "+input_argument)
goto ShowOutput
} else {
argument = input_argument
}
// connect to router and run command
if allok == true {
// check if command need suffix
if viper.IsSet(input_router+".command_"+input_action+"_suffix") != false {
suffix = " "+viper.GetString(input_router+".command_"+input_action+"_suffix")
}
output = SSHRun(router_ip, port, username, password, Command, argument, suffix)
// show result to user
t.Execute(w, output)
} else {
// show result to user
t.Execute(w, output)
}
} else {
// show page without result
output := PrepareOutput(RouterList, "", "")
t.Execute(w, output)
}
}
// show JSON with routers and commands
func ShowJSON (w http.ResponseWriter, r *http.Request) {
jsonout, _ := json.MarshalIndent(ParseRoutersFromConfig(), "", "\t")
// show result to user
ShowOutput:
jsonout, _ := json.MarshalIndent(output, "", "\t")
w.Write(jsonout)
default:
w.Write([]byte("Not allowed!"))
}
}
func main() {
......
......@@ -6,7 +6,7 @@
</head>
<body>
<p>&nbsp;</p>
<form action="/" method="post">
<form>
<table style="margin-left: auto; margin-right: auto;">
<tbody>
<tr>
......@@ -20,8 +20,6 @@
<td style="width: 50px;">&nbsp;</td>
<td>
<select id="router" name="router">
{{range .RoutersList}}<option value="{{ .RouterId }}">{{ .RouterName }}</option>
{{else}}<option>no enabled routers</option>{{end}}
</select>
</td>
</tr>
......@@ -36,12 +34,12 @@
<tr>
<td>Argument</td>
<td>&nbsp;</td>
<td><input name="argument" type="text" /></td>
<td><input id="argument" name="argument" type="text" /></td>
</tr>
<tr>
<td style="text-align: center;" colspan="3">
<p>&nbsp;</p>
<p><input type="submit" value="Do it!" /></p>
<p><button type="button" onclick="doit()">Do it!</button></p>
</td>
</tr>
</tbody>
......@@ -50,10 +48,10 @@
<table style="margin-left: auto; margin-right: auto;">
<tbody>
<tr>
<td><strong>{{.OutputHeader}}</strong></td>
<td id="output-header" style="text-align: center;"></td>
</tr>
<tr>
<td><pre>{{.OutputBody}}</pre></td>
<td id="output-body"><pre></pre></td>
</tr>
</tbody>
</table>
......@@ -67,6 +65,7 @@
$.getJSON( "json", function (jsonraw) {
jsondata = jsonraw;
// fill actions for selected router
FillInRouter();
FillInAction();
});
......@@ -86,6 +85,18 @@
});
}
function FillInRouter() {
var router = document.getElementById('router');
// add routers to list
$.each(jsondata, function(i, v) {
var option = document.createElement("option");
option.value = v.RouterId;
option.text = v.RouterName;
router.add(option);
});
}
function FillInAction() {
var router = document.getElementById('router');
var RouterId = router.value;
......@@ -99,6 +110,33 @@
}
});
}
function doit() {
// get selected form values
var router = document.getElementById('router').value;
var action = document.getElementById('action').value;
var argument = document.getElementById('argument').value;
// format JSON
var request_data = JSON.stringify({ "router": router, "action": action, "argument": argument });
document.getElementById("output-header").innerHTML = "Please wait...";
// make POST request to server with JSON data
$.ajax({
url: '/json',
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: request_data,
dataType: "json"
}).done(DrawResult);
}
// show result to user
function DrawResult(jsonresult) {
document.getElementById("output-header").innerHTML = jsonresult['Status'];
document.getElementById("output-body").innerHTML = jsonresult['Result'];
}
</script>
</body>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment