From dbf7694e91b7af18416f8c477efdedf50bc86b8b Mon Sep 17 00:00:00 2001 From: Frank Lin Date: Sat, 15 Aug 2020 07:50:37 +1000 Subject: [PATCH] Move Sashimi.Azure into Sashimi.Azure.Accounts (#96) * Merge Sashimi.Azure into Sashimi.Azure.Accounts --- .../Sashimi.Azure.Accounts.Tests.csproj | 1 + .../Web/AzureEnvironmentsListActionFixture.cs | 7 +- .../AzureAccountModule.cs | 11 +++ .../AzureServicePrincipalAccountExtensions.cs | 22 ++++- .../PropertyDictionaryExtensions.cs | 33 ++++---- .../Sashimi.Azure.Accounts.csproj | 1 + .../Web/AzureApi.cs | 2 +- .../Web/AzureEnvironmentsListAction.cs | 19 ++--- .../Web/AzureHomeLinksContributor.cs | 5 +- .../AzureServicePrincipalAccountExtensions.cs | 81 ------------------- .../OnlyExposeWhatIsNecessary.cs | 12 --- .../Sashimi.Azure.Tests.csproj | 24 ------ source/Sashimi.Azure/AzureModule.cs | 24 ------ .../Properties/InternalsVisibleTo.cs | 4 - source/Sashimi.Azure/Sashimi.Azure.csproj | 20 ----- source/Sashimi.sln | 16 ---- 16 files changed, 68 insertions(+), 214 deletions(-) rename source/{Sashimi.Azure.Tests => Sashimi.Azure.Accounts.Tests}/Web/AzureEnvironmentsListActionFixture.cs (91%) rename source/{Sashimi.Azure => Sashimi.Azure.Accounts}/Web/AzureApi.cs (93%) rename source/{Sashimi.Azure => Sashimi.Azure.Accounts}/Web/AzureEnvironmentsListAction.cs (86%) rename source/{Sashimi.Azure => Sashimi.Azure.Accounts}/Web/AzureHomeLinksContributor.cs (85%) delete mode 100644 source/Sashimi.Azure.Accounts/Web/AzureServicePrincipalAccountExtensions.cs delete mode 100644 source/Sashimi.Azure.Tests/OnlyExposeWhatIsNecessary.cs delete mode 100644 source/Sashimi.Azure.Tests/Sashimi.Azure.Tests.csproj delete mode 100644 source/Sashimi.Azure/AzureModule.cs delete mode 100644 source/Sashimi.Azure/Properties/InternalsVisibleTo.cs delete mode 100644 source/Sashimi.Azure/Sashimi.Azure.csproj diff --git a/source/Sashimi.Azure.Accounts.Tests/Sashimi.Azure.Accounts.Tests.csproj b/source/Sashimi.Azure.Accounts.Tests/Sashimi.Azure.Accounts.Tests.csproj index f149bced..fe12657a 100644 --- a/source/Sashimi.Azure.Accounts.Tests/Sashimi.Azure.Accounts.Tests.csproj +++ b/source/Sashimi.Azure.Accounts.Tests/Sashimi.Azure.Accounts.Tests.csproj @@ -6,6 +6,7 @@ + diff --git a/source/Sashimi.Azure.Tests/Web/AzureEnvironmentsListActionFixture.cs b/source/Sashimi.Azure.Accounts.Tests/Web/AzureEnvironmentsListActionFixture.cs similarity index 91% rename from source/Sashimi.Azure.Tests/Web/AzureEnvironmentsListActionFixture.cs rename to source/Sashimi.Azure.Accounts.Tests/Web/AzureEnvironmentsListActionFixture.cs index 30ea8ff9..3060bf2b 100644 --- a/source/Sashimi.Azure.Tests/Web/AzureEnvironmentsListActionFixture.cs +++ b/source/Sashimi.Azure.Accounts.Tests/Web/AzureEnvironmentsListActionFixture.cs @@ -1,12 +1,13 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Threading.Tasks; using FluentAssertions; using NSubstitute; using NUnit.Framework; using Octopus.Server.Extensibility.Extensions.Infrastructure.Web.Api; -using Sashimi.Azure.Web; +using Sashimi.Azure.Accounts.Web; -namespace Sashimi.Azure.Tests.Web +namespace Sashimi.Azure.Accounts.Tests.Web { [TestFixture] public class AzureEnvironmentsListActionFixture diff --git a/source/Sashimi.Azure.Accounts/AzureAccountModule.cs b/source/Sashimi.Azure.Accounts/AzureAccountModule.cs index 22fc8ab3..6c4b3acd 100644 --- a/source/Sashimi.Azure.Accounts/AzureAccountModule.cs +++ b/source/Sashimi.Azure.Accounts/AzureAccountModule.cs @@ -1,6 +1,8 @@ using Autofac; using Octopus.Extensibility.Actions.Sashimi; +using Octopus.Server.Extensibility.Extensions.Infrastructure.Web.Api; using Octopus.Server.Extensibility.Extensions.Mappings; +using Octopus.Server.Extensibility.HostServices.Web; using Sashimi.Azure.Accounts.Web; using Sashimi.Server.Contracts.Accounts; @@ -12,6 +14,15 @@ protected override void Load(ContainerBuilder builder) { builder.RegisterType().As().As().SingleInstance(); + LoadWebSubModule(builder); + } + + void LoadWebSubModule(ContainerBuilder builder) + { + builder.RegisterType().As().AsSelf().InstancePerLifetimeScope(); + builder.RegisterType().AsSelf().InstancePerDependency(); + builder.RegisterType().As().InstancePerDependency(); + builder.RegisterType().AsSelf().As().InstancePerLifetimeScope(); builder.RegisterType().AsSelf().As().InstancePerLifetimeScope(); builder.RegisterType().AsSelf().As().InstancePerLifetimeScope(); diff --git a/source/Sashimi.Azure.Accounts/AzureServicePrincipalAccountExtensions.cs b/source/Sashimi.Azure.Accounts/AzureServicePrincipalAccountExtensions.cs index a96461d8..eec677d4 100644 --- a/source/Sashimi.Azure.Accounts/AzureServicePrincipalAccountExtensions.cs +++ b/source/Sashimi.Azure.Accounts/AzureServicePrincipalAccountExtensions.cs @@ -2,12 +2,13 @@ using System.Net.Http; using System.Net.Http.Headers; using Microsoft.Azure.Management.ResourceManager; +using Microsoft.Azure.Management.Storage; +using Microsoft.Azure.Management.WebSites; using Microsoft.IdentityModel.Clients.ActiveDirectory; using Microsoft.Rest; -using Sashimi.Azure.Accounts; -using IHttpClientFactory = Microsoft.IdentityModel.Clients.ActiveDirectory.IHttpClientFactory; - +namespace Sashimi.Azure.Accounts +{ static class AzureServicePrincipalAccountExtensions { static ServiceClientCredentials Credentials(this AzureServicePrincipalAccountDetails account, HttpMessageHandler handler) @@ -22,6 +23,20 @@ public static ResourceManagementClient CreateResourceManagementClient(this Azure new ResourceManagementClient(new Uri(account.ResourceManagementEndpointBaseUri), account.Credentials(httpClientHandler), httpClientHandler) { SubscriptionId = account.SubscriptionNumber }; } + public static StorageManagementClient CreateStorageManagementClient(this AzureServicePrincipalAccountDetails account, HttpClientHandler httpClientHandler) + { + return string.IsNullOrWhiteSpace(account.ResourceManagementEndpointBaseUri) ? + new StorageManagementClient(account.Credentials(httpClientHandler), httpClientHandler) { SubscriptionId = account.SubscriptionNumber } : + new StorageManagementClient(new Uri(account.ResourceManagementEndpointBaseUri), account.Credentials(httpClientHandler), httpClientHandler) { SubscriptionId = account.SubscriptionNumber }; + } + + public static WebSiteManagementClient CreateWebSiteManagementClient(this AzureServicePrincipalAccountDetails account, HttpClientHandler httpClientHandler) + { + return string.IsNullOrWhiteSpace(account.ResourceManagementEndpointBaseUri) ? + new WebSiteManagementClient(account.Credentials(httpClientHandler), httpClientHandler) { SubscriptionId = account.SubscriptionNumber } : + new WebSiteManagementClient(new Uri(account.ResourceManagementEndpointBaseUri), account.Credentials(httpClientHandler), httpClientHandler) { SubscriptionId = account.SubscriptionNumber }; + } + static string GetAuthorizationToken(AzureServicePrincipalAccountDetails account, HttpMessageHandler handler) { var adDirectory = "https://login.windows.net/"; @@ -63,3 +78,4 @@ public HttpClient GetHttpClient() } } } +} \ No newline at end of file diff --git a/source/Sashimi.Azure.Accounts/PropertyDictionaryExtensions.cs b/source/Sashimi.Azure.Accounts/PropertyDictionaryExtensions.cs index 88e9c3aa..f2dd4170 100644 --- a/source/Sashimi.Azure.Accounts/PropertyDictionaryExtensions.cs +++ b/source/Sashimi.Azure.Accounts/PropertyDictionaryExtensions.cs @@ -1,27 +1,30 @@ using System; using System.Collections.Generic; -static class PropertyDictionaryExtensions +namespace Sashimi.Azure.Accounts { - public static bool ContainsPropertyWithValue(this IDictionary dictionary, string key) + static class PropertyDictionaryExtensions { - if (!dictionary.ContainsKey(key)) + public static bool ContainsPropertyWithValue(this IDictionary dictionary, string key) { - return false; - } + if (!dictionary.ContainsKey(key)) + { + return false; + } - string value = dictionary[key]; - return value != null && !string.IsNullOrEmpty(value); - } + string value = dictionary[key]; + return value != null && !string.IsNullOrEmpty(value); + } - public static bool ContainsPropertyWithGuid(this IDictionary dictionary, string key) - { - if (!ContainsPropertyWithValue(dictionary, key)) + public static bool ContainsPropertyWithGuid(this IDictionary dictionary, string key) { - return false; - } + if (!ContainsPropertyWithValue(dictionary, key)) + { + return false; + } - string guid = dictionary[key]; - return Guid.TryParse(guid, out Guid _); + string guid = dictionary[key]; + return Guid.TryParse(guid, out Guid _); + } } } diff --git a/source/Sashimi.Azure.Accounts/Sashimi.Azure.Accounts.csproj b/source/Sashimi.Azure.Accounts/Sashimi.Azure.Accounts.csproj index e1db0273..7394f9c8 100644 --- a/source/Sashimi.Azure.Accounts/Sashimi.Azure.Accounts.csproj +++ b/source/Sashimi.Azure.Accounts/Sashimi.Azure.Accounts.csproj @@ -16,6 +16,7 @@ + diff --git a/source/Sashimi.Azure/Web/AzureApi.cs b/source/Sashimi.Azure.Accounts/Web/AzureApi.cs similarity index 93% rename from source/Sashimi.Azure/Web/AzureApi.cs rename to source/Sashimi.Azure.Accounts/Web/AzureApi.cs index 2e3b73a1..795a82ea 100644 --- a/source/Sashimi.Azure/Web/AzureApi.cs +++ b/source/Sashimi.Azure.Accounts/Web/AzureApi.cs @@ -2,7 +2,7 @@ using System.Net.Http; using Octopus.Server.Extensibility.Extensions.Infrastructure.Web.Api; -namespace Sashimi.Azure.Web +namespace Sashimi.Azure.Accounts.Web { class AzureApi : RegistersEndpoints { diff --git a/source/Sashimi.Azure/Web/AzureEnvironmentsListAction.cs b/source/Sashimi.Azure.Accounts/Web/AzureEnvironmentsListAction.cs similarity index 86% rename from source/Sashimi.Azure/Web/AzureEnvironmentsListAction.cs rename to source/Sashimi.Azure.Accounts/Web/AzureEnvironmentsListAction.cs index 3c6b02a8..23706df5 100644 --- a/source/Sashimi.Azure/Web/AzureEnvironmentsListAction.cs +++ b/source/Sashimi.Azure.Accounts/Web/AzureEnvironmentsListAction.cs @@ -1,10 +1,11 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.Azure.Management.ResourceManager.Fluent; using Octopus.Server.Extensibility.Extensions.Infrastructure.Web.Api; -namespace Sashimi.Azure.Web +namespace Sashimi.Azure.Accounts.Web { class AzureEnvironmentsListAction : IAsyncApiAction { @@ -80,12 +81,12 @@ static string GetKnownEnvironmentDisplayName(string environmentName) class AzureEnvironmentResource { - public string Name { get; set; } - public string DisplayName { get; set; } - public string AuthenticationEndpoint { get; set; } - public string ResourceManagerEndpoint { get; set; } - public string GraphEndpoint { get; set; } - public string ManagementEndpoint { get; set; } - public string StorageEndpointSuffix { get; set; } + public string Name { get; set; } = null!; + public string DisplayName { get; set; } = null!; + public string AuthenticationEndpoint { get; set; } = null!; + public string ResourceManagerEndpoint { get; set; } = null!; + public string GraphEndpoint { get; set; } = null!; + public string ManagementEndpoint { get; set; } = null!; + public string StorageEndpointSuffix { get; set; } = null!; } } \ No newline at end of file diff --git a/source/Sashimi.Azure/Web/AzureHomeLinksContributor.cs b/source/Sashimi.Azure.Accounts/Web/AzureHomeLinksContributor.cs similarity index 85% rename from source/Sashimi.Azure/Web/AzureHomeLinksContributor.cs rename to source/Sashimi.Azure.Accounts/Web/AzureHomeLinksContributor.cs index 43b8e422..9f3c7649 100644 --- a/source/Sashimi.Azure/Web/AzureHomeLinksContributor.cs +++ b/source/Sashimi.Azure.Accounts/Web/AzureHomeLinksContributor.cs @@ -1,7 +1,8 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using Octopus.Server.Extensibility.HostServices.Web; -namespace Sashimi.Azure.Web +namespace Sashimi.Azure.Accounts.Web { class AzureHomeLinksContributor : IHomeLinksContributor { diff --git a/source/Sashimi.Azure.Accounts/Web/AzureServicePrincipalAccountExtensions.cs b/source/Sashimi.Azure.Accounts/Web/AzureServicePrincipalAccountExtensions.cs deleted file mode 100644 index 2168653c..00000000 --- a/source/Sashimi.Azure.Accounts/Web/AzureServicePrincipalAccountExtensions.cs +++ /dev/null @@ -1,81 +0,0 @@ -using System; -using System.Net.Http; -using System.Net.Http.Headers; -using Microsoft.Azure.Management.ResourceManager; -using Microsoft.Azure.Management.Storage; -using Microsoft.Azure.Management.WebSites; -using Microsoft.IdentityModel.Clients.ActiveDirectory; -using Microsoft.Rest; - -namespace Sashimi.Azure.Accounts.Web -{ - static class AzureServicePrincipalAccountExtensions - { - static ServiceClientCredentials Credentials(this AzureServicePrincipalAccountDetails account, HttpMessageHandler handler) - { - return new TokenCredentials(GetAuthorizationToken(account, handler)); - } - - public static ResourceManagementClient CreateResourceManagementClient(this AzureServicePrincipalAccountDetails account, HttpClientHandler httpClientHandler) - { - return string.IsNullOrWhiteSpace(account.ResourceManagementEndpointBaseUri) ? - new ResourceManagementClient(account.Credentials(httpClientHandler), httpClientHandler) { SubscriptionId = account.SubscriptionNumber } : - new ResourceManagementClient(new Uri(account.ResourceManagementEndpointBaseUri), account.Credentials(httpClientHandler), httpClientHandler) { SubscriptionId = account.SubscriptionNumber }; - } - - public static StorageManagementClient CreateStorageManagementClient(this AzureServicePrincipalAccountDetails account, HttpClientHandler httpClientHandler) - { - return string.IsNullOrWhiteSpace(account.ResourceManagementEndpointBaseUri) ? - new StorageManagementClient(account.Credentials(httpClientHandler), httpClientHandler) { SubscriptionId = account.SubscriptionNumber } : - new StorageManagementClient(new Uri(account.ResourceManagementEndpointBaseUri), account.Credentials(httpClientHandler), httpClientHandler) { SubscriptionId = account.SubscriptionNumber }; - } - - public static WebSiteManagementClient CreateWebSiteManagementClient(this AzureServicePrincipalAccountDetails account, HttpClientHandler httpClientHandler) - { - return string.IsNullOrWhiteSpace(account.ResourceManagementEndpointBaseUri) ? - new WebSiteManagementClient(account.Credentials(httpClientHandler), httpClientHandler) { SubscriptionId = account.SubscriptionNumber } : - new WebSiteManagementClient(new Uri(account.ResourceManagementEndpointBaseUri), account.Credentials(httpClientHandler), httpClientHandler) { SubscriptionId = account.SubscriptionNumber }; - } - - static string GetAuthorizationToken(AzureServicePrincipalAccountDetails account, HttpMessageHandler handler) - { - var adDirectory = "https://login.windows.net/"; - if (!string.IsNullOrWhiteSpace(account.ActiveDirectoryEndpointBaseUri)) - { - adDirectory = account.ActiveDirectoryEndpointBaseUri; - } - var context = new AuthenticationContext(adDirectory + account.TenantId, true, TokenCache.DefaultShared, new HttpClientFactory(handler)); - - var resourceManagementEndpointBaseUri = "https://management.core.windows.net/"; - if (!string.IsNullOrWhiteSpace(account.ResourceManagementEndpointBaseUri)) - { - resourceManagementEndpointBaseUri = account.ResourceManagementEndpointBaseUri; - } - var result = context.AcquireTokenAsync(resourceManagementEndpointBaseUri, new ClientCredential(account.ClientId, account.Password?.Value)).GetAwaiter().GetResult(); - return result.AccessToken; - } - - // We decided to "copy" the impl from https://github.com/AzureAD/azure-activedirectory-library-for-dotnet/blob/af10dd15cdb082bc3dbe14b0c2c6d81f6ca5b541/src/Microsoft.IdentityModel.Clients.ActiveDirectory/Core/Http/HttpClientFactory.cs - // This was we are setting the same headers as the Azure impl. - class HttpClientFactory : IHttpClientFactory - { - readonly HttpClient client; - const long MaxResponseContentBufferSizeInBytes = 1048576; - - public HttpClientFactory(HttpMessageHandler handler) - { - client = new HttpClient(handler) - { - MaxResponseContentBufferSize = MaxResponseContentBufferSizeInBytes - }; - client.DefaultRequestHeaders.Accept.Clear(); - client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); - } - - public HttpClient GetHttpClient() - { - return client; - } - } - } -} \ No newline at end of file diff --git a/source/Sashimi.Azure.Tests/OnlyExposeWhatIsNecessary.cs b/source/Sashimi.Azure.Tests/OnlyExposeWhatIsNecessary.cs deleted file mode 100644 index c7aacc60..00000000 --- a/source/Sashimi.Azure.Tests/OnlyExposeWhatIsNecessary.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using NUnit.Framework; -using Octopus.Server.Extensibility.Tests; - -namespace Sashimi.Azure.Tests -{ - [TestFixture] - public class OnlyExposeWhatIsNecessary : OnlyExposeWhatIsNecessaryFixture - { - protected override Type EntryPointTypeUnderTest => typeof(AzureModule); - } -} \ No newline at end of file diff --git a/source/Sashimi.Azure.Tests/Sashimi.Azure.Tests.csproj b/source/Sashimi.Azure.Tests/Sashimi.Azure.Tests.csproj deleted file mode 100644 index 1b5a7fe4..00000000 --- a/source/Sashimi.Azure.Tests/Sashimi.Azure.Tests.csproj +++ /dev/null @@ -1,24 +0,0 @@ - - - - netcoreapp3.1 - - false - enable - - - - - - - - - - - - - - - - - diff --git a/source/Sashimi.Azure/AzureModule.cs b/source/Sashimi.Azure/AzureModule.cs deleted file mode 100644 index ca7cd37e..00000000 --- a/source/Sashimi.Azure/AzureModule.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Autofac; -using Octopus.Server.Extensibility.Extensions.Infrastructure.Web.Api; -using Octopus.Server.Extensibility.HostServices.Web; -using Sashimi.Azure.Web; - -namespace Sashimi.Azure -{ - public class AzureModule : Module - { - protected override void Load(ContainerBuilder builder) - { - LoadWebSubModule(builder); - } - - void LoadWebSubModule(ContainerBuilder builder) - { - builder.RegisterType().As().AsSelf().InstancePerLifetimeScope(); - - builder.RegisterType().AsSelf().InstancePerDependency(); - - builder.RegisterType().As().InstancePerDependency(); - } - } -} \ No newline at end of file diff --git a/source/Sashimi.Azure/Properties/InternalsVisibleTo.cs b/source/Sashimi.Azure/Properties/InternalsVisibleTo.cs deleted file mode 100644 index afbfd0ad..00000000 --- a/source/Sashimi.Azure/Properties/InternalsVisibleTo.cs +++ /dev/null @@ -1,4 +0,0 @@ - -using System.Runtime.CompilerServices; - -[assembly:InternalsVisibleTo("Sashimi.Azure.Tests")] \ No newline at end of file diff --git a/source/Sashimi.Azure/Sashimi.Azure.csproj b/source/Sashimi.Azure/Sashimi.Azure.csproj deleted file mode 100644 index c983e37b..00000000 --- a/source/Sashimi.Azure/Sashimi.Azure.csproj +++ /dev/null @@ -1,20 +0,0 @@ - - - - Sashimi.Azure - Sashimi.Azure - netstandard2.1 - true - false - bin\ - disable - https://github.com/OctopusDeploy/Sashimi/ - Apache-2.0 - - - - - - - - diff --git a/source/Sashimi.sln b/source/Sashimi.sln index 8025fe0b..3d162e82 100644 --- a/source/Sashimi.sln +++ b/source/Sashimi.sln @@ -26,12 +26,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sashimi.Azure.Common", "Azu EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sashimi.Aws.Common", "Aws.Common\Sashimi.Aws.Common.csproj", "{EF64A3BD-9FF7-45E9-96D4-B3DC446C032E}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure", "Azure", "{6288E064-DE6F-4012-B887-64B364482B5C}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sashimi.Azure", "Sashimi.Azure\Sashimi.Azure.csproj", "{E79F91CA-CD16-4068-8170-C66804533720}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sashimi.Azure.Tests", "Sashimi.Azure.Tests\Sashimi.Azure.Tests.csproj", "{54EF951A-AA50-4ED2-BB79-C9CBC70BCA65}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sashimi.Azure.Accounts", "Sashimi.Azure.Accounts\Sashimi.Azure.Accounts.csproj", "{2BF290BD-9231-4895-AF83-6B15BF24EE0D}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sashimi.Aws.Accounts", "Sashimi.Aws.Accounts\Sashimi.Aws.Accounts.csproj", "{D2C212C6-4F29-44EB-82A9-6580A7E30C6C}" @@ -82,14 +76,6 @@ Global {EF64A3BD-9FF7-45E9-96D4-B3DC446C032E}.Debug|Any CPU.Build.0 = Debug|Any CPU {EF64A3BD-9FF7-45E9-96D4-B3DC446C032E}.Release|Any CPU.ActiveCfg = Release|Any CPU {EF64A3BD-9FF7-45E9-96D4-B3DC446C032E}.Release|Any CPU.Build.0 = Release|Any CPU - {E79F91CA-CD16-4068-8170-C66804533720}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E79F91CA-CD16-4068-8170-C66804533720}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E79F91CA-CD16-4068-8170-C66804533720}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E79F91CA-CD16-4068-8170-C66804533720}.Release|Any CPU.Build.0 = Release|Any CPU - {54EF951A-AA50-4ED2-BB79-C9CBC70BCA65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {54EF951A-AA50-4ED2-BB79-C9CBC70BCA65}.Debug|Any CPU.Build.0 = Debug|Any CPU - {54EF951A-AA50-4ED2-BB79-C9CBC70BCA65}.Release|Any CPU.ActiveCfg = Release|Any CPU - {54EF951A-AA50-4ED2-BB79-C9CBC70BCA65}.Release|Any CPU.Build.0 = Release|Any CPU {2BF290BD-9231-4895-AF83-6B15BF24EE0D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2BF290BD-9231-4895-AF83-6B15BF24EE0D}.Debug|Any CPU.Build.0 = Debug|Any CPU {2BF290BD-9231-4895-AF83-6B15BF24EE0D}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -135,8 +121,6 @@ Global HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {E79F91CA-CD16-4068-8170-C66804533720} = {6288E064-DE6F-4012-B887-64B364482B5C} - {54EF951A-AA50-4ED2-BB79-C9CBC70BCA65} = {6288E064-DE6F-4012-B887-64B364482B5C} {238BD45A-A67D-474D-847D-87F72B64772F} = {2E47DADC-351F-4DC3-BDD2-BA03867B1C69} {D229E77B-3607-437B-91D0-598BFDD0F091} = {2E47DADC-351F-4DC3-BDD2-BA03867B1C69} {58C49A1A-6705-4485-BFE3-5CB73FAEC99B} = {2E47DADC-351F-4DC3-BDD2-BA03867B1C69}