Use python package instead of sshpass to execute remote commands.

Use python package instead of sshpass to execute remote commands.
Fixing this issue, by using paramiko.
Closes-bug: #1511658

Change-Id: I102d178b2fb1f621f2a61b26a939e69613156c19
This commit is contained in:
dharmendra 2016-02-11 17:42:01 +05:30
parent 814c9509e6
commit a362aadaaa
2 changed files with 110 additions and 6 deletions

View File

@ -0,0 +1,104 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import paramiko
import socket
class CommandResult(object):
"""Result class contains command, stdout, stderror and return code."""
def __init__(self, cmd, stdout, stderr, return_code):
self.__cmd = cmd
self.__stdout = stdout
self.__stderr = stderr
self.__return_code = return_code
def get_command(self):
return self.__cmd
def get_stdout(self):
return self.__stdout
def get_stderr(self):
return self.__stderr
def get_return_code(self):
return self.__return_code
def __str__(self):
return "cmd: %s, stdout: %s, stderr: %s, return code: %s" \
% (self.__cmd, self.__stdout, self.__stderr, self.__return_code)
def __repr__(self):
return "cmd: %s, stdout: %s, stderr: %s, return code: %s" \
% (self.__cmd, self.__stdout, self.__stderr, self.__return_code)
class RemoteCommandExecutor(object):
"""Class to execute a command on remote location"""
def __init__(self, user, password, ip, port=22, con_timeout=10):
self.__ip = ip
self.__port = port
self.__user = user
self.__password = password
self.__paramiko_conn = None
self.__sock = None
self.__con_timeout = con_timeout
self.__connect()
def __connect(self):
self.__sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.__sock.settimeout(self.__con_timeout)
self.__sock.connect((self.__ip, self.__port))
self.__paramiko_conn = paramiko.Transport(self.__sock)
self.__paramiko_conn.start_client()
if not self.__paramiko_conn.is_active():
self.__paramiko_conn.close()
raise Exception('client negotiation failed with %s' % self.__ip)
self.__paramiko_conn.auth_password(self.__user, self.__password)
if not self.__paramiko_conn.is_authenticated():
self.__paramiko_conn.close()
raise Exception('Authentication failed: %s' % self.__ip)
def close_session(self):
self.__paramiko_conn.close()
def reconnect(self):
try:
self.close_session()
except Exception:
pass
self.__connect()
def execute_command(self, cmd, input_data=None, timeout=None):
channel = self.__paramiko_conn.open_session()
if channel is None:
raise Exception("Channel already closed")
if timeout:
channel.settimeout(timeout)
channel.exec_command(cmd)
try:
if input_data:
stdin = channel.makefile('wb')
stdin.write(input_data)
stdout = channel.makefile('rb')
stderr = channel.makefile_stderr()
cmd_err = stderr.readlines()
cmd_out = stdout.readlines()
return_code = channel.recv_exit_status()
stdin.close()
stdout.close()
except socket.timeout:
raise
result = CommandResult(cmd, cmd_out, cmd_err, return_code)
return result

View File

@ -19,7 +19,7 @@
from oslo_config import cfg
import yaml
from tacker.agent.linux import utils
from tacker.common import cmd_executer
from tacker.common import log
from tacker.openstack.common import jsonutils
from tacker.openstack.common import log as logging
@ -53,11 +53,11 @@ class DeviceMgmtOpenWRT(abstract_driver.DeviceMGMTAbstractDriver):
def _config_service(self, mgmt_ip_address, service, config):
user = cfg.CONF.openwrt.user
password = cfg.CONF.openwrt.password
cmd = ["sshpass", "-p", "%s" % password,
"ssh", "-o", "StrictHostKeyChecking=no",
"%s@%s" % (user, mgmt_ip_address),
"uci import %s; /etc/init.d/%s restart" % (service, service)]
utils.execute(cmd, process_input=config)
commander = cmd_executer.RemoteCommandExecutor(user,
password,
mgmt_ip_address)
cmd = "uci import %s; /etc/init.d/%s restart" % (service, service)
commander.execute_command(cmd, input_data=config)
@log.log
def mgmt_call(self, plugin, context, device, kwargs):