Skip to content

Commit ceb5375

Browse files
Mpdreamzrusscam
authored andcommitted
Add support for _license related API's
- License.LoadFromDisk(path) - Backported elasticsearch node improvements from master branch - Added bat file generations for the various clusters, allows you to manually start one of our test clusters with the right settings - Make sure tests that inherit ApiTestBase directly do not use a "real" client in `mixed` testing mode - Validate license information on startup, if this fails all tests fails. From the commandline we always start a fresh cluster so the trial license'll stay valid. If you manually start a node with no license but you have ES_LICENSE_FILE pointing to a license file we will try and register that.
1 parent 867cb36 commit ceb5375

File tree

8 files changed

+374
-697
lines changed

8 files changed

+374
-697
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"license.delete": {
3+
"documentation": "https://www.elastic.co/guide/en/shield/current/license-management.html",
4+
"methods": ["DELETE"],
5+
"url": {
6+
"path": "/_license",
7+
"paths": ["/_license"],
8+
"parts" : { },
9+
"params": { }
10+
},
11+
"body": null
12+
}
13+
}

src/Elasticsearch.Net/Domain/RequestParameters/RequestParameters.Generated.cs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5111,4 +5111,66 @@ public class GraphExploreRequestParameters : FluentRequestParameters<GraphExplor
51115111
public GraphExploreRequestParameters FilterPath(string filter_path) => this.AddQueryString("filter_path", filter_path);
51125112

51135113
}
5114+
5115+
///<summary>Request parameters descriptor for LicenseDelete
5116+
///<pre>
5117+
///https://www.elastic.co/guide/en/shield/current/license-management.html
5118+
///</pre>
5119+
///</summary>
5120+
public class DeleteLicenseRequestParameters : FluentRequestParameters<DeleteLicenseRequestParameters>
5121+
{
5122+
public override HttpMethod DefaultHttpMethod => HttpMethod.DELETE;
5123+
5124+
///<summary>The URL-encoded request definition</summary>
5125+
public DeleteLicenseRequestParameters Source(string source) => this.AddQueryString("source", source);
5126+
5127+
5128+
///<summary>Comma separated list of filters used to reduce the response returned by Elasticsearch</summary>
5129+
public DeleteLicenseRequestParameters FilterPath(string filter_path) => this.AddQueryString("filter_path", filter_path);
5130+
5131+
}
5132+
5133+
///<summary>Request parameters descriptor for LicenseGet
5134+
///<pre>
5135+
///https://www.elastic.co/guide/en/shield/current/license-management.html
5136+
///</pre>
5137+
///</summary>
5138+
public class GetLicenseRequestParameters : FluentRequestParameters<GetLicenseRequestParameters>
5139+
{
5140+
public override HttpMethod DefaultHttpMethod => HttpMethod.GET;
5141+
5142+
///<summary>Return local information, do not retrieve the state from master node (default: false)</summary>
5143+
public GetLicenseRequestParameters Local(bool local) => this.AddQueryString("local", local);
5144+
5145+
5146+
///<summary>The URL-encoded request definition</summary>
5147+
public GetLicenseRequestParameters Source(string source) => this.AddQueryString("source", source);
5148+
5149+
5150+
///<summary>Comma separated list of filters used to reduce the response returned by Elasticsearch</summary>
5151+
public GetLicenseRequestParameters FilterPath(string filter_path) => this.AddQueryString("filter_path", filter_path);
5152+
5153+
}
5154+
5155+
///<summary>Request parameters descriptor for LicensePost
5156+
///<pre>
5157+
///https://www.elastic.co/guide/en/shield/current/license-management.html
5158+
///</pre>
5159+
///</summary>
5160+
public class PostLicenseRequestParameters : FluentRequestParameters<PostLicenseRequestParameters>
5161+
{
5162+
public override HttpMethod DefaultHttpMethod => HttpMethod.PUT;
5163+
5164+
///<summary>whether the user has acknowledged acknowledge messages (default: false)</summary>
5165+
public PostLicenseRequestParameters Acknowledge(bool acknowledge) => this.AddQueryString("acknowledge", acknowledge);
5166+
5167+
5168+
///<summary>The URL-encoded request definition</summary>
5169+
public PostLicenseRequestParameters Source(string source) => this.AddQueryString("source", source);
5170+
5171+
5172+
///<summary>Comma separated list of filters used to reduce the response returned by Elasticsearch</summary>
5173+
public PostLicenseRequestParameters FilterPath(string filter_path) => this.AddQueryString("filter_path", filter_path);
5174+
5175+
}
51145176
}

