diff --git a/.ci/test-matrix.yml b/.ci/test-matrix.yml index 6936e68c..3cb91ee6 100644 --- a/.ci/test-matrix.yml +++ b/.ci/test-matrix.yml @@ -8,6 +8,6 @@ TEST_SUITE: - platinum RUST_TOOLCHAIN: - - latest + - "1.50" exclude: ~ diff --git a/Makefile.toml b/Makefile.toml index 8702554c..cceddd44 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -120,6 +120,17 @@ exec cargo publish %{CARGO_MAKE_CARGO_PUBLISH_FLAGS} # Public tasks # ============ +[tasks.log-env] +script_runner = "@duckscript" +script = """ +rust_version = exec rustc --version +rust_version = trim ${rust_version.stdout} +echo rustc --version: ${rust_version} +echo RUST_VERSION: ${RUST_VERSION} +echo STACK_VERSION: ${STACK_VERSION} +echo TEST_SUITE: ${TEST_SUITE} +""" + [tasks.start-elasticsearch] extend = "run-elasticsearch" private = false @@ -136,7 +147,7 @@ env = { "CLEANUP" = true, "DETACH" = false } category = "Elasticsearch" description = "Generates and runs yaml_test_runner package platinum/free tests against a given Elasticsearch version" condition = { env_set = [ "STACK_VERSION", "TEST_SUITE" ] } -dependencies = ["generate-yaml-tests", "create-test-results-dir", "test-yaml-test-runner", "test-yaml-test-runner-ci", "convert-test-results-junit"] +dependencies = ["log-env", "generate-yaml-tests", "create-test-results-dir", "test-yaml-test-runner", "test-yaml-test-runner-ci", "convert-test-results-junit"] run_task = "stop-elasticsearch" [tasks.test-generator] diff --git a/api_generator/docs/namespaces/features.md b/api_generator/docs/namespaces/features.md new file mode 100644 index 00000000..19791309 --- /dev/null +++ b/api_generator/docs/namespaces/features.md @@ -0,0 +1,3 @@ +Features APIs + +Allows [introspecting and managing features](https://www.elastic.co/guide/en/elasticsearch/reference/current/features-apis.html) provided by Elasticsearch and Elasticsearch plugins. diff --git a/api_generator/rest_specs/cat.nodes.json b/api_generator/rest_specs/cat.nodes.json index fe3c0c52..06920cde 100644 --- a/api_generator/rest_specs/cat.nodes.json +++ b/api_generator/rest_specs/cat.nodes.json @@ -87,6 +87,11 @@ "type":"boolean", "description":"Verbose mode. Display column headers", "default":false + }, + "include_unloaded_segments":{ + "type":"boolean", + "description":"If set to true segment stats will include stats for segments that are not currently loaded into memory", + "default":false } } } diff --git a/api_generator/rest_specs/snapshot.get_features.json b/api_generator/rest_specs/features.get_features.json similarity index 67% rename from api_generator/rest_specs/snapshot.get_features.json rename to api_generator/rest_specs/features.get_features.json index 76b340d3..6d5e8b5a 100644 --- a/api_generator/rest_specs/snapshot.get_features.json +++ b/api_generator/rest_specs/features.get_features.json @@ -1,8 +1,8 @@ { - "snapshot.get_features":{ + "features.get_features":{ "documentation":{ - "url":"https://www.elastic.co/guide/en/elasticsearch/reference/master/modules-snapshots.html", - "description":"Returns a list of features which can be snapshotted in this cluster." + "url":"https://www.elastic.co/guide/en/elasticsearch/reference/master/get-features-api.html", + "description":"Gets a list of features which can be included in snapshots using the feature_states field when creating a snapshot" }, "stability":"stable", "visibility":"public", @@ -12,7 +12,7 @@ "url":{ "paths":[ { - "path":"/_snapshottable_features", + "path":"/_features", "methods":[ "GET" ] diff --git a/api_generator/rest_specs/features.reset_features.json b/api_generator/rest_specs/features.reset_features.json new file mode 100644 index 00000000..1a7f944e --- /dev/null +++ b/api_generator/rest_specs/features.reset_features.json @@ -0,0 +1,23 @@ +{ + "features.reset_features":{ + "documentation":{ + "url":"https://www.elastic.co/guide/en/elasticsearch/reference/master/modules-snapshots.html", + "description":"Resets the internal state of features, usually by deleting system indices" + }, + "stability":"experimental", + "visibility":"public", + "headers":{ + "accept": [ "application/json"] + }, + "url":{ + "paths":[ + { + "path":"/_features/_reset", + "methods":[ + "POST" + ] + } + ] + } + } +} diff --git a/api_generator/rest_specs/ingest.geo_ip_stats.json b/api_generator/rest_specs/ingest.geo_ip_stats.json new file mode 100644 index 00000000..1013d7dc --- /dev/null +++ b/api_generator/rest_specs/ingest.geo_ip_stats.json @@ -0,0 +1,25 @@ +{ + "ingest.geo_ip_stats": { + "documentation": { + "url": "https://www.elastic.co/guide/en/elasticsearch/reference/master/geoip-stats-api.html", + "description": "Returns statistical information about geoip databases" + }, + "stability": "stable", + "visibility": "public", + "headers": { + "accept": [ + "application/json" + ] + }, + "url": { + "paths": [ + { + "path": "/_ingest/geoip/stats", + "methods": [ + "GET" + ] + } + ] + } + } +} diff --git a/api_generator/rest_specs/ingest.get_pipeline.json b/api_generator/rest_specs/ingest.get_pipeline.json index c438c3bd..d6d408ea 100644 --- a/api_generator/rest_specs/ingest.get_pipeline.json +++ b/api_generator/rest_specs/ingest.get_pipeline.json @@ -32,6 +32,10 @@ ] }, "params":{ + "summary":{ + "type":"boolean", + "description":"Return pipelines without their definitions (default: false)" + }, "master_timeout":{ "type":"time", "description":"Explicit operation timeout for connection to master node" diff --git a/api_generator/rest_specs/ml.delete_trained_model_alias.json b/api_generator/rest_specs/ml.delete_trained_model_alias.json new file mode 100644 index 00000000..1e51ceea --- /dev/null +++ b/api_generator/rest_specs/ml.delete_trained_model_alias.json @@ -0,0 +1,34 @@ +{ + "ml.delete_trained_model_alias":{ + "documentation":{ + "url":"https://www.elastic.co/guide/en/elasticsearch/reference/current/delete-trained-models-aliases.html", + "description":"Deletes a model alias that refers to the trained model" + }, + "stability":"beta", + "visibility":"public", + "headers":{ + "accept": [ "application/json"], + "content_type": ["application/json"] + }, + "url":{ + "paths":[ + { + "path":"/_ml/trained_models/{model_id}/model_aliases/{model_alias}", + "methods":[ + "DELETE" + ], + "parts":{ + "model_alias":{ + "type":"string", + "description":"The trained model alias to delete" + }, + "model_id": { + "type": "string", + "description": "The trained model where the model alias is assigned" + } + } + } + ] + } + } +} diff --git a/api_generator/rest_specs/ml.preview_data_frame_analytics.json b/api_generator/rest_specs/ml.preview_data_frame_analytics.json new file mode 100644 index 00000000..dc671506 --- /dev/null +++ b/api_generator/rest_specs/ml.preview_data_frame_analytics.json @@ -0,0 +1,43 @@ +{ + "ml.preview_data_frame_analytics":{ + "documentation":{ + "url":"http://www.elastic.co/guide/en/elasticsearch/reference/current/preview-dfanalytics.html", + "description":"Previews that will be analyzed given a data frame analytics config." + }, + "stability":"beta", + "visibility":"public", + "headers":{ + "accept":[ "application/json"], + "content_type":["application/json"] + }, + "url":{ + "paths":[ + { + "path":"/_ml/data_frame/analytics/_preview", + "methods":[ + "GET", + "POST" + ], + "parts":{} + }, + { + "path":"/_ml/data_frame/analytics/{id}/_preview", + "methods":[ + "GET", + "POST" + ], + "parts":{ + "id":{ + "type":"string", + "description":"The ID of the data frame analytics to preview" + } + } + } + ] + }, + "body":{ + "description":"The data frame analytics config to preview", + "required":false + } + } +} diff --git a/api_generator/rest_specs/ml.preview_datafeed.json b/api_generator/rest_specs/ml.preview_datafeed.json index 5cd94bc2..2077cc5d 100644 --- a/api_generator/rest_specs/ml.preview_datafeed.json +++ b/api_generator/rest_specs/ml.preview_datafeed.json @@ -14,7 +14,8 @@ { "path":"/_ml/datafeeds/{datafeed_id}/_preview", "methods":[ - "GET" + "GET", + "POST" ], "parts":{ "datafeed_id":{ @@ -22,8 +23,19 @@ "description":"The ID of the datafeed to preview" } } + }, + { + "path":"/_ml/datafeeds/_preview", + "methods":[ + "GET", + "POST" + ] } ] + }, + "body":{ + "description":"The datafeed config and job config with which to execute the preview", + "required":false } } } diff --git a/api_generator/rest_specs/ml.put_trained_model_alias.json b/api_generator/rest_specs/ml.put_trained_model_alias.json new file mode 100644 index 00000000..c07e9639 --- /dev/null +++ b/api_generator/rest_specs/ml.put_trained_model_alias.json @@ -0,0 +1,40 @@ +{ + "ml.put_trained_model_alias":{ + "documentation":{ + "url":"https://www.elastic.co/guide/en/elasticsearch/reference/current/put-trained-models-aliases.html", + "description":"Creates a new model alias (or reassigns an existing one) to refer to the trained model" + }, + "stability":"beta", + "visibility":"public", + "headers":{ + "accept": [ "application/json"], + "content_type": ["application/json"] + }, + "url":{ + "paths":[ + { + "path":"/_ml/trained_models/{model_id}/model_aliases/{model_alias}", + "methods":[ + "PUT" + ], + "parts":{ + "model_alias":{ + "type":"string", + "description":"The trained model alias to update" + }, + "model_id": { + "type": "string", + "description": "The trained model where the model alias should be assigned" + } + } + } + ] + }, + "params":{ + "reassign":{ + "type":"boolean", + "description":"If the model_alias already exists and points to a separate model_id, this parameter must be true. Defaults to false." + } + } + } +} diff --git a/api_generator/rest_specs/nodes.stats.json b/api_generator/rest_specs/nodes.stats.json index dc8c96ff..3a0b1cb7 100644 --- a/api_generator/rest_specs/nodes.stats.json +++ b/api_generator/rest_specs/nodes.stats.json @@ -226,6 +226,11 @@ "type":"boolean", "description":"Whether to report the aggregated disk usage of each one of the Lucene index files (only applies if segment stats are requested)", "default":false + }, + "include_unloaded_segments":{ + "type":"boolean", + "description":"If set to true segment stats will include stats for segments that are not currently loaded into memory", + "default":false } } } diff --git a/api_generator/rest_specs/shutdown.delete_node.json b/api_generator/rest_specs/shutdown.delete_node.json new file mode 100644 index 00000000..864bf44d --- /dev/null +++ b/api_generator/rest_specs/shutdown.delete_node.json @@ -0,0 +1,31 @@ +{ + "shutdown.delete_node":{ + "documentation":{ + "url":"https://www.elastic.co/guide/en/elasticsearch/reference/current", + "description":"Removes a node from the shutdown list" + }, + "stability":"experimental", + "visibility":"public", + "headers":{ + "accept": [ "application/json"], + "content_type": ["application/json"] + }, + "url":{ + "paths":[ + { + "path":"/_nodes/{node_id}/shutdown", + "methods":[ + "DELETE" + ], + "parts":{ + "node_id":{ + "type":"string", + "description":"The node id of node to be removed from the shutdown state" + } + } + } + ] + }, + "params":{} + } +} diff --git a/api_generator/rest_specs/shutdown.get_node.json b/api_generator/rest_specs/shutdown.get_node.json new file mode 100644 index 00000000..02aec640 --- /dev/null +++ b/api_generator/rest_specs/shutdown.get_node.json @@ -0,0 +1,34 @@ +{ + "shutdown.get_node":{ + "documentation":{ + "url":"https://www.elastic.co/guide/en/elasticsearch/reference/current", + "description":"Retrieve status of a node or nodes that are currently marked as shutting down" + }, + "stability":"experimental", + "visibility":"public", + "headers":{ + "accept": [ "application/json"], + "content_type": ["application/json"] + }, + "url":{ + "paths":[ + { + "path":"/_nodes/shutdown", + "methods":["GET"], + "parts":{} + }, + { + "path":"/_nodes/{node_id}/shutdown", + "methods":["GET"], + "parts":{ + "node_id":{ + "type":"string", + "description":"Which node for which to retrieve the shutdown status" + } + } + } + ] + }, + "params":{} + } +} diff --git a/api_generator/rest_specs/shutdown.put_node.json b/api_generator/rest_specs/shutdown.put_node.json new file mode 100644 index 00000000..257e7b62 --- /dev/null +++ b/api_generator/rest_specs/shutdown.put_node.json @@ -0,0 +1,35 @@ +{ + "shutdown.put_node":{ + "documentation":{ + "url":"https://www.elastic.co/guide/en/elasticsearch/reference/current", + "description":"Adds a node to be shut down" + }, + "stability":"experimental", + "visibility":"public", + "headers":{ + "accept": [ "application/json"], + "content_type": ["application/json"] + }, + "url":{ + "paths":[ + { + "path":"/_nodes/{node_id}/shutdown", + "methods":[ + "PUT" + ], + "parts":{ + "node_id":{ + "type":"string", + "description":"The node id of node to be shut down" + } + } + } + ] + }, + "params":{}, + "body":{ + "description":"The shutdown type definition to register", + "required": true + } + } +} diff --git a/api_generator/src/generator/code_gen/mod.rs b/api_generator/src/generator/code_gen/mod.rs index 37095d65..e2157c72 100644 --- a/api_generator/src/generator/code_gen/mod.rs +++ b/api_generator/src/generator/code_gen/mod.rs @@ -137,7 +137,7 @@ impl GetPath for syn::Ty { fn get_path(&self) -> &syn::Path { match *self { syn::Ty::Path(_, ref p) => &p, - ref p => panic!(format!("Expected syn::Ty::Path, but found {:?}", p)), + ref p => panic!("Expected syn::Ty::Path, but found {:?}", p), } } } diff --git a/elasticsearch/Cargo.toml b/elasticsearch/Cargo.toml index 3f1b1e2b..6dbc5a53 100644 --- a/elasticsearch/Cargo.toml +++ b/elasticsearch/Cargo.toml @@ -29,6 +29,7 @@ rustls-tls = ["reqwest/rustls-tls"] base64 = "^0.11" bytes = "^1.0" dyn-clone = "~1" +lazy_static = "1.4" percent-encoding = "2.1.0" reqwest = { version = "~0.11", default-features = false, features = ["gzip", "json"] } url = "^2.1" @@ -45,6 +46,7 @@ futures = "0.3.1" http = "0.2" hyper = { version = "0.14", default-features = false, features = ["tcp", "stream", "server"] } os_type = "2.2" +regex="1.4" sysinfo = "0.12.0" textwrap = "^0.11" tokio = { version = "1.0", default-features = false, features = ["macros", "net", "time", "rt-multi-thread"] } diff --git a/elasticsearch/build.rs b/elasticsearch/build.rs index 1a213aa3..53983a99 100644 --- a/elasticsearch/build.rs +++ b/elasticsearch/build.rs @@ -20,7 +20,8 @@ extern crate rustc_version; use rustc_version::{version_meta, Channel}; fn main() { - match version_meta().unwrap().channel { + let version = version_meta().unwrap(); + match version.channel { Channel::Stable => { println!("cargo:rustc-cfg=RUSTC_IS_STABLE"); } @@ -34,4 +35,11 @@ fn main() { println!("cargo:rustc-cfg=RUSTC_IS_DEV"); } } + + let semver = version.semver; + let mut rustcv: String = format!("{}.{}.{}", semver.major, semver.minor, semver.patch); + if version.channel != Channel::Stable { + rustcv.push('p'); + } + println!("cargo:rustc-env=RUSTC_VERSION={}", rustcv); } diff --git a/elasticsearch/src/.generated.toml b/elasticsearch/src/.generated.toml index 06ea6570..6c8fe35d 100644 --- a/elasticsearch/src/.generated.toml +++ b/elasticsearch/src/.generated.toml @@ -7,6 +7,7 @@ written = [ 'dangling_indices.rs', 'enrich.rs', 'eql.rs', + 'features.rs', 'graph.rs', 'ilm.rs', 'indices.rs', @@ -21,6 +22,7 @@ written = [ 'root/mod.rs', 'searchable_snapshots.rs', 'security.rs', + 'shutdown.rs', 'slm.rs', 'snapshot.rs', 'sql.rs', diff --git a/elasticsearch/src/cat.rs b/elasticsearch/src/cat.rs index eae6dbe5..c79193e2 100644 --- a/elasticsearch/src/cat.rs +++ b/elasticsearch/src/cat.rs @@ -2649,6 +2649,7 @@ pub struct CatNodes<'a, 'b> { headers: HeaderMap, help: Option, human: Option, + include_unloaded_segments: Option, local: Option, master_timeout: Option<&'b str>, pretty: Option, @@ -2676,6 +2677,7 @@ impl<'a, 'b> CatNodes<'a, 'b> { h: None, help: None, human: None, + include_unloaded_segments: None, local: None, master_timeout: None, pretty: None, @@ -2731,6 +2733,11 @@ impl<'a, 'b> CatNodes<'a, 'b> { self.human = Some(human); self } + #[doc = "If set to true segment stats will include stats for segments that are not currently loaded into memory"] + pub fn include_unloaded_segments(mut self, include_unloaded_segments: bool) -> Self { + self.include_unloaded_segments = Some(include_unloaded_segments); + self + } #[doc = "Calculate the selected nodes using the local cluster state rather than the state from master node (default: false)"] pub fn local(mut self, local: bool) -> Self { self.local = Some(local); @@ -2791,6 +2798,7 @@ impl<'a, 'b> CatNodes<'a, 'b> { h: Option<&'b [&'b str]>, help: Option, human: Option, + include_unloaded_segments: Option, local: Option, master_timeout: Option<&'b str>, pretty: Option, @@ -2809,6 +2817,7 @@ impl<'a, 'b> CatNodes<'a, 'b> { h: self.h, help: self.help, human: self.human, + include_unloaded_segments: self.include_unloaded_segments, local: self.local, master_timeout: self.master_timeout, pretty: self.pretty, diff --git a/elasticsearch/src/features.rs b/elasticsearch/src/features.rs new file mode 100644 index 00000000..5ed4bbf5 --- /dev/null +++ b/elasticsearch/src/features.rs @@ -0,0 +1,336 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +// ----------------------------------------------- +// This file is generated, Please do not edit it manually. +// Run the following in the root of the repo to regenerate: +// +// cargo make generate-api +// ----------------------------------------------- + +//! Features APIs +//! +//! Allows [introspecting and managing features](https://www.elastic.co/guide/en/elasticsearch/reference/current/features-apis.html) provided by Elasticsearch and Elasticsearch plugins. + +#![allow(unused_imports)] +use crate::{ + client::Elasticsearch, + error::Error, + http::{ + headers::{HeaderMap, HeaderName, HeaderValue, ACCEPT, CONTENT_TYPE}, + request::{Body, JsonBody, NdBody, PARTS_ENCODED}, + response::Response, + transport::Transport, + Method, + }, + params::*, +}; +use percent_encoding::percent_encode; +use serde::Serialize; +use std::{borrow::Cow, time::Duration}; +#[derive(Debug, Clone, PartialEq)] +#[doc = "API parts for the Features Get Features API"] +pub enum FeaturesGetFeaturesParts { + #[doc = "No parts"] + None, +} +impl FeaturesGetFeaturesParts { + #[doc = "Builds a relative URL path to the Features Get Features API"] + pub fn url(self) -> Cow<'static, str> { + match self { + FeaturesGetFeaturesParts::None => "/_features".into(), + } + } +} +#[doc = "Builder for the [Features Get Features API](https://www.elastic.co/guide/en/elasticsearch/reference/7.11/get-features-api.html)\n\nGets a list of features which can be included in snapshots using the feature_states field when creating a snapshot"] +#[derive(Clone, Debug)] +pub struct FeaturesGetFeatures<'a, 'b> { + transport: &'a Transport, + parts: FeaturesGetFeaturesParts, + error_trace: Option, + filter_path: Option<&'b [&'b str]>, + headers: HeaderMap, + human: Option, + master_timeout: Option<&'b str>, + pretty: Option, + request_timeout: Option, + source: Option<&'b str>, +} +impl<'a, 'b> FeaturesGetFeatures<'a, 'b> { + #[doc = "Creates a new instance of [FeaturesGetFeatures]"] + pub fn new(transport: &'a Transport) -> Self { + let headers = HeaderMap::new(); + FeaturesGetFeatures { + transport, + parts: FeaturesGetFeaturesParts::None, + headers, + error_trace: None, + filter_path: None, + human: None, + master_timeout: None, + pretty: None, + request_timeout: None, + source: None, + } + } + #[doc = "Include the stack trace of returned errors."] + pub fn error_trace(mut self, error_trace: bool) -> Self { + self.error_trace = Some(error_trace); + self + } + #[doc = "A comma-separated list of filters used to reduce the response."] + pub fn filter_path(mut self, filter_path: &'b [&'b str]) -> Self { + self.filter_path = Some(filter_path); + self + } + #[doc = "Adds a HTTP header"] + pub fn header(mut self, key: HeaderName, value: HeaderValue) -> Self { + self.headers.insert(key, value); + self + } + #[doc = "Return human readable values for statistics."] + pub fn human(mut self, human: bool) -> Self { + self.human = Some(human); + self + } + #[doc = "Explicit operation timeout for connection to master node"] + pub fn master_timeout(mut self, master_timeout: &'b str) -> Self { + self.master_timeout = Some(master_timeout); + self + } + #[doc = "Pretty format the returned JSON response."] + pub fn pretty(mut self, pretty: bool) -> Self { + self.pretty = Some(pretty); + self + } + #[doc = "Sets a request timeout for this API call.\n\nThe timeout is applied from when the request starts connecting until the response body has finished."] + pub fn request_timeout(mut self, timeout: Duration) -> Self { + self.request_timeout = Some(timeout); + self + } + #[doc = "The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests."] + pub fn source(mut self, source: &'b str) -> Self { + self.source = Some(source); + self + } + #[doc = "Creates an asynchronous call to the Features Get Features API that can be awaited"] + pub async fn send(self) -> Result { + let path = self.parts.url(); + let method = Method::Get; + let headers = self.headers; + let timeout = self.request_timeout; + let query_string = { + #[serde_with::skip_serializing_none] + #[derive(Serialize)] + struct QueryParams<'b> { + error_trace: Option, + #[serde(serialize_with = "crate::client::serialize_coll_qs")] + filter_path: Option<&'b [&'b str]>, + human: Option, + master_timeout: Option<&'b str>, + pretty: Option, + source: Option<&'b str>, + } + let query_params = QueryParams { + error_trace: self.error_trace, + filter_path: self.filter_path, + human: self.human, + master_timeout: self.master_timeout, + pretty: self.pretty, + source: self.source, + }; + Some(query_params) + }; + let body = Option::<()>::None; + let response = self + .transport + .send(method, &path, headers, query_string.as_ref(), body, timeout) + .await?; + Ok(response) + } +} +#[cfg(feature = "experimental-apis")] +#[derive(Debug, Clone, PartialEq)] +#[doc = "API parts for the Features Reset Features API"] +pub enum FeaturesResetFeaturesParts { + #[doc = "No parts"] + None, +} +#[cfg(feature = "experimental-apis")] +impl FeaturesResetFeaturesParts { + #[doc = "Builds a relative URL path to the Features Reset Features API"] + pub fn url(self) -> Cow<'static, str> { + match self { + FeaturesResetFeaturesParts::None => "/_features/_reset".into(), + } + } +} +#[doc = "Builder for the [Features Reset Features API](https://www.elastic.co/guide/en/elasticsearch/reference/7.11/modules-snapshots.html)\n\nResets the internal state of features, usually by deleting system indices"] +#[doc = " \n# Optional, experimental\nThis requires the `experimental-apis` feature. Can have breaking changes in future\nversions or might even be removed entirely.\n "] +#[cfg(feature = "experimental-apis")] +#[derive(Clone, Debug)] +pub struct FeaturesResetFeatures<'a, 'b, B> { + transport: &'a Transport, + parts: FeaturesResetFeaturesParts, + body: Option, + error_trace: Option, + filter_path: Option<&'b [&'b str]>, + headers: HeaderMap, + human: Option, + pretty: Option, + request_timeout: Option, + source: Option<&'b str>, +} +#[cfg(feature = "experimental-apis")] +impl<'a, 'b, B> FeaturesResetFeatures<'a, 'b, B> +where + B: Body, +{ + #[doc = "Creates a new instance of [FeaturesResetFeatures]"] + pub fn new(transport: &'a Transport) -> Self { + let headers = HeaderMap::new(); + FeaturesResetFeatures { + transport, + parts: FeaturesResetFeaturesParts::None, + headers, + body: None, + error_trace: None, + filter_path: None, + human: None, + pretty: None, + request_timeout: None, + source: None, + } + } + #[doc = "The body for the API call"] + pub fn body(self, body: T) -> FeaturesResetFeatures<'a, 'b, JsonBody> + where + T: Serialize, + { + FeaturesResetFeatures { + transport: self.transport, + parts: self.parts, + body: Some(body.into()), + error_trace: self.error_trace, + filter_path: self.filter_path, + headers: self.headers, + human: self.human, + pretty: self.pretty, + request_timeout: self.request_timeout, + source: self.source, + } + } + #[doc = "Include the stack trace of returned errors."] + pub fn error_trace(mut self, error_trace: bool) -> Self { + self.error_trace = Some(error_trace); + self + } + #[doc = "A comma-separated list of filters used to reduce the response."] + pub fn filter_path(mut self, filter_path: &'b [&'b str]) -> Self { + self.filter_path = Some(filter_path); + self + } + #[doc = "Adds a HTTP header"] + pub fn header(mut self, key: HeaderName, value: HeaderValue) -> Self { + self.headers.insert(key, value); + self + } + #[doc = "Return human readable values for statistics."] + pub fn human(mut self, human: bool) -> Self { + self.human = Some(human); + self + } + #[doc = "Pretty format the returned JSON response."] + pub fn pretty(mut self, pretty: bool) -> Self { + self.pretty = Some(pretty); + self + } + #[doc = "Sets a request timeout for this API call.\n\nThe timeout is applied from when the request starts connecting until the response body has finished."] + pub fn request_timeout(mut self, timeout: Duration) -> Self { + self.request_timeout = Some(timeout); + self + } + #[doc = "The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests."] + pub fn source(mut self, source: &'b str) -> Self { + self.source = Some(source); + self + } + #[doc = "Creates an asynchronous call to the Features Reset Features API that can be awaited"] + pub async fn send(self) -> Result { + let path = self.parts.url(); + let method = Method::Post; + let headers = self.headers; + let timeout = self.request_timeout; + let query_string = { + #[serde_with::skip_serializing_none] + #[derive(Serialize)] + struct QueryParams<'b> { + error_trace: Option, + #[serde(serialize_with = "crate::client::serialize_coll_qs")] + filter_path: Option<&'b [&'b str]>, + human: Option, + pretty: Option, + source: Option<&'b str>, + } + let query_params = QueryParams { + error_trace: self.error_trace, + filter_path: self.filter_path, + human: self.human, + pretty: self.pretty, + source: self.source, + }; + Some(query_params) + }; + let body = self.body; + let response = self + .transport + .send(method, &path, headers, query_string.as_ref(), body, timeout) + .await?; + Ok(response) + } +} +#[doc = "Namespace client for Features APIs"] +pub struct Features<'a> { + transport: &'a Transport, +} +impl<'a> Features<'a> { + #[doc = "Creates a new instance of [Features]"] + pub fn new(transport: &'a Transport) -> Self { + Self { transport } + } + pub fn transport(&self) -> &Transport { + self.transport + } + #[doc = "[Features Get Features API](https://www.elastic.co/guide/en/elasticsearch/reference/7.11/get-features-api.html)\n\nGets a list of features which can be included in snapshots using the feature_states field when creating a snapshot"] + pub fn get_features<'b>(&'a self) -> FeaturesGetFeatures<'a, 'b> { + FeaturesGetFeatures::new(self.transport()) + } + #[doc = "[Features Reset Features API](https://www.elastic.co/guide/en/elasticsearch/reference/7.11/modules-snapshots.html)\n\nResets the internal state of features, usually by deleting system indices"] + #[doc = " \n# Optional, experimental\nThis requires the `experimental-apis` feature. Can have breaking changes in future\nversions or might even be removed entirely.\n "] + #[cfg(feature = "experimental-apis")] + pub fn reset_features<'b>(&'a self) -> FeaturesResetFeatures<'a, 'b, ()> { + FeaturesResetFeatures::new(self.transport()) + } +} +impl Elasticsearch { + #[doc = "Creates a namespace client for Features APIs"] + pub fn features(&self) -> Features { + Features::new(self.transport()) + } +} diff --git a/elasticsearch/src/http/transport.rs b/elasticsearch/src/http/transport.rs index 14a2cdea..ead0c82a 100644 --- a/elasticsearch/src/http/transport.rs +++ b/elasticsearch/src/http/transport.rs @@ -37,6 +37,7 @@ use crate::{ }; use base64::write::EncoderWriter as Base64Encoder; use bytes::BytesMut; +use lazy_static::lazy_static; use serde::Serialize; use std::{ error, fmt, @@ -97,6 +98,37 @@ impl fmt::Display for BuildError { /// Default address to Elasticsearch running on `http://localhost:9200` pub static DEFAULT_ADDRESS: &str = "http://localhost:9200"; +lazy_static! { + /// Client metadata header: service, language, transport, followed by additional information + static ref CLIENT_META: String = build_meta(); +} + +fn build_meta() -> String { + let mut version_parts = env!("CARGO_PKG_VERSION").split(&['.', '-'][..]); + let mut version = String::new(); + + // major.minor.patch followed with an optional 'p' for preliminary versions + version.push_str(version_parts.next().unwrap()); + version.push('.'); + version.push_str(version_parts.next().unwrap()); + version.push('.'); + version.push_str(version_parts.next().unwrap()); + if version_parts.next().is_some() { + version.push('p'); + } + + let rustc = env!("RUSTC_VERSION"); + let mut meta = format!("es={},rs={},t={}", version, rustc, version); + + if cfg!(feature = "native-tls") { + meta.push_str(",tls=n"); + } else if cfg!(feature = "rustls-tls") { + meta.push_str(",tls=r"); + } + + meta +} + /// Builds a HTTP transport to make API calls to Elasticsearch pub struct TransportBuilder { client_builder: reqwest::ClientBuilder, @@ -108,6 +140,7 @@ pub struct TransportBuilder { proxy_credentials: Option, disable_proxy: bool, headers: HeaderMap, + meta_header: bool, timeout: Option, } @@ -128,6 +161,7 @@ impl TransportBuilder { proxy_credentials: None, disable_proxy: false, headers: HeaderMap::new(), + meta_header: true, timeout: None, } } @@ -187,6 +221,16 @@ impl TransportBuilder { self } + /// Whether to send a `x-elastic-client-meta` header that describes the runtime environment. + /// + /// This header contains information that is similar to what could be found in `User-Agent`. Using a separate + /// header allows applications to use `User-Agent` for their own needs, e.g. to identify application version + /// or other environment information. Defaults to `true`. + pub fn enable_meta_header(mut self, enable: bool) -> Self { + self.meta_header = enable; + self + } + /// Sets a global request timeout for the client. /// /// The timeout is applied from when the request starts connecting until the response body has finished. @@ -270,6 +314,7 @@ impl TransportBuilder { client, conn_pool: self.conn_pool, credentials: self.credentials, + send_meta: self.meta_header, }) } } @@ -309,6 +354,7 @@ pub struct Transport { client: reqwest::Client, credentials: Option, conn_pool: Box, + send_meta: bool, } impl Transport { @@ -396,13 +442,20 @@ impl Transport { } // default headers first, overwrite with any provided - let mut request_headers = HeaderMap::with_capacity(3 + headers.len()); + let mut request_headers = HeaderMap::with_capacity(4 + headers.len()); request_headers.insert(CONTENT_TYPE, HeaderValue::from_static(DEFAULT_CONTENT_TYPE)); request_headers.insert(ACCEPT, HeaderValue::from_static(DEFAULT_ACCEPT)); request_headers.insert(USER_AGENT, HeaderValue::from_static(DEFAULT_USER_AGENT)); for (name, value) in headers { request_headers.insert(name.unwrap(), value); } + // if meta header enabled, send it last so that it's not overridden. + if self.send_meta { + request_headers.insert( + "x-elastic-client-meta", + HeaderValue::from_static(CLIENT_META.as_str()), + ); + } request_builder = request_builder.headers(request_headers); @@ -601,9 +654,10 @@ impl ConnectionPool for CloudConnectionPool { #[cfg(test)] pub mod tests { + use super::*; #[cfg(any(feature = "native-tls", feature = "rustls-tls"))] use crate::auth::ClientCertificate; - use crate::http::transport::{CloudId, Connection, SingleNodeConnectionPool, TransportBuilder}; + use regex::Regex; use url::Url; #[test] @@ -742,4 +796,12 @@ pub mod tests { let conn = Connection::new(url); assert_eq!(conn.url.as_str(), "http://10.1.2.3/"); } + + #[test] + pub fn test_meta_header() { + let re = Regex::new(r"^es=[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,3}p?,rs=[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,3}p?,t=[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,3}p?(,tls=[rn])?$").unwrap(); + let x: &str = CLIENT_META.as_str(); + println!("{}", x); + assert!(re.is_match(x)); + } } diff --git a/elasticsearch/src/ingest.rs b/elasticsearch/src/ingest.rs index 4823ca34..bbe791da 100644 --- a/elasticsearch/src/ingest.rs +++ b/elasticsearch/src/ingest.rs @@ -195,6 +195,118 @@ impl<'a, 'b> IngestDeletePipeline<'a, 'b> { } } #[derive(Debug, Clone, PartialEq)] +#[doc = "API parts for the Ingest Geo Ip Stats API"] +pub enum IngestGeoIpStatsParts { + #[doc = "No parts"] + None, +} +impl IngestGeoIpStatsParts { + #[doc = "Builds a relative URL path to the Ingest Geo Ip Stats API"] + pub fn url(self) -> Cow<'static, str> { + match self { + IngestGeoIpStatsParts::None => "/_ingest/geoip/stats".into(), + } + } +} +#[doc = "Builder for the [Ingest Geo Ip Stats API](https://www.elastic.co/guide/en/elasticsearch/reference/7.11/geoip-stats-api.html)\n\nReturns statistical information about geoip databases"] +#[derive(Clone, Debug)] +pub struct IngestGeoIpStats<'a, 'b> { + transport: &'a Transport, + parts: IngestGeoIpStatsParts, + error_trace: Option, + filter_path: Option<&'b [&'b str]>, + headers: HeaderMap, + human: Option, + pretty: Option, + request_timeout: Option, + source: Option<&'b str>, +} +impl<'a, 'b> IngestGeoIpStats<'a, 'b> { + #[doc = "Creates a new instance of [IngestGeoIpStats]"] + pub fn new(transport: &'a Transport) -> Self { + let headers = HeaderMap::new(); + IngestGeoIpStats { + transport, + parts: IngestGeoIpStatsParts::None, + headers, + error_trace: None, + filter_path: None, + human: None, + pretty: None, + request_timeout: None, + source: None, + } + } + #[doc = "Include the stack trace of returned errors."] + pub fn error_trace(mut self, error_trace: bool) -> Self { + self.error_trace = Some(error_trace); + self + } + #[doc = "A comma-separated list of filters used to reduce the response."] + pub fn filter_path(mut self, filter_path: &'b [&'b str]) -> Self { + self.filter_path = Some(filter_path); + self + } + #[doc = "Adds a HTTP header"] + pub fn header(mut self, key: HeaderName, value: HeaderValue) -> Self { + self.headers.insert(key, value); + self + } + #[doc = "Return human readable values for statistics."] + pub fn human(mut self, human: bool) -> Self { + self.human = Some(human); + self + } + #[doc = "Pretty format the returned JSON response."] + pub fn pretty(mut self, pretty: bool) -> Self { + self.pretty = Some(pretty); + self + } + #[doc = "Sets a request timeout for this API call.\n\nThe timeout is applied from when the request starts connecting until the response body has finished."] + pub fn request_timeout(mut self, timeout: Duration) -> Self { + self.request_timeout = Some(timeout); + self + } + #[doc = "The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests."] + pub fn source(mut self, source: &'b str) -> Self { + self.source = Some(source); + self + } + #[doc = "Creates an asynchronous call to the Ingest Geo Ip Stats API that can be awaited"] + pub async fn send(self) -> Result { + let path = self.parts.url(); + let method = Method::Get; + let headers = self.headers; + let timeout = self.request_timeout; + let query_string = { + #[serde_with::skip_serializing_none] + #[derive(Serialize)] + struct QueryParams<'b> { + error_trace: Option, + #[serde(serialize_with = "crate::client::serialize_coll_qs")] + filter_path: Option<&'b [&'b str]>, + human: Option, + pretty: Option, + source: Option<&'b str>, + } + let query_params = QueryParams { + error_trace: self.error_trace, + filter_path: self.filter_path, + human: self.human, + pretty: self.pretty, + source: self.source, + }; + Some(query_params) + }; + let body = Option::<()>::None; + let response = self + .transport + .send(method, &path, headers, query_string.as_ref(), body, timeout) + .await?; + Ok(response) + } +} +#[derive(Debug, Clone, PartialEq)] #[doc = "API parts for the Ingest Get Pipeline API"] pub enum IngestGetPipelineParts<'b> { #[doc = "No parts"] @@ -230,6 +342,7 @@ pub struct IngestGetPipeline<'a, 'b> { pretty: Option, request_timeout: Option, source: Option<&'b str>, + summary: Option, } impl<'a, 'b> IngestGetPipeline<'a, 'b> { #[doc = "Creates a new instance of [IngestGetPipeline] with the specified API parts"] @@ -246,6 +359,7 @@ impl<'a, 'b> IngestGetPipeline<'a, 'b> { pretty: None, request_timeout: None, source: None, + summary: None, } } #[doc = "Include the stack trace of returned errors."] @@ -288,6 +402,11 @@ impl<'a, 'b> IngestGetPipeline<'a, 'b> { self.source = Some(source); self } + #[doc = "Return pipelines without their definitions (default: false)"] + pub fn summary(mut self, summary: bool) -> Self { + self.summary = Some(summary); + self + } #[doc = "Creates an asynchronous call to the Ingest Get Pipeline API that can be awaited"] pub async fn send(self) -> Result { let path = self.parts.url(); @@ -305,6 +424,7 @@ impl<'a, 'b> IngestGetPipeline<'a, 'b> { master_timeout: Option<&'b str>, pretty: Option, source: Option<&'b str>, + summary: Option, } let query_params = QueryParams { error_trace: self.error_trace, @@ -313,6 +433,7 @@ impl<'a, 'b> IngestGetPipeline<'a, 'b> { master_timeout: self.master_timeout, pretty: self.pretty, source: self.source, + summary: self.summary, }; Some(query_params) }; @@ -774,6 +895,10 @@ impl<'a> Ingest<'a> { ) -> IngestDeletePipeline<'a, 'b> { IngestDeletePipeline::new(self.transport(), parts) } + #[doc = "[Ingest Geo Ip Stats API](https://www.elastic.co/guide/en/elasticsearch/reference/7.11/geoip-stats-api.html)\n\nReturns statistical information about geoip databases"] + pub fn geo_ip_stats<'b>(&'a self) -> IngestGeoIpStats<'a, 'b> { + IngestGeoIpStats::new(self.transport()) + } #[doc = "[Ingest Get Pipeline API](https://www.elastic.co/guide/en/elasticsearch/reference/7.11/get-pipeline-api.html)\n\nReturns a pipeline."] pub fn get_pipeline<'b>( &'a self, diff --git a/elasticsearch/src/lib.rs b/elasticsearch/src/lib.rs index 24a12cf1..16bfbd05 100644 --- a/elasticsearch/src/lib.rs +++ b/elasticsearch/src/lib.rs @@ -372,6 +372,7 @@ pub mod cluster; pub mod dangling_indices; pub mod enrich; pub mod eql; +pub mod features; pub mod graph; pub mod ilm; pub mod indices; @@ -385,6 +386,7 @@ pub mod nodes; pub mod rollup; pub mod searchable_snapshots; pub mod security; +pub mod shutdown; pub mod slm; pub mod snapshot; pub mod sql; diff --git a/elasticsearch/src/ml.rs b/elasticsearch/src/ml.rs index 150ba5dd..5d1bf49e 100644 --- a/elasticsearch/src/ml.rs +++ b/elasticsearch/src/ml.rs @@ -1689,6 +1689,136 @@ impl<'a, 'b> MlDeleteTrainedModel<'a, 'b> { Ok(response) } } +#[cfg(feature = "beta-apis")] +#[derive(Debug, Clone, PartialEq)] +#[doc = "API parts for the Ml Delete Trained Model Alias API"] +pub enum MlDeleteTrainedModelAliasParts<'b> { + #[doc = "ModelId and ModelAlias"] + ModelIdModelAlias(&'b str, &'b str), +} +#[cfg(feature = "beta-apis")] +impl<'b> MlDeleteTrainedModelAliasParts<'b> { + #[doc = "Builds a relative URL path to the Ml Delete Trained Model Alias API"] + pub fn url(self) -> Cow<'static, str> { + match self { + MlDeleteTrainedModelAliasParts::ModelIdModelAlias(ref model_id, ref model_alias) => { + let encoded_model_id: Cow = + percent_encode(model_id.as_bytes(), PARTS_ENCODED).into(); + let encoded_model_alias: Cow = + percent_encode(model_alias.as_bytes(), PARTS_ENCODED).into(); + let mut p = String::with_capacity( + 35usize + encoded_model_id.len() + encoded_model_alias.len(), + ); + p.push_str("/_ml/trained_models/"); + p.push_str(encoded_model_id.as_ref()); + p.push_str("/model_aliases/"); + p.push_str(encoded_model_alias.as_ref()); + p.into() + } + } + } +} +#[doc = "Builder for the [Ml Delete Trained Model Alias API](https://www.elastic.co/guide/en/elasticsearch/reference/7.11/delete-trained-models-aliases.html)\n\nDeletes a model alias that refers to the trained model"] +#[doc = " \n# Optional, beta\nThis requires the `beta-apis` feature. On track to become stable but breaking changes can\nhappen in minor versions.\n "] +#[cfg(feature = "beta-apis")] +#[derive(Clone, Debug)] +pub struct MlDeleteTrainedModelAlias<'a, 'b> { + transport: &'a Transport, + parts: MlDeleteTrainedModelAliasParts<'b>, + error_trace: Option, + filter_path: Option<&'b [&'b str]>, + headers: HeaderMap, + human: Option, + pretty: Option, + request_timeout: Option, + source: Option<&'b str>, +} +#[cfg(feature = "beta-apis")] +impl<'a, 'b> MlDeleteTrainedModelAlias<'a, 'b> { + #[doc = "Creates a new instance of [MlDeleteTrainedModelAlias] with the specified API parts"] + pub fn new(transport: &'a Transport, parts: MlDeleteTrainedModelAliasParts<'b>) -> Self { + let headers = HeaderMap::new(); + MlDeleteTrainedModelAlias { + transport, + parts, + headers, + error_trace: None, + filter_path: None, + human: None, + pretty: None, + request_timeout: None, + source: None, + } + } + #[doc = "Include the stack trace of returned errors."] + pub fn error_trace(mut self, error_trace: bool) -> Self { + self.error_trace = Some(error_trace); + self + } + #[doc = "A comma-separated list of filters used to reduce the response."] + pub fn filter_path(mut self, filter_path: &'b [&'b str]) -> Self { + self.filter_path = Some(filter_path); + self + } + #[doc = "Adds a HTTP header"] + pub fn header(mut self, key: HeaderName, value: HeaderValue) -> Self { + self.headers.insert(key, value); + self + } + #[doc = "Return human readable values for statistics."] + pub fn human(mut self, human: bool) -> Self { + self.human = Some(human); + self + } + #[doc = "Pretty format the returned JSON response."] + pub fn pretty(mut self, pretty: bool) -> Self { + self.pretty = Some(pretty); + self + } + #[doc = "Sets a request timeout for this API call.\n\nThe timeout is applied from when the request starts connecting until the response body has finished."] + pub fn request_timeout(mut self, timeout: Duration) -> Self { + self.request_timeout = Some(timeout); + self + } + #[doc = "The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests."] + pub fn source(mut self, source: &'b str) -> Self { + self.source = Some(source); + self + } + #[doc = "Creates an asynchronous call to the Ml Delete Trained Model Alias API that can be awaited"] + pub async fn send(self) -> Result { + let path = self.parts.url(); + let method = Method::Delete; + let headers = self.headers; + let timeout = self.request_timeout; + let query_string = { + #[serde_with::skip_serializing_none] + #[derive(Serialize)] + struct QueryParams<'b> { + error_trace: Option, + #[serde(serialize_with = "crate::client::serialize_coll_qs")] + filter_path: Option<&'b [&'b str]>, + human: Option, + pretty: Option, + source: Option<&'b str>, + } + let query_params = QueryParams { + error_trace: self.error_trace, + filter_path: self.filter_path, + human: self.human, + pretty: self.pretty, + source: self.source, + }; + Some(query_params) + }; + let body = Option::<()>::None; + let response = self + .transport + .send(method, &path, headers, query_string.as_ref(), body, timeout) + .await?; + Ok(response) + } +} #[derive(Debug, Clone, PartialEq)] #[doc = "API parts for the Ml Estimate Model Memory API"] pub enum MlEstimateModelMemoryParts { @@ -6123,11 +6253,166 @@ where Ok(response) } } +#[cfg(feature = "beta-apis")] +#[derive(Debug, Clone, PartialEq)] +#[doc = "API parts for the Ml Preview Data Frame Analytics API"] +pub enum MlPreviewDataFrameAnalyticsParts<'b> { + #[doc = "No parts"] + None, + #[doc = "Id"] + Id(&'b str), +} +#[cfg(feature = "beta-apis")] +impl<'b> MlPreviewDataFrameAnalyticsParts<'b> { + #[doc = "Builds a relative URL path to the Ml Preview Data Frame Analytics API"] + pub fn url(self) -> Cow<'static, str> { + match self { + MlPreviewDataFrameAnalyticsParts::None => "/_ml/data_frame/analytics/_preview".into(), + MlPreviewDataFrameAnalyticsParts::Id(ref id) => { + let encoded_id: Cow = percent_encode(id.as_bytes(), PARTS_ENCODED).into(); + let mut p = String::with_capacity(35usize + encoded_id.len()); + p.push_str("/_ml/data_frame/analytics/"); + p.push_str(encoded_id.as_ref()); + p.push_str("/_preview"); + p.into() + } + } + } +} +#[doc = "Builder for the [Ml Preview Data Frame Analytics API](http://www.elastic.co/guide/en/elasticsearch/reference/7.11/preview-dfanalytics.html)\n\nPreviews that will be analyzed given a data frame analytics config."] +#[doc = " \n# Optional, beta\nThis requires the `beta-apis` feature. On track to become stable but breaking changes can\nhappen in minor versions.\n "] +#[cfg(feature = "beta-apis")] +#[derive(Clone, Debug)] +pub struct MlPreviewDataFrameAnalytics<'a, 'b, B> { + transport: &'a Transport, + parts: MlPreviewDataFrameAnalyticsParts<'b>, + body: Option, + error_trace: Option, + filter_path: Option<&'b [&'b str]>, + headers: HeaderMap, + human: Option, + pretty: Option, + request_timeout: Option, + source: Option<&'b str>, +} +#[cfg(feature = "beta-apis")] +impl<'a, 'b, B> MlPreviewDataFrameAnalytics<'a, 'b, B> +where + B: Body, +{ + #[doc = "Creates a new instance of [MlPreviewDataFrameAnalytics] with the specified API parts"] + pub fn new(transport: &'a Transport, parts: MlPreviewDataFrameAnalyticsParts<'b>) -> Self { + let headers = HeaderMap::new(); + MlPreviewDataFrameAnalytics { + transport, + parts, + headers, + body: None, + error_trace: None, + filter_path: None, + human: None, + pretty: None, + request_timeout: None, + source: None, + } + } + #[doc = "The body for the API call"] + pub fn body(self, body: T) -> MlPreviewDataFrameAnalytics<'a, 'b, JsonBody> + where + T: Serialize, + { + MlPreviewDataFrameAnalytics { + transport: self.transport, + parts: self.parts, + body: Some(body.into()), + error_trace: self.error_trace, + filter_path: self.filter_path, + headers: self.headers, + human: self.human, + pretty: self.pretty, + request_timeout: self.request_timeout, + source: self.source, + } + } + #[doc = "Include the stack trace of returned errors."] + pub fn error_trace(mut self, error_trace: bool) -> Self { + self.error_trace = Some(error_trace); + self + } + #[doc = "A comma-separated list of filters used to reduce the response."] + pub fn filter_path(mut self, filter_path: &'b [&'b str]) -> Self { + self.filter_path = Some(filter_path); + self + } + #[doc = "Adds a HTTP header"] + pub fn header(mut self, key: HeaderName, value: HeaderValue) -> Self { + self.headers.insert(key, value); + self + } + #[doc = "Return human readable values for statistics."] + pub fn human(mut self, human: bool) -> Self { + self.human = Some(human); + self + } + #[doc = "Pretty format the returned JSON response."] + pub fn pretty(mut self, pretty: bool) -> Self { + self.pretty = Some(pretty); + self + } + #[doc = "Sets a request timeout for this API call.\n\nThe timeout is applied from when the request starts connecting until the response body has finished."] + pub fn request_timeout(mut self, timeout: Duration) -> Self { + self.request_timeout = Some(timeout); + self + } + #[doc = "The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests."] + pub fn source(mut self, source: &'b str) -> Self { + self.source = Some(source); + self + } + #[doc = "Creates an asynchronous call to the Ml Preview Data Frame Analytics API that can be awaited"] + pub async fn send(self) -> Result { + let path = self.parts.url(); + let method = match self.body { + Some(_) => Method::Post, + None => Method::Get, + }; + let headers = self.headers; + let timeout = self.request_timeout; + let query_string = { + #[serde_with::skip_serializing_none] + #[derive(Serialize)] + struct QueryParams<'b> { + error_trace: Option, + #[serde(serialize_with = "crate::client::serialize_coll_qs")] + filter_path: Option<&'b [&'b str]>, + human: Option, + pretty: Option, + source: Option<&'b str>, + } + let query_params = QueryParams { + error_trace: self.error_trace, + filter_path: self.filter_path, + human: self.human, + pretty: self.pretty, + source: self.source, + }; + Some(query_params) + }; + let body = self.body; + let response = self + .transport + .send(method, &path, headers, query_string.as_ref(), body, timeout) + .await?; + Ok(response) + } +} #[derive(Debug, Clone, PartialEq)] #[doc = "API parts for the Ml Preview Datafeed API"] pub enum MlPreviewDatafeedParts<'b> { #[doc = "DatafeedId"] DatafeedId(&'b str), + #[doc = "No parts"] + None, } impl<'b> MlPreviewDatafeedParts<'b> { #[doc = "Builds a relative URL path to the Ml Preview Datafeed API"] @@ -6142,14 +6427,16 @@ impl<'b> MlPreviewDatafeedParts<'b> { p.push_str("/_preview"); p.into() } + MlPreviewDatafeedParts::None => "/_ml/datafeeds/_preview".into(), } } } #[doc = "Builder for the [Ml Preview Datafeed API](https://www.elastic.co/guide/en/elasticsearch/reference/7.11/ml-preview-datafeed.html)\n\nPreviews a datafeed."] #[derive(Clone, Debug)] -pub struct MlPreviewDatafeed<'a, 'b> { +pub struct MlPreviewDatafeed<'a, 'b, B> { transport: &'a Transport, parts: MlPreviewDatafeedParts<'b>, + body: Option, error_trace: Option, filter_path: Option<&'b [&'b str]>, headers: HeaderMap, @@ -6158,7 +6445,10 @@ pub struct MlPreviewDatafeed<'a, 'b> { request_timeout: Option, source: Option<&'b str>, } -impl<'a, 'b> MlPreviewDatafeed<'a, 'b> { +impl<'a, 'b, B> MlPreviewDatafeed<'a, 'b, B> +where + B: Body, +{ #[doc = "Creates a new instance of [MlPreviewDatafeed] with the specified API parts"] pub fn new(transport: &'a Transport, parts: MlPreviewDatafeedParts<'b>) -> Self { let headers = HeaderMap::new(); @@ -6166,6 +6456,7 @@ impl<'a, 'b> MlPreviewDatafeed<'a, 'b> { transport, parts, headers, + body: None, error_trace: None, filter_path: None, human: None, @@ -6174,6 +6465,24 @@ impl<'a, 'b> MlPreviewDatafeed<'a, 'b> { source: None, } } + #[doc = "The body for the API call"] + pub fn body(self, body: T) -> MlPreviewDatafeed<'a, 'b, JsonBody> + where + T: Serialize, + { + MlPreviewDatafeed { + transport: self.transport, + parts: self.parts, + body: Some(body.into()), + error_trace: self.error_trace, + filter_path: self.filter_path, + headers: self.headers, + human: self.human, + pretty: self.pretty, + request_timeout: self.request_timeout, + source: self.source, + } + } #[doc = "Include the stack trace of returned errors."] pub fn error_trace(mut self, error_trace: bool) -> Self { self.error_trace = Some(error_trace); @@ -6212,7 +6521,10 @@ impl<'a, 'b> MlPreviewDatafeed<'a, 'b> { #[doc = "Creates an asynchronous call to the Ml Preview Datafeed API that can be awaited"] pub async fn send(self) -> Result { let path = self.parts.url(); - let method = Method::Get; + let method = match self.body { + Some(_) => Method::Post, + None => Method::Get, + }; let headers = self.headers; let timeout = self.request_timeout; let query_string = { @@ -6235,7 +6547,7 @@ impl<'a, 'b> MlPreviewDatafeed<'a, 'b> { }; Some(query_params) }; - let body = Option::<()>::None; + let body = self.body; let response = self .transport .send(method, &path, headers, query_string.as_ref(), body, timeout) @@ -7293,6 +7605,169 @@ where Ok(response) } } +#[cfg(feature = "beta-apis")] +#[derive(Debug, Clone, PartialEq)] +#[doc = "API parts for the Ml Put Trained Model Alias API"] +pub enum MlPutTrainedModelAliasParts<'b> { + #[doc = "ModelId and ModelAlias"] + ModelIdModelAlias(&'b str, &'b str), +} +#[cfg(feature = "beta-apis")] +impl<'b> MlPutTrainedModelAliasParts<'b> { + #[doc = "Builds a relative URL path to the Ml Put Trained Model Alias API"] + pub fn url(self) -> Cow<'static, str> { + match self { + MlPutTrainedModelAliasParts::ModelIdModelAlias(ref model_id, ref model_alias) => { + let encoded_model_id: Cow = + percent_encode(model_id.as_bytes(), PARTS_ENCODED).into(); + let encoded_model_alias: Cow = + percent_encode(model_alias.as_bytes(), PARTS_ENCODED).into(); + let mut p = String::with_capacity( + 35usize + encoded_model_id.len() + encoded_model_alias.len(), + ); + p.push_str("/_ml/trained_models/"); + p.push_str(encoded_model_id.as_ref()); + p.push_str("/model_aliases/"); + p.push_str(encoded_model_alias.as_ref()); + p.into() + } + } + } +} +#[doc = "Builder for the [Ml Put Trained Model Alias API](https://www.elastic.co/guide/en/elasticsearch/reference/7.11/put-trained-models-aliases.html)\n\nCreates a new model alias (or reassigns an existing one) to refer to the trained model"] +#[doc = " \n# Optional, beta\nThis requires the `beta-apis` feature. On track to become stable but breaking changes can\nhappen in minor versions.\n "] +#[cfg(feature = "beta-apis")] +#[derive(Clone, Debug)] +pub struct MlPutTrainedModelAlias<'a, 'b, B> { + transport: &'a Transport, + parts: MlPutTrainedModelAliasParts<'b>, + body: Option, + error_trace: Option, + filter_path: Option<&'b [&'b str]>, + headers: HeaderMap, + human: Option, + pretty: Option, + reassign: Option, + request_timeout: Option, + source: Option<&'b str>, +} +#[cfg(feature = "beta-apis")] +impl<'a, 'b, B> MlPutTrainedModelAlias<'a, 'b, B> +where + B: Body, +{ + #[doc = "Creates a new instance of [MlPutTrainedModelAlias] with the specified API parts"] + pub fn new(transport: &'a Transport, parts: MlPutTrainedModelAliasParts<'b>) -> Self { + let headers = HeaderMap::new(); + MlPutTrainedModelAlias { + transport, + parts, + headers, + body: None, + error_trace: None, + filter_path: None, + human: None, + pretty: None, + reassign: None, + request_timeout: None, + source: None, + } + } + #[doc = "The body for the API call"] + pub fn body(self, body: T) -> MlPutTrainedModelAlias<'a, 'b, JsonBody> + where + T: Serialize, + { + MlPutTrainedModelAlias { + transport: self.transport, + parts: self.parts, + body: Some(body.into()), + error_trace: self.error_trace, + filter_path: self.filter_path, + headers: self.headers, + human: self.human, + pretty: self.pretty, + reassign: self.reassign, + request_timeout: self.request_timeout, + source: self.source, + } + } + #[doc = "Include the stack trace of returned errors."] + pub fn error_trace(mut self, error_trace: bool) -> Self { + self.error_trace = Some(error_trace); + self + } + #[doc = "A comma-separated list of filters used to reduce the response."] + pub fn filter_path(mut self, filter_path: &'b [&'b str]) -> Self { + self.filter_path = Some(filter_path); + self + } + #[doc = "Adds a HTTP header"] + pub fn header(mut self, key: HeaderName, value: HeaderValue) -> Self { + self.headers.insert(key, value); + self + } + #[doc = "Return human readable values for statistics."] + pub fn human(mut self, human: bool) -> Self { + self.human = Some(human); + self + } + #[doc = "Pretty format the returned JSON response."] + pub fn pretty(mut self, pretty: bool) -> Self { + self.pretty = Some(pretty); + self + } + #[doc = "If the model_alias already exists and points to a separate model_id, this parameter must be true. Defaults to false."] + pub fn reassign(mut self, reassign: bool) -> Self { + self.reassign = Some(reassign); + self + } + #[doc = "Sets a request timeout for this API call.\n\nThe timeout is applied from when the request starts connecting until the response body has finished."] + pub fn request_timeout(mut self, timeout: Duration) -> Self { + self.request_timeout = Some(timeout); + self + } + #[doc = "The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests."] + pub fn source(mut self, source: &'b str) -> Self { + self.source = Some(source); + self + } + #[doc = "Creates an asynchronous call to the Ml Put Trained Model Alias API that can be awaited"] + pub async fn send(self) -> Result { + let path = self.parts.url(); + let method = Method::Put; + let headers = self.headers; + let timeout = self.request_timeout; + let query_string = { + #[serde_with::skip_serializing_none] + #[derive(Serialize)] + struct QueryParams<'b> { + error_trace: Option, + #[serde(serialize_with = "crate::client::serialize_coll_qs")] + filter_path: Option<&'b [&'b str]>, + human: Option, + pretty: Option, + reassign: Option, + source: Option<&'b str>, + } + let query_params = QueryParams { + error_trace: self.error_trace, + filter_path: self.filter_path, + human: self.human, + pretty: self.pretty, + reassign: self.reassign, + source: self.source, + }; + Some(query_params) + }; + let body = self.body; + let response = self + .transport + .send(method, &path, headers, query_string.as_ref(), body, timeout) + .await?; + Ok(response) + } +} #[derive(Debug, Clone, PartialEq)] #[doc = "API parts for the Ml Revert Model Snapshot API"] pub enum MlRevertModelSnapshotParts<'b> { @@ -9593,6 +10068,15 @@ impl<'a> Ml<'a> { ) -> MlDeleteTrainedModel<'a, 'b> { MlDeleteTrainedModel::new(self.transport(), parts) } + #[doc = "[Ml Delete Trained Model Alias API](https://www.elastic.co/guide/en/elasticsearch/reference/7.11/delete-trained-models-aliases.html)\n\nDeletes a model alias that refers to the trained model"] + #[doc = " \n# Optional, beta\nThis requires the `beta-apis` feature. On track to become stable but breaking changes can\nhappen in minor versions.\n "] + #[cfg(feature = "beta-apis")] + pub fn delete_trained_model_alias<'b>( + &'a self, + parts: MlDeleteTrainedModelAliasParts<'b>, + ) -> MlDeleteTrainedModelAlias<'a, 'b> { + MlDeleteTrainedModelAlias::new(self.transport(), parts) + } #[doc = "[Ml Estimate Model Memory API](https://www.elastic.co/guide/en/elasticsearch/reference/7.11/ml-apis.html)\n\nEstimates the model memory"] pub fn estimate_model_memory<'b>(&'a self) -> MlEstimateModelMemory<'a, 'b, ()> { MlEstimateModelMemory::new(self.transport()) @@ -9748,11 +10232,20 @@ impl<'a> Ml<'a> { pub fn post_data<'b>(&'a self, parts: MlPostDataParts<'b>) -> MlPostData<'a, 'b, ()> { MlPostData::new(self.transport(), parts) } + #[doc = "[Ml Preview Data Frame Analytics API](http://www.elastic.co/guide/en/elasticsearch/reference/7.11/preview-dfanalytics.html)\n\nPreviews that will be analyzed given a data frame analytics config."] + #[doc = " \n# Optional, beta\nThis requires the `beta-apis` feature. On track to become stable but breaking changes can\nhappen in minor versions.\n "] + #[cfg(feature = "beta-apis")] + pub fn preview_data_frame_analytics<'b>( + &'a self, + parts: MlPreviewDataFrameAnalyticsParts<'b>, + ) -> MlPreviewDataFrameAnalytics<'a, 'b, ()> { + MlPreviewDataFrameAnalytics::new(self.transport(), parts) + } #[doc = "[Ml Preview Datafeed API](https://www.elastic.co/guide/en/elasticsearch/reference/7.11/ml-preview-datafeed.html)\n\nPreviews a datafeed."] pub fn preview_datafeed<'b>( &'a self, parts: MlPreviewDatafeedParts<'b>, - ) -> MlPreviewDatafeed<'a, 'b> { + ) -> MlPreviewDatafeed<'a, 'b, ()> { MlPreviewDatafeed::new(self.transport(), parts) } #[doc = "[Ml Put Calendar API](https://www.elastic.co/guide/en/elasticsearch/reference/7.11/ml-put-calendar.html)\n\nInstantiates a calendar."] @@ -9796,6 +10289,15 @@ impl<'a> Ml<'a> { ) -> MlPutTrainedModel<'a, 'b, ()> { MlPutTrainedModel::new(self.transport(), parts) } + #[doc = "[Ml Put Trained Model Alias API](https://www.elastic.co/guide/en/elasticsearch/reference/7.11/put-trained-models-aliases.html)\n\nCreates a new model alias (or reassigns an existing one) to refer to the trained model"] + #[doc = " \n# Optional, beta\nThis requires the `beta-apis` feature. On track to become stable but breaking changes can\nhappen in minor versions.\n "] + #[cfg(feature = "beta-apis")] + pub fn put_trained_model_alias<'b>( + &'a self, + parts: MlPutTrainedModelAliasParts<'b>, + ) -> MlPutTrainedModelAlias<'a, 'b, ()> { + MlPutTrainedModelAlias::new(self.transport(), parts) + } #[doc = "[Ml Revert Model Snapshot API](https://www.elastic.co/guide/en/elasticsearch/reference/7.11/ml-revert-snapshot.html)\n\nReverts to a specific snapshot."] pub fn revert_model_snapshot<'b>( &'a self, diff --git a/elasticsearch/src/nodes.rs b/elasticsearch/src/nodes.rs index 3e1b1ba5..428b0784 100644 --- a/elasticsearch/src/nodes.rs +++ b/elasticsearch/src/nodes.rs @@ -662,6 +662,7 @@ pub struct NodesStats<'a, 'b> { headers: HeaderMap, human: Option, include_segment_file_sizes: Option, + include_unloaded_segments: Option, level: Option, pretty: Option, request_timeout: Option, @@ -685,6 +686,7 @@ impl<'a, 'b> NodesStats<'a, 'b> { groups: None, human: None, include_segment_file_sizes: None, + include_unloaded_segments: None, level: None, pretty: None, request_timeout: None, @@ -738,6 +740,11 @@ impl<'a, 'b> NodesStats<'a, 'b> { self.include_segment_file_sizes = Some(include_segment_file_sizes); self } + #[doc = "If set to true segment stats will include stats for segments that are not currently loaded into memory"] + pub fn include_unloaded_segments(mut self, include_unloaded_segments: bool) -> Self { + self.include_unloaded_segments = Some(include_unloaded_segments); + self + } #[doc = "Return indices stats aggregated at index, node or shard level"] pub fn level(mut self, level: Level) -> Self { self.level = Some(level); @@ -790,6 +797,7 @@ impl<'a, 'b> NodesStats<'a, 'b> { groups: Option, human: Option, include_segment_file_sizes: Option, + include_unloaded_segments: Option, level: Option, pretty: Option, source: Option<&'b str>, @@ -806,6 +814,7 @@ impl<'a, 'b> NodesStats<'a, 'b> { groups: self.groups, human: self.human, include_segment_file_sizes: self.include_segment_file_sizes, + include_unloaded_segments: self.include_unloaded_segments, level: self.level, pretty: self.pretty, source: self.source, diff --git a/elasticsearch/src/shutdown.rs b/elasticsearch/src/shutdown.rs new file mode 100644 index 00000000..a42beb56 --- /dev/null +++ b/elasticsearch/src/shutdown.rs @@ -0,0 +1,489 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +// ----------------------------------------------- +// This file is generated, Please do not edit it manually. +// Run the following in the root of the repo to regenerate: +// +// cargo make generate-api +// ----------------------------------------------- + +#![cfg(feature = "experimental-apis")] +#![doc = " \n# Optional, experimental\nThis requires the `experimental-apis` feature. Can have breaking changes in future\nversions or might even be removed entirely.\n "] +#![allow(unused_imports)] +use crate::{ + client::Elasticsearch, + error::Error, + http::{ + headers::{HeaderMap, HeaderName, HeaderValue, ACCEPT, CONTENT_TYPE}, + request::{Body, JsonBody, NdBody, PARTS_ENCODED}, + response::Response, + transport::Transport, + Method, + }, + params::*, +}; +use percent_encoding::percent_encode; +use serde::Serialize; +use std::{borrow::Cow, time::Duration}; +#[cfg(feature = "experimental-apis")] +#[derive(Debug, Clone, PartialEq)] +#[doc = "API parts for the Shutdown Delete Node API"] +pub enum ShutdownDeleteNodeParts<'b> { + #[doc = "NodeId"] + NodeId(&'b str), +} +#[cfg(feature = "experimental-apis")] +impl<'b> ShutdownDeleteNodeParts<'b> { + #[doc = "Builds a relative URL path to the Shutdown Delete Node API"] + pub fn url(self) -> Cow<'static, str> { + match self { + ShutdownDeleteNodeParts::NodeId(ref node_id) => { + let encoded_node_id: Cow = + percent_encode(node_id.as_bytes(), PARTS_ENCODED).into(); + let mut p = String::with_capacity(17usize + encoded_node_id.len()); + p.push_str("/_nodes/"); + p.push_str(encoded_node_id.as_ref()); + p.push_str("/shutdown"); + p.into() + } + } + } +} +#[doc = "Builder for the [Shutdown Delete Node API](https://www.elastic.co/guide/en/elasticsearch/reference/7.11)\n\nRemoves a node from the shutdown list"] +#[doc = " \n# Optional, experimental\nThis requires the `experimental-apis` feature. Can have breaking changes in future\nversions or might even be removed entirely.\n "] +#[cfg(feature = "experimental-apis")] +#[derive(Clone, Debug)] +pub struct ShutdownDeleteNode<'a, 'b> { + transport: &'a Transport, + parts: ShutdownDeleteNodeParts<'b>, + error_trace: Option, + filter_path: Option<&'b [&'b str]>, + headers: HeaderMap, + human: Option, + pretty: Option, + request_timeout: Option, + source: Option<&'b str>, +} +#[cfg(feature = "experimental-apis")] +impl<'a, 'b> ShutdownDeleteNode<'a, 'b> { + #[doc = "Creates a new instance of [ShutdownDeleteNode] with the specified API parts"] + pub fn new(transport: &'a Transport, parts: ShutdownDeleteNodeParts<'b>) -> Self { + let headers = HeaderMap::new(); + ShutdownDeleteNode { + transport, + parts, + headers, + error_trace: None, + filter_path: None, + human: None, + pretty: None, + request_timeout: None, + source: None, + } + } + #[doc = "Include the stack trace of returned errors."] + pub fn error_trace(mut self, error_trace: bool) -> Self { + self.error_trace = Some(error_trace); + self + } + #[doc = "A comma-separated list of filters used to reduce the response."] + pub fn filter_path(mut self, filter_path: &'b [&'b str]) -> Self { + self.filter_path = Some(filter_path); + self + } + #[doc = "Adds a HTTP header"] + pub fn header(mut self, key: HeaderName, value: HeaderValue) -> Self { + self.headers.insert(key, value); + self + } + #[doc = "Return human readable values for statistics."] + pub fn human(mut self, human: bool) -> Self { + self.human = Some(human); + self + } + #[doc = "Pretty format the returned JSON response."] + pub fn pretty(mut self, pretty: bool) -> Self { + self.pretty = Some(pretty); + self + } + #[doc = "Sets a request timeout for this API call.\n\nThe timeout is applied from when the request starts connecting until the response body has finished."] + pub fn request_timeout(mut self, timeout: Duration) -> Self { + self.request_timeout = Some(timeout); + self + } + #[doc = "The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests."] + pub fn source(mut self, source: &'b str) -> Self { + self.source = Some(source); + self + } + #[doc = "Creates an asynchronous call to the Shutdown Delete Node API that can be awaited"] + pub async fn send(self) -> Result { + let path = self.parts.url(); + let method = Method::Delete; + let headers = self.headers; + let timeout = self.request_timeout; + let query_string = { + #[serde_with::skip_serializing_none] + #[derive(Serialize)] + struct QueryParams<'b> { + error_trace: Option, + #[serde(serialize_with = "crate::client::serialize_coll_qs")] + filter_path: Option<&'b [&'b str]>, + human: Option, + pretty: Option, + source: Option<&'b str>, + } + let query_params = QueryParams { + error_trace: self.error_trace, + filter_path: self.filter_path, + human: self.human, + pretty: self.pretty, + source: self.source, + }; + Some(query_params) + }; + let body = Option::<()>::None; + let response = self + .transport + .send(method, &path, headers, query_string.as_ref(), body, timeout) + .await?; + Ok(response) + } +} +#[cfg(feature = "experimental-apis")] +#[derive(Debug, Clone, PartialEq)] +#[doc = "API parts for the Shutdown Get Node API"] +pub enum ShutdownGetNodeParts<'b> { + #[doc = "No parts"] + None, + #[doc = "NodeId"] + NodeId(&'b str), +} +#[cfg(feature = "experimental-apis")] +impl<'b> ShutdownGetNodeParts<'b> { + #[doc = "Builds a relative URL path to the Shutdown Get Node API"] + pub fn url(self) -> Cow<'static, str> { + match self { + ShutdownGetNodeParts::None => "/_nodes/shutdown".into(), + ShutdownGetNodeParts::NodeId(ref node_id) => { + let encoded_node_id: Cow = + percent_encode(node_id.as_bytes(), PARTS_ENCODED).into(); + let mut p = String::with_capacity(17usize + encoded_node_id.len()); + p.push_str("/_nodes/"); + p.push_str(encoded_node_id.as_ref()); + p.push_str("/shutdown"); + p.into() + } + } + } +} +#[doc = "Builder for the [Shutdown Get Node API](https://www.elastic.co/guide/en/elasticsearch/reference/7.11)\n\nRetrieve status of a node or nodes that are currently marked as shutting down"] +#[doc = " \n# Optional, experimental\nThis requires the `experimental-apis` feature. Can have breaking changes in future\nversions or might even be removed entirely.\n "] +#[cfg(feature = "experimental-apis")] +#[derive(Clone, Debug)] +pub struct ShutdownGetNode<'a, 'b> { + transport: &'a Transport, + parts: ShutdownGetNodeParts<'b>, + error_trace: Option, + filter_path: Option<&'b [&'b str]>, + headers: HeaderMap, + human: Option, + pretty: Option, + request_timeout: Option, + source: Option<&'b str>, +} +#[cfg(feature = "experimental-apis")] +impl<'a, 'b> ShutdownGetNode<'a, 'b> { + #[doc = "Creates a new instance of [ShutdownGetNode] with the specified API parts"] + pub fn new(transport: &'a Transport, parts: ShutdownGetNodeParts<'b>) -> Self { + let headers = HeaderMap::new(); + ShutdownGetNode { + transport, + parts, + headers, + error_trace: None, + filter_path: None, + human: None, + pretty: None, + request_timeout: None, + source: None, + } + } + #[doc = "Include the stack trace of returned errors."] + pub fn error_trace(mut self, error_trace: bool) -> Self { + self.error_trace = Some(error_trace); + self + } + #[doc = "A comma-separated list of filters used to reduce the response."] + pub fn filter_path(mut self, filter_path: &'b [&'b str]) -> Self { + self.filter_path = Some(filter_path); + self + } + #[doc = "Adds a HTTP header"] + pub fn header(mut self, key: HeaderName, value: HeaderValue) -> Self { + self.headers.insert(key, value); + self + } + #[doc = "Return human readable values for statistics."] + pub fn human(mut self, human: bool) -> Self { + self.human = Some(human); + self + } + #[doc = "Pretty format the returned JSON response."] + pub fn pretty(mut self, pretty: bool) -> Self { + self.pretty = Some(pretty); + self + } + #[doc = "Sets a request timeout for this API call.\n\nThe timeout is applied from when the request starts connecting until the response body has finished."] + pub fn request_timeout(mut self, timeout: Duration) -> Self { + self.request_timeout = Some(timeout); + self + } + #[doc = "The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests."] + pub fn source(mut self, source: &'b str) -> Self { + self.source = Some(source); + self + } + #[doc = "Creates an asynchronous call to the Shutdown Get Node API that can be awaited"] + pub async fn send(self) -> Result { + let path = self.parts.url(); + let method = Method::Get; + let headers = self.headers; + let timeout = self.request_timeout; + let query_string = { + #[serde_with::skip_serializing_none] + #[derive(Serialize)] + struct QueryParams<'b> { + error_trace: Option, + #[serde(serialize_with = "crate::client::serialize_coll_qs")] + filter_path: Option<&'b [&'b str]>, + human: Option, + pretty: Option, + source: Option<&'b str>, + } + let query_params = QueryParams { + error_trace: self.error_trace, + filter_path: self.filter_path, + human: self.human, + pretty: self.pretty, + source: self.source, + }; + Some(query_params) + }; + let body = Option::<()>::None; + let response = self + .transport + .send(method, &path, headers, query_string.as_ref(), body, timeout) + .await?; + Ok(response) + } +} +#[cfg(feature = "experimental-apis")] +#[derive(Debug, Clone, PartialEq)] +#[doc = "API parts for the Shutdown Put Node API"] +pub enum ShutdownPutNodeParts<'b> { + #[doc = "NodeId"] + NodeId(&'b str), +} +#[cfg(feature = "experimental-apis")] +impl<'b> ShutdownPutNodeParts<'b> { + #[doc = "Builds a relative URL path to the Shutdown Put Node API"] + pub fn url(self) -> Cow<'static, str> { + match self { + ShutdownPutNodeParts::NodeId(ref node_id) => { + let encoded_node_id: Cow = + percent_encode(node_id.as_bytes(), PARTS_ENCODED).into(); + let mut p = String::with_capacity(17usize + encoded_node_id.len()); + p.push_str("/_nodes/"); + p.push_str(encoded_node_id.as_ref()); + p.push_str("/shutdown"); + p.into() + } + } + } +} +#[doc = "Builder for the [Shutdown Put Node API](https://www.elastic.co/guide/en/elasticsearch/reference/7.11)\n\nAdds a node to be shut down"] +#[doc = " \n# Optional, experimental\nThis requires the `experimental-apis` feature. Can have breaking changes in future\nversions or might even be removed entirely.\n "] +#[cfg(feature = "experimental-apis")] +#[derive(Clone, Debug)] +pub struct ShutdownPutNode<'a, 'b, B> { + transport: &'a Transport, + parts: ShutdownPutNodeParts<'b>, + body: Option, + error_trace: Option, + filter_path: Option<&'b [&'b str]>, + headers: HeaderMap, + human: Option, + pretty: Option, + request_timeout: Option, + source: Option<&'b str>, +} +#[cfg(feature = "experimental-apis")] +impl<'a, 'b, B> ShutdownPutNode<'a, 'b, B> +where + B: Body, +{ + #[doc = "Creates a new instance of [ShutdownPutNode] with the specified API parts"] + pub fn new(transport: &'a Transport, parts: ShutdownPutNodeParts<'b>) -> Self { + let headers = HeaderMap::new(); + ShutdownPutNode { + transport, + parts, + headers, + body: None, + error_trace: None, + filter_path: None, + human: None, + pretty: None, + request_timeout: None, + source: None, + } + } + #[doc = "The body for the API call"] + pub fn body(self, body: T) -> ShutdownPutNode<'a, 'b, JsonBody> + where + T: Serialize, + { + ShutdownPutNode { + transport: self.transport, + parts: self.parts, + body: Some(body.into()), + error_trace: self.error_trace, + filter_path: self.filter_path, + headers: self.headers, + human: self.human, + pretty: self.pretty, + request_timeout: self.request_timeout, + source: self.source, + } + } + #[doc = "Include the stack trace of returned errors."] + pub fn error_trace(mut self, error_trace: bool) -> Self { + self.error_trace = Some(error_trace); + self + } + #[doc = "A comma-separated list of filters used to reduce the response."] + pub fn filter_path(mut self, filter_path: &'b [&'b str]) -> Self { + self.filter_path = Some(filter_path); + self + } + #[doc = "Adds a HTTP header"] + pub fn header(mut self, key: HeaderName, value: HeaderValue) -> Self { + self.headers.insert(key, value); + self + } + #[doc = "Return human readable values for statistics."] + pub fn human(mut self, human: bool) -> Self { + self.human = Some(human); + self + } + #[doc = "Pretty format the returned JSON response."] + pub fn pretty(mut self, pretty: bool) -> Self { + self.pretty = Some(pretty); + self + } + #[doc = "Sets a request timeout for this API call.\n\nThe timeout is applied from when the request starts connecting until the response body has finished."] + pub fn request_timeout(mut self, timeout: Duration) -> Self { + self.request_timeout = Some(timeout); + self + } + #[doc = "The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests."] + pub fn source(mut self, source: &'b str) -> Self { + self.source = Some(source); + self + } + #[doc = "Creates an asynchronous call to the Shutdown Put Node API that can be awaited"] + pub async fn send(self) -> Result { + let path = self.parts.url(); + let method = Method::Put; + let headers = self.headers; + let timeout = self.request_timeout; + let query_string = { + #[serde_with::skip_serializing_none] + #[derive(Serialize)] + struct QueryParams<'b> { + error_trace: Option, + #[serde(serialize_with = "crate::client::serialize_coll_qs")] + filter_path: Option<&'b [&'b str]>, + human: Option, + pretty: Option, + source: Option<&'b str>, + } + let query_params = QueryParams { + error_trace: self.error_trace, + filter_path: self.filter_path, + human: self.human, + pretty: self.pretty, + source: self.source, + }; + Some(query_params) + }; + let body = self.body; + let response = self + .transport + .send(method, &path, headers, query_string.as_ref(), body, timeout) + .await?; + Ok(response) + } +} +#[doc = "Namespace client for Shutdown APIs"] +#[doc = " \n# Optional, experimental\nThis requires the `experimental-apis` feature. Can have breaking changes in future\nversions or might even be removed entirely.\n "] +#[cfg(feature = "experimental-apis")] +pub struct Shutdown<'a> { + transport: &'a Transport, +} +#[cfg(feature = "experimental-apis")] +impl<'a> Shutdown<'a> { + #[doc = "Creates a new instance of [Shutdown]"] + pub fn new(transport: &'a Transport) -> Self { + Self { transport } + } + pub fn transport(&self) -> &Transport { + self.transport + } + #[doc = "[Shutdown Delete Node API](https://www.elastic.co/guide/en/elasticsearch/reference/7.11)\n\nRemoves a node from the shutdown list"] + #[doc = " \n# Optional, experimental\nThis requires the `experimental-apis` feature. Can have breaking changes in future\nversions or might even be removed entirely.\n "] + #[cfg(feature = "experimental-apis")] + pub fn delete_node<'b>( + &'a self, + parts: ShutdownDeleteNodeParts<'b>, + ) -> ShutdownDeleteNode<'a, 'b> { + ShutdownDeleteNode::new(self.transport(), parts) + } + #[doc = "[Shutdown Get Node API](https://www.elastic.co/guide/en/elasticsearch/reference/7.11)\n\nRetrieve status of a node or nodes that are currently marked as shutting down"] + #[doc = " \n# Optional, experimental\nThis requires the `experimental-apis` feature. Can have breaking changes in future\nversions or might even be removed entirely.\n "] + #[cfg(feature = "experimental-apis")] + pub fn get_node<'b>(&'a self, parts: ShutdownGetNodeParts<'b>) -> ShutdownGetNode<'a, 'b> { + ShutdownGetNode::new(self.transport(), parts) + } + #[doc = "[Shutdown Put Node API](https://www.elastic.co/guide/en/elasticsearch/reference/7.11)\n\nAdds a node to be shut down"] + #[doc = " \n# Optional, experimental\nThis requires the `experimental-apis` feature. Can have breaking changes in future\nversions or might even be removed entirely.\n "] + #[cfg(feature = "experimental-apis")] + pub fn put_node<'b>(&'a self, parts: ShutdownPutNodeParts<'b>) -> ShutdownPutNode<'a, 'b, ()> { + ShutdownPutNode::new(self.transport(), parts) + } +} +#[cfg(feature = "experimental-apis")] +impl Elasticsearch { + #[doc = "Creates a namespace client for Shutdown APIs"] + pub fn shutdown(&self) -> Shutdown { + Shutdown::new(self.transport()) + } +} diff --git a/elasticsearch/src/snapshot.rs b/elasticsearch/src/snapshot.rs index 19fda9a9..c2e7561b 100644 --- a/elasticsearch/src/snapshot.rs +++ b/elasticsearch/src/snapshot.rs @@ -1145,127 +1145,6 @@ impl<'a, 'b> SnapshotGet<'a, 'b> { } } #[derive(Debug, Clone, PartialEq)] -#[doc = "API parts for the Snapshot Get Features API"] -pub enum SnapshotGetFeaturesParts { - #[doc = "No parts"] - None, -} -impl SnapshotGetFeaturesParts { - #[doc = "Builds a relative URL path to the Snapshot Get Features API"] - pub fn url(self) -> Cow<'static, str> { - match self { - SnapshotGetFeaturesParts::None => "/_snapshottable_features".into(), - } - } -} -#[doc = "Builder for the [Snapshot Get Features API](https://www.elastic.co/guide/en/elasticsearch/reference/7.11/modules-snapshots.html)\n\nReturns a list of features which can be snapshotted in this cluster."] -#[derive(Clone, Debug)] -pub struct SnapshotGetFeatures<'a, 'b> { - transport: &'a Transport, - parts: SnapshotGetFeaturesParts, - error_trace: Option, - filter_path: Option<&'b [&'b str]>, - headers: HeaderMap, - human: Option, - master_timeout: Option<&'b str>, - pretty: Option, - request_timeout: Option, - source: Option<&'b str>, -} -impl<'a, 'b> SnapshotGetFeatures<'a, 'b> { - #[doc = "Creates a new instance of [SnapshotGetFeatures]"] - pub fn new(transport: &'a Transport) -> Self { - let headers = HeaderMap::new(); - SnapshotGetFeatures { - transport, - parts: SnapshotGetFeaturesParts::None, - headers, - error_trace: None, - filter_path: None, - human: None, - master_timeout: None, - pretty: None, - request_timeout: None, - source: None, - } - } - #[doc = "Include the stack trace of returned errors."] - pub fn error_trace(mut self, error_trace: bool) -> Self { - self.error_trace = Some(error_trace); - self - } - #[doc = "A comma-separated list of filters used to reduce the response."] - pub fn filter_path(mut self, filter_path: &'b [&'b str]) -> Self { - self.filter_path = Some(filter_path); - self - } - #[doc = "Adds a HTTP header"] - pub fn header(mut self, key: HeaderName, value: HeaderValue) -> Self { - self.headers.insert(key, value); - self - } - #[doc = "Return human readable values for statistics."] - pub fn human(mut self, human: bool) -> Self { - self.human = Some(human); - self - } - #[doc = "Explicit operation timeout for connection to master node"] - pub fn master_timeout(mut self, master_timeout: &'b str) -> Self { - self.master_timeout = Some(master_timeout); - self - } - #[doc = "Pretty format the returned JSON response."] - pub fn pretty(mut self, pretty: bool) -> Self { - self.pretty = Some(pretty); - self - } - #[doc = "Sets a request timeout for this API call.\n\nThe timeout is applied from when the request starts connecting until the response body has finished."] - pub fn request_timeout(mut self, timeout: Duration) -> Self { - self.request_timeout = Some(timeout); - self - } - #[doc = "The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests."] - pub fn source(mut self, source: &'b str) -> Self { - self.source = Some(source); - self - } - #[doc = "Creates an asynchronous call to the Snapshot Get Features API that can be awaited"] - pub async fn send(self) -> Result { - let path = self.parts.url(); - let method = Method::Get; - let headers = self.headers; - let timeout = self.request_timeout; - let query_string = { - #[serde_with::skip_serializing_none] - #[derive(Serialize)] - struct QueryParams<'b> { - error_trace: Option, - #[serde(serialize_with = "crate::client::serialize_coll_qs")] - filter_path: Option<&'b [&'b str]>, - human: Option, - master_timeout: Option<&'b str>, - pretty: Option, - source: Option<&'b str>, - } - let query_params = QueryParams { - error_trace: self.error_trace, - filter_path: self.filter_path, - human: self.human, - master_timeout: self.master_timeout, - pretty: self.pretty, - source: self.source, - }; - Some(query_params) - }; - let body = Option::<()>::None; - let response = self - .transport - .send(method, &path, headers, query_string.as_ref(), body, timeout) - .await?; - Ok(response) - } -} -#[derive(Debug, Clone, PartialEq)] #[doc = "API parts for the Snapshot Get Repository API"] pub enum SnapshotGetRepositoryParts<'b> { #[doc = "No parts"] @@ -1946,10 +1825,6 @@ impl<'a> Snapshot<'a> { pub fn get<'b>(&'a self, parts: SnapshotGetParts<'b>) -> SnapshotGet<'a, 'b> { SnapshotGet::new(self.transport(), parts) } - #[doc = "[Snapshot Get Features API](https://www.elastic.co/guide/en/elasticsearch/reference/7.11/modules-snapshots.html)\n\nReturns a list of features which can be snapshotted in this cluster."] - pub fn get_features<'b>(&'a self) -> SnapshotGetFeatures<'a, 'b> { - SnapshotGetFeatures::new(self.transport()) - } #[doc = "[Snapshot Get Repository API](https://www.elastic.co/guide/en/elasticsearch/reference/7.11/modules-snapshots.html)\n\nReturns information about a repository."] pub fn get_repository<'b>( &'a self, diff --git a/yaml_test_runner/src/github.rs b/yaml_test_runner/src/github.rs index c4eaf9ec..6287b3f5 100644 --- a/yaml_test_runner/src/github.rs +++ b/yaml_test_runner/src/github.rs @@ -18,7 +18,6 @@ */ use flate2::read::GzDecoder; use globset::Glob; -use io::Write; use reqwest::{ header::{HeaderMap, HeaderValue, USER_AGENT}, Response, @@ -55,6 +54,10 @@ pub fn download_test_suites(branch: &str, download_dir: &PathBuf) -> Result<(), .unwrap(); let response = client.get(&url).send()?; + + info!("tarball response status: {}", response.status().as_u16()); + info!("tarball response headers: {:?}", response.headers()); + let tar = GzDecoder::new(response); let mut archive = Archive::new(tar); @@ -63,21 +66,24 @@ pub fn download_test_suites(branch: &str, download_dir: &PathBuf) -> Result<(), let xpack_test = Glob::new("**/x-pack/plugin/src/test/resources/rest-api-spec/test/**/*.yml")? .compile_matcher(); + let mut entry_count = 0; + let mut test_count = 0; for entry in archive.entries()? { + entry_count += 1; let file = entry?; let path = file.path()?; if oss_test.is_match(&path) { + test_count += 1; write_test_file(download_dir, "free", file)?; } else if xpack_test.is_match(&path) { + test_count += 1; write_test_file(download_dir, "xpack", file)?; } } - info!("Downloaded yaml tests from {}", &branch); - File::create(last_downloaded_version) - .expect("failed to create last_downloaded_version file") - .write_all(branch.as_bytes()) - .expect("unable to write branch to last_downloaded_version file"); + info!("Downloaded {} yaml tests (out of {} files) from {}", test_count, entry_count, &branch); + fs::write(&last_downloaded_version, branch) + .expect(&format!("Unable to write branch to {:?}", &last_downloaded_version)); Ok(()) } @@ -89,18 +95,17 @@ fn write_test_file( ) -> Result<(), failure::Error> { let path = entry.path()?; - let mut dir = { - let mut dir = download_dir.clone(); - dir.push(suite_dir); - let parent = path.parent().unwrap().file_name().unwrap(); - dir.push(parent); - dir - }; + let mut file = download_dir.clone(); + file.push(suite_dir); + file.push(path); + + let parent = file.parent().unwrap(); + fs::create_dir_all(parent) + .expect(&format!("Cannot create directory {:?}", &parent)); - fs::create_dir_all(&dir)?; - dir.push(path.file_name().unwrap()); - let mut file = File::create(&dir)?; - io::copy(&mut entry, &mut file)?; + let mut out = File::create(&file)?; + io::copy(&mut entry, &mut out) + .expect(&format!("Cannot write to {:?}", &file)); Ok(()) }