//* ============================================================================ //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.Reflection; using System.Security.Policy; using OpenStack.Client.Powershell.Utility; using System.Linq; using OpenStack.Identity; using System.Threading; using Openstack.Client.Powershell.Utility; namespace OpenStack.Client.Powershell.Utility { public class ExtensionManager { private SessionState _session; private Context _context; #region Properties public Context Context { get { return _context; } set { _context = value; } } public SessionState Session { get { return _session; } set { _session = value; } } #endregion //================================================================================================== /// <summary> /// /// </summary> /// <param name="session"></param> /// <param name="context"></param> //================================================================================================== public ExtensionManager(SessionState session, Context context) { _session = session; _context = context; } //================================================================================================== /// <summary> /// /// </summary> /// <param name="provider"></param> /// <returns></returns> //================================================================================================== private Settings GetSettings(ServiceProvider provider) { if (provider.ConfigFilePath == null) { Settings.Default.Reset(); return Settings.Default; } else { return Settings.LoadConfig(provider.ConfigFilePath); } } //================================================================================================== /// <summary> /// /// </summary> /// <param name="credential"></param> /// <param name="context"></param> /// <param name="client"></param> //================================================================================================== private void SetSessionState(IOpenStackCredential credential, IOpenStackClient client, ServiceProvider provider) { // Setup the environment based on what came back from Auth.. Context context = new Context(); context.ServiceCatalog = credential.ServiceCatalog; context.Settings = this.GetSettings(provider); context.ProductName = "OpenStack-WinCLI"; context.Version = Assembly.GetExecutingAssembly().GetName().Version.ToString(); context.CurrentServiceProvider = provider; context.CurrentRegion = provider.AvailabilityZones.Where(z => z.IsDefault == true).Single().Name; this.Session.PSVariable.Set(new PSVariable("Context", context)); this.Session.PSVariable.Set(new PSVariable("CoreClient", client)); } //================================================================================================== /// <summary> /// /// </summary> //================================================================================================== private RegistrationManager GetRegistrationManager(string serviceProviderName) { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); // Iterate through all Assemblies in Current AppDomain that contain a RegistrationManager class.. foreach (Assembly assembly in assemblies) { Type[] types = assembly.GetTypes().Where(b => b != null && b.BaseType != null && b.BaseType.UnderlyingSystemType.FullName == "OpenStack.Client.Powershell.Utility.RegistrationManager").ToArray<Type>(); // Now that we found one, make sure that it's the one we're looking for.. foreach (Type type in types) { MemberInfo info = type; foreach (object attribute in info.GetCustomAttributes(true)) { ServiceProviderAttribute identifier = attribute as ServiceProviderAttribute; if (identifier != null && identifier.Name == serviceProviderName) { var result = (RegistrationManager)Activator.CreateInstance(type, null); if (result == null) { throw new NullReferenceException("Could not create a valid RegistrationManager instance for " + type.FullName); } else return result; } } } } return new OpenstackCoreRegistrationManager(); } //================================================================================================== /// <summary> /// /// </summary> /// <returns></returns> //================================================================================================== public void LoadCore(ServiceProvider provider) { OpenstackCoreRegistrationManager manager = new OpenstackCoreRegistrationManager(); RegistrationResponse response = manager.Register(provider); // Setup our shared Cancellation Token Source so that Cmdlets \ Users can abort long running operations.. CancellationTokenSource source = new CancellationTokenSource(); CancellationToken token = source.Token; this.Session.PSVariable.Set(new PSVariable("CancellationTokenSource", source)); // Connect to the Service Provider.. var client = OpenStackClientFactory.CreateClient<OpenStackClient>(response.Credentials, token, String.Empty); var connectTask = client.Connect(); connectTask.Wait(); this.SetSessionState(response.Credentials, client, provider); ConfigurationManager configManager = new ConfigurationManager(); configManager.WriteServiceProvider(response.Provider, true); } //================================================================================================== /// <summary> /// /// </summary> //================================================================================================== public void LoadExtension(ServiceProvider targetProvider) { string moduleName = targetProvider.Name; AppDomain currentDomain = AppDomain.CurrentDomain; Evidence asEvidence = currentDomain.Evidence; IOpenStackClient client = null; IOpenStackCredential credential = null; // Load up the default config file.. ConfigurationManager configManager = new ConfigurationManager(); configManager.Load(false); // Load the specified module into the Current AppDomain... this.Session.InvokeCommand.InvokeScript("Import-Module " + moduleName + " -DisableNameChecking"); // Register the Module if it isn't already and grab the resulting credentials for Auth.. RegistrationManager manager = this.GetRegistrationManager(moduleName); RegistrationResponse response = manager.Register(configManager.GetServiceProvider(moduleName)); credential = response.Credentials; // Setup our shared Cancellation Token Source so that Cmdlets \ Users can abort long running operations.. CancellationTokenSource source = new CancellationTokenSource(); CancellationToken token = source.Token; this.Session.PSVariable.Set(new PSVariable("CancellationTokenSource", source)); // Authenticate and create our Extension Client and stash it.... client = OpenStackClientFactory.CreateClient<OpenStackClient>(credential, token, String.Empty); var connectTask = client.Connect(); connectTask.Wait(); // Save the credentials if there are any changes (The RegistrationManager may have prompted for missing Credentials) configManager.WriteServiceProvider(response.Provider); // Store Context and Client so that all PS-Providers and Cmdlets have access to it.. this.SetSessionState(credential, client, targetProvider); } } }