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

607 lines
25 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;
using System.Management.Automation;
using System.Management.Automation.Provider;
using System.Collections.ObjectModel;
using System.IO;
using Openstack.Administration.Domain;
using Openstack.Client.Powershell.Providers.Common;
using Openstack.Objects.Domain.Compute;
using System.Diagnostics.Contracts;
using System.Linq;
using Openstack.Objects.Domain;
using System.Management.Automation.Runspaces;
namespace Openstack.Client.Powershell.Providers.Security
{
public enum ContainerAxis
{
Ancestor = 0,
Descendant = 1,
Neutral = 3,
Root = 4,
NotFound = 5
}
[CmdletProvider("OS-Cloud", ProviderCapabilities.None)]
public class CommonServiceProvider : BaseNavigationCmdletProvider
{
#region Provider LifeCycle Support
//==================================================================================================
/// <summary>
///
/// </summary>
/// <returns></returns>
//==================================================================================================
protected override System.Collections.ObjectModel.Collection<PSDriveInfo> InitializeDefaultDrives()
{
this.InitializeSession();
// Check to see if this provider is in the list of returned Services in the Catalog (indicating access is granted)
PSDriveInfo driveInfo = new PSDriveInfo("OpenStack", this.ProviderInfo, "/", "Openstack Services Provider", null);
Collection<PSDriveInfo> drives = new Collection<PSDriveInfo>();
drives.Add(driveInfo);
return drives;
}
//==================================================================================================
/// <summary>
///
/// </summary>
/// <param name="providerInfo"></param>
/// <returns></returns>
//==================================================================================================
protected override ProviderInfo Start(ProviderInfo providerInfo)
{
return base.Start(providerInfo);
}
//==================================================================================================
/// <summary>
///
/// </summary>
/// <param name="drive"></param>
/// <returns></returns>
//==================================================================================================
protected override PSDriveInfo NewDrive(PSDriveInfo drive)
{
WriteDebug("Enter : CloudServiceProvider.NewDrive");
if (drive == null)
{
WriteError(new ErrorRecord(new ArgumentNullException("drive"), "NullDrive", ErrorCategory.InvalidArgument, drive));
return null;
}
if (drive.Root == null)
{
WriteError(new ErrorRecord(new ArgumentNullException("drive.Root"), "NullRoot", ErrorCategory.InvalidArgument, drive));
return null;
}
if (drive is CommonDriveInfo)
{
return drive;
}
var driveParams = this.DynamicParameters as CommonDriveParameters;
WriteDebug("Exit : CloudServiceProvider.NewDrive");
return new CommonDriveInfo(drive, driveParams);
}
//==================================================================================================
/// <summary>
///
/// </summary>
/// <returns></returns>
//==================================================================================================
protected override object NewDriveDynamicParameters()
{
return new CommonDriveParameters();
}
#endregion
#region Basic Operations (LS, CD xxx, CD.. etc)
//==================================================================================================
/// <summary>
///
/// </summary>
/// <param name="path"></param>
/// <param name="recurse"></param>
//==================================================================================================
protected override void GetChildItems(string path, bool recurse)
{
WriteContainer(this.Drive.CurrentContainer);
}
//==================================================================================================
/// <summary>
///
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
//==================================================================================================
private bool IsParentPath(string path)
{
if (Path.GetFileNameWithoutExtension(path) == Path.GetFileNameWithoutExtension(this.Drive.CurrentContainer.Parent.Path))
return true;
else
return false;
}
//==================================================================================================
/// <summary>
///
/// </summary>
/// <returns></returns>
//==================================================================================================
private void SetRoot()
{
string defaultTenantId = "TENANTAC1001";
BaseUIContainer root = new AccountUIContainer(null, "Account", "The Users assigned Account", @"\\", this.Context, this.RepositoryFactory);
Account fake = new Account();
fake.Name = "TestAccount";
fake.Id = defaultTenantId;
root.Entity = fake;
CurrentAccountUIContainer.CurrentAccount = (AccountUIContainer)root;
this.Drive.CurrentContainer = root;
}
//==================================================================================================
/// <summary>
///
/// </summary>
/// <param name="lastPathEntry"></param>
/// <returns></returns>
//==================================================================================================
private bool IsMovingToContainer(string lastPathEntry)
{
bool isMovingToContainer = false;
if (this.Drive.CurrentContainer.Name == lastPathEntry) isMovingToContainer = true;
foreach (BaseUIContainer container in this.Drive.CurrentContainer.Containers)
{
if (container.Id == lastPathEntry) isMovingToContainer = true;
}
return isMovingToContainer;
}
//==================================================================================================
/// <summary>
///
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
//==================================================================================================
private ContainerAxis CheckContainerAxis(string path)
{
// Do our Root and Neutrality Checks (by Neutral I mean the User has issued LS on the same entity so no movement along the axis).
if (path == "\\") return ContainerAxis.Root;
string lastPathEntry = Path.GetFileNameWithoutExtension(path);
// See if the User is moving back up to the Parent node of the Current Container.
if ((this.Drive.CurrentContainer != null && this.Drive.CurrentContainer.Parent != null && lastPathEntry == this.Drive.CurrentContainer.Parent.Id)) return ContainerAxis.Ancestor;
if (this.IsNamedAncestor(path)) return ContainerAxis.Ancestor;
// Before we get started verifying the decendant move, make sure the next node is populated with something first..
if (this.Drive.CurrentContainer != null && this.Drive.CurrentContainer.Containers.Count == 0)
this.Drive.CurrentContainer.Load();
// Finally see if the User is moving downward into a decendant BaseUIContainer from the current one, if not the input supplied is invalid.
if (lastPathEntry == this.Drive.CurrentContainer.Id) return ContainerAxis.Descendant;
if (this.IsMovingToContainer(lastPathEntry)) return ContainerAxis.Descendant;
else
return ContainerAxis.NotFound;
}
//==================================================================================================
/// <summary>
///
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
//==================================================================================================
private bool IsNamedAncestor(string path)
{
string lastPathEntry = Path.GetFileNameWithoutExtension(path);
if (Path.GetFileNameWithoutExtension(path).StartsWith("-") || path == "\\")
{
return false;
}
else if (this.Drive.CurrentContainer.Parent != null && this.Drive.CurrentContainer.Parent.Name == lastPathEntry)
{
return true;
}
else
{
return false;
}
}
//==================================================================================================
/// <summary>
///
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
//==================================================================================================
private string TranslateQuickPickNumber(string path)
{
BaseUIContainer result = null;
int number = 0;
if (Int32.TryParse(Path.GetFileName(path), out number))
{
if (path == "\\" + this.Drive.CurrentLocation)
{
return path.Replace(Path.GetFileName(path), this.Drive.CurrentContainer.Entity.Id);
}
else if (path.Length < this.Drive.CurrentLocation.Length)
{
result = this.Drive.CurrentContainer.Parent;
}
else
{
try
{
result = this.Drive.CurrentContainer.Containers.Where(q => q.Entity.QuickPickNumber == number).FirstOrDefault<BaseUIContainer>();
}
catch (NullReferenceException ex)
{
return null;
}
}
if (result != null)
return path.Replace(Path.GetFileName(path), result.Id);
else return null;
}
else return null;
}
//==================================================================================================
/// <summary>
///
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
//==================================================================================================
private bool IsQuickPickNumber(string path)
{
int test = 0;
return Int32.TryParse(Path.GetFileName(path), out test);
}
//==================================================================================================
/// <summary>
///
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
//==================================================================================================
protected override bool IsItemContainer(string path)
{
if (this.IsQuickPickNumber(path))
{
string testPath = this.TranslateQuickPickNumber(path);
if (testPath == null && this.Drive.CurrentContainer.Entity != null)
{
path = path.Replace(Path.GetFileName(path), this.Drive.CurrentContainer.Entity.Id);
}
else {
path = testPath;
}
}
switch (this.CheckContainerAxis(path))
{
case (ContainerAxis.Ancestor):
// The User has issued "cd .." so we're moving up the Ancestor axis...
this.Drive.CurrentContainer = this.Drive.CurrentContainer.Parent;
this.SessionState.PSVariable.Set("CurrentContainer", this.Drive.CurrentContainer);
return true;
case (ContainerAxis.Descendant):
// The User has moved down the decendant axis either into a Container representing a single Entity or one that represents
// a full blown association of entities.
this.SetDescendant(path);
break;
case (ContainerAxis.Neutral):
// The User has issued LS one the same Container so no movement on the axis..
return true;
case (ContainerAxis.Root):
// The User has issued cd\ bringing them all the way back to Root..
this.SetRoot();
return true;
case (ContainerAxis.NotFound):
return false;
}
return true;
}
//==================================================================================================
/// <summary>
///
/// </summary>
//==================================================================================================
private bool SetDescendant(string path)
{
if (this.Drive.CurrentContainer != null && this.Drive.CurrentContainer.Containers != null)
{
// To clarify, we're looking for the value of the last delimited entry in the path..
string lastPathEntry = Path.GetFileNameWithoutExtension(path);
if (lastPathEntry != "" && lastPathEntry != this.Drive.CurrentContainer.Id)
{
BaseUIContainer container = null;
container = this.Drive.CurrentContainer.GetContainer(lastPathEntry);
this.SessionState.PSVariable.Set("CurrentContainer", container);
if (container != null)
{
// NAVIGATION SUCCESS : The commands value can be matched to an available association so set that node
// as the current container\position..
this.Drive.CurrentContainer = container;
this.SessionState.PSVariable.Set("CurrentContainer", container);
return true;
}
else
{
// SHOW ENTITY DETAILS : Check to see if the key supplied by the User matches any Entity that is being managed
// by the current Container. Here, the User has moved (CD) into an Entity and has issued an LS command.
if (this.Drive.CurrentContainer.Entity != null && this.Drive.CurrentContainer.IsEntityId(lastPathEntry)) return true;
// The User tried to view the details of some entity yet we havn't pulled that Entity into the Container yet.
BaseUIContainer entityContainer = this.Drive.CurrentContainer.CreateContainer(lastPathEntry);
if (entityContainer != null)
{
// The Read operation on that Entity succeeded so set that Container as current..
this.Drive.CurrentContainer = entityContainer;
this.SessionState.PSVariable.Set("CurrentContainer", container);
return true;
}
else
{
return false;
}
}
}
if (this.Drive.CurrentContainer != null)
{
return true;
}
else
{
return false;
}
}
return false;
}
//==================================================================================================
/// <summary>
///
/// </summary>
/// <param name="containers"></param>
//==================================================================================================
private void WriteDecendantContainers(BaseUIContainer container)
{
Contract.Assert(container != null);
if (container.Containers != null && container.Containers.Where(c => c.ObjectType == ObjectType.Container).Count() > 0)
{
Console.ForegroundColor = ConsoleColor.DarkGray;
WriteItemObject("==========================================================================================================", container.Path, false);
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine(container.Name + " " + "Associations");
Console.ForegroundColor = ConsoleColor.DarkGray;
WriteItemObject("==========================================================================================================", container.Path, false);
Console.ForegroundColor = (ConsoleColor)Enum.Parse(typeof(ConsoleColor), this.Context.Forecolor);
foreach (BaseUIContainer testContainer in container.Containers)
{
if (testContainer.ObjectType == ObjectType.Container)
{
WriteItemObject(testContainer, container.Path, false);
}
}
//container.Containers.ForEach(c => WriteItemObject(c, c.Path, true));
WriteItemObject("", container.Path, false);
}
}
//==================================================================================================
/// <summary>
///
/// </summary>
/// <param name="entities"></param>
//==================================================================================================
private void WriteEntities(BaseUIContainer container)
{
//if (container.Entities.Count == 0)
//container.Load();
if (container.Entities != null && container.Entities.Count > 0)
{
Console.ForegroundColor = ConsoleColor.DarkGray;
WriteItemObject("", container.Path, false);
WriteItemObject("==========================================================================================================", container.Path, false);
Console.ForegroundColor = ConsoleColor.Yellow;
WriteItemObject("The following " + container.Name + " " + "are available.", container.Path, false);
Console.ForegroundColor = ConsoleColor.DarkGray;
WriteItemObject("==========================================================================================================", container.Path, false);
WriteItemObject("", container.Path, false);
Console.ForegroundColor = (ConsoleColor)Enum.Parse(typeof(ConsoleColor), this.Context.Forecolor);
int count = 0;
foreach (object obj in container.Entities)
{
this.Host.UI.RawUI.ForegroundColor = (ConsoleColor)Enum.Parse(typeof(ConsoleColor), this.Context.Forecolor);
BaseEntity tempObj = obj as BaseEntity;
if (tempObj != null)
{
tempObj.QuickPickNumber = count;
WriteItemObject(tempObj, this.Drive.CurrentLocation, false);
}
else
{
WriteItemObject(obj, this.Drive.CurrentLocation, false);
}
++count;
}
WriteItemObject("", this.Drive.CurrentLocation, false);
WriteItemObject(Convert.ToString(count) + " " + container.Name + "(s) found", this.Drive.CurrentLocation, false);
WriteItemObject("", this.Drive.CurrentLocation, false);
}
else
{
Console.ForegroundColor = (ConsoleColor)Enum.Parse(typeof(ConsoleColor), this.Context.Forecolor);
}
}
//==================================================================================================
/// <summary>
///
/// </summary>
/// <param name="container"></param>
//==================================================================================================
private void WriteEntity(BaseUIContainer container)
{
if (container.ObjectType == ObjectType.Entity)
{
container.WriteEntityDetails();
}
}
//==================================================================================================
/// <summary>
///
/// </summary>
/// <param name="container"></param>
//==================================================================================================
private void WriteUIContainer(BaseUIContainer container)
{
container.Load();
this.WriteDecendantContainers(container);
this.WriteEntities(container);
this.WriteEntity(container);
}
//==================================================================================================
/// <summary>
///
/// </summary>
/// <param name="container"></param>
//==================================================================================================
private void WriteEntityContainer(BaseEntityUIContainer container)
{ }
//==================================================================================================
/// <summary>
///
/// </summary>
/// <param name="container"></param>
//==================================================================================================
private void WriteContainer(BaseUIContainer container)
{
this.WriteUIContainer(container);
}
//==================================================================================================
/// <summary>
///
/// </summary>
/// <param name="path"></param>
/// <param name="returnContainers"></param>
//==================================================================================================
protected override void GetChildNames(string path, ReturnContainers returnContainers)
{
WriteItemObject(path, path, true);
}
//==================================================================================================
/// <summary>
///
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
//==================================================================================================
protected override string GetChildName(string path)
{
return base.GetChildName(path);
}
//==================================================================================================
/// <summary>
///
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
//==================================================================================================
protected override bool ItemExists(string path)
{
return true;
}
//==================================================================================================
/// <summary>
/// This test should not verify the existance of the item at the path.
/// It should only perform syntactic and semantic validation of the
/// path. For instance, for the file system provider, that path should
/// be canonicalized, syntactically verified, and ensure that the path
/// does not refer to a device.
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
//==================================================================================================
protected override bool IsValidPath(string path)
{
return true;
}
#endregion
#region Properties
//==================================================================================================
/// <summary>
///
/// </summary>
//==================================================================================================
private CommonDriveInfo Drive
{
get
{
return this.PSDriveInfo as CommonDriveInfo;
}
}
#endregion
}
}