paybackman 961f31ef64 Initial Code Import
Change-Id: Ic5be6fe4e739c01656160ee8a8070ab08aef448f
2014-04-07 15:48:17 -05:00

317 lines
14 KiB
C#

/* ============================================================================
Copyright 2014 Hewlett Packard
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.
============================================================================ */
using System.Management.Automation;
using Openstack.Client.Powershell.Cmdlets.Common;
using Openstack.Objects.Domain.Compute;
using Openstack.Objects.DataAccess.Compute;
using Openstack.Objects.DataAccess.Security;
using Openstack.Client.Powershell.Providers.Common;
using Openstack.Client.Powershell.Providers.Security;
using Openstack.Objects.Domain.Compute.Servers.Actions;
using Openstack.Objects.Domain.Compute.Servers;
using System;
using System.IO;
using System.Xml.Linq;
using System.Xml.XPath;
using Openstack.Client.Powershell.Providers.Compute;
namespace Openstack.Client.Powershell.Cmdlets.Compute.Server
{
[Cmdlet("Connect", "Server", SupportsShouldProcess = true)]
public class ConnectServerCmdletd : BasePSCmdlet
{
private string _serverId;
private string _keypairName = null;
#region Parameters
//=========================================================================================
/// <summary>
///
/// </summary>
//=========================================================================================
[Parameter(Position = 0, ParameterSetName = "ConnectServerPS", Mandatory = false, ValueFromPipelineByPropertyName = true, HelpMessage = "The Id of the Server.")]
[Alias("s")]
public string ServerId
{
get
{
if (_serverId != null)
return _serverId;
else
{
BaseUIContainer currentContainer = this.SessionState.PSVariable.Get("CurrentContainer").Value as BaseUIContainer;
ServerUIContainer serverContainer = currentContainer as ServerUIContainer;
if (serverContainer != null) {
return serverContainer.Entity.Id;
}
}
return null;
}
set { _serverId = value; }
}
#endregion
#region Methods
//=========================================================================================
/// <summary>
///
/// </summary>
/// <returns></returns>
//=========================================================================================
private bool IsWindowsImage(string imageId)
{
Image image = this.RepositoryFactory.CreateImageRepository().GetImage(imageId);
return image.IsWindowsImage;
}
//=========================================================================================
/// <summary>
///
/// </summary>
/// <returns></returns>
//=========================================================================================
private string GetAdminPassword(string keyname)
{
GetServerLogAction action = new GetServerLogAction();
action.ServerId = this.ServerId;
Log log = this.RepositoryFactory.CreateServerRepository().GetServerLog(action);
if (log != null)
{
Console.WriteLine("");
string pw = log.ExtractAdminPassword(this.Settings.KeyStoragePath + keyname + ".pem");
Console.WriteLine("Administrator Password : " + pw);
return pw;
}
else
return null;
}
//=========================================================================================
/// <summary>
///
/// </summary>
//=========================================================================================
private void ShowCredentialsNotFoundMsg()
{
Console.WriteLine("");
Console.WriteLine("Credentials not found. You'll have to manually enter your Administrator credentials for this instance.");
Console.WriteLine("If you want to continue to use Automatic Credential Tracking for this instance make sure that you update");
Console.WriteLine("our records with the new password. To do this, use the Reset-Password cmdlet.");
Console.WriteLine("");
}
//=========================================================================================
/// <summary>
///
/// </summary>
/// <param name="message"></param>
//=========================================================================================
private void WriteSection(string headerText)
{
ConsoleColor oldColor = Console.ForegroundColor;
Console.WriteLine(" ");
Console.ForegroundColor = ConsoleColor.DarkGray;
Console.WriteLine("==============================================================================================================================================");
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine(headerText);
Console.ForegroundColor = ConsoleColor.DarkGray;
Console.WriteLine("==============================================================================================================================================");
Console.ForegroundColor = oldColor;
}
//=========================================================================================
/// <summary>
///
/// </summary>
//===================================================================================K=====
private void ShowKeyBasedLoginInstructions(string keyname)
{
if (keyname == null) keyname = "YourKeyfile";
this.WriteSection("Unable to find a suitable Putty key file!");
Console.WriteLine("1. Make sure that you have downloaded the latest version of Putty and PuttyGen for Windows.");
Console.WriteLine("2. Tell us where Putty.exe exist by setting the Config file entry SSHClientPath (use Set-Config)");
Console.WriteLine("3. Tell PuttyGen to Load an existing key file. This file will be located at " + this.Settings.KeyStoragePath + @"\OS\" + keyname + ".pem");
Console.WriteLine("4. Convert the .pem file to the .ppk format that Putty.exe understands by clicking the Save Private Key button.");
Console.WriteLine("5. Save the .ppk file as " + keyname + ".ppk");
Console.WriteLine("6. Launch the SSH session with the Connect-Server cmdlet");
Console.WriteLine("7. HINT : If you use the same keypair name for each Server you create you can skip steps 1-5 after the steps have been completed once.");
Console.WriteLine("");
}
//=========================================================================================
/// <summary>
///
/// </summary>
//=========================================================================================
private bool LaunchPasswordBasedSSHSession(Openstack.Objects.Domain.Compute.Server server)
{
CredentialListManager manager = new CredentialListManager(this.Settings);
SSHClient sshClient = new SSHClient(this.Settings);
sshClient.Username = "ubuntu";
sshClient.Address = server.Addresses.Private[1].Addr;
sshClient.Password = manager.GetPassword(server.Id);
if (sshClient.Password == null) {
return false;
}
else {
sshClient.LaunchClient();
return true;
}
}
//=========================================================================================
/// <summary>
///
/// </summary>
//=========================================================================================
private bool IsSSHClientConfigured()
{
if (this.Settings.SSHClientPath == string.Empty)
return false;
else
return File.Exists(this.Settings.SSHClientPath);
}
//=========================================================================================
/// <summary>
///
/// </summary>
//=========================================================================================
private bool DoesPPKExist(string keyName)
{
return File.Exists(this.Settings.KeyStoragePath + @"\OS\" + keyName + ".ppk");
}
//=========================================================================================
/// <summary>
///
/// </summary>
//=========================================================================================
private void SaveSSHClientLocation(string path)
{
string configFilePath = this.ConfigFilePath;
XDocument doc = XDocument.Load(configFilePath);
XElement clientPathNode = doc.XPathSelectElement("//add[@key='SSHClientPath']");
clientPathNode.SetAttributeValue("value", path);
doc.Save(configFilePath);
this.Settings.SSHClientPath = path;
}
//=========================================================================================
/// <summary>
///
/// </summary>
//=========================================================================================
private void ConfigureSSHClient()
{
Console.WriteLine("");
Console.WriteLine("You're trying to establish a remote session with a non-Windows based server. This requires a fully qualified path to the SSH client (putty.exe)");
Console.Write("SSH Client Path : ");
string path = Console.ReadLine();
if (File.Exists(path))
{
Console.WriteLine("");
Console.WriteLine("Putty.exe found! Saving location for future sessions..");
Console.WriteLine("");
this.SaveSSHClientLocation(path);
}
else
{
Console.WriteLine("");
Console.WriteLine("Putty.exe not found! Invalid path supplied.");
Console.WriteLine("");
}
}
//=========================================================================================
/// <summary>
///
/// </summary>
//=========================================================================================
private void LaunchSSHSession(Openstack.Objects.Domain.Compute.Server server)
{
if (!IsSSHClientConfigured()) {
this.ConfigureSSHClient();
}
if (server.KeyName != null && this.DoesPPKExist(server.KeyName))
{
SSHClient sshClient = new SSHClient(this.Settings);
sshClient.Username = "ubuntu";
sshClient.KeypairName = server.KeyName;
sshClient.Address = server.Addresses.Private[1].Addr;
sshClient.LaunchClient();
}
else
{
this.ShowKeyBasedLoginInstructions(server.KeyName);
}
}
//=========================================================================================
/// <summary>
///
/// </summary>
//=========================================================================================
private void LaunchWindowsSession(Openstack.Objects.Domain.Compute.Server server)
{
CredentialListManager manager = new CredentialListManager(this.Settings);
RDPClient client = new RDPClient();
client.Address = server.Addresses.Private[1].Addr;
client.Username = "Administrator";
if (this.Settings.EnableCredentialTracking == true)
{
client.Password = manager.GetPassword(server.Id);
if (client.Password == null)
{
this.ShowCredentialsNotFoundMsg();
return;
}
}
client.LaunchClient();
}
//=========================================================================================
/// <summary>
///
/// </summary>
//=========================================================================================
protected override void ProcessRecord()
{
string id = this.TranslateQuickPickNumber(this.ServerId);
if (id != null)
{
Openstack.Objects.Domain.Compute.Server server = this.RepositoryFactory.CreateServerRepository().GetServer(id);
if (server != null)
{
if (IsWindowsImage(server.Image.Id))
{
this.LaunchWindowsSession(server);
}
else
{
this.LaunchSSHSession(server);
}
}
else
{
Console.WriteLine("");
Console.WriteLine("Server not found.");
Console.WriteLine("");
}
}
}
#endregion
}
}