760 lines
29 KiB
C#
760 lines
29 KiB
C#
using Renci.SshNet;
|
|
using Renci.SshNet.Common;
|
|
using Termo.Active.CmsConnectGateway.Events;
|
|
using Termo.Active.CmsConnectGateway.Exceptions;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Net.Sockets;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace Termo.Active.CmsConnectGateway
|
|
{
|
|
public class GatewayAdapter : IDisposable
|
|
{
|
|
//Internal Constant
|
|
private const string SSH_SET_PROXY_COMMAND = "sudo ./setProxy.sh ";
|
|
private const string SSH_SET_DNSIP_COMMAND = "sudo ./setDnsIp.sh ";
|
|
private const string SSH_SET_DNSSUFFIX_COMMAND = "sudo ./setDnsSuffix.sh ";
|
|
private const string SSH_SET_NETWORK_COMMAND = "sudo ./setNetwork.sh ";
|
|
private const string SSH_GET_NETWORK_COMMAND = "sudo ./getNetworkConfiguration.sh ";
|
|
private const string SSH_GET_PROXY_COMMAND = "sudo ./getProxyConfiguration.sh ";
|
|
private const string SSH_TEST_CONNECTION_COMMAND = "sudo ./testConnection.sh ";
|
|
private const string SSH_GW_REBOOT_COMMAND = "sudo ./gatewayReboot.sh ";
|
|
|
|
const string IP_ADDR_LABEL = "IP_ADDRESS=";
|
|
const string GATEWAY_LABEL = "DEFAULT_GATEWAY=";
|
|
const string DNSIP_LABEL = "DNS_IP=";
|
|
const string DNSPREFIX_LABEL = "DNS_SUFFIX=";
|
|
const string PROXY_ADDR_LABEL = "PROXY=";
|
|
const string NO_PROXY_LABEL = "NO_PROXY=";
|
|
const string UNDEF_VALUE = "none";
|
|
const string CONNECTION_OK_VALUE = "OK";
|
|
const string CONNECTION_NOWEB_VALUE = "NO_WEB";
|
|
const string CONNECTION_NOPORT_VALUE = "NO_PORTS";
|
|
|
|
const int REBOOT_MINUTES_MAX = 2;
|
|
const int REBOOT_MSWAIT_BETWEEN_OP = 500;
|
|
|
|
|
|
//Internal Private Variable
|
|
private string host;
|
|
private string username;
|
|
private string password;
|
|
|
|
//---------------------------------------------------------------------------------------------------
|
|
#region Public_methods
|
|
|
|
/// <summary>
|
|
/// Simple constructor.
|
|
/// Create an instance with this configuration: hostname: localhost, username: root, password: root.
|
|
/// </summary>
|
|
public GatewayAdapter()
|
|
{
|
|
this.host = "localhost";
|
|
this.username = "root";
|
|
this.password = "root";
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Advanced constructor.
|
|
/// Create an instance with the configuration passed by arguments
|
|
/// </summary>
|
|
/// <param name="hostname">Name (or IP-Address) of the gateway</param>
|
|
/// <param name="username">Username for Gateway Login</param>
|
|
/// <param name="password">Password for Gateway Login</param>
|
|
/// <exception cref="System.NullReferenceException">Thrown when one parameter is null</exception>
|
|
public GatewayAdapter(string hostname, string username, string password)
|
|
{
|
|
Setup(hostname, username, password);
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Setup parameters Method.
|
|
/// </summary>
|
|
/// <param name="hostname">Name (or IP-Address) of the gateway</param>
|
|
/// <param name="username">Username for Gateway Login</param>
|
|
/// <param name="password">Password for Gateway Login</param>
|
|
/// <exception cref="System.NullReferenceException">Thrown when one parameter is null</exception>
|
|
public void Setup(string hostname, string username, string password)
|
|
{
|
|
this.host = hostname ?? throw new NullReferenceException("hostname is mandatory");
|
|
this.username = username ?? throw new NullReferenceException("username is mandatory");
|
|
this.password = password ?? throw new NullReferenceException("password is mandatory");
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Write Proxy-Configuration on Gateway.
|
|
/// <para />See <see cref="GatewayProxyConfigurationBuilder"/> for generate the configuration.
|
|
/// </summary>
|
|
/// <param name="proxyConfiguration">Configuration of the proxy.</param>
|
|
/// <exception cref="GatewayException"></exception>
|
|
public void WriteGatewayProxyConfiguration(GatewayProxyConfiguration proxyConfiguration)
|
|
{
|
|
String Command = GenerateSshProxyCommand(proxyConfiguration);
|
|
SendSSHCommand(Command);
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Write Newtork-Configuration on Gateway.
|
|
/// <para />See <see cref="GatewayNetworkConfigurationBuilder"/> for generate the configuration.
|
|
/// </summary>
|
|
/// <param name="networkConfiguration">Configuration of the network.</param>
|
|
/// <exception cref="GatewayException"></exception>
|
|
public void WriteGatewayNetworkConfiguration(GatewayNetworkConfiguration networkConfiguration)
|
|
{
|
|
String NetworkCommand = GenerateSshNetworkCommand(networkConfiguration);
|
|
String DnsIpCommand = GenerateSshDnsCommand(networkConfiguration);
|
|
String DnsSuffixCommand = GenerateSshDnsSuffxCommand(networkConfiguration);
|
|
|
|
SendSSHCommand(new List<string>() { NetworkCommand, DnsIpCommand, DnsSuffixCommand });
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Read Newtork-Configuration saved on Gateway.
|
|
/// </summary>
|
|
/// <returns>See <see cref="GatewayNetworkConfiguration"/>
|
|
/// </returns>
|
|
/// <exception cref="GatewayException"></exception>
|
|
public GatewayNetworkConfiguration ReadGatewayNetworkConfiguration()
|
|
{
|
|
return ElaborateConfigFromSshNetworkCommand( SendSSHCommand(SSH_GET_NETWORK_COMMAND) );
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Read Proxy-Configuration saved on Gateway.
|
|
/// </summary>
|
|
/// <returns>See <see cref="GatewayProxyConfiguration"/>
|
|
/// </returns>
|
|
/// <exception cref="GatewayException"></exception>
|
|
public GatewayProxyConfiguration ReadGatewayProxyConfiguration()
|
|
{
|
|
return ElaborateConfigFromSshProxyCommand(SendSSHCommand(SSH_GET_PROXY_COMMAND));
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Test connection to SCM/CMS Server, on Gateway.
|
|
/// </summary>
|
|
/// <param name="timeout">Seconds timeout for the request</param>
|
|
/// <exception cref="GatewayException"></exception>
|
|
public GatewayConnectionStatus TestGatewayConnection(int timeout)
|
|
{
|
|
if (timeout < 0)
|
|
throw new ArgumentOutOfRangeException("Timeout must be > 0");
|
|
|
|
return ElaborateTestConnectionCommand(SendSSHCommand(SSH_TEST_CONNECTION_COMMAND + timeout));
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Reboot asynchronously the Gateway.
|
|
/// </summary>
|
|
/// <param name="delay">Serconds to delay before reboot</param>
|
|
/// <param name="handler">Handler Callback when the operation is finished or an error occours.
|
|
/// See <see cref="GatewayRebootEventHandlerArgs"/>
|
|
/// </param>
|
|
public void RebootGatewayAsync(int delay, EventHandler<GatewayRebootEventHandlerArgs> handler)
|
|
{
|
|
if (delay < 0)
|
|
throw new ArgumentOutOfRangeException("Delay must be > 0");
|
|
|
|
//Create the Action
|
|
Action<int, EventHandler<GatewayRebootEventHandlerArgs>> action = (int del, EventHandler<GatewayRebootEventHandlerArgs> hand) =>
|
|
{
|
|
GatewayRebootEventHandlerArgs ev = new GatewayRebootEventHandlerArgs();
|
|
try
|
|
{
|
|
this.SendSSHReboot(del);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
ev.errorStatus = true;
|
|
ev.errorMessage = e.Message;
|
|
}
|
|
hand(this, ev);
|
|
};
|
|
|
|
// Create a task and not start it.
|
|
Task t = new Task (() => action(delay, handler));
|
|
t.Start();
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Reboot and wait a new session of the Gateway.
|
|
/// </summary>
|
|
/// <param name="delay">Seconds to delay before reboot</param>
|
|
/// <exception cref="GatewayException"></exception>
|
|
public void RebootGateway(int delay)
|
|
{
|
|
if (delay < 0)
|
|
throw new ArgumentOutOfRangeException("Delay must be > 0");
|
|
|
|
//Send Command
|
|
this.SendSSHReboot(delay);
|
|
}
|
|
|
|
|
|
public void Dispose()
|
|
{
|
|
}
|
|
|
|
|
|
public override string ToString()
|
|
{
|
|
return "CmsConnectAdapter - Host:" + this.host;
|
|
}
|
|
|
|
#endregion
|
|
|
|
//---------------------------------------------------------------------------------------------------
|
|
#region SSH_commands_preparations_sub_methods
|
|
|
|
//SSH command generator for Proxy setting
|
|
private string GenerateSshProxyCommand(GatewayProxyConfiguration configuration)
|
|
{
|
|
StringBuilder command = new StringBuilder(SSH_SET_PROXY_COMMAND);
|
|
|
|
//Call the script without an argument will disable the Proxy
|
|
if (configuration.hasProxy)
|
|
{
|
|
/* 1St parameter. Must be one of these:
|
|
* - Address:Port
|
|
* - User:Password@Address:Port
|
|
*/
|
|
|
|
//Setup Username & password if needed
|
|
if (!String.IsNullOrWhiteSpace(configuration.username) && !String.IsNullOrWhiteSpace(configuration.password))
|
|
command.Append(configuration.username).Append(":").Append(configuration.password).Append("@");
|
|
|
|
//Setup Address & Port
|
|
command.Append(configuration.address).Append(":").Append(configuration.port).Append(" ");
|
|
|
|
|
|
/* 2nd parameter. Must be:
|
|
* "no_proxy1,no_proxy2,…,no_proxyN"
|
|
*/
|
|
if (configuration.noproxyAddresses != null)
|
|
{
|
|
command.Append("\"");
|
|
command.Append(string.Join(",", configuration.noproxyAddresses));
|
|
command.Append("\"");
|
|
}
|
|
}
|
|
|
|
return command.ToString();
|
|
}
|
|
|
|
|
|
//SSH command generator for Network setting
|
|
private string GenerateSshNetworkCommand(GatewayNetworkConfiguration configuration)
|
|
{
|
|
StringBuilder command = new StringBuilder(SSH_SET_NETWORK_COMMAND);
|
|
|
|
if (configuration.hasDhcp)
|
|
{
|
|
command.Append("DHCP");
|
|
}
|
|
else
|
|
{
|
|
//Set IP address / Netmask
|
|
IPNetwork tempIpNetw = IPNetwork.Parse(configuration.ipAddress, configuration.netMaskAddress);
|
|
command.Append(configuration.ipAddress).Append("/").Append(tempIpNetw.Cidr).Append(" ");
|
|
|
|
if(configuration.defaultGatewayAddress != null)
|
|
command.Append(configuration.defaultGatewayAddress);
|
|
|
|
}
|
|
|
|
return command.ToString();
|
|
}
|
|
|
|
|
|
//SSH command generator for Dns setting
|
|
private string GenerateSshDnsCommand(GatewayNetworkConfiguration configuration)
|
|
{
|
|
StringBuilder command = new StringBuilder(SSH_SET_DNSIP_COMMAND);
|
|
|
|
if (configuration.dnsAddresses != null)
|
|
command.Append(string.Join(",", configuration.dnsAddresses));
|
|
|
|
return command.ToString();
|
|
}
|
|
|
|
|
|
//SSH command generator for Dns-Suffix setting
|
|
private string GenerateSshDnsSuffxCommand(GatewayNetworkConfiguration configuration)
|
|
{
|
|
StringBuilder command = new StringBuilder(SSH_SET_DNSSUFFIX_COMMAND);
|
|
|
|
if(configuration.dnsPrefixes != null)
|
|
command.Append(string.Join(",", configuration.dnsPrefixes));
|
|
|
|
return command.ToString();
|
|
}
|
|
|
|
#endregion
|
|
|
|
//---------------------------------------------------------------------------------------------------
|
|
#region elaborate_SSH_values_sub_methods
|
|
|
|
private GatewayNetworkConfiguration ElaborateConfigFromSshNetworkCommand(List<string> lines)
|
|
{
|
|
GatewayNetworkConfiguration configuration = new GatewayNetworkConfiguration();
|
|
foreach (string line in lines)
|
|
{
|
|
if (line.StartsWith(IP_ADDR_LABEL))
|
|
DecodeNetworkIPAddress(line.Remove(0, IP_ADDR_LABEL.Length).Trim(), ref configuration);
|
|
else if (line.StartsWith(GATEWAY_LABEL))
|
|
DecodeNetworkDefGateway(line.Remove(0, GATEWAY_LABEL.Length).Trim(), ref configuration);
|
|
else if (line.StartsWith(DNSIP_LABEL))
|
|
DecodeNetworkDnsIp(line.Remove(0, DNSIP_LABEL.Length).Trim(), ref configuration);
|
|
else if (line.StartsWith(DNSPREFIX_LABEL))
|
|
DecodeNetworkDnsPrefix(line.Remove(0, DNSPREFIX_LABEL.Length).Trim(), ref configuration);
|
|
}
|
|
return configuration;
|
|
}
|
|
|
|
private GatewayProxyConfiguration ElaborateConfigFromSshProxyCommand(List<string> lines)
|
|
{
|
|
GatewayProxyConfiguration configuration = new GatewayProxyConfiguration();
|
|
foreach (string line in lines)
|
|
{
|
|
if (line.StartsWith(PROXY_ADDR_LABEL))
|
|
DecodeProxyAddress(line.Remove(0, PROXY_ADDR_LABEL.Length).Trim(), ref configuration);
|
|
else if (line.StartsWith(NO_PROXY_LABEL))
|
|
DecodeNoProxyUrls(line.Remove(0, NO_PROXY_LABEL.Length).Trim(), ref configuration);
|
|
}
|
|
return configuration;
|
|
}
|
|
|
|
private GatewayConnectionStatus ElaborateTestConnectionCommand(List<string> lines)
|
|
{
|
|
GatewayConnectionStatus status = new GatewayConnectionStatus();
|
|
foreach (string line in lines)
|
|
{
|
|
if (!String.IsNullOrWhiteSpace(line))
|
|
DecodeConnectionStatus(line.Trim(), ref status);
|
|
}
|
|
return status;
|
|
}
|
|
|
|
#endregion
|
|
|
|
//---------------------------------------------------------------------------------------------------
|
|
#region decode_SSH_values_sub_methods
|
|
|
|
private void DecodeNetworkIPAddress(string stringValue, ref GatewayNetworkConfiguration configuration)
|
|
{
|
|
//Check if has DHCP
|
|
if (stringValue == "DHCP")
|
|
configuration.hasDhcp = true;
|
|
else
|
|
{
|
|
configuration.hasDhcp = false;
|
|
|
|
//Check if has / for netmask
|
|
if (!stringValue.Contains('/'))
|
|
throw new GatewayException("Internal Gateway Error during read (bad format): " + IP_ADDR_LABEL + stringValue);
|
|
|
|
string [] tempAddr = stringValue.Split('/');
|
|
//Check if has lenght == 2
|
|
if (tempAddr.Length != 2)
|
|
throw new GatewayException("Internal Gateway Error during read (bad format): " + IP_ADDR_LABEL + stringValue);
|
|
|
|
|
|
//Set the IPAddress / Netmask
|
|
IPAddress tempIp;
|
|
if (!EvaluateIPV4(tempAddr[0], out tempIp))
|
|
throw new GatewayException("Internal Gateway Error during read (bad format): " + IP_ADDR_LABEL + stringValue);
|
|
|
|
IPNetwork tempIpNetw;
|
|
if (!IPNetwork.TryParse(stringValue, out tempIpNetw))
|
|
throw new GatewayException("Internal Gateway Error during read (bad format): " + IP_ADDR_LABEL + stringValue);
|
|
|
|
|
|
configuration.ipAddress = tempIp;
|
|
configuration.netMaskAddress = tempIpNetw.Netmask;
|
|
}
|
|
}
|
|
|
|
|
|
private void DecodeNetworkDefGateway(string stringValue, ref GatewayNetworkConfiguration configuration)
|
|
{
|
|
//check if is defined
|
|
if (stringValue == UNDEF_VALUE)
|
|
configuration.defaultGatewayAddress = null;
|
|
else
|
|
{
|
|
IPAddress tempIp;
|
|
if (!EvaluateIPV4(stringValue, out tempIp))
|
|
throw new GatewayException("Internal Gateway Error during read (bad format): " + GATEWAY_LABEL + stringValue);
|
|
configuration.defaultGatewayAddress = tempIp;
|
|
}
|
|
}
|
|
|
|
|
|
private void DecodeNetworkDnsIp(string stringValue, ref GatewayNetworkConfiguration configuration)
|
|
{
|
|
//check if is defined
|
|
if (stringValue == UNDEF_VALUE)
|
|
configuration.dnsAddresses = null;
|
|
else
|
|
{
|
|
string[] tempStr = stringValue.Split(' ');
|
|
if (tempStr.Length == 0)
|
|
configuration.dnsAddresses = null;
|
|
else
|
|
{
|
|
IPAddress tempIp;
|
|
List<IPAddress> tempDns = new List<IPAddress>();
|
|
foreach (string str in tempStr)
|
|
{
|
|
if (string.IsNullOrEmpty(str))
|
|
continue;
|
|
if (!EvaluateIPV4(str, out tempIp))
|
|
throw new GatewayException("Internal Gateway Error during read (bad format): " + DNSIP_LABEL + stringValue);
|
|
tempDns.Add(tempIp);
|
|
}
|
|
configuration.dnsAddresses = tempDns;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
private void DecodeNetworkDnsPrefix(string stringValue, ref GatewayNetworkConfiguration configuration)
|
|
{
|
|
//check if is defined
|
|
if (stringValue == UNDEF_VALUE)
|
|
configuration.dnsPrefixes = null;
|
|
else
|
|
{
|
|
string[] tempStr = stringValue.Split(' ');
|
|
if (tempStr.Length == 0)
|
|
configuration.dnsPrefixes = null;
|
|
else
|
|
configuration.dnsPrefixes = tempStr.Where(X=> !String.IsNullOrEmpty(X)).ToList();
|
|
}
|
|
}
|
|
|
|
|
|
private void DecodeProxyAddress(string stringValue, ref GatewayProxyConfiguration configuration)
|
|
{
|
|
//check if is defined
|
|
if (stringValue == UNDEF_VALUE)
|
|
configuration.hasProxy = false;
|
|
else
|
|
{
|
|
configuration.hasProxy = true;
|
|
|
|
/* Must be one of these:
|
|
* - Address:Port
|
|
* - User:Password@Address:Port
|
|
*/
|
|
if (!stringValue.Contains("@"))
|
|
{
|
|
//Set username & password
|
|
configuration.username = null;
|
|
configuration.password = null;
|
|
|
|
//Check if has :
|
|
if (!stringValue.Contains(':'))
|
|
throw new GatewayException("Internal Gateway Error during read (bad format): " + PROXY_ADDR_LABEL + stringValue);
|
|
string[] tempAddr = stringValue.Split(':');
|
|
|
|
//Check if has lenght == 2
|
|
if (tempAddr.Length != 2)
|
|
throw new GatewayException("Internal Gateway Error during read (bad format): " + PROXY_ADDR_LABEL + stringValue);
|
|
|
|
//Set the address
|
|
configuration.address = tempAddr[0];
|
|
|
|
//Set the port
|
|
UInt32 tempPort;
|
|
if (!UInt32.TryParse(tempAddr[1], out tempPort))
|
|
throw new GatewayException("Internal Gateway Error during read (bad format): " + PROXY_ADDR_LABEL + stringValue);
|
|
configuration.port = tempPort;
|
|
|
|
}
|
|
else
|
|
{
|
|
string[] splitted = stringValue.Split('@');
|
|
|
|
//Check if has lenght == 2
|
|
if (splitted.Length != 2)
|
|
throw new GatewayException("Internal Gateway Error during read (bad format): " + PROXY_ADDR_LABEL + stringValue);
|
|
|
|
//Check if has :
|
|
if (!splitted[0].Contains(':'))
|
|
throw new GatewayException("Internal Gateway Error during read (bad format): " + PROXY_ADDR_LABEL + stringValue);
|
|
if (!splitted[1].Contains(':'))
|
|
throw new GatewayException("Internal Gateway Error during read (bad format): " + PROXY_ADDR_LABEL + stringValue);
|
|
|
|
string[] tempLogin = splitted[0].Split(':');
|
|
string[] tempAddr = splitted[1].Split(':');
|
|
|
|
//Check if has lenght == 2
|
|
if (tempLogin.Length != 2)
|
|
throw new GatewayException("Internal Gateway Error during read (bad format): " + PROXY_ADDR_LABEL + stringValue);
|
|
if (tempAddr.Length != 2)
|
|
throw new GatewayException("Internal Gateway Error during read (bad format): " + PROXY_ADDR_LABEL + stringValue);
|
|
|
|
//Set the username
|
|
configuration.username = tempLogin[0];
|
|
//Set the password
|
|
configuration.password = tempLogin[1];
|
|
//Set the address
|
|
configuration.address = tempAddr[0];
|
|
|
|
//Set the port
|
|
UInt32 tempPort;
|
|
if (!UInt32.TryParse(tempAddr[1], out tempPort))
|
|
throw new GatewayException("Internal Gateway Error during read (bad format): " + PROXY_ADDR_LABEL + stringValue);
|
|
configuration.port = tempPort;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
private void DecodeNoProxyUrls(string stringValue, ref GatewayProxyConfiguration configuration)
|
|
{
|
|
//check if is defined
|
|
if (stringValue == UNDEF_VALUE)
|
|
configuration.noproxyAddresses = null;
|
|
else
|
|
{
|
|
string[] tempStr = stringValue.Trim('"').Split(',');
|
|
|
|
for (int i=0;i<tempStr.Length;i++)
|
|
tempStr[i] = tempStr[i].Trim();
|
|
|
|
if (tempStr.Length == 0)
|
|
configuration.noproxyAddresses = null;
|
|
else
|
|
configuration.noproxyAddresses = tempStr.ToList();
|
|
}
|
|
}
|
|
|
|
|
|
private void DecodeConnectionStatus(string stringValue, ref GatewayConnectionStatus status)
|
|
{
|
|
if (stringValue == CONNECTION_OK_VALUE)
|
|
status = GatewayConnectionStatus.OK;
|
|
else if (stringValue == CONNECTION_NOWEB_VALUE)
|
|
status = GatewayConnectionStatus.WEB_ERROR;
|
|
else if (stringValue == CONNECTION_NOPORT_VALUE)
|
|
status = GatewayConnectionStatus.PORT_ERROR;
|
|
else
|
|
throw new GatewayException("Internal Gateway Error during Connection-Test (bad format): " + stringValue);
|
|
}
|
|
|
|
|
|
private bool EvaluateIPV4(string stringValue,out IPAddress address)
|
|
{
|
|
Regex rgx = new Regex(@"^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$");
|
|
|
|
if (rgx.IsMatch(stringValue))
|
|
{
|
|
IPAddress.TryParse(stringValue, out address);
|
|
return true;
|
|
}
|
|
|
|
address = new IPAddress(0);
|
|
return false;
|
|
}
|
|
#endregion
|
|
|
|
//---------------------------------------------------------------------------------------------------
|
|
#region ssh_sub_methods
|
|
|
|
//Override sendCommand for single command
|
|
private List<string> SendSSHCommand(string command)
|
|
{
|
|
return SendSSHCommand(new List<string> {command});
|
|
}
|
|
|
|
|
|
//Send multiple SSH Command
|
|
private List<string> SendSSHCommand(IEnumerable<string> command)
|
|
{
|
|
SshCommand sshCmd;
|
|
List<string> returnedValues = new List<string>();
|
|
|
|
//Create the SSH Gateway
|
|
SshClient _sshGateway = new SshClient(this.host, this.username, this.password);
|
|
try
|
|
{
|
|
//Connect
|
|
_sshGateway.Connect();
|
|
foreach(string cmd in command)
|
|
{
|
|
//Run command
|
|
sshCmd = _sshGateway.RunCommand(cmd);
|
|
|
|
//Add return values if esists
|
|
returnedValues.AddRange(sshCmd.Result.Split(new[] { "\n" }, StringSplitOptions.None));
|
|
|
|
//Check for errors
|
|
if (sshCmd.ExitStatus != 0)
|
|
{
|
|
_sshGateway.Disconnect();
|
|
throw new GatewayException("Internal Gateway Error: " + sshCmd.Error);
|
|
}
|
|
}
|
|
|
|
//Disconnect
|
|
_sshGateway.Disconnect();
|
|
}
|
|
catch (SocketException e)
|
|
{
|
|
throw new GatewayException("Connection Error: - Host:" + this.host);
|
|
}
|
|
catch (SshConnectionException e)
|
|
{
|
|
throw new GatewayException("Connection Error: - Host:" + this.host);
|
|
}
|
|
catch (ProxyException e)
|
|
{
|
|
throw new GatewayException("Proxy Error: - Host:" + this.host);
|
|
}
|
|
catch (SshAuthenticationException e)
|
|
{
|
|
throw new GatewayException("Authentication Error: - Host:" + this.host);
|
|
}
|
|
catch (SshException e)
|
|
{
|
|
throw new GatewayException("Internal command Error: - Host:" + this.host);
|
|
}
|
|
catch (GatewayException e)
|
|
{
|
|
throw new GatewayException(e.Message);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
throw new GatewayException("Unknown Error: " + e);
|
|
}
|
|
|
|
return returnedValues;
|
|
}
|
|
|
|
|
|
//Send REBOOT Command
|
|
private void SendSSHReboot(int seconds)
|
|
{
|
|
//Send SSH Command
|
|
SendSSHCommand(SSH_GW_REBOOT_COMMAND + seconds);
|
|
|
|
//Wait the time for reboot
|
|
Thread.Sleep((seconds + 5) * 1000);
|
|
|
|
//Save actual timestamp
|
|
DateTime nowAfterReboot = DateTime.Now;
|
|
|
|
//Create the Instance
|
|
SshClient _sshGateway = new SshClient(this.host, this.username, this.password);
|
|
|
|
//Phase 1 Wait Disconnection Cycle
|
|
bool disconnected = false;
|
|
do
|
|
{
|
|
try
|
|
{
|
|
//If TimeSpan > TOT MIN -> Exception
|
|
if ((DateTime.Now - nowAfterReboot) > TimeSpan.FromMinutes(REBOOT_MINUTES_MAX))
|
|
throw new GatewayException("Timeout Error during reboot - Gateway has never been rebooted");
|
|
|
|
//Try Connection
|
|
_sshGateway.Connect();
|
|
Thread.Sleep(REBOOT_MSWAIT_BETWEEN_OP);
|
|
_sshGateway.Disconnect();
|
|
}
|
|
catch (SocketException e)
|
|
{
|
|
//Not Connected
|
|
disconnected = true;
|
|
}
|
|
catch (SshConnectionException e)
|
|
{
|
|
//Not Connected
|
|
disconnected = true;
|
|
}
|
|
catch (SshException e)
|
|
{
|
|
//Not Connected
|
|
disconnected = true;
|
|
}
|
|
catch (GatewayException e)
|
|
{
|
|
//Error
|
|
throw new GatewayException(e.Message);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
//Error
|
|
throw new GatewayException("Unknown Error during reboot: " + e);
|
|
}
|
|
} while (!disconnected);
|
|
|
|
|
|
//Phase 2 Wait Re-connection Cycle
|
|
bool connected = false;
|
|
do
|
|
{
|
|
try
|
|
{
|
|
//If TimeSpan > TOT MIN -> Exception
|
|
if((DateTime.Now - nowAfterReboot) > TimeSpan.FromMinutes(REBOOT_MINUTES_MAX))
|
|
throw new GatewayException("Timeout Error during reboot - Gateway not found during reboot");
|
|
|
|
//Try Connection
|
|
_sshGateway.Connect();
|
|
connected = true;
|
|
}
|
|
catch (SocketException e)
|
|
{
|
|
//Not Connected
|
|
Thread.Sleep(REBOOT_MSWAIT_BETWEEN_OP);
|
|
}
|
|
catch (SshConnectionException e)
|
|
{
|
|
//Not Connected
|
|
Thread.Sleep(REBOOT_MSWAIT_BETWEEN_OP);
|
|
}
|
|
catch (SshException e)
|
|
{
|
|
//Not Connected
|
|
Thread.Sleep(REBOOT_MSWAIT_BETWEEN_OP);
|
|
}
|
|
catch (GatewayException e)
|
|
{
|
|
//Error
|
|
throw new GatewayException(e.Message);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
//Error
|
|
throw new GatewayException("Unknown Error during reboot: " + e);
|
|
}
|
|
} while (!connected);
|
|
|
|
_sshGateway.Disconnect();
|
|
}
|
|
|
|
#endregion
|
|
|
|
}
|
|
}
|