github.com/mmatczuk/gohan@v0.0.0-20170206152520-30e45d9bdb69/extension/otto/gohan_remote.go (about)

     1  // Copyright (C) 2015 NTT Innovation Institute, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //    http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
    12  // implied.
    13  // See the License for the specific language governing permissions and
    14  // limitations under the License.
    15  
    16  package otto
    17  
    18  import (
    19  	"bytes"
    20  
    21  	"github.com/robertkrimen/otto"
    22  	"golang.org/x/crypto/ssh"
    23  
    24  	"github.com/Juniper/go-netconf/netconf"
    25  	"github.com/cloudwan/gohan/util"
    26  	//Import otto underscore lib
    27  	_ "github.com/robertkrimen/otto/underscore"
    28  )
    29  
    30  //SetUp sets up vm to with environment
    31  func init() {
    32  	gohanRemoteInit := func(env *Environment) {
    33  		vm := env.VM
    34  
    35  		builtins := map[string]interface{}{
    36  			"gohan_netconf_open": func(call otto.FunctionCall) otto.Value {
    37  				if len(call.ArgumentList) != 2 {
    38  					panic("Wrong number of arguments in gohan_netconf_open call.")
    39  				}
    40  				rawHost, _ := call.Argument(0).Export()
    41  				host, ok := rawHost.(string)
    42  				if !ok {
    43  					return otto.NullValue()
    44  				}
    45  				rawUserName, _ := call.Argument(1).Export()
    46  				userName, ok := rawUserName.(string)
    47  				if !ok {
    48  					return otto.NullValue()
    49  				}
    50  				config := util.GetConfig()
    51  				publicKeyFile := config.GetString("ssh/key_file", "")
    52  				if publicKeyFile == "" {
    53  					return otto.NullValue()
    54  				}
    55  				sshConfig := &ssh.ClientConfig{
    56  					User: userName,
    57  					Auth: []ssh.AuthMethod{
    58  						util.PublicKeyFile(publicKeyFile),
    59  					},
    60  				}
    61  				s, err := netconf.DialSSH(host, sshConfig)
    62  
    63  				if err != nil {
    64  					ThrowOttoException(&call, "Error during gohan_netconf_open: %s", err.Error())
    65  				}
    66  				value, _ := vm.ToValue(s)
    67  				return value
    68  			},
    69  			"gohan_netconf_close": func(call otto.FunctionCall) otto.Value {
    70  				if len(call.ArgumentList) != 1 {
    71  					panic("Wrong number of arguments in gohan_netconf_close call.")
    72  				}
    73  				rawSession, _ := call.Argument(0).Export()
    74  				s, ok := rawSession.(*netconf.Session)
    75  				if !ok {
    76  					ThrowOttoException(&call, "Error during gohan_netconf_close")
    77  				}
    78  				s.Close()
    79  				return otto.NullValue()
    80  			},
    81  			"gohan_netconf_exec": func(call otto.FunctionCall) otto.Value {
    82  				if len(call.ArgumentList) != 2 {
    83  					panic("Wrong number of arguments in gohan_netconf_exec call.")
    84  				}
    85  				rawSession, _ := call.Argument(0).Export()
    86  				s, ok := rawSession.(*netconf.Session)
    87  				if !ok {
    88  					return otto.NullValue()
    89  				}
    90  				rawCommand, _ := call.Argument(1).Export()
    91  				command, ok := rawCommand.(string)
    92  				if !ok {
    93  					return otto.NullValue()
    94  				}
    95  				reply, err := s.Exec(netconf.RawMethod(command))
    96  				resp := map[string]interface{}{}
    97  				if err != nil {
    98  					resp["status"] = "error"
    99  					resp["output"] = err.Error()
   100  				} else {
   101  					resp["status"] = "success"
   102  					resp["output"] = reply
   103  				}
   104  				value, _ := vm.ToValue(resp)
   105  				return value
   106  			},
   107  			"gohan_ssh_open": func(call otto.FunctionCall) otto.Value {
   108  				if len(call.ArgumentList) != 2 {
   109  					panic("Wrong number of arguments in gohan_ssh_open call.")
   110  				}
   111  				rawHost, _ := call.Argument(0).Export()
   112  				host, ok := rawHost.(string)
   113  				if !ok {
   114  					return otto.NullValue()
   115  				}
   116  				rawUserName, _ := call.Argument(1).Export()
   117  				userName, ok := rawUserName.(string)
   118  				if !ok {
   119  					return otto.NullValue()
   120  				}
   121  				config := util.GetConfig()
   122  				publicKeyFile := config.GetString("ssh/key_file", "")
   123  				if publicKeyFile == "" {
   124  					return otto.NullValue()
   125  				}
   126  				sshConfig := &ssh.ClientConfig{
   127  					User: userName,
   128  					Auth: []ssh.AuthMethod{
   129  						util.PublicKeyFile(publicKeyFile),
   130  					},
   131  				}
   132  				conn, err := ssh.Dial("tcp", host, sshConfig)
   133  				if err != nil {
   134  					ThrowOttoException(&call, "Error during gohan_ssh_open %s", err)
   135  				}
   136  				session, err := conn.NewSession()
   137  				if err != nil {
   138  					ThrowOttoException(&call, "Error during gohan_ssh_open %s", err)
   139  				}
   140  				value, _ := vm.ToValue(session)
   141  				return value
   142  			},
   143  			"gohan_ssh_close": func(call otto.FunctionCall) otto.Value {
   144  				if len(call.ArgumentList) != 1 {
   145  					panic("Wrong number of arguments in gohan_ssh_close call.")
   146  				}
   147  				rawSession, _ := call.Argument(0).Export()
   148  				s, ok := rawSession.(*ssh.Session)
   149  				if !ok {
   150  					ThrowOttoException(&call, "Error during gohan_ssh_close")
   151  				}
   152  				s.Close()
   153  				return otto.NullValue()
   154  			},
   155  			"gohan_ssh_exec": func(call otto.FunctionCall) otto.Value {
   156  				if len(call.ArgumentList) != 2 {
   157  					panic("Wrong number of arguments in gohan_ssh_exec call.")
   158  				}
   159  				rawSession, _ := call.Argument(0).Export()
   160  				s, ok := rawSession.(*ssh.Session)
   161  				if !ok {
   162  					return otto.NullValue()
   163  				}
   164  				rawCommand, _ := call.Argument(1).Export()
   165  				command, ok := rawCommand.(string)
   166  				if !ok {
   167  					return otto.NullValue()
   168  				}
   169  				var stdoutBuf bytes.Buffer
   170  				s.Stdout = &stdoutBuf
   171  				err := s.Run(command)
   172  				resp := map[string]interface{}{}
   173  				if err != nil {
   174  					resp["status"] = "error"
   175  					resp["output"] = err.Error()
   176  				} else {
   177  					resp["status"] = "success"
   178  					resp["output"] = stdoutBuf.String()
   179  				}
   180  				value, _ := vm.ToValue(resp)
   181  				return value
   182  			},
   183  		}
   184  		for name, object := range builtins {
   185  			vm.Set(name, object)
   186  		}
   187  	}
   188  	RegisterInit(gohanRemoteInit)
   189  }