From 78514f69d7dcf554bcba81ae71c9dfd611c0318f Mon Sep 17 00:00:00 2001 From: Shannon Lewis Date: Thu, 3 May 2018 12:05:35 +1000 Subject: [PATCH 01/19] setting up new AccountRepository for better scripting experience --- .../Conventions/AccountTypeConventions.cs | 41 +++++++ ...houldNotRegress..NETFramework.approved.txt | 31 +++++ .../Extensions/TypeExtensions.cs | 22 ++++ .../Repositories/Async/AccountRepository.cs | 108 ++++++++++++++++++ .../AzureServicePrincipalAccountRepository.cs | 24 ++++ .../Repositories/IAccountRepository.cs | 104 +++++++++++++++++ 6 files changed, 330 insertions(+) create mode 100644 source/Octopus.Client.Tests/Conventions/AccountTypeConventions.cs create mode 100644 source/Octopus.Client/Repositories/Async/AzureServicePrincipalAccountRepository.cs diff --git a/source/Octopus.Client.Tests/Conventions/AccountTypeConventions.cs b/source/Octopus.Client.Tests/Conventions/AccountTypeConventions.cs new file mode 100644 index 000000000..4f4759899 --- /dev/null +++ b/source/Octopus.Client.Tests/Conventions/AccountTypeConventions.cs @@ -0,0 +1,41 @@ +using System; +using System.Linq; +using System.Reflection; +using NUnit.Framework; +using Octopus.Client.Extensions; +using Octopus.Client.Model.Accounts; + +namespace Octopus.Client.Tests.Conventions +{ + [TestFixture] + public class AccountTypeConventions + { + private static readonly TypeInfo[] ExportedTypes = typeof(AccountResource).GetTypeInfo().Assembly.GetExportedTypes().Select(t => t.GetTypeInfo()).ToArray(); + + [Test] + public void AllAccountResourceTypeCanBeMappedToAnAccountType() + { + var derivedAccountTypes = ExportedTypes + .Where(t => !t.IsAbstract) + .Where(t => typeof(AccountResource).IsAssignableFrom(t)) + .ToArray(); + + var typesThatCannotBeMapped = derivedAccountTypes.Where(t => + { + try + { + t.DetermineAccountType(); + return false; + } + catch (ArgumentException) + { + return true; + } + }) + .ToArray(); + + if (typesThatCannotBeMapped.Any()) + Assert.Fail($"The following AccountResource types cannot be mapped to an AccountType: " + typesThatCannotBeMapped.CommaSeperate()); + } + } +} \ No newline at end of file diff --git a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt index a2f0da94b..b4d53c149 100644 --- a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt +++ b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt @@ -1035,6 +1035,7 @@ Octopus.Client.Extensions } abstract class TypeExtensions { + static Octopus.Client.Model.Accounts.AccountType DetermineAccountType(Type) static Object GetDefault(Type) } abstract class UriExtensions @@ -4456,6 +4457,16 @@ Octopus.Client.Repositories Octopus.Client.Repositories.IFindByName Octopus.Client.Repositories.IPaginate { + Octopus.Client.Model.Accounts.AccountType DetermineAccountType() + List FindAllOfType(Object) + Octopus.Client.Repositories.TAccount FindByNameOfType(String) + List FindByNamesOfType(IEnumerable) + List FindManyOfType(Func, Object) + Octopus.Client.Repositories.TAccount FindOneOfType(Func, Object) + Octopus.Client.Repositories.TAccount GetOfType(String) + List GetOfType(String[]) + void PaginateOfType(Func, Boolean>, Object) + Octopus.Client.Repositories.TAccount RefreshOfType(Octopus.Client.Repositories.TAccount) } interface IActionTemplateRepository Octopus.Client.Repositories.ICreate @@ -4916,6 +4927,12 @@ Octopus.Client.Repositories } Octopus.Client.Repositories.Async { + class AzureServicePrincipalAccountRepository + Octopus.Client.Repositories.Async.IAzureServicePrincipalAccountRepository + { + .ctor(Octopus.Client.IOctopusAsyncClient) + void WebSites(Octopus.Client.Model.Accounts.AzureServicePrincipalAccountResource) + } interface IAccountRepository Octopus.Client.Repositories.Async.ICreate Octopus.Client.Repositories.Async.IModify @@ -4924,6 +4941,16 @@ Octopus.Client.Repositories.Async Octopus.Client.Repositories.Async.IFindByName Octopus.Client.Repositories.Async.IPaginate { + Octopus.Client.Model.Accounts.AccountType DetermineAccountType() + Task> FindAllOfType(Object) + Task FindByNameOfType(String) + Task> FindByNamesOfType(IEnumerable) + Task> FindManyOfType(Func, Object) + Task FindOneOfType(Func, Object) + Task GetOfType(String) + Task> GetOfType(String[]) + Task PaginateOfType(Func, Boolean>, Object) + Task RefreshOfType(Octopus.Client.Repositories.Async.TAccount) } interface IActionTemplateRepository Octopus.Client.Repositories.Async.ICreate @@ -4950,6 +4977,10 @@ Octopus.Client.Repositories.Async Task GetContent(Octopus.Client.Model.ArtifactResource) Task PutContent(Octopus.Client.Model.ArtifactResource, Stream) } + interface IAzureServicePrincipalAccountRepository + { + void WebSites(Octopus.Client.Model.Accounts.AzureServicePrincipalAccountResource) + } interface IBackupRepository { Task GetConfiguration() diff --git a/source/Octopus.Client/Extensions/TypeExtensions.cs b/source/Octopus.Client/Extensions/TypeExtensions.cs index a7ed26e0a..49b6b7970 100644 --- a/source/Octopus.Client/Extensions/TypeExtensions.cs +++ b/source/Octopus.Client/Extensions/TypeExtensions.cs @@ -1,10 +1,32 @@ using System; using System.Reflection; +using Octopus.Client.Model.Accounts; namespace Octopus.Client.Extensions { public static class TypeExtensions { public static object GetDefault(this Type t) => t.GetTypeInfo().IsValueType ? Activator.CreateInstance(t) : null; + + public static AccountType DetermineAccountType(this Type type) + { + var accountType = AccountType.None; + + if (type == typeof(UsernamePasswordAccountResource)) + accountType = AccountType.UsernamePassword; + else if (type == typeof(SshKeyPairAccountResource)) + accountType = AccountType.SshKeyPair; + else if (type == typeof(AzureServicePrincipalAccountResource)) + accountType = AccountType.AzureServicePrincipal; + else if (type == typeof(AzureSubscriptionAccountResource)) + accountType = AccountType.AzureSubscription; + else if (type == typeof(AmazonWebServicesAccountResource)) + accountType = AccountType.AmazonWebServicesAccount; + else if (type == typeof(AmazonWebServicesRoleAccountResource)) + accountType = AccountType.AmazonWebServicesRoleAccount; + else + throw new ArgumentException($"Account type {type} is not supported"); + return accountType; + } } } \ No newline at end of file diff --git a/source/Octopus.Client/Repositories/Async/AccountRepository.cs b/source/Octopus.Client/Repositories/Async/AccountRepository.cs index 4ec7123a2..15579ab44 100644 --- a/source/Octopus.Client/Repositories/Async/AccountRepository.cs +++ b/source/Octopus.Client/Repositories/Async/AccountRepository.cs @@ -1,10 +1,29 @@ using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Octopus.Client.Extensibility; +using Octopus.Client.Extensions; +using Octopus.Client.Model; using Octopus.Client.Model.Accounts; namespace Octopus.Client.Repositories.Async { public interface IAccountRepository : ICreate, IModify, IDelete, IGet, IFindByName { + AccountType DetermineAccountType() where TAccount : AccountResource; + + Task GetOfType(string idOrHref) where TAccount : AccountResource; + Task> GetOfType(params string[] ids) where TAccount : AccountResource; + Task RefreshOfType(TAccount resource) where TAccount : AccountResource; + + Task FindByNameOfType(string name) where TAccount : AccountResource; + Task> FindByNamesOfType(IEnumerable names) where TAccount : AccountResource; + + Task PaginateOfType(Func, bool> getNextPage, object pathParameters = null) where TAccount : AccountResource; + Task FindOneOfType(Func search, object pathParameters = null) where TAccount : AccountResource; + Task> FindManyOfType(Func search, object pathParameters = null) where TAccount : AccountResource; + Task> FindAllOfType(object pathParameters = null) where TAccount : AccountResource; } class AccountRepository : BasicRepository, IAccountRepository @@ -13,5 +32,94 @@ public AccountRepository(IOctopusAsyncClient client) : base(client, "Accounts") { } + + public async Task GetOfType(string idOrHref) where TAccount : AccountResource + { + var account = await base.Get(idOrHref); + return account as TAccount; + } + + public async Task> GetOfType(params string[] ids) where TAccount : AccountResource + { + var accounts = await base.Get(ids); + return accounts as List; + } + + public async Task RefreshOfType(TAccount resource) where TAccount : AccountResource + { + var account = await base.Refresh(resource); + return account as TAccount; + } + + public Task FindByNameOfType(string name) where TAccount : AccountResource + { + var accountType = DetermineAccountType(); + name = (name ?? string.Empty).Trim(); + + return FindOneOfType(r => + { + if (r is INamedResource named) + return string.Equals((named.Name ?? string.Empty).Trim(), name, StringComparison.OrdinalIgnoreCase); + return false; + }, pathParameters: new {accountType, name}); + } + + public Task> FindByNamesOfType(IEnumerable names) where TAccount : AccountResource + { + var nameSet = new HashSet((names ?? new string[0]).Select(n => (n ?? string.Empty).Trim()), StringComparer.OrdinalIgnoreCase); + return FindManyOfType(r => + { + if (r is INamedResource named) + return nameSet.Contains((named.Name ?? string.Empty).Trim()); + return false; + }, pathParameters: DetermineAccountType()); + } + + object PathParametersOfType(object pathParameters) where TAccount : AccountResource + { + if (pathParameters != null) + return pathParameters; + var accountType = DetermineAccountType(); + return new {accountType}; + } + + public Task PaginateOfType(Func, bool> getNextPage, object pathParameters = null) where TAccount : AccountResource + { + return Client.Paginate(Client.RootDocument.Link(CollectionLinkName), PathParametersOfType(pathParameters), getNextPage); + } + + public async Task FindOneOfType(Func search, object pathParameters = null) where TAccount : AccountResource + { + TAccount resource = null; + await PaginateOfType(page => + { + resource = page.Items.FirstOrDefault(search); + return resource == null; + }, pathParameters: PathParametersOfType(pathParameters)) + .ConfigureAwait(false); + return resource; + } + + public async Task> FindManyOfType(Func search, object pathParameters = null) where TAccount : AccountResource + { + var resources = new List(); + await PaginateOfType(page => + { + resources.AddRange(page.Items.Where(search)); + return true; + }, pathParameters: PathParametersOfType(pathParameters)) + .ConfigureAwait(false); + return resources; + } + + public Task> FindAllOfType(object pathParameters = null) where TAccount : AccountResource + { + return FindManyOfType(x => true, PathParametersOfType(pathParameters)); + } + + public AccountType DetermineAccountType() where TAccount : AccountResource + { + return typeof(TAccount).DetermineAccountType(); + } } } diff --git a/source/Octopus.Client/Repositories/Async/AzureServicePrincipalAccountRepository.cs b/source/Octopus.Client/Repositories/Async/AzureServicePrincipalAccountRepository.cs new file mode 100644 index 000000000..b21c4b8f9 --- /dev/null +++ b/source/Octopus.Client/Repositories/Async/AzureServicePrincipalAccountRepository.cs @@ -0,0 +1,24 @@ +using Octopus.Client.Model.Accounts; + +namespace Octopus.Client.Repositories.Async +{ + public interface IAzureServicePrincipalAccountRepository + { + void WebSites(AzureServicePrincipalAccountResource account); + } + + public class AzureServicePrincipalAccountRepository : IAzureServicePrincipalAccountRepository + { + private readonly IOctopusAsyncClient client; + + public AzureServicePrincipalAccountRepository(IOctopusAsyncClient client) + { + this.client = client; + } + + public void WebSites(AzureServicePrincipalAccountResource account) + { + client.Get(account.Link("WebSites")); + } + } +} \ No newline at end of file diff --git a/source/Octopus.Client/Repositories/IAccountRepository.cs b/source/Octopus.Client/Repositories/IAccountRepository.cs index 36fa8441f..fc113b18e 100644 --- a/source/Octopus.Client/Repositories/IAccountRepository.cs +++ b/source/Octopus.Client/Repositories/IAccountRepository.cs @@ -1,10 +1,28 @@ using System; +using System.Collections.Generic; +using System.Linq; +using Octopus.Client.Extensibility; +using Octopus.Client.Extensions; +using Octopus.Client.Model; using Octopus.Client.Model.Accounts; namespace Octopus.Client.Repositories { public interface IAccountRepository : ICreate, IModify, IDelete, IGet, IFindByName { + AccountType DetermineAccountType() where TAccount : AccountResource; + + TAccount GetOfType(string idOrHref) where TAccount : AccountResource; + List GetOfType(params string[] ids) where TAccount : AccountResource; + TAccount RefreshOfType(TAccount resource) where TAccount : AccountResource; + + TAccount FindByNameOfType(string name) where TAccount : AccountResource; + List FindByNamesOfType(IEnumerable names) where TAccount : AccountResource; + + void PaginateOfType(Func, bool> getNextPage, object pathParameters = null) where TAccount : AccountResource; + TAccount FindOneOfType(Func search, object pathParameters = null) where TAccount : AccountResource; + List FindManyOfType(Func search, object pathParameters = null) where TAccount : AccountResource; + List FindAllOfType(object pathParameters = null) where TAccount : AccountResource; } class AccountRepository : BasicRepository, IAccountRepository @@ -13,5 +31,91 @@ public AccountRepository(IOctopusClient client) : base(client, "Accounts") { } + public TAccount GetOfType(string idOrHref) where TAccount : AccountResource + { + var account = base.Get(idOrHref); + return account as TAccount; + } + + public List GetOfType(params string[] ids) where TAccount : AccountResource + { + var accounts = base.Get(ids); + return accounts as List; + } + + public TAccount RefreshOfType(TAccount resource) where TAccount : AccountResource + { + var account = base.Refresh(resource); + return account as TAccount; + } + + public TAccount FindByNameOfType(string name) where TAccount : AccountResource + { + var accountType = DetermineAccountType(); + name = (name ?? string.Empty).Trim(); + + return FindOneOfType(r => + { + if (r is INamedResource named) + return string.Equals((named.Name ?? string.Empty).Trim(), name, StringComparison.OrdinalIgnoreCase); + return false; + }, pathParameters: new {accountType, name}); + } + + public List FindByNamesOfType(IEnumerable names) where TAccount : AccountResource + { + var nameSet = new HashSet((names ?? new string[0]).Select(n => (n ?? string.Empty).Trim()), StringComparer.OrdinalIgnoreCase); + return FindManyOfType(r => + { + if (r is INamedResource named) + return nameSet.Contains((named.Name ?? string.Empty).Trim()); + return false; + }, pathParameters: DetermineAccountType()); + } + + object PathParametersOfType(object pathParameters) where TAccount : AccountResource + { + if (pathParameters != null) + return pathParameters; + var accountType = DetermineAccountType(); + return new {accountType}; + } + + public void PaginateOfType(Func, bool> getNextPage, object pathParameters = null) where TAccount : AccountResource + { + Client.Paginate(Client.RootDocument.Link(CollectionLinkName), PathParametersOfType(pathParameters), getNextPage); + } + + public TAccount FindOneOfType(Func search, object pathParameters = null) where TAccount : AccountResource + { + TAccount resource = null; + PaginateOfType(page => + { + resource = page.Items.FirstOrDefault(search); + return resource == null; + }, pathParameters: PathParametersOfType(pathParameters)); + return resource; + } + + public List FindManyOfType(Func search, object pathParameters = null) where TAccount : AccountResource + { + var resources = new List(); + PaginateOfType(page => + { + resources.AddRange(page.Items.Where(search)); + return true; + }, pathParameters: PathParametersOfType(pathParameters)); + return resources; + } + + public List FindAllOfType(object pathParameters = null) where TAccount : AccountResource + { + return FindManyOfType(x => true, PathParametersOfType(pathParameters)); + } + + public AccountType DetermineAccountType() where TAccount : AccountResource + { + return typeof(TAccount).DetermineAccountType(); + } } } \ No newline at end of file From d9275472118c1ee8b537cb24a93a65d11bcc31ba Mon Sep 17 00:00:00 2001 From: Shannon Lewis Date: Thu, 3 May 2018 12:26:06 +1000 Subject: [PATCH 02/19] setup to where we should be able to script the Azure WebSites calls --- .../Octopus.Client/IOctopusAsyncRepository.cs | 1 + source/Octopus.Client/IOctopusRepository.cs | 1 + .../AzureServicePrincipalAccountResource.cs | 6 +++++ .../AzureSubscriptionAccountResource.cs | 7 ++++++ .../Octopus.Client/OctopusAsyncRepository.cs | 2 ++ source/Octopus.Client/OctopusRepository.cs | 2 ++ .../AzureServicePrincipalAccountRepository.cs | 8 +++--- .../AzureServicePrincipalAccountRepository.cs | 25 +++++++++++++++++++ 8 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 source/Octopus.Client/Repositories/AzureServicePrincipalAccountRepository.cs diff --git a/source/Octopus.Client/IOctopusAsyncRepository.cs b/source/Octopus.Client/IOctopusAsyncRepository.cs index cc45ea93d..3d065d478 100644 --- a/source/Octopus.Client/IOctopusAsyncRepository.cs +++ b/source/Octopus.Client/IOctopusAsyncRepository.cs @@ -16,6 +16,7 @@ public interface IOctopusAsyncRepository IOctopusAsyncClient Client { get; } IAccountRepository Accounts { get; } + IAzureServicePrincipalAccountRepository AzureServicePrincipalAccounts { get; } IActionTemplateRepository ActionTemplates { get; } IArtifactRepository Artifacts { get; } IBackupRepository Backups { get; } diff --git a/source/Octopus.Client/IOctopusRepository.cs b/source/Octopus.Client/IOctopusRepository.cs index e7fd7883e..8ae90d127 100644 --- a/source/Octopus.Client/IOctopusRepository.cs +++ b/source/Octopus.Client/IOctopusRepository.cs @@ -17,6 +17,7 @@ public interface IOctopusRepository IOctopusClient Client { get; } IAccountRepository Accounts { get; } + IAzureServicePrincipalAccountRepository AzureServicePrincipalAccounts { get; } IActionTemplateRepository ActionTemplates { get; } IArtifactRepository Artifacts { get; } IBackupRepository Backups { get; } diff --git a/source/Octopus.Client/Model/Accounts/AzureServicePrincipalAccountResource.cs b/source/Octopus.Client/Model/Accounts/AzureServicePrincipalAccountResource.cs index a2b28b521..1baf9105b 100644 --- a/source/Octopus.Client/Model/Accounts/AzureServicePrincipalAccountResource.cs +++ b/source/Octopus.Client/Model/Accounts/AzureServicePrincipalAccountResource.cs @@ -37,5 +37,11 @@ public class AzureServicePrincipalAccountResource : AccountResource [Trim] [Writeable] public string ActiveDirectoryEndpointBaseUri { get; set; } + + public class WebSiteResource + { + public string Name { get; } + public string ResourceGroup { get; set; } + } } } \ No newline at end of file diff --git a/source/Octopus.Client/Model/Accounts/AzureSubscriptionAccountResource.cs b/source/Octopus.Client/Model/Accounts/AzureSubscriptionAccountResource.cs index f2563bd16..6bb960a00 100644 --- a/source/Octopus.Client/Model/Accounts/AzureSubscriptionAccountResource.cs +++ b/source/Octopus.Client/Model/Accounts/AzureSubscriptionAccountResource.cs @@ -36,5 +36,12 @@ public override AccountType AccountType [Trim] [Writeable] public string ServiceManagementEndpointBaseUri { get; set; } + + public class WebSiteResource + { + public string Name { get; } + public string WebSpace { get; set; } + public string ResourceGroup { get; set; } + } } } \ No newline at end of file diff --git a/source/Octopus.Client/OctopusAsyncRepository.cs b/source/Octopus.Client/OctopusAsyncRepository.cs index c511441bc..f58cc5898 100644 --- a/source/Octopus.Client/OctopusAsyncRepository.cs +++ b/source/Octopus.Client/OctopusAsyncRepository.cs @@ -31,6 +31,7 @@ public OctopusAsyncRepository(IOctopusAsyncClient client) this.Client = client; Accounts = new AccountRepository(client); + AzureServicePrincipalAccounts = new AzureServicePrincipalAccountRepository(client); ActionTemplates = new ActionTemplateRepository(client); Artifacts = new ArtifactRepository(client); Backups = new BackupRepository(client); @@ -79,6 +80,7 @@ public OctopusAsyncRepository(IOctopusAsyncClient client) public IOctopusAsyncClient Client { get; } public IAccountRepository Accounts { get; } + public IAzureServicePrincipalAccountRepository AzureServicePrincipalAccounts { get; } public IActionTemplateRepository ActionTemplates { get; } public IArtifactRepository Artifacts { get; } public IBackupRepository Backups { get; } diff --git a/source/Octopus.Client/OctopusRepository.cs b/source/Octopus.Client/OctopusRepository.cs index f1afcdc27..76b148c7e 100644 --- a/source/Octopus.Client/OctopusRepository.cs +++ b/source/Octopus.Client/OctopusRepository.cs @@ -25,6 +25,7 @@ public OctopusRepository(IOctopusClient client) this.Client = client; Accounts = new AccountRepository(client); + AzureServicePrincipalAccounts = new AzureServicePrincipalAccountRepository(client); ActionTemplates = new ActionTemplateRepository(client); Artifacts = new ArtifactRepository(client); Backups = new BackupRepository(client); @@ -73,6 +74,7 @@ public OctopusRepository(IOctopusClient client) public IOctopusClient Client { get; } public IAccountRepository Accounts { get; } + public IAzureServicePrincipalAccountRepository AzureServicePrincipalAccounts { get; } public IActionTemplateRepository ActionTemplates { get; } public IArtifactRepository Artifacts { get; } public IBackupRepository Backups { get; } diff --git a/source/Octopus.Client/Repositories/Async/AzureServicePrincipalAccountRepository.cs b/source/Octopus.Client/Repositories/Async/AzureServicePrincipalAccountRepository.cs index b21c4b8f9..43a409dbd 100644 --- a/source/Octopus.Client/Repositories/Async/AzureServicePrincipalAccountRepository.cs +++ b/source/Octopus.Client/Repositories/Async/AzureServicePrincipalAccountRepository.cs @@ -1,10 +1,12 @@ +using System.Collections.Generic; +using System.Threading.Tasks; using Octopus.Client.Model.Accounts; namespace Octopus.Client.Repositories.Async { public interface IAzureServicePrincipalAccountRepository { - void WebSites(AzureServicePrincipalAccountResource account); + Task> WebSites(AzureServicePrincipalAccountResource account); } public class AzureServicePrincipalAccountRepository : IAzureServicePrincipalAccountRepository @@ -16,9 +18,9 @@ public AzureServicePrincipalAccountRepository(IOctopusAsyncClient client) this.client = client; } - public void WebSites(AzureServicePrincipalAccountResource account) + public Task> WebSites(AzureServicePrincipalAccountResource account) { - client.Get(account.Link("WebSites")); + return client.Get>(account.Link("WebSites")); } } } \ No newline at end of file diff --git a/source/Octopus.Client/Repositories/AzureServicePrincipalAccountRepository.cs b/source/Octopus.Client/Repositories/AzureServicePrincipalAccountRepository.cs new file mode 100644 index 000000000..4aa760fd4 --- /dev/null +++ b/source/Octopus.Client/Repositories/AzureServicePrincipalAccountRepository.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; +using Octopus.Client.Model.Accounts; + +namespace Octopus.Client.Repositories +{ + public interface IAzureServicePrincipalAccountRepository + { + List WebSites(AzureServicePrincipalAccountResource account); + } + + public class AzureServicePrincipalAccountRepository : IAzureServicePrincipalAccountRepository + { + private readonly IOctopusClient client; + + public AzureServicePrincipalAccountRepository(IOctopusClient client) + { + this.client = client; + } + + public List WebSites(AzureServicePrincipalAccountResource account) + { + return client.Get>(account.Link("WebSites")); + } + } +} \ No newline at end of file From ffc60361399b8dc51009fd5b200a3a72e6b3f40b Mon Sep 17 00:00:00 2001 From: Shannon Lewis Date: Thu, 3 May 2018 14:13:54 +1000 Subject: [PATCH 03/19] missed an approval test --- ...houldNotRegress..NETFramework.approved.txt | 44 ++++++++++++++++++- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt index b4d53c149..c11d9cc36 100644 --- a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt +++ b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt @@ -53,6 +53,7 @@ Octopus.Client Octopus.Client.Repositories.Async.IAccountRepository Accounts { get; } Octopus.Client.Repositories.Async.IActionTemplateRepository ActionTemplates { get; } Octopus.Client.Repositories.Async.IArtifactRepository Artifacts { get; } + Octopus.Client.Repositories.Async.IAzureServicePrincipalAccountRepository AzureServicePrincipalAccounts { get; } Octopus.Client.Repositories.Async.IBackupRepository Backups { get; } Octopus.Client.Repositories.Async.IBuiltInPackageRepositoryRepository BuiltInPackageRepository { get; } Octopus.Client.Repositories.Async.ICertificateConfigurationRepository CertificateConfiguration { get; } @@ -131,6 +132,7 @@ Octopus.Client Octopus.Client.Repositories.IAccountRepository Accounts { get; } Octopus.Client.Repositories.IActionTemplateRepository ActionTemplates { get; } Octopus.Client.Repositories.IArtifactRepository Artifacts { get; } + Octopus.Client.Repositories.IAzureServicePrincipalAccountRepository AzureServicePrincipalAccounts { get; } Octopus.Client.Repositories.IBackupRepository Backups { get; } Octopus.Client.Repositories.IBuiltInPackageRepositoryRepository BuiltInPackageRepository { get; } Octopus.Client.Repositories.ICertificateConfigurationRepository CertificateConfiguration { get; } @@ -212,6 +214,7 @@ Octopus.Client Octopus.Client.Repositories.Async.IAccountRepository Accounts { get; } Octopus.Client.Repositories.Async.IActionTemplateRepository ActionTemplates { get; } Octopus.Client.Repositories.Async.IArtifactRepository Artifacts { get; } + Octopus.Client.Repositories.Async.IAzureServicePrincipalAccountRepository AzureServicePrincipalAccounts { get; } Octopus.Client.Repositories.Async.IBackupRepository Backups { get; } Octopus.Client.Repositories.Async.IBuiltInPackageRepositoryRepository BuiltInPackageRepository { get; } Octopus.Client.Repositories.Async.ICertificateConfigurationRepository CertificateConfiguration { get; } @@ -310,6 +313,7 @@ Octopus.Client Octopus.Client.Repositories.IAccountRepository Accounts { get; } Octopus.Client.Repositories.IActionTemplateRepository ActionTemplates { get; } Octopus.Client.Repositories.IArtifactRepository Artifacts { get; } + Octopus.Client.Repositories.IAzureServicePrincipalAccountRepository AzureServicePrincipalAccounts { get; } Octopus.Client.Repositories.IBackupRepository Backups { get; } Octopus.Client.Repositories.IBuiltInPackageRepositoryRepository BuiltInPackageRepository { get; } Octopus.Client.Repositories.ICertificateConfigurationRepository CertificateConfiguration { get; } @@ -3821,6 +3825,12 @@ Octopus.Client.Model.Accounts String ResourceManagementEndpointBaseUri { get; set; } String SubscriptionNumber { get; set; } String TenantId { get; set; } + class WebSiteResource + { + .ctor() + String Name { get; } + String ResourceGroup { get; set; } + } } class AzureSubscriptionAccountResource Octopus.Client.Extensibility.IResource @@ -3835,6 +3845,13 @@ Octopus.Client.Model.Accounts String CertificateThumbprint { get; set; } String ServiceManagementEndpointBaseUri { get; set; } String SubscriptionNumber { get; set; } + class WebSiteResource + { + .ctor() + String Name { get; } + String ResourceGroup { get; set; } + String WebSpace { get; set; } + } } class SshKeyPairAccountResource Octopus.Client.Extensibility.IResource @@ -3866,6 +3883,19 @@ Octopus.Client.Model.Accounts Octopus.Client.Model.SensitiveValue Password { get; set; } String Username { get; set; } } + class WebSiteResource + { + .ctor() + String Name { get; } + String ResourceGroup { get; set; } + } + class WebSiteResource + { + .ctor() + String Name { get; } + String ResourceGroup { get; set; } + String WebSpace { get; set; } + } } Octopus.Client.Model.DeploymentProcess { @@ -4449,6 +4479,12 @@ Octopus.Client.Operations } Octopus.Client.Repositories { + class AzureServicePrincipalAccountRepository + Octopus.Client.Repositories.IAzureServicePrincipalAccountRepository + { + .ctor(Octopus.Client.IOctopusClient) + List WebSites(Octopus.Client.Model.Accounts.AzureServicePrincipalAccountResource) + } interface IAccountRepository Octopus.Client.Repositories.ICreate Octopus.Client.Repositories.IModify @@ -4493,6 +4529,10 @@ Octopus.Client.Repositories Stream GetContent(Octopus.Client.Model.ArtifactResource) void PutContent(Octopus.Client.Model.ArtifactResource, Stream) } + interface IAzureServicePrincipalAccountRepository + { + List WebSites(Octopus.Client.Model.Accounts.AzureServicePrincipalAccountResource) + } interface IBackupRepository { Octopus.Client.Model.BackupConfigurationResource GetConfiguration() @@ -4931,7 +4971,7 @@ Octopus.Client.Repositories.Async Octopus.Client.Repositories.Async.IAzureServicePrincipalAccountRepository { .ctor(Octopus.Client.IOctopusAsyncClient) - void WebSites(Octopus.Client.Model.Accounts.AzureServicePrincipalAccountResource) + Task> WebSites(Octopus.Client.Model.Accounts.AzureServicePrincipalAccountResource) } interface IAccountRepository Octopus.Client.Repositories.Async.ICreate @@ -4979,7 +5019,7 @@ Octopus.Client.Repositories.Async } interface IAzureServicePrincipalAccountRepository { - void WebSites(Octopus.Client.Model.Accounts.AzureServicePrincipalAccountResource) + Task> WebSites(Octopus.Client.Model.Accounts.AzureServicePrincipalAccountResource) } interface IBackupRepository { From e177dd25dd9db9fc24bba296323f08f2afaf09ca Mon Sep 17 00:00:00 2001 From: Shannon Lewis Date: Thu, 3 May 2018 15:02:16 +1000 Subject: [PATCH 04/19] and the .NETCore approval file --- ...AreaShouldNotRegress..NETCore.approved.txt | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt index 88090395d..485990451 100644 --- a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt +++ b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt @@ -46,6 +46,7 @@ Octopus.Client Octopus.Client.Repositories.Async.IAccountRepository Accounts { get; } Octopus.Client.Repositories.Async.IActionTemplateRepository ActionTemplates { get; } Octopus.Client.Repositories.Async.IArtifactRepository Artifacts { get; } + Octopus.Client.Repositories.Async.IAzureServicePrincipalAccountRepository AzureServicePrincipalAccounts { get; } Octopus.Client.Repositories.Async.IBackupRepository Backups { get; } Octopus.Client.Repositories.Async.IBuiltInPackageRepositoryRepository BuiltInPackageRepository { get; } Octopus.Client.Repositories.Async.ICertificateConfigurationRepository CertificateConfiguration { get; } @@ -131,6 +132,7 @@ Octopus.Client Octopus.Client.Repositories.Async.IAccountRepository Accounts { get; } Octopus.Client.Repositories.Async.IActionTemplateRepository ActionTemplates { get; } Octopus.Client.Repositories.Async.IArtifactRepository Artifacts { get; } + Octopus.Client.Repositories.Async.IAzureServicePrincipalAccountRepository AzureServicePrincipalAccounts { get; } Octopus.Client.Repositories.Async.IBackupRepository Backups { get; } Octopus.Client.Repositories.Async.IBuiltInPackageRepositoryRepository BuiltInPackageRepository { get; } Octopus.Client.Repositories.Async.ICertificateConfigurationRepository CertificateConfiguration { get; } @@ -631,6 +633,7 @@ Octopus.Client.Extensions } abstract class TypeExtensions { + static Octopus.Client.Model.Accounts.AccountType DetermineAccountType(Type) static Object GetDefault(Type) } abstract class UriExtensions @@ -3407,6 +3410,12 @@ Octopus.Client.Model.Accounts String ResourceManagementEndpointBaseUri { get; set; } String SubscriptionNumber { get; set; } String TenantId { get; set; } + class WebSiteResource + { + .ctor() + String Name { get; } + String ResourceGroup { get; set; } + } } class AzureSubscriptionAccountResource Octopus.Client.Extensibility.IResource @@ -3421,6 +3430,13 @@ Octopus.Client.Model.Accounts String CertificateThumbprint { get; set; } String ServiceManagementEndpointBaseUri { get; set; } String SubscriptionNumber { get; set; } + class WebSiteResource + { + .ctor() + String Name { get; } + String ResourceGroup { get; set; } + String WebSpace { get; set; } + } } class SshKeyPairAccountResource Octopus.Client.Extensibility.IResource @@ -3451,6 +3467,19 @@ Octopus.Client.Model.Accounts Octopus.Client.Model.SensitiveValue Password { get; set; } String Username { get; set; } } + class WebSiteResource + { + .ctor() + String Name { get; } + String ResourceGroup { get; set; } + } + class WebSiteResource + { + .ctor() + String Name { get; } + String ResourceGroup { get; set; } + String WebSpace { get; set; } + } } Octopus.Client.Model.DeploymentProcess { @@ -4028,6 +4057,12 @@ Octopus.Client.Operations } Octopus.Client.Repositories.Async { + class AzureServicePrincipalAccountRepository + Octopus.Client.Repositories.Async.IAzureServicePrincipalAccountRepository + { + .ctor(Octopus.Client.IOctopusAsyncClient) + Task> WebSites(Octopus.Client.Model.Accounts.AzureServicePrincipalAccountResource) + } interface IAccountRepository Octopus.Client.Repositories.Async.ICreate Octopus.Client.Repositories.Async.IModify @@ -4036,6 +4071,16 @@ Octopus.Client.Repositories.Async Octopus.Client.Repositories.Async.IFindByName Octopus.Client.Repositories.Async.IPaginate { + Octopus.Client.Model.Accounts.AccountType DetermineAccountType() + Task> FindAllOfType(Object) + Task FindByNameOfType(String) + Task> FindByNamesOfType(IEnumerable) + Task> FindManyOfType(Func, Object) + Task FindOneOfType(Func, Object) + Task GetOfType(String) + Task> GetOfType(String[]) + Task PaginateOfType(Func, Boolean>, Object) + Task RefreshOfType(Octopus.Client.Repositories.Async.TAccount) } interface IActionTemplateRepository Octopus.Client.Repositories.Async.ICreate @@ -4062,6 +4107,10 @@ Octopus.Client.Repositories.Async Task GetContent(Octopus.Client.Model.ArtifactResource) Task PutContent(Octopus.Client.Model.ArtifactResource, Stream) } + interface IAzureServicePrincipalAccountRepository + { + Task> WebSites(Octopus.Client.Model.Accounts.AzureServicePrincipalAccountResource) + } interface IBackupRepository { Task GetConfiguration() From e898fa23b5388856697d0985a021b197c50f6d44 Mon Sep 17 00:00:00 2001 From: Shannon Lewis Date: Fri, 4 May 2018 14:49:36 +1000 Subject: [PATCH 05/19] replaced the repository idea with Editors --- ...AreaShouldNotRegress..NETCore.approved.txt | 102 +++++++++-- ...houldNotRegress..NETFramework.approved.txt | 172 +++++++++++++++--- .../Octopus.Client/Editors/AccountEditor.cs | 56 ++++++ .../Editors/AmazonWebServicesAccountEditor.cs | 12 ++ .../AmazonWebServicesRoleAccountEditor.cs | 12 ++ .../Editors/Async/AccountEditor.cs | 57 ++++++ .../Async/AmazonWebServicesAccountEditor.cs | 12 ++ .../AmazonWebServicesRoleAccountEditor.cs | 12 ++ .../AzureServicePrincipalAccountEditor.cs | 35 ++++ .../Async/AzureSubscriptionAccountEditor.cs | 34 ++++ .../Editors/Async/SshKeyPairAccountEditor.cs | 12 ++ .../Async/UsernamePasswordAccountEditor.cs | 12 ++ .../AzureServicePrincipalAccountEditor.cs | 34 ++++ .../Editors/AzureSubscriptionAccountEditor.cs | 33 ++++ .../Editors/SshKeyPairAccountEditor.cs | 12 ++ .../Editors/UsernamePasswordAccountEditor.cs | 12 ++ .../Octopus.Client/IOctopusAsyncRepository.cs | 1 - source/Octopus.Client/IOctopusRepository.cs | 1 - .../Model/Accounts/AzureCloudService.cs | 8 + .../AzureServicePrincipalAccountResource.cs | 8 +- .../Model/Accounts/AzureStorageAccount.cs | 8 + .../AzureSubscriptionAccountResource.cs | 2 +- .../Octopus.Client/OctopusAsyncRepository.cs | 2 - source/Octopus.Client/OctopusRepository.cs | 2 - .../AzureServicePrincipalAccountRepository.cs | 26 --- .../AzureServicePrincipalAccountRepository.cs | 25 --- 26 files changed, 599 insertions(+), 103 deletions(-) create mode 100644 source/Octopus.Client/Editors/AccountEditor.cs create mode 100644 source/Octopus.Client/Editors/AmazonWebServicesAccountEditor.cs create mode 100644 source/Octopus.Client/Editors/AmazonWebServicesRoleAccountEditor.cs create mode 100644 source/Octopus.Client/Editors/Async/AccountEditor.cs create mode 100644 source/Octopus.Client/Editors/Async/AmazonWebServicesAccountEditor.cs create mode 100644 source/Octopus.Client/Editors/Async/AmazonWebServicesRoleAccountEditor.cs create mode 100644 source/Octopus.Client/Editors/Async/AzureServicePrincipalAccountEditor.cs create mode 100644 source/Octopus.Client/Editors/Async/AzureSubscriptionAccountEditor.cs create mode 100644 source/Octopus.Client/Editors/Async/SshKeyPairAccountEditor.cs create mode 100644 source/Octopus.Client/Editors/Async/UsernamePasswordAccountEditor.cs create mode 100644 source/Octopus.Client/Editors/AzureServicePrincipalAccountEditor.cs create mode 100644 source/Octopus.Client/Editors/AzureSubscriptionAccountEditor.cs create mode 100644 source/Octopus.Client/Editors/SshKeyPairAccountEditor.cs create mode 100644 source/Octopus.Client/Editors/UsernamePasswordAccountEditor.cs create mode 100644 source/Octopus.Client/Model/Accounts/AzureCloudService.cs create mode 100644 source/Octopus.Client/Model/Accounts/AzureStorageAccount.cs delete mode 100644 source/Octopus.Client/Repositories/Async/AzureServicePrincipalAccountRepository.cs delete mode 100644 source/Octopus.Client/Repositories/AzureServicePrincipalAccountRepository.cs diff --git a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt index 485990451..eaa4f6739 100644 --- a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt +++ b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt @@ -46,7 +46,6 @@ Octopus.Client Octopus.Client.Repositories.Async.IAccountRepository Accounts { get; } Octopus.Client.Repositories.Async.IActionTemplateRepository ActionTemplates { get; } Octopus.Client.Repositories.Async.IArtifactRepository Artifacts { get; } - Octopus.Client.Repositories.Async.IAzureServicePrincipalAccountRepository AzureServicePrincipalAccounts { get; } Octopus.Client.Repositories.Async.IBackupRepository Backups { get; } Octopus.Client.Repositories.Async.IBuiltInPackageRepositoryRepository BuiltInPackageRepository { get; } Octopus.Client.Repositories.Async.ICertificateConfigurationRepository CertificateConfiguration { get; } @@ -132,7 +131,6 @@ Octopus.Client Octopus.Client.Repositories.Async.IAccountRepository Accounts { get; } Octopus.Client.Repositories.Async.IActionTemplateRepository ActionTemplates { get; } Octopus.Client.Repositories.Async.IArtifactRepository Artifacts { get; } - Octopus.Client.Repositories.Async.IAzureServicePrincipalAccountRepository AzureServicePrincipalAccounts { get; } Octopus.Client.Repositories.Async.IBackupRepository Backups { get; } Octopus.Client.Repositories.Async.IBuiltInPackageRepositoryRepository BuiltInPackageRepository { get; } Octopus.Client.Repositories.Async.ICertificateConfigurationRepository CertificateConfiguration { get; } @@ -245,6 +243,50 @@ Octopus.Client } Octopus.Client.Editors.Async { + class AccountEditor`1 + Octopus.Client.Editors.Async.IResourceEditor> + Octopus.Client.Editors.Async.IResourceBuilder + { + .ctor(Octopus.Client.Repositories.Async.IAccountRepository) + Octopus.Client.Editors.Async.TAccountResource Instance { get; } + Task> CreateOrModify(String) + Octopus.Client.Editors.Async.AccountEditor Customize(Action) + Task> Save() + } + class AmazonWebServicesAccountEditor + Octopus.Client.Editors.Async.IResourceEditor> + Octopus.Client.Editors.Async.IResourceBuilder + Octopus.Client.Editors.Async.AccountEditor + { + .ctor(Octopus.Client.Repositories.Async.IAccountRepository) + } + class AmazonWebServicesRoleAccountEditor + Octopus.Client.Editors.Async.IResourceEditor> + Octopus.Client.Editors.Async.IResourceBuilder + Octopus.Client.Editors.Async.AccountEditor + { + .ctor(Octopus.Client.Repositories.Async.IAccountRepository) + } + class AzureServicePrincipalAccountEditor + Octopus.Client.Editors.Async.IResourceEditor> + Octopus.Client.Editors.Async.IResourceBuilder + Octopus.Client.Editors.Async.AccountEditor + { + .ctor(Octopus.Client.IOctopusAsyncClient, Octopus.Client.Repositories.Async.IAccountRepository) + Task> ResourceGroups() + Task> StorageAccounts() + Task> WebSites() + } + class AzureSubscriptionAccountEditor + Octopus.Client.Editors.Async.IResourceEditor> + Octopus.Client.Editors.Async.IResourceBuilder + Octopus.Client.Editors.Async.AccountEditor + { + .ctor(Octopus.Client.IOctopusAsyncClient, Octopus.Client.Repositories.Async.IAccountRepository) + Task> CloudServices(Octopus.Client.Model.Accounts.AzureSubscriptionAccountResource) + Task> StorageAccounts(Octopus.Client.Model.Accounts.AzureSubscriptionAccountResource) + Task> WebSites(Octopus.Client.Model.Accounts.AzureSubscriptionAccountResource) + } class ChannelEditor Octopus.Client.Editors.Async.IResourceEditor Octopus.Client.Editors.Async.IResourceBuilder @@ -392,6 +434,13 @@ Octopus.Client.Editors.Async Task Delete(String) Task SaveAll() } + class SshKeyPairAccountEditor + Octopus.Client.Editors.Async.IResourceEditor> + Octopus.Client.Editors.Async.IResourceBuilder + Octopus.Client.Editors.Async.AccountEditor + { + .ctor(Octopus.Client.Repositories.Async.IAccountRepository) + } class SubscriptionEditor Octopus.Client.Editors.Async.IResourceEditor Octopus.Client.Editors.Async.IResourceBuilder @@ -442,6 +491,13 @@ Octopus.Client.Editors.Async Task Load() Task Save() } + class UsernamePasswordAccountEditor + Octopus.Client.Editors.Async.IResourceEditor> + Octopus.Client.Editors.Async.IResourceBuilder + Octopus.Client.Editors.Async.AccountEditor + { + .ctor(Octopus.Client.Repositories.Async.IAccountRepository) + } class VariableSetEditor Octopus.Client.Editors.Async.IResourceEditor Octopus.Client.Editors.Async.IResourceBuilder @@ -3395,6 +3451,12 @@ Octopus.Client.Model.Accounts .ctor() Octopus.Client.Model.Accounts.AccountType AccountType { get; } } + class AzureCloudService + { + .ctor() + String Location { get; set; } + String Name { get; set; } + } class AzureServicePrincipalAccountResource Octopus.Client.Extensibility.IResource Octopus.Client.Model.IAuditedResource @@ -3410,13 +3472,25 @@ Octopus.Client.Model.Accounts String ResourceManagementEndpointBaseUri { get; set; } String SubscriptionNumber { get; set; } String TenantId { get; set; } - class WebSiteResource + class ResourceGroup + { + .ctor() + String Id { get; set; } + String Name { get; set; } + } + class WebSite { .ctor() String Name { get; } String ResourceGroup { get; set; } } } + class AzureStorageAccount + { + .ctor() + String Location { get; set; } + String Name { get; set; } + } class AzureSubscriptionAccountResource Octopus.Client.Extensibility.IResource Octopus.Client.Model.IAuditedResource @@ -3430,7 +3504,7 @@ Octopus.Client.Model.Accounts String CertificateThumbprint { get; set; } String ServiceManagementEndpointBaseUri { get; set; } String SubscriptionNumber { get; set; } - class WebSiteResource + class WebSite { .ctor() String Name { get; } @@ -3438,6 +3512,12 @@ Octopus.Client.Model.Accounts String WebSpace { get; set; } } } + class ResourceGroup + { + .ctor() + String Id { get; set; } + String Name { get; set; } + } class SshKeyPairAccountResource Octopus.Client.Extensibility.IResource Octopus.Client.Model.IAuditedResource @@ -3467,13 +3547,13 @@ Octopus.Client.Model.Accounts Octopus.Client.Model.SensitiveValue Password { get; set; } String Username { get; set; } } - class WebSiteResource + class WebSite { .ctor() String Name { get; } String ResourceGroup { get; set; } } - class WebSiteResource + class WebSite { .ctor() String Name { get; } @@ -4057,12 +4137,6 @@ Octopus.Client.Operations } Octopus.Client.Repositories.Async { - class AzureServicePrincipalAccountRepository - Octopus.Client.Repositories.Async.IAzureServicePrincipalAccountRepository - { - .ctor(Octopus.Client.IOctopusAsyncClient) - Task> WebSites(Octopus.Client.Model.Accounts.AzureServicePrincipalAccountResource) - } interface IAccountRepository Octopus.Client.Repositories.Async.ICreate Octopus.Client.Repositories.Async.IModify @@ -4107,10 +4181,6 @@ Octopus.Client.Repositories.Async Task GetContent(Octopus.Client.Model.ArtifactResource) Task PutContent(Octopus.Client.Model.ArtifactResource, Stream) } - interface IAzureServicePrincipalAccountRepository - { - Task> WebSites(Octopus.Client.Model.Accounts.AzureServicePrincipalAccountResource) - } interface IBackupRepository { Task GetConfiguration() diff --git a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt index c11d9cc36..8b39cc063 100644 --- a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt +++ b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt @@ -53,7 +53,6 @@ Octopus.Client Octopus.Client.Repositories.Async.IAccountRepository Accounts { get; } Octopus.Client.Repositories.Async.IActionTemplateRepository ActionTemplates { get; } Octopus.Client.Repositories.Async.IArtifactRepository Artifacts { get; } - Octopus.Client.Repositories.Async.IAzureServicePrincipalAccountRepository AzureServicePrincipalAccounts { get; } Octopus.Client.Repositories.Async.IBackupRepository Backups { get; } Octopus.Client.Repositories.Async.IBuiltInPackageRepositoryRepository BuiltInPackageRepository { get; } Octopus.Client.Repositories.Async.ICertificateConfigurationRepository CertificateConfiguration { get; } @@ -132,7 +131,6 @@ Octopus.Client Octopus.Client.Repositories.IAccountRepository Accounts { get; } Octopus.Client.Repositories.IActionTemplateRepository ActionTemplates { get; } Octopus.Client.Repositories.IArtifactRepository Artifacts { get; } - Octopus.Client.Repositories.IAzureServicePrincipalAccountRepository AzureServicePrincipalAccounts { get; } Octopus.Client.Repositories.IBackupRepository Backups { get; } Octopus.Client.Repositories.IBuiltInPackageRepositoryRepository BuiltInPackageRepository { get; } Octopus.Client.Repositories.ICertificateConfigurationRepository CertificateConfiguration { get; } @@ -214,7 +212,6 @@ Octopus.Client Octopus.Client.Repositories.Async.IAccountRepository Accounts { get; } Octopus.Client.Repositories.Async.IActionTemplateRepository ActionTemplates { get; } Octopus.Client.Repositories.Async.IArtifactRepository Artifacts { get; } - Octopus.Client.Repositories.Async.IAzureServicePrincipalAccountRepository AzureServicePrincipalAccounts { get; } Octopus.Client.Repositories.Async.IBackupRepository Backups { get; } Octopus.Client.Repositories.Async.IBuiltInPackageRepositoryRepository BuiltInPackageRepository { get; } Octopus.Client.Repositories.Async.ICertificateConfigurationRepository CertificateConfiguration { get; } @@ -313,7 +310,6 @@ Octopus.Client Octopus.Client.Repositories.IAccountRepository Accounts { get; } Octopus.Client.Repositories.IActionTemplateRepository ActionTemplates { get; } Octopus.Client.Repositories.IArtifactRepository Artifacts { get; } - Octopus.Client.Repositories.IAzureServicePrincipalAccountRepository AzureServicePrincipalAccounts { get; } Octopus.Client.Repositories.IBackupRepository Backups { get; } Octopus.Client.Repositories.IBuiltInPackageRepositoryRepository BuiltInPackageRepository { get; } Octopus.Client.Repositories.ICertificateConfigurationRepository CertificateConfiguration { get; } @@ -410,6 +406,50 @@ Octopus.Client } Octopus.Client.Editors { + class AccountEditor`1 + Octopus.Client.Editors.IResourceEditor> + Octopus.Client.Editors.IResourceBuilder + { + .ctor(Octopus.Client.Repositories.IAccountRepository) + Octopus.Client.Editors.TAccountResource Instance { get; } + Octopus.Client.Editors.AccountEditor CreateOrModify(String) + Octopus.Client.Editors.AccountEditor Customize(Action) + Octopus.Client.Editors.AccountEditor Save() + } + class AmazonWebServicesAccountEditor + Octopus.Client.Editors.IResourceEditor> + Octopus.Client.Editors.IResourceBuilder + Octopus.Client.Editors.AccountEditor + { + .ctor(Octopus.Client.Repositories.IAccountRepository) + } + class AmazonWebServicesRoleAccountEditor + Octopus.Client.Editors.IResourceEditor> + Octopus.Client.Editors.IResourceBuilder + Octopus.Client.Editors.AccountEditor + { + .ctor(Octopus.Client.Repositories.IAccountRepository) + } + class AzureServicePrincipalAccountEditor + Octopus.Client.Editors.IResourceEditor> + Octopus.Client.Editors.IResourceBuilder + Octopus.Client.Editors.AccountEditor + { + .ctor(Octopus.Client.IOctopusClient, Octopus.Client.Repositories.IAccountRepository) + List ResourceGroups() + List StorageAccounts() + List WebSites() + } + class AzureSubscriptionAccountEditor + Octopus.Client.Editors.IResourceEditor> + Octopus.Client.Editors.IResourceBuilder + Octopus.Client.Editors.AccountEditor + { + .ctor(Octopus.Client.IOctopusClient, Octopus.Client.Repositories.IAccountRepository) + List CloudServices(Octopus.Client.Model.Accounts.AzureSubscriptionAccountResource) + List StorageAccounts(Octopus.Client.Model.Accounts.AzureSubscriptionAccountResource) + List WebSites(Octopus.Client.Model.Accounts.AzureSubscriptionAccountResource) + } class ChannelEditor Octopus.Client.Editors.IResourceEditor Octopus.Client.Editors.IResourceBuilder @@ -557,6 +597,13 @@ Octopus.Client.Editors Octopus.Client.Editors.ProjectTriggersEditor Delete(String) Octopus.Client.Editors.ProjectTriggersEditor SaveAll() } + class SshKeyPairAccountEditor + Octopus.Client.Editors.IResourceEditor> + Octopus.Client.Editors.IResourceBuilder + Octopus.Client.Editors.AccountEditor + { + .ctor(Octopus.Client.Repositories.IAccountRepository) + } class SubscriptionEditor Octopus.Client.Editors.IResourceEditor Octopus.Client.Editors.IResourceBuilder @@ -607,6 +654,13 @@ Octopus.Client.Editors Octopus.Client.Editors.TenantVariablesEditor Load() Octopus.Client.Editors.TenantVariablesEditor Save() } + class UsernamePasswordAccountEditor + Octopus.Client.Editors.IResourceEditor> + Octopus.Client.Editors.IResourceBuilder + Octopus.Client.Editors.AccountEditor + { + .ctor(Octopus.Client.Repositories.IAccountRepository) + } class VariableSetEditor Octopus.Client.Editors.IResourceEditor Octopus.Client.Editors.IResourceBuilder @@ -639,6 +693,50 @@ Octopus.Client.Editors } Octopus.Client.Editors.Async { + class AccountEditor`1 + Octopus.Client.Editors.Async.IResourceEditor> + Octopus.Client.Editors.Async.IResourceBuilder + { + .ctor(Octopus.Client.Repositories.Async.IAccountRepository) + Octopus.Client.Editors.Async.TAccountResource Instance { get; } + Task> CreateOrModify(String) + Octopus.Client.Editors.Async.AccountEditor Customize(Action) + Task> Save() + } + class AmazonWebServicesAccountEditor + Octopus.Client.Editors.Async.IResourceEditor> + Octopus.Client.Editors.Async.IResourceBuilder + Octopus.Client.Editors.Async.AccountEditor + { + .ctor(Octopus.Client.Repositories.Async.IAccountRepository) + } + class AmazonWebServicesRoleAccountEditor + Octopus.Client.Editors.Async.IResourceEditor> + Octopus.Client.Editors.Async.IResourceBuilder + Octopus.Client.Editors.Async.AccountEditor + { + .ctor(Octopus.Client.Repositories.Async.IAccountRepository) + } + class AzureServicePrincipalAccountEditor + Octopus.Client.Editors.Async.IResourceEditor> + Octopus.Client.Editors.Async.IResourceBuilder + Octopus.Client.Editors.Async.AccountEditor + { + .ctor(Octopus.Client.IOctopusAsyncClient, Octopus.Client.Repositories.Async.IAccountRepository) + Task> ResourceGroups() + Task> StorageAccounts() + Task> WebSites() + } + class AzureSubscriptionAccountEditor + Octopus.Client.Editors.Async.IResourceEditor> + Octopus.Client.Editors.Async.IResourceBuilder + Octopus.Client.Editors.Async.AccountEditor + { + .ctor(Octopus.Client.IOctopusAsyncClient, Octopus.Client.Repositories.Async.IAccountRepository) + Task> CloudServices(Octopus.Client.Model.Accounts.AzureSubscriptionAccountResource) + Task> StorageAccounts(Octopus.Client.Model.Accounts.AzureSubscriptionAccountResource) + Task> WebSites(Octopus.Client.Model.Accounts.AzureSubscriptionAccountResource) + } class ChannelEditor Octopus.Client.Editors.Async.IResourceEditor Octopus.Client.Editors.Async.IResourceBuilder @@ -786,6 +884,13 @@ Octopus.Client.Editors.Async Task Delete(String) Task SaveAll() } + class SshKeyPairAccountEditor + Octopus.Client.Editors.Async.IResourceEditor> + Octopus.Client.Editors.Async.IResourceBuilder + Octopus.Client.Editors.Async.AccountEditor + { + .ctor(Octopus.Client.Repositories.Async.IAccountRepository) + } class SubscriptionEditor Octopus.Client.Editors.Async.IResourceEditor Octopus.Client.Editors.Async.IResourceBuilder @@ -836,6 +941,13 @@ Octopus.Client.Editors.Async Task Load() Task Save() } + class UsernamePasswordAccountEditor + Octopus.Client.Editors.Async.IResourceEditor> + Octopus.Client.Editors.Async.IResourceBuilder + Octopus.Client.Editors.Async.AccountEditor + { + .ctor(Octopus.Client.Repositories.Async.IAccountRepository) + } class VariableSetEditor Octopus.Client.Editors.Async.IResourceEditor Octopus.Client.Editors.Async.IResourceBuilder @@ -3810,6 +3922,12 @@ Octopus.Client.Model.Accounts .ctor() Octopus.Client.Model.Accounts.AccountType AccountType { get; } } + class AzureCloudService + { + .ctor() + String Location { get; set; } + String Name { get; set; } + } class AzureServicePrincipalAccountResource Octopus.Client.Extensibility.IResource Octopus.Client.Model.IAuditedResource @@ -3825,13 +3943,25 @@ Octopus.Client.Model.Accounts String ResourceManagementEndpointBaseUri { get; set; } String SubscriptionNumber { get; set; } String TenantId { get; set; } - class WebSiteResource + class ResourceGroup + { + .ctor() + String Id { get; set; } + String Name { get; set; } + } + class WebSite { .ctor() String Name { get; } String ResourceGroup { get; set; } } } + class AzureStorageAccount + { + .ctor() + String Location { get; set; } + String Name { get; set; } + } class AzureSubscriptionAccountResource Octopus.Client.Extensibility.IResource Octopus.Client.Model.IAuditedResource @@ -3845,7 +3975,7 @@ Octopus.Client.Model.Accounts String CertificateThumbprint { get; set; } String ServiceManagementEndpointBaseUri { get; set; } String SubscriptionNumber { get; set; } - class WebSiteResource + class WebSite { .ctor() String Name { get; } @@ -3853,6 +3983,12 @@ Octopus.Client.Model.Accounts String WebSpace { get; set; } } } + class ResourceGroup + { + .ctor() + String Id { get; set; } + String Name { get; set; } + } class SshKeyPairAccountResource Octopus.Client.Extensibility.IResource Octopus.Client.Model.IAuditedResource @@ -3883,13 +4019,13 @@ Octopus.Client.Model.Accounts Octopus.Client.Model.SensitiveValue Password { get; set; } String Username { get; set; } } - class WebSiteResource + class WebSite { .ctor() String Name { get; } String ResourceGroup { get; set; } } - class WebSiteResource + class WebSite { .ctor() String Name { get; } @@ -4479,12 +4615,6 @@ Octopus.Client.Operations } Octopus.Client.Repositories { - class AzureServicePrincipalAccountRepository - Octopus.Client.Repositories.IAzureServicePrincipalAccountRepository - { - .ctor(Octopus.Client.IOctopusClient) - List WebSites(Octopus.Client.Model.Accounts.AzureServicePrincipalAccountResource) - } interface IAccountRepository Octopus.Client.Repositories.ICreate Octopus.Client.Repositories.IModify @@ -4529,10 +4659,6 @@ Octopus.Client.Repositories Stream GetContent(Octopus.Client.Model.ArtifactResource) void PutContent(Octopus.Client.Model.ArtifactResource, Stream) } - interface IAzureServicePrincipalAccountRepository - { - List WebSites(Octopus.Client.Model.Accounts.AzureServicePrincipalAccountResource) - } interface IBackupRepository { Octopus.Client.Model.BackupConfigurationResource GetConfiguration() @@ -4967,12 +5093,6 @@ Octopus.Client.Repositories } Octopus.Client.Repositories.Async { - class AzureServicePrincipalAccountRepository - Octopus.Client.Repositories.Async.IAzureServicePrincipalAccountRepository - { - .ctor(Octopus.Client.IOctopusAsyncClient) - Task> WebSites(Octopus.Client.Model.Accounts.AzureServicePrincipalAccountResource) - } interface IAccountRepository Octopus.Client.Repositories.Async.ICreate Octopus.Client.Repositories.Async.IModify @@ -5017,10 +5137,6 @@ Octopus.Client.Repositories.Async Task GetContent(Octopus.Client.Model.ArtifactResource) Task PutContent(Octopus.Client.Model.ArtifactResource, Stream) } - interface IAzureServicePrincipalAccountRepository - { - Task> WebSites(Octopus.Client.Model.Accounts.AzureServicePrincipalAccountResource) - } interface IBackupRepository { Task GetConfiguration() diff --git a/source/Octopus.Client/Editors/AccountEditor.cs b/source/Octopus.Client/Editors/AccountEditor.cs new file mode 100644 index 000000000..f0c0b98cc --- /dev/null +++ b/source/Octopus.Client/Editors/AccountEditor.cs @@ -0,0 +1,56 @@ +using System; +using Octopus.Client.Model.Accounts; +using Octopus.Client.Repositories; + +namespace Octopus.Client.Editors +{ + public class AccountEditor : IResourceEditor> + where TAccountResource : AccountResource, new() + { + private readonly IAccountRepository repository; + + public AccountEditor(IAccountRepository repository) + { + this.repository = repository; + } + + public TAccountResource Instance { get; private set; } + + public AccountEditor CreateOrModify(string name) + { + var existing = repository.FindByName(name); + if (existing == null) + { + Instance = (TAccountResource)repository.Create(new TAccountResource + { + Name = name + }); + } + else + { + if (!(existing is TAccountResource)) + { + throw new ArgumentException($"An account with that name exists but is not of type {typeof(TAccountResource).Name}"); + } + + existing.Name = name; + + Instance = (TAccountResource)repository.Modify(existing); + } + + return this; + } + + public virtual AccountEditor Customize(Action customize) + { + customize?.Invoke(Instance); + return this; + } + + public virtual AccountEditor Save() + { + Instance = (TAccountResource)repository.Modify(Instance); + return this; + } + } +} \ No newline at end of file diff --git a/source/Octopus.Client/Editors/AmazonWebServicesAccountEditor.cs b/source/Octopus.Client/Editors/AmazonWebServicesAccountEditor.cs new file mode 100644 index 000000000..591298327 --- /dev/null +++ b/source/Octopus.Client/Editors/AmazonWebServicesAccountEditor.cs @@ -0,0 +1,12 @@ +using Octopus.Client.Model.Accounts; +using Octopus.Client.Repositories; + +namespace Octopus.Client.Editors +{ + public class AmazonWebServicesAccountEditor : AccountEditor + { + public AmazonWebServicesAccountEditor(IAccountRepository repository) : base(repository) + { + } + } +} \ No newline at end of file diff --git a/source/Octopus.Client/Editors/AmazonWebServicesRoleAccountEditor.cs b/source/Octopus.Client/Editors/AmazonWebServicesRoleAccountEditor.cs new file mode 100644 index 000000000..df15fb730 --- /dev/null +++ b/source/Octopus.Client/Editors/AmazonWebServicesRoleAccountEditor.cs @@ -0,0 +1,12 @@ +using Octopus.Client.Model.Accounts; +using Octopus.Client.Repositories; + +namespace Octopus.Client.Editors +{ + public class AmazonWebServicesRoleAccountEditor : AccountEditor + { + public AmazonWebServicesRoleAccountEditor(IAccountRepository repository) : base(repository) + { + } + } +} \ No newline at end of file diff --git a/source/Octopus.Client/Editors/Async/AccountEditor.cs b/source/Octopus.Client/Editors/Async/AccountEditor.cs new file mode 100644 index 000000000..df1e828df --- /dev/null +++ b/source/Octopus.Client/Editors/Async/AccountEditor.cs @@ -0,0 +1,57 @@ +using System; +using System.Threading.Tasks; +using Octopus.Client.Model.Accounts; +using Octopus.Client.Repositories.Async; + +namespace Octopus.Client.Editors.Async +{ + public class AccountEditor : IResourceEditor> + where TAccountResource : AccountResource, new() + { + private readonly IAccountRepository repository; + + public AccountEditor(IAccountRepository repository) + { + this.repository = repository; + } + + public TAccountResource Instance { get; private set; } + + public async Task> CreateOrModify(string name) + { + var existing = await repository.FindByName(name); + if (existing == null) + { + Instance = (TAccountResource)await repository.Create(new TAccountResource + { + Name = name + }); + } + else + { + if (!(existing is TAccountResource)) + { + throw new ArgumentException($"An account with that name exists but is not of type {typeof(TAccountResource).Name}"); + } + + existing.Name = name; + + Instance = (TAccountResource)await repository.Modify(existing); + } + + return this; + } + + public virtual AccountEditor Customize(Action customize) + { + customize?.Invoke(Instance); + return this; + } + + public virtual async Task> Save() + { + Instance = (TAccountResource)await repository.Modify(Instance).ConfigureAwait(false); + return this; + } + } +} \ No newline at end of file diff --git a/source/Octopus.Client/Editors/Async/AmazonWebServicesAccountEditor.cs b/source/Octopus.Client/Editors/Async/AmazonWebServicesAccountEditor.cs new file mode 100644 index 000000000..093e66734 --- /dev/null +++ b/source/Octopus.Client/Editors/Async/AmazonWebServicesAccountEditor.cs @@ -0,0 +1,12 @@ +using Octopus.Client.Model.Accounts; +using Octopus.Client.Repositories.Async; + +namespace Octopus.Client.Editors.Async +{ + public class AmazonWebServicesAccountEditor : AccountEditor + { + public AmazonWebServicesAccountEditor(IAccountRepository repository) : base(repository) + { + } + } +} \ No newline at end of file diff --git a/source/Octopus.Client/Editors/Async/AmazonWebServicesRoleAccountEditor.cs b/source/Octopus.Client/Editors/Async/AmazonWebServicesRoleAccountEditor.cs new file mode 100644 index 000000000..d8cd6f41e --- /dev/null +++ b/source/Octopus.Client/Editors/Async/AmazonWebServicesRoleAccountEditor.cs @@ -0,0 +1,12 @@ +using Octopus.Client.Model.Accounts; +using Octopus.Client.Repositories.Async; + +namespace Octopus.Client.Editors.Async +{ + public class AmazonWebServicesRoleAccountEditor : AccountEditor + { + public AmazonWebServicesRoleAccountEditor(IAccountRepository repository) : base(repository) + { + } + } +} \ No newline at end of file diff --git a/source/Octopus.Client/Editors/Async/AzureServicePrincipalAccountEditor.cs b/source/Octopus.Client/Editors/Async/AzureServicePrincipalAccountEditor.cs new file mode 100644 index 000000000..06f0174a2 --- /dev/null +++ b/source/Octopus.Client/Editors/Async/AzureServicePrincipalAccountEditor.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Octopus.Client.Model.Accounts; +using Octopus.Client.Repositories.Async; + +namespace Octopus.Client.Editors.Async +{ + public class AzureServicePrincipalAccountEditor : AccountEditor + { + private readonly IOctopusAsyncClient client; + + public AzureServicePrincipalAccountEditor( + IOctopusAsyncClient client, + IAccountRepository repository) : base(repository) + { + this.client = client; + } + + public Task> ResourceGroups() + { + return client.Get>(Instance.Link("ResourceGroups")); + } + + public Task> WebSites() + { + return client.Get>(Instance.Link("WebSites")); + } + + public Task> StorageAccounts() + { + return client.Get>(Instance.Link("StorageAccounts")); + } + } +} \ No newline at end of file diff --git a/source/Octopus.Client/Editors/Async/AzureSubscriptionAccountEditor.cs b/source/Octopus.Client/Editors/Async/AzureSubscriptionAccountEditor.cs new file mode 100644 index 000000000..f4716c6c7 --- /dev/null +++ b/source/Octopus.Client/Editors/Async/AzureSubscriptionAccountEditor.cs @@ -0,0 +1,34 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Octopus.Client.Model.Accounts; +using Octopus.Client.Repositories.Async; + +namespace Octopus.Client.Editors.Async +{ + public class AzureSubscriptionAccountEditor : AccountEditor + { + private readonly IOctopusAsyncClient client; + + public AzureSubscriptionAccountEditor( + IOctopusAsyncClient client, + IAccountRepository repository) : base(repository) + { + this.client = client; + } + + public Task> CloudServices(AzureSubscriptionAccountResource account) + { + return client.Get>(account.Link("CloudServices")); + } + + public Task> StorageAccounts(AzureSubscriptionAccountResource account) + { + return client.Get>(account.Link("StorageAccounts")); + } + + public Task> WebSites(AzureSubscriptionAccountResource account) + { + return client.Get>(account.Link("WebSites")); + } + } +} \ No newline at end of file diff --git a/source/Octopus.Client/Editors/Async/SshKeyPairAccountEditor.cs b/source/Octopus.Client/Editors/Async/SshKeyPairAccountEditor.cs new file mode 100644 index 000000000..36aa3857b --- /dev/null +++ b/source/Octopus.Client/Editors/Async/SshKeyPairAccountEditor.cs @@ -0,0 +1,12 @@ +using Octopus.Client.Model.Accounts; +using Octopus.Client.Repositories.Async; + +namespace Octopus.Client.Editors.Async +{ + public class SshKeyPairAccountEditor : AccountEditor + { + public SshKeyPairAccountEditor(IAccountRepository repository) : base(repository) + { + } + } +} \ No newline at end of file diff --git a/source/Octopus.Client/Editors/Async/UsernamePasswordAccountEditor.cs b/source/Octopus.Client/Editors/Async/UsernamePasswordAccountEditor.cs new file mode 100644 index 000000000..d123f1543 --- /dev/null +++ b/source/Octopus.Client/Editors/Async/UsernamePasswordAccountEditor.cs @@ -0,0 +1,12 @@ +using Octopus.Client.Model.Accounts; +using Octopus.Client.Repositories.Async; + +namespace Octopus.Client.Editors.Async +{ + public class UsernamePasswordAccountEditor : AccountEditor + { + public UsernamePasswordAccountEditor(IAccountRepository repository) : base(repository) + { + } + } +} \ No newline at end of file diff --git a/source/Octopus.Client/Editors/AzureServicePrincipalAccountEditor.cs b/source/Octopus.Client/Editors/AzureServicePrincipalAccountEditor.cs new file mode 100644 index 000000000..9401c736a --- /dev/null +++ b/source/Octopus.Client/Editors/AzureServicePrincipalAccountEditor.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using Octopus.Client.Model.Accounts; +using Octopus.Client.Repositories; + +namespace Octopus.Client.Editors +{ + public class AzureServicePrincipalAccountEditor : AccountEditor + { + private readonly IOctopusClient client; + + public AzureServicePrincipalAccountEditor( + IOctopusClient client, + IAccountRepository repository) : base(repository) + { + this.client = client; + } + + public List ResourceGroups() + { + return client.Get>(Instance.Link("ResourceGroups")); + } + + public List WebSites() + { + return client.Get>(Instance.Link("WebSites")); + } + + public List StorageAccounts() + { + return client.Get>(Instance.Link("StorageAccounts")); + } + } +} \ No newline at end of file diff --git a/source/Octopus.Client/Editors/AzureSubscriptionAccountEditor.cs b/source/Octopus.Client/Editors/AzureSubscriptionAccountEditor.cs new file mode 100644 index 000000000..ce9311473 --- /dev/null +++ b/source/Octopus.Client/Editors/AzureSubscriptionAccountEditor.cs @@ -0,0 +1,33 @@ +using System.Collections.Generic; +using Octopus.Client.Model.Accounts; +using Octopus.Client.Repositories; + +namespace Octopus.Client.Editors +{ + public class AzureSubscriptionAccountEditor : AccountEditor + { + private readonly IOctopusClient client; + + public AzureSubscriptionAccountEditor( + IOctopusClient client, + IAccountRepository repository) : base(repository) + { + this.client = client; + } + + public List CloudServices(AzureSubscriptionAccountResource account) + { + return client.Get>(account.Link("CloudServices")); + } + + public List StorageAccounts(AzureSubscriptionAccountResource account) + { + return client.Get>(account.Link("StorageAccounts")); + } + + public List WebSites(AzureSubscriptionAccountResource account) + { + return client.Get>(account.Link("WebSites")); + } + } +} \ No newline at end of file diff --git a/source/Octopus.Client/Editors/SshKeyPairAccountEditor.cs b/source/Octopus.Client/Editors/SshKeyPairAccountEditor.cs new file mode 100644 index 000000000..98827b6ec --- /dev/null +++ b/source/Octopus.Client/Editors/SshKeyPairAccountEditor.cs @@ -0,0 +1,12 @@ +using Octopus.Client.Model.Accounts; +using Octopus.Client.Repositories; + +namespace Octopus.Client.Editors +{ + public class SshKeyPairAccountEditor : AccountEditor + { + public SshKeyPairAccountEditor(IAccountRepository repository) : base(repository) + { + } + } +} \ No newline at end of file diff --git a/source/Octopus.Client/Editors/UsernamePasswordAccountEditor.cs b/source/Octopus.Client/Editors/UsernamePasswordAccountEditor.cs new file mode 100644 index 000000000..b2f7b380d --- /dev/null +++ b/source/Octopus.Client/Editors/UsernamePasswordAccountEditor.cs @@ -0,0 +1,12 @@ +using Octopus.Client.Model.Accounts; +using Octopus.Client.Repositories; + +namespace Octopus.Client.Editors +{ + public class UsernamePasswordAccountEditor : AccountEditor + { + public UsernamePasswordAccountEditor(IAccountRepository repository) : base(repository) + { + } + } +} \ No newline at end of file diff --git a/source/Octopus.Client/IOctopusAsyncRepository.cs b/source/Octopus.Client/IOctopusAsyncRepository.cs index 3d065d478..cc45ea93d 100644 --- a/source/Octopus.Client/IOctopusAsyncRepository.cs +++ b/source/Octopus.Client/IOctopusAsyncRepository.cs @@ -16,7 +16,6 @@ public interface IOctopusAsyncRepository IOctopusAsyncClient Client { get; } IAccountRepository Accounts { get; } - IAzureServicePrincipalAccountRepository AzureServicePrincipalAccounts { get; } IActionTemplateRepository ActionTemplates { get; } IArtifactRepository Artifacts { get; } IBackupRepository Backups { get; } diff --git a/source/Octopus.Client/IOctopusRepository.cs b/source/Octopus.Client/IOctopusRepository.cs index 8ae90d127..e7fd7883e 100644 --- a/source/Octopus.Client/IOctopusRepository.cs +++ b/source/Octopus.Client/IOctopusRepository.cs @@ -17,7 +17,6 @@ public interface IOctopusRepository IOctopusClient Client { get; } IAccountRepository Accounts { get; } - IAzureServicePrincipalAccountRepository AzureServicePrincipalAccounts { get; } IActionTemplateRepository ActionTemplates { get; } IArtifactRepository Artifacts { get; } IBackupRepository Backups { get; } diff --git a/source/Octopus.Client/Model/Accounts/AzureCloudService.cs b/source/Octopus.Client/Model/Accounts/AzureCloudService.cs new file mode 100644 index 000000000..ac1baa8c9 --- /dev/null +++ b/source/Octopus.Client/Model/Accounts/AzureCloudService.cs @@ -0,0 +1,8 @@ +namespace Octopus.Client.Model.Accounts +{ + public class AzureCloudService + { + public string Name { get; set; } + public string Location { get; set; } + } +} \ No newline at end of file diff --git a/source/Octopus.Client/Model/Accounts/AzureServicePrincipalAccountResource.cs b/source/Octopus.Client/Model/Accounts/AzureServicePrincipalAccountResource.cs index 1baf9105b..67c394b23 100644 --- a/source/Octopus.Client/Model/Accounts/AzureServicePrincipalAccountResource.cs +++ b/source/Octopus.Client/Model/Accounts/AzureServicePrincipalAccountResource.cs @@ -38,10 +38,16 @@ public class AzureServicePrincipalAccountResource : AccountResource [Writeable] public string ActiveDirectoryEndpointBaseUri { get; set; } - public class WebSiteResource + public class WebSite { public string Name { get; } public string ResourceGroup { get; set; } } + + public class ResourceGroup + { + public string Id { get; set; } + public string Name { get; set; } + } } } \ No newline at end of file diff --git a/source/Octopus.Client/Model/Accounts/AzureStorageAccount.cs b/source/Octopus.Client/Model/Accounts/AzureStorageAccount.cs new file mode 100644 index 000000000..54d5baf90 --- /dev/null +++ b/source/Octopus.Client/Model/Accounts/AzureStorageAccount.cs @@ -0,0 +1,8 @@ +namespace Octopus.Client.Model.Accounts +{ + public class AzureStorageAccount + { + public string Name { get; set; } + public string Location { get; set; } + } +} \ No newline at end of file diff --git a/source/Octopus.Client/Model/Accounts/AzureSubscriptionAccountResource.cs b/source/Octopus.Client/Model/Accounts/AzureSubscriptionAccountResource.cs index 6bb960a00..7614c66a0 100644 --- a/source/Octopus.Client/Model/Accounts/AzureSubscriptionAccountResource.cs +++ b/source/Octopus.Client/Model/Accounts/AzureSubscriptionAccountResource.cs @@ -37,7 +37,7 @@ public override AccountType AccountType [Writeable] public string ServiceManagementEndpointBaseUri { get; set; } - public class WebSiteResource + public class WebSite { public string Name { get; } public string WebSpace { get; set; } diff --git a/source/Octopus.Client/OctopusAsyncRepository.cs b/source/Octopus.Client/OctopusAsyncRepository.cs index f58cc5898..c511441bc 100644 --- a/source/Octopus.Client/OctopusAsyncRepository.cs +++ b/source/Octopus.Client/OctopusAsyncRepository.cs @@ -31,7 +31,6 @@ public OctopusAsyncRepository(IOctopusAsyncClient client) this.Client = client; Accounts = new AccountRepository(client); - AzureServicePrincipalAccounts = new AzureServicePrincipalAccountRepository(client); ActionTemplates = new ActionTemplateRepository(client); Artifacts = new ArtifactRepository(client); Backups = new BackupRepository(client); @@ -80,7 +79,6 @@ public OctopusAsyncRepository(IOctopusAsyncClient client) public IOctopusAsyncClient Client { get; } public IAccountRepository Accounts { get; } - public IAzureServicePrincipalAccountRepository AzureServicePrincipalAccounts { get; } public IActionTemplateRepository ActionTemplates { get; } public IArtifactRepository Artifacts { get; } public IBackupRepository Backups { get; } diff --git a/source/Octopus.Client/OctopusRepository.cs b/source/Octopus.Client/OctopusRepository.cs index 76b148c7e..f1afcdc27 100644 --- a/source/Octopus.Client/OctopusRepository.cs +++ b/source/Octopus.Client/OctopusRepository.cs @@ -25,7 +25,6 @@ public OctopusRepository(IOctopusClient client) this.Client = client; Accounts = new AccountRepository(client); - AzureServicePrincipalAccounts = new AzureServicePrincipalAccountRepository(client); ActionTemplates = new ActionTemplateRepository(client); Artifacts = new ArtifactRepository(client); Backups = new BackupRepository(client); @@ -74,7 +73,6 @@ public OctopusRepository(IOctopusClient client) public IOctopusClient Client { get; } public IAccountRepository Accounts { get; } - public IAzureServicePrincipalAccountRepository AzureServicePrincipalAccounts { get; } public IActionTemplateRepository ActionTemplates { get; } public IArtifactRepository Artifacts { get; } public IBackupRepository Backups { get; } diff --git a/source/Octopus.Client/Repositories/Async/AzureServicePrincipalAccountRepository.cs b/source/Octopus.Client/Repositories/Async/AzureServicePrincipalAccountRepository.cs deleted file mode 100644 index 43a409dbd..000000000 --- a/source/Octopus.Client/Repositories/Async/AzureServicePrincipalAccountRepository.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; -using Octopus.Client.Model.Accounts; - -namespace Octopus.Client.Repositories.Async -{ - public interface IAzureServicePrincipalAccountRepository - { - Task> WebSites(AzureServicePrincipalAccountResource account); - } - - public class AzureServicePrincipalAccountRepository : IAzureServicePrincipalAccountRepository - { - private readonly IOctopusAsyncClient client; - - public AzureServicePrincipalAccountRepository(IOctopusAsyncClient client) - { - this.client = client; - } - - public Task> WebSites(AzureServicePrincipalAccountResource account) - { - return client.Get>(account.Link("WebSites")); - } - } -} \ No newline at end of file diff --git a/source/Octopus.Client/Repositories/AzureServicePrincipalAccountRepository.cs b/source/Octopus.Client/Repositories/AzureServicePrincipalAccountRepository.cs deleted file mode 100644 index 4aa760fd4..000000000 --- a/source/Octopus.Client/Repositories/AzureServicePrincipalAccountRepository.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System.Collections.Generic; -using Octopus.Client.Model.Accounts; - -namespace Octopus.Client.Repositories -{ - public interface IAzureServicePrincipalAccountRepository - { - List WebSites(AzureServicePrincipalAccountResource account); - } - - public class AzureServicePrincipalAccountRepository : IAzureServicePrincipalAccountRepository - { - private readonly IOctopusClient client; - - public AzureServicePrincipalAccountRepository(IOctopusClient client) - { - this.client = client; - } - - public List WebSites(AzureServicePrincipalAccountResource account) - { - return client.Get>(account.Link("WebSites")); - } - } -} \ No newline at end of file From e68f1846594bb2626f7c3435c8fc2f587a379c5c Mon Sep 17 00:00:00 2001 From: Ben Pearce Date: Tue, 8 May 2018 13:55:18 +1000 Subject: [PATCH 06/19] added account usage support --- ...houldNotRegress..NETFramework.approved.txt | 71 +++++++++++++++ .../Octopus.Client/Editors/AccountEditor.cs | 10 ++- .../Accounts/Usages/AccountUsageResource.cs | 90 +++++++++++++++++++ source/Octopus.Client/Model/UsageEntry.cs | 20 +++++ .../Repositories/Async/AccountRepository.cs | 9 ++ .../Repositories/IAccountRepository.cs | 9 ++ 6 files changed, 205 insertions(+), 4 deletions(-) create mode 100644 source/Octopus.Client/Model/Accounts/Usages/AccountUsageResource.cs create mode 100644 source/Octopus.Client/Model/UsageEntry.cs diff --git a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt index 8b39cc063..15c7082d5 100644 --- a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt +++ b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt @@ -3715,6 +3715,12 @@ Octopus.Client.Model static System.String MachineIds } } + class UsageEntry`1 + { + Octopus.Client.Model.TEntry Entry { get; } + Boolean IsMissingScopedPermissions { get; } + String MissingId { get; } + } class UserPermissionRestriction { .ctor() @@ -4033,6 +4039,69 @@ Octopus.Client.Model.Accounts String WebSpace { get; set; } } } +Octopus.Client.Model.Accounts.Usages +{ + class AccountUsageResource + Octopus.Client.Extensibility.IResource + Octopus.Client.Model.IAuditedResource + Octopus.Client.Model.Resource + { + .ctor() + ICollection> DeploymentProcesses { get; set; } + ICollection> LibraryVariableSets { get; set; } + ICollection> ProjectVariableSets { get; set; } + ICollection> Releases { get; set; } + ICollection> Targets { get; set; } + } + class LibraryVariableSetUsageEntry + { + .ctor() + String LibraryVariableSetId { get; set; } + String LibraryVariableSetName { get; set; } + } + class ProjectVariableSetUsage + { + .ctor() + Boolean IsCurrentlyBeingUsedInProject { get; set; } + String ProjectId { get; set; } + String ProjectName { get; set; } + String ProjectSlug { get; set; } + ICollection Releases { get; set; } + } + class ReleaseUsage + { + .ctor() + String ProjectId { get; set; } + String ProjectName { get; set; } + ICollection Releases { get; set; } + } + class ReleaseUsageEntry + { + .ctor() + String ReleaseId { get; set; } + String ReleaseVersion { get; set; } + } + class StepUsage + { + .ctor() + String ProjectId { get; set; } + String ProjectName { get; set; } + String ProjectSlug { get; set; } + ICollection Steps { get; set; } + } + class StepUsageEntry + { + .ctor() + String StepId { get; set; } + String StepName { get; set; } + } + class TargetUsageEntry + { + .ctor() + String TargetId { get; set; } + String TargetName { get; set; } + } +} Octopus.Client.Model.DeploymentProcess { class InlineScriptAction @@ -4629,6 +4698,7 @@ Octopus.Client.Repositories List FindByNamesOfType(IEnumerable) List FindManyOfType(Func, Object) Octopus.Client.Repositories.TAccount FindOneOfType(Func, Object) + Octopus.Client.Model.Accounts.Usages.AccountUsageResource GetAccountUsage(String) Octopus.Client.Repositories.TAccount GetOfType(String) List GetOfType(String[]) void PaginateOfType(Func, Boolean>, Object) @@ -5107,6 +5177,7 @@ Octopus.Client.Repositories.Async Task> FindByNamesOfType(IEnumerable) Task> FindManyOfType(Func, Object) Task FindOneOfType(Func, Object) + Task GetAccountUsage(String) Task GetOfType(String) Task> GetOfType(String[]) Task PaginateOfType(Func, Boolean>, Object) diff --git a/source/Octopus.Client/Editors/AccountEditor.cs b/source/Octopus.Client/Editors/AccountEditor.cs index f0c0b98cc..89bb21e6c 100644 --- a/source/Octopus.Client/Editors/AccountEditor.cs +++ b/source/Octopus.Client/Editors/AccountEditor.cs @@ -1,5 +1,6 @@ using System; using Octopus.Client.Model.Accounts; +using Octopus.Client.Model.Accounts.Usages; using Octopus.Client.Repositories; namespace Octopus.Client.Editors @@ -21,7 +22,7 @@ public AccountEditor CreateOrModify(string name) var existing = repository.FindByName(name); if (existing == null) { - Instance = (TAccountResource)repository.Create(new TAccountResource + Instance = (TAccountResource) repository.Create(new TAccountResource { Name = name }); @@ -30,12 +31,13 @@ public AccountEditor CreateOrModify(string name) { if (!(existing is TAccountResource)) { - throw new ArgumentException($"An account with that name exists but is not of type {typeof(TAccountResource).Name}"); + throw new ArgumentException( + $"An account with that name exists but is not of type {typeof(TAccountResource).Name}"); } existing.Name = name; - Instance = (TAccountResource)repository.Modify(existing); + Instance = (TAccountResource) repository.Modify(existing); } return this; @@ -49,7 +51,7 @@ public virtual AccountEditor Customize(Action Save() { - Instance = (TAccountResource)repository.Modify(Instance); + Instance = (TAccountResource) repository.Modify(Instance); return this; } } diff --git a/source/Octopus.Client/Model/Accounts/Usages/AccountUsageResource.cs b/source/Octopus.Client/Model/Accounts/Usages/AccountUsageResource.cs new file mode 100644 index 000000000..d2a38ac31 --- /dev/null +++ b/source/Octopus.Client/Model/Accounts/Usages/AccountUsageResource.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Octopus.Client.Model.Accounts.Usages +{ + public class AccountUsageResource : Resource + { + public AccountUsageResource() + { + Targets = new List>(); + DeploymentProcesses = new List>(); + Releases = new List>(); + ProjectVariableSets = new List>(); + LibraryVariableSets = new List>(); + } + + public ICollection> Targets { get; set; } + public ICollection> DeploymentProcesses { get; set; } + public ICollection> Releases { get; set; } + public ICollection> ProjectVariableSets { get; set; } + public ICollection> LibraryVariableSets { get; set; } + } + + public class TargetUsageEntry + { + public string TargetName { get; set; } + public string TargetId { get; set; } + } + + public class ProjectVariableSetUsage + { + public ProjectVariableSetUsage() + { + Releases = new List(); + } + + public string ProjectSlug { get; set; } + public string ProjectName { get; set; } + public string ProjectId { get; set; } + public ICollection Releases { get; set; } + public bool IsCurrentlyBeingUsedInProject { get; set; } + } + + public class LibraryVariableSetUsageEntry + { + public string LibraryVariableSetId { get; set; } + public string LibraryVariableSetName { get; set; } + } + + public class ReleaseUsage + { + public ReleaseUsage() + { + Releases = new List(); + } + + public string ProjectName { get; set; } + public string ProjectId { get; set; } + public ICollection Releases { get; set; } + } + + public class ReleaseUsageEntry + { + public string ReleaseId { get; set; } + public string ReleaseVersion { get; set; } + } + + public class StepUsage + { + public StepUsage() + { + Steps = new List(); + } + + public string ProjectName { get; set; } + public string ProjectSlug { get; set; } + public string ProjectId { get; set; } + + public ICollection Steps { get; set; } + } + + public class StepUsageEntry + { + public string StepName { get; set; } + public string StepId { get; set; } + } +} diff --git a/source/Octopus.Client/Model/UsageEntry.cs b/source/Octopus.Client/Model/UsageEntry.cs new file mode 100644 index 000000000..4cfe5d926 --- /dev/null +++ b/source/Octopus.Client/Model/UsageEntry.cs @@ -0,0 +1,20 @@ +namespace Octopus.Client.Model +{ + public class UsageEntry + { + UsageEntry(bool isMissingScopedPermissions, string missingId) + { + IsMissingScopedPermissions = isMissingScopedPermissions; + MissingId = missingId; + } + + UsageEntry(TEntry entry) + { + Entry = entry; + } + + public bool IsMissingScopedPermissions { get; } + public string MissingId { get; } + public TEntry Entry { get; } + } +} \ No newline at end of file diff --git a/source/Octopus.Client/Repositories/Async/AccountRepository.cs b/source/Octopus.Client/Repositories/Async/AccountRepository.cs index 15579ab44..031334097 100644 --- a/source/Octopus.Client/Repositories/Async/AccountRepository.cs +++ b/source/Octopus.Client/Repositories/Async/AccountRepository.cs @@ -6,6 +6,7 @@ using Octopus.Client.Extensions; using Octopus.Client.Model; using Octopus.Client.Model.Accounts; +using Octopus.Client.Model.Accounts.Usages; namespace Octopus.Client.Repositories.Async { @@ -24,6 +25,8 @@ public interface IAccountRepository : ICreate, IModify FindOneOfType(Func search, object pathParameters = null) where TAccount : AccountResource; Task> FindManyOfType(Func search, object pathParameters = null) where TAccount : AccountResource; Task> FindAllOfType(object pathParameters = null) where TAccount : AccountResource; + + Task GetAccountUsage(string id); } class AccountRepository : BasicRepository, IAccountRepository @@ -117,6 +120,12 @@ public Task> FindAllOfType(object pathParameters = null return FindManyOfType(x => true, PathParametersOfType(pathParameters)); } + public async Task GetAccountUsage(string id) + { + var account = await Client.Get(id); + return await Client.Get(account.Link("Usages")); + } + public AccountType DetermineAccountType() where TAccount : AccountResource { return typeof(TAccount).DetermineAccountType(); diff --git a/source/Octopus.Client/Repositories/IAccountRepository.cs b/source/Octopus.Client/Repositories/IAccountRepository.cs index fc113b18e..b023b9213 100644 --- a/source/Octopus.Client/Repositories/IAccountRepository.cs +++ b/source/Octopus.Client/Repositories/IAccountRepository.cs @@ -5,6 +5,7 @@ using Octopus.Client.Extensions; using Octopus.Client.Model; using Octopus.Client.Model.Accounts; +using Octopus.Client.Model.Accounts.Usages; namespace Octopus.Client.Repositories { @@ -23,6 +24,8 @@ public interface IAccountRepository : ICreate, IModify(Func search, object pathParameters = null) where TAccount : AccountResource; List FindManyOfType(Func search, object pathParameters = null) where TAccount : AccountResource; List FindAllOfType(object pathParameters = null) where TAccount : AccountResource; + + AccountUsageResource GetAccountUsage(string id); } class AccountRepository : BasicRepository, IAccountRepository @@ -117,5 +120,11 @@ public AccountType DetermineAccountType() where TAccount : AccountReso { return typeof(TAccount).DetermineAccountType(); } + + public AccountUsageResource GetAccountUsage(string id) + { + var account = Client.Get(id); + return Client.Get(account.Link("Usages")); + } } } \ No newline at end of file From 2db194d39ea7ead074dcf97ea537e8a58e7d24b5 Mon Sep 17 00:00:00 2001 From: Ben Pearce Date: Tue, 8 May 2018 14:29:31 +1000 Subject: [PATCH 07/19] Updated .net core test approved surface area --- ...AreaShouldNotRegress..NETCore.approved.txt | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt index eaa4f6739..864a887a2 100644 --- a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt +++ b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt @@ -3244,6 +3244,12 @@ Octopus.Client.Model static System.String MachineIds } } + class UsageEntry`1 + { + Octopus.Client.Model.TEntry Entry { get; } + Boolean IsMissingScopedPermissions { get; } + String MissingId { get; } + } class UserPermissionRestriction { .ctor() @@ -3561,6 +3567,69 @@ Octopus.Client.Model.Accounts String WebSpace { get; set; } } } +Octopus.Client.Model.Accounts.Usages +{ + class AccountUsageResource + Octopus.Client.Extensibility.IResource + Octopus.Client.Model.IAuditedResource + Octopus.Client.Model.Resource + { + .ctor() + ICollection> DeploymentProcesses { get; set; } + ICollection> LibraryVariableSets { get; set; } + ICollection> ProjectVariableSets { get; set; } + ICollection> Releases { get; set; } + ICollection> Targets { get; set; } + } + class LibraryVariableSetUsageEntry + { + .ctor() + String LibraryVariableSetId { get; set; } + String LibraryVariableSetName { get; set; } + } + class ProjectVariableSetUsage + { + .ctor() + Boolean IsCurrentlyBeingUsedInProject { get; set; } + String ProjectId { get; set; } + String ProjectName { get; set; } + String ProjectSlug { get; set; } + ICollection Releases { get; set; } + } + class ReleaseUsage + { + .ctor() + String ProjectId { get; set; } + String ProjectName { get; set; } + ICollection Releases { get; set; } + } + class ReleaseUsageEntry + { + .ctor() + String ReleaseId { get; set; } + String ReleaseVersion { get; set; } + } + class StepUsage + { + .ctor() + String ProjectId { get; set; } + String ProjectName { get; set; } + String ProjectSlug { get; set; } + ICollection Steps { get; set; } + } + class StepUsageEntry + { + .ctor() + String StepId { get; set; } + String StepName { get; set; } + } + class TargetUsageEntry + { + .ctor() + String TargetId { get; set; } + String TargetName { get; set; } + } +} Octopus.Client.Model.DeploymentProcess { class InlineScriptAction @@ -4151,6 +4220,7 @@ Octopus.Client.Repositories.Async Task> FindByNamesOfType(IEnumerable) Task> FindManyOfType(Func, Object) Task FindOneOfType(Func, Object) + Task GetAccountUsage(String) Task GetOfType(String) Task> GetOfType(String[]) Task PaginateOfType(Func, Boolean>, Object) From 46fe4a9b1efbd36525e6a39a6d34eb820e6a215a Mon Sep 17 00:00:00 2001 From: Shannon Lewis Date: Tue, 8 May 2018 15:56:47 +1000 Subject: [PATCH 08/19] reworking some of the generics to make the test code in Octopus work --- source/Octopus.Client/Editors/AccountEditor.cs | 15 ++++++++------- .../Editors/AmazonWebServicesAccountEditor.cs | 2 +- .../Editors/AmazonWebServicesRoleAccountEditor.cs | 2 +- .../Octopus.Client/Editors/Async/AccountEditor.cs | 15 ++++++++------- .../Async/AmazonWebServicesAccountEditor.cs | 2 +- .../Async/AmazonWebServicesRoleAccountEditor.cs | 2 +- .../Async/AzureSubscriptionAccountEditor.cs | 2 +- .../Editors/Async/SshKeyPairAccountEditor.cs | 2 +- .../Async/UsernamePasswordAccountEditor.cs | 2 +- .../Editors/AzureServicePrincipalAccountEditor.cs | 7 ++++++- .../Editors/AzureSubscriptionAccountEditor.cs | 2 +- .../Editors/SshKeyPairAccountEditor.cs | 2 +- .../Editors/UsernamePasswordAccountEditor.cs | 2 +- 13 files changed, 32 insertions(+), 25 deletions(-) diff --git a/source/Octopus.Client/Editors/AccountEditor.cs b/source/Octopus.Client/Editors/AccountEditor.cs index f0c0b98cc..d459df22b 100644 --- a/source/Octopus.Client/Editors/AccountEditor.cs +++ b/source/Octopus.Client/Editors/AccountEditor.cs @@ -4,8 +4,9 @@ namespace Octopus.Client.Editors { - public class AccountEditor : IResourceEditor> + public class AccountEditor : IResourceEditor where TAccountResource : AccountResource, new() + where TAccountEditor : AccountEditor { private readonly IAccountRepository repository; @@ -16,7 +17,7 @@ public AccountEditor(IAccountRepository repository) public TAccountResource Instance { get; private set; } - public AccountEditor CreateOrModify(string name) + public virtual TAccountEditor CreateOrModify(string name) { var existing = repository.FindByName(name); if (existing == null) @@ -38,19 +39,19 @@ public AccountEditor CreateOrModify(string name) Instance = (TAccountResource)repository.Modify(existing); } - return this; + return (TAccountEditor) this; } - public virtual AccountEditor Customize(Action customize) + public virtual TAccountEditor Customize(Action customize) { customize?.Invoke(Instance); - return this; + return (TAccountEditor)this; } - public virtual AccountEditor Save() + public virtual TAccountEditor Save() { Instance = (TAccountResource)repository.Modify(Instance); - return this; + return (TAccountEditor)this; } } } \ No newline at end of file diff --git a/source/Octopus.Client/Editors/AmazonWebServicesAccountEditor.cs b/source/Octopus.Client/Editors/AmazonWebServicesAccountEditor.cs index 591298327..a2849cac9 100644 --- a/source/Octopus.Client/Editors/AmazonWebServicesAccountEditor.cs +++ b/source/Octopus.Client/Editors/AmazonWebServicesAccountEditor.cs @@ -3,7 +3,7 @@ namespace Octopus.Client.Editors { - public class AmazonWebServicesAccountEditor : AccountEditor + public class AmazonWebServicesAccountEditor : AccountEditor { public AmazonWebServicesAccountEditor(IAccountRepository repository) : base(repository) { diff --git a/source/Octopus.Client/Editors/AmazonWebServicesRoleAccountEditor.cs b/source/Octopus.Client/Editors/AmazonWebServicesRoleAccountEditor.cs index df15fb730..a6152693c 100644 --- a/source/Octopus.Client/Editors/AmazonWebServicesRoleAccountEditor.cs +++ b/source/Octopus.Client/Editors/AmazonWebServicesRoleAccountEditor.cs @@ -3,7 +3,7 @@ namespace Octopus.Client.Editors { - public class AmazonWebServicesRoleAccountEditor : AccountEditor + public class AmazonWebServicesRoleAccountEditor : AccountEditor { public AmazonWebServicesRoleAccountEditor(IAccountRepository repository) : base(repository) { diff --git a/source/Octopus.Client/Editors/Async/AccountEditor.cs b/source/Octopus.Client/Editors/Async/AccountEditor.cs index df1e828df..2dd35e50a 100644 --- a/source/Octopus.Client/Editors/Async/AccountEditor.cs +++ b/source/Octopus.Client/Editors/Async/AccountEditor.cs @@ -5,8 +5,9 @@ namespace Octopus.Client.Editors.Async { - public class AccountEditor : IResourceEditor> + public class AccountEditor : IResourceEditor where TAccountResource : AccountResource, new() + where TAccountEditor : AccountEditor { private readonly IAccountRepository repository; @@ -17,7 +18,7 @@ public AccountEditor(IAccountRepository repository) public TAccountResource Instance { get; private set; } - public async Task> CreateOrModify(string name) + public async Task CreateOrModify(string name) { var existing = await repository.FindByName(name); if (existing == null) @@ -39,19 +40,19 @@ public async Task> CreateOrModify(string name) Instance = (TAccountResource)await repository.Modify(existing); } - return this; + return (TAccountEditor)this; } - public virtual AccountEditor Customize(Action customize) + public virtual TAccountEditor Customize(Action customize) { customize?.Invoke(Instance); - return this; + return (TAccountEditor)this; } - public virtual async Task> Save() + public virtual async Task Save() { Instance = (TAccountResource)await repository.Modify(Instance).ConfigureAwait(false); - return this; + return (TAccountEditor)this; } } } \ No newline at end of file diff --git a/source/Octopus.Client/Editors/Async/AmazonWebServicesAccountEditor.cs b/source/Octopus.Client/Editors/Async/AmazonWebServicesAccountEditor.cs index 093e66734..82f01ffe2 100644 --- a/source/Octopus.Client/Editors/Async/AmazonWebServicesAccountEditor.cs +++ b/source/Octopus.Client/Editors/Async/AmazonWebServicesAccountEditor.cs @@ -3,7 +3,7 @@ namespace Octopus.Client.Editors.Async { - public class AmazonWebServicesAccountEditor : AccountEditor + public class AmazonWebServicesAccountEditor : AccountEditor { public AmazonWebServicesAccountEditor(IAccountRepository repository) : base(repository) { diff --git a/source/Octopus.Client/Editors/Async/AmazonWebServicesRoleAccountEditor.cs b/source/Octopus.Client/Editors/Async/AmazonWebServicesRoleAccountEditor.cs index d8cd6f41e..9f5215e82 100644 --- a/source/Octopus.Client/Editors/Async/AmazonWebServicesRoleAccountEditor.cs +++ b/source/Octopus.Client/Editors/Async/AmazonWebServicesRoleAccountEditor.cs @@ -3,7 +3,7 @@ namespace Octopus.Client.Editors.Async { - public class AmazonWebServicesRoleAccountEditor : AccountEditor + public class AmazonWebServicesRoleAccountEditor : AccountEditor { public AmazonWebServicesRoleAccountEditor(IAccountRepository repository) : base(repository) { diff --git a/source/Octopus.Client/Editors/Async/AzureSubscriptionAccountEditor.cs b/source/Octopus.Client/Editors/Async/AzureSubscriptionAccountEditor.cs index f4716c6c7..35809a865 100644 --- a/source/Octopus.Client/Editors/Async/AzureSubscriptionAccountEditor.cs +++ b/source/Octopus.Client/Editors/Async/AzureSubscriptionAccountEditor.cs @@ -5,7 +5,7 @@ namespace Octopus.Client.Editors.Async { - public class AzureSubscriptionAccountEditor : AccountEditor + public class AzureSubscriptionAccountEditor : AccountEditor { private readonly IOctopusAsyncClient client; diff --git a/source/Octopus.Client/Editors/Async/SshKeyPairAccountEditor.cs b/source/Octopus.Client/Editors/Async/SshKeyPairAccountEditor.cs index 36aa3857b..479bb3cba 100644 --- a/source/Octopus.Client/Editors/Async/SshKeyPairAccountEditor.cs +++ b/source/Octopus.Client/Editors/Async/SshKeyPairAccountEditor.cs @@ -3,7 +3,7 @@ namespace Octopus.Client.Editors.Async { - public class SshKeyPairAccountEditor : AccountEditor + public class SshKeyPairAccountEditor : AccountEditor { public SshKeyPairAccountEditor(IAccountRepository repository) : base(repository) { diff --git a/source/Octopus.Client/Editors/Async/UsernamePasswordAccountEditor.cs b/source/Octopus.Client/Editors/Async/UsernamePasswordAccountEditor.cs index d123f1543..c513cb479 100644 --- a/source/Octopus.Client/Editors/Async/UsernamePasswordAccountEditor.cs +++ b/source/Octopus.Client/Editors/Async/UsernamePasswordAccountEditor.cs @@ -3,7 +3,7 @@ namespace Octopus.Client.Editors.Async { - public class UsernamePasswordAccountEditor : AccountEditor + public class UsernamePasswordAccountEditor : AccountEditor { public UsernamePasswordAccountEditor(IAccountRepository repository) : base(repository) { diff --git a/source/Octopus.Client/Editors/AzureServicePrincipalAccountEditor.cs b/source/Octopus.Client/Editors/AzureServicePrincipalAccountEditor.cs index 9401c736a..4d928fa7d 100644 --- a/source/Octopus.Client/Editors/AzureServicePrincipalAccountEditor.cs +++ b/source/Octopus.Client/Editors/AzureServicePrincipalAccountEditor.cs @@ -5,7 +5,7 @@ namespace Octopus.Client.Editors { - public class AzureServicePrincipalAccountEditor : AccountEditor + public class AzureServicePrincipalAccountEditor : AccountEditor { private readonly IOctopusClient client; @@ -16,6 +16,11 @@ public AzureServicePrincipalAccountEditor( this.client = client; } + public override AzureServicePrincipalAccountEditor CreateOrModify(string name) + { + return base.CreateOrModify(name); + } + public List ResourceGroups() { return client.Get>(Instance.Link("ResourceGroups")); diff --git a/source/Octopus.Client/Editors/AzureSubscriptionAccountEditor.cs b/source/Octopus.Client/Editors/AzureSubscriptionAccountEditor.cs index ce9311473..eaffcba23 100644 --- a/source/Octopus.Client/Editors/AzureSubscriptionAccountEditor.cs +++ b/source/Octopus.Client/Editors/AzureSubscriptionAccountEditor.cs @@ -4,7 +4,7 @@ namespace Octopus.Client.Editors { - public class AzureSubscriptionAccountEditor : AccountEditor + public class AzureSubscriptionAccountEditor : AccountEditor { private readonly IOctopusClient client; diff --git a/source/Octopus.Client/Editors/SshKeyPairAccountEditor.cs b/source/Octopus.Client/Editors/SshKeyPairAccountEditor.cs index 98827b6ec..3d3b0d686 100644 --- a/source/Octopus.Client/Editors/SshKeyPairAccountEditor.cs +++ b/source/Octopus.Client/Editors/SshKeyPairAccountEditor.cs @@ -3,7 +3,7 @@ namespace Octopus.Client.Editors { - public class SshKeyPairAccountEditor : AccountEditor + public class SshKeyPairAccountEditor : AccountEditor { public SshKeyPairAccountEditor(IAccountRepository repository) : base(repository) { diff --git a/source/Octopus.Client/Editors/UsernamePasswordAccountEditor.cs b/source/Octopus.Client/Editors/UsernamePasswordAccountEditor.cs index b2f7b380d..45a865750 100644 --- a/source/Octopus.Client/Editors/UsernamePasswordAccountEditor.cs +++ b/source/Octopus.Client/Editors/UsernamePasswordAccountEditor.cs @@ -3,7 +3,7 @@ namespace Octopus.Client.Editors { - public class UsernamePasswordAccountEditor : AccountEditor + public class UsernamePasswordAccountEditor : AccountEditor { public UsernamePasswordAccountEditor(IAccountRepository repository) : base(repository) { From 3ff3a5c4d20d080fe1ce4c169f5c89c968f15960 Mon Sep 17 00:00:00 2001 From: Shannon Lewis Date: Tue, 8 May 2018 16:55:57 +1000 Subject: [PATCH 09/19] refactored the account editors --- .../Conventions/ClientConventions.cs | 4 +- ...AreaShouldNotRegress..NETCore.approved.txt | 44 ++++++---- ...houldNotRegress..NETFramework.approved.txt | 88 +++++++++++-------- .../Octopus.Client/Editors/AccountEditor.cs | 17 ++-- .../Editors/Async/AccountEditor.cs | 18 ++-- .../AzureServicePrincipalAccountEditor.cs | 13 +-- .../Async/AzureSubscriptionAccountEditor.cs | 13 +-- .../AzureServicePrincipalAccountEditor.cs | 13 +-- .../Editors/AzureSubscriptionAccountEditor.cs | 13 +-- .../Repositories/Async/AccountRepository.cs | 2 +- .../Repositories/Async/IResourceRepository.cs | 7 ++ .../Repositories/IAccountRepository.cs | 2 +- .../Repositories/IResourceRepository.cs | 7 ++ 13 files changed, 132 insertions(+), 109 deletions(-) create mode 100644 source/Octopus.Client/Repositories/Async/IResourceRepository.cs create mode 100644 source/Octopus.Client/Repositories/IResourceRepository.cs diff --git a/source/Octopus.Client.Tests/Conventions/ClientConventions.cs b/source/Octopus.Client.Tests/Conventions/ClientConventions.cs index d68d9950e..3e4ab4e09 100644 --- a/source/Octopus.Client.Tests/Conventions/ClientConventions.cs +++ b/source/Octopus.Client.Tests/Conventions/ClientConventions.cs @@ -25,9 +25,9 @@ public class ClientConventions private static readonly TypeInfo[] RepositoryInterfaceTypes = ExportedTypes .Where(t => t.IsInterface && t.Name.EndsWith("Repository")) - .Where(t => t.AsType() != typeof(IOctopusAsyncRepository)) + .Where(t => t.AsType() != typeof(IOctopusAsyncRepository) && t.AsType() != typeof(IResourceRepository)) #if SYNC_CLIENT - .Where(t => t.AsType() != typeof(IOctopusRepository)) + .Where(t => t.AsType() != typeof(IOctopusRepository) && t.AsType() != typeof(Sync.IResourceRepository)) #endif .ToArray(); diff --git a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt index 864a887a2..e8421131f 100644 --- a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt +++ b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt @@ -243,46 +243,47 @@ Octopus.Client } Octopus.Client.Editors.Async { - class AccountEditor`1 - Octopus.Client.Editors.Async.IResourceEditor> + class AccountEditor`2 + Octopus.Client.Editors.Async.IResourceEditor Octopus.Client.Editors.Async.IResourceBuilder { .ctor(Octopus.Client.Repositories.Async.IAccountRepository) Octopus.Client.Editors.Async.TAccountResource Instance { get; } - Task> CreateOrModify(String) - Octopus.Client.Editors.Async.AccountEditor Customize(Action) - Task> Save() + Task CreateOrModify(String) + Octopus.Client.Editors.Async.TAccountEditor Customize(Action) + Task Save() + Task Usage() } class AmazonWebServicesAccountEditor - Octopus.Client.Editors.Async.IResourceEditor> + Octopus.Client.Editors.Async.IResourceEditor Octopus.Client.Editors.Async.IResourceBuilder - Octopus.Client.Editors.Async.AccountEditor + Octopus.Client.Editors.Async.AccountEditor { .ctor(Octopus.Client.Repositories.Async.IAccountRepository) } class AmazonWebServicesRoleAccountEditor - Octopus.Client.Editors.Async.IResourceEditor> + Octopus.Client.Editors.Async.IResourceEditor Octopus.Client.Editors.Async.IResourceBuilder - Octopus.Client.Editors.Async.AccountEditor + Octopus.Client.Editors.Async.AccountEditor { .ctor(Octopus.Client.Repositories.Async.IAccountRepository) } class AzureServicePrincipalAccountEditor - Octopus.Client.Editors.Async.IResourceEditor> + Octopus.Client.Editors.Async.IResourceEditor Octopus.Client.Editors.Async.IResourceBuilder - Octopus.Client.Editors.Async.AccountEditor + Octopus.Client.Editors.Async.AccountEditor { - .ctor(Octopus.Client.IOctopusAsyncClient, Octopus.Client.Repositories.Async.IAccountRepository) + .ctor(Octopus.Client.Repositories.Async.IAccountRepository) Task> ResourceGroups() Task> StorageAccounts() Task> WebSites() } class AzureSubscriptionAccountEditor - Octopus.Client.Editors.Async.IResourceEditor> + Octopus.Client.Editors.Async.IResourceEditor Octopus.Client.Editors.Async.IResourceBuilder - Octopus.Client.Editors.Async.AccountEditor + Octopus.Client.Editors.Async.AccountEditor { - .ctor(Octopus.Client.IOctopusAsyncClient, Octopus.Client.Repositories.Async.IAccountRepository) + .ctor(Octopus.Client.Repositories.Async.IAccountRepository) Task> CloudServices(Octopus.Client.Model.Accounts.AzureSubscriptionAccountResource) Task> StorageAccounts(Octopus.Client.Model.Accounts.AzureSubscriptionAccountResource) Task> WebSites(Octopus.Client.Model.Accounts.AzureSubscriptionAccountResource) @@ -435,9 +436,9 @@ Octopus.Client.Editors.Async Task SaveAll() } class SshKeyPairAccountEditor - Octopus.Client.Editors.Async.IResourceEditor> + Octopus.Client.Editors.Async.IResourceEditor Octopus.Client.Editors.Async.IResourceBuilder - Octopus.Client.Editors.Async.AccountEditor + Octopus.Client.Editors.Async.AccountEditor { .ctor(Octopus.Client.Repositories.Async.IAccountRepository) } @@ -492,9 +493,9 @@ Octopus.Client.Editors.Async Task Save() } class UsernamePasswordAccountEditor - Octopus.Client.Editors.Async.IResourceEditor> + Octopus.Client.Editors.Async.IResourceEditor Octopus.Client.Editors.Async.IResourceBuilder - Octopus.Client.Editors.Async.AccountEditor + Octopus.Client.Editors.Async.AccountEditor { .ctor(Octopus.Client.Repositories.Async.IAccountRepository) } @@ -4207,6 +4208,7 @@ Octopus.Client.Operations Octopus.Client.Repositories.Async { interface IAccountRepository + Octopus.Client.Repositories.Async.IResourceRepository Octopus.Client.Repositories.Async.ICreate Octopus.Client.Repositories.Async.IModify Octopus.Client.Repositories.Async.IDelete @@ -4553,6 +4555,10 @@ Octopus.Client.Repositories.Async Task Modify(Octopus.Client.Model.ReleaseResource, Boolean) Task SnapshotVariables(Octopus.Client.Model.ReleaseResource) } + interface IResourceRepository + { + Octopus.Client.IOctopusAsyncClient Client { get; } + } interface IRetentionPolicyRepository { Task ApplyNow() diff --git a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt index 15c7082d5..a979b794e 100644 --- a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt +++ b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt @@ -406,46 +406,47 @@ Octopus.Client } Octopus.Client.Editors { - class AccountEditor`1 - Octopus.Client.Editors.IResourceEditor> + class AccountEditor`2 + Octopus.Client.Editors.IResourceEditor Octopus.Client.Editors.IResourceBuilder { .ctor(Octopus.Client.Repositories.IAccountRepository) Octopus.Client.Editors.TAccountResource Instance { get; } - Octopus.Client.Editors.AccountEditor CreateOrModify(String) - Octopus.Client.Editors.AccountEditor Customize(Action) - Octopus.Client.Editors.AccountEditor Save() + Octopus.Client.Editors.TAccountEditor CreateOrModify(String) + Octopus.Client.Editors.TAccountEditor Customize(Action) + Octopus.Client.Editors.TAccountEditor Save() + Octopus.Client.Model.Accounts.Usages.AccountUsageResource Usage() } class AmazonWebServicesAccountEditor - Octopus.Client.Editors.IResourceEditor> + Octopus.Client.Editors.IResourceEditor Octopus.Client.Editors.IResourceBuilder - Octopus.Client.Editors.AccountEditor + Octopus.Client.Editors.AccountEditor { .ctor(Octopus.Client.Repositories.IAccountRepository) } class AmazonWebServicesRoleAccountEditor - Octopus.Client.Editors.IResourceEditor> + Octopus.Client.Editors.IResourceEditor Octopus.Client.Editors.IResourceBuilder - Octopus.Client.Editors.AccountEditor + Octopus.Client.Editors.AccountEditor { .ctor(Octopus.Client.Repositories.IAccountRepository) } class AzureServicePrincipalAccountEditor - Octopus.Client.Editors.IResourceEditor> + Octopus.Client.Editors.IResourceEditor Octopus.Client.Editors.IResourceBuilder - Octopus.Client.Editors.AccountEditor + Octopus.Client.Editors.AccountEditor { - .ctor(Octopus.Client.IOctopusClient, Octopus.Client.Repositories.IAccountRepository) + .ctor(Octopus.Client.Repositories.IAccountRepository) List ResourceGroups() List StorageAccounts() List WebSites() } class AzureSubscriptionAccountEditor - Octopus.Client.Editors.IResourceEditor> + Octopus.Client.Editors.IResourceEditor Octopus.Client.Editors.IResourceBuilder - Octopus.Client.Editors.AccountEditor + Octopus.Client.Editors.AccountEditor { - .ctor(Octopus.Client.IOctopusClient, Octopus.Client.Repositories.IAccountRepository) + .ctor(Octopus.Client.Repositories.IAccountRepository) List CloudServices(Octopus.Client.Model.Accounts.AzureSubscriptionAccountResource) List StorageAccounts(Octopus.Client.Model.Accounts.AzureSubscriptionAccountResource) List WebSites(Octopus.Client.Model.Accounts.AzureSubscriptionAccountResource) @@ -598,9 +599,9 @@ Octopus.Client.Editors Octopus.Client.Editors.ProjectTriggersEditor SaveAll() } class SshKeyPairAccountEditor - Octopus.Client.Editors.IResourceEditor> + Octopus.Client.Editors.IResourceEditor Octopus.Client.Editors.IResourceBuilder - Octopus.Client.Editors.AccountEditor + Octopus.Client.Editors.AccountEditor { .ctor(Octopus.Client.Repositories.IAccountRepository) } @@ -655,9 +656,9 @@ Octopus.Client.Editors Octopus.Client.Editors.TenantVariablesEditor Save() } class UsernamePasswordAccountEditor - Octopus.Client.Editors.IResourceEditor> + Octopus.Client.Editors.IResourceEditor Octopus.Client.Editors.IResourceBuilder - Octopus.Client.Editors.AccountEditor + Octopus.Client.Editors.AccountEditor { .ctor(Octopus.Client.Repositories.IAccountRepository) } @@ -693,46 +694,47 @@ Octopus.Client.Editors } Octopus.Client.Editors.Async { - class AccountEditor`1 - Octopus.Client.Editors.Async.IResourceEditor> + class AccountEditor`2 + Octopus.Client.Editors.Async.IResourceEditor Octopus.Client.Editors.Async.IResourceBuilder { .ctor(Octopus.Client.Repositories.Async.IAccountRepository) Octopus.Client.Editors.Async.TAccountResource Instance { get; } - Task> CreateOrModify(String) - Octopus.Client.Editors.Async.AccountEditor Customize(Action) - Task> Save() + Task CreateOrModify(String) + Octopus.Client.Editors.Async.TAccountEditor Customize(Action) + Task Save() + Task Usage() } class AmazonWebServicesAccountEditor - Octopus.Client.Editors.Async.IResourceEditor> + Octopus.Client.Editors.Async.IResourceEditor Octopus.Client.Editors.Async.IResourceBuilder - Octopus.Client.Editors.Async.AccountEditor + Octopus.Client.Editors.Async.AccountEditor { .ctor(Octopus.Client.Repositories.Async.IAccountRepository) } class AmazonWebServicesRoleAccountEditor - Octopus.Client.Editors.Async.IResourceEditor> + Octopus.Client.Editors.Async.IResourceEditor Octopus.Client.Editors.Async.IResourceBuilder - Octopus.Client.Editors.Async.AccountEditor + Octopus.Client.Editors.Async.AccountEditor { .ctor(Octopus.Client.Repositories.Async.IAccountRepository) } class AzureServicePrincipalAccountEditor - Octopus.Client.Editors.Async.IResourceEditor> + Octopus.Client.Editors.Async.IResourceEditor Octopus.Client.Editors.Async.IResourceBuilder - Octopus.Client.Editors.Async.AccountEditor + Octopus.Client.Editors.Async.AccountEditor { - .ctor(Octopus.Client.IOctopusAsyncClient, Octopus.Client.Repositories.Async.IAccountRepository) + .ctor(Octopus.Client.Repositories.Async.IAccountRepository) Task> ResourceGroups() Task> StorageAccounts() Task> WebSites() } class AzureSubscriptionAccountEditor - Octopus.Client.Editors.Async.IResourceEditor> + Octopus.Client.Editors.Async.IResourceEditor Octopus.Client.Editors.Async.IResourceBuilder - Octopus.Client.Editors.Async.AccountEditor + Octopus.Client.Editors.Async.AccountEditor { - .ctor(Octopus.Client.IOctopusAsyncClient, Octopus.Client.Repositories.Async.IAccountRepository) + .ctor(Octopus.Client.Repositories.Async.IAccountRepository) Task> CloudServices(Octopus.Client.Model.Accounts.AzureSubscriptionAccountResource) Task> StorageAccounts(Octopus.Client.Model.Accounts.AzureSubscriptionAccountResource) Task> WebSites(Octopus.Client.Model.Accounts.AzureSubscriptionAccountResource) @@ -885,9 +887,9 @@ Octopus.Client.Editors.Async Task SaveAll() } class SshKeyPairAccountEditor - Octopus.Client.Editors.Async.IResourceEditor> + Octopus.Client.Editors.Async.IResourceEditor Octopus.Client.Editors.Async.IResourceBuilder - Octopus.Client.Editors.Async.AccountEditor + Octopus.Client.Editors.Async.AccountEditor { .ctor(Octopus.Client.Repositories.Async.IAccountRepository) } @@ -942,9 +944,9 @@ Octopus.Client.Editors.Async Task Save() } class UsernamePasswordAccountEditor - Octopus.Client.Editors.Async.IResourceEditor> + Octopus.Client.Editors.Async.IResourceEditor Octopus.Client.Editors.Async.IResourceBuilder - Octopus.Client.Editors.Async.AccountEditor + Octopus.Client.Editors.Async.AccountEditor { .ctor(Octopus.Client.Repositories.Async.IAccountRepository) } @@ -4685,6 +4687,7 @@ Octopus.Client.Operations Octopus.Client.Repositories { interface IAccountRepository + Octopus.Client.Repositories.IResourceRepository Octopus.Client.Repositories.ICreate Octopus.Client.Repositories.IModify Octopus.Client.Repositories.IDelete @@ -5031,6 +5034,10 @@ Octopus.Client.Repositories Octopus.Client.Model.ReleaseResource Modify(Octopus.Client.Model.ReleaseResource, Boolean) Octopus.Client.Model.ReleaseResource SnapshotVariables(Octopus.Client.Model.ReleaseResource) } + interface IResourceRepository + { + Octopus.Client.IOctopusClient Client { get; } + } interface IRetentionPolicyRepository { Octopus.Client.Model.TaskResource ApplyNow() @@ -5164,6 +5171,7 @@ Octopus.Client.Repositories Octopus.Client.Repositories.Async { interface IAccountRepository + Octopus.Client.Repositories.Async.IResourceRepository Octopus.Client.Repositories.Async.ICreate Octopus.Client.Repositories.Async.IModify Octopus.Client.Repositories.Async.IDelete @@ -5510,6 +5518,10 @@ Octopus.Client.Repositories.Async Task Modify(Octopus.Client.Model.ReleaseResource, Boolean) Task SnapshotVariables(Octopus.Client.Model.ReleaseResource) } + interface IResourceRepository + { + Octopus.Client.IOctopusAsyncClient Client { get; } + } interface IRetentionPolicyRepository { Task ApplyNow() diff --git a/source/Octopus.Client/Editors/AccountEditor.cs b/source/Octopus.Client/Editors/AccountEditor.cs index 07cb1e5e6..17ed586ce 100644 --- a/source/Octopus.Client/Editors/AccountEditor.cs +++ b/source/Octopus.Client/Editors/AccountEditor.cs @@ -9,21 +9,21 @@ public class AccountEditor : IResourceEditor { - private readonly IAccountRepository repository; + protected readonly IAccountRepository Repository; public AccountEditor(IAccountRepository repository) { - this.repository = repository; + Repository = repository; } public TAccountResource Instance { get; private set; } public TAccountEditor CreateOrModify(string name) { - var existing = repository.FindByName(name); + var existing = Repository.FindByName(name); if (existing == null) { - Instance = (TAccountResource) repository.Create(new TAccountResource + Instance = (TAccountResource) Repository.Create(new TAccountResource { Name = name }); @@ -38,7 +38,7 @@ public TAccountEditor CreateOrModify(string name) existing.Name = name; - Instance = (TAccountResource) repository.Modify(existing); + Instance = (TAccountResource) Repository.Modify(existing); } return (TAccountEditor) this; @@ -52,8 +52,13 @@ public virtual TAccountEditor Customize(Action customize) public virtual TAccountEditor Save() { - Instance = (TAccountResource)repository.Modify(Instance); + Instance = (TAccountResource)Repository.Modify(Instance); return (TAccountEditor)this; } + + public AccountUsageResource Usage() + { + return Repository.Client.Get(Instance.Link("Usage")); + } } } \ No newline at end of file diff --git a/source/Octopus.Client/Editors/Async/AccountEditor.cs b/source/Octopus.Client/Editors/Async/AccountEditor.cs index 2dd35e50a..a25f83e26 100644 --- a/source/Octopus.Client/Editors/Async/AccountEditor.cs +++ b/source/Octopus.Client/Editors/Async/AccountEditor.cs @@ -1,6 +1,7 @@ using System; using System.Threading.Tasks; using Octopus.Client.Model.Accounts; +using Octopus.Client.Model.Accounts.Usages; using Octopus.Client.Repositories.Async; namespace Octopus.Client.Editors.Async @@ -9,21 +10,21 @@ public class AccountEditor : IResourceEditor { - private readonly IAccountRepository repository; + protected readonly IAccountRepository Repository; public AccountEditor(IAccountRepository repository) { - this.repository = repository; + Repository = repository; } public TAccountResource Instance { get; private set; } public async Task CreateOrModify(string name) { - var existing = await repository.FindByName(name); + var existing = await Repository.FindByName(name); if (existing == null) { - Instance = (TAccountResource)await repository.Create(new TAccountResource + Instance = (TAccountResource)await Repository.Create(new TAccountResource { Name = name }); @@ -37,7 +38,7 @@ public async Task CreateOrModify(string name) existing.Name = name; - Instance = (TAccountResource)await repository.Modify(existing); + Instance = (TAccountResource)await Repository.Modify(existing); } return (TAccountEditor)this; @@ -51,8 +52,13 @@ public virtual TAccountEditor Customize(Action customize) public virtual async Task Save() { - Instance = (TAccountResource)await repository.Modify(Instance).ConfigureAwait(false); + Instance = (TAccountResource)await Repository.Modify(Instance).ConfigureAwait(false); return (TAccountEditor)this; } + + public Task Usage() + { + return Repository.Client.Get(Instance.Link("Usage")); + } } } \ No newline at end of file diff --git a/source/Octopus.Client/Editors/Async/AzureServicePrincipalAccountEditor.cs b/source/Octopus.Client/Editors/Async/AzureServicePrincipalAccountEditor.cs index d4fb565b8..b0381794d 100644 --- a/source/Octopus.Client/Editors/Async/AzureServicePrincipalAccountEditor.cs +++ b/source/Octopus.Client/Editors/Async/AzureServicePrincipalAccountEditor.cs @@ -8,28 +8,23 @@ namespace Octopus.Client.Editors.Async { public class AzureServicePrincipalAccountEditor : AccountEditor { - private readonly IOctopusAsyncClient client; - - public AzureServicePrincipalAccountEditor( - IOctopusAsyncClient client, - IAccountRepository repository) : base(repository) + public AzureServicePrincipalAccountEditor(IAccountRepository repository) : base(repository) { - this.client = client; } public Task> ResourceGroups() { - return client.Get>(Instance.Link("ResourceGroups")); + return Repository.Client.Get>(Instance.Link("ResourceGroups")); } public Task> WebSites() { - return client.Get>(Instance.Link("WebSites")); + return Repository.Client.Get>(Instance.Link("WebSites")); } public Task> StorageAccounts() { - return client.Get>(Instance.Link("StorageAccounts")); + return Repository.Client.Get>(Instance.Link("StorageAccounts")); } } } \ No newline at end of file diff --git a/source/Octopus.Client/Editors/Async/AzureSubscriptionAccountEditor.cs b/source/Octopus.Client/Editors/Async/AzureSubscriptionAccountEditor.cs index 35809a865..76929b866 100644 --- a/source/Octopus.Client/Editors/Async/AzureSubscriptionAccountEditor.cs +++ b/source/Octopus.Client/Editors/Async/AzureSubscriptionAccountEditor.cs @@ -7,28 +7,23 @@ namespace Octopus.Client.Editors.Async { public class AzureSubscriptionAccountEditor : AccountEditor { - private readonly IOctopusAsyncClient client; - - public AzureSubscriptionAccountEditor( - IOctopusAsyncClient client, - IAccountRepository repository) : base(repository) + public AzureSubscriptionAccountEditor(IAccountRepository repository) : base(repository) { - this.client = client; } public Task> CloudServices(AzureSubscriptionAccountResource account) { - return client.Get>(account.Link("CloudServices")); + return Repository.Client.Get>(account.Link("CloudServices")); } public Task> StorageAccounts(AzureSubscriptionAccountResource account) { - return client.Get>(account.Link("StorageAccounts")); + return Repository.Client.Get>(account.Link("StorageAccounts")); } public Task> WebSites(AzureSubscriptionAccountResource account) { - return client.Get>(account.Link("WebSites")); + return Repository.Client.Get>(account.Link("WebSites")); } } } \ No newline at end of file diff --git a/source/Octopus.Client/Editors/AzureServicePrincipalAccountEditor.cs b/source/Octopus.Client/Editors/AzureServicePrincipalAccountEditor.cs index 0be4cb74a..511ec4f60 100644 --- a/source/Octopus.Client/Editors/AzureServicePrincipalAccountEditor.cs +++ b/source/Octopus.Client/Editors/AzureServicePrincipalAccountEditor.cs @@ -7,28 +7,23 @@ namespace Octopus.Client.Editors { public class AzureServicePrincipalAccountEditor : AccountEditor { - private readonly IOctopusClient client; - - public AzureServicePrincipalAccountEditor( - IOctopusClient client, - IAccountRepository repository) : base(repository) + public AzureServicePrincipalAccountEditor(IAccountRepository repository) : base(repository) { - this.client = client; } public List ResourceGroups() { - return client.Get>(Instance.Link("ResourceGroups")); + return Repository.Client.Get>(Instance.Link("ResourceGroups")); } public List WebSites() { - return client.Get>(Instance.Link("WebSites")); + return Repository.Client.Get>(Instance.Link("WebSites")); } public List StorageAccounts() { - return client.Get>(Instance.Link("StorageAccounts")); + return Repository.Client.Get>(Instance.Link("StorageAccounts")); } } } \ No newline at end of file diff --git a/source/Octopus.Client/Editors/AzureSubscriptionAccountEditor.cs b/source/Octopus.Client/Editors/AzureSubscriptionAccountEditor.cs index eaffcba23..a3dc3562d 100644 --- a/source/Octopus.Client/Editors/AzureSubscriptionAccountEditor.cs +++ b/source/Octopus.Client/Editors/AzureSubscriptionAccountEditor.cs @@ -6,28 +6,23 @@ namespace Octopus.Client.Editors { public class AzureSubscriptionAccountEditor : AccountEditor { - private readonly IOctopusClient client; - - public AzureSubscriptionAccountEditor( - IOctopusClient client, - IAccountRepository repository) : base(repository) + public AzureSubscriptionAccountEditor(IAccountRepository repository) : base(repository) { - this.client = client; } public List CloudServices(AzureSubscriptionAccountResource account) { - return client.Get>(account.Link("CloudServices")); + return Repository.Client.Get>(account.Link("CloudServices")); } public List StorageAccounts(AzureSubscriptionAccountResource account) { - return client.Get>(account.Link("StorageAccounts")); + return Repository.Client.Get>(account.Link("StorageAccounts")); } public List WebSites(AzureSubscriptionAccountResource account) { - return client.Get>(account.Link("WebSites")); + return Repository.Client.Get>(account.Link("WebSites")); } } } \ No newline at end of file diff --git a/source/Octopus.Client/Repositories/Async/AccountRepository.cs b/source/Octopus.Client/Repositories/Async/AccountRepository.cs index 031334097..023af890a 100644 --- a/source/Octopus.Client/Repositories/Async/AccountRepository.cs +++ b/source/Octopus.Client/Repositories/Async/AccountRepository.cs @@ -10,7 +10,7 @@ namespace Octopus.Client.Repositories.Async { - public interface IAccountRepository : ICreate, IModify, IDelete, IGet, IFindByName + public interface IAccountRepository : IResourceRepository, ICreate, IModify, IDelete, IGet, IFindByName { AccountType DetermineAccountType() where TAccount : AccountResource; diff --git a/source/Octopus.Client/Repositories/Async/IResourceRepository.cs b/source/Octopus.Client/Repositories/Async/IResourceRepository.cs new file mode 100644 index 000000000..7bbd2aaae --- /dev/null +++ b/source/Octopus.Client/Repositories/Async/IResourceRepository.cs @@ -0,0 +1,7 @@ +namespace Octopus.Client.Repositories.Async +{ + public interface IResourceRepository + { + IOctopusAsyncClient Client { get; } + } +} \ No newline at end of file diff --git a/source/Octopus.Client/Repositories/IAccountRepository.cs b/source/Octopus.Client/Repositories/IAccountRepository.cs index b023b9213..7e893c070 100644 --- a/source/Octopus.Client/Repositories/IAccountRepository.cs +++ b/source/Octopus.Client/Repositories/IAccountRepository.cs @@ -9,7 +9,7 @@ namespace Octopus.Client.Repositories { - public interface IAccountRepository : ICreate, IModify, IDelete, IGet, IFindByName + public interface IAccountRepository : IResourceRepository, ICreate, IModify, IDelete, IGet, IFindByName { AccountType DetermineAccountType() where TAccount : AccountResource; diff --git a/source/Octopus.Client/Repositories/IResourceRepository.cs b/source/Octopus.Client/Repositories/IResourceRepository.cs new file mode 100644 index 000000000..80f430f5e --- /dev/null +++ b/source/Octopus.Client/Repositories/IResourceRepository.cs @@ -0,0 +1,7 @@ +namespace Octopus.Client.Repositories +{ + public interface IResourceRepository + { + IOctopusClient Client { get; } + } +} \ No newline at end of file From d140269748167a9430e15dec584c845be9d577ca Mon Sep 17 00:00:00 2001 From: Shannon Lewis Date: Tue, 8 May 2018 17:57:39 +1000 Subject: [PATCH 10/19] don't try to save when calling CreateOrModify and include a simpler FindByName method --- .../Octopus.Client/Editors/AccountEditor.cs | 24 ++++++++++++++++--- .../Editors/Async/AccountEditor.cs | 22 +++++++++++++++-- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/source/Octopus.Client/Editors/AccountEditor.cs b/source/Octopus.Client/Editors/AccountEditor.cs index 17ed586ce..c55e32938 100644 --- a/source/Octopus.Client/Editors/AccountEditor.cs +++ b/source/Octopus.Client/Editors/AccountEditor.cs @@ -36,13 +36,31 @@ public TAccountEditor CreateOrModify(string name) $"An account with that name exists but is not of type {typeof(TAccountResource).Name}"); } - existing.Name = name; - - Instance = (TAccountResource) Repository.Modify(existing); + Instance = (TAccountResource) existing; } return (TAccountEditor) this; } + + public TAccountEditor FindByName(string name) + { + var existing = Repository.FindByName(name); + if (existing == null) + { + throw new ArgumentException($"An account with the name {name} could not be found"); + } + else + { + if (!(existing is TAccountResource)) + { + throw new ArgumentException($"An account with that name exists but is not of type {typeof(TAccountResource).Name}"); + } + + Instance = (TAccountResource)existing; + } + + return (TAccountEditor)this; + } public virtual TAccountEditor Customize(Action customize) { diff --git a/source/Octopus.Client/Editors/Async/AccountEditor.cs b/source/Octopus.Client/Editors/Async/AccountEditor.cs index a25f83e26..d294d8d85 100644 --- a/source/Octopus.Client/Editors/Async/AccountEditor.cs +++ b/source/Octopus.Client/Editors/Async/AccountEditor.cs @@ -36,9 +36,27 @@ public async Task CreateOrModify(string name) throw new ArgumentException($"An account with that name exists but is not of type {typeof(TAccountResource).Name}"); } - existing.Name = name; + Instance = (TAccountResource)existing; + } + + return (TAccountEditor)this; + } + + public async Task FindByName(string name) + { + var existing = await Repository.FindByName(name); + if (existing == null) + { + throw new ArgumentException($"An account with the name {name} could not be found"); + } + else + { + if (!(existing is TAccountResource)) + { + throw new ArgumentException($"An account with that name exists but is not of type {typeof(TAccountResource).Name}"); + } - Instance = (TAccountResource)await Repository.Modify(existing); + Instance = (TAccountResource)existing; } return (TAccountEditor)this; From d3ecb04c28320e4fae471e2aeb2177f2ba39699d Mon Sep 17 00:00:00 2001 From: Shannon Lewis Date: Tue, 8 May 2018 18:06:22 +1000 Subject: [PATCH 11/19] forgot about the PublicSurfaceAreaFixture --- ...e.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt | 1 + ...PublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt | 2 ++ 2 files changed, 3 insertions(+) diff --git a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt index e8421131f..cb0818a4c 100644 --- a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt +++ b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt @@ -251,6 +251,7 @@ Octopus.Client.Editors.Async Octopus.Client.Editors.Async.TAccountResource Instance { get; } Task CreateOrModify(String) Octopus.Client.Editors.Async.TAccountEditor Customize(Action) + Task FindByName(String) Task Save() Task Usage() } diff --git a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt index a979b794e..97083597e 100644 --- a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt +++ b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt @@ -414,6 +414,7 @@ Octopus.Client.Editors Octopus.Client.Editors.TAccountResource Instance { get; } Octopus.Client.Editors.TAccountEditor CreateOrModify(String) Octopus.Client.Editors.TAccountEditor Customize(Action) + Octopus.Client.Editors.TAccountEditor FindByName(String) Octopus.Client.Editors.TAccountEditor Save() Octopus.Client.Model.Accounts.Usages.AccountUsageResource Usage() } @@ -702,6 +703,7 @@ Octopus.Client.Editors.Async Octopus.Client.Editors.Async.TAccountResource Instance { get; } Task CreateOrModify(String) Octopus.Client.Editors.Async.TAccountEditor Customize(Action) + Task FindByName(String) Task Save() Task Usage() } From 2e2ddd5f52597024f4f0666957e41a5621e3f1be Mon Sep 17 00:00:00 2001 From: Shannon Lewis Date: Tue, 8 May 2018 18:27:28 +1000 Subject: [PATCH 12/19] account Usages should be plural --- ...ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt | 2 +- ...blicSurfaceAreaShouldNotRegress..NETFramework.approved.txt | 4 ++-- source/Octopus.Client/Editors/AccountEditor.cs | 4 ++-- source/Octopus.Client/Editors/Async/AccountEditor.cs | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt index cb0818a4c..b5a38c8c3 100644 --- a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt +++ b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt @@ -253,7 +253,7 @@ Octopus.Client.Editors.Async Octopus.Client.Editors.Async.TAccountEditor Customize(Action) Task FindByName(String) Task Save() - Task Usage() + Task Usages() } class AmazonWebServicesAccountEditor Octopus.Client.Editors.Async.IResourceEditor diff --git a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt index 97083597e..4cb6d70cc 100644 --- a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt +++ b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt @@ -416,7 +416,7 @@ Octopus.Client.Editors Octopus.Client.Editors.TAccountEditor Customize(Action) Octopus.Client.Editors.TAccountEditor FindByName(String) Octopus.Client.Editors.TAccountEditor Save() - Octopus.Client.Model.Accounts.Usages.AccountUsageResource Usage() + Octopus.Client.Model.Accounts.Usages.AccountUsageResource Usages() } class AmazonWebServicesAccountEditor Octopus.Client.Editors.IResourceEditor @@ -705,7 +705,7 @@ Octopus.Client.Editors.Async Octopus.Client.Editors.Async.TAccountEditor Customize(Action) Task FindByName(String) Task Save() - Task Usage() + Task Usages() } class AmazonWebServicesAccountEditor Octopus.Client.Editors.Async.IResourceEditor diff --git a/source/Octopus.Client/Editors/AccountEditor.cs b/source/Octopus.Client/Editors/AccountEditor.cs index c55e32938..0bdd1c31c 100644 --- a/source/Octopus.Client/Editors/AccountEditor.cs +++ b/source/Octopus.Client/Editors/AccountEditor.cs @@ -74,9 +74,9 @@ public virtual TAccountEditor Save() return (TAccountEditor)this; } - public AccountUsageResource Usage() + public AccountUsageResource Usages() { - return Repository.Client.Get(Instance.Link("Usage")); + return Repository.Client.Get(Instance.Link("Usages")); } } } \ No newline at end of file diff --git a/source/Octopus.Client/Editors/Async/AccountEditor.cs b/source/Octopus.Client/Editors/Async/AccountEditor.cs index d294d8d85..4f73ba521 100644 --- a/source/Octopus.Client/Editors/Async/AccountEditor.cs +++ b/source/Octopus.Client/Editors/Async/AccountEditor.cs @@ -74,9 +74,9 @@ public virtual async Task Save() return (TAccountEditor)this; } - public Task Usage() + public Task Usages() { - return Repository.Client.Get(Instance.Link("Usage")); + return Repository.Client.Get(Instance.Link("Usages")); } } } \ No newline at end of file From de7a654abae28336deaedcde8581536ba8ddb460 Mon Sep 17 00:00:00 2001 From: Shannon Lewis Date: Tue, 8 May 2018 21:46:22 +1000 Subject: [PATCH 13/19] WebApp endpoints must have a ResourceGroupName specified --- ...ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt | 1 + ...blicSurfaceAreaShouldNotRegress..NETFramework.approved.txt | 1 + .../Model/Endpoints/AzureWebAppEndpointResource.cs | 4 ++++ 3 files changed, 6 insertions(+) diff --git a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt index b5a38c8c3..85bf164ba 100644 --- a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt +++ b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt @@ -3696,6 +3696,7 @@ Octopus.Client.Model.Endpoints .ctor() String AccountId { get; set; } Octopus.Client.Model.CommunicationStyle CommunicationStyle { get; } + String ResourceGroupName { get; set; } String WebAppName { get; set; } String WebSpaceName { get; set; } } diff --git a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt index 4cb6d70cc..d274d11d1 100644 --- a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt +++ b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt @@ -4170,6 +4170,7 @@ Octopus.Client.Model.Endpoints .ctor() String AccountId { get; set; } Octopus.Client.Model.CommunicationStyle CommunicationStyle { get; } + String ResourceGroupName { get; set; } String WebAppName { get; set; } String WebSpaceName { get; set; } } diff --git a/source/Octopus.Client/Model/Endpoints/AzureWebAppEndpointResource.cs b/source/Octopus.Client/Model/Endpoints/AzureWebAppEndpointResource.cs index 07372ab21..85214c260 100644 --- a/source/Octopus.Client/Model/Endpoints/AzureWebAppEndpointResource.cs +++ b/source/Octopus.Client/Model/Endpoints/AzureWebAppEndpointResource.cs @@ -19,6 +19,10 @@ public override CommunicationStyle CommunicationStyle [Writeable] public string WebSpaceName { get; set; } + [Trim] + [Writeable] + public string ResourceGroupName { get; set; } + [Trim] [Writeable] public string WebAppName { get; set; } From 6aadec875bd621ba88002f5efde095532576208c Mon Sep 17 00:00:00 2001 From: Shannon Lewis Date: Tue, 8 May 2018 22:27:08 +1000 Subject: [PATCH 14/19] UsageEntry on the client doesn't need the non-default ctors --- source/Octopus.Client/Model/UsageEntry.cs | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/source/Octopus.Client/Model/UsageEntry.cs b/source/Octopus.Client/Model/UsageEntry.cs index 4cfe5d926..7cc5d8560 100644 --- a/source/Octopus.Client/Model/UsageEntry.cs +++ b/source/Octopus.Client/Model/UsageEntry.cs @@ -2,19 +2,8 @@ { public class UsageEntry { - UsageEntry(bool isMissingScopedPermissions, string missingId) - { - IsMissingScopedPermissions = isMissingScopedPermissions; - MissingId = missingId; - } - - UsageEntry(TEntry entry) - { - Entry = entry; - } - - public bool IsMissingScopedPermissions { get; } - public string MissingId { get; } - public TEntry Entry { get; } + public bool IsMissingScopedPermissions { get; set; } + public string MissingId { get; set;} + public TEntry Entry { get; set;} } } \ No newline at end of file From b8b6e483d0ffc238f1dd1a773433977fc57612d2 Mon Sep 17 00:00:00 2001 From: Shannon Lewis Date: Tue, 8 May 2018 22:40:19 +1000 Subject: [PATCH 15/19] did I say something about the PublicSurfaceAreaFixture? --- ...PublicSurfaceAreaShouldNotRegress..NETCore.approved.txt | 7 ++++--- ...cSurfaceAreaShouldNotRegress..NETFramework.approved.txt | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt index 85bf164ba..086347fc7 100644 --- a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt +++ b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt @@ -3248,9 +3248,10 @@ Octopus.Client.Model } class UsageEntry`1 { - Octopus.Client.Model.TEntry Entry { get; } - Boolean IsMissingScopedPermissions { get; } - String MissingId { get; } + .ctor() + Octopus.Client.Model.TEntry Entry { get; set; } + Boolean IsMissingScopedPermissions { get; set; } + String MissingId { get; set; } } class UserPermissionRestriction { diff --git a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt index d274d11d1..71a92e385 100644 --- a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt +++ b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt @@ -3721,9 +3721,10 @@ Octopus.Client.Model } class UsageEntry`1 { - Octopus.Client.Model.TEntry Entry { get; } - Boolean IsMissingScopedPermissions { get; } - String MissingId { get; } + .ctor() + Octopus.Client.Model.TEntry Entry { get; set; } + Boolean IsMissingScopedPermissions { get; set; } + String MissingId { get; set; } } class UserPermissionRestriction { From 9cf00054a3e3d4ad6784707efb2559c18dc3b878 Mon Sep 17 00:00:00 2001 From: Shannon Lewis Date: Wed, 9 May 2018 13:32:38 +1000 Subject: [PATCH 16/19] adding scoping checks to Certificate Usages --- ...AreaShouldNotRegress..NETCore.approved.txt | 34 ++++++++++ ...houldNotRegress..NETFramework.approved.txt | 47 ++++++++++++++ .../Editors/Async/CertificateEditor.cs | 64 +++++++++++++++++++ .../Editors/CertificateEditor.cs | 63 ++++++++++++++++++ .../Model/Accounts/AccountResource.cs | 4 +- .../Model/CertificateResource.cs | 2 + .../Model/CertificateUsageResource.cs | 20 ++++++ .../Async/CertificateRepository.cs | 2 +- .../Repositories/CertificateRepository.cs | 2 +- 9 files changed, 235 insertions(+), 3 deletions(-) create mode 100644 source/Octopus.Client/Editors/Async/CertificateEditor.cs create mode 100644 source/Octopus.Client/Editors/CertificateEditor.cs create mode 100644 source/Octopus.Client/Model/CertificateUsageResource.cs diff --git a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt index 086347fc7..0eee7819b 100644 --- a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt +++ b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt @@ -289,6 +289,18 @@ Octopus.Client.Editors.Async Task> StorageAccounts(Octopus.Client.Model.Accounts.AzureSubscriptionAccountResource) Task> WebSites(Octopus.Client.Model.Accounts.AzureSubscriptionAccountResource) } + class CertificateEditor + Octopus.Client.Editors.Async.IResourceEditor + Octopus.Client.Editors.Async.IResourceBuilder + { + .ctor(Octopus.Client.Repositories.Async.ICertificateRepository) + Octopus.Client.Model.CertificateResource Instance { get; } + Task Create(String, String) + Octopus.Client.Editors.Async.CertificateEditor Customize(Action) + Task FindByName(String) + Task Save() + Task Usages() + } class ChannelEditor Octopus.Client.Editors.Async.IResourceEditor Octopus.Client.Editors.Async.IResourceBuilder @@ -1221,6 +1233,27 @@ Octopus.Client.Model String Thumbprint { get; } Int32 Version { get; } } + class CertificateUsageResource + { + .ctor() + ICollection> LibraryVariableSetUsages { get; set; } + ICollection> ProjectUsages { get; set; } + ICollection> TenantUsages { get; set; } + class CertificateVariableUsageResource`1 + { + .ctor() + Boolean IsMissingScopedPermissions { get; set; } + String MissingId { get; set; } + Octopus.Client.Model.T Owner { get; set; } + } + } + class CertificateVariableUsageResource`1 + { + .ctor() + Boolean IsMissingScopedPermissions { get; set; } + String MissingId { get; set; } + Octopus.Client.Model.T Owner { get; set; } + } class ChannelResource Octopus.Client.Extensibility.IResource Octopus.Client.Model.IAuditedResource @@ -4277,6 +4310,7 @@ Octopus.Client.Repositories.Async Task GetOctopusCertificate() } interface ICertificateRepository + Octopus.Client.Repositories.Async.IResourceRepository Octopus.Client.Repositories.Async.IGet Octopus.Client.Repositories.Async.IFindByName Octopus.Client.Repositories.Async.IPaginate diff --git a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt index 71a92e385..06e2e447b 100644 --- a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt +++ b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt @@ -452,6 +452,18 @@ Octopus.Client.Editors List StorageAccounts(Octopus.Client.Model.Accounts.AzureSubscriptionAccountResource) List WebSites(Octopus.Client.Model.Accounts.AzureSubscriptionAccountResource) } + class CertificateEditor + Octopus.Client.Editors.IResourceEditor + Octopus.Client.Editors.IResourceBuilder + { + .ctor(Octopus.Client.Repositories.ICertificateRepository) + Octopus.Client.Model.CertificateResource Instance { get; } + Octopus.Client.Editors.CertificateEditor Create(String, String) + Octopus.Client.Editors.CertificateEditor Customize(Action) + Octopus.Client.Editors.CertificateEditor FindByName(String) + Octopus.Client.Editors.CertificateEditor Save() + Octopus.Client.Model.CertificateUsageResource Usages() + } class ChannelEditor Octopus.Client.Editors.IResourceEditor Octopus.Client.Editors.IResourceBuilder @@ -741,6 +753,18 @@ Octopus.Client.Editors.Async Task> StorageAccounts(Octopus.Client.Model.Accounts.AzureSubscriptionAccountResource) Task> WebSites(Octopus.Client.Model.Accounts.AzureSubscriptionAccountResource) } + class CertificateEditor + Octopus.Client.Editors.Async.IResourceEditor + Octopus.Client.Editors.Async.IResourceBuilder + { + .ctor(Octopus.Client.Repositories.Async.ICertificateRepository) + Octopus.Client.Model.CertificateResource Instance { get; } + Task Create(String, String) + Octopus.Client.Editors.Async.CertificateEditor Customize(Action) + Task FindByName(String) + Task Save() + Task Usages() + } class ChannelEditor Octopus.Client.Editors.Async.IResourceEditor Octopus.Client.Editors.Async.IResourceBuilder @@ -1686,6 +1710,27 @@ Octopus.Client.Model String Thumbprint { get; } Int32 Version { get; } } + class CertificateUsageResource + { + .ctor() + ICollection> LibraryVariableSetUsages { get; set; } + ICollection> ProjectUsages { get; set; } + ICollection> TenantUsages { get; set; } + class CertificateVariableUsageResource`1 + { + .ctor() + Boolean IsMissingScopedPermissions { get; set; } + String MissingId { get; set; } + Octopus.Client.Model.T Owner { get; set; } + } + } + class CertificateVariableUsageResource`1 + { + .ctor() + Boolean IsMissingScopedPermissions { get; set; } + String MissingId { get; set; } + Octopus.Client.Model.T Owner { get; set; } + } class ChannelResource Octopus.Client.Extensibility.IResource Octopus.Client.Model.IAuditedResource @@ -4757,6 +4802,7 @@ Octopus.Client.Repositories Octopus.Client.Model.CertificateConfigurationResource GetOctopusCertificate() } interface ICertificateRepository + Octopus.Client.Repositories.IResourceRepository Octopus.Client.Repositories.IGet Octopus.Client.Repositories.IFindByName Octopus.Client.Repositories.IPaginate @@ -5241,6 +5287,7 @@ Octopus.Client.Repositories.Async Task GetOctopusCertificate() } interface ICertificateRepository + Octopus.Client.Repositories.Async.IResourceRepository Octopus.Client.Repositories.Async.IGet Octopus.Client.Repositories.Async.IFindByName Octopus.Client.Repositories.Async.IPaginate diff --git a/source/Octopus.Client/Editors/Async/CertificateEditor.cs b/source/Octopus.Client/Editors/Async/CertificateEditor.cs new file mode 100644 index 000000000..c6f192212 --- /dev/null +++ b/source/Octopus.Client/Editors/Async/CertificateEditor.cs @@ -0,0 +1,64 @@ +using System; +using System.Threading.Tasks; +using Octopus.Client.Model; +using Octopus.Client.Repositories.Async; + +namespace Octopus.Client.Editors.Async +{ + public class CertificateEditor : IResourceEditor + { + private readonly ICertificateRepository repository; + + public CertificateEditor(ICertificateRepository repository) + { + this.repository = repository; + } + + public CertificateResource Instance { get; private set; } + + public async Task Create(string name, string certificateData) + { + var existing = repository.FindByName(name); + if (existing != null) + { + throw new ArgumentException($"A certificate with the name {name} already exists"); + } + + Instance = await repository.Create(new CertificateResource(name, certificateData)); + + return this; + } + + public async Task FindByName(string name) + { + var existing = await repository.FindByName(name); + if (existing == null) + { + throw new ArgumentException($"A certificate with the name {name} could not be found"); + } + else + { + Instance = existing; + } + + return this; + } + + public CertificateEditor Customize(Action customize) + { + customize?.Invoke(Instance); + return this; + } + + public async Task Save() + { + Instance = await repository.Modify(Instance); + return this; + } + + public async Task Usages() + { + return await repository.Client.Get(Instance.Link("Usages")); + } + } +} \ No newline at end of file diff --git a/source/Octopus.Client/Editors/CertificateEditor.cs b/source/Octopus.Client/Editors/CertificateEditor.cs new file mode 100644 index 000000000..c4e540734 --- /dev/null +++ b/source/Octopus.Client/Editors/CertificateEditor.cs @@ -0,0 +1,63 @@ +using System; +using Octopus.Client.Model; +using Octopus.Client.Repositories; + +namespace Octopus.Client.Editors +{ + public class CertificateEditor : IResourceEditor + { + private readonly ICertificateRepository repository; + + public CertificateEditor(ICertificateRepository repository) + { + this.repository = repository; + } + + public CertificateResource Instance { get; private set; } + + public CertificateEditor Create(string name, string certificateData) + { + var existing = repository.FindByName(name); + if (existing != null) + { + throw new ArgumentException($"A certificate with the name {name} already exists"); + } + + Instance = repository.Create(new CertificateResource(name, certificateData)); + + return this; + } + + public CertificateEditor FindByName(string name) + { + var existing = repository.FindByName(name); + if (existing == null) + { + throw new ArgumentException($"A certificate with the name {name} could not be found"); + } + else + { + Instance = existing; + } + + return this; + } + + public CertificateEditor Customize(Action customize) + { + customize?.Invoke(Instance); + return this; + } + + public CertificateEditor Save() + { + Instance = repository.Modify(Instance); + return this; + } + + public CertificateUsageResource Usages() + { + return repository.Client.Get(Instance.Link("Usages")); + } + } +} \ No newline at end of file diff --git a/source/Octopus.Client/Model/Accounts/AccountResource.cs b/source/Octopus.Client/Model/Accounts/AccountResource.cs index a1282a959..06affe960 100644 --- a/source/Octopus.Client/Model/Accounts/AccountResource.cs +++ b/source/Octopus.Client/Model/Accounts/AccountResource.cs @@ -1,9 +1,11 @@ -using System.Linq; +using System.Diagnostics; +using System.Linq; using Octopus.Client.Extensibility; using Octopus.Client.Extensibility.Attributes; namespace Octopus.Client.Model.Accounts { + [DebuggerDisplay("Name = {Name}")] public abstract class AccountResource : Resource, INamedResource { protected AccountResource() diff --git a/source/Octopus.Client/Model/CertificateResource.cs b/source/Octopus.Client/Model/CertificateResource.cs index b1b7d8928..a2a867a43 100644 --- a/source/Octopus.Client/Model/CertificateResource.cs +++ b/source/Octopus.Client/Model/CertificateResource.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using System.Linq; using Octopus.Client.Extensibility.Attributes; using Newtonsoft.Json; @@ -6,6 +7,7 @@ namespace Octopus.Client.Model { + [DebuggerDisplay("Name = {Name}")] public class CertificateResource : Resource, INamedResource { [JsonConstructor] diff --git a/source/Octopus.Client/Model/CertificateUsageResource.cs b/source/Octopus.Client/Model/CertificateUsageResource.cs new file mode 100644 index 000000000..04f0249b1 --- /dev/null +++ b/source/Octopus.Client/Model/CertificateUsageResource.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic; + +namespace Octopus.Client.Model +{ + public class CertificateUsageResource + { + public ICollection> ProjectUsages { get; set; } + + public ICollection> LibraryVariableSetUsages { get; set; } + + public ICollection> TenantUsages { get; set; } + + public class CertificateVariableUsageResource + { + public bool IsMissingScopedPermissions { get; set; } + public string MissingId { get; set;} + public T Owner { get; set; } + } + } +} \ No newline at end of file diff --git a/source/Octopus.Client/Repositories/Async/CertificateRepository.cs b/source/Octopus.Client/Repositories/Async/CertificateRepository.cs index c74be6179..73be3e204 100644 --- a/source/Octopus.Client/Repositories/Async/CertificateRepository.cs +++ b/source/Octopus.Client/Repositories/Async/CertificateRepository.cs @@ -4,7 +4,7 @@ namespace Octopus.Client.Repositories.Async { - public interface ICertificateRepository : IGet, IFindByName, ICreate, IModify, IDelete + public interface ICertificateRepository : IResourceRepository, IGet, IFindByName, ICreate, IModify, IDelete { /// /// Exports the certificate data. diff --git a/source/Octopus.Client/Repositories/CertificateRepository.cs b/source/Octopus.Client/Repositories/CertificateRepository.cs index d893840b2..149944131 100644 --- a/source/Octopus.Client/Repositories/CertificateRepository.cs +++ b/source/Octopus.Client/Repositories/CertificateRepository.cs @@ -4,7 +4,7 @@ namespace Octopus.Client.Repositories { - public interface ICertificateRepository : IGet, IFindByName, ICreate, IModify, IDelete + public interface ICertificateRepository : IResourceRepository, IGet, IFindByName, ICreate, IModify, IDelete { /// /// Exports the certificate data. From 7a1eab38f078040d694f8c382f1432eeb4272fe9 Mon Sep 17 00:00:00 2001 From: Shannon Lewis Date: Wed, 9 May 2018 15:13:50 +1000 Subject: [PATCH 17/19] giveth, then taketh away. Simplifying usage APIs --- ...AreaShouldNotRegress..NETCore.approved.txt | 37 ++++--------------- ...houldNotRegress..NETFramework.approved.txt | 37 ++++--------------- .../Accounts/Usages/AccountUsageResource.cs | 23 +++++------- .../Model/CertificateUsageResource.cs | 13 ++----- source/Octopus.Client/Model/UsageEntry.cs | 9 ----- 5 files changed, 29 insertions(+), 90 deletions(-) delete mode 100644 source/Octopus.Client/Model/UsageEntry.cs diff --git a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt index 0eee7819b..7e1258d73 100644 --- a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt +++ b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt @@ -1236,23 +1236,9 @@ Octopus.Client.Model class CertificateUsageResource { .ctor() - ICollection> LibraryVariableSetUsages { get; set; } - ICollection> ProjectUsages { get; set; } - ICollection> TenantUsages { get; set; } - class CertificateVariableUsageResource`1 - { - .ctor() - Boolean IsMissingScopedPermissions { get; set; } - String MissingId { get; set; } - Octopus.Client.Model.T Owner { get; set; } - } - } - class CertificateVariableUsageResource`1 - { - .ctor() - Boolean IsMissingScopedPermissions { get; set; } - String MissingId { get; set; } - Octopus.Client.Model.T Owner { get; set; } + ICollection LibraryVariableSetUsages { get; set; } + ICollection ProjectUsages { get; set; } + ICollection TenantUsages { get; set; } } class ChannelResource Octopus.Client.Extensibility.IResource @@ -3279,13 +3265,6 @@ Octopus.Client.Model static System.String MachineIds } } - class UsageEntry`1 - { - .ctor() - Octopus.Client.Model.TEntry Entry { get; set; } - Boolean IsMissingScopedPermissions { get; set; } - String MissingId { get; set; } - } class UserPermissionRestriction { .ctor() @@ -3611,11 +3590,11 @@ Octopus.Client.Model.Accounts.Usages Octopus.Client.Model.Resource { .ctor() - ICollection> DeploymentProcesses { get; set; } - ICollection> LibraryVariableSets { get; set; } - ICollection> ProjectVariableSets { get; set; } - ICollection> Releases { get; set; } - ICollection> Targets { get; set; } + ICollection DeploymentProcesses { get; set; } + ICollection LibraryVariableSets { get; set; } + ICollection ProjectVariableSets { get; set; } + ICollection Releases { get; set; } + ICollection Targets { get; set; } } class LibraryVariableSetUsageEntry { diff --git a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt index 06e2e447b..c226ee5bb 100644 --- a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt +++ b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt @@ -1713,23 +1713,9 @@ Octopus.Client.Model class CertificateUsageResource { .ctor() - ICollection> LibraryVariableSetUsages { get; set; } - ICollection> ProjectUsages { get; set; } - ICollection> TenantUsages { get; set; } - class CertificateVariableUsageResource`1 - { - .ctor() - Boolean IsMissingScopedPermissions { get; set; } - String MissingId { get; set; } - Octopus.Client.Model.T Owner { get; set; } - } - } - class CertificateVariableUsageResource`1 - { - .ctor() - Boolean IsMissingScopedPermissions { get; set; } - String MissingId { get; set; } - Octopus.Client.Model.T Owner { get; set; } + ICollection LibraryVariableSetUsages { get; set; } + ICollection ProjectUsages { get; set; } + ICollection TenantUsages { get; set; } } class ChannelResource Octopus.Client.Extensibility.IResource @@ -3764,13 +3750,6 @@ Octopus.Client.Model static System.String MachineIds } } - class UsageEntry`1 - { - .ctor() - Octopus.Client.Model.TEntry Entry { get; set; } - Boolean IsMissingScopedPermissions { get; set; } - String MissingId { get; set; } - } class UserPermissionRestriction { .ctor() @@ -4097,11 +4076,11 @@ Octopus.Client.Model.Accounts.Usages Octopus.Client.Model.Resource { .ctor() - ICollection> DeploymentProcesses { get; set; } - ICollection> LibraryVariableSets { get; set; } - ICollection> ProjectVariableSets { get; set; } - ICollection> Releases { get; set; } - ICollection> Targets { get; set; } + ICollection DeploymentProcesses { get; set; } + ICollection LibraryVariableSets { get; set; } + ICollection ProjectVariableSets { get; set; } + ICollection Releases { get; set; } + ICollection Targets { get; set; } } class LibraryVariableSetUsageEntry { diff --git a/source/Octopus.Client/Model/Accounts/Usages/AccountUsageResource.cs b/source/Octopus.Client/Model/Accounts/Usages/AccountUsageResource.cs index d2a38ac31..361427b0d 100644 --- a/source/Octopus.Client/Model/Accounts/Usages/AccountUsageResource.cs +++ b/source/Octopus.Client/Model/Accounts/Usages/AccountUsageResource.cs @@ -1,8 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Octopus.Client.Model.Accounts.Usages { @@ -10,18 +7,18 @@ public class AccountUsageResource : Resource { public AccountUsageResource() { - Targets = new List>(); - DeploymentProcesses = new List>(); - Releases = new List>(); - ProjectVariableSets = new List>(); - LibraryVariableSets = new List>(); + Targets = new List(); + DeploymentProcesses = new List(); + Releases = new List(); + ProjectVariableSets = new List(); + LibraryVariableSets = new List(); } - public ICollection> Targets { get; set; } - public ICollection> DeploymentProcesses { get; set; } - public ICollection> Releases { get; set; } - public ICollection> ProjectVariableSets { get; set; } - public ICollection> LibraryVariableSets { get; set; } + public ICollection Targets { get; set; } + public ICollection DeploymentProcesses { get; set; } + public ICollection Releases { get; set; } + public ICollection ProjectVariableSets { get; set; } + public ICollection LibraryVariableSets { get; set; } } public class TargetUsageEntry diff --git a/source/Octopus.Client/Model/CertificateUsageResource.cs b/source/Octopus.Client/Model/CertificateUsageResource.cs index 04f0249b1..64a687d64 100644 --- a/source/Octopus.Client/Model/CertificateUsageResource.cs +++ b/source/Octopus.Client/Model/CertificateUsageResource.cs @@ -4,17 +4,10 @@ namespace Octopus.Client.Model { public class CertificateUsageResource { - public ICollection> ProjectUsages { get; set; } + public ICollection ProjectUsages { get; set; } - public ICollection> LibraryVariableSetUsages { get; set; } + public ICollection LibraryVariableSetUsages { get; set; } - public ICollection> TenantUsages { get; set; } - - public class CertificateVariableUsageResource - { - public bool IsMissingScopedPermissions { get; set; } - public string MissingId { get; set;} - public T Owner { get; set; } - } + public ICollection TenantUsages { get; set; } } } \ No newline at end of file diff --git a/source/Octopus.Client/Model/UsageEntry.cs b/source/Octopus.Client/Model/UsageEntry.cs deleted file mode 100644 index 7cc5d8560..000000000 --- a/source/Octopus.Client/Model/UsageEntry.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Octopus.Client.Model -{ - public class UsageEntry - { - public bool IsMissingScopedPermissions { get; set; } - public string MissingId { get; set;} - public TEntry Entry { get; set;} - } -} \ No newline at end of file From e3453bc75544d62918803ea8f8d98af234b96daa Mon Sep 17 00:00:00 2001 From: Shannon Lewis Date: Thu, 10 May 2018 13:46:13 +1000 Subject: [PATCH 18/19] added AzureAccount to VariableType --- source/Octopus.Client/Model/VariableType.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/Octopus.Client/Model/VariableType.cs b/source/Octopus.Client/Model/VariableType.cs index d748b331f..e9692752e 100644 --- a/source/Octopus.Client/Model/VariableType.cs +++ b/source/Octopus.Client/Model/VariableType.cs @@ -5,6 +5,7 @@ public enum VariableType String, Sensitive, Certificate, - AmazonWebServicesAccount + AmazonWebServicesAccount, + AzureAccount } } \ No newline at end of file From 11df568d1ab66b3b71774a4f8d29246728db9c6e Mon Sep 17 00:00:00 2001 From: Shannon Lewis Date: Thu, 10 May 2018 13:57:17 +1000 Subject: [PATCH 19/19] yep, PublicSurfaceArea tests again --- ...re.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt | 1 + ...ePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt index 7e1258d73..28f1827b5 100644 --- a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt +++ b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETCore.approved.txt @@ -3394,6 +3394,7 @@ Octopus.Client.Model Sensitive = 1 Certificate = 2 AmazonWebServicesAccount = 3 + AzureAccount = 4 } class VersioningStrategyResource { diff --git a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt index c226ee5bb..59c3e5fc6 100644 --- a/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt +++ b/source/Octopus.Client.Tests/PublicSurfaceAreaFixture.ThePublicSurfaceAreaShouldNotRegress..NETFramework.approved.txt @@ -3879,6 +3879,7 @@ Octopus.Client.Model Sensitive = 1 Certificate = 2 AmazonWebServicesAccount = 3 + AzureAccount = 4 } class VersioningStrategyResource {