src/Elasticsearch.Net/ElasticLowLevelClient.Generated.cs

Lines changed: 37 additions & 697 deletions
Large diffs are not rendered by default.

src/Elasticsearch.Net/IElasticLowLevelClient.Generated.cs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8369,5 +8369,79 @@ public partial interface IElasticLowLevelClient
83698369
///<param name="requestParameters">A func that allows you to describe the querystring parameters &amp; request specific connection settings.</param>
83708370
Task<ElasticsearchResponse<T>> GraphExploreAsync<T>(string index, string type, PostData<object> body, Func<GraphExploreRequestParameters, GraphExploreRequestParameters> requestParameters = null) where T : class;
83718371

8372+
///<summary>Represents a DELETE on /_license
8373+
///<para></para>Returns: ElasticsearchResponse&lt;T&gt; where the behavior depends on the type of T:
8374+
///<para> - T, an object you own that the elasticsearch response will be deserialized to </para>
8375+
///<para> - byte[], no deserialization, but the response stream will be closed </para>
8376+
///<para> - Stream, no deserialization, response stream is your responsibility </para>
8377+
///<para> - VoidResponse, no deserialization, response stream never read and closed </para>
8378+
///<para> - DynamicDictionary, a dynamic aware dictionary that can be safely traversed to any depth </para>
8379+
///<para>See also: https://www.elastic.co/guide/en/shield/current/license-management.html </para>
8380+
///</summary>
8381+
///<param name="requestParameters">A func that allows you to describe the querystring parameters &amp; request specific connection settings.</param>
8382+
ElasticsearchResponse<T> LicenseDelete<T>(Func<DeleteLicenseRequestParameters, DeleteLicenseRequestParameters> requestParameters = null) where T : class;
8383+
8384+
///<summary>Represents a DELETE on /_license
8385+
///<para></para>Returns: A task of ElasticsearchResponse&lt;T&gt; where the behaviour depends on the type of T:
8386+
///<para> - T, an object you own that the elasticsearch response will be deserialized to </para>
8387+
///<para> - byte[], no deserialization, but the response stream will be closed </para>
8388+
///<para> - Stream, no deserialization, response stream is your responsibility </para>
8389+
///<para> - VoidResponse, no deserialization, response stream never read and closed </para>
8390+
///<para> - DynamicDictionary, a dynamic aware dictionary that can be safely traversed to any depth </para>
8391+
///<para>See also: https://www.elastic.co/guide/en/shield/current/license-management.html </para>
8392+
///</summary>
8393+
///<param name="requestParameters">A func that allows you to describe the querystring parameters &amp; request specific connection settings.</param>
8394+
Task<ElasticsearchResponse<T>> LicenseDeleteAsync<T>(Func<DeleteLicenseRequestParameters, DeleteLicenseRequestParameters> requestParameters = null) where T : class;
8395+
8396+
///<summary>Represents a GET on /_license
8397+
///<para></para>Returns: ElasticsearchResponse&lt;T&gt; where the behavior depends on the type of T:
8398+
///<para> - T, an object you own that the elasticsearch response will be deserialized to </para>
8399+
///<para> - byte[], no deserialization, but the response stream will be closed </para>
8400+
///<para> - Stream, no deserialization, response stream is your responsibility </para>
8401+
///<para> - VoidResponse, no deserialization, response stream never read and closed </para>
8402+
///<para> - DynamicDictionary, a dynamic aware dictionary that can be safely traversed to any depth </para>
8403+
///<para>See also: https://www.elastic.co/guide/en/shield/current/license-management.html </para>
8404+
///</summary>
8405+
///<param name="requestParameters">A func that allows you to describe the querystring parameters &amp; request specific connection settings.</param>
8406+
ElasticsearchResponse<T> LicenseGet<T>(Func<GetLicenseRequestParameters, GetLicenseRequestParameters> requestParameters = null) where T : class;
8407+
8408+
///<summary>Represents a GET on /_license
8409+
///<para></para>Returns: A task of ElasticsearchResponse&lt;T&gt; where the behaviour depends on the type of T:
8410+
///<para> - T, an object you own that the elasticsearch response will be deserialized to </para>
8411+
///<para> - byte[], no deserialization, but the response stream will be closed </para>
8412+
///<para> - Stream, no deserialization, response stream is your responsibility </para>
8413+
///<para> - VoidResponse, no deserialization, response stream never read and closed </para>
8414+
///<para> - DynamicDictionary, a dynamic aware dictionary that can be safely traversed to any depth </para>
8415+
///<para>See also: https://www.elastic.co/guide/en/shield/current/license-management.html </para>
8416+
///</summary>
8417+
///<param name="requestParameters">A func that allows you to describe the querystring parameters &amp; request specific connection settings.</param>
8418+
Task<ElasticsearchResponse<T>> LicenseGetAsync<T>(Func<GetLicenseRequestParameters, GetLicenseRequestParameters> requestParameters = null) where T : class;
8419+
8420+
///<summary>Represents a PUT on /_license
8421+
///<para></para>Returns: ElasticsearchResponse&lt;T&gt; where the behavior depends on the type of T:
8422+
///<para> - T, an object you own that the elasticsearch response will be deserialized to </para>
8423+
///<para> - byte[], no deserialization, but the response stream will be closed </para>
8424+
///<para> - Stream, no deserialization, response stream is your responsibility </para>
8425+
///<para> - VoidResponse, no deserialization, response stream never read and closed </para>
8426+
///<para> - DynamicDictionary, a dynamic aware dictionary that can be safely traversed to any depth </para>
8427+
///<para>See also: https://www.elastic.co/guide/en/shield/current/license-management.html </para>
8428+
///</summary>
8429+
///<param name="body">licenses to be installed</param>
8430+
///<param name="requestParameters">A func that allows you to describe the querystring parameters &amp; request specific connection settings.</param>
8431+
ElasticsearchResponse<T> LicensePost<T>(PostData<object> body, Func<PostLicenseRequestParameters, PostLicenseRequestParameters> requestParameters = null) where T : class;
8432+
8433+
///<summary>Represents a PUT on /_license
8434+
///<para></para>Returns: A task of ElasticsearchResponse&lt;T&gt; where the behaviour depends on the type of T:
8435+
///<para> - T, an object you own that the elasticsearch response will be deserialized to </para>
8436+
///<para> - byte[], no deserialization, but the response stream will be closed </para>
8437+
///<para> - Stream, no deserialization, response stream is your responsibility </para>
8438+
///<para> - VoidResponse, no deserialization, response stream never read and closed </para>
8439+
///<para> - DynamicDictionary, a dynamic aware dictionary that can be safely traversed to any depth </para>
8440+
///<para>See also: https://www.elastic.co/guide/en/shield/current/license-management.html </para>
8441+
///</summary>
8442+
///<param name="body">licenses to be installed</param>
8443+
///<param name="requestParameters">A func that allows you to describe the querystring parameters &amp; request specific connection settings.</param>
8444+
Task<ElasticsearchResponse<T>> LicensePostAsync<T>(PostData<object> body, Func<PostLicenseRequestParameters, PostLicenseRequestParameters> requestParameters = null) where T : class;
8445+
83728446
}
83738447
}

