From 6899797d0918c57f48e882a87f2f190114295778 Mon Sep 17 00:00:00 2001 From: Russ Cam Date: Wed, 5 Aug 2020 12:15:45 +1000 Subject: [PATCH] Add security.clear_cached_privileges API (#4916) Relates: elastic/elasticsearch#55836 Derive ClearCachedRealmsResponse from NodesResponseBase to expose NodeStatistics. --- .../Configuration/CodeConfiguration.cs | 2 - src/Nest/Descriptors.Security.cs | 21 +++++++ src/Nest/ElasticClient.Security.cs | 24 ++++++++ src/Nest/Requests.Security.cs | 33 +++++++++++ .../ClearCachedPrivilegesRequest.cs | 13 ++++ .../ClearCachedPrivilegesResponse.cs | 19 ++++++ .../ClearCachedRealmsResponse.cs | 2 +- .../_Generated/ApiUrlsLookup.generated.cs | 1 + .../ClearCachedPrivilegesApiTests.cs | 59 +++++++++++++++++++ .../ClearCachedPrivilegesUrlTests.cs | 22 +++++++ .../ClearCachedRealmsApiTests.cs | 6 +- 11 files changed, 196 insertions(+), 6 deletions(-) create mode 100644 src/Nest/XPack/Security/ClearCachedPrivileges/ClearCachedPrivilegesRequest.cs create mode 100644 src/Nest/XPack/Security/ClearCachedPrivileges/ClearCachedPrivilegesResponse.cs create mode 100644 tests/Tests/XPack/Security/ClearCachedPrivileges/ClearCachedPrivilegesApiTests.cs create mode 100644 tests/Tests/XPack/Security/ClearCachedPrivileges/ClearCachedPrivilegesUrlTests.cs diff --git a/src/ApiGenerator/Configuration/CodeConfiguration.cs b/src/ApiGenerator/Configuration/CodeConfiguration.cs index c7b9b63d610..5ab79873b1c 100644 --- a/src/ApiGenerator/Configuration/CodeConfiguration.cs +++ b/src/ApiGenerator/Configuration/CodeConfiguration.cs @@ -36,8 +36,6 @@ public static class CodeConfiguration public static string[] IgnoredApisHighLevel { get; } = { - "security.clear_cached_privileges.json", // TODO: implement - "autoscaling.get_autoscaling_decision.json", // 7.7 experimental "autoscaling.delete_autoscaling_decision.json", // experimental "autoscaling.get_autoscaling_policy.json", // experimental diff --git a/src/Nest/Descriptors.Security.cs b/src/Nest/Descriptors.Security.cs index 9fffd2e3df0..62beaeebfa8 100644 --- a/src/Nest/Descriptors.Security.cs +++ b/src/Nest/Descriptors.Security.cs @@ -62,6 +62,27 @@ public ChangePasswordDescriptor(): base() public ChangePasswordDescriptor Refresh(Refresh? refresh) => Qs("refresh", refresh); } + ///Descriptor for ClearCachedPrivileges https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-clear-privilege-cache.html + public partial class ClearCachedPrivilegesDescriptor : RequestDescriptorBase, IClearCachedPrivilegesRequest + { + internal override ApiUrls ApiUrls => ApiUrlsLookups.SecurityClearCachedPrivileges; + ////_security/privilege/{application}/_clear_cache + ///this parameter is required + public ClearCachedPrivilegesDescriptor(Names application): base(r => r.Required("application", application)) + { + } + + ///Used for serialization purposes, making sure we have a parameterless constructor + [SerializationConstructor] + protected ClearCachedPrivilegesDescriptor(): base() + { + } + + // values part of the url path + Names IClearCachedPrivilegesRequest.Application => Self.RouteValues.Get("application"); + // Request parameters + } + ///Descriptor for ClearCachedRealms https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-clear-cache.html public partial class ClearCachedRealmsDescriptor : RequestDescriptorBase, IClearCachedRealmsRequest { diff --git a/src/Nest/ElasticClient.Security.cs b/src/Nest/ElasticClient.Security.cs index 66e7ef4fedb..9a4d33abe63 100644 --- a/src/Nest/ElasticClient.Security.cs +++ b/src/Nest/ElasticClient.Security.cs @@ -85,6 +85,30 @@ internal SecurityNamespace(ElasticClient client): base(client) /// public Task ChangePasswordAsync(IChangePasswordRequest request, CancellationToken ct = default) => DoRequestAsync(request, request.RequestParameters, ct); /// + /// POST request to the security.clear_cached_privileges API, read more about this API online: + /// + /// https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-clear-privilege-cache.html + /// + public ClearCachedPrivilegesResponse ClearCachedPrivileges(Names application, Func selector = null) => ClearCachedPrivileges(selector.InvokeOrDefault(new ClearCachedPrivilegesDescriptor(application: application))); + /// + /// POST request to the security.clear_cached_privileges API, read more about this API online: + /// + /// https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-clear-privilege-cache.html + /// + public Task ClearCachedPrivilegesAsync(Names application, Func selector = null, CancellationToken ct = default) => ClearCachedPrivilegesAsync(selector.InvokeOrDefault(new ClearCachedPrivilegesDescriptor(application: application)), ct); + /// + /// POST request to the security.clear_cached_privileges API, read more about this API online: + /// + /// https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-clear-privilege-cache.html + /// + public ClearCachedPrivilegesResponse ClearCachedPrivileges(IClearCachedPrivilegesRequest request) => DoRequest(request, request.RequestParameters); + /// + /// POST request to the security.clear_cached_privileges API, read more about this API online: + /// + /// https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-clear-privilege-cache.html + /// + public Task ClearCachedPrivilegesAsync(IClearCachedPrivilegesRequest request, CancellationToken ct = default) => DoRequestAsync(request, request.RequestParameters, ct); + /// /// POST request to the security.clear_cached_realms API, read more about this API online: /// /// https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-clear-cache.html diff --git a/src/Nest/Requests.Security.cs b/src/Nest/Requests.Security.cs index 069186fba59..f8165668306 100644 --- a/src/Nest/Requests.Security.cs +++ b/src/Nest/Requests.Security.cs @@ -86,6 +86,39 @@ public Refresh? Refresh } } + [InterfaceDataContract] + public partial interface IClearCachedPrivilegesRequest : IRequest + { + [IgnoreDataMember] + Names Application + { + get; + } + } + + ///Request for ClearCachedPrivileges https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-clear-privilege-cache.html + public partial class ClearCachedPrivilegesRequest : PlainRequestBase, IClearCachedPrivilegesRequest + { + protected IClearCachedPrivilegesRequest Self => this; + internal override ApiUrls ApiUrls => ApiUrlsLookups.SecurityClearCachedPrivileges; + ////_security/privilege/{application}/_clear_cache + ///this parameter is required + public ClearCachedPrivilegesRequest(Names application): base(r => r.Required("application", application)) + { + } + + ///Used for serialization purposes, making sure we have a parameterless constructor + [SerializationConstructor] + protected ClearCachedPrivilegesRequest(): base() + { + } + + // values part of the url path + [IgnoreDataMember] + Names IClearCachedPrivilegesRequest.Application => Self.RouteValues.Get("application"); + // Request parameters + } + [InterfaceDataContract] public partial interface IClearCachedRealmsRequest : IRequest { diff --git a/src/Nest/XPack/Security/ClearCachedPrivileges/ClearCachedPrivilegesRequest.cs b/src/Nest/XPack/Security/ClearCachedPrivileges/ClearCachedPrivilegesRequest.cs new file mode 100644 index 00000000000..b77a4cca00f --- /dev/null +++ b/src/Nest/XPack/Security/ClearCachedPrivileges/ClearCachedPrivilegesRequest.cs @@ -0,0 +1,13 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information + + namespace Nest +{ + [MapsApi("security.clear_cached_privileges.json")] + public partial interface IClearCachedPrivilegesRequest { } + + public partial class ClearCachedPrivilegesRequest { } + + public partial class ClearCachedPrivilegesDescriptor { } +} diff --git a/src/Nest/XPack/Security/ClearCachedPrivileges/ClearCachedPrivilegesResponse.cs b/src/Nest/XPack/Security/ClearCachedPrivileges/ClearCachedPrivilegesResponse.cs new file mode 100644 index 00000000000..6fd6156c5dc --- /dev/null +++ b/src/Nest/XPack/Security/ClearCachedPrivileges/ClearCachedPrivilegesResponse.cs @@ -0,0 +1,19 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information + + using System.Collections.Generic; +using System.Runtime.Serialization; +using Elasticsearch.Net; + +namespace Nest +{ + public class ClearCachedPrivilegesResponse : NodesResponseBase + { + [DataMember(Name ="cluster_name")] + public string ClusterName { get; internal set; } + + [DataMember(Name ="nodes")] + public IReadOnlyDictionary Nodes { get; internal set; } = EmptyReadOnly.Dictionary; + } +} diff --git a/src/Nest/XPack/Security/ClearCachedRealms/ClearCachedRealmsResponse.cs b/src/Nest/XPack/Security/ClearCachedRealms/ClearCachedRealmsResponse.cs index 92bd05165f8..57a2cafafa3 100644 --- a/src/Nest/XPack/Security/ClearCachedRealms/ClearCachedRealmsResponse.cs +++ b/src/Nest/XPack/Security/ClearCachedRealms/ClearCachedRealmsResponse.cs @@ -8,7 +8,7 @@ namespace Nest { - public class ClearCachedRealmsResponse : ResponseBase + public class ClearCachedRealmsResponse : NodesResponseBase { [DataMember(Name ="cluster_name")] public string ClusterName { get; internal set; } diff --git a/src/Nest/_Generated/ApiUrlsLookup.generated.cs b/src/Nest/_Generated/ApiUrlsLookup.generated.cs index f6434969fa7..01f1d2b4f6a 100644 --- a/src/Nest/_Generated/ApiUrlsLookup.generated.cs +++ b/src/Nest/_Generated/ApiUrlsLookup.generated.cs @@ -233,6 +233,7 @@ internal static class ApiUrlsLookups internal static ApiUrls NoNamespaceSearchTemplate = new ApiUrls(new[]{"_search/template", "{index}/_search/template"}); internal static ApiUrls SecurityAuthenticate = new ApiUrls(new[]{"_security/_authenticate"}); internal static ApiUrls SecurityChangePassword = new ApiUrls(new[]{"_security/user/{username}/_password", "_security/user/_password"}); + internal static ApiUrls SecurityClearCachedPrivileges = new ApiUrls(new[]{"_security/privilege/{application}/_clear_cache"}); internal static ApiUrls SecurityClearCachedRealms = new ApiUrls(new[]{"_security/realm/{realms}/_clear_cache"}); internal static ApiUrls SecurityClearCachedRoles = new ApiUrls(new[]{"_security/role/{name}/_clear_cache"}); internal static ApiUrls SecurityCreateApiKey = new ApiUrls(new[]{"_security/api_key"}); diff --git a/tests/Tests/XPack/Security/ClearCachedPrivileges/ClearCachedPrivilegesApiTests.cs b/tests/Tests/XPack/Security/ClearCachedPrivileges/ClearCachedPrivilegesApiTests.cs new file mode 100644 index 00000000000..f9e9bf9256d --- /dev/null +++ b/tests/Tests/XPack/Security/ClearCachedPrivileges/ClearCachedPrivilegesApiTests.cs @@ -0,0 +1,59 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information + +using System; +using System.Linq; +using Elastic.Elasticsearch.Ephemeral; +using Elastic.Elasticsearch.Xunit.XunitPlumbing; +using Elasticsearch.Net; +using FluentAssertions; +using Nest; +using Tests.Core.Extensions; +using Tests.Core.ManagedElasticsearch.Clusters; +using Tests.Framework.EndpointTests; +using Tests.Framework.EndpointTests.TestState; + +namespace Tests.XPack.Security.ClearCachedPrivileges +{ + [SkipVersion("<7.9.0", "Introduced in 7.9.0")] + public class ClearCachedPrivilegesApiTests + : ApiIntegrationTestBase + { + public ClearCachedPrivilegesApiTests(XPackCluster cluster, EndpointUsage usage) : base(cluster, usage) { } + + protected override bool ExpectIsValid => true; + protected override int ExpectStatusCode => 200; + + protected override Func Fluent => d => d; + protected override HttpMethod HttpMethod => HttpMethod.POST; + + protected override ClearCachedPrivilegesRequest Initializer => new ClearCachedPrivilegesRequest(Application); + + protected override bool SupportsDeserialization => false; + + protected override string UrlPath => $"/_security/privilege/{U(Application)}/_clear_cache"; + + private string Application => "myapp"; + + protected override LazyResponses ClientUsage() => Calls( + (client, f) => client.Security.ClearCachedPrivileges(Application, f), + (client, f) => client.Security.ClearCachedPrivilegesAsync(Application, f), + (client, r) => client.Security.ClearCachedPrivileges(r), + (client, r) => client.Security.ClearCachedPrivilegesAsync(r) + ); + + protected override ClearCachedPrivilegesDescriptor NewDescriptor() => new ClearCachedPrivilegesDescriptor(Application); + + protected override void ExpectResponse(ClearCachedPrivilegesResponse response) + { + response.ClusterName.Should().NotBeNullOrWhiteSpace(); + response.Nodes.Should().NotBeEmpty().And.HaveCount(1); + response.NodeStatistics.Should().NotBeNull(); + var node = response.Nodes.First().Value; + node.Should().NotBeNull(); + node.Name.Should().NotBeNullOrEmpty(); + } + } +} diff --git a/tests/Tests/XPack/Security/ClearCachedPrivileges/ClearCachedPrivilegesUrlTests.cs b/tests/Tests/XPack/Security/ClearCachedPrivileges/ClearCachedPrivilegesUrlTests.cs new file mode 100644 index 00000000000..8fc621e102c --- /dev/null +++ b/tests/Tests/XPack/Security/ClearCachedPrivileges/ClearCachedPrivilegesUrlTests.cs @@ -0,0 +1,22 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information + + using System.Threading.Tasks; +using Elastic.Elasticsearch.Xunit.XunitPlumbing; +using Nest; +using Tests.Framework.EndpointTests; +using static Tests.Framework.EndpointTests.UrlTester; + +namespace Tests.XPack.Security.ClearCachedPrivileges +{ + public class ClearCachedPrivilegesUrlTests : UrlTestsBase + { + [U] public override async Task Urls() => + await POST("/_security/privilege/myapp/_clear_cache") + .Fluent(c => c.Security.ClearCachedPrivileges("myapp")) + .Request(c => c.Security.ClearCachedPrivileges(new ClearCachedPrivilegesRequest("myapp"))) + .FluentAsync(c => c.Security.ClearCachedPrivilegesAsync("myapp")) + .RequestAsync(c => c.Security.ClearCachedPrivilegesAsync(new ClearCachedPrivilegesRequest("myapp"))); + } +} diff --git a/tests/Tests/XPack/Security/ClearCachedRealms/ClearCachedRealmsApiTests.cs b/tests/Tests/XPack/Security/ClearCachedRealms/ClearCachedRealmsApiTests.cs index ae93028c0cf..7437392269f 100644 --- a/tests/Tests/XPack/Security/ClearCachedRealms/ClearCachedRealmsApiTests.cs +++ b/tests/Tests/XPack/Security/ClearCachedRealms/ClearCachedRealmsApiTests.cs @@ -4,8 +4,8 @@ using System; using System.Linq; - using Elastic.Elasticsearch.Ephemeral; - using Elastic.Elasticsearch.Xunit.XunitPlumbing; +using Elastic.Elasticsearch.Ephemeral; +using Elastic.Elasticsearch.Xunit.XunitPlumbing; using Elasticsearch.Net; using FluentAssertions; using Nest; @@ -35,7 +35,6 @@ public ClearCachedRealmsApiTests(XPackCluster cluster, EndpointUsage usage) : ba protected override string UrlPath => $"/_security/realm/{U(Realm)}/_clear_cache"; - //callisolated value can sometimes start with a digit which is not allowed for rolenames private string Realm => SecurityRealms.FileRealm; protected override LazyResponses ClientUsage() => Calls( @@ -51,6 +50,7 @@ protected override void ExpectResponse(ClearCachedRealmsResponse response) { response.ClusterName.Should().NotBeNullOrWhiteSpace(); response.Nodes.Should().NotBeEmpty().And.HaveCount(1); + response.NodeStatistics.Should().NotBeNull(); var node = response.Nodes.First().Value; node.Should().NotBeNull(); node.Name.Should().NotBeNullOrEmpty();