src/Nest/_Generated/_Descriptors.generated.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5357,4 +5357,46 @@ public GraphExploreDescriptor(Indices index) : base(r=>r.Required("index", index
53575357
public GraphExploreDescriptor<T> FilterPath(string filter_path) => AssignParam(p=>p.FilterPath(filter_path));
53585358

53595359
}
5360+
5361+
///<summary>descriptor for LicenseDelete <pre>https://www.elastic.co/guide/en/shield/current/license-management.html</pre></summary>
5362+
public partial class DeleteLicenseDescriptor : RequestDescriptorBase<DeleteLicenseDescriptor,DeleteLicenseRequestParameters, IDeleteLicenseRequest>, IDeleteLicenseRequest
5363+
{
5364+
5365+
///<summary>The URL-encoded request definition</summary>
5366+
public DeleteLicenseDescriptor Source(string source) => AssignParam(p=>p.Source(source));
5367+
5368+
///<summary>Comma separated list of filters used to reduce the response returned by Elasticsearch</summary>
5369+
public DeleteLicenseDescriptor FilterPath(string filter_path) => AssignParam(p=>p.FilterPath(filter_path));
5370+
5371+
}
5372+
5373+
///<summary>descriptor for LicenseGet <pre>https://www.elastic.co/guide/en/shield/current/license-management.html</pre></summary>
5374+
public partial class GetLicenseDescriptor : RequestDescriptorBase<GetLicenseDescriptor,GetLicenseRequestParameters, IGetLicenseRequest>, IGetLicenseRequest
5375+
{
5376+
5377+
///<summary>Return local information, do not retrieve the state from master node (default: false)</summary>
5378+
public GetLicenseDescriptor Local(bool local = true) => AssignParam(p=>p.Local(local));
5379+
5380+
///<summary>The URL-encoded request definition</summary>
5381+
public GetLicenseDescriptor Source(string source) => AssignParam(p=>p.Source(source));
5382+
5383+
///<summary>Comma separated list of filters used to reduce the response returned by Elasticsearch</summary>
5384+
public GetLicenseDescriptor FilterPath(string filter_path) => AssignParam(p=>p.FilterPath(filter_path));
5385+
5386+
}
5387+
5388+
///<summary>descriptor for LicensePost <pre>https://www.elastic.co/guide/en/shield/current/license-management.html</pre></summary>
5389+
public partial class PostLicenseDescriptor : RequestDescriptorBase<PostLicenseDescriptor,PostLicenseRequestParameters, IPostLicenseRequest>, IPostLicenseRequest
5390+
{
5391+
5392+
///<summary>whether the user has acknowledged acknowledge messages (default: false)</summary>
5393+
public PostLicenseDescriptor Acknowledge(bool acknowledge = true) => AssignParam(p=>p.Acknowledge(acknowledge));
5394+
5395+
///<summary>The URL-encoded request definition</summary>
5396+
public PostLicenseDescriptor Source(string source) => AssignParam(p=>p.Source(source));
5397+
5398+
///<summary>Comma separated list of filters used to reduce the response returned by Elasticsearch</summary>
5399+
public PostLicenseDescriptor FilterPath(string filter_path) => AssignParam(p=>p.FilterPath(filter_path));
5400+
5401+
}
53605402
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
using System;
2+
using System.Globalization;
3+
using System.Text.RegularExpressions;
4+
5+
namespace Tests.Framework.Integration
6+
{
7+
public class ElasticsearchMessage
8+
{
9+
/*
10+
[2015-05-26 20:05:07,681][INFO ][node ] [Nick Fury] version[1.5.2], pid[7704], build[62ff986/2015-04-27T09:21:06Z]
11+
[2015-05-26 20:05:07,681][INFO ][node ] [Nick Fury] initializing ...
12+
[2015-05-26 20:05:07,681][INFO ][plugins ] [Nick Fury] loaded [], sites []
13+
[2015-05-26 20:05:10,790][INFO ][node ] [Nick Fury] initialized
14+
[2015-05-26 20:05:10,821][INFO ][node ] [Nick Fury] starting ...
15+
[2015-05-26 20:05:11,041][INFO ][transport ] [Nick Fury] bound_address {inet[/0:0:0:0:0:0:0:0:9300]}, publish_address {inet[/192.168.194.146:9300]}
16+
[2015-05-26 20:05:11,056][INFO ][discovery ] [Nick Fury] elasticsearch-martijnl/yuiyXva3Si6sQE5tY_9CHg
17+
[2015-05-26 20:05:14,103][INFO ][cluster.service ] [Nick Fury] new_master [Nick Fury][yuiyXva3Si6sQE5tY_9CHg][WIN-DK60SLEMH8C][inet[/192.168.194.146:9300]], reason: zen-disco-join (elected_as_master)
18+
[2015-05-26 20:05:14,134][INFO ][gateway ] [Nick Fury] recovered [0] indices into cluster_state
19+
[2015-05-26 20:05:14,150][INFO ][http ] [Nick Fury] bound_address {inet[/0:0:0:0:0:0:0:0:9200]}, publish_address {inet[/192.168.194.146:9200]}
20+
[2015-05-26 20:05:14,150][INFO ][node ] [Nick Fury] started
21+
*/
22+
23+
public DateTime Date { get; }
24+
public string Level { get; }
25+
public string Section { get; }
26+
public string Node { get; }
27+
public string Message { get; }
28+
29+
30+
private static readonly Regex ConsoleLineParser =
31+
new Regex(@"\[(?<date>.*?)\]\[(?<level>.*?)\]\[(?<section>.*?)\] \[(?<node>.*?)\] (?<message>.+)");
32+
33+
public ElasticsearchMessage(string consoleLine)
34+
{
35+
Console.WriteLine(consoleLine);
36+
if (string.IsNullOrEmpty(consoleLine)) return;
37+
var match = ConsoleLineParser.Match(consoleLine);
38+
if (!match.Success) return;
39+
var dateString = match.Groups["date"].Value.Trim();
40+
Date = DateTime.ParseExact(dateString, "yyyy-MM-dd HH:mm:ss,fff", CultureInfo.CurrentCulture);
41+
Level = match.Groups["level"].Value.Trim();
42+
Section = match.Groups["section"].Value.Trim().Replace("org.elasticsearch.", "");
43+
Node = match.Groups["node"].Value.Trim();
44+
Message = match.Groups["message"].Value.Trim();
45+
}
46+
47+
private static readonly Regex InfoParser =
48+
new Regex(@"version\[(?<version>.*)\], pid\[(?<pid>.*)\], build\[(?<build>.+)\]");
49+
50+
public bool TryParseNodeInfo(out ElasticsearchNodeInfo nodeInfo)
51+
{
52+
nodeInfo = null;
53+
if (this.Section != "node") return false;
54+
55+
var match = InfoParser.Match(this.Message);
56+
if (!match.Success) return false;
57+
58+
var version = match.Groups["version"].Value.Trim();
59+
var pid = match.Groups["pid"].Value.Trim();
60+
var build = match.Groups["build"].Value.Trim();
61+
nodeInfo = new ElasticsearchNodeInfo(version, pid, build);
62+
return true;
63+
}
64+
65+
public bool TryGetStartedConfirmation()
66+
{
67+
if (this.Section != "node") return false;
68+
return this.Message == "started";
69+
}
70+
71+
private static readonly Regex PortParser =
72+
new Regex(@"bound_address(es)? {.+\:(?<port>\d+)}");
73+
74+
public bool TryGetPortNumber(out int port)
75+
{
76+
port = 0;
77+
if (this.Section != "http") return false;
78+
79+
var match = PortParser.Match(this.Message);
80+
if (!match.Success) return false;
81+
82+
var portString = match.Groups["port"].Value.Trim();
83+
port = int.Parse(portString);
84+
return true;
85+
}
86+
}
87+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
namespace Tests.Framework.Integration
2+
{
3+
public class ElasticsearchNodeInfo
4+
{
5+
public string Version { get; }
6+
public int? Pid { get; }
7+
public string Build { get; }
8+
9+
public ElasticsearchNodeInfo(string version, string pid, string build)
10+
{
11+
this.Version = version;
12+
if (!string.IsNullOrEmpty(pid))
13+
Pid = int.Parse(pid);
14+
Build = build;
15+
}
16+
17+
}
18+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
using System;
2+
using System.Linq;
3+
using System.Text.RegularExpressions;
4+
using System.Xml.Linq;
5+
6+
namespace Tests.Framework.Integration
7+
{
8+
public class ElasticsearchVersionInfo
9+
{
10+
public ElasticsearchVersionInfo(string version)
11+
{
12+
this.Version = version;
13+
14+
if (this.IsSnapshot)
15+
{
16+
var mavenMetadata = XElement.Load($"{this.RootUrl}/{this.Version}/maven-metadata.xml");
17+
var snapshot = mavenMetadata.Descendants("versioning").Descendants("snapshot").FirstOrDefault();
18+
this.SnapshotTimestamp = snapshot.Descendants("timestamp").FirstOrDefault().Value;
19+
this.SnapshotBuildNumber = snapshot.Descendants("buildNumber").FirstOrDefault().Value;
20+
this.Zip = $"elasticsearch-{this.Version.Replace("SNAPSHOT", "")}{this.SnapshotIdentifier}.zip";
21+
}
22+
23+
this.Zip = this.Zip ?? $"elasticsearch-{this.Version}.zip";
24+
this.DownloadUrl = $"{this.RootUrl}/{this.Version}/{this.Zip}";
25+
this.ParsedVersion = new Version(Regex.Replace(this.Version, @"(?:\-.+)$", ""));
26+
}
27+
28+
public string DownloadUrl { get; set; }
29+
public string Zip { get; set; }
30+
public string Version { get; set; }
31+
public Version ParsedVersion { get; set; }
32+
public string SnapshotTimestamp { get; set; }
33+
public string SnapshotBuildNumber { get; set; }
34+
35+
public string SnapshotIdentifier => $"{this.SnapshotTimestamp}-{this.SnapshotBuildNumber}";
36+
public bool IsSnapshot => this.Version?.ToLower().Contains("snapshot") ?? false;
37+
public string RootUrl => this.IsSnapshot
38+
? "https://oss.sonatype.org/content/repositories/snapshots/org/elasticsearch/distribution/zip/elasticsearch"
39+
: "https://download.elasticsearch.org/elasticsearch/release/org/elasticsearch/distribution/zip/elasticsearch";
40+
}
41+
}

0 commit comments

Comments
 (0)