diff --git a/.ci/pipeline-library/src/test/KibanaBasePipelineTest.groovy b/.ci/pipeline-library/src/test/KibanaBasePipelineTest.groovy index 086484f2385b0..4112cb3c0e14b 100644 --- a/.ci/pipeline-library/src/test/KibanaBasePipelineTest.groovy +++ b/.ci/pipeline-library/src/test/KibanaBasePipelineTest.groovy @@ -78,6 +78,10 @@ class KibanaBasePipelineTest extends BasePipelineTest { return helper.callStack.find { it.methodName == name } } + def fnMocks(String name) { + helper.callStack.findAll { it.methodName == name } + } + void mockFailureBuild() { props([ buildUtils: [ diff --git a/.ci/pipeline-library/src/test/slackNotifications.groovy b/.ci/pipeline-library/src/test/slackNotifications.groovy index 467e4a0e5f520..f7e39f5fad903 100644 --- a/.ci/pipeline-library/src/test/slackNotifications.groovy +++ b/.ci/pipeline-library/src/test/slackNotifications.groovy @@ -59,4 +59,67 @@ class SlackNotificationsTest extends KibanaBasePipelineTest { args.blocks[2].text.text.toString() ) } + + @Test + void 'sendFailedBuild() should call slackSend() with a backup message when first attempt fails'() { + mockFailureBuild() + def counter = 0 + helper.registerAllowedMethod('slackSend', [Map.class], { ++counter > 1 }) + slackNotifications.sendFailedBuild() + + def args = fnMocks('slackSend')[1].args[0] + + def expected = [ + channel: '#kibana-operations-alerts', + username: 'Kibana Operations', + iconEmoji: ':jenkins:', + color: 'danger', + message: ':broken_heart: elastic / kibana # master #1', + ] + + expected.each { + assertEquals(it.value.toString(), args[it.key].toString()) + } + + assertEquals( + ":broken_heart: **" + + "\n\nFirst attempt at sending this notification failed. Please check the build.", + args.blocks[0].text.text.toString() + ) + } + + @Test + void 'getTestFailures() should truncate list of failures to 10'() { + prop('testUtils', [ + getFailures: { + return (1..12).collect { + return [ + url: Mocks.TEST_FAILURE_URL, + fullDisplayName: "Failure #${it}", + ] + } + }, + ]) + + def message = (String) slackNotifications.getTestFailures() + + assertTrue("Message ends with truncated indicator", message.endsWith("...and 2 more")) + assertTrue("Message contains Failure #10", message.contains("Failure #10")) + assertTrue("Message does not contain Failure #11", !message.contains("Failure #11")) + } + + @Test + void 'shortenMessage() should truncate a long message, but leave parts that fit'() { + assertEquals('Hello\nHello\n[...truncated...]', slackNotifications.shortenMessage('Hello\nHello\nthis is a long string', 29)) + } + + @Test + void 'shortenMessage() should not modify a short message'() { + assertEquals('Hello world', slackNotifications.shortenMessage('Hello world', 11)) + } + + @Test + void 'shortenMessage() should truncate an entire message with only one part'() { + assertEquals('[...truncated...]', slackNotifications.shortenMessage('Hello world this is a really long message', 40)) + } } diff --git a/Jenkinsfile b/Jenkinsfile index f6f77ccae8427..0aa2c9a7da134 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -44,7 +44,7 @@ kibanaPipeline(timeoutMinutes: 155, checkPrChanges: true, setCommitStatus: true) 'xpack-savedObjectsFieldMetrics': kibanaPipeline.functionalTestProcess('xpack-savedObjectsFieldMetrics', './test/scripts/jenkins_xpack_saved_objects_field_metrics.sh'), // 'xpack-pageLoadMetrics': kibanaPipeline.functionalTestProcess('xpack-pageLoadMetrics', './test/scripts/jenkins_xpack_page_load_metrics.sh'), 'xpack-securitySolutionCypress': { processNumber -> - whenChanged(['x-pack/plugins/security_solution/', 'x-pack/test/security_solution_cypress/']) { + whenChanged(['x-pack/plugins/security_solution/', 'x-pack/test/security_solution_cypress/', 'x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/', 'x-pack/plugins/triggers_actions_ui/public/application/context/actions_connectors_context.tsx']) { kibanaPipeline.functionalTestProcess('xpack-securitySolutionCypress', './test/scripts/jenkins_security_solution_cypress.sh')(processNumber) } }, diff --git a/docs/apm/error-reports-watcher.asciidoc b/docs/apm/error-reports-watcher.asciidoc deleted file mode 100644 index f41597932b751..0000000000000 --- a/docs/apm/error-reports-watcher.asciidoc +++ /dev/null @@ -1,18 +0,0 @@ -[role="xpack"] -[[errors-alerts-with-watcher]] -=== Error reports with Watcher - -++++ -Enable error reports -++++ - -You can use the power of the alerting features with Watcher to get reports on error occurrences. -The Watcher assistant, which is available on the errors overview, can help you set up a watch per service. - -Configure the watch with an occurrences threshold, time interval, and the desired actions, such as email or Slack notifications. -With Watcher, your team can set up reports within minutes. - -Watches are managed separately in the dedicated Watcher UI available in Advanced Settings. - -[role="screenshot"] -image::apm/images/apm-errors-watcher-assistant.png[Example view of the Watcher assistant for errors in APM app in Kibana] diff --git a/docs/apm/how-to-guides.asciidoc b/docs/apm/how-to-guides.asciidoc index 9b0efb4f7a359..9a415375f17fd 100644 --- a/docs/apm/how-to-guides.asciidoc +++ b/docs/apm/how-to-guides.asciidoc @@ -8,7 +8,6 @@ Learn how to perform common APM app tasks. * <> * <> * <> -* <> * <> * <> * <> @@ -21,8 +20,6 @@ include::apm-alerts.asciidoc[] include::custom-links.asciidoc[] -include::error-reports-watcher.asciidoc[] - include::filters.asciidoc[] include::machine-learning.asciidoc[] diff --git a/docs/development/core/server/kibana-plugin-core-server.routeconfigoptions.md b/docs/development/core/server/kibana-plugin-core-server.routeconfigoptions.md index 5a6103dfc57d4..fee6124f8d866 100644 --- a/docs/development/core/server/kibana-plugin-core-server.routeconfigoptions.md +++ b/docs/development/core/server/kibana-plugin-core-server.routeconfigoptions.md @@ -19,5 +19,6 @@ export interface RouteConfigOptions | [authRequired](./kibana-plugin-core-server.routeconfigoptions.authrequired.md) | boolean | 'optional' | Defines authentication mode for a route: - true. A user has to have valid credentials to access a resource - false. A user can access a resource without any credentials. - 'optional'. A user can access a resource if has valid credentials or no credentials at all. Can be useful when we grant access to a resource but want to identify a user if possible.Defaults to true if an auth mechanism is registered. | | [body](./kibana-plugin-core-server.routeconfigoptions.body.md) | Method extends 'get' | 'options' ? undefined : RouteConfigOptionsBody | Additional body options [RouteConfigOptionsBody](./kibana-plugin-core-server.routeconfigoptionsbody.md). | | [tags](./kibana-plugin-core-server.routeconfigoptions.tags.md) | readonly string[] | Additional metadata tag strings to attach to the route. | +| [timeout](./kibana-plugin-core-server.routeconfigoptions.timeout.md) | number | Timeouts for processing durations. Response timeout is in milliseconds. Default value: 2 minutes | | [xsrfRequired](./kibana-plugin-core-server.routeconfigoptions.xsrfrequired.md) | Method extends 'get' ? never : boolean | Defines xsrf protection requirements for a route: - true. Requires an incoming POST/PUT/DELETE request to contain kbn-xsrf header. - false. Disables xsrf protection.Set to true by default | diff --git a/docs/development/core/server/kibana-plugin-core-server.routeconfigoptions.timeout.md b/docs/development/core/server/kibana-plugin-core-server.routeconfigoptions.timeout.md new file mode 100644 index 0000000000000..479fcf883ec4d --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.routeconfigoptions.timeout.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [RouteConfigOptions](./kibana-plugin-core-server.routeconfigoptions.md) > [timeout](./kibana-plugin-core-server.routeconfigoptions.timeout.md) + +## RouteConfigOptions.timeout property + +Timeouts for processing durations. Response timeout is in milliseconds. Default value: 2 minutes + +Signature: + +```typescript +timeout?: number; +``` diff --git a/docs/images/lens_data_info.png b/docs/images/lens_data_info.png index 3ceb7e5e990f7..5ea6fc64a217d 100644 Binary files a/docs/images/lens_data_info.png and b/docs/images/lens_data_info.png differ diff --git a/docs/images/lens_drag_drop.gif b/docs/images/lens_drag_drop.gif index 2a759abf03020..ca62115e7ea3a 100644 Binary files a/docs/images/lens_drag_drop.gif and b/docs/images/lens_drag_drop.gif differ diff --git a/docs/images/lens_suggestions.gif b/docs/images/lens_suggestions.gif index ad93a9d87d548..3258e924cb205 100644 Binary files a/docs/images/lens_suggestions.gif and b/docs/images/lens_suggestions.gif differ diff --git a/docs/images/lens_tutorial_1.png b/docs/images/lens_tutorial_1.png index 7992276c833e7..77c1532e0ddac 100644 Binary files a/docs/images/lens_tutorial_1.png and b/docs/images/lens_tutorial_1.png differ diff --git a/docs/images/lens_tutorial_2.png b/docs/images/lens_tutorial_2.png index b47e7feff3b9f..e7b8a7b515f52 100644 Binary files a/docs/images/lens_tutorial_2.png and b/docs/images/lens_tutorial_2.png differ diff --git a/docs/images/lens_tutorial_3.png b/docs/images/lens_tutorial_3.png index ea40b458202b7..35fb10d4985e1 100644 Binary files a/docs/images/lens_tutorial_3.png and b/docs/images/lens_tutorial_3.png differ diff --git a/docs/images/lens_viz_types.png b/docs/images/lens_viz_types.png index fb3961ad8bb28..2ecfa6bd0e0e3 100644 Binary files a/docs/images/lens_viz_types.png and b/docs/images/lens_viz_types.png differ diff --git a/docs/redirects.asciidoc b/docs/redirects.asciidoc index d263642b2e90c..cde588ee731d2 100644 --- a/docs/redirects.asciidoc +++ b/docs/redirects.asciidoc @@ -96,3 +96,13 @@ This page was deleted. See <>. == Developing Visualizations This page was deleted. See <>. + +[role="exclude",id="errors-alerts-with-watcher"] +== Error reports with Watcher + +deprecated::[7.9.0] + +Watcher error reports have been removed and replaced with Kibana's <> feature. +To create error alerts with new tool, select **Alerts** - **Create threshold alert** - **Error rate**. + +More information on this new feature is available in <>. diff --git a/docs/settings/reporting-settings.asciidoc b/docs/settings/reporting-settings.asciidoc index c83cd068eff5b..b31ae76d28052 100644 --- a/docs/settings/reporting-settings.asciidoc +++ b/docs/settings/reporting-settings.asciidoc @@ -21,7 +21,7 @@ You can configure `xpack.reporting` settings in your `kibana.yml` to: | Set to `false` to disable the {report-features}. | `xpack.reporting.encryptionKey` - | Set to any text string. By default, {kib} will generate a random key when it + | Set to an alphanumeric, at least 32 characters long text string. By default, {kib} will generate a random key when it starts, which will cause pending reports to fail after restart. Configure this setting to preserve the same key across multiple restarts and multiple instances of {kib}. diff --git a/docs/setup/production.asciidoc b/docs/setup/production.asciidoc index afb4b37df6a28..23dbb3346b7ef 100644 --- a/docs/setup/production.asciidoc +++ b/docs/setup/production.asciidoc @@ -167,7 +167,7 @@ These can be used to automatically update the list of hosts as a cluster is resi Kibana has a default maximum memory limit of 1.4 GB, and in most cases, we recommend leaving this unconfigured. In some scenarios, such as large reporting jobs, it may make sense to tweak limits to meet more specific requirements. -You can modify this limit by setting `--max-old-space-size` in the `node.options` config file that can be found inside `kibana/config` folder or any other configured with the environment variable `KIBANA_PATH_CONF` (for example in debian based system would be `/etc/kibana`). +You can modify this limit by setting `--max-old-space-size` in the `node.options` config file that can be found inside `kibana/config` folder or any other configured with the environment variable `KBN_PATH_CONF` (for example in debian based system would be `/etc/kibana`). The option accepts a limit in MB: -------- diff --git a/docs/user/index.asciidoc b/docs/user/index.asciidoc index 14f900b681aef..42437bbea04d6 100644 --- a/docs/user/index.asciidoc +++ b/docs/user/index.asciidoc @@ -6,7 +6,10 @@ include::getting-started.asciidoc[] include::setup.asciidoc[] -include::monitoring/configuring-monitoring.asciidoc[] +include::monitoring/configuring-monitoring.asciidoc[leveloffset=+1] +include::monitoring/monitoring-metricbeat.asciidoc[leveloffset=+2] +include::monitoring/viewing-metrics.asciidoc[leveloffset=+2] +include::monitoring/monitoring-kibana.asciidoc[leveloffset=+2] include::security/securing-kibana.asciidoc[] diff --git a/docs/user/monitoring/beats-details.asciidoc b/docs/user/monitoring/beats-details.asciidoc index f4ecb2a74d91e..3d7a726d2f8a2 100644 --- a/docs/user/monitoring/beats-details.asciidoc +++ b/docs/user/monitoring/beats-details.asciidoc @@ -1,6 +1,6 @@ [role="xpack"] [[beats-page]] -== Beats Monitoring Metrics += Beats Monitoring Metrics ++++ Beats Metrics ++++ diff --git a/docs/user/monitoring/cluster-alerts-license.asciidoc b/docs/user/monitoring/cluster-alerts-license.asciidoc deleted file mode 100644 index ec86b6f578e19..0000000000000 --- a/docs/user/monitoring/cluster-alerts-license.asciidoc +++ /dev/null @@ -1,2 +0,0 @@ -NOTE: Watcher must be enabled to view cluster alerts. If you have a Basic -license, Top Cluster Alerts are not displayed. \ No newline at end of file diff --git a/docs/user/monitoring/cluster-alerts.asciidoc b/docs/user/monitoring/cluster-alerts.asciidoc index 15c3037183ff0..98d14de226bd9 100644 --- a/docs/user/monitoring/cluster-alerts.asciidoc +++ b/docs/user/monitoring/cluster-alerts.asciidoc @@ -1,6 +1,6 @@ [role="xpack"] [[cluster-alerts]] -== Cluster Alerts += Cluster Alerts The *Stack Monitoring > Clusters* page in {kib} summarizes the status of your {stack}. You can drill down into the metrics to view more information about your @@ -39,11 +39,12 @@ valid for 30 days. The {monitor-features} check the cluster alert conditions every minute. Cluster alerts are automatically dismissed when the condition is resolved. -include::cluster-alerts-license.asciidoc[] +NOTE: {watcher} must be enabled to view cluster alerts. If you have a Basic +license, Top Cluster Alerts are not displayed. [float] [[cluster-alert-email-notifications]] -==== Email Notifications +== Email Notifications To receive email notifications for the Cluster Alerts: 1. Configure an email account as described in diff --git a/docs/user/monitoring/configuring-monitoring.asciidoc b/docs/user/monitoring/configuring-monitoring.asciidoc index 7bcddcac923b2..f158dcc3eee6f 100644 --- a/docs/user/monitoring/configuring-monitoring.asciidoc +++ b/docs/user/monitoring/configuring-monitoring.asciidoc @@ -1,6 +1,6 @@ [role="xpack"] [[configuring-monitoring]] -== Configure monitoring in {kib} += Configure monitoring in {kib} ++++ Configure monitoring ++++ @@ -16,7 +16,3 @@ You can also use {kib} to To learn about monitoring in general, see {ref}/monitor-elasticsearch-cluster.html[Monitor a cluster]. - -include::monitoring-metricbeat.asciidoc[] -include::viewing-metrics.asciidoc[] -include::monitoring-kibana.asciidoc[] diff --git a/docs/user/monitoring/dashboards.asciidoc b/docs/user/monitoring/dashboards.asciidoc deleted file mode 100644 index 4ffe76f634d93..0000000000000 --- a/docs/user/monitoring/dashboards.asciidoc +++ /dev/null @@ -1,67 +0,0 @@ -[[dashboards]] -== Monitoring's Dashboards - -=== Overview Dashboard - -The _Overview_ dashboard is Monitoring's main page. The dashboard displays the -essentials metrics you need to know that your cluster is healthy. It also -provides an overview of your nodes and indices, displayed in two clean tables -with the relevant key metrics. If some value needs your attention, they will -be highlighted in yellow or red. The nodes and indices tables also serve as an -entry point to the more detailed _Node Statistics_ and _Index Statistics_ -dashboards. - -overview_thumb.png["Overview Dashboard",link="images/overview.png"] - -=== Node & Index Statistics - -The _Node Statistics_ dashboard displays metric charts from the perspective of -one or more nodes. Metrics include hardware level metrics (like load and CPU -usage), process and JVM metrics (memory usage, GC), and node level -Elasticsearch metrics such as field data usage, search requests rate and -thread pool rejection. - -node_stats_thumb.png["Node Statistics Dashboard",link="images/node_stats.png"] - -The _Index Statistics_ dashboard is very similar to the _Node Statistics_ -dashboard, but it shows you all the metrics from the perspective of one or -more indices. The metrics are per index, with data aggregated from all of the -nodes in the cluster. For example, the ''store size'' chart shows the total -size of the index data across the whole cluster. - -index_stats_thumb.png["Index Statistics Dashboard",link="images/index_stats.png"] - -=== Shard Allocation - -The _Shard Allocation_ dashboard displays how the shards are allocated across nodes. -The dashboard also shows the status of the shards. It has two perspectives, _By Indices_ and _By Nodes_. -The _By Indices_ view lists each index and shows you how it's shards are -distributed across nodes. The _By Nodes_ view lists each node and shows you which shards the node current host. - -The viewer also has a playback feature which allows you to view the history of the shard allocation. You can rewind to each -allocation event and then play back the history from any point in time. Hover on relocating shards to highlight both -their previous and new location. The time line color changes based on the state of the cluster for -each time period. - -shard_allocation_thumb.png["Shard Allocation Dashboard",link="images/shard_allocation.png"] - -=== Cluster Pulse - -The Cluster Pulse Dashboard allows you to see any event of interest in the cluster. Typical -events include nodes joining or leaving, master election, index creation, shard (re)allocation -and more. - -cluster_pulse_thumb.png["Index Statistics Dashboard",link="images/cluster_pulse.png"] - -[[sense]] -=== Sense - -_Sense_ is a lightweight developer console. The console is handy when you want -to make an extra API call to check something or perhaps tweak a setting. The -developer console understands both JSON and the Elasticsearch API, offering -suggestions and autocompletion. It is very useful for prototyping queries, -researching your data or any other administrative work with the API. - -image::images/sense_thumb.png["Developer Console",link="sense.png"] - - diff --git a/docs/user/monitoring/elasticsearch-details.asciidoc b/docs/user/monitoring/elasticsearch-details.asciidoc index 15e4676c443df..11a561e7ad01f 100644 --- a/docs/user/monitoring/elasticsearch-details.asciidoc +++ b/docs/user/monitoring/elasticsearch-details.asciidoc @@ -1,6 +1,6 @@ [role="xpack"] [[elasticsearch-metrics]] -== {es} Monitoring Metrics += {es} Monitoring Metrics [subs="attributes"] ++++ {es} Metrics @@ -18,7 +18,7 @@ See also {ref}/monitor-elasticsearch-cluster.html[Monitor a cluster]. [float] [[cluster-overview-page]] -==== Cluster Overview +== Cluster Overview To view the key metrics that indicate the overall health of an {es} cluster, click **Overview** in the {es} section. Anything that needs your attention is @@ -44,7 +44,7 @@ From there, you can dive into detailed metrics for particular nodes and indices. [float] [[nodes-page]] -==== Nodes +== Nodes To view node metrics, click **Nodes**. The Nodes section shows the status of each node in your cluster. @@ -54,7 +54,7 @@ image::user/monitoring/images/monitoring-nodes.png["Elasticsearch Nodes"] [float] [[nodes-page-overview]] -===== Node Overview +=== Node Overview Click the name of a node to view its node statistics over time. These represent high-level statistics collected from {es} that provide a good overview of @@ -66,7 +66,7 @@ image::user/monitoring/images/monitoring-node.png["Elasticsearch Node Overview"] [float] [[nodes-page-advanced]] -===== Node Advanced +=== Node Advanced To view advanced node metrics, click the **Advanced** tab for a node. The *Advanced* tab shows additional metrics, such as memory and garbage collection @@ -81,7 +81,7 @@ more advanced knowledge of {es}, such as poor garbage collection performance. [float] [[indices-overview-page]] -==== Indices +== Indices To view index metrics, click **Indices**. The Indices section shows the same overall index and search metrics as the Overview and a table of your indices. @@ -91,7 +91,7 @@ image::user/monitoring/images/monitoring-indices.png["Elasticsearch Indices"] [float] [[indices-page-overview]] -===== Index Overview +=== Index Overview From the Indices listing, you can view data for a particular index. To drill down into the data for a particular index, click its name in the Indices table. @@ -101,7 +101,7 @@ image::user/monitoring/images/monitoring-index.png["Elasticsearch Index Overview [float] [[indices-page-advanced]] -===== Index Advanced +=== Index Advanced To view advanced index metrics, click the **Advanced** tab for an index. The *Advanced* tab shows additional metrics, such as memory statistics reported @@ -116,7 +116,7 @@ more advanced knowledge of {es}, such as wasteful index memory usage. [float] [[jobs-page]] -==== Jobs +== Jobs To view {ml} job metrics, click **Jobs**. For each job in your cluster, it shows information such as its status, the number of records processed, the size of the @@ -127,7 +127,7 @@ image::user/monitoring/images/monitoring-jobs.png["Machine learning jobs",link=" [float] [[ccr-overview-page]] -==== CCR +== CCR To view {ccr} metrics, click **CCR**. For each follower index on the cluster, it shows information such as the leader index, an indication of how much the @@ -149,7 +149,7 @@ For more information, see {ref}/xpack-ccr.html[{ccr-cap}]. [float] [[logs-monitor-page]] -==== Logs +== Logs If you use {filebeat} to collect log data from your cluster, you can see its recent logs in the *Stack Monitoring* application. The *Clusters* page lists the diff --git a/docs/user/monitoring/gs-index.asciidoc b/docs/user/monitoring/gs-index.asciidoc deleted file mode 100644 index 69c523647393c..0000000000000 --- a/docs/user/monitoring/gs-index.asciidoc +++ /dev/null @@ -1,31 +0,0 @@ -[[xpack-monitoring]] -= Monitoring the Elastic Stack - -[partintro] --- -The {monitoring} components enable you to easily monitor the Elastic Stack -from {kibana-ref}/introduction.html[Kibana]. -You can view health and performance data for {es}, Logstash, and {kib} in real -time, as well as analyze past performance. - -A monitoring agent runs on each {es}, {kib}, and Logstash instance to collect -and index metrics. - -By default, metrics are indexed within the cluster you are monitoring. -Setting up a dedicated monitoring cluster ensures you can access historical -monitoring data even if the cluster you're -monitoring goes down. It also enables you to monitor multiple clusters -from a central location. - -When you use a dedicated monitoring cluster, the metrics collected by the -Logstash and Kibana monitoring agents are shipped to the Elasticsearch -cluster you're monitoring, which then forwards all of the metrics to -the monitoring cluster. - -//   - -// image:monitoring-architecture.png["Monitoring Architecture",link="images/monitoring-architecture.png"] - --- - -include::getting-started.asciidoc[] diff --git a/docs/user/monitoring/index.asciidoc b/docs/user/monitoring/index.asciidoc index edc572a56434e..ab773657073ba 100644 --- a/docs/user/monitoring/index.asciidoc +++ b/docs/user/monitoring/index.asciidoc @@ -1,33 +1,7 @@ -[role="xpack"] -[[xpack-monitoring]] -= Stack Monitoring - -[partintro] --- - -The {kib} {monitor-features} serve two separate purposes: - -. To visualize monitoring data from across the {stack}. You can view health and -performance data for {es}, {ls}, and Beats in real time, as well as analyze past -performance. -. To monitor {kib} itself and route that data to the monitoring cluster. - -If you enable monitoring across the {stack}, each {es} node, {ls} node, {kib} -instance, and Beat is considered unique based on its persistent -UUID, which is written to the <> directory when the node -or instance starts. - -NOTE: Watcher must be enabled to view cluster alerts. If you have a Basic -license, Top Cluster Alerts are not displayed. - -For more information, see <> and -{ref}/monitor-elasticsearch-cluster.html[Monitor a cluster]. - --- - -include::beats-details.asciidoc[] -include::cluster-alerts.asciidoc[] -include::elasticsearch-details.asciidoc[] -include::kibana-details.asciidoc[] -include::logstash-details.asciidoc[] -include::monitoring-troubleshooting.asciidoc[] +include::xpack-monitoring.asciidoc[] +include::beats-details.asciidoc[leveloffset=+1] +include::cluster-alerts.asciidoc[leveloffset=+1] +include::elasticsearch-details.asciidoc[leveloffset=+1] +include::kibana-details.asciidoc[leveloffset=+1] +include::logstash-details.asciidoc[leveloffset=+1] +include::monitoring-troubleshooting.asciidoc[leveloffset=+1] diff --git a/docs/user/monitoring/kibana-details.asciidoc b/docs/user/monitoring/kibana-details.asciidoc index 976ef456fcfa5..a5466f1418ae8 100644 --- a/docs/user/monitoring/kibana-details.asciidoc +++ b/docs/user/monitoring/kibana-details.asciidoc @@ -1,6 +1,6 @@ [role="xpack"] [[kibana-page]] -== {kib} Monitoring Metrics += {kib} Monitoring Metrics [subs="attributes"] ++++ {kib} Metrics diff --git a/docs/user/monitoring/logstash-details.asciidoc b/docs/user/monitoring/logstash-details.asciidoc index 1433a6a036ca8..9d7e3ce342e16 100644 --- a/docs/user/monitoring/logstash-details.asciidoc +++ b/docs/user/monitoring/logstash-details.asciidoc @@ -1,6 +1,6 @@ [role="xpack"] [[logstash-page]] -== Logstash Monitoring Metrics += Logstash Monitoring Metrics ++++ Logstash Metrics ++++ diff --git a/docs/user/monitoring/monitoring-details.asciidoc b/docs/user/monitoring/monitoring-details.asciidoc deleted file mode 100644 index 580e02d86155a..0000000000000 --- a/docs/user/monitoring/monitoring-details.asciidoc +++ /dev/null @@ -1,4 +0,0 @@ -[[monitoring-details]] -== Viewing Monitoring Metrics - -See {kibana-ref}/monitoring-data.html[Viewing Monitoring Data in {kib}]. diff --git a/docs/user/monitoring/monitoring-kibana.asciidoc b/docs/user/monitoring/monitoring-kibana.asciidoc index bb8b3e5d42851..47fbe1bea9f2a 100644 --- a/docs/user/monitoring/monitoring-kibana.asciidoc +++ b/docs/user/monitoring/monitoring-kibana.asciidoc @@ -1,6 +1,6 @@ [role="xpack"] [[monitoring-kibana]] -=== Collect monitoring data using legacy collectors += Collect monitoring data using legacy collectors ++++ Legacy collection methods ++++ diff --git a/docs/user/monitoring/monitoring-metricbeat.asciidoc b/docs/user/monitoring/monitoring-metricbeat.asciidoc index f2b32ba1de5dd..d18ebe95c7974 100644 --- a/docs/user/monitoring/monitoring-metricbeat.asciidoc +++ b/docs/user/monitoring/monitoring-metricbeat.asciidoc @@ -1,6 +1,6 @@ [role="xpack"] [[monitoring-metricbeat]] -=== Collect {kib} monitoring data with {metricbeat} += Collect {kib} monitoring data with {metricbeat} [subs="attributes"] ++++ Collect monitoring data with {metricbeat} diff --git a/docs/user/monitoring/monitoring-troubleshooting.asciidoc b/docs/user/monitoring/monitoring-troubleshooting.asciidoc index b9e9204348f33..64f1b01de14b1 100644 --- a/docs/user/monitoring/monitoring-troubleshooting.asciidoc +++ b/docs/user/monitoring/monitoring-troubleshooting.asciidoc @@ -1,6 +1,6 @@ [role="xpack"] [[monitor-troubleshooting]] -== Troubleshooting monitoring in {kib} += Troubleshooting monitoring in {kib} ++++ Troubleshooting ++++ @@ -9,7 +9,7 @@ Use the information in this section to troubleshoot common problems and find answers for frequently asked questions related to the {kib} {monitor-features}. [float] -=== Cannot view the cluster because the license information is invalid +== Cannot view the cluster because the license information is invalid *Symptoms:* @@ -24,7 +24,7 @@ To resolve this issue, upgrade {kib} to 6.3 or later. See {stack-ref}/upgrading-elastic-stack.html[Upgrading the {stack}]. [float] -=== No monitoring data is visible in {kib} +== No monitoring data is visible in {kib} *Symptoms:* diff --git a/docs/user/monitoring/viewing-metrics.asciidoc b/docs/user/monitoring/viewing-metrics.asciidoc index 6203565c3fe93..f35caea025cdd 100644 --- a/docs/user/monitoring/viewing-metrics.asciidoc +++ b/docs/user/monitoring/viewing-metrics.asciidoc @@ -1,6 +1,6 @@ [role="xpack"] [[monitoring-data]] -=== View monitoring data in {kib} += View monitoring data in {kib} ++++ View monitoring data ++++ diff --git a/docs/user/monitoring/xpack-monitoring.asciidoc b/docs/user/monitoring/xpack-monitoring.asciidoc new file mode 100644 index 0000000000000..c3aafe7f90db9 --- /dev/null +++ b/docs/user/monitoring/xpack-monitoring.asciidoc @@ -0,0 +1,26 @@ +[role="xpack"] +[[xpack-monitoring]] += Stack Monitoring + +[partintro] +-- + +The {kib} {monitor-features} serve two separate purposes: + +. To visualize monitoring data from across the {stack}. You can view health and +performance data for {es}, {ls}, and Beats in real time, as well as analyze past +performance. +. To monitor {kib} itself and route that data to the monitoring cluster. + +If you enable monitoring across the {stack}, each {es} node, {ls} node, {kib} +instance, and Beat is considered unique based on its persistent +UUID, which is written to the <> directory when the node +or instance starts. + +NOTE: Watcher must be enabled to view cluster alerts. If you have a Basic +license, Top Cluster Alerts are not displayed. + +For more information, see <> and +{ref}/monitor-elasticsearch-cluster.html[Monitor a cluster]. + +-- \ No newline at end of file diff --git a/docs/user/reporting/configuring-reporting.asciidoc b/docs/user/reporting/configuring-reporting.asciidoc index ca2d79bb2dec0..6a0c44cf4c2a4 100644 --- a/docs/user/reporting/configuring-reporting.asciidoc +++ b/docs/user/reporting/configuring-reporting.asciidoc @@ -23,7 +23,7 @@ reporting job metadata. To set a static encryption key for reporting, set the `xpack.reporting.encryptionKey` property in the `kibana.yml` -configuration file. You can use any text string as the encryption key. +configuration file. You can use any alphanumeric, at least 32 characters long text string as the encryption key. [source,yaml] -------------------------------------------------------------------------------- diff --git a/docs/visualize/images/lens_aggregation_labels.png b/docs/visualize/images/lens_aggregation_labels.png new file mode 100644 index 0000000000000..9dcf1d226a197 Binary files /dev/null and b/docs/visualize/images/lens_aggregation_labels.png differ diff --git a/docs/visualize/images/lens_index_pattern.png b/docs/visualize/images/lens_index_pattern.png new file mode 100644 index 0000000000000..90a34b7a5d225 Binary files /dev/null and b/docs/visualize/images/lens_index_pattern.png differ diff --git a/docs/visualize/images/lens_layers.png b/docs/visualize/images/lens_layers.png new file mode 100644 index 0000000000000..7410425a6977e Binary files /dev/null and b/docs/visualize/images/lens_layers.png differ diff --git a/docs/visualize/images/lens_tutorial_3.1.png b/docs/visualize/images/lens_tutorial_3.1.png new file mode 100644 index 0000000000000..e9ed365e64aec Binary files /dev/null and b/docs/visualize/images/lens_tutorial_3.1.png differ diff --git a/docs/visualize/images/lens_tutorial_3.2.png b/docs/visualize/images/lens_tutorial_3.2.png new file mode 100644 index 0000000000000..c19bcb05dcb00 Binary files /dev/null and b/docs/visualize/images/lens_tutorial_3.2.png differ diff --git a/docs/visualize/lens.asciidoc b/docs/visualize/lens.asciidoc index 09b55af9be2db..6e51433bca3f6 100644 --- a/docs/visualize/lens.asciidoc +++ b/docs/visualize/lens.asciidoc @@ -4,24 +4,22 @@ beta[] -*Lens* is a simple and fast way to create visualizations of your {es} data. With *Lens*, +*Lens* is a simple and fast way to create visualizations of your {es} data. To create visualizations, you drag and drop your data fields onto the visualization builder pane, and *Lens* automatically generates a visualization that best displays your data. With Lens, you can: -* Explore your data in just a few clicks. +* Use the automatically generated visualization suggestions to change the visualization type. * Create visualizations with multiple layers and indices. -* Use the automatically generated visualization suggestions to change the visualization type. - * Add your visualizations to dashboards and Canvas workpads. -To get started with *Lens*, click a field in the data panel, then drag and drop the field on a highlighted area. +To get started with *Lens*, select a field in the data panel, then drag and drop the field on a highlighted area. [role="screenshot"] -image::images/lens_drag_drop.gif[] +image::images/lens_drag_drop.gif[Drag and drop] You can incorporate many fields into your visualization, and Lens uses heuristics to decide how to apply each one to the visualization. @@ -30,9 +28,9 @@ you can still configure the customization options for your visualization. [float] [[apply-lens-filters]] -==== Filter the data panel fields +==== Change the data panel fields -The fields in the data panel based on your selected <>, and the <>. +The fields in the data panel are based on the selected <> and <>. To change the index pattern, click it, then select a new one. The fields in the data panel automatically update. @@ -46,12 +44,12 @@ To filter the fields in the data panel: [[view-data-summaries]] ==== Data summaries -To help you decide exactly the data you want to display, get a quick summary of each field. The summary shows the distribution of values in the time range. +To help you decide exactly the data you want to display, get a quick summary of each field. The summary shows the distribution of values within the selected time range. To view the field summary information, navigate to the field, then click *i*. [role="screenshot"] -image::images/lens_data_info.png[] +image::images/lens_data_info.png[Data summary window] [float] [[change-the-visualization-type]] @@ -62,7 +60,7 @@ image::images/lens_data_info.png[] *Suggestions* are shortcuts to alternate visualizations that *Lens* generates for you. [role="screenshot"] -image::images/lens_suggestions.gif[] +image::images/lens_suggestions.gif[Visualization suggestions] If you'd like to use a visualization type that is not suggested, click the visualization type, then select a new one. @@ -78,19 +76,30 @@ still allows you to make the change. [[customize-operation]] ==== Change the aggregation and labels -Lens allows some customizations of the data for each visualization. +For each visualization, Lens allows some customizations of the data. . Click *Drop a field here* or the field name in the column. -. Change the options that appear depending on the type of field. +. Change the options that appear. Options vary depending on the type of field. ++ +[role="screenshot"] +image::images/lens_aggregation_labels.png[Quick function options] [float] [[layers]] ==== Add layers and indices -Bar, line, and area charts allow you to visualize multiple data layers and indices so that you can compare and analyze data from multiple sources. +Area, line, and bar charts allow you to visualize multiple data layers and indices so that you can compare and analyze data from multiple sources. + +To add a layer, click *+*, then drag and drop the fields for the new layer. + +[role="screenshot"] +image::images/lens_layers.png[Add layers] + +To view a different index, click it, then select a new one. -To add a layer, click *+*, then drag and drop the fields for the new layer. To view a different index, click it, then select a new one. +[role="screenshot"] +image::images/lens_index_pattern.png[Add index pattern] [float] [[lens-tutorial]] @@ -110,8 +119,6 @@ To start, you'll need to add the <>. Drag and drop your data onto the visualization builder pane. -. Open *Lens*. - . Select the *kibana_sample_data_ecommerce* index pattern. . Click image:images/time-filter-calendar.png[], then click *Last 7 days*. @@ -138,16 +145,19 @@ image::images/lens_tutorial_2.png[Lens tutorial] Make your visualization look exactly how you want with the customization options. -. Click *Average of taxful_total_price*. - -.. Change the *Label* to `Sales`. - -. Click *Top values of category.keyword*. +. Click *Average of taxful_total_price*, then change the *Label* to `Sales`. ++ +[role="screenshot"] +image::images/lens_tutorial_3.1.png[Lens tutorial] -.. Change *Number of values* to `10`. The visualization updates to show there are only -six available categories. +. Click *Top values of category.keyword*, then change *Number of values* to `10`. ++ +[role="screenshot"] +image::images/lens_tutorial_3.2.png[Lens tutorial] ++ +The visualization updates to show there are only six available categories. + -Look at the *Suggestions*. An area chart is not an option, but for sales data, a stacked area chart might be the best option. +Look at the *Suggestions*. An area chart is not an option, but for the sales data, a stacked area chart might be the best option. . To switch the chart type, click *Stacked bar chart* in the column, then click *Stacked area* from the *Select a visualizations* window. + diff --git a/package.json b/package.json index 4935d5f9cea73..bf005066796ba 100644 --- a/package.json +++ b/package.json @@ -458,7 +458,7 @@ "jest-cli": "^25.5.4", "jest-environment-jsdom-thirteen": "^1.0.1", "jest-raw-loader": "^1.0.1", - "jimp": "^0.9.6", + "jimp": "^0.14.0", "json5": "^1.0.1", "karma": "5.0.2", "karma-chrome-launcher": "2.2.0", diff --git a/src/core/public/doc_links/doc_links_service.ts b/src/core/public/doc_links/doc_links_service.ts index e45d48c52528a..b9b69e995501d 100644 --- a/src/core/public/doc_links/doc_links_service.ts +++ b/src/core/public/doc_links/doc_links_service.ts @@ -112,7 +112,7 @@ export class DocLinksService { kibana: `${ELASTIC_WEBSITE_URL}guide/en/kibana/${DOC_LINK_VERSION}/index.html`, siem: { guide: `${ELASTIC_WEBSITE_URL}guide/en/security/${DOC_LINK_VERSION}/index.html`, - gettingStarted: `${ELASTIC_WEBSITE_URL}guide/en/security/${DOC_LINK_VERSION}/install-siem.html`, + gettingStarted: `${ELASTIC_WEBSITE_URL}guide/en/security/${DOC_LINK_VERSION}/index.html`, }, query: { luceneQuerySyntax: `${ELASTICSEARCH_DOCS}query-dsl-query-string-query.html#query-string-syntax`, diff --git a/src/core/server/config/deprecation/core_deprecations.test.ts b/src/core/server/config/deprecation/core_deprecations.test.ts index ebdb6f1c88b16..adf0f52339366 100644 --- a/src/core/server/config/deprecation/core_deprecations.test.ts +++ b/src/core/server/config/deprecation/core_deprecations.test.ts @@ -51,7 +51,7 @@ describe('core deprecations', () => { const { messages } = applyCoreDeprecations(); expect(messages).toMatchInlineSnapshot(` Array [ - "Environment variable CONFIG_PATH is deprecated. It has been replaced with KIBANA_PATH_CONF pointing to a config folder", + "Environment variable CONFIG_PATH is deprecated. It has been replaced with KBN_PATH_CONF pointing to a config folder", ] `); }); diff --git a/src/core/server/config/deprecation/core_deprecations.ts b/src/core/server/config/deprecation/core_deprecations.ts index f8d337cdbb987..881ad278e9914 100644 --- a/src/core/server/config/deprecation/core_deprecations.ts +++ b/src/core/server/config/deprecation/core_deprecations.ts @@ -23,7 +23,7 @@ import { ConfigDeprecationProvider, ConfigDeprecation } from './types'; const configPathDeprecation: ConfigDeprecation = (settings, fromPath, log) => { if (has(process.env, 'CONFIG_PATH')) { log( - `Environment variable CONFIG_PATH is deprecated. It has been replaced with KIBANA_PATH_CONF pointing to a config folder` + `Environment variable CONFIG_PATH is deprecated. It has been replaced with KBN_PATH_CONF pointing to a config folder` ); } return settings; diff --git a/src/core/server/http/http_server.test.ts b/src/core/server/http/http_server.test.ts index 3e170dac07a09..53c7fdf9f8037 100644 --- a/src/core/server/http/http_server.test.ts +++ b/src/core/server/http/http_server.test.ts @@ -992,6 +992,133 @@ describe('body options', () => { }); }); +describe('timeout options', () => { + test('should accept a socket "timeout" which is 3 minutes in milliseconds, "300000" for a POST', async () => { + const { registerRouter, server: innerServer } = await server.setup(config); + + const router = new Router('', logger, enhanceWithContext); + router.post( + { + path: '/', + validate: false, + options: { timeout: 300000 }, + }, + (context, req, res) => { + try { + return res.ok({ body: { timeout: req.route.options.timeout } }); + } catch (err) { + return res.internalError({ body: err.message }); + } + } + ); + registerRouter(router); + await server.start(); + await supertest(innerServer.listener).post('/').send({ test: 1 }).expect(200, { + timeout: 300000, + }); + }); + + test('should accept a socket "timeout" which is 3 minutes in milliseconds, "300000" for a GET', async () => { + const { registerRouter, server: innerServer } = await server.setup(config); + + const router = new Router('', logger, enhanceWithContext); + router.get( + { + path: '/', + validate: false, + options: { timeout: 300000 }, + }, + (context, req, res) => { + try { + return res.ok({ body: { timeout: req.route.options.timeout } }); + } catch (err) { + return res.internalError({ body: err.message }); + } + } + ); + registerRouter(router); + await server.start(); + await supertest(innerServer.listener).get('/').expect(200, { + timeout: 300000, + }); + }); + + test('should accept a socket "timeout" which is 3 minutes in milliseconds, "300000" for a DELETE', async () => { + const { registerRouter, server: innerServer } = await server.setup(config); + + const router = new Router('', logger, enhanceWithContext); + router.delete( + { + path: '/', + validate: false, + options: { timeout: 300000 }, + }, + (context, req, res) => { + try { + return res.ok({ body: { timeout: req.route.options.timeout } }); + } catch (err) { + return res.internalError({ body: err.message }); + } + } + ); + registerRouter(router); + await server.start(); + await supertest(innerServer.listener).delete('/').expect(200, { + timeout: 300000, + }); + }); + + test('should accept a socket "timeout" which is 3 minutes in milliseconds, "300000" for a PUT', async () => { + const { registerRouter, server: innerServer } = await server.setup(config); + + const router = new Router('', logger, enhanceWithContext); + router.put( + { + path: '/', + validate: false, + options: { timeout: 300000 }, + }, + (context, req, res) => { + try { + return res.ok({ body: { timeout: req.route.options.timeout } }); + } catch (err) { + return res.internalError({ body: err.message }); + } + } + ); + registerRouter(router); + await server.start(); + await supertest(innerServer.listener).put('/').expect(200, { + timeout: 300000, + }); + }); + + test('should accept a socket "timeout" which is 3 minutes in milliseconds, "300000" for a PATCH', async () => { + const { registerRouter, server: innerServer } = await server.setup(config); + + const router = new Router('', logger, enhanceWithContext); + router.patch( + { + path: '/', + validate: false, + options: { timeout: 300000 }, + }, + (context, req, res) => { + try { + return res.ok({ body: { timeout: req.route.options.timeout } }); + } catch (err) { + return res.internalError({ body: err.message }); + } + } + ); + registerRouter(router); + await server.start(); + await supertest(innerServer.listener).patch('/').expect(200, { + timeout: 300000, + }); + }); +}); + test('should return a stream in the body', async () => { const { registerRouter, server: innerServer } = await server.setup(config); diff --git a/src/core/server/http/http_server.ts b/src/core/server/http/http_server.ts index 9c16162d69334..4b70f58deba99 100644 --- a/src/core/server/http/http_server.ts +++ b/src/core/server/http/http_server.ts @@ -161,8 +161,10 @@ export class HttpServer { this.log.debug(`registering route handler for [${route.path}]`); // Hapi does not allow payload validation to be specified for 'head' or 'get' requests const validate = isSafeMethod(route.method) ? undefined : { payload: true }; - const { authRequired, tags, body = {} } = route.options; + const { authRequired, tags, body = {}, timeout } = route.options; const { accepts: allow, maxBytes, output, parse } = body; + // Hapi does not allow timeouts on payloads to be specified for 'head' or 'get' requests + const payloadTimeout = isSafeMethod(route.method) || timeout == null ? undefined : timeout; const kibanaRouteState: KibanaRouteState = { xsrfRequired: route.options.xsrfRequired ?? !isSafeMethod(route.method), @@ -181,9 +183,23 @@ export class HttpServer { // validation applied in ./http_tools#getServerOptions // (All NP routes are already required to specify their own validation in order to access the payload) validate, - payload: [allow, maxBytes, output, parse].some((v) => typeof v !== 'undefined') - ? { allow, maxBytes, output, parse } + payload: [allow, maxBytes, output, parse, payloadTimeout].some( + (v) => typeof v !== 'undefined' + ) + ? { + allow, + maxBytes, + output, + parse, + timeout: payloadTimeout, + } : undefined, + timeout: + timeout != null + ? { + socket: timeout + 1, // Hapi server requires the socket to be greater than payload settings so we add 1 millisecond + } + : undefined, }, }); } diff --git a/src/core/server/http/integration_tests/router.test.ts b/src/core/server/http/integration_tests/router.test.ts index bb36fefa96611..434e22e3cf6f5 100644 --- a/src/core/server/http/integration_tests/router.test.ts +++ b/src/core/server/http/integration_tests/router.test.ts @@ -302,6 +302,130 @@ describe('Options', () => { }); }); }); + + describe('timeout', () => { + it('should timeout if configured with a small timeout value for a POST', async () => { + const { server: innerServer, createRouter } = await server.setup(setupDeps); + const router = createRouter('/'); + + router.post( + { path: '/a', validate: false, options: { timeout: 1000 } }, + async (context, req, res) => { + await new Promise((resolve) => setTimeout(resolve, 2000)); + return res.ok({}); + } + ); + router.post({ path: '/b', validate: false }, (context, req, res) => res.ok({})); + await server.start(); + expect(supertest(innerServer.listener).post('/a')).rejects.toThrow('socket hang up'); + await supertest(innerServer.listener).post('/b').expect(200, {}); + }); + + it('should timeout if configured with a small timeout value for a PUT', async () => { + const { server: innerServer, createRouter } = await server.setup(setupDeps); + const router = createRouter('/'); + + router.put( + { path: '/a', validate: false, options: { timeout: 1000 } }, + async (context, req, res) => { + await new Promise((resolve) => setTimeout(resolve, 2000)); + return res.ok({}); + } + ); + router.put({ path: '/b', validate: false }, (context, req, res) => res.ok({})); + await server.start(); + + expect(supertest(innerServer.listener).put('/a')).rejects.toThrow('socket hang up'); + await supertest(innerServer.listener).put('/b').expect(200, {}); + }); + + it('should timeout if configured with a small timeout value for a DELETE', async () => { + const { server: innerServer, createRouter } = await server.setup(setupDeps); + const router = createRouter('/'); + + router.delete( + { path: '/a', validate: false, options: { timeout: 1000 } }, + async (context, req, res) => { + await new Promise((resolve) => setTimeout(resolve, 2000)); + return res.ok({}); + } + ); + router.delete({ path: '/b', validate: false }, (context, req, res) => res.ok({})); + await server.start(); + expect(supertest(innerServer.listener).delete('/a')).rejects.toThrow('socket hang up'); + await supertest(innerServer.listener).delete('/b').expect(200, {}); + }); + + it('should timeout if configured with a small timeout value for a GET', async () => { + const { server: innerServer, createRouter } = await server.setup(setupDeps); + const router = createRouter('/'); + + router.get( + // Note: There is a bug within Hapi Server where it cannot set the payload timeout for a GET call but it also cannot configure a timeout less than the payload body + // so the least amount of possible time to configure the timeout is 10 seconds. + { path: '/a', validate: false, options: { timeout: 100000 } }, + async (context, req, res) => { + // Cause a wait of 20 seconds to cause the socket hangup + await new Promise((resolve) => setTimeout(resolve, 200000)); + return res.ok({}); + } + ); + router.get({ path: '/b', validate: false }, (context, req, res) => res.ok({})); + await server.start(); + + expect(supertest(innerServer.listener).get('/a')).rejects.toThrow('socket hang up'); + await supertest(innerServer.listener).get('/b').expect(200, {}); + }); + + it('should not timeout if configured with a 5 minute timeout value for a POST', async () => { + const { server: innerServer, createRouter } = await server.setup(setupDeps); + const router = createRouter('/'); + + router.post( + { path: '/a', validate: false, options: { timeout: 300000 } }, + async (context, req, res) => res.ok({}) + ); + await server.start(); + await supertest(innerServer.listener).post('/a').expect(200, {}); + }); + + it('should not timeout if configured with a 5 minute timeout value for a PUT', async () => { + const { server: innerServer, createRouter } = await server.setup(setupDeps); + const router = createRouter('/'); + + router.put( + { path: '/a', validate: false, options: { timeout: 300000 } }, + async (context, req, res) => res.ok({}) + ); + await server.start(); + + await supertest(innerServer.listener).put('/a').expect(200, {}); + }); + + it('should not timeout if configured with a 5 minute timeout value for a DELETE', async () => { + const { server: innerServer, createRouter } = await server.setup(setupDeps); + const router = createRouter('/'); + + router.delete( + { path: '/a', validate: false, options: { timeout: 300000 } }, + async (context, req, res) => res.ok({}) + ); + await server.start(); + await supertest(innerServer.listener).delete('/a').expect(200, {}); + }); + + it('should not timeout if configured with a 5 minute timeout value for a GET', async () => { + const { server: innerServer, createRouter } = await server.setup(setupDeps); + const router = createRouter('/'); + + router.get( + { path: '/a', validate: false, options: { timeout: 300000 } }, + async (context, req, res) => res.ok({}) + ); + await server.start(); + await supertest(innerServer.listener).get('/a').expect(200, {}); + }); + }); }); describe('Cache-Control', () => { diff --git a/src/core/server/http/router/request.ts b/src/core/server/http/router/request.ts index fefd75ad9710e..0e73431fe7c6d 100644 --- a/src/core/server/http/router/request.ts +++ b/src/core/server/http/router/request.ts @@ -197,12 +197,14 @@ export class KibanaRequest< private getRouteInfo(request: Request): KibanaRequestRoute { const method = request.method as Method; const { parse, maxBytes, allow, output } = request.route.settings.payload || {}; + const timeout = request.route.settings.timeout?.socket; const options = ({ authRequired: this.getAuthRequired(request), // some places in LP call KibanaRequest.from(request) manually. remove fallback to true before v8 xsrfRequired: (request.route.settings.app as KibanaRouteState)?.xsrfRequired ?? true, tags: request.route.settings.tags || [], + timeout: typeof timeout === 'number' ? timeout - 1 : undefined, // We are forced to have the timeout be 1 millisecond greater than the server and payload so we subtract one here to give the user consist settings body: isSafeMethod(method) ? undefined : { diff --git a/src/core/server/http/router/route.ts b/src/core/server/http/router/route.ts index 9789d266587af..676c494bec522 100644 --- a/src/core/server/http/router/route.ts +++ b/src/core/server/http/router/route.ts @@ -144,6 +144,12 @@ export interface RouteConfigOptions { * Additional body options {@link RouteConfigOptionsBody}. */ body?: Method extends 'get' | 'options' ? undefined : RouteConfigOptionsBody; + + /** + * Timeouts for processing durations. Response timeout is in milliseconds. + * Default value: 2 minutes + */ + timeout?: number; } /** diff --git a/src/core/server/path/index.ts b/src/core/server/path/index.ts index 1bb650518c47a..7c1a81643fbc8 100644 --- a/src/core/server/path/index.ts +++ b/src/core/server/path/index.ts @@ -25,14 +25,18 @@ import { fromRoot } from '../utils'; const isString = (v: any): v is string => typeof v === 'string'; const CONFIG_PATHS = [ + process.env.KBN_PATH_CONF && join(process.env.KBN_PATH_CONF, 'kibana.yml'), process.env.KIBANA_PATH_CONF && join(process.env.KIBANA_PATH_CONF, 'kibana.yml'), process.env.CONFIG_PATH, // deprecated fromRoot('config/kibana.yml'), ].filter(isString); -const CONFIG_DIRECTORIES = [process.env.KIBANA_PATH_CONF, fromRoot('config'), '/etc/kibana'].filter( - isString -); +const CONFIG_DIRECTORIES = [ + process.env.KBN_PATH_CONF, + process.env.KIBANA_PATH_CONF, + fromRoot('config'), + '/etc/kibana', +].filter(isString); const DATA_PATHS = [ process.env.DATA_PATH, // deprecated diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index a0e16602ba4bf..48b480f2f61d2 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -1789,6 +1789,7 @@ export interface RouteConfigOptions { authRequired?: boolean | 'optional'; body?: Method extends 'get' | 'options' ? undefined : RouteConfigOptionsBody; tags?: readonly string[]; + timeout?: number; xsrfRequired?: Method extends 'get' ? never : boolean; } diff --git a/src/dev/build/tasks/bin/scripts/kibana-keystore b/src/dev/build/tasks/bin/scripts/kibana-keystore index f83df118d24e8..d811e70095548 100755 --- a/src/dev/build/tasks/bin/scripts/kibana-keystore +++ b/src/dev/build/tasks/bin/scripts/kibana-keystore @@ -14,7 +14,7 @@ while [ -h "$SCRIPT" ] ; do done DIR="$(dirname "${SCRIPT}")/.." -CONFIG_DIR=${KIBANA_PATH_CONF:-"$DIR/config"} +CONFIG_DIR=${KBN_PATH_CONF:-"$DIR/config"} NODE="${DIR}/node/bin/node" test -x "$NODE" if [ ! -x "$NODE" ]; then diff --git a/src/dev/build/tasks/bin/scripts/kibana-keystore.bat b/src/dev/build/tasks/bin/scripts/kibana-keystore.bat index 389eb5bf488e4..7e227141c8ba3 100755 --- a/src/dev/build/tasks/bin/scripts/kibana-keystore.bat +++ b/src/dev/build/tasks/bin/scripts/kibana-keystore.bat @@ -12,8 +12,8 @@ If Not Exist "%NODE%" ( Exit /B 1 ) -set CONFIG_DIR=%KIBANA_PATH_CONF% -If [%KIBANA_PATH_CONF%] == [] ( +set CONFIG_DIR=%KBN_PATH_CONF% +If [%KBN_PATH_CONF%] == [] ( set CONFIG_DIR=%DIR%\config ) diff --git a/src/dev/build/tasks/bin/scripts/kibana-plugin b/src/dev/build/tasks/bin/scripts/kibana-plugin index f1102e1ef5a32..f4486e9cf85fb 100755 --- a/src/dev/build/tasks/bin/scripts/kibana-plugin +++ b/src/dev/build/tasks/bin/scripts/kibana-plugin @@ -14,7 +14,7 @@ while [ -h "$SCRIPT" ] ; do done DIR="$(dirname "${SCRIPT}")/.." -CONFIG_DIR=${KIBANA_PATH_CONF:-"$DIR/config"} +CONFIG_DIR=${KBN_PATH_CONF:-"$DIR/config"} NODE="${DIR}/node/bin/node" test -x "$NODE" if [ ! -x "$NODE" ]; then diff --git a/src/dev/build/tasks/bin/scripts/kibana-plugin.bat b/src/dev/build/tasks/bin/scripts/kibana-plugin.bat index 6815b1b9eab8c..4fb30977fda06 100755 --- a/src/dev/build/tasks/bin/scripts/kibana-plugin.bat +++ b/src/dev/build/tasks/bin/scripts/kibana-plugin.bat @@ -13,8 +13,8 @@ If Not Exist "%NODE%" ( Exit /B 1 ) -set CONFIG_DIR=%KIBANA_PATH_CONF% -If [%KIBANA_PATH_CONF%] == [] ( +set CONFIG_DIR=%KBN_PATH_CONF% +If [%KBN_PATH_CONF%] == [] ( set CONFIG_DIR=%DIR%\config ) diff --git a/src/dev/build/tasks/bin/scripts/kibana.bat b/src/dev/build/tasks/bin/scripts/kibana.bat index d3edc92f110a5..98dd9ec05a48c 100755 --- a/src/dev/build/tasks/bin/scripts/kibana.bat +++ b/src/dev/build/tasks/bin/scripts/kibana.bat @@ -14,8 +14,8 @@ If Not Exist "%NODE%" ( Exit /B 1 ) -set CONFIG_DIR=%KIBANA_PATH_CONF% -If [%KIBANA_PATH_CONF%] == [] ( +set CONFIG_DIR=%KBN_PATH_CONF% +If [%KBN_PATH_CONF%] == [] ( set CONFIG_DIR=%DIR%\config ) diff --git a/src/dev/build/tasks/os_packages/docker_generator/bundle_dockerfiles.js b/src/dev/build/tasks/os_packages/docker_generator/bundle_dockerfiles.ts similarity index 80% rename from src/dev/build/tasks/os_packages/docker_generator/bundle_dockerfiles.js rename to src/dev/build/tasks/os_packages/docker_generator/bundle_dockerfiles.ts index 3f34a84057668..7a8f7316913be 100644 --- a/src/dev/build/tasks/os_packages/docker_generator/bundle_dockerfiles.js +++ b/src/dev/build/tasks/os_packages/docker_generator/bundle_dockerfiles.ts @@ -18,10 +18,14 @@ */ import { resolve } from 'path'; -import { compressTar, copyAll, mkdirp, write } from '../../../lib'; + +import { ToolingLog } from '@kbn/dev-utils'; + +import { compressTar, copyAll, mkdirp, write, Config } from '../../../lib'; import { dockerfileTemplate } from './templates'; +import { TemplateContext } from './template_context'; -export async function bundleDockerFiles(config, log, build, scope) { +export async function bundleDockerFiles(config: Config, log: ToolingLog, scope: TemplateContext) { log.info( `Generating kibana${scope.imageFlavor}${scope.ubiImageFlavor} docker build context bundle` ); @@ -50,17 +54,15 @@ export async function bundleDockerFiles(config, log, build, scope) { // Compress dockerfiles dir created inside // docker build dir as output it as a target // on targets folder - await compressTar( - { - archiverOptions: { - gzip: true, - gzipOptions: { - level: 9, - }, + await compressTar({ + source: dockerFilesBuildDir, + destination: dockerFilesOutputDir, + archiverOptions: { + gzip: true, + gzipOptions: { + level: 9, }, - createRootDirectory: false, }, - dockerFilesBuildDir, - dockerFilesOutputDir - ); + createRootDirectory: false, + }); } diff --git a/src/dev/build/tasks/os_packages/docker_generator/index.ts b/src/dev/build/tasks/os_packages/docker_generator/index.ts index 78d2b197dc7b2..dff56585fc704 100644 --- a/src/dev/build/tasks/os_packages/docker_generator/index.ts +++ b/src/dev/build/tasks/os_packages/docker_generator/index.ts @@ -17,5 +17,4 @@ * under the License. */ -// @ts-expect-error not ts yet export { runDockerGenerator, runDockerGeneratorForUBI } from './run'; diff --git a/src/dev/build/tasks/os_packages/docker_generator/resources/bin/kibana-docker b/src/dev/build/tasks/os_packages/docker_generator/resources/bin/kibana-docker index d9d0ce49971eb..2da2177b54e81 100755 --- a/src/dev/build/tasks/os_packages/docker_generator/resources/bin/kibana-docker +++ b/src/dev/build/tasks/os_packages/docker_generator/resources/bin/kibana-docker @@ -174,6 +174,8 @@ kibana_vars=( xpack.infra.sources.default.fields.timestamp xpack.infra.sources.default.logAlias xpack.infra.sources.default.metricAlias + xpack.ingestManager.fleet.tlsCheckDisabled + xpack.ingestManager.registryUrl xpack.license_management.enabled xpack.ml.enabled xpack.reporting.capture.browser.autoDownload diff --git a/src/dev/build/tasks/os_packages/docker_generator/run.js b/src/dev/build/tasks/os_packages/docker_generator/run.ts similarity index 90% rename from src/dev/build/tasks/os_packages/docker_generator/run.js rename to src/dev/build/tasks/os_packages/docker_generator/run.ts index b6dab43887f14..0a26729f3502d 100644 --- a/src/dev/build/tasks/os_packages/docker_generator/run.js +++ b/src/dev/build/tasks/os_packages/docker_generator/run.ts @@ -20,8 +20,12 @@ import { access, link, unlink, chmod } from 'fs'; import { resolve } from 'path'; import { promisify } from 'util'; -import { write, copyAll, mkdirp, exec } from '../../../lib'; + +import { ToolingLog } from '@kbn/dev-utils'; + +import { write, copyAll, mkdirp, exec, Config, Build } from '../../../lib'; import * as dockerTemplates from './templates'; +import { TemplateContext } from './template_context'; import { bundleDockerFiles } from './bundle_dockerfiles'; const accessAsync = promisify(access); @@ -29,7 +33,12 @@ const linkAsync = promisify(link); const unlinkAsync = promisify(unlink); const chmodAsync = promisify(chmod); -export async function runDockerGenerator(config, log, build, ubi = false) { +export async function runDockerGenerator( + config: Config, + log: ToolingLog, + build: Build, + ubi: boolean = false +) { // UBI var config const baseOSImage = ubi ? 'registry.access.redhat.com/ubi7/ubi-minimal:7.7' : 'centos:7'; const ubiVersionTag = 'ubi7'; @@ -52,7 +61,7 @@ export async function runDockerGenerator(config, log, build, ubi = false) { const dockerOutputDir = config.resolveFromTarget( `kibana${imageFlavor}${ubiImageFlavor}-${versionTag}-docker.tar.gz` ); - const scope = { + const scope: TemplateContext = { artifactTarball, imageFlavor, versionTag, @@ -112,10 +121,10 @@ export async function runDockerGenerator(config, log, build, ubi = false) { }); // Pack Dockerfiles and create a target for them - await bundleDockerFiles(config, log, build, scope); + await bundleDockerFiles(config, log, scope); } -export async function runDockerGeneratorForUBI(config, log, build) { +export async function runDockerGeneratorForUBI(config: Config, log: ToolingLog, build: Build) { // Only run ubi docker image build for default distribution if (build.isOss()) { return; diff --git a/src/dev/build/tasks/os_packages/docker_generator/template_context.ts b/src/dev/build/tasks/os_packages/docker_generator/template_context.ts new file mode 100644 index 0000000000000..115d4c6927c30 --- /dev/null +++ b/src/dev/build/tasks/os_packages/docker_generator/template_context.ts @@ -0,0 +1,33 @@ +/* + * 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. + */ + +export interface TemplateContext { + artifactTarball: string; + imageFlavor: string; + versionTag: string; + license: string; + artifactsDir: string; + imageTag: string; + dockerBuildDir: string; + dockerOutputDir: string; + baseOSImage: string; + ubiImageFlavor: string; + dockerBuildDate: string; + usePublicArtifact?: boolean; +} diff --git a/src/dev/build/tasks/os_packages/docker_generator/templates/build_docker_sh.template.js b/src/dev/build/tasks/os_packages/docker_generator/templates/build_docker_sh.template.ts similarity index 94% rename from src/dev/build/tasks/os_packages/docker_generator/templates/build_docker_sh.template.js rename to src/dev/build/tasks/os_packages/docker_generator/templates/build_docker_sh.template.ts index 4e8dfe188b867..ff6fcf7548d9d 100644 --- a/src/dev/build/tasks/os_packages/docker_generator/templates/build_docker_sh.template.js +++ b/src/dev/build/tasks/os_packages/docker_generator/templates/build_docker_sh.template.ts @@ -19,6 +19,8 @@ import dedent from 'dedent'; +import { TemplateContext } from '../template_context'; + function generator({ imageTag, imageFlavor, @@ -26,7 +28,7 @@ function generator({ dockerOutputDir, baseOSImage, ubiImageFlavor, -}) { +}: TemplateContext) { return dedent(` #!/usr/bin/env bash # diff --git a/src/dev/build/tasks/os_packages/docker_generator/templates/dockerfile.template.js b/src/dev/build/tasks/os_packages/docker_generator/templates/dockerfile.template.ts similarity index 98% rename from src/dev/build/tasks/os_packages/docker_generator/templates/dockerfile.template.js rename to src/dev/build/tasks/os_packages/docker_generator/templates/dockerfile.template.ts index 5832d00162b20..ea2f881768c8f 100755 --- a/src/dev/build/tasks/os_packages/docker_generator/templates/dockerfile.template.js +++ b/src/dev/build/tasks/os_packages/docker_generator/templates/dockerfile.template.ts @@ -19,6 +19,8 @@ import dedent from 'dedent'; +import { TemplateContext } from '../template_context'; + function generator({ artifactTarball, versionTag, @@ -27,7 +29,7 @@ function generator({ baseOSImage, ubiImageFlavor, dockerBuildDate, -}) { +}: TemplateContext) { const copyArtifactTarballInsideDockerOptFolder = () => { if (usePublicArtifact) { return `RUN cd /opt && curl --retry 8 -s -L -O https://artifacts.elastic.co/downloads/kibana/${artifactTarball} && cd -`; diff --git a/src/dev/build/tasks/os_packages/docker_generator/templates/index.js b/src/dev/build/tasks/os_packages/docker_generator/templates/index.ts similarity index 100% rename from src/dev/build/tasks/os_packages/docker_generator/templates/index.js rename to src/dev/build/tasks/os_packages/docker_generator/templates/index.ts diff --git a/src/dev/build/tasks/os_packages/docker_generator/templates/kibana_yml.template.js b/src/dev/build/tasks/os_packages/docker_generator/templates/kibana_yml.template.ts similarity index 91% rename from src/dev/build/tasks/os_packages/docker_generator/templates/kibana_yml.template.js rename to src/dev/build/tasks/os_packages/docker_generator/templates/kibana_yml.template.ts index c80f9334cfaeb..240ec6f4e9326 100644 --- a/src/dev/build/tasks/os_packages/docker_generator/templates/kibana_yml.template.js +++ b/src/dev/build/tasks/os_packages/docker_generator/templates/kibana_yml.template.ts @@ -19,7 +19,9 @@ import dedent from 'dedent'; -function generator({ imageFlavor }) { +import { TemplateContext } from '../template_context'; + +function generator({ imageFlavor }: TemplateContext) { return dedent(` # # ** THIS IS AN AUTO-GENERATED FILE ** diff --git a/src/dev/build/tasks/os_packages/package_scripts/post_install.sh b/src/dev/build/tasks/os_packages/package_scripts/post_install.sh index c49b291d1a0c9..1c679bdb40b59 100644 --- a/src/dev/build/tasks/os_packages/package_scripts/post_install.sh +++ b/src/dev/build/tasks/os_packages/package_scripts/post_install.sh @@ -31,6 +31,10 @@ case $1 in --ingroup "<%= group %>" --shell /bin/false "<%= user %>" fi + if [ -n "$2" ]; then + IS_UPGRADE=true + fi + set_access ;; abort-deconfigure|abort-upgrade|abort-remove) @@ -47,6 +51,10 @@ case $1 in -c "kibana service user" "<%= user %>" fi + if [ "$1" = "2" ]; then + IS_UPGRADE=true + fi + set_access ;; @@ -55,3 +63,9 @@ case $1 in exit 1 ;; esac + +if [ "$IS_UPGRADE" = "true" ]; then + if command -v systemctl >/dev/null; then + systemctl daemon-reload + fi +fi diff --git a/src/dev/build/tasks/os_packages/service_templates/sysv/etc/default/kibana b/src/dev/build/tasks/os_packages/service_templates/sysv/etc/default/kibana index 092dc6482fa1d..ee019d348ed97 100644 --- a/src/dev/build/tasks/os_packages/service_templates/sysv/etc/default/kibana +++ b/src/dev/build/tasks/os_packages/service_templates/sysv/etc/default/kibana @@ -12,4 +12,4 @@ KILL_ON_STOP_TIMEOUT=0 BABEL_CACHE_PATH="/var/lib/kibana/optimize/.babel_register_cache.json" -KIBANA_PATH_CONF="/etc/kibana" +KBN_PATH_CONF="/etc/kibana" diff --git a/src/dev/run_i18n_integrate.ts b/src/dev/run_i18n_integrate.ts index 25c3ea32783aa..c0b2302c91c54 100644 --- a/src/dev/run_i18n_integrate.ts +++ b/src/dev/run_i18n_integrate.ts @@ -111,6 +111,7 @@ run( const reporter = new ErrorReporter(); const messages: Map = new Map(); await list.run({ messages, reporter }); + process.exitCode = 0; } catch (error) { process.exitCode = 1; if (error instanceof ErrorReporter) { @@ -120,6 +121,7 @@ run( log.error(error); } } + process.exit(); }, { flags: { diff --git a/src/plugins/dashboard/public/application/dashboard_app_controller.tsx b/src/plugins/dashboard/public/application/dashboard_app_controller.tsx index 8138e1c7f4dfd..afccf8deaa217 100644 --- a/src/plugins/dashboard/public/application/dashboard_app_controller.tsx +++ b/src/plugins/dashboard/public/application/dashboard_app_controller.tsx @@ -25,8 +25,8 @@ import React, { useState, ReactElement } from 'react'; import ReactDOM from 'react-dom'; import angular from 'angular'; -import { Subscription } from 'rxjs'; -import { map } from 'rxjs/operators'; +import { Observable, pipe, Subscription } from 'rxjs'; +import { filter, map, mapTo, startWith, switchMap } from 'rxjs/operators'; import { History } from 'history'; import { SavedObjectSaveOpts } from 'src/plugins/saved_objects/public'; import { NavigationPublicPluginStart as NavigationStart } from 'src/plugins/navigation/public'; @@ -172,6 +172,10 @@ export class DashboardAppController { chrome.docTitle.change(dash.title); } + const incomingEmbeddable = embeddable + .getStateTransfer(scopedHistory()) + .getIncomingEmbeddablePackage(); + const dashboardStateManager = new DashboardStateManager({ savedDashboard: dash, hideWriteControls: dashboardConfig.getHideWriteControls(), @@ -253,11 +257,7 @@ export class DashboardAppController { navActions[TopNavIds.VISUALIZE](); }; - const updateIndexPatterns = (container?: DashboardContainer) => { - if (!container || isErrorEmbeddable(container)) { - return; - } - + function getDashboardIndexPatterns(container: DashboardContainer): IndexPattern[] { let panelIndexPatterns: IndexPattern[] = []; Object.values(container.getChildIds()).forEach((id) => { const embeddableInstance = container.getChild(id); @@ -267,19 +267,34 @@ export class DashboardAppController { panelIndexPatterns.push(...embeddableIndexPatterns); }); panelIndexPatterns = uniqBy(panelIndexPatterns, 'id'); + return panelIndexPatterns; + } - if (panelIndexPatterns && panelIndexPatterns.length > 0) { - $scope.$evalAsync(() => { - $scope.indexPatterns = panelIndexPatterns; - }); - } else { - indexPatterns.getDefault().then((defaultIndexPattern) => { - $scope.$evalAsync(() => { - $scope.indexPatterns = [defaultIndexPattern as IndexPattern]; - }); + const updateIndexPatternsOperator = pipe( + filter((container: DashboardContainer) => !!container && !isErrorEmbeddable(container)), + map(getDashboardIndexPatterns), + // using switchMap for previous task cancellation + switchMap((panelIndexPatterns: IndexPattern[]) => { + return new Observable((observer) => { + if (panelIndexPatterns && panelIndexPatterns.length > 0) { + $scope.$evalAsync(() => { + if (observer.closed) return; + $scope.indexPatterns = panelIndexPatterns; + observer.complete(); + }); + } else { + indexPatterns.getDefault().then((defaultIndexPattern) => { + if (observer.closed) return; + $scope.$evalAsync(() => { + if (observer.closed) return; + $scope.indexPatterns = [defaultIndexPattern as IndexPattern]; + observer.complete(); + }); + }); + } }); - } - }; + }) + ); const getEmptyScreenProps = ( shouldShowEditHelp: boolean, @@ -384,11 +399,17 @@ export class DashboardAppController { ) : null; }; - updateIndexPatterns(dashboardContainer); - - outputSubscription = dashboardContainer.getOutput$().subscribe(() => { - updateIndexPatterns(dashboardContainer); - }); + outputSubscription = new Subscription(); + outputSubscription.add( + dashboardContainer + .getOutput$() + .pipe( + mapTo(dashboardContainer), + startWith(dashboardContainer), // to trigger initial index pattern update + updateIndexPatternsOperator + ) + .subscribe() + ); inputSubscription = dashboardContainer.getInput$().subscribe(() => { let dirty = false; @@ -427,21 +448,24 @@ export class DashboardAppController { refreshDashboardContainer(); }); - const incomingState = embeddable - .getStateTransfer(scopedHistory()) - .getIncomingEmbeddablePackage(); - if (incomingState) { - if ('id' in incomingState) { - container.addOrUpdateEmbeddable(incomingState.type, { - savedObjectId: incomingState.id, - }); - } else if ('input' in incomingState) { - const input = incomingState.input; + if (incomingEmbeddable) { + if ('id' in incomingEmbeddable) { + container.addOrUpdateEmbeddable( + incomingEmbeddable.type, + { + savedObjectId: incomingEmbeddable.id, + } + ); + } else if ('input' in incomingEmbeddable) { + const input = incomingEmbeddable.input; delete input.id; const explicitInput = { savedVis: input, }; - container.addOrUpdateEmbeddable(incomingState.type, explicitInput); + container.addOrUpdateEmbeddable( + incomingEmbeddable.type, + explicitInput + ); } } } diff --git a/test/common/services/elasticsearch.ts b/test/common/services/elasticsearch.ts index 0436dc901292d..a01f9ff3c8da5 100644 --- a/test/common/services/elasticsearch.ts +++ b/test/common/services/elasticsearch.ts @@ -27,11 +27,18 @@ import { FtrProviderContext } from '../ftr_provider_context'; export function ElasticsearchProvider({ getService }: FtrProviderContext) { const config = getService('config'); - return new Client({ - ssl: { - ca: fs.readFileSync(CA_CERT_PATH, 'utf-8'), - }, - nodes: [formatUrl(config.get('servers.elasticsearch'))], - requestTimeout: config.get('timeouts.esRequestTimeout'), - }); + if (process.env.TEST_CLOUD) { + return new Client({ + nodes: [formatUrl(config.get('servers.elasticsearch'))], + requestTimeout: config.get('timeouts.esRequestTimeout'), + }); + } else { + return new Client({ + ssl: { + ca: fs.readFileSync(CA_CERT_PATH, 'utf-8'), + }, + nodes: [formatUrl(config.get('servers.elasticsearch'))], + requestTimeout: config.get('timeouts.esRequestTimeout'), + }); + } } diff --git a/test/functional/apps/visualize/input_control_vis/chained_controls.js b/test/functional/apps/visualize/input_control_vis/chained_controls.js index 179ffa5125a9a..89cca7dc7827e 100644 --- a/test/functional/apps/visualize/input_control_vis/chained_controls.js +++ b/test/functional/apps/visualize/input_control_vis/chained_controls.js @@ -34,6 +34,7 @@ export default function ({ getService, getPageObjects }) { await PageObjects.visualize.loadSavedVisualization('chained input control', { navigateToVisualize: false, }); + await testSubjects.waitForEnabled('addFilter', 10000); }); it('should disable child control when parent control is not set', async () => { diff --git a/test/functional/page_objects/timelion_page.ts b/test/functional/page_objects/timelion_page.ts index f025fc946bef1..23a9cc514a444 100644 --- a/test/functional/page_objects/timelion_page.ts +++ b/test/functional/page_objects/timelion_page.ts @@ -47,7 +47,7 @@ export function TimelionPageProvider({ getService, getPageObjects }: FtrProvider public async updateExpression(updates: string) { const input = await testSubjects.find('timelionExpressionTextArea'); await input.type(updates); - await PageObjects.common.sleep(500); + await PageObjects.common.sleep(1000); } public async getExpression() { @@ -60,7 +60,7 @@ export function TimelionPageProvider({ getService, getPageObjects }: FtrProvider return await Promise.all(elements.map(async (element) => await element.getVisibleText())); } - public async clickSuggestion(suggestionIndex = 0, waitTime = 500) { + public async clickSuggestion(suggestionIndex = 0, waitTime = 1000) { const elements = await testSubjects.findAll('timelionSuggestionListItem'); if (suggestionIndex > elements.length) { throw new Error( diff --git a/test/functional/page_objects/visual_builder_page.ts b/test/functional/page_objects/visual_builder_page.ts index 0db8cac0f0758..2771982fecdea 100644 --- a/test/functional/page_objects/visual_builder_page.ts +++ b/test/functional/page_objects/visual_builder_page.ts @@ -315,9 +315,9 @@ export function VisualBuilderPageProvider({ getService, getPageObjects }: FtrPro public async getRhythmChartLegendValue(nth = 0) { await PageObjects.visChart.waitForVisualizationRenderingStabilized(); - const metricValue = (await find.allByCssSelector(`.echLegendItem .echLegendItem__extra`))[ - nth - ]; + const metricValue = ( + await find.allByCssSelector(`.echLegendItem .echLegendItem__extra`, 20000) + )[nth]; await metricValue.moveMouseTo(); return await metricValue.getVisibleText(); } @@ -408,7 +408,7 @@ export function VisualBuilderPageProvider({ getService, getPageObjects }: FtrPro * @memberof VisualBuilderPage */ public async getViewTable(): Promise { - const tableView = await testSubjects.find('tableView'); + const tableView = await testSubjects.find('tableView', 20000); return await tableView.getVisibleText(); } diff --git a/test/functional/services/combo_box.ts b/test/functional/services/combo_box.ts index 60fea7ea86cf9..ac7a40361d065 100644 --- a/test/functional/services/combo_box.ts +++ b/test/functional/services/combo_box.ts @@ -90,7 +90,7 @@ export function ComboBoxProvider({ getService, getPageObjects }: FtrProviderCont await this.clickOption(options.clickWithMouse, selectOptions[0]); } else { // if it doesn't find the item which text starts with value, it will choose the first option - const firstOption = await find.byCssSelector('.euiFilterSelectItem'); + const firstOption = await find.byCssSelector('.euiFilterSelectItem', 5000); await this.clickOption(options.clickWithMouse, firstOption); } } else { diff --git a/vars/slackNotifications.groovy b/vars/slackNotifications.groovy index 2ffb420ecf3f4..30f86e6d6f0ad 100644 --- a/vars/slackNotifications.groovy +++ b/vars/slackNotifications.groovy @@ -13,12 +13,35 @@ def dividerBlock() { return [ type: "divider" ] } +// If a message is longer than the limit, split it up by '\n' into parts, and return as many parts as will fit within the limit +def shortenMessage(message, sizeLimit = 3000) { + if (message.size() <= sizeLimit) { + return message + } + + def truncatedMessage = "[...truncated...]" + + def parts = message.split("\n") + message = "" + + for(def part in parts) { + if ((message.size() + part.size() + truncatedMessage.size() + 1) > sizeLimit) { + break; + } + message += part+"\n" + } + + message += truncatedMessage + + return message.size() <= sizeLimit ? message : truncatedMessage +} + def markdownBlock(message) { return [ type: "section", text: [ type: "mrkdwn", - text: message, + text: shortenMessage(message, 3000), // 3000 is max text length for `section`s only ], ] } @@ -29,7 +52,7 @@ def contextBlock(message) { elements: [ [ type: 'mrkdwn', - text: message, + text: message, // Not sure what the size limit is here, I tried 10000s of characters and it still worked ] ] ] @@ -62,7 +85,7 @@ def getTestFailures() { def messages = [] messages << "*Test Failures*" - def list = failures.collect { + def list = failures.take(10).collect { def name = it .fullDisplayName .split(/\./, 2)[-1] @@ -73,7 +96,9 @@ def getTestFailures() { return "• <${it.url}|${name}>" }.join("\n") - return "*Test Failures*\n${list}" + + def moreText = failures.size() > 10 ? "\n• ...and ${failures.size()-10} more" : "" + return "*Test Failures*\n${list}${moreText}" } def getDefaultDisplayName() { @@ -98,6 +123,10 @@ def getStatusIcon() { return ':broken_heart:' } +def getBackupMessage(config) { + return "${getStatusIcon()} ${config.title}\n\nFirst attempt at sending this notification failed. Please check the build." +} + def sendFailedBuild(Map params = [:]) { def config = [ channel: '#kibana-operations-alerts', @@ -117,7 +146,7 @@ def sendFailedBuild(Map params = [:]) { blocks << dividerBlock() blocks << config.context - slackSend( + def resp = slackSend( channel: config.channel, username: config.username, iconEmoji: config.icon, @@ -125,6 +154,17 @@ def sendFailedBuild(Map params = [:]) { message: message, blocks: blocks ) + + if (!resp) { + slackSend( + channel: config.channel, + username: config.username, + iconEmoji: config.icon, + color: config.color, + message: message, + blocks: [markdownBlock(getBackupMessage(config))] + ) + } } def onFailure(Map options = [:]) { diff --git a/x-pack/package.json b/x-pack/package.json index 0868d21b1bc6d..5df62df003426 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -133,7 +133,7 @@ "cheerio": "0.22.0", "commander": "3.0.2", "copy-webpack-plugin": "^6.0.2", - "cypress": "4.5.0", + "cypress": "4.11.0", "cypress-multi-reporters": "^1.2.3", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.2", diff --git a/x-pack/plugins/alerts/server/saved_objects/index.ts b/x-pack/plugins/alerts/server/saved_objects/index.ts index 06ce8d673e6b7..c98d9bcbd9ae5 100644 --- a/x-pack/plugins/alerts/server/saved_objects/index.ts +++ b/x-pack/plugins/alerts/server/saved_objects/index.ts @@ -6,7 +6,6 @@ import { SavedObjectsServiceSetup } from 'kibana/server'; import mappings from './mappings.json'; -import { getMigrations } from './migrations'; import { EncryptedSavedObjectsPluginSetup } from '../../../encrypted_saved_objects/server'; export function setupSavedObjects( @@ -17,7 +16,6 @@ export function setupSavedObjects( name: 'alert', hidden: true, namespaceType: 'single', - migrations: getMigrations(encryptedSavedObjects), mappings: mappings.alert, }); diff --git a/x-pack/plugins/alerts/server/saved_objects/migrations.test.ts b/x-pack/plugins/alerts/server/saved_objects/migrations.test.ts deleted file mode 100644 index 38cda5a9a0f7c..0000000000000 --- a/x-pack/plugins/alerts/server/saved_objects/migrations.test.ts +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -import uuid from 'uuid'; -import { getMigrations } from './migrations'; -import { RawAlert } from '../types'; -import { SavedObjectUnsanitizedDoc } from 'kibana/server'; -import { encryptedSavedObjectsMock } from '../../../encrypted_saved_objects/server/mocks'; -import { migrationMocks } from 'src/core/server/mocks'; - -const { log } = migrationMocks.createContext(); -const encryptedSavedObjectsSetup = encryptedSavedObjectsMock.createSetup(); - -describe('7.9.0', () => { - beforeEach(() => { - jest.resetAllMocks(); - encryptedSavedObjectsSetup.createMigration.mockImplementation( - (shouldMigrateWhenPredicate, migration) => migration - ); - }); - - test('changes nothing on alerts by other plugins', () => { - const migration790 = getMigrations(encryptedSavedObjectsSetup)['7.9.0']; - const alert = getMockData({}); - expect(migration790(alert, { log })).toMatchObject(alert); - - expect(encryptedSavedObjectsSetup.createMigration).toHaveBeenCalledWith( - expect.any(Function), - expect.any(Function) - ); - }); - - test('migrates the consumer for alerting', () => { - const migration790 = getMigrations(encryptedSavedObjectsSetup)['7.9.0']; - const alert = getMockData({ - consumer: 'alerting', - }); - expect(migration790(alert, { log })).toMatchObject({ - ...alert, - attributes: { - ...alert.attributes, - consumer: 'alerts', - }, - }); - }); -}); - -function getMockData( - overwrites: Record = {} -): SavedObjectUnsanitizedDoc { - return { - attributes: { - enabled: true, - name: 'abc', - tags: ['foo'], - alertTypeId: '123', - consumer: 'bar', - apiKey: '', - apiKeyOwner: '', - schedule: { interval: '10s' }, - throttle: null, - params: { - bar: true, - }, - muteAll: false, - mutedInstanceIds: [], - createdBy: new Date().toISOString(), - updatedBy: new Date().toISOString(), - createdAt: new Date().toISOString(), - actions: [ - { - group: 'default', - actionRef: '1', - actionTypeId: '1', - params: { - foo: true, - }, - }, - ], - ...overwrites, - }, - id: uuid.v4(), - type: 'alert', - }; -} diff --git a/x-pack/plugins/alerts/server/saved_objects/migrations.ts b/x-pack/plugins/alerts/server/saved_objects/migrations.ts deleted file mode 100644 index 142102dd711c7..0000000000000 --- a/x-pack/plugins/alerts/server/saved_objects/migrations.ts +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -import { - SavedObjectMigrationMap, - SavedObjectUnsanitizedDoc, - SavedObjectMigrationFn, -} from '../../../../../src/core/server'; -import { RawAlert } from '../types'; -import { EncryptedSavedObjectsPluginSetup } from '../../../encrypted_saved_objects/server'; - -export function getMigrations( - encryptedSavedObjects: EncryptedSavedObjectsPluginSetup -): SavedObjectMigrationMap { - return { - '7.9.0': changeAlertingConsumer(encryptedSavedObjects), - }; -} - -/** - * In v7.9.0 we changed the Alerting plugin so it uses the `consumer` value of `alerts` - * prior to that we were using `alerting` and we need to keep these in sync - */ -function changeAlertingConsumer( - encryptedSavedObjects: EncryptedSavedObjectsPluginSetup -): SavedObjectMigrationFn { - const consumerMigration = new Map(); - consumerMigration.set('alerting', 'alerts'); - - return encryptedSavedObjects.createMigration( - function shouldBeMigrated(doc): doc is SavedObjectUnsanitizedDoc { - return consumerMigration.has(doc.attributes.consumer); - }, - (doc: SavedObjectUnsanitizedDoc): SavedObjectUnsanitizedDoc => { - const { - attributes: { consumer }, - } = doc; - return { - ...doc, - attributes: { - ...doc.attributes, - consumer: consumerMigration.get(consumer) ?? consumer, - }, - }; - } - ); -} diff --git a/x-pack/plugins/apm/public/components/app/ServiceMap/Popover/Buttons.test.tsx b/x-pack/plugins/apm/public/components/app/ServiceMap/Popover/Buttons.test.tsx new file mode 100644 index 0000000000000..4146266b17916 --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/ServiceMap/Popover/Buttons.test.tsx @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; +import { Buttons } from './Buttons'; +import { render } from '@testing-library/react'; + +describe('Popover Buttons', () => { + it('renders', () => { + expect(() => + render() + ).not.toThrowError(); + }); + + it('handles focus click', async () => { + const onFocusClick = jest.fn(); + const result = render( + + ); + const focusButton = await result.findByText('Focus map'); + + focusButton.click(); + + expect(onFocusClick).toHaveBeenCalledTimes(1); + }); +}); diff --git a/x-pack/plugins/apm/public/components/app/ServiceMap/Popover/Buttons.tsx b/x-pack/plugins/apm/public/components/app/ServiceMap/Popover/Buttons.tsx index d67447e04ef81..cb33fb32f3b0d 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceMap/Popover/Buttons.tsx +++ b/x-pack/plugins/apm/public/components/app/ServiceMap/Popover/Buttons.tsx @@ -22,7 +22,12 @@ export function Buttons({ onFocusClick = () => {}, selectedNodeServiceName, }: ButtonsProps) { - const urlParams = useUrlParams().urlParams as APMQueryParams; + // The params may contain the service name. We want to use the selected node's + // service name in the button URLs, so make a copy and set the + // `serviceName` property. + const urlParams = { ...useUrlParams().urlParams } as APMQueryParams; + urlParams.serviceName = selectedNodeServiceName; + const detailsUrl = getAPMHref( `/services/${selectedNodeServiceName}/transactions`, '', diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/empty_states/error_state.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/empty_states/error_state.tsx index 7ac02082ee75c..346e70d32f7b1 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/empty_states/error_state.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/empty_states/error_state.tsx @@ -21,7 +21,7 @@ export const ErrorState: React.FC = () => { - + diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview_header/engine_overview_header.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview_header/engine_overview_header.test.tsx index 2e49540270ef0..7d2106f2a56f7 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview_header/engine_overview_header.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview_header/engine_overview_header.test.tsx @@ -30,12 +30,4 @@ describe('EngineOverviewHeader', () => { button.simulate('click'); expect(sendTelemetry).toHaveBeenCalled(); }); - - it('renders a disabled button when isButtonDisabled is true', () => { - const wrapper = shallow(); - const button = wrapper.find('[data-test-subj="launchButton"]'); - - expect(button.prop('isDisabled')).toBe(true); - expect(button.prop('href')).toBeUndefined(); - }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview_header/engine_overview_header.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview_header/engine_overview_header.tsx index 9aafa8ec0380c..cc480d241ad50 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview_header/engine_overview_header.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview_header/engine_overview_header.tsx @@ -18,34 +18,23 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { sendTelemetry } from '../../../shared/telemetry'; import { KibanaContext, IKibanaContext } from '../../../index'; -interface IEngineOverviewHeaderProps { - isButtonDisabled?: boolean; -} - -export const EngineOverviewHeader: React.FC = ({ - isButtonDisabled, -}) => { +export const EngineOverviewHeader: React.FC = () => { const { enterpriseSearchUrl, http } = useContext(KibanaContext) as IKibanaContext; const buttonProps = { fill: true, iconType: 'popout', 'data-test-subj': 'launchButton', - } as EuiButtonProps & EuiLinkProps; - - if (isButtonDisabled) { - buttonProps.isDisabled = true; - } else { - buttonProps.href = `${enterpriseSearchUrl}/as`; - buttonProps.target = '_blank'; - buttonProps.onClick = () => + href: `${enterpriseSearchUrl}/as`, + target: '_blank', + onClick: () => sendTelemetry({ http, product: 'app_search', action: 'clicked', metric: 'header_launch_button', - }); - } + }), + } as EuiButtonProps & EuiLinkProps; return ( diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.scss b/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.scss new file mode 100644 index 0000000000000..0d9926ab147bf --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.scss @@ -0,0 +1,12 @@ +.troubleshootingSteps { + text-align: left; + + li { + margin: $euiSizeS auto; + } + + ul, + ol { + margin-bottom: 0; + } +} diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.tsx index 81455cea0b497..ccd5beff66e70 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.tsx @@ -11,6 +11,8 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { EuiButton } from '../react_router_helpers'; import { KibanaContext, IKibanaContext } from '../../index'; +import './error_state_prompt.scss'; + export const ErrorStatePrompt: React.FC = () => { const { enterpriseSearchUrl } = useContext(KibanaContext) as IKibanaContext; @@ -38,7 +40,7 @@ export const ErrorStatePrompt: React.FC = () => { }} />

-
    +
    1. { defaultMessage="Confirm that the Enterprise Search server is responsive." />
    2. +
    3. + +
        +
      • + +
      • +
      • + +
      • +
      +
    4. ; +const logIndexStatusRT = rt.keyof({ + missing: null, + empty: null, + available: null, +}); + +export type LogIndexStatus = rt.TypeOf; + const logSourceStatusRT = rt.strict({ logIndexFields: rt.array(logIndexFieldRT), - logIndicesExist: rt.boolean, + logIndexStatus: logIndexStatusRT, }); export type LogSourceStatus = rt.TypeOf; diff --git a/x-pack/plugins/infra/common/http_api/snapshot_api.ts b/x-pack/plugins/infra/common/http_api/snapshot_api.ts index 9ddbcb17089f3..11cb57238f917 100644 --- a/x-pack/plugins/infra/common/http_api/snapshot_api.ts +++ b/x-pack/plugins/infra/common/http_api/snapshot_api.ts @@ -107,6 +107,7 @@ export const SnapshotRequestRT = rt.intersection([ region: rt.string, filterQuery: rt.union([rt.string, rt.null]), includeTimeseries: rt.boolean, + overrideCompositeSize: rt.number, }), ]); diff --git a/x-pack/plugins/infra/public/alerting/inventory/components/expression.tsx b/x-pack/plugins/infra/public/alerting/inventory/components/expression.tsx index 8d36262b55792..583cbe18ee9db 100644 --- a/x-pack/plugins/infra/public/alerting/inventory/components/expression.tsx +++ b/x-pack/plugins/infra/public/alerting/inventory/components/expression.tsx @@ -364,7 +364,7 @@ export const Expressions: React.FC = (props) => { ({ const renderDeleteAction = useCallback( (item: SavedView) => { + if (item.id === '0') { + return <>; + } + return ( (props: Props) { /> - + (props: Props) { {currentView ? currentView.name : i18n.translate('xpack.infra.savedView.unknownView', { - defaultMessage: 'Unknown', + defaultMessage: 'No view seleted', })} diff --git a/x-pack/plugins/infra/public/containers/saved_view/saved_view.tsx b/x-pack/plugins/infra/public/containers/saved_view/saved_view.tsx index 58fecdd54e303..3f38d8b97a296 100644 --- a/x-pack/plugins/infra/public/containers/saved_view/saved_view.tsx +++ b/x-pack/plugins/infra/public/containers/saved_view/saved_view.tsx @@ -50,7 +50,7 @@ export const useSavedView = (props: Props) => { const { data, loading, find, error: errorOnFind, hasView } = useFindSavedObject< SavedViewSavedObject >(viewType); - + const [shouldLoadDefault] = useState(props.shouldLoadDefault); const [currentView, setCurrentView] = useState | null>(null); const [loadingDefaultView, setLoadingDefaultView] = useState(null); const { create, error: errorOnCreate, data: createdViewData, createdId } = useCreateSavedObject( @@ -211,8 +211,6 @@ export const useSavedView = (props: Props) => { }, [setCurrentView, defaultViewId, defaultViewState]); useEffect(() => { - const shouldLoadDefault = props.shouldLoadDefault; - if (loadingDefaultView || currentView || !shouldLoadDefault) { return; } @@ -225,7 +223,7 @@ export const useSavedView = (props: Props) => { } }, [ loadDefaultView, - props.shouldLoadDefault, + shouldLoadDefault, setDefault, loadingDefaultView, currentView, @@ -246,7 +244,7 @@ export const useSavedView = (props: Props) => { errorOnUpdate, errorOnFind, errorOnCreate: createError, - shouldLoadDefault: props.shouldLoadDefault, + shouldLoadDefault, makeDefault, sourceIsLoading, deleteView, diff --git a/x-pack/plugins/infra/public/metrics_overview_fetchers.test.ts b/x-pack/plugins/infra/public/metrics_overview_fetchers.test.ts index 88bc426e9a0f7..135b4ea9a5335 100644 --- a/x-pack/plugins/infra/public/metrics_overview_fetchers.test.ts +++ b/x-pack/plugins/infra/public/metrics_overview_fetchers.test.ts @@ -75,6 +75,7 @@ describe('Metrics UI Observability Homepage Functions', () => { groupBy: [], nodeType: 'host', includeTimeseries: true, + overrideCompositeSize: 5, timerange: { from: startTime.valueOf(), to: endTime.valueOf(), diff --git a/x-pack/plugins/infra/public/metrics_overview_fetchers.ts b/x-pack/plugins/infra/public/metrics_overview_fetchers.ts index 4eaf903e17608..79e0850635138 100644 --- a/x-pack/plugins/infra/public/metrics_overview_fetchers.ts +++ b/x-pack/plugins/infra/public/metrics_overview_fetchers.ts @@ -87,6 +87,7 @@ export const createMetricsFetchData = ( groupBy: [], nodeType: 'host', includeTimeseries: true, + overrideCompositeSize: 5, timerange: { from: start, to: end, diff --git a/x-pack/plugins/infra/public/pages/logs/stream/page_content.tsx b/x-pack/plugins/infra/public/pages/logs/stream/page_content.tsx index b2a4ce65ab2b6..fe362dcf8da8c 100644 --- a/x-pack/plugins/infra/public/pages/logs/stream/page_content.tsx +++ b/x-pack/plugins/infra/public/pages/logs/stream/page_content.tsx @@ -25,7 +25,7 @@ export const StreamPageContent: React.FunctionComponent = () => { return ; } else if (hasFailedLoadingSource) { return ; - } else if (sourceStatus?.logIndicesExist) { + } else if (sourceStatus?.logIndexStatus !== 'missing') { return ; } else { return ; diff --git a/x-pack/plugins/infra/public/pages/logs/stream/page_providers.tsx b/x-pack/plugins/infra/public/pages/logs/stream/page_providers.tsx index 82c21f663bc96..1a1cc13576556 100644 --- a/x-pack/plugins/infra/public/pages/logs/stream/page_providers.tsx +++ b/x-pack/plugins/infra/public/pages/logs/stream/page_providers.tsx @@ -107,7 +107,7 @@ export const LogsPageProviders: React.FunctionComponent = ({ children }) => { const { sourceStatus } = useLogSourceContext(); // The providers assume the source is loaded, so short-circuit them otherwise - if (!sourceStatus?.logIndicesExist) { + if (sourceStatus?.logIndexStatus === 'missing') { return <>{children}; } diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/layout.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/layout.tsx index fddd92128708a..ad92c054ee459 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/layout.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/layout.tsx @@ -55,7 +55,8 @@ export const Layout = () => { sourceId, currentTime, accountId, - region + region, + false ); const options = { diff --git a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/index.tsx b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/index.tsx index cd875ae54071c..20efca79650a1 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/index.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/index.tsx @@ -57,7 +57,8 @@ export const MetricsExplorerPage = ({ source, derivedIndexPattern }: MetricsExpl // load metrics explorer data after default view loaded, unless we're not loading a view loadData(); } - }, [loadData, currentView, shouldLoadDefault]); + /* eslint-disable-next-line react-hooks/exhaustive-deps */ + }, [loadData, shouldLoadDefault]); return ( diff --git a/x-pack/plugins/infra/public/utils/logs_overview_fetchers.ts b/x-pack/plugins/infra/public/utils/logs_overview_fetchers.ts index 53f7e00a3354c..3716e618068a3 100644 --- a/x-pack/plugins/infra/public/utils/logs_overview_fetchers.ts +++ b/x-pack/plugins/infra/public/utils/logs_overview_fetchers.ts @@ -43,7 +43,7 @@ export function getLogsHasDataFetcher( return async () => { const [core] = await getStartServices(); const sourceStatus = await callFetchLogSourceStatusAPI(DEFAULT_SOURCE_ID, core.http.fetch); - return sourceStatus.data.logIndicesExist; + return sourceStatus.data.logIndexStatus === 'available'; }; } diff --git a/x-pack/plugins/infra/public/utils/logs_overview_fetches.test.ts b/x-pack/plugins/infra/public/utils/logs_overview_fetches.test.ts index 6f9e41fbd08f3..a2b4e162756e3 100644 --- a/x-pack/plugins/infra/public/utils/logs_overview_fetches.test.ts +++ b/x-pack/plugins/infra/public/utils/logs_overview_fetches.test.ts @@ -3,17 +3,18 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ + +import { CoreStart } from 'kibana/public'; import { coreMock } from 'src/core/public/mocks'; import { dataPluginMock } from 'src/plugins/data/public/mocks'; -import { CoreStart } from 'kibana/public'; -import { getLogsHasDataFetcher } from './logs_overview_fetchers'; -import { InfraClientStartDeps, InfraClientStartExports } from '../types'; import { callFetchLogSourceStatusAPI } from '../containers/logs/log_source/api/fetch_log_source_status'; +import { InfraClientStartDeps, InfraClientStartExports } from '../types'; +import { getLogsHasDataFetcher } from './logs_overview_fetchers'; -// Note -// Calls to `.mock*` functions will fail the typecheck because how jest does the mocking. -// The calls will be preluded with a `@ts-expect-error` jest.mock('../containers/logs/log_source/api/fetch_log_source_status'); +const mockedCallFetchLogSourceStatusAPI = callFetchLogSourceStatusAPI as jest.MockedFunction< + typeof callFetchLogSourceStatusAPI +>; function setup() { const core = coreMock.createStart(); @@ -33,36 +34,47 @@ function setup() { describe('Logs UI Observability Homepage Functions', () => { describe('getLogsHasDataFetcher()', () => { beforeEach(() => { - // @ts-expect-error - callFetchLogSourceStatusAPI.mockReset(); + mockedCallFetchLogSourceStatusAPI.mockReset(); }); - it('should return true when some index is present', async () => { + it('should return true when non-empty indices exist', async () => { const { mockedGetStartServices } = setup(); - // @ts-expect-error - callFetchLogSourceStatusAPI.mockResolvedValue({ - data: { logIndexFields: [], logIndicesExist: true }, + mockedCallFetchLogSourceStatusAPI.mockResolvedValue({ + data: { logIndexFields: [], logIndexStatus: 'available' }, }); const hasData = getLogsHasDataFetcher(mockedGetStartServices); const response = await hasData(); - expect(callFetchLogSourceStatusAPI).toHaveBeenCalledTimes(1); + expect(mockedCallFetchLogSourceStatusAPI).toHaveBeenCalledTimes(1); expect(response).toBe(true); }); - it('should return false when no index is present', async () => { + it('should return false when only empty indices exist', async () => { + const { mockedGetStartServices } = setup(); + + mockedCallFetchLogSourceStatusAPI.mockResolvedValue({ + data: { logIndexFields: [], logIndexStatus: 'empty' }, + }); + + const hasData = getLogsHasDataFetcher(mockedGetStartServices); + const response = await hasData(); + + expect(mockedCallFetchLogSourceStatusAPI).toHaveBeenCalledTimes(1); + expect(response).toBe(false); + }); + + it('should return false when no index exists', async () => { const { mockedGetStartServices } = setup(); - // @ts-expect-error - callFetchLogSourceStatusAPI.mockResolvedValue({ - data: { logIndexFields: [], logIndicesExist: false }, + mockedCallFetchLogSourceStatusAPI.mockResolvedValue({ + data: { logIndexFields: [], logIndexStatus: 'missing' }, }); const hasData = getLogsHasDataFetcher(mockedGetStartServices); const response = await hasData(); - expect(callFetchLogSourceStatusAPI).toHaveBeenCalledTimes(1); + expect(mockedCallFetchLogSourceStatusAPI).toHaveBeenCalledTimes(1); expect(response).toBe(false); }); }); diff --git a/x-pack/plugins/infra/server/features.ts b/x-pack/plugins/infra/server/features.ts index fa228e03194a9..9393bfc1bdbf1 100644 --- a/x-pack/plugins/infra/server/features.ts +++ b/x-pack/plugins/infra/server/features.ts @@ -14,11 +14,11 @@ export const METRICS_FEATURE = { order: 700, icon: 'metricsApp', navLinkId: 'metrics', - app: ['infra', 'kibana'], + app: ['infra', 'metrics', 'kibana'], catalogue: ['infraops'], privileges: { all: { - app: ['infra', 'kibana'], + app: ['infra', 'metrics', 'kibana'], catalogue: ['infraops'], api: ['infra', 'actions-read', 'actions-all', 'alerting-read', 'alerting-all'], savedObject: { @@ -38,7 +38,7 @@ export const METRICS_FEATURE = { ], }, read: { - app: ['infra', 'kibana'], + app: ['infra', 'metrics', 'kibana'], catalogue: ['infraops'], api: ['infra', 'actions-read', 'actions-all', 'alerting-read', 'alerting-all'], savedObject: { @@ -66,11 +66,11 @@ export const LOGS_FEATURE = { order: 800, icon: 'logsApp', navLinkId: 'logs', - app: ['infra', 'kibana'], + app: ['infra', 'logs', 'kibana'], catalogue: ['infralogging'], privileges: { all: { - app: ['infra', 'kibana'], + app: ['infra', 'logs', 'kibana'], catalogue: ['infralogging'], api: ['infra'], savedObject: { @@ -80,7 +80,7 @@ export const LOGS_FEATURE = { ui: ['show', 'configureSource', 'save'], }, read: { - app: ['infra', 'kibana'], + app: ['infra', 'logs', 'kibana'], catalogue: ['infralogging'], api: ['infra'], savedObject: { diff --git a/x-pack/plugins/infra/server/graphql/source_status/resolvers.ts b/x-pack/plugins/infra/server/graphql/source_status/resolvers.ts index 848d66058e64c..bd92dd0f7da8b 100644 --- a/x-pack/plugins/infra/server/graphql/source_status/resolvers.ts +++ b/x-pack/plugins/infra/server/graphql/source_status/resolvers.ts @@ -73,7 +73,7 @@ export const createSourceStatusResolvers = (libs: { return await libs.sourceStatus.hasLogAlias(req, source.id); }, async logIndicesExist(source, args, { req }) { - return await libs.sourceStatus.hasLogIndices(req, source.id); + return (await libs.sourceStatus.getLogIndexStatus(req, source.id)) !== 'missing'; }, async logIndices(source, args, { req }) { return await libs.sourceStatus.getLogIndexNames(req, source.id); diff --git a/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts b/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts index b1e3ae45f8a0a..b6f121ddb2f8d 100644 --- a/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts +++ b/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts @@ -38,6 +38,7 @@ export interface CallWithRequestParams extends GenericParams { fields?: string | string[]; path?: string; query?: string | object; + track_total_hits?: boolean | number; } export type InfraResponse = Lifecycle.ReturnValue; diff --git a/x-pack/plugins/infra/server/lib/adapters/source_status/elasticsearch_source_status_adapter.ts b/x-pack/plugins/infra/server/lib/adapters/source_status/elasticsearch_source_status_adapter.ts index 9bc58604f12a5..2a61e64c94fcd 100644 --- a/x-pack/plugins/infra/server/lib/adapters/source_status/elasticsearch_source_status_adapter.ts +++ b/x-pack/plugins/infra/server/lib/adapters/source_status/elasticsearch_source_status_adapter.ts @@ -5,7 +5,7 @@ */ import { RequestHandlerContext } from 'src/core/server'; -import { InfraSourceStatusAdapter } from '../../source_status'; +import { InfraSourceStatusAdapter, SourceIndexStatus } from '../../source_status'; import { InfraDatabaseGetIndicesResponse } from '../framework'; import { KibanaFramework } from '../framework/kibana_framework_adapter'; @@ -40,7 +40,10 @@ export class InfraElasticsearchSourceStatusAdapter implements InfraSourceStatusA }); } - public async hasIndices(requestContext: RequestHandlerContext, indexNames: string) { + public async getIndexStatus( + requestContext: RequestHandlerContext, + indexNames: string + ): Promise { return await this.framework .callWithRequest(requestContext, 'search', { ignore_unavailable: true, @@ -48,12 +51,23 @@ export class InfraElasticsearchSourceStatusAdapter implements InfraSourceStatusA index: indexNames, size: 0, terminate_after: 1, + track_total_hits: 1, }) .then( - (response) => response._shards.total > 0, + (response) => { + if (response._shards.total <= 0) { + return 'missing'; + } + + if (response.hits.total.value > 0) { + return 'available'; + } + + return 'empty'; + }, (err) => { if (err.status === 404) { - return false; + return 'missing'; } throw err; } diff --git a/x-pack/plugins/infra/server/lib/alerting/common/messages.ts b/x-pack/plugins/infra/server/lib/alerting/common/messages.ts index 4add0ee9af5d3..18b1460d643d5 100644 --- a/x-pack/plugins/infra/server/lib/alerting/common/messages.ts +++ b/x-pack/plugins/infra/server/lib/alerting/common/messages.ts @@ -29,6 +29,9 @@ export const stateToAlertMessage = { }), }; +const toNumber = (value: number | string) => + typeof value === 'string' ? parseFloat(value) : value; + const comparatorToI18n = (comparator: Comparator, threshold: number[], currentValue: number) => { const gtText = i18n.translate('xpack.infra.metrics.alerting.threshold.gtComparator', { defaultMessage: 'greater than', @@ -54,10 +57,11 @@ const comparatorToI18n = (comparator: Comparator, threshold: number[], currentVa case Comparator.LT: return ltText; case Comparator.GT_OR_EQ: - case Comparator.LT_OR_EQ: + case Comparator.LT_OR_EQ: { if (threshold[0] === currentValue) return eqText; else if (threshold[0] < currentValue) return ltText; return gtText; + } } }; @@ -88,7 +92,7 @@ const recoveredComparatorToI18n = ( } }; -const thresholdToI18n = ([a, b]: number[]) => { +const thresholdToI18n = ([a, b]: Array) => { if (typeof b === 'undefined') return a; return i18n.translate('xpack.infra.metrics.alerting.threshold.thresholdRange', { defaultMessage: '{a} and {b}', @@ -99,15 +103,15 @@ const thresholdToI18n = ([a, b]: number[]) => { export const buildFiredAlertReason: (alertResult: { metric: string; comparator: Comparator; - threshold: number[]; - currentValue: number; + threshold: Array; + currentValue: number | string; }) => string = ({ metric, comparator, threshold, currentValue }) => i18n.translate('xpack.infra.metrics.alerting.threshold.firedAlertReason', { defaultMessage: '{metric} is {comparator} a threshold of {threshold} (current value is {currentValue})', values: { metric, - comparator: comparatorToI18n(comparator, threshold, currentValue), + comparator: comparatorToI18n(comparator, threshold.map(toNumber), toNumber(currentValue)), threshold: thresholdToI18n(threshold), currentValue, }, @@ -116,15 +120,19 @@ export const buildFiredAlertReason: (alertResult: { export const buildRecoveredAlertReason: (alertResult: { metric: string; comparator: Comparator; - threshold: number[]; - currentValue: number; + threshold: Array; + currentValue: number | string; }) => string = ({ metric, comparator, threshold, currentValue }) => i18n.translate('xpack.infra.metrics.alerting.threshold.recoveredAlertReason', { defaultMessage: '{metric} is now {comparator} a threshold of {threshold} (current value is {currentValue})', values: { metric, - comparator: recoveredComparatorToI18n(comparator, threshold, currentValue), + comparator: recoveredComparatorToI18n( + comparator, + threshold.map(toNumber), + toNumber(currentValue) + ), threshold: thresholdToI18n(threshold), currentValue, }, @@ -150,3 +158,56 @@ export const buildErrorAlertReason = (metric: string) => metric, }, }); + +export const groupActionVariableDescription = i18n.translate( + 'xpack.infra.metrics.alerting.groupActionVariableDescription', + { + defaultMessage: 'Name of the group reporting data', + } +); + +export const alertStateActionVariableDescription = i18n.translate( + 'xpack.infra.metrics.alerting.alertStateActionVariableDescription', + { + defaultMessage: 'Current state of the alert', + } +); + +export const reasonActionVariableDescription = i18n.translate( + 'xpack.infra.metrics.alerting.reasonActionVariableDescription', + { + defaultMessage: + 'A description of why the alert is in this state, including which metrics have crossed which thresholds', + } +); + +export const timestampActionVariableDescription = i18n.translate( + 'xpack.infra.metrics.alerting.timestampDescription', + { + defaultMessage: 'A timestamp of when the alert was detected.', + } +); + +export const valueActionVariableDescription = i18n.translate( + 'xpack.infra.metrics.alerting.valueActionVariableDescription', + { + defaultMessage: + 'The value of the metric in the specified condition. Usage: (ctx.value.condition0, ctx.value.condition1, etc...).', + } +); + +export const metricActionVariableDescription = i18n.translate( + 'xpack.infra.metrics.alerting.metricActionVariableDescription', + { + defaultMessage: + 'The metric name in the specified condition. Usage: (ctx.metric.condition0, ctx.metric.condition1, etc...).', + } +); + +export const thresholdActionVariableDescription = i18n.translate( + 'xpack.infra.metrics.alerting.thresholdActionVariableDescription', + { + defaultMessage: + 'The threshold value of the metric for the specified condition. Usage: (ctx.threshold.condition0, ctx.threshold.condition1, etc...).', + } +); diff --git a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/evaluate_condition.ts b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/evaluate_condition.ts index c991e482a62e5..5c31c78b10fa9 100644 --- a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/evaluate_condition.ts +++ b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/evaluate_condition.ts @@ -112,6 +112,8 @@ const getData = async ( try { const { nodes } = await snapshot.getNodes(esClient, options); + if (!nodes.length) return { [UNGROUPED_FACTORY_KEY]: null }; // No Data state + return nodes.reduce((acc, n) => { const nodePathItem = last(n.path) as any; const m = first(n.metrics); diff --git a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts index 0a3910f2c5d7c..60eee49a5010d 100644 --- a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts +++ b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts @@ -79,6 +79,7 @@ export const createInventoryMetricThresholdExecutor = (libs: InfraBackendLibs) = const resultWithVerboseMetricName = { ...result[item], metric: toMetricOpt(result[item].metric)?.text || result[item].metric, + currentValue: formatMetric(result[item].metric, result[item].currentValue), }; return buildFiredAlertReason(resultWithVerboseMetricName); }) diff --git a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/register_inventory_metric_threshold_alert_type.ts b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/register_inventory_metric_threshold_alert_type.ts index 85b38f48d9f22..5e1c0f0962ede 100644 --- a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/register_inventory_metric_threshold_alert_type.ts +++ b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/register_inventory_metric_threshold_alert_type.ts @@ -3,7 +3,6 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { i18n } from '@kbn/i18n'; import { schema } from '@kbn/config-schema'; import { createInventoryMetricThresholdExecutor, @@ -12,6 +11,15 @@ import { import { METRIC_INVENTORY_THRESHOLD_ALERT_TYPE_ID, Comparator } from './types'; import { InfraBackendLibs } from '../../infra_types'; import { oneOfLiterals, validateIsStringElasticsearchJSONFilter } from '../common/utils'; +import { + groupActionVariableDescription, + alertStateActionVariableDescription, + reasonActionVariableDescription, + timestampActionVariableDescription, + valueActionVariableDescription, + metricActionVariableDescription, + thresholdActionVariableDescription, +} from '../common/messages'; const condition = schema.object({ threshold: schema.arrayOf(schema.number()), @@ -44,45 +52,13 @@ export const registerMetricInventoryThresholdAlertType = (libs: InfraBackendLibs executor: createInventoryMetricThresholdExecutor(libs), actionVariables: { context: [ - { - name: 'group', - description: i18n.translate( - 'xpack.infra.metrics.alerting.threshold.alerting.groupActionVariableDescription', - { - defaultMessage: 'Name of the group reporting data', - } - ), - }, - { - name: 'valueOf', - description: i18n.translate( - 'xpack.infra.metrics.alerting.threshold.alerting.valueOfActionVariableDescription', - { - defaultMessage: - 'Record of the current value of the watched metric; grouped by condition, i.e valueOf.condition0, valueOf.condition1, etc.', - } - ), - }, - { - name: 'thresholdOf', - description: i18n.translate( - 'xpack.infra.metrics.alerting.threshold.alerting.thresholdOfActionVariableDescription', - { - defaultMessage: - 'Record of the alerting threshold; grouped by condition, i.e thresholdOf.condition0, thresholdOf.condition1, etc.', - } - ), - }, - { - name: 'metricOf', - description: i18n.translate( - 'xpack.infra.metrics.alerting.threshold.alerting.metricOfActionVariableDescription', - { - defaultMessage: - 'Record of the watched metric; grouped by condition, i.e metricOf.condition0, metricOf.condition1, etc.', - } - ), - }, + { name: 'group', description: groupActionVariableDescription }, + { name: 'alertState', description: alertStateActionVariableDescription }, + { name: 'reason', description: reasonActionVariableDescription }, + { name: 'timestamp', description: timestampActionVariableDescription }, + { name: 'value', description: valueActionVariableDescription }, + { name: 'metric', description: metricActionVariableDescription }, + { name: 'threshold', description: thresholdActionVariableDescription }, ], }, }); diff --git a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/register_metric_threshold_alert_type.ts b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/register_metric_threshold_alert_type.ts index 529a1d176c437..07d729f17de45 100644 --- a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/register_metric_threshold_alert_type.ts +++ b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/register_metric_threshold_alert_type.ts @@ -3,13 +3,21 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { i18n } from '@kbn/i18n'; import { schema } from '@kbn/config-schema'; import { METRIC_EXPLORER_AGGREGATIONS } from '../../../../common/http_api/metrics_explorer'; import { createMetricThresholdExecutor, FIRED_ACTIONS } from './metric_threshold_executor'; import { METRIC_THRESHOLD_ALERT_TYPE_ID, Comparator } from './types'; import { InfraBackendLibs } from '../../infra_types'; import { oneOfLiterals, validateIsStringElasticsearchJSONFilter } from '../common/utils'; +import { + groupActionVariableDescription, + alertStateActionVariableDescription, + reasonActionVariableDescription, + timestampActionVariableDescription, + valueActionVariableDescription, + metricActionVariableDescription, + thresholdActionVariableDescription, +} from '../common/messages'; export function registerMetricThresholdAlertType(libs: InfraBackendLibs) { const baseCriterion = { @@ -31,59 +39,6 @@ export function registerMetricThresholdAlertType(libs: InfraBackendLibs) { metric: schema.never(), }); - const groupActionVariableDescription = i18n.translate( - 'xpack.infra.metrics.alerting.threshold.alerting.groupActionVariableDescription', - { - defaultMessage: 'Name of the group reporting data', - } - ); - - const alertStateActionVariableDescription = i18n.translate( - 'xpack.infra.metrics.alerting.threshold.alerting.alertStateActionVariableDescription', - { - defaultMessage: 'Current state of the alert', - } - ); - - const reasonActionVariableDescription = i18n.translate( - 'xpack.infra.metrics.alerting.threshold.alerting.reasonActionVariableDescription', - { - defaultMessage: - 'A description of why the alert is in this state, including which metrics have crossed which thresholds', - } - ); - - const timestampActionVariableDescription = i18n.translate( - 'xpack.infra.metrics.alerting.threshold.alerting.timestampDescription', - { - defaultMessage: 'A timestamp of when the alert was detected.', - } - ); - - const valueActionVariableDescription = i18n.translate( - 'xpack.infra.metrics.alerting.threshold.alerting.valueActionVariableDescription', - { - defaultMessage: - 'The value of the metric in the specified condition. Usage: (ctx.value.condition0, ctx.value.condition1, etc...).', - } - ); - - const metricActionVariableDescription = i18n.translate( - 'xpack.infra.metrics.alerting.threshold.alerting.metricActionVariableDescription', - { - defaultMessage: - 'The metric name in the specified condition. Usage: (ctx.metric.condition0, ctx.metric.condition1, etc...).', - } - ); - - const thresholdActionVariableDescription = i18n.translate( - 'xpack.infra.metrics.alerting.threshold.alerting.thresholdActionVariableDescription', - { - defaultMessage: - 'The threshold value of the metric for the specified condition. Usage: (ctx.threshold.condition0, ctx.threshold.condition1, etc...).', - } - ); - return { id: METRIC_THRESHOLD_ALERT_TYPE_ID, name: 'Metric threshold', diff --git a/x-pack/plugins/infra/server/lib/create_search_client.ts b/x-pack/plugins/infra/server/lib/create_search_client.ts new file mode 100644 index 0000000000000..d79d20b502e94 --- /dev/null +++ b/x-pack/plugins/infra/server/lib/create_search_client.ts @@ -0,0 +1,16 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { RequestHandlerContext } from 'src/core/server'; +import { CallWithRequestParams, InfraDatabaseSearchResponse } from './adapters/framework'; +import { KibanaFramework } from './adapters/framework/kibana_framework_adapter'; + +export const createSearchClient = ( + requestContext: RequestHandlerContext, + framework: KibanaFramework +) => ( + opts: CallWithRequestParams +): Promise> => + framework.callWithRequest(requestContext, 'search', opts); diff --git a/x-pack/plugins/infra/server/lib/snapshot/response_helpers.test.ts b/x-pack/plugins/infra/server/lib/snapshot/response_helpers.test.ts index 20220aef1133d..74840afc157d2 100644 --- a/x-pack/plugins/infra/server/lib/snapshot/response_helpers.test.ts +++ b/x-pack/plugins/infra/server/lib/snapshot/response_helpers.test.ts @@ -4,7 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -import { isIPv4, getIPFromBucket, InfraSnapshotNodeGroupByBucket } from './response_helpers'; +import { + isIPv4, + getIPFromBucket, + InfraSnapshotNodeGroupByBucket, + getMetricValueFromBucket, + InfraSnapshotMetricsBucket, +} from './response_helpers'; describe('InfraOps ResponseHelpers', () => { describe('isIPv4', () => { @@ -74,4 +80,40 @@ describe('InfraOps ResponseHelpers', () => { expect(getIPFromBucket('host', bucket)).toBe(null); }); }); + + describe('getMetricValueFromBucket', () => { + it('should return the value of a bucket with data', () => { + expect(getMetricValueFromBucket('custom', testBucket, 1)).toBe(0.5); + }); + it('should return the normalized value of a bucket with data', () => { + expect(getMetricValueFromBucket('cpu', testNormalizedBucket, 1)).toBe(50); + }); + it('should return null for a bucket with no data', () => { + expect(getMetricValueFromBucket('custom', testEmptyBucket, 1)).toBe(null); + }); + }); }); + +// Hack to get around TypeScript +const buckets = [ + { + key: 'a', + doc_count: 1, + custom_1: { + value: 0.5, + }, + }, + { + key: 'b', + doc_count: 1, + cpu: { + value: 0.5, + normalized_value: 50, + }, + }, + { + key: 'c', + doc_count: 0, + }, +] as InfraSnapshotMetricsBucket[]; +const [testBucket, testNormalizedBucket, testEmptyBucket] = buckets; diff --git a/x-pack/plugins/infra/server/lib/snapshot/response_helpers.ts b/x-pack/plugins/infra/server/lib/snapshot/response_helpers.ts index 317a7da95ce6b..646ce9f2409af 100644 --- a/x-pack/plugins/infra/server/lib/snapshot/response_helpers.ts +++ b/x-pack/plugins/infra/server/lib/snapshot/response_helpers.ts @@ -158,14 +158,15 @@ const findLastFullBucket = ( }, last(buckets)); }; -const getMetricValueFromBucket = ( +export const getMetricValueFromBucket = ( type: SnapshotMetricType, bucket: InfraSnapshotMetricsBucket, index: number ) => { const key = type === 'custom' ? `custom_${index}` : type; const metric = bucket[key]; - return (metric && (metric.normalized_value || metric.value)) || 0; + const value = metric && (metric.normalized_value || metric.value); + return isFinite(value) ? value : null; }; function calculateMax( diff --git a/x-pack/plugins/infra/server/lib/snapshot/snapshot.ts b/x-pack/plugins/infra/server/lib/snapshot/snapshot.ts index 9ca10d5e39da7..5f359b0523d9f 100644 --- a/x-pack/plugins/infra/server/lib/snapshot/snapshot.ts +++ b/x-pack/plugins/infra/server/lib/snapshot/snapshot.ts @@ -86,7 +86,7 @@ const requestGroupedNodes = async ( aggregations: { nodes: { composite: { - size: SNAPSHOT_COMPOSITE_REQUEST_SIZE, + size: options.overrideCompositeSize || SNAPSHOT_COMPOSITE_REQUEST_SIZE, sources: getGroupedNodesSources(options), }, aggs: { @@ -142,7 +142,7 @@ const requestNodeMetrics = async ( aggregations: { nodes: { composite: { - size: SNAPSHOT_COMPOSITE_REQUEST_SIZE, + size: options.overrideCompositeSize || SNAPSHOT_COMPOSITE_REQUEST_SIZE, sources: getMetricsSources(options), }, aggregations: { diff --git a/x-pack/plugins/infra/server/lib/source_status.ts b/x-pack/plugins/infra/server/lib/source_status.ts index 9bb953845e5a1..c383d01933562 100644 --- a/x-pack/plugins/infra/server/lib/source_status.ts +++ b/x-pack/plugins/infra/server/lib/source_status.ts @@ -69,19 +69,19 @@ export class InfraSourceStatus { ); return hasAlias; } - public async hasLogIndices( + public async getLogIndexStatus( requestContext: RequestHandlerContext, sourceId: string - ): Promise { + ): Promise { const sourceConfiguration = await this.libs.sources.getSourceConfiguration( requestContext.core.savedObjects.client, sourceId ); - const hasIndices = await this.adapter.hasIndices( + const indexStatus = await this.adapter.getIndexStatus( requestContext, sourceConfiguration.configuration.logAlias ); - return hasIndices; + return indexStatus; } public async hasMetricIndices( requestContext: RequestHandlerContext, @@ -91,16 +91,21 @@ export class InfraSourceStatus { requestContext.core.savedObjects.client, sourceId ); - const hasIndices = await this.adapter.hasIndices( + const indexStatus = await this.adapter.getIndexStatus( requestContext, sourceConfiguration.configuration.metricAlias ); - return hasIndices; + return indexStatus !== 'missing'; } } +export type SourceIndexStatus = 'missing' | 'empty' | 'available'; + export interface InfraSourceStatusAdapter { getIndexNames(requestContext: RequestHandlerContext, aliasName: string): Promise; hasAlias(requestContext: RequestHandlerContext, aliasName: string): Promise; - hasIndices(requestContext: RequestHandlerContext, indexNames: string): Promise; + getIndexStatus( + requestContext: RequestHandlerContext, + indexNames: string + ): Promise; } diff --git a/x-pack/plugins/infra/server/lib/sources/has_data.ts b/x-pack/plugins/infra/server/lib/sources/has_data.ts new file mode 100644 index 0000000000000..79b1375059dcb --- /dev/null +++ b/x-pack/plugins/infra/server/lib/sources/has_data.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { ESSearchClient } from '../snapshot'; + +export const hasData = async (index: string, client: ESSearchClient) => { + const params = { + index, + allowNoIndices: true, + terminate_after: 1, + ignoreUnavailable: true, + body: { + size: 0, + }, + }; + const results = await client(params); + return results.hits.total.value !== 0; +}; diff --git a/x-pack/plugins/infra/server/routes/log_sources/status.ts b/x-pack/plugins/infra/server/routes/log_sources/status.ts index 4cd85ecfe23c1..193c3541d740b 100644 --- a/x-pack/plugins/infra/server/routes/log_sources/status.ts +++ b/x-pack/plugins/infra/server/routes/log_sources/status.ts @@ -31,16 +31,17 @@ export const initLogSourceStatusRoutes = ({ const { sourceId } = request.params; try { - const logIndicesExist = await sourceStatus.hasLogIndices(requestContext, sourceId); - const logIndexFields = logIndicesExist - ? await fields.getFields(requestContext, sourceId, InfraIndexType.LOGS) - : []; + const logIndexStatus = await sourceStatus.getLogIndexStatus(requestContext, sourceId); + const logIndexFields = + logIndexStatus !== 'missing' + ? await fields.getFields(requestContext, sourceId, InfraIndexType.LOGS) + : []; return response.ok({ body: getLogSourceStatusSuccessResponsePayloadRT.encode({ data: { - logIndicesExist, logIndexFields, + logIndexStatus, }, }), }); diff --git a/x-pack/plugins/infra/server/routes/snapshot/index.ts b/x-pack/plugins/infra/server/routes/snapshot/index.ts index 7c81c6eef675f..00bc1e74ea871 100644 --- a/x-pack/plugins/infra/server/routes/snapshot/index.ts +++ b/x-pack/plugins/infra/server/routes/snapshot/index.ts @@ -13,7 +13,7 @@ import { UsageCollector } from '../../usage/usage_collector'; import { parseFilterQuery } from '../../utils/serialized_query'; import { SnapshotRequestRT, SnapshotNodeResponseRT } from '../../../common/http_api/snapshot_api'; import { throwErrors } from '../../../common/runtime_types'; -import { CallWithRequestParams, InfraDatabaseSearchResponse } from '../../lib/adapters/framework'; +import { createSearchClient } from '../../lib/create_search_client'; const escapeHatch = schema.object({}, { unknowns: 'allow' }); @@ -40,6 +40,7 @@ export const initSnapshotRoute = (libs: InfraBackendLibs) => { accountId, region, includeTimeseries, + overrideCompositeSize, } = pipe( SnapshotRequestRT.decode(request.body), fold(throwErrors(Boom.badRequest), identity) @@ -59,14 +60,11 @@ export const initSnapshotRoute = (libs: InfraBackendLibs) => { metrics, timerange, includeTimeseries, + overrideCompositeSize, }; - const searchES = ( - opts: CallWithRequestParams - ): Promise> => - framework.callWithRequest(requestContext, 'search', opts); - - const nodesWithInterval = await libs.snapshot.getNodes(searchES, options); + const client = createSearchClient(requestContext, framework); + const nodesWithInterval = await libs.snapshot.getNodes(client, options); return response.ok({ body: SnapshotNodeResponseRT.encode(nodesWithInterval), }); diff --git a/x-pack/plugins/infra/server/routes/source/index.ts b/x-pack/plugins/infra/server/routes/source/index.ts index 2843897071e19..9ff3902f1eae7 100644 --- a/x-pack/plugins/infra/server/routes/source/index.ts +++ b/x-pack/plugins/infra/server/routes/source/index.ts @@ -7,6 +7,8 @@ import { schema } from '@kbn/config-schema'; import { SourceResponseRuntimeType } from '../../../common/http_api/source_api'; import { InfraBackendLibs } from '../../lib/infra_types'; import { InfraIndexType } from '../../graphql/types'; +import { hasData } from '../../lib/sources/has_data'; +import { createSearchClient } from '../../lib/create_search_client'; const typeToInfraIndexType = (value: string | undefined) => { switch (value) { @@ -37,9 +39,9 @@ export const initSourceRoute = (libs: InfraBackendLibs) => { try { const { type, sourceId } = request.params; - const [source, logIndicesExist, metricIndicesExist, indexFields] = await Promise.all([ + const [source, logIndexStatus, metricIndicesExist, indexFields] = await Promise.all([ libs.sources.getSourceConfiguration(requestContext.core.savedObjects.client, sourceId), - libs.sourceStatus.hasLogIndices(requestContext, sourceId), + libs.sourceStatus.getLogIndexStatus(requestContext, sourceId), libs.sourceStatus.hasMetricIndices(requestContext, sourceId), libs.fields.getFields(requestContext, sourceId, typeToInfraIndexType(type)), ]); @@ -49,7 +51,7 @@ export const initSourceRoute = (libs: InfraBackendLibs) => { } const status = { - logIndicesExist, + logIndicesExist: logIndexStatus !== 'missing', metricIndicesExist, indexFields, }; @@ -80,13 +82,17 @@ export const initSourceRoute = (libs: InfraBackendLibs) => { try { const { type, sourceId } = request.params; - const hasData = - type === 'metrics' - ? await libs.sourceStatus.hasMetricIndices(requestContext, sourceId) - : await libs.sourceStatus.hasLogIndices(requestContext, sourceId); + const client = createSearchClient(requestContext, framework); + const source = await libs.sources.getSourceConfiguration( + requestContext.core.savedObjects.client, + sourceId + ); + const indexPattern = + type === 'metrics' ? source.configuration.metricAlias : source.configuration.logAlias; + const results = await hasData(indexPattern, client); return response.ok({ - body: { hasData }, + body: { hasData: results }, }); } catch (error) { return response.internalError({ diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/enrollment_instructions/manual/index.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/enrollment_instructions/manual/index.tsx index 78f4f73cf18be..fe11c4cb08d13 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/enrollment_instructions/manual/index.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/enrollment_instructions/manual/index.tsx @@ -5,7 +5,8 @@ */ import React from 'react'; -import { EuiText, EuiSpacer, EuiCode, EuiCodeBlock, EuiCopy, EuiButton } from '@elastic/eui'; +import styled from 'styled-components'; +import { EuiText, EuiSpacer, EuiCode, EuiTitle, EuiCodeBlock } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { EnrollmentAPIKey } from '../../../types'; @@ -15,42 +16,86 @@ interface Props { kibanaCASha256?: string; } +// Otherwise the copy button is over the text +const CommandCode = styled.pre({ + overflow: 'scroll', +}); + export const ManualInstructions: React.FunctionComponent = ({ kibanaUrl, apiKey, kibanaCASha256, }) => { - const command = ` -./elastic-agent enroll ${kibanaUrl} ${apiKey.api_key}${ + const enrollArgs = `${kibanaUrl} ${apiKey.api_key}${ kibanaCASha256 ? ` --ca_sha256=${kibanaCASha256}` : '' - } + }`; + const macOsLinuxTarCommand = `./elastic-agent enroll ${enrollArgs} ./elastic-agent run`; + + const linuxDebRpmCommand = `./elastic-agent enroll ${enrollArgs} +systemctl enable elastic-agent +systemctl start elastic-agent`; + + const windowsCommand = `./elastic-agent enroll ${enrollArgs} +./install-service-elastic-agent.ps1`; + return ( <> + + + +

      + +

      +
      + + + {windowsCommand} + + + +

      + +

      +
      + + + {linuxDebRpmCommand} + + + +

      + +

      +
      + + + agent enroll, + command: ./elastic-agent run, }} /> - - -
      {command}
      + + + {macOsLinuxTarCommand} - - - {(copy) => ( - - - - )} - ); }; diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_package_config_page/components/package_config_input_config.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_package_config_page/components/package_config_input_config.tsx index 98f04dbd92659..fd3a64bc760a0 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_package_config_page/components/package_config_input_config.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_package_config_page/components/package_config_input_config.tsx @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import React, { useState, Fragment, memo, useMemo } from 'react'; +import styled from 'styled-components'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiFlexGrid, @@ -21,6 +22,10 @@ import { } from '../services'; import { PackageConfigInputVarField } from './package_config_input_var_field'; +const FlexItemWithMaxWidth = styled(EuiFlexItem)` + max-width: calc(50% - ${(props) => props.theme.eui.euiSizeL}); +`; + export const PackageConfigInputConfig: React.FunctionComponent<{ packageInputVars?: RegistryVarsEntry[]; packageConfigInput: PackageConfigInput; @@ -88,7 +93,7 @@ export const PackageConfigInputConfig: React.FunctionComponent<{
      - + {requiredVars.map((varDef) => { const { name: varName, type: varType } = varDef; @@ -176,7 +181,7 @@ export const PackageConfigInputConfig: React.FunctionComponent<{ ) : null} - + ); } diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_details_page/components/actions_menu.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_details_page/components/actions_menu.tsx index 7afc57b30cef4..0f48a230bbf5c 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_details_page/components/actions_menu.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_details_page/components/actions_menu.tsx @@ -53,6 +53,7 @@ export const AgentDetailsActionMenu: React.FunctionComponent<{ onClick={() => { setIsReassignFlyoutOpen(true); }} + disabled={!agent.active} key="reassignConfig" > void; refre onClick={() => { onReassignClick(); }} + disabled={!agent.active} key="reassignConfig" > void; refre defaultMessage="Assign new agent config" /> , - {(unenrollAgentsPrompt) => ( { unenrollAgentsPrompt([agent.id], 1, () => { @@ -536,9 +536,9 @@ export const AgentListPage: React.FunctionComponent<{}> = () => { ), }} /> - ) : !isLoading && totalAgents === 0 ? ( + ) : ( emptyPrompt - ) : undefined + ) } items={totalAgents ? agents : []} itemId="id" diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_enrollment_flyout/config_selection.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_enrollment_flyout/config_selection.tsx index 09b00240dc127..e98ebb7cadc7c 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_enrollment_flyout/config_selection.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_enrollment_flyout/config_selection.tsx @@ -39,71 +39,105 @@ export const EnrollmentStepAgentConfig: React.FC = (props) => { enrollmentAPIKeyId?: string; }>({}); - useEffect(() => { - if (agentConfigs && agentConfigs.length && !selectedState.agentConfigId) { - setSelectedState({ - ...selectedState, - agentConfigId: agentConfigs[0].id, - }); - } - }, [agentConfigs, selectedState]); + useEffect( + function triggerOnConfigChangeEffect() { + if (onConfigChange && selectedState.agentConfigId) { + onConfigChange(selectedState.agentConfigId); + } + }, + [selectedState.agentConfigId, onConfigChange] + ); - useEffect(() => { - if (onConfigChange && selectedState.agentConfigId) { - onConfigChange(selectedState.agentConfigId); - } - }, [selectedState.agentConfigId, onConfigChange]); + useEffect( + function triggerOnKeyChangeEffect() { + if (!withKeySelection || !onKeyChange) { + return; + } - useEffect(() => { - if (!withKeySelection) { - return; - } - if (!selectedState.agentConfigId) { - setEnrollmentAPIKeys([]); - return; - } + if (selectedState.enrollmentAPIKeyId) { + onKeyChange(selectedState.enrollmentAPIKeyId); + } + }, + [withKeySelection, onKeyChange, selectedState.enrollmentAPIKeyId] + ); - async function fetchEnrollmentAPIKeys() { - try { - const res = await sendGetEnrollmentAPIKeys({ - page: 1, - perPage: 10000, - }); - if (res.error) { - throw res.error; + useEffect( + function useDefaultConfigEffect() { + if (agentConfigs && agentConfigs.length && !selectedState.agentConfigId) { + const defaultConfig = agentConfigs.find((config) => config.is_default); + if (defaultConfig) { + setSelectedState({ + ...selectedState, + agentConfigId: defaultConfig.id, + }); } + } + }, + [agentConfigs, selectedState] + ); - if (!res.data) { - throw new Error('No data while fetching enrollment API keys'); + useEffect( + function useEnrollmentKeysForConfigEffect() { + if (!withKeySelection) { + return; + } + if (!selectedState.agentConfigId) { + setEnrollmentAPIKeys([]); + return; + } + + async function fetchEnrollmentAPIKeys() { + try { + const res = await sendGetEnrollmentAPIKeys({ + page: 1, + perPage: 10000, + }); + if (res.error) { + throw res.error; + } + + if (!res.data) { + throw new Error('No data while fetching enrollment API keys'); + } + + setEnrollmentAPIKeys( + res.data.list.filter((key) => key.config_id === selectedState.agentConfigId) + ); + } catch (error) { + notifications.toasts.addError(error, { + title: 'Error', + }); } + } + fetchEnrollmentAPIKeys(); + }, + [withKeySelection, selectedState.agentConfigId, notifications.toasts] + ); - setEnrollmentAPIKeys( - res.data.list.filter((key) => key.config_id === selectedState.agentConfigId) - ); - } catch (error) { - notifications.toasts.addError(error, { - title: 'Error', + useEffect( + function useDefaultEnrollmentKeyForConfigEffect() { + if (!withKeySelection) { + return; + } + if ( + !selectedState.enrollmentAPIKeyId && + enrollmentAPIKeys.length > 0 && + enrollmentAPIKeys[0].config_id === selectedState.agentConfigId + ) { + const enrollmentAPIKeyId = enrollmentAPIKeys[0].id; + setSelectedState({ + agentConfigId: selectedState.agentConfigId, + enrollmentAPIKeyId, }); } - } - fetchEnrollmentAPIKeys(); - }, [withKeySelection, selectedState.agentConfigId, notifications.toasts]); - - // Select first API key when config change - React.useEffect(() => { - if (!withKeySelection || !onKeyChange) { - return; - } - if (!selectedState.enrollmentAPIKeyId && enrollmentAPIKeys.length > 0) { - const enrollmentAPIKeyId = enrollmentAPIKeys[0].id; - setSelectedState({ - agentConfigId: selectedState.agentConfigId, - enrollmentAPIKeyId, - }); - onKeyChange(enrollmentAPIKeyId); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [enrollmentAPIKeys, selectedState.enrollmentAPIKeyId, selectedState.agentConfigId]); + }, + [ + withKeySelection, + enrollmentAPIKeys, + selectedState.enrollmentAPIKeyId, + selectedState.agentConfigId, + ] + ); return ( <> @@ -174,7 +208,6 @@ export const EnrollmentStepAgentConfig: React.FC = (props) => { ...selectedState, enrollmentAPIKeyId: e.target.value, }); - onKeyChange(e.target.value); }} /> diff --git a/x-pack/plugins/ingest_manager/server/services/agent_config.ts b/x-pack/plugins/ingest_manager/server/services/agent_config.ts index 0a9adc1f1c593..3886146e28806 100644 --- a/x-pack/plugins/ingest_manager/server/services/agent_config.ts +++ b/x-pack/plugins/ingest_manager/server/services/agent_config.ts @@ -233,16 +233,14 @@ class AgentConfigService { if (baseAgentConfig.package_configs.length) { const newPackageConfigs = (baseAgentConfig.package_configs as PackageConfig[]).map( (packageConfig: PackageConfig) => { - const { id: packageConfigId, ...newPackageConfig } = packageConfig; + const { id: packageConfigId, version, ...newPackageConfig } = packageConfig; return newPackageConfig; } ); - await packageConfigService.bulkCreate( - soClient, - newPackageConfigs, - newAgentConfig.id, - options - ); + await packageConfigService.bulkCreate(soClient, newPackageConfigs, newAgentConfig.id, { + ...options, + bumpConfigRevision: false, + }); } // Get updated config diff --git a/x-pack/plugins/ingest_manager/server/services/package_config.ts b/x-pack/plugins/ingest_manager/server/services/package_config.ts index c2d465cf7c73f..5d1c5d1717714 100644 --- a/x-pack/plugins/ingest_manager/server/services/package_config.ts +++ b/x-pack/plugins/ingest_manager/server/services/package_config.ts @@ -121,7 +121,7 @@ class PackageConfigService { options?: { user?: AuthenticatedUser; bumpConfigRevision?: boolean } ): Promise { const isoDate = new Date().toISOString(); - const { saved_objects: newSos } = await soClient.bulkCreate( + const { saved_objects } = await soClient.bulkCreate( packageConfigs.map((packageConfig) => ({ type: SAVED_OBJECT_TYPE, attributes: { @@ -136,6 +136,9 @@ class PackageConfigService { })) ); + // Filter out invalid SOs + const newSos = saved_objects.filter((so) => !so.error && so.attributes); + // Assign it to the given agent config await agentConfigService.assignPackageConfigs( soClient, diff --git a/x-pack/plugins/lists/common/constants.mock.ts b/x-pack/plugins/lists/common/constants.mock.ts index 30f219c3ec101..b7609b5a3602a 100644 --- a/x-pack/plugins/lists/common/constants.mock.ts +++ b/x-pack/plugins/lists/common/constants.mock.ts @@ -3,9 +3,11 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { EntriesArray } from './schemas/types'; +import moment from 'moment'; +import { EntriesArray } from './schemas/types'; export const DATE_NOW = '2020-04-20T15:25:31.830Z'; +export const OLD_DATE_RELATIVE_TO_DATE_NOW = '2020-04-19T15:25:31.830Z'; export const USER = 'some user'; export const LIST_INDEX = '.lists'; export const LIST_ITEM_INDEX = '.items'; @@ -63,3 +65,4 @@ export const CURSOR = 'c29tZXN0cmluZ2ZvcnlvdQ=='; export const _VERSION = 'WzI5NywxXQ=='; export const VERSION = 1; export const IMMUTABLE = false; +export const IMPORT_TIMEOUT = moment.duration(5, 'minutes'); diff --git a/x-pack/plugins/lists/common/constants.ts b/x-pack/plugins/lists/common/constants.ts index df16085b53405..6c73dc1656302 100644 --- a/x-pack/plugins/lists/common/constants.ts +++ b/x-pack/plugins/lists/common/constants.ts @@ -48,3 +48,5 @@ export const ENDPOINT_LIST_NAME = 'Elastic Endpoint Security Exception List'; /** The description of the single global space agnostic endpoint list */ export const ENDPOINT_LIST_DESCRIPTION = 'Elastic Endpoint Security Exception List'; + +export const MAX_EXCEPTION_LIST_SIZE = 10000; diff --git a/x-pack/plugins/lists/common/schemas/request/create_endpoint_list_item_schema.test.ts b/x-pack/plugins/lists/common/schemas/request/create_endpoint_list_item_schema.test.ts index 5de9fbb0d5b50..75e0410be610a 100644 --- a/x-pack/plugins/lists/common/schemas/request/create_endpoint_list_item_schema.test.ts +++ b/x-pack/plugins/lists/common/schemas/request/create_endpoint_list_item_schema.test.ts @@ -8,8 +8,8 @@ import { left } from 'fp-ts/lib/Either'; import { pipe } from 'fp-ts/lib/pipeable'; import { exactCheck, foldLeftRight, getPaths } from '../../siem_common_deps'; -import { getCreateCommentsArrayMock } from '../types/create_comments.mock'; -import { getCommentsMock } from '../types/comments.mock'; +import { getCreateCommentsArrayMock } from '../types/create_comment.mock'; +import { getCommentsMock } from '../types/comment.mock'; import { CommentsArray } from '../types'; import { @@ -19,7 +19,7 @@ import { import { getCreateEndpointListItemSchemaMock } from './create_endpoint_list_item_schema.mock'; describe('create_endpoint_list_item_schema', () => { - test('it should validate a typical list item request not counting the auto generated uuid', () => { + test('it should pass validation when supplied a typical list item request not counting the auto generated uuid', () => { const payload = getCreateEndpointListItemSchemaMock(); const decoded = createEndpointListItemSchema.decode(payload); const checked = exactCheck(payload, decoded); @@ -29,7 +29,7 @@ describe('create_endpoint_list_item_schema', () => { expect(message.schema).toEqual(payload); }); - test('it should not validate an undefined for "description"', () => { + test('it should fail validation when supplied an undefined for "description"', () => { const payload = getCreateEndpointListItemSchemaMock(); delete payload.description; const decoded = createEndpointListItemSchema.decode(payload); @@ -41,7 +41,7 @@ describe('create_endpoint_list_item_schema', () => { expect(message.schema).toEqual({}); }); - test('it should not validate an undefined for "name"', () => { + test('it should fail validation when supplied an undefined for "name"', () => { const payload = getCreateEndpointListItemSchemaMock(); delete payload.name; const decoded = createEndpointListItemSchema.decode(payload); @@ -53,7 +53,7 @@ describe('create_endpoint_list_item_schema', () => { expect(message.schema).toEqual({}); }); - test('it should not validate an undefined for "type"', () => { + test('it should fail validation when supplied an undefined for "type"', () => { const payload = getCreateEndpointListItemSchemaMock(); delete payload.type; const decoded = createEndpointListItemSchema.decode(payload); @@ -65,7 +65,7 @@ describe('create_endpoint_list_item_schema', () => { expect(message.schema).toEqual({}); }); - test('it should not validate a "list_id" since it does not required one', () => { + test('it should fail validation when supplied a "list_id" since it does not required one', () => { const inputPayload: CreateEndpointListItemSchema & { list_id: string } = { ...getCreateEndpointListItemSchemaMock(), list_id: 'list-123', @@ -77,7 +77,7 @@ describe('create_endpoint_list_item_schema', () => { expect(message.schema).toEqual({}); }); - test('it should not validate a "namespace_type" since it does not required one', () => { + test('it should fail validation when supplied a "namespace_type" since it does not required one', () => { const inputPayload: CreateEndpointListItemSchema & { namespace_type: string } = { ...getCreateEndpointListItemSchemaMock(), namespace_type: 'single', @@ -89,7 +89,7 @@ describe('create_endpoint_list_item_schema', () => { expect(message.schema).toEqual({}); }); - test('it should validate an undefined for "meta" but strip it out and generate a correct body not counting the auto generated uuid', () => { + test('it should pass validation when supplied an undefined for "meta" but strip it out and generate a correct body not counting the auto generated uuid', () => { const payload = getCreateEndpointListItemSchemaMock(); const outputPayload = getCreateEndpointListItemSchemaMock(); delete payload.meta; @@ -102,7 +102,7 @@ describe('create_endpoint_list_item_schema', () => { expect(message.schema).toEqual(outputPayload); }); - test('it should validate an undefined for "comments" but return an array and generate a correct body not counting the auto generated uuid', () => { + test('it should pass validation when supplied an undefined for "comments" but return an array and generate a correct body not counting the auto generated uuid', () => { const inputPayload = getCreateEndpointListItemSchemaMock(); const outputPayload = getCreateEndpointListItemSchemaMock(); delete inputPayload.comments; @@ -115,7 +115,7 @@ describe('create_endpoint_list_item_schema', () => { expect(message.schema).toEqual(outputPayload); }); - test('it should validate "comments" array', () => { + test('it should pass validation when supplied "comments" array', () => { const inputPayload = { ...getCreateEndpointListItemSchemaMock(), comments: getCreateCommentsArrayMock(), @@ -128,7 +128,7 @@ describe('create_endpoint_list_item_schema', () => { expect(message.schema).toEqual(inputPayload); }); - test('it should NOT validate "comments" with "created_at" or "created_by" values', () => { + test('it should fail validation when supplied "comments" with "created_at", "created_by", or "id" values', () => { const inputPayload: Omit & { comments?: CommentsArray; } = { @@ -138,11 +138,11 @@ describe('create_endpoint_list_item_schema', () => { const decoded = createEndpointListItemSchema.decode(inputPayload); const checked = exactCheck(inputPayload, decoded); const message = pipe(checked, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['invalid keys "created_at,created_by"']); + expect(getPaths(left(message.errors))).toEqual(['invalid keys "created_at,created_by,id"']); expect(message.schema).toEqual({}); }); - test('it should NOT validate an undefined for "entries"', () => { + test('it should fail validation when supplied an undefined for "entries"', () => { const inputPayload = getCreateEndpointListItemSchemaMock(); const outputPayload = getCreateEndpointListItemSchemaMock(); delete inputPayload.entries; @@ -157,7 +157,7 @@ describe('create_endpoint_list_item_schema', () => { expect(message.schema).toEqual({}); }); - test('it should validate an undefined for "tags" but return an array and generate a correct body not counting the auto generated uuid', () => { + test('it should pass validation when supplied an undefined for "tags" but return an array and generate a correct body not counting the auto generated uuid', () => { const inputPayload = getCreateEndpointListItemSchemaMock(); const outputPayload = getCreateEndpointListItemSchemaMock(); delete inputPayload.tags; @@ -170,7 +170,7 @@ describe('create_endpoint_list_item_schema', () => { expect(message.schema).toEqual(outputPayload); }); - test('it should validate an undefined for "_tags" but return an array and generate a correct body not counting the auto generated uuid', () => { + test('it should pass validation when supplied an undefined for "_tags" but return an array and generate a correct body not counting the auto generated uuid', () => { const inputPayload = getCreateEndpointListItemSchemaMock(); const outputPayload = getCreateEndpointListItemSchemaMock(); delete inputPayload._tags; @@ -183,7 +183,7 @@ describe('create_endpoint_list_item_schema', () => { expect(message.schema).toEqual(outputPayload); }); - test('it should validate an undefined for "item_id" and auto generate a uuid', () => { + test('it should pass validation when supplied an undefined for "item_id" and auto generate a uuid', () => { const inputPayload = getCreateEndpointListItemSchemaMock(); delete inputPayload.item_id; const decoded = createEndpointListItemSchema.decode(inputPayload); @@ -195,7 +195,7 @@ describe('create_endpoint_list_item_schema', () => { ); }); - test('it should validate an undefined for "item_id" and generate a correct body not counting the uuid', () => { + test('it should pass validation when supplied an undefined for "item_id" and generate a correct body not counting the uuid', () => { const inputPayload = getCreateEndpointListItemSchemaMock(); delete inputPayload.item_id; const decoded = createEndpointListItemSchema.decode(inputPayload); diff --git a/x-pack/plugins/lists/common/schemas/request/create_exception_list_item_schema.test.ts b/x-pack/plugins/lists/common/schemas/request/create_exception_list_item_schema.test.ts index 08f3966af08d9..cf4c1fea0306f 100644 --- a/x-pack/plugins/lists/common/schemas/request/create_exception_list_item_schema.test.ts +++ b/x-pack/plugins/lists/common/schemas/request/create_exception_list_item_schema.test.ts @@ -8,8 +8,8 @@ import { left } from 'fp-ts/lib/Either'; import { pipe } from 'fp-ts/lib/pipeable'; import { exactCheck, foldLeftRight, getPaths } from '../../siem_common_deps'; -import { getCreateCommentsArrayMock } from '../types/create_comments.mock'; -import { getCommentsMock } from '../types/comments.mock'; +import { getCreateCommentsArrayMock } from '../types/create_comment.mock'; +import { getCommentsMock } from '../types/comment.mock'; import { CommentsArray } from '../types'; import { @@ -19,7 +19,7 @@ import { import { getCreateExceptionListItemSchemaMock } from './create_exception_list_item_schema.mock'; describe('create_exception_list_item_schema', () => { - test('it should validate a typical exception list item request not counting the auto generated uuid', () => { + test('it should pass validation when supplied a typical exception list item request not counting the auto generated uuid', () => { const payload = getCreateExceptionListItemSchemaMock(); const decoded = createExceptionListItemSchema.decode(payload); const checked = exactCheck(payload, decoded); @@ -29,7 +29,7 @@ describe('create_exception_list_item_schema', () => { expect(message.schema).toEqual(payload); }); - test('it should not validate an undefined for "description"', () => { + test('it should fail validation when supplied an undefined for "description"', () => { const payload = getCreateExceptionListItemSchemaMock(); delete payload.description; const decoded = createExceptionListItemSchema.decode(payload); @@ -41,7 +41,7 @@ describe('create_exception_list_item_schema', () => { expect(message.schema).toEqual({}); }); - test('it should not validate an undefined for "name"', () => { + test('it should fail validation when supplied an undefined for "name"', () => { const payload = getCreateExceptionListItemSchemaMock(); delete payload.name; const decoded = createExceptionListItemSchema.decode(payload); @@ -53,7 +53,7 @@ describe('create_exception_list_item_schema', () => { expect(message.schema).toEqual({}); }); - test('it should not validate an undefined for "type"', () => { + test('it should fail validation when supplied an undefined for "type"', () => { const payload = getCreateExceptionListItemSchemaMock(); delete payload.type; const decoded = createExceptionListItemSchema.decode(payload); @@ -65,7 +65,7 @@ describe('create_exception_list_item_schema', () => { expect(message.schema).toEqual({}); }); - test('it should not validate an undefined for "list_id"', () => { + test('it should fail validation when supplied an undefined for "list_id"', () => { const inputPayload = getCreateExceptionListItemSchemaMock(); delete inputPayload.list_id; const decoded = createExceptionListItemSchema.decode(inputPayload); @@ -77,7 +77,7 @@ describe('create_exception_list_item_schema', () => { expect(message.schema).toEqual({}); }); - test('it should validate an undefined for "meta" but strip it out and generate a correct body not counting the auto generated uuid', () => { + test('it should pass validation when supplied an undefined for "meta" but strip it out and generate a correct body not counting the auto generated uuid', () => { const payload = getCreateExceptionListItemSchemaMock(); const outputPayload = getCreateExceptionListItemSchemaMock(); delete payload.meta; @@ -90,7 +90,7 @@ describe('create_exception_list_item_schema', () => { expect(message.schema).toEqual(outputPayload); }); - test('it should validate an undefined for "comments" but return an array and generate a correct body not counting the auto generated uuid', () => { + test('it should pass validation when supplied an undefined for "comments" but return an array and generate a correct body not counting the auto generated uuid', () => { const inputPayload = getCreateExceptionListItemSchemaMock(); const outputPayload = getCreateExceptionListItemSchemaMock(); delete inputPayload.comments; @@ -103,7 +103,7 @@ describe('create_exception_list_item_schema', () => { expect(message.schema).toEqual(outputPayload); }); - test('it should validate "comments" array', () => { + test('it should pass validation when supplied "comments" array', () => { const inputPayload = { ...getCreateExceptionListItemSchemaMock(), comments: getCreateCommentsArrayMock(), @@ -116,7 +116,7 @@ describe('create_exception_list_item_schema', () => { expect(message.schema).toEqual(inputPayload); }); - test('it should NOT validate "comments" with "created_at" or "created_by" values', () => { + test('it should fail validation when supplied "comments" with "created_at" or "created_by" values', () => { const inputPayload: Omit & { comments?: CommentsArray; } = { @@ -126,11 +126,11 @@ describe('create_exception_list_item_schema', () => { const decoded = createExceptionListItemSchema.decode(inputPayload); const checked = exactCheck(inputPayload, decoded); const message = pipe(checked, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['invalid keys "created_at,created_by"']); + expect(getPaths(left(message.errors))).toEqual(['invalid keys "created_at,created_by,id"']); expect(message.schema).toEqual({}); }); - test('it should NOT validate an undefined for "entries"', () => { + test('it should fail validation when supplied an undefined for "entries"', () => { const inputPayload = getCreateExceptionListItemSchemaMock(); const outputPayload = getCreateExceptionListItemSchemaMock(); delete inputPayload.entries; @@ -145,7 +145,7 @@ describe('create_exception_list_item_schema', () => { expect(message.schema).toEqual({}); }); - test('it should validate an undefined for "namespace_type" but return enum "single" and generate a correct body not counting the auto generated uuid', () => { + test('it should pass validation when supplied an undefined for "namespace_type" but return enum "single" and generate a correct body not counting the auto generated uuid', () => { const inputPayload = getCreateExceptionListItemSchemaMock(); const outputPayload = getCreateExceptionListItemSchemaMock(); delete inputPayload.namespace_type; @@ -158,7 +158,7 @@ describe('create_exception_list_item_schema', () => { expect(message.schema).toEqual(outputPayload); }); - test('it should validate an undefined for "tags" but return an array and generate a correct body not counting the auto generated uuid', () => { + test('it should pass validation when supplied an undefined for "tags" but return an array and generate a correct body not counting the auto generated uuid', () => { const inputPayload = getCreateExceptionListItemSchemaMock(); const outputPayload = getCreateExceptionListItemSchemaMock(); delete inputPayload.tags; @@ -171,7 +171,7 @@ describe('create_exception_list_item_schema', () => { expect(message.schema).toEqual(outputPayload); }); - test('it should validate an undefined for "_tags" but return an array and generate a correct body not counting the auto generated uuid', () => { + test('it should pass validation when supplied an undefined for "_tags" but return an array and generate a correct body not counting the auto generated uuid', () => { const inputPayload = getCreateExceptionListItemSchemaMock(); const outputPayload = getCreateExceptionListItemSchemaMock(); delete inputPayload._tags; @@ -184,7 +184,7 @@ describe('create_exception_list_item_schema', () => { expect(message.schema).toEqual(outputPayload); }); - test('it should validate an undefined for "item_id" and auto generate a uuid', () => { + test('it should pass validation when supplied an undefined for "item_id" and auto generate a uuid', () => { const inputPayload = getCreateExceptionListItemSchemaMock(); delete inputPayload.item_id; const decoded = createExceptionListItemSchema.decode(inputPayload); @@ -196,7 +196,7 @@ describe('create_exception_list_item_schema', () => { ); }); - test('it should validate an undefined for "item_id" and generate a correct body not counting the uuid', () => { + test('it should pass validation when supplied an undefined for "item_id" and generate a correct body not counting the uuid', () => { const inputPayload = getCreateExceptionListItemSchemaMock(); delete inputPayload.item_id; const decoded = createExceptionListItemSchema.decode(inputPayload); diff --git a/x-pack/plugins/lists/common/schemas/request/update_exception_list_item_validation.test.ts b/x-pack/plugins/lists/common/schemas/request/update_exception_list_item_validation.test.ts new file mode 100644 index 0000000000000..3358582786cc7 --- /dev/null +++ b/x-pack/plugins/lists/common/schemas/request/update_exception_list_item_validation.test.ts @@ -0,0 +1,43 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { getUpdateExceptionListItemSchemaMock } from './update_exception_list_item_schema.mock'; +import { validateComments } from './update_exception_list_item_validation'; + +describe('update_exception_list_item_validation', () => { + describe('#validateComments', () => { + test('it returns no errors if comments is undefined', () => { + const payload = getUpdateExceptionListItemSchemaMock(); + delete payload.comments; + const output = validateComments(payload); + + expect(output).toEqual([]); + }); + + test('it returns no errors if new comments are append only', () => { + const payload = getUpdateExceptionListItemSchemaMock(); + payload.comments = [ + { comment: 'Im an old comment', id: '1' }, + { comment: 'Im a new comment' }, + ]; + const output = validateComments(payload); + + expect(output).toEqual([]); + }); + + test('it returns error if comments are not append only', () => { + const payload = getUpdateExceptionListItemSchemaMock(); + payload.comments = [ + { comment: 'Im an old comment', id: '1' }, + { comment: 'Im a new comment modifying the order of existing comments' }, + { comment: 'Im an old comment', id: '2' }, + ]; + const output = validateComments(payload); + + expect(output).toEqual(['item "comments" are append only']); + }); + }); +}); diff --git a/x-pack/plugins/lists/common/schemas/request/update_exception_list_item_validation.ts b/x-pack/plugins/lists/common/schemas/request/update_exception_list_item_validation.ts new file mode 100644 index 0000000000000..5e44c4e9f73e7 --- /dev/null +++ b/x-pack/plugins/lists/common/schemas/request/update_exception_list_item_validation.ts @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { UpdateExceptionListItemSchema } from './update_exception_list_item_schema'; + +export const validateComments = (item: UpdateExceptionListItemSchema): string[] => { + if (item.comments == null) { + return []; + } + + const [appendOnly] = item.comments.reduce( + (acc, comment) => { + const [, hasNewComments] = acc; + if (comment.id == null) { + return [true, true]; + } + + if (hasNewComments && comment.id != null) { + return [false, true]; + } + + return acc; + }, + [true, false] + ); + if (!appendOnly) { + return ['item "comments" are append only']; + } else { + return []; + } +}; + +export const updateExceptionListItemValidate = ( + schema: UpdateExceptionListItemSchema +): string[] => { + return [...validateComments(schema)]; +}; diff --git a/x-pack/plugins/lists/common/schemas/types/comments.mock.ts b/x-pack/plugins/lists/common/schemas/types/comment.mock.ts similarity index 71% rename from x-pack/plugins/lists/common/schemas/types/comments.mock.ts rename to x-pack/plugins/lists/common/schemas/types/comment.mock.ts index 9e56ac292f8b5..213259b3cce29 100644 --- a/x-pack/plugins/lists/common/schemas/types/comments.mock.ts +++ b/x-pack/plugins/lists/common/schemas/types/comment.mock.ts @@ -4,14 +4,15 @@ * you may not use this file except in compliance with the Elastic License. */ -import { DATE_NOW, USER } from '../../constants.mock'; +import { DATE_NOW, ID, USER } from '../../constants.mock'; -import { Comments, CommentsArray } from './comments'; +import { Comment, CommentsArray } from './comment'; -export const getCommentsMock = (): Comments => ({ +export const getCommentsMock = (): Comment => ({ comment: 'some old comment', created_at: DATE_NOW, created_by: USER, + id: ID, }); export const getCommentsArrayMock = (): CommentsArray => [getCommentsMock(), getCommentsMock()]; diff --git a/x-pack/plugins/lists/common/schemas/types/comments.test.ts b/x-pack/plugins/lists/common/schemas/types/comment.test.ts similarity index 56% rename from x-pack/plugins/lists/common/schemas/types/comments.test.ts rename to x-pack/plugins/lists/common/schemas/types/comment.test.ts index 29bfde03abcc8..c7c945277f756 100644 --- a/x-pack/plugins/lists/common/schemas/types/comments.test.ts +++ b/x-pack/plugins/lists/common/schemas/types/comment.test.ts @@ -10,56 +10,79 @@ import { left } from 'fp-ts/lib/Either'; import { DATE_NOW } from '../../constants.mock'; import { foldLeftRight, getPaths } from '../../siem_common_deps'; -import { getCommentsArrayMock, getCommentsMock } from './comments.mock'; +import { getCommentsArrayMock, getCommentsMock } from './comment.mock'; import { - Comments, + Comment, CommentsArray, CommentsArrayOrUndefined, - comments, + comment, commentsArray, commentsArrayOrUndefined, -} from './comments'; +} from './comment'; -describe('Comments', () => { - describe('comments', () => { - test('it should validate a comments', () => { +describe('Comment', () => { + describe('comment', () => { + test('it fails validation when "id" is undefined', () => { + const payload = { ...getCommentsMock(), id: undefined }; + const decoded = comment.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "id"', + ]); + expect(message.schema).toEqual({}); + }); + + test('it passes validation with a typical comment', () => { const payload = getCommentsMock(); - const decoded = comments.decode(payload); + const decoded = comment.decode(payload); const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); expect(message.schema).toEqual(payload); }); - test('it should validate with "updated_at" and "updated_by"', () => { + test('it passes validation with "updated_at" and "updated_by" fields included', () => { const payload = getCommentsMock(); payload.updated_at = DATE_NOW; payload.updated_by = 'someone'; - const decoded = comments.decode(payload); + const decoded = comment.decode(payload); const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); expect(message.schema).toEqual(payload); }); - test('it should not validate when undefined', () => { + test('it fails validation when undefined', () => { const payload = undefined; - const decoded = comments.decode(payload); + const decoded = comment.decode(payload); const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "undefined" supplied to "({| comment: string, created_at: string, created_by: string |} & Partial<{| updated_at: string, updated_by: string |}>)"', - 'Invalid value "undefined" supplied to "({| comment: string, created_at: string, created_by: string |} & Partial<{| updated_at: string, updated_by: string |}>)"', + 'Invalid value "undefined" supplied to "({| comment: NonEmptyString, created_at: string, created_by: string, id: NonEmptyString |} & Partial<{| updated_at: string, updated_by: string |}>)"', + 'Invalid value "undefined" supplied to "({| comment: NonEmptyString, created_at: string, created_by: string, id: NonEmptyString |} & Partial<{| updated_at: string, updated_by: string |}>)"', ]); expect(message.schema).toEqual({}); }); - test('it should not validate when "comment" is not a string', () => { - const payload: Omit & { comment: string[] } = { + test('it fails validation when "comment" is an empty string', () => { + const payload: Omit & { comment: string } = { + ...getCommentsMock(), + comment: '', + }; + const decoded = comment.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "" supplied to "comment"']); + expect(message.schema).toEqual({}); + }); + + test('it fails validation when "comment" is not a string', () => { + const payload: Omit & { comment: string[] } = { ...getCommentsMock(), comment: ['some value'], }; - const decoded = comments.decode(payload); + const decoded = comment.decode(payload); const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -68,12 +91,12 @@ describe('Comments', () => { expect(message.schema).toEqual({}); }); - test('it should not validate when "created_at" is not a string', () => { - const payload: Omit & { created_at: number } = { + test('it fails validation when "created_at" is not a string', () => { + const payload: Omit & { created_at: number } = { ...getCommentsMock(), created_at: 1, }; - const decoded = comments.decode(payload); + const decoded = comment.decode(payload); const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -82,12 +105,12 @@ describe('Comments', () => { expect(message.schema).toEqual({}); }); - test('it should not validate when "created_by" is not a string', () => { - const payload: Omit & { created_by: number } = { + test('it fails validation when "created_by" is not a string', () => { + const payload: Omit & { created_by: number } = { ...getCommentsMock(), created_by: 1, }; - const decoded = comments.decode(payload); + const decoded = comment.decode(payload); const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -96,12 +119,12 @@ describe('Comments', () => { expect(message.schema).toEqual({}); }); - test('it should not validate when "updated_at" is not a string', () => { - const payload: Omit & { updated_at: number } = { + test('it fails validation when "updated_at" is not a string', () => { + const payload: Omit & { updated_at: number } = { ...getCommentsMock(), updated_at: 1, }; - const decoded = comments.decode(payload); + const decoded = comment.decode(payload); const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -110,12 +133,12 @@ describe('Comments', () => { expect(message.schema).toEqual({}); }); - test('it should not validate when "updated_by" is not a string', () => { - const payload: Omit & { updated_by: number } = { + test('it fails validation when "updated_by" is not a string', () => { + const payload: Omit & { updated_by: number } = { ...getCommentsMock(), updated_by: 1, }; - const decoded = comments.decode(payload); + const decoded = comment.decode(payload); const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -125,11 +148,11 @@ describe('Comments', () => { }); test('it should strip out extra keys', () => { - const payload: Comments & { + const payload: Comment & { extraKey?: string; } = getCommentsMock(); payload.extraKey = 'some value'; - const decoded = comments.decode(payload); + const decoded = comment.decode(payload); const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -138,7 +161,7 @@ describe('Comments', () => { }); describe('commentsArray', () => { - test('it should validate an array of comments', () => { + test('it passes validation an array of Comment', () => { const payload = getCommentsArrayMock(); const decoded = commentsArray.decode(payload); const message = pipe(decoded, foldLeftRight); @@ -147,7 +170,7 @@ describe('Comments', () => { expect(message.schema).toEqual(payload); }); - test('it should validate when a comments includes "updated_at" and "updated_by"', () => { + test('it passes validation when a Comment includes "updated_at" and "updated_by"', () => { const commentsPayload = getCommentsMock(); commentsPayload.updated_at = DATE_NOW; commentsPayload.updated_by = 'someone'; @@ -159,32 +182,32 @@ describe('Comments', () => { expect(message.schema).toEqual(payload); }); - test('it should not validate when undefined', () => { + test('it fails validation when undefined', () => { const payload = undefined; const decoded = commentsArray.decode(payload); const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "undefined" supplied to "Array<({| comment: string, created_at: string, created_by: string |} & Partial<{| updated_at: string, updated_by: string |}>)>"', + 'Invalid value "undefined" supplied to "Array<({| comment: NonEmptyString, created_at: string, created_by: string, id: NonEmptyString |} & Partial<{| updated_at: string, updated_by: string |}>)>"', ]); expect(message.schema).toEqual({}); }); - test('it should not validate when array includes non comments types', () => { + test('it fails validation when array includes non Comment types', () => { const payload = ([1] as unknown) as CommentsArray; const decoded = commentsArray.decode(payload); const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "1" supplied to "Array<({| comment: string, created_at: string, created_by: string |} & Partial<{| updated_at: string, updated_by: string |}>)>"', - 'Invalid value "1" supplied to "Array<({| comment: string, created_at: string, created_by: string |} & Partial<{| updated_at: string, updated_by: string |}>)>"', + 'Invalid value "1" supplied to "Array<({| comment: NonEmptyString, created_at: string, created_by: string, id: NonEmptyString |} & Partial<{| updated_at: string, updated_by: string |}>)>"', + 'Invalid value "1" supplied to "Array<({| comment: NonEmptyString, created_at: string, created_by: string, id: NonEmptyString |} & Partial<{| updated_at: string, updated_by: string |}>)>"', ]); expect(message.schema).toEqual({}); }); }); describe('commentsArrayOrUndefined', () => { - test('it should validate an array of comments', () => { + test('it passes validation an array of Comment', () => { const payload = getCommentsArrayMock(); const decoded = commentsArrayOrUndefined.decode(payload); const message = pipe(decoded, foldLeftRight); @@ -193,7 +216,7 @@ describe('Comments', () => { expect(message.schema).toEqual(payload); }); - test('it should validate when undefined', () => { + test('it passes validation when undefined', () => { const payload = undefined; const decoded = commentsArrayOrUndefined.decode(payload); const message = pipe(decoded, foldLeftRight); @@ -202,14 +225,14 @@ describe('Comments', () => { expect(message.schema).toEqual(payload); }); - test('it should not validate when array includes non comments types', () => { + test('it fails validation when array includes non Comment types', () => { const payload = ([1] as unknown) as CommentsArrayOrUndefined; const decoded = commentsArray.decode(payload); const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "1" supplied to "Array<({| comment: string, created_at: string, created_by: string |} & Partial<{| updated_at: string, updated_by: string |}>)>"', - 'Invalid value "1" supplied to "Array<({| comment: string, created_at: string, created_by: string |} & Partial<{| updated_at: string, updated_by: string |}>)>"', + 'Invalid value "1" supplied to "Array<({| comment: NonEmptyString, created_at: string, created_by: string, id: NonEmptyString |} & Partial<{| updated_at: string, updated_by: string |}>)>"', + 'Invalid value "1" supplied to "Array<({| comment: NonEmptyString, created_at: string, created_by: string, id: NonEmptyString |} & Partial<{| updated_at: string, updated_by: string |}>)>"', ]); expect(message.schema).toEqual({}); }); diff --git a/x-pack/plugins/lists/common/schemas/types/comments.ts b/x-pack/plugins/lists/common/schemas/types/comment.ts similarity index 56% rename from x-pack/plugins/lists/common/schemas/types/comments.ts rename to x-pack/plugins/lists/common/schemas/types/comment.ts index 0ee3b05c8102f..6b0b0166b9ee1 100644 --- a/x-pack/plugins/lists/common/schemas/types/comments.ts +++ b/x-pack/plugins/lists/common/schemas/types/comment.ts @@ -3,26 +3,33 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ + +/* eslint-disable @typescript-eslint/camelcase */ + import * as t from 'io-ts'; -export const comments = t.intersection([ +import { NonEmptyString } from '../../siem_common_deps'; +import { created_at, created_by, id, updated_at, updated_by } from '../common/schemas'; + +export const comment = t.intersection([ t.exact( t.type({ - comment: t.string, - created_at: t.string, // TODO: Make this into an ISO Date string check, - created_by: t.string, + comment: NonEmptyString, + created_at, + created_by, + id, }) ), t.exact( t.partial({ - updated_at: t.string, - updated_by: t.string, + updated_at, + updated_by, }) ), ]); -export const commentsArray = t.array(comments); +export const commentsArray = t.array(comment); export type CommentsArray = t.TypeOf; -export type Comments = t.TypeOf; +export type Comment = t.TypeOf; export const commentsArrayOrUndefined = t.union([commentsArray, t.undefined]); export type CommentsArrayOrUndefined = t.TypeOf; diff --git a/x-pack/plugins/lists/common/schemas/types/create_comments.mock.ts b/x-pack/plugins/lists/common/schemas/types/create_comment.mock.ts similarity index 73% rename from x-pack/plugins/lists/common/schemas/types/create_comments.mock.ts rename to x-pack/plugins/lists/common/schemas/types/create_comment.mock.ts index 60a59432275ca..689d4ccdc2c2e 100644 --- a/x-pack/plugins/lists/common/schemas/types/create_comments.mock.ts +++ b/x-pack/plugins/lists/common/schemas/types/create_comment.mock.ts @@ -3,9 +3,9 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { CreateComments, CreateCommentsArray } from './create_comments'; +import { CreateComment, CreateCommentsArray } from './create_comment'; -export const getCreateCommentsMock = (): CreateComments => ({ +export const getCreateCommentsMock = (): CreateComment => ({ comment: 'some comments', }); diff --git a/x-pack/plugins/lists/common/schemas/types/create_comments.test.ts b/x-pack/plugins/lists/common/schemas/types/create_comment.test.ts similarity index 72% rename from x-pack/plugins/lists/common/schemas/types/create_comments.test.ts rename to x-pack/plugins/lists/common/schemas/types/create_comment.test.ts index d2680750e05e4..366bf84d48bbf 100644 --- a/x-pack/plugins/lists/common/schemas/types/create_comments.test.ts +++ b/x-pack/plugins/lists/common/schemas/types/create_comment.test.ts @@ -9,44 +9,44 @@ import { left } from 'fp-ts/lib/Either'; import { foldLeftRight, getPaths } from '../../siem_common_deps'; -import { getCreateCommentsArrayMock, getCreateCommentsMock } from './create_comments.mock'; +import { getCreateCommentsArrayMock, getCreateCommentsMock } from './create_comment.mock'; import { - CreateComments, + CreateComment, CreateCommentsArray, CreateCommentsArrayOrUndefined, - createComments, + createComment, createCommentsArray, createCommentsArrayOrUndefined, -} from './create_comments'; +} from './create_comment'; -describe('CreateComments', () => { - describe('createComments', () => { - test('it should validate a comments', () => { +describe('CreateComment', () => { + describe('createComment', () => { + test('it passes validation with a default comment', () => { const payload = getCreateCommentsMock(); - const decoded = createComments.decode(payload); + const decoded = createComment.decode(payload); const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); expect(message.schema).toEqual(payload); }); - test('it should not validate when undefined', () => { + test('it fails validation when undefined', () => { const payload = undefined; - const decoded = createComments.decode(payload); + const decoded = createComment.decode(payload); const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "undefined" supplied to "{| comment: string |}"', + 'Invalid value "undefined" supplied to "{| comment: NonEmptyString |}"', ]); expect(message.schema).toEqual({}); }); - test('it should not validate when "comment" is not a string', () => { - const payload: Omit & { comment: string[] } = { + test('it fails validation when "comment" is not a string', () => { + const payload: Omit & { comment: string[] } = { ...getCreateCommentsMock(), comment: ['some value'], }; - const decoded = createComments.decode(payload); + const decoded = createComment.decode(payload); const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -56,11 +56,11 @@ describe('CreateComments', () => { }); test('it should strip out extra keys', () => { - const payload: CreateComments & { + const payload: CreateComment & { extraKey?: string; } = getCreateCommentsMock(); payload.extraKey = 'some value'; - const decoded = createComments.decode(payload); + const decoded = createComment.decode(payload); const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -69,7 +69,7 @@ describe('CreateComments', () => { }); describe('createCommentsArray', () => { - test('it should validate an array of comments', () => { + test('it passes validation an array of comments', () => { const payload = getCreateCommentsArrayMock(); const decoded = createCommentsArray.decode(payload); const message = pipe(decoded, foldLeftRight); @@ -78,31 +78,31 @@ describe('CreateComments', () => { expect(message.schema).toEqual(payload); }); - test('it should not validate when undefined', () => { + test('it fails validation when undefined', () => { const payload = undefined; const decoded = createCommentsArray.decode(payload); const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "undefined" supplied to "Array<{| comment: string |}>"', + 'Invalid value "undefined" supplied to "Array<{| comment: NonEmptyString |}>"', ]); expect(message.schema).toEqual({}); }); - test('it should not validate when array includes non comments types', () => { + test('it fails validation when array includes non comments types', () => { const payload = ([1] as unknown) as CreateCommentsArray; const decoded = createCommentsArray.decode(payload); const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "1" supplied to "Array<{| comment: string |}>"', + 'Invalid value "1" supplied to "Array<{| comment: NonEmptyString |}>"', ]); expect(message.schema).toEqual({}); }); }); describe('createCommentsArrayOrUndefined', () => { - test('it should validate an array of comments', () => { + test('it passes validation an array of comments', () => { const payload = getCreateCommentsArrayMock(); const decoded = createCommentsArrayOrUndefined.decode(payload); const message = pipe(decoded, foldLeftRight); @@ -111,7 +111,7 @@ describe('CreateComments', () => { expect(message.schema).toEqual(payload); }); - test('it should validate when undefined', () => { + test('it passes validation when undefined', () => { const payload = undefined; const decoded = createCommentsArrayOrUndefined.decode(payload); const message = pipe(decoded, foldLeftRight); @@ -120,13 +120,13 @@ describe('CreateComments', () => { expect(message.schema).toEqual(payload); }); - test('it should not validate when array includes non comments types', () => { + test('it fails validation when array includes non comments types', () => { const payload = ([1] as unknown) as CreateCommentsArrayOrUndefined; const decoded = createCommentsArray.decode(payload); const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "1" supplied to "Array<{| comment: string |}>"', + 'Invalid value "1" supplied to "Array<{| comment: NonEmptyString |}>"', ]); expect(message.schema).toEqual({}); }); diff --git a/x-pack/plugins/lists/common/schemas/types/create_comments.ts b/x-pack/plugins/lists/common/schemas/types/create_comment.ts similarity index 64% rename from x-pack/plugins/lists/common/schemas/types/create_comments.ts rename to x-pack/plugins/lists/common/schemas/types/create_comment.ts index c34419298ef93..fd33313430ce6 100644 --- a/x-pack/plugins/lists/common/schemas/types/create_comments.ts +++ b/x-pack/plugins/lists/common/schemas/types/create_comment.ts @@ -5,14 +5,17 @@ */ import * as t from 'io-ts'; -export const createComments = t.exact( +import { NonEmptyString } from '../../siem_common_deps'; + +export const createComment = t.exact( t.type({ - comment: t.string, + comment: NonEmptyString, }) ); -export const createCommentsArray = t.array(createComments); +export type CreateComment = t.TypeOf; +export const createCommentsArray = t.array(createComment); export type CreateCommentsArray = t.TypeOf; -export type CreateComments = t.TypeOf; +export type CreateComments = t.TypeOf; export const createCommentsArrayOrUndefined = t.union([createCommentsArray, t.undefined]); export type CreateCommentsArrayOrUndefined = t.TypeOf; diff --git a/x-pack/plugins/lists/common/schemas/types/default_comments_array.test.ts b/x-pack/plugins/lists/common/schemas/types/default_comments_array.test.ts index 3a4241aaec82d..541b8ab1c799c 100644 --- a/x-pack/plugins/lists/common/schemas/types/default_comments_array.test.ts +++ b/x-pack/plugins/lists/common/schemas/types/default_comments_array.test.ts @@ -10,11 +10,11 @@ import { left } from 'fp-ts/lib/Either'; import { foldLeftRight, getPaths } from '../../siem_common_deps'; import { DefaultCommentsArray } from './default_comments_array'; -import { CommentsArray } from './comments'; -import { getCommentsArrayMock } from './comments.mock'; +import { CommentsArray } from './comment'; +import { getCommentsArrayMock } from './comment.mock'; describe('default_comments_array', () => { - test('it should validate an empty array', () => { + test('it should pass validation when supplied an empty array', () => { const payload: CommentsArray = []; const decoded = DefaultCommentsArray.decode(payload); const message = pipe(decoded, foldLeftRight); @@ -23,7 +23,7 @@ describe('default_comments_array', () => { expect(message.schema).toEqual(payload); }); - test('it should validate an array of comments', () => { + test('it should pass validation when supplied an array of comments', () => { const payload: CommentsArray = getCommentsArrayMock(); const decoded = DefaultCommentsArray.decode(payload); const message = pipe(decoded, foldLeftRight); @@ -32,27 +32,26 @@ describe('default_comments_array', () => { expect(message.schema).toEqual(payload); }); - test('it should NOT validate an array of numbers', () => { + test('it should fail validation when supplied an array of numbers', () => { const payload = [1]; const decoded = DefaultCommentsArray.decode(payload); const message = pipe(decoded, foldLeftRight); - // TODO: Known weird error formatting that is on our list to address expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "1" supplied to "Array<({| comment: string, created_at: string, created_by: string |} & Partial<{| updated_at: string, updated_by: string |}>)>"', - 'Invalid value "1" supplied to "Array<({| comment: string, created_at: string, created_by: string |} & Partial<{| updated_at: string, updated_by: string |}>)>"', + 'Invalid value "1" supplied to "Array<({| comment: NonEmptyString, created_at: string, created_by: string, id: NonEmptyString |} & Partial<{| updated_at: string, updated_by: string |}>)>"', + 'Invalid value "1" supplied to "Array<({| comment: NonEmptyString, created_at: string, created_by: string, id: NonEmptyString |} & Partial<{| updated_at: string, updated_by: string |}>)>"', ]); expect(message.schema).toEqual({}); }); - test('it should NOT validate an array of strings', () => { + test('it should fail validation when supplied an array of strings', () => { const payload = ['some string']; const decoded = DefaultCommentsArray.decode(payload); const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "some string" supplied to "Array<({| comment: string, created_at: string, created_by: string |} & Partial<{| updated_at: string, updated_by: string |}>)>"', - 'Invalid value "some string" supplied to "Array<({| comment: string, created_at: string, created_by: string |} & Partial<{| updated_at: string, updated_by: string |}>)>"', + 'Invalid value "some string" supplied to "Array<({| comment: NonEmptyString, created_at: string, created_by: string, id: NonEmptyString |} & Partial<{| updated_at: string, updated_by: string |}>)>"', + 'Invalid value "some string" supplied to "Array<({| comment: NonEmptyString, created_at: string, created_by: string, id: NonEmptyString |} & Partial<{| updated_at: string, updated_by: string |}>)>"', ]); expect(message.schema).toEqual({}); }); diff --git a/x-pack/plugins/lists/common/schemas/types/default_comments_array.ts b/x-pack/plugins/lists/common/schemas/types/default_comments_array.ts index 342cf8b0d7091..0d7e28e69cf71 100644 --- a/x-pack/plugins/lists/common/schemas/types/default_comments_array.ts +++ b/x-pack/plugins/lists/common/schemas/types/default_comments_array.ts @@ -7,7 +7,7 @@ import * as t from 'io-ts'; import { Either } from 'fp-ts/lib/Either'; -import { CommentsArray, comments } from './comments'; +import { CommentsArray, comment } from './comment'; /** * Types the DefaultCommentsArray as: @@ -15,8 +15,8 @@ import { CommentsArray, comments } from './comments'; */ export const DefaultCommentsArray = new t.Type( 'DefaultCommentsArray', - t.array(comments).is, + t.array(comment).is, (input): Either => - input == null ? t.success([]) : t.array(comments).decode(input), + input == null ? t.success([]) : t.array(comment).decode(input), t.identity ); diff --git a/x-pack/plugins/lists/common/schemas/types/default_create_comments_array.test.ts b/x-pack/plugins/lists/common/schemas/types/default_create_comments_array.test.ts index f5ef7d0ad96bd..eb960b5411904 100644 --- a/x-pack/plugins/lists/common/schemas/types/default_create_comments_array.test.ts +++ b/x-pack/plugins/lists/common/schemas/types/default_create_comments_array.test.ts @@ -10,11 +10,12 @@ import { left } from 'fp-ts/lib/Either'; import { foldLeftRight, getPaths } from '../../siem_common_deps'; import { DefaultCreateCommentsArray } from './default_create_comments_array'; -import { CreateCommentsArray } from './create_comments'; -import { getCreateCommentsArrayMock } from './create_comments.mock'; +import { CreateCommentsArray } from './create_comment'; +import { getCreateCommentsArrayMock } from './create_comment.mock'; +import { getCommentsArrayMock } from './comment.mock'; describe('default_create_comments_array', () => { - test('it should validate an empty array', () => { + test('it should pass validation when an empty array', () => { const payload: CreateCommentsArray = []; const decoded = DefaultCreateCommentsArray.decode(payload); const message = pipe(decoded, foldLeftRight); @@ -23,7 +24,7 @@ describe('default_create_comments_array', () => { expect(message.schema).toEqual(payload); }); - test('it should validate an array of comments', () => { + test('it should pass validation when an array of comments', () => { const payload: CreateCommentsArray = getCreateCommentsArrayMock(); const decoded = DefaultCreateCommentsArray.decode(payload); const message = pipe(decoded, foldLeftRight); @@ -32,25 +33,38 @@ describe('default_create_comments_array', () => { expect(message.schema).toEqual(payload); }); - test('it should NOT validate an array of numbers', () => { + test('it should strip out "created_at" and "created_by" if they are passed in', () => { + const payload = getCommentsArrayMock(); + const decoded = DefaultCreateCommentsArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + // TODO: Known weird error formatting that is on our list to address + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual([ + { comment: 'some old comment' }, + { comment: 'some old comment' }, + ]); + }); + + test('it should not pass validation when an array of numbers', () => { const payload = [1]; const decoded = DefaultCreateCommentsArray.decode(payload); const message = pipe(decoded, foldLeftRight); // TODO: Known weird error formatting that is on our list to address expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "1" supplied to "Array<{| comment: string |}>"', + 'Invalid value "1" supplied to "Array<{| comment: NonEmptyString |}>"', ]); expect(message.schema).toEqual({}); }); - test('it should NOT validate an array of strings', () => { + test('it should not pass validation when an array of strings', () => { const payload = ['some string']; const decoded = DefaultCreateCommentsArray.decode(payload); const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "some string" supplied to "Array<{| comment: string |}>"', + 'Invalid value "some string" supplied to "Array<{| comment: NonEmptyString |}>"', ]); expect(message.schema).toEqual({}); }); diff --git a/x-pack/plugins/lists/common/schemas/types/default_create_comments_array.ts b/x-pack/plugins/lists/common/schemas/types/default_create_comments_array.ts index 7fd79782836e3..4df888ba728fb 100644 --- a/x-pack/plugins/lists/common/schemas/types/default_create_comments_array.ts +++ b/x-pack/plugins/lists/common/schemas/types/default_create_comments_array.ts @@ -7,7 +7,7 @@ import * as t from 'io-ts'; import { Either } from 'fp-ts/lib/Either'; -import { CreateCommentsArray, createComments } from './create_comments'; +import { CreateCommentsArray, createComment } from './create_comment'; /** * Types the DefaultCreateComments as: @@ -19,8 +19,8 @@ export const DefaultCreateCommentsArray = new t.Type< unknown >( 'DefaultCreateComments', - t.array(createComments).is, + t.array(createComment).is, (input): Either => - input == null ? t.success([]) : t.array(createComments).decode(input), + input == null ? t.success([]) : t.array(createComment).decode(input), t.identity ); diff --git a/x-pack/plugins/lists/common/schemas/types/default_update_comments_array.test.ts b/x-pack/plugins/lists/common/schemas/types/default_update_comments_array.test.ts index b023e73cb9328..612148dc4ccab 100644 --- a/x-pack/plugins/lists/common/schemas/types/default_update_comments_array.test.ts +++ b/x-pack/plugins/lists/common/schemas/types/default_update_comments_array.test.ts @@ -10,11 +10,11 @@ import { left } from 'fp-ts/lib/Either'; import { foldLeftRight, getPaths } from '../../siem_common_deps'; import { DefaultUpdateCommentsArray } from './default_update_comments_array'; -import { UpdateCommentsArray } from './update_comments'; -import { getUpdateCommentsArrayMock } from './update_comments.mock'; +import { UpdateCommentsArray } from './update_comment'; +import { getUpdateCommentsArrayMock } from './update_comment.mock'; describe('default_update_comments_array', () => { - test('it should validate an empty array', () => { + test('it should pass validation when supplied an empty array', () => { const payload: UpdateCommentsArray = []; const decoded = DefaultUpdateCommentsArray.decode(payload); const message = pipe(decoded, foldLeftRight); @@ -23,7 +23,7 @@ describe('default_update_comments_array', () => { expect(message.schema).toEqual(payload); }); - test('it should validate an array of comments', () => { + test('it should pass validation when supplied an array of comments', () => { const payload: UpdateCommentsArray = getUpdateCommentsArrayMock(); const decoded = DefaultUpdateCommentsArray.decode(payload); const message = pipe(decoded, foldLeftRight); @@ -32,29 +32,26 @@ describe('default_update_comments_array', () => { expect(message.schema).toEqual(payload); }); - test('it should NOT validate an array of numbers', () => { + test('it should fail validation when supplied an array of numbers', () => { const payload = [1]; const decoded = DefaultUpdateCommentsArray.decode(payload); const message = pipe(decoded, foldLeftRight); - // TODO: Known weird error formatting that is on our list to address expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "1" supplied to "Array<(({| comment: string, created_at: string, created_by: string |} & Partial<{| updated_at: string, updated_by: string |}>) | {| comment: string |})>"', - 'Invalid value "1" supplied to "Array<(({| comment: string, created_at: string, created_by: string |} & Partial<{| updated_at: string, updated_by: string |}>) | {| comment: string |})>"', - 'Invalid value "1" supplied to "Array<(({| comment: string, created_at: string, created_by: string |} & Partial<{| updated_at: string, updated_by: string |}>) | {| comment: string |})>"', + 'Invalid value "1" supplied to "Array<({| comment: NonEmptyString |} & Partial<{| id: NonEmptyString |}>)>"', + 'Invalid value "1" supplied to "Array<({| comment: NonEmptyString |} & Partial<{| id: NonEmptyString |}>)>"', ]); expect(message.schema).toEqual({}); }); - test('it should NOT validate an array of strings', () => { + test('it should fail validation when supplied an array of strings', () => { const payload = ['some string']; const decoded = DefaultUpdateCommentsArray.decode(payload); const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "some string" supplied to "Array<(({| comment: string, created_at: string, created_by: string |} & Partial<{| updated_at: string, updated_by: string |}>) | {| comment: string |})>"', - 'Invalid value "some string" supplied to "Array<(({| comment: string, created_at: string, created_by: string |} & Partial<{| updated_at: string, updated_by: string |}>) | {| comment: string |})>"', - 'Invalid value "some string" supplied to "Array<(({| comment: string, created_at: string, created_by: string |} & Partial<{| updated_at: string, updated_by: string |}>) | {| comment: string |})>"', + 'Invalid value "some string" supplied to "Array<({| comment: NonEmptyString |} & Partial<{| id: NonEmptyString |}>)>"', + 'Invalid value "some string" supplied to "Array<({| comment: NonEmptyString |} & Partial<{| id: NonEmptyString |}>)>"', ]); expect(message.schema).toEqual({}); }); diff --git a/x-pack/plugins/lists/common/schemas/types/default_update_comments_array.ts b/x-pack/plugins/lists/common/schemas/types/default_update_comments_array.ts index 854b7cf7ada7e..35338dae64387 100644 --- a/x-pack/plugins/lists/common/schemas/types/default_update_comments_array.ts +++ b/x-pack/plugins/lists/common/schemas/types/default_update_comments_array.ts @@ -7,7 +7,7 @@ import * as t from 'io-ts'; import { Either } from 'fp-ts/lib/Either'; -import { UpdateCommentsArray, updateCommentsArray } from './update_comments'; +import { UpdateCommentsArray, updateCommentsArray } from './update_comment'; /** * Types the DefaultCommentsUpdate as: diff --git a/x-pack/plugins/lists/common/schemas/types/entries.mock.ts b/x-pack/plugins/lists/common/schemas/types/entries.mock.ts index 3ed3f4e7ff88f..16794415138b2 100644 --- a/x-pack/plugins/lists/common/schemas/types/entries.mock.ts +++ b/x-pack/plugins/lists/common/schemas/types/entries.mock.ts @@ -11,10 +11,22 @@ import { getEntryListMock } from './entry_list.mock'; import { getEntryExistsMock } from './entry_exists.mock'; import { getEntryNestedMock } from './entry_nested.mock'; -export const getEntriesArrayMock = (): EntriesArray => [ +export const getListAndNonListEntriesArrayMock = (): EntriesArray => [ { ...getEntryMatchMock() }, { ...getEntryMatchAnyMock() }, { ...getEntryListMock() }, { ...getEntryExistsMock() }, { ...getEntryNestedMock() }, ]; + +export const getListEntriesArrayMock = (): EntriesArray => [ + { ...getEntryListMock() }, + { ...getEntryListMock() }, +]; + +export const getEntriesArrayMock = (): EntriesArray => [ + { ...getEntryMatchMock() }, + { ...getEntryMatchAnyMock() }, + { ...getEntryExistsMock() }, + { ...getEntryNestedMock() }, +]; diff --git a/x-pack/plugins/lists/common/schemas/types/index.ts b/x-pack/plugins/lists/common/schemas/types/index.ts index 463f7cfe51ce3..6b7e9fd17a1af 100644 --- a/x-pack/plugins/lists/common/schemas/types/index.ts +++ b/x-pack/plugins/lists/common/schemas/types/index.ts @@ -3,9 +3,9 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -export * from './comments'; -export * from './create_comments'; -export * from './update_comments'; +export * from './comment'; +export * from './create_comment'; +export * from './update_comment'; export * from './default_comments_array'; export * from './default_create_comments_array'; export * from './default_update_comments_array'; diff --git a/x-pack/plugins/lists/common/schemas/types/non_empty_entries_array.test.ts b/x-pack/plugins/lists/common/schemas/types/non_empty_entries_array.test.ts index ab7002982cf28..a2697286aa038 100644 --- a/x-pack/plugins/lists/common/schemas/types/non_empty_entries_array.test.ts +++ b/x-pack/plugins/lists/common/schemas/types/non_empty_entries_array.test.ts @@ -11,10 +11,13 @@ import { foldLeftRight, getPaths } from '../../siem_common_deps'; import { getEntryMatchMock } from './entry_match.mock'; import { getEntryMatchAnyMock } from './entry_match_any.mock'; -import { getEntryListMock } from './entry_list.mock'; import { getEntryExistsMock } from './entry_exists.mock'; import { getEntryNestedMock } from './entry_nested.mock'; -import { getEntriesArrayMock } from './entries.mock'; +import { + getEntriesArrayMock, + getListAndNonListEntriesArrayMock, + getListEntriesArrayMock, +} from './entries.mock'; import { nonEmptyEntriesArray } from './non_empty_entries_array'; import { EntriesArray } from './entries'; @@ -80,7 +83,7 @@ describe('non_empty_entries_array', () => { }); test('it should validate an array of "list" entries', () => { - const payload: EntriesArray = [{ ...getEntryListMock() }, { ...getEntryListMock() }]; + const payload: EntriesArray = [...getListEntriesArrayMock()]; const decoded = nonEmptyEntriesArray.decode(payload); const message = pipe(decoded, foldLeftRight); @@ -106,6 +109,15 @@ describe('non_empty_entries_array', () => { expect(message.schema).toEqual(payload); }); + test('it should NOT validate an array of entries of value list and non-value list entries', () => { + const payload: EntriesArray = [...getListAndNonListEntriesArrayMock()]; + const decoded = nonEmptyEntriesArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Cannot have entry of type list and other']); + expect(message.schema).toEqual({}); + }); + test('it should NOT validate an array of non entries', () => { const payload = [1]; const decoded = nonEmptyEntriesArray.decode(payload); diff --git a/x-pack/plugins/lists/common/schemas/types/non_empty_entries_array.ts b/x-pack/plugins/lists/common/schemas/types/non_empty_entries_array.ts index 1370fe022c258..3683ca97dedb8 100644 --- a/x-pack/plugins/lists/common/schemas/types/non_empty_entries_array.ts +++ b/x-pack/plugins/lists/common/schemas/types/non_empty_entries_array.ts @@ -8,6 +8,7 @@ import * as t from 'io-ts'; import { Either } from 'fp-ts/lib/Either'; import { EntriesArray, entriesArray } from './entries'; +import { entriesList } from './entry_list'; /** * Types the nonEmptyEntriesArray as: @@ -21,6 +22,14 @@ export const nonEmptyEntriesArray = new t.Type entriesList.is(entry)) && + input.some((entry) => !entriesList.is(entry)) + ) { + // fail when an exception item contains both a value list entry and a non-value list entry + return t.failure(input, context, 'Cannot have entry of type list and other'); + } return entriesArray.validate(input, context); } }, diff --git a/x-pack/plugins/lists/common/schemas/types/update_comments.mock.ts b/x-pack/plugins/lists/common/schemas/types/update_comment.mock.ts similarity index 54% rename from x-pack/plugins/lists/common/schemas/types/update_comments.mock.ts rename to x-pack/plugins/lists/common/schemas/types/update_comment.mock.ts index 3e963c2607dc5..9b85a24abe40b 100644 --- a/x-pack/plugins/lists/common/schemas/types/update_comments.mock.ts +++ b/x-pack/plugins/lists/common/schemas/types/update_comment.mock.ts @@ -4,11 +4,16 @@ * you may not use this file except in compliance with the Elastic License. */ -import { getCommentsMock } from './comments.mock'; -import { getCreateCommentsMock } from './create_comments.mock'; -import { UpdateCommentsArray } from './update_comments'; +import { ID } from '../../constants.mock'; + +import { UpdateComment, UpdateCommentsArray } from './update_comment'; + +export const getUpdateCommentMock = (): UpdateComment => ({ + comment: 'some comment', + id: ID, +}); export const getUpdateCommentsArrayMock = (): UpdateCommentsArray => [ - getCommentsMock(), - getCreateCommentsMock(), + getUpdateCommentMock(), + getUpdateCommentMock(), ]; diff --git a/x-pack/plugins/lists/common/schemas/types/update_comment.test.ts b/x-pack/plugins/lists/common/schemas/types/update_comment.test.ts new file mode 100644 index 0000000000000..ac7716af40966 --- /dev/null +++ b/x-pack/plugins/lists/common/schemas/types/update_comment.test.ts @@ -0,0 +1,150 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { pipe } from 'fp-ts/lib/pipeable'; +import { left } from 'fp-ts/lib/Either'; + +import { foldLeftRight, getPaths } from '../../siem_common_deps'; + +import { getUpdateCommentMock, getUpdateCommentsArrayMock } from './update_comment.mock'; +import { + UpdateComment, + UpdateCommentsArray, + UpdateCommentsArrayOrUndefined, + updateComment, + updateCommentsArray, + updateCommentsArrayOrUndefined, +} from './update_comment'; + +describe('CommentsUpdate', () => { + describe('updateComment', () => { + test('it should pass validation when supplied typical comment update', () => { + const payload = getUpdateCommentMock(); + const decoded = updateComment.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should fail validation when supplied an undefined for "comment"', () => { + const payload = getUpdateCommentMock(); + delete payload.comment; + const decoded = updateComment.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "comment"', + ]); + expect(message.schema).toEqual({}); + }); + + test('it should fail validation when supplied an empty string for "comment"', () => { + const payload = { ...getUpdateCommentMock(), comment: '' }; + const decoded = updateComment.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "" supplied to "comment"']); + expect(message.schema).toEqual({}); + }); + + test('it should pass validation when supplied an undefined for "id"', () => { + const payload = getUpdateCommentMock(); + delete payload.id; + const decoded = updateComment.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should fail validation when supplied an empty string for "id"', () => { + const payload = { ...getUpdateCommentMock(), id: '' }; + const decoded = updateComment.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual(['Invalid value "" supplied to "id"']); + expect(message.schema).toEqual({}); + }); + + test('it should strip out extra key passed in', () => { + const payload: UpdateComment & { + extraKey?: string; + } = { ...getUpdateCommentMock(), extraKey: 'some new value' }; + const decoded = updateComment.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(getUpdateCommentMock()); + }); + }); + + describe('updateCommentsArray', () => { + test('it should pass validation when supplied an array of comments', () => { + const payload = getUpdateCommentsArrayMock(); + const decoded = updateCommentsArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should fail validation when undefined', () => { + const payload = undefined; + const decoded = updateCommentsArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "Array<({| comment: NonEmptyString |} & Partial<{| id: NonEmptyString |}>)>"', + ]); + expect(message.schema).toEqual({}); + }); + + test('it should fail validation when array includes non comments types', () => { + const payload = ([1] as unknown) as UpdateCommentsArray; + const decoded = updateCommentsArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "1" supplied to "Array<({| comment: NonEmptyString |} & Partial<{| id: NonEmptyString |}>)>"', + 'Invalid value "1" supplied to "Array<({| comment: NonEmptyString |} & Partial<{| id: NonEmptyString |}>)>"', + ]); + expect(message.schema).toEqual({}); + }); + }); + + describe('updateCommentsArrayOrUndefined', () => { + test('it should pass validation when supplied an array of comments', () => { + const payload = getUpdateCommentsArrayMock(); + const decoded = updateCommentsArrayOrUndefined.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should pass validation when supplied when undefined', () => { + const payload = undefined; + const decoded = updateCommentsArrayOrUndefined.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should fail validation when array includes non comments types', () => { + const payload = ([1] as unknown) as UpdateCommentsArrayOrUndefined; + const decoded = updateCommentsArray.decode(payload); + const message = pipe(decoded, foldLeftRight); + + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "1" supplied to "Array<({| comment: NonEmptyString |} & Partial<{| id: NonEmptyString |}>)>"', + 'Invalid value "1" supplied to "Array<({| comment: NonEmptyString |} & Partial<{| id: NonEmptyString |}>)>"', + ]); + expect(message.schema).toEqual({}); + }); + }); +}); diff --git a/x-pack/plugins/lists/common/schemas/types/update_comments.ts b/x-pack/plugins/lists/common/schemas/types/update_comment.ts similarity index 58% rename from x-pack/plugins/lists/common/schemas/types/update_comments.ts rename to x-pack/plugins/lists/common/schemas/types/update_comment.ts index 4a21bfa363d45..b95812cb35bf9 100644 --- a/x-pack/plugins/lists/common/schemas/types/update_comments.ts +++ b/x-pack/plugins/lists/common/schemas/types/update_comment.ts @@ -5,10 +5,24 @@ */ import * as t from 'io-ts'; -import { comments } from './comments'; -import { createComments } from './create_comments'; +import { NonEmptyString } from '../../siem_common_deps'; +import { id } from '../common/schemas'; -export const updateCommentsArray = t.array(t.union([comments, createComments])); +export const updateComment = t.intersection([ + t.exact( + t.type({ + comment: NonEmptyString, + }) + ), + t.exact( + t.partial({ + id, + }) + ), +]); + +export type UpdateComment = t.TypeOf; +export const updateCommentsArray = t.array(updateComment); export type UpdateCommentsArray = t.TypeOf; export const updateCommentsArrayOrUndefined = t.union([updateCommentsArray, t.undefined]); export type UpdateCommentsArrayOrUndefined = t.TypeOf; diff --git a/x-pack/plugins/lists/common/schemas/types/update_comments.test.ts b/x-pack/plugins/lists/common/schemas/types/update_comments.test.ts deleted file mode 100644 index 7668504b031b5..0000000000000 --- a/x-pack/plugins/lists/common/schemas/types/update_comments.test.ts +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { pipe } from 'fp-ts/lib/pipeable'; -import { left } from 'fp-ts/lib/Either'; - -import { foldLeftRight, getPaths } from '../../siem_common_deps'; - -import { getUpdateCommentsArrayMock } from './update_comments.mock'; -import { - UpdateCommentsArray, - UpdateCommentsArrayOrUndefined, - updateCommentsArray, - updateCommentsArrayOrUndefined, -} from './update_comments'; -import { getCommentsMock } from './comments.mock'; -import { getCreateCommentsMock } from './create_comments.mock'; - -describe('CommentsUpdate', () => { - describe('updateCommentsArray', () => { - test('it should validate an array of comments', () => { - const payload = getUpdateCommentsArrayMock(); - const decoded = updateCommentsArray.decode(payload); - const message = pipe(decoded, foldLeftRight); - - expect(getPaths(left(message.errors))).toEqual([]); - expect(message.schema).toEqual(payload); - }); - - test('it should validate an array of existing comments', () => { - const payload = [getCommentsMock()]; - const decoded = updateCommentsArray.decode(payload); - const message = pipe(decoded, foldLeftRight); - - expect(getPaths(left(message.errors))).toEqual([]); - expect(message.schema).toEqual(payload); - }); - - test('it should validate an array of new comments', () => { - const payload = [getCreateCommentsMock()]; - const decoded = updateCommentsArray.decode(payload); - const message = pipe(decoded, foldLeftRight); - - expect(getPaths(left(message.errors))).toEqual([]); - expect(message.schema).toEqual(payload); - }); - - test('it should not validate when undefined', () => { - const payload = undefined; - const decoded = updateCommentsArray.decode(payload); - const message = pipe(decoded, foldLeftRight); - - expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "undefined" supplied to "Array<(({| comment: string, created_at: string, created_by: string |} & Partial<{| updated_at: string, updated_by: string |}>) | {| comment: string |})>"', - ]); - expect(message.schema).toEqual({}); - }); - - test('it should not validate when array includes non comments types', () => { - const payload = ([1] as unknown) as UpdateCommentsArray; - const decoded = updateCommentsArray.decode(payload); - const message = pipe(decoded, foldLeftRight); - - expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "1" supplied to "Array<(({| comment: string, created_at: string, created_by: string |} & Partial<{| updated_at: string, updated_by: string |}>) | {| comment: string |})>"', - 'Invalid value "1" supplied to "Array<(({| comment: string, created_at: string, created_by: string |} & Partial<{| updated_at: string, updated_by: string |}>) | {| comment: string |})>"', - 'Invalid value "1" supplied to "Array<(({| comment: string, created_at: string, created_by: string |} & Partial<{| updated_at: string, updated_by: string |}>) | {| comment: string |})>"', - ]); - expect(message.schema).toEqual({}); - }); - }); - - describe('updateCommentsArrayOrUndefined', () => { - test('it should validate an array of comments', () => { - const payload = getUpdateCommentsArrayMock(); - const decoded = updateCommentsArrayOrUndefined.decode(payload); - const message = pipe(decoded, foldLeftRight); - - expect(getPaths(left(message.errors))).toEqual([]); - expect(message.schema).toEqual(payload); - }); - - test('it should validate when undefined', () => { - const payload = undefined; - const decoded = updateCommentsArrayOrUndefined.decode(payload); - const message = pipe(decoded, foldLeftRight); - - expect(getPaths(left(message.errors))).toEqual([]); - expect(message.schema).toEqual(payload); - }); - - test('it should not validate when array includes non comments types', () => { - const payload = ([1] as unknown) as UpdateCommentsArrayOrUndefined; - const decoded = updateCommentsArray.decode(payload); - const message = pipe(decoded, foldLeftRight); - - expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "1" supplied to "Array<(({| comment: string, created_at: string, created_by: string |} & Partial<{| updated_at: string, updated_by: string |}>) | {| comment: string |})>"', - 'Invalid value "1" supplied to "Array<(({| comment: string, created_at: string, created_by: string |} & Partial<{| updated_at: string, updated_by: string |}>) | {| comment: string |})>"', - 'Invalid value "1" supplied to "Array<(({| comment: string, created_at: string, created_by: string |} & Partial<{| updated_at: string, updated_by: string |}>) | {| comment: string |})>"', - ]); - expect(message.schema).toEqual({}); - }); - }); -}); diff --git a/x-pack/plugins/lists/common/shared_exports.ts b/x-pack/plugins/lists/common/shared_exports.ts index dc0a9aa5926ef..1f6c65919b063 100644 --- a/x-pack/plugins/lists/common/shared_exports.ts +++ b/x-pack/plugins/lists/common/shared_exports.ts @@ -8,8 +8,8 @@ export { ListSchema, CommentsArray, CreateCommentsArray, - Comments, - CreateComments, + Comment, + CreateComment, ExceptionListSchema, ExceptionListItemSchema, CreateExceptionListSchema, @@ -28,6 +28,7 @@ export { OperatorType, OperatorTypeEnum, ExceptionListTypeEnum, + comment, exceptionListItemSchema, exceptionListType, createExceptionListItemSchema, diff --git a/x-pack/plugins/lists/public/exceptions/api.test.ts b/x-pack/plugins/lists/public/exceptions/api.test.ts index 455670098307f..9add15c533d14 100644 --- a/x-pack/plugins/lists/public/exceptions/api.test.ts +++ b/x-pack/plugins/lists/public/exceptions/api.test.ts @@ -26,7 +26,7 @@ import { deleteExceptionListItemById, fetchExceptionListById, fetchExceptionListItemById, - fetchExceptionListItemsByListId, + fetchExceptionListsItemsByListIds, updateExceptionList, updateExceptionListItem, } from './api'; @@ -358,17 +358,18 @@ describe('Exceptions Lists API', () => { }); }); - describe('#fetchExceptionListItemsByListId', () => { + describe('#fetchExceptionListsItemsByListIds', () => { beforeEach(() => { fetchMock.mockClear(); fetchMock.mockResolvedValue(getFoundExceptionListItemSchemaMock()); }); - test('it invokes "fetchExceptionListItemsByListId" with expected url and body values', async () => { - await fetchExceptionListItemsByListId({ + test('it invokes "fetchExceptionListsItemsByListIds" with expected url and body values', async () => { + await fetchExceptionListsItemsByListIds({ + filterOptions: [], http: mockKibanaHttpService(), - listId: 'myList', - namespaceType: 'single', + listIds: ['myList', 'myOtherListId'], + namespaceTypes: ['single', 'single'], pagination: { page: 1, perPage: 20, @@ -379,8 +380,8 @@ describe('Exceptions Lists API', () => { expect(fetchMock).toHaveBeenCalledWith('/api/exception_lists/items/_find', { method: 'GET', query: { - list_id: 'myList', - namespace_type: 'single', + list_id: 'myList,myOtherListId', + namespace_type: 'single,single', page: '1', per_page: '20', }, @@ -389,14 +390,16 @@ describe('Exceptions Lists API', () => { }); test('it invokes with expected url and body values when a filter exists and "namespaceType" of "single"', async () => { - await fetchExceptionListItemsByListId({ - filterOptions: { - filter: 'hello world', - tags: [], - }, + await fetchExceptionListsItemsByListIds({ + filterOptions: [ + { + filter: 'hello world', + tags: [], + }, + ], http: mockKibanaHttpService(), - listId: 'myList', - namespaceType: 'single', + listIds: ['myList'], + namespaceTypes: ['single'], pagination: { page: 1, perPage: 20, @@ -418,14 +421,16 @@ describe('Exceptions Lists API', () => { }); test('it invokes with expected url and body values when a filter exists and "namespaceType" of "agnostic"', async () => { - await fetchExceptionListItemsByListId({ - filterOptions: { - filter: 'hello world', - tags: [], - }, + await fetchExceptionListsItemsByListIds({ + filterOptions: [ + { + filter: 'hello world', + tags: [], + }, + ], http: mockKibanaHttpService(), - listId: 'myList', - namespaceType: 'agnostic', + listIds: ['myList'], + namespaceTypes: ['agnostic'], pagination: { page: 1, perPage: 20, @@ -447,14 +452,16 @@ describe('Exceptions Lists API', () => { }); test('it invokes with expected url and body values when tags exists', async () => { - await fetchExceptionListItemsByListId({ - filterOptions: { - filter: '', - tags: ['malware'], - }, + await fetchExceptionListsItemsByListIds({ + filterOptions: [ + { + filter: '', + tags: ['malware'], + }, + ], http: mockKibanaHttpService(), - listId: 'myList', - namespaceType: 'agnostic', + listIds: ['myList'], + namespaceTypes: ['agnostic'], pagination: { page: 1, perPage: 20, @@ -476,14 +483,16 @@ describe('Exceptions Lists API', () => { }); test('it invokes with expected url and body values when filter and tags exists', async () => { - await fetchExceptionListItemsByListId({ - filterOptions: { - filter: 'host.name', - tags: ['malware'], - }, + await fetchExceptionListsItemsByListIds({ + filterOptions: [ + { + filter: 'host.name', + tags: ['malware'], + }, + ], http: mockKibanaHttpService(), - listId: 'myList', - namespaceType: 'agnostic', + listIds: ['myList'], + namespaceTypes: ['agnostic'], pagination: { page: 1, perPage: 20, @@ -506,10 +515,11 @@ describe('Exceptions Lists API', () => { }); test('it returns expected format when call succeeds', async () => { - const exceptionResponse = await fetchExceptionListItemsByListId({ + const exceptionResponse = await fetchExceptionListsItemsByListIds({ + filterOptions: [], http: mockKibanaHttpService(), - listId: 'endpoint_list_id', - namespaceType: 'single', + listIds: ['endpoint_list_id'], + namespaceTypes: ['single'], pagination: { page: 1, perPage: 20, @@ -521,16 +531,17 @@ describe('Exceptions Lists API', () => { test('it returns error and does not make request if request payload fails decode', async () => { const payload = ({ + filterOptions: [], http: mockKibanaHttpService(), - listId: '1', - namespaceType: 'not a namespace type', + listIds: ['myList'], + namespaceTypes: ['not a namespace type'], pagination: { page: 1, perPage: 20, }, signal: abortCtrl.signal, } as unknown) as ApiCallByListIdProps & { listId: number }; - await expect(fetchExceptionListItemsByListId(payload)).rejects.toEqual( + await expect(fetchExceptionListsItemsByListIds(payload)).rejects.toEqual( 'Invalid value "not a namespace type" supplied to "namespace_type"' ); }); @@ -541,10 +552,11 @@ describe('Exceptions Lists API', () => { fetchMock.mockResolvedValue(badPayload); await expect( - fetchExceptionListItemsByListId({ + fetchExceptionListsItemsByListIds({ + filterOptions: [], http: mockKibanaHttpService(), - listId: 'myList', - namespaceType: 'single', + listIds: ['myList'], + namespaceTypes: ['single'], pagination: { page: 1, perPage: 20, diff --git a/x-pack/plugins/lists/public/exceptions/api.ts b/x-pack/plugins/lists/public/exceptions/api.ts index 4d9397ec0adc6..d661cb103fad8 100644 --- a/x-pack/plugins/lists/public/exceptions/api.ts +++ b/x-pack/plugins/lists/public/exceptions/api.ts @@ -249,42 +249,46 @@ export const fetchExceptionListById = async ({ * Fetch an ExceptionList's ExceptionItems by providing a ExceptionList list_id * * @param http Kibana http service - * @param listId ExceptionList list_id (not ID) - * @param namespaceType ExceptionList namespace_type + * @param listIds ExceptionList list_ids (not ID) + * @param namespaceTypes ExceptionList namespace_types * @param filterOptions optional - filter by field or tags * @param pagination optional * @param signal to cancel request * * @throws An error if response is not OK */ -export const fetchExceptionListItemsByListId = async ({ +export const fetchExceptionListsItemsByListIds = async ({ http, - listId, - namespaceType, - filterOptions = { - filter: '', - tags: [], - }, + listIds, + namespaceTypes, + filterOptions, pagination, signal, }: ApiCallByListIdProps): Promise => { - const namespace = - namespaceType === 'agnostic' ? EXCEPTION_LIST_NAMESPACE_AGNOSTIC : EXCEPTION_LIST_NAMESPACE; - const filters = [ - ...(filterOptions.filter.length - ? [`${namespace}.attributes.entries.field:${filterOptions.filter}*`] - : []), - ...(filterOptions.tags.length - ? filterOptions.tags.map((t) => `${namespace}.attributes.tags:${t}`) - : []), - ]; + const filters: string = filterOptions + .map((filter, index) => { + const namespace = namespaceTypes[index]; + const filterNamespace = + namespace === 'agnostic' ? EXCEPTION_LIST_NAMESPACE_AGNOSTIC : EXCEPTION_LIST_NAMESPACE; + const formattedFilters = [ + ...(filter.filter.length + ? [`${filterNamespace}.attributes.entries.field:${filter.filter}*`] + : []), + ...(filter.tags.length + ? filter.tags.map((t) => `${filterNamespace}.attributes.tags:${t}`) + : []), + ]; + + return formattedFilters.join(' AND '); + }) + .join(','); const query = { - list_id: listId, - namespace_type: namespaceType, + list_id: listIds.join(','), + namespace_type: namespaceTypes.join(','), page: pagination.page ? `${pagination.page}` : '1', per_page: pagination.perPage ? `${pagination.perPage}` : '20', - ...(filters.length ? { filter: filters.join(' AND ') } : {}), + ...(filters.trim() !== '' ? { filter: filters } : {}), }; const [validatedRequest, errorsRequest] = validate(query, findExceptionListItemSchema); diff --git a/x-pack/plugins/lists/public/exceptions/hooks/use_api.test.ts b/x-pack/plugins/lists/public/exceptions/hooks/use_api.test.ts index 1e0f7e58a0f4c..c93155274937e 100644 --- a/x-pack/plugins/lists/public/exceptions/hooks/use_api.test.ts +++ b/x-pack/plugins/lists/public/exceptions/hooks/use_api.test.ts @@ -9,9 +9,10 @@ import { act, renderHook } from '@testing-library/react-hooks'; import * as api from '../api'; import { createKibanaCoreStartMock } from '../../common/mocks/kibana_core'; import { getExceptionListSchemaMock } from '../../../common/schemas/response/exception_list_schema.mock'; +import { getFoundExceptionListItemSchemaMock } from '../../../common/schemas/response/found_exception_list_item_schema.mock'; import { getExceptionListItemSchemaMock } from '../../../common/schemas/response/exception_list_item_schema.mock'; import { HttpStart } from '../../../../../../src/core/public'; -import { ApiCallByIdProps } from '../types'; +import { ApiCallByIdProps, ApiCallByListIdProps } from '../types'; import { ExceptionsApi, useApi } from './use_api'; @@ -252,4 +253,116 @@ describe('useApi', () => { expect(onErrorMock).toHaveBeenCalledWith(mockError); }); }); + + test('it invokes "fetchExceptionListsItemsByListIds" when "getExceptionItem" used', async () => { + const output = getFoundExceptionListItemSchemaMock(); + const onSuccessMock = jest.fn(); + const spyOnFetchExceptionListsItemsByListIds = jest + .spyOn(api, 'fetchExceptionListsItemsByListIds') + .mockResolvedValue(output); + + await act(async () => { + const { result, waitForNextUpdate } = renderHook(() => + useApi(mockKibanaHttpService) + ); + await waitForNextUpdate(); + + await result.current.getExceptionListsItems({ + filterOptions: [], + lists: [{ id: 'myListId', listId: 'list_id', namespaceType: 'single', type: 'detection' }], + onError: jest.fn(), + onSuccess: onSuccessMock, + pagination: { + page: 1, + perPage: 20, + total: 0, + }, + showDetectionsListsOnly: false, + showEndpointListsOnly: false, + }); + + const expected: ApiCallByListIdProps = { + filterOptions: [], + http: mockKibanaHttpService, + listIds: ['list_id'], + namespaceTypes: ['single'], + pagination: { + page: 1, + perPage: 20, + total: 0, + }, + signal: new AbortController().signal, + }; + + expect(spyOnFetchExceptionListsItemsByListIds).toHaveBeenCalledWith(expected); + expect(onSuccessMock).toHaveBeenCalled(); + }); + }); + + test('it does not invoke "fetchExceptionListsItemsByListIds" if no listIds', async () => { + const output = getFoundExceptionListItemSchemaMock(); + const onSuccessMock = jest.fn(); + const spyOnFetchExceptionListsItemsByListIds = jest + .spyOn(api, 'fetchExceptionListsItemsByListIds') + .mockResolvedValue(output); + + await act(async () => { + const { result, waitForNextUpdate } = renderHook(() => + useApi(mockKibanaHttpService) + ); + await waitForNextUpdate(); + + await result.current.getExceptionListsItems({ + filterOptions: [], + lists: [{ id: 'myListId', listId: 'list_id', namespaceType: 'single', type: 'detection' }], + onError: jest.fn(), + onSuccess: onSuccessMock, + pagination: { + page: 1, + perPage: 20, + total: 0, + }, + showDetectionsListsOnly: false, + showEndpointListsOnly: true, + }); + + expect(spyOnFetchExceptionListsItemsByListIds).not.toHaveBeenCalled(); + expect(onSuccessMock).toHaveBeenCalledWith({ + exceptions: [], + pagination: { + page: 0, + perPage: 20, + total: 0, + }, + }); + }); + }); + + test('invokes "onError" callback if "fetchExceptionListsItemsByListIds" fails', async () => { + const mockError = new Error('failed to delete item'); + jest.spyOn(api, 'fetchExceptionListsItemsByListIds').mockRejectedValue(mockError); + + await act(async () => { + const { result, waitForNextUpdate } = renderHook(() => + useApi(mockKibanaHttpService) + ); + await waitForNextUpdate(); + + await result.current.getExceptionListsItems({ + filterOptions: [], + lists: [{ id: 'myListId', listId: 'list_id', namespaceType: 'single', type: 'detection' }], + onError: onErrorMock, + onSuccess: jest.fn(), + pagination: { + page: 1, + perPage: 20, + total: 0, + }, + showDetectionsListsOnly: false, + showEndpointListsOnly: false, + }); + + expect(onErrorMock).toHaveBeenCalledWith(mockError); + }); + }); }); diff --git a/x-pack/plugins/lists/public/exceptions/hooks/use_api.ts b/x-pack/plugins/lists/public/exceptions/hooks/use_api.ts index 45e180d9d617c..def2f2626b8ec 100644 --- a/x-pack/plugins/lists/public/exceptions/hooks/use_api.ts +++ b/x-pack/plugins/lists/public/exceptions/hooks/use_api.ts @@ -9,7 +9,8 @@ import { useMemo } from 'react'; import * as Api from '../api'; import { HttpStart } from '../../../../../../src/core/public'; import { ExceptionListItemSchema, ExceptionListSchema } from '../../../common/schemas'; -import { ApiCallMemoProps } from '../types'; +import { ApiCallFindListsItemsMemoProps, ApiCallMemoProps } from '../types'; +import { getIdsAndNamespaces } from '../utils'; export interface ExceptionsApi { deleteExceptionItem: (arg: ApiCallMemoProps) => Promise; @@ -20,6 +21,7 @@ export interface ExceptionsApi { getExceptionList: ( arg: ApiCallMemoProps & { onSuccess: (arg: ExceptionListSchema) => void } ) => Promise; + getExceptionListsItems: (arg: ApiCallFindListsItemsMemoProps) => Promise; } export const useApi = (http: HttpStart): ExceptionsApi => { @@ -105,6 +107,59 @@ export const useApi = (http: HttpStart): ExceptionsApi => { onError(error); } }, + async getExceptionListsItems({ + lists, + filterOptions, + pagination, + showDetectionsListsOnly, + showEndpointListsOnly, + onSuccess, + onError, + }: ApiCallFindListsItemsMemoProps): Promise { + const abortCtrl = new AbortController(); + const { ids, namespaces } = getIdsAndNamespaces({ + lists, + showDetection: showDetectionsListsOnly, + showEndpoint: showEndpointListsOnly, + }); + + try { + if (ids.length > 0 && namespaces.length > 0) { + const { + data, + page, + per_page: perPage, + total, + } = await Api.fetchExceptionListsItemsByListIds({ + filterOptions, + http, + listIds: ids, + namespaceTypes: namespaces, + pagination, + signal: abortCtrl.signal, + }); + onSuccess({ + exceptions: data, + pagination: { + page, + perPage, + total, + }, + }); + } else { + onSuccess({ + exceptions: [], + pagination: { + page: 0, + perPage: pagination.perPage ?? 0, + total: 0, + }, + }); + } + } catch (error) { + onError(error); + } + }, }), [http] ); diff --git a/x-pack/plugins/lists/public/exceptions/hooks/use_exception_list.test.ts b/x-pack/plugins/lists/public/exceptions/hooks/use_exception_list.test.ts index 918397d01ce2c..3a8b1713b901b 100644 --- a/x-pack/plugins/lists/public/exceptions/hooks/use_exception_list.test.ts +++ b/x-pack/plugins/lists/public/exceptions/hooks/use_exception_list.test.ts @@ -8,10 +8,9 @@ import { act, renderHook } from '@testing-library/react-hooks'; import * as api from '../api'; import { createKibanaCoreStartMock } from '../../common/mocks/kibana_core'; -import { getExceptionListSchemaMock } from '../../../common/schemas/response/exception_list_schema.mock'; import { getFoundExceptionListItemSchemaMock } from '../../../common/schemas/response/found_exception_list_item_schema.mock'; import { ExceptionListItemSchema } from '../../../common/schemas'; -import { ExceptionList, UseExceptionListProps, UseExceptionListSuccess } from '../types'; +import { UseExceptionListProps, UseExceptionListSuccess } from '../types'; import { ReturnExceptionListAndItems, useExceptionList } from './use_exception_list'; @@ -21,9 +20,8 @@ describe('useExceptionList', () => { const onErrorMock = jest.fn(); beforeEach(() => { - jest.spyOn(api, 'fetchExceptionListById').mockResolvedValue(getExceptionListSchemaMock()); jest - .spyOn(api, 'fetchExceptionListItemsByListId') + .spyOn(api, 'fetchExceptionListsItemsByListIds') .mockResolvedValue(getFoundExceptionListItemSchemaMock()); }); @@ -39,15 +37,20 @@ describe('useExceptionList', () => { ReturnExceptionListAndItems >(() => useExceptionList({ - filterOptions: { filter: '', tags: [] }, + filterOptions: [], http: mockKibanaHttpService, - lists: [{ id: 'myListId', namespaceType: 'single', type: 'detection' }], + lists: [ + { id: 'myListId', listId: 'list_id', namespaceType: 'single', type: 'detection' }, + ], + matchFilters: false, onError: onErrorMock, pagination: { page: 1, perPage: 20, total: 0, }, + showDetectionsListsOnly: false, + showEndpointListsOnly: false, }) ); await waitForNextUpdate(); @@ -55,7 +58,6 @@ describe('useExceptionList', () => { expect(result.current).toEqual([ true, [], - [], { page: 1, perPage: 20, @@ -66,7 +68,7 @@ describe('useExceptionList', () => { }); }); - test('fetch exception list and items', async () => { + test('fetches exception items', async () => { await act(async () => { const onSuccessMock = jest.fn(); const { result, waitForNextUpdate } = renderHook< @@ -74,9 +76,12 @@ describe('useExceptionList', () => { ReturnExceptionListAndItems >(() => useExceptionList({ - filterOptions: { filter: '', tags: [] }, + filterOptions: [], http: mockKibanaHttpService, - lists: [{ id: 'myListId', namespaceType: 'single', type: 'detection' }], + lists: [ + { id: 'myListId', listId: 'list_id', namespaceType: 'single', type: 'detection' }, + ], + matchFilters: false, onError: onErrorMock, onSuccess: onSuccessMock, pagination: { @@ -84,54 +89,279 @@ describe('useExceptionList', () => { perPage: 20, total: 0, }, + showDetectionsListsOnly: false, + showEndpointListsOnly: false, }) ); + // NOTE: First `waitForNextUpdate` is initialization + // Second call applies the params await waitForNextUpdate(); await waitForNextUpdate(); - const expectedListResult: ExceptionList[] = [ - { ...getExceptionListSchemaMock(), totalItems: 1 }, - ]; - const expectedListItemsResult: ExceptionListItemSchema[] = getFoundExceptionListItemSchemaMock() .data; const expectedResult: UseExceptionListSuccess = { exceptions: expectedListItemsResult, - lists: expectedListResult, pagination: { page: 1, perPage: 1, total: 1 }, }; expect(result.current).toEqual([ false, - expectedListResult, expectedListItemsResult, { page: 1, perPage: 1, total: 1, }, - result.current[4], + result.current[3], ]); expect(onSuccessMock).toHaveBeenCalledWith(expectedResult); }); }); - test('fetch a new exception list and its items', async () => { - const spyOnfetchExceptionListById = jest.spyOn(api, 'fetchExceptionListById'); - const spyOnfetchExceptionListItemsByListId = jest.spyOn(api, 'fetchExceptionListItemsByListId'); + test('fetches only detection list items if "showDetectionsListsOnly" is true', async () => { + const spyOnfetchExceptionListsItemsByListIds = jest.spyOn( + api, + 'fetchExceptionListsItemsByListIds' + ); + + await act(async () => { + const onSuccessMock = jest.fn(); + const { waitForNextUpdate } = renderHook( + () => + useExceptionList({ + filterOptions: [], + http: mockKibanaHttpService, + lists: [ + { id: 'myListId', listId: 'list_id', namespaceType: 'single', type: 'detection' }, + { + id: 'myListIdEndpoint', + listId: 'list_id_endpoint', + namespaceType: 'agnostic', + type: 'endpoint', + }, + ], + matchFilters: false, + onError: onErrorMock, + onSuccess: onSuccessMock, + pagination: { + page: 1, + perPage: 20, + total: 0, + }, + showDetectionsListsOnly: true, + showEndpointListsOnly: false, + }) + ); + // NOTE: First `waitForNextUpdate` is initialization + // Second call applies the params + await waitForNextUpdate(); + await waitForNextUpdate(); + + expect(spyOnfetchExceptionListsItemsByListIds).toHaveBeenCalledWith({ + filterOptions: [], + http: mockKibanaHttpService, + listIds: ['list_id'], + namespaceTypes: ['single'], + pagination: { page: 1, perPage: 20 }, + signal: new AbortController().signal, + }); + }); + }); + + test('fetches only detection list items if "showEndpointListsOnly" is true', async () => { + const spyOnfetchExceptionListsItemsByListIds = jest.spyOn( + api, + 'fetchExceptionListsItemsByListIds' + ); + + await act(async () => { + const onSuccessMock = jest.fn(); + const { waitForNextUpdate } = renderHook( + () => + useExceptionList({ + filterOptions: [], + http: mockKibanaHttpService, + lists: [ + { id: 'myListId', listId: 'list_id', namespaceType: 'single', type: 'detection' }, + { + id: 'myListIdEndpoint', + listId: 'list_id_endpoint', + namespaceType: 'agnostic', + type: 'endpoint', + }, + ], + matchFilters: false, + onError: onErrorMock, + onSuccess: onSuccessMock, + pagination: { + page: 1, + perPage: 20, + total: 0, + }, + showDetectionsListsOnly: false, + showEndpointListsOnly: true, + }) + ); + // NOTE: First `waitForNextUpdate` is initialization + // Second call applies the params + await waitForNextUpdate(); + await waitForNextUpdate(); + + expect(spyOnfetchExceptionListsItemsByListIds).toHaveBeenCalledWith({ + filterOptions: [], + http: mockKibanaHttpService, + listIds: ['list_id_endpoint'], + namespaceTypes: ['agnostic'], + pagination: { page: 1, perPage: 20 }, + signal: new AbortController().signal, + }); + }); + }); + + test('does not fetch items if no lists to fetch', async () => { + const spyOnfetchExceptionListsItemsByListIds = jest.spyOn( + api, + 'fetchExceptionListsItemsByListIds' + ); + + await act(async () => { + const onSuccessMock = jest.fn(); + const { result, waitForNextUpdate } = renderHook< + UseExceptionListProps, + ReturnExceptionListAndItems + >(() => + useExceptionList({ + filterOptions: [], + http: mockKibanaHttpService, + lists: [ + { id: 'myListId', listId: 'list_id', namespaceType: 'single', type: 'detection' }, + ], + matchFilters: false, + onError: onErrorMock, + onSuccess: onSuccessMock, + pagination: { + page: 1, + perPage: 20, + total: 0, + }, + showDetectionsListsOnly: false, + showEndpointListsOnly: true, + }) + ); + // NOTE: First `waitForNextUpdate` is initialization + // Second call applies the params + await waitForNextUpdate(); + await waitForNextUpdate(); + + expect(spyOnfetchExceptionListsItemsByListIds).not.toHaveBeenCalled(); + expect(result.current).toEqual([ + false, + [], + { + page: 0, + perPage: 20, + total: 0, + }, + result.current[3], + ]); + }); + }); + + test('applies first filterOptions filter to all lists if "matchFilters" is true', async () => { + const spyOnfetchExceptionListsItemsByListIds = jest.spyOn( + api, + 'fetchExceptionListsItemsByListIds' + ); + + await act(async () => { + const onSuccessMock = jest.fn(); + const { waitForNextUpdate } = renderHook( + () => + useExceptionList({ + filterOptions: [{ filter: 'host.name', tags: [] }], + http: mockKibanaHttpService, + lists: [ + { id: 'myListId', listId: 'list_id', namespaceType: 'single', type: 'detection' }, + { + id: 'myListIdEndpoint', + listId: 'list_id_endpoint', + namespaceType: 'agnostic', + type: 'endpoint', + }, + ], + matchFilters: true, + onError: onErrorMock, + onSuccess: onSuccessMock, + pagination: { + page: 1, + perPage: 20, + total: 0, + }, + showDetectionsListsOnly: false, + showEndpointListsOnly: false, + }) + ); + // NOTE: First `waitForNextUpdate` is initialization + // Second call applies the params + await waitForNextUpdate(); + await waitForNextUpdate(); + + expect(spyOnfetchExceptionListsItemsByListIds).toHaveBeenCalledWith({ + filterOptions: [ + { filter: 'host.name', tags: [] }, + { filter: 'host.name', tags: [] }, + ], + http: mockKibanaHttpService, + listIds: ['list_id', 'list_id_endpoint'], + namespaceTypes: ['single', 'agnostic'], + pagination: { page: 1, perPage: 20 }, + signal: new AbortController().signal, + }); + }); + }); + + test('fetches a new exception list and its items', async () => { + const spyOnfetchExceptionListsItemsByListIds = jest.spyOn( + api, + 'fetchExceptionListsItemsByListIds' + ); const onSuccessMock = jest.fn(); await act(async () => { const { rerender, waitForNextUpdate } = renderHook< UseExceptionListProps, ReturnExceptionListAndItems >( - ({ filterOptions, http, lists, pagination, onError, onSuccess }) => - useExceptionList({ filterOptions, http, lists, onError, onSuccess, pagination }), + ({ + filterOptions, + http, + lists, + matchFilters, + pagination, + onError, + onSuccess, + showDetectionsListsOnly, + showEndpointListsOnly, + }) => + useExceptionList({ + filterOptions, + http, + lists, + matchFilters, + onError, + onSuccess, + pagination, + showDetectionsListsOnly, + showEndpointListsOnly, + }), { initialProps: { - filterOptions: { filter: '', tags: [] }, + filterOptions: [], http: mockKibanaHttpService, - lists: [{ id: 'myListId', namespaceType: 'single', type: 'detection' }], + lists: [ + { id: 'myListId', listId: 'list_id', namespaceType: 'single', type: 'detection' }, + ], + matchFilters: false, onError: onErrorMock, onSuccess: onSuccessMock, pagination: { @@ -139,14 +369,23 @@ describe('useExceptionList', () => { perPage: 20, total: 0, }, + showDetectionsListsOnly: false, + showEndpointListsOnly: false, }, } ); + // NOTE: First `waitForNextUpdate` is initialization + // Second call applies the params await waitForNextUpdate(); + await waitForNextUpdate(); + rerender({ - filterOptions: { filter: '', tags: [] }, + filterOptions: [], http: mockKibanaHttpService, - lists: [{ id: 'newListId', namespaceType: 'single', type: 'detection' }], + lists: [ + { id: 'newListId', listId: 'new_list_id', namespaceType: 'single', type: 'detection' }, + ], + matchFilters: false, onError: onErrorMock, onSuccess: onSuccessMock, pagination: { @@ -154,103 +393,92 @@ describe('useExceptionList', () => { perPage: 20, total: 0, }, + showDetectionsListsOnly: false, + showEndpointListsOnly: false, }); + // NOTE: Only need one call here because hook already initilaized await waitForNextUpdate(); - expect(spyOnfetchExceptionListById).toHaveBeenCalledTimes(2); - expect(spyOnfetchExceptionListItemsByListId).toHaveBeenCalledTimes(2); + expect(spyOnfetchExceptionListsItemsByListIds).toHaveBeenCalledTimes(2); }); }); test('fetches list and items when refreshExceptionList callback invoked', async () => { - const spyOnfetchExceptionListById = jest.spyOn(api, 'fetchExceptionListById'); - const spyOnfetchExceptionListItemsByListId = jest.spyOn(api, 'fetchExceptionListItemsByListId'); + const spyOnfetchExceptionListsItemsByListIds = jest.spyOn( + api, + 'fetchExceptionListsItemsByListIds' + ); await act(async () => { const { result, waitForNextUpdate } = renderHook< UseExceptionListProps, ReturnExceptionListAndItems >(() => useExceptionList({ - filterOptions: { filter: '', tags: [] }, + filterOptions: [], http: mockKibanaHttpService, - lists: [{ id: 'myListId', namespaceType: 'single', type: 'detection' }], + lists: [ + { id: 'myListId', listId: 'list_id', namespaceType: 'single', type: 'detection' }, + ], + matchFilters: false, onError: onErrorMock, pagination: { page: 1, perPage: 20, total: 0, }, + showDetectionsListsOnly: false, + showEndpointListsOnly: false, }) ); + // NOTE: First `waitForNextUpdate` is initialization + // Second call applies the params await waitForNextUpdate(); await waitForNextUpdate(); - expect(typeof result.current[4]).toEqual('function'); + expect(typeof result.current[3]).toEqual('function'); - if (result.current[4] != null) { - result.current[4](); + if (result.current[3] != null) { + result.current[3](); } - + // NOTE: Only need one call here because hook already initilaized await waitForNextUpdate(); - expect(spyOnfetchExceptionListById).toHaveBeenCalledTimes(2); - expect(spyOnfetchExceptionListItemsByListId).toHaveBeenCalledTimes(2); + expect(spyOnfetchExceptionListsItemsByListIds).toHaveBeenCalledTimes(2); }); }); - test('invokes "onError" callback if "fetchExceptionListItemsByListId" fails', async () => { - const mockError = new Error('failed to fetch list items'); - const spyOnfetchExceptionListById = jest.spyOn(api, 'fetchExceptionListById'); - const spyOnfetchExceptionListItemsByListId = jest - .spyOn(api, 'fetchExceptionListItemsByListId') + test('invokes "onError" callback if "fetchExceptionListsItemsByListIds" fails', async () => { + const mockError = new Error('failed to fetches list items'); + const spyOnfetchExceptionListsItemsByListIds = jest + .spyOn(api, 'fetchExceptionListsItemsByListIds') .mockRejectedValue(mockError); await act(async () => { const { waitForNextUpdate } = renderHook( () => useExceptionList({ - filterOptions: { filter: '', tags: [] }, - http: mockKibanaHttpService, - lists: [{ id: 'myListId', namespaceType: 'single', type: 'detection' }], - onError: onErrorMock, - pagination: { - page: 1, - perPage: 20, - total: 0, - }, - }) - ); - await waitForNextUpdate(); - await waitForNextUpdate(); - - expect(spyOnfetchExceptionListById).toHaveBeenCalledTimes(1); - expect(onErrorMock).toHaveBeenCalledWith(mockError); - expect(spyOnfetchExceptionListItemsByListId).toHaveBeenCalledTimes(1); - }); - }); - - test('invokes "onError" callback if "fetchExceptionListById" fails', async () => { - const mockError = new Error('failed to fetch list'); - jest.spyOn(api, 'fetchExceptionListById').mockRejectedValue(mockError); - - await act(async () => { - const { waitForNextUpdate } = renderHook( - () => - useExceptionList({ - filterOptions: { filter: '', tags: [] }, + filterOptions: [], http: mockKibanaHttpService, - lists: [{ id: 'myListId', namespaceType: 'single', type: 'detection' }], + lists: [ + { id: 'myListId', listId: 'list_id', namespaceType: 'single', type: 'detection' }, + ], + matchFilters: false, onError: onErrorMock, pagination: { page: 1, perPage: 20, total: 0, }, + showDetectionsListsOnly: false, + showEndpointListsOnly: false, }) ); + // NOTE: First `waitForNextUpdate` is initialization + // Second call applies the params await waitForNextUpdate(); await waitForNextUpdate(); expect(onErrorMock).toHaveBeenCalledWith(mockError); + expect(spyOnfetchExceptionListsItemsByListIds).toHaveBeenCalledTimes(1); }); }); }); diff --git a/x-pack/plugins/lists/public/exceptions/hooks/use_exception_list.ts b/x-pack/plugins/lists/public/exceptions/hooks/use_exception_list.ts index c639dcff8b537..8097a7b8c5898 100644 --- a/x-pack/plugins/lists/public/exceptions/hooks/use_exception_list.ts +++ b/x-pack/plugins/lists/public/exceptions/hooks/use_exception_list.ts @@ -4,16 +4,16 @@ * you may not use this file except in compliance with the Elastic License. */ -import { useEffect, useMemo, useRef, useState } from 'react'; +import { useEffect, useRef, useState } from 'react'; -import { fetchExceptionListById, fetchExceptionListItemsByListId } from '../api'; -import { ExceptionIdentifiers, ExceptionList, Pagination, UseExceptionListProps } from '../types'; -import { ExceptionListItemSchema, NamespaceType } from '../../../common/schemas'; +import { fetchExceptionListsItemsByListIds } from '../api'; +import { FilterExceptionsOptions, Pagination, UseExceptionListProps } from '../types'; +import { ExceptionListItemSchema } from '../../../common/schemas'; +import { getIdsAndNamespaces } from '../utils'; type Func = () => void; export type ReturnExceptionListAndItems = [ boolean, - ExceptionList[], ExceptionListItemSchema[], Pagination, Func | null @@ -27,6 +27,10 @@ export type ReturnExceptionListAndItems = [ * @param onError error callback * @param onSuccess callback when all lists fetched successfully * @param filterOptions optional - filter by fields or tags + * @param showDetectionsListsOnly boolean, if true, only detection lists are searched + * @param showEndpointListsOnly boolean, if true, only endpoint lists are searched + * @param matchFilters boolean, if true, applies first filter in filterOptions to + * all lists * @param pagination optional * */ @@ -38,134 +42,112 @@ export const useExceptionList = ({ perPage: 20, total: 0, }, - filterOptions = { - filter: '', - tags: [], - }, + filterOptions, + showDetectionsListsOnly, + showEndpointListsOnly, + matchFilters, onError, onSuccess, }: UseExceptionListProps): ReturnExceptionListAndItems => { - const [exceptionLists, setExceptionLists] = useState([]); const [exceptionItems, setExceptionListItems] = useState([]); const [paginationInfo, setPagination] = useState(pagination); - const fetchExceptionList = useRef(null); + const fetchExceptionListsItems = useRef(null); const [loading, setLoading] = useState(true); - const tags = useMemo(() => filterOptions.tags.sort().join(), [filterOptions.tags]); - const listIds = useMemo( - () => - lists - .map((t) => t.id) - .sort() - .join(), - [lists] - ); + const { ids, namespaces } = getIdsAndNamespaces({ + lists, + showDetection: showDetectionsListsOnly, + showEndpoint: showEndpointListsOnly, + }); + const filters: FilterExceptionsOptions[] = + matchFilters && filterOptions.length > 0 ? ids.map(() => filterOptions[0]) : filterOptions; + const idsAsString: string = ids.join(','); + const namespacesAsString: string = namespaces.join(','); + const filterAsString: string = filterOptions.map(({ filter }) => filter).join(','); + const filterTagsAsString: string = filterOptions.map(({ tags }) => tags.join(',')).join(','); useEffect( () => { - let isSubscribed = false; - let abortCtrl: AbortController; - - const fetchLists = async (): Promise => { - isSubscribed = true; - abortCtrl = new AbortController(); - - // TODO: workaround until api updated, will be cleaned up - let exceptions: ExceptionListItemSchema[] = []; - let exceptionListsReturned: ExceptionList[] = []; - - const fetchData = async ({ - id, - namespaceType, - }: { - id: string; - namespaceType: NamespaceType; - }): Promise => { - try { - setLoading(true); - - const { - list_id, - namespace_type, - ...restOfExceptionList - } = await fetchExceptionListById({ - http, - id, - namespaceType, - signal: abortCtrl.signal, + let isSubscribed = true; + const abortCtrl = new AbortController(); + + const fetchData = async (): Promise => { + try { + setLoading(true); + + if (ids.length === 0 && isSubscribed) { + setPagination({ + page: 0, + perPage: pagination.perPage, + total: 0, }); - const fetchListItemsResult = await fetchExceptionListItemsByListId({ - filterOptions, + setExceptionListItems([]); + + if (onSuccess != null) { + onSuccess({ + exceptions: [], + pagination: { + page: 0, + perPage: pagination.perPage, + total: 0, + }, + }); + } + setLoading(false); + } else { + const { page, per_page, total, data } = await fetchExceptionListsItemsByListIds({ + filterOptions: filters, http, - listId: list_id, - namespaceType: namespace_type, - pagination, + listIds: ids, + namespaceTypes: namespaces, + pagination: { + page: pagination.page, + perPage: pagination.perPage, + }, signal: abortCtrl.signal, }); if (isSubscribed) { - exceptionListsReturned = [ - ...exceptionListsReturned, - { - list_id, - namespace_type, - ...restOfExceptionList, - totalItems: fetchListItemsResult.total, - }, - ]; - setExceptionLists(exceptionListsReturned); setPagination({ - page: fetchListItemsResult.page, - perPage: fetchListItemsResult.per_page, - total: fetchListItemsResult.total, + page, + perPage: per_page, + total, }); - - exceptions = [...exceptions, ...fetchListItemsResult.data]; - setExceptionListItems(exceptions); + setExceptionListItems(data); if (onSuccess != null) { onSuccess({ - exceptions, - lists: exceptionListsReturned, + exceptions: data, pagination: { - page: fetchListItemsResult.page, - perPage: fetchListItemsResult.per_page, - total: fetchListItemsResult.total, + page, + perPage: per_page, + total, }, }); } } - } catch (error) { - if (isSubscribed) { - setExceptionLists([]); - setExceptionListItems([]); - setPagination({ - page: 1, - perPage: 20, - total: 0, - }); - if (onError != null) { - onError(error); - } + } + } catch (error) { + if (isSubscribed) { + setExceptionListItems([]); + setPagination({ + page: 1, + perPage: 20, + total: 0, + }); + if (onError != null) { + onError(error); } } - }; - - // TODO: Workaround for now. Once api updated, we can pass in array of lists to fetch - await Promise.all( - lists.map( - ({ id, namespaceType }: ExceptionIdentifiers): Promise => - fetchData({ id, namespaceType }) - ) - ); + } if (isSubscribed) { setLoading(false); } }; - fetchLists(); + fetchData(); - fetchExceptionList.current = fetchLists; + fetchExceptionListsItems.current = fetchData; return (): void => { isSubscribed = false; abortCtrl.abort(); @@ -173,15 +155,15 @@ export const useExceptionList = ({ }, // eslint-disable-next-line react-hooks/exhaustive-deps [ http, - listIds, - setExceptionLists, + idsAsString, + namespacesAsString, setExceptionListItems, pagination.page, pagination.perPage, - filterOptions.filter, - tags, + filterAsString, + filterTagsAsString, ] ); - return [loading, exceptionLists, exceptionItems, paginationInfo, fetchExceptionList.current]; + return [loading, exceptionItems, paginationInfo, fetchExceptionListsItems.current]; }; diff --git a/x-pack/plugins/lists/public/exceptions/types.ts b/x-pack/plugins/lists/public/exceptions/types.ts index f99323b384781..ac21288848154 100644 --- a/x-pack/plugins/lists/public/exceptions/types.ts +++ b/x-pack/plugins/lists/public/exceptions/types.ts @@ -44,7 +44,6 @@ export interface ExceptionList extends ExceptionListSchema { } export interface UseExceptionListSuccess { - lists: ExceptionList[]; exceptions: ExceptionListItemSchema[]; pagination: Pagination; } @@ -53,22 +52,26 @@ export interface UseExceptionListProps { http: HttpStart; lists: ExceptionIdentifiers[]; onError?: (arg: string[]) => void; - filterOptions?: FilterExceptionsOptions; + filterOptions: FilterExceptionsOptions[]; pagination?: Pagination; + showDetectionsListsOnly: boolean; + showEndpointListsOnly: boolean; + matchFilters: boolean; onSuccess?: (arg: UseExceptionListSuccess) => void; } export interface ExceptionIdentifiers { id: string; + listId: string; namespaceType: NamespaceType; type: ExceptionListType; } export interface ApiCallByListIdProps { http: HttpStart; - listId: string; - namespaceType: NamespaceType; - filterOptions?: FilterExceptionsOptions; + listIds: string[]; + namespaceTypes: NamespaceType[]; + filterOptions: FilterExceptionsOptions[]; pagination: Partial; signal: AbortSignal; } @@ -87,6 +90,16 @@ export interface ApiCallMemoProps { onSuccess: () => void; } +export interface ApiCallFindListsItemsMemoProps { + lists: ExceptionIdentifiers[]; + filterOptions: FilterExceptionsOptions[]; + pagination: Partial; + showDetectionsListsOnly: boolean; + showEndpointListsOnly: boolean; + onError: (arg: string[]) => void; + onSuccess: (arg: UseExceptionListSuccess) => void; +} + export interface AddExceptionListProps { http: HttpStart; list: CreateExceptionListSchema; diff --git a/x-pack/plugins/lists/public/exceptions/utils.test.ts b/x-pack/plugins/lists/public/exceptions/utils.test.ts new file mode 100644 index 0000000000000..cc1a96132b045 --- /dev/null +++ b/x-pack/plugins/lists/public/exceptions/utils.test.ts @@ -0,0 +1,105 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { getIdsAndNamespaces } from './utils'; + +describe('Exceptions utils', () => { + describe('#getIdsAndNamespaces', () => { + test('it returns empty arrays if no lists found', async () => { + const output = getIdsAndNamespaces({ + lists: [], + showDetection: false, + showEndpoint: false, + }); + + expect(output).toEqual({ ids: [], namespaces: [] }); + }); + + test('it returns all lists if "showDetection" and "showEndpoint" are "false"', async () => { + const output = getIdsAndNamespaces({ + lists: [ + { id: 'myListId', listId: 'list_id', namespaceType: 'single', type: 'detection' }, + { + id: 'myListIdEndpoint', + listId: 'list_id_endpoint', + namespaceType: 'agnostic', + type: 'endpoint', + }, + ], + showDetection: false, + showEndpoint: false, + }); + + expect(output).toEqual({ + ids: ['list_id', 'list_id_endpoint'], + namespaces: ['single', 'agnostic'], + }); + }); + + test('it returns only detections lists if "showDetection" is "true"', async () => { + const output = getIdsAndNamespaces({ + lists: [ + { id: 'myListId', listId: 'list_id', namespaceType: 'single', type: 'detection' }, + { + id: 'myListIdEndpoint', + listId: 'list_id_endpoint', + namespaceType: 'agnostic', + type: 'endpoint', + }, + ], + showDetection: true, + showEndpoint: false, + }); + + expect(output).toEqual({ + ids: ['list_id'], + namespaces: ['single'], + }); + }); + + test('it returns only endpoint lists if "showEndpoint" is "true"', async () => { + const output = getIdsAndNamespaces({ + lists: [ + { id: 'myListId', listId: 'list_id', namespaceType: 'single', type: 'detection' }, + { + id: 'myListIdEndpoint', + listId: 'list_id_endpoint', + namespaceType: 'agnostic', + type: 'endpoint', + }, + ], + showDetection: false, + showEndpoint: true, + }); + + expect(output).toEqual({ + ids: ['list_id_endpoint'], + namespaces: ['agnostic'], + }); + }); + + test('it returns only detection lists if both "showEndpoint" and "showDetection" are "true"', async () => { + const output = getIdsAndNamespaces({ + lists: [ + { id: 'myListId', listId: 'list_id', namespaceType: 'single', type: 'detection' }, + { + id: 'myListIdEndpoint', + listId: 'list_id_endpoint', + namespaceType: 'agnostic', + type: 'endpoint', + }, + ], + showDetection: true, + showEndpoint: true, + }); + + expect(output).toEqual({ + ids: ['list_id'], + namespaces: ['single'], + }); + }); + }); +}); diff --git a/x-pack/plugins/lists/public/exceptions/utils.ts b/x-pack/plugins/lists/public/exceptions/utils.ts new file mode 100644 index 0000000000000..2acb690d3822c --- /dev/null +++ b/x-pack/plugins/lists/public/exceptions/utils.ts @@ -0,0 +1,36 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { NamespaceType } from '../../common/schemas'; + +import { ExceptionIdentifiers } from './types'; + +export const getIdsAndNamespaces = ({ + lists, + showDetection, + showEndpoint, +}: { + lists: ExceptionIdentifiers[]; + showDetection: boolean; + showEndpoint: boolean; +}): { ids: string[]; namespaces: NamespaceType[] } => + lists + .filter((list) => { + if (showDetection) { + return list.type === 'detection'; + } else if (showEndpoint) { + return list.type === 'endpoint'; + } else { + return true; + } + }) + .reduce<{ ids: string[]; namespaces: NamespaceType[] }>( + (acc, { listId, namespaceType }) => ({ + ids: [...acc.ids, listId], + namespaces: [...acc.namespaces, namespaceType], + }), + { ids: [], namespaces: [] } + ); diff --git a/x-pack/plugins/lists/server/config.mock.ts b/x-pack/plugins/lists/server/config.mock.ts index 3cf5040c73675..b272f18c4e809 100644 --- a/x-pack/plugins/lists/server/config.mock.ts +++ b/x-pack/plugins/lists/server/config.mock.ts @@ -6,6 +6,7 @@ import { IMPORT_BUFFER_SIZE, + IMPORT_TIMEOUT, LIST_INDEX, LIST_ITEM_INDEX, MAX_IMPORT_PAYLOAD_BYTES, @@ -21,6 +22,7 @@ export const getConfigMock = (): Partial => ({ export const getConfigMockDecoded = (): ConfigType => ({ enabled: true, importBufferSize: IMPORT_BUFFER_SIZE, + importTimeout: IMPORT_TIMEOUT, listIndex: LIST_INDEX, listItemIndex: LIST_ITEM_INDEX, maxImportPayloadBytes: MAX_IMPORT_PAYLOAD_BYTES, diff --git a/x-pack/plugins/lists/server/config.test.ts b/x-pack/plugins/lists/server/config.test.ts index 60501322dcfa2..40b04edd4c007 100644 --- a/x-pack/plugins/lists/server/config.test.ts +++ b/x-pack/plugins/lists/server/config.test.ts @@ -4,6 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +import moment from 'moment'; + import { ConfigSchema, ConfigType } from './config'; import { getConfigMock, getConfigMockDecoded } from './config.mock'; @@ -61,4 +63,24 @@ describe('config_schema', () => { '[importBufferSize]: Value must be equal to or greater than [1].' ); }); + + test('it throws if the "importTimeout" value is less than 2 minutes', () => { + const mock: ConfigType = { + ...getConfigMockDecoded(), + importTimeout: moment.duration(2, 'minutes').subtract(1, 'second'), + }; + expect(() => ConfigSchema.validate(mock)).toThrow( + '[importTimeout]: duration cannot be less than 2 minutes' + ); + }); + + test('it throws if the "importTimeout" value is greater than 1 hour', () => { + const mock: ConfigType = { + ...getConfigMockDecoded(), + importTimeout: moment.duration(1, 'hour').add(1, 'second'), + }; + expect(() => ConfigSchema.validate(mock)).toThrow( + '[importTimeout]: duration cannot be greater than 30 minutes' + ); + }); }); diff --git a/x-pack/plugins/lists/server/config.ts b/x-pack/plugins/lists/server/config.ts index 394f85ecfb642..6e36d135abfcc 100644 --- a/x-pack/plugins/lists/server/config.ts +++ b/x-pack/plugins/lists/server/config.ts @@ -9,6 +9,16 @@ import { TypeOf, schema } from '@kbn/config-schema'; export const ConfigSchema = schema.object({ enabled: schema.boolean({ defaultValue: true }), importBufferSize: schema.number({ defaultValue: 1000, min: 1 }), + importTimeout: schema.duration({ + defaultValue: '5m', + validate: (value) => { + if (value.asMinutes() < 2) { + throw new Error('duration cannot be less than 2 minutes'); + } else if (value.asMinutes() > 30) { + throw new Error('duration cannot be greater than 30 minutes'); + } + }, + }), listIndex: schema.string({ defaultValue: '.lists' }), listItemIndex: schema.string({ defaultValue: '.items' }), maxImportPayloadBytes: schema.number({ defaultValue: 9000000, min: 1 }), diff --git a/x-pack/plugins/lists/server/routes/create_endpoint_list_item_route.ts b/x-pack/plugins/lists/server/routes/create_endpoint_list_item_route.ts index 5ff2a9d9df9f4..22aa1fb59858b 100644 --- a/x-pack/plugins/lists/server/routes/create_endpoint_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/create_endpoint_list_item_route.ts @@ -6,7 +6,7 @@ import { IRouter } from 'kibana/server'; -import { ENDPOINT_LIST_ITEM_URL } from '../../common/constants'; +import { ENDPOINT_LIST_ID, ENDPOINT_LIST_ITEM_URL } from '../../common/constants'; import { buildRouteValidation, buildSiemResponse, transformError } from '../siem_server_deps'; import { validate } from '../../common/siem_common_deps'; import { @@ -16,6 +16,7 @@ import { } from '../../common/schemas'; import { getExceptionListClient } from './utils/get_exception_list_client'; +import { validateExceptionListSize } from './validate'; export const createEndpointListItemRoute = (router: IRouter): void => { router.post( @@ -71,6 +72,18 @@ export const createEndpointListItemRoute = (router: IRouter): void => { if (errors != null) { return siemResponse.error({ body: errors, statusCode: 500 }); } else { + const listSizeError = await validateExceptionListSize( + exceptionLists, + ENDPOINT_LIST_ID, + 'agnostic' + ); + if (listSizeError != null) { + await exceptionLists.deleteExceptionListItemById({ + id: createdList.id, + namespaceType: 'agnostic', + }); + return siemResponse.error(listSizeError); + } return response.ok({ body: validated ?? {} }); } } diff --git a/x-pack/plugins/lists/server/routes/create_exception_list_item_route.ts b/x-pack/plugins/lists/server/routes/create_exception_list_item_route.ts index e4885c7393bd4..ed58621dae973 100644 --- a/x-pack/plugins/lists/server/routes/create_exception_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/create_exception_list_item_route.ts @@ -17,6 +17,7 @@ import { import { getExceptionListClient } from './utils/get_exception_list_client'; import { endpointDisallowedFields } from './endpoint_disallowed_fields'; +import { validateExceptionListSize } from './validate'; export const createExceptionListItemRoute = (router: IRouter): void => { router.post( @@ -104,6 +105,18 @@ export const createExceptionListItemRoute = (router: IRouter): void => { if (errors != null) { return siemResponse.error({ body: errors, statusCode: 500 }); } else { + const listSizeError = await validateExceptionListSize( + exceptionLists, + listId, + namespaceType + ); + if (listSizeError != null) { + await exceptionLists.deleteExceptionListItemById({ + id: createdList.id, + namespaceType, + }); + return siemResponse.error(listSizeError); + } return response.ok({ body: validated ?? {} }); } } diff --git a/x-pack/plugins/lists/server/routes/import_list_item_route.ts b/x-pack/plugins/lists/server/routes/import_list_item_route.ts index 1003a0c52a794..e162e7829e456 100644 --- a/x-pack/plugins/lists/server/routes/import_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/import_list_item_route.ts @@ -27,6 +27,7 @@ export const importListItemRoute = (router: IRouter, config: ConfigType): void = parse: false, }, tags: ['access:lists-all'], + timeout: config.importTimeout.asMilliseconds(), }, path: `${LIST_ITEM_URL}/_import`, validate: { diff --git a/x-pack/plugins/lists/server/routes/update_exception_list_item_route.ts b/x-pack/plugins/lists/server/routes/update_exception_list_item_route.ts index 293435b3f6202..f5e0e7ae75700 100644 --- a/x-pack/plugins/lists/server/routes/update_exception_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/update_exception_list_item_route.ts @@ -14,6 +14,7 @@ import { exceptionListItemSchema, updateExceptionListItemSchema, } from '../../common/schemas'; +import { updateExceptionListItemValidate } from '../../common/schemas/request/update_exception_list_item_validation'; import { getExceptionListClient } from '.'; @@ -33,6 +34,11 @@ export const updateExceptionListItemRoute = (router: IRouter): void => { }, async (context, request, response) => { const siemResponse = buildSiemResponse(response); + const validationErrors = updateExceptionListItemValidate(request.body); + if (validationErrors.length) { + return siemResponse.error({ body: validationErrors, statusCode: 400 }); + } + try { const { description, diff --git a/x-pack/plugins/lists/server/routes/validate.ts b/x-pack/plugins/lists/server/routes/validate.ts new file mode 100644 index 0000000000000..bbd4b0eaf0e33 --- /dev/null +++ b/x-pack/plugins/lists/server/routes/validate.ts @@ -0,0 +1,56 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { ExceptionListClient } from '../services/exception_lists/exception_list_client'; +import { MAX_EXCEPTION_LIST_SIZE } from '../../common/constants'; +import { foundExceptionListItemSchema } from '../../common/schemas'; +import { NamespaceType } from '../../common/schemas/types'; +import { validate } from '../../common/siem_common_deps'; + +export const validateExceptionListSize = async ( + exceptionLists: ExceptionListClient, + listId: string, + namespaceType: NamespaceType +): Promise<{ body: string; statusCode: number } | null> => { + const exceptionListItems = await exceptionLists.findExceptionListItem({ + filter: undefined, + listId, + namespaceType, + page: undefined, + perPage: undefined, + sortField: undefined, + sortOrder: undefined, + }); + if (exceptionListItems == null) { + // If exceptionListItems is null then we couldn't find the list so it may have been deleted + return { + body: `Unable to find list id: ${listId} to verify max exception list size`, + statusCode: 500, + }; + } + const [validatedItems, err] = validate(exceptionListItems, foundExceptionListItemSchema); + if (err != null) { + return { + body: err, + statusCode: 500, + }; + } + // Unnecessary since validatedItems comes from exceptionListItems which is already + // checked for null, but typescript fails to detect that + if (validatedItems == null) { + return { + body: `Unable to find list id: ${listId} to verify max exception list size`, + statusCode: 500, + }; + } + if (validatedItems.total > MAX_EXCEPTION_LIST_SIZE) { + return { + body: `Failed to add exception item, exception list would exceed max size of ${MAX_EXCEPTION_LIST_SIZE}`, + statusCode: 400, + }; + } + return null; +}; diff --git a/x-pack/plugins/lists/server/saved_objects/exception_list.ts b/x-pack/plugins/lists/server/saved_objects/exception_list.ts index 3bde3545837cf..f9e408833e069 100644 --- a/x-pack/plugins/lists/server/saved_objects/exception_list.ts +++ b/x-pack/plugins/lists/server/saved_objects/exception_list.ts @@ -83,6 +83,9 @@ export const exceptionListItemMapping: SavedObjectsType['mappings'] = { created_by: { type: 'keyword', }, + id: { + type: 'keyword', + }, updated_at: { type: 'keyword', }, diff --git a/x-pack/plugins/lists/server/scripts/exception_lists/new/exception_list_item_auto_id.json b/x-pack/plugins/lists/server/scripts/exception_lists/new/exception_list_item_auto_id.json index d63adc84a361d..f1281e2ea0560 100644 --- a/x-pack/plugins/lists/server/scripts/exception_lists/new/exception_list_item_auto_id.json +++ b/x-pack/plugins/lists/server/scripts/exception_lists/new/exception_list_item_auto_id.json @@ -1,5 +1,5 @@ { - "list_id": "endpoint_list", + "list_id": "simple_list", "_tags": ["endpoint", "process", "malware", "os:linux"], "tags": ["user added string for a tag", "malware"], "type": "simple", diff --git a/x-pack/plugins/lists/server/scripts/exception_lists/updates/simple_update_item.json b/x-pack/plugins/lists/server/scripts/exception_lists/updates/simple_update_item.json index da345fb930c04..81db909277595 100644 --- a/x-pack/plugins/lists/server/scripts/exception_lists/updates/simple_update_item.json +++ b/x-pack/plugins/lists/server/scripts/exception_lists/updates/simple_update_item.json @@ -1,17 +1,18 @@ { - "item_id": "simple_list_item", - "_tags": ["endpoint", "process", "malware", "os:windows"], - "tags": ["user added string for a tag", "malware"], - "type": "simple", - "description": "This is a sample change here this list", - "name": "Sample Endpoint Exception List update change", - "comments": [{ "comment": "this is a newly added comment" }], + "_tags": ["detection"], + "comments": [], + "description": "Test comments - exception list item", "entries": [ { - "field": "event.category", - "operator": "included", - "type": "match_any", - "value": ["process", "malware"] + "field": "host.name", + "type": "match", + "value": "rock01", + "operator": "included" } - ] + ], + "item_id": "993f43f7-325d-4df3-9338-964e77c37053", + "name": "Test comments - exception list item", + "namespace_type": "single", + "tags": [], + "type": "simple" } diff --git a/x-pack/plugins/lists/server/services/exception_lists/create_exception_list_item.ts b/x-pack/plugins/lists/server/services/exception_lists/create_exception_list_item.ts index a90ec61aef4af..47c21735b45f4 100644 --- a/x-pack/plugins/lists/server/services/exception_lists/create_exception_list_item.ts +++ b/x-pack/plugins/lists/server/services/exception_lists/create_exception_list_item.ts @@ -64,7 +64,10 @@ export const createExceptionListItem = async ({ }: CreateExceptionListItemOptions): Promise => { const savedObjectType = getSavedObjectType({ namespaceType }); const dateNow = new Date().toISOString(); - const transformedComments = transformCreateCommentsToComments({ comments, user }); + const transformedComments = transformCreateCommentsToComments({ + incomingComments: comments, + user, + }); const savedObject = await savedObjectsClient.create(savedObjectType, { _tags, comments: transformedComments, diff --git a/x-pack/plugins/lists/server/services/exception_lists/delete_exception_list_item.ts b/x-pack/plugins/lists/server/services/exception_lists/delete_exception_list_item.ts index 8dce1f1f79e35..ee85cf36a48b5 100644 --- a/x-pack/plugins/lists/server/services/exception_lists/delete_exception_list_item.ts +++ b/x-pack/plugins/lists/server/services/exception_lists/delete_exception_list_item.ts @@ -8,6 +8,7 @@ import { SavedObjectsClientContract } from 'kibana/server'; import { ExceptionListItemSchema, + Id, IdOrUndefined, ItemIdOrUndefined, NamespaceType, @@ -23,6 +24,12 @@ interface DeleteExceptionListItemOptions { savedObjectsClient: SavedObjectsClientContract; } +interface DeleteExceptionListItemByIdOptions { + id: Id; + namespaceType: NamespaceType; + savedObjectsClient: SavedObjectsClientContract; +} + export const deleteExceptionListItem = async ({ itemId, id, @@ -43,3 +50,12 @@ export const deleteExceptionListItem = async ({ return exceptionListItem; } }; + +export const deleteExceptionListItemById = async ({ + id, + namespaceType, + savedObjectsClient, +}: DeleteExceptionListItemByIdOptions): Promise => { + const savedObjectType = getSavedObjectType({ namespaceType }); + await savedObjectsClient.delete(savedObjectType, id); +}; diff --git a/x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts b/x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts index 11302e64b3538..83b44ababf9de 100644 --- a/x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts +++ b/x-pack/plugins/lists/server/services/exception_lists/exception_list_client.ts @@ -20,6 +20,7 @@ import { CreateExceptionListItemOptions, CreateExceptionListOptions, DeleteEndpointListItemOptions, + DeleteExceptionListItemByIdOptions, DeleteExceptionListItemOptions, DeleteExceptionListOptions, FindEndpointListItemOptions, @@ -40,7 +41,7 @@ import { createExceptionListItem } from './create_exception_list_item'; import { updateExceptionList } from './update_exception_list'; import { updateExceptionListItem } from './update_exception_list_item'; import { deleteExceptionList } from './delete_exception_list'; -import { deleteExceptionListItem } from './delete_exception_list_item'; +import { deleteExceptionListItem, deleteExceptionListItemById } from './delete_exception_list_item'; import { findExceptionListItem } from './find_exception_list_item'; import { findExceptionList } from './find_exception_list'; import { findExceptionListsItem } from './find_exception_list_items'; @@ -326,6 +327,18 @@ export class ExceptionListClient { }); }; + public deleteExceptionListItemById = async ({ + id, + namespaceType, + }: DeleteExceptionListItemByIdOptions): Promise => { + const { savedObjectsClient } = this; + return deleteExceptionListItemById({ + id, + namespaceType, + savedObjectsClient, + }); + }; + /** * This is the same as "deleteExceptionListItem" except it applies specifically to the endpoint list. */ diff --git a/x-pack/plugins/lists/server/services/exception_lists/exception_list_client_types.ts b/x-pack/plugins/lists/server/services/exception_lists/exception_list_client_types.ts index 555b9c5e95a77..963716b55ea77 100644 --- a/x-pack/plugins/lists/server/services/exception_lists/exception_list_client_types.ts +++ b/x-pack/plugins/lists/server/services/exception_lists/exception_list_client_types.ts @@ -19,6 +19,7 @@ import { ExceptionListType, ExceptionListTypeOrUndefined, FilterOrUndefined, + Id, IdOrUndefined, Immutable, ItemId, @@ -93,6 +94,11 @@ export interface DeleteExceptionListItemOptions { namespaceType: NamespaceType; } +export interface DeleteExceptionListItemByIdOptions { + id: Id; + namespaceType: NamespaceType; +} + export interface DeleteEndpointListItemOptions { id: IdOrUndefined; itemId: ItemIdOrUndefined; diff --git a/x-pack/plugins/lists/server/services/exception_lists/utils.test.ts b/x-pack/plugins/lists/server/services/exception_lists/utils.test.ts index 6f0c5195f2025..e3d96a9c3f6d0 100644 --- a/x-pack/plugins/lists/server/services/exception_lists/utils.test.ts +++ b/x-pack/plugins/lists/server/services/exception_lists/utils.test.ts @@ -5,15 +5,11 @@ */ import sinon from 'sinon'; import moment from 'moment'; +import uuid from 'uuid'; -import { USER } from '../../../common/constants.mock'; +import { transformCreateCommentsToComments, transformUpdateCommentsToComments } from './utils'; -import { - isCommentEqual, - transformCreateCommentsToComments, - transformUpdateComments, - transformUpdateCommentsToComments, -} from './utils'; +jest.mock('uuid/v4'); describe('utils', () => { const oldDate = '2020-03-17T20:34:51.337Z'; @@ -22,59 +18,43 @@ describe('utils', () => { let clock: sinon.SinonFakeTimers; beforeEach(() => { + ((uuid.v4 as unknown) as jest.Mock) + .mockImplementationOnce(() => '123') + .mockImplementationOnce(() => '456'); + clock = sinon.useFakeTimers(unix); }); afterEach(() => { clock.restore(); + jest.clearAllMocks(); + jest.restoreAllMocks(); + jest.resetAllMocks(); }); describe('#transformUpdateCommentsToComments', () => { - test('it returns empty array if "comments" is undefined and no comments exist', () => { + test('it formats new comments', () => { const comments = transformUpdateCommentsToComments({ - comments: undefined, + comments: [{ comment: 'Im a new comment' }], existingComments: [], user: 'lily', }); - expect(comments).toEqual([]); - }); - - test('it formats newly added comments', () => { - const comments = transformUpdateCommentsToComments({ - comments: [ - { comment: 'Im an old comment', created_at: oldDate, created_by: 'bane' }, - { comment: 'Im a new comment' }, - ], - existingComments: [ - { comment: 'Im an old comment', created_at: oldDate, created_by: 'bane' }, - ], - user: 'lily', - }); - expect(comments).toEqual([ - { - comment: 'Im an old comment', - created_at: oldDate, - created_by: 'bane', - }, { comment: 'Im a new comment', created_at: dateNow, created_by: 'lily', + id: '123', }, ]); }); - test('it formats multiple newly added comments', () => { + test('it formats new comments and preserves existing comments', () => { const comments = transformUpdateCommentsToComments({ - comments: [ - { comment: 'Im an old comment', created_at: oldDate, created_by: 'lily' }, - { comment: 'Im a new comment' }, - { comment: 'Im another new comment' }, - ], + comments: [{ comment: 'Im an old comment', id: '1' }, { comment: 'Im a new comment' }], existingComments: [ - { comment: 'Im an old comment', created_at: oldDate, created_by: 'lily' }, + { comment: 'Im an old comment', created_at: oldDate, created_by: 'bane', id: '1' }, ], user: 'lily', }); @@ -83,26 +63,23 @@ describe('utils', () => { { comment: 'Im an old comment', created_at: oldDate, - created_by: 'lily', + created_by: 'bane', + id: '1', }, { comment: 'Im a new comment', created_at: dateNow, created_by: 'lily', - }, - { - comment: 'Im another new comment', - created_at: dateNow, - created_by: 'lily', + id: '123', }, ]); }); - test('it should not throw if comments match existing comments', () => { + test('it returns existing comments if empty array passed for "comments"', () => { const comments = transformUpdateCommentsToComments({ - comments: [{ comment: 'Im an old comment', created_at: oldDate, created_by: 'lily' }], + comments: [], existingComments: [ - { comment: 'Im an old comment', created_at: oldDate, created_by: 'lily' }, + { comment: 'Im an old comment', created_at: oldDate, created_by: 'bane', id: '1' }, ], user: 'lily', }); @@ -111,170 +88,42 @@ describe('utils', () => { { comment: 'Im an old comment', created_at: oldDate, - created_by: 'lily', + created_by: 'bane', + id: '1', }, ]); }); - test('it does not throw if user tries to update one of their own existing comments', () => { + test('it acts as append only, only modifying new comments', () => { const comments = transformUpdateCommentsToComments({ - comments: [ - { - comment: 'Im an old comment that is trying to be updated', - created_at: oldDate, - created_by: 'lily', - }, - ], + comments: [{ comment: 'Im a new comment' }], existingComments: [ - { comment: 'Im an old comment', created_at: oldDate, created_by: 'lily' }, + { comment: 'Im an old comment', created_at: oldDate, created_by: 'bane', id: '1' }, ], user: 'lily', }); expect(comments).toEqual([ { - comment: 'Im an old comment that is trying to be updated', + comment: 'Im an old comment', created_at: oldDate, + created_by: 'bane', + id: '1', + }, + { + comment: 'Im a new comment', + created_at: dateNow, created_by: 'lily', - updated_at: dateNow, - updated_by: 'lily', + id: '123', }, ]); }); - - test('it throws an error if user tries to update their comment, without passing in the "created_at" and "created_by" properties', () => { - expect(() => - transformUpdateCommentsToComments({ - comments: [ - { - comment: 'Im an old comment that is trying to be updated', - }, - ], - existingComments: [ - { comment: 'Im an old comment', created_at: oldDate, created_by: 'lily' }, - ], - user: 'lily', - }) - ).toThrowErrorMatchingInlineSnapshot( - `"When trying to update a comment, \\"created_at\\" and \\"created_by\\" must be present"` - ); - }); - - test('it throws an error if user tries to delete comments', () => { - expect(() => - transformUpdateCommentsToComments({ - comments: [], - existingComments: [ - { comment: 'Im an old comment', created_at: oldDate, created_by: 'lily' }, - ], - user: 'lily', - }) - ).toThrowErrorMatchingInlineSnapshot( - `"Comments cannot be deleted, only new comments may be added"` - ); - }); - - test('it throws if user tries to update existing comment timestamp', () => { - expect(() => - transformUpdateCommentsToComments({ - comments: [{ comment: 'Im an old comment', created_at: dateNow, created_by: 'lily' }], - existingComments: [ - { comment: 'Im an old comment', created_at: oldDate, created_by: 'lily' }, - ], - user: 'bane', - }) - ).toThrowErrorMatchingInlineSnapshot(`"Not authorized to edit others comments"`); - }); - - test('it throws if user tries to update existing comment author', () => { - expect(() => - transformUpdateCommentsToComments({ - comments: [{ comment: 'Im an old comment', created_at: oldDate, created_by: 'lily' }], - existingComments: [ - { comment: 'Im an old comment', created_at: oldDate, created_by: 'me!' }, - ], - user: 'bane', - }) - ).toThrowErrorMatchingInlineSnapshot(`"Not authorized to edit others comments"`); - }); - - test('it throws if user tries to update an existing comment that is not their own', () => { - expect(() => - transformUpdateCommentsToComments({ - comments: [ - { - comment: 'Im an old comment that is trying to be updated', - created_at: oldDate, - created_by: 'lily', - }, - ], - existingComments: [ - { comment: 'Im an old comment', created_at: oldDate, created_by: 'lily' }, - ], - user: 'bane', - }) - ).toThrowErrorMatchingInlineSnapshot(`"Not authorized to edit others comments"`); - }); - - test('it throws if user tries to update order of comments', () => { - expect(() => - transformUpdateCommentsToComments({ - comments: [ - { comment: 'Im a new comment' }, - { comment: 'Im an old comment', created_at: oldDate, created_by: 'lily' }, - ], - existingComments: [ - { comment: 'Im an old comment', created_at: oldDate, created_by: 'lily' }, - ], - user: 'lily', - }) - ).toThrowErrorMatchingInlineSnapshot( - `"When trying to update a comment, \\"created_at\\" and \\"created_by\\" must be present"` - ); - }); - - test('it throws an error if user tries to add comment formatted as existing comment when none yet exist', () => { - expect(() => - transformUpdateCommentsToComments({ - comments: [ - { comment: 'Im an old comment', created_at: oldDate, created_by: 'lily' }, - { comment: 'Im a new comment' }, - ], - existingComments: [], - user: 'lily', - }) - ).toThrowErrorMatchingInlineSnapshot(`"Only new comments may be added"`); - }); - - test('it throws if empty comment exists', () => { - expect(() => - transformUpdateCommentsToComments({ - comments: [ - { comment: 'Im an old comment', created_at: oldDate, created_by: 'lily' }, - { comment: ' ' }, - ], - existingComments: [ - { comment: 'Im an old comment', created_at: oldDate, created_by: 'lily' }, - ], - user: 'lily', - }) - ).toThrowErrorMatchingInlineSnapshot(`"Empty comments not allowed"`); - }); }); describe('#transformCreateCommentsToComments', () => { - test('it returns "undefined" if "comments" is "undefined"', () => { - const comments = transformCreateCommentsToComments({ - comments: undefined, - user: 'lily', - }); - - expect(comments).toBeUndefined(); - }); - test('it formats newly added comments', () => { const comments = transformCreateCommentsToComments({ - comments: [{ comment: 'Im a new comment' }, { comment: 'Im another new comment' }], + incomingComments: [{ comment: 'Im a new comment' }, { comment: 'Im another new comment' }], user: 'lily', }); @@ -283,178 +132,15 @@ describe('utils', () => { comment: 'Im a new comment', created_at: dateNow, created_by: 'lily', + id: '123', }, { comment: 'Im another new comment', created_at: dateNow, created_by: 'lily', + id: '456', }, ]); }); - - test('it throws an error if user tries to add an empty comment', () => { - expect(() => - transformCreateCommentsToComments({ - comments: [{ comment: ' ' }], - user: 'lily', - }) - ).toThrowErrorMatchingInlineSnapshot(`"Empty comments not allowed"`); - }); - }); - - describe('#transformUpdateComments', () => { - test('it updates comment and adds "updated_at" and "updated_by" if content differs', () => { - const comments = transformUpdateComments({ - comment: { - comment: 'Im an old comment that is trying to be updated', - created_at: oldDate, - created_by: 'lily', - }, - existingComment: { - comment: 'Im an old comment', - created_at: oldDate, - created_by: 'lily', - }, - user: 'lily', - }); - - expect(comments).toEqual({ - comment: 'Im an old comment that is trying to be updated', - created_at: oldDate, - created_by: 'lily', - updated_at: dateNow, - updated_by: 'lily', - }); - }); - - test('it does not update comment and add "updated_at" and "updated_by" if content is the same', () => { - const comments = transformUpdateComments({ - comment: { - comment: 'Im an old comment ', - created_at: oldDate, - created_by: 'lily', - }, - existingComment: { - comment: 'Im an old comment', - created_at: oldDate, - created_by: 'lily', - }, - user: 'lily', - }); - - expect(comments).toEqual({ - comment: 'Im an old comment', - created_at: oldDate, - created_by: 'lily', - }); - }); - - test('it throws if user tries to update an existing comment that is not their own', () => { - expect(() => - transformUpdateComments({ - comment: { - comment: 'Im an old comment that is trying to be updated', - created_at: oldDate, - created_by: 'lily', - }, - existingComment: { - comment: 'Im an old comment', - created_at: oldDate, - created_by: 'lily', - }, - user: 'bane', - }) - ).toThrowErrorMatchingInlineSnapshot(`"Not authorized to edit others comments"`); - }); - - test('it throws if user tries to update an existing comments timestamp', () => { - expect(() => - transformUpdateComments({ - comment: { - comment: 'Im an old comment', - created_at: dateNow, - created_by: 'lily', - }, - existingComment: { - comment: 'Im an old comment', - created_at: oldDate, - created_by: 'lily', - }, - user: 'lily', - }) - ).toThrowErrorMatchingInlineSnapshot(`"Unable to update comment"`); - }); - }); - - describe('#isCommentEqual', () => { - test('it returns false if "comment" values differ', () => { - const result = isCommentEqual( - { - comment: 'some old comment', - created_at: oldDate, - created_by: USER, - }, - { - comment: 'some older comment', - created_at: oldDate, - created_by: USER, - } - ); - - expect(result).toBeFalsy(); - }); - - test('it returns false if "created_at" values differ', () => { - const result = isCommentEqual( - { - comment: 'some old comment', - created_at: oldDate, - created_by: USER, - }, - { - comment: 'some old comment', - created_at: dateNow, - created_by: USER, - } - ); - - expect(result).toBeFalsy(); - }); - - test('it returns false if "created_by" values differ', () => { - const result = isCommentEqual( - { - comment: 'some old comment', - created_at: oldDate, - created_by: USER, - }, - { - comment: 'some old comment', - created_at: oldDate, - created_by: 'lily', - } - ); - - expect(result).toBeFalsy(); - }); - - test('it returns true if comment values are equivalent', () => { - const result = isCommentEqual( - { - comment: 'some old comment', - created_at: oldDate, - created_by: USER, - }, - { - created_at: oldDate, - created_by: USER, - // Disabling to assure that order doesn't matter - // eslint-disable-next-line sort-keys - comment: 'some old comment', - } - ); - - expect(result).toBeTruthy(); - }); }); }); diff --git a/x-pack/plugins/lists/server/services/exception_lists/utils.ts b/x-pack/plugins/lists/server/services/exception_lists/utils.ts index b168fae741822..836f642899086 100644 --- a/x-pack/plugins/lists/server/services/exception_lists/utils.ts +++ b/x-pack/plugins/lists/server/services/exception_lists/utils.ts @@ -3,17 +3,14 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ - +import uuid from 'uuid'; import { SavedObject, SavedObjectsFindResponse, SavedObjectsUpdateResponse } from 'kibana/server'; import { NamespaceTypeArray } from '../../../common/schemas/types/default_namespace_array'; -import { ErrorWithStatusCode } from '../../error_with_status_code'; import { - Comments, CommentsArray, - CommentsArrayOrUndefined, - CreateComments, - CreateCommentsArrayOrUndefined, + CreateComment, + CreateCommentsArray, ExceptionListItemSchema, ExceptionListSchema, ExceptionListSoSchema, @@ -21,7 +18,6 @@ import { FoundExceptionListSchema, NamespaceType, UpdateCommentsArrayOrUndefined, - comments as commentsSchema, exceptionListItemType, exceptionListType, } from '../../../common/schemas'; @@ -296,17 +292,6 @@ export const transformSavedObjectsToFoundExceptionList = ({ }; }; -/* - * Determines whether two comments are equal, this is a very - * naive implementation, not meant to be used for deep equality of complex objects - */ -export const isCommentEqual = (commentA: Comments, commentB: Comments): boolean => { - const a = Object.values(commentA).sort().join(); - const b = Object.values(commentB).sort().join(); - - return a === b; -}; - export const transformUpdateCommentsToComments = ({ comments, existingComments, @@ -316,90 +301,28 @@ export const transformUpdateCommentsToComments = ({ existingComments: CommentsArray; user: string; }): CommentsArray => { - const newComments = comments ?? []; + const incomingComments = comments ?? []; + const newComments = incomingComments.filter((comment) => comment.id == null); + const newCommentsFormatted = transformCreateCommentsToComments({ + incomingComments: newComments, + user, + }); - if (newComments.length < existingComments.length) { - throw new ErrorWithStatusCode( - 'Comments cannot be deleted, only new comments may be added', - 403 - ); - } else { - return newComments.flatMap((c, index) => { - const existingComment = existingComments[index]; - - if (commentsSchema.is(existingComment) && !commentsSchema.is(c)) { - throw new ErrorWithStatusCode( - 'When trying to update a comment, "created_at" and "created_by" must be present', - 403 - ); - } else if (existingComment == null && commentsSchema.is(c)) { - throw new ErrorWithStatusCode('Only new comments may be added', 403); - } else if ( - commentsSchema.is(c) && - existingComment != null && - isCommentEqual(c, existingComment) - ) { - return existingComment; - } else if (commentsSchema.is(c) && existingComment != null) { - return transformUpdateComments({ comment: c, existingComment, user }); - } else { - return transformCreateCommentsToComments({ comments: [c], user }) ?? []; - } - }); - } -}; - -export const transformUpdateComments = ({ - comment, - existingComment, - user, -}: { - comment: Comments; - existingComment: Comments; - user: string; -}): Comments => { - if (comment.created_by !== user) { - // existing comment is being edited, can only be edited by author - throw new ErrorWithStatusCode('Not authorized to edit others comments', 401); - } else if (existingComment.created_at !== comment.created_at) { - throw new ErrorWithStatusCode('Unable to update comment', 403); - } else if (comment.comment.trim().length === 0) { - throw new ErrorWithStatusCode('Empty comments not allowed', 403); - } else if (comment.comment.trim() !== existingComment.comment) { - const dateNow = new Date().toISOString(); - - return { - ...existingComment, - comment: comment.comment, - updated_at: dateNow, - updated_by: user, - }; - } else { - return existingComment; - } + return [...existingComments, ...newCommentsFormatted]; }; export const transformCreateCommentsToComments = ({ - comments, + incomingComments, user, }: { - comments: CreateCommentsArrayOrUndefined; + incomingComments: CreateCommentsArray; user: string; -}): CommentsArrayOrUndefined => { +}): CommentsArray => { const dateNow = new Date().toISOString(); - if (comments != null) { - return comments.map((c: CreateComments) => { - if (c.comment.trim().length === 0) { - throw new ErrorWithStatusCode('Empty comments not allowed', 403); - } else { - return { - comment: c.comment, - created_at: dateNow, - created_by: user, - }; - } - }); - } else { - return comments; - } + return incomingComments.map((comment: CreateComment) => ({ + comment: comment.comment, + created_at: dateNow, + created_by: user, + id: uuid.v4(), + })); }; diff --git a/x-pack/plugins/lists/server/services/lists/list_client.mock.ts b/x-pack/plugins/lists/server/services/lists/list_client.mock.ts index e5036d561ddc6..a2959a024f292 100644 --- a/x-pack/plugins/lists/server/services/lists/list_client.mock.ts +++ b/x-pack/plugins/lists/server/services/lists/list_client.mock.ts @@ -11,6 +11,7 @@ import { getListResponseMock } from '../../../common/schemas/response/list_schem import { getCallClusterMock } from '../../../common/get_call_cluster.mock'; import { IMPORT_BUFFER_SIZE, + IMPORT_TIMEOUT, LIST_INDEX, LIST_ITEM_INDEX, MAX_IMPORT_PAYLOAD_BYTES, @@ -65,6 +66,7 @@ export const getListClientMock = (): ListClient => { config: { enabled: true, importBufferSize: IMPORT_BUFFER_SIZE, + importTimeout: IMPORT_TIMEOUT, listIndex: LIST_INDEX, listItemIndex: LIST_ITEM_INDEX, maxImportPayloadBytes: MAX_IMPORT_PAYLOAD_BYTES, diff --git a/x-pack/plugins/maps/public/actions/data_request_actions.ts b/x-pack/plugins/maps/public/actions/data_request_actions.ts index a0c484a82e530..6c84dd41d80d4 100644 --- a/x-pack/plugins/maps/public/actions/data_request_actions.ts +++ b/x-pack/plugins/maps/public/actions/data_request_actions.ts @@ -39,6 +39,8 @@ import { import { ILayer } from '../classes/layers/layer'; import { DataMeta, MapExtent, MapFilters } from '../../common/descriptor_types'; import { DataRequestAbortError } from '../classes/util/data_request'; +// @ts-expect-error +import { turfBboxToBounds } from '../elasticsearch_geo_utils'; export type DataRequestContext = { startLoading(dataId: string, requestToken: symbol, meta: DataMeta): void; @@ -351,13 +353,7 @@ export function fitToDataBounds() { return; } - const turfUnionBbox = turf.bbox(turf.multiPoint(corners)); - const dataBounds = { - minLon: turfUnionBbox[0], - minLat: turfUnionBbox[1], - maxLon: turfUnionBbox[2], - maxLat: turfUnionBbox[3], - }; + const dataBounds = turfBboxToBounds(turf.bbox(turf.multiPoint(corners))); dispatch(setGotoWithBounds(dataBounds)); }; diff --git a/x-pack/plugins/maps/public/classes/sources/es_pew_pew_source/es_pew_pew_source.js b/x-pack/plugins/maps/public/classes/sources/es_pew_pew_source/es_pew_pew_source.js index 98db7bcdcc8a3..33d5deef2e39f 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_pew_pew_source/es_pew_pew_source.js +++ b/x-pack/plugins/maps/public/classes/sources/es_pew_pew_source/es_pew_pew_source.js @@ -6,6 +6,7 @@ import React from 'react'; import uuid from 'uuid/v4'; +import turf from 'turf'; import { UpdateSourceEditor } from './update_source_editor'; import { i18n } from '@kbn/i18n'; @@ -13,8 +14,9 @@ import { SOURCE_TYPES, VECTOR_SHAPE_TYPE } from '../../../../common/constants'; import { getDataSourceLabel } from '../../../../common/i18n_getters'; import { convertToLines } from './convert_to_lines'; import { AbstractESAggSource, DEFAULT_METRIC } from '../es_agg_source'; -import { indexPatterns } from '../../../../../../../src/plugins/data/public'; import { registerSource } from '../source_registry'; +import { turfBboxToBounds } from '../../../elasticsearch_geo_utils'; +import { DataRequestAbortError } from '../../util/data_request'; const MAX_GEOTILE_LEVEL = 29; @@ -158,19 +160,63 @@ export class ESPewPewSource extends AbstractESAggSource { }; } - async _getGeoField() { - const indexPattern = await this.getIndexPattern(); - const field = indexPattern.fields.getByName(this._descriptor.destGeoField); - const geoField = indexPatterns.isNestedField(field) ? undefined : field; - if (!geoField) { - throw new Error( - i18n.translate('xpack.maps.source.esSource.noGeoFieldErrorMessage', { - defaultMessage: `Index pattern {indexPatternTitle} no longer contains the geo field {geoField}`, - values: { indexPatternTitle: indexPattern.title, geoField: this._descriptor.geoField }, - }) - ); + getGeoFieldName() { + return this._descriptor.destGeoField; + } + + async getBoundsForFilters(boundsFilters, registerCancelCallback) { + const searchSource = await this.makeSearchSource(boundsFilters, 0); + searchSource.setField('aggs', { + destFitToBounds: { + geo_bounds: { + field: this._descriptor.destGeoField, + }, + }, + sourceFitToBounds: { + geo_bounds: { + field: this._descriptor.sourceGeoField, + }, + }, + }); + + const corners = []; + try { + const abortController = new AbortController(); + registerCancelCallback(() => abortController.abort()); + const esResp = await searchSource.fetch({ abortSignal: abortController.signal }); + if (esResp.aggregations.destFitToBounds.bounds) { + corners.push([ + esResp.aggregations.destFitToBounds.bounds.top_left.lon, + esResp.aggregations.destFitToBounds.bounds.top_left.lat, + ]); + corners.push([ + esResp.aggregations.destFitToBounds.bounds.bottom_right.lon, + esResp.aggregations.destFitToBounds.bounds.bottom_right.lat, + ]); + } + if (esResp.aggregations.sourceFitToBounds.bounds) { + corners.push([ + esResp.aggregations.sourceFitToBounds.bounds.top_left.lon, + esResp.aggregations.sourceFitToBounds.bounds.top_left.lat, + ]); + corners.push([ + esResp.aggregations.sourceFitToBounds.bounds.bottom_right.lon, + esResp.aggregations.sourceFitToBounds.bounds.bottom_right.lat, + ]); + } + } catch (error) { + if (error.name === 'AbortError') { + throw new DataRequestAbortError(); + } + + return null; + } + + if (corners.length === 0) { + return null; } - return geoField; + + return turfBboxToBounds(turf.bbox(turf.multiPoint(corners))); } canFormatFeatureProperties() { diff --git a/x-pack/plugins/maps/public/classes/sources/es_source/es_source.js b/x-pack/plugins/maps/public/classes/sources/es_source/es_source.js index 450894d81485c..c043e6d6994ab 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_source/es_source.js +++ b/x-pack/plugins/maps/public/classes/sources/es_source/es_source.js @@ -150,7 +150,7 @@ export class AbstractESSource extends AbstractVectorSource { searchSource.setField('aggs', { fitToBounds: { geo_bounds: { - field: this._descriptor.geoField, + field: this.getGeoFieldName(), }, }, }); @@ -230,12 +230,12 @@ export class AbstractESSource extends AbstractVectorSource { async _getGeoField() { const indexPattern = await this.getIndexPattern(); - const geoField = indexPattern.fields.getByName(this._descriptor.geoField); + const geoField = indexPattern.fields.getByName(this.getGeoFieldName()); if (!geoField) { throw new Error( i18n.translate('xpack.maps.source.esSource.noGeoFieldErrorMessage', { defaultMessage: `Index pattern {indexPatternTitle} no longer contains the geo field {geoField}`, - values: { indexPatternTitle: indexPattern.title, geoField: this._descriptor.geoField }, + values: { indexPatternTitle: indexPattern.title, geoField: this.getGeoFieldName() }, }) ); } diff --git a/x-pack/plugins/maps/public/elasticsearch_geo_utils.js b/x-pack/plugins/maps/public/elasticsearch_geo_utils.js index 0d247d389f478..71d8deb7438aa 100644 --- a/x-pack/plugins/maps/public/elasticsearch_geo_utils.js +++ b/x-pack/plugins/maps/public/elasticsearch_geo_utils.js @@ -469,3 +469,12 @@ export function extractFeaturesFromFilters(filters) { return features; } + +export function turfBboxToBounds(turfBbox) { + return { + minLon: turfBbox[0], + minLat: turfBbox[1], + maxLon: turfBbox[2], + maxLat: turfBbox[3], + }; +} diff --git a/x-pack/plugins/ml/common/license/index.ts b/x-pack/plugins/ml/common/license/index.ts index e87986a26a3bd..e09040a9a26f4 100644 --- a/x-pack/plugins/ml/common/license/index.ts +++ b/x-pack/plugins/ml/common/license/index.ts @@ -11,4 +11,5 @@ export { MINIMUM_LICENSE, isFullLicense, isMinimumLicense, + isMlEnabled, } from './ml_license'; diff --git a/x-pack/plugins/ml/common/license/ml_license.ts b/x-pack/plugins/ml/common/license/ml_license.ts index e4367c9b921f4..44ed892ff0d0a 100644 --- a/x-pack/plugins/ml/common/license/ml_license.ts +++ b/x-pack/plugins/ml/common/license/ml_license.ts @@ -82,3 +82,7 @@ export function isFullLicense(license: ILicense) { export function isMinimumLicense(license: ILicense) { return license.check(PLUGIN_ID, MINIMUM_LICENSE).state === 'valid'; } + +export function isMlEnabled(license: ILicense) { + return license.getFeature(PLUGIN_ID).isEnabled; +} diff --git a/x-pack/plugins/ml/common/types/capabilities.ts b/x-pack/plugins/ml/common/types/capabilities.ts index 504cd28b8fa14..58a2043502d27 100644 --- a/x-pack/plugins/ml/common/types/capabilities.ts +++ b/x-pack/plugins/ml/common/types/capabilities.ts @@ -7,6 +7,10 @@ import { KibanaRequest } from 'kibana/server'; import { PLUGIN_ID } from '../constants/app'; +export const apmUserMlCapabilities = { + canGetJobs: false, +}; + export const userMlCapabilities = { canAccessML: false, // Anomaly Detection @@ -68,6 +72,7 @@ export function getDefaultCapabilities(): MlCapabilities { } export function getPluginPrivileges() { + const apmUserMlCapabilitiesKeys = Object.keys(apmUserMlCapabilities); const userMlCapabilitiesKeys = Object.keys(userMlCapabilities); const adminMlCapabilitiesKeys = Object.keys(adminMlCapabilities); const allMlCapabilitiesKeys = [...adminMlCapabilitiesKeys, ...userMlCapabilitiesKeys]; @@ -101,6 +106,17 @@ export function getPluginPrivileges() { read: savedObjects, }, }, + apmUser: { + excludeFromBasePrivileges: true, + app: [], + catalogue: [], + savedObject: { + all: [], + read: [], + }, + api: apmUserMlCapabilitiesKeys.map((k) => `ml:${k}`), + ui: apmUserMlCapabilitiesKeys, + }, }; } diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/outlier_exploration.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/outlier_exploration.tsx index 9341c0aa1a338..4c4731d0dad5f 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/outlier_exploration.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/outlier_exploration.tsx @@ -56,6 +56,13 @@ export const OutlierExploration: FC = React.memo(({ jobId }) = const { columnsWithCharts, errorMessage, status, tableItems } = outlierData; + /* eslint-disable-next-line react-hooks/rules-of-hooks */ + const colorRange = useColorRange( + COLOR_RANGE.BLUE, + COLOR_RANGE_SCALE.INFLUENCER, + jobConfig !== undefined ? getFeatureCount(jobConfig.dest.results_field, tableItems) : 1 + ); + // if it's a searchBar syntax error leave the table visible so they can try again if (status === INDEX_STATUS.ERROR && !errorMessage.includes('failed to create query')) { return ( @@ -74,13 +81,6 @@ export const OutlierExploration: FC = React.memo(({ jobId }) = ); } - /* eslint-disable-next-line react-hooks/rules-of-hooks */ - const colorRange = useColorRange( - COLOR_RANGE.BLUE, - COLOR_RANGE_SCALE.INFLUENCER, - jobConfig !== undefined ? getFeatureCount(jobConfig.dest.results_field, tableItems) : 1 - ); - return ( {jobConfig !== undefined && needsDestIndexPattern && ( diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_view/get_view_link_status.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_view/get_view_link_status.ts new file mode 100644 index 0000000000000..e5f6c27582a05 --- /dev/null +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_view/get_view_link_status.ts @@ -0,0 +1,83 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; +import { + isRegressionAnalysis, + isOutlierAnalysis, + isClassificationAnalysis, +} from '../../../../common/analytics'; +import { + DataFrameAnalyticsListRow, + isDataFrameAnalyticsStopped, + isDataFrameAnalyticsFailed, + getDataFrameAnalyticsProgressPhase, +} from '../analytics_list/common'; + +const unknownJobTypeMessage = i18n.translate( + 'xpack.ml.dataframe.analyticsList.viewActionUnknownJobTypeToolTipContent', + { + defaultMessage: 'There is no results page available for this type of data frame analytics job.', + } +); +const jobNotStartedMessage = i18n.translate( + 'xpack.ml.dataframe.analyticsList.viewActionJobNotStartedToolTipContent', + { + defaultMessage: + 'The data frame analytics job did not start. There is no results page available.', + } +); +const jobNotFinishedMessage = i18n.translate( + 'xpack.ml.dataframe.analyticsList.viewActionJobNotFinishedToolTipContent', + { + defaultMessage: + 'The data frame analytics job is not finished. There is no results page available.', + } +); +const jobFailedMessage = i18n.translate( + 'xpack.ml.dataframe.analyticsList.viewActionJobFailedToolTipContent', + { + defaultMessage: 'The data frame analytics job failed. There is no results page available.', + } +); + +interface ViewLinkStatusReturn { + disabled: boolean; + tooltipContent?: string; +} + +export function getViewLinkStatus(item: DataFrameAnalyticsListRow): ViewLinkStatusReturn { + const viewLinkStatus: ViewLinkStatusReturn = { disabled: false }; + + const progressStats = getDataFrameAnalyticsProgressPhase(item.stats); + const jobFailed = isDataFrameAnalyticsFailed(item.stats.state); + const jobNotStarted = progressStats.currentPhase === 1 && progressStats.progress === 0; + const jobFinished = + isDataFrameAnalyticsStopped(item.stats.state) && + progressStats.currentPhase === progressStats.totalPhases && + progressStats.progress === 100; + const isUnknownJobType = + !isRegressionAnalysis(item.config.analysis) && + !isOutlierAnalysis(item.config.analysis) && + !isClassificationAnalysis(item.config.analysis); + + const disabled = !jobFinished || jobFailed || isUnknownJobType; + + if (disabled) { + viewLinkStatus.disabled = true; + if (isUnknownJobType) { + viewLinkStatus.tooltipContent = unknownJobTypeMessage; + } else if (jobFailed) { + viewLinkStatus.tooltipContent = jobFailedMessage; + } else if (jobNotStarted) { + viewLinkStatus.tooltipContent = jobNotStartedMessage; + } else if (!jobFinished) { + viewLinkStatus.tooltipContent = jobNotFinishedMessage; + } + } + + return viewLinkStatus; +} diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_view/view_button.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_view/view_button.tsx index 52b2513d13e39..8a4509ebfd007 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_view/view_button.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_view/view_button.tsx @@ -8,16 +8,13 @@ import React, { FC } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiButtonEmpty, EuiToolTip } from '@elastic/eui'; -import { - getAnalysisType, - isRegressionAnalysis, - isOutlierAnalysis, - isClassificationAnalysis, -} from '../../../../common/analytics'; +import { getAnalysisType } from '../../../../common/analytics'; import { useMlKibana } from '../../../../../contexts/kibana'; import { getResultsUrl, DataFrameAnalyticsListRow } from '../analytics_list/common'; +import { getViewLinkStatus } from './get_view_link_status'; + interface ViewButtonProps { item: DataFrameAnalyticsListRow; isManagementTable: boolean; @@ -30,11 +27,8 @@ export const ViewButton: FC = ({ item, isManagementTable }) => }, } = useMlKibana(); + const { disabled, tooltipContent } = getViewLinkStatus(item); const analysisType = getAnalysisType(item.config.analysis); - const buttonDisabled = - !isRegressionAnalysis(item.config.analysis) && - !isOutlierAnalysis(item.config.analysis) && - !isClassificationAnalysis(item.config.analysis); const url = getResultsUrl(item.id, analysisType); const navigator = isManagementTable @@ -52,7 +46,7 @@ export const ViewButton: FC = ({ item, isManagementTable }) => data-test-subj="mlAnalyticsJobViewButton" flush="left" iconType="visTable" - isDisabled={buttonDisabled} + isDisabled={disabled} onClick={navigator} size="s" > @@ -60,15 +54,9 @@ export const ViewButton: FC = ({ item, isManagementTable }) => ); - if (buttonDisabled) { + if (disabled) { return ( - + {button} ); diff --git a/x-pack/plugins/ml/public/application/management/index.ts b/x-pack/plugins/ml/public/application/management/index.ts index 897731304ee7a..a1b8484f200ec 100644 --- a/x-pack/plugins/ml/public/application/management/index.ts +++ b/x-pack/plugins/ml/public/application/management/index.ts @@ -11,37 +11,28 @@ */ import { i18n } from '@kbn/i18n'; -import { take } from 'rxjs/operators'; import { CoreSetup } from 'kibana/public'; -import { MlStartDependencies, MlSetupDependencies } from '../../plugin'; +import { ManagementSetup } from 'src/plugins/management/public'; +import { MlStartDependencies } from '../../plugin'; import { ManagementAppMountParams } from '../../../../../../src/plugins/management/public'; -import { PLUGIN_ID } from '../../../common/constants/app'; -import { MINIMUM_FULL_LICENSE } from '../../../common/license'; -export function initManagementSection( - pluginsSetup: MlSetupDependencies, +export function registerManagementSection( + management: ManagementSetup | undefined, core: CoreSetup ) { - const licensing = pluginsSetup.licensing.license$.pipe(take(1)); - licensing.subscribe((license) => { - const management = pluginsSetup.management; - if ( - management !== undefined && - license.check(PLUGIN_ID, MINIMUM_FULL_LICENSE).state === 'valid' - ) { - management.sections.section.insightsAndAlerting.registerApp({ - id: 'jobsListLink', - title: i18n.translate('xpack.ml.management.jobsListTitle', { - defaultMessage: 'Machine Learning Jobs', - }), - order: 2, - async mount(params: ManagementAppMountParams) { - const { mountApp } = await import('./jobs_list'); - return mountApp(core, params); - }, - }); - } - }); + if (management !== undefined) { + management.sections.section.insightsAndAlerting.registerApp({ + id: 'jobsListLink', + title: i18n.translate('xpack.ml.management.jobsListTitle', { + defaultMessage: 'Machine Learning Jobs', + }), + order: 2, + async mount(params: ManagementAppMountParams) { + const { mountApp } = await import('./jobs_list'); + return mountApp(core, params); + }, + }); + } } diff --git a/x-pack/plugins/ml/public/plugin.ts b/x-pack/plugins/ml/public/plugin.ts index 449d8baa2a184..a8e1e804c2fe3 100644 --- a/x-pack/plugins/ml/public/plugin.ts +++ b/x-pack/plugins/ml/public/plugin.ts @@ -12,6 +12,8 @@ import { AppMountParameters, PluginInitializerContext, } from 'kibana/public'; +import { BehaviorSubject } from 'rxjs'; +import { take } from 'rxjs/operators'; import { ManagementSetup } from 'src/plugins/management/public'; import { SharePluginSetup, SharePluginStart, UrlGeneratorState } from 'src/plugins/share/public'; import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; @@ -19,9 +21,10 @@ import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; import { DataPublicPluginStart } from 'src/plugins/data/public'; import { HomePublicPluginSetup } from 'src/plugins/home/public'; import { EmbeddableSetup } from 'src/plugins/embeddable/public'; +import { AppStatus, AppUpdater } from '../../../../src/core/public'; import { SecurityPluginSetup } from '../../security/public'; import { LicensingPluginSetup } from '../../licensing/public'; -import { initManagementSection } from './application/management'; +import { registerManagementSection } from './application/management'; import { LicenseManagementUIPluginSetup } from '../../license_management/public'; import { setDependencyCache } from './application/util/dependency_cache'; import { PLUGIN_ID, PLUGIN_ICON } from '../common/constants/app'; @@ -31,7 +34,8 @@ import { registerEmbeddables } from './embeddables'; import { UiActionsSetup, UiActionsStart } from '../../../../src/plugins/ui_actions/public'; import { registerMlUiActions } from './ui_actions'; import { KibanaLegacyStart } from '../../../../src/plugins/kibana_legacy/public'; -import { MlUrlGenerator, MlUrlGeneratorState, ML_APP_URL_GENERATOR } from './url_generator'; +import { registerUrlGenerator, MlUrlGeneratorState, ML_APP_URL_GENERATOR } from './url_generator'; +import { isMlEnabled, isFullLicense } from '../common/license'; export interface MlStartDependencies { data: DataPublicPluginStart; @@ -61,18 +65,11 @@ declare module '../../../../src/plugins/share/public' { export type MlCoreSetup = CoreSetup; export class MlPlugin implements Plugin { + private appUpdater = new BehaviorSubject(() => ({})); + constructor(private initializerContext: PluginInitializerContext) {} setup(core: MlCoreSetup, pluginsSetup: MlSetupDependencies) { - const baseUrl = core.http.basePath.prepend('/app/ml'); - - pluginsSetup.share.urlGenerators.registerUrlGenerator( - new MlUrlGenerator({ - appBasePath: baseUrl, - useHash: core.uiSettings.get('state:storeInSessionStorage'), - }) - ); - core.application.register({ id: PLUGIN_ID, title: i18n.translate('xpack.ml.plugin.title', { @@ -82,6 +79,7 @@ export class MlPlugin implements Plugin { euiIconType: PLUGIN_ICON, appRoute: '/app/ml', category: DEFAULT_APP_CATEGORIES.kibana, + updater$: this.appUpdater, mount: async (params: AppMountParameters) => { const [coreStart, pluginsStart] = await core.getStartServices(); const kibanaVersion = this.initializerContext.env.packageInfo.version; @@ -112,11 +110,26 @@ export class MlPlugin implements Plugin { }, }); - registerFeature(pluginsSetup.home); + const licensing = pluginsSetup.licensing.license$.pipe(take(1)); + licensing.subscribe((license) => { + if (isMlEnabled(license)) { + // add ML to home page + registerFeature(pluginsSetup.home); - initManagementSection(pluginsSetup, core); - registerEmbeddables(pluginsSetup.embeddable, core); - registerMlUiActions(pluginsSetup.uiActions, core); + // register various ML plugin features which require a full license + if (isFullLicense(license)) { + registerManagementSection(pluginsSetup.management, core); + registerEmbeddables(pluginsSetup.embeddable, core); + registerMlUiActions(pluginsSetup.uiActions, core); + registerUrlGenerator(pluginsSetup.share, core); + } + } else { + // if ml is disabled in elasticsearch, disable ML in kibana + this.appUpdater.next(() => ({ + status: AppStatus.inaccessible, + })); + } + }); return {}; } diff --git a/x-pack/plugins/ml/public/url_generator.ts b/x-pack/plugins/ml/public/url_generator.ts index 65d5077e081a3..c2b57f6349d81 100644 --- a/x-pack/plugins/ml/public/url_generator.ts +++ b/x-pack/plugins/ml/public/url_generator.ts @@ -4,11 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -import { UrlGeneratorsDefinition } from '../../../../src/plugins/share/public'; +import { CoreSetup } from 'kibana/public'; +import { SharePluginSetup, UrlGeneratorsDefinition } from '../../../../src/plugins/share/public'; import { TimeRange } from '../../../../src/plugins/data/public'; import { setStateToKbnUrl } from '../../../../src/plugins/kibana_utils/public'; import { JobId } from '../../reporting/common/types'; import { ExplorerAppState } from './application/explorer/explorer_dashboard_service'; +import { MlStartDependencies } from './plugin'; export const ML_APP_URL_GENERATOR = 'ML_APP_URL_GENERATOR'; @@ -88,3 +90,19 @@ export class MlUrlGenerator implements UrlGeneratorsDefinition +) { + const baseUrl = core.http.basePath.prepend('/app/ml'); + share.urlGenerators.registerUrlGenerator( + new MlUrlGenerator({ + appBasePath: baseUrl, + useHash: core.uiSettings.get('state:storeInSessionStorage'), + }) + ); +} diff --git a/x-pack/plugins/ml/server/client/elasticsearch_ml.ts b/x-pack/plugins/ml/server/client/elasticsearch_ml.ts index 24c80c450f61a..63153d18cb10b 100644 --- a/x-pack/plugins/ml/server/client/elasticsearch_ml.ts +++ b/x-pack/plugins/ml/server/client/elasticsearch_ml.ts @@ -828,7 +828,7 @@ export const elasticsearchJsPlugin = (Client: any, config: any, components: any) ml.categories = ca({ urls: [ { - fmt: '/_xpack/ml/anomaly_detectors/<%=jobId%>/results/categories/<%=categoryId%>', + fmt: '/_ml/anomaly_detectors/<%=jobId%>/results/categories/<%=categoryId%>', req: { jobId: { type: 'string', @@ -839,7 +839,7 @@ export const elasticsearchJsPlugin = (Client: any, config: any, components: any) }, }, { - fmt: '/_xpack/ml/anomaly_detectors/<%=jobId%>/results/categories', + fmt: '/_ml/anomaly_detectors/<%=jobId%>/results/categories', req: { jobId: { type: 'string', @@ -853,7 +853,7 @@ export const elasticsearchJsPlugin = (Client: any, config: any, components: any) ml.modelSnapshots = ca({ urls: [ { - fmt: '/_xpack/ml/anomaly_detectors/<%=jobId%>/model_snapshots/<%=snapshotId%>', + fmt: '/_ml/anomaly_detectors/<%=jobId%>/model_snapshots/<%=snapshotId%>', req: { jobId: { type: 'string', @@ -864,7 +864,7 @@ export const elasticsearchJsPlugin = (Client: any, config: any, components: any) }, }, { - fmt: '/_xpack/ml/anomaly_detectors/<%=jobId%>/model_snapshots', + fmt: '/_ml/anomaly_detectors/<%=jobId%>/model_snapshots', req: { jobId: { type: 'string', @@ -878,7 +878,7 @@ export const elasticsearchJsPlugin = (Client: any, config: any, components: any) ml.updateModelSnapshot = ca({ urls: [ { - fmt: '/_xpack/ml/anomaly_detectors/<%=jobId%>/model_snapshots/<%=snapshotId%>/_update', + fmt: '/_ml/anomaly_detectors/<%=jobId%>/model_snapshots/<%=snapshotId%>/_update', req: { jobId: { type: 'string', @@ -896,7 +896,7 @@ export const elasticsearchJsPlugin = (Client: any, config: any, components: any) ml.deleteModelSnapshot = ca({ urls: [ { - fmt: '/_xpack/ml/anomaly_detectors/<%=jobId%>/model_snapshots/<%=snapshotId%>', + fmt: '/_ml/anomaly_detectors/<%=jobId%>/model_snapshots/<%=snapshotId%>', req: { jobId: { type: 'string', @@ -913,7 +913,7 @@ export const elasticsearchJsPlugin = (Client: any, config: any, components: any) ml.revertModelSnapshot = ca({ urls: [ { - fmt: '/_xpack/ml/anomaly_detectors/<%=jobId%>/model_snapshots/<%=snapshotId%>/_revert', + fmt: '/_ml/anomaly_detectors/<%=jobId%>/model_snapshots/<%=snapshotId%>/_revert', req: { jobId: { type: 'string', diff --git a/x-pack/plugins/ml/server/lib/capabilities/capabilities_switcher.ts b/x-pack/plugins/ml/server/lib/capabilities/capabilities_switcher.ts index 5b8cbc4bdbbe8..f2fff4cc64aab 100644 --- a/x-pack/plugins/ml/server/lib/capabilities/capabilities_switcher.ts +++ b/x-pack/plugins/ml/server/lib/capabilities/capabilities_switcher.ts @@ -9,7 +9,7 @@ import { Observable } from 'rxjs'; import { take } from 'rxjs/operators'; import { CapabilitiesSwitcher, CoreSetup, Logger } from 'src/core/server'; import { ILicense } from '../../../../licensing/common/types'; -import { isFullLicense, isMinimumLicense } from '../../../common/license'; +import { isFullLicense, isMinimumLicense, isMlEnabled } from '../../../common/license'; import { MlCapabilities, basicLicenseMlCapabilities } from '../../../common/types/capabilities'; export const setupCapabilitiesSwitcher = ( @@ -30,9 +30,10 @@ function getSwitcher(license$: Observable, logger: Logger): Capabiliti try { const license = await license$.pipe(take(1)).toPromise(); + const mlEnabled = isMlEnabled(license); // full license, leave capabilities as they were - if (isFullLicense(license)) { + if (mlEnabled && isFullLicense(license)) { return capabilities; } @@ -45,7 +46,7 @@ function getSwitcher(license$: Observable, logger: Logger): Capabiliti }); // for a basic license, reapply the original capabilities for the basic license features - if (isMinimumLicense(license)) { + if (mlEnabled && isMinimumLicense(license)) { basicLicenseMlCapabilities.forEach((c) => (mlCaps[c] = originalCapabilities[c])); } diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/low_request_rate_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/low_request_rate_ecs.json index d6d3879e8300f..5950d088d49e2 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/low_request_rate_ecs.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/low_request_rate_ecs.json @@ -1,7 +1,7 @@ { "groups": ["apache"], "description": "HTTP Access Logs: Detect low request rates (ECS)", - "analysis_config" : { + "analysis_config": { "bucket_span": "15m", "summary_count_field_name": "doc_count", "detectors": [ @@ -27,7 +27,7 @@ "custom_urls": [ { "url_name": "Raw data", - "url_value": "discover#/ml_http_access_filebeat_ecs?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(columns:!(_source),filters:!((\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:event.dataset,negate:!f,params:(query:\u0027apache.access\u0027),type:phrase,value:\u0027apache.access\u0027),query:(match:(event.dataset:(query:\u0027apache.access\u0027,type:phrase))))),index:\u0027INDEX_PATTERN_ID\u0027,interval:auto,query:(language:kuery,query:\u0027\u0027),sort:!(\u0027@timestamp\u0027,desc))" + "url_value": "discover#/?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(columns:!(_source),filters:!((\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:event.dataset,negate:!f,params:(query:\u0027apache.access\u0027),type:phrase,value:\u0027apache.access\u0027),query:(match:(event.dataset:(query:\u0027apache.access\u0027,type:phrase))))),index:\u0027INDEX_PATTERN_ID\u0027,interval:auto,query:(language:kuery,query:\u0027\u0027),sort:!(\u0027@timestamp\u0027,desc))" } ] } diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/source_ip_request_rate_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/source_ip_request_rate_ecs.json index 876b89b03952f..f888e4d44c844 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/source_ip_request_rate_ecs.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/source_ip_request_rate_ecs.json @@ -1,18 +1,16 @@ { "groups": ["apache"], "description": "HTTP Access Logs: Detect unusual source IPs - high request rates (ECS)", - "analysis_config" : { + "analysis_config": { "bucket_span": "1h", "detectors": [ - { + { "detector_description": "Apache access source IP high count", "function": "high_count", "over_field_name": "source.address" } ], - "influencers": [ - "source.address" - ] + "influencers": ["source.address"] }, "data_description": { "time_field": "@timestamp", @@ -27,7 +25,7 @@ }, { "url_name": "Raw data", - "url_value": "discover#/ml_http_access_filebeat_ecs?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(columns:!(_source),filters:!((\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:event.dataset,negate:!f,params:(query:\u0027apache.access\u0027),type:phrase,value:\u0027apache.access\u0027),query:(match:(event.dataset:(query:\u0027apache.access\u0027,type:phrase)))),(\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:source.address,negate:!f,params:(query:\u0027$source.address$\u0027),type:phrase,value:\u0027$source.address$\u0027),query:(match:(source.address:(query:\u0027$source.address$\u0027,type:phrase))))),index:\u0027INDEX_PATTERN_ID\u0027,interval:auto,query:(language:kuery,query:\u0027\u0027),sort:!(\u0027@timestamp\u0027,desc))" + "url_value": "discover#/?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(columns:!(_source),filters:!((\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:event.dataset,negate:!f,params:(query:\u0027apache.access\u0027),type:phrase,value:\u0027apache.access\u0027),query:(match:(event.dataset:(query:\u0027apache.access\u0027,type:phrase)))),(\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:source.address,negate:!f,params:(query:\u0027$source.address$\u0027),type:phrase,value:\u0027$source.address$\u0027),query:(match:(source.address:(query:\u0027$source.address$\u0027,type:phrase))))),index:\u0027INDEX_PATTERN_ID\u0027,interval:auto,query:(language:kuery,query:\u0027\u0027),sort:!(\u0027@timestamp\u0027,desc))" } ] } diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/source_ip_url_count_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/source_ip_url_count_ecs.json index 810c61073ecc6..e4886b531ba42 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/source_ip_url_count_ecs.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/source_ip_url_count_ecs.json @@ -1,19 +1,17 @@ { "groups": ["apache"], "description": "HTTP Access Logs: Detect unusual source IPs - high distinct count of URLs (ECS)", - "analysis_config" : { + "analysis_config": { "bucket_span": "1h", "detectors": [ - { + { "detector_description": "Apache access source IP high dc URL", "function": "high_distinct_count", "field_name": "url.original", "over_field_name": "source.address" } ], - "influencers": [ - "source.address" - ] + "influencers": ["source.address"] }, "data_description": { "time_field": "@timestamp", @@ -28,7 +26,7 @@ }, { "url_name": "Raw data", - "url_value": "discover#/ml_http_access_filebeat_ecs?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(columns:!(_source),filters:!((\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:event.dataset,negate:!f,params:(query:\u0027apache.access\u0027),type:phrase,value:\u0027apache.access\u0027),query:(match:(event.dataset:(query:\u0027apache.access\u0027,type:phrase)))),(\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:source.address,negate:!f,params:(query:\u0027$source.address$\u0027),type:phrase,value:\u0027$source.address$\u0027),query:(match:(source.address:(query:\u0027$source.address$\u0027,type:phrase))))),index:\u0027INDEX_PATTERN_ID\u0027,interval:auto,query:(language:kuery,query:\u0027\u0027),sort:!(\u0027@timestamp\u0027,desc))" + "url_value": "discover#/?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(columns:!(_source),filters:!((\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:event.dataset,negate:!f,params:(query:\u0027apache.access\u0027),type:phrase,value:\u0027apache.access\u0027),query:(match:(event.dataset:(query:\u0027apache.access\u0027,type:phrase)))),(\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:source.address,negate:!f,params:(query:\u0027$source.address$\u0027),type:phrase,value:\u0027$source.address$\u0027),query:(match:(source.address:(query:\u0027$source.address$\u0027,type:phrase))))),index:\u0027INDEX_PATTERN_ID\u0027,interval:auto,query:(language:kuery,query:\u0027\u0027),sort:!(\u0027@timestamp\u0027,desc))" } ] } diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/status_code_rate_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/status_code_rate_ecs.json index a9341e43723a6..ac5bd5e478c16 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/status_code_rate_ecs.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/status_code_rate_ecs.json @@ -1,19 +1,16 @@ { "groups": ["apache"], "description": "HTTP Access Logs: Detect unusual status code rates (ECS)", - "analysis_config" : { + "analysis_config": { "bucket_span": "15m", "detectors": [ - { + { "detector_description": "Apache access status code rate", "function": "count", "partition_field_name": "http.response.status_code" } ], - "influencers": [ - "http.response.status_code", - "source.address" - ] + "influencers": ["http.response.status_code", "source.address"] }, "analysis_limits": { "model_memory_limit": "100mb" @@ -34,7 +31,7 @@ }, { "url_name": "Raw data", - "url_value": "discover#/ml_http_access_filebeat_ecs?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(columns:!(_source),filters:!((\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:event.dataset,negate:!f,params:(query:\u0027apache.access\u0027),type:phrase,value:\u0027apache.access\u0027),query:(match:(event.dataset:(query:\u0027apache.access\u0027,type:phrase)))),(\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:http.response.status_code,negate:!f,params:(query:\u0027$http.response.status_code$\u0027),type:phrase,value:\u0027$http.response.status_code$\u0027),query:(match:(http.response.status_code:(query:\u0027$http.response.status_code$\u0027,type:phrase))))),index:\u0027INDEX_PATTERN_ID\u0027,interval:auto,query:(language:kuery,query:\u0027\u0027),sort:!(\u0027@timestamp\u0027,desc))" + "url_value": "discover#/?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(columns:!(_source),filters:!((\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:event.dataset,negate:!f,params:(query:\u0027apache.access\u0027),type:phrase,value:\u0027apache.access\u0027),query:(match:(event.dataset:(query:\u0027apache.access\u0027,type:phrase)))),(\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:http.response.status_code,negate:!f,params:(query:\u0027$http.response.status_code$\u0027),type:phrase,value:\u0027$http.response.status_code$\u0027),query:(match:(http.response.status_code:(query:\u0027$http.response.status_code$\u0027,type:phrase))))),index:\u0027INDEX_PATTERN_ID\u0027,interval:auto,query:(language:kuery,query:\u0027\u0027),sort:!(\u0027@timestamp\u0027,desc))" } ] } diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/visitor_rate_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/visitor_rate_ecs.json index 5bc641315bc3f..f513e53a964f3 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/visitor_rate_ecs.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/visitor_rate_ecs.json @@ -1,7 +1,7 @@ { "groups": ["apache"], "description": "HTTP Access Logs: Detect unusual visitor rates (ECS)", - "analysis_config" : { + "analysis_config": { "bucket_span": "15m", "summary_count_field_name": "dc_source_address", "detectors": [ @@ -27,7 +27,7 @@ "custom_urls": [ { "url_name": "Raw data", - "url_value": "discover#/ml_http_access_filebeat_ecs?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(columns:!(_source),filters:!((\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:event.dataset,negate:!f,params:(query:\u0027apache.access\u0027),type:phrase,value:\u0027apache.access\u0027),query:(match:(event.dataset:(query:\u0027apache.access\u0027,type:phrase))))),index:\u0027INDEX_PATTERN_ID\u0027,interval:auto,query:(language:kuery,query:\u0027\u0027),sort:!(\u0027@timestamp\u0027,desc))" + "url_value": "discover#/?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(columns:!(_source),filters:!((\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:event.dataset,negate:!f,params:(query:\u0027apache.access\u0027),type:phrase,value:\u0027apache.access\u0027),query:(match:(event.dataset:(query:\u0027apache.access\u0027,type:phrase))))),index:\u0027INDEX_PATTERN_ID\u0027,interval:auto,query:(language:kuery,query:\u0027\u0027),sort:!(\u0027@timestamp\u0027,desc))" } ] } diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_docker_ecs/ml/docker_high_count_process_events_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_docker_ecs/ml/docker_high_count_process_events_ecs.json index 27949c76b3e13..046736b6f5559 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_docker_ecs/ml/docker_high_count_process_events_ecs.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_docker_ecs/ml/docker_high_count_process_events_ecs.json @@ -11,10 +11,7 @@ "partition_field_name": "container.name" } ], - "influencers": [ - "container.name", - "process.executable" - ] + "influencers": ["container.name", "process.executable"] }, "analysis_limits": { "model_memory_limit": "256mb", @@ -35,7 +32,7 @@ { "url_name": "Raw data", "time_range": "1h", - "url_value": "discover#/ml_auditbeat_docker_process_events_ecs?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(index:\u0027INDEX_PATTERN_ID\u0027,query:(language:kuery,query:\u0027container.name:\u0022$container.name$\u0022\u0027))" + "url_value": "discover#/?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(index:\u0027INDEX_PATTERN_ID\u0027,query:(language:kuery,query:\u0027container.name:\u0022$container.name$\u0022\u0027))" } ] } diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_docker_ecs/ml/docker_rare_process_activity_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_docker_ecs/ml/docker_rare_process_activity_ecs.json index 899518f30f7a3..ab405d47484d9 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_docker_ecs/ml/docker_rare_process_activity_ecs.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_docker_ecs/ml/docker_rare_process_activity_ecs.json @@ -12,10 +12,7 @@ "partition_field_name": "container.name" } ], - "influencers": [ - "container.name", - "process.executable" - ] + "influencers": ["container.name", "process.executable"] }, "analysis_limits": { "model_memory_limit": "256mb" @@ -35,7 +32,7 @@ { "url_name": "Raw data", "time_range": "1h", - "url_value": "discover#/ml_auditbeat_docker_process_events_ecs?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(index:\u0027INDEX_PATTERN_ID\u0027,query:(language:kuery,query:\u0027container.name:\u0022$container.name$\u0022 AND process.executable:\u0022$process.executable$\u0022\u0027))" + "url_value": "discover#/?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(index:\u0027INDEX_PATTERN_ID\u0027,query:(language:kuery,query:\u0027container.name:\u0022$container.name$\u0022 AND process.executable:\u0022$process.executable$\u0022\u0027))" } ] } diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_hosts_ecs/ml/hosts_high_count_process_events_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_hosts_ecs/ml/hosts_high_count_process_events_ecs.json index 1664e19096ee3..192842309dd92 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_hosts_ecs/ml/hosts_high_count_process_events_ecs.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_hosts_ecs/ml/hosts_high_count_process_events_ecs.json @@ -11,10 +11,7 @@ "partition_field_name": "host.name" } ], - "influencers": [ - "host.name", - "process.executable" - ] + "influencers": ["host.name", "process.executable"] }, "analysis_limits": { "model_memory_limit": "256mb" @@ -34,7 +31,7 @@ { "url_name": "Raw data", "time_range": "1h", - "url_value": "discover#/ml_auditbeat_hosts_process_events_ecs?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(index:\u0027INDEX_PATTERN_ID\u0027,query:(language:kuery,query:\u0027host.name:\u0022$host.name$\u0022\u0027))" + "url_value": "discover#/?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(index:\u0027INDEX_PATTERN_ID\u0027,query:(language:kuery,query:\u0027host.name:\u0022$host.name$\u0022\u0027))" } ] } diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_hosts_ecs/ml/hosts_rare_process_activity_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_hosts_ecs/ml/hosts_rare_process_activity_ecs.json index d83f36db5a491..9448537b387c2 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_hosts_ecs/ml/hosts_rare_process_activity_ecs.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_hosts_ecs/ml/hosts_rare_process_activity_ecs.json @@ -12,10 +12,7 @@ "partition_field_name": "host.name" } ], - "influencers": [ - "host.name", - "process.executable" - ] + "influencers": ["host.name", "process.executable"] }, "analysis_limits": { "model_memory_limit": "256mb" @@ -35,7 +32,7 @@ { "url_name": "Raw data", "time_range": "1h", - "url_value": "discover#/ml_auditbeat_hosts_process_events_ecs?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(index:\u0027INDEX_PATTERN_ID\u0027,query:(language:kuery,query:\u0027host.name:\u0022$host.name$\u0022 AND process.executable:\u0022$process.executable$\u0022\u0027))" + "url_value": "discover#/?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(index:\u0027INDEX_PATTERN_ID\u0027,query:(language:kuery,query:\u0027host.name:\u0022$host.name$\u0022 AND process.executable:\u0022$process.executable$\u0022\u0027))" } ] } diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/low_request_rate_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/low_request_rate_ecs.json index 54c2f540e334f..3dfe04766a9e9 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/low_request_rate_ecs.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/low_request_rate_ecs.json @@ -1,7 +1,7 @@ { "groups": ["nginx"], "description": "HTTP Access Logs: Detect low request rates (ECS)", - "analysis_config" : { + "analysis_config": { "bucket_span": "15m", "summary_count_field_name": "doc_count", "detectors": [ @@ -27,7 +27,7 @@ "custom_urls": [ { "url_name": "Raw data", - "url_value": "discover#/ml_http_access_filebeat_ecs?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(columns:!(_source),filters:!((\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:event.dataset,negate:!f,params:(query:\u0027nginx.access\u0027),type:phrase,value:\u0027nginx.access\u0027),query:(match:(event.dataset:(query:\u0027nginx.access\u0027,type:phrase))))),index:\u0027INDEX_PATTERN_ID\u0027,interval:auto,query:(language:kuery,query:\u0027\u0027),sort:!(\u0027@timestamp\u0027,desc))" + "url_value": "discover#/?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(columns:!(_source),filters:!((\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:event.dataset,negate:!f,params:(query:\u0027nginx.access\u0027),type:phrase,value:\u0027nginx.access\u0027),query:(match:(event.dataset:(query:\u0027nginx.access\u0027,type:phrase))))),index:\u0027INDEX_PATTERN_ID\u0027,interval:auto,query:(language:kuery,query:\u0027\u0027),sort:!(\u0027@timestamp\u0027,desc))" } ] } diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/source_ip_request_rate_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/source_ip_request_rate_ecs.json index 6fc7ce7e0699d..209b4e66dbac4 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/source_ip_request_rate_ecs.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/source_ip_request_rate_ecs.json @@ -1,18 +1,16 @@ { "groups": ["nginx"], "description": "HTTP Access Logs: Detect unusual source IPs - high request rates (ECS)", - "analysis_config" : { + "analysis_config": { "bucket_span": "1h", "detectors": [ - { + { "detector_description": "Nginx access source IP high count", "function": "high_count", "over_field_name": "source.address" } ], - "influencers": [ - "source.address" - ] + "influencers": ["source.address"] }, "data_description": { "time_field": "@timestamp", @@ -27,7 +25,7 @@ }, { "url_name": "Raw data", - "url_value": "discover#/ml_http_access_filebeat_ecs?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(columns:!(_source),filters:!((\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:event.dataset,negate:!f,params:(query:\u0027nginx.access\u0027),type:phrase,value:\u0027nginx.access\u0027),query:(match:(event.dataset:(query:\u0027nginx.access\u0027,type:phrase)))),(\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:source.address,negate:!f,params:(query:\u0027$source.address$\u0027),type:phrase,value:\u0027$source.address$\u0027),query:(match:(source.address:(query:\u0027$source.address$\u0027,type:phrase))))),index:\u0027INDEX_PATTERN_ID\u0027,interval:auto,query:(language:kuery,query:\u0027\u0027),sort:!(\u0027@timestamp\u0027,desc))" + "url_value": "discover#/?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(columns:!(_source),filters:!((\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:event.dataset,negate:!f,params:(query:\u0027nginx.access\u0027),type:phrase,value:\u0027nginx.access\u0027),query:(match:(event.dataset:(query:\u0027nginx.access\u0027,type:phrase)))),(\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:source.address,negate:!f,params:(query:\u0027$source.address$\u0027),type:phrase,value:\u0027$source.address$\u0027),query:(match:(source.address:(query:\u0027$source.address$\u0027,type:phrase))))),index:\u0027INDEX_PATTERN_ID\u0027,interval:auto,query:(language:kuery,query:\u0027\u0027),sort:!(\u0027@timestamp\u0027,desc))" } ] } diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/source_ip_url_count_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/source_ip_url_count_ecs.json index 1c3f9f96a36b4..dea65ef701cb1 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/source_ip_url_count_ecs.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/source_ip_url_count_ecs.json @@ -1,19 +1,17 @@ { "groups": ["nginx"], "description": "HTTP Access Logs: Detect unusual source IPs - high distinct count of URLs (ECS)", - "analysis_config" : { + "analysis_config": { "bucket_span": "1h", "detectors": [ - { + { "detector_description": "Nginx access source IP high dc URL", "function": "high_distinct_count", "field_name": "url.original", "over_field_name": "source.address" } ], - "influencers": [ - "source.address" - ] + "influencers": ["source.address"] }, "data_description": { "time_field": "@timestamp", @@ -28,7 +26,7 @@ }, { "url_name": "Raw data", - "url_value": "discover#/ml_http_access_filebeat_ecs?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(columns:!(_source),filters:!((\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:event.dataset,negate:!f,params:(query:\u0027nginx.access\u0027),type:phrase,value:\u0027nginx.access\u0027),query:(match:(event.dataset:(query:\u0027nginx.access\u0027,type:phrase)))),(\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:source.address,negate:!f,params:(query:\u0027$source.address$\u0027),type:phrase,value:\u0027$source.address$\u0027),query:(match:(source.address:(query:\u0027$source.address$\u0027,type:phrase))))),index:\u0027INDEX_PATTERN_ID\u0027,interval:auto,query:(language:kuery,query:\u0027\u0027),sort:!(\u0027@timestamp\u0027,desc))" + "url_value": "discover#/?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(columns:!(_source),filters:!((\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:event.dataset,negate:!f,params:(query:\u0027nginx.access\u0027),type:phrase,value:\u0027nginx.access\u0027),query:(match:(event.dataset:(query:\u0027nginx.access\u0027,type:phrase)))),(\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:source.address,negate:!f,params:(query:\u0027$source.address$\u0027),type:phrase,value:\u0027$source.address$\u0027),query:(match:(source.address:(query:\u0027$source.address$\u0027,type:phrase))))),index:\u0027INDEX_PATTERN_ID\u0027,interval:auto,query:(language:kuery,query:\u0027\u0027),sort:!(\u0027@timestamp\u0027,desc))" } ] } diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/status_code_rate_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/status_code_rate_ecs.json index df917ed43c5fa..2475b33aa24f2 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/status_code_rate_ecs.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/status_code_rate_ecs.json @@ -1,19 +1,16 @@ { "groups": ["nginx"], "description": "HTTP Access Logs: Detect unusual status code rates (ECS)", - "analysis_config" : { + "analysis_config": { "bucket_span": "15m", "detectors": [ - { + { "detector_description": "Nginx access status code rate", "function": "count", "partition_field_name": "http.response.status_code" } ], - "influencers": [ - "http.response.status_code", - "source.address" - ] + "influencers": ["http.response.status_code", "source.address"] }, "analysis_limits": { "model_memory_limit": "100mb" @@ -34,7 +31,7 @@ }, { "url_name": "Raw data", - "url_value": "discover#/ml_http_access_filebeat_ecs?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(columns:!(_source),filters:!((\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:event.dataset,negate:!f,params:(query:\u0027nginx.access\u0027),type:phrase,value:\u0027nginx.access\u0027),query:(match:(event.dataset:(query:\u0027nginx.access\u0027,type:phrase)))),(\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:http.response.status_code,negate:!f,params:(query:\u0027$http.response.status_code$\u0027),type:phrase,value:\u0027$http.response.status_code$\u0027),query:(match:(http.response.status_code:(query:\u0027$http.response.status_code$\u0027,type:phrase))))),index:\u0027INDEX_PATTERN_ID\u0027,interval:auto,query:(language:kuery,query:\u0027\u0027),sort:!(\u0027@timestamp\u0027,desc))" + "url_value": "discover#/?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(columns:!(_source),filters:!((\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:event.dataset,negate:!f,params:(query:\u0027nginx.access\u0027),type:phrase,value:\u0027nginx.access\u0027),query:(match:(event.dataset:(query:\u0027nginx.access\u0027,type:phrase)))),(\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:http.response.status_code,negate:!f,params:(query:\u0027$http.response.status_code$\u0027),type:phrase,value:\u0027$http.response.status_code$\u0027),query:(match:(http.response.status_code:(query:\u0027$http.response.status_code$\u0027,type:phrase))))),index:\u0027INDEX_PATTERN_ID\u0027,interval:auto,query:(language:kuery,query:\u0027\u0027),sort:!(\u0027@timestamp\u0027,desc))" } ] } diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/visitor_rate_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/visitor_rate_ecs.json index 5ff35a7e2aed7..3182ac3fd3a79 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/visitor_rate_ecs.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/visitor_rate_ecs.json @@ -1,7 +1,7 @@ { "groups": ["nginx"], "description": "HTTP Access Logs: Detect unusual visitor rates (ECS)", - "analysis_config" : { + "analysis_config": { "bucket_span": "15m", "summary_count_field_name": "dc_source_address", "detectors": [ @@ -27,7 +27,7 @@ "custom_urls": [ { "url_name": "Raw data", - "url_value": "discover#/ml_http_access_filebeat_ecs?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(columns:!(_source),filters:!((\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:event.dataset,negate:!f,params:(query:\u0027nginx.access\u0027),type:phrase,value:\u0027nginx.access\u0027),query:(match:(event.dataset:(query:\u0027nginx.access\u0027,type:phrase))))),index:\u0027INDEX_PATTERN_ID\u0027,interval:auto,query:(language:kuery,query:\u0027\u0027),sort:!(\u0027@timestamp\u0027,desc))" + "url_value": "discover#/?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(columns:!(_source),filters:!((\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:event.dataset,negate:!f,params:(query:\u0027nginx.access\u0027),type:phrase,value:\u0027nginx.access\u0027),query:(match:(event.dataset:(query:\u0027nginx.access\u0027,type:phrase))))),index:\u0027INDEX_PATTERN_ID\u0027,interval:auto,query:(language:kuery,query:\u0027\u0027),sort:!(\u0027@timestamp\u0027,desc))" } ] } diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_auditbeat/logo.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_auditbeat/logo.json index 40a5c59677147..dfd22f6b1140b 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_auditbeat/logo.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_auditbeat/logo.json @@ -1,3 +1,3 @@ { - "icon": "securityAnalyticsApp" + "icon": "logoSecurity" } diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_auditbeat_auth/logo.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_auditbeat_auth/logo.json index 6b02648ccf287..dfd22f6b1140b 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_auditbeat_auth/logo.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_auditbeat_auth/logo.json @@ -1,3 +1,3 @@ { - "icon": "securityAnalyticsApp" -} \ No newline at end of file + "icon": "logoSecurity" +} diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_packetbeat/logo.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_packetbeat/logo.json index 6b02648ccf287..dfd22f6b1140b 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_packetbeat/logo.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_packetbeat/logo.json @@ -1,3 +1,3 @@ { - "icon": "securityAnalyticsApp" -} \ No newline at end of file + "icon": "logoSecurity" +} diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_winlogbeat/logo.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_winlogbeat/logo.json index 40a5c59677147..dfd22f6b1140b 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_winlogbeat/logo.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_winlogbeat/logo.json @@ -1,3 +1,3 @@ { - "icon": "securityAnalyticsApp" + "icon": "logoSecurity" } diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_winlogbeat_auth/logo.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_winlogbeat_auth/logo.json index 6b02648ccf287..dfd22f6b1140b 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_winlogbeat_auth/logo.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_winlogbeat_auth/logo.json @@ -1,3 +1,3 @@ { - "icon": "securityAnalyticsApp" -} \ No newline at end of file + "icon": "logoSecurity" +} diff --git a/x-pack/plugins/ml/server/plugin.ts b/x-pack/plugins/ml/server/plugin.ts index 812db744d1bda..3c3824a785032 100644 --- a/x-pack/plugins/ml/server/plugin.ts +++ b/x-pack/plugins/ml/server/plugin.ts @@ -75,7 +75,7 @@ export class MlServerPlugin implements Plugin { beforeAll(() => { if (typeof window.URL.revokeObjectURL === 'undefined') { - Object.defineProperty(window.URL, 'revokeObjectURL', { value: () => {} }); + Object.defineProperty(window.URL, 'revokeObjectURL', { + configurable: true, + writable: true, + value: () => {}, + }); } }); diff --git a/x-pack/plugins/security/server/authorization/disable_ui_capabilities.test.ts b/x-pack/plugins/security/server/authorization/disable_ui_capabilities.test.ts index 45f55b34baf96..9037970e80b69 100644 --- a/x-pack/plugins/security/server/authorization/disable_ui_capabilities.test.ts +++ b/x-pack/plugins/security/server/authorization/disable_ui_capabilities.test.ts @@ -50,7 +50,7 @@ describe('usingPrivileges', () => { new Feature({ id: 'fooFeature', name: 'Foo Feature', - app: ['fooApp'], + app: ['fooApp', 'foo'], navLinkId: 'foo', privileges: null, }), @@ -126,7 +126,7 @@ describe('usingPrivileges', () => { new Feature({ id: 'fooFeature', name: 'Foo Feature', - app: [], + app: ['foo'], navLinkId: 'foo', privileges: null, }), @@ -259,7 +259,7 @@ describe('usingPrivileges', () => { id: 'barFeature', name: 'Bar Feature', navLinkId: 'bar', - app: [], + app: ['bar'], privileges: null, }), ], @@ -409,7 +409,7 @@ describe('all', () => { new Feature({ id: 'fooFeature', name: 'Foo Feature', - app: [], + app: ['foo'], navLinkId: 'foo', privileges: null, }), diff --git a/x-pack/plugins/security/server/authorization/disable_ui_capabilities.ts b/x-pack/plugins/security/server/authorization/disable_ui_capabilities.ts index a9b3fa54d3617..c126be1b07f6e 100644 --- a/x-pack/plugins/security/server/authorization/disable_ui_capabilities.ts +++ b/x-pack/plugins/security/server/authorization/disable_ui_capabilities.ts @@ -18,12 +18,11 @@ export function disableUICapabilitiesFactory( logger: Logger, authz: AuthorizationServiceSetup ) { - // nav links are sourced from two places: - // 1) The `navLinkId` property. This is deprecated and will be removed (https://github.com/elastic/kibana/issues/66217) - // 2) The apps property. The Kibana Platform associates nav links to the app which registers it, in a 1:1 relationship. - // This behavior is replacing the `navLinkId` property above. + // nav links are sourced from the apps property. + // The Kibana Platform associates nav links to the app which registers it, in a 1:1 relationship. + // This behavior is replacing the `navLinkId` property. const featureNavLinkIds = features - .flatMap((feature) => [feature.navLinkId, ...feature.app]) + .flatMap((feature) => feature.app) .filter((navLinkId) => navLinkId != null); const shouldDisableFeatureUICapability = ( diff --git a/x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/navlink.ts b/x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/navlink.ts index f25632407be86..a6e5a01c7dba8 100644 --- a/x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/navlink.ts +++ b/x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/navlink.ts @@ -9,9 +9,6 @@ import { BaseFeaturePrivilegeBuilder } from './feature_privilege_builder'; export class FeaturePrivilegeNavlinkBuilder extends BaseFeaturePrivilegeBuilder { public getActions(privilegeDefinition: FeatureKibanaPrivileges, feature: Feature): string[] { - const appNavLinks = feature.app.map((app) => this.actions.ui.get('navLinks', app)); - return feature.navLinkId - ? [this.actions.ui.get('navLinks', feature.navLinkId), ...appNavLinks] - : appNavLinks; + return (privilegeDefinition.app ?? []).map((app) => this.actions.ui.get('navLinks', app)); } } diff --git a/x-pack/plugins/security/server/authorization/privileges/privileges.test.ts b/x-pack/plugins/security/server/authorization/privileges/privileges.test.ts index d8ece8f68d425..89ac73c220756 100644 --- a/x-pack/plugins/security/server/authorization/privileges/privileges.test.ts +++ b/x-pack/plugins/security/server/authorization/privileges/privileges.test.ts @@ -54,20 +54,8 @@ describe('features', () => { const actual = privileges.get(); expect(actual).toHaveProperty('features.foo-feature', { - all: [ - actions.login, - actions.version, - actions.ui.get('navLinks', 'kibana:foo'), - actions.ui.get('navLinks', 'app-1'), - actions.ui.get('navLinks', 'app-2'), - ], - read: [ - actions.login, - actions.version, - actions.ui.get('navLinks', 'kibana:foo'), - actions.ui.get('navLinks', 'app-1'), - actions.ui.get('navLinks', 'app-2'), - ], + all: [actions.login, actions.version], + read: [actions.login, actions.version], }); }); @@ -275,7 +263,6 @@ describe('features', () => { actions.ui.get('catalogue', 'all-catalogue-2'), actions.ui.get('management', 'all-management', 'all-management-1'), actions.ui.get('management', 'all-management', 'all-management-2'), - actions.ui.get('navLinks', 'kibana:foo'), actions.savedObject.get('all-savedObject-all-1', 'bulk_get'), actions.savedObject.get('all-savedObject-all-1', 'get'), actions.savedObject.get('all-savedObject-all-1', 'find'), @@ -386,7 +373,6 @@ describe('features', () => { actions.ui.get('catalogue', 'read-catalogue-2'), actions.ui.get('management', 'read-management', 'read-management-1'), actions.ui.get('management', 'read-management', 'read-management-2'), - actions.ui.get('navLinks', 'kibana:foo'), actions.savedObject.get('read-savedObject-all-1', 'bulk_get'), actions.savedObject.get('read-savedObject-all-1', 'get'), actions.savedObject.get('read-savedObject-all-1', 'find'), @@ -644,12 +630,7 @@ describe('reserved', () => { const privileges = privilegesFactory(actions, mockXPackMainPlugin as any, mockLicenseService); const actual = privileges.get(); - expect(actual).toHaveProperty('reserved.foo', [ - actions.version, - actions.ui.get('navLinks', 'kibana:foo'), - actions.ui.get('navLinks', 'app-1'), - actions.ui.get('navLinks', 'app-2'), - ]); + expect(actual).toHaveProperty('reserved.foo', [actions.version]); }); test(`actions only specified at the privilege are alright too`, () => { diff --git a/x-pack/plugins/security_solution/common/constants.ts b/x-pack/plugins/security_solution/common/constants.ts index f934d90c740a5..c74cf888a2db6 100644 --- a/x-pack/plugins/security_solution/common/constants.ts +++ b/x-pack/plugins/security_solution/common/constants.ts @@ -32,6 +32,7 @@ export const DEFAULT_INTERVAL_PAUSE = true; export const DEFAULT_INTERVAL_TYPE = 'manual'; export const DEFAULT_INTERVAL_VALUE = 300000; // ms export const DEFAULT_TIMEPICKER_QUICK_RANGES = 'timepicker:quickRanges'; +export const SCROLLING_DISABLED_CLASS_NAME = 'scrolling-disabled'; export const FILTERS_GLOBAL_HEIGHT = 109; // px export const FULL_SCREEN_TOGGLED_CLASS_NAME = 'fullScreenToggled'; export const NO_ALERT_INDEX = 'no-alert-index-049FC71A-4C2C-446F-9901-37XMC5024C51'; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/common/schemas.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/common/schemas.ts index 273ea72a2ffe3..21fa780badd84 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/common/schemas.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/common/schemas.ts @@ -222,8 +222,9 @@ export const risk_score_mapping_value = t.string; export const risk_score_mapping_item = t.exact( t.type({ field: risk_score_mapping_field, - operator, value: risk_score_mapping_value, + operator, + risk_score: riskScoreOrUndefined, }) ); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/add_prepackged_rules_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/add_prepackged_rules_schema.test.ts index 5fd2c3dbbf894..3cad48ec18fc1 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/add_prepackged_rules_schema.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/add_prepackged_rules_schema.test.ts @@ -1446,11 +1446,13 @@ describe('add prepackaged rules schema', () => { exceptions_list: [ { id: 'some_uuid', + list_id: 'list_id_single', namespace_type: 'single', type: 'detection', }, { - id: 'some_uuid', + id: 'endpoint_list', + list_id: 'endpoint_list', namespace_type: 'agnostic', type: 'endpoint', }, @@ -1535,6 +1537,7 @@ describe('add prepackaged rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "exceptions_list,list_id"', 'Invalid value "undefined" supplied to "exceptions_list,type"', 'Invalid value "not a namespace type" supplied to "exceptions_list,namespace_type"', ]); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_schema.test.ts index 71f3964956249..c2c2f4784f2b5 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_schema.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_schema.test.ts @@ -1513,11 +1513,13 @@ describe('create rules schema', () => { exceptions_list: [ { id: 'some_uuid', + list_id: 'list_id_single', namespace_type: 'single', type: 'detection', }, { - id: 'some_uuid', + id: 'endpoint_list', + list_id: 'endpoint_list', namespace_type: 'agnostic', type: 'endpoint', }, @@ -1600,6 +1602,7 @@ describe('create rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "exceptions_list,list_id"', 'Invalid value "undefined" supplied to "exceptions_list,type"', 'Invalid value "not a namespace type" supplied to "exceptions_list,namespace_type"', ]); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_schema.test.ts index 828626ef26d6f..00a3f2126f44a 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_schema.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_schema.test.ts @@ -1642,11 +1642,13 @@ describe('import rules schema', () => { exceptions_list: [ { id: 'some_uuid', + list_id: 'list_id_single', namespace_type: 'single', type: 'detection', }, { - id: 'some_uuid', + id: 'endpoint_list', + list_id: 'endpoint_list', namespace_type: 'agnostic', type: 'endpoint', }, @@ -1730,6 +1732,7 @@ describe('import rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "exceptions_list,list_id"', 'Invalid value "undefined" supplied to "exceptions_list,type"', 'Invalid value "not a namespace type" supplied to "exceptions_list,namespace_type"', ]); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_schema.test.ts index e75aff1abe3e9..e4fc53b934f58 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_schema.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_schema.test.ts @@ -1176,11 +1176,13 @@ describe('patch_rules_schema', () => { exceptions_list: [ { id: 'some_uuid', + list_id: 'list_id_single', namespace_type: 'single', type: 'detection', }, { - id: 'some_uuid', + id: 'endpoint_list', + list_id: 'endpoint_list', namespace_type: 'agnostic', type: 'endpoint', }, @@ -1251,6 +1253,7 @@ describe('patch_rules_schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "exceptions_list,list_id"', 'Invalid value "undefined" supplied to "exceptions_list,type"', 'Invalid value "not a namespace type" supplied to "exceptions_list,namespace_type"', 'Invalid value "[{"id":"uuid_here","namespace_type":"not a namespace type"}]" supplied to "exceptions_list"', diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_schema.test.ts index d18d2d91b963c..024198d783048 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_schema.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_schema.test.ts @@ -1448,11 +1448,13 @@ describe('update rules schema', () => { exceptions_list: [ { id: 'some_uuid', + list_id: 'list_id_single', namespace_type: 'single', type: 'detection', }, { - id: 'some_uuid', + id: 'endpoint_list', + list_id: 'endpoint_list', namespace_type: 'agnostic', type: 'endpoint', }, @@ -1534,6 +1536,7 @@ describe('update rules schema', () => { const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "exceptions_list,list_id"', 'Invalid value "undefined" supplied to "exceptions_list,type"', 'Invalid value "not a namespace type" supplied to "exceptions_list,namespace_type"', ]); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/lists.mock.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/lists.mock.ts index 0c7853bc3c08a..fec7548811820 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/lists.mock.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/lists.mock.ts @@ -4,17 +4,20 @@ * you may not use this file except in compliance with the Elastic License. */ import { List, ListArray } from './lists'; +import { ENDPOINT_LIST_ID } from '../../../shared_imports'; export const getListMock = (): List => ({ id: 'some_uuid', + list_id: 'list_id_single', namespace_type: 'single', type: 'detection', }); -export const getListAgnosticMock = (): List => ({ - id: 'some_uuid', +export const getEndpointListMock = (): List => ({ + id: ENDPOINT_LIST_ID, + list_id: ENDPOINT_LIST_ID, namespace_type: 'agnostic', type: 'endpoint', }); -export const getListArrayMock = (): ListArray => [getListMock(), getListAgnosticMock()]; +export const getListArrayMock = (): ListArray => [getListMock(), getEndpointListMock()]; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/lists.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/lists.test.ts index 56ee4630996fd..7a2c167bfd855 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/lists.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/lists.test.ts @@ -9,7 +9,7 @@ import { left } from 'fp-ts/lib/Either'; import { foldLeftRight, getPaths } from '../../../test_utils'; -import { getListAgnosticMock, getListMock, getListArrayMock } from './lists.mock'; +import { getEndpointListMock, getListMock, getListArrayMock } from './lists.mock'; import { List, ListArray, @@ -31,7 +31,7 @@ describe('Lists', () => { }); test('it should validate a list with "namespace_type" of "agnostic"', () => { - const payload = getListAgnosticMock(); + const payload = getEndpointListMock(); const decoded = list.decode(payload); const message = pipe(decoded, foldLeftRight); @@ -91,7 +91,7 @@ describe('Lists', () => { const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "1" supplied to "Array<{| id: string, type: "detection" | "endpoint", namespace_type: "agnostic" | "single" |}>"', + 'Invalid value "1" supplied to "Array<{| id: NonEmptyString, list_id: NonEmptyString, type: "detection" | "endpoint", namespace_type: "agnostic" | "single" |}>"', ]); expect(message.schema).toEqual({}); }); @@ -122,8 +122,8 @@ describe('Lists', () => { const message = pipe(decoded, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "1" supplied to "(Array<{| id: string, type: "detection" | "endpoint", namespace_type: "agnostic" | "single" |}> | undefined)"', - 'Invalid value "[1]" supplied to "(Array<{| id: string, type: "detection" | "endpoint", namespace_type: "agnostic" | "single" |}> | undefined)"', + 'Invalid value "1" supplied to "(Array<{| id: NonEmptyString, list_id: NonEmptyString, type: "detection" | "endpoint", namespace_type: "agnostic" | "single" |}> | undefined)"', + 'Invalid value "[1]" supplied to "(Array<{| id: NonEmptyString, list_id: NonEmptyString, type: "detection" | "endpoint", namespace_type: "agnostic" | "single" |}> | undefined)"', ]); expect(message.schema).toEqual({}); }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/lists.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/lists.ts index e5aaee6d3ec74..fecdd0761aade 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/types/lists.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/types/lists.ts @@ -8,9 +8,12 @@ import * as t from 'io-ts'; import { exceptionListType, namespaceType } from '../../../shared_imports'; +import { NonEmptyString } from './non_empty_string'; + export const list = t.exact( t.type({ - id: t.string, + id: NonEmptyString, + list_id: NonEmptyString, type: exceptionListType, namespace_type: namespaceType, }) diff --git a/x-pack/plugins/security_solution/common/endpoint/generate_data.test.ts b/x-pack/plugins/security_solution/common/endpoint/generate_data.test.ts index fcea86be4ae9e..debe4a3da6a6f 100644 --- a/x-pack/plugins/security_solution/common/endpoint/generate_data.test.ts +++ b/x-pack/plugins/security_solution/common/endpoint/generate_data.test.ts @@ -3,6 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ +import _ from 'lodash'; import { EndpointDocGenerator, Event, @@ -79,9 +80,9 @@ describe('data generator', () => { const timestamp = new Date().getTime(); const processEvent = generator.generateEvent({ timestamp }); expect(processEvent['@timestamp']).toEqual(timestamp); - expect(processEvent.event.category).toEqual('process'); + expect(processEvent.event.category).toEqual(['process']); expect(processEvent.event.kind).toEqual('event'); - expect(processEvent.event.type).toEqual('start'); + expect(processEvent.event.type).toEqual(['start']); expect(processEvent.agent).not.toBeNull(); expect(processEvent.host).not.toBeNull(); expect(processEvent.process.entity_id).not.toBeNull(); @@ -94,7 +95,7 @@ describe('data generator', () => { expect(processEvent['@timestamp']).toEqual(timestamp); expect(processEvent.event.category).toEqual('dns'); expect(processEvent.event.kind).toEqual('event'); - expect(processEvent.event.type).toEqual('start'); + expect(processEvent.event.type).toEqual(['start']); expect(processEvent.agent).not.toBeNull(); expect(processEvent.host).not.toBeNull(); expect(processEvent.process.entity_id).not.toBeNull(); @@ -332,6 +333,12 @@ describe('data generator', () => { describe('creates alert ancestor tree', () => { let events: Event[]; + const isCategoryProcess = (event: Event) => { + return ( + _.isEqual(event.event.category, ['process']) || _.isEqual(event.event.category, 'process') + ); + }; + beforeEach(() => { events = generator.createAlertEventAncestry({ ancestors: 3, @@ -343,11 +350,7 @@ describe('data generator', () => { it('with n-1 process events', () => { for (let i = events.length - 2; i > 0; ) { const parentEntityIdOfChild = events[i].process.parent?.entity_id; - for ( - ; - --i >= -1 && (events[i].event.kind !== 'event' || events[i].event.category !== 'process'); - - ) { + for (; --i >= -1 && (events[i].event.kind !== 'event' || !isCategoryProcess(events[i])); ) { // related event - skip it } expect(i).toBeGreaterThanOrEqual(0); @@ -361,7 +364,7 @@ describe('data generator', () => { ; previousProcessEventIndex >= -1 && (events[previousProcessEventIndex].event.kind !== 'event' || - events[previousProcessEventIndex].event.category !== 'process'); + !isCategoryProcess(events[previousProcessEventIndex])); previousProcessEventIndex-- ) { // related event - skip it diff --git a/x-pack/plugins/security_solution/common/endpoint/generate_data.ts b/x-pack/plugins/security_solution/common/endpoint/generate_data.ts index 66e786cb02e63..9a92270fc9c14 100644 --- a/x-pack/plugins/security_solution/common/endpoint/generate_data.ts +++ b/x-pack/plugins/security_solution/common/endpoint/generate_data.ts @@ -35,7 +35,7 @@ interface EventOptions { timestamp?: number; entityID?: string; parentEntityID?: string; - eventType?: string; + eventType?: string | string[]; eventCategory?: string | string[]; processName?: string; ancestry?: string[]; @@ -572,9 +572,9 @@ export class EndpointDocGenerator { }, ...detailRecordForEventType, event: { - category: options.eventCategory ? options.eventCategory : 'process', + category: options.eventCategory ? options.eventCategory : ['process'], kind: 'event', - type: options.eventType ? options.eventType : 'start', + type: options.eventType ? options.eventType : ['start'], id: this.seededUUIDv4(), }, host: this.commonInfo.host, @@ -633,7 +633,12 @@ export class EndpointDocGenerator { // place the event in the right array depending on its category if (event.event.kind === 'event') { - if (event.event.category === 'process') { + if ( + (Array.isArray(event.event.category) && + event.event.category.length === 1 && + event.event.category[0] === 'process') || + event.event.category === 'process' + ) { node.lifecycle.push(event); } else { node.relatedEvents.push(event); @@ -812,8 +817,8 @@ export class EndpointDocGenerator { timestamp: timestamp + termProcessDuration * 1000, entityID: root.process.entity_id, parentEntityID: root.process.parent?.entity_id, - eventCategory: 'process', - eventType: 'end', + eventCategory: ['process'], + eventType: ['end'], }) ); } @@ -838,8 +843,8 @@ export class EndpointDocGenerator { timestamp: timestamp + termProcessDuration * 1000, entityID: ancestor.process.entity_id, parentEntityID: ancestor.process.parent?.entity_id, - eventCategory: 'process', - eventType: 'end', + eventCategory: ['process'], + eventType: ['end'], ancestry: ancestor.process.Ext?.ancestry, ancestryArrayLimit: opts.ancestryArraySize, }) @@ -936,8 +941,8 @@ export class EndpointDocGenerator { timestamp: timestamp + processDuration * 1000, entityID: child.process.entity_id, parentEntityID: child.process.parent?.entity_id, - eventCategory: 'process', - eventType: 'end', + eventCategory: ['process'], + eventType: ['end'], ancestry: child.process.Ext?.ancestry, ancestryArrayLimit: opts.ancestryArraySize, }); @@ -1036,7 +1041,7 @@ export class EndpointDocGenerator { config: { artifact_manifest: { value: { - manifest_version: 'WzAsMF0=', + manifest_version: '1.0.0', schema_version: 'v1', artifacts: {}, }, diff --git a/x-pack/plugins/security_solution/common/endpoint/models/event.test.ts b/x-pack/plugins/security_solution/common/endpoint/models/event.test.ts index a0bf00f0274e6..62f923aa6d793 100644 --- a/x-pack/plugins/security_solution/common/endpoint/models/event.test.ts +++ b/x-pack/plugins/security_solution/common/endpoint/models/event.test.ts @@ -4,38 +4,90 @@ * you may not use this file except in compliance with the Elastic License. */ import { EndpointDocGenerator } from '../generate_data'; -import { descriptiveName } from './event'; +import { descriptiveName, isStart } from './event'; +import { ResolverEvent } from '../types'; -describe('Event descriptive names', () => { +describe('Generated documents', () => { let generator: EndpointDocGenerator; beforeEach(() => { generator = new EndpointDocGenerator('seed'); }); - it('returns the right name for a registry event', () => { - const extensions = { registry: { key: `HKLM/Windows/Software/abc` } }; - const event = generator.generateEvent({ eventCategory: 'registry', extensions }); - expect(descriptiveName(event)).toEqual({ subject: `HKLM/Windows/Software/abc` }); - }); + describe('Event descriptive names', () => { + it('returns the right name for a registry event', () => { + const extensions = { registry: { key: `HKLM/Windows/Software/abc` } }; + const event = generator.generateEvent({ eventCategory: 'registry', extensions }); + expect(descriptiveName(event)).toEqual({ subject: `HKLM/Windows/Software/abc` }); + }); - it('returns the right name for a network event', () => { - const randomIP = `${generator.randomIP()}`; - const extensions = { network: { direction: 'outbound', forwarded_ip: randomIP } }; - const event = generator.generateEvent({ eventCategory: 'network', extensions }); - expect(descriptiveName(event)).toEqual({ subject: `${randomIP}`, descriptor: 'outbound' }); - }); + it('returns the right name for a network event', () => { + const randomIP = `${generator.randomIP()}`; + const extensions = { network: { direction: 'outbound', forwarded_ip: randomIP } }; + const event = generator.generateEvent({ eventCategory: 'network', extensions }); + expect(descriptiveName(event)).toEqual({ subject: `${randomIP}`, descriptor: 'outbound' }); + }); - it('returns the right name for a file event', () => { - const extensions = { file: { path: 'C:\\My Documents\\business\\January\\processName' } }; - const event = generator.generateEvent({ eventCategory: 'file', extensions }); - expect(descriptiveName(event)).toEqual({ - subject: 'C:\\My Documents\\business\\January\\processName', + it('returns the right name for a file event', () => { + const extensions = { file: { path: 'C:\\My Documents\\business\\January\\processName' } }; + const event = generator.generateEvent({ eventCategory: 'file', extensions }); + expect(descriptiveName(event)).toEqual({ + subject: 'C:\\My Documents\\business\\January\\processName', + }); + }); + + it('returns the right name for a dns event', () => { + const extensions = { dns: { question: { name: `${generator.randomIP()}` } } }; + const event = generator.generateEvent({ eventCategory: 'dns', extensions }); + expect(descriptiveName(event)).toEqual({ subject: extensions.dns.question.name }); }); }); - it('returns the right name for a dns event', () => { - const extensions = { dns: { question: { name: `${generator.randomIP()}` } } }; - const event = generator.generateEvent({ eventCategory: 'dns', extensions }); - expect(descriptiveName(event)).toEqual({ subject: extensions.dns.question.name }); + describe('Start events', () => { + it('is a start event when event.type is a string', () => { + const event: ResolverEvent = generator.generateEvent({ + eventType: 'start', + }); + expect(isStart(event)).toBeTruthy(); + }); + + it('is a start event when event.type is an array of strings', () => { + const event: ResolverEvent = generator.generateEvent({ + eventType: ['start'], + }); + expect(isStart(event)).toBeTruthy(); + }); + + it('is a start event when event.type is an array of strings and contains start', () => { + let event: ResolverEvent = generator.generateEvent({ + eventType: ['bogus', 'start', 'creation'], + }); + expect(isStart(event)).toBeTruthy(); + + event = generator.generateEvent({ + eventType: ['start', 'bogus'], + }); + expect(isStart(event)).toBeTruthy(); + }); + + it('is not a start event when event.type is not start', () => { + const event: ResolverEvent = generator.generateEvent({ + eventType: ['end'], + }); + expect(isStart(event)).toBeFalsy(); + }); + + it('is not a start event when event.type is empty', () => { + const event: ResolverEvent = generator.generateEvent({ + eventType: [], + }); + expect(isStart(event)).toBeFalsy(); + }); + + it('is not a start event when event.type is bogus', () => { + const event: ResolverEvent = generator.generateEvent({ + eventType: ['bogus'], + }); + expect(isStart(event)).toBeFalsy(); + }); }); }); diff --git a/x-pack/plugins/security_solution/common/endpoint/models/event.ts b/x-pack/plugins/security_solution/common/endpoint/models/event.ts index f53da8fb1f096..216b5cc028588 100644 --- a/x-pack/plugins/security_solution/common/endpoint/models/event.ts +++ b/x-pack/plugins/security_solution/common/endpoint/models/event.ts @@ -9,10 +9,15 @@ export function isLegacyEvent(event: ResolverEvent): event is LegacyEndpointEven return (event as LegacyEndpointEvent).endgame !== undefined; } -export function isProcessStart(event: ResolverEvent): boolean { +export function isStart(event: ResolverEvent): boolean { if (isLegacyEvent(event)) { return event.event?.type === 'process_start' || event.event?.action === 'fork_event'; } + + if (Array.isArray(event.event.type)) { + return event.event.type.includes('start'); + } + return event.event.type === 'start'; } diff --git a/x-pack/plugins/security_solution/common/endpoint/schema/common.ts b/x-pack/plugins/security_solution/common/endpoint/schema/common.ts index 8f2ea1f8a6452..1c910927a7afa 100644 --- a/x-pack/plugins/security_solution/common/endpoint/schema/common.ts +++ b/x-pack/plugins/security_solution/common/endpoint/schema/common.ts @@ -23,8 +23,6 @@ export const encryptionAlgorithm = t.keyof({ export const identifier = t.string; -export const manifestVersion = t.string; - export const manifestSchemaVersion = t.keyof({ v1: null, }); @@ -34,4 +32,7 @@ export const relativeUrl = t.string; export const sha256 = t.string; +export const semanticVersion = t.string; +export type SemanticVersion = t.TypeOf; + export const size = t.number; diff --git a/x-pack/plugins/security_solution/common/endpoint/schema/manifest.ts b/x-pack/plugins/security_solution/common/endpoint/schema/manifest.ts index f8bb8b70f2d5b..f03db881837d5 100644 --- a/x-pack/plugins/security_solution/common/endpoint/schema/manifest.ts +++ b/x-pack/plugins/security_solution/common/endpoint/schema/manifest.ts @@ -11,9 +11,9 @@ import { encryptionAlgorithm, identifier, manifestSchemaVersion, - manifestVersion, relativeUrl, sha256, + semanticVersion, size, } from './common'; @@ -50,7 +50,7 @@ export type ManifestEntryDispatchSchema = t.TypeOf { +describe.skip('timeline flyout button', () => { before(() => { loginAndWaitForPage(HOSTS_URL); waitForAllHostsToBeLoaded(); diff --git a/x-pack/plugins/security_solution/cypress/integration/timeline_local_storage.spec.ts b/x-pack/plugins/security_solution/cypress/integration/timeline_local_storage.spec.ts index 383ebe2220585..2fb265c55e3ad 100644 --- a/x-pack/plugins/security_solution/cypress/integration/timeline_local_storage.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/timeline_local_storage.spec.ts @@ -13,7 +13,8 @@ import { TABLE_COLUMN_EVENTS_MESSAGE } from '../screens/hosts/external_events'; import { waitsForEventsToBeLoaded, openEventsViewerFieldsBrowser } from '../tasks/hosts/events'; import { removeColumn, resetFields } from '../tasks/timeline'; -describe('persistent timeline', () => { +// FLAKY: https://github.com/elastic/kibana/issues/72339 +describe.skip('persistent timeline', () => { before(() => { loginAndWaitForPage(HOSTS_URL); openEvents(); diff --git a/x-pack/plugins/security_solution/cypress/tasks/common.ts b/x-pack/plugins/security_solution/cypress/tasks/common.ts index a385ad78f63b7..e16db54599981 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/common.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/common.ts @@ -23,14 +23,14 @@ export const drag = (subject: JQuery) => { clientY: subjectLocation.top, force: true, }) - .wait(1000) + .wait(3000) .trigger('mousemove', { button: primaryButton, clientX: subjectLocation.left + dndSloppyClickDetectionThreshold, clientY: subjectLocation.top, force: true, }) - .wait(1000); + .wait(3000); }; /** Drags the subject being dragged on the specified drop target, but does not drop it */ @@ -44,9 +44,9 @@ export const dragWithoutDrop = (dropTarget: JQuery) => { export const drop = (dropTarget: JQuery) => { cy.wrap(dropTarget) .trigger('mousemove', { button: primaryButton, force: true }) - .wait(1000) + .wait(3000) .trigger('mouseup', { force: true }) - .wait(1000); + .wait(3000); }; export const reload = (afterReload: () => void) => { diff --git a/x-pack/plugins/security_solution/cypress/tasks/hosts/events.ts b/x-pack/plugins/security_solution/cypress/tasks/hosts/events.ts index 57c819d967883..1d2c4aa8d0834 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/hosts/events.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/hosts/events.ts @@ -68,7 +68,7 @@ export const dragAndDropColumn = ({ .eq(column) .then((header) => drag(header)); - cy.wait(3000); // wait for DOM updates before moving + cy.wait(5000); // wait for DOM updates before moving cy.get(DRAGGABLE_HEADER) .eq(newPosition) diff --git a/x-pack/plugins/security_solution/public/cases/pages/saved_object_no_permissions.tsx b/x-pack/plugins/security_solution/public/cases/pages/saved_object_no_permissions.tsx index 7129aa04bdf69..c61ff6d18caab 100644 --- a/x-pack/plugins/security_solution/public/cases/pages/saved_object_no_permissions.tsx +++ b/x-pack/plugins/security_solution/public/cases/pages/saved_object_no_permissions.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import React from 'react'; +import React, { useMemo } from 'react'; import { EmptyPage } from '../../common/components/empty_page'; import * as i18n from './translations'; @@ -12,13 +12,21 @@ import { useKibana } from '../../common/lib/kibana'; export const CaseSavedObjectNoPermissions = React.memo(() => { const docLinks = useKibana().services.docLinks; + const actions = useMemo( + () => ({ + savedObject: { + icon: 'documents', + label: i18n.GO_TO_DOCUMENTATION, + url: `${docLinks.ELASTIC_WEBSITE_URL}guide/en/security/${docLinks.DOC_LINK_VERSION}s`, + target: '_blank', + }, + }), + [docLinks] + ); return ( { ); beforeEach(() => { + jest.useFakeTimers(); store = createStore( state, SUB_PLUGINS_REDUCER, @@ -159,6 +160,8 @@ describe('AddFilterToGlobalSearchBar Component', () => { wrapper.find('[data-test-subj="withHoverActionsButton"]').simulate('mouseenter'); wrapper.update(); + jest.runAllTimers(); + wrapper.update(); wrapper .find('[data-test-subj="hover-actions-container"] [data-euiicon-type]') diff --git a/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper.test.tsx b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper.test.tsx index e17fc7b9ef9bd..ebfa9ac22bdc7 100644 --- a/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper.test.tsx @@ -22,6 +22,10 @@ describe('DraggableWrapper', () => { const message = 'draggable wrapper content'; const mount = useMountAppended(); + beforeEach(() => { + jest.useFakeTimers(); + }); + describe('rendering', () => { test('it renders against the snapshot', () => { const wrapper = shallow( @@ -78,6 +82,8 @@ describe('DraggableWrapper', () => { wrapper.find('[data-test-subj="withHoverActionsButton"]').simulate('mouseenter'); wrapper.update(); + jest.runAllTimers(); + wrapper.update(); expect(wrapper.find('[data-test-subj="copy-to-clipboard"]').exists()).toBe(true); }); }); diff --git a/x-pack/plugins/security_solution/public/common/components/drag_and_drop/provider_container.tsx b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/provider_container.tsx index 06cb8ee2e1a46..8db6d073f9687 100644 --- a/x-pack/plugins/security_solution/public/common/components/drag_and_drop/provider_container.tsx +++ b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/provider_container.tsx @@ -13,13 +13,6 @@ interface ProviderContainerProps { } const ProviderContainerComponent = styled.div` - &, - &::before, - &::after { - transition: background ${({ theme }) => theme.eui.euiAnimSpeedFast} ease, - color ${({ theme }) => theme.eui.euiAnimSpeedFast} ease; - } - ${({ isDragging }) => !isDragging && css` diff --git a/x-pack/plugins/security_solution/public/common/components/empty_page/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/empty_page/__snapshots__/index.test.tsx.snap index 623b15aa76d12..9bf3be7b5dfa4 100644 --- a/x-pack/plugins/security_solution/public/common/components/empty_page/__snapshots__/index.test.tsx.snap +++ b/x-pack/plugins/security_solution/public/common/components/empty_page/__snapshots__/index.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`renders correctly 1`] = ` +exports[`EmptyPage component renders actions with descriptions 1`] = ` + + Do Something + + } + title={false} + /> + + + } + iconType="logoSecurity" + title={ +

      + My Super Title +

      + } +/> +`; + +exports[`EmptyPage component renders actions without descriptions 1`] = ` + + Do Something diff --git a/x-pack/plugins/security_solution/public/common/components/empty_page/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/empty_page/index.test.tsx index 6a14c12cee0f8..28e01eaa3eead 100644 --- a/x-pack/plugins/security_solution/public/common/components/empty_page/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/empty_page/index.test.tsx @@ -9,13 +9,27 @@ import React from 'react'; import { EmptyPage } from './index'; -test('renders correctly', () => { - const EmptyComponent = shallow( - - ); - expect(EmptyComponent).toMatchSnapshot(); +describe('EmptyPage component', () => { + it('renders actions without descriptions', () => { + const actions = { + actions: { + label: 'Do Something', + url: 'my/url/from/nowwhere', + }, + }; + const EmptyComponent = shallow(); + expect(EmptyComponent).toMatchSnapshot(); + }); + + it('renders actions with descriptions', () => { + const actions = { + actions: { + description: 'My Description', + label: 'Do Something', + url: 'my/url/from/nowwhere', + }, + }; + const EmptyComponent = shallow(); + expect(EmptyComponent).toMatchSnapshot(); + }); }); diff --git a/x-pack/plugins/security_solution/public/common/components/empty_page/index.tsx b/x-pack/plugins/security_solution/public/common/components/empty_page/index.tsx index f6d6752729b6d..e0db1e90374ad 100644 --- a/x-pack/plugins/security_solution/public/common/components/empty_page/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/empty_page/index.tsx @@ -4,84 +4,114 @@ * you may not use this file except in compliance with the Elastic License. */ -import { EuiButton, EuiEmptyPrompt, EuiFlexGroup, EuiFlexItem, IconType } from '@elastic/eui'; -import React, { MouseEventHandler, ReactNode } from 'react'; +import { + EuiButton, + EuiEmptyPrompt, + EuiFlexGroup, + EuiFlexItem, + IconType, + EuiCard, +} from '@elastic/eui'; +import React, { MouseEventHandler, ReactNode, useMemo } from 'react'; import styled from 'styled-components'; const EmptyPrompt = styled(EuiEmptyPrompt)` align-self: center; /* Corrects horizontal centering in IE11 */ + max-width: 60em; `; EmptyPrompt.displayName = 'EmptyPrompt'; +interface EmptyPageActions { + icon?: IconType; + label: string; + target?: string; + url: string; + descriptionTitle?: string; + description?: string; + fill?: boolean; + onClick?: MouseEventHandler; +} + +export type EmptyPageActionsProps = Record; + interface EmptyPageProps { - actionPrimaryIcon?: IconType; - actionPrimaryLabel: string; - actionPrimaryTarget?: string; - actionPrimaryUrl: string; - actionPrimaryFill?: boolean; - actionSecondaryIcon?: IconType; - actionSecondaryLabel?: string; - actionSecondaryTarget?: string; - actionSecondaryUrl?: string; - actionSecondaryOnClick?: MouseEventHandler; + actions: EmptyPageActionsProps; 'data-test-subj'?: string; message?: ReactNode; title: string; } -export const EmptyPage = React.memo( - ({ - actionPrimaryIcon, - actionPrimaryLabel, - actionPrimaryTarget, - actionPrimaryUrl, - actionPrimaryFill = true, - actionSecondaryIcon, - actionSecondaryLabel, - actionSecondaryTarget, - actionSecondaryUrl, - actionSecondaryOnClick, - message, - title, - ...rest - }) => ( +const EmptyPageComponent = React.memo(({ actions, message, title, ...rest }) => { + const titles = Object.keys(actions); + const maxItemWidth = 283; + const renderActions = useMemo( + () => + Object.values(actions) + .filter((a) => a.label && a.url) + .map( + ( + { icon, label, target, url, descriptionTitle, description, onClick, fill = true }, + idx + ) => + descriptionTitle != null || description != null ? ( + + + {label} + + } + /> + + ) : ( + + {/* eslint-disable-next-line @elastic/eui/href-or-on-click */} + + {label} + + + ) + ), + [actions, titles] + ); + + return ( {title}} body={message &&

      {message}

      } - actions={ - - - - {actionPrimaryLabel} - - - - {actionSecondaryLabel && actionSecondaryUrl && ( - - {/* eslint-disable-next-line @elastic/eui/href-or-on-click */} - - {actionSecondaryLabel} - - - )} - - } + actions={{renderActions}} {...rest} /> - ) -); + ); +}); + +EmptyPageComponent.displayName = 'EmptyPageComponent'; +export const EmptyPage = React.memo(EmptyPageComponent); EmptyPage.displayName = 'EmptyPage'; diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.tsx index bc036b38524ba..e836e2e20432a 100644 --- a/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.tsx +++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.tsx @@ -222,6 +222,7 @@ const EventsViewerComponent: React.FC = ({ sourceId="default" startDate={start} endDate={end} + queryDeduplication="events_viewer" > {({ events, diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx index 80831b4022ace..c402116ee2714 100644 --- a/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx @@ -69,7 +69,10 @@ const StatefulEventsViewerComponent: React.FC = ({ }) => { const [ { docValueFields, browserFields, indexPatterns, isLoading: isLoadingIndexPattern }, - ] = useFetchIndexPatterns(defaultIndices ?? useUiSetting(DEFAULT_INDEX_KEY)); + ] = useFetchIndexPatterns( + defaultIndices ?? useUiSetting(DEFAULT_INDEX_KEY), + 'events_viewer' + ); useEffect(() => { if (createTimeline != null) { diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/mock.ts b/x-pack/plugins/security_solution/public/common/components/events_viewer/mock.ts index ea2e60ebc82b8..6266e84051901 100644 --- a/x-pack/plugins/security_solution/public/common/components/events_viewer/mock.ts +++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/mock.ts @@ -40,6 +40,7 @@ export const mockEventViewerResponse = [ { field: 'event.end', format: 'date_time' }, ], inspect: false, + queryDeduplication: 'events_viewer', }, }, result: { diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_comments.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_comments.tsx index db2d0540971de..22d14ec6bedb1 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_comments.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_comments.tsx @@ -16,13 +16,13 @@ import { EuiCommentProps, EuiText, } from '@elastic/eui'; -import { Comments } from '../../../lists_plugin_deps'; +import { Comment } from '../../../shared_imports'; import * as i18n from './translations'; import { useCurrentUser } from '../../lib/kibana'; import { getFormattedComments } from './helpers'; interface AddExceptionCommentsProps { - exceptionItemComments?: Comments[]; + exceptionItemComments?: Comment[]; newCommentValue: string; newCommentOnChange: (value: string) => void; } diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_modal/index.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_modal/index.tsx index a4fe52eaacf4e..bb547f05090b7 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_modal/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_modal/index.tsx @@ -38,7 +38,7 @@ import { useSignalIndex } from '../../../../detections/containers/detection_engi import { useFetchOrCreateRuleExceptionList } from '../use_fetch_or_create_rule_exception_list'; import { AddExceptionComments } from '../add_exception_comments'; import { - enrichExceptionItemsWithComments, + enrichNewExceptionItemsWithComments, enrichExceptionItemsWithOS, defaultEndpointExceptionItems, entryHasListType, @@ -67,7 +67,8 @@ export interface AddExceptionModalProps extends AddExceptionModalBaseProps { const Modal = styled(EuiModal)` ${({ theme }) => css` - width: ${theme.eui.euiBreakpoints.m}; + width: ${theme.eui.euiBreakpoints.l}; + max-width: ${theme.eui.euiBreakpoints.l}; `} `; @@ -233,7 +234,7 @@ export const AddExceptionModal = memo(function AddExceptionModal({ ); const retrieveAlertOsTypes = useCallback(() => { - const osDefaults = ['windows', 'macos', 'linux']; + const osDefaults = ['windows', 'macos']; if (alertData) { const osTypes = getMappedNonEcsValue({ data: alertData.nonEcsData, @@ -251,7 +252,7 @@ export const AddExceptionModal = memo(function AddExceptionModal({ let enriched: Array = []; enriched = comment !== '' - ? enrichExceptionItemsWithComments(exceptionItemsToAdd, [{ comment }]) + ? enrichNewExceptionItemsWithComments(exceptionItemsToAdd, [{ comment }]) : exceptionItemsToAdd; if (exceptionListType === 'endpoint') { const osTypes = retrieveAlertOsTypes(); @@ -285,7 +286,9 @@ export const AddExceptionModal = memo(function AddExceptionModal({ - {i18n.ADD_EXCEPTION} + + {exceptionListType === 'endpoint' ? i18n.ADD_ENDPOINT_EXCEPTION : i18n.ADD_EXCEPTION} + {ruleName} @@ -330,13 +333,6 @@ export const AddExceptionModal = memo(function AddExceptionModal({ - {exceptionListType === 'endpoint' && ( - <> - {i18n.ENDPOINT_QUARANTINE_TEXT} - - - )} - + {exceptionListType === 'endpoint' && ( + <> + + + {i18n.ENDPOINT_QUARANTINE_TEXT} + + + )} )} diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_modal/translations.ts b/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_modal/translations.ts index 81db1b10f7021..abc296e9c0e1a 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_modal/translations.ts +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_modal/translations.ts @@ -17,6 +17,13 @@ export const ADD_EXCEPTION = i18n.translate( } ); +export const ADD_ENDPOINT_EXCEPTION = i18n.translate( + 'xpack.securitySolution.exceptions.addException.addEndpointException', + { + defaultMessage: 'Add Endpoint Exception', + } +); + export const ADD_EXCEPTION_ERROR = i18n.translate( 'xpack.securitySolution.exceptions.addException.error', { @@ -49,14 +56,15 @@ export const ENDPOINT_QUARANTINE_TEXT = i18n.translate( 'xpack.securitySolution.exceptions.addException.endpointQuarantineText', { defaultMessage: - 'Any file in quarantine on any endpoint that matches the attribute(s) selected will automatically be restored to its original location', + 'Any file in quarantine on any endpoint that matches the attribute(s) selected will automatically be restored to its original location. This exception will apply to any rule that is linked to the Global Endpoint Exception List.', } ); export const BULK_CLOSE_LABEL = i18n.translate( 'xpack.securitySolution.exceptions.addException.bulkCloseLabel', { - defaultMessage: 'Close all alerts that match attributes in this exception', + defaultMessage: + 'Close all alerts that match this exception, including alerts generated by other rules', } ); diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/builder_entry_item.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/builder_entry_item.tsx index dcc8a0e4fb1ba..5939a5a1b576e 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/builder_entry_item.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/builder_entry_item.tsx @@ -110,6 +110,7 @@ export const BuilderEntryItem: React.FC = ({ isDisabled={indexPattern == null} onChange={handleFieldChange} data-test-subj="exceptionBuilderEntryField" + fieldInputWidth={275} /> ); diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/index.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/index.tsx index 1ec49425ce8fd..734434484fb4c 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/index.tsx @@ -392,7 +392,7 @@ export const ExceptionBuilder = ({ )} css` - width: ${theme.eui.euiBreakpoints.m}; + width: ${theme.eui.euiBreakpoints.l}; + max-width: ${theme.eui.euiBreakpoints.l}; `} `; @@ -88,6 +90,7 @@ export const EditExceptionModal = memo(function EditExceptionModal({ }: EditExceptionModalProps) { const { http } = useKibana().services; const [comment, setComment] = useState(''); + const [hasVersionConflict, setHasVersionConflict] = useState(false); const [shouldBulkCloseAlert, setShouldBulkCloseAlert] = useState(false); const [shouldDisableBulkClose, setShouldDisableBulkClose] = useState(false); const [exceptionItemsToAdd, setExceptionItemsToAdd] = useState< @@ -106,8 +109,12 @@ export const EditExceptionModal = memo(function EditExceptionModal({ const onError = useCallback( (error) => { - addError(error, { title: i18n.EDIT_EXCEPTION_ERROR }); - onCancel(); + if (error.message.includes('Conflict')) { + setHasVersionConflict(true); + } else { + addError(error, { title: i18n.EDIT_EXCEPTION_ERROR }); + onCancel(); + } }, [addError, onCancel] ); @@ -147,8 +154,8 @@ export const EditExceptionModal = memo(function EditExceptionModal({ }, [shouldDisableBulkClose]); const isSubmitButtonDisabled = useMemo( - () => exceptionItemsToAdd.every((item) => item.entries.length === 0), - [exceptionItemsToAdd] + () => exceptionItemsToAdd.every((item) => item.entries.length === 0) || hasVersionConflict, + [exceptionItemsToAdd, hasVersionConflict] ); const handleBuilderOnChange = useCallback( @@ -177,11 +184,15 @@ export const EditExceptionModal = memo(function EditExceptionModal({ ); const enrichExceptionItems = useCallback(() => { - let enriched: Array = []; - enriched = enrichExceptionItemsWithComments(exceptionItemsToAdd, [ - ...(exceptionItem.comments ? exceptionItem.comments : []), - ...(comment !== '' ? [{ comment }] : []), - ]); + const [exceptionItemToEdit] = exceptionItemsToAdd; + let enriched: Array = [ + { + ...enrichExistingExceptionItemWithComments(exceptionItemToEdit, [ + ...exceptionItem.comments, + ...(comment.trim() !== '' ? [{ comment }] : []), + ]), + }, + ]; if (exceptionListType === 'endpoint') { const osTypes = exceptionItem._tags ? getOperatingSystems(exceptionItem._tags) : []; enriched = enrichExceptionItemsWithOS(enriched, osTypes); @@ -201,7 +212,11 @@ export const EditExceptionModal = memo(function EditExceptionModal({ - {i18n.EDIT_EXCEPTION_TITLE} + + {exceptionListType === 'endpoint' + ? i18n.EDIT_ENDPOINT_EXCEPTION_TITLE + : i18n.EDIT_EXCEPTION_TITLE} + {ruleName} @@ -222,7 +237,7 @@ export const EditExceptionModal = memo(function EditExceptionModal({ listId={exceptionItem.list_id} listNamespaceType={exceptionItem.namespace_type} ruleName={ruleName} - isOrDisabled={false} + isOrDisabled isAndDisabled={false} isNestedDisabled={false} data-test-subj="edit-exception-modal-builder" @@ -233,13 +248,6 @@ export const EditExceptionModal = memo(function EditExceptionModal({ - {exceptionListType === 'endpoint' && ( - <> - {i18n.ENDPOINT_QUARANTINE_TEXT} - - - )} - + {exceptionListType === 'endpoint' && ( + <> + + + {i18n.ENDPOINT_QUARANTINE_TEXT} + + + )} )} + {hasVersionConflict && ( + + +

      {i18n.VERSION_CONFLICT_ERROR_DESCRIPTION}

      +
      +
      + )} + {i18n.CANCEL} diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/edit_exception_modal/translations.ts b/x-pack/plugins/security_solution/public/common/components/exceptions/edit_exception_modal/translations.ts index 6c5cb733b7a73..c5b6fc8a6a9ae 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/edit_exception_modal/translations.ts +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/edit_exception_modal/translations.ts @@ -24,6 +24,13 @@ export const EDIT_EXCEPTION_TITLE = i18n.translate( } ); +export const EDIT_ENDPOINT_EXCEPTION_TITLE = i18n.translate( + 'xpack.securitySolution.exceptions.editException.editEndpointExceptionTitle', + { + defaultMessage: 'Edit Endpoint Exception', + } +); + export const EDIT_EXCEPTION_ERROR = i18n.translate( 'xpack.securitySolution.exceptions.editException.error', { @@ -41,7 +48,8 @@ export const EDIT_EXCEPTION_SUCCESS = i18n.translate( export const BULK_CLOSE_LABEL = i18n.translate( 'xpack.securitySolution.exceptions.editException.bulkCloseLabel', { - defaultMessage: 'Close all alerts that match attributes in this exception', + defaultMessage: + 'Close all alerts that match this exception, including alerts generated by other rules', } ); @@ -57,7 +65,7 @@ export const ENDPOINT_QUARANTINE_TEXT = i18n.translate( 'xpack.securitySolution.exceptions.editException.endpointQuarantineText', { defaultMessage: - 'Any file in quarantine on any endpoint that matches the attribute(s) selected will automatically be restored to its original location', + 'Any file in quarantine on any endpoint that matches the attribute(s) selected will automatically be restored to its original location. This exception will apply to any rule that is linked to the Global Endpoint Exception List.', } ); @@ -67,3 +75,18 @@ export const EXCEPTION_BUILDER_INFO = i18n.translate( defaultMessage: "Alerts are generated when the rule's conditions are met, except when:", } ); + +export const VERSION_CONFLICT_ERROR_TITLE = i18n.translate( + 'xpack.securitySolution.exceptions.editException.versionConflictTitle', + { + defaultMessage: 'Sorry, there was an error', + } +); + +export const VERSION_CONFLICT_ERROR_DESCRIPTION = i18n.translate( + 'xpack.securitySolution.exceptions.editException.versionConflictDescription', + { + defaultMessage: + "It appears this exception was updated since you first selected to edit it. Try clicking 'Cancel' and editing the exception again.", + } +); diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/exceptionable_fields.json b/x-pack/plugins/security_solution/public/common/components/exceptions/exceptionable_fields.json index 18257b0de0a17..fdf0ea60ecf6a 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/exceptionable_fields.json +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/exceptionable_fields.json @@ -7,25 +7,32 @@ "Target.process.Ext.services", "Target.process.Ext.user", "Target.process.command_line", + "Target.process.command_line.text", "Target.process.executable", + "Target.process.executable.text", "Target.process.hash.md5", "Target.process.hash.sha1", "Target.process.hash.sha256", "Target.process.hash.sha512", "Target.process.name", + "Target.process.name.text", "Target.process.parent.Ext.code_signature.status", "Target.process.parent.Ext.code_signature.subject_name", "Target.process.parent.Ext.code_signature.trusted", "Target.process.parent.Ext.code_signature.valid", "Target.process.parent.command_line", + "Target.process.parent.command_line.text", "Target.process.parent.executable", + "Target.process.parent.executable.text", "Target.process.parent.hash.md5", "Target.process.parent.hash.sha1", "Target.process.parent.hash.sha256", "Target.process.parent.hash.sha512", "Target.process.parent.name", + "Target.process.parent.name.text", "Target.process.parent.pgid", "Target.process.parent.working_directory", + "Target.process.parent.working_directory.text", "Target.process.pe.company", "Target.process.pe.description", "Target.process.pe.file_version", @@ -33,6 +40,7 @@ "Target.process.pe.product", "Target.process.pgid", "Target.process.working_directory", + "Target.process.working_directory.text", "agent.id", "agent.type", "agent.version", @@ -67,6 +75,7 @@ "file.name", "file.owner", "file.path", + "file.path.text", "file.pe.company", "file.pe.description", "file.pe.file_version", @@ -74,6 +83,7 @@ "file.pe.product", "file.size", "file.target_path", + "file.target_path.text", "file.type", "file.uid", "group.Ext.real.id", @@ -85,8 +95,10 @@ "host.os.Ext.variant", "host.os.family", "host.os.full", + "host.os.full.text", "host.os.kernel", "host.os.name", + "host.os.name.text", "host.os.platform", "host.os.version", "host.type", @@ -97,25 +109,32 @@ "process.Ext.services", "process.Ext.user", "process.command_line", + "process.command_line.text", "process.executable", + "process.executable.text", "process.hash.md5", "process.hash.sha1", "process.hash.sha256", "process.hash.sha512", "process.name", + "process.name.text", "process.parent.Ext.code_signature.status", "process.parent.Ext.code_signature.subject_name", "process.parent.Ext.code_signature.trusted", "process.parent.Ext.code_signature.valid", "process.parent.command_line", + "process.parent.command_line.text", "process.parent.executable", + "process.parent.executable.text", "process.parent.hash.md5", "process.parent.hash.sha1", "process.parent.hash.sha256", "process.parent.hash.sha512", "process.parent.name", + "process.parent.name.text", "process.parent.pgid", "process.parent.working_directory", + "process.parent.working_directory.text", "process.pe.company", "process.pe.description", "process.pe.file_version", @@ -123,5 +142,6 @@ "process.pe.product", "process.pgid", "process.working_directory", + "process.working_directory.text", "rule.uuid" ] \ No newline at end of file diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.test.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.test.tsx index 78936d5d0da6f..5cb65ee6db8ff 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.test.tsx @@ -18,7 +18,8 @@ import { formatOperatingSystems, getEntryValue, formatExceptionItemForUpdate, - enrichExceptionItemsWithComments, + enrichNewExceptionItemsWithComments, + enrichExistingExceptionItemWithComments, enrichExceptionItemsWithOS, entryHasListType, entryHasNonEcsType, @@ -35,14 +36,14 @@ import { existsOperator, doesNotExistOperator, } from '../autocomplete/operators'; -import { OperatorTypeEnum, OperatorEnum, EntryNested } from '../../../lists_plugin_deps'; +import { OperatorTypeEnum, OperatorEnum, EntryNested } from '../../../shared_imports'; import { getExceptionListItemSchemaMock } from '../../../../../lists/common/schemas/response/exception_list_item_schema.mock'; import { getEntryMatchMock } from '../../../../../lists/common/schemas/types/entry_match.mock'; import { getEntryMatchAnyMock } from '../../../../../lists/common/schemas/types/entry_match_any.mock'; import { getEntryExistsMock } from '../../../../../lists/common/schemas/types/entry_exists.mock'; import { getEntryListMock } from '../../../../../lists/common/schemas/types/entry_list.mock'; -import { getCommentsArrayMock } from '../../../../../lists/common/schemas/types/comments.mock'; -import { ENTRIES } from '../../../../../lists/common/constants.mock'; +import { getCommentsArrayMock } from '../../../../../lists/common/schemas/types/comment.mock'; +import { ENTRIES, OLD_DATE_RELATIVE_TO_DATE_NOW } from '../../../../../lists/common/constants.mock'; import { CreateExceptionListItemSchema, ExceptionListItemSchema, @@ -410,12 +411,52 @@ describe('Exception helpers', () => { expect(result).toEqual(expected); }); }); + describe('#enrichExistingExceptionItemWithComments', () => { + test('it should return exception item with comments stripped of "created_by", "created_at", "updated_by", "updated_at" fields', () => { + const payload = getExceptionListItemSchemaMock(); + const comments = [ + { + comment: 'Im an existing comment', + created_at: OLD_DATE_RELATIVE_TO_DATE_NOW, + created_by: 'lily', + id: '1', + }, + { + comment: 'Im another existing comment', + created_at: OLD_DATE_RELATIVE_TO_DATE_NOW, + created_by: 'lily', + id: '2', + }, + { + comment: 'Im a new comment', + }, + ]; + const result = enrichExistingExceptionItemWithComments(payload, comments); + const expected = { + ...getExceptionListItemSchemaMock(), + comments: [ + { + comment: 'Im an existing comment', + id: '1', + }, + { + comment: 'Im another existing comment', + id: '2', + }, + { + comment: 'Im a new comment', + }, + ], + }; + expect(result).toEqual(expected); + }); + }); - describe('#enrichExceptionItemsWithComments', () => { + describe('#enrichNewExceptionItemsWithComments', () => { test('it should add comments to an exception item', () => { const payload = [getExceptionListItemSchemaMock()]; const comments = getCommentsArrayMock(); - const result = enrichExceptionItemsWithComments(payload, comments); + const result = enrichNewExceptionItemsWithComments(payload, comments); const expected = [ { ...getExceptionListItemSchemaMock(), @@ -428,7 +469,7 @@ describe('Exception helpers', () => { test('it should add comments to multiple exception items', () => { const payload = [getExceptionListItemSchemaMock(), getExceptionListItemSchemaMock()]; const comments = getCommentsArrayMock(); - const result = enrichExceptionItemsWithComments(payload, comments); + const result = enrichNewExceptionItemsWithComments(payload, comments); const expected = [ { ...getExceptionListItemSchemaMock(), diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.tsx index a54f20f56d56f..3abb788312ff4 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.tsx @@ -20,13 +20,14 @@ import { EXCEPTION_OPERATORS, isOperator } from '../autocomplete/operators'; import { OperatorOption } from '../autocomplete/types'; import { CommentsArray, - Comments, - CreateComments, + Comment, + CreateComment, Entry, ExceptionListItemSchema, NamespaceType, OperatorTypeEnum, CreateExceptionListItemSchema, + comment, entry, entriesNested, createExceptionListItemSchema, @@ -34,7 +35,7 @@ import { UpdateExceptionListItemSchema, ExceptionListType, EntryNested, -} from '../../../lists_plugin_deps'; +} from '../../../shared_imports'; import { IIndexPattern } from '../../../../../../../src/plugins/data/common'; import { validate } from '../../../../common/validate'; import { TimelineNonEcsData } from '../../../graphql/types'; @@ -140,16 +141,16 @@ export const getTagsInclude = ({ * @param comments ExceptionItem.comments */ export const getFormattedComments = (comments: CommentsArray): EuiCommentProps[] => - comments.map((comment) => ({ - username: comment.created_by, - timestamp: moment(comment.created_at).format('on MMM Do YYYY @ HH:mm:ss'), + comments.map((commentItem) => ({ + username: commentItem.created_by, + timestamp: moment(commentItem.created_at).format('on MMM Do YYYY @ HH:mm:ss'), event: i18n.COMMENT_EVENT, - timelineIcon: , - children: {comment.comment}, + timelineIcon: , + children: {commentItem.comment}, actions: ( ), @@ -271,11 +272,11 @@ export const prepareExceptionItemsForBulkClose = ( /** * Adds new and existing comments to all new exceptionItems if not present already * @param exceptionItems new or existing ExceptionItem[] - * @param comments new Comments + * @param comments new Comment */ -export const enrichExceptionItemsWithComments = ( +export const enrichNewExceptionItemsWithComments = ( exceptionItems: Array, - comments: Array + comments: Array ): Array => { return exceptionItems.map((item: ExceptionListItemSchema | CreateExceptionListItemSchema) => { return { @@ -285,6 +286,36 @@ export const enrichExceptionItemsWithComments = ( }); }; +/** + * Adds new and existing comments to exceptionItem + * @param exceptionItem existing ExceptionItem + * @param comments array of comments that can include existing + * and new comments + */ +export const enrichExistingExceptionItemWithComments = ( + exceptionItem: ExceptionListItemSchema | CreateExceptionListItemSchema, + comments: Array +): ExceptionListItemSchema | CreateExceptionListItemSchema => { + const formattedComments = comments.map((item) => { + if (comment.is(item)) { + const { id, comment: existingComment } = item; + return { + id, + comment: existingComment, + }; + } else { + return { + comment: item.comment, + }; + } + }); + + return { + ...exceptionItem, + comments: formattedComments, + }; +}; + /** * Adds provided osTypes to all exceptionItems if not present already * @param exceptionItems new or existing ExceptionItem[] @@ -409,7 +440,7 @@ export const defaultEndpointExceptionItems = ( ], }, { - field: 'file.path', + field: 'file.path.text', operator: 'included', type: 'match', value: filePath ?? '', diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/translations.ts b/x-pack/plugins/security_solution/public/common/components/exceptions/translations.ts index 87d2f9dcda935..b826c1e49f274 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/translations.ts +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/translations.ts @@ -95,6 +95,13 @@ export const EXCEPTION_EMPTY_PROMPT_TITLE = i18n.translate( } ); +export const EXCEPTION_NO_SEARCH_RESULTS_PROMPT_BODY = i18n.translate( + 'xpack.securitySolution.exceptions.viewer.noSearchResultsPromptBody', + { + defaultMessage: 'No search results found.', + } +); + export const EXCEPTION_EMPTY_PROMPT_BODY = i18n.translate( 'xpack.securitySolution.exceptions.viewer.emptyPromptBody', { @@ -176,3 +183,10 @@ export const ADD_TO_CLIPBOARD = i18n.translate( export const DESCRIPTION = i18n.translate('xpack.securitySolution.exceptions.descriptionLabel', { defaultMessage: 'Description', }); + +export const TOTAL_ITEMS_FETCH_ERROR = i18n.translate( + 'xpack.securitySolution.exceptions.viewer.fetchTotalsError', + { + defaultMessage: 'Error getting exception item totals', + } +); diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/types.ts b/x-pack/plugins/security_solution/public/common/components/exceptions/types.ts index 54caab03e615a..83367e5b9e739 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/types.ts +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/types.ts @@ -38,14 +38,14 @@ export interface ExceptionListItemIdentifiers { export interface FilterOptions { filter: string; - showDetectionsList: boolean; - showEndpointList: boolean; tags: string[]; } export interface Filter { filter: Partial; pagination: Partial; + showDetectionsListsOnly: boolean; + showEndpointListsOnly: boolean; } export interface ExceptionsPagination { diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/use_fetch_or_create_rule_exception_list.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/use_fetch_or_create_rule_exception_list.tsx index 2a5ef7b21b519..0d367e03a799f 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/use_fetch_or_create_rule_exception_list.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/use_fetch_or_create_rule_exception_list.tsx @@ -102,6 +102,7 @@ export const useFetchOrCreateRuleExceptionList = ({ const newExceptionListReference = { id: newExceptionList.id, + list_id: newExceptionList.list_id, type: newExceptionList.type, namespace_type: newExceptionList.namespace_type, }; diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exception_item/exception_details.test.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exception_item/exception_details.test.tsx index 8df7b51bb9d31..ab6588b67d5ba 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exception_item/exception_details.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exception_item/exception_details.test.tsx @@ -12,7 +12,7 @@ import moment from 'moment-timezone'; import { ExceptionDetails } from './exception_details'; import { getExceptionListItemSchemaMock } from '../../../../../../../lists/common/schemas/response/exception_list_item_schema.mock'; -import { getCommentsArrayMock } from '../../../../../../../lists/common/schemas/types/comments.mock'; +import { getCommentsArrayMock } from '../../../../../../../lists/common/schemas/types/comment.mock'; describe('ExceptionDetails', () => { beforeEach(() => { diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exception_item/index.stories.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exception_item/index.stories.tsx index 56b029aaee81e..fec7354855935 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exception_item/index.stories.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exception_item/index.stories.tsx @@ -11,7 +11,7 @@ import euiLightVars from '@elastic/eui/dist/eui_theme_light.json'; import { ExceptionItem } from './'; import { getExceptionListItemSchemaMock } from '../../../../../../../lists/common/schemas/response/exception_list_item_schema.mock'; -import { getCommentsArrayMock } from '../../../../../../../lists/common/schemas/types/comments.mock'; +import { getCommentsArrayMock } from '../../../../../../../lists/common/schemas/types/comment.mock'; addDecorator((storyFn) => ( ({ eui: euiLightVars, darkMode: false })}>{storyFn()} diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exception_item/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exception_item/index.test.tsx index 90752f9450e4c..c9def092fda47 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exception_item/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exception_item/index.test.tsx @@ -11,7 +11,7 @@ import euiLightVars from '@elastic/eui/dist/eui_theme_light.json'; import { ExceptionItem } from './'; import { getExceptionListItemSchemaMock } from '../../../../../../../lists/common/schemas/response/exception_list_item_schema.mock'; -import { getCommentsArrayMock } from '../../../../../../../lists/common/schemas/types/comments.mock'; +import { getCommentsArrayMock } from '../../../../../../../lists/common/schemas/types/comment.mock'; jest.mock('../../../../lib/kibana'); diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exceptions_pagination.test.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exceptions_pagination.test.tsx index dcc8611cd7298..768af7b837d9b 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exceptions_pagination.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exceptions_pagination.test.tsx @@ -80,7 +80,6 @@ describe('ExceptionsViewerPagination', () => { wrapper.find('button[data-test-subj="exceptionsPerPageItem"]').at(0).simulate('click'); expect(mockOnPaginationChange).toHaveBeenCalledWith({ - filter: {}, pagination: { pageIndex: 0, pageSize: 20, totalItemCount: 1 }, }); }); @@ -127,8 +126,7 @@ describe('ExceptionsViewerPagination', () => { wrapper.find('[data-test-subj="pagination-button-next"]').at(1).simulate('click'); expect(mockOnPaginationChange).toHaveBeenCalledWith({ - filter: {}, - pagination: { pageIndex: 2, pageSize: 50, totalItemCount: 160 }, + pagination: { pageIndex: 1, pageSize: 50, totalItemCount: 160 }, }); }); @@ -151,8 +149,7 @@ describe('ExceptionsViewerPagination', () => { wrapper.find('button[data-test-subj="pagination-button-3"]').simulate('click'); expect(mockOnPaginationChange).toHaveBeenCalledWith({ - filter: {}, - pagination: { pageIndex: 4, pageSize: 50, totalItemCount: 160 }, + pagination: { pageIndex: 3, pageSize: 50, totalItemCount: 160 }, }); }); }); diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exceptions_pagination.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exceptions_pagination.tsx index afc6d55de364d..ae1a777116441 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exceptions_pagination.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exceptions_pagination.tsx @@ -20,7 +20,7 @@ import { ExceptionsPagination, Filter } from '../types'; interface ExceptionsViewerPaginationProps { pagination: ExceptionsPagination; - onPaginationChange: (arg: Filter) => void; + onPaginationChange: (arg: Partial) => void; } const ExceptionsViewerPaginationComponent = ({ @@ -39,9 +39,8 @@ const ExceptionsViewerPaginationComponent = ({ const handlePageClick = useCallback( (pageIndex: number): void => { onPaginationChange({ - filter: {}, pagination: { - pageIndex: pageIndex + 1, + pageIndex, pageSize: pagination.pageSize, totalItemCount: pagination.totalItemCount, }, @@ -57,9 +56,8 @@ const ExceptionsViewerPaginationComponent = ({ icon="empty" onClick={() => { onPaginationChange({ - filter: {}, pagination: { - pageIndex: pagination.pageIndex, + pageIndex: 0, pageSize: rows, totalItemCount: pagination.totalItemCount, }, diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exceptions_utility.test.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exceptions_utility.test.tsx index d697023b2ced4..6927ecec788fb 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exceptions_utility.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exceptions_utility.test.tsx @@ -22,12 +22,8 @@ describe('ExceptionsViewerUtility', () => { totalItemCount: 2, pageSizeOptions: [5, 10, 20, 50, 100], }} - filterOptions={{ - filter: '', - showEndpointList: false, - showDetectionsList: false, - tags: [], - }} + showEndpointListsOnly={false} + showDetectionsListsOnly={false} ruleSettingsUrl={'some/url'} onRefreshClick={jest.fn()} /> @@ -49,12 +45,8 @@ describe('ExceptionsViewerUtility', () => { totalItemCount: 1, pageSizeOptions: [5, 10, 20, 50, 100], }} - filterOptions={{ - filter: '', - showEndpointList: false, - showDetectionsList: false, - tags: [], - }} + showEndpointListsOnly={false} + showDetectionsListsOnly={false} ruleSettingsUrl={'some/url'} onRefreshClick={jest.fn()} /> @@ -77,12 +69,8 @@ describe('ExceptionsViewerUtility', () => { totalItemCount: 1, pageSizeOptions: [5, 10, 20, 50, 100], }} - filterOptions={{ - filter: '', - showEndpointList: false, - showDetectionsList: false, - tags: [], - }} + showEndpointListsOnly={false} + showDetectionsListsOnly={false} ruleSettingsUrl={'some/url'} onRefreshClick={mockOnRefreshClick} /> @@ -104,12 +92,8 @@ describe('ExceptionsViewerUtility', () => { totalItemCount: 1, pageSizeOptions: [5, 10, 20, 50, 100], }} - filterOptions={{ - filter: '', - showEndpointList: false, - showDetectionsList: false, - tags: [], - }} + showEndpointListsOnly={false} + showDetectionsListsOnly={false} ruleSettingsUrl={'some/url'} onRefreshClick={jest.fn()} /> @@ -130,12 +114,8 @@ describe('ExceptionsViewerUtility', () => { totalItemCount: 1, pageSizeOptions: [5, 10, 20, 50, 100], }} - filterOptions={{ - filter: '', - showEndpointList: false, - showDetectionsList: true, - tags: [], - }} + showEndpointListsOnly={false} + showDetectionsListsOnly ruleSettingsUrl={'some/url'} onRefreshClick={jest.fn()} /> @@ -156,12 +136,8 @@ describe('ExceptionsViewerUtility', () => { totalItemCount: 1, pageSizeOptions: [5, 10, 20, 50, 100], }} - filterOptions={{ - filter: '', - showEndpointList: true, - showDetectionsList: false, - tags: [], - }} + showEndpointListsOnly + showDetectionsListsOnly={false} ruleSettingsUrl={'some/url'} onRefreshClick={jest.fn()} /> diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exceptions_utility.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exceptions_utility.tsx index 9ab4e170f4090..206983f3d82d9 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exceptions_utility.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exceptions_utility.tsx @@ -10,7 +10,7 @@ import { FormattedMessage } from 'react-intl'; import styled from 'styled-components'; import * as i18n from '../translations'; -import { ExceptionsPagination, FilterOptions } from '../types'; +import { ExceptionsPagination } from '../types'; import { UtilityBar, UtilityBarSection, @@ -29,14 +29,16 @@ const MyUtilities = styled(EuiFlexGroup)` interface ExceptionsViewerUtilityProps { pagination: ExceptionsPagination; - filterOptions: FilterOptions; + showEndpointListsOnly: boolean; + showDetectionsListsOnly: boolean; ruleSettingsUrl: string; onRefreshClick: () => void; } const ExceptionsViewerUtilityComponent: React.FC = ({ pagination, - filterOptions, + showEndpointListsOnly, + showDetectionsListsOnly, ruleSettingsUrl, onRefreshClick, }): JSX.Element => ( @@ -65,7 +67,7 @@ const ExceptionsViewerUtilityComponent: React.FC =
      - {filterOptions.showEndpointList && ( + {showEndpointListsOnly && ( = }} /> )} - {filterOptions.showDetectionsList && ( + {showDetectionsListsOnly && ( { expect(mockOnFilterChange).toHaveBeenCalledWith({ filter: { filter: '', - showDetectionsList: true, - showEndpointList: false, tags: [], }, - pagination: {}, + pagination: { + pageIndex: 0, + }, + showDetectionsListsOnly: true, + showEndpointListsOnly: false, }); }); @@ -175,11 +177,13 @@ describe('ExceptionsViewerHeader', () => { expect(mockOnFilterChange).toHaveBeenCalledWith({ filter: { filter: '', - showDetectionsList: false, - showEndpointList: true, tags: [], }, - pagination: {}, + pagination: { + pageIndex: 0, + }, + showDetectionsListsOnly: false, + showEndpointListsOnly: true, }); }); diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exceptions_viewer_header.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exceptions_viewer_header.tsx index c207f91f651ed..9cbe5f0f36891 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exceptions_viewer_header.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exceptions_viewer_header.tsx @@ -26,7 +26,7 @@ interface ExceptionsViewerHeaderProps { supportedListTypes: ExceptionListTypeEnum[]; detectionsListItems: number; endpointListItems: number; - onFilterChange: (arg: Filter) => void; + onFilterChange: (arg: Partial) => void; onAddExceptionClick: (type: ExceptionListTypeEnum) => void; } @@ -43,16 +43,20 @@ const ExceptionsViewerHeaderComponent = ({ }: ExceptionsViewerHeaderProps): JSX.Element => { const [filter, setFilter] = useState(''); const [tags, setTags] = useState([]); - const [showDetectionsList, setShowDetectionsList] = useState(false); - const [showEndpointList, setShowEndpointList] = useState(false); + const [showDetectionsListsOnly, setShowDetectionsList] = useState(false); + const [showEndpointListsOnly, setShowEndpointList] = useState(false); const [isAddExceptionMenuOpen, setAddExceptionMenuOpen] = useState(false); useEffect((): void => { onFilterChange({ - filter: { filter, showDetectionsList, showEndpointList, tags }, - pagination: {}, + filter: { filter, tags }, + pagination: { + pageIndex: 0, + }, + showDetectionsListsOnly, + showEndpointListsOnly, }); - }, [filter, tags, showDetectionsList, showEndpointList, onFilterChange]); + }, [filter, tags, showDetectionsListsOnly, showEndpointListsOnly, onFilterChange]); const onAddExceptionDropdownClick = useCallback( (): void => setAddExceptionMenuOpen(!isAddExceptionMenuOpen), @@ -60,14 +64,14 @@ const ExceptionsViewerHeaderComponent = ({ ); const handleDetectionsListClick = useCallback((): void => { - setShowDetectionsList(!showDetectionsList); + setShowDetectionsList(!showDetectionsListsOnly); setShowEndpointList(false); - }, [showDetectionsList, setShowDetectionsList, setShowEndpointList]); + }, [showDetectionsListsOnly, setShowDetectionsList, setShowEndpointList]); const handleEndpointListClick = useCallback((): void => { - setShowEndpointList(!showEndpointList); + setShowEndpointList(!showEndpointListsOnly); setShowDetectionsList(false); - }, [showEndpointList, setShowEndpointList, setShowDetectionsList]); + }, [showEndpointListsOnly, setShowEndpointList, setShowDetectionsList]); const handleOnSearch = useCallback( (searchValue: string): void => { @@ -148,7 +152,7 @@ const ExceptionsViewerHeaderComponent = ({ @@ -157,7 +161,7 @@ const ExceptionsViewerHeaderComponent = ({ diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exceptions_viewer_item.test.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exceptions_viewer_items.test.tsx similarity index 78% rename from x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exceptions_viewer_item.test.tsx rename to x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exceptions_viewer_items.test.tsx index 7ccb8d251eae1..3024ae0f14144 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exceptions_viewer_item.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exceptions_viewer_items.test.tsx @@ -9,6 +9,7 @@ import { ThemeProvider } from 'styled-components'; import { mount } from 'enzyme'; import euiLightVars from '@elastic/eui/dist/eui_theme_light.json'; +import * as i18n from '../translations'; import { getExceptionListItemSchemaMock } from '../../../../../../lists/common/schemas/response/exception_list_item_schema.mock'; import { ExceptionsViewerItems } from './exceptions_viewer_items'; @@ -17,7 +18,8 @@ describe('ExceptionsViewerItems', () => { const wrapper = mount( ({ eui: euiLightVars, darkMode: false })}> { expect(wrapper.find('[data-test-subj="exceptionsEmptyPrompt"]').exists()).toBeTruthy(); expect(wrapper.find('[data-test-subj="exceptionsContainer"]').exists()).toBeFalsy(); + expect(wrapper.find('[data-test-subj="exceptionsEmptyPromptTitle"]').text()).toEqual( + i18n.EXCEPTION_EMPTY_PROMPT_TITLE + ); + expect(wrapper.find('[data-test-subj="exceptionsEmptyPromptBody"]').text()).toEqual( + i18n.EXCEPTION_EMPTY_PROMPT_BODY + ); + }); + + it('it renders no search results found prompt if "showNoResults" is "true"', () => { + const wrapper = mount( + ({ eui: euiLightVars, darkMode: false })}> + + + ); + + expect(wrapper.find('[data-test-subj="exceptionsEmptyPrompt"]').exists()).toBeTruthy(); + expect(wrapper.find('[data-test-subj="exceptionsContainer"]').exists()).toBeFalsy(); + expect(wrapper.find('[data-test-subj="exceptionsEmptyPromptTitle"]').text()).toEqual(''); + expect(wrapper.find('[data-test-subj="exceptionsEmptyPromptBody"]').text()).toEqual( + i18n.EXCEPTION_NO_SEARCH_RESULTS_PROMPT_BODY + ); }); it('it renders exceptions if "showEmpty" and "isInitLoading" is "false", and exceptions exist', () => { @@ -37,6 +69,7 @@ describe('ExceptionsViewerItems', () => { ({ eui: euiLightVars, darkMode: false })}> { ({ eui: euiLightVars, darkMode: false })}> { ({ eui: euiLightVars, darkMode: false })}> { ({ eui: euiLightVars, darkMode: false })}> { ({ eui: euiLightVars, darkMode: false })}> = ({ showEmpty, + showNoResults, isInitLoading, exceptions, loadingItemIds, @@ -51,12 +53,22 @@ const ExceptionsViewerItemsComponent: React.FC = ({ onEditExceptionItem, }): JSX.Element => ( - {showEmpty || isInitLoading ? ( + {showEmpty || showNoResults || isInitLoading ? ( {i18n.EXCEPTION_EMPTY_PROMPT_TITLE}} - body={

      {i18n.EXCEPTION_EMPTY_PROMPT_BODY}

      } + iconType={showNoResults ? 'searchProfilerApp' : 'list'} + title={ +

      + {showNoResults ? '' : i18n.EXCEPTION_EMPTY_PROMPT_TITLE} +

      + } + body={ +

      + {showNoResults + ? i18n.EXCEPTION_NO_SEARCH_RESULTS_PROMPT_BODY + : i18n.EXCEPTION_EMPTY_PROMPT_BODY} +

      + } data-test-subj="exceptionsEmptyPrompt" />
      diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/helpers.test.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/helpers.test.tsx index fe00e3530fa83..5d4340db9a448 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/helpers.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/helpers.test.tsx @@ -93,12 +93,6 @@ describe('Exception viewer helpers', () => { operator: 'is one of', value: ['some host name'], }, - { - fieldName: 'host.name', - isNested: false, - operator: 'is in list', - value: 'some-list-id', - }, { fieldName: 'host.name', isNested: false, diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/index.test.tsx index 986f27f6495ec..84613d1c73536 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/index.test.tsx @@ -72,6 +72,7 @@ describe('ExceptionsViewer', () => { exceptionListsMeta={[ { id: '5b543420', + listId: 'list_id', type: 'endpoint', namespaceType: 'single', }, @@ -124,6 +125,7 @@ describe('ExceptionsViewer', () => { exceptionListsMeta={[ { id: '5b543420', + listId: 'list_id', type: 'endpoint', namespaceType: 'single', }, diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/index.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/index.tsx index 34dc47b9cd411..7482068454a97 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/index.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { useCallback, useMemo, useEffect, useReducer } from 'react'; +import React, { useCallback, useEffect, useReducer } from 'react'; import { EuiSpacer } from '@elastic/eui'; import uuid from 'uuid'; @@ -31,23 +31,23 @@ import { EditExceptionModal } from '../edit_exception_modal'; import { AddExceptionModal } from '../add_exception_modal'; const initialState: State = { - filterOptions: { filter: '', showEndpointList: false, showDetectionsList: false, tags: [] }, + filterOptions: { filter: '', tags: [] }, pagination: { pageIndex: 0, pageSize: 20, totalItemCount: 0, pageSizeOptions: [5, 10, 20, 50, 100, 200, 300], }, - endpointList: null, - detectionsList: null, - allExceptions: [], exceptions: [], exceptionToEdit: null, - loadingLists: [], loadingItemIds: [], isInitLoading: true, currentModal: null, exceptionListTypeToEdit: null, + totalEndpointItems: 0, + totalDetectionsItems: 0, + showEndpointListsOnly: false, + showDetectionsListsOnly: false, }; interface ExceptionsViewerProps { @@ -87,46 +87,47 @@ const ExceptionsViewerComponent = ({ ); const [ { - endpointList, - detectionsList, exceptions, filterOptions, pagination, - loadingLists, loadingItemIds, isInitLoading, currentModal, exceptionToEdit, exceptionListTypeToEdit, + totalEndpointItems, + totalDetectionsItems, + showDetectionsListsOnly, + showEndpointListsOnly, }, dispatch, - ] = useReducer(allExceptionItemsReducer(), { ...initialState, loadingLists: exceptionListsMeta }); - const { deleteExceptionItem } = useApi(services.http); + ] = useReducer(allExceptionItemsReducer(), { ...initialState }); + const { deleteExceptionItem, getExceptionListsItems } = useApi(services.http); const setExceptions = useCallback( - ({ - lists: newLists, - exceptions: newExceptions, - pagination: newPagination, - }: UseExceptionListSuccess): void => { + ({ exceptions: newExceptions, pagination: newPagination }: UseExceptionListSuccess): void => { dispatch({ type: 'setExceptions', - lists: newLists, + lists: exceptionListsMeta, exceptions: newExceptions, pagination: newPagination, }); }, - [dispatch] + [dispatch, exceptionListsMeta] ); - const [loadingList, , , , fetchList] = useExceptionList({ + const [loadingList, , , fetchListItems] = useExceptionList({ http: services.http, - lists: loadingLists, - filterOptions, + lists: exceptionListsMeta, + filterOptions: + filterOptions.filter !== '' || filterOptions.tags.length > 0 ? [filterOptions] : [], pagination: { page: pagination.pageIndex + 1, perPage: pagination.pageSize, total: pagination.totalItemCount, }, + showDetectionsListsOnly, + showEndpointListsOnly, + matchFilters: true, onSuccess: setExceptions, onError: onDispatchToaster({ color: 'danger', @@ -145,22 +146,81 @@ const ExceptionsViewerComponent = ({ [dispatch] ); + const setExceptionItemTotals = useCallback( + (endpointItemTotals: number | null, detectionItemTotals: number | null): void => { + dispatch({ + type: 'setExceptionItemTotals', + totalEndpointItems: endpointItemTotals, + totalDetectionsItems: detectionItemTotals, + }); + }, + [dispatch] + ); + + const handleGetTotals = useCallback(async (): Promise => { + await getExceptionListsItems({ + lists: exceptionListsMeta, + filterOptions: [], + pagination: { + page: 0, + perPage: 1, + total: 0, + }, + showDetectionsListsOnly: true, + showEndpointListsOnly: false, + onSuccess: ({ pagination: detectionPagination }) => { + setExceptionItemTotals(null, detectionPagination.total ?? 0); + }, + onError: () => { + const dispatchToasterError = onDispatchToaster({ + color: 'danger', + title: i18n.TOTAL_ITEMS_FETCH_ERROR, + iconType: 'alert', + }); + + dispatchToasterError(); + }, + }); + await getExceptionListsItems({ + lists: exceptionListsMeta, + filterOptions: [], + pagination: { + page: 0, + perPage: 1, + total: 0, + }, + showDetectionsListsOnly: false, + showEndpointListsOnly: true, + onSuccess: ({ pagination: endpointPagination }) => { + setExceptionItemTotals(endpointPagination.total ?? 0, null); + }, + onError: () => { + const dispatchToasterError = onDispatchToaster({ + color: 'danger', + title: i18n.TOTAL_ITEMS_FETCH_ERROR, + iconType: 'alert', + }); + + dispatchToasterError(); + }, + }); + }, [setExceptionItemTotals, exceptionListsMeta, getExceptionListsItems, onDispatchToaster]); + const handleFetchList = useCallback((): void => { - if (fetchList != null) { - fetchList(); + if (fetchListItems != null) { + fetchListItems(); + handleGetTotals(); } - }, [fetchList]); + }, [fetchListItems, handleGetTotals]); const handleFilterChange = useCallback( - ({ filter, pagination: pag }: Filter): void => { + (filters: Partial): void => { dispatch({ type: 'updateFilterOptions', - filterOptions: filter, - pagination: pag, - allLists: exceptionListsMeta, + filters, }); }, - [dispatch, exceptionListsMeta] + [dispatch] ); const handleAddException = useCallback( @@ -176,21 +236,21 @@ const ExceptionsViewerComponent = ({ const handleEditException = useCallback( (exception: ExceptionListItemSchema): void => { - // TODO: Added this just for testing. Update - // modal state logic as needed once ready dispatch({ type: 'updateExceptionToEdit', + lists: exceptionListsMeta, exception, }); setCurrentModal('editModal'); }, - [setCurrentModal] + [setCurrentModal, exceptionListsMeta] ); const handleOnCancelExceptionModal = useCallback((): void => { setCurrentModal(null); - }, [setCurrentModal]); + handleFetchList(); + }, [setCurrentModal, handleFetchList]); const handleOnConfirmExceptionModal = useCallback((): void => { setCurrentModal(null); @@ -236,23 +296,24 @@ const ExceptionsViewerComponent = ({ // Logic for initial render useEffect((): void => { if (isInitLoading && !loadingList && (exceptions.length === 0 || exceptions != null)) { + handleGetTotals(); dispatch({ type: 'updateIsInitLoading', loading: false, }); } - }, [isInitLoading, exceptions, loadingList, dispatch]); + }, [handleGetTotals, isInitLoading, exceptions, loadingList, dispatch]); // Used in utility bar info text - const ruleSettingsUrl = useMemo((): string => { - return services.application.getUrlForApp( - `security/detections/rules/id/${encodeURI(ruleId)}/edit` - ); - }, [ruleId, services.application]); + const ruleSettingsUrl = services.application.getUrlForApp( + `security/detections/rules/id/${encodeURI(ruleId)}/edit` + ); + + const showEmpty: boolean = + !isInitLoading && !loadingList && totalEndpointItems === 0 && totalDetectionsItems === 0; - const showEmpty = useMemo((): boolean => { - return !isInitLoading && !loadingList && exceptions.length === 0; - }, [isInitLoading, exceptions.length, loadingList]); + const showNoResults: boolean = + exceptions.length === 0 && (totalEndpointItems > 0 || totalDetectionsItems > 0); return ( <> @@ -289,8 +350,8 @@ const ExceptionsViewerComponent = ({ @@ -299,13 +360,15 @@ const ExceptionsViewerComponent = ({ ; - pagination: Partial; - allLists: ExceptionIdentifiers[]; + filters: Partial; } | { type: 'updateIsInitLoading'; loading: boolean } | { type: 'updateModalOpen'; modalName: ViewerModalName } - | { type: 'updateExceptionToEdit'; exception: ExceptionListItemSchema } + | { + type: 'updateExceptionToEdit'; + lists: ExceptionIdentifiers[]; + exception: ExceptionListItemSchema; + } | { type: 'updateLoadingItemIds'; items: ExceptionListItemIdentifiers[] } - | { type: 'updateExceptionListTypeToEdit'; exceptionListType: ExceptionListType | null }; + | { type: 'updateExceptionListTypeToEdit'; exceptionListType: ExceptionListType | null } + | { + type: 'setExceptionItemTotals'; + totalEndpointItems: number | null; + totalDetectionsItems: number | null; + }; export const allExceptionItemsReducer = () => (state: State, action: Action): State => { switch (action.type) { case 'setExceptions': { - const endpointList = action.lists.filter((t) => t.type === 'endpoint'); - const detectionsList = action.lists.filter((t) => t.type === 'detection'); + const { exceptions, pagination } = action; return { ...state, - endpointList: state.filterOptions.showDetectionsList - ? state.endpointList - : endpointList[0] ?? null, - detectionsList: state.filterOptions.showEndpointList - ? state.detectionsList - : detectionsList[0] ?? null, pagination: { ...state.pagination, - pageIndex: action.pagination.page - 1, - pageSize: action.pagination.perPage, - totalItemCount: action.pagination.total ?? 0, + pageIndex: pagination.page - 1, + pageSize: pagination.perPage, + totalItemCount: pagination.total ?? 0, }, - allExceptions: action.exceptions, - exceptions: action.exceptions, + exceptions, }; } case 'updateFilterOptions': { - const returnState = { + const { filter, pagination, showEndpointListsOnly, showDetectionsListsOnly } = action.filters; + return { ...state, filterOptions: { ...state.filterOptions, - ...action.filterOptions, + ...filter, }, pagination: { ...state.pagination, - ...action.pagination, + ...pagination, }, + showEndpointListsOnly: showEndpointListsOnly ?? state.showEndpointListsOnly, + showDetectionsListsOnly: showDetectionsListsOnly ?? state.showDetectionsListsOnly, + }; + } + case 'setExceptionItemTotals': { + return { + ...state, + totalEndpointItems: + action.totalEndpointItems == null ? state.totalEndpointItems : action.totalEndpointItems, + totalDetectionsItems: + action.totalDetectionsItems == null + ? state.totalDetectionsItems + : action.totalDetectionsItems, }; - - if (action.filterOptions.showEndpointList) { - const list = action.allLists.filter((t) => t.type === 'endpoint'); - - return { - ...returnState, - loadingLists: list, - exceptions: list.length === 0 ? [] : [...state.exceptions], - }; - } else if (action.filterOptions.showDetectionsList) { - const list = action.allLists.filter((t) => t.type === 'detection'); - - return { - ...returnState, - loadingLists: list, - exceptions: list.length === 0 ? [] : [...state.exceptions], - }; - } else { - return { - ...returnState, - loadingLists: action.allLists, - }; - } } case 'updateIsInitLoading': { return { @@ -121,13 +115,13 @@ export const allExceptionItemsReducer = () => (state: State, action: Action): St }; } case 'updateExceptionToEdit': { - const exception = action.exception; - const exceptionListToEdit = [state.endpointList, state.detectionsList].find((list) => { - return list !== null && exception.list_id === list.list_id; + const { exception, lists } = action; + const exceptionListToEdit = lists.find((list) => { + return list !== null && exception.list_id === list.listId; }); return { ...state, - exceptionToEdit: action.exception, + exceptionToEdit: exception, exceptionListTypeToEdit: exceptionListToEdit ? exceptionListToEdit.type : null, }; } diff --git a/x-pack/plugins/security_solution/public/common/components/filters_global/filters_global.test.tsx b/x-pack/plugins/security_solution/public/common/components/filters_global/filters_global.test.tsx index ffac0496e9f1a..9fda60b1f289d 100644 --- a/x-pack/plugins/security_solution/public/common/components/filters_global/filters_global.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/filters_global/filters_global.test.tsx @@ -4,20 +4,120 @@ * you may not use this file except in compliance with the Elastic License. */ -import { shallow } from 'enzyme'; +import { mount, ReactWrapper, shallow } from 'enzyme'; import React from 'react'; +import { StickyContainer } from 'react-sticky'; import '../../mock/match_media'; import { FiltersGlobal } from './filters_global'; +import { TestProviders } from '../../mock/test_providers'; describe('rendering', () => { test('renders correctly', () => { const wrapper = shallow( - +

      {'Additional filters here.'}

      ); expect(wrapper).toMatchSnapshot(); }); + + describe('full screen mode', () => { + let wrapper: ReactWrapper; + + beforeEach(() => { + wrapper = mount( + + + +

      {'Filter content'}

      +
      +
      +
      + ); + }); + + test('it does NOT render the sticky container', () => { + expect(wrapper.find('[data-test-subj="sticky-filters-global-container"]').exists()).toBe( + false + ); + }); + + test('it renders the non-sticky container', () => { + expect(wrapper.find('[data-test-subj="non-sticky-global-container"]').exists()).toBe(true); + }); + + test('it does NOT render the container with a `display: none` style when `show` is true (the default)', () => { + expect( + wrapper.find('[data-test-subj="non-sticky-global-container"]').first() + ).not.toHaveStyleRule('display', 'none'); + }); + }); + + describe('non-full screen mode', () => { + let wrapper: ReactWrapper; + + beforeEach(() => { + wrapper = mount( + + + +

      {'Filter content'}

      +
      +
      +
      + ); + }); + + test('it renders the sticky container', () => { + expect(wrapper.find('[data-test-subj="sticky-filters-global-container"]').exists()).toBe( + true + ); + }); + + test('it does NOT render the non-sticky container', () => { + expect(wrapper.find('[data-test-subj="non-sticky-global-container"]').exists()).toBe(false); + }); + + test('it does NOT render the container with a `display: none` style when `show` is true (the default)', () => { + expect( + wrapper.find('[data-test-subj="sticky-filters-global-container"]').first() + ).not.toHaveStyleRule('display', 'none'); + }); + }); + + describe('when show is false', () => { + test('in full screen mode it renders the container with a `display: none` style', () => { + const wrapper = mount( + + + +

      {'Filter content'}

      +
      +
      +
      + ); + + expect( + wrapper.find('[data-test-subj="non-sticky-global-container"]').first() + ).toHaveStyleRule('display', 'none'); + }); + + test('in non-full screen mode it renders the container with a `display: none` style', () => { + const wrapper = mount( + + + +

      {'Filter content'}

      +
      +
      +
      + ); + + expect( + wrapper.find('[data-test-subj="sticky-filters-global-container"]').first() + ).toHaveStyleRule('display', 'none'); + }); + }); }); diff --git a/x-pack/plugins/security_solution/public/common/components/filters_global/filters_global.tsx b/x-pack/plugins/security_solution/public/common/components/filters_global/filters_global.tsx index b52438486406e..80e7209492fa5 100644 --- a/x-pack/plugins/security_solution/public/common/components/filters_global/filters_global.tsx +++ b/x-pack/plugins/security_solution/public/common/components/filters_global/filters_global.tsx @@ -47,20 +47,33 @@ const FiltersGlobalContainer = styled.header<{ show: boolean }>` FiltersGlobalContainer.displayName = 'FiltersGlobalContainer'; +const NO_STYLE: React.CSSProperties = {}; + export interface FiltersGlobalProps { children: React.ReactNode; + globalFullScreen: boolean; show?: boolean; } -export const FiltersGlobal = React.memo(({ children, show = true }) => ( - - {({ style, isSticky }) => ( - - +export const FiltersGlobal = React.memo( + ({ children, globalFullScreen, show = true }) => + globalFullScreen ? ( + + {children} - )} - -)); + ) : ( + + {({ style, isSticky }) => ( + + + {children} + + + )} + + ) +); + FiltersGlobal.displayName = 'FiltersGlobal'; diff --git a/x-pack/plugins/security_solution/public/common/components/help_menu/index.tsx b/x-pack/plugins/security_solution/public/common/components/help_menu/index.tsx index f4477740f7b58..1eaa16fd058a5 100644 --- a/x-pack/plugins/security_solution/public/common/components/help_menu/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/help_menu/index.tsx @@ -39,7 +39,7 @@ export const HelpMenu = React.memo(() => { }, { linkType: 'discuss', - href: 'https://discuss.elastic.co/c/siem', + href: 'https://discuss.elastic.co/c/security', target: '_blank', rel: 'noopener', }, diff --git a/x-pack/plugins/security_solution/public/common/components/markdown_editor/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/markdown_editor/index.test.tsx new file mode 100644 index 0000000000000..b5e5b01189418 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/markdown_editor/index.test.tsx @@ -0,0 +1,49 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { mount } from 'enzyme'; +import React from 'react'; + +import { MarkdownEditor } from '.'; +import { TestProviders } from '../../mock'; + +describe('Markdown Editor', () => { + const onChange = jest.fn(); + const onCursorPositionUpdate = jest.fn(); + const defaultProps = { + content: 'hello world', + onChange, + onCursorPositionUpdate, + }; + beforeEach(() => { + jest.clearAllMocks(); + }); + test('it calls onChange with correct value', () => { + const wrapper = mount( + + + + ); + const newValue = 'a new string'; + wrapper + .find(`[data-test-subj="textAreaInput"]`) + .first() + .simulate('change', { target: { value: newValue } }); + expect(onChange).toBeCalledWith(newValue); + }); + test('it calls onCursorPositionUpdate with correct args', () => { + const wrapper = mount( + + + + ); + wrapper.find(`[data-test-subj="textAreaInput"]`).first().simulate('blur'); + expect(onCursorPositionUpdate).toBeCalledWith({ + start: 0, + end: 0, + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/common/components/markdown_editor/index.tsx b/x-pack/plugins/security_solution/public/common/components/markdown_editor/index.tsx index c40b3910ec152..d4ad4a11b60a3 100644 --- a/x-pack/plugins/security_solution/public/common/components/markdown_editor/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/markdown_editor/index.tsx @@ -103,7 +103,6 @@ export const MarkdownEditor = React.memo<{ end: e!.target!.selectionEnd ?? 0, }); } - return false; }, [onCursorPositionUpdate] ); diff --git a/x-pack/plugins/security_solution/public/common/components/ml_popover/api.tsx b/x-pack/plugins/security_solution/public/common/components/ml_popover/api.tsx index b4da4fa79e035..7c72098209a06 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml_popover/api.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml_popover/api.tsx @@ -71,7 +71,7 @@ export const setupMlJob = async ({ configTemplate, indexPatternName = 'auditbeat-*', jobIdErrorFilter = [], - groups = ['siem'], + groups = ['security'], prefix = '', }: MlSetupArgs): Promise => { const response = await KibanaServices.get().http.fetch( diff --git a/x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/translations.ts b/x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/translations.ts index 2b37c437866e0..7b29bab2e38f3 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/translations.ts +++ b/x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/translations.ts @@ -9,6 +9,6 @@ import { i18n } from '@kbn/i18n'; export const SIEM_JOB_FETCH_FAILURE = i18n.translate( 'xpack.securitySolution.components.mlPopup.hooks.errors.siemJobFetchFailureTitle', { - defaultMessage: 'SIEM job fetch failure', + defaultMessage: 'Security job fetch failure', } ); diff --git a/x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/use_siem_jobs_helpers.tsx b/x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/use_siem_jobs_helpers.tsx index 658d2659282ce..adbd712ffeb3e 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/use_siem_jobs_helpers.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml_popover/hooks/use_siem_jobs_helpers.tsx @@ -104,7 +104,7 @@ export const getInstalledJobs = ( compatibleModuleIds: string[] ): SiemJob[] => jobSummaryData - .filter(({ groups }) => groups.includes('siem')) + .filter(({ groups }) => groups.includes('siem') || groups.includes('security')) .map((jobSummary) => ({ ...jobSummary, ...getAugmentedFields(jobSummary.id, moduleJobs, compatibleModuleIds), diff --git a/x-pack/plugins/security_solution/public/common/components/ml_popover/jobs_table/filters/groups_filter_popover.tsx b/x-pack/plugins/security_solution/public/common/components/ml_popover/jobs_table/filters/groups_filter_popover.tsx index 1aa3ad630306e..d879942b8b101 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml_popover/jobs_table/filters/groups_filter_popover.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml_popover/jobs_table/filters/groups_filter_popover.tsx @@ -25,8 +25,8 @@ interface GroupsFilterPopoverProps { /** * Popover for selecting which SiemJob groups to filter on. Component extracts unique groups and - * their counts from the provided SiemJobs. The 'siem' group is filtered out as all jobs will be - * siem jobs + * their counts from the provided SiemJobs. The 'siem' & 'security' groups are filtered out as all jobs will be + * siem/security jobs * * @param siemJobs jobs to fetch groups from to display for filtering * @param onSelectedGroupsChanged change listener to be notified when group selection changes @@ -41,7 +41,7 @@ export const GroupsFilterPopoverComponent = ({ const groups = siemJobs .map((j) => j.groups) .flat() - .filter((g) => g !== 'siem'); + .filter((g) => g !== 'siem' && g !== 'security'); const uniqueGroups = Array.from(new Set(groups)); useEffect(() => { diff --git a/x-pack/plugins/security_solution/public/common/components/ml_popover/ml_modules.tsx b/x-pack/plugins/security_solution/public/common/components/ml_popover/ml_modules.tsx index b956cf2c1494c..4dccba08590a4 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml_popover/ml_modules.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml_popover/ml_modules.tsx @@ -12,6 +12,7 @@ export const mlModules: string[] = [ 'siem_auditbeat', 'siem_auditbeat_auth', + 'siem_cloudtrail', 'siem_packetbeat', 'siem_winlogbeat', 'siem_winlogbeat_auth', diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.test.ts b/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.test.ts index 7e508c28c62df..89aa77106933e 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.test.ts +++ b/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.test.ts @@ -36,6 +36,13 @@ const getMockObject = ( ): RouteSpyState & TabNavigationProps => ({ detailName, navTabs: { + case: { + disabled: false, + href: '/app/security/cases', + id: 'case', + name: 'Cases', + urlKey: 'case', + }, hosts: { disabled: false, href: '/app/security/hosts', @@ -227,6 +234,73 @@ describe('Navigation Breadcrumbs', () => { { text: 'Flows', href: '' }, ]); }); + + test('should return Alerts breadcrumbs when supplied detection pathname', () => { + const breadcrumbs = getBreadcrumbsForRoute( + getMockObject('detections', '/', undefined), + getUrlForAppMock + ); + expect(breadcrumbs).toEqual([ + { text: 'Security', href: '/app/security/overview' }, + { + text: 'Detections', + href: + "securitySolution:detections?timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", + }, + ]); + }); + test('should return Cases breadcrumbs when supplied case pathname', () => { + const breadcrumbs = getBreadcrumbsForRoute( + getMockObject('case', '/', undefined), + getUrlForAppMock + ); + expect(breadcrumbs).toEqual([ + { text: 'Security', href: '/app/security/overview' }, + { + text: 'Cases', + href: + "securitySolution:case?timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", + }, + ]); + }); + test('should return Case details breadcrumbs when supplied case details pathname', () => { + const sampleCase = { + id: 'my-case-id', + name: 'Case name', + }; + const breadcrumbs = getBreadcrumbsForRoute( + { + ...getMockObject('case', `/${sampleCase.id}`, sampleCase.id), + state: { caseTitle: sampleCase.name }, + }, + getUrlForAppMock + ); + expect(breadcrumbs).toEqual([ + { text: 'Security', href: '/app/security/overview' }, + { + text: 'Cases', + href: + "securitySolution:case?timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", + }, + { + text: sampleCase.name, + href: `securitySolution:case/${sampleCase.id}?timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))`, + }, + ]); + }); + test('should return Admin breadcrumbs when supplied admin pathname', () => { + const breadcrumbs = getBreadcrumbsForRoute( + getMockObject('administration', '/', undefined), + getUrlForAppMock + ); + expect(breadcrumbs).toEqual([ + { text: 'Security', href: '/app/security/overview' }, + { + text: 'Administration', + href: 'securitySolution:administration', + }, + ]); + }); }); describe('setBreadcrumbs()', () => { diff --git a/x-pack/plugins/security_solution/public/common/components/news_feed/helpers.test.ts b/x-pack/plugins/security_solution/public/common/components/news_feed/helpers.test.ts index cdd04b50a6d50..35a59f4d18e8b 100644 --- a/x-pack/plugins/security_solution/public/common/components/news_feed/helpers.test.ts +++ b/x-pack/plugins/security_solution/public/common/components/news_feed/helpers.test.ts @@ -144,7 +144,7 @@ describe('helpers', () => { hash: '5a35c984a9cdc1c6a25913f3d0b99b1aefc7257bc3b936c39db9fa0435edeed0', imageUrl: 'https://aws1.discourse-cdn.com/elastic/original/3X/f/8/f8c3d0b9971cfcd0be349d973aa5799f71d280cc.png?blade=securitysolutionfeed', - linkUrl: 'https://discuss.elastic.co/c/siem?blade=securitysolutionfeed', + linkUrl: 'https://discuss.elastic.co/c/security?blade=securitysolutionfeed', publishOn: expect.any(Date), title: 'Got SIEM Questions?', }, @@ -284,7 +284,7 @@ describe('helpers', () => { }, link_text: null, link_url: { - en: 'https://discuss.elastic.co/c/siem?blade=securitysolutionfeed', + en: 'https://discuss.elastic.co/c/security?blade=securitysolutionfeed', ja: translatedLinkUrl, }, languages: null, diff --git a/x-pack/plugins/security_solution/public/common/components/page/index.tsx b/x-pack/plugins/security_solution/public/common/components/page/index.tsx index 9a5654ed6475f..8bf0690bfd0ad 100644 --- a/x-pack/plugins/security_solution/public/common/components/page/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/page/index.tsx @@ -7,7 +7,10 @@ import { EuiBadge, EuiDescriptionList, EuiFlexGroup, EuiIcon, EuiPage } from '@elastic/eui'; import styled, { createGlobalStyle } from 'styled-components'; -import { FULL_SCREEN_TOGGLED_CLASS_NAME } from '../../../../common/constants'; +import { + FULL_SCREEN_TOGGLED_CLASS_NAME, + SCROLLING_DISABLED_CLASS_NAME, +} from '../../../../common/constants'; /* SIDE EFFECT: the following `createGlobalStyle` overrides default styling in angular code that was not theme-friendly @@ -49,8 +52,8 @@ export const AppGlobalStyle = createGlobalStyle<{ theme: { eui: { euiColorPrimar border: none; } - /* hide open popovers when a modal is being displayed to prevent them from covering the modal */ - body.euiBody-hasOverlayMask .euiPopover__panel-isOpen { + /* hide open draggable popovers when a modal is being displayed to prevent them from covering the modal */ + body.euiBody-hasOverlayMask .withHoverActions__popover.euiPopover__panel-isOpen{ visibility: hidden !important; } @@ -63,6 +66,14 @@ export const AppGlobalStyle = createGlobalStyle<{ theme: { eui: { euiColorPrimar .${FULL_SCREEN_TOGGLED_CLASS_NAME} { ${({ theme }) => `background-color: ${theme.eui.euiColorPrimary} !important`}; } + + .${SCROLLING_DISABLED_CLASS_NAME} body { + overflow-y: hidden; + } + + .${SCROLLING_DISABLED_CLASS_NAME} #kibana-body { + overflow-y: hidden; + } `; export const DescriptionListStyled = styled(EuiDescriptionList)` diff --git a/x-pack/plugins/security_solution/public/common/components/with_hover_actions/index.tsx b/x-pack/plugins/security_solution/public/common/components/with_hover_actions/index.tsx index e6577bd040e25..b4abdd4b91805 100644 --- a/x-pack/plugins/security_solution/public/common/components/with_hover_actions/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/with_hover_actions/index.tsx @@ -10,6 +10,11 @@ import styled from 'styled-components'; import { IS_DRAGGING_CLASS_NAME } from '../drag_and_drop/helpers'; +/** + * To avoid expensive changes to the DOM, delay showing the popover menu + */ +const HOVER_INTENT_DELAY = 100; // ms + // eslint-disable-next-line @typescript-eslint/no-explicit-any const WithHoverActionsPopover = (styled(EuiPopover as any)` .euiPopover__anchor { @@ -51,18 +56,27 @@ export const WithHoverActions = React.memo( ({ alwaysShow = false, closePopOverTrigger, hoverContent, render }) => { const [isOpen, setIsOpen] = useState(hoverContent != null && alwaysShow); const [showHoverContent, setShowHoverContent] = useState(false); + const [hoverTimeout, setHoverTimeout] = useState(undefined); + const onMouseEnter = useCallback(() => { - // NOTE: the following read from the DOM is expensive, but not as - // expensive as the default behavior, which adds a div to the body, - // which-in turn performs a more expensive change to the layout - if (!document.body.classList.contains(IS_DRAGGING_CLASS_NAME)) { - setShowHoverContent(true); - } - }, []); + setHoverTimeout( + Number( + setTimeout(() => { + // NOTE: the following read from the DOM is expensive, but not as + // expensive as the default behavior, which adds a div to the body, + // which-in turn performs a more expensive change to the layout + if (!document.body.classList.contains(IS_DRAGGING_CLASS_NAME)) { + setShowHoverContent(true); + } + }, HOVER_INTENT_DELAY) + ) + ); + }, [setHoverTimeout, setShowHoverContent]); const onMouseLeave = useCallback(() => { + clearTimeout(hoverTimeout); setShowHoverContent(false); - }, []); + }, [hoverTimeout, setShowHoverContent]); const content = useMemo( () => ( @@ -90,6 +104,7 @@ export const WithHoverActions = React.memo( hasArrow={false} isOpen={isOpen} panelPaddingSize={!alwaysShow ? 's' : 'none'} + panelClassName="withHoverActions__popover" > {isOpen ? <>{hoverContent} : null} diff --git a/x-pack/plugins/security_solution/public/common/containers/source/index.tsx b/x-pack/plugins/security_solution/public/common/containers/source/index.tsx index 54d49d7279d68..ffbecf9e3d433 100644 --- a/x-pack/plugins/security_solution/public/common/containers/source/index.tsx +++ b/x-pack/plugins/security_solution/public/common/containers/source/index.tsx @@ -122,7 +122,12 @@ interface UseWithSourceState { export const useWithSource = ( sourceId = 'default', indexToAdd?: string[] | null, - onlyCheckIndexToAdd?: boolean + onlyCheckIndexToAdd?: boolean, + // Fun fact: When using this hook multiple times within a component (e.g. add_exception_modal & edit_exception_modal), + // the apolloClient will perform queryDeduplication and prevent the first query from executing. A deep compare is not + // performed on `indices`, so another field must be passed to circumvent this. + // For details, see https://github.com/apollographql/react-apollo/issues/2202 + queryDeduplication = 'default' ) => { const [configIndex] = useUiSetting$(DEFAULT_INDEX_KEY); const defaultIndex = useMemo(() => { @@ -154,12 +159,16 @@ export const useWithSource = ( setState((prevState) => ({ ...prevState, loading: true })); try { - const result = await apolloClient.query({ + const result = await apolloClient.query< + SourceQuery.Query, + SourceQuery.Variables & { queryDeduplication: string } + >({ query: sourceQuery, - fetchPolicy: 'network-only', + fetchPolicy: 'cache-first', variables: { sourceId, defaultIndex, + queryDeduplication, }, context: { fetchOptions: { @@ -206,7 +215,7 @@ export const useWithSource = ( isSubscribed = false; return abortCtrl.abort(); }; - }, [apolloClient, sourceId, defaultIndex]); + }, [apolloClient, sourceId, defaultIndex, queryDeduplication]); return state; }; diff --git a/x-pack/plugins/security_solution/public/common/containers/use_full_screen/index.tsx b/x-pack/plugins/security_solution/public/common/containers/use_full_screen/index.tsx index b8050034d34a6..aa0d90a216035 100644 --- a/x-pack/plugins/security_solution/public/common/containers/use_full_screen/index.tsx +++ b/x-pack/plugins/security_solution/public/common/containers/use_full_screen/index.tsx @@ -6,6 +6,7 @@ import { useCallback, useMemo } from 'react'; import { useDispatch, useSelector } from 'react-redux'; +import { SCROLLING_DISABLED_CLASS_NAME } from '../../../../common/constants'; import { inputsSelectors } from '../../store'; import { inputsActions } from '../../store/actions'; @@ -16,7 +17,16 @@ export const useFullScreen = () => { const timelineFullScreen = useSelector(inputsSelectors.timelineFullScreenSelector) ?? false; const setGlobalFullScreen = useCallback( - (fullScreen: boolean) => dispatch(inputsActions.setFullScreen({ id: 'global', fullScreen })), + (fullScreen: boolean) => { + if (fullScreen) { + document.body.classList.add(SCROLLING_DISABLED_CLASS_NAME); + } else { + document.body.classList.remove(SCROLLING_DISABLED_CLASS_NAME); + setTimeout(() => window.scrollTo(0, 0), 0); + } + + dispatch(inputsActions.setFullScreen({ id: 'global', fullScreen })); + }, [dispatch] ); diff --git a/x-pack/plugins/security_solution/public/common/mock/news.ts b/x-pack/plugins/security_solution/public/common/mock/news.ts index 3e421ce19ae9c..51449347e649a 100644 --- a/x-pack/plugins/security_solution/public/common/mock/news.ts +++ b/x-pack/plugins/security_solution/public/common/mock/news.ts @@ -16,7 +16,7 @@ export const rawNewsApiResponse: RawNewsApiResponse = { "There's an awesome community of Elastic SIEM users out there. Join the discussion about configuring, learning, and using the Elastic SIEM app, and detecting threats!", }, link_text: null, - link_url: { en: 'https://discuss.elastic.co/c/siem?blade=securitysolutionfeed' }, + link_url: { en: 'https://discuss.elastic.co/c/security?blade=securitysolutionfeed' }, languages: null, badge: { en: '7.6' }, image_url: { diff --git a/x-pack/plugins/security_solution/public/common/mock/raw_news.ts b/x-pack/plugins/security_solution/public/common/mock/raw_news.ts index 85bef15a41b23..9cd06ed107956 100644 --- a/x-pack/plugins/security_solution/public/common/mock/raw_news.ts +++ b/x-pack/plugins/security_solution/public/common/mock/raw_news.ts @@ -17,7 +17,7 @@ export const rawNewsJSON = ` }, "link_text":null, "link_url":{ - "en":"https://discuss.elastic.co/c/siem?blade=securitysolutionfeed" + "en":"https://discuss.elastic.co/c/security?blade=securitysolutionfeed" }, "languages":null, "badge":{ diff --git a/x-pack/plugins/security_solution/public/common/translations.ts b/x-pack/plugins/security_solution/public/common/translations.ts index 413119fb40f14..3b94ac8959496 100644 --- a/x-pack/plugins/security_solution/public/common/translations.ts +++ b/x-pack/plugins/security_solution/public/common/translations.ts @@ -7,16 +7,39 @@ import { i18n } from '@kbn/i18n'; export const EMPTY_TITLE = i18n.translate('xpack.securitySolution.pages.common.emptyTitle', { - defaultMessage: 'Welcome to Security Solution. Let’s get you started.', + defaultMessage: 'Welcome to Elastic Security. Let’s get you started.', }); -export const EMPTY_ACTION_PRIMARY = i18n.translate( - 'xpack.securitySolution.pages.common.emptyActionPrimary', +export const EMPTY_ACTION_ELASTIC_AGENT = i18n.translate( + 'xpack.securitySolution.pages.common.emptyActionElasticAgent', + { + defaultMessage: 'Add data with Elastic Agent', + } +); + +export const EMPTY_ACTION_ELASTIC_AGENT_DESCRIPTION = i18n.translate( + 'xpack.securitySolution.pages.common.emptyActionElasticAgentDescription', + { + defaultMessage: + 'The Elastic Agent provides a simple, unified way to add monitoring to your hosts.', + } +); + +export const EMPTY_ACTION_BEATS = i18n.translate( + 'xpack.securitySolution.pages.common.emptyActionBeats', { defaultMessage: 'Add data with Beats', } ); +export const EMPTY_ACTION_BEATS_DESCRIPTION = i18n.translate( + 'xpack.securitySolution.pages.common.emptyActionBeatsDescription', + { + defaultMessage: + 'Lightweight Beats can send data from hundreds or thousands of machines and systems', + } +); + export const EMPTY_ACTION_SECONDARY = i18n.translate( 'xpack.securitySolution.pages.common.emptyActionSecondary', { @@ -27,6 +50,14 @@ export const EMPTY_ACTION_SECONDARY = i18n.translate( export const EMPTY_ACTION_ENDPOINT = i18n.translate( 'xpack.securitySolution.pages.common.emptyActionEndpoint', { - defaultMessage: 'Add data with Elastic Agent (Beta)', + defaultMessage: 'Add Elastic Endpoint Security', + } +); + +export const EMPTY_ACTION_ENDPOINT_DESCRIPTION = i18n.translate( + 'xpack.securitySolution.pages.common.emptyActionEndpointDescription', + { + defaultMessage: + 'Protect your hosts with threat prevention, detection, and deep security data visibility.', } ); diff --git a/x-pack/plugins/security_solution/public/common/utils/timeline/use_show_timeline.test.tsx b/x-pack/plugins/security_solution/public/common/utils/timeline/use_show_timeline.test.tsx new file mode 100644 index 0000000000000..db6e2536ce558 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/utils/timeline/use_show_timeline.test.tsx @@ -0,0 +1,33 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { renderHook, act } from '@testing-library/react-hooks'; +import { useShowTimeline } from './use_show_timeline'; +import { globalNode } from '../../mock'; + +describe('use show timeline', () => { + it('shows timeline for routes on default', async () => { + await act(async () => { + const { result, waitForNextUpdate } = renderHook(() => useShowTimeline()); + await waitForNextUpdate(); + const uninitializedTimeline = result.current; + expect(uninitializedTimeline).toEqual([true]); + }); + }); + it('hides timeline for blacklist routes', async () => { + await act(async () => { + Object.defineProperty(globalNode.window, 'location', { + value: { + pathname: `/cases/configure`, + }, + }); + const { result, waitForNextUpdate } = renderHook(() => useShowTimeline()); + await waitForNextUpdate(); + const uninitializedTimeline = result.current; + expect(uninitializedTimeline).toEqual([false]); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx index 1eda358fe5944..ab95e433d92f3 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx @@ -116,8 +116,9 @@ export const AlertsTableComponent: React.FC = ({ const [addExceptionModalState, setAddExceptionModalState] = useState( addExceptionModalInitialState ); - const [{ browserFields, indexPatterns }] = useFetchIndexPatterns( - signalsIndex !== '' ? [signalsIndex] : [] + const [{ browserFields, indexPatterns, isLoading: indexPatternsLoading }] = useFetchIndexPatterns( + signalsIndex !== '' ? [signalsIndex] : [], + 'alerts_table' ); const kibana = useKibana(); const [, dispatchToaster] = useStateToaster(); @@ -433,7 +434,7 @@ export const AlertsTableComponent: React.FC = ({ closeAddExceptionModal, ]); - if (loading || isEmpty(signalsIndex)) { + if (loading || indexPatternsLoading || isEmpty(signalsIndex)) { return ( diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/description_step/helpers.test.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/description_step/helpers.test.tsx index 2a6cd3fc5bb7a..0d98a0f2f26ff 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/description_step/helpers.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/description_step/helpers.test.tsx @@ -331,6 +331,7 @@ describe('helpers', () => { const result: ListItems[] = buildSeverityDescription({ value: 'low', mapping: [{ field: 'host.name', operator: 'equals', value: 'hello', severity: 'high' }], + isMappingChecked: true, }); expect(result[0].title).toEqual('Severity'); diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/description_step/helpers.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/description_step/helpers.tsx index 1110c8c098988..600bc999849d1 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/description_step/helpers.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/description_step/helpers.tsx @@ -35,6 +35,7 @@ import { SeverityBadge } from '../severity_badge'; import ListTreeIcon from './assets/list_tree_icon.svg'; import { assertUnreachable } from '../../../../common/lib/helpers'; import { AboutStepRiskScore, AboutStepSeverity } from '../../../pages/detection_engine/rules/types'; +import { defaultToEmptyTag } from '../../../../common/components/empty_value'; const NoteDescriptionContainer = styled(EuiFlexItem)` height: 105px; @@ -236,35 +237,44 @@ export const buildSeverityDescription = (severity: AboutStepSeverity): ListItems title: i18nSeverity.DEFAULT_SEVERITY, description: , }, - ...severity.mapping.map((severityItem, index) => { - return { - title: index === 0 ? i18nSeverity.SEVERITY_MAPPING : '', - description: ( - - - - <>{severityItem.field} - - - - <>{severityItem.value} - - - - - - - - - ), - }; - }), + ...(severity.isMappingChecked + ? severity.mapping + .filter((severityItem) => severityItem.field !== '') + .map((severityItem, index) => { + return { + title: index === 0 ? i18nSeverity.SEVERITY_MAPPING : '', + description: ( + + + + <>{`${severityItem.field}:`} + + + + + {defaultToEmptyTag(severityItem.value)} + + + + + + + + + + ), + }; + }) + : []), ]; export const buildRiskScoreDescription = (riskScore: AboutStepRiskScore): ListItems[] => [ @@ -272,27 +282,31 @@ export const buildRiskScoreDescription = (riskScore: AboutStepRiskScore): ListIt title: i18nRiskScore.RISK_SCORE, description: riskScore.value, }, - ...riskScore.mapping.map((riskScoreItem, index) => { - return { - title: index === 0 ? i18nRiskScore.RISK_SCORE_MAPPING : '', - description: ( - - - - <>{riskScoreItem.field} - - - - - - {'signal.rule.risk_score'} - - ), - }; - }), + ...(riskScore.isMappingChecked + ? riskScore.mapping + .filter((riskScoreItem) => riskScoreItem.field !== '') + .map((riskScoreItem, index) => { + return { + title: index === 0 ? i18nRiskScore.RISK_SCORE_MAPPING : '', + description: ( + + + + <>{riskScoreItem.field} + + + + + + {'signal.rule.risk_score'} + + ), + }; + }) + : []), ]; const MyRefUrlLink = styled(EuiLink)` diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/ml_job_select/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/ml_job_select/index.tsx index cb084d4daa782..cdfdf4ca6b66b 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/ml_job_select/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/ml_job_select/index.tsx @@ -41,7 +41,7 @@ const HelpText: React.FC<{ href: string; showEnableWarning: boolean }> = ({ <> diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/translations.ts b/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/translations.ts index 37c1715c05d71..49da7dbf6d514 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/translations.ts +++ b/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/translations.ts @@ -24,7 +24,7 @@ export const PRE_BUILT_MSG = i18n.translate( export const PRE_BUILT_ACTION = i18n.translate( 'xpack.securitySolution.detectionEngine.rules.prePackagedRules.loadPreBuiltButton', { - defaultMessage: 'Load prebuilt detection rules', + defaultMessage: 'Load prebuilt detection rules and timeline templates', } ); diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/update_callout.test.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/update_callout.test.tsx index 5033fcd11dc7c..283bba462792c 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/update_callout.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/update_callout.test.tsx @@ -9,6 +9,7 @@ import { shallow } from 'enzyme'; import { UpdatePrePackagedRulesCallOut } from './update_callout'; import { useKibana } from '../../../../common/lib/kibana'; + jest.mock('../../../../common/lib/kibana'); describe('UpdatePrePackagedRulesCallOut', () => { @@ -22,6 +23,7 @@ describe('UpdatePrePackagedRulesCallOut', () => { }, }); }); + it('renders correctly', () => { const wrapper = shallow( { expect(wrapper.find('EuiCallOut')).toHaveLength(1); }); + + it('renders callOutMessage correctly: numberOfUpdatedRules > 0 and numberOfUpdatedTimelines = 0', () => { + const wrapper = shallow( + + ); + + expect(wrapper.find('[data-test-subj="update-callout"]').find('p').text()).toEqual( + 'You can update 1 Elastic prebuilt ruleRelease notes' + ); + }); + + it('renders buttonTitle correctly: numberOfUpdatedRules > 0 and numberOfUpdatedTimelines = 0', () => { + const wrapper = shallow( + + ); + + expect(wrapper.find('[data-test-subj="update-callout-button"]').prop('children')).toEqual( + 'Update 1 Elastic prebuilt rule' + ); + }); + + it('renders callOutMessage correctly: numberOfUpdatedRules = 0 and numberOfUpdatedTimelines > 0', () => { + const wrapper = shallow( + + ); + + expect(wrapper.find('[data-test-subj="update-callout"]').find('p').text()).toEqual( + 'You can update 1 Elastic prebuilt timelineRelease notes' + ); + }); + + it('renders buttonTitle correctly: numberOfUpdatedRules = 0 and numberOfUpdatedTimelines > 0', () => { + const wrapper = shallow( + + ); + + expect(wrapper.find('[data-test-subj="update-callout-button"]').prop('children')).toEqual( + 'Update 1 Elastic prebuilt timeline' + ); + }); + + it('renders callOutMessage correctly: numberOfUpdatedRules > 0 and numberOfUpdatedTimelines > 0', () => { + const wrapper = shallow( + + ); + + expect(wrapper.find('[data-test-subj="update-callout"]').find('p').text()).toEqual( + 'You can update 1 Elastic prebuilt rule and 1 Elastic prebuilt timeline. Note that this will reload deleted Elastic prebuilt rules.Release notes' + ); + }); + + it('renders buttonTitle correctly: numberOfUpdatedRules > 0 and numberOfUpdatedTimelines > 0', () => { + const wrapper = shallow( + + ); + + expect(wrapper.find('[data-test-subj="update-callout-button"]').prop('children')).toEqual( + 'Update 1 Elastic prebuilt rule and 1 Elastic prebuilt timeline' + ); + }); }); diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/update_callout.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/update_callout.tsx index 4b454a9ed4d4a..30f8cfa7fb3a5 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/update_callout.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/update_callout.tsx @@ -51,7 +51,7 @@ const UpdatePrePackagedRulesCallOutComponent: React.FC +

      {prepackagedRulesOrTimelines?.callOutMessage}
      @@ -62,7 +62,12 @@ const UpdatePrePackagedRulesCallOutComponent: React.FC

      - + {prepackagedRulesOrTimelines?.buttonTitle}
      diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/risk_score_mapping/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/risk_score_mapping/index.tsx index c9e2cb1a8ca24..35816e82540d1 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/risk_score_mapping/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/risk_score_mapping/index.tsx @@ -14,8 +14,9 @@ import { EuiIcon, EuiSpacer, } from '@elastic/eui'; -import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import React, { useCallback, useMemo } from 'react'; import styled from 'styled-components'; +import { noop } from 'lodash/fp'; import * as i18n from './translations'; import { FieldHook } from '../../../../../../../../src/plugins/es_ui_shared/static/forms/hook_form_lib'; import { CommonUseField } from '../../../../cases/components/create'; @@ -24,6 +25,10 @@ import { FieldComponent } from '../../../../common/components/autocomplete/field import { IFieldType } from '../../../../../../../../src/plugins/data/common/index_patterns/fields'; import { IIndexPattern } from '../../../../../../../../src/plugins/data/common/index_patterns'; +const RiskScoreMappingEuiFormRow = styled(EuiFormRow)` + width: 468px; +`; + const NestedContent = styled.div` margin-left: 24px; `; @@ -41,6 +46,7 @@ interface RiskScoreFieldProps { field: FieldHook; idAria: string; indices: IIndexPattern; + isDisabled: boolean; placeholder?: string; } @@ -49,40 +55,23 @@ export const RiskScoreField = ({ field, idAria, indices, + isDisabled, placeholder, }: RiskScoreFieldProps) => { - const [isRiskScoreMappingChecked, setIsRiskScoreMappingChecked] = useState(false); - const [initialFieldCheck, setInitialFieldCheck] = useState(true); - const fieldTypeFilter = useMemo(() => ['number'], []); - useEffect(() => { - if ( - !isRiskScoreMappingChecked && - initialFieldCheck && - (field.value as AboutStepRiskScore).mapping?.length > 0 - ) { - setIsRiskScoreMappingChecked(true); - setInitialFieldCheck(false); - } - }, [ - field, - initialFieldCheck, - isRiskScoreMappingChecked, - setIsRiskScoreMappingChecked, - setInitialFieldCheck, - ]); - const handleFieldChange = useCallback( ([newField]: IFieldType[]): void => { const values = field.value as AboutStepRiskScore; field.setValue({ value: values.value, + isMappingChecked: values.isMappingChecked, mapping: [ { field: newField?.name ?? '', operator: 'equals', - value: '', + value: undefined, + riskScore: undefined, }, ], }); @@ -99,8 +88,13 @@ export const RiskScoreField = ({ }, [field.value, indices]); const handleRiskScoreMappingChecked = useCallback(() => { - setIsRiskScoreMappingChecked(!isRiskScoreMappingChecked); - }, [isRiskScoreMappingChecked, setIsRiskScoreMappingChecked]); + const values = field.value as AboutStepRiskScore; + field.setValue({ + value: values.value, + mapping: [...values.mapping], + isMappingChecked: !values.isMappingChecked, + }); + }, [field]); const riskScoreLabel = useMemo(() => { return ( @@ -117,11 +111,16 @@ export const RiskScoreField = ({ const riskScoreMappingLabel = useMemo(() => { return (
      - + @@ -133,7 +132,7 @@ export const RiskScoreField = ({
      ); - }, [handleRiskScoreMappingChecked, isRiskScoreMappingChecked]); + }, [field.value, handleRiskScoreMappingChecked, isDisabled]); return ( @@ -153,6 +152,7 @@ export const RiskScoreField = ({ componentProps={{ idAria: 'detectionEngineStepAboutRuleRiskScore', 'data-test-subj': 'detectionEngineStepAboutRuleRiskScore', + isDisabled, euiFieldProps: { max: 100, min: 0, @@ -166,11 +166,11 @@ export const RiskScoreField = ({
      - {i18n.RISK_SCORE_MAPPING_DETAILS} ) : ( '' @@ -184,7 +184,7 @@ export const RiskScoreField = ({ > - {isRiskScoreMappingChecked && ( + {(field.value as AboutStepRiskScore).isMappingChecked && ( @@ -208,11 +208,11 @@ export const RiskScoreField = ({ fieldTypeFilter={fieldTypeFilter} isLoading={false} isClearable={false} - isDisabled={false} + isDisabled={isDisabled} onChange={handleFieldChange} data-test-subj={dataTestSubj} aria-label={idAria} - fieldInputWidth={230} + fieldInputWidth={270} /> @@ -226,7 +226,7 @@ export const RiskScoreField = ({ )} - + ); diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/severity_mapping/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/severity_mapping/index.tsx index 579c60579b32e..54d505a4d867f 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/severity_mapping/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/severity_mapping/index.tsx @@ -14,7 +14,8 @@ import { EuiIcon, EuiSpacer, } from '@elastic/eui'; -import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import { noop } from 'lodash/fp'; +import React, { useCallback, useMemo } from 'react'; import styled from 'styled-components'; import * as i18n from './translations'; import { FieldHook } from '../../../../../../../../src/plugins/es_ui_shared/static/forms/hook_form_lib'; @@ -27,10 +28,16 @@ import { } from '../../../../../../../../src/plugins/data/common/index_patterns'; import { FieldComponent } from '../../../../common/components/autocomplete/field'; import { AutocompleteFieldMatchComponent } from '../../../../common/components/autocomplete/field_value_match'; +import { + Severity, + SeverityMapping, + SeverityMappingItem, +} from '../../../../../common/detection_engine/schemas/common/schemas'; -const SeverityMappingParentContainer = styled(EuiFlexItem)` - max-width: 471px; +const SeverityMappingEuiFormRow = styled(EuiFormRow)` + width: 468px; `; + const NestedContent = styled.div` margin-left: 24px; `; @@ -48,6 +55,7 @@ interface SeverityFieldProps { field: FieldHook; idAria: string; indices: IIndexPattern; + isDisabled: boolean; options: SeverityOptionItem[]; } @@ -56,42 +64,20 @@ export const SeverityField = ({ field, idAria, indices, + isDisabled, options, }: SeverityFieldProps) => { - const [isSeverityMappingChecked, setIsSeverityMappingChecked] = useState(false); - const [initialFieldCheck, setInitialFieldCheck] = useState(true); const fieldValueInputWidth = 160; - useEffect(() => { - if ( - !isSeverityMappingChecked && - initialFieldCheck && - (field.value as AboutStepSeverity).mapping?.length > 0 - ) { - setIsSeverityMappingChecked(true); - setInitialFieldCheck(false); - } - }, [ - field, - initialFieldCheck, - isSeverityMappingChecked, - setIsSeverityMappingChecked, - setInitialFieldCheck, - ]); - - const handleFieldChange = useCallback( - (index: number, severity: string, [newField]: IFieldType[]): void => { + const handleFieldValueChange = useCallback( + (newMappingItems: SeverityMapping, index: number): void => { const values = field.value as AboutStepSeverity; field.setValue({ value: values.value, + isMappingChecked: values.isMappingChecked, mapping: [ ...values.mapping.slice(0, index), - { - ...values.mapping[index], - field: newField?.name ?? '', - operator: 'equals', - severity, - }, + ...newMappingItems, ...values.mapping.slice(index + 1), ], }); @@ -99,40 +85,59 @@ export const SeverityField = ({ [field] ); + const handleFieldChange = useCallback( + (index: number, severity: Severity, [newField]: IFieldType[]): void => { + const values = field.value as AboutStepSeverity; + const newMappingItems: SeverityMapping = [ + { + ...values.mapping[index], + field: newField?.name ?? '', + value: newField != null ? values.mapping[index].value : '', + operator: 'equals', + severity, + }, + ]; + handleFieldValueChange(newMappingItems, index); + }, + [field, handleFieldValueChange] + ); + const handleFieldMatchValueChange = useCallback( - (index: number, severity: string, newMatchValue: string): void => { + (index: number, severity: Severity, newMatchValue: string): void => { const values = field.value as AboutStepSeverity; - field.setValue({ - value: values.value, - mapping: [ - ...values.mapping.slice(0, index), - { - ...values.mapping[index], - value: newMatchValue, - operator: 'equals', - severity, - }, - ...values.mapping.slice(index + 1), - ], - }); + const newMappingItems: SeverityMapping = [ + { + ...values.mapping[index], + field: values.mapping[index].field, + value: + values.mapping[index].field != null && values.mapping[index].field !== '' + ? newMatchValue + : '', + operator: 'equals', + severity, + }, + ]; + handleFieldValueChange(newMappingItems, index); }, - [field] + [field, handleFieldValueChange] ); - const selectedState = useMemo(() => { - return ( - (field.value as AboutStepSeverity).mapping?.map((mapping) => { - const [newSelectedField] = indices.fields.filter( - ({ name }) => mapping.field != null && mapping.field === name - ); - return { field: newSelectedField, value: mapping.value }; - }) ?? [] - ); - }, [field.value, indices]); + const getIFieldTypeFromFieldName = ( + fieldName: string | undefined, + iIndexPattern: IIndexPattern + ): IFieldType | undefined => { + const [iFieldType] = iIndexPattern.fields.filter(({ name }) => fieldName === name); + return iFieldType; + }; - const handleSeverityMappingSelected = useCallback(() => { - setIsSeverityMappingChecked(!isSeverityMappingChecked); - }, [isSeverityMappingChecked, setIsSeverityMappingChecked]); + const handleSeverityMappingChecked = useCallback(() => { + const values = field.value as AboutStepSeverity; + field.setValue({ + value: values.value, + mapping: [...values.mapping], + isMappingChecked: !values.isMappingChecked, + }); + }, [field]); const severityLabel = useMemo(() => { return ( @@ -149,12 +154,17 @@ export const SeverityField = ({ const severityMappingLabel = useMemo(() => { return (
      - + {i18n.SEVERITY_MAPPING} @@ -165,7 +175,7 @@ export const SeverityField = ({
      ); - }, [handleSeverityMappingSelected, isSeverityMappingChecked]); + }, [field.value, handleSeverityMappingChecked, isDisabled]); return ( @@ -185,6 +195,7 @@ export const SeverityField = ({ componentProps={{ idAria: 'detectionEngineStepAboutRuleSeverity', 'data-test-subj': 'detectionEngineStepAboutRuleSeverity', + isDisabled, euiFieldProps: { fullWidth: false, disabled: false, @@ -195,12 +206,12 @@ export const SeverityField = ({ - - + {i18n.SEVERITY_MAPPING_DETAILS} ) : ( '' @@ -214,7 +225,7 @@ export const SeverityField = ({ > - {isSeverityMappingChecked && ( + {(field.value as AboutStepSeverity).isMappingChecked && ( @@ -231,53 +242,72 @@ export const SeverityField = ({ - {options.map((option, index) => ( - - - - - + {(field.value as AboutStepSeverity).mapping.map( + (severityMappingItem: SeverityMappingItem, index) => ( + + + + + - - - - - - - - {option.inputDisplay} - - - - ))} + + + + + + + + { + options.find((o) => o.value === severityMappingItem.severity) + ?.inputDisplay + } + + + + ) + )} )} - - + + ); }; diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/default_value.ts b/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/default_value.ts index f5d61553b595b..b9c3e4f84c18e 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/default_value.ts +++ b/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/default_value.ts @@ -5,6 +5,7 @@ */ import { AboutStepRule } from '../../../pages/detection_engine/rules/types'; +import { fillEmptySeverityMappings } from '../../../pages/detection_engine/rules/helpers'; export const threatDefault = [ { @@ -21,8 +22,8 @@ export const stepAboutDefaultValue: AboutStepRule = { isAssociatedToEndpointList: false, isBuildingBlock: false, isNew: true, - severity: { value: 'low', mapping: [] }, - riskScore: { value: 50, mapping: [] }, + severity: { value: 'low', mapping: fillEmptySeverityMappings([]), isMappingChecked: false }, + riskScore: { value: 50, mapping: [], isMappingChecked: false }, references: [''], falsePositives: [''], license: '', diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/index.test.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/index.test.tsx index a86c1b7ce1bea..cb3fd5e5bec32 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/index.test.tsx @@ -16,6 +16,7 @@ import { stepAboutDefaultValue } from './default_value'; // we don't have the types for waitFor just yet, so using "as waitFor" until when we do import { wait as waitFor } from '@testing-library/react'; import { AboutStepRule } from '../../../pages/detection_engine/rules/types'; +import { fillEmptySeverityMappings } from '../../../pages/detection_engine/rules/helpers'; const theme = () => ({ eui: euiDarkVars, darkMode: true }); @@ -176,8 +177,8 @@ describe('StepAboutRuleComponent', () => { name: 'Test name text', note: '', references: [''], - riskScore: { value: 50, mapping: [] }, - severity: { value: 'low', mapping: [] }, + riskScore: { value: 50, mapping: [], isMappingChecked: false }, + severity: { value: 'low', mapping: fillEmptySeverityMappings([]), isMappingChecked: false }, tags: [], threat: [ { @@ -236,8 +237,8 @@ describe('StepAboutRuleComponent', () => { name: 'Test name text', note: '', references: [''], - riskScore: { value: 80, mapping: [] }, - severity: { value: 'low', mapping: [] }, + riskScore: { value: 80, mapping: [], isMappingChecked: false }, + severity: { value: 'low', mapping: fillEmptySeverityMappings([]), isMappingChecked: false }, tags: [], threat: [ { diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/index.tsx index 2ff3b1c50ec4d..fbac453303476 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/index.tsx @@ -75,7 +75,8 @@ const StepAboutRuleComponent: FC = ({ }) => { const [myStepData, setMyStepData] = useState(stepAboutDefaultValue); const [{ isLoading: indexPatternLoading, indexPatterns }] = useFetchIndexPatterns( - defineRuleData?.index ?? [] + defineRuleData?.index ?? [], + 'step_about_rule' ); const canUseExceptions = defineRuleData?.ruleType && diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/schema.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/schema.tsx index fbd03850eee75..20470d7bb924f 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/schema.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/schema.tsx @@ -117,18 +117,16 @@ export const schema: FormSchema = { }, ], }, - mapping: { - type: FIELD_TYPES.TEXT, - }, + mapping: {}, + isMappingChecked: {}, }, riskScore: { value: { type: FIELD_TYPES.RANGE, serializer: (input: string) => Number(input), }, - mapping: { - type: FIELD_TYPES.TEXT, - }, + mapping: {}, + isMappingChecked: {}, }, references: { label: i18n.translate( diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/index.tsx index c7d70684b34cf..1c87cc3c95cd1 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/index.tsx @@ -119,7 +119,7 @@ const StepDefineRuleComponent: FC = ({ }); const [ { browserFields, indexPatterns: indexPatternQueryBar, isLoading: indexPatternLoadingQueryBar }, - ] = useFetchIndexPatterns(myStepData.index); + ] = useFetchIndexPatterns(myStepData.index, 'step_define_rule'); const { form } = useForm({ defaultValue: myStepData, diff --git a/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/auto_download.test.tsx b/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/auto_download.test.tsx new file mode 100644 index 0000000000000..92626f6761c38 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/auto_download.test.tsx @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; +import { mount } from 'enzyme'; + +import { globalNode } from '../../../common/mock'; +import { AutoDownload } from './auto_download'; + +describe.skip('AutoDownload', () => { + beforeEach(() => { + Object.defineProperty(globalNode.window.URL, 'revokeObjectURL', { + configurable: true, + writable: true, + value: jest.fn(), + }); + }); + + it('calls onDownload once if a blob is provided', () => { + const onDownload = jest.fn(); + mount(); + + expect(onDownload).toHaveBeenCalledTimes(1); + }); + + it('does not call onDownload if no blob is provided', () => { + const onDownload = jest.fn(); + mount(); + + expect(onDownload).not.toHaveBeenCalled(); + }); +}); diff --git a/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/auto_download.tsx b/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/auto_download.tsx new file mode 100644 index 0000000000000..9c8280bebe4fd --- /dev/null +++ b/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/auto_download.tsx @@ -0,0 +1,42 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { useEffect, useRef } from 'react'; +import styled from 'styled-components'; + +const InvisibleAnchor = styled.a` + display: none; +`; + +interface AutoDownloadProps { + blob: Blob | undefined; + name?: string; + onDownload?: () => void; +} + +export const AutoDownload: React.FC = ({ blob, name, onDownload }) => { + const anchorRef = useRef(null); + + useEffect(() => { + if (blob && anchorRef?.current) { + if (typeof window.navigator.msSaveOrOpenBlob === 'function') { + window.navigator.msSaveBlob(blob); + } else { + const objectURL = window.URL.createObjectURL(blob); + anchorRef.current.href = objectURL; + anchorRef.current.download = name ?? 'download.txt'; + anchorRef.current.click(); + window.URL.revokeObjectURL(objectURL); + } + + if (onDownload) { + onDownload(); + } + } + }, [blob, name, onDownload]); + + return ; +}; diff --git a/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/modal.test.tsx b/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/modal.test.tsx index 175882de551cb..ff743d1d5090a 100644 --- a/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/modal.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/modal.test.tsx @@ -6,11 +6,38 @@ import React from 'react'; import { mount } from 'enzyme'; +import { act } from 'react-dom/test-utils'; +import { getListResponseMock } from '../../../../../lists/common/schemas/response/list_schema.mock'; +import { exportList, useDeleteList, useFindLists, ListSchema } from '../../../shared_imports'; import { TestProviders } from '../../../common/mock'; import { ValueListsModal } from './modal'; +jest.mock('../../../shared_imports', () => { + const actual = jest.requireActual('../../../shared_imports'); + + return { + ...actual, + exportList: jest.fn(), + useDeleteList: jest.fn(), + useFindLists: jest.fn(), + }; +}); + describe('ValueListsModal', () => { + beforeEach(() => { + // Do not resolve the export in tests as it causes unexpected state updates + (exportList as jest.Mock).mockImplementation(() => new Promise(() => {})); + (useFindLists as jest.Mock).mockReturnValue({ + start: jest.fn(), + result: { data: Array(3).fill(getListResponseMock()), total: 3 }, + }); + (useDeleteList as jest.Mock).mockReturnValue({ + start: jest.fn(), + result: getListResponseMock(), + }); + }); + it('renders nothing if showModal is false', () => { const container = mount( @@ -47,7 +74,7 @@ describe('ValueListsModal', () => { container.unmount(); }); - it('renders ValueListsForm and ValueListsTable', () => { + it('renders ValueListsForm and an EuiTable', () => { const container = mount( @@ -55,7 +82,50 @@ describe('ValueListsModal', () => { ); expect(container.find('ValueListsForm')).toHaveLength(1); - expect(container.find('ValueListsTable')).toHaveLength(1); + expect(container.find('EuiBasicTable')).toHaveLength(1); container.unmount(); }); + + describe('modal table actions', () => { + it('calls exportList when export is clicked', () => { + const container = mount( + + + + ); + + act(() => { + container + .find('button[data-test-subj="action-export-value-list"]') + .first() + .simulate('click'); + container.unmount(); + }); + + expect(exportList).toHaveBeenCalledWith(expect.objectContaining({ listId: 'some-list-id' })); + }); + + it('calls deleteList when delete is clicked', () => { + const deleteListMock = jest.fn(); + (useDeleteList as jest.Mock).mockReturnValue({ + start: deleteListMock, + result: getListResponseMock(), + }); + const container = mount( + + + + ); + + act(() => { + container + .find('button[data-test-subj="action-delete-value-list"]') + .first() + .simulate('click'); + container.unmount(); + }); + + expect(deleteListMock).toHaveBeenCalledWith(expect.objectContaining({ id: 'some-list-id' })); + }); + }); }); diff --git a/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/modal.tsx b/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/modal.tsx index dc72260439090..4921a98b38bd1 100644 --- a/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/modal.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/modal.tsx @@ -6,6 +6,7 @@ import React, { useCallback, useEffect, useState } from 'react'; import { + EuiBasicTable, EuiButton, EuiModal, EuiModalBody, @@ -13,7 +14,9 @@ import { EuiModalHeader, EuiModalHeaderTitle, EuiOverlayMask, + EuiPanel, EuiSpacer, + EuiText, } from '@elastic/eui'; import { @@ -25,10 +28,10 @@ import { } from '../../../shared_imports'; import { useKibana } from '../../../common/lib/kibana'; import { useAppToasts } from '../../../common/hooks/use_app_toasts'; -import { GenericDownloader } from '../../../common/components/generic_downloader'; import * as i18n from './translations'; -import { ValueListsTable } from './table'; +import { buildColumns } from './table_helpers'; import { ValueListsForm } from './form'; +import { AutoDownload } from './auto_download'; interface ValueListsModalProps { onClose: () => void; @@ -45,8 +48,9 @@ export const ValueListsModalComponent: React.FC = ({ const { http } = useKibana().services; const { start: findLists, ...lists } = useFindLists(); const { start: deleteList, result: deleteResult } = useDeleteList(); - const [exportListId, setExportListId] = useState(); const [deletingListIds, setDeletingListIds] = useState([]); + const [exportingListIds, setExportingListIds] = useState([]); + const [exportDownload, setExportDownload] = useState<{ name?: string; blob?: Blob }>({}); const { addError, addSuccess } = useAppToasts(); const fetchLists = useCallback(() => { @@ -62,19 +66,26 @@ export const ValueListsModalComponent: React.FC = ({ ); useEffect(() => { - if (deleteResult != null && deletingListIds.length > 0) { - setDeletingListIds([...deletingListIds.filter((id) => id !== deleteResult.id)]); + if (deleteResult != null) { + setDeletingListIds((ids) => [...ids.filter((id) => id !== deleteResult.id)]); fetchLists(); } - }, [deleteResult, deletingListIds, fetchLists]); + }, [deleteResult, fetchLists]); const handleExport = useCallback( - async ({ ids }: { ids: string[] }) => - exportList({ http, listId: ids[0], signal: new AbortController().signal }), - [http] + async ({ id }: { id: string }) => { + try { + setExportingListIds((ids) => [...ids, id]); + const blob = await exportList({ http, listId: id, signal: new AbortController().signal }); + setExportDownload({ name: id, blob }); + } catch (error) { + addError(error, { title: i18n.EXPORT_ERROR }); + } finally { + setExportingListIds((ids) => [...ids.filter((_id) => _id !== id)]); + } + }, + [addError, http] ); - const handleExportClick = useCallback(({ id }: { id: string }) => setExportListId(id), []); - const handleExportComplete = useCallback(() => setExportListId(undefined), []); const handleTableChange = useCallback( ({ page: { index, size } }: { page: { index: number; size: number } }) => { @@ -121,8 +132,8 @@ export const ValueListsModalComponent: React.FC = ({ const tableItems = (lists.result?.data ?? []).map((item) => ({ ...item, - isExporting: item.id === exportListId, isDeleting: deletingListIds.includes(item.id), + isExporting: exportingListIds.includes(item.id), })); const pagination = { @@ -131,6 +142,7 @@ export const ValueListsModalComponent: React.FC = ({ totalItemCount: lists.result?.total ?? 0, hidePerPageOptions: true, }; + const columns = buildColumns(handleExport, handleDelete); return ( @@ -141,14 +153,19 @@ export const ValueListsModalComponent: React.FC = ({ - + + +

      {i18n.TABLE_TITLE}

      +
      + +
      @@ -156,12 +173,10 @@ export const ValueListsModalComponent: React.FC = ({ - setExportDownload({})} />
      ); diff --git a/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/table.test.tsx b/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/table.test.tsx deleted file mode 100644 index 2724c0a0696b6..0000000000000 --- a/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/table.test.tsx +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React from 'react'; -import { mount } from 'enzyme'; -import { act } from 'react-dom/test-utils'; - -import { getListResponseMock } from '../../../../../lists/common/schemas/response/list_schema.mock'; -import { ListSchema } from '../../../../../lists/common/schemas/response'; -import { TestProviders } from '../../../common/mock'; -import { ValueListsTable } from './table'; -import { TableItem } from './types'; - -const buildItems = (lists: ListSchema[]): TableItem[] => - lists.map((list) => ({ - ...list, - isDeleting: false, - isExporting: false, - })); - -describe('ValueListsTable', () => { - it('renders a row for each list', () => { - const lists = Array(3).fill(getListResponseMock()); - const items = buildItems(lists); - const container = mount( - - - - ); - - expect(container.find('tbody tr')).toHaveLength(3); - }); - - it('calls onChange when pagination is modified', () => { - const lists = Array(6).fill(getListResponseMock()); - const items = buildItems(lists); - const onChange = jest.fn(); - const container = mount( - - - - ); - - act(() => { - container.find('a[data-test-subj="pagination-button-next"]').simulate('click'); - }); - - expect(onChange).toHaveBeenCalledWith( - expect.objectContaining({ page: expect.objectContaining({ index: 1 }) }) - ); - }); - - it('calls onExport when export is clicked', () => { - const lists = Array(3).fill(getListResponseMock()); - const items = buildItems(lists); - const onExport = jest.fn(); - const container = mount( - - - - ); - - act(() => { - container - .find('tbody tr') - .first() - .find('button[data-test-subj="action-export-value-list"]') - .simulate('click'); - }); - - expect(onExport).toHaveBeenCalledWith(expect.objectContaining({ id: 'some-list-id' })); - }); - - it('calls onDelete when delete is clicked', () => { - const lists = Array(3).fill(getListResponseMock()); - const items = buildItems(lists); - const onDelete = jest.fn(); - const container = mount( - - - - ); - - act(() => { - container - .find('tbody tr') - .first() - .find('button[data-test-subj="action-delete-value-list"]') - .simulate('click'); - }); - - expect(onDelete).toHaveBeenCalledWith(expect.objectContaining({ id: 'some-list-id' })); - }); -}); diff --git a/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/table.tsx b/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/table.tsx deleted file mode 100644 index a2e3b73a0abf0..0000000000000 --- a/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/table.tsx +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React from 'react'; -import { EuiBasicTable, EuiText, EuiPanel } from '@elastic/eui'; - -import * as i18n from './translations'; -import { buildColumns } from './table_helpers'; -import { TableProps, TableItemCallback } from './types'; - -export interface ValueListsTableProps { - items: TableProps['items']; - loading: boolean; - onChange: TableProps['onChange']; - onExport: TableItemCallback; - onDelete: TableItemCallback; - pagination: Exclude; -} - -export const ValueListsTableComponent: React.FC = ({ - items, - loading, - onChange, - onExport, - onDelete, - pagination, -}) => { - const columns = buildColumns(onExport, onDelete); - return ( - - -

      {i18n.TABLE_TITLE}

      -
      - -
      - ); -}; - -ValueListsTableComponent.displayName = 'ValueListsTableComponent'; - -export const ValueListsTable = React.memo(ValueListsTableComponent); - -ValueListsTable.displayName = 'ValueListsTable'; diff --git a/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/table_helpers.tsx b/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/table_helpers.tsx index e90d106636e63..bb3a97749a11a 100644 --- a/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/table_helpers.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/table_helpers.tsx @@ -8,40 +8,18 @@ import React from 'react'; import styled from 'styled-components'; -import { EuiButtonIcon, IconType, EuiLoadingSpinner, EuiToolTip } from '@elastic/eui'; +import { EuiButtonIcon, EuiLoadingSpinner, EuiToolTip } from '@elastic/eui'; import { ListSchema } from '../../../../../lists/common/schemas/response'; import { FormattedDate } from '../../../common/components/formatted_date'; import * as i18n from './translations'; -import { TableItem, TableItemCallback, TableProps } from './types'; +import { TableItemCallback, TableProps } from './types'; const AlignedSpinner = styled(EuiLoadingSpinner)` margin: ${({ theme }) => theme.eui.euiSizeXS}; vertical-align: middle; `; -const ActionButton: React.FC<{ - content: string; - dataTestSubj: string; - icon: IconType; - isLoading: boolean; - item: TableItem; - onClick: TableItemCallback; -}> = ({ content, dataTestSubj, icon, item, onClick, isLoading }) => ( - - {isLoading ? ( - - ) : ( - onClick(item)} - /> - )} - -); - export const buildColumns = ( onExport: TableItemCallback, onDelete: TableItemCallback @@ -70,26 +48,34 @@ export const buildColumns = ( actions: [ { render: (item) => ( - + + {item.isExporting ? ( + + ) : ( + onExport(item)} + /> + )} + ), }, { render: (item) => ( - + + {item.isDeleting ? ( + + ) : ( + onDelete(item)} + /> + )} + ), }, ], diff --git a/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/translations.ts b/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/translations.ts index b7b2cae7b0ad6..7063dca2341ca 100644 --- a/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/translations.ts +++ b/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/translations.ts @@ -65,6 +65,10 @@ export const uploadSuccessMessage = (fileName: string) => values: { fileName }, }); +export const EXPORT_ERROR = i18n.translate('xpack.securitySolution.lists.valueListsExportError', { + defaultMessage: 'There was an error exporting the value list.', +}); + export const COLUMN_FILE_NAME = i18n.translate( 'xpack.securitySolution.lists.valueListsTable.fileNameColumn', { diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/fetch_index_patterns.tsx b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/fetch_index_patterns.tsx index c0997a5e62908..82c9292af7451 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/fetch_index_patterns.tsx +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/fetch_index_patterns.tsx @@ -77,7 +77,7 @@ export const useFetchIndexPatterns = ( apolloClient .query({ query: sourceQuery, - fetchPolicy: 'network-only', + fetchPolicy: 'cache-first', variables: { sourceId: 'default', defaultIndex: indices, diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_pre_packaged_rules.tsx b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_pre_packaged_rules.tsx index 08c85695e9313..d82d97883a3d0 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_pre_packaged_rules.tsx +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_pre_packaged_rules.tsx @@ -169,7 +169,9 @@ export const usePrePackagedRules = ({ if ( isSubscribed && ((prePackagedRuleStatusResponse.rules_not_installed === 0 && - prePackagedRuleStatusResponse.rules_not_updated === 0) || + prePackagedRuleStatusResponse.rules_not_updated === 0 && + prePackagedRuleStatusResponse.timelines_not_installed === 0 && + prePackagedRuleStatusResponse.timelines_not_updated === 0) || iterationTryOfFetchingPrePackagedCount > 100) ) { setLoadingCreatePrePackagedRules(false); diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.test.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.test.tsx index 110620fad7eba..982712cbe9797 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.test.tsx @@ -53,6 +53,9 @@ jest.mock('react-router-dom', () => { useHistory: jest.fn(), }; }); +jest.mock('../../components/alerts_info', () => ({ + useAlertInfo: jest.fn().mockReturnValue([]), +})); const state: State = { ...mockGlobalState, diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx index 090fdc4980933..c114e4519df10 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx @@ -36,7 +36,7 @@ import { alertsHistogramOptions } from '../../components/alerts_histogram_panel/ import { useUserInfo } from '../../components/user_info'; import { EVENTS_VIEWER_HEADER_HEIGHT } from '../../../common/components/events_viewer/events_viewer'; import { OverviewEmpty } from '../../../overview/components/overview_empty'; -import { DetectionEngineNoIndex } from './detection_engine_no_signal_index'; +import { DetectionEngineNoIndex } from './detection_engine_no_index'; import { DetectionEngineHeaderPage } from '../../components/detection_engine_header_page'; import { useListsConfig } from '../../containers/detection_engine/lists/use_lists_config'; import { DetectionEngineUserUnauthenticated } from './detection_engine_user_unauthenticated'; @@ -144,7 +144,10 @@ export const DetectionEnginePageComponent: React.FC = ({ return ( - + ); } @@ -156,7 +159,10 @@ export const DetectionEnginePageComponent: React.FC = ({ {indicesExist ? ( - + diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine_no_signal_index.test.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine_no_index.test.tsx similarity index 72% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine_no_signal_index.test.tsx rename to x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine_no_index.test.tsx index 34d55908c9ba1..82d8ee9c63862 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine_no_signal_index.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine_no_index.test.tsx @@ -7,12 +7,14 @@ import React from 'react'; import { shallow } from 'enzyme'; -import { DetectionEngineNoIndex } from './detection_engine_no_signal_index'; +import { DetectionEngineNoIndex } from './detection_engine_no_index'; jest.mock('../../../common/lib/kibana'); describe('DetectionEngineNoIndex', () => { it('renders correctly', () => { - const wrapper = shallow(); + const wrapper = shallow( + + ); expect(wrapper.find('EmptyPage')).toHaveLength(1); }); diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine_no_index.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine_no_index.tsx new file mode 100644 index 0000000000000..648a9405606ef --- /dev/null +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine_no_index.tsx @@ -0,0 +1,53 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { useMemo } from 'react'; + +import { EmptyPage } from '../../../common/components/empty_page'; +import * as i18n from './translations'; +import { useKibana } from '../../../common/lib/kibana'; + +const buildMessage = (needsListsIndex: boolean, needsSignalsIndex: boolean): string => { + if (needsSignalsIndex && needsListsIndex) { + return i18n.NEEDS_INDEX_PERMISSIONS(i18n.NEEDS_SIGNALS_AND_LISTS_INDEXES); + } else if (needsSignalsIndex) { + return i18n.NEEDS_INDEX_PERMISSIONS(i18n.NEEDS_SIGNALS_INDEX); + } else if (needsListsIndex) { + return i18n.NEEDS_INDEX_PERMISSIONS(i18n.NEEDS_LISTS_INDEXES); + } else { + return i18n.NEEDS_INDEX_PERMISSIONS(''); + } +}; + +const DetectionEngineNoIndexComponent: React.FC<{ + needsListsIndex: boolean; + needsSignalsIndex: boolean; +}> = ({ needsListsIndex, needsSignalsIndex }) => { + const docLinks = useKibana().services.docLinks; + const actions = useMemo( + () => ({ + detections: { + icon: 'documents', + label: i18n.GO_TO_DOCUMENTATION, + url: `${docLinks.ELASTIC_WEBSITE_URL}guide/en/security/${docLinks.DOC_LINK_VERSION}/detection-engine-overview.html#detections-permissions`, + target: '_blank', + }, + }), + [docLinks] + ); + const message = buildMessage(needsListsIndex, needsSignalsIndex); + + return ( + + ); +}; + +export const DetectionEngineNoIndex = React.memo(DetectionEngineNoIndexComponent); diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine_no_signal_index.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine_no_signal_index.tsx deleted file mode 100644 index 32ae585aec191..0000000000000 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine_no_signal_index.tsx +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React from 'react'; - -import { EmptyPage } from '../../../common/components/empty_page'; -import * as i18n from './translations'; -import { useKibana } from '../../../common/lib/kibana'; - -export const DetectionEngineNoIndex = React.memo(() => { - const docLinks = useKibana().services.docLinks; - return ( - - ); -}); - -DetectionEngineNoIndex.displayName = 'DetectionEngineNoIndex'; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine_user_unauthenticated.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine_user_unauthenticated.tsx index 6123e3740e306..355898cff0120 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine_user_unauthenticated.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine_user_unauthenticated.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import React from 'react'; +import React, { useMemo } from 'react'; import { EmptyPage } from '../../../common/components/empty_page'; import * as i18n from './translations'; @@ -12,13 +12,20 @@ import { useKibana } from '../../../common/lib/kibana'; export const DetectionEngineUserUnauthenticated = React.memo(() => { const docLinks = useKibana().services.docLinks; - + const actions = useMemo( + () => ({ + detectionUnauthenticated: { + icon: 'documents', + label: i18n.GO_TO_DOCUMENTATION, + url: `${docLinks.ELASTIC_WEBSITE_URL}guide/en/security/${docLinks.DOC_LINK_VERSION}/detection-engine-overview.html#detections-permissions`, + target: '_blank', + }, + }), + [docLinks] + ); return ( ({ license: 'Elastic License', name: 'Query with rule-id', description: '24/7', - severity: { value: 'low', mapping: [] }, - riskScore: { value: 21, mapping: [] }, + riskScore: { value: 21, mapping: [], isMappingChecked: false }, + severity: { value: 'low', mapping: fillEmptySeverityMappings([]), isMappingChecked: false }, references: ['www.test.co'], falsePositives: ['test'], tags: ['tag1', 'tag2'], @@ -241,9 +241,3 @@ export const mockRules: Rule[] = [ mockRule('abe6c564-050d-45a5-aaf0-386c37dd1f61'), mockRule('63f06f34-c181-4b2d-af35-f2ace572a1ee'), ]; - -export const mockExceptionsList: List = { - namespace_type: 'single', - id: '75cd4380-cc5e-11ea-9101-5b34f44aeb44', - type: 'detection', -}; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/helpers.test.ts b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/helpers.test.ts index 6458d2faa2468..4f2055424ca61 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/helpers.test.ts +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/helpers.test.ts @@ -5,9 +5,11 @@ */ import { List } from '../../../../../../common/detection_engine/schemas/types'; -import { ENDPOINT_LIST_ID } from '../../../../../shared_imports'; import { NewRule } from '../../../../containers/detection_engine/rules'; - +import { + getListMock, + getEndpointListMock, +} from '../../../../../../common/detection_engine/schemas/types/lists.mock'; import { DefineStepRuleJson, ScheduleStepRuleJson, @@ -29,19 +31,12 @@ import { } from './helpers'; import { mockDefineStepRule, - mockExceptionsList, mockQueryBar, mockScheduleStepRule, mockAboutStepRule, mockActionsStepRule, } from '../all/__mocks__/mock'; -const ENDPOINT_LIST = { - id: ENDPOINT_LIST_ID, - namespace_type: 'agnostic', - type: 'endpoint', -} as List; - describe('helpers', () => { describe('getTimeTypeValue', () => { test('returns timeObj with value 0 if no time value found', () => { @@ -391,14 +386,12 @@ describe('helpers', () => { }, [] ); - expect(result.exceptions_list).toEqual([ - { id: ENDPOINT_LIST_ID, namespace_type: 'agnostic', type: 'endpoint' }, - ]); + expect(result.exceptions_list).toEqual([getEndpointListMock()]); }); test('returns formatted object with detections exceptions_list', () => { - const result: AboutStepRuleJson = formatAboutStepData(mockData, [mockExceptionsList]); - expect(result.exceptions_list).toEqual([mockExceptionsList]); + const result: AboutStepRuleJson = formatAboutStepData(mockData, [getListMock()]); + expect(result.exceptions_list).toEqual([getListMock()]); }); test('returns formatted object with both exceptions_lists', () => { @@ -407,13 +400,13 @@ describe('helpers', () => { ...mockData, isAssociatedToEndpointList: true, }, - [mockExceptionsList] + [getListMock()] ); - expect(result.exceptions_list).toEqual([ENDPOINT_LIST, mockExceptionsList]); + expect(result.exceptions_list).toEqual([getEndpointListMock(), getListMock()]); }); test('returns formatted object with pre-existing exceptions lists', () => { - const exceptionsLists: List[] = [ENDPOINT_LIST, mockExceptionsList]; + const exceptionsLists: List[] = [getEndpointListMock(), getListMock()]; const result: AboutStepRuleJson = formatAboutStepData( { ...mockData, @@ -425,9 +418,9 @@ describe('helpers', () => { }); test('returns formatted object with pre-existing endpoint exceptions list disabled', () => { - const exceptionsLists: List[] = [ENDPOINT_LIST, mockExceptionsList]; + const exceptionsLists: List[] = [getEndpointListMock(), getListMock()]; const result: AboutStepRuleJson = formatAboutStepData(mockData, exceptionsLists); - expect(result.exceptions_list).toEqual([mockExceptionsList]); + expect(result.exceptions_list).toEqual([getListMock()]); }); test('returns formatted object with empty falsePositive and references filtered out', () => { diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/helpers.ts b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/helpers.ts index a972afbd8c0c5..434a33ac37722 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/helpers.ts +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/helpers.ts @@ -12,6 +12,7 @@ import { NOTIFICATION_THROTTLE_NO_ACTIONS } from '../../../../../../common/const import { transformAlertToRuleAction } from '../../../../../../common/detection_engine/transform_actions'; import { RuleType } from '../../../../../../common/detection_engine/types'; import { isMlRule } from '../../../../../../common/machine_learning/helpers'; +import { isThresholdRule } from '../../../../../../common/detection_engine/utils'; import { List } from '../../../../../../common/detection_engine/schemas/types'; import { ENDPOINT_LIST_ID } from '../../../../../shared_imports'; import { NewRule, Rule } from '../../../../containers/detection_engine/rules'; @@ -57,7 +58,7 @@ export interface RuleFields { } type QueryRuleFields = Omit; type ThresholdRuleFields = Omit; -type MlRuleFields = Omit; +type MlRuleFields = Omit; const isMlFields = ( fields: QueryRuleFields | MlRuleFields | ThresholdRuleFields @@ -69,9 +70,9 @@ const isThresholdFields = ( export const filterRuleFieldsForType = (fields: T, type: RuleType) => { if (isMlRule(type)) { - const { index, queryBar, ...mlRuleFields } = fields; + const { index, queryBar, threshold, ...mlRuleFields } = fields; return mlRuleFields; - } else if (type === 'threshold') { + } else if (isThresholdRule(type)) { const { anomalyThreshold, machineLearningJobId, ...thresholdRuleFields } = fields; return thresholdRuleFields; } else { @@ -176,7 +177,12 @@ export const formatAboutStepData = ( ...(isAssociatedToEndpointList ? { exceptions_list: [ - { id: ENDPOINT_LIST_ID, namespace_type: 'agnostic', type: 'endpoint' }, + { + id: ENDPOINT_LIST_ID, + list_id: ENDPOINT_LIST_ID, + namespace_type: 'agnostic', + type: 'endpoint', + }, ...detectionExceptionLists, ] as AboutStepRuleJson['exceptions_list'], } @@ -188,10 +194,14 @@ export const formatAboutStepData = ( false_positives: falsePositives.filter((item) => !isEmpty(item)), references: references.filter((item) => !isEmpty(item)), risk_score: riskScore.value, - risk_score_mapping: riskScore.mapping, + risk_score_mapping: riskScore.isMappingChecked + ? riskScore.mapping.filter((m) => m.field != null && m.field !== '') + : [], rule_name_override: ruleNameOverride !== '' ? ruleNameOverride : undefined, severity: severity.value, - severity_mapping: severity.mapping, + severity_mapping: severity.isMappingChecked + ? severity.mapping.filter((m) => m.field != null && m.field !== '' && m.value != null) + : [], threat: threat .filter((singleThreat) => singleThreat.tactic.name !== 'none') .map((singleThreat) => ({ diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx index 9c130a7d351fa..789469e981fb4 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx @@ -328,13 +328,13 @@ export const RuleDetailsPageComponent: FC = ({ lists: ExceptionIdentifiers[]; allowedExceptionListTypes: ExceptionListTypeEnum[]; }>( - (acc, { id, namespace_type, type }) => { + (acc, { id, list_id, namespace_type, type }) => { const { allowedExceptionListTypes, lists } = acc; const shouldAddEndpoint = type === ExceptionListTypeEnum.ENDPOINT && !allowedExceptionListTypes.includes(ExceptionListTypeEnum.ENDPOINT); return { - lists: [...lists, { id, namespaceType: namespace_type, type }], + lists: [...lists, { id, listId: list_id, namespaceType: namespace_type, type }], allowedExceptionListTypes: shouldAddEndpoint ? [...allowedExceptionListTypes, ExceptionListTypeEnum.ENDPOINT] : allowedExceptionListTypes, @@ -366,7 +366,10 @@ export const RuleDetailsPageComponent: FC = ({ {indicesExist ? ( - + diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.test.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.test.tsx index c01317e4f48c5..10a20807d6f87 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.test.tsx @@ -13,8 +13,11 @@ import { getActionsStepsData, getHumanizedDuration, getModifiedAboutDetailsData, + getPrePackagedRuleStatus, + getPrePackagedTimelineStatus, determineDetailsValue, userHasNoPermissions, + fillEmptySeverityMappings, } from './helpers'; import { mockRuleWithEverything, mockRule } from './all/__mocks__/mock'; import { esFilters } from '../../../../../../../../src/plugins/data/public'; @@ -95,9 +98,9 @@ describe('rule helpers', () => { name: 'Query with rule-id', note: '# this is some markdown documentation', references: ['www.test.co'], - riskScore: { value: 21, mapping: [] }, + riskScore: { value: 21, mapping: [], isMappingChecked: false }, ruleNameOverride: 'message', - severity: { value: 'low', mapping: [] }, + severity: { value: 'low', mapping: fillEmptySeverityMappings([]), isMappingChecked: false }, tags: ['tag1', 'tag2'], threat: [ { @@ -394,4 +397,138 @@ describe('rule helpers', () => { expect(result).toEqual(userHasNoPermissionsExpectedResult); }); }); + + describe('getPrePackagedRuleStatus', () => { + test('ruleNotInstalled', () => { + const rulesInstalled = 0; + const rulesNotInstalled = 1; + const rulesNotUpdated = 0; + const result: string = getPrePackagedRuleStatus( + rulesInstalled, + rulesNotInstalled, + rulesNotUpdated + ); + + expect(result).toEqual('ruleNotInstalled'); + }); + + test('ruleInstalled', () => { + const rulesInstalled = 1; + const rulesNotInstalled = 0; + const rulesNotUpdated = 0; + const result: string = getPrePackagedRuleStatus( + rulesInstalled, + rulesNotInstalled, + rulesNotUpdated + ); + + expect(result).toEqual('ruleInstalled'); + }); + + test('someRuleUninstall', () => { + const rulesInstalled = 1; + const rulesNotInstalled = 1; + const rulesNotUpdated = 0; + const result: string = getPrePackagedRuleStatus( + rulesInstalled, + rulesNotInstalled, + rulesNotUpdated + ); + + expect(result).toEqual('someRuleUninstall'); + }); + + test('ruleNeedUpdate', () => { + const rulesInstalled = 1; + const rulesNotInstalled = 0; + const rulesNotUpdated = 1; + const result: string = getPrePackagedRuleStatus( + rulesInstalled, + rulesNotInstalled, + rulesNotUpdated + ); + + expect(result).toEqual('ruleNeedUpdate'); + }); + + test('unknown', () => { + const rulesInstalled = null; + const rulesNotInstalled = null; + const rulesNotUpdated = null; + const result: string = getPrePackagedRuleStatus( + rulesInstalled, + rulesNotInstalled, + rulesNotUpdated + ); + + expect(result).toEqual('unknown'); + }); + }); + + describe('getPrePackagedTimelineStatus', () => { + test('timelinesNotInstalled', () => { + const timelinesInstalled = 0; + const timelinesNotInstalled = 1; + const timelinesNotUpdated = 0; + const result: string = getPrePackagedTimelineStatus( + timelinesInstalled, + timelinesNotInstalled, + timelinesNotUpdated + ); + + expect(result).toEqual('timelinesNotInstalled'); + }); + + test('timelinesInstalled', () => { + const timelinesInstalled = 1; + const timelinesNotInstalled = 0; + const timelinesNotUpdated = 0; + const result: string = getPrePackagedTimelineStatus( + timelinesInstalled, + timelinesNotInstalled, + timelinesNotUpdated + ); + + expect(result).toEqual('timelinesInstalled'); + }); + + test('someTimelineUninstall', () => { + const timelinesInstalled = 1; + const timelinesNotInstalled = 1; + const timelinesNotUpdated = 0; + const result: string = getPrePackagedTimelineStatus( + timelinesInstalled, + timelinesNotInstalled, + timelinesNotUpdated + ); + + expect(result).toEqual('someTimelineUninstall'); + }); + + test('timelineNeedUpdate', () => { + const timelinesInstalled = 1; + const timelinesNotInstalled = 0; + const timelinesNotUpdated = 1; + const result: string = getPrePackagedTimelineStatus( + timelinesInstalled, + timelinesNotInstalled, + timelinesNotUpdated + ); + + expect(result).toEqual('timelineNeedUpdate'); + }); + + test('unknown', () => { + const timelinesInstalled = null; + const timelinesNotInstalled = null; + const timelinesNotUpdated = null; + const result: string = getPrePackagedTimelineStatus( + timelinesInstalled, + timelinesNotInstalled, + timelinesNotUpdated + ); + + expect(result).toEqual('unknown'); + }); + }); }); diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx index 1f7b495bad920..1fcfcb4adb5bb 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx @@ -24,6 +24,8 @@ import { ScheduleStepRule, ActionsStepRule, } from './types'; +import { SeverityMapping } from '../../../../../common/detection_engine/schemas/common/schemas'; +import { severityOptions } from '../../../components/rules/step_about_rule/data'; export interface GetStepsData { aboutRuleData: AboutStepRule; @@ -150,18 +152,38 @@ export const getAboutStepsData = (rule: Rule, detailsView: boolean): AboutStepRu references, severity: { value: severity, - mapping: severityMapping, + mapping: fillEmptySeverityMappings(severityMapping), + isMappingChecked: severityMapping.length > 0, }, tags, riskScore: { value: riskScore, mapping: riskScoreMapping, + isMappingChecked: riskScoreMapping.length > 0, }, falsePositives, threat: threat as IMitreEnterpriseAttack[], }; }; +const severitySortMapping = { + low: 0, + medium: 1, + high: 2, + critical: 3, +}; + +export const fillEmptySeverityMappings = (mappings: SeverityMapping): SeverityMapping => { + const missingMappings: SeverityMapping = severityOptions.flatMap((so) => + mappings.find((mapping) => mapping.severity === so.value) == null + ? [{ field: '', value: '', operator: 'equals', severity: so.value }] + : [] + ); + return [...mappings, ...missingMappings].sort( + (a, b) => severitySortMapping[a.severity] - severitySortMapping[b.severity] + ); +}; + export const determineDetailsValue = ( rule: Rule, detailsView: boolean diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/index.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/index.tsx index f49ee8246024a..b6f58ef7045f8 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/index.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { EuiButton, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiToolTip } from '@elastic/eui'; import React, { useCallback, useRef, useState } from 'react'; import { useHistory } from 'react-router-dom'; @@ -204,14 +204,16 @@ const RulesPageComponent: React.FC = () => { )} - - {i18n.UPLOAD_VALUE_LISTS} - + + + {i18n.UPLOAD_VALUE_LISTS} + + + i18n.translate('xpack.securitySolution.detectionEngine.needsIndexPermissionsMessage', { + values: { additionalContext }, + defaultMessage: + 'To use the detection engine, a user with the required cluster and index privileges must first access this page. {additionalContext} For more help, contact your Elastic Stack administrator.', + }); + export const GO_TO_DOCUMENTATION = i18n.translate( 'xpack.securitySolution.detectionEngine.goToDocumentationButton', { diff --git a/x-pack/plugins/security_solution/public/hosts/pages/details/index.tsx b/x-pack/plugins/security_solution/public/hosts/pages/details/index.tsx index 781aa711ff0d9..b6c1727ee6afa 100644 --- a/x-pack/plugins/security_solution/public/hosts/pages/details/index.tsx +++ b/x-pack/plugins/security_solution/public/hosts/pages/details/index.tsx @@ -104,7 +104,10 @@ const HostDetailsComponent = React.memo( {indicesExist ? ( - + diff --git a/x-pack/plugins/security_solution/public/hosts/pages/hosts.tsx b/x-pack/plugins/security_solution/public/hosts/pages/hosts.tsx index 1219effa5ff6d..1d0b73f80a69a 100644 --- a/x-pack/plugins/security_solution/public/hosts/pages/hosts.tsx +++ b/x-pack/plugins/security_solution/public/hosts/pages/hosts.tsx @@ -98,7 +98,10 @@ export const HostsComponent = React.memo( {indicesExist ? ( - + diff --git a/x-pack/plugins/security_solution/public/management/components/management_empty_state.tsx b/x-pack/plugins/security_solution/public/management/components/management_empty_state.tsx index fb9f97f3f7570..a4518d1a1f493 100644 --- a/x-pack/plugins/security_solution/public/management/components/management_empty_state.tsx +++ b/x-pack/plugins/security_solution/public/management/components/management_empty_state.tsx @@ -77,57 +77,6 @@ const PolicyEmptyState = React.memo<{ /> - - - - - - - - -

      - -

      -
      -
      -
      - - - - -
      - - - - - - - -

      - -

      -
      -
      -
      - - - - -
      -
      - [ { title: i18n.translate('xpack.securitySolution.endpoint.hostList.stepOneTitle', { - defaultMessage: 'Select the policy you want to use to protect your hosts', + defaultMessage: 'Select the integration you want to use', }), children: ( <> @@ -203,7 +152,7 @@ const HostsEmptyState = React.memo<{ ) : selectionOptions.length ? ( @@ -211,7 +160,7 @@ const HostsEmptyState = React.memo<{ ) : ( ); }} @@ -263,13 +212,13 @@ const HostsEmptyState = React.memo<{ headerComponent={ } bodyComponent={ } /> diff --git a/x-pack/plugins/security_solution/public/management/components/management_page_view.tsx b/x-pack/plugins/security_solution/public/management/components/management_page_view.tsx index 42341b524362d..aa562b9a20201 100644 --- a/x-pack/plugins/security_solution/public/management/components/management_page_view.tsx +++ b/x-pack/plugins/security_solution/public/management/components/management_page_view.tsx @@ -4,52 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { memo, useMemo } from 'react'; -import { i18n } from '@kbn/i18n'; -import { useParams } from 'react-router-dom'; +import React, { memo } from 'react'; import { PageView, PageViewProps } from '../../common/components/endpoint/page_view'; -import { AdministrationSubTab } from '../types'; -import { SecurityPageName } from '../../app/types'; -import { useFormatUrl } from '../../common/components/link_to'; -import { getHostListPath, getPoliciesPath } from '../common/routing'; -import { useNavigateByRouterEventHandler } from '../../common/hooks/endpoint/use_navigate_by_router_event_handler'; export const ManagementPageView = memo>((options) => { - const { formatUrl, search } = useFormatUrl(SecurityPageName.administration); - const { tabName } = useParams<{ tabName: AdministrationSubTab }>(); - - const goToEndpoint = useNavigateByRouterEventHandler( - getHostListPath({ name: 'hostList' }, search) - ); - - const goToPolicies = useNavigateByRouterEventHandler(getPoliciesPath(search)); - - const tabs = useMemo((): PageViewProps['tabs'] | undefined => { - if (options.viewType === 'details') { - return undefined; - } - return [ - { - name: i18n.translate('xpack.securitySolution.managementTabs.hosts', { - defaultMessage: 'Hosts', - }), - id: AdministrationSubTab.hosts, - isSelected: tabName === AdministrationSubTab.hosts, - href: formatUrl(getHostListPath({ name: 'hostList' })), - onClick: goToEndpoint, - }, - { - name: i18n.translate('xpack.securitySolution.managementTabs.policies', { - defaultMessage: 'Policies', - }), - id: AdministrationSubTab.policies, - isSelected: tabName === AdministrationSubTab.policies, - href: formatUrl(getPoliciesPath()), - onClick: goToPolicies, - }, - ]; - }, [formatUrl, goToEndpoint, goToPolicies, options.viewType, tabName]); - return ; + return ; }); ManagementPageView.displayName = 'ManagementPageView'; diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/host_details.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/host_details.tsx index cea66acbef8ca..109392cb7a929 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/host_details.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/host_details.tsx @@ -121,7 +121,7 @@ export const HostDetails = memo(({ details }: { details: HostMetadata }) => { return [ { title: i18n.translate('xpack.securitySolution.endpoint.host.details.policy', { - defaultMessage: 'Policy', + defaultMessage: 'Integration', }), description: ( <> @@ -136,7 +136,7 @@ export const HostDetails = memo(({ details }: { details: HostMetadata }) => { }, { title: i18n.translate('xpack.securitySolution.endpoint.host.details.policyStatus', { - defaultMessage: 'Policy Status', + defaultMessage: 'Configuration response', }), description: ( { diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/index.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/index.tsx index 71b3885308558..212c8977a8852 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/index.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/index.tsx @@ -158,7 +158,7 @@ const PolicyResponseFlyoutPanel = memo<{

      @@ -167,7 +167,7 @@ const PolicyResponseFlyoutPanel = memo<{ title={ } /> diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx index 47227244b7066..9d49c8705affe 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx @@ -431,7 +431,7 @@ describe('when on the hosts page', () => { const renderResult = render(); const linkToReassign = await renderResult.findByTestId('hostDetailsLinkToIngest'); expect(linkToReassign).not.toBeNull(); - expect(linkToReassign.textContent).toEqual('Reassign Policy'); + expect(linkToReassign.textContent).toEqual('Reassign Configuration'); expect(linkToReassign.getAttribute('href')).toEqual( `/app/ingestManager#/fleet/agents/${agentId}/activity?openReassignFlyout=true` ); @@ -492,7 +492,7 @@ describe('when on the hosts page', () => { it('should include the sub-panel title', async () => { expect( (await renderResult.findByTestId('hostDetailsPolicyResponseFlyoutTitle')).textContent - ).toBe('Policy Response'); + ).toBe('Configuration Response'); }); it('should show a configuration section for each protection', async () => { diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.tsx index e38ef1bd5fe86..2692f7791b7c0 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.tsx @@ -237,7 +237,7 @@ export const HostList = () => { { field: 'metadata.Endpoint.policy.applied', name: i18n.translate('xpack.securitySolution.endpointList.policy', { - defaultMessage: 'Policy', + defaultMessage: 'Integration', }), truncateText: true, // eslint-disable-next-line react/display-name @@ -256,7 +256,7 @@ export const HostList = () => { { field: 'metadata.Endpoint.policy.applied', name: i18n.translate('xpack.securitySolution.endpointList.policyStatus', { - defaultMessage: 'Policy Status', + defaultMessage: 'Configuration Status', }), // eslint-disable-next-line react/display-name render: (policy: HostInfo['metadata']['Endpoint']['policy']['applied'], item: HostInfo) => { diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/index.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/index.tsx index 5122bbcd5d55d..681f1f1430926 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/index.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/index.tsx @@ -6,17 +6,13 @@ import React, { memo } from 'react'; import { Route, Switch } from 'react-router-dom'; -import { PolicyDetails, PolicyList } from './view'; -import { - MANAGEMENT_ROUTING_POLICIES_PATH, - MANAGEMENT_ROUTING_POLICY_DETAILS_PATH, -} from '../../common/constants'; +import { PolicyDetails } from './view'; +import { MANAGEMENT_ROUTING_POLICY_DETAILS_PATH } from '../../common/constants'; import { NotFoundPage } from '../../../app/404'; export const PolicyContainer = memo(() => { return ( - diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/configure_package_config.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/configure_package_config.tsx index 67f24977406c6..2b08bfd2b282b 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/configure_package_config.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/configure_package_config.tsx @@ -6,8 +6,7 @@ import React, { memo, useMemo } from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; -import { EuiCallOut, EuiText, EuiTitle, EuiSpacer } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; +import { EuiCallOut, EuiText, EuiSpacer } from '@elastic/eui'; import { LinkToApp } from '../../../../../common/components/endpoint/link_to_app'; import { CustomConfigurePackageConfigContent, @@ -50,52 +49,37 @@ export const ConfigureEndpointPackageConfig = memo - -

      - -

      -

      {from === 'edit' ? ( - <> - - - - - - + + + + ), + }} + /> ) : ( )}

      diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.test.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.test.tsx index 4f7c14735fe21..6ed4e06ee51c5 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.test.tsx @@ -10,7 +10,7 @@ import { mount } from 'enzyme'; import { PolicyDetails } from './policy_details'; import { EndpointDocGenerator } from '../../../../../common/endpoint/generate_data'; import { AppContextTestRender, createAppRootMockRenderer } from '../../../../common/mock/endpoint'; -import { getPolicyDetailPath, getPoliciesPath } from '../../../common/routing'; +import { getPolicyDetailPath, getHostListPath } from '../../../common/routing'; import { apiPathMockResponseProviders } from '../store/policy_list/test_mock_utils'; jest.mock('../../../../common/components/link_to'); @@ -19,7 +19,7 @@ describe('Policy Details', () => { type FindReactWrapperResponse = ReturnType['find']>; const policyDetailsPathUrl = getPolicyDetailPath('1'); - const policyListPathUrl = getPoliciesPath(); + const hostListPath = getHostListPath({ name: 'hostList' }); const sleep = (ms = 100) => new Promise((wakeup) => setTimeout(wakeup, ms)); const generator = new EndpointDocGenerator(); let history: AppContextTestRender['history']; @@ -127,8 +127,8 @@ describe('Policy Details', () => { const backToListButton = pageHeaderLeft.find('EuiButtonEmpty'); expect(backToListButton.prop('iconType')).toBe('arrowLeft'); - expect(backToListButton.prop('href')).toBe(policyListPathUrl); - expect(backToListButton.text()).toBe('Back to policy list'); + expect(backToListButton.prop('href')).toBe(hostListPath); + expect(backToListButton.text()).toBe('Back to endpoint hosts'); const pageTitle = pageHeaderLeft.find('[data-test-subj="pageViewHeaderLeftTitle"]'); expect(pageTitle).toHaveLength(1); @@ -141,7 +141,7 @@ describe('Policy Details', () => { ); expect(history.location.pathname).toEqual(policyDetailsPathUrl); backToListButton.simulate('click', { button: 0 }); - expect(history.location.pathname).toEqual(policyListPathUrl); + expect(history.location.pathname).toEqual(hostListPath); }); it('should display agent stats', async () => { await asyncActions; @@ -173,7 +173,7 @@ describe('Policy Details', () => { const navigateToAppMockedCalls = coreStart.application.navigateToApp.mock.calls; expect(navigateToAppMockedCalls[navigateToAppMockedCalls.length - 1]).toEqual([ 'securitySolution:administration', - { path: policyListPathUrl }, + { path: hostListPath }, ]); }); it('should display save button', async () => { @@ -232,7 +232,7 @@ describe('Policy Details', () => { ); expect(warningCallout).toHaveLength(1); expect(warningCallout.text()).toEqual( - 'This action will update 5 hostsSaving these changes will apply updates to all endpoints assigned to this policy' + 'This action will update 5 hostsSaving these changes will apply updates to all endpoints assigned to this agent configuration.' ); }); it('should close dialog if cancel button is clicked', () => { diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.tsx index 288bc484c23b5..cd63991dbac93 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.tsx @@ -42,7 +42,7 @@ import { PageViewHeaderTitle } from '../../../../common/components/endpoint/page import { ManagementPageView } from '../../../components/management_page_view'; import { SpyRoute } from '../../../../common/utils/route/spy_routes'; import { SecurityPageName } from '../../../../app/types'; -import { getPoliciesPath } from '../../../common/routing'; +import { getHostListPath } from '../../../common/routing'; import { useFormatUrl } from '../../../../common/components/link_to'; import { useNavigateToAppEventHandler } from '../../../../common/hooks/endpoint/use_navigate_to_app_event_handler'; import { MANAGEMENT_APP_ID } from '../../../common/constants'; @@ -56,7 +56,7 @@ export const PolicyDetails = React.memo(() => { application: { navigateToApp }, }, } = useKibana(); - const { formatUrl, search } = useFormatUrl(SecurityPageName.administration); + const { formatUrl } = useFormatUrl(SecurityPageName.administration); const { state: locationRouteState } = useLocation(); // Store values @@ -70,6 +70,7 @@ export const PolicyDetails = React.memo(() => { const [showConfirm, setShowConfirm] = useState(false); const [routeState, setRouteState] = useState(); const policyName = policyItem?.name ?? ''; + const hostListRouterPath = getHostListPath({ name: 'hostList' }); // Handle showing update statuses useEffect(() => { @@ -87,7 +88,7 @@ export const PolicyDetails = React.memo(() => { @@ -109,11 +110,11 @@ export const PolicyDetails = React.memo(() => { } }, [navigateToApp, notifications.toasts, policyName, policyUpdateStatus, routeState]); - const handleBackToListOnClick = useNavigateByRouterEventHandler(getPoliciesPath()); + const handleBackToListOnClick = useNavigateByRouterEventHandler(hostListRouterPath); const navigateToAppArguments = useMemo((): Parameters => { - return routeState?.onCancelNavigateTo ?? [MANAGEMENT_APP_ID, { path: getPoliciesPath() }]; - }, [routeState?.onCancelNavigateTo]); + return routeState?.onCancelNavigateTo ?? [MANAGEMENT_APP_ID, { path: hostListRouterPath }]; + }, [hostListRouterPath, routeState?.onCancelNavigateTo]); const handleCancelOnClick = useNavigateToAppEventHandler(...navigateToAppArguments); const handleSaveOnClick = useCallback(() => { @@ -162,11 +163,11 @@ export const PolicyDetails = React.memo(() => { iconType="arrowLeft" contentProps={{ style: { paddingLeft: '0' } }} onClick={handleBackToListOnClick} - href={formatUrl(getPoliciesPath(search))} + href={formatUrl(hostListRouterPath)} > {policyItem.name} @@ -306,7 +307,7 @@ const ConfirmUpdate = React.memo<{ >
      diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/malware.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/malware.tsx index dee1e27782e69..84d4bf5355cd9 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/malware.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/malware.tsx @@ -7,9 +7,18 @@ import React, { useCallback, useMemo } from 'react'; import { useDispatch } from 'react-redux'; import styled from 'styled-components'; -import { EuiRadio, EuiSwitch, EuiTitle, EuiSpacer, htmlIdGenerator } from '@elastic/eui'; +import { + EuiRadio, + EuiSwitch, + EuiTitle, + EuiSpacer, + htmlIdGenerator, + EuiCallOut, +} from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; +import { APP_ID } from '../../../../../../../common/constants'; +import { SecurityPageName } from '../../../../../../app/types'; import { Immutable, ProtectionModes } from '../../../../../../../common/endpoint/types'; import { OS, MalwareProtectionOSes } from '../../../types'; @@ -17,6 +26,7 @@ import { ConfigForm } from '../config_form'; import { policyConfig } from '../../../store/policy_details/selectors'; import { usePolicyDetailsSelector } from '../../policy_hooks'; import { clone } from '../../../models/policy_details_config'; +import { LinkToApp } from '../../../../../../common/components/endpoint/link_to_app'; const ProtectionRadioGroup = styled.div` display: flex; @@ -177,6 +187,23 @@ export const MalwareProtections = React.memo(() => { rightCorner={protectionSwitch} > {radioButtons} + + + + + + ), + }} + /> + ); }); diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_list.test.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_list.test.tsx index 047aa6918736e..e35c97698f5cb 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_list.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_list.test.tsx @@ -14,7 +14,8 @@ import { AppAction } from '../../../../common/store/actions'; jest.mock('../../../../common/components/link_to'); -describe('when on the policies page', () => { +// Skipping these test now that the Policy List has been hidden +describe.skip('when on the policies page', () => { let render: () => ReturnType; let history: AppContextTestRender['history']; let store: AppContextTestRender['store']; diff --git a/x-pack/plugins/security_solution/public/network/pages/ip_details/index.tsx b/x-pack/plugins/security_solution/public/network/pages/ip_details/index.tsx index e06f5489a3fc2..42469a4bf29da 100644 --- a/x-pack/plugins/security_solution/public/network/pages/ip_details/index.tsx +++ b/x-pack/plugins/security_solution/public/network/pages/ip_details/index.tsx @@ -90,7 +90,7 @@ export const IPDetailsComponent: React.FC {indicesExist ? ( - + diff --git a/x-pack/plugins/security_solution/public/network/pages/network.tsx b/x-pack/plugins/security_solution/public/network/pages/network.tsx index ca8da4eb711e5..f516f2a2de346 100644 --- a/x-pack/plugins/security_solution/public/network/pages/network.tsx +++ b/x-pack/plugins/security_solution/public/network/pages/network.tsx @@ -106,7 +106,10 @@ const NetworkComponent = React.memo( {indicesExist ? ( - + diff --git a/x-pack/plugins/security_solution/public/overview/components/endpoint_notice/index.tsx b/x-pack/plugins/security_solution/public/overview/components/endpoint_notice/index.tsx index 7170412cb55ad..1d726a7dbd901 100644 --- a/x-pack/plugins/security_solution/public/overview/components/endpoint_notice/index.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/endpoint_notice/index.tsx @@ -33,7 +33,7 @@ export const EndpointNotice = memo<{ onDismiss: () => void }>(({ onDismiss }) => } @@ -49,7 +49,7 @@ export const EndpointNotice = memo<{ onDismiss: () => void }>(({ onDismiss }) => diff --git a/x-pack/plugins/security_solution/public/overview/components/host_overview/endpoint_overview/translations.ts b/x-pack/plugins/security_solution/public/overview/components/host_overview/endpoint_overview/translations.ts index 34e3347b5ff9a..a7f1be3debb83 100644 --- a/x-pack/plugins/security_solution/public/overview/components/host_overview/endpoint_overview/translations.ts +++ b/x-pack/plugins/security_solution/public/overview/components/host_overview/endpoint_overview/translations.ts @@ -9,14 +9,14 @@ import { i18n } from '@kbn/i18n'; export const ENDPOINT_POLICY = i18n.translate( 'xpack.securitySolution.host.details.endpoint.endpointPolicy', { - defaultMessage: 'Endpoint policy', + defaultMessage: 'Integration', } ); export const POLICY_STATUS = i18n.translate( 'xpack.securitySolution.host.details.endpoint.policyStatus', { - defaultMessage: 'Policy status', + defaultMessage: 'Configuration Status', } ); diff --git a/x-pack/plugins/security_solution/public/overview/components/overview_empty/index.test.tsx b/x-pack/plugins/security_solution/public/overview/components/overview_empty/index.test.tsx new file mode 100644 index 0000000000000..2112350278e8e --- /dev/null +++ b/x-pack/plugins/security_solution/public/overview/components/overview_empty/index.test.tsx @@ -0,0 +1,83 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import React from 'react'; +import { shallow, ShallowWrapper } from 'enzyme'; +import { OverviewEmpty } from '.'; +import { useIngestEnabledCheck } from '../../../common/hooks/endpoint/ingest_enabled'; +jest.mock('../../../common/lib/kibana'); +jest.mock('../../../management/pages/endpoint_hosts/view/hooks', () => ({ + useIngestUrl: jest + .fn() + .mockReturnValue({ appId: 'ingestAppId', appPath: 'ingestPath', url: 'ingestUrl' }), +})); + +jest.mock('../../../common/hooks/endpoint/ingest_enabled', () => ({ + useIngestEnabledCheck: jest.fn().mockReturnValue({ allEnabled: true }), +})); + +jest.mock('../../../common/hooks/endpoint/use_navigate_to_app_event_handler', () => ({ + useNavigateToAppEventHandler: jest.fn(), +})); + +describe('OverviewEmpty', () => { + describe('When isIngestEnabled = true', () => { + let wrapper: ShallowWrapper; + beforeAll(() => { + wrapper = shallow(); + }); + + afterAll(() => { + (useIngestEnabledCheck as jest.Mock).mockReset(); + }); + + test('render with correct actions ', () => { + expect(wrapper.find('[data-test-subj="empty-page"]').prop('actions')).toEqual({ + beats: { + description: + 'Lightweight Beats can send data from hundreds or thousands of machines and systems', + fill: false, + label: 'Add data with Beats', + url: '/app/home#/tutorial_directory/security', + }, + elasticAgent: { + description: + 'The Elastic Agent provides a simple, unified way to add monitoring to your hosts.', + fill: false, + label: 'Add data with Elastic Agent', + url: 'ingestUrl', + }, + endpoint: { + description: + 'Protect your hosts with threat prevention, detection, and deep security data visibility.', + fill: false, + label: 'Add Elastic Endpoint Security', + onClick: undefined, + url: '/app/home#/tutorial_directory/security', + }, + }); + }); + }); + + describe('When isIngestEnabled = false', () => { + let wrapper: ShallowWrapper; + beforeAll(() => { + (useIngestEnabledCheck as jest.Mock).mockReturnValue({ allEnabled: false }); + wrapper = shallow(); + }); + + test('render with correct actions ', () => { + expect(wrapper.find('[data-test-subj="empty-page"]').prop('actions')).toEqual({ + beats: { + description: + 'Lightweight Beats can send data from hundreds or thousands of machines and systems', + fill: false, + label: 'Add data with Beats', + url: '/app/home#/tutorial_directory/security', + }, + }); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/overview/components/overview_empty/index.tsx b/x-pack/plugins/security_solution/public/overview/components/overview_empty/index.tsx index 33413be10079e..1d2c6889213f1 100644 --- a/x-pack/plugins/security_solution/public/overview/components/overview_empty/index.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/overview_empty/index.tsx @@ -4,11 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -import React from 'react'; +import React, { useMemo } from 'react'; +import { omit } from 'lodash/fp'; + import { FormattedMessage } from '@kbn/i18n/react'; import { EuiLink } from '@elastic/eui'; import * as i18nCommon from '../../../common/translations'; -import { EmptyPage } from '../../../common/components/empty_page'; +import { EmptyPage, EmptyPageActionsProps } from '../../../common/components/empty_page'; import { useKibana } from '../../../common/lib/kibana'; import { ADD_DATA_PATH } from '../../../../common/constants'; import { useIngestUrl } from '../../../management/pages/endpoint_hosts/view/hooks'; @@ -23,23 +25,45 @@ const OverviewEmptyComponent: React.FC = () => { ); const handleOnClick = useNavigateToAppEventHandler(ingestAppId, { path: ingestPath }); const { allEnabled: isIngestEnabled } = useIngestEnabledCheck(); + const emptyPageActions: EmptyPageActionsProps = useMemo( + () => ({ + elasticAgent: { + label: i18nCommon.EMPTY_ACTION_ELASTIC_AGENT, + url: ingestUrl, + description: i18nCommon.EMPTY_ACTION_ELASTIC_AGENT_DESCRIPTION, + fill: false, + }, + beats: { + label: i18nCommon.EMPTY_ACTION_BEATS, + url: `${basePath}${ADD_DATA_PATH}`, + description: i18nCommon.EMPTY_ACTION_BEATS_DESCRIPTION, + fill: false, + }, + endpoint: { + label: i18nCommon.EMPTY_ACTION_ENDPOINT, + url: `${basePath}${ADD_DATA_PATH}`, + description: i18nCommon.EMPTY_ACTION_ENDPOINT_DESCRIPTION, + onClick: handleOnClick, + fill: false, + }, + }), + [basePath, ingestUrl, handleOnClick] + ); + + const emptyPageIngestDisabledActions = useMemo( + () => omit(['elasticAgent', 'endpoint'], emptyPageActions), + [emptyPageActions] + ); return isIngestEnabled === true ? ( {i18nCommon.EMPTY_ACTION_SECONDARY} @@ -50,16 +74,13 @@ const OverviewEmptyComponent: React.FC = () => { /> ) : ( {i18nCommon.EMPTY_ACTION_SECONDARY} diff --git a/x-pack/plugins/security_solution/public/overview/pages/overview.test.tsx b/x-pack/plugins/security_solution/public/overview/pages/overview.test.tsx index 286cc870378e1..74225c4e4f823 100644 --- a/x-pack/plugins/security_solution/public/overview/pages/overview.test.tsx +++ b/x-pack/plugins/security_solution/public/overview/pages/overview.test.tsx @@ -83,7 +83,7 @@ describe('Overview', () => {
      ); - expect(wrapper.find('[data-test-subj="empty-page-secondary-action"]').exists()).toBe(false); + expect(wrapper.find('[data-test-subj="empty-page-endpoint-action"]').exists()).toBe(false); }); it('shows Endpoint get ready button when ingest is enabled', () => { @@ -95,7 +95,7 @@ describe('Overview', () => {
      ); - expect(wrapper.find('[data-test-subj="empty-page-secondary-action"]').exists()).toBe(true); + expect(wrapper.find('[data-test-subj="empty-page-endpoint-action"]').exists()).toBe(true); }); }); diff --git a/x-pack/plugins/security_solution/public/overview/pages/overview.tsx b/x-pack/plugins/security_solution/public/overview/pages/overview.tsx index 6563f3c2b824d..1b743c259555a 100644 --- a/x-pack/plugins/security_solution/public/overview/pages/overview.tsx +++ b/x-pack/plugins/security_solution/public/overview/pages/overview.tsx @@ -17,6 +17,7 @@ import { SiemSearchBar } from '../../common/components/search_bar'; import { WrapperPage } from '../../common/components/wrapper_page'; import { useGlobalTime } from '../../common/containers/use_global_time'; import { useWithSource } from '../../common/containers/source'; + import { EventsByDataset } from '../components/events_by_dataset'; import { EventCounts } from '../components/event_counts'; import { OverviewEmpty } from '../components/overview_empty'; @@ -66,12 +67,11 @@ const OverviewComponent: React.FC = ({ addMessage('management', 'dismissEndpointNotice'); }, [addMessage]); const { allEnabled: isIngestEnabled } = useIngestEnabledCheck(); - return ( <> {indicesExist ? ( - + diff --git a/x-pack/plugins/security_solution/public/overview/pages/summary.tsx b/x-pack/plugins/security_solution/public/overview/pages/summary.tsx index 0f20e8bea9dc5..d8260858aa245 100644 --- a/x-pack/plugins/security_solution/public/overview/pages/summary.tsx +++ b/x-pack/plugins/security_solution/public/overview/pages/summary.tsx @@ -71,7 +71,7 @@ export const Summary = React.memo(() => { defaultMessage="If you have input or suggestions regarding your experience with Elastic SIEM, please feel free to {feedback}." values={{ feedback: ( - + { - describe('getFriendlyElapsedTime', () => { - const second = 1000; - const minute = second * 60; - const hour = minute * 60; - const day = hour * 24; - const week = day * 7; - const month = day * 30; - const year = day * 365; + const second = 1000; + const minute = second * 60; + const hour = minute * 60; + const day = hour * 24; + const week = day * 7; + const month = day * 30; + const year = day * 365; - const initialTime = new Date('6/1/2020').getTime(); + describe('getUnixTime', () => { + const unixTime = new Date('6/1/2020').getTime(); + const unixStringTime = String(unixTime); + const isoTime = new Date('6/1/2020').toISOString(); + const notATime = 'imLate'; + + it('should return the time if already a unix timestamp', () => { + expect(getUnixTime(unixTime)).toEqual(unixTime); + }); + + it('should properly convert a unix timestamp string to a number', () => { + expect(getUnixTime(unixStringTime)).toEqual(unixTime); + }); + + it('should properly convert an ISO string to a unix timestamp', () => { + expect(getUnixTime(isoTime)).toEqual(unixTime); + }); - const oneMillisecond = new Date(initialTime + 1).getTime(); + it('should return NaN if an invalid time is provided', () => { + expect(getUnixTime(notATime)).toBeNaN(); + }); + }); + + describe('getFriendlyElapsedTime', () => { + const initialTime = new Date('6/1/2020').getTime(); + const oneMillisecond = new Date(initialTime + 1).toISOString(); const oneSecond = new Date(initialTime + 1 * second).getTime(); const oneMinute = new Date(initialTime + 1 * minute).getTime(); - const oneHour = new Date(initialTime + 1 * hour).getTime(); + const oneHour = new Date(initialTime + 1 * hour).toISOString(); const oneDay = new Date(initialTime + 1 * day).getTime(); - const oneWeek = new Date(initialTime + 1 * week).getTime(); + const oneWeek = `${new Date(initialTime + 1 * week).getTime()}`; const oneMonth = new Date(initialTime + 1 * month).getTime(); const oneYear = new Date(initialTime + 1 * year).getTime(); const almostASecond = new Date(initialTime + 999).getTime(); - const almostAMinute = new Date(initialTime + 59.9 * second).getTime(); + const almostAMinute = new Date(initialTime + 59.9 * second).toISOString(); const almostAnHour = new Date(initialTime + 59.9 * minute).getTime(); const almostADay = new Date(initialTime + 23.9 * hour).getTime(); - const almostAWeek = new Date(initialTime + 6.9 * day).getTime(); + const almostAWeek = new Date(initialTime + 6.9 * day).toISOString(); const almostAMonth = new Date(initialTime + 3.9 * week).getTime(); const almostAYear = new Date(initialTime + 11.9 * month).getTime(); const threeYears = new Date(initialTime + 3 * year).getTime(); + it('should return null if invalid times are given', () => { + expect(getFriendlyElapsedTime(initialTime, 'ImTimeless')).toEqual(null); + }); + it('should return the correct singular relative time', () => { expect(getFriendlyElapsedTime(initialTime, initialTime)).toEqual({ duration: '<1', diff --git a/x-pack/plugins/security_solution/public/resolver/lib/date.ts b/x-pack/plugins/security_solution/public/resolver/lib/date.ts index a5e07e6a02a88..3cd0c910f46f3 100644 --- a/x-pack/plugins/security_solution/public/resolver/lib/date.ts +++ b/x-pack/plugins/security_solution/public/resolver/lib/date.ts @@ -6,6 +6,26 @@ import { DurationDetails, DurationTypes } from '../types'; +/** + * Given a time, it will convert it to a unix timestamp if not one already. If it is unable to do so, it will return NaN + */ +export const getUnixTime = (time: number | string): number | typeof NaN => { + if (!time) { + return NaN; + } + if (typeof time === 'number') { + return time; + } + // If it's a date string just get the time in MS + let unixTime = Date.parse(time); + if (Number.isNaN(unixTime)) { + // If not an ISO date string, last check will be if it's a unix timestamp string + unixTime = parseInt(time, 10); + } + + return unixTime; +}; + /* * Given two unix timestamps, it will return an object containing the time difference and properly pluralized friendly version of the time difference. * i.e. a time difference of 1000ms will yield => { duration: 1, durationType: 'second' } and 10000ms will yield => { duration: 10, durationType: 'seconds' } @@ -15,12 +35,13 @@ export const getFriendlyElapsedTime = ( from: number | string, to: number | string ): DurationDetails | null => { - const startTime = typeof from === 'number' ? from : parseInt(from, 10); - const endTime = typeof to === 'number' ? to : parseInt(to, 10); - const elapsedTimeInMs = endTime - startTime; - if (Number.isNaN(elapsedTimeInMs)) { + const startTime = getUnixTime(from); + const endTime = getUnixTime(to); + + if (Number.isNaN(startTime) || Number.isNaN(endTime)) { return null; } + const elapsedTimeInMs = endTime - startTime; const second = 1000; const minute = second * 60; diff --git a/x-pack/plugins/security_solution/public/resolver/models/process_event.ts b/x-pack/plugins/security_solution/public/resolver/models/process_event.ts index 4f8df87b3ac0b..af465c77c4ba8 100644 --- a/x-pack/plugins/security_solution/public/resolver/models/process_event.ts +++ b/x-pack/plugins/security_solution/public/resolver/models/process_event.ts @@ -144,7 +144,7 @@ export function processPath(passedEvent: ResolverEvent): string | undefined { */ export function userInfoForProcess( passedEvent: ResolverEvent -): { user?: string; domain?: string } | undefined { +): { name?: string; domain?: string } | undefined { return passedEvent.user; } diff --git a/x-pack/plugins/security_solution/public/resolver/store/data/selectors.test.ts b/x-pack/plugins/security_solution/public/resolver/store/data/selectors.test.ts index 9e1c396723a27..6786a93f1d9ca 100644 --- a/x-pack/plugins/security_solution/public/resolver/store/data/selectors.test.ts +++ b/x-pack/plugins/security_solution/public/resolver/store/data/selectors.test.ts @@ -13,6 +13,8 @@ import { mockTreeWithNoAncestorsAnd2Children, mockTreeWith2AncestorsAndNoChildren, mockTreeWith1AncestorAnd2ChildrenAndAllNodesHave2GraphableEvents, + mockTreeWithAllProcessesTerminated, + mockTreeWithNoProcessEvents, } from '../mocks/resolver_tree'; import { uniquePidForProcess } from '../../models/process_event'; import { EndpointEvent } from '../../../../common/endpoint/types'; @@ -299,6 +301,34 @@ describe('data state', () => { expect(selectors.ariaFlowtoCandidate(state())(secondAncestorID)).toBe(null); }); }); + describe('with a tree with all processes terminated', () => { + const originID = 'c'; + const firstAncestorID = 'b'; + const secondAncestorID = 'a'; + beforeEach(() => { + actions.push({ + type: 'serverReturnedResolverData', + payload: { + result: mockTreeWithAllProcessesTerminated({ + originID, + firstAncestorID, + secondAncestorID, + }), + // this value doesn't matter + databaseDocumentID: '', + }, + }); + }); + it('should have origin as terminated', () => { + expect(selectors.isProcessTerminated(state())(originID)).toBe(true); + }); + it('should have first ancestor as termianted', () => { + expect(selectors.isProcessTerminated(state())(firstAncestorID)).toBe(true); + }); + it('should have second ancestor as terminated', () => { + expect(selectors.isProcessTerminated(state())(secondAncestorID)).toBe(true); + }); + }); describe('with a tree with 2 children and no ancestors', () => { const originID = 'c'; const firstChildID = 'd'; @@ -379,4 +409,26 @@ describe('data state', () => { expect(selectors.graphableProcesses(state()).length).toBe(4); }); }); + describe('with a tree with no process events', () => { + beforeEach(() => { + const tree = mockTreeWithNoProcessEvents(); + actions.push({ + type: 'serverReturnedResolverData', + payload: { + result: tree, + // this value doesn't matter + databaseDocumentID: '', + }, + }); + }); + it('should return an empty layout', () => { + expect(selectors.layout(state())).toMatchInlineSnapshot(` + Object { + "ariaLevels": Map {}, + "edgeLineSegments": Array [], + "processNodePositions": Map {}, + } + `); + }); + }); }); diff --git a/x-pack/plugins/security_solution/public/resolver/store/data/selectors.ts b/x-pack/plugins/security_solution/public/resolver/store/data/selectors.ts index 1d65b406306a3..10ace895b3267 100644 --- a/x-pack/plugins/security_solution/public/resolver/store/data/selectors.ts +++ b/x-pack/plugins/security_solution/public/resolver/store/data/selectors.ts @@ -105,6 +105,19 @@ export const terminatedProcesses = createSelector(resolverTreeResponse, function ); }); +/** + * A function that given an entity id returns a boolean indicating if the id is in the set of terminated processes. + */ +export const isProcessTerminated = createSelector(terminatedProcesses, function ( + /* eslint-disable no-shadow */ + terminatedProcesses + /* eslint-enable no-shadow */ +) { + return (entityId: string) => { + return terminatedProcesses.has(entityId); + }; +}); + /** * Process events that will be graphed. */ @@ -361,9 +374,9 @@ export const layout = createSelector( // find the origin node const originNode = indexedProcessTreeModel.processEvent(indexedProcessTree, originID); - if (!originNode) { - // this should only happen if the `ResolverTree` from the server has an entity ID with no matching lifecycle events. - throw new Error('Origin node not found in ResolverTree'); + if (originNode === null) { + // If a tree is returned that has no process events for the origin, this can happen. + return taxiLayout; } // Find the position of the origin, we'll center the map on it intrinsically diff --git a/x-pack/plugins/security_solution/public/resolver/store/mocks/endpoint_event.ts b/x-pack/plugins/security_solution/public/resolver/store/mocks/endpoint_event.ts index b58ea73e1fdc7..8f2e0ad3a6d85 100644 --- a/x-pack/plugins/security_solution/public/resolver/store/mocks/endpoint_event.ts +++ b/x-pack/plugins/security_solution/public/resolver/store/mocks/endpoint_event.ts @@ -14,16 +14,18 @@ export function mockEndpointEvent({ name, parentEntityId, timestamp, + lifecycleType, }: { entityID: string; name: string; parentEntityId: string | undefined; timestamp: number; + lifecycleType?: string; }): EndpointEvent { return { '@timestamp': timestamp, event: { - type: 'start', + type: lifecycleType ? lifecycleType : 'start', category: 'process', }, process: { diff --git a/x-pack/plugins/security_solution/public/resolver/store/mocks/resolver_tree.ts b/x-pack/plugins/security_solution/public/resolver/store/mocks/resolver_tree.ts index 2860eec5a6ab6..6a8ab61ccf9b6 100644 --- a/x-pack/plugins/security_solution/public/resolver/store/mocks/resolver_tree.ts +++ b/x-pack/plugins/security_solution/public/resolver/store/mocks/resolver_tree.ts @@ -46,6 +46,69 @@ export function mockTreeWith2AncestorsAndNoChildren({ } as unknown) as ResolverTree; } +export function mockTreeWithAllProcessesTerminated({ + originID, + firstAncestorID, + secondAncestorID, +}: { + secondAncestorID: string; + firstAncestorID: string; + originID: string; +}): ResolverTree { + const secondAncestor: ResolverEvent = mockEndpointEvent({ + entityID: secondAncestorID, + name: 'a', + parentEntityId: 'none', + timestamp: 0, + }); + const firstAncestor: ResolverEvent = mockEndpointEvent({ + entityID: firstAncestorID, + name: 'b', + parentEntityId: secondAncestorID, + timestamp: 1, + }); + const originEvent: ResolverEvent = mockEndpointEvent({ + entityID: originID, + name: 'c', + parentEntityId: firstAncestorID, + timestamp: 2, + }); + const secondAncestorTermination: ResolverEvent = mockEndpointEvent({ + entityID: secondAncestorID, + name: 'a', + parentEntityId: 'none', + timestamp: 0, + lifecycleType: 'end', + }); + const firstAncestorTermination: ResolverEvent = mockEndpointEvent({ + entityID: firstAncestorID, + name: 'b', + parentEntityId: secondAncestorID, + timestamp: 1, + lifecycleType: 'end', + }); + const originEventTermination: ResolverEvent = mockEndpointEvent({ + entityID: originID, + name: 'c', + parentEntityId: firstAncestorID, + timestamp: 2, + lifecycleType: 'end', + }); + return ({ + entityID: originID, + children: { + childNodes: [], + }, + ancestry: { + ancestors: [ + { lifecycle: [secondAncestor, secondAncestorTermination] }, + { lifecycle: [firstAncestor, firstAncestorTermination] }, + ], + }, + lifecycle: [originEvent, originEventTermination], + } as unknown) as ResolverTree; +} + export function mockTreeWithNoAncestorsAnd2Children({ originID, firstChildID, @@ -163,3 +226,33 @@ export function mockTreeWith1AncestorAnd2ChildrenAndAllNodesHave2GraphableEvents lifecycle: [origin, originClone], } as unknown) as ResolverTree; } + +export function mockTreeWithNoProcessEvents(): ResolverTree { + return { + entityID: 'entityID', + children: { + childNodes: [], + nextChild: null, + }, + relatedEvents: { + events: [], + nextEvent: null, + }, + relatedAlerts: { + alerts: [], + nextAlert: null, + }, + lifecycle: [], + ancestry: { + ancestors: [], + nextAncestor: null, + }, + stats: { + totalAlerts: 0, + events: { + total: 0, + byCategory: {}, + }, + }, + }; +} diff --git a/x-pack/plugins/security_solution/public/resolver/store/selectors.ts b/x-pack/plugins/security_solution/public/resolver/store/selectors.ts index 66d7e04d118ed..87ef8d5d095ef 100644 --- a/x-pack/plugins/security_solution/public/resolver/store/selectors.ts +++ b/x-pack/plugins/security_solution/public/resolver/store/selectors.ts @@ -53,6 +53,14 @@ export const userIsPanning = composeSelectors(cameraStateSelector, cameraSelecto */ export const isAnimating = composeSelectors(cameraStateSelector, cameraSelectors.isAnimating); +/** + * Whether or not a given entity id is in the set of termination events. + */ +export const isProcessTerminated = composeSelectors( + dataStateSelector, + dataSelectors.isProcessTerminated +); + /** * Given a nodeID (aka entity_id) get the indexed process event. * Legacy functions take process events instead of nodeID, use this to get diff --git a/x-pack/plugins/security_solution/public/resolver/view/map.tsx b/x-pack/plugins/security_solution/public/resolver/view/map.tsx index 30aa4b63a138d..0ca71c5bf60ce 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/map.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/map.tsx @@ -69,6 +69,7 @@ export const ResolverMap = React.memo(function ({ const activeDescendantId = useSelector(selectors.ariaActiveDescendant); const { colorMap } = useResolverTheme(); const { cleanUpQueryParams } = useResolverQueryParams(); + useEffectOnce(() => { return () => cleanUpQueryParams(); }); diff --git a/x-pack/plugins/security_solution/public/resolver/view/panel.tsx b/x-pack/plugins/security_solution/public/resolver/view/panel.tsx index cb0acdc29ceb1..83d3930065da6 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/panel.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/panel.tsx @@ -162,19 +162,10 @@ const PanelContent = memo(function PanelContent() { return 'processListWithCounts'; }, [uiSelectedEvent, crumbEvent, crumbId, graphableProcessEntityIds]); - const terminatedProcesses = useSelector(selectors.terminatedProcesses); - const processEntityId = uiSelectedEvent ? event.entityId(uiSelectedEvent) : undefined; - const isProcessTerminated = processEntityId ? terminatedProcesses.has(processEntityId) : false; - const panelInstance = useMemo(() => { if (panelToShow === 'processDetails') { return ( - + ); } @@ -213,13 +204,7 @@ const PanelContent = memo(function PanelContent() { ); } // The default 'Event List' / 'List of all processes' view - return ( - - ); + return ; }, [ uiSelectedEvent, crumbEvent, @@ -227,7 +212,6 @@ const PanelContent = memo(function PanelContent() { pushToQueryParams, relatedStatsForIdFromParams, panelToShow, - isProcessTerminated, ]); return <>{panelInstance}; diff --git a/x-pack/plugins/security_solution/public/resolver/view/panels/panel_content_process_detail.tsx b/x-pack/plugins/security_solution/public/resolver/view/panels/panel_content_process_detail.tsx index 5d90cd11d31af..1ae16fd93dbb1 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/panels/panel_content_process_detail.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/panels/panel_content_process_detail.tsx @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import React, { memo, useMemo } from 'react'; +import { useSelector } from 'react-redux'; import { i18n } from '@kbn/i18n'; import { htmlIdGenerator, @@ -15,6 +16,7 @@ import { } from '@elastic/eui'; import styled from 'styled-components'; import { FormattedMessage } from 'react-intl'; +import * as selectors from '../../store/selectors'; import * as event from '../../../../common/endpoint/models/event'; import { CrumbInfo, formatDate, StyledBreadcrumbs } from './panel_content_utilities'; import { @@ -41,16 +43,14 @@ const StyledDescriptionList = styled(EuiDescriptionList)` */ export const ProcessDetails = memo(function ProcessDetails({ processEvent, - isProcessTerminated, - isProcessOrigin, pushToQueryParams, }: { processEvent: ResolverEvent; - isProcessTerminated: boolean; - isProcessOrigin: boolean; pushToQueryParams: (queryStringKeyValuePair: CrumbInfo) => unknown; }) { const processName = event.eventName(processEvent); + const entityId = event.entityId(processEvent); + const isProcessTerminated = useSelector(selectors.isProcessTerminated)(entityId); const processInfoEntry = useMemo(() => { const eventTime = event.eventTimestamp(processEvent); const dateTime = eventTime ? formatDate(eventTime) : ''; @@ -72,12 +72,12 @@ export const ProcessDetails = memo(function ProcessDetails({ const userEntry = { title: 'user.name', - description: (userInfoForProcess(processEvent) as { name: string }).name, + description: userInfoForProcess(processEvent)?.name, }; const domainEntry = { title: 'user.domain', - description: (userInfoForProcess(processEvent) as { domain: string }).domain, + description: userInfoForProcess(processEvent)?.domain, }; const parentPidEntry = { @@ -151,8 +151,8 @@ export const ProcessDetails = memo(function ProcessDetails({ if (!processEvent) { return { descriptionText: '' }; } - return cubeAssetsForNode(isProcessTerminated, isProcessOrigin); - }, [processEvent, cubeAssetsForNode, isProcessTerminated, isProcessOrigin]); + return cubeAssetsForNode(isProcessTerminated, false); + }, [processEvent, cubeAssetsForNode, isProcessTerminated]); const titleId = useMemo(() => htmlIdGenerator('resolverTable')(), []); return ( @@ -161,10 +161,7 @@ export const ProcessDetails = memo(function ProcessDetails({

      - + {processName}

      diff --git a/x-pack/plugins/security_solution/public/resolver/view/panels/panel_content_process_list.tsx b/x-pack/plugins/security_solution/public/resolver/view/panels/panel_content_process_list.tsx index 6f9bfad8c08c2..efb96cde431e5 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/panels/panel_content_process_list.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/panels/panel_content_process_list.tsx @@ -50,12 +50,8 @@ const StyledLimitWarning = styled(LimitWarning)` */ export const ProcessListWithCounts = memo(function ProcessListWithCounts({ pushToQueryParams, - isProcessTerminated, - isProcessOrigin, }: { pushToQueryParams: (queryStringKeyValuePair: CrumbInfo) => unknown; - isProcessTerminated: boolean; - isProcessOrigin: boolean; }) { interface ProcessTableView { name: string; @@ -65,6 +61,7 @@ export const ProcessListWithCounts = memo(function ProcessListWithCounts({ const dispatch = useResolverDispatch(); const { timestamp } = useContext(SideEffectContext); + const isProcessTerminated = useSelector(selectors.isProcessTerminated); const handleBringIntoViewClick = useCallback( (processTableViewItem) => { dispatch({ @@ -92,6 +89,8 @@ export const ProcessListWithCounts = memo(function ProcessListWithCounts({ sortable: true, truncateText: true, render(name: string, item: ProcessTableView) { + const entityId = event.entityId(item.event); + const isTerminated = isProcessTerminated(entityId); return name === '' ? ( {i18n.translate( @@ -108,10 +107,7 @@ export const ProcessListWithCounts = memo(function ProcessListWithCounts({ pushToQueryParams({ crumbId: event.entityId(item.event), crumbEvent: '' }); }} > - + {name} ); @@ -143,7 +139,7 @@ export const ProcessListWithCounts = memo(function ProcessListWithCounts({ }, }, ], - [pushToQueryParams, handleBringIntoViewClick, isProcessOrigin, isProcessTerminated] + [pushToQueryParams, handleBringIntoViewClick, isProcessTerminated] ); const { processNodePositions } = useSelector(selectors.layout); diff --git a/x-pack/plugins/security_solution/public/resolver/view/panels/process_cube_icon.tsx b/x-pack/plugins/security_solution/public/resolver/view/panels/process_cube_icon.tsx index 98eea51a011b6..b073324b27f9b 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/panels/process_cube_icon.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/panels/process_cube_icon.tsx @@ -13,13 +13,11 @@ import { useResolverTheme } from '../assets'; */ export const CubeForProcess = memo(function CubeForProcess({ isProcessTerminated, - isProcessOrigin, }: { isProcessTerminated: boolean; - isProcessOrigin: boolean; }) { const { cubeAssetsForNode } = useResolverTheme(); - const { cubeSymbol, descriptionText } = cubeAssetsForNode(isProcessTerminated, isProcessOrigin); + const { cubeSymbol, descriptionText } = cubeAssetsForNode(isProcessTerminated, false); return ( <> diff --git a/x-pack/plugins/security_solution/public/timelines/components/fields_browser/field_name.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/fields_browser/field_name.test.tsx index ddd5c6f07e8b5..2e48215a89473 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/fields_browser/field_name.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/fields_browser/field_name.test.tsx @@ -28,6 +28,10 @@ const defaultProps = { }; describe('FieldName', () => { + beforeEach(() => { + jest.useFakeTimers(); + }); + test('it renders the field name', () => { const wrapper = mount( @@ -48,6 +52,8 @@ describe('FieldName', () => { ); wrapper.find('[data-test-subj="withHoverActionsButton"]').at(0).simulate('mouseenter'); wrapper.update(); + jest.runAllTimers(); + wrapper.update(); expect(wrapper.find('[data-test-subj="copy-to-clipboard"]').exists()).toBe(true); }); diff --git a/x-pack/plugins/security_solution/public/timelines/components/manage_timeline/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/manage_timeline/index.test.tsx new file mode 100644 index 0000000000000..b918e5abc652b --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/manage_timeline/index.test.tsx @@ -0,0 +1,145 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { renderHook, act } from '@testing-library/react-hooks'; +import { getTimelineDefaults, useTimelineManager, UseTimelineManager } from './'; +import { FilterManager } from '../../../../../../../src/plugins/data/public/query/filter_manager'; +import { coreMock } from '../../../../../../../src/core/public/mocks'; +import { TimelineRowAction } from '../timeline/body/actions'; + +const isStringifiedComparisonEqual = (a: {}, b: {}): boolean => + JSON.stringify(a) === JSON.stringify(b); + +describe('useTimelineManager', () => { + const setupMock = coreMock.createSetup(); + const testId = 'coolness'; + const timelineDefaults = getTimelineDefaults(testId); + const timelineRowActions = () => []; + const mockFilterManager = new FilterManager(setupMock.uiSettings); + beforeEach(() => { + jest.clearAllMocks(); + jest.restoreAllMocks(); + }); + it('initilizes an undefined timeline', async () => { + await act(async () => { + const { result, waitForNextUpdate } = renderHook(() => + useTimelineManager() + ); + await waitForNextUpdate(); + const uninitializedTimeline = result.current.getManageTimelineById(testId); + expect(isStringifiedComparisonEqual(uninitializedTimeline, timelineDefaults)).toBeTruthy(); + }); + }); + it('getIndexToAddById', async () => { + await act(async () => { + const { result, waitForNextUpdate } = renderHook(() => + useTimelineManager() + ); + await waitForNextUpdate(); + const data = result.current.getIndexToAddById(testId); + expect(data).toEqual(timelineDefaults.indexToAdd); + }); + }); + it('setIndexToAdd', async () => { + await act(async () => { + const indexToAddArgs = { id: testId, indexToAdd: ['example'] }; + const { result, waitForNextUpdate } = renderHook(() => + useTimelineManager() + ); + await waitForNextUpdate(); + result.current.initializeTimeline({ + id: testId, + timelineRowActions, + }); + result.current.setIndexToAdd(indexToAddArgs); + const data = result.current.getIndexToAddById(testId); + expect(data).toEqual(indexToAddArgs.indexToAdd); + }); + }); + it('setIsTimelineLoading', async () => { + await act(async () => { + const isLoadingArgs = { id: testId, isLoading: true }; + const { result, waitForNextUpdate } = renderHook(() => + useTimelineManager() + ); + await waitForNextUpdate(); + result.current.initializeTimeline({ + id: testId, + timelineRowActions, + }); + let timeline = result.current.getManageTimelineById(testId); + expect(timeline.isLoading).toBeFalsy(); + result.current.setIsTimelineLoading(isLoadingArgs); + timeline = result.current.getManageTimelineById(testId); + expect(timeline.isLoading).toBeTruthy(); + }); + }); + it('setTimelineRowActions', async () => { + await act(async () => { + const timelineRowActionsEx = () => [ + { id: 'wow', content: 'hey', displayType: 'icon', onClick: () => {} } as TimelineRowAction, + ]; + const { result, waitForNextUpdate } = renderHook(() => + useTimelineManager() + ); + await waitForNextUpdate(); + result.current.initializeTimeline({ + id: testId, + timelineRowActions, + }); + let timeline = result.current.getManageTimelineById(testId); + expect(timeline.timelineRowActions).toEqual(timelineRowActions); + result.current.setTimelineRowActions({ + id: testId, + timelineRowActions: timelineRowActionsEx, + }); + timeline = result.current.getManageTimelineById(testId); + expect(timeline.timelineRowActions).toEqual(timelineRowActionsEx); + }); + }); + it('getTimelineFilterManager undefined on uninitialized', async () => { + await act(async () => { + const { result, waitForNextUpdate } = renderHook(() => + useTimelineManager() + ); + await waitForNextUpdate(); + const data = result.current.getTimelineFilterManager(testId); + expect(data).toEqual(undefined); + }); + }); + it('getTimelineFilterManager defined at initialize', async () => { + await act(async () => { + const { result, waitForNextUpdate } = renderHook(() => + useTimelineManager() + ); + await waitForNextUpdate(); + result.current.initializeTimeline({ + id: testId, + timelineRowActions, + filterManager: mockFilterManager, + }); + const data = result.current.getTimelineFilterManager(testId); + expect(data).toEqual(mockFilterManager); + }); + }); + it('isManagedTimeline returns false when unset and then true when set', async () => { + await act(async () => { + const { result, waitForNextUpdate } = renderHook(() => + useTimelineManager() + ); + await waitForNextUpdate(); + let data = result.current.isManagedTimeline(testId); + expect(data).toBeFalsy(); + result.current.initializeTimeline({ + id: testId, + timelineRowActions, + filterManager: mockFilterManager, + }); + data = result.current.isManagedTimeline(testId); + expect(data).toBeTruthy(); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/timelines/components/manage_timeline/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/manage_timeline/index.tsx index dba8506add0ad..a425f9b49add0 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/manage_timeline/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/manage_timeline/index.tsx @@ -137,7 +137,7 @@ const reducerManageTimeline = ( } }; -interface UseTimelineManager { +export interface UseTimelineManager { getIndexToAddById: (id: string) => string[] | null; getManageTimelineById: (id: string) => ManageTimeline; getTimelineFilterManager: (id: string) => FilterManager | undefined; @@ -152,7 +152,9 @@ interface UseTimelineManager { }) => void; } -const useTimelineManager = (manageTimelineForTesting?: ManageTimelineById): UseTimelineManager => { +export const useTimelineManager = ( + manageTimelineForTesting?: ManageTimelineById +): UseTimelineManager => { const [state, dispatch] = useReducer< (state: ManageTimelineById, action: ActionManageTimeline) => ManageTimelineById >(reducerManageTimeline, manageTimelineForTesting ?? initManageTimeline); @@ -241,12 +243,12 @@ const useTimelineManager = (manageTimelineForTesting?: ManageTimelineById): UseT }; const init = { - getManageTimelineById: (id: string) => getTimelineDefaults(id), getIndexToAddById: (id: string) => null, + getManageTimelineById: (id: string) => getTimelineDefaults(id), getTimelineFilterManager: () => undefined, - setIndexToAdd: () => undefined, - isManagedTimeline: () => false, initializeTimeline: () => noop, + isManagedTimeline: () => false, + setIndexToAdd: () => undefined, setIsTimelineLoading: () => noop, setTimelineRowActions: () => noop, }; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/helpers.test.ts b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/helpers.test.ts index 8ba1a999e2b2a..c8adaa891610a 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/helpers.test.ts +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/helpers.test.ts @@ -6,7 +6,13 @@ import { Ecs } from '../../../../graphql/types'; -import { eventHasNotes, eventIsPinned, getPinTooltip, stringifyEvent } from './helpers'; +import { + eventHasNotes, + eventIsPinned, + getPinTooltip, + stringifyEvent, + isInvestigateInResolverActionEnabled, +} from './helpers'; import { TimelineType } from '../../../../../common/types/timeline'; describe('helpers', () => { @@ -242,4 +248,54 @@ describe('helpers', () => { expect(eventIsPinned({ eventId, pinnedEventIds })).toEqual(false); }); }); + + describe('isInvestigateInResolverActionEnabled', () => { + it('returns false if agent.type does not equal endpoint', () => { + const data: Ecs = { _id: '1', agent: { type: ['blah'] } }; + + expect(isInvestigateInResolverActionEnabled(data)).toBeFalsy(); + }); + + it('returns false if agent.type does not have endpoint in first array index', () => { + const data: Ecs = { _id: '1', agent: { type: ['blah', 'endpoint'] } }; + + expect(isInvestigateInResolverActionEnabled(data)).toBeFalsy(); + }); + + it('returns false if process.entity_id is not defined', () => { + const data: Ecs = { _id: '1', agent: { type: ['endpoint'] } }; + + expect(isInvestigateInResolverActionEnabled(data)).toBeFalsy(); + }); + + it('returns true if agent.type has endpoint in first array index', () => { + const data: Ecs = { + _id: '1', + agent: { type: ['endpoint', 'blah'] }, + process: { entity_id: ['5'] }, + }; + + expect(isInvestigateInResolverActionEnabled(data)).toBeTruthy(); + }); + + it('returns false if multiple entity_ids', () => { + const data: Ecs = { + _id: '1', + agent: { type: ['endpoint', 'blah'] }, + process: { entity_id: ['5', '10'] }, + }; + + expect(isInvestigateInResolverActionEnabled(data)).toBeFalsy(); + }); + + it('returns false if entity_id is an empty string', () => { + const data: Ecs = { + _id: '1', + agent: { type: ['endpoint', 'blah'] }, + process: { entity_id: [''] }, + }; + + expect(isInvestigateInResolverActionEnabled(data)).toBeFalsy(); + }); + }); }); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/helpers.ts b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/helpers.ts index 067cea175c99b..6a5e25632c29b 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/helpers.ts +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/helpers.ts @@ -106,7 +106,8 @@ export const getEventType = (event: Ecs): Omit => { export const isInvestigateInResolverActionEnabled = (ecsData?: Ecs) => { return ( get(['agent', 'type', 0], ecsData) === 'endpoint' && - get(['process', 'entity_id'], ecsData)?.length > 0 + get(['process', 'entity_id'], ecsData)?.length === 1 && + get(['process', 'entity_id', 0], ecsData) !== '' ); }; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/header/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/header/index.test.tsx index e0043f3b232da..e7b0ce7b7428e 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/header/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/header/index.test.tsx @@ -177,7 +177,7 @@ describe('Header', () => { expect( wrapper.find('[data-test-subj="timelineImmutableCallOut"]').first().prop('title') ).toEqual( - 'This timeline is immutable, therefore not allowed to save it within the security application, though you may continue to use the timeline to search and filter security events' + 'This prebuilt timeline template cannot be modified. To make changes, please duplicate this template and make modifications to the duplicate template.' ); }); }); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/header/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/header/index.tsx index 75bfb52f2756b..e50a6ed1e45fe 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/header/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/header/index.tsx @@ -73,7 +73,7 @@ const TimelineHeaderComponent: React.FC = ({ {status === TimelineStatus.immutable && ( ( timelineTitle, ]); - return ( - - {buttonText} - + const button = useMemo( + () => ( + + {buttonText} + + ), + [compact, timelineStatus, handleClick, buttonText] + ); + return timelineStatus === TimelineStatus.draft ? ( + + {button} + + ) : ( + button ); } ); @@ -225,8 +235,8 @@ export const ExistingCase = React.memo( ? i18n.ATTACH_TO_EXISTING_CASE : i18n.ATTACH_TIMELINE_TO_EXISTING_CASE; - return ( - <> + const button = useMemo( + () => ( ( > {buttonText} - + ), + [buttonText, handleClick, timelineStatus, compact] + ); + return timelineStatus === TimelineStatus.draft ? ( + + {button} + + ) : ( + button ); } ); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/translations.ts b/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/translations.ts index 34681d5ed6809..1fc3b7b00f847 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/translations.ts +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/properties/translations.ts @@ -151,6 +151,13 @@ export const ATTACH_TO_EXISTING_CASE = i18n.translate( } ); +export const ATTACH_TIMELINE_TO_CASE_TOOLTIP = i18n.translate( + 'xpack.securitySolution.timeline.properties.attachTimelineToCaseTooltip', + { + defaultMessage: 'Please provide a title for your timeline in order to attach it to a case', + } +); + export const STREAM_LIVE = i18n.translate( 'xpack.securitySolution.timeline.properties.streamLiveButtonLabel', { diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/search_super_select/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/search_super_select/index.tsx index 825d4fe3b29b1..3019a8add4e36 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/search_super_select/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/search_super_select/index.tsx @@ -4,19 +4,41 @@ * you may not use this file except in compliance with the Elastic License. */ -import { EuiInputPopover, EuiSelectableOption, EuiSuperSelect } from '@elastic/eui'; +import { EuiInputPopover, EuiSelectableOption, EuiFieldText } from '@elastic/eui'; import React, { memo, useCallback, useMemo, useState } from 'react'; -import { createGlobalStyle } from 'styled-components'; +import styled from 'styled-components'; import { OpenTimelineResult } from '../../open_timeline/types'; import { SelectableTimeline } from '../selectable_timeline'; import * as i18n from '../translations'; import { TimelineType, TimelineTypeLiteral } from '../../../../../common/types/timeline'; -const SearchTimelineSuperSelectGlobalStyle = createGlobalStyle` - .euiPopover__panel.euiPopover__panel-isOpen.timeline-search-super-select-popover__popoverPanel { - visibility: hidden; - z-index: 0; +const StyledEuiFieldText = styled(EuiFieldText)` + padding-left: 12px; + padding-right: 40px; + + &[readonly] { + cursor: pointer; + background-size: 0 100%; + background-repeat: no-repeat; + + // To match EuiFieldText focus state + &:focus { + background-color: #fff; + background-image: linear-gradient( + to top, + #006bb4, + #006bb4 2px, + transparent 2px, + transparent 100% + ); + background-size: 100% 100%; + } + } + + & + .euiFormControlLayoutIcons { + left: unset; + right: 12px; } `; @@ -29,13 +51,6 @@ interface SearchTimelineSuperSelectProps { onTimelineChange: (timelineTitle: string, timelineId: string | null) => void; } -const basicSuperSelectOptions = [ - { - value: '-1', - inputDisplay: i18n.DEFAULT_TIMELINE_TITLE, - }, -]; - const getBasicSelectableOptions = (timelineId: string) => [ { description: i18n.DEFAULT_TIMELINE_DESCRIPTION, @@ -67,26 +82,15 @@ const SearchTimelineSuperSelectComponent: React.FC ( - ), - [handleOpenPopover, isDisabled, timelineId, timelineTitle] + [handleOpenPopover, isDisabled, timelineTitle] ); const handleGetSelectableOptions = useCallback( @@ -126,7 +130,6 @@ const SearchTimelineSuperSelectComponent: React.FC - ); }; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/selectable_timeline/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/selectable_timeline/index.tsx index ae8bf53090789..7ecbc9a53cb21 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/selectable_timeline/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/selectable_timeline/index.tsx @@ -165,7 +165,7 @@ const SelectableTimelineComponent: React.FC = ({ responsive={false} > - + diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/timeline.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/timeline.tsx index c27af94addeab..a2ee1e56306b5 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/timeline.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/timeline.tsx @@ -286,6 +286,7 @@ export const TimelineComponent: React.FC = ({ filterQuery={combinedQueries!.filterQuery} sortField={timelineQuerySortField} startDate={start} + queryDeduplication="timeline" > {({ events, diff --git a/x-pack/plugins/security_solution/public/timelines/containers/index.tsx b/x-pack/plugins/security_solution/public/timelines/containers/index.tsx index 510d58dbe6a69..562999108b4b0 100644 --- a/x-pack/plugins/security_solution/public/timelines/containers/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/containers/index.tsx @@ -58,6 +58,7 @@ export interface OwnProps extends QueryTemplateProps { sortField: SortField; fields: string[]; startDate: string; + queryDeduplication: string; } type TimelineQueryProps = OwnProps & PropsFromRedux & WithKibanaProps & CustomReduxProps; @@ -93,6 +94,7 @@ class TimelineQueryComponent extends QueryTemplate< sourceId, sortField, startDate, + queryDeduplication, } = this.props; const defaultKibanaIndex = kibana.services.uiSettings.get(DEFAULT_INDEX_KEY); const defaultIndex = @@ -102,7 +104,11 @@ class TimelineQueryComponent extends QueryTemplate< ...(['all', 'alert', 'signal'].includes(eventType) ? indexToAdd : []), ] : indexPattern?.title.split(',') ?? []; - const variables: GetTimelineQuery.Variables = { + // Fun fact: When using this hook multiple times within a component (e.g. add_exception_modal & edit_exception_modal), + // the apolloClient will perform queryDeduplication and prevent the first query from executing. A deep compare is not + // performed on `indices`, so another field must be passed to circumvent this. + // For details, see https://github.com/apollographql/react-apollo/issues/2202 + const variables: GetTimelineQuery.Variables & { queryDeduplication: string } = { fieldRequested: fields, filterQuery: createFilter(filterQuery), sourceId, @@ -116,6 +122,7 @@ class TimelineQueryComponent extends QueryTemplate< defaultIndex, docValueFields: docValueFields ?? [], inspect: isInspected, + queryDeduplication, }; return ( diff --git a/x-pack/plugins/security_solution/server/config.ts b/x-pack/plugins/security_solution/server/config.ts index f7d961ae3ec5c..e2c06ae9f931f 100644 --- a/x-pack/plugins/security_solution/server/config.ts +++ b/x-pack/plugins/security_solution/server/config.ts @@ -29,6 +29,12 @@ export const configSchema = schema.object({ from: schema.string({ defaultValue: 'now-15m' }), to: schema.string({ defaultValue: 'now' }), }), + + /** + * Artifacts Configuration + */ + packagerTaskInterval: schema.string({ defaultValue: '60s' }), + validateArtifactDownloads: schema.boolean({ defaultValue: true }), }); export const createConfig$ = (context: PluginInitializerContext) => diff --git a/x-pack/plugins/security_solution/server/endpoint/config.ts b/x-pack/plugins/security_solution/server/endpoint/config.ts index 908e14468c5c7..6a3644f7aaf71 100644 --- a/x-pack/plugins/security_solution/server/endpoint/config.ts +++ b/x-pack/plugins/security_solution/server/endpoint/config.ts @@ -27,6 +27,12 @@ export const EndpointConfigSchema = schema.object({ from: schema.string({ defaultValue: 'now-15m' }), to: schema.string({ defaultValue: 'now' }), }), + + /** + * Artifacts Configuration + */ + packagerTaskInterval: schema.string({ defaultValue: '60s' }), + validateArtifactDownloads: schema.boolean({ defaultValue: true }), }); export function createConfig$(context: PluginInitializerContext) { diff --git a/x-pack/plugins/security_solution/server/endpoint/ingest_integration.test.ts b/x-pack/plugins/security_solution/server/endpoint/ingest_integration.test.ts index be749b2ebd25a..03999715dfc71 100644 --- a/x-pack/plugins/security_solution/server/endpoint/ingest_integration.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/ingest_integration.test.ts @@ -12,7 +12,6 @@ import { ManifestManagerMockType, } from './services/artifacts/manifest_manager/manifest_manager.mock'; import { getPackageConfigCreateCallback } from './ingest_integration'; -import { ManifestConstants } from './lib/artifacts'; describe('ingest_integration tests ', () => { describe('ingest_integration sanity checks', () => { @@ -30,16 +29,6 @@ describe('ingest_integration tests ', () => { expect(newPolicyConfig.inputs[0]!.config!.policy.value).toEqual(policyConfigFactory()); expect(newPolicyConfig.inputs[0]!.config!.artifact_manifest.value).toEqual({ artifacts: { - 'endpoint-exceptionlist-linux-v1': { - compression_algorithm: 'zlib', - decoded_sha256: 'd801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', - decoded_size: 14, - encoded_sha256: 'f8e6afa1d5662f5b37f83337af774b5785b5b7f1daee08b7b00c2d6813874cda', - encoded_size: 22, - encryption_algorithm: 'none', - relative_url: - '/api/endpoint/artifacts/download/endpoint-exceptionlist-linux-v1/d801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', - }, 'endpoint-exceptionlist-macos-v1': { compression_algorithm: 'zlib', decoded_sha256: 'd801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', @@ -61,7 +50,7 @@ describe('ingest_integration tests ', () => { '/api/endpoint/artifacts/download/endpoint-exceptionlist-windows-v1/d801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', }, }, - manifest_version: 'a9b7ef358a363f327f479e31efc4f228b2277a7fb4d1914ca9b4e7ca9ffcf537', + manifest_version: '1.0.0', schema_version: 'v1', }); }); @@ -70,9 +59,7 @@ describe('ingest_integration tests ', () => { const logger = loggingSystemMock.create().get('ingest_integration.test'); const manifestManager = getManifestManagerMock(); manifestManager.pushArtifacts = jest.fn().mockResolvedValue([new Error('error updating')]); - const lastComputed = await manifestManager.getLastComputedManifest( - ManifestConstants.SCHEMA_VERSION - ); + const lastComputed = await manifestManager.getLastComputedManifest(); const callback = getPackageConfigCreateCallback(logger, manifestManager); const policyConfig = createNewPackageConfigMock(); @@ -90,9 +77,7 @@ describe('ingest_integration tests ', () => { const manifestManager = getManifestManagerMock({ mockType: ManifestManagerMockType.InitialSystemState, }); - const lastComputed = await manifestManager.getLastComputedManifest( - ManifestConstants.SCHEMA_VERSION - ); + const lastComputed = await manifestManager.getLastComputedManifest(); expect(lastComputed).toEqual(null); manifestManager.buildNewManifest = jest.fn().mockRejectedValue(new Error('abcd')); @@ -107,9 +92,7 @@ describe('ingest_integration tests ', () => { test('subsequent policy creations succeed', async () => { const logger = loggingSystemMock.create().get('ingest_integration.test'); const manifestManager = getManifestManagerMock(); - const lastComputed = await manifestManager.getLastComputedManifest( - ManifestConstants.SCHEMA_VERSION - ); + const lastComputed = await manifestManager.getLastComputedManifest(); manifestManager.buildNewManifest = jest.fn().mockResolvedValue(lastComputed); // no diffs const callback = getPackageConfigCreateCallback(logger, manifestManager); diff --git a/x-pack/plugins/security_solution/server/endpoint/ingest_integration.ts b/x-pack/plugins/security_solution/server/endpoint/ingest_integration.ts index 11d4b12d0b76a..695267f322857 100644 --- a/x-pack/plugins/security_solution/server/endpoint/ingest_integration.ts +++ b/x-pack/plugins/security_solution/server/endpoint/ingest_integration.ts @@ -10,7 +10,7 @@ import { factory as policyConfigFactory } from '../../common/endpoint/models/pol import { NewPolicyData } from '../../common/endpoint/types'; import { ManifestManager } from './services/artifacts'; import { Manifest } from './lib/artifacts'; -import { reportErrors, ManifestConstants } from './lib/artifacts/common'; +import { reportErrors } from './lib/artifacts/common'; import { InternalArtifactCompleteSchema } from './schemas/artifacts'; import { manifestDispatchSchema } from '../../common/endpoint/schema/manifest'; @@ -18,14 +18,14 @@ const getManifest = async (logger: Logger, manifestManager: ManifestManager): Pr let manifest: Manifest | null = null; try { - manifest = await manifestManager.getLastComputedManifest(ManifestConstants.SCHEMA_VERSION); + manifest = await manifestManager.getLastComputedManifest(); // If we have not yet computed a manifest, then we have to do so now. This should only happen // once. if (manifest == null) { // New computed manifest based on current state of exception list - const newManifest = await manifestManager.buildNewManifest(ManifestConstants.SCHEMA_VERSION); - const diffs = newManifest.diff(Manifest.getDefault(ManifestConstants.SCHEMA_VERSION)); + const newManifest = await manifestManager.buildNewManifest(); + const diffs = newManifest.diff(Manifest.getDefault()); // Compress new artifacts const adds = diffs.filter((diff) => diff.type === 'add').map((diff) => diff.id); @@ -63,7 +63,7 @@ const getManifest = async (logger: Logger, manifestManager: ManifestManager): Pr logger.error(err); } - return manifest ?? Manifest.getDefault(ManifestConstants.SCHEMA_VERSION); + return manifest ?? Manifest.getDefault(); }; /** diff --git a/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/common.ts b/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/common.ts index 7298a9bfa72a6..7f90aa7b91063 100644 --- a/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/common.ts +++ b/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/common.ts @@ -13,13 +13,11 @@ import { export const ArtifactConstants = { GLOBAL_ALLOWLIST_NAME: 'endpoint-exceptionlist', SAVED_OBJECT_TYPE: 'endpoint:user-artifact', - SUPPORTED_OPERATING_SYSTEMS: ['linux', 'macos', 'windows'], - SCHEMA_VERSION: 'v1', + SUPPORTED_OPERATING_SYSTEMS: ['macos', 'windows'], }; export const ManifestConstants = { SAVED_OBJECT_TYPE: 'endpoint:user-artifact-manifest', - SCHEMA_VERSION: 'v1', }; export const getArtifactId = (artifact: InternalArtifactSchema) => { diff --git a/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/lists.test.ts b/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/lists.test.ts index bb8b4fb3d5ce7..fea3b2b9a4526 100644 --- a/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/lists.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/lists.test.ts @@ -314,21 +314,23 @@ describe('buildEventTypeSignal', () => { test('it should convert the exception lists response to the proper endpoint format while paging', async () => { // The first call returns two exceptions const first = getFoundExceptionListItemSchemaMock(); + first.per_page = 2; + first.total = 4; first.data.push(getExceptionListItemSchemaMock()); // The second call returns two exceptions const second = getFoundExceptionListItemSchemaMock(); + second.per_page = 2; + second.total = 4; second.data.push(getExceptionListItemSchemaMock()); - // The third call returns no exceptions, paging stops - const third = getFoundExceptionListItemSchemaMock(); - third.data = []; mockExceptionClient.findExceptionListItem = jest .fn() .mockReturnValueOnce(first) - .mockReturnValueOnce(second) - .mockReturnValueOnce(third); + .mockReturnValueOnce(second); + const resp = await getFullEndpointExceptionList(mockExceptionClient, 'linux', 'v1'); + // Expect 2 exceptions, the first two calls returned the same exception list items expect(resp.entries.length).toEqual(2); }); diff --git a/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/lists.ts b/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/lists.ts index 5998a88527f2f..e41781dd605a0 100644 --- a/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/lists.ts +++ b/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/lists.ts @@ -79,10 +79,10 @@ export async function getFullEndpointExceptionList( schemaVersion: string ): Promise { const exceptions: WrappedTranslatedExceptionList = { entries: [] }; - let numResponses = 0; let page = 1; + let paging = true; - do { + while (paging) { const response = await eClient.findExceptionListItem({ listId: ENDPOINT_LIST_ID, namespaceType: 'agnostic', @@ -94,17 +94,16 @@ export async function getFullEndpointExceptionList( }); if (response?.data !== undefined) { - numResponses = response.data.length; - exceptions.entries = exceptions.entries.concat( translateToEndpointExceptions(response, schemaVersion) ); + paging = (page - 1) * 100 + response.data.length < response.total; page++; } else { break; } - } while (numResponses > 0); + } const [validated, errors] = validate(exceptions, wrappedTranslatedExceptionList); if (errors != null) { diff --git a/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/manifest.test.ts b/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/manifest.test.ts index 95587c6fc105d..3d70f7266277f 100644 --- a/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/manifest.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/manifest.test.ts @@ -6,7 +6,7 @@ import { ManifestSchemaVersion } from '../../../../common/endpoint/schema/common'; import { InternalArtifactCompleteSchema } from '../../schemas'; -import { ManifestConstants, getArtifactId } from './common'; +import { getArtifactId } from './common'; import { Manifest } from './manifest'; import { getMockArtifacts, @@ -30,29 +30,21 @@ describe('manifest', () => { }); test('Can create manifest with valid schema version', () => { - const manifest = new Manifest('v1'); + const manifest = new Manifest(); expect(manifest).toBeInstanceOf(Manifest); }); test('Cannot create manifest with invalid schema version', () => { expect(() => { - new Manifest('abcd' as ManifestSchemaVersion); + new Manifest({ + schemaVersion: 'abcd' as ManifestSchemaVersion, + }); }).toThrow(); }); test('Empty manifest transforms correctly to expected endpoint format', async () => { expect(emptyManifest.toEndpointFormat()).toStrictEqual({ artifacts: { - 'endpoint-exceptionlist-linux-v1': { - compression_algorithm: 'zlib', - encryption_algorithm: 'none', - decoded_sha256: 'd801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', - encoded_sha256: 'f8e6afa1d5662f5b37f83337af774b5785b5b7f1daee08b7b00c2d6813874cda', - decoded_size: 14, - encoded_size: 22, - relative_url: - '/api/endpoint/artifacts/download/endpoint-exceptionlist-linux-v1/d801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', - }, 'endpoint-exceptionlist-macos-v1': { compression_algorithm: 'zlib', encryption_algorithm: 'none', @@ -74,7 +66,7 @@ describe('manifest', () => { '/api/endpoint/artifacts/download/endpoint-exceptionlist-windows-v1/d801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', }, }, - manifest_version: 'a9b7ef358a363f327f479e31efc4f228b2277a7fb4d1914ca9b4e7ca9ffcf537', + manifest_version: '1.0.0', schema_version: 'v1', }); }); @@ -82,16 +74,6 @@ describe('manifest', () => { test('Manifest transforms correctly to expected endpoint format', async () => { expect(manifest1.toEndpointFormat()).toStrictEqual({ artifacts: { - 'endpoint-exceptionlist-linux-v1': { - compression_algorithm: 'zlib', - encryption_algorithm: 'none', - decoded_sha256: '96b76a1a911662053a1562ac14c4ff1e87c2ff550d6fe52e1e0b3790526597d3', - encoded_sha256: '975382ab55d019cbab0bbac207a54e2a7d489fad6e8f6de34fc6402e5ef37b1e', - decoded_size: 432, - encoded_size: 147, - relative_url: - '/api/endpoint/artifacts/download/endpoint-exceptionlist-linux-v1/96b76a1a911662053a1562ac14c4ff1e87c2ff550d6fe52e1e0b3790526597d3', - }, 'endpoint-exceptionlist-macos-v1': { compression_algorithm: 'zlib', encryption_algorithm: 'none', @@ -113,15 +95,16 @@ describe('manifest', () => { '/api/endpoint/artifacts/download/endpoint-exceptionlist-windows-v1/96b76a1a911662053a1562ac14c4ff1e87c2ff550d6fe52e1e0b3790526597d3', }, }, - manifest_version: 'a7f4760bfa2662e85e30fe4fb8c01b4c4a20938c76ab21d3c5a3e781e547cce7', + manifest_version: '1.0.0', schema_version: 'v1', }); }); test('Manifest transforms correctly to expected saved object format', async () => { expect(manifest1.toSavedObject()).toStrictEqual({ + schemaVersion: 'v1', + semanticVersion: '1.0.0', ids: [ - 'endpoint-exceptionlist-linux-v1-96b76a1a911662053a1562ac14c4ff1e87c2ff550d6fe52e1e0b3790526597d3', 'endpoint-exceptionlist-macos-v1-96b76a1a911662053a1562ac14c4ff1e87c2ff550d6fe52e1e0b3790526597d3', 'endpoint-exceptionlist-windows-v1-96b76a1a911662053a1562ac14c4ff1e87c2ff550d6fe52e1e0b3790526597d3', ], @@ -133,12 +116,12 @@ describe('manifest', () => { expect(diffs).toEqual([ { id: - 'endpoint-exceptionlist-linux-v1-96b76a1a911662053a1562ac14c4ff1e87c2ff550d6fe52e1e0b3790526597d3', + 'endpoint-exceptionlist-macos-v1-96b76a1a911662053a1562ac14c4ff1e87c2ff550d6fe52e1e0b3790526597d3', type: 'delete', }, { id: - 'endpoint-exceptionlist-linux-v1-0a5a2013a79f9e60682472284a1be45ab1ff68b9b43426d00d665016612c15c8', + 'endpoint-exceptionlist-macos-v1-0a5a2013a79f9e60682472284a1be45ab1ff68b9b43426d00d665016612c15c8', type: 'add', }, ]); @@ -154,7 +137,6 @@ describe('manifest', () => { const entries = manifest1.getEntries(); const keys = Object.keys(entries); expect(keys).toEqual([ - 'endpoint-exceptionlist-linux-v1-96b76a1a911662053a1562ac14c4ff1e87c2ff550d6fe52e1e0b3790526597d3', 'endpoint-exceptionlist-macos-v1-96b76a1a911662053a1562ac14c4ff1e87c2ff550d6fe52e1e0b3790526597d3', 'endpoint-exceptionlist-windows-v1-96b76a1a911662053a1562ac14c4ff1e87c2ff550d6fe52e1e0b3790526597d3', ]); @@ -168,13 +150,8 @@ describe('manifest', () => { }); test('Manifest can be created from list of artifacts', async () => { - const oldManifest = new Manifest(ManifestConstants.SCHEMA_VERSION); - const manifest = Manifest.fromArtifacts(artifacts, 'v1', oldManifest); - expect( - manifest.contains( - 'endpoint-exceptionlist-linux-v1-96b76a1a911662053a1562ac14c4ff1e87c2ff550d6fe52e1e0b3790526597d3' - ) - ).toEqual(true); + const oldManifest = new Manifest(); + const manifest = Manifest.fromArtifacts(artifacts, oldManifest); expect( manifest.contains( 'endpoint-exceptionlist-macos-v1-96b76a1a911662053a1562ac14c4ff1e87c2ff550d6fe52e1e0b3790526597d3' diff --git a/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/manifest.ts b/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/manifest.ts index 6ece2bf0f48e8..9e0e940ea9a1d 100644 --- a/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/manifest.ts +++ b/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/manifest.ts @@ -3,8 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ - -import { createHash } from 'crypto'; +import semver from 'semver'; import { validate } from '../../../../common/validate'; import { InternalArtifactSchema, @@ -13,13 +12,15 @@ import { InternalArtifactCompleteSchema, } from '../../schemas/artifacts'; import { - manifestSchemaVersion, ManifestSchemaVersion, + SemanticVersion, + semanticVersion, } from '../../../../common/endpoint/schema/common'; -import { ManifestSchema, manifestSchema } from '../../../../common/endpoint/schema/manifest'; +import { manifestSchema, ManifestSchema } from '../../../../common/endpoint/schema/manifest'; import { ManifestEntry } from './manifest_entry'; import { maybeCompressArtifact, isCompressed } from './lists'; import { getArtifactId } from './common'; +import { ManifestVersion, manifestVersion } from '../../schemas/artifacts/manifest'; export interface ManifestDiff { type: string; @@ -28,37 +29,39 @@ export interface ManifestDiff { export class Manifest { private entries: Record; - private schemaVersion: ManifestSchemaVersion; - - // For concurrency control - private version: string | undefined; + private version: ManifestVersion; - constructor(schemaVersion: string, version?: string) { + constructor(version?: Partial) { this.entries = {}; - this.version = version; - const [validated, errors] = validate( - (schemaVersion as unknown) as object, - manifestSchemaVersion - ); + const decodedVersion = { + schemaVersion: version?.schemaVersion ?? 'v1', + semanticVersion: version?.semanticVersion ?? '1.0.0', + soVersion: version?.soVersion, + }; + const [validated, errors] = validate(decodedVersion, manifestVersion); if (errors != null || validated === null) { - throw new Error(`Invalid manifest schema version: ${schemaVersion}`); + throw new Error(errors ?? 'Invalid version format.'); } - this.schemaVersion = validated; + this.version = validated; } - public static getDefault(schemaVersion: string) { - return new Manifest(schemaVersion); + public static getDefault(schemaVersion?: ManifestSchemaVersion) { + return new Manifest({ schemaVersion, semanticVersion: '1.0.0' }); } public static fromArtifacts( artifacts: InternalArtifactCompleteSchema[], - schemaVersion: string, - oldManifest: Manifest + oldManifest: Manifest, + schemaVersion?: ManifestSchemaVersion ): Manifest { - const manifest = new Manifest(schemaVersion, oldManifest.getSoVersion()); + const manifest = new Manifest({ + schemaVersion, + semanticVersion: oldManifest.getSemanticVersion(), + soVersion: oldManifest.getSavedObjectVersion(), + }); artifacts.forEach((artifact) => { const id = getArtifactId(artifact); const existingArtifact = oldManifest.getArtifact(id); @@ -71,25 +74,12 @@ export class Manifest { return manifest; } - public static fromPkgConfig(manifestPkgConfig: ManifestSchema): Manifest | null { - if (manifestSchema.is(manifestPkgConfig)) { - const manifest = new Manifest(manifestPkgConfig.schema_version); - for (const [identifier, artifactRecord] of Object.entries(manifestPkgConfig.artifacts)) { - const artifact = { - identifier, - compressionAlgorithm: artifactRecord.compression_algorithm, - encryptionAlgorithm: artifactRecord.encryption_algorithm, - decodedSha256: artifactRecord.decoded_sha256, - decodedSize: artifactRecord.decoded_size, - encodedSha256: artifactRecord.encoded_sha256, - encodedSize: artifactRecord.encoded_size, - }; - manifest.addEntry(artifact); - } - return manifest; - } else { - return null; + public bumpSemanticVersion() { + const newSemanticVersion = semver.inc(this.getSemanticVersion(), 'patch'); + if (!semanticVersion.is(newSemanticVersion)) { + throw new Error(`Invalid semver: ${newSemanticVersion}`); } + this.version.semanticVersion = newSemanticVersion; } public async compressArtifact(id: string): Promise { @@ -112,30 +102,16 @@ export class Manifest { return null; } - public equals(manifest: Manifest): boolean { - return this.getSha256() === manifest.getSha256(); - } - - public getSha256(): string { - let sha256 = createHash('sha256'); - Object.keys(this.entries) - .sort() - .forEach((docId) => { - sha256 = sha256.update(docId); - }); - return sha256.digest('hex'); - } - public getSchemaVersion(): ManifestSchemaVersion { - return this.schemaVersion; + return this.version.schemaVersion; } - public getSoVersion(): string | undefined { - return this.version; + public getSavedObjectVersion(): string | undefined { + return this.version.soVersion; } - public setSoVersion(version: string) { - this.version = version; + public getSemanticVersion(): SemanticVersion { + return this.version.semanticVersion; } public addEntry(artifact: InternalArtifactSchema) { @@ -179,8 +155,8 @@ export class Manifest { public toEndpointFormat(): ManifestSchema { const manifestObj: ManifestSchema = { - manifest_version: this.getSha256(), - schema_version: this.schemaVersion, + manifest_version: this.getSemanticVersion(), + schema_version: this.getSchemaVersion(), artifacts: {}, }; @@ -198,7 +174,9 @@ export class Manifest { public toSavedObject(): InternalManifestSchema { return { - ids: Object.keys(this.entries), + ids: Object.keys(this.getEntries()), + schemaVersion: this.getSchemaVersion(), + semanticVersion: this.getSemanticVersion(), }; } } diff --git a/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/mocks.ts b/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/mocks.ts index 0ec6cb2bd61b3..62fff4715b562 100644 --- a/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/mocks.ts +++ b/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/mocks.ts @@ -29,7 +29,7 @@ export const getMockArtifactsWithDiff = async (opts?: { compress: boolean }) => return Promise.all( ArtifactConstants.SUPPORTED_OPERATING_SYSTEMS.map>( async (os) => { - if (os === 'linux') { + if (os === 'macos') { return getInternalArtifactMockWithDiffs(os, 'v1'); } return getInternalArtifactMock(os, 'v1', opts); @@ -49,21 +49,21 @@ export const getEmptyMockArtifacts = async (opts?: { compress: boolean }) => { }; export const getMockManifest = async (opts?: { compress: boolean }) => { - const manifest = new Manifest('v1'); + const manifest = new Manifest(); const artifacts = await getMockArtifacts(opts); artifacts.forEach((artifact) => manifest.addEntry(artifact)); return manifest; }; export const getMockManifestWithDiffs = async (opts?: { compress: boolean }) => { - const manifest = new Manifest('v1'); + const manifest = new Manifest(); const artifacts = await getMockArtifactsWithDiff(opts); artifacts.forEach((artifact) => manifest.addEntry(artifact)); return manifest; }; export const getEmptyMockManifest = async (opts?: { compress: boolean }) => { - const manifest = new Manifest('v1'); + const manifest = new Manifest(); const artifacts = await getEmptyMockArtifacts(opts); artifacts.forEach((artifact) => manifest.addEntry(artifact)); return manifest; @@ -74,16 +74,6 @@ export const createPackageConfigWithInitialManifestMock = (): PackageConfig => { packageConfig.inputs[0].config!.artifact_manifest = { value: { artifacts: { - 'endpoint-exceptionlist-linux-v1': { - compression_algorithm: 'zlib', - encryption_algorithm: 'none', - decoded_sha256: 'd801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', - encoded_sha256: 'f8e6afa1d5662f5b37f83337af774b5785b5b7f1daee08b7b00c2d6813874cda', - decoded_size: 14, - encoded_size: 22, - relative_url: - '/api/endpoint/artifacts/download/endpoint-exceptionlist-linux-v1/d801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', - }, 'endpoint-exceptionlist-macos-v1': { compression_algorithm: 'zlib', encryption_algorithm: 'none', @@ -105,7 +95,7 @@ export const createPackageConfigWithInitialManifestMock = (): PackageConfig => { '/api/endpoint/artifacts/download/endpoint-exceptionlist-windows-v1/d801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', }, }, - manifest_version: 'a9b7ef358a363f327f479e31efc4f228b2277a7fb4d1914ca9b4e7ca9ffcf537', + manifest_version: '1.0.0', schema_version: 'v1', }, }; @@ -117,16 +107,6 @@ export const createPackageConfigWithManifestMock = (): PackageConfig => { packageConfig.inputs[0].config!.artifact_manifest = { value: { artifacts: { - 'endpoint-exceptionlist-linux-v1': { - compression_algorithm: 'zlib', - encryption_algorithm: 'none', - decoded_sha256: '0a5a2013a79f9e60682472284a1be45ab1ff68b9b43426d00d665016612c15c8', - encoded_sha256: '57941169bb2c5416f9bd7224776c8462cb9a2be0fe8b87e6213e77a1d29be824', - decoded_size: 292, - encoded_size: 131, - relative_url: - '/api/endpoint/artifacts/download/endpoint-exceptionlist-linux-v1/0a5a2013a79f9e60682472284a1be45ab1ff68b9b43426d00d665016612c15c8', - }, 'endpoint-exceptionlist-macos-v1': { compression_algorithm: 'zlib', encryption_algorithm: 'none', @@ -148,7 +128,7 @@ export const createPackageConfigWithManifestMock = (): PackageConfig => { '/api/endpoint/artifacts/download/endpoint-exceptionlist-windows-v1/96b76a1a911662053a1562ac14c4ff1e87c2ff550d6fe52e1e0b3790526597d3', }, }, - manifest_version: '520f6cf88b3f36a065c6ca81058d5f8690aadadf6fe857f8dec4cc37589e7283', + manifest_version: '1.0.1', schema_version: 'v1', }, }; diff --git a/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/saved_object_mappings.ts b/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/saved_object_mappings.ts index 0fb433df95de3..734304516e37e 100644 --- a/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/saved_object_mappings.ts +++ b/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/saved_object_mappings.ts @@ -55,7 +55,13 @@ export const manifestSavedObjectMappings: SavedObjectsType['mappings'] = { type: 'date', index: false, }, - // array of doc ids + schemaVersion: { + type: 'keyword', + }, + semanticVersion: { + type: 'keyword', + index: false, + }, ids: { type: 'keyword', index: false, diff --git a/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/task.test.ts b/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/task.test.ts index daa8a7dd83ee0..32d58da5c3b78 100644 --- a/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/task.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/task.test.ts @@ -38,7 +38,7 @@ describe('task', () => { taskManager: mockTaskManagerSetup, }); const mockTaskManagerStart = taskManagerMock.createStart(); - manifestTask.start({ taskManager: mockTaskManagerStart }); + await manifestTask.start({ taskManager: mockTaskManagerStart }); expect(mockTaskManagerStart.ensureScheduled).toHaveBeenCalled(); }); diff --git a/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/task.ts b/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/task.ts index ba164059866ea..4f2dbdf7644e2 100644 --- a/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/task.ts +++ b/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/task.ts @@ -3,7 +3,6 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ - import { Logger } from 'src/core/server'; import { ConcreteTaskInstance, @@ -11,7 +10,7 @@ import { TaskManagerStartContract, } from '../../../../../task_manager/server'; import { EndpointAppContext } from '../../types'; -import { reportErrors, ManifestConstants } from './common'; +import { reportErrors } from './common'; import { InternalArtifactCompleteSchema } from '../../schemas/artifacts'; export const ManifestTaskConstants = { @@ -45,7 +44,23 @@ export class ManifestTask { createTaskRunner: ({ taskInstance }: { taskInstance: ConcreteTaskInstance }) => { return { run: async () => { + const taskInterval = (await this.endpointAppContext.config()).packagerTaskInterval; await this.runTask(taskInstance.id); + const nextRun = new Date(); + if (taskInterval.endsWith('s')) { + const seconds = parseInt(taskInterval.slice(0, -1), 10); + nextRun.setSeconds(nextRun.getSeconds() + seconds); + } else if (taskInterval.endsWith('m')) { + const minutes = parseInt(taskInterval.slice(0, -1), 10); + nextRun.setMinutes(nextRun.getMinutes() + minutes); + } else { + this.logger.error(`Invalid task interval: ${taskInterval}`); + return; + } + return { + state: {}, + runAt: nextRun, + }; }, cancel: async () => {}, }; @@ -61,7 +76,7 @@ export class ManifestTask { taskType: ManifestTaskConstants.TYPE, scope: ['securitySolution'], schedule: { - interval: '60s', + interval: (await this.endpointAppContext.config()).packagerTaskInterval, }, state: {}, params: { version: ManifestTaskConstants.VERSION }, @@ -92,19 +107,14 @@ export class ManifestTask { try { // Last manifest we computed, which was saved to ES - const oldManifest = await manifestManager.getLastComputedManifest( - ManifestConstants.SCHEMA_VERSION - ); + const oldManifest = await manifestManager.getLastComputedManifest(); if (oldManifest == null) { this.logger.debug('User manifest not available yet.'); return; } // New computed manifest based on current state of exception list - const newManifest = await manifestManager.buildNewManifest( - ManifestConstants.SCHEMA_VERSION, - oldManifest - ); + const newManifest = await manifestManager.buildNewManifest(oldManifest); const diffs = newManifest.diff(oldManifest); // Compress new artifacts @@ -131,6 +141,7 @@ export class ManifestTask { // Commit latest manifest state, if different if (diffs.length) { + newManifest.bumpSemanticVersion(); const error = await manifestManager.commit(newManifest); if (error) { throw error; diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/artifacts/download_exception_list.ts b/x-pack/plugins/security_solution/server/endpoint/routes/artifacts/download_exception_list.ts index 38e900c4d5015..d825841f1e257 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/artifacts/download_exception_list.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/artifacts/download_exception_list.ts @@ -3,7 +3,6 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ - import { IRouter, SavedObjectsClientContract, @@ -14,7 +13,6 @@ import { import LRU from 'lru-cache'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { authenticateAgentWithAccessToken } from '../../../../../ingest_manager/server/services/agents/authenticate'; -import { validate } from '../../../../common/validate'; import { LIMITED_CONCURRENCY_ENDPOINT_ROUTE_TAG } from '../../../../common/endpoint/constants'; import { buildRouteValidation } from '../../../utils/build_validation/route_validation'; import { ArtifactConstants } from '../../lib/artifacts'; @@ -63,6 +61,7 @@ export function registerDownloadExceptionListRoute( } } + const validateDownload = (await endpointContext.config()).validateArtifactDownloads; const buildAndValidateResponse = (artName: string, body: Buffer): IKibanaResponse => { const artifact: HttpResponseOptions = { body, @@ -72,11 +71,10 @@ export function registerDownloadExceptionListRoute( }, }; - const [validated, errors] = validate(artifact, downloadArtifactResponseSchema); - if (errors !== null || validated === null) { - return res.internalError({ body: errors! }); + if (validateDownload && !downloadArtifactResponseSchema.is(artifact)) { + return res.internalError({ body: 'Artifact failed to validate.' }); } else { - return res.ok((validated as unknown) as HttpResponseOptions); + return res.ok(artifact); } }; diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/entity.ts b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/entity.ts index ae91201646103..c79bcda71de9b 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/entity.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/entity.ts @@ -70,6 +70,13 @@ export function handleEntities(): RequestHandler implements MSearchQuer } private buildQuery(ids: string | string[]): { query: JsonObject; index: string | string[] } { - const idsArray = ResolverQuery.createIdsArray(ids); + // only accept queries for entity_ids that are not an empty string + const idsArray = ResolverQuery.createIdsArray(ids).filter((id) => id !== ''); if (this.endpointID) { return { query: this.legacyQuery(this.endpointID, idsArray), index: legacyEventIndexPattern }; } diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/queries/children.ts b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/queries/children.ts index 7fd3808662baa..d99533e23f2c2 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/queries/children.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/queries/children.ts @@ -74,6 +74,18 @@ export class ChildrenQuery extends ResolverQuery { ], }, }, + { + exists: { + field: 'process.entity_id', + }, + }, + { + bool: { + must_not: { + term: { 'process.entity_id': '' }, + }, + }, + }, { term: { 'event.category': 'process' }, }, diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/utils/children_helper.test.ts b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/utils/children_helper.test.ts index ca5b5aef0f651..01dd59b2611d9 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/utils/children_helper.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/utils/children_helper.test.ts @@ -10,12 +10,12 @@ import { TreeNode, } from '../../../../../common/endpoint/generate_data'; import { ChildrenNodesHelper } from './children_helper'; -import { eventId, isProcessStart } from '../../../../../common/endpoint/models/event'; +import { eventId, isStart } from '../../../../../common/endpoint/models/event'; function getStartEvents(events: Event[]): Event[] { const startEvents: Event[] = []; for (const event of events) { - if (isProcessStart(event)) { + if (isStart(event)) { startEvents.push(event); } } diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/utils/children_helper.ts b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/utils/children_helper.ts index 01e356682ac47..d3ca7a54c16d2 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/utils/children_helper.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/utils/children_helper.ts @@ -7,7 +7,7 @@ import { entityId, parentEntityId, - isProcessStart, + isStart, getAncestryAsArray, } from '../../../../../common/endpoint/models/event'; import { @@ -99,7 +99,7 @@ export class ChildrenNodesHelper { for (const event of startEvents) { const parentID = parentEntityId(event); const entityID = entityId(event); - if (parentID && entityID && isProcessStart(event)) { + if (parentID && entityID && isStart(event)) { // don't actually add the start event to the node, because that'll be done in // a different call const childNode = this.getOrCreateChildNode(entityID); diff --git a/x-pack/plugins/security_solution/server/endpoint/schemas/artifacts/manifest.ts b/x-pack/plugins/security_solution/server/endpoint/schemas/artifacts/manifest.ts new file mode 100644 index 0000000000000..707d4c1374fe2 --- /dev/null +++ b/x-pack/plugins/security_solution/server/endpoint/schemas/artifacts/manifest.ts @@ -0,0 +1,23 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as t from 'io-ts'; +import { manifestSchemaVersion, semanticVersion } from '../../../../common/endpoint/schema/common'; + +const optionalVersions = t.partial({ + soVersion: t.string, +}); + +export const manifestVersion = t.intersection([ + optionalVersions, + t.exact( + t.type({ + schemaVersion: manifestSchemaVersion, + semanticVersion, + }) + ), +]); +export type ManifestVersion = t.TypeOf; diff --git a/x-pack/plugins/security_solution/server/endpoint/schemas/artifacts/saved_objects.mock.ts b/x-pack/plugins/security_solution/server/endpoint/schemas/artifacts/saved_objects.mock.ts index d95627601a183..ae565f785c399 100644 --- a/x-pack/plugins/security_solution/server/endpoint/schemas/artifacts/saved_objects.mock.ts +++ b/x-pack/plugins/security_solution/server/endpoint/schemas/artifacts/saved_objects.mock.ts @@ -53,4 +53,6 @@ export const getInternalArtifactMockWithDiffs = async ( export const getInternalManifestMock = (): InternalManifestSchema => ({ ids: [], + schemaVersion: 'v1', + semanticVersion: '1.0.0', }); diff --git a/x-pack/plugins/security_solution/server/endpoint/schemas/artifacts/saved_objects.ts b/x-pack/plugins/security_solution/server/endpoint/schemas/artifacts/saved_objects.ts index 4dea916dcb436..56f247b65d802 100644 --- a/x-pack/plugins/security_solution/server/endpoint/schemas/artifacts/saved_objects.ts +++ b/x-pack/plugins/security_solution/server/endpoint/schemas/artifacts/saved_objects.ts @@ -9,8 +9,10 @@ import { compressionAlgorithm, encryptionAlgorithm, identifier, + semanticVersion, sha256, size, + manifestSchemaVersion, } from '../../../../common/endpoint/schema/common'; import { created } from './common'; @@ -58,6 +60,8 @@ export type InternalArtifactCreateSchema = t.TypeOf; diff --git a/x-pack/plugins/security_solution/server/endpoint/services/artifacts/manifest_client.ts b/x-pack/plugins/security_solution/server/endpoint/services/artifacts/manifest_client.ts index 385f115e6301a..e55243f0650a5 100644 --- a/x-pack/plugins/security_solution/server/endpoint/services/artifacts/manifest_client.ts +++ b/x-pack/plugins/security_solution/server/endpoint/services/artifacts/manifest_client.ts @@ -3,7 +3,6 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ - import { SavedObject, SavedObjectsClientContract, diff --git a/x-pack/plugins/security_solution/server/endpoint/services/artifacts/manifest_manager/manifest_manager.test.ts b/x-pack/plugins/security_solution/server/endpoint/services/artifacts/manifest_manager/manifest_manager.test.ts index c838f772fb66b..d99d6a959d7aa 100644 --- a/x-pack/plugins/security_solution/server/endpoint/services/artifacts/manifest_manager/manifest_manager.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/services/artifacts/manifest_manager/manifest_manager.test.ts @@ -16,22 +16,17 @@ describe('manifest_manager', () => { describe('ManifestManager sanity checks', () => { test('ManifestManager can retrieve and diff manifests', async () => { const manifestManager = getManifestManagerMock(); - const oldManifest = await manifestManager.getLastComputedManifest( - ManifestConstants.SCHEMA_VERSION - ); - const newManifest = await manifestManager.buildNewManifest( - ManifestConstants.SCHEMA_VERSION, - oldManifest! - ); + const oldManifest = await manifestManager.getLastComputedManifest(); + const newManifest = await manifestManager.buildNewManifest(oldManifest!); expect(newManifest.diff(oldManifest!)).toEqual([ { id: - 'endpoint-exceptionlist-linux-v1-96b76a1a911662053a1562ac14c4ff1e87c2ff550d6fe52e1e0b3790526597d3', + 'endpoint-exceptionlist-macos-v1-96b76a1a911662053a1562ac14c4ff1e87c2ff550d6fe52e1e0b3790526597d3', type: 'delete', }, { id: - 'endpoint-exceptionlist-linux-v1-0a5a2013a79f9e60682472284a1be45ab1ff68b9b43426d00d665016612c15c8', + 'endpoint-exceptionlist-macos-v1-0a5a2013a79f9e60682472284a1be45ab1ff68b9b43426d00d665016612c15c8', type: 'add', }, ]); @@ -40,23 +35,18 @@ describe('manifest_manager', () => { test('ManifestManager populates cache properly', async () => { const cache = new LRU({ max: 10, maxAge: 1000 * 60 * 60 }); const manifestManager = getManifestManagerMock({ cache }); - const oldManifest = await manifestManager.getLastComputedManifest( - ManifestConstants.SCHEMA_VERSION - ); - const newManifest = await manifestManager.buildNewManifest( - ManifestConstants.SCHEMA_VERSION, - oldManifest! - ); + const oldManifest = await manifestManager.getLastComputedManifest(); + const newManifest = await manifestManager.buildNewManifest(oldManifest!); const diffs = newManifest.diff(oldManifest!); expect(diffs).toEqual([ { id: - 'endpoint-exceptionlist-linux-v1-96b76a1a911662053a1562ac14c4ff1e87c2ff550d6fe52e1e0b3790526597d3', + 'endpoint-exceptionlist-macos-v1-96b76a1a911662053a1562ac14c4ff1e87c2ff550d6fe52e1e0b3790526597d3', type: 'delete', }, { id: - 'endpoint-exceptionlist-linux-v1-0a5a2013a79f9e60682472284a1be45ab1ff68b9b43426d00d665016612c15c8', + 'endpoint-exceptionlist-macos-v1-0a5a2013a79f9e60682472284a1be45ab1ff68b9b43426d00d665016612c15c8', type: 'add', }, ]); @@ -104,13 +94,8 @@ describe('manifest_manager', () => { test('ManifestManager cannot dispatch incomplete (uncompressed) artifact', async () => { const packageConfigService = createPackageConfigServiceMock(); const manifestManager = getManifestManagerMock({ packageConfigService }); - const oldManifest = await manifestManager.getLastComputedManifest( - ManifestConstants.SCHEMA_VERSION - ); - const newManifest = await manifestManager.buildNewManifest( - ManifestConstants.SCHEMA_VERSION, - oldManifest! - ); + const oldManifest = await manifestManager.getLastComputedManifest(); + const newManifest = await manifestManager.buildNewManifest(oldManifest!); const dispatchErrors = await manifestManager.tryDispatch(newManifest); expect(dispatchErrors.length).toEqual(1); expect(dispatchErrors[0].message).toEqual('Invalid manifest'); @@ -119,17 +104,14 @@ describe('manifest_manager', () => { test('ManifestManager can dispatch manifest', async () => { const packageConfigService = createPackageConfigServiceMock(); const manifestManager = getManifestManagerMock({ packageConfigService }); - const oldManifest = await manifestManager.getLastComputedManifest( - ManifestConstants.SCHEMA_VERSION - ); - const newManifest = await manifestManager.buildNewManifest( - ManifestConstants.SCHEMA_VERSION, - oldManifest! - ); + const oldManifest = await manifestManager.getLastComputedManifest(); + const newManifest = await manifestManager.buildNewManifest(oldManifest!); const diffs = newManifest.diff(oldManifest!); const newArtifactId = diffs[1].id; await newManifest.compressArtifact(newArtifactId); + newManifest.bumpSemanticVersion(); + const dispatchErrors = await manifestManager.tryDispatch(newManifest); expect(dispatchErrors).toEqual([]); @@ -140,10 +122,10 @@ describe('manifest_manager', () => { expect( packageConfigService.update.mock.calls[0][2].inputs[0].config!.artifact_manifest.value ).toEqual({ - manifest_version: '520f6cf88b3f36a065c6ca81058d5f8690aadadf6fe857f8dec4cc37589e7283', + manifest_version: '1.0.1', schema_version: 'v1', artifacts: { - 'endpoint-exceptionlist-linux-v1': { + 'endpoint-exceptionlist-macos-v1': { compression_algorithm: 'zlib', encryption_algorithm: 'none', decoded_sha256: '0a5a2013a79f9e60682472284a1be45ab1ff68b9b43426d00d665016612c15c8', @@ -151,17 +133,7 @@ describe('manifest_manager', () => { decoded_size: 292, encoded_size: 131, relative_url: - '/api/endpoint/artifacts/download/endpoint-exceptionlist-linux-v1/0a5a2013a79f9e60682472284a1be45ab1ff68b9b43426d00d665016612c15c8', - }, - 'endpoint-exceptionlist-macos-v1': { - compression_algorithm: 'zlib', - encryption_algorithm: 'none', - decoded_sha256: '96b76a1a911662053a1562ac14c4ff1e87c2ff550d6fe52e1e0b3790526597d3', - encoded_sha256: '975382ab55d019cbab0bbac207a54e2a7d489fad6e8f6de34fc6402e5ef37b1e', - decoded_size: 432, - encoded_size: 147, - relative_url: - '/api/endpoint/artifacts/download/endpoint-exceptionlist-macos-v1/96b76a1a911662053a1562ac14c4ff1e87c2ff550d6fe52e1e0b3790526597d3', + '/api/endpoint/artifacts/download/endpoint-exceptionlist-macos-v1/0a5a2013a79f9e60682472284a1be45ab1ff68b9b43426d00d665016612c15c8', }, 'endpoint-exceptionlist-windows-v1': { compression_algorithm: 'zlib', @@ -180,17 +152,14 @@ describe('manifest_manager', () => { test('ManifestManager fails to dispatch on conflict', async () => { const packageConfigService = createPackageConfigServiceMock(); const manifestManager = getManifestManagerMock({ packageConfigService }); - const oldManifest = await manifestManager.getLastComputedManifest( - ManifestConstants.SCHEMA_VERSION - ); - const newManifest = await manifestManager.buildNewManifest( - ManifestConstants.SCHEMA_VERSION, - oldManifest! - ); + const oldManifest = await manifestManager.getLastComputedManifest(); + const newManifest = await manifestManager.buildNewManifest(oldManifest!); const diffs = newManifest.diff(oldManifest!); const newArtifactId = diffs[1].id; await newManifest.compressArtifact(newArtifactId); + newManifest.bumpSemanticVersion(); + packageConfigService.update.mockRejectedValueOnce({ status: 409 }); const dispatchErrors = await manifestManager.tryDispatch(newManifest); expect(dispatchErrors).toEqual([{ status: 409 }]); @@ -202,13 +171,8 @@ describe('manifest_manager', () => { savedObjectsClient, }); - const oldManifest = await manifestManager.getLastComputedManifest( - ManifestConstants.SCHEMA_VERSION - ); - const newManifest = await manifestManager.buildNewManifest( - ManifestConstants.SCHEMA_VERSION, - oldManifest! - ); + const oldManifest = await manifestManager.getLastComputedManifest(); + const newManifest = await manifestManager.buildNewManifest(oldManifest!); const diffs = newManifest.diff(oldManifest!); const oldArtifactId = diffs[0].id; const newArtifactId = diffs[1].id; diff --git a/x-pack/plugins/security_solution/server/endpoint/services/artifacts/manifest_manager/manifest_manager.ts b/x-pack/plugins/security_solution/server/endpoint/services/artifacts/manifest_manager/manifest_manager.ts index 13ca51e1f2b39..b5f7b1384750f 100644 --- a/x-pack/plugins/security_solution/server/endpoint/services/artifacts/manifest_manager/manifest_manager.ts +++ b/x-pack/plugins/security_solution/server/endpoint/services/artifacts/manifest_manager/manifest_manager.ts @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ - +import semver from 'semver'; import { Logger, SavedObjectsClientContract } from 'src/core/server'; import LRU from 'lru-cache'; import { PackageConfigServiceInterface } from '../../../../../../ingest_manager/server'; @@ -13,7 +13,6 @@ import { manifestDispatchSchema } from '../../../../../common/endpoint/schema/ma import { ArtifactConstants, - ManifestConstants, Manifest, buildArtifact, getFullEndpointExceptionList, @@ -52,6 +51,7 @@ export class ManifestManager { protected savedObjectsClient: SavedObjectsClientContract; protected logger: Logger; protected cache: LRU; + protected schemaVersion: ManifestSchemaVersion; constructor(context: ManifestManagerContext) { this.artifactClient = context.artifactClient; @@ -60,28 +60,27 @@ export class ManifestManager { this.savedObjectsClient = context.savedObjectsClient; this.logger = context.logger; this.cache = context.cache; + this.schemaVersion = 'v1'; } /** - * Gets a ManifestClient for the provided schemaVersion. + * Gets a ManifestClient for this manager's schemaVersion. * - * @param schemaVersion The schema version of the manifest. - * @returns {ManifestClient} A ManifestClient scoped to the provided schemaVersion. + * @returns {ManifestClient} A ManifestClient scoped to the appropriate schemaVersion. */ - protected getManifestClient(schemaVersion: string): ManifestClient { - return new ManifestClient(this.savedObjectsClient, schemaVersion as ManifestSchemaVersion); + protected getManifestClient(): ManifestClient { + return new ManifestClient(this.savedObjectsClient, this.schemaVersion); } /** * Builds an array of artifacts (one per supported OS) based on the current * state of exception-list-agnostic SOs. * - * @param schemaVersion The schema version of the artifact * @returns {Promise} An array of uncompressed artifacts built from exception-list-agnostic SOs. * @throws Throws/rejects if there are errors building the list. */ protected async buildExceptionListArtifacts( - schemaVersion: string + artifactSchemaVersion?: string ): Promise { return ArtifactConstants.SUPPORTED_OPERATING_SYSTEMS.reduce< Promise @@ -89,10 +88,10 @@ export class ManifestManager { const exceptionList = await getFullEndpointExceptionList( this.exceptionListClient, os, - schemaVersion + artifactSchemaVersion ?? 'v1' ); const artifacts = await acc; - const artifact = await buildArtifact(exceptionList, os, schemaVersion); + const artifact = await buildArtifact(exceptionList, os, artifactSchemaVersion ?? 'v1'); return Promise.resolve([...artifacts, artifact]); }, Promise.resolve([])); } @@ -168,20 +167,23 @@ export class ManifestManager { * Returns the last computed manifest based on the state of the * user-artifact-manifest SO. * - * @param schemaVersion The schema version of the manifest. * @returns {Promise} The last computed manifest, or null if does not exist. * @throws Throws/rejects if there is an unexpected error retrieving the manifest. */ - public async getLastComputedManifest(schemaVersion: string): Promise { + public async getLastComputedManifest(): Promise { try { - const manifestClient = this.getManifestClient(schemaVersion); + const manifestClient = this.getManifestClient(); const manifestSo = await manifestClient.getManifest(); if (manifestSo.version === undefined) { throw new Error('No version returned for manifest.'); } - const manifest = new Manifest(schemaVersion, manifestSo.version); + const manifest = new Manifest({ + schemaVersion: this.schemaVersion, + semanticVersion: manifestSo.attributes.semanticVersion, + soVersion: manifestSo.version, + }); for (const id of manifestSo.attributes.ids) { const artifactSo = await this.artifactClient.getArtifact(id); @@ -199,22 +201,17 @@ export class ManifestManager { /** * Builds a new manifest based on the current user exception list. * - * @param schemaVersion The schema version of the manifest. * @param baselineManifest A baseline manifest to use for initializing pre-existing artifacts. * @returns {Promise} A new Manifest object reprenting the current exception list. */ - public async buildNewManifest( - schemaVersion: string, - baselineManifest?: Manifest - ): Promise { + public async buildNewManifest(baselineManifest?: Manifest): Promise { // Build new exception list artifacts - const artifacts = await this.buildExceptionListArtifacts(ArtifactConstants.SCHEMA_VERSION); + const artifacts = await this.buildExceptionListArtifacts(); // Build new manifest const manifest = Manifest.fromArtifacts( artifacts, - ManifestConstants.SCHEMA_VERSION, - baselineManifest ?? Manifest.getDefault(schemaVersion) + baselineManifest ?? Manifest.getDefault(this.schemaVersion) ); return manifest; @@ -247,14 +244,12 @@ export class ManifestManager { for (const packageConfig of items) { const { id, revision, updated_at, updated_by, ...newPackageConfig } = packageConfig; if (newPackageConfig.inputs.length > 0 && newPackageConfig.inputs[0].config !== undefined) { - const artifactManifest = newPackageConfig.inputs[0].config.artifact_manifest ?? { + const oldManifest = newPackageConfig.inputs[0].config.artifact_manifest ?? { value: {}, }; - const oldManifest = - Manifest.fromPkgConfig(artifactManifest.value) ?? - Manifest.getDefault(ManifestConstants.SCHEMA_VERSION); - if (!manifest.equals(oldManifest)) { + const newManifestVersion = manifest.getSemanticVersion(); + if (semver.gt(newManifestVersion, oldManifest.value.manifest_version)) { newPackageConfig.inputs[0].config.artifact_manifest = { value: serializedManifest, }; @@ -262,7 +257,7 @@ export class ManifestManager { try { await this.packageConfigService.update(this.savedObjectsClient, id, newPackageConfig); this.logger.debug( - `Updated package config ${id} with manifest version ${manifest.getSha256()}` + `Updated package config ${id} with manifest version ${manifest.getSemanticVersion()}` ); } catch (err) { errors.push(err); @@ -274,8 +269,7 @@ export class ManifestManager { errors.push(new Error(`Package config ${id} has no config.`)); } } - - paging = page * items.length < total; + paging = (page - 1) * 20 + items.length < total; page++; } @@ -290,11 +284,11 @@ export class ManifestManager { */ public async commit(manifest: Manifest): Promise { try { - const manifestClient = this.getManifestClient(manifest.getSchemaVersion()); + const manifestClient = this.getManifestClient(); // Commit the new manifest const manifestSo = manifest.toSavedObject(); - const version = manifest.getSoVersion(); + const version = manifest.getSavedObjectVersion(); if (version == null) { await manifestClient.createManifest(manifestSo); @@ -304,7 +298,7 @@ export class ManifestManager { }); } - this.logger.info(`Committed manifest ${manifest.getSha256()}`); + this.logger.info(`Committed manifest ${manifest.getSemanticVersion()}`); } catch (err) { return err; } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/index.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/index.ts index bfaab096a5013..196d816b6b257 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/index.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/index.ts @@ -25,6 +25,8 @@ export const createMockConfig = () => ({ from: 'now-15m', to: 'now', }, + packagerTaskInterval: '60s', + validateArtifactDownloads: true, }); export const mockGetCurrentUser = { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_prepackaged_rules_status_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_prepackaged_rules_status_route.test.ts index f8b6f7e3ddcba..fa2a575d3f69f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_prepackaged_rules_status_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_prepackaged_rules_status_route.test.ts @@ -14,6 +14,11 @@ import { } from '../__mocks__/request_responses'; import { requestContextMock, serverMock, createMockConfig } from '../__mocks__'; import { SecurityPluginSetup } from '../../../../../../security/server'; +import { checkTimelinesStatus } from '../../../timeline/routes/utils/check_timelines_status'; +import { + mockCheckTimelinesStatusBeforeInstallResult, + mockCheckTimelinesStatusAfterInstallResult, +} from '../../../timeline/routes/__mocks__/import_timelines'; jest.mock('../../rules/get_prepackaged_rules', () => { return { @@ -38,6 +43,12 @@ jest.mock('../../rules/get_prepackaged_rules', () => { }; }); +jest.mock('../../../timeline/routes/utils/check_timelines_status', () => { + return { + checkTimelinesStatus: jest.fn(), + }; +}); + describe('get_prepackaged_rule_status_route', () => { const mockGetCurrentUser = { user: { @@ -126,5 +137,45 @@ describe('get_prepackaged_rule_status_route', () => { timelines_not_updated: 0, }); }); + + test('0 timelines installed, 3 timelines not installed, 0 timelines not updated', async () => { + clients.alertsClient.find.mockResolvedValue(getEmptyFindResult()); + (checkTimelinesStatus as jest.Mock).mockResolvedValue( + mockCheckTimelinesStatusBeforeInstallResult + ); + const request = getPrepackagedRulesStatusRequest(); + const response = await server.inject(request, context); + + expect(response.status).toEqual(200); + expect(response.body).toEqual({ + rules_custom_installed: 0, + rules_installed: 0, + rules_not_installed: 1, + rules_not_updated: 0, + timelines_installed: 0, + timelines_not_installed: 3, + timelines_not_updated: 0, + }); + }); + + test('3 timelines installed, 0 timelines not installed, 0 timelines not updated', async () => { + clients.alertsClient.find.mockResolvedValue(getEmptyFindResult()); + (checkTimelinesStatus as jest.Mock).mockResolvedValue( + mockCheckTimelinesStatusAfterInstallResult + ); + const request = getPrepackagedRulesStatusRequest(); + const response = await server.inject(request, context); + + expect(response.status).toEqual(200); + expect(response.body).toEqual({ + rules_custom_installed: 0, + rules_installed: 0, + rules_not_installed: 1, + rules_not_updated: 0, + timelines_installed: 3, + timelines_not_installed: 0, + timelines_not_updated: 0, + }); + }); }); }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint.json index e6a517d85db81..05601ec8ffb4c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint.json @@ -1,20 +1,17 @@ { - "author": [ - "Elastic" - ], + "author": ["Elastic"], "description": "Generates a detection alert each time an Elastic Endpoint Security alert is received. Enabling this rule allows you to immediately begin investigating your Elastic Endpoint alerts.", "enabled": true, "exceptions_list": [ { "id": "endpoint_list", + "list_id": "endpoint_list", "namespace_type": "agnostic", "type": "endpoint" } ], "from": "now-10m", - "index": [ - "logs-endpoint.alerts-*" - ], + "index": ["logs-endpoint.alerts-*"], "language": "kuery", "license": "Elastic License", "max_signals": 10000, @@ -57,10 +54,7 @@ "value": "99" } ], - "tags": [ - "Elastic", - "Endpoint" - ], + "tags": ["Elastic", "Endpoint"], "timestamp_override": "event.ingested", "type": "query", "version": 1 diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/external_alerts.json b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/external_alerts.json index 678ad9eb03b50..8b627c48d2904 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/external_alerts.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/external_alerts.json @@ -1,12 +1,9 @@ { - "author": [ - "Elastic" - ], + "author": ["Elastic"], "description": "Generates a detection alert for each external alert written to the configured indices. Enabling this rule allows you to immediately begin investigating external alerts in the app.", "index": [ "apm-*-transaction*", "auditbeat-*", - "endgame-*", "filebeat-*", "logs-*", "packetbeat-*", @@ -54,9 +51,7 @@ "value": "99" } ], - "tags": [ - "Elastic" - ], + "tags": ["Elastic"], "timestamp_override": "event.ingested", "type": "query", "version": 1 diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/rules/patches/simplest_updated_name.json b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/rules/patches/simplest_updated_name.json index 56c9f151dc712..bec88bcb0e30e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/rules/patches/simplest_updated_name.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/rules/patches/simplest_updated_name.json @@ -1,4 +1,60 @@ { - "rule_id": "query-rule-id", - "name": "Changes only the name to this new value" + "author": [], + "actions": [], + "description": "endpoint list only", + "enabled": true, + "false_positives": [], + "filters": [], + "from": "now-360s", + "index": [ + "apm-*-transaction*", + "auditbeat-*", + "endgame-*", + "filebeat-*", + "logs-*", + "packetbeat-*", + "winlogbeat-*" + ], + "interval": "5m", + "rule_id": "bf8ee47a-3f7f-4561-b2e6-92c9d618a0b2", + "language": "kuery", + "license": "", + "output_index": ".siem-signals-ytercero-default", + "max_signals": 100, + "risk_score": 50, + "risk_score_mapping": [], + "name": "endpoint list only", + "query": "host.name: * ", + "references": [], + "meta": { + "from": "1m", + "kibana_siem_app_url": "http://localhost:5601/app/security" + }, + "severity": "low", + "severity_mapping": [], + "tags": [], + "to": "now", + "type": "query", + "threat": [], + "throttle": "no_actions", + "exceptions_list": [ + { + "list_id": "endpoint_list", + "namespace_type": "agnostic", + "id": "endpoint_list", + "type": "endpoint" + }, + { + "list_id": "b27b7e13-4105-49cf-8142-cee0c61de321", + "namespace_type": "single", + "id": "8da260a0-d1bb-11ea-b248-4ba44bc54af7", + "type": "detection" + }, + { + "list_id": "b27b7e13-4105-49cf-8142-cee0c61de321", + "namespace_type": "single", + "id": "8da260a0-d1bb-11ea-b248-4ba44bc54af7", + "type": "detection" + } + ] } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_risk_score_from_mapping.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_risk_score_from_mapping.ts index 356cf95fc0d24..888642f77af60 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_risk_score_from_mapping.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_risk_score_from_mapping.ts @@ -10,7 +10,6 @@ import { RiskScoreMappingOrUndefined, } from '../../../../../common/detection_engine/schemas/common/schemas'; import { SignalSourceHit } from '../types'; -import { RiskScore as RiskScoreIOTS } from '../../../../../common/detection_engine/schemas/types'; interface BuildRiskScoreFromMappingProps { doc: SignalSourceHit; @@ -33,8 +32,12 @@ export const buildRiskScoreFromMapping = ({ const mappedField = riskScoreMapping[0].field; // TODO: Expand by verifying fieldType from index via doc._index const mappedValue = get(mappedField, doc._source); - // TODO: This doesn't seem to validate...identified riskScore > 100 😬 - if (RiskScoreIOTS.is(mappedValue)) { + if ( + typeof mappedValue === 'number' && + Number.isSafeInteger(mappedValue) && + mappedValue >= 0 && + mappedValue <= 100 + ) { return { riskScore: mappedValue, riskScoreMeta: { riskScoreOverridden: true } }; } } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/utils.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/utils.test.ts index a610970907bf8..3c41f29625a51 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/utils.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/utils.test.ts @@ -716,26 +716,31 @@ describe('utils', () => { describe('#getExceptions', () => { test('it successfully returns array of exception list items', async () => { + listMock.getExceptionListClient = () => + (({ + findExceptionListsItem: jest.fn().mockResolvedValue({ + data: [getExceptionListItemSchemaMock()], + page: 1, + per_page: 10000, + total: 1, + }), + } as unknown) as ExceptionListClient); const client = listMock.getExceptionListClient(); const exceptions = await getExceptions({ client, lists: getListArrayMock(), }); - expect(client.getExceptionList).toHaveBeenNthCalledWith(1, { - id: 'some_uuid', - listId: undefined, - namespaceType: 'single', - }); - expect(client.getExceptionList).toHaveBeenNthCalledWith(2, { - id: 'some_uuid', - listId: undefined, - namespaceType: 'agnostic', + expect(client.findExceptionListsItem).toHaveBeenCalledWith({ + listId: ['list_id_single', 'endpoint_list'], + namespaceType: ['single', 'agnostic'], + page: 1, + perPage: 10000, + filter: [], + sortOrder: undefined, + sortField: undefined, }); - expect(exceptions).toEqual([ - getExceptionListItemSchemaMock(), - getExceptionListItemSchemaMock(), - ]); + expect(exceptions).toEqual([getExceptionListItemSchemaMock()]); }); test('it throws if "client" is undefined', async () => { @@ -747,7 +752,7 @@ describe('utils', () => { ).rejects.toThrowError('lists plugin unavailable during rule execution'); }); - test('it returns empty array if no "lists" is undefined', async () => { + test('it returns empty array if "lists" is undefined', async () => { const exceptions = await getExceptions({ client: listMock.getExceptionListClient(), lists: undefined, @@ -771,11 +776,11 @@ describe('utils', () => { ).rejects.toThrowError('unable to fetch exception list items'); }); - test('it throws if "findExceptionListItem" fails', async () => { + test('it throws if "findExceptionListsItem" fails', async () => { const err = new Error('error fetching list'); listMock.getExceptionListClient = () => (({ - findExceptionListItem: jest.fn().mockRejectedValue(err), + findExceptionListsItem: jest.fn().mockRejectedValue(err), } as unknown) as ExceptionListClient); await expect(() => @@ -786,24 +791,10 @@ describe('utils', () => { ).rejects.toThrowError('unable to fetch exception list items'); }); - test('it returns empty array if "getExceptionList" returns null', async () => { - listMock.getExceptionListClient = () => - (({ - getExceptionList: jest.fn().mockResolvedValue(null), - } as unknown) as ExceptionListClient); - - const exceptions = await getExceptions({ - client: listMock.getExceptionListClient(), - lists: undefined, - }); - - expect(exceptions).toEqual([]); - }); - - test('it returns empty array if "findExceptionListItem" returns null', async () => { + test('it returns empty array if "findExceptionListsItem" returns null', async () => { listMock.getExceptionListClient = () => (({ - findExceptionListItem: jest.fn().mockResolvedValue(null), + findExceptionListsItem: jest.fn().mockResolvedValue(null), } as unknown) as ExceptionListClient); const exceptions = await getExceptions({ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/utils.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/utils.ts index 1c59a4b7ea5d0..9519720d0bbec 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/utils.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/utils.ts @@ -15,6 +15,7 @@ import { ListArrayOrUndefined } from '../../../../common/detection_engine/schema import { BulkResponse, BulkResponseErrorAggregation, isValidUnit } from './types'; import { BuildRuleMessage } from './rule_messages'; import { hasLargeValueList } from '../../../../common/detection_engine/utils'; +import { MAX_EXCEPTION_LIST_SIZE } from '../../../../../lists/common/constants'; interface SortExceptionsReturn { exceptionsWithValueLists: ExceptionListItemSchema[]; @@ -160,43 +161,20 @@ export const getExceptions = async ({ throw new Error('lists plugin unavailable during rule execution'); } - if (lists != null) { + if (lists != null && lists.length > 0) { try { - // Gather all exception items of all exception lists linked to rule - const exceptions = await Promise.all( - lists - .map(async (list) => { - const { id, namespace_type: namespaceType } = list; - try { - // TODO update once exceptions client `findExceptionListItem` - // accepts an array of list ids - const foundList = await client.getExceptionList({ - id, - namespaceType, - listId: undefined, - }); - - if (foundList == null) { - return []; - } else { - const items = await client.findExceptionListItem({ - listId: foundList.list_id, - namespaceType, - page: 1, - perPage: 5000, - filter: undefined, - sortOrder: undefined, - sortField: undefined, - }); - return items != null ? items.data : []; - } - } catch { - throw new Error('unable to fetch exception list items'); - } - }) - .flat() - ); - return exceptions.flat(); + const listIds = lists.map(({ list_id: listId }) => listId); + const namespaceTypes = lists.map(({ namespace_type: namespaceType }) => namespaceType); + const items = await client.findExceptionListsItem({ + listId: listIds, + namespaceType: namespaceTypes, + page: 1, + perPage: MAX_EXCEPTION_LIST_SIZE, + filter: [], + sortOrder: undefined, + sortField: undefined, + }); + return items != null ? items.data : []; } catch { throw new Error('unable to fetch exception list items'); } diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/import_timelines_route.test.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/import_timelines_route.test.ts index fe5993cb0161d..b817896e901c1 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/routes/import_timelines_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/import_timelines_route.test.ts @@ -598,6 +598,28 @@ describe('import timeline templates', () => { mockNewTemplateTimelineId ); }); + + test('should return 200 if create via import without a templateTimelineId or templateTimelineVersion', async () => { + mockGetTupleDuplicateErrorsAndUniqueTimeline.mockReturnValue([ + mockDuplicateIdErrors, + [ + { + ...mockUniqueParsedTemplateTimelineObjects[0], + templateTimelineId: null, + templateTimelineVersion: null, + }, + ], + ]); + const mockRequest = getImportTimelinesRequest(); + const result = await server.inject(mockRequest, context); + expect(result.body).toEqual({ + errors: [], + success: true, + success_count: 1, + timelines_installed: 1, + timelines_updated: 0, + }); + }); }); describe('Import a timeline template already exist', () => { diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/utils/compare_timelines_status.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/utils/compare_timelines_status.ts index d61d217a4cf49..f9515741d1250 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/routes/utils/compare_timelines_status.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/utils/compare_timelines_status.ts @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { isEmpty } from 'lodash/fp'; +import { isEmpty, isInteger } from 'lodash/fp'; import { TimelineTypeLiteralWithNull, TimelineType, @@ -71,13 +71,28 @@ export class CompareTimelinesStatus { } public get isCreatable() { + const noExistingTimeline = this.timelineObject.isCreatable && !this.isHandlingTemplateTimeline; + + const templateCreatable = + this.isHandlingTemplateTimeline && this.templateTimelineObject.isCreatable; + + const noExistingTimelineOrTemplate = templateCreatable && this.timelineObject.isCreatable; + + // From Line 87-91 is the condition for creating a template via import without given a templateTimelineId or templateTimelineVersion, + // but keep the existing savedObjectId and version there. + // Therefore even the timeline exists, we still allow it to create a new timeline template by assigning a templateTimelineId and templateTimelineVersion. + // https://github.com/elastic/kibana/pull/67496#discussion_r454337222 + // Line 90-91 means that we want to make sure the existing timeline retrieved by savedObjectId is atemplate. + // If it is not a template, we show an error this timeline is already exist instead. + const retriveTemplateViaSavedObjectId = + templateCreatable && + !this.timelineObject.isCreatable && + this.timelineObject.getData?.timelineType === this.timelineType; + return ( this.isTitleValid && !this.isSavedObjectVersionConflict && - ((this.timelineObject.isCreatable && !this.isHandlingTemplateTimeline) || - (this.templateTimelineObject.isCreatable && - this.timelineObject.isCreatable && - this.isHandlingTemplateTimeline)) + (noExistingTimeline || noExistingTimelineOrTemplate || retriveTemplateViaSavedObjectId) ); } @@ -195,24 +210,27 @@ export class CompareTimelinesStatus { } private get isTemplateVersionConflict() { - const version = this.templateTimelineObject?.getVersion; + const templateTimelineVersion = this.templateTimelineObject?.getVersion; const existingTemplateTimelineVersion = this.templateTimelineObject?.data ?.templateTimelineVersion; if ( - version != null && + templateTimelineVersion != null && this.templateTimelineObject.isExists && existingTemplateTimelineVersion != null ) { - return version <= existingTemplateTimelineVersion; - } else if (this.templateTimelineObject.isExists && version == null) { + return templateTimelineVersion <= existingTemplateTimelineVersion; + } else if (this.templateTimelineObject.isExists && templateTimelineVersion == null) { return true; } return false; } private get isTemplateVersionValid() { - const version = this.templateTimelineObject?.getVersion; - return typeof version === 'number' && !this.isTemplateVersionConflict; + const templateTimelineVersion = this.templateTimelineObject?.getVersion; + return ( + templateTimelineVersion == null || + (isInteger(templateTimelineVersion) && !this.isTemplateVersionConflict) + ); } private get isUpdatedTimelineStatusValid() { diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/utils/failure_cases.test.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/utils/failure_cases.test.ts new file mode 100644 index 0000000000000..3c3ad1cf2d7f8 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/utils/failure_cases.test.ts @@ -0,0 +1,542 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + commonFailureChecker, + checkIsCreateFailureCases, + checkIsUpdateFailureCases, + checkIsCreateViaImportFailureCases, + EMPTY_TITLE_ERROR_MESSAGE, + UPDATE_STATUS_ERROR_MESSAGE, + CREATE_TIMELINE_ERROR_MESSAGE, + CREATE_TEMPLATE_TIMELINE_ERROR_MESSAGE, + CREATE_TEMPLATE_TIMELINE_WITHOUT_VERSION_ERROR_MESSAGE, + NO_MATCH_ID_ERROR_MESSAGE, + NO_MATCH_VERSION_ERROR_MESSAGE, + NOT_ALLOW_UPDATE_TIMELINE_TYPE_ERROR_MESSAGE, + UPDATE_TEMPLATE_TIMELINE_ERROR_MESSAGE, + CREATE_WITH_INVALID_STATUS_ERROR_MESSAGE, + getImportExistingTimelineError, + checkIsUpdateViaImportFailureCases, + NOT_ALLOW_UPDATE_STATUS_ERROR_MESSAGE, + TEMPLATE_TIMELINE_VERSION_CONFLICT_MESSAGE, +} from './failure_cases'; +import { + TimelineStatus, + TimelineType, + TimelineSavedObject, +} from '../../../../../common/types/timeline'; +import { mockGetTimelineValue, mockGetTemplateTimelineValue } from '../__mocks__/import_timelines'; + +describe('failure cases', () => { + describe('commonFailureChecker', () => { + test('If timeline type is draft, it should not return error if title is not given', () => { + const result = commonFailureChecker(TimelineStatus.draft, null); + + expect(result).toBeNull(); + }); + + test('If timeline type is active, it should return error if title is not given', () => { + const result = commonFailureChecker(TimelineStatus.active, null); + + expect(result).toEqual({ + body: EMPTY_TITLE_ERROR_MESSAGE, + statusCode: 405, + }); + }); + + test('If timeline type is immutable, it should return error if title is not given', () => { + const result = commonFailureChecker(TimelineStatus.immutable, null); + + expect(result).toEqual({ + body: EMPTY_TITLE_ERROR_MESSAGE, + statusCode: 405, + }); + }); + + test('If timeline type is not a draft, it should return no error if title is given', () => { + const result = commonFailureChecker(TimelineStatus.active, 'title'); + + expect(result).toBeNull(); + }); + }); + + describe('checkIsCreateFailureCases', () => { + test('Should return error if trying to create a timeline that is already exist', () => { + const isHandlingTemplateTimeline = false; + const version = null; + const templateTimelineVersion = null; + const templateTimelineId = null; + const existTimeline = mockGetTimelineValue as TimelineSavedObject; + const existTemplateTimeline = null; + const result = checkIsCreateFailureCases( + isHandlingTemplateTimeline, + TimelineStatus.active, + TimelineType.default, + version, + templateTimelineVersion, + templateTimelineId, + existTimeline, + existTemplateTimeline + ); + + expect(result).toEqual({ + body: CREATE_TIMELINE_ERROR_MESSAGE, + statusCode: 405, + }); + }); + + test('Should return error if trying to create a timeline template that is already exist', () => { + const isHandlingTemplateTimeline = true; + const version = null; + const templateTimelineVersion = 1; + const templateTimelineId = 'template-timeline-id-one'; + const existTimeline = null; + const existTemplateTimeline = mockGetTemplateTimelineValue as TimelineSavedObject; + const result = checkIsCreateFailureCases( + isHandlingTemplateTimeline, + TimelineStatus.active, + TimelineType.template, + version, + templateTimelineVersion, + templateTimelineId, + existTimeline, + existTemplateTimeline + ); + + expect(result).toEqual({ + body: CREATE_TEMPLATE_TIMELINE_ERROR_MESSAGE, + statusCode: 405, + }); + }); + + test('Should return error if trying to create a timeline template without providing templateTimelineVersion', () => { + const isHandlingTemplateTimeline = true; + const version = null; + const templateTimelineVersion = null; + const templateTimelineId = 'template-timeline-id-one'; + const existTimeline = null; + const existTemplateTimeline = null; + const result = checkIsCreateFailureCases( + isHandlingTemplateTimeline, + TimelineStatus.active, + TimelineType.template, + version, + templateTimelineVersion, + templateTimelineId, + existTimeline, + existTemplateTimeline + ); + + expect(result).toEqual({ + body: CREATE_TEMPLATE_TIMELINE_WITHOUT_VERSION_ERROR_MESSAGE, + statusCode: 403, + }); + }); + }); + + describe('checkIsUpdateFailureCases', () => { + test('Should return error if trying to update status field of an existing immutable timeline', () => { + const isHandlingTemplateTimeline = false; + const version = mockGetTimelineValue.version; + const templateTimelineVersion = null; + const templateTimelineId = null; + const existTimeline = { + ...(mockGetTimelineValue as TimelineSavedObject), + status: TimelineStatus.immutable, + }; + const existTemplateTimeline = null; + const result = checkIsUpdateFailureCases( + isHandlingTemplateTimeline, + TimelineStatus.active, + TimelineType.default, + version, + templateTimelineVersion, + templateTimelineId, + existTimeline, + existTemplateTimeline + ); + + expect(result).toEqual({ + body: UPDATE_STATUS_ERROR_MESSAGE, + statusCode: 403, + }); + }); + + test('Should return error if trying to update status field of an existing immutable timeline template', () => { + const isHandlingTemplateTimeline = true; + const version = mockGetTemplateTimelineValue.version; + const templateTimelineVersion = mockGetTemplateTimelineValue.templateTimelineVersion; + const templateTimelineId = mockGetTemplateTimelineValue.templateTimelineId; + const existTimeline = null; + const existTemplateTimeline = { + ...(mockGetTemplateTimelineValue as TimelineSavedObject), + status: TimelineStatus.immutable, + }; + const result = checkIsUpdateFailureCases( + isHandlingTemplateTimeline, + TimelineStatus.active, + TimelineType.template, + version, + templateTimelineVersion, + templateTimelineId, + existTimeline, + existTemplateTimeline + ); + + expect(result).toEqual({ + body: UPDATE_STATUS_ERROR_MESSAGE, + statusCode: 403, + }); + }); + + test('should return error if trying to update timelineType field of an existing timeline template', () => { + const isHandlingTemplateTimeline = true; + const version = mockGetTemplateTimelineValue.version; + const templateTimelineVersion = mockGetTemplateTimelineValue.templateTimelineVersion; + const templateTimelineId = mockGetTemplateTimelineValue.templateTimelineId; + const existTimeline = null; + const existTemplateTimeline = mockGetTemplateTimelineValue as TimelineSavedObject; + const result = checkIsUpdateFailureCases( + isHandlingTemplateTimeline, + TimelineStatus.active, + TimelineType.default, + version, + templateTimelineVersion, + templateTimelineId, + existTimeline, + existTemplateTimeline + ); + + expect(result).toEqual({ + body: NOT_ALLOW_UPDATE_TIMELINE_TYPE_ERROR_MESSAGE, + statusCode: 403, + }); + }); + + test('should return error if trying to update a timeline template that does not exist', () => { + const isHandlingTemplateTimeline = true; + const version = mockGetTemplateTimelineValue.version; + const templateTimelineVersion = mockGetTemplateTimelineValue.templateTimelineVersion; + const templateTimelineId = mockGetTemplateTimelineValue.templateTimelineId; + const existTimeline = null; + const existTemplateTimeline = null; + const result = checkIsUpdateFailureCases( + isHandlingTemplateTimeline, + TimelineStatus.active, + TimelineType.default, + version, + templateTimelineVersion, + templateTimelineId, + existTimeline, + existTemplateTimeline + ); + + expect(result).toEqual({ + body: UPDATE_TEMPLATE_TIMELINE_ERROR_MESSAGE, + statusCode: 405, + }); + }); + + test('should return error if there is no matched timeline found by given templateTimelineId', () => { + const isHandlingTemplateTimeline = true; + const version = mockGetTemplateTimelineValue.version; + const templateTimelineVersion = mockGetTemplateTimelineValue.templateTimelineVersion; + const templateTimelineId = mockGetTemplateTimelineValue.templateTimelineId; + const existTimeline = { + ...(mockGetTemplateTimelineValue as TimelineSavedObject), + savedObjectId: 'someOtherId', + }; + const existTemplateTimeline = mockGetTemplateTimelineValue as TimelineSavedObject; + const result = checkIsUpdateFailureCases( + isHandlingTemplateTimeline, + TimelineStatus.active, + TimelineType.template, + version, + templateTimelineVersion, + templateTimelineId, + existTimeline, + existTemplateTimeline + ); + + expect(result).toEqual({ + body: NO_MATCH_ID_ERROR_MESSAGE, + statusCode: 409, + }); + }); + + test('should return error if given version field is defferent from existing version of timelin template', () => { + const isHandlingTemplateTimeline = true; + const version = 'xxx'; + const templateTimelineVersion = mockGetTemplateTimelineValue.templateTimelineVersion; + const templateTimelineId = mockGetTemplateTimelineValue.templateTimelineId; + const existTimeline = null; + const existTemplateTimeline = mockGetTemplateTimelineValue as TimelineSavedObject; + const result = checkIsUpdateFailureCases( + isHandlingTemplateTimeline, + TimelineStatus.active, + TimelineType.template, + version, + templateTimelineVersion, + templateTimelineId, + existTimeline, + existTemplateTimeline + ); + + expect(result).toEqual({ + body: NO_MATCH_VERSION_ERROR_MESSAGE, + statusCode: 409, + }); + }); + }); + + describe('checkIsCreateViaImportFailureCases', () => { + test('should return error if trying to create a draft timeline', () => { + const isHandlingTemplateTimeline = true; + const version = mockGetTemplateTimelineValue.version; + const templateTimelineVersion = mockGetTemplateTimelineValue.templateTimelineVersion; + const templateTimelineId = mockGetTemplateTimelineValue.templateTimelineId; + const existTimeline = null; + const existTemplateTimeline = mockGetTemplateTimelineValue as TimelineSavedObject; + const result = checkIsCreateViaImportFailureCases( + isHandlingTemplateTimeline, + TimelineStatus.draft, + TimelineType.template, + version, + templateTimelineVersion, + templateTimelineId, + existTimeline, + existTemplateTimeline + ); + + expect(result).toEqual({ + body: CREATE_WITH_INVALID_STATUS_ERROR_MESSAGE, + statusCode: 405, + }); + }); + + test('should return error if trying to create a timeline template which is already exist', () => { + const isHandlingTemplateTimeline = true; + const version = mockGetTemplateTimelineValue.version; + const templateTimelineVersion = mockGetTemplateTimelineValue.templateTimelineVersion; + const templateTimelineId = mockGetTemplateTimelineValue.templateTimelineId; + const existTimeline = null; + const existTemplateTimeline = mockGetTemplateTimelineValue as TimelineSavedObject; + const result = checkIsCreateViaImportFailureCases( + isHandlingTemplateTimeline, + TimelineStatus.active, + TimelineType.template, + version, + templateTimelineVersion, + templateTimelineId, + existTimeline, + existTemplateTimeline + ); + + expect(result).toEqual({ + body: getImportExistingTimelineError(mockGetTimelineValue.savedObjectId), + statusCode: 405, + }); + }); + + test('should return error if importe a timeline which is already exists', () => { + const isHandlingTemplateTimeline = false; + const version = mockGetTimelineValue.version; + const templateTimelineVersion = null; + const templateTimelineId = null; + const existTimeline = mockGetTimelineValue as TimelineSavedObject; + const existTemplateTimeline = null; + const result = checkIsCreateViaImportFailureCases( + isHandlingTemplateTimeline, + TimelineStatus.active, + TimelineType.default, + version, + templateTimelineVersion, + templateTimelineId, + existTimeline, + existTemplateTimeline + ); + + expect(result).toEqual({ + body: getImportExistingTimelineError(mockGetTimelineValue.savedObjectId), + statusCode: 405, + }); + }); + }); + + describe('checkIsUpdateViaImportFailureCases', () => { + test('should return error if trying to update a timeline which does not exist', () => { + const isHandlingTemplateTimeline = false; + const version = mockGetTimelineValue.version; + const templateTimelineVersion = null; + const templateTimelineId = null; + const existTimeline = mockGetTimelineValue as TimelineSavedObject; + const existTemplateTimeline = null; + const result = checkIsUpdateViaImportFailureCases( + isHandlingTemplateTimeline, + TimelineStatus.active, + TimelineType.default, + version, + templateTimelineVersion, + templateTimelineId, + existTimeline, + existTemplateTimeline + ); + + expect(result).toEqual({ + body: getImportExistingTimelineError(mockGetTimelineValue.savedObjectId), + statusCode: 405, + }); + }); + + test('should return error if trying to update timelineType field of an existing timeline template', () => { + const isHandlingTemplateTimeline = true; + const version = mockGetTemplateTimelineValue.version; + const templateTimelineVersion = mockGetTemplateTimelineValue.templateTimelineVersion; + const templateTimelineId = mockGetTemplateTimelineValue.templateTimelineId; + const existTimeline = null; + const existTemplateTimeline = mockGetTemplateTimelineValue as TimelineSavedObject; + const result = checkIsUpdateViaImportFailureCases( + isHandlingTemplateTimeline, + TimelineStatus.active, + TimelineType.default, + version, + templateTimelineVersion, + templateTimelineId, + existTimeline, + existTemplateTimeline + ); + + expect(result).toEqual({ + body: NOT_ALLOW_UPDATE_TIMELINE_TYPE_ERROR_MESSAGE, + statusCode: 403, + }); + }); + + test('should return error if trying to update status field of an existing timeline template', () => { + const isHandlingTemplateTimeline = true; + const version = mockGetTemplateTimelineValue.version; + const templateTimelineVersion = mockGetTemplateTimelineValue.templateTimelineVersion; + const templateTimelineId = mockGetTemplateTimelineValue.templateTimelineId; + const existTimeline = null; + const existTemplateTimeline = mockGetTemplateTimelineValue as TimelineSavedObject; + const result = checkIsUpdateViaImportFailureCases( + isHandlingTemplateTimeline, + TimelineStatus.immutable, + TimelineType.template, + version, + templateTimelineVersion, + templateTimelineId, + existTimeline, + existTemplateTimeline + ); + + expect(result).toEqual({ + body: NOT_ALLOW_UPDATE_STATUS_ERROR_MESSAGE, + statusCode: 405, + }); + }); + + test('should return error if trying to update a timeline template that does not exist', () => { + const isHandlingTemplateTimeline = true; + const version = mockGetTemplateTimelineValue.version; + const templateTimelineVersion = mockGetTemplateTimelineValue.templateTimelineVersion; + const templateTimelineId = mockGetTemplateTimelineValue.templateTimelineId; + const existTimeline = null; + const existTemplateTimeline = null; + const result = checkIsUpdateViaImportFailureCases( + isHandlingTemplateTimeline, + TimelineStatus.active, + TimelineType.default, + version, + templateTimelineVersion, + templateTimelineId, + existTimeline, + existTemplateTimeline + ); + + expect(result).toEqual({ + body: UPDATE_TEMPLATE_TIMELINE_ERROR_MESSAGE, + statusCode: 405, + }); + }); + + test('should return error if there is no matched timeline found by given templateTimelineId', () => { + const isHandlingTemplateTimeline = true; + const version = mockGetTemplateTimelineValue.version; + const templateTimelineVersion = mockGetTemplateTimelineValue.templateTimelineVersion; + const templateTimelineId = mockGetTemplateTimelineValue.templateTimelineId; + const existTimeline = { + ...(mockGetTemplateTimelineValue as TimelineSavedObject), + savedObjectId: 'someOtherId', + }; + const existTemplateTimeline = mockGetTemplateTimelineValue as TimelineSavedObject; + const result = checkIsUpdateViaImportFailureCases( + isHandlingTemplateTimeline, + TimelineStatus.active, + TimelineType.template, + version, + templateTimelineVersion, + templateTimelineId, + existTimeline, + existTemplateTimeline + ); + + expect(result).toEqual({ + body: NO_MATCH_ID_ERROR_MESSAGE, + statusCode: 409, + }); + }); + + test('should return error if given version field is defferent from existing version of timelin template', () => { + const isHandlingTemplateTimeline = true; + const version = 'xxx'; + const templateTimelineVersion = mockGetTemplateTimelineValue.templateTimelineVersion; + const templateTimelineId = mockGetTemplateTimelineValue.templateTimelineId; + const existTimeline = null; + const existTemplateTimeline = mockGetTemplateTimelineValue as TimelineSavedObject; + const result = checkIsUpdateViaImportFailureCases( + isHandlingTemplateTimeline, + TimelineStatus.active, + TimelineType.template, + version, + templateTimelineVersion, + templateTimelineId, + existTimeline, + existTemplateTimeline + ); + + expect(result).toEqual({ + body: NO_MATCH_VERSION_ERROR_MESSAGE, + statusCode: 409, + }); + }); + + test('should return error if given templateTimelineVersion field is less or equal to existing templateTimelineVersion of timelin template', () => { + const isHandlingTemplateTimeline = true; + const version = mockGetTemplateTimelineValue.version; + const templateTimelineVersion = mockGetTemplateTimelineValue.templateTimelineVersion; + const templateTimelineId = mockGetTemplateTimelineValue.templateTimelineId; + const existTimeline = null; + const existTemplateTimeline = mockGetTemplateTimelineValue as TimelineSavedObject; + const result = checkIsUpdateViaImportFailureCases( + isHandlingTemplateTimeline, + TimelineStatus.active, + TimelineType.template, + version, + templateTimelineVersion, + templateTimelineId, + existTimeline, + existTemplateTimeline + ); + + expect(result).toEqual({ + body: TEMPLATE_TIMELINE_VERSION_CONFLICT_MESSAGE, + statusCode: 409, + }); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/utils/failure_cases.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/utils/failure_cases.ts index d41e8fc190983..b926819d66c92 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/routes/utils/failure_cases.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/utils/failure_cases.ts @@ -78,7 +78,10 @@ const commonUpdateTemplateTimelineCheck = ( existTemplateTimeline: TimelineSavedObject | null ) => { if (isHandlingTemplateTimeline) { - if (existTimeline != null && timelineType !== existTimeline.timelineType) { + if ( + (existTimeline != null && timelineType !== existTimeline.timelineType) || + (existTemplateTimeline != null && timelineType !== existTemplateTimeline.timelineType) + ) { return { body: NOT_ALLOW_UPDATE_TIMELINE_TYPE_ERROR_MESSAGE, statusCode: 403, @@ -106,11 +109,7 @@ const commonUpdateTemplateTimelineCheck = ( }; } - if ( - existTemplateTimeline != null && - existTemplateTimeline.templateTimelineVersion == null && - existTemplateTimeline.version !== version - ) { + if (existTemplateTimeline != null && existTemplateTimeline.version !== version) { // throw error 409 conflict timeline return { body: NO_MATCH_VERSION_ERROR_MESSAGE, @@ -231,12 +230,6 @@ export const checkIsUpdateViaImportFailureCases = ( }; } } else { - if (existTemplateTimeline != null && timelineType !== existTemplateTimeline?.timelineType) { - return { - body: NOT_ALLOW_UPDATE_TIMELINE_TYPE_ERROR_MESSAGE, - statusCode: 403, - }; - } const isStatusValid = ((existTemplateTimeline?.status == null || existTemplateTimeline?.status === TimelineStatus.active) && diff --git a/x-pack/plugins/security_solution/server/plugin.ts b/x-pack/plugins/security_solution/server/plugin.ts index 611f35c6d402a..b2fd57f9c1247 100644 --- a/x-pack/plugins/security_solution/server/plugin.ts +++ b/x-pack/plugins/security_solution/server/plugin.ts @@ -178,6 +178,7 @@ export class Plugin implements IPlugin module.jobs); - const jobs = await ml.jobServiceProvider(internalMlClient, fakeRequest).jobsSummary(['siem']); + const jobs = await ml + .jobServiceProvider(internalMlClient, fakeRequest) + .jobsSummary(['siem', 'security']); jobsUsage = jobs.reduce((usage, job) => { const isElastic = moduleJobs.some((moduleJob) => moduleJob.id === job.id); diff --git a/x-pack/plugins/spaces/server/capabilities/capabilities_switcher.test.ts b/x-pack/plugins/spaces/server/capabilities/capabilities_switcher.test.ts index 797d7fd1bdcc4..c9ea1b44e723d 100644 --- a/x-pack/plugins/spaces/server/capabilities/capabilities_switcher.test.ts +++ b/x-pack/plugins/spaces/server/capabilities/capabilities_switcher.test.ts @@ -23,7 +23,7 @@ const features = ([ id: 'feature_2', name: 'Feature 2', navLinkId: 'feature2', - app: [], + app: ['feature2'], catalogue: ['feature2Entry'], management: { kibana: ['somethingElse'], diff --git a/x-pack/plugins/spaces/server/capabilities/capabilities_switcher.ts b/x-pack/plugins/spaces/server/capabilities/capabilities_switcher.ts index 00e2419136f48..e8d964b22010c 100644 --- a/x-pack/plugins/spaces/server/capabilities/capabilities_switcher.ts +++ b/x-pack/plugins/spaces/server/capabilities/capabilities_switcher.ts @@ -83,8 +83,7 @@ function toggleDisabledFeatures( for (const feature of disabledFeatures) { // Disable associated navLink, if one exists - const featureNavLinks = feature.navLinkId ? [feature.navLinkId, ...feature.app] : feature.app; - featureNavLinks.forEach((app) => { + feature.app.forEach((app) => { if (navLinks.hasOwnProperty(app) && !enabledAppEntries.has(app)) { navLinks[app] = false; } diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index ed25094d5fc2b..33a90e65cd1f3 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -87,6 +87,7 @@ "advancedSettings.categoryNames.notificationsLabel": "通知", "advancedSettings.categoryNames.reportingLabel": "レポート", "advancedSettings.categoryNames.searchLabel": "検索", + "advancedSettings.categoryNames.securitySolutionLabel": "セキュリティソリューション", "advancedSettings.categoryNames.timelionLabel": "Timelion", "advancedSettings.categoryNames.visualizationsLabel": "可視化", "advancedSettings.categorySearchLabel": "カテゴリー", @@ -236,6 +237,8 @@ "apmOss.tutorial.startServer.title": "APM Server の起動", "apmOss.tutorial.windowsServerInstructions.textPost": "注:システムでスクリプトの実行が無効な場合、スクリプトを実行するために現在のセッションの実行ポリシーの設定が必要となります。例: {command}。", "apmOss.tutorial.windowsServerInstructions.textPre": "1.[ダウンロードページ]({downloadPageLink}) から APM Server Windows zip ファイルをダウンロードします。\n2.zip ファイルの内容を {zipFileExtractFolder} に抽出します。\n3.「{apmServerDirectory} ディレクトリの名前を「APM-Server」に変更します。\n4.管理者として PowerShell プロンプトを開きます (PowerShell アイコンを右クリックして「管理者として実行」を選択します)。Windows XP をご使用の場合、PowerShell のダウンロードとインストールが必要な場合があります。\n5.PowerShellプロンプトで次のコマンドを実行し、APM ServerをWindowsサービスとしてインストールします。", + "charts.advancedSettings.visualization.colorMappingText": "ビジュアライゼーション内の特定の色のマップ値です", + "charts.advancedSettings.visualization.colorMappingTitle": "カラーマッピング", "charts.colormaps.bluesText": "青", "charts.colormaps.greensText": "緑", "charts.colormaps.greenToRedText": "緑から赤", @@ -353,6 +356,7 @@ "console.welcomePage.supportedRequestFormatTitle": "コンソールは cURL と同様に、コンパクトなフォーマットのリクエストを理解できます。", "core.application.appNotFound.pageDescription": "この URL にアプリケーションが見つかりませんでした。前の画面に戻るか、メニューからアプリを選択してみてください。", "core.application.appNotFound.title": "アプリケーションが見つかりません", + "core.application.appRenderError.defaultTitle": "アプリケーションエラー", "core.chrome.browserDeprecationLink": "Web サイトのサポートマトリックス", "core.chrome.browserDeprecationWarning": "このソフトウェアの将来のバージョンでは、Internet Explorerのサポートが削除されます。{link}をご確認ください。", "core.chrome.legacyBrowserWarning": "ご使用のブラウザが Kibana のセキュリティ要件を満たしていません。", @@ -489,6 +493,16 @@ "core.ui.chrome.sideGlobalNav.viewRecentItemsFlyoutTitle": "最近のアイテム", "core.ui.chrome.sideGlobalNav.viewRecentItemsLabel": "最近閲覧", "core.ui.EmptyRecentlyViewed": "最近閲覧したアイテムはありません", + "core.ui.enterpriseSearchNavList.label": "エンタープライズサーチ", + "core.ui.errorUrlOverflow.bigUrlWarningNotificationMessage": "{advancedSettingsLink}で{storeInSessionStorageParam}オプションを有効にするか、オンスクリーンビジュアルを簡素化してください。", + "core.ui.errorUrlOverflow.bigUrlWarningNotificationMessage.advancedSettingsLinkText": "高度な設定", + "core.ui.errorUrlOverflow.bigUrlWarningNotificationTitle": "URLが大きく、Kibanaの動作が停止する可能性があります", + "core.ui.errorUrlOverflow.errorTitle": "このオブジェクトのURLは長すぎます。表示できません", + "core.ui.errorUrlOverflow.optionsToFixError.doNotUseIEText": "最新のブラウザーにアップグレードしてください。他の対応ブラウザーでは、いずれもこの制限がありません。", + "core.ui.errorUrlOverflow.optionsToFixError.enableOptionText": "{kibanaSettingsLink}で{storeInSessionStorageConfig}オプションを有効にしてください。", + "core.ui.errorUrlOverflow.optionsToFixError.enableOptionText.advancedSettingsLinkText": "高度な設定", + "core.ui.errorUrlOverflow.optionsToFixError.removeStuffFromDashboardText": "コンテンツまたはフィルターを削除すると、編集しているオブジェクトがシンプルになります。", + "core.ui.errorUrlOverflow.optionsToFixErrorDescription": "次を試してください。", "core.ui.kibanaNavList.label": "Kibana", "core.ui.legacyBrowserMessage": "このElasticインストレーションは、現在ご使用のブラウザが満たしていない厳格なセキュリティ要件が有効になっています。", "core.ui.legacyBrowserTitle": "ブラウザをアップグレードしてください", @@ -531,8 +545,14 @@ "dashboard.dashboardAppBreadcrumbsTitle": "ダッシュボード", "dashboard.dashboardBreadcrumbsTitle": "ダッシュボード", "dashboard.dashboardGrid.toast.unableToLoadDashboardDangerMessage": "ダッシュボードが読み込めません。", + "dashboard.dashboardPageTitle": "ダッシュボード", "dashboard.dashboardWasNotSavedDangerMessage": "ダッシュボード「{dashTitle}」が保存されませんでした。エラー:{errorMessage}", "dashboard.dashboardWasSavedSuccessMessage": "ダッシュボード「{dashTitle}」が保存されました。", + "dashboard.embedUrlParamExtension.filterBar": "フィルターバー", + "dashboard.embedUrlParamExtension.include": "含める", + "dashboard.embedUrlParamExtension.query": "クエリ", + "dashboard.embedUrlParamExtension.timeFilter": "時間フィルター", + "dashboard.embedUrlParamExtension.topMenu": "トップメニュー", "dashboard.emptyDashboardAdditionalPrivilege": "このダッシュボードを編集するには、追加権限が必要です。", "dashboard.emptyDashboardTitle": "このダッシュボードは空です。", "dashboard.factory.displayName": "ダッシュボード", @@ -600,6 +620,85 @@ "dashboard.topNave.viewConfigDescription": "編集をキャンセルして表示限定モードに切り替えます", "dashboard.urlWasRemovedInSixZeroWarningMessage": "URL「dashboard/create」は6.0で廃止されました。ブックマークを更新してください。", "dashboard.visitVisualizeAppLinkText": "可視化アプリにアクセス", + "data.advancedSettings.courier.batchSearchesText": "無効の場合、ダッシュボードパネルは個々に読み込まれ、検索リクエストはユーザーが移動するか\n クエリを更新すると停止します。有効の場合、ダッシュボードパネルはすべてのデータが読み込まれると同時に読み込まれ、\n 検索は停止しません。", + "data.advancedSettings.courier.batchSearchesTextDeprecation": "この設定はサポートが終了し、Kibana 8.0 では削除されます。", + "data.advancedSettings.courier.batchSearchesTitle": "同時検索のバッチ処理", + "data.advancedSettings.courier.customRequestPreference.requestPreferenceLinkText": "リクエスト設定", + "data.advancedSettings.courier.customRequestPreferenceText": "{setRequestReferenceSetting} が {customSettingValue} に設定されている時に使用される {requestPreferenceLink} です。", + "data.advancedSettings.courier.customRequestPreferenceTitle": "カスタムリクエスト設定", + "data.advancedSettings.courier.ignoreFilterText": "この構成は、似ていないインデックスにアクセスするビジュアライゼーションを含むダッシュボードのサポートを強化します。無効にすると、すべてのフィルターがすべてのビジュアライゼーションに適用されます。有効にすると、ビジュアライゼーションのインデックスにフィルター対象のフィールドが含まれていない場合、ビジュアライゼーションの際にフィルターが無視されます。", + "data.advancedSettings.courier.ignoreFilterTitle": "フィルターの無視", + "data.advancedSettings.courier.maxRequestsText": "Kibanaから送信された_msearchリクエストに使用される{maxRequestsLink}設定を管理します。この構成を無効にしてElasticsearchのデフォルトを使用するには、0に設定します。", + "data.advancedSettings.courier.maxRequestsTitle": "最大同時シャードリクエスト", + "data.advancedSettings.courier.requestPreferenceCustom": "カスタム", + "data.advancedSettings.courier.requestPreferenceNone": "なし", + "data.advancedSettings.courier.requestPreferenceSessionId": "セッションID", + "data.advancedSettings.courier.requestPreferenceText": "どのシャードが検索リクエストを扱うかを設定できます。
        \n
      • {sessionId}:同じシャードのすべての検索リクエストを実行するため、オペレーションを制限します。\n これにはリクエスト間でシャードのキャッシュを共有できるというメリットがあります。
      • \n
      • {custom}:独自の設定が可能になります。\n 'courier:customRequestPreference'で設定値をカスタマイズします。
      • \n
      • {none}:設定されていないことを意味します。\n これにより、リクエストが全シャードコピー間に分散されるため、パフォーマンスが改善される可能性があります。\n ただし、シャードによって更新ステータスが異なる場合があるため、結果に矛盾が生じる可能性があります。
      • \n
      ", + "data.advancedSettings.courier.requestPreferenceTitle": "リクエスト設定", + "data.advancedSettings.defaultIndexText": "インデックスが設定されていない時にアクセスするインデックスです", + "data.advancedSettings.defaultIndexTitle": "デフォルトのインデックス", + "data.advancedSettings.docTableHighlightText": "ディスカバリと保存された検索ダッシュボードの結果をハイライトします。ハイライトすることで、大きなドキュメントを扱う際にリクエストが遅くなります。", + "data.advancedSettings.docTableHighlightTitle": "結果をハイライト", + "data.advancedSettings.format.bytesFormat.numeralFormatLinkText": "数字フォーマット", + "data.advancedSettings.format.bytesFormatText": "「バイト」フォーマットのデフォルト{numeralFormatLink}です", + "data.advancedSettings.format.bytesFormatTitle": "バイトフォーマット", + "data.advancedSettings.format.currencyFormat.numeralFormatLinkText": "数字フォーマット", + "data.advancedSettings.format.currencyFormatText": "「通貨」フォーマットのデフォルト{numeralFormatLink}です", + "data.advancedSettings.format.currencyFormatTitle": "通貨フォーマット", + "data.advancedSettings.format.defaultTypeMapText": "各フィールドタイプにデフォルトで使用するフォーマット名のマップです。フィールドタイプが特に指定されていない場合は {defaultFormat} が使用されます", + "data.advancedSettings.format.defaultTypeMapTitle": "フィールドタイプフォーマット名", + "data.advancedSettings.format.formattingLocale.numeralLanguageLinkText": "数字言語", + "data.advancedSettings.format.formattingLocaleText": "{numeralLanguageLink} ロケール", + "data.advancedSettings.format.formattingLocaleTitle": "フォーマットロケール", + "data.advancedSettings.format.numberFormat.numeralFormatLinkText": "数字フォーマット", + "data.advancedSettings.format.numberFormatText": "「数字」フォーマットのデフォルト{numeralFormatLink}です", + "data.advancedSettings.format.numberFormatTitle": "数字フォーマット", + "data.advancedSettings.format.percentFormat.numeralFormatLinkText": "数字フォーマット", + "data.advancedSettings.format.percentFormatText": "「パーセント」フォーマットのデフォルト{numeralFormatLink}です", + "data.advancedSettings.format.percentFormatTitle": "パーセントフォーマット", + "data.advancedSettings.histogram.barTargetText": "日付ヒストグラムで「自動」間隔を使用する際、この数に近いバーの作成を試みます", + "data.advancedSettings.histogram.barTargetTitle": "目標バー数", + "data.advancedSettings.histogram.maxBarsText": "日付ヒストグラムに表示されるバーの数の上限です。必要に応じて値をスケーリングしてください", + "data.advancedSettings.histogram.maxBarsTitle": "最高バー数", + "data.advancedSettings.historyLimitText": "履歴があるフィールド (例: クエリインプット) に個の数の最近の値が表示されます", + "data.advancedSettings.historyLimitTitle": "履歴制限数", + "data.advancedSettings.indexPatternPlaceholderText": "「管理 > インデックスパターン > インデックスパターンを作成」で使用される「インデックスパターン名」フィールドのプレースホルダーです。", + "data.advancedSettings.indexPatternPlaceholderTitle": "インデックスパターンのプレースホルダー", + "data.advancedSettings.metaFieldsText": "_source の外にあり、ドキュメントが表示される時に融合されるフィールドです", + "data.advancedSettings.metaFieldsTitle": "メタフィールド", + "data.advancedSettings.pinFiltersText": "フィルターがデフォルトでグローバル (ピン付けされた状態) になるかの設定です", + "data.advancedSettings.pinFiltersTitle": "フィルターをデフォルトでピン付けする", + "data.advancedSettings.query.allowWildcardsText": "設定すると、クエリ句の頭に*が使えるようになります。現在クエリバーで実験的クエリ機能が有効になっている場合にのみ適用されます。基本的なLuceneクエリでリーディングワイルドカードを無効にするには、{queryStringOptionsPattern}を使用します。", + "data.advancedSettings.query.allowWildcardsTitle": "クエリでリーディングワイルドカードを許可する", + "data.advancedSettings.query.queryStringOptions.optionsLinkText": "オプション", + "data.advancedSettings.query.queryStringOptionsText": "Luceneクエリ文字列パーサーの{optionsLink}。「{queryLanguage}」が{luceneLanguage}に設定されているときにのみ使用されます。", + "data.advancedSettings.query.queryStringOptionsTitle": "クエリ文字列のオプション", + "data.advancedSettings.searchQueryLanguageKql": "KQL", + "data.advancedSettings.searchQueryLanguageLucene": "Lucene", + "data.advancedSettings.searchQueryLanguageText": "クエリ言語はクエリバーで使用されます。KQLはKibana用に特別に開発された新しい言語です。", + "data.advancedSettings.searchQueryLanguageTitle": "クエリ言語", + "data.advancedSettings.shortenFieldsText": "長いフィールドを短くします。例:foo.bar.bazの代わりにf.b.bazと表示", + "data.advancedSettings.shortenFieldsTitle": "フィールドの短縮", + "data.advancedSettings.sortOptions.optionsLinkText": "オプション", + "data.advancedSettings.sortOptionsText": "Elasticsearch の並べ替えパラメーターの {optionsLink}", + "data.advancedSettings.sortOptionsTitle": "並べ替えオプション", + "data.advancedSettings.suggestFilterValuesText": "フィルターエディターがフィールドの値の候補を表示しないようにするには、このプロパティをfalseにしてください。", + "data.advancedSettings.suggestFilterValuesTitle": "フィルターエディターの候補値", + "data.advancedSettings.timepicker.last15Minutes": "過去15分間", + "data.advancedSettings.timepicker.last1Hour": "過去1時間", + "data.advancedSettings.timepicker.last1Year": "過去1年間", + "data.advancedSettings.timepicker.last24Hours": "過去24時間", + "data.advancedSettings.timepicker.last30Days": "過去30日間", + "data.advancedSettings.timepicker.last30Minutes": "過去30分間", + "data.advancedSettings.timepicker.last7Days": "過去7日間", + "data.advancedSettings.timepicker.last90Days": "過去90日間", + "data.advancedSettings.timepicker.quickRanges.acceptedFormatsLinkText": "対応フォーマット", + "data.advancedSettings.timepicker.quickRangesText": "時間フィルターのクイックセクションに表示される範囲のリストです。それぞれのオブジェクトに「開始」、「終了」({acceptedFormatsLink}を参照)、「表示」(表示するタイトル) が含まれるオブジェクトの配列です。", + "data.advancedSettings.timepicker.quickRangesTitle": "タイムピッカーのクイック範囲", + "data.advancedSettings.timepicker.refreshIntervalDefaultsText": "時間フィルターのデフォルト更新間隔「値」はミリ秒で指定する必要があります。", + "data.advancedSettings.timepicker.refreshIntervalDefaultsTitle": "タイムピッカーの更新間隔", + "data.advancedSettings.timepicker.thisWeek": "今週", + "data.advancedSettings.timepicker.today": "今日", "data.aggTypes.buckets.ranges.rangesFormatMessage": "{gte} {from} と {lt} {to}", "data.common.kql.errors.endOfInputText": "インプットの終わり", "data.common.kql.errors.fieldNameText": "フィールド名", @@ -668,7 +767,10 @@ "data.filter.filterBar.filterItemBadgeIconAriaLabel": "削除", "data.filter.filterBar.includeFilterButtonLabel": "結果を含める", "data.filter.filterBar.indexPatternSelectPlaceholder": "インデックスパターンの選択", + "data.filter.filterBar.labelErrorInfo": "インデックスパターン{indexPattern}が見つかりません", "data.filter.filterBar.labelErrorText": "エラー", + "data.filter.filterBar.labelWarningInfo": "フィールド{fieldName}は現在のビューに存在しません", + "data.filter.filterBar.labelWarningText": "警告", "data.filter.filterBar.moreFilterActionsMessage": "フィルター:{innerText}。他のフィルターアクションを使用するには選択してください。", "data.filter.filterBar.negatedFilterPrefix": "NOT ", "data.filter.filterBar.pinFilterButtonLabel": "すべてのアプリにピン付け", @@ -718,6 +820,8 @@ "data.functions.esaggs.help": "AggConfig 集約を実行します", "data.functions.esaggs.inspector.dataRequest.description": "このリクエストは Elasticsearch にクエリし、ビジュアライゼーション用のデータを取得します。", "data.functions.esaggs.inspector.dataRequest.title": "データ", + "data.functions.indexPatternLoad.help": "インデックスパターンを読み込みます", + "data.functions.indexPatternLoad.id.help": "読み込むインデックスパターンID", "data.indexPatterns.editIndexPattern": "インデックスパターンを編集", "data.indexPatterns.ensureDefaultIndexPattern.bannerLabel": "Kibanaでデータの可視化と閲覧を行うには、Elasticsearchからデータを取得するためのインデックスパターンの作成が必要です。", "data.indexPatterns.fetchFieldErrorTitle": "インデックスパターンのフィールド取得中にエラーが発生 {title} (ID: {id})", @@ -726,6 +830,10 @@ "data.indexPatterns.unknownFieldHeader": "不明なフィールドタイプ {type}", "data.indexPatterns.warningText": "現在{index}に一致するすべてのインデックスにクエリを実行しています。{title}はワイルドカードベースのインデックスパターンに移行されるはずです。", "data.indexPatterns.warningTitle": "時間間隔インデックスパターンのサポートは廃止されました", + "data.noDataPopover.content": "この時間範囲にはデータが含まれていません表示するフィールドを増やし、グラフを作成するには、時間範囲を広げるか、調整してください。", + "data.noDataPopover.dismissAction": "今後表示しない", + "data.noDataPopover.subtitle": "ヒント", + "data.noDataPopover.title": "空のデータセット", "data.parseEsInterval.invalidEsCalendarIntervalErrorMessage": "無効なカレンダー間隔:{interval}、1よりも大きな値が必要です", "data.parseEsInterval.invalidEsIntervalFormatErrorMessage": "無効な間隔フォーマット:{interval}", "data.query.queryBar.comboboxAriaLabel": "{pageType} ページの検索とフィルタリング", @@ -754,6 +862,7 @@ "data.search.aggs.buckets.dateHistogram.customLabel.help": "このアグリゲーションのカスタムラベルを表します", "data.search.aggs.buckets.dateHistogram.dropPartials.help": "このアグリゲーションでdrop_partialsを使用するかどうかを指定します", "data.search.aggs.buckets.dateHistogram.enabled.help": "このアグリゲーションが有効かどうかを指定します", + "data.search.aggs.buckets.dateHistogram.extendedBounds.help": "extended_bounds設定を使用すると、強制的にヒストグラムアグリゲーションを実行し、特定の最小値に対してバケットの作成を開始し、最大値までバケットを作成し続けます。 ", "data.search.aggs.buckets.dateHistogram.field.help": "このアグリゲーションで使用するフィールド", "data.search.aggs.buckets.dateHistogram.format.help": "このアグリゲーションで使用するフォーマット", "data.search.aggs.buckets.dateHistogram.id.help": "このアグリゲーションのID", @@ -812,6 +921,7 @@ "data.search.aggs.buckets.geotileGridTitle": "ジオタイル", "data.search.aggs.buckets.histogram.customLabel.help": "このアグリゲーションのカスタムラベルを表します", "data.search.aggs.buckets.histogram.enabled.help": "このアグリゲーションが有効かどうかを指定します", + "data.search.aggs.buckets.histogram.extendedBounds.help": "extended_bounds設定を使用すると、強制的にヒストグラムアグリゲーションを実行し、特定の最小値に対してバケットの作成を開始し、最大値までバケットを作成し続けます。 ", "data.search.aggs.buckets.histogram.field.help": "このアグリゲーションで使用するフィールド", "data.search.aggs.buckets.histogram.hasExtendedBounds.help": "このアグリゲーションでhas_extended_boundsを使用するかどうかを指定します", "data.search.aggs.buckets.histogram.id.help": "このアグリゲーションのID", @@ -822,14 +932,14 @@ "data.search.aggs.buckets.histogram.schema.help": "このアグリゲーションで使用するスキーマ", "data.search.aggs.buckets.histogramTitle": "ヒストグラム", "data.search.aggs.buckets.intervalOptions.autoDisplayName": "自動", - "data.search.aggs.buckets.intervalOptions.dailyDisplayName": "日ごと", - "data.search.aggs.buckets.intervalOptions.hourlyDisplayName": "1 時間ごと", + "data.search.aggs.buckets.intervalOptions.dailyDisplayName": "日", + "data.search.aggs.buckets.intervalOptions.hourlyDisplayName": "時間", "data.search.aggs.buckets.intervalOptions.millisecondDisplayName": "ミリ秒", "data.search.aggs.buckets.intervalOptions.minuteDisplayName": "分", - "data.search.aggs.buckets.intervalOptions.monthlyDisplayName": "月ごと", + "data.search.aggs.buckets.intervalOptions.monthlyDisplayName": "月", "data.search.aggs.buckets.intervalOptions.secondDisplayName": "秒", - "data.search.aggs.buckets.intervalOptions.weeklyDisplayName": "週ごと", - "data.search.aggs.buckets.intervalOptions.yearlyDisplayName": "年ごと", + "data.search.aggs.buckets.intervalOptions.weeklyDisplayName": "週", + "data.search.aggs.buckets.intervalOptions.yearlyDisplayName": "年", "data.search.aggs.buckets.ipRange.customLabel.help": "このアグリゲーションのカスタムラベルを表します", "data.search.aggs.buckets.ipRange.enabled.help": "このアグリゲーションが有効かどうかを指定します", "data.search.aggs.buckets.ipRange.field.help": "このアグリゲーションで使用するフィールド", @@ -1188,7 +1298,86 @@ "data.search.unableToGetSavedQueryToastTitle": "保存したクエリ {savedQueryId} を読み込めません", "devTools.badge.readOnly.text": "読み込み専用", "devTools.badge.readOnly.tooltip": "を保存できませんでした", + "devTools.devToolsTitle": "開発ツール", "devTools.k7BreadcrumbsDevToolsLabel": "開発ツール", + "devTools.pageTitle": "開発ツール", + "discover.advancedSettings.aggsTermsSizeText": "「可視化」ボタンをクリックした際に、フィールドドロップダウンやディスカバリサイドバーに可視化される用語の数を設定します。", + "discover.advancedSettings.aggsTermsSizeTitle": "用語数", + "discover.advancedSettings.context.defaultSizeText": "コンテキストビューに表示される周りのエントリーの数", + "discover.advancedSettings.context.defaultSizeTitle": "コンテキストサイズ", + "discover.advancedSettings.context.sizeStepText": "コンテキストサイズを増減させる際の最低単位です", + "discover.advancedSettings.context.sizeStepTitle": "コンテキストサイズのステップ", + "discover.advancedSettings.context.tieBreakerFieldsText": "同じタイムスタンプ値のドキュメントを区別するためのコンマ区切りのフィールドのリストです。このリストから、現在のインデックスパターンに含まれ並べ替え可能な初めのフィールドが使用されます。", + "discover.advancedSettings.context.tieBreakerFieldsTitle": "タイブレーカーフィールド", + "discover.advancedSettings.defaultColumnsText": "デフォルトでディスカバリタブに表示される列です", + "discover.advancedSettings.defaultColumnsTitle": "デフォルトの列", + "discover.advancedSettings.docTableHideTimeColumnText": "ディスカバリと、ダッシュボードのすべての保存された検索で、「時刻」列を非表示にします。", + "discover.advancedSettings.docTableHideTimeColumnTitle": "「時刻」列を非表示", + "discover.advancedSettings.fieldsPopularLimitText": "最も頻繁に使用されるフィールドのトップNを表示します", + "discover.advancedSettings.fieldsPopularLimitTitle": "頻繁に使用されるフィールドの制限", + "discover.advancedSettings.sampleSizeText": "表に表示する行数です", + "discover.advancedSettings.sampleSizeTitle": "行数", + "discover.advancedSettings.searchOnPageLoadText": "ディスカバリの最初の読み込み時に検索を実行するかを制御します。この設定は、保存された検索の読み込み時には影響しません。", + "discover.advancedSettings.searchOnPageLoadTitle": "ページの読み込み時の検索", + "discover.advancedSettings.sortDefaultOrderText": "ディスカバリアプリのインデックスパターンに基づく時刻のデフォルトの並べ替え方向をコントロールします。", + "discover.advancedSettings.sortDefaultOrderTitle": "デフォルトの並べ替え方向", + "discover.advancedSettings.sortOrderAsc": "昇順", + "discover.advancedSettings.sortOrderDesc": "降順", + "discover.backToTopLinkText": "最上部へ戻る。", + "discover.badge.readOnly.text": "読み取り専用", + "discover.badge.readOnly.tooltip": "検索を保存できません", + "discover.bucketIntervalTooltip": "この間隔は選択された時間範囲に表示される{bucketsDescription}が作成されるため、{bucketIntervalDescription}にスケーリングされています。", + "discover.bucketIntervalTooltip.tooLargeBucketsText": "大きすぎるバケット", + "discover.bucketIntervalTooltip.tooManyBucketsText": "バケットが多すぎます", + "discover.context.breadcrumb": "{indexPatternTitle}#{docId} のコンテキスト", + "discover.context.failedToLoadAnchorDocumentDescription": "アンカードキュメントの読み込みに失敗しました", + "discover.context.failedToLoadAnchorDocumentErrorDescription": "アンカードキュメントの読み込みに失敗しました。", + "discover.context.loadButtonLabel": "読み込み", + "discover.context.loadingDescription": "読み込み中...", + "discover.context.newerDocumentsAriaLabel": "新しいドキュメントの数", + "discover.context.newerDocumentsDescription": "新しいドキュメント", + "discover.context.newerDocumentsWarning": "アンカーよりも新しいドキュメントは{docCount}件しか見つかりませんでした。", + "discover.context.newerDocumentsWarningZero": "アンカーよりも新しいドキュメントは見つかりませんでした。", + "discover.context.olderDocumentsAriaLabel": "古いドキュメントの数", + "discover.context.olderDocumentsDescription": "古いドキュメント", + "discover.context.olderDocumentsWarning": "アンカーよりも古いドキュメントは{docCount}件しか見つかりませんでした。", + "discover.context.olderDocumentsWarningZero": "アンカーよりも古いドキュメントは見つかりませんでした。", + "discover.context.reloadPageDescription.reloadOrVisitTextMessage": "ドキュメントリストを再読み込みするか、ドキュメントリストに戻り、有効なアンカードキュメントを選択してください。", + "discover.context.unableToLoadAnchorDocumentDescription": "アンカードキュメントを読み込めません", + "discover.context.unableToLoadDocumentDescription": "ドキュメントを読み込めません", + "discover.discoverBreadcrumbTitle": "発見", + "discover.discoverDescription": "ドキュメントにクエリをかけたりフィルターを適用することで、データをインタラクティブに閲覧できます。", + "discover.discoverTitle": "発見", + "discover.doc.couldNotFindDocumentsDescription": "そのIDに一致するドキュメントがありません。", + "discover.doc.failedToExecuteQueryDescription": "検索の実行に失敗しました", + "discover.doc.failedToLocateDocumentDescription": "ドキュメントが見つかりませんでした", + "discover.doc.failedToLocateIndexPattern": "ID {indexPatternId}に一致するインデックスパターンがありません", + "discover.doc.loadingDescription": "読み込み中...", + "discover.doc.somethingWentWrongDescription": "{indexName}が見つかりません。", + "discover.doc.somethingWentWrongDescriptionAddon": "インデックスが存在することを確認してください。", + "discover.docTable.limitedSearchResultLabel": "{resultCount}件の結果のみが表示されます。検索結果を絞り込みます。", + "discover.docTable.noResultsTitle": "結果が見つかりませんでした", + "discover.docTable.pager.toolbarPagerButtons.nextButtonAriaLabel": "表内の次ページ", + "discover.docTable.pager.toolbarPagerButtons.previousButtonAriaLabel": "表内の前ページ", + "discover.docTable.pagerControl.pagesCountLabel": "{startItem}–{endItem}/{totalItems}", + "discover.docTable.tableHeader.moveColumnLeftButtonAriaLabel": "{columnName}列を左に移動", + "discover.docTable.tableHeader.moveColumnLeftButtonTooltip": "列を左に移動", + "discover.docTable.tableHeader.moveColumnRightButtonAriaLabel": "{columnName}列を右に移動", + "discover.docTable.tableHeader.moveColumnRightButtonTooltip": "列を右に移動", + "discover.docTable.tableHeader.removeColumnButtonAriaLabel": "{columnName}列を削除", + "discover.docTable.tableHeader.removeColumnButtonTooltip": "列の削除", + "discover.docTable.tableHeader.sortByColumnAscendingAriaLabel": "{columnName}を昇順に並べ替える", + "discover.docTable.tableHeader.sortByColumnDescendingAriaLabel": "{columnName}を降順に並べ替える", + "discover.docTable.tableHeader.sortByColumnUnsortedAriaLabel": "{columnName}で並べ替えを止める", + "discover.docTable.tableRow.detailHeading": "拡張ドキュメント", + "discover.docTable.tableRow.filterForValueButtonAriaLabel": "値でフィルター", + "discover.docTable.tableRow.filterForValueButtonTooltip": "値でフィルター", + "discover.docTable.tableRow.filterOutValueButtonAriaLabel": "値を除外", + "discover.docTable.tableRow.filterOutValueButtonTooltip": "値を除外", + "discover.docTable.tableRow.toggleRowDetailsButtonAriaLabel": "行の詳細を切り替える", + "discover.docTable.tableRow.viewSingleDocumentLinkText": "単一のドキュメントを表示", + "discover.docTable.tableRow.viewSurroundingDocumentsLinkText": "周りのドキュメントを表示", + "discover.documentsAriaLabel": "ドキュメント", "discover.docViews.json.codeEditorAriaLabel": "Elasticsearch ドキュメントの JSON ビューのみを読み込む", "discover.docViews.json.jsonTitle": "JSON", "discover.docViews.table.fieldNamesBeginningWithUnderscoreUnsupportedAriaLabel": "警告", @@ -1208,6 +1397,46 @@ "discover.docViews.table.unableToFilterForPresenceOfMetaFieldsTooltip": "メタフィールドの有無でフィルタリングできません", "discover.docViews.table.unableToFilterForPresenceOfScriptedFieldsTooltip": "スクリプトフィールドの有無でフィルタリングできません", "discover.docViews.table.unindexedFieldsCanNotBeSearchedTooltip": "インデックスされていないフィールドは検索できません", + "discover.embeddable.inspectorRequestDataTitle": "データ", + "discover.embeddable.inspectorRequestDescription": "このリクエストはElasticsearchにクエリをかけ、検索データを取得します。", + "discover.embeddable.search.displayName": "検索", + "discover.errorLoadingData": "データの読み込み中にエラーが発生", + "discover.fetchError.howToAddressErrorDescription": "このエラーは、{scriptedFields}タブにある {managementLink}の{fetchErrorScript}フィールドを編集することで解決できます。", + "discover.fetchError.managmentLinkText": "管理>インデックスパターン", + "discover.fetchError.scriptedFieldsText": "「スクリプトフィールド」", + "discover.fieldChooser.detailViews.emptyStringText": "空の文字列", + "discover.fieldChooser.detailViews.filterOutValueButtonAriaLabel": "{field}を除外:\"{value}\"", + "discover.fieldChooser.detailViews.filterValueButtonAriaLabel": "{field}を除外:\"{value}\"", + "discover.fieldChooser.detailViews.recordsText": "記録", + "discover.fieldChooser.detailViews.topValuesInRecordsDescription": "次の記録のトップ5の値", + "discover.fieldChooser.detailViews.visualizeLinkText": "可視化", + "discover.fieldChooser.discoverField.addButtonAriaLabel": "{field}を表に追加", + "discover.fieldChooser.discoverField.addButtonLabel": "追加", + "discover.fieldChooser.discoverField.removeButtonAriaLabel": "{field}を表から削除", + "discover.fieldChooser.discoverField.removeButtonLabel": "削除", + "discover.fieldChooser.discoverField.scriptedFieldsTakeLongExecuteDescription": "スクリプトフィールドは実行に時間がかかる場合があります。", + "discover.fieldChooser.fieldCalculator.analysisIsNotAvailableForGeoFieldsErrorMessage": "ジオフィールドは分析できません。", + "discover.fieldChooser.fieldCalculator.analysisIsNotAvailableForObjectFieldsErrorMessage": "オブジェクトフィールドは分析できません。", + "discover.fieldChooser.fieldCalculator.fieldIsNotPresentInDocumentsErrorMessage": "このフィールドはElasticsearchマッピングに表示されますが、ドキュメントテーブルの{hitsLength}件のドキュメントには含まれません。可視化や検索は可能な場合があります。", + "discover.fieldChooser.fieldFilterFacetButtonLabel": "タイプでフィルタリング", + "discover.fieldChooser.filter.aggregatableLabel": "集約可能", + "discover.fieldChooser.filter.availableFieldsTitle": "利用可能なフィールド", + "discover.fieldChooser.filter.fieldSelectorLabel": "{id}フィルターオプションの選択", + "discover.fieldChooser.filter.filterByTypeLabel": "タイプでフィルタリング", + "discover.fieldChooser.filter.hideMissingFieldsLabel": "未入力のフィールドを非表示", + "discover.fieldChooser.filter.indexAndFieldsSectionAriaLabel": "インデックスとフィールド", + "discover.fieldChooser.filter.indexAndFieldsSectionHideAriaLabel": "フィールドを非表示", + "discover.fieldChooser.filter.indexAndFieldsSectionShowAriaLabel": "フィールドを表示", + "discover.fieldChooser.filter.popularTitle": "人気", + "discover.fieldChooser.filter.searchableLabel": "検索可能", + "discover.fieldChooser.filter.selectedFieldsTitle": "スクリプトフィールド", + "discover.fieldChooser.filter.typeLabel": "タイプ", + "discover.fieldChooser.indexPattern.changeIndexPatternTitle": "インデックスパターンを変更", + "discover.fieldChooser.indexPattern.changeLinkAriaLabel": "現在のインデックスパターンを変更", + "discover.fieldChooser.indexPattern.changeLinkTooltip": "現在のインデックスパターンを変更", + "discover.fieldChooser.searchPlaceHolder": "検索フィールド名", + "discover.fieldChooser.toggleFieldFilterButtonHideAriaLabel": "フィールド設定を非表示", + "discover.fieldChooser.toggleFieldFilterButtonShowAriaLabel": "フィールド設定を表示", "discover.fieldNameIcons.booleanAriaLabel": "ブールフィールド", "discover.fieldNameIcons.conflictFieldAriaLabel": "矛盾フィールド", "discover.fieldNameIcons.dateFieldAriaLabel": "日付フィールド", @@ -1220,6 +1449,61 @@ "discover.fieldNameIcons.sourceFieldAriaLabel": "ソースフィールド", "discover.fieldNameIcons.stringFieldAriaLabel": "文字列フィールド", "discover.fieldNameIcons.unknownFieldAriaLabel": "不明なフィールド", + "discover.helpMenu.appName": "発見", + "discover.histogram.partialData.bucketTooltipText": "選択された時間範囲にはこのバケット全体は含まれていませんが、一部データが含まれている可能性があります。", + "discover.histogramOfFoundDocumentsAriaLabel": "検出されたドキュメントのヒストグラム", + "discover.hitsPluralTitle": "{hits, plural, one {ヒット} other {ヒット}}", + "discover.howToChangeTheTimeTooltip": "時刻を変更するには、上記のグローバル時刻フィルターを使用します。", + "discover.howToSeeOtherMatchingDocumentsDescription": "これらは検索条件に一致した初めの{sampleSize}件のドキュメントです。他の結果を表示するには検索条件を絞ってください。 ", + "discover.inspectorRequestDataTitle": "データ", + "discover.inspectorRequestDescription": "このリクエストはElasticsearchにクエリをかけ、検索データを取得します。", + "discover.localMenu.inspectTitle": "検査", + "discover.localMenu.localMenu.newSearchTitle": "新規", + "discover.localMenu.newSearchDescription": "新規検索", + "discover.localMenu.openInspectorForSearchDescription": "検索用にインスペクターを開きます", + "discover.localMenu.openSavedSearchDescription": "保存された検索を開きます", + "discover.localMenu.openTitle": "開く", + "discover.localMenu.saveSaveSearchDescription": "ビジュアライゼーションとダッシュボードで使用できるようにディスカバリの検索を保存します", + "discover.localMenu.saveSearchDescription": "検索を保存します", + "discover.localMenu.saveTitle": "保存", + "discover.localMenu.shareSearchDescription": "検索を共有します", + "discover.localMenu.shareTitle": "共有", + "discover.noResults.addressShardFailuresTitle": "シャードエラーの解決", + "discover.noResults.expandYourTimeRangeTitle": "時間範囲を拡大", + "discover.noResults.indexFailureIndexText": "インデックス {failureIndex}", + "discover.noResults.indexFailureShardText": "{index}、シャード {failureShard}", + "discover.noResults.queryMayNotMatchTitle": "1つ以上の表示されているインデックスに日付フィールドが含まれています。クエリが現在の時間範囲のデータと一致しないか、現在選択された時間範囲にデータが全く存在しない可能性があります。データが存在する時間範囲に変えることができます。", + "discover.noResults.searchExamples.400to499StatusCodeExampleTitle": "400-499のすべてのステータスコードを検索", + "discover.noResults.searchExamples.400to499StatusCodeWithPhpExtensionExampleTitle": "400-499のphp拡張子のステータスコードを検索", + "discover.noResults.searchExamples.400to499StatusCodeWithPhpOrHtmlExtensionExampleTitle": "400-499のphpまたはhtml拡張子のステータスコードを検索", + "discover.noResults.searchExamples.anyField200StatusCodeExampleTitle": "いずれかのフィールドに数字200が含まれているリクエストを検索", + "discover.noResults.searchExamples.howTosearchForWebServerLogsDescription": "画面上部の検索バーは、ElasticsearchのLucene {queryStringSyntaxLink}サポートを利用します。新規フィールドにパースされたウェブサーバーログの検索方法の例は、次のとおりです。", + "discover.noResults.searchExamples.noResultsMatchSearchCriteriaTitle": "検索条件と一致する結果がありません。", + "discover.noResults.searchExamples.queryStringSyntaxLinkText": "クエリ文字列の構文", + "discover.noResults.searchExamples.refineYourQueryTitle": "クエリの調整", + "discover.noResults.searchExamples.statusField200StatusCodeExampleTitle": "ステータスフィールドの200を検索", + "discover.noResults.shardFailuresDescription": "次のシャードエラーが発生しました。", + "discover.notifications.invalidTimeRangeText": "指定された時間範囲が無効です。(開始:'{from}'、終了:'{to}')", + "discover.notifications.invalidTimeRangeTitle": "無効な時間範囲", + "discover.notifications.notSavedSearchTitle": "検索「{savedSearchTitle}」は保存されませんでした。", + "discover.notifications.savedSearchTitle": "検索「{savedSearchTitle}」が保存されました。", + "discover.painlessError.painlessScriptedFieldErrorMessage": "Painlessスクリプトのフィールド「{script}」のエラー.", + "discover.reloadSavedSearchButton": "検索をリセット", + "discover.rootBreadcrumb": "発見", + "discover.savedSearch.savedObjectName": "保存検索", + "discover.searchingTitle": "検索中", + "discover.showingDefaultIndexPatternWarningDescription": "デフォルトのインデックスパターン「{loadedIndexPatternTitle}」 ({loadedIndexPatternId}) を表示中", + "discover.showingSavedIndexPatternWarningDescription": "保存されたインデックスパターン「{ownIndexPatternTitle}」 ({ownIndexPatternId}) を表示中", + "discover.skipToBottomButtonLabel": "テーブルの最後までスキップ", + "discover.timechartHeader.timeIntervalSelect.ariaLabel": "時間間隔", + "discover.timechartHeader.timeIntervalSelect.per": "ごと", + "discover.topNav.openSearchPanel.manageSearchesButtonLabel": "検索の管理", + "discover.topNav.openSearchPanel.noSearchesFoundDescription": "一致する検索が見つかりませんでした。", + "discover.topNav.openSearchPanel.openSearchTitle": "検索を開く", + "discover.uninitializedRefreshButtonText": "データを更新", + "discover.uninitializedText": "クエリを作成、フィルターを追加、または[更新]をクリックして、現在のクエリの結果を取得します。", + "discover.uninitializedTitle": "検索開始", + "discover.valueIsNotConfiguredIndexPatternIDWarningTitle": "{stateVal}は設定されたインデックスパターンIDではありません", "embeddableApi.actions.applyFilterActionTitle": "現在のビューにフィルターを適用", "embeddableApi.addPanel.createNewDefaultOption": "新規作成...", "embeddableApi.addPanel.displayName": "パネルの追加", @@ -1242,6 +1526,8 @@ "embeddableApi.panel.editPanel.displayName": "{value} を編集", "embeddableApi.panel.enhancedDashboardPanelAriaLabel": "ダッシュボードパネル: {title}", "embeddableApi.panel.inspectPanel.displayName": "検査", + "embeddableApi.panel.labelAborted": "中断しました", + "embeddableApi.panel.labelError": "エラー", "embeddableApi.panel.optionsMenu.panelOptionsButtonAriaLabel": "パネルオプション", "embeddableApi.panel.optionsMenu.panelOptionsButtonEnhancedAriaLabel": "{title} のパネルオプション", "embeddableApi.panel.removePanel.displayName": "ダッシュボードから削除", @@ -1301,6 +1587,10 @@ "esUi.forms.fieldValidation.indexNameStartsWithDotError": "インデックス名の始めにピリオド (.) は使用できません。", "esUi.forms.fieldValidation.indexPatternInvalidCharactersError": "インデックスパターンに無効な{characterListLength, plural, one {文字} other {文字}} { characterList } が含まれています。", "esUi.forms.fieldValidation.indexPatternSpacesError": "インデックスパターンにはスペースを使用できません。", + "esUi.formWizard.backButtonLabel": "戻る", + "esUi.formWizard.nextButtonLabel": "次へ", + "esUi.formWizard.saveButtonLabel": "保存", + "esUi.formWizard.savingButtonLabel": "保存中…", "esUi.validation.string.invalidJSONError": "無効なJSON", "expressions.defaultErrorRenderer.errorTitle": "ビジュアライゼーションエラー", "expressions.functions.font.args.alignHelpText": "水平テキスト配置", @@ -1337,6 +1627,9 @@ "home.addData.metrics.nameTitle": "メトリック", "home.addData.sampleDataLink": "データセットと Kibana ダッシュボードを読み込む", "home.addData.sampleDataTitle": "サンプルデータの追加", + "home.addData.securitySolution.addSecurityEventsButtonLabel": "イベントを追加", + "home.addData.securitySolution.nameDescription": "即利用可能なビジュアライゼーションで、セキュリティイベントをまとめてインタラクティブな調査を可能にします。", + "home.addData.securitySolution.nameTitle": "セキュリティ", "home.addData.title.observability": "オブザーバビリティ", "home.addData.title.security": "セキュリティ", "home.addData.uploadFileLink": "CSV、NDJSON、またはログファイルをインポート", @@ -1366,6 +1659,7 @@ "home.letsStartTitle": "始めましょう", "home.loadTutorials.requestFailedErrorMessage": "リクエスト失敗、ステータスコード: {status}", "home.loadTutorials.unableToLoadErrorMessage": "チュートリアルが読み込めません。", + "home.pageTitle": "ホーム", "home.recentlyAccessed.recentlyViewedTitle": "最近閲覧", "home.sampleData.ecommerceSpec.averageSalesPerRegionTitle": "[e コマース] 地域ごとの平均売上", "home.sampleData.ecommerceSpec.averageSalesPriceTitle": "[e コマース] 平均販売価格", @@ -1468,6 +1762,7 @@ "home.tutorial.tabs.loggingTitle": "ログ", "home.tutorial.tabs.metricsTitle": "メトリック", "home.tutorial.tabs.sampleDataTitle": "サンプルデータ", + "home.tutorial.tabs.securitySolutionTitle": "セキュリティ", "home.tutorial.unexpectedStatusCheckStateErrorDescription": "予期せぬステータス確認ステータス {statusCheckState}", "home.tutorial.unhandledInstructionTypeErrorDescription": "予期せぬ指示タイプ {visibleInstructions}", "home.tutorials.activemqLogs.artifacts.dashboards.linkLabel": "ActiveMQ アプリケーションイベント", @@ -1490,7 +1785,7 @@ "home.tutorials.apacheMetrics.longDescription": "Metricbeat モジュール「apache」は、Apache 2 HTTP サーバーから内部メトリックを取得します。[詳細]({learnMoreLink})。", "home.tutorials.apacheMetrics.nameTitle": "Apache メトリック", "home.tutorials.apacheMetrics.shortDescription": "Apache 2 HTTP サーバーから内部メトリックを取得します。", - "home.tutorials.auditbeat.artifacts.dashboards.linkLabel": "SIEM アプリ", + "home.tutorials.auditbeat.artifacts.dashboards.linkLabel": "セキュリティアプリ", "home.tutorials.auditbeat.longDescription": "Auditbeat を使用してホストから監査データを収集します。これらにはプロセス、ユーザー、ログイン、ソケット情報、ファイルアクセス、その他が含まれます。[詳細]({learnMoreLink})。", "home.tutorials.auditbeat.nameTitle": "Auditbeat", "home.tutorials.auditbeat.shortDescription": "ホストから監査データを収集します。", @@ -1502,6 +1797,11 @@ "home.tutorials.awsMetrics.longDescription": "Metricbeat モジュール「aws」は、AWS API と Cloudwatch から監視メトリックを取得します。[詳細]({learnMoreLink})。", "home.tutorials.awsMetrics.nameTitle": "AWS メトリック", "home.tutorials.awsMetrics.shortDescription": "AWS API と Cloudwatch からの EC2 インスタンスの監視メトリックです。", + "home.tutorials.azureLogs.artifacts.dashboards.linkLabel": "Apacheログダッシュボード", + "home.tutorials.azureLogs.longDescription": "「azure」Filebeatモジュールは、Azureアクティビティと監査関連ログを収集します。[詳細]({learnMoreLink})。", + "home.tutorials.azureLogs.nameTitle": "Azureログ", + "home.tutorials.azureLogs.shortDescription": "Azureアクティビティと監査関連ログを収集します。", + "home.tutorials.azureMetrics.artifacts.dashboards.linkLabel": "Apacheメトリックダッシュボード", "home.tutorials.azureMetrics.longDescription": "Metricbeat モジュール「azure」は、Azure から監視メトリックを取得します。[詳細]({learnMoreLink})。", "home.tutorials.azureMetrics.nameTitle": "Azure メトリック", "home.tutorials.azureMetrics.shortDescription": "Azure 監視メトリックをフェッチします。", @@ -1509,7 +1809,7 @@ "home.tutorials.cephMetrics.longDescription": "Metricbeat モジュール「ceph」は、Ceph から内部メトリックを取得します。[詳細]({learnMoreLink})。", "home.tutorials.cephMetrics.nameTitle": "Ceph メトリック", "home.tutorials.cephMetrics.shortDescription": "Ceph サーバーから内部メトリックを取得します。", - "home.tutorials.ciscoLogs.artifacts.dashboards.linkLabel": "SIEM アプリ", + "home.tutorials.ciscoLogs.artifacts.dashboards.linkLabel": "セキュリティアプリ", "home.tutorials.ciscoLogs.longDescription": "これは Cisco ネットワークデバイスのログ用のモジュールです。現在、syslog 経由またはファイルから読み込まれた Cisco ASA ファイアウォールログの「asa」ファイルセットをサポートしています。[詳細]({learnMoreLink})。", "home.tutorials.ciscoLogs.nameTitle": "Cisco", "home.tutorials.ciscoLogs.shortDescription": "Cisco ASA ファイアウォールからのログを収集・解析します。", @@ -1839,7 +2139,7 @@ "home.tutorials.elasticsearchMetrics.longDescription": "Metricbeat モジュール「elasticsearch」は、Elasticsearch から内部メトリックを取得します。[詳細]({learnMoreLink})。", "home.tutorials.elasticsearchMetrics.nameTitle": "Elasticsearch メトリック", "home.tutorials.elasticsearchMetrics.shortDescription": "Elasticsearch から内部メトリックを取得します。", - "home.tutorials.envoyproxyLogs.artifacts.dashboards.linkLabel": "SIEM アプリ", + "home.tutorials.envoyproxyLogs.artifacts.dashboards.linkLabel": "セキュリティアプリ", "home.tutorials.envoyproxyLogs.longDescription": "これは [Envoy proxy access log](https://www.envoyproxy.io/docs/envoy/v1.10.0/configuration/access_log) 用の Filebeatモジュールです。Kubernetes でのスタンドアロンのデプロイメントと Envoy プロキシデプロイメントの両方をサポートします。[詳細]({learnMoreLink})。", "home.tutorials.envoyproxyLogs.nameTitle": "Envoyproxy", "home.tutorials.envoyproxyLogs.shortDescription": "Envoy プロキシからのログを収集・解析します。", @@ -1854,6 +2154,10 @@ "home.tutorials.golangMetrics.longDescription": "Metricbeat モジュール「{moduleName}」は、Golang アプリから内部メトリックを取得します。[詳細]({learnMoreLink})。", "home.tutorials.golangMetrics.nameTitle": "Golang メトリック", "home.tutorials.golangMetrics.shortDescription": "Golang アプリから内部メトリックを取得します。", + "home.tutorials.googlecloudMetrics.artifacts.dashboards.linkLabel": "Google Cloudメトリックダッシュボード", + "home.tutorials.googlecloudMetrics.longDescription": "「googlecloud」Metricbeatモジュールは、Stackdriver Monitoring APIを使用して、Google Cloud Platformから監視メトリックを取得します。[詳細]({learnMoreLink})。", + "home.tutorials.googlecloudMetrics.nameTitle": "Google Cloudメトリック", + "home.tutorials.googlecloudMetrics.shortDescription": "Stackdriver Monitoring APIを使用して、Google Cloud Platformから監視メトリックを取得します。", "home.tutorials.haproxyMetrics.artifacts.application.label": "発見", "home.tutorials.haproxyMetrics.longDescription": "Metricbeat モジュール「haproxy」は、HAProxy アプリから内部メトリックを取得します。[詳細]({learnMoreLink})。", "home.tutorials.haproxyMetrics.nameTitle": "HAProxy メトリック", @@ -1870,7 +2174,11 @@ "home.tutorials.iisLogs.longDescription": "「iis」Filebeat モジュールが、Nginx HTTP サーバーにより作成されたアクセスとエラーのログをパースします。[詳細]({learnMoreLink})。", "home.tutorials.iisLogs.nameTitle": "IIS ログ", "home.tutorials.iisLogs.shortDescription": "IIS HTTP サーバーにより作成されたアクセスとエラーのログを収集しパースします。", - "home.tutorials.iptablesLogs.artifacts.dashboards.linkLabel": "SIEM アプリ", + "home.tutorials.iisMetrics.artifacts.dashboards.linkLabel": "IISメトリックダッシュボード", + "home.tutorials.iisMetrics.longDescription": "「iis」Metricbeatモジュールは、IISサーバーおよび実行中のアプリケーションプールとWebサイトからメトリックを収集します。[詳細]({learnMoreLink})。", + "home.tutorials.iisMetrics.nameTitle": "IISメトリック", + "home.tutorials.iisMetrics.shortDescription": "IISサーバー関連メトリックを収集します。", + "home.tutorials.iptablesLogs.artifacts.dashboards.linkLabel": "セキュリティアプリ", "home.tutorials.iptablesLogs.longDescription": "これは iptables と ip6tables ログ用のモジュールです。ネットワーク上で受信した syslog ログ経由や、ファイルからのログをパースします。また、ルールセット名、ルール番号、トラフィックに実行されたアクション (許可/拒否) を含む、Ubiquiti ファイアウォールにより追加された接頭辞も認識できます。[詳細]({learnMoreLink})。", "home.tutorials.iptablesLogs.nameTitle": "Iptables / Ubiquiti", "home.tutorials.iptablesLogs.shortDescription": "iptables と ip6tables ログ、または Ubiqiti からのログを収集・解析します。", @@ -1970,6 +2278,10 @@ "home.tutorials.openmetricsMetrics.longDescription": "Metricbeat モジュール「openmetrics」は、OpenMetrics の形式でメトリックを提供するエンドポイントからメトリックをフェッチします。[詳細]({learnMoreLink})。", "home.tutorials.openmetricsMetrics.nameTitle": "OpenMetrics メトリック", "home.tutorials.openmetricsMetrics.shortDescription": "OpenMetrics 形式でメトリックを提供するエンドポイントからメトリックを取得します。", + "home.tutorials.oracleMetrics.artifacts.application.label": "発見", + "home.tutorials.oracleMetrics.longDescription": "「{moduleName}」Metricbeatモジュールは、Oracleサーバーから内部メトリックを取得します。[詳細]({learnMoreLink})。", + "home.tutorials.oracleMetrics.nameTitle": "Oracleメトリック", + "home.tutorials.oracleMetrics.shortDescription": "Oracleサーバーから内部メトリックを取得します。", "home.tutorials.osqueryLogs.artifacts.dashboards.linkLabel": "Osquery ログダッシュボード", "home.tutorials.osqueryLogs.longDescription": "「osquery」Filebeat モジュールは、「osqueryd」が作成した JSON 結果ページを収集します。[詳細]({learnMoreLink})。", "home.tutorials.osqueryLogs.nameTitle": "Osquery ログ", @@ -2060,10 +2372,306 @@ "home.tutorials.zookeeperMetrics.shortDescription": "Zookeeper サーバーから内部メトリックを取得します。", "home.welcomeHomePageHeader": "Kibana ホーム", "home.welcomeTitle": "Elasticへようこそ", + "indexPatternManagement.actions.cancelButton": "キャンセル", + "indexPatternManagement.actions.createButton": "フィールドを作成", + "indexPatternManagement.actions.deleteButton": "削除", + "indexPatternManagement.actions.saveButton": "フィールドを保存", + "indexPatternManagement.aliasLabel": "エイリアス", + "indexPatternManagement.color.actions": "アクション", + "indexPatternManagement.color.addColorButton": "色を追加", + "indexPatternManagement.color.backgroundLabel": "背景色", + "indexPatternManagement.color.deleteAria": "削除", + "indexPatternManagement.color.deleteTitle": "色のフォーマットを削除", + "indexPatternManagement.color.exampleLabel": "例", + "indexPatternManagement.color.patternLabel": "パターン(正規表現)", + "indexPatternManagement.color.rangeLabel": "範囲(min:max)", + "indexPatternManagement.color.textColorLabel": "文字の色", + "indexPatternManagement.createHeader": "スクリプトフィールドを作成", + "indexPatternManagement.createIndexPattern.betaLabel": "ベータ", + "indexPatternManagement.createIndexPattern.description": "インデックスパターンは、{single}または{multiple}データソース、{star}と一致します。", + "indexPatternManagement.createIndexPattern.documentation": "ドキュメンテーションを表示", + "indexPatternManagement.createIndexPattern.emptyState.checkDataButton": "新規データを確認", + "indexPatternManagement.createIndexPattern.emptyStateHeader": "Elasticsearchデータが見つかりませんでした", + "indexPatternManagement.createIndexPattern.emptyStateLabel.emptyStateDetail": "{needToIndex} {learnHowLink}または{getStartedLink}", + "indexPatternManagement.createIndexPattern.emptyStateLabel.getStartedLink": "サンプルデータで始めましょう。", + "indexPatternManagement.createIndexPattern.emptyStateLabel.learnHowLink": "方法を学習", + "indexPatternManagement.createIndexPattern.emptyStateLabel.needToIndexLabel": "インデックスパターンを作成する前に、Elasticsearchへのデータのインデックスが必要です。", + "indexPatternManagement.createIndexPattern.includeSystemIndicesToggleSwitchLabel": "システムと非表示のインデックスを含める", + "indexPatternManagement.createIndexPattern.loadClustersFailMsg": "リモートクラスターの読み込みに失敗", + "indexPatternManagement.createIndexPattern.loadIndicesFailMsg": "インデックスの読み込みに失敗", + "indexPatternManagement.createIndexPattern.loadingState.checkingLabel": "Elasticsearchデータを確認中", + "indexPatternManagement.createIndexPattern.step.indexPattern.allowLabel": "複数インデックスの一致にアスタリスク({asterisk})を使用。", + "indexPatternManagement.createIndexPattern.step.indexPattern.disallowLabel": "スペースと{characterList}は使用できません。", + "indexPatternManagement.createIndexPattern.step.indexPatternLabel": "インデックスパターン名", + "indexPatternManagement.createIndexPattern.step.indexPatternPlaceholder": "index-name-*", + "indexPatternManagement.createIndexPattern.step.invalidCharactersErrorMessage": "{indexPatternName}にはスペースや{characterList}は使えません。", + "indexPatternManagement.createIndexPattern.step.loadingHeader": "一致するインデックスを検索中…", + "indexPatternManagement.createIndexPattern.step.loadingLabel": "お待ちください…", + "indexPatternManagement.createIndexPattern.step.nextStepButton": "次のステップ", + "indexPatternManagement.createIndexPattern.step.pagingLabel": "ページごとの行数: {perPage}", + "indexPatternManagement.createIndexPattern.step.status.matchAnyLabel.matchAnyDetail": "インデックスパターンは、{sourceCount, plural, one {個のソース} other {個のソース} }と一致します。", + "indexPatternManagement.createIndexPattern.step.status.noSystemIndicesLabel": "パターンに一致するElasticsearchインデックスがありません。", + "indexPatternManagement.createIndexPattern.step.status.noSystemIndicesWithPromptLabel": "パターンに一致するElasticsearchインデックスがありません。一致するシステムインデックスを表示するには、上のスイッチを切り替えます。", + "indexPatternManagement.createIndexPattern.step.status.notMatchLabel.allIndicesLabel": "{indicesLength, plural, one {# インデックス} other {# インデックス}}", + "indexPatternManagement.createIndexPattern.step.status.notMatchLabel.notMatchDetail": "入力されたインデックスパターンがどのインデックスにも一致しません。以下で、{indicesLength, plural, one {個の} other {個の} } {strongIndices}と一致します。", + "indexPatternManagement.createIndexPattern.step.status.partialMatchLabel.partialMatchDetail": "インデックスパターンがどのインデックスとも一致ませんが、似た{matchedIndicesLength, plural, one {ように思われる} other {ように思われる} }{strongIndices}があります。", + "indexPatternManagement.createIndexPattern.step.status.partialMatchLabel.strongIndicesLabel": "{matchedIndicesLength, plural, one {インデックス} other {# インデックス} }", + "indexPatternManagement.createIndexPattern.step.status.successLabel.successDetail": "インデックスパターンは、{sourceCount} {sourceCount, plural, one {個のソース} other {個のソース} }と一致します。", + "indexPatternManagement.createIndexPattern.step.warningHeader": "すでに{query}という名前のインデックスパターンがあります。", + "indexPatternManagement.createIndexPattern.stepHeader": "ステップ1/2:インデックスパターンの定義", + "indexPatternManagement.createIndexPattern.stepTime.backButton": "戻る", + "indexPatternManagement.createIndexPattern.stepTime.createPatternButton": "インデックスパターンを作成", + "indexPatternManagement.createIndexPattern.stepTime.creatingLabel": "インデックスパターンを作成中…", + "indexPatternManagement.createIndexPattern.stepTime.error": "エラー", + "indexPatternManagement.createIndexPattern.stepTime.field.loadingDropDown": "読み込み中...", + "indexPatternManagement.createIndexPattern.stepTime.field.noTimeFieldsLabel": "このインデックスパターンに一致するインデックスには時間フィールドがありません。", + "indexPatternManagement.createIndexPattern.stepTime.fieldLabel": "時間フィールド", + "indexPatternManagement.createIndexPattern.stepTime.noTimeFieldOptionLabel": "時間フィルターを使用しない", + "indexPatternManagement.createIndexPattern.stepTime.noTimeFieldsLabel": "このインデックスパターンに一致するインデックスには時間フィールドがありません。", + "indexPatternManagement.createIndexPattern.stepTime.options.hideButton": "高度なオプションを非表示", + "indexPatternManagement.createIndexPattern.stepTime.options.patternHeader": "カスタムインデックスパターンID", + "indexPatternManagement.createIndexPattern.stepTime.options.patternLabel": "Kibanaはそれぞれのインデックスパターンに固有の識別子を割り当てます。固有のIDを使用しない場合は、カスタムIDを入力してください。", + "indexPatternManagement.createIndexPattern.stepTime.options.patternPlaceholder": "custom-index-pattern-id", + "indexPatternManagement.createIndexPattern.stepTime.options.showButton": "高度なオプションを表示", + "indexPatternManagement.createIndexPattern.stepTime.patterAlreadyExists": "カスタムインデックスパターンIDがすでに存在します。", + "indexPatternManagement.createIndexPattern.stepTime.refreshButton": "更新", + "indexPatternManagement.createIndexPattern.stepTime.timeDescription": "グローバル時間フィルターで使用するためのプライマリ時間フィールドを選択してください。", + "indexPatternManagement.createIndexPattern.stepTimeHeader": "ステップ2/2:設定の構成", + "indexPatternManagement.createIndexPatternHeader": "{indexPatternName}の作成", + "indexPatternManagement.dataStreamLabel": "データストリーム", + "indexPatternManagement.date.documentationLabel": "ドキュメント", + "indexPatternManagement.date.momentLabel": "Moment.jsのフォーマットパターン(デフォルト: {defaultPattern})", + "indexPatternManagement.defaultErrorMessage": "このフォーマット構成の使用を試みた際にエラーが発生しました: {message}", + "indexPatternManagement.defaultFormatDropDown": "- デフォルト -", + "indexPatternManagement.defaultFormatHeader": "フォーマット (デフォルト: {defaultFormat})", + "indexPatternManagement.deleteField.cancelButton": "キャンセル", + "indexPatternManagement.deleteField.deleteButton": "削除", + "indexPatternManagement.deleteField.deletedHeader": "「{fieldName}」が削除されました", + "indexPatternManagement.deleteField.savedHeader": "「{fieldName}」が保存されました", + "indexPatternManagement.deleteFieldHeader": "フィールド「{fieldName}」を削除", + "indexPatternManagement.deleteFieldLabel": "削除されたフィールドは復元できません。{separator}続行してよろしいですか?", + "indexPatternManagement.disabledCallOutHeader": "スクリプティングが無効です", + "indexPatternManagement.disabledCallOutLabel": "Elasticsearchでのすべてのインラインスクリプティングが無効になっています。Kibanaでスクリプトフィールドを使用するには、インラインスクリプティングを有効にする必要があります。", + "indexPatternManagement.duration.decimalPlacesLabel": "小数部分の桁数", + "indexPatternManagement.duration.inputFormatLabel": "インプット形式", + "indexPatternManagement.duration.outputFormatLabel": "アウトプット形式", + "indexPatternManagement.durationErrorMessage": "小数部分の桁数は0から20までの間で指定する必要があります", + "indexPatternManagement.editHeader": "{fieldName}を編集", "indexPatternManagement.editIndexPattern.createIndex.defaultButtonDescription": "すべてのデータに完全アグリゲーションを実行", "indexPatternManagement.editIndexPattern.createIndex.defaultButtonText": "標準インデックスパターン", "indexPatternManagement.editIndexPattern.createIndex.defaultTypeName": "インデックスパターン", + "indexPatternManagement.editIndexPattern.deleteButton": "削除", + "indexPatternManagement.editIndexPattern.deleteHeader": "インデックスパターンを削除しますか?", + "indexPatternManagement.editIndexPattern.detailsAria": "インデックスパターンの詳細", + "indexPatternManagement.editIndexPattern.fields.allLangsDropDown": "すべての言語", + "indexPatternManagement.editIndexPattern.fields.allTypesDropDown": "すべてのフィールドタイプ", + "indexPatternManagement.editIndexPattern.fields.filterAria": "フィールドタイプをフィルター", + "indexPatternManagement.editIndexPattern.fields.filterPlaceholder": "検索", + "indexPatternManagement.editIndexPattern.fields.searchAria": "検索フィールド", + "indexPatternManagement.editIndexPattern.fields.table.additionalInfoAriaLabel": "追加フィールド情報", + "indexPatternManagement.editIndexPattern.fields.table.aggregatableDescription": "これらのフィールドはビジュアライゼーションの集約に使用できます", + "indexPatternManagement.editIndexPattern.fields.table.aggregatableLabel": "集約可能", + "indexPatternManagement.editIndexPattern.fields.table.editDescription": "編集", + "indexPatternManagement.editIndexPattern.fields.table.editLabel": "編集", + "indexPatternManagement.editIndexPattern.fields.table.excludedDescription": "取得の際に_sourceから除外されるフィールドです", + "indexPatternManagement.editIndexPattern.fields.table.excludedLabel": "除外", + "indexPatternManagement.editIndexPattern.fields.table.formatHeader": "フォーマット", + "indexPatternManagement.editIndexPattern.fields.table.isAggregatableAria": "は集約可能です", + "indexPatternManagement.editIndexPattern.fields.table.isExcludedAria": "は除外されています", + "indexPatternManagement.editIndexPattern.fields.table.isSearchableAria": "は検索可能です", + "indexPatternManagement.editIndexPattern.fields.table.multiTypeAria": "複数タイプのフィールド", + "indexPatternManagement.editIndexPattern.fields.table.multiTypeTooltip": "このフィールドのタイプはインデックスごとに変わります。多くの分析機能には使用できません。", + "indexPatternManagement.editIndexPattern.fields.table.nameHeader": "名前", + "indexPatternManagement.editIndexPattern.fields.table.primaryTimeAriaLabel": "プライマリ時間フィールド", + "indexPatternManagement.editIndexPattern.fields.table.primaryTimeTooltip": "このフィールドはイベントの発生時刻を表します。", + "indexPatternManagement.editIndexPattern.fields.table.searchableDescription": "これらのフィールドはフィルターバーで使用できます", + "indexPatternManagement.editIndexPattern.fields.table.searchableHeader": "検索可能", + "indexPatternManagement.editIndexPattern.fields.table.typeHeader": "タイプ", "indexPatternManagement.editIndexPattern.list.defaultIndexPatternListName": "デフォルト", + "indexPatternManagement.editIndexPattern.mappingConflictHeader": "マッピングの矛盾", + "indexPatternManagement.editIndexPattern.mappingConflictLabel": "{conflictFieldsLength, plural, one {フィールド} other {フィールド}}が、このパターンと一致するインデックスの間で異なるタイプ(文字列、整数など)に定義されています。これらの矛盾したフィールドはKibanaの一部で使用できますが、Kibanaがタイプを把握しなければならない機能には使用できません。この問題を修正するにはデータのレンダリングが必要です。", + "indexPatternManagement.editIndexPattern.refreshAria": "フィールドリストを再度読み込みます。", + "indexPatternManagement.editIndexPattern.refreshButton": "更新", + "indexPatternManagement.editIndexPattern.refreshHeader": "フィールドリストを更新しますか?", + "indexPatternManagement.editIndexPattern.refreshLabel": "この操作は各フィールドの使用頻度をリセットします。", + "indexPatternManagement.editIndexPattern.refreshTooltip": "フィールドリストを更新します。", + "indexPatternManagement.editIndexPattern.removeAria": "インデックスパターンを削除します。", + "indexPatternManagement.editIndexPattern.removeTooltip": "インデックスパターンを削除します。", + "indexPatternManagement.editIndexPattern.scripted.addFieldButton": "スクリプトフィールドを追加", + "indexPatternManagement.editIndexPattern.scripted.deleteField.cancelButton": "キャンセル", + "indexPatternManagement.editIndexPattern.scripted.deleteField.deleteButton": "削除", + "indexPatternManagement.editIndexPattern.scripted.deleteFieldLabel": "スクリプトフィールド「{fieldName}」を削除しますか?", + "indexPatternManagement.editIndexPattern.scripted.deprecationLangHeader": "廃止された言語が使用されています", + "indexPatternManagement.editIndexPattern.scripted.deprecationLangLabel.deprecationLangDetail": "次の廃止された言語が使用されています。{deprecatedLangsInUse}これらの言語は、KibanaとElasticsearchの次のメジャーバージョンでサポートされなくなります。問題を避けるため、スクリプトフィールドを{link}に変換してください。", + "indexPatternManagement.editIndexPattern.scripted.deprecationLangLabel.painlessDescription": "Painless", + "indexPatternManagement.editIndexPattern.scripted.newFieldPlaceholder": "新規スクリプトフィールド", + "indexPatternManagement.editIndexPattern.scripted.noFieldLabel": "「{indexPatternTitle}」インデックスパターンには「{fieldName}」というスクリプトフィールドがありません", + "indexPatternManagement.editIndexPattern.scripted.table.deleteDescription": "このフィールドを削除します", + "indexPatternManagement.editIndexPattern.scripted.table.deleteHeader": "削除", + "indexPatternManagement.editIndexPattern.scripted.table.editDescription": "このフィールドを編集します", + "indexPatternManagement.editIndexPattern.scripted.table.editHeader": "編集", + "indexPatternManagement.editIndexPattern.scripted.table.formatDescription": "フィールドに使用されているフォーマットです", + "indexPatternManagement.editIndexPattern.scripted.table.formatHeader": "フォーマット", + "indexPatternManagement.editIndexPattern.scripted.table.langDescription": "フィールドに使用されている言語です", + "indexPatternManagement.editIndexPattern.scripted.table.langHeader": "言語", + "indexPatternManagement.editIndexPattern.scripted.table.nameDescription": "フィールドの名前です", + "indexPatternManagement.editIndexPattern.scripted.table.nameHeader": "名前", + "indexPatternManagement.editIndexPattern.scripted.table.scriptDescription": "フィールドのスクリプトです", + "indexPatternManagement.editIndexPattern.scripted.table.scriptHeader": "スクリプト", + "indexPatternManagement.editIndexPattern.scriptedHeader": "スクリプトフィールド", + "indexPatternManagement.editIndexPattern.scriptedLabel": "ビジュアライゼーションにスクリプトフィールドを使用し、ドキュメントに表示させることができます。但し、スクリプトフィールドは検索できません。", + "indexPatternManagement.editIndexPattern.setDefaultAria": "デフォルトのインデックスに設定します。", + "indexPatternManagement.editIndexPattern.setDefaultTooltip": "デフォルトのインデックスに設定します。", + "indexPatternManagement.editIndexPattern.source.addButtonLabel": "追加", + "indexPatternManagement.editIndexPattern.source.deleteFilter.cancelButtonLabel": "キャンセル", + "indexPatternManagement.editIndexPattern.source.deleteFilter.deleteButtonLabel": "削除", + "indexPatternManagement.editIndexPattern.source.deleteSourceFilterLabel": "ソースフィルター「{value}」を削除しますか?", + "indexPatternManagement.editIndexPattern.source.noteLabel": "下の表で、マルチフィールドが一致として誤って表示されます。これらのフィルターは、オリジナルのソースドキュメントのフィールドのみに適用されるため、一致するマルチフィールドはフィルタリングされません。", + "indexPatternManagement.editIndexPattern.source.table.cancelAria": "キャンセル", + "indexPatternManagement.editIndexPattern.source.table.deleteAria": "削除", + "indexPatternManagement.editIndexPattern.source.table.editAria": "編集", + "indexPatternManagement.editIndexPattern.source.table.filterDescription": "フィルター名", + "indexPatternManagement.editIndexPattern.source.table.filterHeader": "フィルター", + "indexPatternManagement.editIndexPattern.source.table.matchesDescription": "フィールドに使用されている言語です", + "indexPatternManagement.editIndexPattern.source.table.matchesHeader": "一致", + "indexPatternManagement.editIndexPattern.source.table.notMatchedLabel": "ソースフィルターが既知のフィールドと一致しません。", + "indexPatternManagement.editIndexPattern.source.table.saveAria": "保存", + "indexPatternManagement.editIndexPattern.sourceHeader": "ソースフィルター", + "indexPatternManagement.editIndexPattern.sourceLabel": "ソースフィルターは、ドキュメントソースの取得時に1つまたは複数のフィールドを除外するのに使用される場合もあります。これはディスカバリアプリでのドキュメントの表示中、またはダッシュボードアプリの保存された検索の結果を表示する表で起こります。それぞれの行は1つのドキュメントのソースで作成されており、ドキュメントに大きなフィールドや重要ではないフィールドが含まれている場合、この程度の低いレベルでフィルターにより除外すると良いかもしれません。", + "indexPatternManagement.editIndexPattern.sourcePlaceholder": "ソースフィルター、ワイルドカード使用可 (例: 「user」と入力して「user」で始まるフィールドをフィルタリング)", + "indexPatternManagement.editIndexPattern.tabs.fieldsHeader": "フィールド", + "indexPatternManagement.editIndexPattern.tabs.scriptedHeader": "スクリプトフィールド", + "indexPatternManagement.editIndexPattern.tabs.sourceHeader": "ソースフィルター", + "indexPatternManagement.editIndexPattern.timeFilterHeader": "時間フィルターフィールド名:'{timeFieldName}'", + "indexPatternManagement.editIndexPattern.timeFilterLabel.mappingAPILink": "マッピングAPI", + "indexPatternManagement.editIndexPattern.timeFilterLabel.timeFilterDetail": "このページは{indexPatternTitle}インデックス内のすべてのフィールドと、Elasticsearchに記録された各フィールドのコアタイプを一覧表示します。フィールドタイプを変更するにはElasticsearchを使用します", + "indexPatternManagement.editIndexPatternLiveRegionAriaLabel": "インデックスパターン", + "indexPatternManagement.fieldTypeConflict": "フィールドタイプの矛盾", + "indexPatternManagement.formatHeader": "フォーマット", + "indexPatternManagement.formatLabel": "フォーマットは、特定の値の表示形式を管理できます。また、値を完全に変更したり、ディスカバリでのハイライト機能を無効にしたりすることも可能です。", + "indexPatternManagement.frozenLabel": "凍結", + "indexPatternManagement.indexLabel": "インデックス", + "indexPatternManagement.indexNameLabel": "インデックス名", + "indexPatternManagement.indexPattern.goToPatternButtonLabel": "既存のパターンに移動", + "indexPatternManagement.indexPattern.sectionsHeader": "インデックスパターン", + "indexPatternManagement.indexPattern.titleExistsLabel": "「{title}」というタイトルのインデックスパターンがすでに存在します。", + "indexPatternManagement.indexPatternList.createButton.betaLabel": "ベータ", + "indexPatternManagement.indexPatternPrompt.exampleOne": "チャートを作成したりコンテンツを素早くクエリできるように log-west-001 という名前の単一のデータソースをインデックスします。", + "indexPatternManagement.indexPatternPrompt.exampleOneTitle": "単一のデータソース", + "indexPatternManagement.indexPatternPrompt.examplesTitle": "インデックスパターンの例", + "indexPatternManagement.indexPatternPrompt.exampleThree": "比較目的に履歴の動向を集約できるよう、これらのログのアーカイブされた月々のロールアップメトリックスを指定どおりに別々のインデックスパターンにグループ分けします。", + "indexPatternManagement.indexPatternPrompt.exampleThreeTitle": "カスタムグルーピング", + "indexPatternManagement.indexPatternPrompt.exampleTwo": "すべての西海岸のサーバーログに対してクエリを実行できるように、頭に「log-west」の付いたすべての受信データソースをグループ化します。", + "indexPatternManagement.indexPatternPrompt.exampleTwoTitle": "複数データソース", + "indexPatternManagement.indexPatternPrompt.subtitle": "インデックスパターンは、Kibanaで共有フィールドにクエリを実行できるよう、種類の異なるデータソースをバケットにまとめることができます。", + "indexPatternManagement.indexPatternPrompt.title": "インデックスパターンについて", + "indexPatternManagement.indexPatterns.badge.readOnly.text": "読み取り専用", + "indexPatternManagement.indexPatterns.badge.readOnly.tooltip": "インデックスパターンを保存できません", + "indexPatternManagement.indexPatterns.createBreadcrumb": "インデックスパターンを作成", + "indexPatternManagement.indexPatterns.createFieldBreadcrumb": "フィールドを作成", + "indexPatternManagement.indexPatterns.listBreadcrumb": "インデックスパターン", + "indexPatternManagement.indexPatternTable.createBtn": "インデックスパターンを作成", + "indexPatternManagement.indexPatternTable.title": "インデックスパターン", + "indexPatternManagement.labelTemplate.example.idLabel": "ユーザー#{value}", + "indexPatternManagement.labelTemplate.example.output.idLabel": "ユーザー", + "indexPatternManagement.labelTemplate.example.output.pathLabel": "アセットを表示", + "indexPatternManagement.labelTemplate.example.pathLabel": "アセットを表示", + "indexPatternManagement.labelTemplate.examplesHeader": "例", + "indexPatternManagement.labelTemplate.inputHeader": "インプット", + "indexPatternManagement.labelTemplate.labelHeader": "ラベルテンプレート", + "indexPatternManagement.labelTemplate.outputHeader": "アウトプット", + "indexPatternManagement.labelTemplate.urlHeader": "URLテンプレート", + "indexPatternManagement.labelTemplate.urlLabel": "フォーマット済みURL", + "indexPatternManagement.labelTemplate.valueLabel": "フィールド値", + "indexPatternManagement.labelTemplateHeader": "ラベルテンプレート", + "indexPatternManagement.labelTemplateLabel": "このフィールドのURLが長い場合、URLのテキストバージョン用の代替テンプレートを使用すると良いかもしれません。URLの代わりに表示されますが、URLにリンクされます。このフォーマットは、値の投入に二重中括弧の表記{doubleCurlyBraces}を使用する文字列です。次の値にアクセスできます。", + "indexPatternManagement.languageLabel": "言語", + "indexPatternManagement.mappingConflictLabel.mappingConflictDetail": "{mappingConflict} {fieldName}というフィールドはすでに存在します。スクリプトフィールドに同じ名前を付けると、同時に両方のフィールドにクエリが実行できなくなります。", + "indexPatternManagement.mappingConflictLabel.mappingConflictLabel": "マッピングの矛盾:", + "indexPatternManagement.multiTypeLabelDesc": "このフィールドのタイプはインデックスごとに変わります。多くの分析機能には使用できません。タイプごとのインデックスは次のとおりです。", + "indexPatternManagement.nameErrorMessage": "名前が必要です", + "indexPatternManagement.nameLabel": "名前", + "indexPatternManagement.namePlaceholder": "新規スクリプトフィールド", + "indexPatternManagement.number.documentationLabel": "ドキュメント", + "indexPatternManagement.number.numeralLabel": "Numeral.js のフォーマットパターン (デフォルト: {defaultPattern})", + "indexPatternManagement.popularityLabel": "利用頻度", + "indexPatternManagement.samples.inputHeader": "インプット", + "indexPatternManagement.samples.outputHeader": "アウトプット", + "indexPatternManagement.samplesHeader": "サンプル", + "indexPatternManagement.script.accessWithLabel": "{code} でフィールドにアクセスします。", + "indexPatternManagement.script.getHelpLabel": "構文のヒントを得たり、スクリプトの結果をプレビューしたりできます。", + "indexPatternManagement.scriptingLanguages.errorFetchingToastDescription": "Elasticsearchから利用可能なスクリプト言語の取得中にエラーが発生しました", + "indexPatternManagement.scriptInvalidErrorMessage": "スクリプトが無効です。詳細については、スクリプトプレビューを表示してください", + "indexPatternManagement.scriptLabel": "スクリプト", + "indexPatternManagement.scriptRequiredErrorMessage": "スクリプトが必要です", + "indexPatternManagement.staticLookup.actions": "アクション", + "indexPatternManagement.staticLookup.addEntryButton": "エントリーを追加", + "indexPatternManagement.staticLookup.deleteAria": "削除", + "indexPatternManagement.staticLookup.deleteTitle": "エントリーの削除", + "indexPatternManagement.staticLookup.keyLabel": "キー", + "indexPatternManagement.staticLookup.leaveBlankPlaceholder": "値をそのままにするには空欄にします", + "indexPatternManagement.staticLookup.unknownKeyLabel": "不明なキーの値", + "indexPatternManagement.staticLookup.valueLabel": "値", + "indexPatternManagement.string.transformLabel": "変換", + "indexPatternManagement.syntax.default.formatLabel": "doc['some_field'].value", + "indexPatternManagement.syntax.defaultLabel.defaultDetail": "デフォルトで、KibanaのスクリプトフィールドはElasticsearchでの使用を目的に特別に開発されたシンプルでセキュアなスクリプト言語の{painless}を使用します。ドキュメントの値にアクセスするには次のフォーマットを使用します。", + "indexPatternManagement.syntax.defaultLabel.painlessLink": "Painless", + "indexPatternManagement.syntax.kibanaLabel": "現在、Kibanaでは、作成するPainlessスクリプトに特別な制限が1つ設定されています。Named関数を含めることができません。", + "indexPatternManagement.syntax.lucene.commonLabel.commonDetail": "Kibanaの旧バージョンからのアップグレードですか?おなじみの{lucene}は引き続きご利用いただけます。Lucene式はJavaScriptと非常に似ていますが、基本的な計算、ビット処理、比較オペレーション用に開発されたものです。", + "indexPatternManagement.syntax.lucene.commonLabel.luceneLink": "Lucene表現", + "indexPatternManagement.syntax.lucene.limits.fieldsLabel": "格納されたフィールドは利用できません", + "indexPatternManagement.syntax.lucene.limits.sparseLabel": "フィールドがまばらな (ドキュメントの一部にしか値がない) 場合、値がないドキュメントには 0 の値が入力されます", + "indexPatternManagement.syntax.lucene.limits.typesLabel": "数字、ブール、日付、geo_pointフィールドのみアクセスできます", + "indexPatternManagement.syntax.lucene.limitsLabel": "Lucene表現には次のいくつかの制限があります。", + "indexPatternManagement.syntax.lucene.operations.arithmeticLabel": "算術演算子: {operators}", + "indexPatternManagement.syntax.lucene.operations.bitwiseLabel": "ビット処理演算子: {operators}", + "indexPatternManagement.syntax.lucene.operations.booleanLabel": "ブール演算子 (三項演算子を含む): {operators}", + "indexPatternManagement.syntax.lucene.operations.comparisonLabel": "比較演算子: {operators}", + "indexPatternManagement.syntax.lucene.operations.distanceLabel": "距離関数: {operators}", + "indexPatternManagement.syntax.lucene.operations.mathLabel": "一般的な関数: {operators}", + "indexPatternManagement.syntax.lucene.operations.miscellaneousLabel": "その他関数: {operators}", + "indexPatternManagement.syntax.lucene.operations.trigLabel": "三角ライブラリ関数: {operators}", + "indexPatternManagement.syntax.lucene.operationsLabel": "Lucene表現で利用可能なオペレーションは次のとおりです。", + "indexPatternManagement.syntax.painlessLabel.javaAPIsLink": "ネイティブJava API", + "indexPatternManagement.syntax.painlessLabel.painlessDetail": "Painlessは非常に強力かつ使いやすい言語です。多くの{javaAPIs}にアクセスすることができます。{syntax}について読めば、すぐに習得することができます!", + "indexPatternManagement.syntax.painlessLabel.syntaxLink": "構文", + "indexPatternManagement.syntaxHeader": "構文", + "indexPatternManagement.testScript.errorMessage": "スクリプト内にエラーがあります", + "indexPatternManagement.testScript.fieldsLabel": "追加フィールド", + "indexPatternManagement.testScript.fieldsPlaceholder": "選択してください…", + "indexPatternManagement.testScript.instructions": "スクリプトを実行すると、最初の検索結果10件をプレビューできます。追加フィールドを選択して結果に含み、コンテクストをさらに加えたり、特定の文書上でフィルタにクエリを追加したりすることもできます。", + "indexPatternManagement.testScript.resultsLabel": "最初の10件", + "indexPatternManagement.testScript.resultsTitle": "結果を表示", + "indexPatternManagement.testScript.submitButtonLabel": "スクリプトを実行", + "indexPatternManagement.truncate.lengthLabel": "フィールドの長さ", + "indexPatternManagement.typeLabel": "タイプ", + "indexPatternManagement.url.heightLabel": "高さ", + "indexPatternManagement.url.labelTemplateHelpText": "ラベルテンプレートのヘルプ", + "indexPatternManagement.url.labelTemplateLabel": "ラベルテンプレート", + "indexPatternManagement.url.offLabel": "オフ", + "indexPatternManagement.url.onLabel": "オン", + "indexPatternManagement.url.openTabLabel": "新規タブで開く", + "indexPatternManagement.url.template.helpLinkText": "URLテンプレートのヘルプ", + "indexPatternManagement.url.typeLabel": "タイプ", + "indexPatternManagement.url.urlTemplateLabel": "URLテンプレート", + "indexPatternManagement.url.widthLabel": "幅", + "indexPatternManagement.urlTemplate.examplesHeader": "例", + "indexPatternManagement.urlTemplate.inputHeader": "インプット", + "indexPatternManagement.urlTemplate.outputHeader": "アウトプット", + "indexPatternManagement.urlTemplate.rawValueLabel": "非エスケープ値", + "indexPatternManagement.urlTemplate.templateHeader": "テンプレート", + "indexPatternManagement.urlTemplate.valueLabel": "URLエスケープ値", + "indexPatternManagement.urlTemplateHeader": "URLテンプレート", + "indexPatternManagement.urlTemplateLabel.fieldDetail": "フィールドにURLの一部のみが含まれている場合、{strongUrlTemplate}でその値を完全なURLとしてフォーマットできます。このフォーマットは、値の投入に二重中括弧の表記{doubleCurlyBraces}を使用する文字列です。次の値にアクセスできます。", + "indexPatternManagement.urlTemplateLabel.strongUrlTemplateLabel": "URLテンプレート", + "indexPatternManagement.warningCallOut.descriptionLabel": "計算値の表示と集約にスクリプトフィールドが使用できます。そのため非常に遅い場合があり、適切に行わないとKibanaが使用できなくなる可能性もあります。この場合安全策はありません。入力ミスがあると、あちこちに予期せぬ例外が起こります!", + "indexPatternManagement.warningCallOutHeader": "十分ご注意ください", + "indexPatternManagement.warningCallOutLabel.callOutDetail": "スクリプトフィールドを使う前に、{scripFields}と{scriptsInAggregation}についてよく理解するようにしてください。", + "indexPatternManagement.warningCallOutLabel.scripFieldsLink": "スクリプトフィールド", + "indexPatternManagement.warningCallOutLabel.scriptsInAggregationLink": "集約におけるスクリプト", + "indexPatternManagement.warningHeader": "廃止警告:", + "indexPatternManagement.warningLabel.painlessLinkLabel": "Painless", + "indexPatternManagement.warningLabel.warningDetail": "{language}は廃止され、KibanaとElasticsearchの次のメジャーバージョンではサポートされなくなります。新規スクリプトフィールドには{painlessLink}を使うことをお勧めします。", "inputControl.control.noIndexPatternTooltip": "index-pattern id が見つかりませんでした: {indexPatternId}.", "inputControl.control.notInitializedTooltip": "コントロールが初期化されていません", "inputControl.control.noValuesDisableTooltip": "「{indexPatternName}」インデックスパターンでいずれのドキュメントにも存在しない「{fieldName}」フィールドがフィルターの対象になっています。異なるフィールドを選択するか、このフィールドに値が入力されているドキュメントをインデックスしてください。", @@ -2186,6 +2794,8 @@ "kbn.advancedSettings.pageNavigationName": "サイドナビゲーションスタイル", "kbn.advancedSettings.storeUrlText": "URL は長くなりすぎてブラウザが対応できない場合があります。セッションストレージに URL の一部を保存することがで この問題に対処できるかテストしています。結果を教えてください!", "kbn.advancedSettings.storeUrlTitle": "セッションストレージに URL を格納", + "kbn.advancedSettings.themeVersionText": "現在のバージョンと次のバージョンのKibanaで使用されるテーマを切り替えます。この設定を適用するにはページの更新が必要です。", + "kbn.advancedSettings.themeVersionTitle": "テーマバージョン", "kbn.advancedSettings.timepicker.timeDefaultsText": "時間フィルターが選択されずに Kibana が起動した際に使用される時間フィルターです", "kbn.advancedSettings.timepicker.timeDefaultsTitle": "デフォルトのタイムピッカー", "kbn.advancedSettings.visualization.showRegionMapWarningsText": "用語がマップの形に合わない場合に地域マップに警告を表示するかどうかです。", @@ -2223,6 +2833,8 @@ "kibana-react.tableListView.listing.deleteSelectedItemsConfirmModal.cancelButtonLabel": "キャンセル", "kibana-react.tableListView.listing.deleteSelectedItemsConfirmModal.confirmButtonLabel": "削除", "kibana-react.tableListView.listing.deleteSelectedItemsConfirmModal.confirmButtonLabelDeleting": "削除中", + "kibana-react.tableListView.listing.fetchErrorDescription": "{entityName}リストを取得できませんでした。{message}", + "kibana-react.tableListView.listing.fetchErrorTitle": "リストを取得できませんでした", "kibana-react.tableListView.listing.listingLimitExceeded.advancedSettingsLinkText": "高度な設定", "kibana-react.tableListView.listing.listingLimitExceededDescription": "{totalItems} 件の {entityNamePlural} がありますが、{listingLimitText} の設定により {listingLimitValue} 件までしか下の表に表示できません。この設定は {advancedSettingsLink} で変更できます。{advancedSettingsLink} の下でこの設定を変更できます。", "kibana-react.tableListView.listing.listingLimitExceededTitle": "リスティング制限超過", @@ -2233,10 +2845,26 @@ "kibana-react.tableListView.listing.table.editActionName": "編集", "kibana-react.tableListView.listing.unableToDeleteDangerMessage": "{entityName} を削除できません", "management.breadcrumb": "スタック管理", + "management.landing.header": "Stack Management {version}へようこそ", + "management.landing.subhead": "インデックス、インデックスパターン、保存されたオブジェクト、Kibanaの設定、その他を管理します。", + "management.landing.text": "アプリの一覧は左側のメニューにあります。", "management.nav.label": "管理", "management.nav.menu": "管理メニュー", + "management.sections.dataTip": "クラスターデータとバックアップを管理します", + "management.sections.dataTitle": "データ", + "management.sections.ingestTip": "データを変換し、クラスターに読み込む方法を管理します", + "management.sections.ingestTitle": "投入", + "management.sections.insightsAndAlertingTip": "データの変化を検出する方法を管理します", + "management.sections.insightsAndAlertingTitle": "アラートとインサイト", + "management.sections.kibanaTip": "Kibanaをカスタマイズし、保存されたオブジェクトを管理します", + "management.sections.kibanaTitle": "Kibana", + "management.sections.section.tip": "機能とデータへのアクセスを制御します", + "management.sections.section.title": "セキュリティ", + "management.sections.stackTip": "ライセンスを管理し、スタックをアップグレードします", + "management.sections.stackTitle": "スタック", "management.stackManagement.managementDescription": "Elastic Stack の管理を行うセンターコンソールです。", "management.stackManagement.managementLabel": "スタック管理", + "management.stackManagement.title": "スタック管理", "maps_legacy.baseMapsVisualization.childShouldImplementMethodErrorMessage": "子はdata-updateに対応できるようこのメソッドを導入する必要があります", "maps_legacy.kibanaMap.leaflet.fitDataBoundsAriaLabel": "データバウンドを合わせる", "maps_legacy.kibanaMap.zoomWarning": "ズームレベルが最大に達しました。完全にズームインするには、ElasticsearchとKibanaの{defaultDistribution}にアップグレードしてください。{ems}ではより多くのズームレベルを無料で利用できます。または、独自のマップサーバーを構成できます。詳細は、{ wms }または{ configSettings}をご覧ください。", @@ -2288,6 +2916,10 @@ "regionMap.visParams.vectorMapLabel": "ベクトルマップ", "regionMap.visualization.unableToShowMismatchesWarningText": "次の各用語がシェイプの結合フィールドのシェイプと一致することを確認してください: {mismatches}", "regionMap.visualization.unableToShowMismatchesWarningTitle": "{mismatchesLength} {oneMismatch, plural, one { 件の結果} other { 件の結果}}をマップに表示できません", + "savedObjects.advancedSettings.listingLimitText": "一覧ページ用に取得するオブジェクトの数です", + "savedObjects.advancedSettings.listingLimitTitle": "オブジェクト取得制限", + "savedObjects.advancedSettings.perPageText": "読み込みダイアログで表示されるページごとのオブジェクトの数です", + "savedObjects.advancedSettings.perPageTitle": "ページごとのオブジェクト数", "savedObjects.confirmModal.cancelButtonLabel": "キャンセル", "savedObjects.confirmModal.overwriteButtonLabel": "上書き", "savedObjects.confirmModal.overwriteConfirmationMessage": "{title} を上書きしてよろしいですか?", @@ -2443,6 +3075,10 @@ "server.status.redTitle": "赤", "server.status.uninitializedTitle": "アンインストールしました", "server.status.yellowTitle": "黄色", + "share.advancedSettings.csv.quoteValuesText": "csvエクスポートに値を引用するかどうかです", + "share.advancedSettings.csv.quoteValuesTitle": "CSVの値を引用", + "share.advancedSettings.csv.separatorText": "エクスポートされた値をこの文字列で区切ります", + "share.advancedSettings.csv.separatorTitle": "CSVセパレーター", "share.contextMenu.embedCodeLabel": "埋め込みコード", "share.contextMenu.embedCodePanelTitle": "埋め込みコード", "share.contextMenu.permalinkPanelTitle": "パーマリンク", @@ -3107,6 +3743,8 @@ "visTypeTimeseries.addDeleteButtons.deleteButtonDefaultTooltip": "削除", "visTypeTimeseries.addDeleteButtons.reEnableTooltip": "再度有効にする", "visTypeTimeseries.addDeleteButtons.temporarilyDisableTooltip": "一時的に無効にする", + "visTypeTimeseries.advancedSettings.maxBucketsText": "1つのデータソースが返せるバケットの最大数です", + "visTypeTimeseries.advancedSettings.maxBucketsTitle": "バケットの最大数", "visTypeTimeseries.aggLookup.averageLabel": "平均", "visTypeTimeseries.aggLookup.calculationLabel": "計算", "visTypeTimeseries.aggLookup.cardinalityLabel": "基数", @@ -3554,6 +4192,7 @@ "visTypeTimeseries.timeseries.optionsTab.panelOptionsButtonLabel": "パネルオプション", "visTypeTimeseries.timeseries.optionsTab.showLegendLabel": "凡例を表示しますか?", "visTypeTimeseries.timeseries.optionsTab.styleLabel": "スタイル", + "visTypeTimeseries.timeseries.optionsTab.tooltipMode": "ツールチップ", "visTypeTimeseries.timeSeries.overrideIndexPatternLabel": "インデックスパターンを上書きしますか?", "visTypeTimeseries.timeSeries.percentLabel": "パーセント", "visTypeTimeseries.timeseries.positionOptions.leftLabel": "左", @@ -3571,6 +4210,8 @@ "visTypeTimeseries.timeSeries.templateHelpText": "例: {templateExample}", "visTypeTimeseries.timeSeries.templateLabel": "テンプレート", "visTypeTimeseries.timeSeries.toggleSeriesEditorAriaLabel": "数列エディターを切り替える", + "visTypeTimeseries.timeseries.tooltipOptions.showAll": "すべての値を表示", + "visTypeTimeseries.timeseries.tooltipOptions.showFocused": "フォーカスされた値を表示", "visTypeTimeseries.topHit.aggregateWith.selectPlaceholder": "選択してください…", "visTypeTimeseries.topHit.aggregateWithLabel": "アグリゲーション:", "visTypeTimeseries.topHit.aggregationLabel": "集約", @@ -3612,6 +4253,7 @@ "visTypeTimeseries.unsupportedAgg.aggIsNotSupportedDescription": "{modelType} 集約はサポートされなくなりました。", "visTypeTimeseries.unsupportedAgg.aggIsTemporaryUnsupportedDescription": "{modelType} 集約は現在サポートされていません。", "visTypeTimeseries.unsupportedSplit.splitIsUnsupportedDescription": "{modelType} による分割はサポートされていません。", + "visTypeTimeseries.validateInterval.notifier.maxBucketsExceededErrorMessage": "クエリが取得を試みたデータが多すぎます。通常、時間範囲を狭くするか、使用される間隔を変更すると、問題が解決します。", "visTypeTimeseries.vars.variableNameAriaLabel": "変数名", "visTypeTimeseries.vars.variableNamePlaceholder": "変数名", "visTypeTimeseries.visEditorVisualization.applyChangesLabel": "変更を適用", @@ -3680,6 +4322,10 @@ "visTypeVega.visualization.renderErrorTitle": "Vega エラー", "visTypeVega.visualization.unableToFindDefaultIndexErrorMessage": "デフォルトのインデックスが見つかりません", "visTypeVega.visualization.unableToRenderWithoutDataWarningMessage": "データなしにはレンダリングできません", + "visTypeVislib.advancedSettings.visualization.dimmingOpacityText": "チャートの別のエレメントが選択された時に暗くなるチャート項目の透明度です。この数字が小さければ小さいほど、ハイライトされたエレメントが目立ちます。0と1の間の数字で設定します。", + "visTypeVislib.advancedSettings.visualization.dimmingOpacityTitle": "減光透明度", + "visTypeVislib.advancedSettings.visualization.heatmap.maxBucketsText": "1つのデータソースが返せるバケットの最大数です。値が大きいとブラウザのレンダリング速度が下がる可能性があります。", + "visTypeVislib.advancedSettings.visualization.heatmap.maxBucketsTitle": "ヒートマップの最大バケット数", "visTypeVislib.aggResponse.allDocsTitle": "すべてのドキュメント", "visTypeVislib.area.areaDescription": "折れ線グラフの下の数量を強調します。", "visTypeVislib.area.areaTitle": "エリア", @@ -3861,6 +4507,8 @@ "visTypeVislib.vislib.legend.toggleOptionsButtonAriaLabel": "{legendDataLabel}、トグルオプション", "visTypeVislib.vislib.tooltip.fieldLabel": "フィールド", "visTypeVislib.vislib.tooltip.valueLabel": "値", + "visualizations.advancedSettings.visualizeEnableLabsText": "ユーザーが実験的なビジュアライゼーションを作成、表示、編集できるようになります。無効の場合、\n ユーザーは本番準備が整ったビジュアライゼーションのみを利用できます。", + "visualizations.advancedSettings.visualizeEnableLabsTitle": "実験的なビジュアライゼーションを有効にする", "visualizations.disabledLabVisualizationMessage": "ラボビジュアライゼーションを表示するには、高度な設定でラボモードをオンにしてください。", "visualizations.disabledLabVisualizationTitle": "{title} はラボビジュアライゼーションです。", "visualizations.displayName": "ビジュアライゼーション", @@ -3873,6 +4521,7 @@ "visualizations.function.visDimension.formatParams.help": "フォーマットパラメーター", "visualizations.function.visDimension.help": "visConfig ディメンションオブジェクトを生成します", "visualizations.functions.visualization.help": "シンプルなビジュアライゼーションです", + "visualizations.initializeWithoutIndexPatternErrorMessage": "インデックスパターンなしで集約を初期化しようとしています", "visualizations.newVisWizard.betaDescription": "このビジュアライゼーションはベータ段階で、変更される可能性があります。デザインとコードはオフィシャル GA 機能よりも完成度が低く、現状のまま保証なしで提供されています。ベータ機能にはオフィシャル GA 機能の SLA が適用されません", "visualizations.newVisWizard.betaTitle": "ベータ", "visualizations.newVisWizard.chooseSourceTitle": "ソースの選択", @@ -3892,11 +4541,15 @@ "visualizations.newVisWizard.visTypeAliasDescription": "Visualize 外で Kibana アプリケーションを開きます。", "visualizations.newVisWizard.visTypeAliasTitle": "Kibana アプリケーション", "visualizations.savedObjectName": "ビジュアライゼーション", + "visualizations.visualizationTypeInvalidMessage": "無効なビジュアライゼーションタイプ \"{visType}\"", "visualize.badge.readOnly.text": "読み取り専用", "visualize.badge.readOnly.tooltip": "ビジュアライゼーションを保存できません", + "visualize.createVisualization.failedToLoadErrorMessage": "ビジュアライゼーションを読み込めませんでした", "visualize.createVisualization.noIndexPatternOrSavedSearchIdErrorMessage": "indexPatternまたはsavedSearchIdが必要です", + "visualize.createVisualization.noVisTypeErrorMessage": "有効なビジュアライゼーションタイプを指定してください", "visualize.editor.createBreadcrumb": "作成", - "visualize.experimentalVisInfoText": "このビジュアライゼーションは実験的なものです。", + "visualize.error.title": "ビジュアライゼーションエラー", + "visualize.experimentalVisInfoText": "このビジュアライゼーションは実験的なものです。フィードバックがありますか?で問題を報告してください。", "visualize.helpMenu.appName": "可視化", "visualize.linkedToSearch.unlinkSuccessNotificationText": "保存された検索「{searchTitle}」からリンクが解除されました", "visualize.listing.betaTitle": "ベータ", @@ -3913,6 +4566,9 @@ "visualize.listing.table.listTitle": "可視化", "visualize.listing.table.titleColumnName": "タイトル", "visualize.listing.table.typeColumnName": "タイプ", + "visualize.listingPageTitle": "可視化", + "visualize.noMatchRoute.bannerText": "Visualizeアプリケーションはこのルートを認識できません。{route}", + "visualize.noMatchRoute.bannerTitleText": "ページが見つかりません", "visualize.pageHeading": "{chartName} {chartType}可視化", "visualize.topNavMenu.openInspectorButtonAriaLabel": "ビジュアライゼーションのインスペクターを開く", "visualize.topNavMenu.openInspectorButtonLabel": "検査", @@ -3928,6 +4584,7 @@ "visualize.topNavMenu.saveVisualizationDisabledButtonTooltip": "保存する前に変更を適用または破棄", "visualize.topNavMenu.shareVisualizationButtonAriaLabel": "ビジュアライゼーションを共有", "visualize.topNavMenu.shareVisualizationButtonLabel": "共有", + "visualize.visualizationLoadingFailedErrorMessage": "ビジュアライゼーションを読み込めませんでした", "visualize.visualizeDescription": "ビジュアライゼーションを作成してElasticsearchインデックスに保存されたデータをアグリゲーションします。", "visualize.visualizeListingBreadcrumbsTitle": "可視化", "visualize.visualizeListingDeleteErrorTitle": "ビジュアライゼーションの削除中にエラーが発生", @@ -3942,6 +4599,8 @@ "xpack.actions.builtin.case.configuration.emptyMapping": "[casesConfiguration.mapping]:空以外の値が必要ですが空でした", "xpack.actions.builtin.case.connectorApiNullError": "コネクター[apiUrl]が必要です", "xpack.actions.builtin.case.jiraTitle": "Jira", + "xpack.actions.builtin.case.resilientTitle": "IBM Resilient", + "xpack.actions.builtin.configuration.apiWhitelistError": "コネクターアクションの構成エラー:{message}", "xpack.actions.builtin.email.errorSendingErrorMessage": "エラー送信メールアドレス", "xpack.actions.builtin.emailTitle": "メール", "xpack.actions.builtin.esIndex.errorIndexingErrorMessage": "エラーインデックス作成ドキュメント", @@ -3955,6 +4614,8 @@ "xpack.actions.builtin.pagerdutyTitle": "PagerDuty", "xpack.actions.builtin.serverLog.errorLoggingErrorMessage": "メッセージのロギングエラー", "xpack.actions.builtin.serverLogTitle": "サーバーログ", + "xpack.actions.builtin.servicenow.configuration.emptyMapping": "[incidentConfiguration.mapping]:空以外の値が必要ですが空でした", + "xpack.actions.builtin.servicenowTitle": "ServiceNow", "xpack.actions.builtin.slack.errorPostingErrorMessage": "slack メッセージの投稿エラー", "xpack.actions.builtin.slack.errorPostingRetryDateErrorMessage": "slack メッセージの投稿エラー、 {retryString} に再試行", "xpack.actions.builtin.slack.errorPostingRetryLaterErrorMessage": "slack メッセージの投稿エラー、後ほど再試行", @@ -3969,6 +4630,7 @@ "xpack.actions.builtin.webhook.invalidUsernamePassword": "ユーザーとパスワードの両方を指定する必要があります", "xpack.actions.builtin.webhook.unreachableErrorMessage": "webhookの呼び出しエラー、予期せぬエラー", "xpack.actions.builtin.webhook.webhookConfigurationError": "Web フックアクションの構成中にエラーが発生: {message}", + "xpack.actions.builtin.webhook.webhookConfigurationErrorNoHostname": "Webフックアクションの構成エラーです。URLを解析できません。{err}", "xpack.actions.builtin.webhookTitle": "Web フック", "xpack.actions.disabledActionTypeError": "アクションタイプ \"{actionType}\" は、Kibana 構成 xpack.actions.enabledActionTypes では有効化されません", "xpack.actions.serverSideErrors.expirerdLicenseErrorMessage": "{licenseType} ライセンスの期限が切れたのでアクションタイプ {actionTypeId} は無効です。", @@ -4002,6 +4664,17 @@ "xpack.alertingBuiltins.indexThreshold.maxIntervalsErrorMessage": "間隔 {intervals} の計算値が {maxIntervals} よりも大です", "xpack.alertingBuiltins.indexThreshold.termFieldRequiredErrorMessage": "[termField]: [groupBy] がトップのときには termField が必要です", "xpack.alertingBuiltins.indexThreshold.termSizeRequiredErrorMessage": "[termSize]: [groupBy] がトップのときには termSize が必要です", + "xpack.alerts.alertNavigationRegistry.get.missingNavigationError": "「{consumer}」内のアラートタイプ「{alertType}」のナビゲーションは登録されていません。", + "xpack.alerts.alertNavigationRegistry.register.duplicateDefaultError": "「{consumer}」内のデフォルトナビゲーションはすでに登録されています。", + "xpack.alerts.alertNavigationRegistry.register.duplicateNavigationError": "「{consumer}」内のアラートタイプ「{alertType}」のナビゲーションはすでに登録されています。", + "xpack.alerts.alertsClient.validateActions.invalidGroups": "無効なアクショングループ:{groups}", + "xpack.alerts.alertTypeRegistry.get.missingAlertTypeError": "アラートタイプ「{id}」は登録されていません。", + "xpack.alerts.alertTypeRegistry.register.duplicateAlertTypeError": "アラートタイプ\"{id}\"はすでに登録されています。", + "xpack.alerts.api.error.disabledApiKeys": "アラートは API キーに依存しますがキーが無効になっているようです", + "xpack.alerts.appName": "アラート", + "xpack.alerts.loadAlertType.missingAlertTypeError": "アラートタイプ「{id}」は登録されていません。", + "xpack.alerts.serverSideErrors.unavailableLicenseInformationErrorMessage": "アラートを利用できません。現在ライセンス情報が利用できません。", + "xpack.apm.addDataButtonLabel": "データの追加", "xpack.apm.agentConfig.allOptionLabel": "すべて", "xpack.apm.agentConfig.apiRequestSize.description": "チャンクエンコーディング(HTTPストリーミング)を経由してAPM ServerインテークAPIに送信されるリクエスト本文の最大合計圧縮サイズ。\nわずかなオーバーシュートの可能性があることに注意してください。\n\n使用できるバイト単位は、「b」、「kb」、「mb」です。「1kb」は「1024b」と等価です。", "xpack.apm.agentConfig.apiRequestSize.label": "API リクエストサイズ", @@ -4112,6 +4785,13 @@ "xpack.apm.agentMetrics.java.threadCountMax": "最高カウント", "xpack.apm.alertTypes.errorRate": "エラー率", "xpack.apm.alertTypes.transactionDuration": "トランザクション期間", + "xpack.apm.anomalyDetection.createJobs.failed.text": "APMサービス環境用に[{environments}]1つ以上の異常検知ジョブを作成しているときに問題が発生しました。エラー: 「{errorMessage}」", + "xpack.apm.anomalyDetection.createJobs.failed.title": "異常検知ジョブを作成できませんでした", + "xpack.apm.anomalyDetection.createJobs.succeeded.text": "APMサービス環境[{environments}]の異常検知ジョブが正常に作成されました。機械学習がトラフィック異常値の分析を開始するには、少し時間がかかります。", + "xpack.apm.anomalyDetection.createJobs.succeeded.title": "異常検知ジョブが作成されました", + "xpack.apm.anomalyDetectionSetup.linkLabel": "異常検知", + "xpack.apm.anomalyDetectionSetup.notEnabledForEnvironmentText": "「{currentEnvironment}」環境では、まだ異常検知が有効ではありません。クリックすると、セットアップを続行します。", + "xpack.apm.anomalyDetectionSetup.notEnabledText": "異常検知はまだ有効ではありません。クリックすると、セットアップを続行します。", "xpack.apm.apmDescription": "アプリケーション内から自動的に詳細なパフォーマンスメトリックやエラーを集めます。", "xpack.apm.applyFilter": "{title} フィルターを適用", "xpack.apm.applyOptions": "オプションを適用", @@ -4122,6 +4802,7 @@ "xpack.apm.breadcrumb.serviceMapTitle": "サービスマップ", "xpack.apm.breadcrumb.servicesTitle": "サービス", "xpack.apm.breadcrumb.settings.agentConfigurationTitle": "エージェントの編集", + "xpack.apm.breadcrumb.settings.anomalyDetection": "異常検知", "xpack.apm.breadcrumb.settings.createAgentConfigurationTitle": "エージェント構成の作成", "xpack.apm.breadcrumb.settings.customizeUI": "UI をカスタマイズ", "xpack.apm.breadcrumb.settings.editAgentConfigurationTitle": "エージェント構成の編集", @@ -4144,6 +4825,7 @@ "xpack.apm.environment.allLabel": "すべて", "xpack.apm.error.prompt.body": "詳細はブラウザの開発者コンソールをご確認ください。", "xpack.apm.error.prompt.title": "申し訳ございませんが、エラーが発生しました :(", + "xpack.apm.errorGroupDetails.avgLabel": "平均", "xpack.apm.errorGroupDetails.culpritLabel": "原因", "xpack.apm.errorGroupDetails.errorGroupTitle": "エラーグループ {errorGroupId}", "xpack.apm.errorGroupDetails.errorOccurrenceTitle": "エラーのオカレンス", @@ -4161,6 +4843,9 @@ "xpack.apm.errorRateAlertTrigger.environment": "環境", "xpack.apm.errorRateAlertTrigger.errors": "エラー", "xpack.apm.errorRateAlertTrigger.isAbove": "の下限は", + "xpack.apm.errorRateChart.avgLabel": "平均", + "xpack.apm.errorRateChart.rateLabel": "レート", + "xpack.apm.errorRateChart.title": "トランザクションエラー率", "xpack.apm.errorsTable.errorMessageAndCulpritColumnLabel": "エラーメッセージと原因", "xpack.apm.errorsTable.groupIdColumnDescription": "スタックトレースのハッシュ。動的パラメータのため、エラーメッセージが異なる場合でも、類似したエラーをグループ化します。", "xpack.apm.errorsTable.groupIdColumnLabel": "グループ ID", @@ -4187,6 +4872,8 @@ "xpack.apm.header.badge.readOnly.text": "読み込み専用", "xpack.apm.header.badge.readOnly.tooltip": "を保存できませんでした", "xpack.apm.helpMenu.upgradeAssistantLink": "アップグレードアシスタント", + "xpack.apm.histogram.plot.noDataLabel": "この時間範囲のデータがありません。", + "xpack.apm.home.rumOverview.title": "リアルユーザー監視", "xpack.apm.home.serviceMapTabLabel": "サービスマップ", "xpack.apm.home.servicesTabLabel": "サービス", "xpack.apm.home.tracesTabLabel": "トレース", @@ -4201,7 +4888,7 @@ "xpack.apm.jvmsTable.noJvmsLabel": "JVM が見つかりませんでした", "xpack.apm.jvmsTable.nonHeapMemoryColumnLabel": "非ヒープ領域の平均", "xpack.apm.jvmsTable.threadCountColumnLabel": "最大スレッド数", - "xpack.apm.kueryBar.disabledPlaceholder": "サービスマップの検索は利用できません", + "xpack.apm.kueryBar.disabledPlaceholder": "ここでは検索は利用できません", "xpack.apm.kueryBar.placeholder": "検索 {event, select,\n トランザクション {transactions}\n メトリック: {metric}\n エラー {errors}\n その他 {transactions, errors and metrics}\n } (E.g. {queryExample})", "xpack.apm.license.betaBadge": "ベータ", "xpack.apm.license.betaTooltipMessage": "現在、この機能はベータです。不具合を見つけた場合やご意見がある場合、サポートに問い合わせるか、またはディスカッションフォーラムにご報告ください。", @@ -4209,12 +4896,18 @@ "xpack.apm.license.title": "無料の 30 日トライアルを開始", "xpack.apm.loadingServiceMap": "サービスマップを読み込み中...多少時間がかかる場合があります。", "xpack.apm.localFilters.titles.agentName": "エージェント名", + "xpack.apm.localFilters.titles.browser": "ブラウザー", "xpack.apm.localFilters.titles.containerId": "コンテナー ID", + "xpack.apm.localFilters.titles.device": "デバイス", "xpack.apm.localFilters.titles.host": "ホスト", + "xpack.apm.localFilters.titles.location": "場所", + "xpack.apm.localFilters.titles.os": "OS", "xpack.apm.localFilters.titles.podName": "Kubernetes ポッド", + "xpack.apm.localFilters.titles.serviceName": "サービス名", "xpack.apm.localFilters.titles.serviceVersion": "サービスバージョン", "xpack.apm.localFilters.titles.transactionResult": "トランザクション結果", "xpack.apm.localFilters.titles.transactionType": "トランザクションタイプ", + "xpack.apm.localFilters.titles.transactionUrl": "Url", "xpack.apm.localFiltersTitle": "各種フィルター", "xpack.apm.metadataTable.section.agentLabel": "エージェント", "xpack.apm.metadataTable.section.clientLabel": "クライアント", @@ -4240,7 +4933,7 @@ "xpack.apm.metrics.pageLoadCharts.avgPageLoadByBrowser": "ブラウザごとの平均ページ読み込み時間の分布", "xpack.apm.metrics.plot.noDataLabel": "この時間範囲のデータがありません。", "xpack.apm.metrics.transactionChart.machineLearningLabel": "機械学習:", - "xpack.apm.metrics.transactionChart.machineLearningTooltip": "平均期間の周りのストリームには予測バウンドが表示されます。異常スコアが >= 75 の場合、注釈が表示されます。", + "xpack.apm.metrics.transactionChart.machineLearningTooltip": "平均期間の周りのストリームには予測バウンドが表示されます。異常スコアが>= 75の場合、注釈が表示されます。", "xpack.apm.metrics.transactionChart.pageLoadTimesLabel": "ページ読み込み時間", "xpack.apm.metrics.transactionChart.requestsPerMinuteLabel": "1 分あたりのリクエスト", "xpack.apm.metrics.transactionChart.routeChangeTimesLabel": "ルート変更時間", @@ -4257,6 +4950,20 @@ "xpack.apm.registerErrorRateAlertType.variables.serviceName": "サービス名", "xpack.apm.registerTransactionDurationAlertType.variables.serviceName": "サービス名", "xpack.apm.registerTransactionDurationAlertType.variables.transactionType": "トランザクションタイプ", + "xpack.apm.rum.dashboard.backend": "バックエンド", + "xpack.apm.rum.dashboard.dateTime.label": "日付/時刻", + "xpack.apm.rum.dashboard.frontend": "フロントエンド", + "xpack.apm.rum.dashboard.overall.label": "全体", + "xpack.apm.rum.dashboard.pageLoadDistribution.label": "ページ読み込み分布", + "xpack.apm.rum.dashboard.pageLoadTime.label": "ページ読み込み時間(秒)", + "xpack.apm.rum.dashboard.pageLoadTimes.label": "ページ読み込み時間", + "xpack.apm.rum.dashboard.pagesLoaded.label": "ページが読み込まれました", + "xpack.apm.rum.dashboard.pageViews": "ページビュー", + "xpack.apm.rum.dashboard.resetZoom.label": "ズームをリセット", + "xpack.apm.rum.filterGroup.breakdown": "内訳", + "xpack.apm.rum.filterGroup.seconds": "秒", + "xpack.apm.rum.filterGroup.selectBreakdown": "内訳を選択", + "xpack.apm.rum.visitorBreakdown": "アクセスユーザー内訳", "xpack.apm.searchInput.filter": "フィルター...", "xpack.apm.selectPlaceholder": "オプションを選択:", "xpack.apm.serviceDetails.alertsMenu.alerts": "アラート", @@ -4271,14 +4978,23 @@ "xpack.apm.serviceDetails.metricsTabLabel": "メトリック", "xpack.apm.serviceDetails.nodesTabLabel": "JVM", "xpack.apm.serviceDetails.transactionsTabLabel": "トランザクション", + "xpack.apm.serviceMap.anomalyDetectionPopoverDisabled": "APM設定で異常検知を有効にすると、サービス正常性インジケーターが表示されます。", + "xpack.apm.serviceMap.anomalyDetectionPopoverLink": "異常を表示", + "xpack.apm.serviceMap.anomalyDetectionPopoverNoData": "選択した時間範囲で、異常スコアを検出できませんでした。異常エクスプローラーで詳細を確認してください。", + "xpack.apm.serviceMap.anomalyDetectionPopoverScoreMetric": "スコア(最大)", + "xpack.apm.serviceMap.anomalyDetectionPopoverTitle": "異常検知", + "xpack.apm.serviceMap.anomalyDetectionPopoverTooltip": "サービス正常性インジケーターは、機械学習の異常検知に基づいています。", + "xpack.apm.serviceMap.avgReqPerMinutePopoverMetric": "1分あたりのリクエスト(平均)", "xpack.apm.serviceMap.betaBadge": "ベータ", "xpack.apm.serviceMap.betaTooltipMessage": "現在、この機能はベータです。不具合を見つけた場合やご意見がある場合、サポートに問い合わせるか、またはディスカッションフォーラムにご報告ください。", "xpack.apm.serviceMap.center": "中央", + "xpack.apm.serviceMap.download": "ダウンロード", "xpack.apm.serviceMap.emptyBanner.docsLink": "詳細はドキュメントをご覧ください", "xpack.apm.serviceMap.emptyBanner.message": "接続されているサービスや外部リクエストを検出できる場合、システムはそれらをマップします。最新版の APM エージェントが動作していることを確認してください。", "xpack.apm.serviceMap.emptyBanner.title": "単一のサービスしかないようです。", "xpack.apm.serviceMap.focusMapButtonText": "焦点マップ", "xpack.apm.serviceMap.invalidLicenseMessage": "サービスマップを利用するには、Elastic Platinum ライセンスが必要です。これにより、APM データとともにアプリケーションスタック全てを可視化することができるようになります。", + "xpack.apm.serviceMap.popoverMetrics.noDataText": "選択した環境のデータがありません。別の環境に切り替えてください。", "xpack.apm.serviceMap.serviceDetailsButtonText": "サービス詳細", "xpack.apm.serviceMap.viewFullMap": "サービスの全体マップを表示", "xpack.apm.serviceMap.zoomIn": "ズームイン", @@ -4309,6 +5025,28 @@ "xpack.apm.servicesTable.UpgradeAssistantLink": "Kibana アップグレードアシスタントで詳細をご覧ください", "xpack.apm.serviceVersion": "サービスバージョン", "xpack.apm.settings.agentConfig": "エージェントの編集", + "xpack.apm.settings.anomaly_detection.legacy_jobs.body": "以前の統合のレガシー機械学習ジョブが見つかりました。これは、APMアプリでは使用されていません。", + "xpack.apm.settings.anomaly_detection.legacy_jobs.button": "ジョブの確認", + "xpack.apm.settings.anomaly_detection.legacy_jobs.title": "レガシーMLジョブはAPMアプリで使用されていません。", + "xpack.apm.settings.anomaly_detection.license.text": "異常検知を使用するには、Elastic Platinumライセンスのサブスクリプションが必要です。このライセンスがあれば、機械学習を活用して、サービスを監視できます。", + "xpack.apm.settings.anomalyDetection": "異常検知", + "xpack.apm.settings.anomalyDetection.addEnvironments.cancelButtonText": "キャンセル", + "xpack.apm.settings.anomalyDetection.addEnvironments.createJobsButtonText": "ジョブの作成", + "xpack.apm.settings.anomalyDetection.addEnvironments.descriptionText": "異常検知を有効にするサービス環境を選択してください。異常は選択した環境内のすべてのサービスとトランザクションタイプで表面化します。", + "xpack.apm.settings.anomalyDetection.addEnvironments.selectorLabel": "環境", + "xpack.apm.settings.anomalyDetection.addEnvironments.selectorPlaceholder": "環境を選択または追加", + "xpack.apm.settings.anomalyDetection.addEnvironments.titleText": "環境を選択", + "xpack.apm.settings.anomalyDetection.descriptionText": "機械学習異常検知統合により、トランザクション期間の異常を特定することで、サービスマップの各構成された環境で、アプリケーション正常性ステータスインジケーターが有効になります。", + "xpack.apm.settings.anomalyDetection.jobList.actionColumnLabel": "アクション", + "xpack.apm.settings.anomalyDetection.jobList.addEnvironments": "MLジョブを作成", + "xpack.apm.settings.anomalyDetection.jobList.emptyListText": "異常検知ジョブがありません。", + "xpack.apm.settings.anomalyDetection.jobList.environmentColumnLabel": "環境", + "xpack.apm.settings.anomalyDetection.jobList.environments": "環境", + "xpack.apm.settings.anomalyDetection.jobList.failedFetchText": "異常検知ジョブを取得できませんでした。", + "xpack.apm.settings.anomalyDetection.jobList.mlDescriptionText": "異常検知を新しい環境に追加するには、機械学習ジョブを作成します。既存の機械学習ジョブは、{mlJobsLink}で管理できます。", + "xpack.apm.settings.anomalyDetection.jobList.mlDescriptionText.mlJobsLinkText": "機械学習", + "xpack.apm.settings.anomalyDetection.jobList.mlJobLinkText": "MLでジョブを表示", + "xpack.apm.settings.anomalyDetection.titleText": "異常検知", "xpack.apm.settings.apmIndices.applyButton": "変更を適用", "xpack.apm.settings.apmIndices.applyChanges.failed.text": "インデックスの適用時に何か問題が発生しました。エラー: {errorMessage}", "xpack.apm.settings.apmIndices.applyChanges.failed.title": "インデックスが適用できませんでした。", @@ -4415,6 +5153,9 @@ "xpack.apm.transactionActionMenu.viewSampleDocumentLinkLabel": "サンプルドキュメントを表示", "xpack.apm.transactionBreakdown.chartTitle": "スパンタイプ別時間", "xpack.apm.transactionBreakdown.noData": "この時間範囲のデータがありません。", + "xpack.apm.transactionCardinalityWarning.body": "一意のトランザクション名の数が構成された値{bucketSize}を超えています。エージェントを再構成し、類似したトランザクションをグループ化するか、{codeBlock}の値を増やしてください。", + "xpack.apm.transactionCardinalityWarning.docsLink": "詳細はドキュメントをご覧ください", + "xpack.apm.transactionCardinalityWarning.title": "このビューには、報告されたトランザクションのサブセットが表示されます。", "xpack.apm.transactionDetails.errorCount": "{errorCount, number} {errorCount, plural, one {件のエラー} other {件のエラー}}", "xpack.apm.transactionDetails.errorsOverviewLinkTooltip": "{errorCount, plural, one {1 件の関連エラーを表示} other {# 件の関連エラーを表示}}", "xpack.apm.transactionDetails.notFoundLabel": "トランザクションが見つかりませんでした。", @@ -4546,7 +5287,7 @@ "xpack.beatsManagement.breadcrumb.beatTags": "{beatId} のビートタグ", "xpack.beatsManagement.breadcrumb.configurationTags": "構成タグ", "xpack.beatsManagement.breadcrumb.enrolledBeats": "登録済みのビート", - "xpack.beatsManagement.centralManagementLinkLabel": "集中管理", + "xpack.beatsManagement.centralManagementLinkLabel": "Beatsの集中管理", "xpack.beatsManagement.config.other.error": "有効な YAML フォーマットを使用してください", "xpack.beatsManagement.config.otherConfigDescription": "YAML フォーマットで Filebeat インプットの他の設定を指定します", "xpack.beatsManagement.config.otherConfigLabel": "他の構成", @@ -5192,10 +5933,25 @@ "xpack.canvas.keyboardShortcutsDoc.flyout.closeButtonAriaLabel": "キーボードショートカットリファレンスを作成", "xpack.canvas.keyboardShortcutsDoc.flyoutHeaderTitle": "キーボードショートカット", "xpack.canvas.keyboardShortcutsDoc.shortcutListSeparator": "または", + "xpack.canvas.lib.palettes.canvasLabel": "{CANVAS}", + "xpack.canvas.lib.palettes.colorBlindLabel": "Color Blind", + "xpack.canvas.lib.palettes.earthTonesLabel": "Earth Tones", + "xpack.canvas.lib.palettes.elasticBlueLabel": "Elastic青", + "xpack.canvas.lib.palettes.elasticGreenLabel": "Elastic緑", + "xpack.canvas.lib.palettes.elasticOrangeLabel": "Elasticオレンジ", + "xpack.canvas.lib.palettes.elasticPinkLabel": "Elasticピンク", + "xpack.canvas.lib.palettes.elasticPurpleLabel": "Elastic紫", + "xpack.canvas.lib.palettes.elasticTealLabel": "Elasticティール", + "xpack.canvas.lib.palettes.elasticYellowLabel": "Elastic黄", + "xpack.canvas.lib.palettes.greenBlueRedLabel": "緑、青、赤", + "xpack.canvas.lib.palettes.instagramLabel": "{INSTAGRAM}", + "xpack.canvas.lib.palettes.yellowBlueLabel": "黄、青", + "xpack.canvas.lib.palettes.yellowGreenLabel": "黄、緑", + "xpack.canvas.lib.palettes.yellowRedLabel": "黄、赤", "xpack.canvas.link.errorMessage": "リンクエラー: {message}", "xpack.canvas.pageConfig.backgroundColorDescription": "HEX、RGB、また HTML 色名が使用できます", "xpack.canvas.pageConfig.backgroundColorLabel": "背景", - "xpack.canvas.pageConfig.title": "ページスタイル", + "xpack.canvas.pageConfig.title": "ページ設定", "xpack.canvas.pageConfig.transitionLabel": "トランジション", "xpack.canvas.pageConfig.transitionPreviewLabel": "プレビュー", "xpack.canvas.pageConfig.transitions.noneDropDownOptionLabel": "なし", @@ -5204,6 +5960,8 @@ "xpack.canvas.pagePreviewPageControls.clonePageTooltip": "クローンを作成", "xpack.canvas.pagePreviewPageControls.deletePageAriaLabel": "ページを削除", "xpack.canvas.pagePreviewPageControls.deletePageTooltip": "削除", + "xpack.canvas.palettePicker.emptyPaletteLabel": "なし", + "xpack.canvas.palettePicker.noPaletteFoundErrorTitle": "カラーパレットが見つかりません", "xpack.canvas.renderer.advancedFilter.applyButtonLabel": "適用", "xpack.canvas.renderer.advancedFilter.displayName": "高度なフィルター", "xpack.canvas.renderer.advancedFilter.helpDescription": "Canvas フィルター表現をレンダリングします。", @@ -5327,6 +6085,7 @@ "xpack.canvas.uis.arguments.axisConfigDisabledText": "軸設定表示への切り替え", "xpack.canvas.uis.arguments.axisConfigLabel": "ビジュアライゼーションの軸の構成", "xpack.canvas.uis.arguments.axisConfigTitle": "軸の構成", + "xpack.canvas.uis.arguments.customPaletteLabel": "カスタム", "xpack.canvas.uis.arguments.dataColumn.options.averageDropDown": "平均", "xpack.canvas.uis.arguments.dataColumn.options.countDropDown": "カウント", "xpack.canvas.uis.arguments.dataColumn.options.firstDropDown": "最初", @@ -5363,7 +6122,7 @@ "xpack.canvas.uis.arguments.numberFormatTitle": "数字フォーマット", "xpack.canvas.uis.arguments.numberLabel": "数字を入力", "xpack.canvas.uis.arguments.numberTitle": "数字", - "xpack.canvas.uis.arguments.paletteLabel": "カラーパレットを選択", + "xpack.canvas.uis.arguments.paletteLabel": "要素を表示するために使用される色のコレクション", "xpack.canvas.uis.arguments.paletteTitle": "カラーパレット", "xpack.canvas.uis.arguments.percentageLabel": "パーセンテージのスライダー ", "xpack.canvas.uis.arguments.percentageTitle": "パーセンテージ", @@ -5570,6 +6329,38 @@ "xpack.canvas.units.time.hours": "{hours, plural, one {# 時間} other {# 時間}}", "xpack.canvas.units.time.minutes": "{minutes, plural, one {# 分} other {# 分}}", "xpack.canvas.units.time.seconds": "{seconds, plural, one {# 秒} other {# 秒}}", + "xpack.canvas.varConfig.addButtonLabel": "変数の追加", + "xpack.canvas.varConfig.addTooltipLabel": "変数の追加", + "xpack.canvas.varConfig.copyActionButtonLabel": "スニペットをコピー", + "xpack.canvas.varConfig.copyActionTooltipLabel": "変数構文をクリップボードにコピー", + "xpack.canvas.varConfig.copyNotificationDescription": "変数構文がクリップボードにコピーされました", + "xpack.canvas.varConfig.deleteActionButtonLabel": "変数の削除", + "xpack.canvas.varConfig.deleteNotificationDescription": "変数の削除が正常に完了しました", + "xpack.canvas.varConfig.editActionButtonLabel": "変数の編集", + "xpack.canvas.varConfig.emptyDescription": "このワークパッドには現在変数がありません。変数を追加して、共通の値を格納したり、編集したりすることができます。これらの変数は、要素または式エディターで使用できます。", + "xpack.canvas.varConfig.tableNameLabel": "名前", + "xpack.canvas.varConfig.tableTypeLabel": "タイプ", + "xpack.canvas.varConfig.tableValueLabel": "値", + "xpack.canvas.varConfig.titleLabel": "変数", + "xpack.canvas.varConfig.titleTooltip": "変数を追加して、共通の値を格納したり、編集したりします", + "xpack.canvas.varConfigDeleteVar.cancelButtonLabel": "キャンセル", + "xpack.canvas.varConfigDeleteVar.deleteButtonLabel": "変数の削除", + "xpack.canvas.varConfigDeleteVar.titleLabel": "変数を削除しますか?", + "xpack.canvas.varConfigDeleteVar.warningDescription": "この変数を削除すると、ワークパッドに悪影響を及ぼす可能性があります。続行していいですか?", + "xpack.canvas.varConfigEditVar.addTitleLabel": "変数を追加", + "xpack.canvas.varConfigEditVar.cancelButtonLabel": "キャンセル", + "xpack.canvas.varConfigEditVar.duplicateNameError": "変数名はすでに使用中です", + "xpack.canvas.varConfigEditVar.editTitleLabel": "変数の編集", + "xpack.canvas.varConfigEditVar.editWarning": "使用中の変数を編集すると、ワークパッドに悪影響を及ぼす可能性があります", + "xpack.canvas.varConfigEditVar.nameFieldLabel": "名前", + "xpack.canvas.varConfigEditVar.saveButtonLabel": "変更を保存", + "xpack.canvas.varConfigEditVar.typeBooleanLabel": "ブール", + "xpack.canvas.varConfigEditVar.typeFieldLabel": "タイプ", + "xpack.canvas.varConfigEditVar.typeNumberLabel": "数字", + "xpack.canvas.varConfigEditVar.typeStringLabel": "文字列", + "xpack.canvas.varConfigEditVar.valueFieldLabel": "値", + "xpack.canvas.varConfigVarValueField.falseOption": "False", + "xpack.canvas.varConfigVarValueField.trueOption": "True", "xpack.canvas.workpadConfig.applyStylesheetButtonLabel": "スタイルシートを適用", "xpack.canvas.workpadConfig.backgroundColorLabel": "背景色", "xpack.canvas.workpadConfig.globalCSSLabel": "グローバル CSS オーバーライド", @@ -5707,10 +6498,12 @@ "xpack.canvas.workpadManager.workpadTemplatesTabLabel": "テンプレート", "xpack.canvas.workpadSearch.searchPlaceholder": "ワークパッドを検索", "xpack.canvas.workpadTemplate.cloneTemplateLinkAriaLabel": "ワークパッドテンプレート「{templateName}」のクローンを作成", + "xpack.canvas.workpadTemplate.creatingTemplateLabel": "テンプレート「{templateName}」から作成しています", "xpack.canvas.workpadTemplate.searchPlaceholder": "テンプレートを検索", "xpack.canvas.workpadTemplates.table.descriptionColumnTitle": "説明", "xpack.canvas.workpadTemplates.table.nameColumnTitle": "テンプレート名", "xpack.canvas.workpadTemplates.table.tagsColumnTitle": "タグ", + "xpack.cloud.deploymentLinkLabel": "このデプロイの管理", "xpack.crossClusterReplication.addAutoFollowPatternButtonLabel": "自動フォローパターンを作成", "xpack.crossClusterReplication.addBreadcrumbTitle": "追加", "xpack.crossClusterReplication.addFollowerButtonLabel": "フォロワーインデックスを作成", @@ -6049,6 +6842,73 @@ "xpack.data.kueryAutocomplete.orOperatorDescription.oneOrMoreArgumentsText": "1つ以上の引数", "xpack.data.query.queryBar.cancelLongQuery": "キャンセル", "xpack.data.query.queryBar.runBeyond": "タイムアウトを越えて実行", + "xpack.discover.FlyoutCreateDrilldownAction.displayName": "基本データを調査", + "xpack.embeddableEnhanced.actions.panelNotifications.manyDrilldowns": "パネルには{count}個のドリルダウンがあります", + "xpack.embeddableEnhanced.actions.panelNotifications.oneDrilldown": "パネルには1個のドリルダウンがあります", + "xpack.enterpriseSearch.appSearch.emptyState.createFirstEngineCta": "エンジンを作成", + "xpack.enterpriseSearch.appSearch.emptyState.description1": "App Searchエンジンは、検索エクスペリエンスのために、ドキュメントを格納します。", + "xpack.enterpriseSearch.appSearch.emptyState.title": "初めてのエンジンの作成", + "xpack.enterpriseSearch.appSearch.enginesOverview.engines": "エンジン", + "xpack.enterpriseSearch.appSearch.enginesOverview.metaEngines": "メタエンジン", + "xpack.enterpriseSearch.appSearch.enginesOverview.table.action.manage": "管理", + "xpack.enterpriseSearch.appSearch.enginesOverview.table.column.actions": "アクション", + "xpack.enterpriseSearch.appSearch.enginesOverview.table.column.createdAt": "作成日時", + "xpack.enterpriseSearch.appSearch.enginesOverview.table.column.documentCount": "ドキュメントカウント", + "xpack.enterpriseSearch.appSearch.enginesOverview.table.column.fieldCount": "フィールドカウント", + "xpack.enterpriseSearch.appSearch.enginesOverview.table.column.name": "名前", + "xpack.enterpriseSearch.appSearch.enginesOverview.title": "エンジン概要", + "xpack.enterpriseSearch.appSearch.productCta": "App Searchの起動", + "xpack.enterpriseSearch.appSearch.productName": "App Search", + "xpack.enterpriseSearch.appSearch.setupGuide.description": "Elastic App Searchには、強力な検索を設計し、Webサイトやモバイルアプリケーションにデプロイするためのツールがあります。", + "xpack.enterpriseSearch.appSearch.setupGuide.notConfigured": "App SearchはまだKibanaインスタンスで構成されていません。", + "xpack.enterpriseSearch.appSearch.setupGuide.videoAlt": "App Searchの基本という短い動画では、App Searchを起動して実行する方法について説明します。", + "xpack.enterpriseSearch.errorConnectingState.description1": "ホストURL {enterpriseSearchUrl}では、エンタープライズ サーチへの接続を確立できません", + "xpack.enterpriseSearch.errorConnectingState.description2": "ホストURLが{configFile}で正しく構成されていることを確認してください。", + "xpack.enterpriseSearch.errorConnectingState.description3": "エンタープライズ サーチサーバーが応答していることを確認してください。", + "xpack.enterpriseSearch.errorConnectingState.description4": "セットアップガイドを確認するか、サーバーログの{pluginLog}ログメッセージを確認してください。", + "xpack.enterpriseSearch.errorConnectingState.setupGuideCta": "セットアップガイドを確認", + "xpack.enterpriseSearch.errorConnectingState.title": "接続できません", + "xpack.enterpriseSearch.setupGuide.step1.instruction1": "{configFile}ファイルで、{configSetting}を{productName}インスタンスのURLに設定します。例:", + "xpack.enterpriseSearch.setupGuide.step1.title": "{productName}ホストURLをKibana構成に追加", + "xpack.enterpriseSearch.setupGuide.step2.instruction1": "Kibanaを再起動して、前のステップから構成変更を取得します。", + "xpack.enterpriseSearch.setupGuide.step2.instruction2": "{productName}で{elasticsearchNativeAuthLink}を使用している場合は、すべて設定済みです。ユーザーは、現在の{productName}アクセスおよび権限を使用して、Kibanaで{productName}にアクセスできます。", + "xpack.enterpriseSearch.setupGuide.step2.title": "Kibanaインスタンスの再読み込み", + "xpack.enterpriseSearch.setupGuide.step3.title": "トラブルシューティングのヒント", + "xpack.enterpriseSearch.setupGuide.title": "セットアップガイド", + "xpack.enterpriseSearch.troubleshooting.differentAuth.description": "このプラグインは現在、異なる認証方法で運用されている{productName}およびKibanaをサポートしています。たとえば、Kibana以外のSAMLプロバイダーを使用している{productName}はサポートされません。", + "xpack.enterpriseSearch.troubleshooting.differentAuth.title": "{productName}とKibanaは別の認証方法を使用しています", + "xpack.enterpriseSearch.troubleshooting.differentEsClusters.description": "このプラグインは現在、異なるクラスターで実行されている{productName}とKibanaをサポートしていません。", + "xpack.enterpriseSearch.troubleshooting.differentEsClusters.title": "{productName}とKibanaは別のElasticsearchクラスターにあります", + "xpack.enterpriseSearch.troubleshooting.standardAuth.description": "このプラグインは、{standardAuthLink}の{productName}を完全にはサポートしていません。{productName}で作成されたユーザーはKibanaアクセス権が必要です。Kibanaで作成されたユーザーは、ナビゲーションメニューに{productName}が表示されません。", + "xpack.enterpriseSearch.troubleshooting.standardAuth.title": "標準認証の{productName}はサポートされていません", + "xpack.enterpriseSearch.workplaceSearch.activityFeedEmptyDefault.title": "組織には最近のアクティビティがありません", + "xpack.enterpriseSearch.workplaceSearch.activityFeedNamedDefault.title": "{name}には最近のアクティビティがありません", + "xpack.enterpriseSearch.workplaceSearch.organizationStats.activeUsers": "アクティブなユーザー", + "xpack.enterpriseSearch.workplaceSearch.organizationStats.invitations": "招待", + "xpack.enterpriseSearch.workplaceSearch.organizationStats.privateSources": "プライベートソース", + "xpack.enterpriseSearch.workplaceSearch.organizationStats.sharedSources": "共有ソース", + "xpack.enterpriseSearch.workplaceSearch.organizationStats.title": "使用統計情報", + "xpack.enterpriseSearch.workplaceSearch.orgNameOnboarding.buttonLabel": "組織名を指定", + "xpack.enterpriseSearch.workplaceSearch.orgNameOnboarding.description": "同僚を招待する前に、組織名を指定し、認識しやすくしてください。", + "xpack.enterpriseSearch.workplaceSearch.overviewHeader.description": "組織の統計情報とアクティビティ", + "xpack.enterpriseSearch.workplaceSearch.overviewHeader.title": "組織概要", + "xpack.enterpriseSearch.workplaceSearch.overviewOnboardingHeader.description": "次の手順を完了し、組織を設定してください。", + "xpack.enterpriseSearch.workplaceSearch.overviewOnboardingHeader.title": "Workplace Searchの基本", + "xpack.enterpriseSearch.workplaceSearch.overviewOnboardingSourcesCard.description": "検索を開始するには、組織の共有ソースを追加してください。", + "xpack.enterpriseSearch.workplaceSearch.overviewOnboardingSourcesCard.title": "共有ソース", + "xpack.enterpriseSearch.workplaceSearch.overviewOnboardingUsersCard.description": "検索できるように、同僚をこの組織に招待します。", + "xpack.enterpriseSearch.workplaceSearch.overviewOnboardingUsersCard.title": "ユーザーと招待", + "xpack.enterpriseSearch.workplaceSearch.overviewUsersCard.title": "検索できるように、同僚を招待しました。", + "xpack.enterpriseSearch.workplaceSearch.productCta": "Workplace Searchの起動", + "xpack.enterpriseSearch.workplaceSearch.productName": "Workplace Search", + "xpack.enterpriseSearch.workplaceSearch.recentActivity.title": "最近のアクティビティ", + "xpack.enterpriseSearch.workplaceSearch.recentActivitySourceLink.linkLabel": "ソースを表示", + "xpack.enterpriseSearch.workplaceSearch.setupGuide.description": "Elastic Workplace Searchは、コンテンツプラットフォーム(Google Drive、Salesforce)を、パーソナライズされた検索エクスペリエンスに統合します。", + "xpack.enterpriseSearch.workplaceSearch.setupGuide.imageAlt": "Workplace Searchの基本というガイドでは、Workplace Searchを起動して実行する方法について説明します。", + "xpack.enterpriseSearch.workplaceSearch.setupGuide.notConfigured": "Workplace SearchはKibanaでは構成されていません。このページの手順に従ってください。", + "xpack.enterpriseSearch.workplaceSearch.sourcesOnboardingCard.buttonLabel": "{label}ソースを追加", + "xpack.enterpriseSearch.workplaceSearch.sourcesOnboardingCard.description": "{sourcesCount, number}{sourcesCount, plural, one {個の共有ソース} other {個の共有ソース}}を追加しました。検索をご利用ください。", + "xpack.enterpriseSearch.workplaceSearch.usersOnboardingCard.buttonLabel": "{label}ユーザーを招待", "xpack.features.advancedSettingsFeatureName": "高度な設定", "xpack.features.dashboardFeatureName": "ダッシュボード", "xpack.features.devToolsFeatureName": "開発ツール", @@ -6116,6 +6976,7 @@ "xpack.fileUpload.jsonUploadAndParse.writingToIndex": "インデックスに書き込み中", "xpack.fileUpload.noIndexSuppliedErrorMessage": "インデックスが指定されていません。", "xpack.fileUpload.patternReader.featuresOmitted": "ジオメトリのない一部の機能は省略されました", + "xpack.globalSearch.find.invalidLicenseError": "GlobalSearch APIは、ライセンス状態が無効であるため、無効になっています。{errorMessage}", "xpack.graph.badge.readOnly.text": "読み込み専用", "xpack.graph.badge.readOnly.tooltip": "Graph ワークスペースを保存できません", "xpack.graph.bar.exploreLabel": "グラフ", @@ -6235,6 +7096,7 @@ "xpack.graph.outlinkEncoders.textLuceneTitle": "Lucene エスケープテキスト", "xpack.graph.outlinkEncoders.textPlainDescription": "選択されたパス URL エンコード文字列としての頂点ラベル のテキストです", "xpack.graph.outlinkEncoders.textPlainTitle": "プレインテキスト", + "xpack.graph.pageTitle": "グラフ", "xpack.graph.pluginDescription": "Elasticsearch データの関連性のある関係を浮上させ分析します。", "xpack.graph.sampleData.label": "グラフ", "xpack.graph.savedWorkspace.workspaceNameTitle": "新規グラフワークスペース", @@ -6305,6 +7167,7 @@ "xpack.graph.sidebar.selectionsTitle": "選択項目", "xpack.graph.sidebar.styleVerticesTitle": "スタイルが選択された頂点", "xpack.graph.sidebar.topMenu.addLinksButtonTooltip": "既存の用語の間にリンクを追加します", + "xpack.graph.sidebar.topMenu.blocklistButtonTooltip": "選択内容がワークスペースに表示されないようにします", "xpack.graph.sidebar.topMenu.customStyleButtonTooltip": "選択された頂点のカスタムスタイル", "xpack.graph.sidebar.topMenu.drillDownButtonTooltip": "ドリルダウン", "xpack.graph.sidebar.topMenu.expandSelectionButtonTooltip": "選択項目を拡張", @@ -6355,6 +7218,7 @@ "xpack.grokDebugger.simulateButtonLabel": "シミュレート", "xpack.grokDebugger.structuredDataLabel": "構造化データ", "xpack.grokDebugger.trialLicenseTitle": "トライアル", + "xpack.idxMgmt.aliasesTab.noAliasesTitle": "エイリアスが定義されていません。", "xpack.idxMgmt.appTitle": "インデックス管理", "xpack.idxMgmt.badgeAriaLabel": "{label}。これをフィルタリングするよう選択。", "xpack.idxMgmt.breadcrumb.cloneTemplateLabel": "テンプレートのクローンを作成", @@ -6364,9 +7228,157 @@ "xpack.idxMgmt.breadcrumb.templatesLabel": "テンプレート", "xpack.idxMgmt.clearCacheIndicesAction.successMessage": "キャッシュ [{indexNames}] が削除されました:", "xpack.idxMgmt.closeIndicesAction.successfullyClosedIndicesMessage": "[{indexNames}] がクローズされました", + "xpack.idxMgmt.componentTemplate.breadcrumb.componentTemplatesLabel": "コンポーネントテンプレート", + "xpack.idxMgmt.componentTemplate.breadcrumb.createComponentTemplateLabel": "コンポーネントテンプレートの作成", + "xpack.idxMgmt.componentTemplate.breadcrumb.editComponentTemplateLabel": "コンポーネントテンプレートの編集", + "xpack.idxMgmt.componentTemplate.breadcrumb.homeLabel": "インデックス管理", + "xpack.idxMgmt.componentTemplateClone.loadComponentTemplateTitle": "コンポーネントテンプレート「{sourceComponentTemplateName}」の読み込みエラー", + "xpack.idxMgmt.componentTemplateDetails.aliasesTabTitle": "エイリアス", + "xpack.idxMgmt.componentTemplateDetails.cloneActionLabel": "クローンを作成", + "xpack.idxMgmt.componentTemplateDetails.closeButtonLabel": "閉じる", + "xpack.idxMgmt.componentTemplateDetails.deleteButtonLabel": "削除", + "xpack.idxMgmt.componentTemplateDetails.editButtonLabel": "編集", + "xpack.idxMgmt.componentTemplateDetails.loadingErrorMessage": "コンポーネントテンプレートの読み込みエラー", + "xpack.idxMgmt.componentTemplateDetails.loadingIndexTemplateDescription": "コンポーネントテンプレートを読み込んでいます...", + "xpack.idxMgmt.componentTemplateDetails.manageButtonDisabledTooltipLabel": "テンプレートは使用中であるため、削除できません", + "xpack.idxMgmt.componentTemplateDetails.manageButtonLabel": "管理", + "xpack.idxMgmt.componentTemplateDetails.manageContextMenuPanelTitle": "オプション", + "xpack.idxMgmt.componentTemplateDetails.managedBadgeLabel": "管理中", + "xpack.idxMgmt.componentTemplateDetails.mappingsTabTitle": "マッピング", + "xpack.idxMgmt.componentTemplateDetails.settingsTabTitle": "設定", + "xpack.idxMgmt.componentTemplateDetails.summaryTab.createTemplateLink": "作成", + "xpack.idxMgmt.componentTemplateDetails.summaryTab.metaDescriptionListTitle": "メタデータ", + "xpack.idxMgmt.componentTemplateDetails.summaryTab.notInUseDescription": "インデックステンプレートを{createLink}するか、既存のインデックステンプレートを{editLink}します。", + "xpack.idxMgmt.componentTemplateDetails.summaryTab.notInUseTitle": "このコンポーネントテンプレートはインデックステンプレートによって使用されていません。", + "xpack.idxMgmt.componentTemplateDetails.summaryTab.updateTemplateLink": "更新", + "xpack.idxMgmt.componentTemplateDetails.summaryTab.usedByDescriptionListTitle": "使用者", + "xpack.idxMgmt.componentTemplateDetails.summaryTab.versionDescriptionListTitle": "バージョン", + "xpack.idxMgmt.componentTemplateDetails.summaryTabTitle": "まとめ", + "xpack.idxMgmt.componentTemplateEdit.editPageTitle": "コンポーネントテンプレート「{name}」の編集", + "xpack.idxMgmt.componentTemplateEdit.loadComponentTemplateError": "コンポーネントテンプレートの読み込みエラー", + "xpack.idxMgmt.componentTemplateEdit.loadingDescription": "コンポーネントテンプレートを読み込んでいます...", + "xpack.idxMgmt.componentTemplateForm.createButtonLabel": "コンポーネントテンプレートの作成", + "xpack.idxMgmt.componentTemplateForm.saveButtonLabel": "コンポーネントテンプレートの保存", + "xpack.idxMgmt.componentTemplateForm.saveTemplateError": "コンポーネントテンプレートを作成できません", + "xpack.idxMgmt.componentTemplateForm.stepLogistics.docsButtonLabel": "コンポーネントテンプレートドキュメント", + "xpack.idxMgmt.componentTemplateForm.stepLogistics.metaAriaLabel": "_meta fieldデータエディター", + "xpack.idxMgmt.componentTemplateForm.stepLogistics.metadataDescription": "メタデータを追加", + "xpack.idxMgmt.componentTemplateForm.stepLogistics.metaDescription": "クラスター状態に格納された、テンプレートに関する任意の情報。{learnMoreLink}", + "xpack.idxMgmt.componentTemplateForm.stepLogistics.metaDocumentionLink": "詳細情報", + "xpack.idxMgmt.componentTemplateForm.stepLogistics.metaFieldLabel": "_metaフィールドデータ(任意)", + "xpack.idxMgmt.componentTemplateForm.stepLogistics.metaHelpText": "JSONフォーマットを使用:{code}", + "xpack.idxMgmt.componentTemplateForm.stepLogistics.metaTitle": "メタデータ", + "xpack.idxMgmt.componentTemplateForm.stepLogistics.nameDescription": "このコンポーネントテンプレートの一意の名前。", + "xpack.idxMgmt.componentTemplateForm.stepLogistics.nameFieldLabel": "名前", + "xpack.idxMgmt.componentTemplateForm.stepLogistics.nameTitle": "名前", + "xpack.idxMgmt.componentTemplateForm.stepLogistics.stepTitle": "ロジスティクス", + "xpack.idxMgmt.componentTemplateForm.stepLogistics.validation.metaJsonError": "入力が無効です。", + "xpack.idxMgmt.componentTemplateForm.stepLogistics.validation.nameSpacesError": "コンポーネントテンプレート名にスペースは使用できません。", + "xpack.idxMgmt.componentTemplateForm.stepLogistics.versionDescription": "外部管理システムで、コンポーネントテンプレートを特定するために使用される番号。", + "xpack.idxMgmt.componentTemplateForm.stepLogistics.versionFieldLabel": "バージョン(任意)", + "xpack.idxMgmt.componentTemplateForm.stepLogistics.versionTitle": "バージョン", + "xpack.idxMgmt.componentTemplateForm.stepReview.requestTab.descriptionText": "このリクエストは次のコンポーネントテンプレートを作成します。", + "xpack.idxMgmt.componentTemplateForm.stepReview.requestTabTitle": "リクエスト", + "xpack.idxMgmt.componentTemplateForm.stepReview.stepTitle": "「{templateName}」の詳細の確認", + "xpack.idxMgmt.componentTemplateForm.stepReview.summaryTab.aliasesLabel": "エイリアス", + "xpack.idxMgmt.componentTemplateForm.stepReview.summaryTab.mappingLabel": "マッピング", + "xpack.idxMgmt.componentTemplateForm.stepReview.summaryTab.noDescriptionText": "いいえ", + "xpack.idxMgmt.componentTemplateForm.stepReview.summaryTab.settingsLabel": "インデックス設定", + "xpack.idxMgmt.componentTemplateForm.stepReview.summaryTab.yesDescriptionText": "はい", + "xpack.idxMgmt.componentTemplateForm.stepReview.summaryTabTitle": "まとめ", + "xpack.idxMgmt.componentTemplateForm.steps.aliasesStepName": "エイリアス", + "xpack.idxMgmt.componentTemplateForm.steps.logisticsStepName": "ロジスティクス", + "xpack.idxMgmt.componentTemplateForm.steps.mappingsStepName": "マッピング", + "xpack.idxMgmt.componentTemplateForm.steps.settingsStepName": "インデックス設定", + "xpack.idxMgmt.componentTemplateForm.steps.summaryStepName": "見直し", + "xpack.idxMgmt.componentTemplateForm.validation.nameRequiredError": "コンポーネントテンプレート名が必要です。", + "xpack.idxMgmt.componentTemplates.createRoute.duplicateErrorMessage": "「{name}」という名前のコンポーネントテンプレートがすでに存在します。", + "xpack.idxMgmt.componentTemplates.list.learnMoreLinkText": "詳細情報", + "xpack.idxMgmt.componentTemplatesFlyout.createComponentTemplateFromExistingButtonLabel": "既存のインデックステンプレートから", + "xpack.idxMgmt.componentTemplatesFlyout.createComponentTemplateFromScratchButtonLabel": "最初から", + "xpack.idxMgmt.componentTemplatesFlyout.createContextMenuPanelTitle": "新しいコンポーネントテンプレート", + "xpack.idxMgmt.componentTemplatesFlyout.manageButtonLabel": "作成", + "xpack.idxMgmt.componentTemplatesList.table.actionCloneDecription": "このコンポーネントテンプレートを複製", + "xpack.idxMgmt.componentTemplatesList.table.actionCloneText": "クローンを作成", + "xpack.idxMgmt.componentTemplatesList.table.actionColumnTitle": "アクション", + "xpack.idxMgmt.componentTemplatesList.table.actionEditDecription": "このコンポーネントテンプレートを編集", + "xpack.idxMgmt.componentTemplatesList.table.actionEditText": "編集", + "xpack.idxMgmt.componentTemplatesList.table.aliasesColumnTitle": "エイリアス", + "xpack.idxMgmt.componentTemplatesList.table.createButtonLabel": "コンポーネントテンプレートを作成", + "xpack.idxMgmt.componentTemplatesList.table.deleteActionDescription": "このコンポーネントテンプレートを削除", + "xpack.idxMgmt.componentTemplatesList.table.deleteActionLabel": "削除", + "xpack.idxMgmt.componentTemplatesList.table.deleteComponentTemplatesButtonLabel": "{count, plural, one {個のコンポーネントテンプレート} other {個のコンポーネントテンプレート} }を削除", + "xpack.idxMgmt.componentTemplatesList.table.disabledSelectionLabel": "コンポーネントテンプレートは使用中であるため、削除できません", + "xpack.idxMgmt.componentTemplatesList.table.inUseFilterOptionLabel": "使用中", + "xpack.idxMgmt.componentTemplatesList.table.isInUseColumnTitle": "使用カウント", + "xpack.idxMgmt.componentTemplatesList.table.isManagedFilterLabel": "管理中", + "xpack.idxMgmt.componentTemplatesList.table.managedBadgeLabel": "管理中", + "xpack.idxMgmt.componentTemplatesList.table.mappingsColumnTitle": "マッピング", + "xpack.idxMgmt.componentTemplatesList.table.nameColumnTitle": "名前", + "xpack.idxMgmt.componentTemplatesList.table.notInUseCellDescription": "使用されていません", + "xpack.idxMgmt.componentTemplatesList.table.notInUseFilterOptionLabel": "使用されていません", + "xpack.idxMgmt.componentTemplatesList.table.reloadButtonLabel": "再読み込み", + "xpack.idxMgmt.componentTemplatesList.table.selectionLabel": "このコンポーネントテンプレートを選択", + "xpack.idxMgmt.componentTemplatesList.table.settingsColumnTitle": "設定", + "xpack.idxMgmt.componentTemplatesSelector.emptyPromptDescription": "コンポーネントテンプレートでは、インデックス設定、マッピング、エイリアスを保存し、インデックステンプレートでそれらを継承できます。", + "xpack.idxMgmt.componentTemplatesSelector.emptyPromptLearnMoreLinkText": "詳細情報", + "xpack.idxMgmt.componentTemplatesSelector.emptyPromptTitle": "まだコンポーネントがありません", + "xpack.idxMgmt.componentTemplatesSelector.filters.aliasesLabel": "エイリアス", + "xpack.idxMgmt.componentTemplatesSelector.filters.indexSettingsLabel": "インデックス設定", + "xpack.idxMgmt.componentTemplatesSelector.filters.mappingsLabel": "マッピング", + "xpack.idxMgmt.componentTemplatesSelector.loadingComponentsDescription": "コンポーネントテンプレートを読み込んでいます...", + "xpack.idxMgmt.componentTemplatesSelector.loadingComponentsErrorMessage": "コンポーネントの読み込みエラー", + "xpack.idxMgmt.componentTemplatesSelector.noComponentSelectedLabel": "コンポーネントテンプレートが選択されていません。", + "xpack.idxMgmt.componentTemplatesSelector.removeItemIconLabel": "削除", + "xpack.idxMgmt.componentTemplatesSelector.searchBox.placeholder": "コンポーネントテンプレートを検索", + "xpack.idxMgmt.componentTemplatesSelector.searchResult.emptyPrompt.clearSearchButtonLabel": "検索のクリア", + "xpack.idxMgmt.componentTemplatesSelector.searchResult.emptyPromptTitle": "検索と一致するコンポーネントがありません", + "xpack.idxMgmt.componentTemplatesSelector.selectionHeader.componentsSelectedLabel": "選択されたコンポーネント:{count}", + "xpack.idxMgmt.componentTemplatesSelector.selectItemIconLabel": "選択してください", + "xpack.idxMgmt.componentTemplatesSelector.viewItemIconLabel": "表示", + "xpack.idxMgmt.createComponentTemplate.pageTitle": "コンポーネントテンプレートの作成", "xpack.idxMgmt.createRoute.duplicateTemplateIdErrorMessage": "「{name}」という名前のテンプレートが既に存在します。", "xpack.idxMgmt.createTemplate.cloneTemplatePageTitle": "テンプレート「{name}」のクローンの作成", + "xpack.idxMgmt.createTemplate.createLegacyTemplatePageTitle": "レガシーテンプレートの作成", "xpack.idxMgmt.createTemplate.createTemplatePageTitle": "テンプレートを作成", + "xpack.idxMgmt.dataStreamDetailPanel.closeButtonLabel": "閉じる", + "xpack.idxMgmt.dataStreamDetailPanel.deleteButtonLabel": "データストリームを削除", + "xpack.idxMgmt.dataStreamDetailPanel.generationTitle": "生成", + "xpack.idxMgmt.dataStreamDetailPanel.generationToolTip": "データストリームに作成されたバッキングインデックスの累積数", + "xpack.idxMgmt.dataStreamDetailPanel.indicesTitle": "インデックス", + "xpack.idxMgmt.dataStreamDetailPanel.indicesToolTip": "データストリームの現在のバッキングインデックス", + "xpack.idxMgmt.dataStreamDetailPanel.loadingDataStreamDescription": "データストリームを読み込んでいます", + "xpack.idxMgmt.dataStreamDetailPanel.loadingDataStreamErrorMessage": "データの読み込み中にエラーが発生", + "xpack.idxMgmt.dataStreamDetailPanel.timestampFieldTitle": "タイムスタンプフィールド", + "xpack.idxMgmt.dataStreamDetailPanel.timestampFieldToolTip": "タイムスタンプフィールドはデータストリームのすべてのドキュメントで共有されます", + "xpack.idxMgmt.dataStreamList.dataStreamsDescription": "データストリームは複数のインデックスの時系列データを格納します。{learnMoreLink}", + "xpack.idxMgmt.dataStreamList.emptyPrompt.noDataStreamsCtaIndexTemplateLink": "作成可能なインデックステンプレート", + "xpack.idxMgmt.dataStreamList.emptyPrompt.noDataStreamsCtaIndexTemplateMessage": "{link}を作成して、データストリームを開始します。", + "xpack.idxMgmt.dataStreamList.emptyPrompt.noDataStreamsCtaIngestManagerLink": "Ingest Manager", + "xpack.idxMgmt.dataStreamList.emptyPrompt.noDataStreamsCtaIngestManagerMessage": "{link}でデータストリームを開始します。", + "xpack.idxMgmt.dataStreamList.emptyPrompt.noDataStreamsDescription": "データストリームは複数のインデックスの時系列データを格納します。", + "xpack.idxMgmt.dataStreamList.emptyPrompt.noDataStreamsTitle": "まだデータストリームがありません", + "xpack.idxMgmt.dataStreamList.loadingDataStreamsDescription": "データストリームを読み込んでいます...", + "xpack.idxMgmt.dataStreamList.loadingDataStreamsErrorMessage": "データストリームの読み込み中にエラーが発生", + "xpack.idxMgmt.dataStreamList.reloadDataStreamsButtonLabel": "再読み込み", + "xpack.idxMgmt.dataStreamList.table.actionColumnTitle": "アクション", + "xpack.idxMgmt.dataStreamList.table.actionDeleteDecription": "このデータストリームを削除", + "xpack.idxMgmt.dataStreamList.table.actionDeleteText": "削除", + "xpack.idxMgmt.dataStreamList.table.deleteDataStreamsButtonLabel": "{count, plural, one {個のデータストリーム} other {個のデータストリーム}}を削除", + "xpack.idxMgmt.dataStreamList.table.indicesColumnTitle": "インデックス", + "xpack.idxMgmt.dataStreamList.table.nameColumnTitle": "名前", + "xpack.idxMgmt.dataStreamList.table.noDataStreamsMessage": "データストリームが見つかりません", + "xpack.idxMgmt.dataStreamListDescription.learnMoreLinkText": "詳細情報", + "xpack.idxMgmt.deleteDataStreamsConfirmationModal.cancelButtonLabel": "キャンセル", + "xpack.idxMgmt.deleteDataStreamsConfirmationModal.confirmButtonLabel": "{dataStreamsCount, plural, one {個のデータストリーム} other {個のデータストリーム}}を削除", + "xpack.idxMgmt.deleteDataStreamsConfirmationModal.deleteDescription": "{dataStreamsCount, plural, one {このデータストリーム} other {これらのデータストリーム}}を削除しようとしています。", + "xpack.idxMgmt.deleteDataStreamsConfirmationModal.errorNotificationMessageText": "データストリーム「{name}」の削除エラー", + "xpack.idxMgmt.deleteDataStreamsConfirmationModal.modalTitleText": "{dataStreamsCount, plural, one {個のデータストリーム} other {個のデータストリーム}}を削除", + "xpack.idxMgmt.deleteDataStreamsConfirmationModal.multipleErrorsNotificationMessageText": "{count}件のデータストリームの削除エラー", + "xpack.idxMgmt.deleteDataStreamsConfirmationModal.successDeleteMultipleNotificationMessageText": "{numSuccesses, plural, one {個のデータストリーム} other {個のデータストリーム}}を削除しました", + "xpack.idxMgmt.deleteDataStreamsConfirmationModal.successDeleteSingleNotificationMessageText": "データストリーム「{dataStreamName}」を削除しました", + "xpack.idxMgmt.deleteDataStreamsConfirmationModal.warningMessage": "データストリームは時系列インデックスのコレクションです。データストリームを削除すると、インデックスも削除されます。", + "xpack.idxMgmt.deleteDataStreamsConfirmationModal.warningTitle": "データストリームを削除すると、インデックスも削除されます", "xpack.idxMgmt.deleteIndicesAction.successfullyDeletedIndicesMessage": "[{indexNames}] が削除されました", "xpack.idxMgmt.deleteTemplatesModal.cancelButtonLabel": "キャンセル", "xpack.idxMgmt.deleteTemplatesModal.confirmButtonLabel": "{numTemplatesToDelete, plural, one {テンプレート} other {テンプレート} }を削除", @@ -6395,12 +7407,56 @@ "xpack.idxMgmt.editTemplate.editTemplatePageTitle": "テンプレート「{name}」を編集", "xpack.idxMgmt.flushIndicesAction.successfullyFlushedIndicesMessage": "[{indexNames}] がフラッシュされました", "xpack.idxMgmt.forceMergeIndicesAction.successfullyForceMergedIndicesMessage": "[{indexNames}] が強制結合されました", + "xpack.idxMgmt.formWizard.stepAliases.aliasesDescription": "エイリアスをセットアップして、インデックスに関連付けてください。", + "xpack.idxMgmt.formWizard.stepAliases.aliasesEditorHelpText": "JSONフォーマットを使用:{code}", + "xpack.idxMgmt.formWizard.stepAliases.docsButtonLabel": "インデックスエイリアスドキュメント", + "xpack.idxMgmt.formWizard.stepAliases.fieldAliasesAriaLabel": "エイリアスコードエディター", + "xpack.idxMgmt.formWizard.stepAliases.fieldAliasesLabel": "エイリアス", + "xpack.idxMgmt.formWizard.stepAliases.stepTitle": "エイリアス (任意)", + "xpack.idxMgmt.formWizard.stepComponents.componentsDescription": "コンポーネントテンプレートでは、インデックス設定、マッピング、エイリアスを保存し、インデックステンプレートでそれらを継承できます。", + "xpack.idxMgmt.formWizard.stepComponents.docsButtonLabel": "コンポーネントテンプレートドキュメント", + "xpack.idxMgmt.formWizard.stepComponents.stepTitle": "コンポーネントテンプレート(任意)", + "xpack.idxMgmt.formWizard.stepMappings.docsButtonLabel": "マッピングドキュメント", + "xpack.idxMgmt.formWizard.stepMappings.mappingsDescription": "ドキュメントの保存とインデックス方法を定義します。", + "xpack.idxMgmt.formWizard.stepMappings.stepTitle": "マッピング (任意)", + "xpack.idxMgmt.formWizard.stepSettings.docsButtonLabel": "インデックス設定ドキュメント", + "xpack.idxMgmt.formWizard.stepSettings.fieldIndexSettingsAriaLabel": "インデックス設定エディター", + "xpack.idxMgmt.formWizard.stepSettings.fieldIndexSettingsLabel": "インデックス設定", + "xpack.idxMgmt.formWizard.stepSettings.settingsDescription": "インデックスの動作を定義します。", + "xpack.idxMgmt.formWizard.stepSettings.settingsEditorHelpText": "JSONフォーマットを使用:{code}", + "xpack.idxMgmt.formWizard.stepSettings.stepTitle": "インデックス設定 (任意)", "xpack.idxMgmt.freezeIndicesAction.successfullyFrozeIndicesMessage": "[{indexNames}] が凍結されました", "xpack.idxMgmt.frozenBadgeLabel": "凍結", "xpack.idxMgmt.home.appTitle": "インデックス管理", + "xpack.idxMgmt.home.componentTemplates.checkingPrivilegesDescription": "権限を確認中…", + "xpack.idxMgmt.home.componentTemplates.checkingPrivilegesErrorMessage": "サーバーからユーザー特権を取得中にエラーが発生。", + "xpack.idxMgmt.home.componentTemplates.confirmButtonLabel": "{numComponentTemplatesToDelete, plural, one {個のコンポーネントテンプレート} other {個のコンポーネントテンプレート} }を削除", + "xpack.idxMgmt.home.componentTemplates.deleteModal.cancelButtonLabel": "キャンセル", + "xpack.idxMgmt.home.componentTemplates.deleteModal.deleteDescription": "{numComponentTemplatesToDelete, plural, one {このコンポーネントテンプレート} other {これらのコンポーネントテンプレート} }を削除しようとしています。", + "xpack.idxMgmt.home.componentTemplates.deleteModal.errorNotificationMessageText": "コンポーネントテンプレート「{name}」の削除エラー", + "xpack.idxMgmt.home.componentTemplates.deleteModal.modalTitleText": "{numComponentTemplatesToDelete, plural, one {個のコンポーネントテンプレート} other {個のコンポーネントテンプレート}}を削除", + "xpack.idxMgmt.home.componentTemplates.deleteModal.multipleErrorsNotificationMessageText": "{count}個のコンポーネントテンプレートの削除エラー", + "xpack.idxMgmt.home.componentTemplates.deleteModal.successDeleteMultipleNotificationMessageText": "{numSuccesses, plural, one {個のコンポーネントテンプレート} other {個のコンポーネントテンプレート}}を削除しました", + "xpack.idxMgmt.home.componentTemplates.deleteModal.successDeleteSingleNotificationMessageText": "コンポーネントテンプレート「{componentTemplateName}」を削除しました", + "xpack.idxMgmt.home.componentTemplates.deniedPrivilegeDescription": "コンポーネントテンプレートを使用するには、{privilegesCount, plural, one {このクラスター特権} other {これらのクラスター特権}}が必要です:{missingPrivileges}。", + "xpack.idxMgmt.home.componentTemplates.deniedPrivilegeTitle": "クラスターの権限が必要です", + "xpack.idxMgmt.home.componentTemplates.emptyPromptButtonLabel": "コンポーネントテンプレートを作成", + "xpack.idxMgmt.home.componentTemplates.emptyPromptDescription": "たとえば、インデックステンプレート全体で再利用できるインデックス設定のコンポーネントテンプレートを作成できます。", + "xpack.idxMgmt.home.componentTemplates.emptyPromptDocumentionLink": "詳細情報", + "xpack.idxMgmt.home.componentTemplates.emptyPromptTitle": "コンポーネントテンプレートを作成して開始", + "xpack.idxMgmt.home.componentTemplates.list.componentTemplatesDescription": "コンポーネントテンプレートを使用して、複数のインデックステンプレートで設定、マッピング、エイリアス構成を再利用します。{learnMoreLink}", + "xpack.idxMgmt.home.componentTemplates.list.loadErrorReloadLinkLabel": "再試行してください。", + "xpack.idxMgmt.home.componentTemplates.list.loadErrorTitle": "コンポーネントテンプレートを読み込めません。{reloadLink}", + "xpack.idxMgmt.home.componentTemplates.list.loadingMessage": "コンポーネントテンプレートを読み込んでいます...", + "xpack.idxMgmt.home.componentTemplatesTabTitle": "コンポーネントテンプレート", + "xpack.idxMgmt.home.dataStreamsTabTitle": "データストリーム", + "xpack.idxMgmt.home.idxMgmtDescription": "Elasticsearch インデックスを個々に、または一斉に更新します。{learnMoreLink}", "xpack.idxMgmt.home.idxMgmtDocsLinkText": "インデックス管理ドキュメント", + "xpack.idxMgmt.home.indexTemplatesDescription": "インデックステンプレートを使用して設定、マッピング、エイリアスをインデックスに自動的に適用します。{learnMoreLink}", + "xpack.idxMgmt.home.indexTemplatesDescription.learnMoreLinkText": "詳細情報", "xpack.idxMgmt.home.indexTemplatesTabTitle": "インデックステンプレート", "xpack.idxMgmt.home.indicesTabTitle": "インデックス", + "xpack.idxMgmt.home.legacyIndexTemplatesTitle": "レガシーインデックステンプレート", "xpack.idxMgmt.indexActionsMenu.clearIndexCacheLabel": "{selectedIndexCount, plural, one {インデックス} other {インデックス} }のキャッシュを消去", "xpack.idxMgmt.indexActionsMenu.closeIndex.checkboxLabel": "システムインデックスを閉じることの重大な影響を理解しています", "xpack.idxMgmt.indexActionsMenu.closeIndex.closeDescription": "{selectedIndexCount, plural, one {このインデックス} other {これらのインデックス} }を閉じようとしています。", @@ -6457,6 +7513,7 @@ "xpack.idxMgmt.indexStatusLabels.openingStatusLabel": "開いています...", "xpack.idxMgmt.indexStatusLabels.refreshingStatusLabel": "更新中...", "xpack.idxMgmt.indexTable.captionText": "以下は {total} 列中 {count, plural, one {# 列} other {# 列}} を含むインデックス表です。", + "xpack.idxMgmt.indexTable.headers.dataStreamHeader": "データストリーム", "xpack.idxMgmt.indexTable.headers.documentsHeader": "ドキュメント数", "xpack.idxMgmt.indexTable.headers.healthHeader": "ヘルス", "xpack.idxMgmt.indexTable.headers.nameHeader": "名前", @@ -6464,6 +7521,7 @@ "xpack.idxMgmt.indexTable.headers.replicaHeader": "複製", "xpack.idxMgmt.indexTable.headers.statusHeader": "ステータス", "xpack.idxMgmt.indexTable.headers.storageSizeHeader": "ストレージサイズ", + "xpack.idxMgmt.indexTable.hiddenIndicesSwitchLabel": "非表示のインデックスを含める", "xpack.idxMgmt.indexTable.invalidSearchErrorMessage": "無効な検索: {errorMessage}", "xpack.idxMgmt.indexTable.reloadIndicesButton": "インデックスを再読み込み", "xpack.idxMgmt.indexTable.selectAllIndicesAriaLabel": "すべての行を選択", @@ -6471,9 +7529,15 @@ "xpack.idxMgmt.indexTable.serverErrorTitle": "インデックスの読み込み中にエラーが発生", "xpack.idxMgmt.indexTable.systemIndicesSearchIndicesAriaLabel": "インデックスの検索", "xpack.idxMgmt.indexTable.systemIndicesSearchInputPlaceholder": "検索", + "xpack.idxMgmt.indexTableDescription.learnMoreLinkText": "詳細情報", "xpack.idxMgmt.indexTemplatesList.emptyPrompt.noIndexTemplatesTitle": "まだテンプレートがありません", + "xpack.idxMgmt.indexTemplatesList.filterButtonLabel": "フィルター", "xpack.idxMgmt.indexTemplatesList.loadingIndexTemplatesDescription": "テンプレートを読み込み中…", "xpack.idxMgmt.indexTemplatesList.loadingIndexTemplatesErrorMessage": "テンプレートの読み込み中にエラーが発生", + "xpack.idxMgmt.indexTemplatesList.viewButtonLabel": "表示", + "xpack.idxMgmt.indexTemplatesList.viewCloudManagedTemplateLabel": "クラウド管理されたテンプレート", + "xpack.idxMgmt.indexTemplatesList.viewManagedTemplateLabel": "管理されたテンプレート", + "xpack.idxMgmt.indexTemplatesList.viewSystemTemplateLabel": "システムテンプレート", "xpack.idxMgmt.licenseCheckErrorMessage": "ライセンス確認失敗", "xpack.idxMgmt.mappingsEditor.addFieldButtonLabel": "フィールドの追加", "xpack.idxMgmt.mappingsEditor.addMultiFieldTooltipLabel": "同じフィールドを異なる方法でインデックスするために、マルチフィールドを追加します。", @@ -6955,11 +8019,13 @@ "xpack.idxMgmt.mappingsEditor.updateField.confirmationModal.title": "'{fieldName}'型から'{fieldType}'への変更を確認", "xpack.idxMgmt.mappingsEditor.useNormsFieldDescription": "クエリをスコアリングするときにフィールドの長さを考慮します。Normsには大量のメモリが必要です。フィルタリングまたは集約専用のフィールドは必要ありません。", "xpack.idxMgmt.mappingsEditor.useNormsFieldTitle": "Normsを使用", + "xpack.idxMgmt.mappingsTab.noMappingsTitle": "マッピングが定義されていません。", "xpack.idxMgmt.noMatch.noIndicesDescription": "表示するインデックスがありません", "xpack.idxMgmt.openIndicesAction.successfullyOpenedIndicesMessage": "[{indexNames}] が開かれました", "xpack.idxMgmt.pageErrorForbidden.title": "インデックス管理を使用するパーミッションがありません", "xpack.idxMgmt.refreshIndicesAction.successfullyRefreshedIndicesMessage": "[{indexNames}] が更新されました", "xpack.idxMgmt.reloadIndicesAction.indicesPageRefreshFailureMessage": "現在のインデックスページの更新に失敗しました。", + "xpack.idxMgmt.settingsTab.noIndexSettingsTitle": "設定が定義されていません。", "xpack.idxMgmt.summary.headers.aliases": "エイリアス", "xpack.idxMgmt.summary.headers.deletedDocumentsHeader": "ドキュメントが削除されました", "xpack.idxMgmt.summary.headers.documentsHeader": "ドキュメント数", @@ -6970,11 +8036,19 @@ "xpack.idxMgmt.summary.headers.statusHeader": "ステータス", "xpack.idxMgmt.summary.headers.storageSizeHeader": "ストレージサイズ", "xpack.idxMgmt.summary.summaryTitle": "一般", + "xpack.idxMgmt.templateBadgeType.cloudManaged": "クラウド管理", + "xpack.idxMgmt.templateBadgeType.managed": "管理中", + "xpack.idxMgmt.templateBadgeType.system": "システム", + "xpack.idxMgmt.templateContentIndicator.aliasesTooltipLabel": "エイリアス", + "xpack.idxMgmt.templateContentIndicator.indexSettingsTooltipLabel": "インデックス設定", + "xpack.idxMgmt.templateContentIndicator.mappingsTooltipLabel": "マッピング", "xpack.idxMgmt.templateCreate.loadingTemplateToCloneDescription": "クローンを作成するテンプレートを読み込み中…", "xpack.idxMgmt.templateCreate.loadingTemplateToCloneErrorMessage": "クローンを作成するテンプレートを読み込み中にエラーが発生", "xpack.idxMgmt.templateDetails.aliasesTabTitle": "エイリアス", "xpack.idxMgmt.templateDetails.cloneButtonLabel": "クローンを作成", "xpack.idxMgmt.templateDetails.closeButtonLabel": "閉じる", + "xpack.idxMgmt.templateDetails.cloudManagedTemplateInfoDescription": "クラウドマネージドテンプレートは内部オペレーションに不可欠です。", + "xpack.idxMgmt.templateDetails.cloudManagedTemplateInfoTitle": "クラウドマネジドテンプレートの編集は許可されていません。", "xpack.idxMgmt.templateDetails.deleteButtonLabel": "削除", "xpack.idxMgmt.templateDetails.editButtonLabel": "編集", "xpack.idxMgmt.templateDetails.loadingIndexTemplateDescription": "テンプレートを読み込み中…", @@ -6983,11 +8057,17 @@ "xpack.idxMgmt.templateDetails.manageContextMenuPanelTitle": "テンプレートオプション", "xpack.idxMgmt.templateDetails.mappingsTabTitle": "マッピング", "xpack.idxMgmt.templateDetails.settingsTabTitle": "設定", + "xpack.idxMgmt.templateDetails.summaryTab.componentsDescriptionListTitle": "コンポーネントテンプレート", + "xpack.idxMgmt.templateDetails.summaryTab.dataStreamDescriptionListTitle": "データストリーム", "xpack.idxMgmt.templateDetails.summaryTab.ilmPolicyDescriptionListTitle": "ILM ポリシー", "xpack.idxMgmt.templateDetails.summaryTab.indexPatternsDescriptionListTitle": "インデックス{numIndexPatterns, plural, one {パターン} other {パターン}}", + "xpack.idxMgmt.templateDetails.summaryTab.metaDescriptionListTitle": "メタデータ", + "xpack.idxMgmt.templateDetails.summaryTab.noDescriptionText": "いいえ", "xpack.idxMgmt.templateDetails.summaryTab.noneDescriptionText": "なし", "xpack.idxMgmt.templateDetails.summaryTab.orderDescriptionListTitle": "順序", + "xpack.idxMgmt.templateDetails.summaryTab.priorityDescriptionListTitle": "優先度", "xpack.idxMgmt.templateDetails.summaryTab.versionDescriptionListTitle": "バージョン", + "xpack.idxMgmt.templateDetails.summaryTab.yesDescriptionText": "はい", "xpack.idxMgmt.templateDetails.summaryTabTitle": "まとめ", "xpack.idxMgmt.templateEdit.loadingIndexTemplateDescription": "テンプレートを読み込み中…", "xpack.idxMgmt.templateEdit.loadingIndexTemplateErrorMessage": "テンプレートの読み込み中にエラーが発生", @@ -6998,18 +8078,32 @@ "xpack.idxMgmt.templateForm.createButtonLabel": "テンプレートを作成", "xpack.idxMgmt.templateForm.saveButtonLabel": "テンプレートを保存", "xpack.idxMgmt.templateForm.saveTemplateError": "テンプレートを作成できません", + "xpack.idxMgmt.templateForm.stepLogistics.addMetadataLabel": "メタデータを追加", + "xpack.idxMgmt.templateForm.stepLogistics.dataStreamDescription": "テンプレートは、インデックスではなく、データストリームを作成します。{docsLink}", + "xpack.idxMgmt.templateForm.stepLogistics.dataStreamDocumentionLink": "詳細情報", + "xpack.idxMgmt.templateForm.stepLogistics.datastreamLabel": "データソースを作成", + "xpack.idxMgmt.templateForm.stepLogistics.dataStreamTitle": "データストリーム", "xpack.idxMgmt.templateForm.stepLogistics.docsButtonLabel": "インデックステンプレートドキュメント", "xpack.idxMgmt.templateForm.stepLogistics.fieldIndexPatternsHelpText": "スペースと {invalidCharactersList} は使用できません。", "xpack.idxMgmt.templateForm.stepLogistics.fieldIndexPatternsLabel": "インデックスパターン", "xpack.idxMgmt.templateForm.stepLogistics.fieldNameLabel": "名前", "xpack.idxMgmt.templateForm.stepLogistics.fieldOrderLabel": "その他 (任意)", + "xpack.idxMgmt.templateForm.stepLogistics.fieldPriorityLabel": "優先度(任意)", "xpack.idxMgmt.templateForm.stepLogistics.fieldVersionLabel": "バージョン (任意)", "xpack.idxMgmt.templateForm.stepLogistics.indexPatternsDescription": "テンプレートに適用するインデックスパターンです。", "xpack.idxMgmt.templateForm.stepLogistics.indexPatternsTitle": "インデックスパターン", + "xpack.idxMgmt.templateForm.stepLogistics.metaFieldDescription": "希望するメタデータを保存するために_meta fieldを使用します。", + "xpack.idxMgmt.templateForm.stepLogistics.metaFieldEditorAriaLabel": "_meta fieldデータエディター", + "xpack.idxMgmt.templateForm.stepLogistics.metaFieldEditorHelpText": "JSONフォーマットを使用:{code}", + "xpack.idxMgmt.templateForm.stepLogistics.metaFieldEditorJsonError": "_meta field JSONは無効です。", + "xpack.idxMgmt.templateForm.stepLogistics.metaFieldEditorLabel": "_metaフィールドデータ(任意)", + "xpack.idxMgmt.templateForm.stepLogistics.metaFieldTitle": "_meta field", "xpack.idxMgmt.templateForm.stepLogistics.nameDescription": "このテンプレートの固有の識別子です。", "xpack.idxMgmt.templateForm.stepLogistics.nameTitle": "名前", "xpack.idxMgmt.templateForm.stepLogistics.orderDescription": "複数テンプレートがインデックスと一致した場合の結合順序です。", "xpack.idxMgmt.templateForm.stepLogistics.orderTitle": "結合順序", + "xpack.idxMgmt.templateForm.stepLogistics.priorityDescription": "最高優先度のテンプレートのみが適用されます。", + "xpack.idxMgmt.templateForm.stepLogistics.priorityTitle": "優先度", "xpack.idxMgmt.templateForm.stepLogistics.stepTitle": "ロジスティクス", "xpack.idxMgmt.templateForm.stepLogistics.versionDescription": "テンプレートを外部管理システムで識別するための番号です。", "xpack.idxMgmt.templateForm.stepLogistics.versionTitle": "バージョン", @@ -7017,23 +8111,43 @@ "xpack.idxMgmt.templateForm.stepReview.requestTabTitle": "リクエスト", "xpack.idxMgmt.templateForm.stepReview.stepTitle": "「{templateName}」の詳細の確認", "xpack.idxMgmt.templateForm.stepReview.summaryTab.aliasesLabel": "エイリアス", + "xpack.idxMgmt.templateForm.stepReview.summaryTab.componentsLabel": "コンポーネントテンプレート", "xpack.idxMgmt.templateForm.stepReview.summaryTab.indexPatternsLabel": "インデックス{numIndexPatterns, plural, one {パターン} other {パターン}}", "xpack.idxMgmt.templateForm.stepReview.summaryTab.indexPatternsWarningDescription": "作成するすべての新規インデックスにこのテンプレートが使用されます。", "xpack.idxMgmt.templateForm.stepReview.summaryTab.indexPatternsWarningLinkText": "インデックスパターンの編集。", "xpack.idxMgmt.templateForm.stepReview.summaryTab.indexPatternsWarningTitle": "このテンプレートはワイルドカード (*) をインデックスパターンとして使用します。", "xpack.idxMgmt.templateForm.stepReview.summaryTab.mappingLabel": "マッピング", + "xpack.idxMgmt.templateForm.stepReview.summaryTab.metaLabel": "メタデータ", "xpack.idxMgmt.templateForm.stepReview.summaryTab.noDescriptionText": "いいえ", "xpack.idxMgmt.templateForm.stepReview.summaryTab.noneDescriptionText": "なし", "xpack.idxMgmt.templateForm.stepReview.summaryTab.orderLabel": "順序", + "xpack.idxMgmt.templateForm.stepReview.summaryTab.priorityLabel": "優先度", "xpack.idxMgmt.templateForm.stepReview.summaryTab.settingsLabel": "インデックス設定", "xpack.idxMgmt.templateForm.stepReview.summaryTab.versionLabel": "バージョン", "xpack.idxMgmt.templateForm.stepReview.summaryTab.yesDescriptionText": "はい", "xpack.idxMgmt.templateForm.stepReview.summaryTabTitle": "まとめ", "xpack.idxMgmt.templateForm.steps.aliasesStepName": "エイリアス", + "xpack.idxMgmt.templateForm.steps.componentsStepName": "コンポーネントテンプレート", "xpack.idxMgmt.templateForm.steps.logisticsStepName": "ロジスティクス", "xpack.idxMgmt.templateForm.steps.mappingsStepName": "マッピング", "xpack.idxMgmt.templateForm.steps.settingsStepName": "インデックス設定", "xpack.idxMgmt.templateForm.steps.summaryStepName": "テンプレートのレビュー", + "xpack.idxMgmt.templateList.legacyTable.actionCloneDescription": "このテンプレートのクローンを作成します", + "xpack.idxMgmt.templateList.legacyTable.actionCloneTitle": "クローンを作成", + "xpack.idxMgmt.templateList.legacyTable.actionColumnTitle": "アクション", + "xpack.idxMgmt.templateList.legacyTable.actionDeleteDecription": "このテンプレートを削除します", + "xpack.idxMgmt.templateList.legacyTable.actionDeleteText": "削除", + "xpack.idxMgmt.templateList.legacyTable.actionEditDecription": "このテンプレートを編集します", + "xpack.idxMgmt.templateList.legacyTable.actionEditText": "編集", + "xpack.idxMgmt.templateList.legacyTable.contentColumnTitle": "コンテンツ", + "xpack.idxMgmt.templateList.legacyTable.createLegacyTemplatesButtonLabel": "レガシーテンプレートの作成", + "xpack.idxMgmt.templateList.legacyTable.deleteCloudManagedTemplateTooltip": "管理されているテンプレートは削除できません。", + "xpack.idxMgmt.templateList.legacyTable.deleteTemplatesButtonLabel": "{count, plural, one {テンプレート} other {テンプレート} }を削除", + "xpack.idxMgmt.templateList.legacyTable.ilmPolicyColumnDescription": "インデックスライフサイクルポリシー「{policyName}」", + "xpack.idxMgmt.templateList.legacyTable.ilmPolicyColumnTitle": "ILMポリシー", + "xpack.idxMgmt.templateList.legacyTable.indexPatternsColumnTitle": "インデックスパターン", + "xpack.idxMgmt.templateList.legacyTable.nameColumnTitle": "名前", + "xpack.idxMgmt.templateList.legacyTable.noLegacyIndexTemplatesMessage": "レガシーインデックステンプレートが見つかりません", "xpack.idxMgmt.templateList.table.actionCloneDescription": "このテンプレートのクローンを作成します", "xpack.idxMgmt.templateList.table.actionCloneTitle": "クローンを作成", "xpack.idxMgmt.templateList.table.actionColumnTitle": "アクション", @@ -7041,11 +8155,16 @@ "xpack.idxMgmt.templateList.table.actionDeleteText": "削除", "xpack.idxMgmt.templateList.table.actionEditDecription": "このテンプレートを編集します", "xpack.idxMgmt.templateList.table.actionEditText": "編集", + "xpack.idxMgmt.templateList.table.componentsColumnTitle": "コンポーネント", + "xpack.idxMgmt.templateList.table.contentColumnTitle": "コンテンツ", "xpack.idxMgmt.templateList.table.createTemplatesButtonLabel": "テンプレートを作成", + "xpack.idxMgmt.templateList.table.dataStreamColumnTitle": "データストリーム", + "xpack.idxMgmt.templateList.table.deleteCloudManagedTemplateTooltip": "管理されているテンプレートは削除できません。", "xpack.idxMgmt.templateList.table.deleteTemplatesButtonLabel": "{count, plural, one {テンプレート} other {テンプレート} }を削除", "xpack.idxMgmt.templateList.table.indexPatternsColumnTitle": "インデックスパターン", "xpack.idxMgmt.templateList.table.nameColumnTitle": "名前", "xpack.idxMgmt.templateList.table.noIndexTemplatesMessage": "インデックステンプレートが見つかりません", + "xpack.idxMgmt.templateList.table.noneDescriptionText": "なし", "xpack.idxMgmt.templateList.table.reloadTemplatesButtonLabel": "再読み込み", "xpack.idxMgmt.templateValidation.indexPatternsRequiredError": "インデックスパターンが最低 1 つ必要です。", "xpack.idxMgmt.templateValidation.templateNameInvalidaCharacterError": "テンプレート名に「{invalidChar}」は使用できません", @@ -7085,8 +8204,18 @@ "xpack.indexLifecycleMgmt.editPolicy.creationNanoSecondsOptionLabel": "インデックスの作成からの経過時間(ナノ秒)", "xpack.indexLifecycleMgmt.editPolicy.creationSecondsOptionLabel": "インデックスの作成からの経過時間(秒)", "xpack.indexLifecycleMgmt.editPolicy.deletePhase.activateWarmPhaseSwitchLabel": "削除フェーズを有効にする", + "xpack.indexLifecycleMgmt.editPolicy.deletePhase.customPolicyMessage": "既存のスナップショットポリシーの名前を入力するか、この名前で新しいポリシーを作成します。", + "xpack.indexLifecycleMgmt.editPolicy.deletePhase.customPolicyTitle": "ポリシー名が見つかりません", "xpack.indexLifecycleMgmt.editPolicy.deletePhase.deletePhaseDescriptionText": "今後インデックスは必要ありません。 いつ安全に削除できるかを定義できます。", "xpack.indexLifecycleMgmt.editPolicy.deletePhase.deletePhaseLabel": "削除フェーズ", + "xpack.indexLifecycleMgmt.editPolicy.deletePhase.noPoliciesCreatedMessage": "スナップショットライフサイクルポリシーを作成して、クラスタースナップショットの作成と削除を自動化します。", + "xpack.indexLifecycleMgmt.editPolicy.deletePhase.noPoliciesCreatedTitle": "スナップショットポリシーが見つかりません", + "xpack.indexLifecycleMgmt.editPolicy.deletePhase.noPoliciesLoadedMessage": "このフィールドを更新し、既存のスナップショットポリシーの名前を入力します。", + "xpack.indexLifecycleMgmt.editPolicy.deletePhase.noPoliciesLoadedTitle": "既存のポリシーを読み込めません", + "xpack.indexLifecycleMgmt.editPolicy.deletePhase.reloadPoliciesLabel": "ポリシ-の再読み込み", + "xpack.indexLifecycleMgmt.editPolicy.deletePhase.waitForSnapshotDescription": "インデックスを削除する前に実行するスナップショットポリシーを指定します。これにより、削除されたインデックスのスナップショットが利用可能であることが保証されます。", + "xpack.indexLifecycleMgmt.editPolicy.deletePhase.waitForSnapshotLabel": "スナップショットポリシー名", + "xpack.indexLifecycleMgmt.editPolicy.deletePhase.waitForSnapshotTitle": "スナップショットポリシーを待機", "xpack.indexLifecycleMgmt.editPolicy.differentPolicyNameRequiredError": "ポリシー名は異なるものである必要があります。", "xpack.indexLifecycleMgmt.editPolicy.editingExistingPolicyExplanationMessage": "すべての変更はこのポリシーに関連付けられているインデックスに影響を及ぼします。代わりに、これらの変更を新規ポリシーに保存することもできます。", "xpack.indexLifecycleMgmt.editPolicy.editingExistingPolicyMessage": "既存のポリシーを編集しています", @@ -7270,6 +8399,8 @@ "xpack.indexLifecycleMgmt.warmPhase.numberOfSegmentsLabel": "セグメントの数", "xpack.indexLifecycleMgmt.warmPhase.replicaCountHelpText": "デフォルトで、レプリカの数は同じままになります。", "xpack.indexLifecycleMgmt.warmPhase.shrinkIndexLabel": "インデックスを縮小", + "xpack.infra.alerting.alertFlyout.groupBy.placeholder": "なし(グループなし)", + "xpack.infra.alerting.alertFlyout.groupByLabel": "グループ分けの条件", "xpack.infra.alerting.alertsButton": "アラート", "xpack.infra.alerting.createAlertButton": "アラートの作成", "xpack.infra.alerting.logs.alertsButton": "アラート", @@ -7280,6 +8411,7 @@ "xpack.infra.analysisSetup.configurationStepTitle": "構成", "xpack.infra.analysisSetup.createMlJobButton": "ML ジョブを作成", "xpack.infra.analysisSetup.deleteAnalysisResultsWarning": "これにより以前検出された異常が削除されます。", + "xpack.infra.analysisSetup.endTimeAfterStartTimeErrorMessage": "終了時刻は開始時刻よりも後でなければなりません。", "xpack.infra.analysisSetup.endTimeDefaultDescription": "永久", "xpack.infra.analysisSetup.endTimeLabel": "終了時刻", "xpack.infra.analysisSetup.indexDatasetFilterIncludeAllButtonLabel": "{includeType, select, includeAll {すべてのデータセット} includeSome {{includedDatasetCount, plural, one {# データセット} other {# データセット}}}}", @@ -7292,6 +8424,7 @@ "xpack.infra.analysisSetup.indicesSelectionTitle": "インデックスを選択", "xpack.infra.analysisSetup.indicesSelectionTooFewSelectedIndicesDescription": "1つ以上のインデックス名を選択してください。", "xpack.infra.analysisSetup.recreateMlJobButton": "ML ジョブを再作成", + "xpack.infra.analysisSetup.startTimeBeforeEndTimeErrorMessage": "開始時刻は終了時刻よりも前でなければなりません。", "xpack.infra.analysisSetup.startTimeDefaultDescription": "ログインデックスの開始地点です。", "xpack.infra.analysisSetup.startTimeLabel": "開始時刻", "xpack.infra.analysisSetup.steps.initialConfigurationStep.errorCalloutTitle": "インデックス構成が無効です", @@ -7383,12 +8516,24 @@ "xpack.infra.kibanaMetrics.nodeDoesNotExistErrorMessage": "{nodeId} が存在しません。", "xpack.infra.legendControls.applyButton": "適用", "xpack.infra.legendControls.buttonLabel": "凡例を校正", - "xpack.infra.legendControls.maxLabel": "最高", + "xpack.infra.legendControls.cancelButton": "キャンセル", + "xpack.infra.legendControls.colorPaletteLabel": "カラーパレット", + "xpack.infra.legendControls.maxLabel": "最大", "xpack.infra.legendControls.minLabel": "最低", + "xpack.infra.legendControls.palettes.cool": "Cool", + "xpack.infra.legendControls.palettes.negative": "負", + "xpack.infra.legendControls.palettes.positive": "正", + "xpack.infra.legendControls.palettes.status": "ステータス", + "xpack.infra.legendControls.palettes.temperature": "温度", + "xpack.infra.legendControls.palettes.warm": "ウォーム", + "xpack.infra.legendControls.reverseDirectionLabel": "逆方向", + "xpack.infra.legendControls.stepsLabel": "色の数", "xpack.infra.legendControls.switchLabel": "自動計算範囲", + "xpack.infra.legnedControls.boundRangeError": "最小値は最大値よりも小さくなければなりません", "xpack.infra.linkTo.hostWithIp.error": "IP アドレス「{hostIp}」でホストが見つかりません.", "xpack.infra.linkTo.hostWithIp.loading": "IP アドレス「{hostIp}」のホストを読み込み中", "xpack.infra.lobs.logEntryActionsViewInContextButton": "コンテキストで表示", + "xpack.infra.logAnomalies.logEntryExamplesMenuLabel": "ログエントリのアクションを表示", "xpack.infra.logEntryActionsMenu.apmActionLabel": "APMで表示", "xpack.infra.logEntryActionsMenu.buttonLabel": "アクション", "xpack.infra.logEntryActionsMenu.uptimeActionLabel": "監視ステータスを表示", @@ -7404,6 +8549,7 @@ "xpack.infra.logs.alertFlyout.criterionComparatorValueTitle": "比較:値", "xpack.infra.logs.alertFlyout.criterionFieldTitle": "フィールド", "xpack.infra.logs.alertFlyout.documentCountPrefix": "タイミング", + "xpack.infra.logs.alertFlyout.documentCountSuffix": "{value, plural, one {件発生} other {件発生}}", "xpack.infra.logs.alertFlyout.documentCountValue": "{value, plural, one {ログエントリ} other {ログエントリ}}", "xpack.infra.logs.alertFlyout.error.criterionComparatorRequired": "コンパレーターが必要です。", "xpack.infra.logs.alertFlyout.error.criterionFieldRequired": "フィールドが必要です。", @@ -7428,16 +8574,45 @@ "xpack.infra.logs.alerting.comparator.notMatch": "一致しない", "xpack.infra.logs.alerting.comparator.notMatchPhrase": "語句と一致しない", "xpack.infra.logs.alerting.threshold.conditionsActionVariableDescription": "ログエントリが満たす必要がある条件", - "xpack.infra.logs.alerting.threshold.defaultActionMessage": "\\{\\{context.matchingDocuments\\}\\}ログエントリは次の条件と一致しました:\\{\\{context.conditions\\}\\}", + "xpack.infra.logs.alerting.threshold.defaultActionMessage": "\\{\\{#context.group\\}\\}\\{\\{context.group\\}\\} - \\{\\{/context.group\\}\\}\\{\\{context.matchingDocuments\\}\\}ログエントリは次の条件と一致しました。\\{\\{context.conditions\\}\\}", "xpack.infra.logs.alerting.threshold.documentCountActionVariableDescription": "指定された条件と一致したログエントリ数", "xpack.infra.logs.alerting.threshold.fired": "実行", + "xpack.infra.logs.alerting.threshold.groupByActionVariableDescription": "アラートのトリガーを実行するグループの名前", "xpack.infra.logs.analysis.analyzeInMlButtonLabel": "ML で分析", + "xpack.infra.logs.analysis.anomaliesExpandedRowActualRateDescription": "実際", + "xpack.infra.logs.analysis.anomaliesExpandedRowActualRateTitle": "{actualCount, plural, one {件のメッセージ} other {件のメッセージ}}", + "xpack.infra.logs.analysis.anomaliesExpandedRowTypicalRateDescription": "通常", + "xpack.infra.logs.analysis.anomaliesExpandedRowTypicalRateTitle": "{typicalCount, plural, one {件のメッセージ} other {件のメッセージ}}", "xpack.infra.logs.analysis.anomaliesSectionLineSeriesName": "15 分ごとのログエントリー (平均)", + "xpack.infra.logs.analysis.anomaliesSectionLoadingAriaLabel": "異常を読み込み中", "xpack.infra.logs.analysis.anomaliesSectionTitle": "異常", + "xpack.infra.logs.analysis.anomaliesTableAnomalyDatasetName": "データセット", + "xpack.infra.logs.analysis.anomaliesTableAnomalyMessageName": "異常", + "xpack.infra.logs.analysis.anomaliesTableAnomalyScoreColumnName": "異常スコア", + "xpack.infra.logs.analysis.anomaliesTableAnomalyStartTime": "開始時刻", + "xpack.infra.logs.analysis.anomaliesTableExamplesTitle": "ログエントリの例", + "xpack.infra.logs.analysis.anomaliesTableFewerThanExpectedAnomalyMessage": "この{type, select, logRate {データセット} logCategory {カテゴリ}}のログメッセージ数が想定よりも少なくなっています", + "xpack.infra.logs.analysis.anomaliesTableMoreThanExpectedAnomalyMessage": "この{type, select, logRate {データセット} logCategory {カテゴリ}}のログメッセージ数が想定よりも多くなっています", + "xpack.infra.logs.analysis.anomaliesTableNextPageLabel": "次のページ", + "xpack.infra.logs.analysis.anomaliesTablePreviousPageLabel": "前のページ", + "xpack.infra.logs.analysis.anomalySectionLogRateChartNoData": "表示するログレートデータがありません。", "xpack.infra.logs.analysis.anomalySectionNoDataBody": "時間範囲を調整する必要があるかもしれません。", "xpack.infra.logs.analysis.anomalySectionNoDataTitle": "表示するデータがありません。", + "xpack.infra.logs.analysis.datasetFilterPlaceholder": "データセットでフィルター", + "xpack.infra.logs.analysis.enableAnomalyDetectionButtonLabel": "異常検知を有効にする", + "xpack.infra.logs.analysis.jobConfigurationOutdatedCalloutMessage": "異なるソース構成を使用して{moduleName} MLジョブが作成されました。現在の構成を適用するにはジョブを再作成してください。これにより以前検出された異常が削除されます。", + "xpack.infra.logs.analysis.jobConfigurationOutdatedCalloutTitle": "{moduleName} MLジョブ構成が最新ではありません", + "xpack.infra.logs.analysis.jobDefinitionOutdatedCalloutMessage": "ML {moduleName}ジョブの新しいバージョンが利用可能です。新しいバージョンをデプロイするにはジョブを再作成してください。これにより以前検出された異常が削除されます。", + "xpack.infra.logs.analysis.jobDefinitionOutdatedCalloutTitle": "{moduleName} MLジョブ定義が最新ではありません", "xpack.infra.logs.analysis.jobStoppedCalloutMessage": "ML ジョブが手動またはリソース不足により停止しました。新しいログエントリーはジョブが再起動するまで処理されません。", "xpack.infra.logs.analysis.jobStoppedCalloutTitle": "ML ジョブが停止しました", + "xpack.infra.logs.analysis.logEntryCategoriesModuleDescription": "機械学習を使用して、ログメッセージを自動的に分類します。", + "xpack.infra.logs.analysis.logEntryCategoriesModuleName": "カテゴリー分け", + "xpack.infra.logs.analysis.logEntryExamplesViewAnomalyInMlLabel": "機械学習で異常を表示", + "xpack.infra.logs.analysis.logEntryExamplesViewInStreamLabel": "ストリームで表示", + "xpack.infra.logs.analysis.logEntryRateModuleDescription": "機械学習を使用して自動的に異常ログエントリ率を検出します。", + "xpack.infra.logs.analysis.logEntryRateModuleName": "ログレート", + "xpack.infra.logs.analysis.manageMlJobsButtonLabel": "MLジョブの管理", "xpack.infra.logs.analysis.mlAppButton": "機械学習を開く", "xpack.infra.logs.analysis.mlUnavailableBody": "詳細は{machineLearningAppLink}をご覧ください。", "xpack.infra.logs.analysis.mlUnavailableTitle": "この機能には機械学習が必要です", @@ -7446,11 +8621,15 @@ "xpack.infra.logs.analysis.overallAnomalyChartMaxScoresLabel": "最高異常スコア", "xpack.infra.logs.analysis.partitionMaxAnomalyScoreAnnotationLabel": "最高異常スコア: {maxAnomalyScore}", "xpack.infra.logs.analysis.recreateJobButtonLabel": "ML ジョブを再作成", + "xpack.infra.logs.analysis.setupFlyoutGotoListButtonLabel": "すべての機械学習ジョブ", + "xpack.infra.logs.analysis.setupFlyoutTitle": "機械学習を使用した異常検知", "xpack.infra.logs.analysis.setupStatusTryAgainButton": "再試行", "xpack.infra.logs.analysis.setupStatusUnknownTitle": "MLジョブのステータスを特定できませんでした。", "xpack.infra.logs.analysis.userManagementButtonLabel": "ユーザーの管理", "xpack.infra.logs.analysisPage.loadingMessage": "分析ジョブのステータスを確認中…", "xpack.infra.logs.analysisPage.unavailable.mlAppLink": "機械学習アプリ", + "xpack.infra.logs.categoryExample.viewInContextText": "コンテキストで表示", + "xpack.infra.logs.categoryExample.viewInStreamText": "ストリームで表示", "xpack.infra.logs.customizeLogs.customizeButtonLabel": "カスタマイズ", "xpack.infra.logs.customizeLogs.lineWrappingFormRowLabel": "改行", "xpack.infra.logs.customizeLogs.textSizeFormRowLabel": "テキストサイズ", @@ -7472,12 +8651,23 @@ "xpack.infra.logs.highlights.goToPreviousHighlightButtonLabel": "前のハイライトにスキップ", "xpack.infra.logs.highlights.highlightsPopoverButtonLabel": "ハイライト", "xpack.infra.logs.highlights.highlightTermsFieldLabel": "ハイライトする用語", + "xpack.infra.logs.index.anomaliesTabTitle": "異常", "xpack.infra.logs.index.logCategoriesBetaBadgeTitle": "カテゴリー", "xpack.infra.logs.index.settingsTabTitle": "設定", "xpack.infra.logs.index.streamTabTitle": "ストリーム", "xpack.infra.logs.jumpToTailText": "最も新しいエントリーに移動", "xpack.infra.logs.lastUpdate": "前回の更新 {timestamp}", "xpack.infra.logs.loadingNewEntriesText": "新しいエントリーを読み込み中", + "xpack.infra.logs.logAnalysis.splash.learnMoreLink": "ドキュメンテーションを表示", + "xpack.infra.logs.logAnalysis.splash.learnMoreTitle": "詳細について", + "xpack.infra.logs.logAnalysis.splash.loadingMessage": "ライセンスを確認しています...", + "xpack.infra.logs.logAnalysis.splash.splashImageAlt": "プレースホルダー画像", + "xpack.infra.logs.logAnalysis.splash.startTrialCta": "トライアルを開始", + "xpack.infra.logs.logAnalysis.splash.startTrialDescription": "14日間無料の試用版には、機械学習機能が含まれており、ログで異常を検出することができます。", + "xpack.infra.logs.logAnalysis.splash.startTrialTitle": "異常検知を利用するには、無料の試用版を開始してください", + "xpack.infra.logs.logAnalysis.splash.updateSubscriptionCta": "サブスクリプションのアップグレード", + "xpack.infra.logs.logAnalysis.splash.updateSubscriptionDescription": "機械学習機能を使用するには、プラチナサブスクリプションが必要です。", + "xpack.infra.logs.logAnalysis.splash.updateSubscriptionTitle": "異常検知を利用するには、プラチナサブスクリプションにアップグレードしてください", "xpack.infra.logs.logEntryActionsDetailsButton": "詳細を表示", "xpack.infra.logs.logEntryCategories.analyzeCategoryInMlButtonLabel": "ML で分析", "xpack.infra.logs.logEntryCategories.analyzeCategoryInMlTooltipDescription": "ML アプリでこのカテゴリーを分析します。", @@ -7494,13 +8684,21 @@ "xpack.infra.logs.logEntryCategories.maximumAnomalyScoreColumnTitle": "最高異常スコア", "xpack.infra.logs.logEntryCategories.newCategoryTrendLabel": "新規", "xpack.infra.logs.logEntryCategories.noFrequentCategoryWarningReasonDescription": "抽出されたカテゴリのいずれにも、頻繁にメッセージが割り当てられることはありません。", - "xpack.infra.logs.logEntryCategories.setupDescription": "機械学習を使用して、ログメッセージを自動的に分類します。", - "xpack.infra.logs.logEntryCategories.setupTitle": "機械学習分析を有効にする", + "xpack.infra.logs.logEntryCategories.setupDescription": "ログカテゴリを有効にするには、機械学習ジョブを設定してください。", + "xpack.infra.logs.logEntryCategories.setupTitle": "ログカテゴリ分析を設定", + "xpack.infra.logs.logEntryCategories.showAnalysisSetupButtonLabel": "ML設定", "xpack.infra.logs.logEntryCategories.singleCategoryWarningReasonDescription": "分析では、ログメッセージから2つ以上のカテゴリを抽出できませんでした。", "xpack.infra.logs.logEntryCategories.topCategoriesSectionLoadingAriaLabel": "メッセージカテゴリーを読み込み中", "xpack.infra.logs.logEntryCategories.topCategoriesSectionTitle": "メッセージカテゴリーをログに出力", "xpack.infra.logs.logEntryCategories.trendColumnTitle": "傾向", "xpack.infra.logs.logEntryCategories.truncatedPatternSegmentDescription": "{extraSegmentCount, plural, one {one more segment} other {# more segments}}", + "xpack.infra.logs.logEntryExamples.exampleEmptyDescription": "選択した時間範囲内に例は見つかりませんでした。ログエントリー保持期間を長くするとメッセージサンプルの可用性が向上します。", + "xpack.infra.logs.logEntryExamples.exampleEmptyReloadButtonLabel": "再読み込み", + "xpack.infra.logs.logEntryExamples.exampleLoadingFailureDescription": "サンプルの読み込みに失敗しました。", + "xpack.infra.logs.logEntryExamples.exampleLoadingFailureRetryButtonLabel": "再試行", + "xpack.infra.logs.logEntryRate.setupDescription": "ログ異常を有効にするには、機械学習ジョブを設定してください", + "xpack.infra.logs.logEntryRate.setupTitle": "ログ異常分析を設定", + "xpack.infra.logs.logEntryRate.showAnalysisSetupButtonLabel": "ML設定", "xpack.infra.logs.pluginTitle": "ログ", "xpack.infra.logs.scrollableLogTextStreamView.loadingEntriesLabel": "エントリーを読み込み中", "xpack.infra.logs.search.nextButtonLabel": "次へ", @@ -7508,6 +8706,9 @@ "xpack.infra.logs.search.searchInLogsAriaLabel": "検索", "xpack.infra.logs.search.searchInLogsPlaceholder": "検索", "xpack.infra.logs.searchResultTooltip": "{bucketCount, plural, one {# 件のハイライトされたエントリー} other {# 件のハイライトされたエントリー}}", + "xpack.infra.logs.setupFlyout.logCategoriesDescription": "機械学習を使用して、ログメッセージを自動的に分類します。", + "xpack.infra.logs.setupFlyout.logCategoriesTitle": "ログカテゴリー", + "xpack.infra.logs.setupFlyout.setupFlyoutTitle": "機械学習を使用した異常検知", "xpack.infra.logs.showingEntriesFromTimestamp": "{timestamp} 以降のエントリーを表示中", "xpack.infra.logs.showingEntriesUntilTimestamp": "{timestamp} までのエントリーを表示中", "xpack.infra.logs.startStreamingButtonLabel": "ライブストリーム", @@ -7515,6 +8716,9 @@ "xpack.infra.logs.streamingNewEntriesText": "新しいエントリーをストリーム中", "xpack.infra.logs.streamLive": "ライブストリーム", "xpack.infra.logs.streamPage.documentTitle": "{previousTitle} | ストリーム", + "xpack.infra.logs.viewInContext.logsFromContainerTitle": "表示されたログはコンテナー{container}から取得されました", + "xpack.infra.logs.viewInContext.logsFromFileTitle": "表示されたログは、ファイル{file}と{host}から取得されました", + "xpack.infra.logsHeaderAddDataButtonLabel": "データの追加", "xpack.infra.logSourceConfiguration.unsavedFormPromptMessage": "終了してよろしいですか?変更内容は失われます", "xpack.infra.logsPage.noLoggingIndicesDescription": "追加しましょう!", "xpack.infra.logsPage.noLoggingIndicesInstructionsActionLabel": "セットアップの手順を表示", @@ -7657,9 +8861,17 @@ "xpack.infra.metrics.alertFlyout.aggregationText.sum": "合計", "xpack.infra.metrics.alertFlyout.alertName": "メトリックしきい値", "xpack.infra.metrics.alertFlyout.alertOnNoData": "データがない場合に通知する", + "xpack.infra.metrics.alertFlyout.alertPreviewError": "このアラート条件をプレビューするときにエラーが発生しました", + "xpack.infra.metrics.alertFlyout.alertPreviewErrorResult": "一部のデータを評価するときにエラーが発生しました。", + "xpack.infra.metrics.alertFlyout.alertPreviewGroups": "{numberOfGroups} {groupName}{plural}", + "xpack.infra.metrics.alertFlyout.alertPreviewGroupsAcross": "すべてを対象にする", + "xpack.infra.metrics.alertFlyout.alertPreviewNoDataResult": "データがない{were} {noData}結果{plural}がありました。", + "xpack.infra.metrics.alertFlyout.alertPreviewResult": "このアラートは{firedTimes}回発生しました", + "xpack.infra.metrics.alertFlyout.alertPreviewResultLookback": "過去{lookback}", "xpack.infra.metrics.alertFlyout.conditions": "条件", "xpack.infra.metrics.alertFlyout.createAlertPerHelpText": "すべての一意の値についてアラートを作成します。例:「host.id」または「cloud.region」。", "xpack.infra.metrics.alertFlyout.createAlertPerText": "次の単位でアラートを作成(任意)", + "xpack.infra.metrics.alertFlyout.dayLabel": "日", "xpack.infra.metrics.alertFlyout.error.aggregationRequired": "集約が必要です。", "xpack.infra.metrics.alertFlyout.error.metricRequired": "メトリックが必要です。", "xpack.infra.metrics.alertFlyout.error.thresholdRequired": "しきい値が必要です。", @@ -7673,19 +8885,36 @@ "xpack.infra.metrics.alertFlyout.expression.metric.whenLabel": "タイミング", "xpack.infra.metrics.alertFlyout.filterHelpText": "KQL式を使用して、アラートトリガーの範囲を制限します。", "xpack.infra.metrics.alertFlyout.filterLabel": "フィルター(任意)", + "xpack.infra.metrics.alertFlyout.firedTime": "時間", + "xpack.infra.metrics.alertFlyout.firedTimes": "回数", + "xpack.infra.metrics.alertFlyout.hourLabel": "時間", + "xpack.infra.metrics.alertFlyout.lastDayLabel": "昨日", + "xpack.infra.metrics.alertFlyout.lastHourLabel": "過去1時間", + "xpack.infra.metrics.alertFlyout.lastMonthLabel": "先月", + "xpack.infra.metrics.alertFlyout.lastWeekLabel": "先週", + "xpack.infra.metrics.alertFlyout.monthLabel": "月", "xpack.infra.metrics.alertFlyout.noDataHelpText": "有効にすると、メトリックが想定された期間内にデータを報告しない場合、またはアラートがElasticsearchをクエリできない場合に、アクションをトリガーします", "xpack.infra.metrics.alertFlyout.outsideRangeLabel": "is not between", + "xpack.infra.metrics.alertFlyout.previewIntervalTooShortDescription": "選択するプレビュー長を長くするか、{checkEvery}フィールドの時間を増やしてください。", + "xpack.infra.metrics.alertFlyout.previewIntervalTooShortTitle": "データが不十分です", + "xpack.infra.metrics.alertFlyout.previewLabel": "プレビュー", "xpack.infra.metrics.alertFlyout.removeCondition": "条件を削除", - "xpack.infra.metrics.alerting.inventory.threshold.defaultActionMessage": "\\{\\{alertName\\}\\} - \\{\\{context.group\\}\\}\n\n\\{\\{context.metricOf.condition0\\}\\}はしきい値 \\{\\{context.thresholdOf.condition0\\}\\}を超えました\n現在の値は\\{\\{context.valueOf.condition0\\}\\}です\n", + "xpack.infra.metrics.alertFlyout.testAlertCondition": "アラート条件のテスト", + "xpack.infra.metrics.alertFlyout.tooManyBucketsErrorDescription": "選択するプレビュー長を短くするか、{forTheLast}フィールドの時間を増やしてください。", + "xpack.infra.metrics.alertFlyout.tooManyBucketsErrorTitle": "データが多すぎます(>{maxBuckets}結果)", + "xpack.infra.metrics.alertFlyout.weekLabel": "週", + "xpack.infra.metrics.alerting.inventory.threshold.defaultActionMessage": "\\{\\{alertName\\}\\} - \\{\\{context.group\\}\\}は状態\\{\\{context.alertState\\}\\}です\n\n理由:\n\\{\\{context.reason\\}\\}\n", "xpack.infra.metrics.alerting.inventory.threshold.fired": "実行", - "xpack.infra.metrics.alerting.threshold.alerting.alertStateActionVariableDescription": "現在のアラートの状態", - "xpack.infra.metrics.alerting.threshold.alerting.groupActionVariableDescription": "データを報告するグループの名前", - "xpack.infra.metrics.alerting.threshold.alerting.metricOfActionVariableDescription": "監視されたメトリックのレコード。条件でグループ化されます(metricOf.condition0、metricOf.condition1など)。", - "xpack.infra.metrics.alerting.threshold.alerting.reasonActionVariableDescription": "どのメトリックがどのしきい値を超えたのかを含む、アラートがこの状態である理由に関する説明", - "xpack.infra.metrics.alerting.threshold.alerting.thresholdOfActionVariableDescription": "アラートしきい値のレコード。条件でグループ化されます(thresholdOf.condition0、thresholdOf.condition1など)。", - "xpack.infra.metrics.alerting.threshold.alerting.valueOfActionVariableDescription": "監視されたメトリックの現在の値のレコード。条件でグループ化されます(valueOf.condition0、valueOf.condition1など)。", + "xpack.infra.metrics.alerting.alertStateActionVariableDescription": "現在のアラートの状態", + "xpack.infra.metrics.alerting.groupActionVariableDescription": "データを報告するグループの名前", + "xpack.infra.metrics.alerting.metricActionVariableDescription": "監視されたメトリックのレコード。条件でグループ化されます(metric.condition0、metric.condition1など)。", + "xpack.infra.metrics.alerting.reasonActionVariableDescription": "どのメトリックがどのしきい値を超えたのかを含む、アラートがこの状態である理由に関する説明", + "xpack.infra.metrics.alerting.thresholdActionVariableDescription": "アラートしきい値のレコード。条件でグループ化されます(threshold.condition0、threshold.condition1など)。", + "xpack.infra.metrics.alerting.valueActionVariableDescription": "監視されたメトリックの現在の値のレコード。条件でグループ化されます(value.condition0、value.condition1など)。", "xpack.infra.metrics.alerting.threshold.alertState": "アラート", + "xpack.infra.metrics.alerting.threshold.belowRecovery": "より小", "xpack.infra.metrics.alerting.threshold.betweenComparator": "の間", + "xpack.infra.metrics.alerting.threshold.betweenRecovery": "の間", "xpack.infra.metrics.alerting.threshold.defaultActionMessage": "\\{\\{alertName\\}\\} - \\{\\{context.group\\}\\}は状態\\{\\{context.alertState\\}\\}です\n\n理由:\n\\{\\{context.reason\\}\\}\n", "xpack.infra.metrics.alerting.threshold.documentCount": "ドキュメントカウント", "xpack.infra.metrics.alerting.threshold.eqComparator": "等しい", @@ -7699,6 +8928,7 @@ "xpack.infra.metrics.alerting.threshold.noDataState": "データなし", "xpack.infra.metrics.alerting.threshold.okState": "OK [回復済み]", "xpack.infra.metrics.alerting.threshold.outsideRangeComparator": "の間にない", + "xpack.infra.metrics.alerting.threshold.recoveredAlertReason": "{metric}は{comparator} {threshold}のしきい値です(現在の値は{currentValue})", "xpack.infra.metrics.alerting.threshold.thresholdRange": "{a}と{b}", "xpack.infra.metrics.alerts.dataTimeRangeLabel": "過去{lookback} {timeLabel}", "xpack.infra.metrics.alerts.dataTimeRangeLabelWithGrouping": "{id}のデータの過去{lookback} {timeLabel}", @@ -7718,6 +8948,7 @@ "xpack.infra.metrics.missingTSVBModelError": "{nodeType}では{metricId}のTSVBモデルが存在しません", "xpack.infra.metrics.pluginTitle": "メトリック", "xpack.infra.metrics.refetchButtonLabel": "新規データを確認", + "xpack.infra.metricsExploer.everything": "すべて", "xpack.infra.metricsExplorer.actionsLabel.aria": "{grouping} のアクション", "xpack.infra.metricsExplorer.actionsLabel.button": "アクション", "xpack.infra.metricsExplorer.aggregationLabel": "/", @@ -7732,6 +8963,7 @@ "xpack.infra.metricsExplorer.aggregationLables.sum": "合計", "xpack.infra.metricsExplorer.aggregationSelectLabel": "集約を選択してください", "xpack.infra.metricsExplorer.alerts.createAlertButton": "アラートの作成", + "xpack.infra.metricsExplorer.andLabel": "\"および\"", "xpack.infra.metricsExplorer.chartOptions.areaLabel": "エリア", "xpack.infra.metricsExplorer.chartOptions.autoLabel": "自動 (最低 ~ 最高)", "xpack.infra.metricsExplorer.chartOptions.barLabel": "バー", @@ -7760,6 +8992,7 @@ "xpack.infra.metricsExplorer.noMetrics.title": "不足しているメトリック", "xpack.infra.metricsExplorer.openInTSVB": "ビジュアライザーで開く", "xpack.infra.metricsExplorer.viewNodeDetail": "{name} のメトリックを表示", + "xpack.infra.metricsHeaderAddDataButtonLabel": "データの追加", "xpack.infra.node.ariaLabel": "{nodeName}、クリックしてメニューを開きます", "xpack.infra.nodeContextMenu.createAlertLink": "アラートの作成", "xpack.infra.nodeContextMenu.description": "{label} {value} の詳細を表示", @@ -7788,7 +9021,8 @@ "xpack.infra.openView.cancelButton": "キャンセル", "xpack.infra.openView.columnNames.actions": "アクション", "xpack.infra.openView.columnNames.name": "名前", - "xpack.infra.openView.flyoutHeader": "ビューを読み込む", + "xpack.infra.openView.flyoutHeader": "保存されたビューの管理", + "xpack.infra.openView.loadButton": "ビューの読み込み", "xpack.infra.parseInterval.errorMessage": "{value}は間隔文字列ではありません", "xpack.infra.redirectToNodeLogs.loadingNodeLogsMessage": "{nodeType} ログを読み込み中", "xpack.infra.registerFeatures.infraOpsDescription": "共通のサーバー、コンテナー、サービスのインフラストラクチャーメトリックとログを閲覧します。", @@ -7796,9 +9030,18 @@ "xpack.infra.registerFeatures.logsDescription": "ログをリアルタイムでストリーするか、コンソール式の UI で履歴ビューをスクロールします。", "xpack.infra.registerFeatures.logsTitle": "ログ", "xpack.infra.sampleDataLinkLabel": "ログ", + "xpack.infra.savedView.changeView": "ビューの変更", + "xpack.infra.savedView.currentView": "現在のビュー", + "xpack.infra.savedView.defaultViewNameHosts": "デフォルトビュー", "xpack.infra.savedView.errorOnCreate.duplicateViewName": "その名前のビューは既に存在します", "xpack.infra.savedView.errorOnCreate.title": "ビューの保存中にエラーが発生しました。", "xpack.infra.savedView.findError.title": "ビューの読み込み中にエラーが発生しました。", + "xpack.infra.savedView.loadView": "ビューの読み込み", + "xpack.infra.savedView.manageViews": "ビューの管理", + "xpack.infra.savedView.saveNewView": "新しいビューの保存", + "xpack.infra.savedView.searchPlaceholder": "保存されたビューの検索", + "xpack.infra.savedView.unknownView": "不明", + "xpack.infra.savedView.updateView": "ビューの更新", "xpack.infra.snapshot.missingSnapshotMetricError": "{nodeType}の{metric}の集約を使用できません。", "xpack.infra.sourceConfiguration.addLogColumnButtonLabel": "列を追加", "xpack.infra.sourceConfiguration.applySettingsButtonLabel": "申し込む", @@ -7824,7 +9067,7 @@ "xpack.infra.sourceConfiguration.logIndicesRecommendedValue": "推奨値は {defaultValue} です", "xpack.infra.sourceConfiguration.logIndicesTitle": "ログインデックス", "xpack.infra.sourceConfiguration.messageLogColumnDescription": "このシステムフィールドは、ドキュメントフィールドから取得されたログエントリーメッセージを表示します。", - "xpack.infra.sourceConfiguration.metricIndicesDescription": "Metricbeat データを含む一致するインデックスのインデックスパターンです", + "xpack.infra.sourceConfiguration.metricIndicesDescription": "メトリックデータを含む一致するインデックスのインデックスパターンです", "xpack.infra.sourceConfiguration.metricIndicesLabel": "メトリックインデックス", "xpack.infra.sourceConfiguration.metricIndicesRecommendedValue": "推奨値は {defaultValue} です", "xpack.infra.sourceConfiguration.metricIndicesTitle": "メトリックインデックス", @@ -7854,6 +9097,7 @@ "xpack.infra.tableView.columnName.last1m": "過去 1m", "xpack.infra.tableView.columnName.max": "最高", "xpack.infra.tableView.columnName.name": "名前", + "xpack.infra.trialStatus.trialStatusNetworkErrorMessage": "試用版ライセンスが利用可能かどうかを判断できませんでした", "xpack.infra.useHTTPRequest.error.status": "エラー", "xpack.infra.useHTTPRequest.error.title": "リソースの取得中にエラーが発生しました", "xpack.infra.useHTTPRequest.error.url": "URL", @@ -7861,6 +9105,7 @@ "xpack.infra.viewSwitcher.mapViewLabel": "マップビュー", "xpack.infra.viewSwitcher.tableViewLabel": "表ビュー", "xpack.infra.waffle.accountAllTitle": "すべて", + "xpack.infra.waffle.accountLabel": "アカウント", "xpack.infra.waffle.aggregationNames.avg": "{field} の平均", "xpack.infra.waffle.aggregationNames.max": "{field} の最大値", "xpack.infra.waffle.aggregationNames.min": "{field} の最小値", @@ -7896,8 +9141,10 @@ "xpack.infra.waffle.customMetrics.modeSwitcher.saveButtonAriaLabel": "カスタムメトリックの変更を保存", "xpack.infra.waffle.customMetrics.submitLabel": "保存", "xpack.infra.waffle.groupByAllTitle": "すべて", + "xpack.infra.waffle.groupByLabel": "グループ分けの条件", "xpack.infra.waffle.loadingDataText": "データを読み込み中", "xpack.infra.waffle.maxGroupByTooltip": "一度に選択できるグループは 2 つのみです", + "xpack.infra.waffle.metriclabel": "メトリック", "xpack.infra.waffle.metricOptions.countText": "カウント", "xpack.infra.waffle.metricOptions.cpuUsageText": "CPU 使用状況", "xpack.infra.waffle.metricOptions.diskIOReadBytes": "ディスク読み取り", @@ -7924,7 +9171,10 @@ "xpack.infra.waffle.noDataDescription": "期間またはフィルターを調整してみてください。", "xpack.infra.waffle.noDataTitle": "表示するデータがありません。", "xpack.infra.waffle.region": "すべて", + "xpack.infra.waffle.regionLabel": "地域", "xpack.infra.waffle.savedView.createHeader": "ビューを保存", + "xpack.infra.waffle.savedView.selectViewHeader": "読み込むビューを選択", + "xpack.infra.waffle.savedView.updateHeader": "ビューの更新", "xpack.infra.waffle.savedViews.cancel": "キャンセル", "xpack.infra.waffle.savedViews.cancelButton": "キャンセル", "xpack.infra.waffle.savedViews.includeTimeFilterLabel": "ビューに時刻を保存", @@ -7932,6 +9182,11 @@ "xpack.infra.waffle.savedViews.saveButton": "保存", "xpack.infra.waffle.savedViews.viewNamePlaceholder": "名前", "xpack.infra.waffle.selectTwoGroupingsTitle": "最大 2 つのグループ分けを選択してください", + "xpack.infra.waffle.showLabel": "表示", + "xpack.infra.waffle.sort.valueLabel": "メトリック値", + "xpack.infra.waffle.sortDirectionLabel": "逆方向", + "xpack.infra.waffle.sortLabel": "並べ替え基準", + "xpack.infra.waffle.sortNameLabel": "名前", "xpack.infra.waffle.unableToSelectGroupErrorMessage": "{nodeType} のオプションでグループを選択できません", "xpack.infra.waffle.unableToSelectMetricErrorTitle": "メトリックのオプションまたは値を選択できません", "xpack.infra.waffleTime.autoRefreshButtonLabel": "自動更新", @@ -7942,6 +9197,10 @@ "xpack.ingestManager.agentConfig.confirmModalDescription": "このアクションは元に戻せません。続行していいですか?", "xpack.ingestManager.agentConfig.confirmModalTitle": "変更を保存してデプロイ", "xpack.ingestManager.agentConfig.linkedAgentCountText": "{count, plural, one {# エージェント} other {# エージェント}}", + "xpack.ingestManager.agentConfigActionMenu.buttonText": "アクション", + "xpack.ingestManager.agentConfigActionMenu.copyConfigActionText": "構成のコピー", + "xpack.ingestManager.agentConfigActionMenu.enrollAgentActionText": "エージェントの追加", + "xpack.ingestManager.agentConfigActionMenu.viewConfigText": "構成を表示", "xpack.ingestManager.agentConfigForm.advancedOptionsToggleLabel": "高度なオプション", "xpack.ingestManager.agentConfigForm.descriptionFieldLabel": "説明", "xpack.ingestManager.agentConfigForm.descriptionFieldPlaceholder": "この構成がどのように使用されるか", @@ -7952,11 +9211,12 @@ "xpack.ingestManager.agentConfigForm.nameFieldLabel": "名前", "xpack.ingestManager.agentConfigForm.nameFieldPlaceholder": "名前を選択", "xpack.ingestManager.agentConfigForm.nameRequiredErrorMessage": "エージェント構成名が必要です", - "xpack.ingestManager.agentConfigForm.namespaceFieldDescription": "この構成を使用するデータソースにデフォルトの名前空間を適用します。データソースはその独自の名前空間を指定できます。", + "xpack.ingestManager.agentConfigForm.namespaceFieldDescription": "この構成を使用する統合にデフォルトの名前空間を適用します。統合はその独自の名前空間を指定できます。", "xpack.ingestManager.agentConfigForm.namespaceFieldLabel": "デフォルト名前空間", + "xpack.ingestManager.agentConfigForm.namespaceRequiredErrorMessage": "ネームスペースが必要です", "xpack.ingestManager.agentConfigForm.systemMonitoringFieldLabel": "オプション", "xpack.ingestManager.agentConfigForm.systemMonitoringText": "システムメトリックを収集", - "xpack.ingestManager.agentConfigForm.systemMonitoringTooltipText": "このオプションを有効にすると、システムメトリックと情報を収集するデータソースで構成をブートストラップできます。", + "xpack.ingestManager.agentConfigForm.systemMonitoringTooltipText": "このオプションを有効にすると、システムメトリックと情報を収集する統合で構成をブートストラップできます。", "xpack.ingestManager.agentConfigList.actionsColumnTitle": "アクション", "xpack.ingestManager.agentConfigList.addButton": "エージェント構成を作成", "xpack.ingestManager.agentConfigList.agentsColumnTitle": "エージェント", @@ -7966,6 +9226,7 @@ "xpack.ingestManager.agentConfigList.nameColumnTitle": "名前", "xpack.ingestManager.agentConfigList.noAgentConfigsPrompt": "エージェント構成なし", "xpack.ingestManager.agentConfigList.noFilteredAgentConfigsPrompt": "エージェント構成が見つかりません。 {clearFiltersLink}", + "xpack.ingestManager.agentConfigList.packageConfigsCountColumnTitle": "統合", "xpack.ingestManager.agentConfigList.pageSubtitle": "エージェント構成を使用すると、エージェントとエージェントが収集するデータを管理できます。", "xpack.ingestManager.agentConfigList.pageTitle": "エージェント構成", "xpack.ingestManager.agentConfigList.reloadAgentConfigsButtonText": "再読み込み", @@ -7988,16 +9249,30 @@ "xpack.ingestManager.agentDetails.unexceptedErrorTitle": "エージェントの読み込み中にエラーが発生しました", "xpack.ingestManager.agentDetails.userProvidedMetadataSectionSubtitle": "ユーザー提供メタデータ", "xpack.ingestManager.agentDetails.versionLabel": "エージェントバージョン", - "xpack.ingestManager.agentDetails.viewAgentListTitle": "すべてのエージェント構成を表示", + "xpack.ingestManager.agentDetails.viewAgentListTitle": "すべてのエージェントを表示", "xpack.ingestManager.agentEnrollment.cancelButtonLabel": "キャンセル", "xpack.ingestManager.agentEnrollment.continueButtonLabel": "続行", - "xpack.ingestManager.agentEnrollment.downloadLink": "ダウンロードページ", + "xpack.ingestManager.agentEnrollment.copyConfigurationButton": "クリップボードにコピー", + "xpack.ingestManager.agentEnrollment.copyRunInstructionsButton": "クリップボードにコピー", + "xpack.ingestManager.agentEnrollment.downloadConfigurationButton": "構成のダウンロード", + "xpack.ingestManager.agentEnrollment.downloadDescription": "ホストのコンピューターでElasticエージェントをダウンロードします。Elasticエージェントダウンロードページでは、エージェントバイナリと検証署名にアクセスできます。", + "xpack.ingestManager.agentEnrollment.downloadLink": "elastic.co/downloadsに移動", + "xpack.ingestManager.agentEnrollment.enrollFleetTabLabel": "フリートに登録", + "xpack.ingestManager.agentEnrollment.enrollStandaloneTabLabel": "スタンドアロンモード", "xpack.ingestManager.agentEnrollment.fleetNotInitializedText": "エージェントを登録する前に、フリートを設定する必要があります。{link}", - "xpack.ingestManager.agentEnrollment.flyoutTitle": "新しいエージェントを登録", + "xpack.ingestManager.agentEnrollment.flyoutTitle": "エージェントの追加", "xpack.ingestManager.agentEnrollment.goToFleetButton": "フリートに移動します。", + "xpack.ingestManager.agentEnrollment.managedDescription": "必要なエージェントの数に関係なく、Fleetでは、簡単に一元的に更新を管理し、エージェントにデプロイすることができます。次の手順に従い、Elasticエージェントをダウンロードし、Fleetに登録してください。", + "xpack.ingestManager.agentEnrollment.standaloneDescription": "スタンドアロンモードで実行中のエージェントは、構成を変更したい場合には、手動で更新する必要があります。次の手順に従い、スタンドアロンモードでElasticエージェントをダウンロードし、セットアップしてください。", + "xpack.ingestManager.agentEnrollment.stepCheckForDataDescription": "エージェントを起動した後、エージェントはデータの送信を開始します。Ingest Managerのデータセットページでは、このデータを確認できます。", + "xpack.ingestManager.agentEnrollment.stepCheckForDataTitle": "データを確認", "xpack.ingestManager.agentEnrollment.stepChooseAgentConfigTitle": "エージェント構成を選択", + "xpack.ingestManager.agentEnrollment.stepConfigureAgentDescription": "この構成をコピーし、Elasticエージェントがインストールされているシステムのファイル{fileName}に置きます。必ず、構成ファイルの{outputSection}セクションで{ESUsernameVariable}と{ESPasswordVariable}を修正し、実際のElasticsearch認証資格情報が使用されるようにしてください。", + "xpack.ingestManager.agentEnrollment.stepConfigureAgentTitle": "エージェントの構成", "xpack.ingestManager.agentEnrollment.stepDownloadAgentTitle": "Elasticエージェントをダウンロード", - "xpack.ingestManager.agentEnrollment.stepRunAgentTitle": "Elasticエージェントを登録して実行", + "xpack.ingestManager.agentEnrollment.stepEnrollAndRunAgentTitle": "Elasticエージェントを登録して実行", + "xpack.ingestManager.agentEnrollment.stepRunAgentDescription": "エージェントディレクトリで、次のコマンドを実行し、エージェントを起動します。", + "xpack.ingestManager.agentEnrollment.stepRunAgentTitle": "エージェントの起動", "xpack.ingestManager.agentEventsList.collapseDetailsAriaLabel": "詳細を非表示", "xpack.ingestManager.agentEventsList.expandDetailsAriaLabel": "詳細を表示", "xpack.ingestManager.agentEventsList.messageColumnTitle": "メッセージ", @@ -8023,18 +9298,21 @@ "xpack.ingestManager.agentEventType.errorLabel": "エラー", "xpack.ingestManager.agentEventType.stateLabel": "ステータス", "xpack.ingestManager.agentHealth.checkInTooltipText": "前回のチェックイン {lastCheckIn}", + "xpack.ingestManager.agentHealth.degradedStatusText": "劣化", + "xpack.ingestManager.agentHealth.enrollingStatusText": "登録中", "xpack.ingestManager.agentHealth.errorStatusText": "エラー", "xpack.ingestManager.agentHealth.inactiveStatusText": "非アクティブ", "xpack.ingestManager.agentHealth.noCheckInTooltipText": "チェックインしない", "xpack.ingestManager.agentHealth.offlineStatusText": "オフライン", "xpack.ingestManager.agentHealth.onlineStatusText": "オンライン", + "xpack.ingestManager.agentHealth.unenrollingStatusText": "登録解除中", "xpack.ingestManager.agentHealth.warningStatusText": "エラー", "xpack.ingestManager.agentList.actionsColumnTitle": "アクション", - "xpack.ingestManager.agentList.addButton": "新しいエージェントを登録", + "xpack.ingestManager.agentList.addButton": "エージェントの追加", "xpack.ingestManager.agentList.clearFiltersLinkText": "フィルターを消去", - "xpack.ingestManager.agentList.configColumnTitle": "構成", - "xpack.ingestManager.agentList.configFilterText": "構成", - "xpack.ingestManager.agentList.enrollButton": "新しいエージェントを登録", + "xpack.ingestManager.agentList.configColumnTitle": "エージェント構成", + "xpack.ingestManager.agentList.configFilterText": "エージェント構成", + "xpack.ingestManager.agentList.enrollButton": "エージェントの追加", "xpack.ingestManager.agentList.hostColumnTitle": "ホスト", "xpack.ingestManager.agentList.lastCheckinTitle": "前回のアクティビティ", "xpack.ingestManager.agentList.loadingAgentsMessage": "エージェントを読み込み中...", @@ -8057,70 +9335,118 @@ "xpack.ingestManager.agentListStatus.onlineLabel": "オンライン", "xpack.ingestManager.agentListStatus.totalLabel": "エージェント", "xpack.ingestManager.agentReassignConfig.cancelButtonLabel": "キャンセル", - "xpack.ingestManager.agentReassignConfig.configDescription": "選択したエージェント構成は、{count, plural, one {{countValue}データソース} other {{countValue}データソース}}のデータを収集します:", + "xpack.ingestManager.agentReassignConfig.configDescription": "選択したエージェント構成は、{count, plural, one {{countValue}個の統合} other {{countValue}個の統合}}のデータを収集します。", "xpack.ingestManager.agentReassignConfig.continueButtonLabel": "構成を割り当て", "xpack.ingestManager.agentReassignConfig.flyoutDescription": "選択したエージェントに割り当てる、新しいエージェント構成を選択します。", "xpack.ingestManager.agentReassignConfig.flyoutTitle": "新しいエージェント構成を割り当て", "xpack.ingestManager.agentReassignConfig.selectConfigLabel": "エージェント構成", "xpack.ingestManager.agentReassignConfig.successSingleNotificationTitle": "新しいエージェント構成が再割り当てされました", - "xpack.ingestManager.alphaMessageDescription": "Ingest Managerは開発中であり、本番用ではありません。", - "xpack.ingestManager.alphaMessageTitle": "実験的", + "xpack.ingestManager.alphaMessageDescription": "Ingest Managerは本番環境用ではありません。", + "xpack.ingestManager.alphaMessageLinkText": "詳細を参照してください。", + "xpack.ingestManager.alphaMessageTitle": "ベータリリース", "xpack.ingestManager.alphaMessaging.docsLink": "ドキュメンテーション", "xpack.ingestManager.alphaMessaging.feedbackText": "{docsLink}をお読みになるか、{forumLink}で質問や回答をすることをお勧めします。", "xpack.ingestManager.alphaMessaging.flyoutTitle": "このリリースについて", "xpack.ingestManager.alphaMessaging.forumLink": "ディスカッションフォーラム", - "xpack.ingestManager.alphaMessaging.introText": "このリリースはテスト段階であり、SLAの対象ではありません。ユーザーがIngest Managerと新しいElasticエージェントをテストしてフィードバックを提供することを目的としています。今後のリリースにおいて特定の機能が変更されたり、廃止されたりする可能性があるため、本番環境で使用しないでください。", + "xpack.ingestManager.alphaMessaging.introText": "Ingest Managerは開発中であり、本番環境用ではありません。このベータリリースは、ユーザーがIngest Managerと新しいElasticエージェントをテストしてフィードバックを提供することを目的としています。このプラグインには、サポートSLAが適用されません。", "xpack.ingestManager.alphaMessging.closeFlyoutLabel": "閉じる", "xpack.ingestManager.appNavigation.configurationsLinkText": "構成", - "xpack.ingestManager.appNavigation.dataStreamsLinkText": "データストリーム", + "xpack.ingestManager.appNavigation.dataStreamsLinkText": "データセット", "xpack.ingestManager.appNavigation.epmLinkText": "統合", "xpack.ingestManager.appNavigation.fleetLinkText": "フリート", "xpack.ingestManager.appNavigation.overviewLinkText": "概要", "xpack.ingestManager.appNavigation.sendFeedbackButton": "フィードバックを送信", "xpack.ingestManager.appNavigation.settingsButton": "設定", "xpack.ingestManager.appTitle": "Ingest Manager", + "xpack.ingestManager.betaBadge.labelText": "ベータ", + "xpack.ingestManager.betaBadge.tooltipText": "このプラグインは本番環境用ではありません。バグについてはディスカッションフォーラムで報告してください。", + "xpack.ingestManager.breadcrumbs.addPackageConfigPageTitle": "統合の追加", + "xpack.ingestManager.breadcrumbs.allIntegrationsPageTitle": "すべて", + "xpack.ingestManager.breadcrumbs.appTitle": "Ingest Manager", + "xpack.ingestManager.breadcrumbs.configurationsPageTitle": "構成", + "xpack.ingestManager.breadcrumbs.datastreamsPageTitle": "データセット", + "xpack.ingestManager.breadcrumbs.editPackageConfigPageTitle": "統合の編集", + "xpack.ingestManager.breadcrumbs.fleetAgentsPageTitle": "エージェント", + "xpack.ingestManager.breadcrumbs.fleetEnrollmentTokensPageTitle": "登録トークン", + "xpack.ingestManager.breadcrumbs.fleetPageTitle": "フリート", + "xpack.ingestManager.breadcrumbs.installedIntegrationsPageTitle": "インストール済み", + "xpack.ingestManager.breadcrumbs.integrationsPageTitle": "統合", + "xpack.ingestManager.breadcrumbs.overviewPageTitle": "概要", + "xpack.ingestManager.configDetails.addPackageConfigButtonText": "統合の追加", "xpack.ingestManager.configDetails.configDetailsTitle": "構成「{id}」", "xpack.ingestManager.configDetails.configNotFoundErrorTitle": "構成「{id}」が見つかりません", + "xpack.ingestManager.configDetails.packageConfigsTable.actionsColumnTitle": "アクション", + "xpack.ingestManager.configDetails.packageConfigsTable.deleteActionTitle": "統合の削除", + "xpack.ingestManager.configDetails.packageConfigsTable.descriptionColumnTitle": "説明", + "xpack.ingestManager.configDetails.packageConfigsTable.editActionTitle": "統合の編集", + "xpack.ingestManager.configDetails.packageConfigsTable.nameColumnTitle": "名前", + "xpack.ingestManager.configDetails.packageConfigsTable.namespaceColumnTitle": "名前空間", + "xpack.ingestManager.configDetails.packageConfigsTable.packageNameColumnTitle": "統合", + "xpack.ingestManager.configDetails.subTabs.packageConfigsTabText": "統合", "xpack.ingestManager.configDetails.subTabs.settingsTabText": "設定", "xpack.ingestManager.configDetails.summary.lastUpdated": "最終更新日:", + "xpack.ingestManager.configDetails.summary.package_configs": "統合", "xpack.ingestManager.configDetails.summary.revision": "リビジョン", "xpack.ingestManager.configDetails.summary.usedBy": "使用者", "xpack.ingestManager.configDetails.unexceptedErrorTitle": "構成を読み込む間にエラーが発生しました", "xpack.ingestManager.configDetails.viewAgentListTitle": "すべてのエージェント構成を表示", + "xpack.ingestManager.configDetails.yamlDownloadButtonLabel": "構成のダウンロード", + "xpack.ingestManager.configDetails.yamlFlyoutCloseButtonLabel": "閉じる", + "xpack.ingestManager.configDetails.yamlflyoutTitleWithName": "「{name}」エージェント構成の編集", + "xpack.ingestManager.configDetails.yamlflyoutTitleWithoutName": "エージェント構成", + "xpack.ingestManager.configDetailsPackageConfigs.createFirstButtonText": "統合の追加", + "xpack.ingestManager.configDetailsPackageConfigs.createFirstMessage": "この構成にはまだ統合がありません。", + "xpack.ingestManager.configDetailsPackageConfigs.createFirstTitle": "最初の統合を追加", "xpack.ingestManager.configForm.deleteConfigActionText": "構成を削除", "xpack.ingestManager.configForm.deleteConfigGroupDescription": "既存のデータは削除されません。", "xpack.ingestManager.configForm.deleteConfigGroupTitle": "構成を削除", "xpack.ingestManager.configForm.generalSettingsGroupDescription": "エージェント構成の名前と説明を選択してください。", "xpack.ingestManager.configForm.generalSettingsGroupTitle": "一般設定", "xpack.ingestManager.configForm.unableToDeleteDefaultConfigText": "既定の構成は削除できません。", + "xpack.ingestManager.copyAgentConfig.confirmModal.cancelButtonLabel": "キャンセル", + "xpack.ingestManager.copyAgentConfig.confirmModal.confirmButtonLabel": "構成をコピー", + "xpack.ingestManager.copyAgentConfig.confirmModal.copyConfigPrompt": "新しいエージェント構成の名前と説明を選択してください。", + "xpack.ingestManager.copyAgentConfig.confirmModal.copyConfigTitle": "「{name}」エージェント構成をコピー", + "xpack.ingestManager.copyAgentConfig.confirmModal.defaultNewConfigName": "{name}(コピー)", + "xpack.ingestManager.copyAgentConfig.confirmModal.newDescriptionLabel": "説明", + "xpack.ingestManager.copyAgentConfig.confirmModal.newNameLabel": "新しい構成名", + "xpack.ingestManager.copyAgentConfig.failureNotificationTitle": "エージェント構成「{id}」のコピーエラー", + "xpack.ingestManager.copyAgentConfig.fatalErrorNotificationTitle": "エージェント構成のコピーエラー", + "xpack.ingestManager.copyAgentConfig.successNotificationTitle": "エージェント構成がコピーされました", "xpack.ingestManager.createAgentConfig.cancelButtonLabel": "キャンセル", "xpack.ingestManager.createAgentConfig.errorNotificationTitle": "エージェント構成を作成できません", "xpack.ingestManager.createAgentConfig.flyoutTitle": "エージェント構成を作成", - "xpack.ingestManager.createAgentConfig.flyoutTitleDescription": "エージェント構成は、エージェントのグループ全体にわたる設定を管理する目的で使用されます。エージェント構成にデータソースを追加すると、エージェントで収集するデータを指定できます。エージェント構成の編集時には、フリートを使用して、指定したエージェントのグループに更新をデプロイできます。", + "xpack.ingestManager.createAgentConfig.flyoutTitleDescription": "エージェント構成は、エージェントのグループ全体にわたる設定を管理する目的で使用されます。エージェント構成に統合を追加すると、エージェントで収集するデータを指定できます。エージェント構成の編集時には、フリートを使用して、指定したエージェントのグループに更新をデプロイできます。", "xpack.ingestManager.createAgentConfig.submitButtonLabel": "エージェント構成を作成", "xpack.ingestManager.createAgentConfig.successNotificationTitle": "エージェント構成「{name}」を作成しました", "xpack.ingestManager.createPackageConfig.addedNotificationMessage": "フリートは'{agentConfigName}'構成で使用されているすべてのエージェントに更新をデプロイします。", - "xpack.ingestManager.createPackageConfig.addedNotificationTitle": "正常に'{packageConfigName}'を追加しました", - "xpack.ingestManager.createPackageConfig.agentConfigurationNameLabel": "構成", + "xpack.ingestManager.createPackageConfig.addedNotificationTitle": "正常に「{packageConfigName}」を追加しました", + "xpack.ingestManager.createPackageConfig.agentConfigurationNameLabel": "エージェント構成", "xpack.ingestManager.createPackageConfig.cancelButton": "キャンセル", "xpack.ingestManager.createPackageConfig.cancelLinkText": "キャンセル", - "xpack.ingestManager.createPackageConfig.pageDescriptionfromConfig": "次の手順に従い、統合をこのエージェント構成に追加します。", + "xpack.ingestManager.createPackageConfig.errorOnSaveText": "統合構成にはエラーがあります。保存前に修正してください。", + "xpack.ingestManager.createPackageConfig.pageDescriptionfromConfig": "選択したエージェント構成の統合を構成します。", "xpack.ingestManager.createPackageConfig.pageDescriptionfromPackage": "次の手順に従い、この統合をエージェント構成に追加します。", - "xpack.ingestManager.createPackageConfig.pageTitle": "データソースを追加", - "xpack.ingestManager.createPackageConfig.saveButton": "データソースを保存", - "xpack.ingestManager.createPackageConfig.stepConfigurePackageConfigTitle": "収集するデータを選択", + "xpack.ingestManager.createPackageConfig.pageTitle": "統合の追加", + "xpack.ingestManager.createPackageConfig.pageTitleWithPackageName": "{packageName}統合の追加", + "xpack.ingestManager.createPackageConfig.saveButton": "統合の保存", "xpack.ingestManager.createPackageConfig.stepConfigure.advancedOptionsToggleLinkText": "高度なオプション", - "xpack.ingestManager.createPackageConfig.stepConfigure.packageConfigDescriptionInputLabel": "説明", - "xpack.ingestManager.createPackageConfig.stepConfigure.packageConfigNameInputLabel": "データソース名", - "xpack.ingestManager.createPackageConfig.stepConfigure.packageConfigNamespaceInputLabel": "名前空間", - "xpack.ingestManager.createPackageConfig.stepConfigure.hideStreamsAriaLabel": "{type} ストリームを隠す", - "xpack.ingestManager.createPackageConfig.stepConfigure.inputSettingsDescription": "次の設定はすべてのストリームに適用されます。", + "xpack.ingestManager.createPackageConfig.stepConfigure.errorCountText": "{count, plural, one {件のエラー} other {件のエラー}}", + "xpack.ingestManager.createPackageConfig.stepConfigure.hideStreamsAriaLabel": "{type}入力を非表示", + "xpack.ingestManager.createPackageConfig.stepConfigure.inputSettingsDescription": "次の設定は以下のすべての入力に適用されます。", "xpack.ingestManager.createPackageConfig.stepConfigure.inputSettingsTitle": "設定", "xpack.ingestManager.createPackageConfig.stepConfigure.inputVarFieldOptionalLabel": "オプション", + "xpack.ingestManager.createPackageConfig.stepConfigure.integrationSettingsSectionDescription": "この統合の使用方法を識別できるように、名前と説明を選択してください。", + "xpack.ingestManager.createPackageConfig.stepConfigure.integrationSettingsSectionTitle": "統合設定", "xpack.ingestManager.createPackageConfig.stepConfigure.noConfigOptionsMessage": "構成するものがありません", - "xpack.ingestManager.createPackageConfig.stepConfigure.showStreamsAriaLabel": "{type} ストリームを表示", + "xpack.ingestManager.createPackageConfig.stepConfigure.packageConfigDescriptionInputLabel": "説明", + "xpack.ingestManager.createPackageConfig.stepConfigure.packageConfigNameInputLabel": "統合名", + "xpack.ingestManager.createPackageConfig.stepConfigure.packageConfigNamespaceInputLabel": "名前空間", + "xpack.ingestManager.createPackageConfig.stepConfigure.showStreamsAriaLabel": "{type}入力を表示", "xpack.ingestManager.createPackageConfig.stepConfigure.toggleAdvancedOptionsButtonText": "高度なオプション", + "xpack.ingestManager.createPackageConfig.stepConfigurePackageConfigTitle": "統合の構成", "xpack.ingestManager.createPackageConfig.stepSelectAgentConfigTitle": "エージェント構成を選択する", + "xpack.ingestManager.createPackageConfig.StepSelectConfig.addButton": "新しいエージェント構成", "xpack.ingestManager.createPackageConfig.StepSelectConfig.agentConfigAgentsCountText": "{count, plural, one {# エージェント} other {# エージェント}}", "xpack.ingestManager.createPackageConfig.StepSelectConfig.errorLoadingAgentConfigsTitle": "エージェント構成の読み込みエラー", "xpack.ingestManager.createPackageConfig.StepSelectConfig.errorLoadingPackageTitle": "パッケージ情報の読み込みエラー", @@ -8131,22 +9457,18 @@ "xpack.ingestManager.createPackageConfig.stepSelectPackage.errorLoadingSelectedPackageTitle": "選択した統合の読み込みエラー", "xpack.ingestManager.createPackageConfig.stepSelectPackage.filterPackagesInputPlaceholder": "統合を検索", "xpack.ingestManager.createPackageConfig.stepSelectPackageTitle": "統合を選択", - "xpack.ingestManager.packageConfigValidation.invalidArrayErrorMessage": "無効なフォーマット", - "xpack.ingestManager.packageConfigValidation.invalidYamlFormatErrorMessage": "YAML形式が無効です", - "xpack.ingestManager.packageConfigValidation.nameRequiredErrorMessage": "名前が必要です", - "xpack.ingestManager.packageConfigValidation.requiredErrorMessage": "{fieldName}が必要です", "xpack.ingestManager.dataStreamList.actionsColumnTitle": "アクション", "xpack.ingestManager.dataStreamList.datasetColumnTitle": "データセット", "xpack.ingestManager.dataStreamList.integrationColumnTitle": "統合", "xpack.ingestManager.dataStreamList.lastActivityColumnTitle": "前回のアクティビティ", - "xpack.ingestManager.dataStreamList.loadingDataStreamsMessage": "データストリームを読み込んでいます...", + "xpack.ingestManager.dataStreamList.loadingDataStreamsMessage": "データセットを読み込んでいます...", "xpack.ingestManager.dataStreamList.namespaceColumnTitle": "名前空間", - "xpack.ingestManager.dataStreamList.noDataStreamsPrompt": "データストリームがありません", - "xpack.ingestManager.dataStreamList.noFilteredDataStreamsMessage": "一致するデータストリームが見つかりません", + "xpack.ingestManager.dataStreamList.noDataStreamsPrompt": "データセットなし", + "xpack.ingestManager.dataStreamList.noFilteredDataStreamsMessage": "一致するデータセットが見つかりません", "xpack.ingestManager.dataStreamList.pageSubtitle": "エージェントが作成したデータを管理します。", - "xpack.ingestManager.dataStreamList.pageTitle": "データストリーム", + "xpack.ingestManager.dataStreamList.pageTitle": "データセット", "xpack.ingestManager.dataStreamList.reloadDataStreamsButtonText": "再読み込み", - "xpack.ingestManager.dataStreamList.searchPlaceholderTitle": "データストリームをフィルター", + "xpack.ingestManager.dataStreamList.searchPlaceholderTitle": "データセットのフィルタリング", "xpack.ingestManager.dataStreamList.sizeColumnTitle": "サイズ", "xpack.ingestManager.dataStreamList.typeColumnTitle": "タイプ", "xpack.ingestManager.dataStreamList.viewDashboardActionText": "ダッシュボードを表示", @@ -8164,6 +9486,19 @@ "xpack.ingestManager.deleteAgentConfig.failureSingleNotificationTitle": "エージェント構成「{id}」の削除エラー", "xpack.ingestManager.deleteAgentConfig.fatalErrorNotificationTitle": "エージェント構成の削除エラー", "xpack.ingestManager.deleteAgentConfig.successSingleNotificationTitle": "エージェント構成「{id}」を削除しました", + "xpack.ingestManager.deletePackageConfig.confirmModal.affectedAgentsMessage": "{agentConfigName} が一部のエージェントですでに使用されていることをフリートが検出しました。", + "xpack.ingestManager.deletePackageConfig.confirmModal.affectedAgentsTitle": "このアクションは {agentsCount} {agentsCount, plural, one {# エージェント} other {# エージェント}}に影響します", + "xpack.ingestManager.deletePackageConfig.confirmModal.cancelButtonLabel": "キャンセル", + "xpack.ingestManager.deletePackageConfig.confirmModal.confirmButtonLabel": "{agentConfigsCount, plural, one {個の統合} other {個の統合}}を削除", + "xpack.ingestManager.deletePackageConfig.confirmModal.deleteMultipleTitle": "{count, plural, one {個の統合} other {個の統合}}を削除しますか?", + "xpack.ingestManager.deletePackageConfig.confirmModal.generalMessage": "このアクションは元に戻せません。続行していいですか?", + "xpack.ingestManager.deletePackageConfig.confirmModal.loadingAgentsCountMessage": "影響があるエージェントを確認中...", + "xpack.ingestManager.deletePackageConfig.confirmModal.loadingButtonLabel": "読み込み中...", + "xpack.ingestManager.deletePackageConfig.failureMultipleNotificationTitle": "{count}個の統合の削除エラー", + "xpack.ingestManager.deletePackageConfig.failureSingleNotificationTitle": "統合「{id}」の削除エラー", + "xpack.ingestManager.deletePackageConfig.fatalErrorNotificationTitle": "統合の削除エラー", + "xpack.ingestManager.deletePackageConfig.successMultipleNotificationTitle": "{count}個の統合を削除しました", + "xpack.ingestManager.deletePackageConfig.successSingleNotificationTitle": "統合「{id}」を削除しました", "xpack.ingestManager.disabledSecurityDescription": "Elastic Fleet を使用するには、Kibana と Elasticsearch でセキュリティを有効にする必要があります。", "xpack.ingestManager.disabledSecurityTitle": "セキュリティが有効ではありません", "xpack.ingestManager.editAgentConfig.cancelButtonText": "キャンセル", @@ -8173,17 +9508,18 @@ "xpack.ingestManager.editAgentConfig.successNotificationTitle": "正常に'{name}'設定を更新しました", "xpack.ingestManager.editAgentConfig.unsavedChangesText": "保存されていない変更があります", "xpack.ingestManager.editPackageConfig.cancelButton": "キャンセル", - "xpack.ingestManager.editPackageConfig.errorLoadingDataMessage": "このデータソース情報の読み込みエラーが発生しました", + "xpack.ingestManager.editPackageConfig.errorLoadingDataMessage": "この統合情報の読み込みエラーが発生しました", "xpack.ingestManager.editPackageConfig.errorLoadingDataTitle": "データの読み込み中にエラーが発生", - "xpack.ingestManager.editPackageConfig.pageDescription": "次の手順に従い、このデータソースを編集します。", - "xpack.ingestManager.editPackageConfig.pageTitle": "データソースを編集", - "xpack.ingestManager.editPackageConfig.saveButton": "データソースを保存", + "xpack.ingestManager.editPackageConfig.failedConflictNotificationMessage": "データが最新ではありません。最新の構成を取得するには、ページを更新してください。", + "xpack.ingestManager.editPackageConfig.failedNotificationTitle": "「{packageConfigName}」の更新エラー", + "xpack.ingestManager.editPackageConfig.pageDescription": "統合設定を修正し、選択したエージェント構成に変更をデプロイします。", + "xpack.ingestManager.editPackageConfig.pageTitle": "統合の編集", + "xpack.ingestManager.editPackageConfig.pageTitleWithPackageName": "{packageName}統合の編集", + "xpack.ingestManager.editPackageConfig.saveButton": "統合の保存", "xpack.ingestManager.editPackageConfig.updatedNotificationMessage": "フリートは'{agentConfigName}'構成で使用されているすべてのエージェントに更新をデプロイします。", - "xpack.ingestManager.editPackageConfig.updatedNotificationTitle": "正常に'{packageConfigName}'を更新しました", + "xpack.ingestManager.editPackageConfig.updatedNotificationTitle": "正常に「{packageConfigName}」を更新しました", "xpack.ingestManager.enrollemntAPIKeyList.emptyMessage": "登録トークンが見つかりません。", "xpack.ingestManager.enrollemntAPIKeyList.loadingTokensMessage": "登録トークンを読み込んでいます...", - "xpack.ingestManager.enrollmentInstructions.copyButton": "コマンドをコピー", - "xpack.ingestManager.enrollmentInstructions.descriptionText": "エージェントのディレクトリから、これらのコマンドを実行して、Elasticエージェントを登録して起動します。{enrollCommand}はエージェントの構成ファイルに書き込み、正しい設定になるようにします。このコマンドを使用すると、複数のホストでエージェントを設定できます。", "xpack.ingestManager.enrollmentStepAgentConfig.configSelectAriaLabel": "エージェント構成", "xpack.ingestManager.enrollmentStepAgentConfig.configSelectLabel": "エージェント構成", "xpack.ingestManager.enrollmentStepAgentConfig.enrollmentTokenSelectLabel": "登録トークン", @@ -8194,22 +9530,32 @@ "xpack.ingestManager.enrollmentTokenDeleteModal.title": "登録トークンを削除", "xpack.ingestManager.enrollmentTokensList.actionsTitle": "アクション", "xpack.ingestManager.enrollmentTokensList.activeTitle": "アクティブ", - "xpack.ingestManager.enrollmentTokensList.configTitle": "構成", + "xpack.ingestManager.enrollmentTokensList.configTitle": "エージェント構成", "xpack.ingestManager.enrollmentTokensList.createdAtTitle": "作成日時", "xpack.ingestManager.enrollmentTokensList.nameTitle": "名前", "xpack.ingestManager.enrollmentTokensList.newKeyButton": "新しい登録トークン", "xpack.ingestManager.enrollmentTokensList.pageDescription": "これは、エージェントを登録するために使用できる登録トークンのリストです。", "xpack.ingestManager.enrollmentTokensList.secretTitle": "シークレット", + "xpack.ingestManager.epm.addPackageConfigButtonText": "{packageName}の追加", "xpack.ingestManager.epm.browseAllButtonText": "すべての統合を参照", - "xpack.ingestManager.epm.illustrationAltText": "Elastic統合の例", + "xpack.ingestManager.epm.illustrationAltText": "統合の例", + "xpack.ingestManager.epm.loadingIntegrationErrorTitle": "統合詳細の読み込みエラー", "xpack.ingestManager.epm.packageDetailsNav.overviewLinkText": "概要", + "xpack.ingestManager.epm.packageDetailsNav.packageConfigsLinkText": "使用", "xpack.ingestManager.epm.packageDetailsNav.settingsLinkText": "設定", "xpack.ingestManager.epm.pageSubtitle": "一般的なアプリやサービスの統合を参照する", - "xpack.ingestManager.epm.pageTitle": "Elastic統合", + "xpack.ingestManager.epm.pageTitle": "統合", + "xpack.ingestManager.epm.releaseBadge.betaDescription": "この統合は本番環境用ではありません。", + "xpack.ingestManager.epm.releaseBadge.betaLabel": "ベータ", + "xpack.ingestManager.epm.releaseBadge.experimentalDescription": "この統合は、急に変更されたり、将来のリリースで削除されたりする可能性があります。", + "xpack.ingestManager.epm.releaseBadge.experimentalLabel": "実験的", + "xpack.ingestManager.epm.screenshotsTitle": "スクリーンショット", + "xpack.ingestManager.epm.updateAvailableTooltip": "更新が利用可能です", + "xpack.ingestManager.epm.versionLabel": "バージョン", "xpack.ingestManager.epmList.allFilterLinkText": "すべて", "xpack.ingestManager.epmList.allPackagesFilterLinkText": "すべて", "xpack.ingestManager.epmList.allTabText": "すべての統合", - "xpack.ingestManager.epmList.allTitle": "すべての統合", + "xpack.ingestManager.epmList.allTitle": "カテゴリで参照", "xpack.ingestManager.epmList.installedTabText": "インストールされている統合", "xpack.ingestManager.epmList.installedTitle": "インストールされている統合", "xpack.ingestManager.epmList.noPackagesFoundPlaceholder": "パッケージが見つかりません", @@ -8218,6 +9564,16 @@ "xpack.ingestManager.fleet.pageSubtitle": "構成の更新を管理し、任意のサイズのエージェントのグループにデプロイします。", "xpack.ingestManager.fleet.pageTitle": "フリート", "xpack.ingestManager.genericActionsMenuText": "開く", + "xpack.ingestManager.homeIntegration.tutorialDirectory.dismissNoticeButtonText": "メッセージを消去", + "xpack.ingestManager.homeIntegration.tutorialDirectory.ingestManagerAppButtonText": "Ingest Managerベータを試す", + "xpack.ingestManager.homeIntegration.tutorialDirectory.noticeText": "Elasticエージェントでは、シンプルかつ統合された方法で、ログ、メトリック、他の種類のデータの監視をホストに追加することができます。複数のBeatsと他のエージェントをインストールする必要はありません。このため、インフラストラクチャ全体での構成のデプロイが簡単で高速になりました。詳細については、{blogPostLink}をお読みください。", + "xpack.ingestManager.homeIntegration.tutorialDirectory.noticeText.blogPostLink": "発表ブログ投稿", + "xpack.ingestManager.homeIntegration.tutorialDirectory.noticeTitle": "{newPrefix} ElasticエージェントおよびIngest Managerベータ", + "xpack.ingestManager.homeIntegration.tutorialDirectory.noticeTitle.newPrefix": "新規:", + "xpack.ingestManager.homeIntegration.tutorialModule.noticeText": "{notePrefix} このモジュールの新しいバージョンは、Ingest Managerベータの{availableAsIntegrationLink}です。エージェント構成と新しいElasticエージェントの詳細については、{blogPostLink}をお読みください。", + "xpack.ingestManager.homeIntegration.tutorialModule.noticeText.blogPostLink": "発表ブログ投稿", + "xpack.ingestManager.homeIntegration.tutorialModule.noticeText.integrationLink": "統合として利用可能", + "xpack.ingestManager.homeIntegration.tutorialModule.noticeText.notePrefix": "注:", "xpack.ingestManager.initializationErrorMessageTitle": "Ingest Manager を初期化できません", "xpack.ingestManager.integrations.installPackage.installingPackageButtonLabel": "{title}アセットをインストールしています", "xpack.ingestManager.integrations.installPackage.installPackageButtonLabel": "{title}アセットをインストール", @@ -8244,7 +9600,7 @@ "xpack.ingestManager.integrations.settings.packageInstallTitle": "{title}をインストール", "xpack.ingestManager.integrations.settings.packageSettingsTitle": "設定", "xpack.ingestManager.integrations.settings.packageUninstallDescription": "この統合によってインストールされたKibanaおよびElasticsearchアセットを削除します。", - "xpack.ingestManager.integrations.settings.packageUninstallNoteDescription.packageUninstallNoteDetail": "{strongNote} {title}をアンインストールできません。この統合を使用しているアクティブなエージェントがあります。アンインストールするには、エージェント構成からすべての{title}データソースを削除します。", + "xpack.ingestManager.integrations.settings.packageUninstallNoteDescription.packageUninstallNoteDetail": "{strongNote} {title}をアンインストールできません。この統合を使用しているアクティブなエージェントがあります。アンインストールするには、エージェント構成からすべての{title}統合を削除します。", "xpack.ingestManager.integrations.settings.packageUninstallNoteDescription.packageUninstallNoteLabel": "注:", "xpack.ingestManager.integrations.settings.packageUninstallNoteDescription.packageUninstallUninstallableNoteDetail": "{strongNote} {title}統合は既定でインストールされているため、削除できません。", "xpack.ingestManager.integrations.settings.packageUninstallTitle": "{title}をアンインストール", @@ -8275,48 +9631,81 @@ "xpack.ingestManager.overviewAgentErrorTitle": "エラー", "xpack.ingestManager.overviewAgentOfflineTitle": "オフライン", "xpack.ingestManager.overviewAgentTotalTitle": "合計エージェント数", - "xpack.ingestManager.overviewConfigTotalTitle": "合計構成数", + "xpack.ingestManager.overviewConfigTotalTitle": "合計利用可能数", "xpack.ingestManager.overviewDatastreamNamespacesTitle": "名前空間", "xpack.ingestManager.overviewDatastreamSizeTitle": "合計サイズ", - "xpack.ingestManager.overviewDatastreamTotalTitle": "データストリーム", + "xpack.ingestManager.overviewDatastreamTotalTitle": "データセット", "xpack.ingestManager.overviewIntegrationsInstalledTitle": "インストール済み", "xpack.ingestManager.overviewIntegrationsTotalTitle": "合計利用可能数", "xpack.ingestManager.overviewIntegrationsUpdatesAvailableTitle": "更新が可能です", + "xpack.ingestManager.overviewPackageConfigTitle": "構成された統合", "xpack.ingestManager.overviewPageConfigurationsPanelAction": "構成を表示", - "xpack.ingestManager.overviewPageConfigurationsPanelTitle": "構成", - "xpack.ingestManager.overviewPageDataStreamsPanelAction": "データストリームを表示", - "xpack.ingestManager.overviewPageDataStreamsPanelTitle": "データストリーム", - "xpack.ingestManager.overviewPageEnrollAgentButton": "新しいエージェントを登録", + "xpack.ingestManager.overviewPageConfigurationsPanelTitle": "エージェント構成", + "xpack.ingestManager.overviewPageConfigurationsPanelTooltip": "エージェント構成を使用すると、エージェントが収集するデータを管理できます。", + "xpack.ingestManager.overviewPageDataStreamsPanelAction": "データセットを表示", + "xpack.ingestManager.overviewPageDataStreamsPanelTitle": "データセット", + "xpack.ingestManager.overviewPageDataStreamsPanelTooltip": "エージェントが収集するデータはさまざまなデータセットに整理されます。", + "xpack.ingestManager.overviewPageEnrollAgentButton": "エージェントの追加", "xpack.ingestManager.overviewPageFleetPanelAction": "エージェントを表示", "xpack.ingestManager.overviewPageFleetPanelTitle": "フリート", + "xpack.ingestManager.overviewPageFleetPanelTooltip": "Fleetを使用して、中央の場所からエージェントを登録し、構成を管理します。", "xpack.ingestManager.overviewPageIntegrationsPanelAction": "統合を表示", "xpack.ingestManager.overviewPageIntegrationsPanelTitle": "統合", - "xpack.ingestManager.overviewPageSubtitle": "Elasticエージェントおよび構成の集中管理。", + "xpack.ingestManager.overviewPageIntegrationsPanelTooltip": "Elastic Stackの統合を参照し、インストールします。統合をエージェント構成に追加し、データの送信を開始します。", + "xpack.ingestManager.overviewPageSubtitle": "Elasticエージェントおよびエージェント構成の集中管理。", "xpack.ingestManager.overviewPageTitle": "Ingest Manager", + "xpack.ingestManager.packageConfigValidation.invalidArrayErrorMessage": "無効なフォーマット", + "xpack.ingestManager.packageConfigValidation.invalidYamlFormatErrorMessage": "YAML形式が無効です", + "xpack.ingestManager.packageConfigValidation.nameRequiredErrorMessage": "名前が必要です", + "xpack.ingestManager.packageConfigValidation.namespaceRequiredErrorMessage": "ネームスペースが必要です", + "xpack.ingestManager.packageConfigValidation.requiredErrorMessage": "{fieldName}が必要です", "xpack.ingestManager.permissionDeniedErrorMessage": "Ingest Managerにアクセスする権限がありません。Ingest Managerには{roleName}権限が必要です。", "xpack.ingestManager.permissionDeniedErrorTitle": "パーミッションが拒否されました", "xpack.ingestManager.permissionsRequestErrorMessageDescription": "Ingest Managerアクセス権の確認中に問題が発生しました", "xpack.ingestManager.permissionsRequestErrorMessageTitle": "アクセス権を確認できません", "xpack.ingestManager.securityRequiredErrorMessage": "Ingest Managerを使用するには、KibanaとElasticsearchでセキュリティを有効にする必要があります。", "xpack.ingestManager.securityRequiredErrorTitle": "セキュリティが有効ではありません", + "xpack.ingestManager.settings.autoUpgradeDisabledLabel": "エージェントバイナリバージョンを手動で管理します。ご利用にはゴールドサブスクリプションが必要です。", + "xpack.ingestManager.settings.autoUpgradeEnabledLabel": "エージェントバイナリを自動的に更新し、最新マイナーバージョンを使用します。", + "xpack.ingestManager.settings.autoUpgradeFieldLabel": "Elasticエージェントバイナリバージョン", "xpack.ingestManager.settings.cancelButtonLabel": "キャンセル", + "xpack.ingestManager.settings.elasticHostError": "無効なURL", "xpack.ingestManager.settings.elasticsearchUrlLabel": "Elasticsearch URL", "xpack.ingestManager.settings.flyoutTitle": "Ingest Manager設定", "xpack.ingestManager.settings.globalOutputDescription": "グローバル出力はすべてのエージェント構成に適用され、データの送信先を指定します。", "xpack.ingestManager.settings.globalOutputTitle": "グローバル出力", + "xpack.ingestManager.settings.integrationUpgradeDisabledFieldLabel": "統合バージョンを手動で管理します。", + "xpack.ingestManager.settings.integrationUpgradeEnabledFieldLabel": "自動的に統合を最新バージョンに更新し、最新のアセットを受信します。新しい機能を使用するには、エージェント構成を更新しなければならない場合があります。", + "xpack.ingestManager.settings.integrationUpgradeFieldLabel": "統合バージョン", + "xpack.ingestManager.settings.kibanaUrlError": "無効なURL", "xpack.ingestManager.settings.kibanaUrlLabel": "Kibana URL", "xpack.ingestManager.settings.saveButtonLabel": "設定を保存", "xpack.ingestManager.settings.success.message": "設定が保存されました", + "xpack.ingestManager.setupPage.apiKeyServiceLink": "APIキーサービス", + "xpack.ingestManager.setupPage.elasticsearchApiKeyFlagText": "{apiKeyLink}.{apiKeyFlag}を{true}に設定します。", + "xpack.ingestManager.setupPage.elasticsearchSecurityFlagText": "{esSecurityLink}.{securityFlag}を{true}に設定します。", + "xpack.ingestManager.setupPage.elasticsearchSecurityLink": "Elasticsearchセキュリティ", "xpack.ingestManager.setupPage.enableFleet": "ユーザーを作成してフリートを有効にます", "xpack.ingestManager.setupPage.enableText": "フリートを使用するには、Elasticユーザーを作成する必要があります。このユーザーは、APIキーを作成して、logs-*およびmetrics-*に書き込むことができます。", "xpack.ingestManager.setupPage.enableTitle": "フリートを有効にする", + "xpack.ingestManager.setupPage.encryptionKeyFlagText": "{encryptionKeyLink}.{keyFlag}を32文字以上の英数字に設定します。", + "xpack.ingestManager.setupPage.gettingStartedLink": "はじめに", + "xpack.ingestManager.setupPage.gettingStartedText": "詳細については、{link}ガイドをお読みください。", + "xpack.ingestManager.setupPage.kibanaEncryptionLink": "Kibana暗号化鍵", + "xpack.ingestManager.setupPage.kibanaSecurityLink": "Kibanaセキュリティ", + "xpack.ingestManager.setupPage.missingRequirementsCalloutDescription": "Fleetを使用するには、次のElasticsearchとKibanaセキュリティ機能を有効にする必要があります。", + "xpack.ingestManager.setupPage.missingRequirementsCalloutTitle": "不足しているセキュリティ要件", + "xpack.ingestManager.setupPage.missingRequirementsElasticsearchTitle": "Elasticsearch構成で、次の項目を有効にします。", + "xpack.ingestManager.setupPage.missingRequirementsKibanaTitle": "Kibana構成で、次の項目を有効にします。", + "xpack.ingestManager.setupPage.tlsFlagText": "{kibanaSecurityLink}.{securityFlag}を{true}に設定します。開発目的では、危険な代替として{tlsFlag}を{true}に設定して、{tlsLink}を無効化できます。", + "xpack.ingestManager.setupPage.tlsLink": "TLS", "xpack.ingestManager.unenrollAgents.confirmModal.cancelButtonLabel": "キャンセル", "xpack.ingestManager.unenrollAgents.confirmModal.confirmButtonLabel": "登録解除", "xpack.ingestManager.unenrollAgents.confirmModal.deleteMultipleTitle": "{count, plural, one {# エージェント} other {# エージェント}}の登録を解除しますか?", "xpack.ingestManager.unenrollAgents.confirmModal.deleteSingleTitle": "エージェント「{id}」の登録を解除しますか?", "xpack.ingestManager.unenrollAgents.confirmModal.loadingButtonLabel": "読み込み中...", "xpack.ingestManager.unenrollAgents.fatalErrorNotificationTitle": "エージェントの登録解除エラー", - "xpack.ingestManager.unenrollAgents.successSingleNotificationTitle": "エージェント「{id}」の登録を解除しました", + "xpack.ingestManager.unenrollAgents.successSingleNotificationTitle": "エージェント「{id}」を登録解除しています", "xpack.ingestPipelines.app.checkingPrivilegesDescription": "権限を確認中…", "xpack.ingestPipelines.app.checkingPrivilegesErrorMessage": "サーバーからユーザー特権を取得中にエラーが発生。", "xpack.ingestPipelines.app.deniedPrivilegeDescription": "Ingest Pipelinesを使用するには、{privilegesCount, plural, one {このクラスター特権} other {これらのクラスター特権}}が必要です:{missingPrivileges}。", @@ -8354,9 +9743,13 @@ "xpack.ingestPipelines.form.onFailureFieldHelpText": "JSONフォーマットを使用:{code}", "xpack.ingestPipelines.form.pipelineNameRequiredError": "名前が必要です。", "xpack.ingestPipelines.form.saveButtonLabel": "パイプラインを保存", + "xpack.ingestPipelines.form.savePip10mbelineError.showFewerButton": "{hiddenErrorsCount, plural, one {件のエラー} other {件のエラー}}を非表示", "xpack.ingestPipelines.form.savePipelineError": "パイプラインを作成できません", + "xpack.ingestPipelines.form.savePipelineError.processorLabel": "{type}プロセッサー", + "xpack.ingestPipelines.form.savePipelineError.showAllButton": "{hiddenErrorsCount, plural, one {件のエラー} other {件のエラー}}を追加で表示", "xpack.ingestPipelines.form.savingButtonLabel": "保存中…", "xpack.ingestPipelines.form.showRequestButtonLabel": "リクエストを表示", + "xpack.ingestPipelines.form.unknownError": "不明なエラーが発生しました。", "xpack.ingestPipelines.form.versionFieldLabel": "バージョン(任意)", "xpack.ingestPipelines.form.versionToggleDescription": "バージョン番号を追加", "xpack.ingestPipelines.licenseCheckErrorMessage": "ライセンス確認失敗", @@ -8393,10 +9786,104 @@ "xpack.ingestPipelines.list.table.emptyPromptTitle": "パイプラインを作成して開始", "xpack.ingestPipelines.list.table.nameColumnTitle": "名前", "xpack.ingestPipelines.list.table.reloadButtonLabel": "再読み込み", + "xpack.ingestPipelines.pipelineEditor.addProcessorButtonLabel": "プロセッサーを追加", + "xpack.ingestPipelines.pipelineEditor.commonFields.ifFieldLabel": "条件(任意)", + "xpack.ingestPipelines.pipelineEditor.commonFields.ignoreFailureFieldLabel": "失敗を無視", + "xpack.ingestPipelines.pipelineEditor.commonFields.tagFieldLabel": "タグ(任意)", + "xpack.ingestPipelines.pipelineEditor.customForm.configurationRequiredError": "構成が必要です。", + "xpack.ingestPipelines.pipelineEditor.customForm.invalidJsonError": "入力が無効です。", + "xpack.ingestPipelines.pipelineEditor.customForm.optionsFieldAriaLabel": "構成JSONエディター", + "xpack.ingestPipelines.pipelineEditor.customForm.optionsFieldLabel": "構成", + "xpack.ingestPipelines.pipelineEditor.deleteModal.deleteDescription": "このプロセッサーとエラーハンドラーを削除します。", + "xpack.ingestPipelines.pipelineEditor.dropZoneButton.moveHereToolTip": "ここに移動", + "xpack.ingestPipelines.pipelineEditor.dropZoneButton.unavailableToolTip": "ここに移動できません", + "xpack.ingestPipelines.pipelineEditor.gsubForm.fieldFieldLabel": "フィールド", + "xpack.ingestPipelines.pipelineEditor.gsubForm.fieldRequiredError": "フィールド値が必要です。", + "xpack.ingestPipelines.pipelineEditor.gsubForm.ignoreMissingFieldLabel": "不足しテイル項目を無視", + "xpack.ingestPipelines.pipelineEditor.gsubForm.patternFieldLabel": "パターン", + "xpack.ingestPipelines.pipelineEditor.gsubForm.patternRequiredError": "パターン値が必要です。", + "xpack.ingestPipelines.pipelineEditor.gsubForm.replacementFieldLabel": "置換", + "xpack.ingestPipelines.pipelineEditor.gsubForm.replacementRequiredError": "置換値が必要です。", + "xpack.ingestPipelines.pipelineEditor.gsubForm.targetFieldLabel": "ターゲットフィールド(任意)", + "xpack.ingestPipelines.pipelineEditor.item.cancelMoveButtonAriaLabel": "移動のキャンセル", + "xpack.ingestPipelines.pipelineEditor.item.descriptionPlaceholder": "説明なし", + "xpack.ingestPipelines.pipelineEditor.item.editButtonAriaLabel": "このプロセッサーを編集", + "xpack.ingestPipelines.pipelineEditor.item.moreButtonAriaLabel": "このプロセッサーのその他のアクションを表示", + "xpack.ingestPipelines.pipelineEditor.item.moreMenu.addOnFailureHandlerButtonLabel": "エラーハンドラーを追加", + "xpack.ingestPipelines.pipelineEditor.item.moreMenu.deleteButtonLabel": "削除", + "xpack.ingestPipelines.pipelineEditor.item.moreMenu.duplicateButtonLabel": "このプロセッサーを複製", + "xpack.ingestPipelines.pipelineEditor.item.moveButtonLabel": "このプロセッサーを移動", + "xpack.ingestPipelines.pipelineEditor.item.textInputAriaLabel": "この{type}プロセッサーの説明を入力", + "xpack.ingestPipelines.pipelineEditor.loadFromJson.buttonLabel": "JSONの読み込み", + "xpack.ingestPipelines.pipelineEditor.loadFromJson.buttons.cancel": "キャンセル", + "xpack.ingestPipelines.pipelineEditor.loadFromJson.buttons.confirm": "読み込みと上書き", + "xpack.ingestPipelines.pipelineEditor.loadFromJson.editor": "パイプラインオブジェクト", + "xpack.ingestPipelines.pipelineEditor.loadFromJson.error.body": "JSONが有効なパイプラインオブジェクトであることを確認してください。", + "xpack.ingestPipelines.pipelineEditor.loadFromJson.error.title": "無効なパイプライン", + "xpack.ingestPipelines.pipelineEditor.loadFromJson.modalTitle": "JSONの読み込み", + "xpack.ingestPipelines.pipelineEditor.loadJsonModal.jsonEditorHelpText": "パイプラインオブジェクトを指定してください。これにより、既存のパイプラインプロセッサーとエラープロセッサーが無効化されます。", + "xpack.ingestPipelines.pipelineEditor.onFailureProcessorsDocumentationLink": "詳細情報", + "xpack.ingestPipelines.pipelineEditor.onFailureProcessorsLabel": "エラーハンドラー", + "xpack.ingestPipelines.pipelineEditor.onFailureTreeDescription": "このパイプラインの例外を処理するために使用されるプロセッサー。{learnMoreLink}", + "xpack.ingestPipelines.pipelineEditor.onFailureTreeTitle": "障害プロセッサー", + "xpack.ingestPipelines.pipelineEditor.processorsDocumentationLink": "詳細情報", + "xpack.ingestPipelines.pipelineEditor.processorsTreeDescription": "インデックスの前にドキュメントを前処理するために使用されるプロセッサー。{learnMoreLink}", + "xpack.ingestPipelines.pipelineEditor.processorsTreeTitle": "プロセッサー", + "xpack.ingestPipelines.pipelineEditor.removeProcessorModal.cancelButtonLabel": "キャンセル", + "xpack.ingestPipelines.pipelineEditor.removeProcessorModal.confirmationButtonLabel": "プロセッサーの削除", + "xpack.ingestPipelines.pipelineEditor.removeProcessorModal.titleText": "{type}プロセッサーの削除", + "xpack.ingestPipelines.pipelineEditor.setForm.fieldFieldLabel": "フィールド", + "xpack.ingestPipelines.pipelineEditor.setForm.fieldRequiredError": "フィールド値が必要です。", + "xpack.ingestPipelines.pipelineEditor.setForm.overrideFieldLabel": "無効化", + "xpack.ingestPipelines.pipelineEditor.setForm.valueFieldLabel": "値", + "xpack.ingestPipelines.pipelineEditor.setForm.valueRequiredError": "設定する値が必要です。", + "xpack.ingestPipelines.pipelineEditor.settingsForm.learnMoreLabelLink.processor": "{processorLabel}ドキュメント", + "xpack.ingestPipelines.pipelineEditor.testPipelineButtonLabel": "パイプラインをテスト", + "xpack.ingestPipelines.pipelineEditor.typeField.fieldRequiredError": "タイプが必要です。", + "xpack.ingestPipelines.pipelineEditor.typeField.typeFieldLabel": "プロセッサー", + "xpack.ingestPipelines.processors.label.append": "末尾に追加", + "xpack.ingestPipelines.processors.label.bytes": "バイト", + "xpack.ingestPipelines.processors.label.circle": "円", + "xpack.ingestPipelines.processors.label.convert": "変換", + "xpack.ingestPipelines.processors.label.csv": "CSV", + "xpack.ingestPipelines.processors.label.date": "日付", + "xpack.ingestPipelines.processors.label.dateIndexName": "日付インデックス名", + "xpack.ingestPipelines.processors.label.dissect": "Dissect", + "xpack.ingestPipelines.processors.label.dotExpander": "Dot Expander", + "xpack.ingestPipelines.processors.label.drop": "ドロップ", + "xpack.ingestPipelines.processors.label.enrich": "エンリッチ", + "xpack.ingestPipelines.processors.label.fail": "失敗", + "xpack.ingestPipelines.processors.label.foreach": "Foreach", + "xpack.ingestPipelines.processors.label.geoip": "GeoIP", + "xpack.ingestPipelines.processors.label.grok": "Grok", + "xpack.ingestPipelines.processors.label.gsub": "Gsub", + "xpack.ingestPipelines.processors.label.htmlStrip": "HTML Strip", + "xpack.ingestPipelines.processors.label.inference": "推定", + "xpack.ingestPipelines.processors.label.join": "結合", + "xpack.ingestPipelines.processors.label.json": "JSON", + "xpack.ingestPipelines.processors.label.kv": "KV", + "xpack.ingestPipelines.processors.label.lowercase": "小文字", + "xpack.ingestPipelines.processors.label.pipeline": "パイプライン", + "xpack.ingestPipelines.processors.label.remove": "削除", + "xpack.ingestPipelines.processors.label.rename": "名前の変更", + "xpack.ingestPipelines.processors.label.script": "スクリプト", + "xpack.ingestPipelines.processors.label.set": "設定", + "xpack.ingestPipelines.processors.label.setSecurityUser": "セキュリティユーザーの設定", + "xpack.ingestPipelines.processors.label.sort": "並べ替え", + "xpack.ingestPipelines.processors.label.split": "分割", + "xpack.ingestPipelines.processors.label.trim": "トリム", + "xpack.ingestPipelines.processors.label.uppercase": "大文字", + "xpack.ingestPipelines.processors.label.urldecode": "URLデコード", + "xpack.ingestPipelines.processors.label.userAgent": "ユーザーエージェント", "xpack.ingestPipelines.requestFlyout.closeButtonLabel": "閉じる", "xpack.ingestPipelines.requestFlyout.descriptionText": "このElasticsearchリクエストは、このパイプラインを作成または更新します。", "xpack.ingestPipelines.requestFlyout.namedTitle": "「{name}」のリクエスト", "xpack.ingestPipelines.requestFlyout.unnamedTitle": "リクエスト", + "xpack.ingestPipelines.settingsFormFlyout.title": "プロセッサーの構成", + "xpack.ingestPipelines.settingsFormOnFailureFlyout.addButtonLabel": "追加", + "xpack.ingestPipelines.settingsFormOnFailureFlyout.cancelButtonLabel": "キャンセル", + "xpack.ingestPipelines.settingsFormOnFailureFlyout.title": "エラープロセッサーの構成", + "xpack.ingestPipelines.settingsFormOnFailureFlyout.updateButtonLabel": "更新", "xpack.ingestPipelines.tabs.documentsTabTitle": "ドキュメント", "xpack.ingestPipelines.tabs.outputTabTitle": "アウトプット", "xpack.ingestPipelines.testPipelineFlyout.documentsForm.documentsFieldLabel": "ドキュメント", @@ -8423,11 +9910,17 @@ "xpack.lens.app.saveAndReturn": "保存して戻る", "xpack.lens.app.saveAs": "名前を付けて保存", "xpack.lens.app.saveModalType": "レンズビジュアライゼーション", + "xpack.lens.app.unsavedWorkMessage": "作業内容を保存せずに、Lensから移動しますか?", + "xpack.lens.app.unsavedWorkTitle": "保存されていない変更", "xpack.lens.app404": "404 Not Found", "xpack.lens.breadcrumbsCreate": "作成", "xpack.lens.breadcrumbsTitle": "可視化", "xpack.lens.chartSwitch.dataLossDescription": "このチャートに切り替えると構成の一部が失われます", "xpack.lens.chartSwitch.dataLossLabel": "データ喪失", + "xpack.lens.chartTitle.unsaved": "未保存", + "xpack.lens.configPanel.color.tooltip.auto": "カスタム色を指定しない場合、Lensは自動的に色を選択します。", + "xpack.lens.configPanel.color.tooltip.custom": "[自動]モードに戻すには、カスタム色をオフにしてください。", + "xpack.lens.configPanel.color.tooltip.disabled": "レイヤーに「内訳条件」が含まれている場合は、個別の系列をカスタム色にできません。", "xpack.lens.configPanel.selectVisualization": "ビジュアライゼーションを選択してください", "xpack.lens.configure.addConfig": "構成を追加", "xpack.lens.configure.editConfig": "構成の編集", @@ -8454,8 +9947,10 @@ "xpack.lens.editorFrame.emptyWorkspaceHeading": "レンズはビジュアライゼーションを作成するための新しいツールです", "xpack.lens.editorFrame.expandRenderingErrorButton": "エラーの詳細を表示", "xpack.lens.editorFrame.expressionFailure": "表現を正常に実行できませんでした", + "xpack.lens.editorFrame.formatStyleLabel": "書式とスタイル", "xpack.lens.editorFrame.goToForums": "リクエストとフィードバック", "xpack.lens.editorFrame.previewErrorLabel": "レンダリングのプレビューに失敗しました", + "xpack.lens.editorFrame.quickFunctionsLabel": "クイック機能", "xpack.lens.editorFrame.requiredDimensionWarningLabel": "必要な次元", "xpack.lens.editorFrame.suggestionPanelTitle": "提案", "xpack.lens.editorFrame.tooltipContent": "レンズはベータ段階で、変更される可能性があります。 デザインとコードはオフィシャル GA 機能よりも完成度が低く、現状のまま保証なしで提供されています。ベータ機能にはオフィシャル GA 機能の SLA が適用されません", @@ -8463,11 +9958,22 @@ "xpack.lens.embeddableDisplayName": "レンズ", "xpack.lens.excludeValueButtonAriaLabel": "{value}を除外", "xpack.lens.excludeValueButtonTooltip": "値を除外", + "xpack.lens.fittingFunctionsDescription.carry": "ギャップを最後の値で埋める", + "xpack.lens.fittingFunctionsDescription.linear": "ギャップを線で埋める", + "xpack.lens.fittingFunctionsDescription.lookahead": "ギャップを次の値で埋める", + "xpack.lens.fittingFunctionsDescription.none": "ギャップを埋めない", + "xpack.lens.fittingFunctionsDescription.zero": "ギャップをゼロで埋める", + "xpack.lens.fittingFunctionsTitle.carry": "最後", + "xpack.lens.fittingFunctionsTitle.linear": "線形", + "xpack.lens.fittingFunctionsTitle.lookahead": "次へ", + "xpack.lens.fittingFunctionsTitle.none": "非表示", + "xpack.lens.fittingFunctionsTitle.zero": "ゼロ", "xpack.lens.functions.mergeTables.help": "いくつかの Kibana 表を 1 つの表に結合するのをアシストします", "xpack.lens.functions.renameColumns.help": "データベースの列の名前の変更をアシストします", "xpack.lens.functions.renameColumns.idMap.help": "キーが古い列 ID で値が対応する新しい列 ID となるように JSON エンコーディングされたオブジェクトです。他の列 ID はすべてのそのままです。", "xpack.lens.includeValueButtonAriaLabel": "{value}を含める", "xpack.lens.includeValueButtonTooltip": "値を含める", + "xpack.lens.indexPattern.availableFieldsLabel": "利用可能なフィールド", "xpack.lens.indexPattern.avg": "平均", "xpack.lens.indexPattern.avgOf": "{name} の平均", "xpack.lens.indexPattern.bytesFormatLabel": "バイト (1024)", @@ -8492,6 +9998,7 @@ "xpack.lens.indexPattern.dateHistogram.year": "年", "xpack.lens.indexPattern.decimalPlacesLabel": "小数点以下", "xpack.lens.indexPattern.defaultFormatLabel": "デフォルト", + "xpack.lens.indexPattern.emptyFieldsLabel": "空のフィールド", "xpack.lens.indexpattern.emptyTextColumnValue": "(空)", "xpack.lens.indexPattern.fieldDistributionLabel": "分布", "xpack.lens.indexPattern.fieldItemTooltip": "可視化するには、ドラッグアンドドロップします。", @@ -8541,16 +10048,21 @@ "xpack.lens.indexPattern.termsOf": "{name} のトップの値", "xpack.lens.indexPattern.uniqueLabel": "{label} [{num}]", "xpack.lens.indexPatterns.clearFiltersLabel": "名前とタイプフィルターを消去", + "xpack.lens.indexPatterns.fieldFiltersLabel": "フィールドフィルター", "xpack.lens.indexPatterns.filterByNameAriaLabel": "検索フィールド", "xpack.lens.indexPatterns.filterByNameLabel": "フィールドを検索", + "xpack.lens.indexPatterns.noDataLabel": "データを含むフィールドはありません。", "xpack.lens.indexPatterns.noFields.extendTimeBullet": "時間範囲を拡張中", + "xpack.lens.indexPatterns.noFields.fieldTypeFilterBullet": "別のフィールドフィルターを使用", + "xpack.lens.indexPatterns.noFields.globalFiltersBullet": "グローバルフィルターを変更", "xpack.lens.indexPatterns.noFields.tryText": "試行対象:", "xpack.lens.indexPatterns.noFieldsLabel": "このインデックスパターンにはフィールドがありません。", - "xpack.lens.indexPatterns.noFilteredFieldsLabel": "現在のフィルターと一致するフィールドはありません。", + "xpack.lens.indexPatterns.noFilteredFieldsLabel": "選択したフィルターと一致するフィールドはありません。", "xpack.lens.indexPatternSuggestion.removeLayerLabel": "{indexPatternTitle}のみを表示", "xpack.lens.indexPatternSuggestion.removeLayerPositionLabel": "レイヤー{layerNumber}のみを表示", "xpack.lens.lensSavedObjectLabel": "レンズビジュアライゼーション", "xpack.lens.metric.label": "メトリック", + "xpack.lens.pageTitle": "レンズ", "xpack.lens.pie.donutLabel": "ドーナッツ", "xpack.lens.pie.expressionHelpLabel": "円表示", "xpack.lens.pie.groupsizeLabel": "サイズ単位", @@ -8589,14 +10101,24 @@ "xpack.lens.visTypeAlias.type": "レンズ", "xpack.lens.xyChart.addLayerButton": "レイヤーを追加", "xpack.lens.xyChart.addLayerTooltip": "複数のレイヤーを使用すると、グラフタイプを組み合わせたり、別のインデックスパターンを可視化したりすることができます。", + "xpack.lens.xyChart.axisSide.auto": "自動", + "xpack.lens.xyChart.axisSide.label": "軸側", + "xpack.lens.xyChart.axisSide.left": "左", + "xpack.lens.xyChart.axisSide.right": "右", "xpack.lens.xyChart.chartTypeLabel": "チャートタイプ", "xpack.lens.xyChart.chartTypeLegend": "チャートタイプ", + "xpack.lens.xyChart.fittingDisabledHelpText": "この設定は折れ線グラフとエリアグラフでのみ適用されます。", + "xpack.lens.xyChart.fittingFunction.help": "欠測値の処理方法を定義", + "xpack.lens.xyChart.fittingLabel": "欠測値を埋める", "xpack.lens.xyChart.help": "X/Y チャート", "xpack.lens.xyChart.isVisible.help": "判例の表示・非表示を指定します。", "xpack.lens.xyChart.legend.help": "チャートの凡例を構成します。", "xpack.lens.xyChart.nestUnderRoot": "データセット全体", "xpack.lens.xyChart.position.help": "凡例の配置を指定します。", "xpack.lens.xyChart.renderer.help": "X/Y チャートを再レンダリング", + "xpack.lens.xyChart.seriesColor.auto": "自動", + "xpack.lens.xyChart.seriesColor.label": "系列色", + "xpack.lens.xyChart.settingsLabel": "設定", "xpack.lens.xyChart.splitSeries": "系列を分割", "xpack.lens.xyChart.title.help": "軸のタイトル", "xpack.lens.xyChart.xAxisLabel": "X 軸", @@ -8638,23 +10160,31 @@ "xpack.licenseMgmt.licenseDashboard.licenseStatus.permanentActiveLicenseStatusDescription": "ご使用のライセンスには有効期限がありません。", "xpack.licenseMgmt.licenseDashboard.requestTrialExtension.extendTrialButtonLabel": "トライアルを延長", "xpack.licenseMgmt.licenseDashboard.requestTrialExtension.extendYourTrialTitle": "トライアルの延長", + "xpack.licenseMgmt.licenseDashboard.requestTrialExtension.howToContinueUsingPluginsDescription": "機械学習、高度なセキュリティ、その他の素晴らしい{subscriptionFeaturesLinkText}の使用を続けるには、今すぐ延長をお申し込みください。", + "xpack.licenseMgmt.licenseDashboard.requestTrialExtension.subscriptionFeaturesLinkText": "サブスクリプション機能", "xpack.licenseMgmt.licenseDashboard.revertToBasic.acknowledgeModal.revertToBasicButtonLabel": "ベーシックに戻す", "xpack.licenseMgmt.licenseDashboard.revertToBasic.acknowledgeModalTitle": "ベーシックライセンスに戻す", "xpack.licenseMgmt.licenseDashboard.revertToBasic.confirmModal.cancelButtonLabel": "キャンセル", "xpack.licenseMgmt.licenseDashboard.revertToBasic.confirmModal.confirmButtonLabel": "確認", "xpack.licenseMgmt.licenseDashboard.revertToBasic.confirmModalTitle": "ベーシックライセンスに戻す確認", + "xpack.licenseMgmt.licenseDashboard.revertToBasic.revertToFreeFeaturesDescription": "無料の機能に戻すと、セキュリティ、機械学習、その他{subscriptionFeaturesLinkText}が利用できなくなります。", + "xpack.licenseMgmt.licenseDashboard.revertToBasic.subscriptionFeaturesLinkText": "サブスクリプション機能", "xpack.licenseMgmt.licenseDashboard.startTrial.confirmModal.cancelButtonLabel": "キャンセル", "xpack.licenseMgmt.licenseDashboard.startTrial.confirmModal.startTrialButtonLabel": "トライアルを開始", + "xpack.licenseMgmt.licenseDashboard.startTrial.confirmModalDescription": "この試用版では、Elastic Stackの{subscriptionFeaturesLinkText}のすべての機能が提供されています。すぐに次の機能をご利用いただけます。", "xpack.licenseMgmt.licenseDashboard.startTrial.confirmModalDescription.alertingFeatureTitle": "アラート", "xpack.licenseMgmt.licenseDashboard.startTrial.confirmModalDescription.dataBaseConnectivityFeatureTitle": "{sqlDataBase} の {jdbcStandard} および {odbcStandard} 接続", "xpack.licenseMgmt.licenseDashboard.startTrial.confirmModalDescription.graphCapabilitiesFeatureTitle": "グラフ機能", "xpack.licenseMgmt.licenseDashboard.startTrial.confirmModalDescription.mashingLearningFeatureTitle": "機械学習", "xpack.licenseMgmt.licenseDashboard.startTrial.confirmModalDescription.securityDocumentationLinkText": "ドキュメンテーション", "xpack.licenseMgmt.licenseDashboard.startTrial.confirmModalDescription.securityFeaturesConfigurationDescription": "認証 ({authenticationTypeList})、フィールドとドキュメントレベルのセキュリティ、監査などの高度なセキュリティ機能には構成が必要です。手順は {securityDocumentationLinkText} をご覧ください。", + "xpack.licenseMgmt.licenseDashboard.startTrial.confirmModalDescription.subscriptionFeaturesLinkText": "サブスクリプション機能", "xpack.licenseMgmt.licenseDashboard.startTrial.confirmModalDescription.termsAndConditionsDescription": "このトライアルを開始することで、これらの {termsAndConditionsLinkText} が適用されることに同意したものとみなされます。", "xpack.licenseMgmt.licenseDashboard.startTrial.confirmModalDescription.termsAndConditionsLinkText": "諸条件", "xpack.licenseMgmt.licenseDashboard.startTrial.confirmModalTitle": "30 日間の無料トライアルの開始", "xpack.licenseMgmt.licenseDashboard.startTrial.startTrialButtonLabel": "トライアルを開始", + "xpack.licenseMgmt.licenseDashboard.startTrial.subscriptionFeaturesExperienceDescription": "機械学習、高度なセキュリティ、その他{subscriptionFeaturesLinkText}をお試しください。", + "xpack.licenseMgmt.licenseDashboard.startTrial.subscriptionFeaturesLinkText": "サブスクリプション機能", "xpack.licenseMgmt.licenseDashboard.startTrialTitle": "30 日間のトライアルの開始", "xpack.licenseMgmt.managementSectionDisplayName": "ライセンス管理", "xpack.licenseMgmt.replacingCurrentLicenseWithBasicLicenseWarningMessage": "{currentLicenseType} ライセンスからベーシックライセンスにすると、一部機能が使えなくなります。下の機能のリストをご確認ください。", @@ -8714,7 +10244,7 @@ "xpack.logstash.managementSection.licenseDoesNotSupportDescription": "ご使用の {licenseType} ライセンスは Logstash パイプライン管理をサポートしていません。ライセンスをアップグレードしてください。", "xpack.logstash.managementSection.notPossibleToManagePipelinesMessage": "現在ライセンス情報が利用できないため Logstash パイプラインを使用できません。", "xpack.logstash.managementSection.pipelineCrudOperationsNotAllowedDescription": "ご使用の {licenseType} ライセンスは期限切れのため、Logstash パイプラインの編集、作成、削除ができません。", - "xpack.logstash.managementSection.pipelinesTitle": "パイプライン", + "xpack.logstash.managementSection.pipelinesTitle": "Logstashパイプライン", "xpack.logstash.manualUpgradeButtonLabel": "再試行", "xpack.logstash.newPipelineMessage": "パイプラインを追加する前に、構成をアップグレードする必要があります。", "xpack.logstash.notManualUpgradeButtonLabel": "アップグレード", @@ -8782,6 +10312,7 @@ "xpack.logstash.upgradeFailureActions.goBackButtonLabel": "戻る", "xpack.logstash.upstreamPipelineArgumentMustContainAnIdPropertyErrorMessage": "upstreamPipeline 引数には id プロパティを含める必要があります", "xpack.logstash.workersTooltip": "パイプラインのフィルターとアウトプットステージを同時に実行するワーカーの数です。イベントが詰まってしまう場合や CPU が飽和状態ではない場合は、マシンの処理能力をより有効に活用するため、この数字を上げてみてください。\n\nデフォルト値:ホストの CPU コア数です", + "xpack.main.uiSettings.adminEmailDeprecation": "この設定はサポートが終了し、Kibana 8.0ではサポートされません。kibana.yml設定で、「monitoring.cluster_alerts.email_notifications.email_address」を構成してください。", "xpack.main.uiSettings.adminEmailDescription": "監視からのクラスターアラートメール通知など、X-Pack管理オペレーションの送信先のメールアドレスです。", "xpack.main.uiSettings.adminEmailTitle": "管理者メール", "xpack.maps.addLayerPanel.addLayer": "レイヤーを追加", @@ -8790,6 +10321,18 @@ "xpack.maps.aggs.defaultCountLabel": "カウント", "xpack.maps.appTitle": "マップ", "xpack.maps.blendedVectorLayer.clusteredLayerName": "クラスター化 {displayName}", + "xpack.maps.breadCrumbs.unsavedChangesWarning": "保存されていない変更は保存されない可能性があります", + "xpack.maps.choropleth.boundaries.elasticsearch": "Elasticsearchの点、線、多角形", + "xpack.maps.choropleth.boundaries.ems": "Elastic Maps Serviceの行政区画のベクターシェイプ", + "xpack.maps.choropleth.boundariesLabel": "境界ソース", + "xpack.maps.choropleth.desc": "境界全体で統計を比較する影付き領域", + "xpack.maps.choropleth.geofieldLabel": "地理空間フィールド", + "xpack.maps.choropleth.geofieldPlaceholder": "ジオフィールドを選択", + "xpack.maps.choropleth.joinFieldLabel": "フィールドを結合", + "xpack.maps.choropleth.joinFieldPlaceholder": "フィールドを選択", + "xpack.maps.choropleth.rightSourceLabel": "インデックスパターン", + "xpack.maps.choropleth.statisticsLabel": "統計ソース", + "xpack.maps.choropleth.title": "階級区分図", "xpack.maps.common.esSpatialRelation.containsLabel": "contains", "xpack.maps.common.esSpatialRelation.disjointLabel": "disjoint", "xpack.maps.common.esSpatialRelation.intersectsLabel": "intersects", @@ -8799,6 +10342,7 @@ "xpack.maps.drawTooltip.distanceInstructions": "クリックして点を設定します。マウスを移動して距離を調整します。クリックして終了します。", "xpack.maps.drawTooltip.polygonInstructions": "クリックしてシェイプを開始します。クリックして頂点を追加します。ダブルクリックして終了します。", "xpack.maps.embeddableDisplayName": "マップ", + "xpack.maps.emsFileSelect.selectPlaceholder": "EMSレイヤーを選択", "xpack.maps.emsSource.tooltipsTitle": "ツールチップフィールド", "xpack.maps.es_geo_utils.convert.unsupportedGeometryTypeErrorMessage": "{geometryType} ジオメトリから Geojson に変換できません。サポートされていません", "xpack.maps.es_geo_utils.distanceFilterAlias": "{pointLabel} の {distanceKm}km 以内にある {geoFieldName}", @@ -8816,15 +10360,23 @@ "xpack.maps.esSearch.topHitsSizeMsg": "エンティティごとに上位の{topHitsSize}ドキュメントを表示しています。", "xpack.maps.feature.appDescription": "Elasticsearch と Elastic Maps Service の地理空間データを閲覧します", "xpack.maps.featureRegistry.mapsFeatureName": "マップ", + "xpack.maps.fileUploadWizard.description": "ElasticsearchでGeoJSONデータにインデックスします", + "xpack.maps.fileUploadWizard.importFileSetupLabel": "ファイルのインポート", + "xpack.maps.fileUploadWizard.indexingLabel": "ファイルをインポートしています", + "xpack.maps.fileUploadWizard.title": "GeoJSONをアップロード", "xpack.maps.filterEditor.applyGlobalQueryCheckboxLabel": "レイヤーデータにグローバルフィルターを適用", "xpack.maps.fitToData.fitAriaLabel": "データバウンドに合わせる", "xpack.maps.fitToData.fitButtonLabel": "データバウンドに合わせる", "xpack.maps.geoGrid.resolutionLabel": "グリッド解像度", "xpack.maps.geometryFilterForm.geometryLabelLabel": "ジオメトリラベル", "xpack.maps.geometryFilterForm.relationLabel": "空間関係", + "xpack.maps.geoTileAgg.disabled.docValues": "クラスタリングには集約が必要です。doc_valuesをtrueに設定して、集約を有効にします。", + "xpack.maps.geoTileAgg.disabled.license": "Geo_shapeクラスタリングには、ゴールドライセンスが必要です。", "xpack.maps.heatmap.colorRampLabel": "色の範囲", "xpack.maps.heatmapLegend.coldLabel": "コールド", "xpack.maps.heatmapLegend.hotLabel": "ホット", + "xpack.maps.indexPatternSelectLabel": "インデックスパターン", + "xpack.maps.indexPatternSelectPlaceholder": "インデックスパターンを選択", "xpack.maps.indexSettings.fetchErrorMsg": "インデックスパターン'{indexPatternTitle}'のインデックス設定を取得できません。\n '{viewIndexMetaRole}'ロールがあることを確認してください。", "xpack.maps.initialLayers.unableToParseMessage": "「initialLayers」パラメーターのコンテンツをパースできませんエラー: {errorMsg}", "xpack.maps.initialLayers.unableToParseTitle": "初期レイヤーはマップに追加されません", @@ -8884,6 +10436,7 @@ "xpack.maps.layerPanel.metricsExpression.joinMustBeSetErrorMessage": "JOIN の設定が必要です", "xpack.maps.layerPanel.metricsExpression.metricsPopoverTitle": "メトリック", "xpack.maps.layerPanel.metricsExpression.useMetricsDescription": "{metricsLength, plural, one {してメトリックを使用します} other {してメトリックを使用します}}", + "xpack.maps.layerPanel.settingsPanel.labelsOnTop": "上部にラベルを表示", "xpack.maps.layerPanel.settingsPanel.layerNameLabel": "名前", "xpack.maps.layerPanel.settingsPanel.layerTransparencyLabel": "レイヤーの透明度", "xpack.maps.layerPanel.settingsPanel.percentageLabel": "%", @@ -8904,6 +10457,11 @@ "xpack.maps.layerTocActions.noFitSupportTooltip": "レイヤーが「データに合わせる」をサポートしていません", "xpack.maps.layerTocActions.removeLayerTitle": "レイヤーを削除", "xpack.maps.layerTocActions.showLayerTitle": "レイヤーの表示", + "xpack.maps.layerWizardSelect.allCategories": "すべて", + "xpack.maps.layerWizardSelect.elasticsearchCategoryLabel": "Elasticsearch", + "xpack.maps.layerWizardSelect.referenceCategoryLabel": "リファレンス", + "xpack.maps.layerWizardSelect.solutionsCategoryLabel": "ソリューション", + "xpack.maps.loadMap.errorAttemptingToLoadSavedMap": "マップを読み込めません", "xpack.maps.map.initializeErrorTitle": "マップを初期化できません", "xpack.maps.mapController.fullScreenButtonLabel": "全画面", "xpack.maps.mapController.fullScreenDescription": "全画面", @@ -8927,6 +10485,7 @@ "xpack.maps.mapListing.deleteTitle": "削除", "xpack.maps.mapListing.deleteWarning": "削除されたアイテムは復元できません。", "xpack.maps.mapListing.descriptionFieldTitle": "説明", + "xpack.maps.mapListing.errorAttemptingToLoadSavedMaps": "マップを読み込めません", "xpack.maps.mapListing.limitExceededTitle": "リスティング制限超過", "xpack.maps.mapListing.limitHelpDescription": "{totalItems} 個のアイテムがありますが、listingLimit の設定により {listingLimit} 個までしか下の表に表示できません。この設定は次の場所で変更できます ", "xpack.maps.mapListing.listingTableTitle": "マップ", @@ -8936,6 +10495,7 @@ "xpack.maps.mapListing.searchPlaceholder": "検索…", "xpack.maps.mapListing.titleFieldTitle": "タイトル", "xpack.maps.mapListing.unableToDeleteToastTitle": "マップを削除できません", + "xpack.maps.maps.choropleth.rightSourcePlaceholder": "インデックスパターンを選択", "xpack.maps.mapSavedObjectLabel": "マップ", "xpack.maps.mapSettingsPanel.browserLocationLabel": "ブラウザーの位置情報", "xpack.maps.mapSettingsPanel.cancelLabel": "キャンセル", @@ -8970,6 +10530,14 @@ "xpack.maps.metricSelect.sumDropDownOptionLabel": "合計", "xpack.maps.metricSelect.termsDropDownOptionLabel": "トップ用語", "xpack.maps.multiIndexFieldSelect.fieldLabel": "フィールドのフィルタリング", + "xpack.maps.mvtSource.addFieldLabel": "追加", + "xpack.maps.mvtSource.fieldPlaceholderText": "フィールド名", + "xpack.maps.mvtSource.numberFieldLabel": "数字", + "xpack.maps.mvtSource.sourceSettings": "ソース設定", + "xpack.maps.mvtSource.stringFieldLabel": "文字列", + "xpack.maps.mvtSource.tooltipsTitle": "ツールチップフィールド", + "xpack.maps.mvtSource.trashButtonAriaLabel": "フィールドの削除", + "xpack.maps.mvtSource.trashButtonTitle": "フィールドの削除", "xpack.maps.noIndexPattern.doThisLinkTextDescription": "インデックスパターンを作成します", "xpack.maps.noIndexPattern.doThisPrefixDescription": "次のことが必要です ", "xpack.maps.noIndexPattern.doThisSuffixDescription": " 地理空間フィールドを含む", @@ -8999,6 +10567,12 @@ "xpack.maps.sampleData.flightaSpec.logsTitle": "[ログ ] 合計リクエスト数とバイト数", "xpack.maps.sampleData.flightaSpec.mapsTitle": "[フライト] 出発地と目的地の飛行時間", "xpack.maps.sampleDataLinkLabel": "マップ", + "xpack.maps.security.desc": "セキュリティレイヤー", + "xpack.maps.security.indexPatternLabel": "インデックスパターン", + "xpack.maps.security.title": "セキュリティ", + "xpack.maps.sescurity.destinationLayerLabel": "{indexPatternTitle} | ディスティネーションポイント", + "xpack.maps.sescurity.lineLayerLabel": "{indexPatternTitle} | Line", + "xpack.maps.sescurity.sourceLayerLabel": "{indexPatternTitle} | ソースポイント", "xpack.maps.setViewControl.goToButtonLabel": "移動:", "xpack.maps.setViewControl.latitudeLabel": "緯度", "xpack.maps.setViewControl.longitudeLabel": "経度", @@ -9012,6 +10586,7 @@ "xpack.maps.source.emsFile.layerLabel": "レイヤー", "xpack.maps.source.emsFile.unableToFindIdErrorMessage": "ID {id} の EMS ベクターシェイプが見つかりません", "xpack.maps.source.emsFileDescription": "Elastic Maps Service の行政区画のベクターシェイプ", + "xpack.maps.source.emsFileSelect.selectLabel": "レイヤー", "xpack.maps.source.emsFileTitle": "ベクターシェイプ", "xpack.maps.source.emsTile.autoLabel": "Kibana テーマに基づき自動選択", "xpack.maps.source.emsTile.errorMessage": "ID {id} の EMS タイル構成が見つかりません", @@ -9055,6 +10630,7 @@ "xpack.maps.source.esSearch.geoFieldLabel": "地理空間フィールド", "xpack.maps.source.esSearch.geoFieldTypeLabel": "地理空間フィールドタイプ", "xpack.maps.source.esSearch.indexPatternLabel": "インデックスパターン", + "xpack.maps.source.esSearch.joinsDisabledReason": "クラスターでスケーリングするときに、結合はサポートされていません", "xpack.maps.source.esSearch.limitScalingLabel": "結果を {maxResultWindow} に限定。", "xpack.maps.source.esSearch.loadErrorMessage": "インデックスパターン {id} が見つかりません", "xpack.maps.source.esSearch.loadTooltipPropertiesErrorMsg": "ドキュメントが見つかりません。_id: {docId}", @@ -9066,7 +10642,7 @@ "xpack.maps.source.esSearch.topHitsSplitFieldLabel": "エンティティ", "xpack.maps.source.esSearch.topHitsSplitFieldSelectPlaceholder": "エンティティフィールドを選択", "xpack.maps.source.esSearch.useTopHitsLabel": "エンティティごとにトップヒットを表示。", - "xpack.maps.source.esSearchDescription": "Kibana インデックスパターンの地理空間データ", + "xpack.maps.source.esSearchDescription": "Elasticsearchの点、線、多角形", "xpack.maps.source.esSearchTitle": "ドキュメント", "xpack.maps.source.esSource.noGeoFieldErrorMessage": "インデックスパターン {indexPatternTitle} には現在ジオフィールド {geoField} が含まれていません", "xpack.maps.source.esSource.noIndexPatternErrorMessage": "ID {indexPatternId} のインデックスパターンが見つかりません", @@ -9085,11 +10661,17 @@ "xpack.maps.source.kbnTMSDescription": "kibana.yml で構成されたマップタイルです", "xpack.maps.source.kbnTMSTitle": "カスタムタイルマップサービス", "xpack.maps.source.mapSettingsPanel.initialLocationLabel": "マップの初期位置情報", - "xpack.maps.source.MVTSingleLayerVectorSource.sourceTitle": "ベトルタイルレイヤー", - "xpack.maps.source.MVTSingleLayerVectorSourceEditor.dataZoomRangeMessage": "ズームレベル", - "xpack.maps.source.MVTSingleLayerVectorSourceEditor.layerNameMessage": "レイヤー名", + "xpack.maps.source.MVTSingleLayerVectorSource.sourceTitle": ".pbfベクトルタイル", + "xpack.maps.source.MVTSingleLayerVectorSourceEditor.dataZoomRangeMessage": "ズーム:", + "xpack.maps.source.MVTSingleLayerVectorSourceEditor.fieldsMessage": "フィールド", + "xpack.maps.source.MVTSingleLayerVectorSourceEditor.fieldsPostHelpMessage": "これらはツールチップと動的スタイルで使用できます。", + "xpack.maps.source.MVTSingleLayerVectorSourceEditor.fieldsPreHelpMessage": "使用可能なフィールド ", + "xpack.maps.source.MVTSingleLayerVectorSourceEditor.layerNameMessage": "タイルレイヤー", + "xpack.maps.source.MVTSingleLayerVectorSourceEditor.urlHelpMessage": ".mvtベクトルタイルサービスのURL。例:{url}", "xpack.maps.source.MVTSingleLayerVectorSourceEditor.urlMessage": "Url", - "xpack.maps.source.mvtVectorSourceWizard": "ベクトルソースウィザード", + "xpack.maps.source.MVTSingleLayerVectorSourceEditor.zoomRangeHelpMessage": "レイヤーがタイルに存在するズームレベル。これは直接可視性に対応しません。レベルが低いレイヤーデータは常に高いズームレベルで表示できます(ただし逆はありません)。", + "xpack.maps.source.MVTSingleLayerVectorSourceEditor.zoomRangeTopMessage": "使用可能なレベル", + "xpack.maps.source.mvtVectorSourceWizard": "Mapboxベクトルタイル仕様を実装するデータサービス", "xpack.maps.source.pewPew.destGeoFieldLabel": "送信先", "xpack.maps.source.pewPew.destGeoFieldPlaceholder": "デスティネーション地理情報フィールドを選択", "xpack.maps.source.pewPew.indexPatternLabel": "インデックスパターン", @@ -9226,12 +10808,21 @@ "xpack.ml.accessDenied.description": "ML プラグインへのアクセスパーミッションがありません", "xpack.ml.accessDenied.label": "パーミッションがありません", "xpack.ml.accessDeniedLabel": "アクセスが拒否されました", - "xpack.ml.actions.editSwimlaneTitle": "スイムレーンを編集", + "xpack.ml.actions.applyInfluencersFiltersTitle": "値のフィラー", + "xpack.ml.actions.applyTimeRangeSelectionTitle": "時間範囲選択を適用", + "xpack.ml.actions.editSwimlaneTitle": "スイムレーンの編集", + "xpack.ml.actions.influencerFilterAliasLabel": "インフルエンサー{labelValue}", + "xpack.ml.actions.openInAnomalyExplorerTitle": "異常エクスプローラーで開く", + "xpack.ml.annotationFlyout.applyToPartitionTextLabel": "注釈をこの系列に適用", "xpack.ml.annotationsTable.actionsColumnName": "アクション", "xpack.ml.annotationsTable.annotationColumnName": "注釈", "xpack.ml.annotationsTable.annotationsNotCreatedTitle": "このジョブには注釈が作成されていません", + "xpack.ml.annotationsTable.byAEColumnName": "グループ基準", + "xpack.ml.annotationsTable.byColumnSMVName": "グループ基準", + "xpack.ml.annotationsTable.detectorColumnName": "検知器", "xpack.ml.annotationsTable.editAnnotationsTooltip": "注釈を編集します", "xpack.ml.annotationsTable.editAnnotationsTooltipAriaLabel": "注釈を編集します", + "xpack.ml.annotationsTable.eventColumnName": "イベント", "xpack.ml.annotationsTable.fromColumnName": "開始値:", "xpack.ml.annotationsTable.howToCreateAnnotationDescription": "注釈を作成するには、{linkToSingleMetricView} を開きます", "xpack.ml.annotationsTable.howToCreateAnnotationDescription.singleMetricViewerLinkText": "シングルメトリックビューアー", @@ -9243,6 +10834,11 @@ "xpack.ml.annotationsTable.lastModifiedDateColumnName": "最終更新日", "xpack.ml.annotationsTable.openInSingleMetricViewerAriaLabel": "シングルメトリックビューアーで開く", "xpack.ml.annotationsTable.openInSingleMetricViewerTooltip": "シングルメトリックビューアーで開く", + "xpack.ml.annotationsTable.overAEColumnName": "の", + "xpack.ml.annotationsTable.overColumnSMVName": "の", + "xpack.ml.annotationsTable.partitionAEColumnName": "パーティション", + "xpack.ml.annotationsTable.partitionSMVColumnName": "パーティション", + "xpack.ml.annotationsTable.seriesOnlyFilterName": "系列にフィルタリング", "xpack.ml.annotationsTable.toColumnName": "To", "xpack.ml.anomaliesTable.actionsColumnName": "アクション", "xpack.ml.anomaliesTable.actualSortColumnName": "実際", @@ -9314,6 +10910,10 @@ "xpack.ml.anomalyDetection.singleMetricViewerLabel": "シングルメトリックビューアー", "xpack.ml.anomalyDetectionBreadcrumbLabel": "異常検知", "xpack.ml.anomalyExplorerPageLabel": "異常エクスプローラー", + "xpack.ml.anomalyResultsViewSelector.anomalyExplorerLabel": "異常エクスプローラーで結果を表示", + "xpack.ml.anomalyResultsViewSelector.buttonGroupLegend": "異常結果ビューセレクター", + "xpack.ml.anomalyResultsViewSelector.singleMetricViewerLabel": "シングルメトリックビューアーで結果を表示", + "xpack.ml.anomalySwimLane.noOverallDataMessage": "全体データがありません", "xpack.ml.anomalyUtils.multiBucketImpact.highLabel": "高", "xpack.ml.anomalyUtils.multiBucketImpact.lowLabel": "低", "xpack.ml.anomalyUtils.multiBucketImpact.mediumLabel": "中", @@ -9443,6 +11043,9 @@ "xpack.ml.dataframe.analytics.classificationExploration.showActions": "アクションを表示", "xpack.ml.dataframe.analytics.classificationExploration.showAllColumns": "すべての列を表示", "xpack.ml.dataframe.analytics.classificationExploration.tableJobIdTitle": "分類ジョブID {jobId}のデスティネーションインデックス", + "xpack.ml.dataframe.analytics.create.advancedConfigDetailsTitle": "高度な構成", + "xpack.ml.dataframe.analytics.create.advancedConfigSectionTitle": "高度な構成", + "xpack.ml.dataframe.analytics.create.advancedDetails.editButtonText": "編集", "xpack.ml.dataframe.analytics.create.advancedEditor.codeEditorAriaLabel": "高度な分析ジョブエディター", "xpack.ml.dataframe.analytics.create.advancedEditor.configRequestBody": "構成リクエスト本文", "xpack.ml.dataframe.analytics.create.advancedEditor.jobIdExistsError": "このIDの分析ジョブが既に存在します。", @@ -9453,12 +11056,63 @@ "xpack.ml.dataframe.analytics.create.advancedEditorMessage.destinationIndexNameEmpty": "デスティネーションインデックス名は未入力のままにできません。", "xpack.ml.dataframe.analytics.create.advancedEditorMessage.destinationIndexNameExistsWarn": "この対象インデックス名のインデックスは既に存在します。この分析ジョブを実行すると、デスティネーションインデックスが変更されます。", "xpack.ml.dataframe.analytics.create.advancedEditorMessage.destinationIndexNameValid": "無効なデスティネーションインデックス名。", + "xpack.ml.dataframe.analytics.create.advancedEditorMessage.includesInvalid": "依存変数を含める必要があります。", "xpack.ml.dataframe.analytics.create.advancedEditorMessage.modelMemoryLimitEmpty": "モデルメモリー制限フィールドを空にすることはできません。", "xpack.ml.dataframe.analytics.create.advancedEditorMessage.numTopFeatureImportanceValuesInvalid": "num_top_feature_importance_valuesの値は整数の{min}以上でなければなりません。", + "xpack.ml.dataframe.analytics.create.advancedEditorMessage.resultsFieldEmptyString": "結果フィールドを空の文字列にすることはできません。", "xpack.ml.dataframe.analytics.create.advancedEditorMessage.sourceIndexNameEmpty": "ソースインデックス名は未入力のままにできません。", "xpack.ml.dataframe.analytics.create.advancedEditorMessage.sourceIndexNameValid": "無効なソースインデックス名。", "xpack.ml.dataframe.analytics.create.advancedEditorMessage.trainingPercentInvalid": "学習割合は{min}~{max}の範囲の数値でなければなりません。", + "xpack.ml.dataframe.analytics.create.allDocsMissingFieldsErrorMessage": "メモリ使用量を推計できません。インデックスされたドキュメントに存在しないソースインデックス[{index}]のマッピングされたフィールドがあります。JSONエディターに切り替え、明示的にフィールドを選択し、インデックスされたドキュメントに存在するフィールドのみを含める必要があります。", + "xpack.ml.dataframe.analytics.create.analysisFieldsTable.fieldNameColumn": "フィールド名", + "xpack.ml.dataframe.analytics.create.analysisFieldsTable.minimumFieldsMessage": "1つ以上のフィールドを選択する必要があります。", + "xpack.ml.dataframe.analytics.create.analyticsListCardDescription": "分析管理ページに戻ります。", + "xpack.ml.dataframe.analytics.create.analyticsListCardTitle": "データフレーム分析", + "xpack.ml.dataframe.analytics.create.analyticsProgressCalloutMessage": "分析ジョブ{jobId}が失敗しました。", + "xpack.ml.dataframe.analytics.create.analyticsProgressCalloutTitle": "ジョブが失敗しました", + "xpack.ml.dataframe.analytics.create.analyticsProgressErrorMessage": "分析ジョブ{jobId}の進行状況統計の取得中にエラーが発生しました", + "xpack.ml.dataframe.analytics.create.analyticsProgressPhaseTitle": "フェーズ", + "xpack.ml.dataframe.analytics.create.analyticsProgressTitle": "進捗", + "xpack.ml.dataframe.analytics.create.analyticsTable.isIncludedColumn": "含まれる", + "xpack.ml.dataframe.analytics.create.analyticsTable.isRequiredColumn": "必須", + "xpack.ml.dataframe.analytics.create.analyticsTable.mappingColumn": "マッピング", + "xpack.ml.dataframe.analytics.create.analyticsTable.reasonColumn": "理由", + "xpack.ml.dataframe.analytics.create.calloutMessage": "分析フィールドを読み込むには追加のデータが必要です。", + "xpack.ml.dataframe.analytics.create.calloutTitle": "分析フィールドがありません", + "xpack.ml.dataframe.analytics.create.chooseSourceTitle": "ソースインデックスパターンを選択してください", "xpack.ml.dataframe.analytics.create.classificationHelpText": "分類ジョブには表のようなデータ構造でマッピングされたソースインデックスが必要で、数値、ブール値、テキスト、キーワード、またはIPフィールドのみがサポートされます。予測フィールド名などのカスタムオプションを適用するには、詳細エディターを使用します。", + "xpack.ml.dataframe.analytics.create.computeFeatureInfluenceFalseValue": "False", + "xpack.ml.dataframe.analytics.create.computeFeatureInfluenceLabel": "演算機能影響", + "xpack.ml.dataframe.analytics.create.computeFeatureInfluenceLabelHelpText": "機能影響演算が有効かどうかを指定します。デフォルトはtrueです。", + "xpack.ml.dataframe.analytics.create.computeFeatureInfluenceTrueValue": "True", + "xpack.ml.dataframe.analytics.create.configDetails.computeFeatureInfluence": "特徴量の影響度の計算", + "xpack.ml.dataframe.analytics.create.configDetails.dependentVariable": "従属変数", + "xpack.ml.dataframe.analytics.create.configDetails.destIndex": "デスティネーションインデックス", + "xpack.ml.dataframe.analytics.create.configDetails.editButtonText": "編集", + "xpack.ml.dataframe.analytics.create.configDetails.eta": "Eta", + "xpack.ml.dataframe.analytics.create.configDetails.featureBagFraction": "特徴量bag割合", + "xpack.ml.dataframe.analytics.create.configDetails.featureInfluenceThreshold": "特徴量の影響度しきい値", + "xpack.ml.dataframe.analytics.create.configDetails.gamma": "ガンマ", + "xpack.ml.dataframe.analytics.create.configDetails.includedFields": "含まれるフィールド", + "xpack.ml.dataframe.analytics.create.configDetails.jobDescription": "ジョブの説明", + "xpack.ml.dataframe.analytics.create.configDetails.jobId": "ジョブID", + "xpack.ml.dataframe.analytics.create.configDetails.jobType": "ジョブタイプ", + "xpack.ml.dataframe.analytics.create.configDetails.lambdaFields": "ラムダ", + "xpack.ml.dataframe.analytics.create.configDetails.maxNumThreads": "最大スレッド数", + "xpack.ml.dataframe.analytics.create.configDetails.maxTreesFields": "最大ツリー", + "xpack.ml.dataframe.analytics.create.configDetails.method": "メソド", + "xpack.ml.dataframe.analytics.create.configDetails.modelMemoryLimit": "モデルメモリー制限", + "xpack.ml.dataframe.analytics.create.configDetails.nNeighbors": "N近傍", + "xpack.ml.dataframe.analytics.create.configDetails.numTopClasses": "最上位クラス", + "xpack.ml.dataframe.analytics.create.configDetails.numTopFeatureImportanceValues": "上位特徴量の重要度値", + "xpack.ml.dataframe.analytics.create.configDetails.outlierFraction": "異常値割合", + "xpack.ml.dataframe.analytics.create.configDetails.predictionFieldName": "予測フィールド名", + "xpack.ml.dataframe.analytics.create.configDetails.Query": "クエリ", + "xpack.ml.dataframe.analytics.create.configDetails.randomizedSeed": "ランダム化されたシード", + "xpack.ml.dataframe.analytics.create.configDetails.resultsField": "結果フィールド", + "xpack.ml.dataframe.analytics.create.configDetails.sourceIndex": "ソースインデックス", + "xpack.ml.dataframe.analytics.create.configDetails.standardizationEnabled": "標準化が有効です", + "xpack.ml.dataframe.analytics.create.configDetails.trainingPercent": "トレーニングパーセンテージ", "xpack.ml.dataframe.analytics.create.createIndexPatternErrorMessage": "Kibanaインデックスパターンの作成中にエラーが発生しました。", "xpack.ml.dataframe.analytics.create.createIndexPatternLabel": "インデックスパターンを作成", "xpack.ml.dataframe.analytics.create.createIndexPatternSuccessMessage": "Kibanaインデックスパターン{indexPatternName}が作成されました。", @@ -9472,14 +11126,33 @@ "xpack.ml.dataframe.analytics.create.destinationIndexInputAriaLabel": "固有の宛先インデックス名を選択してください。", "xpack.ml.dataframe.analytics.create.destinationIndexInvalidError": "無効なデスティネーションインデックス名。", "xpack.ml.dataframe.analytics.create.destinationIndexLabel": "デスティネーションインデックス", + "xpack.ml.dataframe.analytics.create.detailsDetails.editButtonText": "編集", "xpack.ml.dataframe.analytics.create.duplicateIndexPatternErrorMessage": "Kibanaインデックスパターンの作成中にエラーが発生しました。", "xpack.ml.dataframe.analytics.create.duplicateIndexPatternErrorMessageError": "インデックスパターン{indexPatternName}はすでに作成されています。", + "xpack.ml.dataframe.analytics.create.enableJsonEditorHelpText": "JSONエディターからこのフォームには戻れません。", "xpack.ml.dataframe.analytics.create.errorCreatingDataFrameAnalyticsJob": "データフレーム分析ジョブの作成中にエラーが発生しました。", "xpack.ml.dataframe.analytics.create.errorGettingDataFrameAnalyticsList": "既存のデータフレーム分析ジョブIDの取得中にエラーが発生しました。", "xpack.ml.dataframe.analytics.create.errorGettingIndexPatternTitles": "既存のインデックスパターンのタイトルの取得中にエラーが発生しました。", "xpack.ml.dataframe.analytics.create.errorStartingDataFrameAnalyticsJob": "データフレーム分析ジョブの開始中にエラーが発生しました。", + "xpack.ml.dataframe.analytics.create.etaInputAriaLabel": "縮小が重みに適用されました", + "xpack.ml.dataframe.analytics.create.etaLabel": "Eta", + "xpack.ml.dataframe.analytics.create.etaText": "縮小が重みに適用されました。0.001から1の範囲でなければなりません。", + "xpack.ml.dataframe.analytics.create.featureBagFractionInputAriaLabel": "各候補分割のランダムなbagを選択したときに使用される特徴量の割合", + "xpack.ml.dataframe.analytics.create.featureBagFractionLabel": "特徴量bag割合", + "xpack.ml.dataframe.analytics.create.featureBagFractionText": "各候補分割のランダムなbagを選択したときに使用される特徴量の割合。", + "xpack.ml.dataframe.analytics.create.featureInfluenceThresholdHelpText": "特徴量の影響度スコアを計算するために、ドキュメントで必要な最低異常値スコア。値範囲:0-1.デフォルトは0.1です。", + "xpack.ml.dataframe.analytics.create.featureInfluenceThresholdLabel": "特徴量の影響度しきい値", + "xpack.ml.dataframe.analytics.create.gammaInputAriaLabel": "フォレストの個別のツリーのサイズに関連付けられた線形ペナルティを乗算します", + "xpack.ml.dataframe.analytics.create.gammaLabel": "ガンマ", + "xpack.ml.dataframe.analytics.create.gammaText": "フォレストの個別のツリーのサイズに関連付けられた線形ペナルティを乗算します。非負の値でなければなりません。", + "xpack.ml.dataframe.analytics.create.hyperParametersDetailsTitle": "ハイパーパラメーター", + "xpack.ml.dataframe.analytics.create.hyperParametersSectionTitle": "ハイパーパラメーター", + "xpack.ml.dataframe.analytics.create.includedFieldsCount": "{numFields, plural, one {個のフィールド} other {個のフィールド}}が分析に含まれます", + "xpack.ml.dataframe.analytics.create.includedFieldsLabel": "含まれるフィールド", "xpack.ml.dataframe.analytics.create.indexPatternAlreadyExistsError": "このタイトルのインデックスパターンが既に存在します。", "xpack.ml.dataframe.analytics.create.indexPatternExistsError": "このタイトルのインデックスパターンが既に存在します。", + "xpack.ml.dataframe.analytics.create.isIncludedOption": "含まれる", + "xpack.ml.dataframe.analytics.create.isNotIncludedOption": "含まれない", "xpack.ml.dataframe.analytics.create.jobDescription.helpText": "オプションの説明テキストです", "xpack.ml.dataframe.analytics.create.jobDescription.label": "ジョブの説明", "xpack.ml.dataframe.analytics.create.jobIdExistsError": "このIDの分析ジョブが既に存在します。", @@ -9489,18 +11162,78 @@ "xpack.ml.dataframe.analytics.create.jobIdLabel": "ジョブID", "xpack.ml.dataframe.analytics.create.jobIdPlaceholder": "ジョブID", "xpack.ml.dataframe.analytics.create.jobTypeLabel": "ジョブタイプ", + "xpack.ml.dataframe.analytics.create.lambdaHelpText": "学習データセットの過剰適合を防止するための正則化パラメーター。非負の値でなければなりません。", + "xpack.ml.dataframe.analytics.create.lambdaInputAriaLabel": "学習データセットの過剰適合を防止するための正則化パラメーター。", + "xpack.ml.dataframe.analytics.create.lambdaLabel": "ラムダ", + "xpack.ml.dataframe.analytics.create.maxNumThreadsError": "最小値は1です。", + "xpack.ml.dataframe.analytics.create.maxNumThreadsHelpText": "分析で使用されるスレッドの最大数。デフォルト値は1です。", + "xpack.ml.dataframe.analytics.create.maxNumThreadsInputAriaLabel": "分析で使用されるスレッドの最大数。", + "xpack.ml.dataframe.analytics.create.maxNumThreadsLabel": "最大スレッド数", + "xpack.ml.dataframe.analytics.create.maxTreesInputAriaLabel": "フォレストに含めることができるツリーの最大数。", + "xpack.ml.dataframe.analytics.create.maxTreesLabel": "最大ツリー", + "xpack.ml.dataframe.analytics.create.maxTreesText": "フォレストに含めることができるツリーの最大数。", + "xpack.ml.dataframe.analytics.create.methodHelpText": "異常値検出で使用される方法を設定します。設定されていない場合は、別の方法を組み合わせて使用し、個別の異常値スコアを正規化して組み合わせ、全体的な異常値スコアを取得します。アンサンブル法を使用することをお勧めします。", + "xpack.ml.dataframe.analytics.create.methodLabel": "メソド", + "xpack.ml.dataframe.analytics.create.modelMemoryEmptyError": "モデルメモリ上限を空にすることはできません", + "xpack.ml.dataframe.analytics.create.modelMemoryLimitHelpText": "分析処理で許可されるメモリリソースのおおよその最大量。", "xpack.ml.dataframe.analytics.create.modelMemoryLimitLabel": "モデルメモリー制限", "xpack.ml.dataframe.analytics.create.modelMemoryUnitsInvalidError": "モデルメモリー制限のデータユニットが認識されません。{str}でなければなりません", "xpack.ml.dataframe.analytics.create.modelMemoryUnitsMinError": "モデルメモリー制限を {mml} 未満にはできません", + "xpack.ml.dataframe.analytics.create.newAnalyticsTitle": "新しい分析ジョブ", + "xpack.ml.dataframe.analytics.create.nNeighborsHelpText": "異常値検出の各方法が異常値スコアを計算するために使用する近傍の数。設定されていない場合、別のアンサンブルメンバーの異なる値が使用されます。正の整数でなければなりません", + "xpack.ml.dataframe.analytics.create.nNeighborsInputAriaLabel": "異常値検出の各方法が異常値スコアを計算するために使用する近傍の数。", + "xpack.ml.dataframe.analytics.create.nNeighborsLabel": "N近傍", + "xpack.ml.dataframe.analytics.create.numTopClassesHelpText": "予測された確率が報告されるカテゴリの数。", + "xpack.ml.dataframe.analytics.create.numTopClassesInputAriaLabel": "予測された確率が報告されるカテゴリの数", + "xpack.ml.dataframe.analytics.create.numTopClassesLabel": "最上位クラス", "xpack.ml.dataframe.analytics.create.numTopFeatureImportanceValuesErrorText": "機能重要度値の最大数が無効です", "xpack.ml.dataframe.analytics.create.numTopFeatureImportanceValuesHelpText": "返すドキュメントごとに機能重要度値の最大数を指定します。", "xpack.ml.dataframe.analytics.create.numTopFeatureImportanceValuesInputAriaLabel": "ドキュメントごとの機能重要度値の最大数。", "xpack.ml.dataframe.analytics.create.numTopFeatureImportanceValuesLabel": "機能重要度値", "xpack.ml.dataframe.analytics.create.outlierDetectionHelpText": "外れ値検出ジョブは、表に示すようなデータ構造でマッピングされたソースインデックスを必要とし、数字とブール値フィールドのみを分析します。カスタムオプションを構成に追加するには、詳細エディターを使用します。", + "xpack.ml.dataframe.analytics.create.outlierFractionHelpText": "異常値検出の前に異常であると想定されるデータセットの比率を設定します。", + "xpack.ml.dataframe.analytics.create.outlierFractionInputAriaLabel": "異常値検出の前に異常であると想定されるデータセットの比率を設定します。", + "xpack.ml.dataframe.analytics.create.outlierFractionLabel": "異常値割合", "xpack.ml.dataframe.analytics.create.outlierRegressionHelpText": "リグレッションジョブは数値フィールドのみを分析します。予測フィールド名などのカスタムオプションを適用するには、詳細エディターを使用します。", + "xpack.ml.dataframe.analytics.create.predictionFieldNameHelpText": "結果で予測フィールドの名前を定義します。デフォルトは_predictionです。", + "xpack.ml.dataframe.analytics.create.predictionFieldNameLabel": "予測フィールド名", + "xpack.ml.dataframe.analytics.create.randomizeSeedInputAriaLabel": "学習で使用されるドキュメントを選択するために使用される乱数生成器のシード", + "xpack.ml.dataframe.analytics.create.randomizeSeedLabel": "シードのランダム化", + "xpack.ml.dataframe.analytics.create.randomizeSeedText": "学習で使用されるドキュメントを選択するために使用される乱数生成器のシード。", "xpack.ml.dataframe.analytics.create.requiredFieldsError": "無効です。 {message}", + "xpack.ml.dataframe.analytics.create.resultsFieldHelpText": "分析の結果を格納するフィールドの名前を定義します。デフォルトはmlです。", + "xpack.ml.dataframe.analytics.create.resultsFieldLabel": "結果フィールド", + "xpack.ml.dataframe.analytics.create.savedSearchLabel": "保存検索", + "xpack.ml.dataFrame.analytics.create.searchSelection.notFoundLabel": "一致インデックスまたは保存した検索が見つかりません。", + "xpack.ml.dataFrame.analytics.create.searchSelection.savedObjectType.indexPattern": "インデックスパターン", + "xpack.ml.dataFrame.analytics.create.searchSelection.savedObjectType.search": "保存検索", + "xpack.ml.dataframe.analytics.create.shouldCreateIndexPatternMessage": "ディスティネーションインデックスのインデックスパターンが作成されていない場合は、ジョブ結果を表示できないことがあります。", + "xpack.ml.dataframe.analytics.create.sourceIndexFieldsCheckError": "ジョブタイプでサポートされているフィールドを確認しているときに問題が発生しました。ページを更新して再起動してください。", + "xpack.ml.dataframe.analytics.create.sourceObjectClassificationHelpText": "このインデックスパターンにはサポートされているフィールドが含まれていません。分類ジョブには、カテゴリ、数値、ブール値フィールドが必要です。", + "xpack.ml.dataframe.analytics.create.sourceObjectHelpText": "このインデックスパターンには数字タイプのフィールドが含まれていません。分析ジョブで外れ値が検出されない可能性があります。", + "xpack.ml.dataframe.analytics.create.sourceObjectRegressionHelpText": "このインデックスパターンにはサポートされているフィールドが含まれていません。回帰ジョブには数値フィールドが必要です。", + "xpack.ml.dataframe.analytics.create.sourceQueryLabel": "クエリ", + "xpack.ml.dataframe.analytics.create.standardizationEnabledFalseValue": "False", + "xpack.ml.dataframe.analytics.create.standardizationEnabledHelpText": "trueの場合、異常値スコアを計算する前に、次の処理が列に対して実行されます。(x_i - mean(x_i)) / sd(x_i)", + "xpack.ml.dataframe.analytics.create.standardizationEnabledInputAriaLabel": "標準化有効設定を設定します。", + "xpack.ml.dataframe.analytics.create.standardizationEnabledLabel": "標準化が有効です", + "xpack.ml.dataframe.analytics.create.standardizationEnabledTrueValue": "True", + "xpack.ml.dataframe.analytics.create.startCheckboxHelpText": "選択されていない場合、ジョブリストに戻ると、後からジョブを開始できます。", "xpack.ml.dataframe.analytics.create.startDataFrameAnalyticsSuccessMessage": "データフレーム分析 {jobId} の開始リクエストが受け付けられました。", + "xpack.ml.dataframe.analytics.create.switchToJsonEditorSwitch": "JSONエディターに切り替える", + "xpack.ml.dataframe.analytics.create.trainingPercentHelpText": "学習で使用可能なドキュメントの割合を定義します。", "xpack.ml.dataframe.analytics.create.trainingPercentLabel": "トレーニングパーセンテージ", + "xpack.ml.dataframe.analytics.create.unsupportedFieldsError": "無効です。 {message}", + "xpack.ml.dataframe.analytics.create.wizardCreateButton": "作成", + "xpack.ml.dataframe.analytics.create.wizardStartCheckbox": "即時開始", + "xpack.ml.dataframe.analytics.createWizard.requiredFieldsErrorMessage": "依存変数のほかに、1つ以上のフィールドを分析に含める必要があります。", + "xpack.ml.dataframe.analytics.creation.advancedStepTitle": "その他のオプション", + "xpack.ml.dataframe.analytics.creation.configurationStepTitle": "構成", + "xpack.ml.dataframe.analytics.creation.continueButtonText": "続行", + "xpack.ml.dataframe.analytics.creation.createStepTitle": "作成", + "xpack.ml.dataframe.analytics.creation.detailsStepTitle": "ジョブの詳細", + "xpack.ml.dataframe.analytics.creationPageSourceIndexTitle": "ソースインデックスパターン:{indexTitle}", + "xpack.ml.dataframe.analytics.creationPageTitle": "ジョブを作成", "xpack.ml.dataframe.analytics.errorCallout.evaluateErrorTitle": "データの読み込み中にエラーが発生しました。", "xpack.ml.dataframe.analytics.errorCallout.generalErrorTitle": "データの読み込み中にエラーが発生しました。", "xpack.ml.dataframe.analytics.errorCallout.noDataCalloutBody": "インデックスのクエリが結果を返しませんでした。ジョブが完了済みで、インデックスにドキュメントがあることを確認してください。", @@ -9517,16 +11250,22 @@ "xpack.ml.dataframe.analytics.explorationResults.documentsShownHelpText": "予測があるドキュメントを示す", "xpack.ml.dataframe.analytics.explorationResults.fieldSelection": "{docFieldsCount, number}件中 showing {selectedFieldsLength, number}件の{docFieldsCount, plural, one {フィールド} other {フィールド}}", "xpack.ml.dataframe.analytics.explorationResults.firstDocumentsShownHelpText": "予測がある最初の{searchSize}のドキュメントを示す", + "xpack.ml.dataframe.analytics.indexPatternPromptLinkText": "インデックスパターンを作成します", + "xpack.ml.dataframe.analytics.indexPatternPromptMessage": "{destIndex}のインデックス{destIndex}. {linkToIndexPatternManagement}にはインデックスパターンが存在しません。", "xpack.ml.dataframe.analytics.jobCaps.errorTitle": "結果を取得できません。インデックスのフィールドデータの読み込み中にエラーが発生しました。", "xpack.ml.dataframe.analytics.jobConfig.errorTitle": "結果を取得できません。ジョブ構成データの読み込み中にエラーが発生しました。", "xpack.ml.dataframe.analytics.regressionExploration.evaluateJobIdTitle": "回帰ジョブID {jobId}の評価", "xpack.ml.dataframe.analytics.regressionExploration.generalizationDocsCount": "{docsCount, plural, one {# doc} other {# docs}}が評価されました", "xpack.ml.dataframe.analytics.regressionExploration.generalizationErrorTitle": "一般化エラー", "xpack.ml.dataframe.analytics.regressionExploration.generalizationFilterText": ".学習データをフィルタリングしています。", + "xpack.ml.dataframe.analytics.regressionExploration.huberLinkText": "Pseudo Huber損失関数", + "xpack.ml.dataframe.analytics.regressionExploration.huberText": "{wikiLink}", "xpack.ml.dataframe.analytics.regressionExploration.indexError": "インデックスデータの読み込み中にエラーが発生しました。", "xpack.ml.dataframe.analytics.regressionExploration.meanSquaredErrorText": "平均二乗エラー", "xpack.ml.dataframe.analytics.regressionExploration.meanSquaredErrorTooltipContent": "回帰分析モデルの実行の効果を測定します。真値と予測値の間の差異の二乗平均合計。", - "xpack.ml.dataframe.analytics.regressionExploration.regressionDocsLink": "CDATA[回帰評価ドキュメント ", + "xpack.ml.dataframe.analytics.regressionExploration.msleText": "平均二乗対数誤差", + "xpack.ml.dataframe.analytics.regressionExploration.msleTooltipContent": "予測された対数と実際の(正解データ)値の対数の間の平均二乗誤差", + "xpack.ml.dataframe.analytics.regressionExploration.regressionDocsLink": "回帰評価ドキュメント ", "xpack.ml.dataframe.analytics.regressionExploration.rSquaredText": "R の二乗", "xpack.ml.dataframe.analytics.regressionExploration.rSquaredTooltipContent": "適合度を表します。モデルによる観察された結果の複製の効果を測定します。", "xpack.ml.dataframe.analytics.regressionExploration.tableJobIdTitle": "回帰ジョブID {jobId}のデスティネーションインデックス", @@ -9536,19 +11275,48 @@ "xpack.ml.dataframe.analyticsList.analyticsDetails.tabs.analyticsMessagesLabel": "ジョブメッセージ", "xpack.ml.dataframe.analyticsList.cloneJobButtonLabel": "ジョブのクローンを作成します", "xpack.ml.dataframe.analyticsList.completeBatchAnalyticsToolTip": "{analyticsId}は完了済みの分析ジョブで、再度開始できません。", - "xpack.ml.dataframe.analyticsList.createDataFrameAnalyticsButton": "分析ジョブの作成", - "xpack.ml.dataframe.analyticsList.deleteActionDisabledToolTipContent": "削除するにはデータフレーム分析を停止してください。", + "xpack.ml.dataframe.analyticsList.createDataFrameAnalyticsButton": "ジョブを作成", + "xpack.ml.dataframe.analyticsList.deleteActionDisabledToolTipContent": "削除するにはデータフレーム分析ジョブを停止してください。", "xpack.ml.dataframe.analyticsList.deleteActionName": "削除", - "xpack.ml.dataframe.analyticsList.deleteAnalyticsSuccessMessage": "データフレーム分析 {analyticsId} の削除リクエストが受け付けられました。", - "xpack.ml.dataframe.analyticsList.deleteModalBody": "この分析ジョブを削除してよろしいですか?この分析ジョブのデスティネーションインデックスとオプションのKibanaインデックスパターンは削除されません。", + "xpack.ml.dataframe.analyticsList.deleteAnalyticsErrorMessage": "データフレーム分析ジョブ{analyticsId}の削除中にエラーが発生しました。", + "xpack.ml.dataframe.analyticsList.deleteAnalyticsPrivilegeErrorMessage": "ユーザーはインデックス{indexName}を削除する権限がありません。{error}", + "xpack.ml.dataframe.analyticsList.deleteAnalyticsSuccessMessage": "データフレーム分析ジョブ{analyticsId}の削除リクエストが受け付けられました。", + "xpack.ml.dataframe.analyticsList.deleteAnalyticsWithIndexErrorMessage": "ディスティネーションインデックス{destinationIndex}の削除中にエラーが発生しました。{error}", + "xpack.ml.dataframe.analyticsList.deleteAnalyticsWithIndexPatternErrorMessage": "インデックスパターン{destinationIndex}の削除中にエラーが発生しました。{error}", + "xpack.ml.dataframe.analyticsList.deleteAnalyticsWithIndexPatternSuccessMessage": "インデックスパターン{destinationIndex}を削除する要求が確認されました。", + "xpack.ml.dataframe.analyticsList.deleteAnalyticsWithIndexSuccessMessage": "ディスティネーションインデックス{destinationIndex}を削除する要求が確認されました。", + "xpack.ml.dataframe.analyticsList.deleteDestinationIndexTitle": "ディスティネーションインデックス{indexName}を削除", + "xpack.ml.dataframe.analyticsList.deleteModalBody": "この分析ジョブを削除してよろしいですか?", "xpack.ml.dataframe.analyticsList.deleteModalCancelButton": "キャンセル", "xpack.ml.dataframe.analyticsList.deleteModalDeleteButton": "削除", "xpack.ml.dataframe.analyticsList.deleteModalTitle": "{analyticsId}の削除", "xpack.ml.dataframe.analyticsList.description": "説明", "xpack.ml.dataframe.analyticsList.destinationIndex": "デスティネーションインデックス", + "xpack.ml.dataframe.analyticsList.editActionName": "編集", + "xpack.ml.dataframe.analyticsList.editActionPermissionTooltip": "分析ジョブを編集する権限がありません。", + "xpack.ml.dataframe.analyticsList.editFlyout.allowLazyStartAriaLabel": "lazy startの許可を更新します。", + "xpack.ml.dataframe.analyticsList.editFlyout.allowLazyStartFalseValue": "False", + "xpack.ml.dataframe.analyticsList.editFlyout.allowLazyStartLabel": "lazy startを許可", + "xpack.ml.dataframe.analyticsList.editFlyout.allowLazyStartTrueValue": "True", + "xpack.ml.dataframe.analyticsList.editFlyout.descriptionAriaLabel": "ジョブ説明を更新します。", + "xpack.ml.dataframe.analyticsList.editFlyout.descriptionLabel": "説明", + "xpack.ml.dataframe.analyticsList.editFlyout.maxNumThreadsAriaLabel": "分析で使用されるスレッドの最大数を更新します。", + "xpack.ml.dataframe.analyticsList.editFlyout.maxNumThreadsError": "最小値は1です。", + "xpack.ml.dataframe.analyticsList.editFlyout.maxNumThreadsHelpText": "最大スレッド数は、ジョブが停止するまで編集できません。", + "xpack.ml.dataframe.analyticsList.editFlyout.maxNumThreadsLabel": "最大スレッド数", + "xpack.ml.dataframe.analyticsList.editFlyout.modelMemoryHelpText": "モデルメモリ上限は、ジョブが停止するまで編集できません。", + "xpack.ml.dataframe.analyticsList.editFlyout.modelMemoryLimitAriaLabel": "モデルメモリ上限を更新します。", + "xpack.ml.dataframe.analyticsList.editFlyout.modelMemoryLimitLabel": "モデルメモリー制限", + "xpack.ml.dataframe.analyticsList.editFlyoutCancelButtonText": "キャンセル", + "xpack.ml.dataframe.analyticsList.editFlyoutErrorMessage": "分析ジョブ{jobId}の変更を保存できませんでした", + "xpack.ml.dataframe.analyticsList.editFlyoutSuccessMessage": "分析ジョブ{jobId}が更新されました。", + "xpack.ml.dataframe.analyticsList.editFlyoutTitle": "{jobId}の編集", + "xpack.ml.dataframe.analyticsList.editFlyoutUpdateButtonText": "更新", "xpack.ml.dataFrame.analyticsList.emptyPromptButtonText": "最初のデータフレーム分析ジョブを作成", "xpack.ml.dataFrame.analyticsList.emptyPromptTitle": "データフレーム分析ジョブが見つかりませんでした", "xpack.ml.dataFrame.analyticsList.errorPromptTitle": "データフレーム分析リストの取得中にエラーが発生しました。", + "xpack.ml.dataframe.analyticsList.errorWithCheckingIfIndexPatternExistsNotificationErrorMessage": "インデックスパターン{indexPattern}が存在するかどうかを確認するときにエラーが発生しました。{error}", + "xpack.ml.dataframe.analyticsList.errorWithCheckingIfUserCanDeleteIndexNotificationErrorMessage": "ユーザーが{destinationIndex}を削除できるかどうかを確認するときにエラーが発生しました。{error}", "xpack.ml.dataframe.analyticsList.expandedRow.tabs.jobSettings.phase": "フェーズ", "xpack.ml.dataframe.analyticsList.expandedRow.tabs.jobSettings.progress": "進捗", "xpack.ml.dataframe.analyticsList.expandedRow.tabs.jobSettings.state": "ステータス", @@ -9556,6 +11324,7 @@ "xpack.ml.dataframe.analyticsList.expandedRow.tabs.jobSettingsLabel": "ジョブの詳細", "xpack.ml.dataframe.analyticsList.experimentalBadgeLabel": "実験的", "xpack.ml.dataframe.analyticsList.experimentalBadgeTooltipContent": "データフレーム分析は実験段階の機能です。フィードバックをお待ちしています。", + "xpack.ml.dataframe.analyticsList.fetchSourceIndexPatternForCloneErrorMessage": "インデックスパターン{indexPattern}が存在するかどうかを確認するときにエラーが発生しました。{error}", "xpack.ml.dataframe.analyticsList.progress": "進捗", "xpack.ml.dataframe.analyticsList.progressOfPhase": "フェーズ{currentPhase}の進捗: {progress}%", "xpack.ml.dataframe.analyticsList.refreshButtonLabel": "更新", @@ -9564,6 +11333,7 @@ "xpack.ml.dataframe.analyticsList.showDetailsColumn.screenReaderDescription": "このカラムには各ジョブの詳細を示すクリック可能なコントロールが含まれます", "xpack.ml.dataframe.analyticsList.sourceIndex": "ソースインデックス", "xpack.ml.dataframe.analyticsList.startActionName": "開始", + "xpack.ml.dataframe.analyticsList.startAnalyticsErrorTitle": "ジョブの開始エラー", "xpack.ml.dataframe.analyticsList.startAnalyticsSuccessMessage": "データフレーム分析 {analyticsId} の開始リクエストが受け付けられました。", "xpack.ml.dataframe.analyticsList.startModalBody": "データフレーム分析ジョブは、クラスターの検索とインデックスによる負荷を増やします。過剰な負荷が生じた場合は分析ジョブを停止してください。この分析ジョブを開始してよろしいですか?", "xpack.ml.dataframe.analyticsList.startModalCancelButton": "キャンセル", @@ -9575,19 +11345,29 @@ "xpack.ml.dataframe.analyticsList.stopAnalyticsErrorMessage": "データフレーム分析{analyticsId}の停止中にエラーが発生しました。{error}", "xpack.ml.dataframe.analyticsList.stopAnalyticsSuccessMessage": "データフレーム分析 {analyticsId} の停止リクエストが受け付けられました。", "xpack.ml.dataframe.analyticsList.tableActionLabel": "アクション", - "xpack.ml.dataframe.analyticsList.title": "分析ジョブ", + "xpack.ml.dataframe.analyticsList.title": "データフレーム分析ジョブ", "xpack.ml.dataframe.analyticsList.type": "タイプ", + "xpack.ml.dataframe.analyticsList.typeFilter": "タイプ", "xpack.ml.dataframe.analyticsList.viewActionName": "表示", "xpack.ml.dataframe.stepCreateForm.createDataFrameAnalyticsSuccessMessage": "データフレーム分析 {jobId} の作成リクエストが受け付けられました。", "xpack.ml.dataframe.stepDetailsForm.destinationIndexInvalidErrorLink": "インデックス名の制限に関する詳細。", - "xpack.ml.dataFrameAnalyticsBreadcrumbs.dataFrameExplorationLabel": "データフレーム分析", - "xpack.ml.dataFrameAnalyticsBreadcrumbs.dataFrameListLabel": "データフレーム分析", + "xpack.ml.dataFrameAnalyticsBreadcrumbs.dataFrameExplorationLabel": "探索", + "xpack.ml.dataFrameAnalyticsBreadcrumbs.dataFrameListLabel": "ジョブ管理", + "xpack.ml.dataFrameAnalyticsBreadcrumbs.dataFrameManagementLabel": "データフレーム分析", "xpack.ml.dataFrameAnalyticsBreadcrumbs.indexLabel": "インデックス", + "xpack.ml.dataFrameAnalyticsLabel": "データフレーム分析", + "xpack.ml.dataGrid.columnChart.ErrorMessageToast": "ヒストグラムデータの取得でエラーが発生しました。{error}", "xpack.ml.dataGrid.dataGridNoDataCalloutTitle": "インデックスプレビューを利用できません", + "xpack.ml.dataGrid.histogramButtonText": "ヒストグラム", + "xpack.ml.dataGrid.histogramButtonToolTipContent": "ヒストグラムデータを取得するために実行されるクエリは、{samplerShardSize}ドキュメントのシャードごとにサンプルサイズを使用します。", "xpack.ml.dataGrid.indexDataError": "インデックスデータの読み込み中にエラーが発生しました。", "xpack.ml.dataGrid.IndexNoDataCalloutBody": "インデックスのクエリが結果を返しませんでした。十分なアクセス権があり、インデックスにドキュメントが含まれていて、クエリ要件が妥当であることを確認してください。", "xpack.ml.dataGrid.IndexNoDataCalloutTitle": "空のインデックスクエリ結果。", "xpack.ml.dataGrid.invalidSortingColumnError": "列「{columnId}」は並べ替えに使用できません。", + "xpack.ml.dataGridChart.histogramNotAvailable": "グラフはサポートされていません。", + "xpack.ml.dataGridChart.notEnoughData": "0個のドキュメントにフィールドが含まれます。", + "xpack.ml.dataGridChart.singleCategoryLegend": "{cardinality, plural, one {カテゴリ} other {カテゴリ}}", + "xpack.ml.dataGridChart.topCategoriesLegend": "上位{MAX_CHART_COLUMNS}/{cardinality}カテゴリ", "xpack.ml.datavisualizer.actionsPanel.advancedDescription": "より高度なユースケースでは、ジョブの作成にすべてのオプションを使用します", "xpack.ml.datavisualizer.actionsPanel.advancedTitle": "高度な設定", "xpack.ml.datavisualizer.actionsPanel.createJobDescription": "高度なジョブウィザードでジョブを作成し、このデータの異常を検出します:", @@ -9630,6 +11410,25 @@ "xpack.ml.datavisualizerBreadcrumbLabel": "データビジュアライザー", "xpack.ml.dataVisualizerPageLabel": "データビジュアライザー", "xpack.ml.dfAnalyticsList.analyticsDetails.messagesPane.errorMessage": "メッセージを読み込めませんでした", + "xpack.ml.editModelSnapshotFlyout.calloutText": "これはジョブ{jobId}で使用されている現在のスナップショットであるため削除できません。", + "xpack.ml.editModelSnapshotFlyout.calloutTitle": "現在のスナップショット", + "xpack.ml.editModelSnapshotFlyout.cancelButton": "キャンセル", + "xpack.ml.editModelSnapshotFlyout.closeButton": "閉じる", + "xpack.ml.editModelSnapshotFlyout.deleteButton": "削除", + "xpack.ml.editModelSnapshotFlyout.deleteErrorTitle": "モデルスナップショットの削除が失敗しました", + "xpack.ml.editModelSnapshotFlyout.deleteTitle": "スナップショットを削除しますか?", + "xpack.ml.editModelSnapshotFlyout.descriptionTitle": "説明", + "xpack.ml.editModelSnapshotFlyout.retainSwitchLabel": "自動スナップショットクリーンアップ処理中にスナップショットを保持", + "xpack.ml.editModelSnapshotFlyout.saveButton": "保存", + "xpack.ml.editModelSnapshotFlyout.saveErrorTitle": "モデルスナップショットの更新が失敗しました", + "xpack.ml.editModelSnapshotFlyout.title": "スナップショット{ssId}の編集", + "xpack.ml.editModelSnapshotFlyout.useDefaultButton": "削除", + "xpack.ml.explorer.addToDashboard.cancelButtonLabel": "キャンセル", + "xpack.ml.explorer.addToDashboard.selectDashboardsLabel": "ダッシュボードを選択:", + "xpack.ml.explorer.addToDashboard.selectSwimlanesLabel": "スイムレーンビューを選択:", + "xpack.ml.explorer.addToDashboardLabel": "ダッシュボードに追加", + "xpack.ml.explorer.annotationsTitle": "注釈{badge}", + "xpack.ml.explorer.annotationsTitleTotalCount": "合計:{count}", "xpack.ml.explorer.anomaliesTitle": "異常", "xpack.ml.explorer.anomalyTimelineTitle": "異常のタイムライン", "xpack.ml.explorer.charts.detectorLabel": "「{fieldName}」で分割された {detectorLabel}{br} Y 軸イベントの分布", @@ -9642,6 +11441,12 @@ "xpack.ml.explorer.charts.tooManyBucketsDescription": "この選択は、表示するバケット数が多すぎます。ダッシュボードは短い時間範囲で表示するのが最適です。", "xpack.ml.explorer.charts.viewLabel": "表示", "xpack.ml.explorer.createNewJobLinkText": "ジョブを作成", + "xpack.ml.explorer.dashboardsTable.addAndEditDashboardLabel": "ダッシュボードの追加と編集", + "xpack.ml.explorer.dashboardsTable.addToDashboardLabel": "ダッシュボードに追加", + "xpack.ml.explorer.dashboardsTable.descriptionColumnHeader": "説明", + "xpack.ml.explorer.dashboardsTable.savedSuccessfullyTitle": "ダッシュボード「{dashboardTitle}」は正常に更新されました", + "xpack.ml.explorer.dashboardsTable.titleColumnHeader": "タイトル", + "xpack.ml.explorer.dashboardsTitle": "スイムレーンをダッシュボードに追加", "xpack.ml.explorer.distributionChart.anomalyScoreLabel": "異常スコア", "xpack.ml.explorer.distributionChart.entityLabel": "エンティティ", "xpack.ml.explorer.distributionChart.typicalLabel": "通常", @@ -9658,6 +11463,7 @@ "xpack.ml.explorer.noInfluencersFoundTitle": "{viewBySwimlaneFieldName}影響因子が見つかりません", "xpack.ml.explorer.noInfluencersFoundTitleFilterMessage": "指定されたフィルターの{viewBySwimlaneFieldName} 影響因子が見つかりません", "xpack.ml.explorer.noJobsFoundLabel": "ジョブが見つかりません", + "xpack.ml.explorer.noResultForSelectedJobsMessage": "選択した{jobsCount, plural, one {個のジョブ} other {個のジョブ}}で結果が見つかりません", "xpack.ml.explorer.noResultsFoundLabel": "結果が見つかりませんでした", "xpack.ml.explorer.overallLabel": "全体", "xpack.ml.explorer.overallSwimlaneUnfilteredLabel": "{label} (フィルタリングなし)", @@ -9673,8 +11479,13 @@ "xpack.ml.explorer.sortedByMaxAnomalyScoreForTimeFormattedLabel": "({viewByLoadedForTimeFormatted} の最高異常スコアで分類)", "xpack.ml.explorer.sortedByMaxAnomalyScoreLabel": "(最高異常スコアで分類)", "xpack.ml.explorer.swimlane.maxAnomalyScoreLabel": "最高異常スコア", + "xpack.ml.explorer.swimlaneActions": "アクション", + "xpack.ml.explorer.swimLanePagination": "異常スイムレーンページネーション", + "xpack.ml.explorer.swimLaneRowsPerPage": "ページごとの行数:{rowsCount}", + "xpack.ml.explorer.swimLaneSelectRowsPerPage": "{rowsCount}行", "xpack.ml.explorer.topInfuencersTitle": "トップ影響因子", "xpack.ml.explorer.tryWideningTimeSelectionLabel": "時間範囲を広げるか、さらに過去に遡ってみてください", + "xpack.ml.explorer.viewByFieldLabel": "{viewByField}が表示", "xpack.ml.explorer.viewByLabel": "表示方式", "xpack.ml.feature.reserved.description": "ユーザーアクセスを許可するには、machine_learning_user か machine_learning_admin ロールのどちらかを割り当てる必要があります。", "xpack.ml.featureRegistry.mlFeatureName": "機械学習", @@ -9898,6 +11709,8 @@ "xpack.ml.itemsGrid.noMatchingItemsTitle": "一致する項目が見つかりません。", "xpack.ml.jobMessages.messageLabel": "メッセージ", "xpack.ml.jobMessages.nodeLabel": "ノード", + "xpack.ml.jobMessages.refreshAriaLabel": "更新", + "xpack.ml.jobMessages.refreshLabel": "更新", "xpack.ml.jobMessages.timeLabel": "時間", "xpack.ml.jobsBreadcrumbs.advancedConfigurationLabel": "高度な構成", "xpack.ml.jobsBreadcrumbs.categorizationLabel": "カテゴリー分け", @@ -9944,6 +11757,8 @@ "xpack.ml.jobService.openJobsLabel": "ジョブを開く", "xpack.ml.jobService.requestMayHaveTimedOutErrorMessage": "リクエストがタイムアウトし、まだバックグラウンドで実行中の可能性があります。", "xpack.ml.jobService.totalJobsLabel": "合計ジョブ数", + "xpack.ml.jobService.updateJobErrorTitle": "ジョブを更新できませんでした: {jobId}", + "xpack.ml.jobService.validateJobErrorTitle": "ジョブ検証エラー", "xpack.ml.jobsList.actionExecuteSuccessfullyNotificationMessage": "{successesJobsCount, plural, one{{successJob}} other{# 件のジョブ}} {actionTextPT}成功", "xpack.ml.jobsList.actionFailedNotificationMessage": "{failureId} が {actionText} に失敗しました", "xpack.ml.jobsList.actionsLabel": "アクション", @@ -9996,11 +11811,13 @@ "xpack.ml.jobsList.editJobFlyout.datafeedTitle": "データフィード", "xpack.ml.jobsList.editJobFlyout.detectorsTitle": "検知器", "xpack.ml.jobsList.editJobFlyout.groupsAndJobsHasSameIdErrorMessage": "この ID のジョブが既に存在します。グループとジョブは同じ ID を共有できません。", + "xpack.ml.jobsList.editJobFlyout.jobDetails.dailyModelSnapshotRetentionAfterDaysLabel": "日次モデルスナップショット保存後日数", "xpack.ml.jobsList.editJobFlyout.jobDetails.jobDescriptionLabel": "ジョブの説明", "xpack.ml.jobsList.editJobFlyout.jobDetails.jobGroupsLabel": "ジョブグループ", "xpack.ml.jobsList.editJobFlyout.jobDetails.jobGroupsPlaceholder": "ジョブを選択または作成", "xpack.ml.jobsList.editJobFlyout.jobDetails.modelMemoryLimitLabel": "モデルメモリー制限", "xpack.ml.jobsList.editJobFlyout.jobDetails.modelMemoryLimitLabelHelp": "データフィードの実行中にはモデルメモリー制限を編集できません。", + "xpack.ml.jobsList.editJobFlyout.jobDetails.modelSnapshotRetentionDaysLabel": "モデルスナップショット保存日数", "xpack.ml.jobsList.editJobFlyout.jobDetailsTitle": "ジョブの詳細", "xpack.ml.jobsList.editJobFlyout.leaveAnywayButtonLabel": "それでも移動", "xpack.ml.jobsList.editJobFlyout.pageTitle": "{jobId} の編集", @@ -10051,6 +11868,7 @@ "xpack.ml.jobsList.jobDetails.tabs.jobMessagesLabel": "ジョブメッセージ", "xpack.ml.jobsList.jobDetails.tabs.jobSettingsLabel": "ジョブ設定", "xpack.ml.jobsList.jobDetails.tabs.jsonLabel": "JSON", + "xpack.ml.jobsList.jobDetails.tabs.modelSnapshotsLabel": "モデルスナップショット", "xpack.ml.jobsList.jobFilterBar.closedLabel": "クローズ済み", "xpack.ml.jobsList.jobFilterBar.failedLabel": "失敗", "xpack.ml.jobsList.jobFilterBar.groupLabel": "グループ", @@ -10141,7 +11959,7 @@ "xpack.ml.management.jobsList.jobsListTitle": "機械学習ジョブ", "xpack.ml.management.jobsList.noGrantedPrivilegesDescription": "ML ジョブを管理するパーミッションがありません", "xpack.ml.management.jobsList.noPermissionToAccessLabel": "ML ジョブへのアクセスにはパーミッションが必要です", - "xpack.ml.management.jobsListTitle": "ジョブリスト", + "xpack.ml.management.jobsListTitle": "機械学習ジョブ", "xpack.ml.maxFileSizeSettingsDescription": "ファイルデータビジュアライザーでデータをインポートするときのファイルサイズ上限を設定します。この設定でサポートされている最大値は1 GBです。", "xpack.ml.maxFileSizeSettingsError": "200 MB、1 GBなどの有効なデータサイズにしてください。", "xpack.ml.maxFileSizeSettingsName": "ファイルデータビジュアライザーの最大ファイルアップロードサイズ", @@ -10164,6 +11982,7 @@ "xpack.ml.models.jobService.deletingJob": "削除中", "xpack.ml.models.jobService.jobHasNoDatafeedErrorMessage": "ジョブにデータフィードがありません", "xpack.ml.models.jobService.requestToActionTimedOutErrorMessage": "「{id}」を{action}するリクエストがタイムアウトしました。{extra}", + "xpack.ml.models.jobService.revertModelSnapshot.autoCreatedCalendar.description": "自動作成されました", "xpack.ml.models.jobValidation.messages.bucketSpanEmptyMessage": "バケットスパンフィールドを指定する必要があります。", "xpack.ml.models.jobValidation.messages.bucketSpanEstimationMismatchHeading": "バケットスパン", "xpack.ml.models.jobValidation.messages.bucketSpanEstimationMismatchMessage": "現在のバケットスパンは {currentBucketSpan} ですが、バケットスパンの予測からは {estimateBucketSpan} が返されました。", @@ -10232,6 +12051,24 @@ "xpack.ml.models.jobValidation.validateJobObject.influencersAreNotArrayErrorMessage": "無効な {invalidParamName}:配列でなければなりません。", "xpack.ml.models.jobValidation.validateJobObject.jobIsNotObjectErrorMessage": "無効な {invalidParamName}:オブジェクトでなければなりません。", "xpack.ml.models.jobValidation.validateJobObject.timeFieldIsNotStringErrorMessage": "無効な {invalidParamName}:文字列でなければなりません。", + "xpack.ml.modelSnapshotTable.actions": "アクション", + "xpack.ml.modelSnapshotTable.actions.edit.description": "このスナップショットを編集", + "xpack.ml.modelSnapshotTable.actions.edit.name": "編集", + "xpack.ml.modelSnapshotTable.actions.revert.description": "このスナップショットに戻す", + "xpack.ml.modelSnapshotTable.actions.revert.name": "元に戻す", + "xpack.ml.modelSnapshotTable.closeJobConfirm.cancelButton": "キャンセル", + "xpack.ml.modelSnapshotTable.closeJobConfirm.close.button": "強制終了", + "xpack.ml.modelSnapshotTable.closeJobConfirm.close.title": "ジョブを閉じますか?", + "xpack.ml.modelSnapshotTable.closeJobConfirm.content": "スナップショットは、終了しているジョブでのみ元に戻すことができます。", + "xpack.ml.modelSnapshotTable.closeJobConfirm.contentOpen": "現在ジョブが開いています。", + "xpack.ml.modelSnapshotTable.closeJobConfirm.contentOpenAndRunning": "現在ジョブは開いていて実行中です。", + "xpack.ml.modelSnapshotTable.closeJobConfirm.stopAndClose.button": "強制停止して終了", + "xpack.ml.modelSnapshotTable.closeJobConfirm.stopAndClose.title": "データフィードを停止して、ジョブを終了しますか?", + "xpack.ml.modelSnapshotTable.description": "説明", + "xpack.ml.modelSnapshotTable.id": "ID", + "xpack.ml.modelSnapshotTable.latestTimestamp": "最新タイムスタンプ", + "xpack.ml.modelSnapshotTable.retain": "保存", + "xpack.ml.modelSnapshotTable.time": "日付が作成されました", "xpack.ml.navMenu.anomalyDetectionTabLinkText": "異常検知", "xpack.ml.navMenu.dataFrameAnalyticsTabLinkText": "分析", "xpack.ml.navMenu.dataVisualizerTabLinkText": "データビジュアライザー", @@ -10258,6 +12095,7 @@ "xpack.ml.newJob.recognize.jobLabelAllowedCharactersDescription": "ジョブラベルにはアルファベットの小文字 (a-z と 0-9)、ハイフンまたはアンダーラインが使用でき、最初と最後を英数字にする必要があります", "xpack.ml.newJob.recognize.jobPrefixInvalidMaxLengthErrorMessage": "ジョブ ID 接頭辞は {maxLength, plural, one {# 文字} other {# 文字}}以内でなければなりません。", "xpack.ml.newJob.recognize.jobsCreatedTitle": "ジョブが作成されました", + "xpack.ml.newJob.recognize.jobsCreationFailed.resetButtonAriaLabel": "リセット", "xpack.ml.newJob.recognize.jobSettingsTitle": "ジョブ設定", "xpack.ml.newJob.recognize.jobsTitle": "ジョブ", "xpack.ml.newJob.recognize.moduleCheckJobsExistWarningDescription": "モジュールのジョブがクラッシュしたか確認する際にエラーが発生しました。", @@ -10336,8 +12174,11 @@ "xpack.ml.newJob.wizard.jobDetailsStep.additionalSection.customUrlsSelection.description": "異常値からKibanaのダッシュボード、検出ページ、その他のWebページへのリンクを提供します。 {learnMoreLink}", "xpack.ml.newJob.wizard.jobDetailsStep.additionalSection.customUrlsSelection.learnMoreLinkText": "詳細", "xpack.ml.newJob.wizard.jobDetailsStep.additionalSectionButton": "追加設定", + "xpack.ml.newJob.wizard.jobDetailsStep.advancedSection.annotationsSwitchCallout.title": "この構成でモデルプロットを有効にする場合は、注釈も有効にすることをお勧めします。", "xpack.ml.newJob.wizard.jobDetailsStep.advancedSection.enableModelPlot.description": "モデルバウンドのプロットに使用される他のモデル情報を格納するには選択してください。これにより、システムのパフォーマンスにオーバーヘッドが追加されるため、基数の高いデータにはお勧めしません。", "xpack.ml.newJob.wizard.jobDetailsStep.advancedSection.enableModelPlot.title": "モデルプロットを有効にする", + "xpack.ml.newJob.wizard.jobDetailsStep.advancedSection.enableModelPlotAnnotations.description": "選択すると、モデルが大幅に変更されたときに注釈を生成します。たとえば、ステップが変更されると、期間や傾向が検出されます。", + "xpack.ml.newJob.wizard.jobDetailsStep.advancedSection.enableModelPlotAnnotations.title": "モデル変更注釈を有効にする", "xpack.ml.newJob.wizard.jobDetailsStep.advancedSection.mmlWarning.message": "モデルプロットの作成には大量のリソースを消費する可能性があり、選択されたフィールドの基数が100を超える場合はお勧めしません。このジョブの予測基数は{highCardinality}です。 この構成でモデルプロットを有効にする場合、専用の結果インデックスを選択することをお勧めします。", "xpack.ml.newJob.wizard.jobDetailsStep.advancedSection.mmlWarning.title": "十分ご注意ください!", "xpack.ml.newJob.wizard.jobDetailsStep.advancedSection.modelMemoryLimit.description": "分析モデルが使用するメモリー容量の上限を設定します。", @@ -10448,6 +12289,21 @@ "xpack.ml.newJob.wizard.pickFieldsStep.summaryCountField.title": "サマリーカウントフィールド", "xpack.ml.newJob.wizard.previewJsonButton": "JSON をプレビュー", "xpack.ml.newJob.wizard.previousStepButton": "前へ", + "xpack.ml.newJob.wizard.revertModelSnapshotFlyout.cancelButton": "キャンセル", + "xpack.ml.newJob.wizard.revertModelSnapshotFlyout.changeSnapshotLabel": "スナップショットの変更", + "xpack.ml.newJob.wizard.revertModelSnapshotFlyout.closeButton": "閉じる", + "xpack.ml.newJob.wizard.revertModelSnapshotFlyout.createCalendarSwitchHelp": "新しいカレンダーとイベントを作成し、データを分析するときに期間をスキップします。", + "xpack.ml.newJob.wizard.revertModelSnapshotFlyout.createCalendarSwitchLabel": "カレンダーを作成し、日付範囲を省略します。", + "xpack.ml.newJob.wizard.revertModelSnapshotFlyout.deleteButton": "適用", + "xpack.ml.newJob.wizard.revertModelSnapshotFlyout.deleteTitle": "スナップショットを元に戻す操作を適用", + "xpack.ml.newJob.wizard.revertModelSnapshotFlyout.realTimeSwitchHelp": "ジョブは、手動で停止されるまで実行し続けます。インデックスに追加されたすべての新しいデータが分析されます。", + "xpack.ml.newJob.wizard.revertModelSnapshotFlyout.realTimeSwitchLabel": "リアルタイムでジョブを実行", + "xpack.ml.newJob.wizard.revertModelSnapshotFlyout.replaySwitchHelp": "ジョブをもう一度開き、元に戻された後に分析を再現します。", + "xpack.ml.newJob.wizard.revertModelSnapshotFlyout.replaySwitchLabel": "分析の再現", + "xpack.ml.newJob.wizard.revertModelSnapshotFlyout.saveButton": "適用", + "xpack.ml.newJob.wizard.revertModelSnapshotFlyout.title": "モデルスナップショット{ssId}に戻す", + "xpack.ml.newJob.wizard.revertModelSnapshotFlyout.warningCallout.contents": "{date}後のすべての異常検知結果は削除されます。", + "xpack.ml.newJob.wizard.revertModelSnapshotFlyout.warningCallout.title": "異常値データが削除されます", "xpack.ml.newJob.wizard.searchSelection.notFoundLabel": "一致するインデックスまたは保存検索が見つかりませんでした。", "xpack.ml.newJob.wizard.searchSelection.savedObjectType.indexPattern": "インデックスパターン", "xpack.ml.newJob.wizard.searchSelection.savedObjectType.search": "保存検索", @@ -10508,6 +12364,7 @@ "xpack.ml.newJob.wizard.timeRangeStep.timeRangePicker.startDateLabel": "開始日", "xpack.ml.newJob.wizard.validateJob.bucketSpanMustBeSetErrorMessage": "バケットスパンを設定する必要があります", "xpack.ml.newJob.wizard.validateJob.duplicatedDetectorsErrorMessage": "重複する検知器が検出されました。", + "xpack.ml.newJob.wizard.validateJob.frequencyInvalidTimeIntervalFormatErrorMessage": "{value}は有効な期間の形式ではありません。例:{thirtySeconds}、{tenMinutes}、{oneHour}、{sevenDays}。また、0よりも大きい数字である必要があります。", "xpack.ml.newJob.wizard.validateJob.groupNameAlreadyExists": "グループ ID が既に存在します。グループ ID は既存のジョブやグループと同じにできません。", "xpack.ml.newJob.wizard.validateJob.jobGroupAllowedCharactersDescription": "ジョブグループ名にはアルファベットの小文字 (a-z と 0-9)、ハイフンまたはアンダーラインが使用でき、最初と最後を英数字にする必要があります", "xpack.ml.newJob.wizard.validateJob.jobGroupMaxLengthDescription": "ジョブグループ名は {maxLength, plural, one {# 文字} other {# 文字}} 以内でなければなりません。", @@ -10520,7 +12377,7 @@ "xpack.ml.newJob.wizard.validateJob.queryIsInvalidEsQuery": "データフィードクエリは有効な Elasticsearch クエリでなければなりません。", "xpack.ml.overview.analyticsList.createFirstJobMessage": "最初のデータフレーム分析ジョブを作成", "xpack.ml.overview.analyticsList.createJobButtonText": "ジョブを作成", - "xpack.ml.overview.analyticsList.emptyPromptText": "データフレーム分析は、様々なデータ分析を行い結果と共に注釈に追加することができます。ジョブは注釈付きデータと共に、ソースデータのコピーを新規インデックスに保存します。", + "xpack.ml.overview.analyticsList.emptyPromptText": "データフレーム分析では、データに対して異常値検出、回帰、分類分析を実行し、結果に注釈を付けることができます。ジョブは注釈付きデータと共に、ソースデータのコピーを新規インデックスに保存します。", "xpack.ml.overview.analyticsList.errorPromptTitle": "データフレーム分析リストの取得中にエラーが発生しました。", "xpack.ml.overview.analyticsList.id": "ID", "xpack.ml.overview.analyticsList.manageJobsButtonText": "ジョブの管理", @@ -10576,6 +12433,13 @@ "xpack.ml.privilege.noPermission.runForecastsTooltip": "予測を実行するパーミッションがありません。", "xpack.ml.privilege.noPermission.startOrStopDatafeedsTooltip": "データフィードを開始・停止するパーミッションがありません。", "xpack.ml.privilege.pleaseContactAdministratorTooltip": "{message} 管理者にお問い合わせください。", + "xpack.ml.revertModelSnapshotFlyout.createCalendar.defaultEventDescription": "自動作成されたイベント{index}", + "xpack.ml.revertModelSnapshotFlyout.createCalendar.deleteLabel": "イベントの削除", + "xpack.ml.revertModelSnapshotFlyout.createCalendar.descriptionLabel": "説明", + "xpack.ml.revertModelSnapshotFlyout.createCalendar.fromLabel": "開始:", + "xpack.ml.revertModelSnapshotFlyout.createCalendar.title": "カレンダーイベントの時間範囲を選択します。", + "xpack.ml.revertModelSnapshotFlyout.createCalendar.toLabel": "終了:", + "xpack.ml.revertModelSnapshotFlyout.revertErrorTitle": "モデルスナップショットを元に戻せませんでした", "xpack.ml.routes.annotations.annotationsFeatureUnavailableErrorMessage": "注釈機能に必要なインデックスとエイリアスが作成されていないか、現在のユーザーがアクセスできません。", "xpack.ml.ruleEditor.actionsSection.chooseActionsDescription": "ルールが異常と一致した際のアクションを選択します。", "xpack.ml.ruleEditor.actionsSection.resultWillNotBeCreatedTooltip": "結果は作成されません。", @@ -10656,6 +12520,19 @@ "xpack.ml.ruleEditor.selectRuleAction.orText": "OR ", "xpack.ml.ruleEditor.typicalAppliesTypeText": "通常", "xpack.ml.sampleDataLinkLabel": "ML ジョブ", + "xpack.ml.settings.anomalyDetection.anomalyDetectionTitle": "異常検知", + "xpack.ml.settings.anomalyDetection.calendarsSummaryCount": "{calendarsCountBadge} {calendarsCount, plural, one {個のカレンダー} other {個のカレンダー}}があります", + "xpack.ml.settings.anomalyDetection.calendarsText": "システム停止日や祝日など、異常値を生成したくないイベントについては、カレンダーに予定されているイベントのリストを登録できます。", + "xpack.ml.settings.anomalyDetection.calendarsTitle": "カレンダー", + "xpack.ml.settings.anomalyDetection.createCalendarLink": "作成", + "xpack.ml.settings.anomalyDetection.createFilterListsLink": "作成", + "xpack.ml.settings.anomalyDetection.filterListsSummaryCount": "{filterListsCountBadge} {filterListsCount, plural, one {個のフィルターリスト} other {個のフィルターリスト}}があります", + "xpack.ml.settings.anomalyDetection.filterListsText": " フィルターリストには、イベントを機械学習分析に含める、または除外するのに使用する値が含まれています。", + "xpack.ml.settings.anomalyDetection.filterListsTitle": "フィルターリスト", + "xpack.ml.settings.anomalyDetection.loadingCalendarsCountErrorMessage": "カレンダー数の取得中にエラーが発生しました", + "xpack.ml.settings.anomalyDetection.loadingFilterListCountErrorMessage": "フィルターリスト数の取得中にエラーが発生しました", + "xpack.ml.settings.anomalyDetection.manageCalendarsLink": "管理", + "xpack.ml.settings.anomalyDetection.manageFilterListsLink": "管理", "xpack.ml.settings.breadcrumbs.calendarManagement.createLabel": "作成", "xpack.ml.settings.breadcrumbs.calendarManagement.editLabel": "編集", "xpack.ml.settings.breadcrumbs.calendarManagementLabel": "カレンダー管理", @@ -10711,21 +12588,24 @@ "xpack.ml.settings.filterLists.table.noFiltersCreatedTitle": "フィルターが 1 つも作成されていません", "xpack.ml.settings.filterLists.table.notInUseAriaLabel": "使用されていません", "xpack.ml.settings.filterLists.toolbar.deleteItemButtonLabel": "アイテムを削除", + "xpack.ml.settings.title": "設定", "xpack.ml.settingsBreadcrumbLabel": "設定", "xpack.ml.singleMetricViewerPageLabel": "シングルメトリックビューアー", "xpack.ml.stepDefineForm.invalidQuery": "無効なクエリ", "xpack.ml.stepDefineForm.queryPlaceholderKql": "例: {example}", "xpack.ml.stepDefineForm.queryPlaceholderLucene": "例: {example}", "xpack.ml.swimlaneEmbeddable.errorMessage": "MLスイムレーンデータを読み込めません", + "xpack.ml.swimlaneEmbeddable.noDataFound": "異常値が見つかりませんでした", "xpack.ml.swimlaneEmbeddable.panelTitleLabel": "パネルタイトル", "xpack.ml.swimlaneEmbeddable.setupModal.cancelButtonLabel": "キャンセル", "xpack.ml.swimlaneEmbeddable.setupModal.confirmButtonLabel": "確認", - "xpack.ml.swimlaneEmbeddable.setupModal.swimlaneTypeLabel": "スイムレーンタイプ", + "xpack.ml.swimlaneEmbeddable.setupModal.swimlaneTypeLabel": "スイムレーンの種類", "xpack.ml.swimlaneEmbeddable.setupModal.title": "異常スイムレーン構成", "xpack.ml.swimlaneEmbeddable.title": "{jobIds}のML異常スイムレーン", "xpack.ml.timeSeriesExplorer.allPartitionValuesLabel": "すべて", "xpack.ml.timeSeriesExplorer.annotationDescriptionList.createdByTitle": "作成者", "xpack.ml.timeSeriesExplorer.annotationDescriptionList.createdTitle": "作成済み", + "xpack.ml.timeSeriesExplorer.annotationDescriptionList.detectorTitle": "検知器", "xpack.ml.timeSeriesExplorer.annotationDescriptionList.endTitle": "終了", "xpack.ml.timeSeriesExplorer.annotationDescriptionList.jobIdTitle": "ジョブ ID", "xpack.ml.timeSeriesExplorer.annotationDescriptionList.lastModifiedTitle": "最終更新:", @@ -10742,6 +12622,7 @@ "xpack.ml.timeSeriesExplorer.annotationFlyout.noAnnotationTextError": "注釈テキストを入力してください", "xpack.ml.timeSeriesExplorer.annotationFlyout.updateButtonLabel": "更新", "xpack.ml.timeSeriesExplorer.annotationsLabel": "注釈", + "xpack.ml.timeSeriesExplorer.annotationsTitle": "注釈{badge}", "xpack.ml.timeSeriesExplorer.anomaliesTitle": "異常", "xpack.ml.timeSeriesExplorer.autoSelectingFirstJobText": "、初めのジョブを自動選択します", "xpack.ml.timeSeriesExplorer.canNotViewRequestedJobsWarningMessage": "リクエストされた‘{invalidIdsCount, plural, one {ジョブ} other {件のジョブ}} {invalidIds} をこのダッシュボードで表示できません", @@ -10847,9 +12728,167 @@ "xpack.monitoring.ajaxErrorHandler.requestErrorNotificationTitle": "監視リクエストエラー", "xpack.monitoring.ajaxErrorHandler.requestFailedNotification.retryButtonLabel": "再試行", "xpack.monitoring.ajaxErrorHandler.requestFailedNotificationTitle": "監視リクエスト失敗", + "xpack.monitoring.alerts.actionGroups.default": "デフォルト", + "xpack.monitoring.alerts.badge.panelTitle": "アラート", + "xpack.monitoring.alerts.callout.dangerLabel": "危険アラート", + "xpack.monitoring.alerts.callout.warningLabel": "警告アラート", + "xpack.monitoring.alerts.clusterHealth.action.danger": "見つからないプライマリおよびレプリカシャードを割り当てます。", + "xpack.monitoring.alerts.clusterHealth.action.warning": "見つからないレプリカシャードを割り当てます。", + "xpack.monitoring.alerts.clusterHealth.actionVariables.action": "このアラートに対する推奨されるアクション。", + "xpack.monitoring.alerts.clusterHealth.actionVariables.actionPlain": "このアラートに推奨されるアクション(Markdownなし)。", + "xpack.monitoring.alerts.clusterHealth.actionVariables.clusterHealth": "クラスターの正常性。", + "xpack.monitoring.alerts.clusterHealth.actionVariables.clusterName": "ノードが属しているクラスター。", + "xpack.monitoring.alerts.clusterHealth.actionVariables.internalFullMessage": "詳細な内部メッセージはElasticで生成されました。", + "xpack.monitoring.alerts.clusterHealth.actionVariables.internalShortMessage": "内部メッセージ(省略あり)はElasticで生成されました。", + "xpack.monitoring.alerts.clusterHealth.actionVariables.state": "現在のアラートの状態。", + "xpack.monitoring.alerts.clusterHealth.firing": "実行中", + "xpack.monitoring.alerts.clusterHealth.firing.internalFullMessage": "クラスター正常性アラートが{clusterName}に対して作動しています。現在の正常性は{health}です。{action}", + "xpack.monitoring.alerts.clusterHealth.firing.internalShortMessage": "クラスター正常性アラートが{clusterName}に対して作動しています。現在の正常性は{health}です。{actionText}", + "xpack.monitoring.alerts.clusterHealth.label": "クラスターの正常性", + "xpack.monitoring.alerts.clusterHealth.redMessage": "見つからないプライマリおよびレプリカシャードを割り当て", + "xpack.monitoring.alerts.clusterHealth.resolved": "解決済み", + "xpack.monitoring.alerts.clusterHealth.resolved.internalFullMessage": "クラスター正常性アラートが{clusterName}に対して作動しています。", + "xpack.monitoring.alerts.clusterHealth.resolved.internalShortMessage": "クラスター正常性アラートが{clusterName}に対して作動しています。", + "xpack.monitoring.alerts.clusterHealth.ui.firingMessage": "Elasticsearchクラスターの正常性は{health}です。", + "xpack.monitoring.alerts.clusterHealth.ui.nextSteps.message1": "{message}. #start_linkView now#end_link", + "xpack.monitoring.alerts.clusterHealth.yellowMessage": "見つからないレプリカシャードを割り当て", + "xpack.monitoring.alerts.cpuUsage.actionVariables.action": "このアラートに対する推奨されるアクション。", + "xpack.monitoring.alerts.cpuUsage.actionVariables.actionPlain": "このアラートに推奨されるアクション(Markdownなし)。", + "xpack.monitoring.alerts.cpuUsage.actionVariables.clusterName": "ノードが属しているクラスター。", + "xpack.monitoring.alerts.cpuUsage.actionVariables.count": "高CPU使用率を報告しているノード数。", + "xpack.monitoring.alerts.cpuUsage.actionVariables.internalFullMessage": "詳細な内部メッセージはElasticで生成されました。", + "xpack.monitoring.alerts.cpuUsage.actionVariables.internalShortMessage": "内部メッセージ(省略あり)はElasticで生成されました。", + "xpack.monitoring.alerts.cpuUsage.actionVariables.nodes": "高CPU使用率を報告しているノードのリスト。", + "xpack.monitoring.alerts.cpuUsage.actionVariables.state": "現在のアラートの状態。", + "xpack.monitoring.alerts.cpuUsage.firing": "実行中", + "xpack.monitoring.alerts.cpuUsage.firing.internalFullMessage": "CPU使用状況アラートはCPU使用状況アラートは、クラスター{clusterName}の{count}個のノードで実行されています。{action}", + "xpack.monitoring.alerts.cpuUsage.firing.internalShortMessage": "CPU使用状況アラートは、クラスター{clusterName}の{count}個のノードで実行されています。{shortActionText}", + "xpack.monitoring.alerts.cpuUsage.fullAction": "ノードの表示", + "xpack.monitoring.alerts.cpuUsage.label": "CPU使用状況", + "xpack.monitoring.alerts.cpuUsage.paramDetails.duration.label": "平均を確認", + "xpack.monitoring.alerts.cpuUsage.paramDetails.threshold.label": "CPUが終了したときに通知", + "xpack.monitoring.alerts.cpuUsage.resolved": "解決済み", + "xpack.monitoring.alerts.cpuUsage.resolved.internalFullMessage": "CPU使用状況アラートは、クラスター{clusterName}の{count}個のノードで解決されました。", + "xpack.monitoring.alerts.cpuUsage.resolved.internalShortMessage": "CPU使用状況アラートは、クラスター{clusterName}の{count}個のノードで解決されました。", + "xpack.monitoring.alerts.cpuUsage.shortAction": "影響を受けるノード全体のCPUレベルを検証します。", + "xpack.monitoring.alerts.cpuUsage.ui.firingMessage": "ノード#start_link{nodeName}#end_linkは、#absoluteでCPU使用率{cpuUsage}%を報告しています", + "xpack.monitoring.alerts.cpuUsage.ui.nextSteps.hotThreads": "#start_linkCheck hot threads#end_link", + "xpack.monitoring.alerts.cpuUsage.ui.nextSteps.runningTasks": "#start_linkCheck long running tasks#end_link", + "xpack.monitoring.alerts.cpuUsage.ui.resolvedMessage": "ノード{nodeName}でのCPU使用状況は現在しきい値を下回っています。現在、#resolved時点で、{cpuUsage}%と報告されています。", + "xpack.monitoring.alerts.cpuUsage.validation.duration": "有効な期間が必要です。", + "xpack.monitoring.alerts.cpuUsage.validation.threshold": "有効な数字が必要です。", + "xpack.monitoring.alerts.elasticsearchVersionMismatch.actionVariables.action": "このアラートに対する推奨されるアクション。", + "xpack.monitoring.alerts.elasticsearchVersionMismatch.actionVariables.actionPlain": "このアラートに推奨されるアクション(Markdownなし)。", + "xpack.monitoring.alerts.elasticsearchVersionMismatch.actionVariables.clusterHealth": "このクラスターを実行しているElasticsearchのバージョン。", + "xpack.monitoring.alerts.elasticsearchVersionMismatch.actionVariables.clusterName": "ノードが属しているクラスター。", + "xpack.monitoring.alerts.elasticsearchVersionMismatch.actionVariables.internalFullMessage": "詳細な内部メッセージはElasticで生成されました。", + "xpack.monitoring.alerts.elasticsearchVersionMismatch.actionVariables.internalShortMessage": "内部メッセージ(省略あり)はElasticで生成されました。", + "xpack.monitoring.alerts.elasticsearchVersionMismatch.actionVariables.state": "現在のアラートの状態。", + "xpack.monitoring.alerts.elasticsearchVersionMismatch.firing": "実行中", + "xpack.monitoring.alerts.elasticsearchVersionMismatch.firing.internalFullMessage": "{clusterName}に対してElasticsearchバージョン不一致アラートが実行されています。Elasticsearchは{versions}を実行しています。{action}", + "xpack.monitoring.alerts.elasticsearchVersionMismatch.firing.internalShortMessage": "{clusterName}に対してElasticsearchバージョン不一致アラートが実行されています。{shortActionText}", + "xpack.monitoring.alerts.elasticsearchVersionMismatch.fullAction": "ノードの表示", + "xpack.monitoring.alerts.elasticsearchVersionMismatch.label": "Elasticsearchバージョン不一致", + "xpack.monitoring.alerts.elasticsearchVersionMismatch.resolved": "解決済み", + "xpack.monitoring.alerts.elasticsearchVersionMismatch.resolved.internalFullMessage": "{clusterName}のElasticsearchバージョン不一致アラートが解決されました。", + "xpack.monitoring.alerts.elasticsearchVersionMismatch.resolved.internalShortMessage": "{clusterName}のElasticsearchバージョン不一致アラートが解決されました。", + "xpack.monitoring.alerts.elasticsearchVersionMismatch.shortAction": "すべてのノードのバージョンが同じことを確認してください。", + "xpack.monitoring.alerts.elasticsearchVersionMismatch.ui.firingMessage": "このクラスターでは、複数のバージョンのElasticsearch({versions})が実行されています。", + "xpack.monitoring.alerts.elasticsearchVersionMismatch.ui.resolvedMessage": "このクラスターではすべてのElasticsearchのバージョンが同じです。", + "xpack.monitoring.alerts.flyoutExpressions.timeUnits.dayLabel": "{timeValue, plural, one {日} other {日}}", + "xpack.monitoring.alerts.flyoutExpressions.timeUnits.hourLabel": "{timeValue, plural, one {時間} other {時間}}", + "xpack.monitoring.alerts.flyoutExpressions.timeUnits.minuteLabel": "{timeValue, plural, one {分} other {分}}", + "xpack.monitoring.alerts.flyoutExpressions.timeUnits.secondLabel": "{timeValue, plural, one {秒} other {秒}}", + "xpack.monitoring.alerts.kibanaVersionMismatch.actionVariables.action": "このアラートに対する推奨されるアクション。", + "xpack.monitoring.alerts.kibanaVersionMismatch.actionVariables.actionPlain": "このアラートに推奨されるアクション(Markdownなし)。", + "xpack.monitoring.alerts.kibanaVersionMismatch.actionVariables.clusterHealth": "このクラスターを実行しているKibanaのバージョン。", + "xpack.monitoring.alerts.kibanaVersionMismatch.actionVariables.clusterName": "インスタンスが属しているクラスター。", + "xpack.monitoring.alerts.kibanaVersionMismatch.actionVariables.internalFullMessage": "詳細な内部メッセージはElasticで生成されました。", + "xpack.monitoring.alerts.kibanaVersionMismatch.actionVariables.internalShortMessage": "内部メッセージ(省略あり)はElasticで生成されました。", + "xpack.monitoring.alerts.kibanaVersionMismatch.actionVariables.state": "現在のアラートの状態。", + "xpack.monitoring.alerts.kibanaVersionMismatch.firing": "実行中", + "xpack.monitoring.alerts.kibanaVersionMismatch.firing.internalFullMessage": "{clusterName}に対してKibanaバージョン不一致アラートが実行されています。Kibanaは{versions}を実行しています。{action}", + "xpack.monitoring.alerts.kibanaVersionMismatch.firing.internalShortMessage": "{clusterName}に対してKibanaバージョン不一致アラートが実行されています。{shortActionText}", + "xpack.monitoring.alerts.kibanaVersionMismatch.fullAction": "インスタンスを表示", + "xpack.monitoring.alerts.kibanaVersionMismatch.label": "Kibanaバージョン不一致", + "xpack.monitoring.alerts.kibanaVersionMismatch.resolved": "解決済み", + "xpack.monitoring.alerts.kibanaVersionMismatch.resolved.internalFullMessage": "{clusterName}のKibanaバージョン不一致アラートが解決されました。", + "xpack.monitoring.alerts.kibanaVersionMismatch.resolved.internalShortMessage": "{clusterName}のKibanaバージョン不一致アラートが解決されました。", + "xpack.monitoring.alerts.kibanaVersionMismatch.shortAction": "すべてのインスタンスのバージョンが同じことを確認してください。", + "xpack.monitoring.alerts.kibanaVersionMismatch.ui.firingMessage": "このクラスターでは、複数のバージョンのKibana({versions})が実行されています。", + "xpack.monitoring.alerts.kibanaVersionMismatch.ui.resolvedMessage": "このクラスターではすべてのKibanaのバージョンが同じです。", + "xpack.monitoring.alerts.legacyAlert.expressionText": "構成するものがありません。", + "xpack.monitoring.alerts.licenseExpiration.action": "ライセンスを更新してください。", + "xpack.monitoring.alerts.licenseExpiration.actionVariables.action": "このアラートに対する推奨されるアクション。", + "xpack.monitoring.alerts.licenseExpiration.actionVariables.actionPlain": "このアラートに推奨されるアクション(Markdownなし)。", + "xpack.monitoring.alerts.licenseExpiration.actionVariables.clusterName": "ライセンスが属しているクラスター。", + "xpack.monitoring.alerts.licenseExpiration.actionVariables.expiredDate": "ライセンスの有効期限。", + "xpack.monitoring.alerts.licenseExpiration.actionVariables.internalFullMessage": "詳細な内部メッセージはElasticで生成されました。", + "xpack.monitoring.alerts.licenseExpiration.actionVariables.internalShortMessage": "内部メッセージ(省略あり)はElasticで生成されました。", + "xpack.monitoring.alerts.licenseExpiration.actionVariables.state": "現在のアラートの状態。", + "xpack.monitoring.alerts.licenseExpiration.firing": "実行中", + "xpack.monitoring.alerts.licenseExpiration.firing.internalFullMessage": "ライセンス有効期限アラートが{clusterName}に対して実行されています。ライセンスは{expiredDate}に期限切れになります。{action}", + "xpack.monitoring.alerts.licenseExpiration.firing.internalShortMessage": "{clusterName}に対してライセンス有効期限アラートが実行されています。ライセンスは{expiredDate}に期限切れになります。{actionText}", + "xpack.monitoring.alerts.licenseExpiration.label": "ライセンス期限", + "xpack.monitoring.alerts.licenseExpiration.resolved": "解決済み", + "xpack.monitoring.alerts.licenseExpiration.resolved.internalFullMessage": "{clusterName}のライセンス有効期限アラートが解決されました。", + "xpack.monitoring.alerts.licenseExpiration.resolved.internalShortMessage": "{clusterName}のライセンス有効期限アラートが解決されました。", "xpack.monitoring.alerts.licenseExpiration.ui.firingMessage": "このクラスターのライセンスは#absoluteの#relativeに期限切れになります。#start_linkライセンスを更新してください。#end_link", - "xpack.monitoring.alerts.licenseExpiration.ui.resolvedMessage": "このクラスターのライセンスはアクティブです。", + "xpack.monitoring.alerts.licenseExpiration.ui.resolvedMessage": "このクラスターのライセンスは有効です。", + "xpack.monitoring.alerts.logstashVersionMismatch.actionVariables.action": "このアラートに対する推奨されるアクション。", + "xpack.monitoring.alerts.logstashVersionMismatch.actionVariables.actionPlain": "このアラートに推奨されるアクション(Markdownなし)。", + "xpack.monitoring.alerts.logstashVersionMismatch.actionVariables.clusterHealth": "このクラスターを実行しているLogstashのバージョン。", + "xpack.monitoring.alerts.logstashVersionMismatch.actionVariables.clusterName": "ノードが属しているクラスター。", + "xpack.monitoring.alerts.logstashVersionMismatch.actionVariables.internalFullMessage": "詳細な内部メッセージはElasticで生成されました。", + "xpack.monitoring.alerts.logstashVersionMismatch.actionVariables.internalShortMessage": "内部メッセージ(省略あり)はElasticで生成されました。", + "xpack.monitoring.alerts.logstashVersionMismatch.actionVariables.state": "現在のアラートの状態。", + "xpack.monitoring.alerts.logstashVersionMismatch.firing": "実行中", + "xpack.monitoring.alerts.logstashVersionMismatch.firing.internalFullMessage": "{clusterName}に対してLogstashバージョン不一致アラートが実行されています。Logstashは{versions}を実行しています。{action}", + "xpack.monitoring.alerts.logstashVersionMismatch.firing.internalShortMessage": "{clusterName}に対してLogstashバージョン不一致アラートが実行されています。{shortActionText}", + "xpack.monitoring.alerts.logstashVersionMismatch.fullAction": "ノードの表示", + "xpack.monitoring.alerts.logstashVersionMismatch.label": "Logstashバージョン不一致", + "xpack.monitoring.alerts.logstashVersionMismatch.resolved": "解決済み", + "xpack.monitoring.alerts.logstashVersionMismatch.resolved.internalFullMessage": "{clusterName}のLogstashバージョン不一致アラートが解決されました。", + "xpack.monitoring.alerts.logstashVersionMismatch.resolved.internalShortMessage": "{clusterName}のLogstashバージョン不一致アラートが解決されました。", + "xpack.monitoring.alerts.logstashVersionMismatch.shortAction": "すべてのノードのバージョンが同じことを確認してください。", + "xpack.monitoring.alerts.logstashVersionMismatch.ui.firingMessage": "このクラスターでは、複数のバージョンのLogstash({versions})が実行されています。", + "xpack.monitoring.alerts.logstashVersionMismatch.ui.resolvedMessage": "このクラスターではすべてのLogstashのバージョンが同じです。", "xpack.monitoring.alerts.migrate.manageAction.requiredFieldError": "{field} は必須フィールドです。", + "xpack.monitoring.alerts.nodesChanged.actionVariables.action": "このアラートに対する推奨されるアクション。", + "xpack.monitoring.alerts.nodesChanged.actionVariables.actionPlain": "このアラートに推奨されるアクション(Markdownなし)。", + "xpack.monitoring.alerts.nodesChanged.actionVariables.added": "ノードのリストがクラスターに追加されました。", + "xpack.monitoring.alerts.nodesChanged.actionVariables.clusterName": "ノードが属しているクラスター。", + "xpack.monitoring.alerts.nodesChanged.actionVariables.internalFullMessage": "詳細な内部メッセージはElasticで生成されました。", + "xpack.monitoring.alerts.nodesChanged.actionVariables.internalShortMessage": "内部メッセージ(省略あり)はElasticで生成されました。", + "xpack.monitoring.alerts.nodesChanged.actionVariables.removed": "ノードのリストがクラスターから削除されました。", + "xpack.monitoring.alerts.nodesChanged.actionVariables.restarted": "ノードのリストがクラスターで再起動しました。", + "xpack.monitoring.alerts.nodesChanged.actionVariables.state": "現在のアラートの状態。", + "xpack.monitoring.alerts.nodesChanged.firing": "実行中", + "xpack.monitoring.alerts.nodesChanged.firing.internalFullMessage": "{clusterName}に対してノード変更アラートが実行されています。次のElasticsearchノードが追加されました:{added}、削除:{removed}、再起動:{restarted}。{action}", + "xpack.monitoring.alerts.nodesChanged.firing.internalShortMessage": "{clusterName}に対してノード変更アラートが実行されています。{shortActionText}", + "xpack.monitoring.alerts.nodesChanged.fullAction": "ノードの表示", + "xpack.monitoring.alerts.nodesChanged.label": "ノードが変更されました", + "xpack.monitoring.alerts.nodesChanged.resolved": "解決済み", + "xpack.monitoring.alerts.nodesChanged.resolved.internalFullMessage": "{clusterName}のElasticsearchノード変更アラートが解決されました。", + "xpack.monitoring.alerts.nodesChanged.resolved.internalShortMessage": "{clusterName}のElasticsearchノード変更アラートが解決されました。", + "xpack.monitoring.alerts.nodesChanged.shortAction": "ノードを追加、削除、または再起動したことを確認してください。", + "xpack.monitoring.alerts.nodesChanged.ui.addedFiringMessage": "Elasticsearchノード「{added}」がこのクラスターに追加されました。", + "xpack.monitoring.alerts.nodesChanged.ui.removedFiringMessage": "Elasticsearchノード「{removed}」がこのクラスターから削除されました。", + "xpack.monitoring.alerts.nodesChanged.ui.resolvedMessage": "このクラスターのElasticsearchノードは変更されていません。", + "xpack.monitoring.alerts.nodesChanged.ui.restartedFiringMessage": "このクラスターでElasticsearchノード「{restarted}」が再起動しました。", + "xpack.monitoring.alerts.panel.disableAlert.errorTitle": "アラートを無効にできません", + "xpack.monitoring.alerts.panel.disableTitle": "無効にする", + "xpack.monitoring.alerts.panel.editAlert": "アラートを編集", + "xpack.monitoring.alerts.panel.enableAlert.errorTitle": "アラートを有効にできません", + "xpack.monitoring.alerts.panel.muteAlert.errorTitle": "アラートをミュートできません", + "xpack.monitoring.alerts.panel.muteTitle": "ミュート", + "xpack.monitoring.alerts.panel.ummuteAlert.errorTitle": "アラートをミュート解除できません", + "xpack.monitoring.alerts.status.alertsTooltip": "アラート", + "xpack.monitoring.alerts.status.clearText": "クリア", + "xpack.monitoring.alerts.status.clearToolip": "アラートは実行されていません", + "xpack.monitoring.alerts.status.highSeverityTooltip": "すぐに対処が必要な致命的な問題があります!", + "xpack.monitoring.alerts.status.lowSeverityTooltip": "低重要度の問題があります", + "xpack.monitoring.alerts.status.mediumSeverityTooltip": "スタックに影響を及ぼす可能性がある問題があります。", "xpack.monitoring.apm.healthStatusLabel": "ヘルス: {status}", "xpack.monitoring.apm.instance.routeTitle": "{apm} - インスタンス", "xpack.monitoring.apm.instance.status.lastEventDescription": "{timeOfLastEvent} 前", @@ -10985,12 +13024,15 @@ "xpack.monitoring.cluster.overview.esPanel.diskUsageLabel": "ディスク使用量", "xpack.monitoring.cluster.overview.esPanel.documentsLabel": "ドキュメント", "xpack.monitoring.cluster.overview.esPanel.errorLogsTooltipText": "エラーログの数です", + "xpack.monitoring.cluster.overview.esPanel.expireDateText": "有効期限:{expiryDate}", "xpack.monitoring.cluster.overview.esPanel.fatalLogsTooltipText": "致命的ログの数です", + "xpack.monitoring.cluster.overview.esPanel.healthLabel": "ヘルス", "xpack.monitoring.cluster.overview.esPanel.indicesCountLinkAriaLabel": "Elasticsearch インデックス: {indicesCount}", "xpack.monitoring.cluster.overview.esPanel.indicesCountLinkLabel": "インデックス: {indicesCount}", "xpack.monitoring.cluster.overview.esPanel.infoLogsTooltipText": "情報ログの数です", "xpack.monitoring.cluster.overview.esPanel.jobsLabel": "ジョブ", "xpack.monitoring.cluster.overview.esPanel.jvmHeapLabel": "{javaVirtualMachine} ヒープ", + "xpack.monitoring.cluster.overview.esPanel.licenseLabel": "ライセンス", "xpack.monitoring.cluster.overview.esPanel.logsLinkAriaLabel": "Elasticsearch ログ", "xpack.monitoring.cluster.overview.esPanel.logsLinkLabel": "ログ", "xpack.monitoring.cluster.overview.esPanel.nodesTotalLinkLabel": "ノード: {nodesTotal}", @@ -11120,11 +13162,13 @@ "xpack.monitoring.elasticsearch.nodeDetailStatus.shardsLabel": "シャード", "xpack.monitoring.elasticsearch.nodeDetailStatus.transportAddress": "トランスポートアドレス", "xpack.monitoring.elasticsearch.nodeDetailStatus.typeLabel": "タイプ", + "xpack.monitoring.elasticsearch.nodes.alertsColumnTitle": "アラート", "xpack.monitoring.elasticsearch.nodes.cells.maxText": "最高 {metric}", "xpack.monitoring.elasticsearch.nodes.cells.minText": "最低 {metric}", "xpack.monitoring.elasticsearch.nodes.cpuThrottlingColumnTitle": "CPU スロットル", "xpack.monitoring.elasticsearch.nodes.cpuUsageColumnTitle": "CPU 使用状況", "xpack.monitoring.elasticsearch.nodes.diskFreeSpaceColumnTitle": "ディスクの空き容量", + "xpack.monitoring.elasticsearch.nodes.healthAltIcon": "ステータス: {status}", "xpack.monitoring.elasticsearch.nodes.jvmMemoryColumnTitle": "{javaVirtualMachine}ヒープ", "xpack.monitoring.elasticsearch.nodes.loadAverageColumnTitle": "平均負荷", "xpack.monitoring.elasticsearch.nodes.metricbeatMigration.detectedNodeDescription": "次のインデックスは監視されていません。下の「Metricbeat で監視」をクリックして、監視を開始してください。", @@ -11226,6 +13270,7 @@ "xpack.monitoring.kibana.detailStatus.versionLabel": "バージョン", "xpack.monitoring.kibana.instances.metricbeatMigration.detectedNodeDescription": "次のインスタンスは監視されていません。\n 下の「Metricbeat で監視」をクリックして、監視を開始してください。", "xpack.monitoring.kibana.instances.metricbeatMigration.detectedNodeTitle": "Kibana インスタンスが検出されました", + "xpack.monitoring.kibana.listing.alertsColumnTitle": "アラート", "xpack.monitoring.kibana.listing.filterInstancesPlaceholder": "フィルターインスタンス…", "xpack.monitoring.kibana.listing.loadAverageColumnTitle": "平均負荷", "xpack.monitoring.kibana.listing.memorySizeColumnTitle": "メモリーサイズ", @@ -11304,6 +13349,7 @@ "xpack.monitoring.logstash.node.pipelines.notAvailableDescription": "パイプラインの監視は Logstash バージョン 6.0.0 以降でのみ利用できます。このノードはバージョン {logstashVersion} を実行しています。", "xpack.monitoring.logstash.node.pipelines.routeTitle": "Logstash - {nodeName} - パイプライン", "xpack.monitoring.logstash.node.routeTitle": "Logstash - {nodeName}", + "xpack.monitoring.logstash.nodes.alertsColumnTitle": "アラート", "xpack.monitoring.logstash.nodes.configReloadsFailuresCountLabel": "{reloadsFailures} 失敗", "xpack.monitoring.logstash.nodes.configReloadsSuccessCountLabel": "{reloadsSuccesses} 成功", "xpack.monitoring.logstash.nodes.configReloadsTitle": "構成の再読み込み", @@ -11426,6 +13472,36 @@ "xpack.monitoring.metricbeatMigration.partiallyMigratedStatusTitle": "まだ自己監視からのデータが届いています", "xpack.monitoring.metricbeatMigration.securitySetup": "セキュリティが有効の場合、{link} が必要な可能性があります。", "xpack.monitoring.metricbeatMigration.securitySetupLinkText": "追加設定", + "xpack.monitoring.metrics.apm.acmRequest.countTitle": "要求エージェント構成管理", + "xpack.monitoring.metrics.apm.acmRequest.countTitleDescription": "エージェント構成管理で受信したHTTP要求", + "xpack.monitoring.metrics.apm.acmRequest.countTitleLabel": "カウント", + "xpack.monitoring.metrics.apm.acmResponse.countDescription": "APMサーバーにより応答されたHTTP要求です", + "xpack.monitoring.metrics.apm.acmResponse.countLabel": "カウント", + "xpack.monitoring.metrics.apm.acmResponse.countTitle": "応答数エージェント構成管理", + "xpack.monitoring.metrics.apm.acmResponse.errorCountDescription": "HTTPエラー数", + "xpack.monitoring.metrics.apm.acmResponse.errorCountLabel": "エラー数", + "xpack.monitoring.metrics.apm.acmResponse.errorCountTitle": "応答エラー数エージェント構成管理", + "xpack.monitoring.metrics.apm.acmResponse.errors.forbiddenDescription": "禁止されたHTTP要求拒否数", + "xpack.monitoring.metrics.apm.acmResponse.errors.forbiddenLabel": "カウント", + "xpack.monitoring.metrics.apm.acmResponse.errors.forbiddenTitle": "応答エラーエージェント構成管理", + "xpack.monitoring.metrics.apm.acmResponse.errors.invalidqueryDescription": "無効なHTTPクエリ", + "xpack.monitoring.metrics.apm.acmResponse.errors.invalidqueryLabel": "無効なクエリ", + "xpack.monitoring.metrics.apm.acmResponse.errors.invalidqueryTitle": "応答無効クエリエラーエージェント構成管理", + "xpack.monitoring.metrics.apm.acmResponse.errors.methodDescription": "HTTPメソッドが正しくないため、HTTPリクエストが拒否されました", + "xpack.monitoring.metrics.apm.acmResponse.errors.methodLabel": "メソド", + "xpack.monitoring.metrics.apm.acmResponse.errors.methodTitle": "応答方法エラーエージェント構成管理", + "xpack.monitoring.metrics.apm.acmResponse.errors.unauthorizedDescription": "許可されていないHTTP要求拒否数", + "xpack.monitoring.metrics.apm.acmResponse.errors.unauthorizedLabel": "不正", + "xpack.monitoring.metrics.apm.acmResponse.errors.unauthorizedTitle": "応答許可されていないエラーエージェント構成管理", + "xpack.monitoring.metrics.apm.acmResponse.errors.unavailableDescription": "利用不可HTTP応答数。Kibanaの構成エラーまたはサポートされていないバージョンの可能性", + "xpack.monitoring.metrics.apm.acmResponse.errors.unavailableLabel": "選択済み", + "xpack.monitoring.metrics.apm.acmResponse.errors.unavailableTitle": "応答利用不可エラーエージェント構成管理", + "xpack.monitoring.metrics.apm.acmResponse.validNotModifiedDescription": "304 未修正応答数", + "xpack.monitoring.metrics.apm.acmResponse.validNotModifiedLabel": "未修正", + "xpack.monitoring.metrics.apm.acmResponse.validNotModifiedTitle": "応答未修正エージェント構成管理", + "xpack.monitoring.metrics.apm.acmResponse.validOkDescription": "200 OK 応答カウント", + "xpack.monitoring.metrics.apm.acmResponse.validOkLabel": "OK", + "xpack.monitoring.metrics.apm.acmResponse.validOkTitle": "応答OK数エージェント構成管理", "xpack.monitoring.metrics.apm.outputAckedEventsRate.ackedDescription": "アウトプットにより処理されたイベントです (再試行を含む)", "xpack.monitoring.metrics.apm.outputAckedEventsRate.ackedLabel": "承認済み", "xpack.monitoring.metrics.apm.outputAckedEventsRateTitle": "アウトプット承認イベントレート", @@ -11441,6 +13517,7 @@ "xpack.monitoring.metrics.apm.outputFailedEventsRate.failedDescription": "アウトプットにより処理されたイベントです (再試行を含む)", "xpack.monitoring.metrics.apm.outputFailedEventsRate.failedLabel": "失敗", "xpack.monitoring.metrics.apm.outputFailedEventsRateTitle": "アウトプットイベント失敗率", + "xpack.monitoring.metrics.apm.perSecondUnitLabel": "/s", "xpack.monitoring.metrics.apm.processedEvents.transactionDescription": "処理されたトランザクションイベントです", "xpack.monitoring.metrics.apm.processedEvents.transactionLabel": "トランザクション", "xpack.monitoring.metrics.apm.processedEventsTitle": "処理済みのイベント", @@ -11978,6 +14055,7 @@ "xpack.monitoring.noData.setupMetricbeatInstead": "または、Metricbeat で設定 (推奨)", "xpack.monitoring.novLabel": "11月", "xpack.monitoring.octLabel": "10月", + "xpack.monitoring.overview.heading": "スタック監視概要", "xpack.monitoring.pageLoadingTitle": "読み込み中…", "xpack.monitoring.permanentActiveLicenseStatusDescription": "ご使用のライセンスには有効期限がありません。", "xpack.monitoring.pie.unableToDrawLabelsInsideCanvasErrorMessage": "キャンバス内のラベルではパイを作成できません", @@ -12020,6 +14098,7 @@ "xpack.monitoring.setupMode.usingMetricbeatCollection": "Metricbeat で監視", "xpack.monitoring.stackMonitoringDocTitle": "スタック監視 {clusterName} {suffix}", "xpack.monitoring.stackMonitoringTitle": "スタック監視", + "xpack.monitoring.summaryStatus.alertsDescription": "アラート", "xpack.monitoring.summaryStatus.statusDescription": "ステータス", "xpack.monitoring.summaryStatus.statusIconLabel": "ステータス: {status}", "xpack.monitoring.summaryStatus.statusIconTitle": "ステータス: {statusIcon}", @@ -12030,6 +14109,78 @@ "xpack.monitoring.updateLicenseTitle": "ライセンスの更新", "xpack.monitoring.useAvailableLicenseDescription": "既に新しいライセンスがある場合は、今すぐアップロードしてください。", "xpack.monitoring.wedLabel": "水", + "xpack.observability.beta": "ベータ", + "xpack.observability.emptySection.apps.alert.description": "503エラーが累積していますか?サービスは応答していますか?CPUとRAMの使用量が跳ね上がっていますか?このような警告を、事後にではなく、発生と同時に把握しましょう。", + "xpack.observability.emptySection.apps.alert.link": "アラートの作成", + "xpack.observability.emptySection.apps.alert.title": "アラートが見つかりません。", + "xpack.observability.emptySection.apps.apm.description": "分散アーキテクチャ全体でトランザクションを追跡し、サービスの通信をマップ化して、簡単にパフォーマンスボトルネックを特定できます。", + "xpack.observability.emptySection.apps.apm.link": "エージェントのインストール", + "xpack.observability.emptySection.apps.apm.title": "APM", + "xpack.observability.emptySection.apps.logs.description": "任意のソースからログを一元化します。より迅速に対応できるように、検索、追跡、異常検知の自動化、傾向の可視化を行います。", + "xpack.observability.emptySection.apps.logs.link": "Filebeatをインストール", + "xpack.observability.emptySection.apps.logs.title": "ログ", + "xpack.observability.emptySection.apps.metrics.description": "インフラストラクチャ、アプリ、サービスからメトリックを分析します。傾向、予測動作を発見し、異常などに関するアラートを通知します。", + "xpack.observability.emptySection.apps.metrics.link": "メトリックモジュールのインストール", + "xpack.observability.emptySection.apps.metrics.title": "メトリック", + "xpack.observability.emptySection.apps.uptime.description": "サイトとサービスの可用性をアクティブに監視するアラートを受信し、問題をより迅速に解決して、ユーザーエクスペリエンスを最適化します。", + "xpack.observability.emptySection.apps.uptime.link": "Heartbeatのインストール", + "xpack.observability.emptySection.apps.uptime.title": "アップタイム", + "xpack.observability.home.addData": "データの追加", + "xpack.observability.home.breadcrumb": "概要", + "xpack.observability.home.feedback": "フィードバックを送信する", + "xpack.observability.home.getStatedButton": "使ってみる", + "xpack.observability.home.sectionsubtitle": "ログ、メトリック、トレースを大規模に、1つのスタックにまとめて、環境内のあらゆる場所で生じるイベントの監視、分析、対応を行います。", + "xpack.observability.home.sectionTitle": "エコシステム全体の一元的な可視性", + "xpack.observability.home.title": "オブザーバビリティ", + "xpack.observability.ingestManafer.beta": "ベータ", + "xpack.observability.ingestManafer.button": "Ingest Managerベータを試す", + "xpack.observability.ingestManafer.text": "Elasticエージェントでは、シンプルかつ統合された方法で、ログ、メトリック、他の種類のデータの監視をホストに追加することができます。複数のBeatsと他のエージェントをインストールする必要はありません。このため、インフラストラクチャ全体での構成のデプロイが簡単で高速になりました。", + "xpack.observability.ingestManafer.title": "新しいIngest Managerをご覧になりましたか?", + "xpack.observability.landing.breadcrumb": "はじめて使う", + "xpack.observability.news.readFullStory": "詳細なストーリーを読む", + "xpack.observability.news.title": "新機能", + "xpack.observability.observability.breadcrumb.": "オブザーバビリティ", + "xpack.observability.overview.alert.allTypes": "すべてのタイプ", + "xpack.observability.overview.alert.appLink": "アラートを管理", + "xpack.observability.overview.alert.view": "表示", + "xpack.observability.overview.alerts.muted": "ミュート", + "xpack.observability.overview.alerts.title": "アラート", + "xpack.observability.overview.apm.appLink": "アプリで表示", + "xpack.observability.overview.apm.services": "サービス", + "xpack.observability.overview.apm.title": "APM", + "xpack.observability.overview.apm.transactionsPerMinute": "1分あたりのトランザクション数", + "xpack.observability.overview.breadcrumb": "概要", + "xpack.observability.overview.loadingObservability": "オブザーバビリティを読み込んでいます", + "xpack.observability.overview.logs.appLink": "アプリで表示", + "xpack.observability.overview.logs.subtitle": "毎分のログレート", + "xpack.observability.overview.logs.title": "ログ", + "xpack.observability.overview.metrics.appLink": "アプリで表示", + "xpack.observability.overview.metrics.cpuUsage": "CPU使用状況", + "xpack.observability.overview.metrics.hosts": "ホスト", + "xpack.observability.overview.metrics.inboundTraffic": "受信トラフィック", + "xpack.observability.overview.metrics.memoryUsage": "メモリー使用状況", + "xpack.observability.overview.metrics.outboundTraffic": "送信トラフィック", + "xpack.observability.overview.metrics.title": "メトリック", + "xpack.observability.overview.uptime.appLink": "アプリで表示", + "xpack.observability.overview.uptime.chart.down": "ダウン", + "xpack.observability.overview.uptime.chart.up": "アップ", + "xpack.observability.overview.uptime.down": "ダウン", + "xpack.observability.overview.uptime.monitors": "監視", + "xpack.observability.overview.uptime.title": "アップタイム", + "xpack.observability.overview.uptime.up": "アップ", + "xpack.observability.resources.documentation": "ドキュメント", + "xpack.observability.resources.forum": "ディスカッションフォーラム", + "xpack.observability.resources.title": "リソース", + "xpack.observability.resources.training": "オブザーバビリティの基本", + "xpack.observability.section.apps.apm.description": "分散アーキテクチャ全体でトランザクションを追跡し、サービスの通信をマップ化して、簡単にパフォーマンスボトルネックを特定できます。", + "xpack.observability.section.apps.apm.title": "APM", + "xpack.observability.section.apps.logs.description": "任意のソースからログを一元化します。より迅速に対応できるように、検索、追跡、異常検知の自動化、傾向の可視化を行います。", + "xpack.observability.section.apps.logs.title": "ログ", + "xpack.observability.section.apps.metrics.description": "インフラストラクチャ、アプリ、サービスからメトリックを分析します。傾向、予測動作を発見し、異常などに関するアラートを通知します。", + "xpack.observability.section.apps.metrics.title": "メトリック", + "xpack.observability.section.apps.uptime.description": "サイトとサービスの可用性をアクティブに監視するアラートを受信し、問題をより迅速に解決して、ユーザーエクスペリエンスを最適化します。", + "xpack.observability.section.apps.uptime.title": "アップタイム", + "xpack.observability.section.errorPanel": "データの取得時にエラーが発生しました。再試行してください", "xpack.painlessLab.apiReferenceButtonLabel": "API リファレンス", "xpack.painlessLab.context.defaultLabel": "スクリプト結果は文字列に変換されます", "xpack.painlessLab.context.filterLabel": "フィルターのスクリプトクエリのコンテキストを使用する", @@ -13046,13 +15197,26 @@ "xpack.security.roles.createBreadcrumb": "作成", "xpack.security.users.breadcrumb": "ユーザー", "xpack.security.users.createBreadcrumb": "作成", - "xpack.server.checkLicense.errorExpiredMessage": "{licenseType} ライセンスが期限切れのため {pluginName} を使用できません", - "xpack.server.checkLicense.errorUnavailableMessage": "現在ライセンス情報が利用できないため {pluginName} を使用できません。", - "xpack.server.checkLicense.errorUnsupportedMessage": "ご使用の {licenseType} ライセンスは {pluginName} をサポートしていません。ライセンスをアップグレードしてください。", - "xpack.securitySolution.add_filter_to_global_search_bar.filterForValueHoverAction": "値でフィルターします", + "xpack.securitySolution.add_filter_to_global_search_bar.filterForValueHoverAction": "値でフィルター", "xpack.securitySolution.add_filter_to_global_search_bar.filterOutValueHoverAction": "値を除外", + "xpack.securitySolution.alerts.riskScoreMapping.defaultDescriptionLabel": "このルールで生成されたすべてのアラートのリスクスコアを選択します。", + "xpack.securitySolution.alerts.riskScoreMapping.defaultRiskScoreTitle": "デフォルトリスクスコア", + "xpack.securitySolution.alerts.riskScoreMapping.mappingDescriptionLabel": "ソースイベント(スケール1-100)からリスクスコアにフィールドをマッピングします。", + "xpack.securitySolution.alerts.riskScoreMapping.mappingDetailsLabel": "値が境界外の場合、またはフィールドがない場合は、デフォルトリスクスコアが使用されます。", + "xpack.securitySolution.alerts.riskScoreMapping.riskScoreFieldTitle": "signal.rule.risk_score", + "xpack.securitySolution.alerts.riskScoreMapping.riskScoreMappingTitle": "リスクスコア無効化", + "xpack.securitySolution.alerts.riskScoreMapping.riskScoreTitle": "リスクスコア", + "xpack.securitySolution.alerts.riskScoreMapping.sourceFieldTitle": "ソースフィールド", + "xpack.securitySolution.alerts.severityMapping.defaultDescriptionLabel": "このルールで生成されたすべてのアラートの重要度sレベルを選択します。", + "xpack.securitySolution.alerts.severityMapping.defaultSeverityTitle": "深刻度", + "xpack.securitySolution.alerts.severityMapping.mappingDescriptionLabel": "ソースイベントから特定の重要度に値をマッピングします。", + "xpack.securitySolution.alerts.severityMapping.mappingDetailsLabel": "複数の一致がある場合、最高重要度の一致が適用されます。一致がない場合は、デフォルト重要度が使用されます。", + "xpack.securitySolution.alerts.severityMapping.severityMappingTitle": "重要度無効化", + "xpack.securitySolution.alerts.severityMapping.severityTitle": "デフォルト重要度", + "xpack.securitySolution.alerts.severityMapping.sourceFieldTitle": "ソースフィールド", + "xpack.securitySolution.alerts.severityMapping.sourceValueTitle": "ソース値", "xpack.securitySolution.alertsView.alertsDocumentType": "外部アラート", - "xpack.securitySolution.alertsView.alertsGraphTitle": "外部アラート数", + "xpack.securitySolution.alertsView.alertsGraphTitle": "外部アラート傾向", "xpack.securitySolution.alertsView.alertsStackByOptions.module": "モジュール", "xpack.securitySolution.alertsView.alertsTableTitle": "外部アラート", "xpack.securitySolution.alertsView.categoryLabel": "カテゴリー", @@ -13060,13 +15224,13 @@ "xpack.securitySolution.alertsView.moduleLabel": "モジュール", "xpack.securitySolution.alertsView.showing": "表示中", "xpack.securitySolution.alertsView.totalCountOfAlerts": "外部アラートが検索条件に一致します", - "xpack.securitySolution.alertsView.unit": "外部{totalCount, plural, =1 {alert} other {alerts}}", + "xpack.securitySolution.alertsView.unit": "外部{totalCount, plural, =1 {アラート} other {アラート}}", "xpack.securitySolution.andOrBadge.and": "AND", "xpack.securitySolution.andOrBadge.or": "OR", "xpack.securitySolution.anomaliesTable.table.anomaliesDescription": "異常", - "xpack.securitySolution.anomaliesTable.table.anomaliesTooltip": "異常表は Security グローバル KQL 検索でフィルタリングできません。", + "xpack.securitySolution.anomaliesTable.table.anomaliesTooltip": "異常表はSIEMグローバルKQL検索でフィルタリングできません。", "xpack.securitySolution.anomaliesTable.table.showingDescription": "表示中", - "xpack.securitySolution.anomaliesTable.table.unit": "{totalCount, plural, =1 {anomaly} other {anomalies}}", + "xpack.securitySolution.anomaliesTable.table.unit": "{totalCount, plural, =1 {異常} other {異常}}", "xpack.securitySolution.auditd.abortedAuditStartupDescription": "中断された監査のスタートアップ", "xpack.securitySolution.auditd.accessErrorDescription": "アクセスエラー", "xpack.securitySolution.auditd.accessPermissionDescription": "アクセス権限", @@ -13076,42 +15240,42 @@ "xpack.securitySolution.auditd.addedUserAccountDescription": "ユーザーアカウントを追加しました", "xpack.securitySolution.auditd.allocatedMemoryForDescription": "割当メモリー", "xpack.securitySolution.auditd.asDescription": "as", - "xpack.securitySolution.auditd.assignedUserRoleToDescription": "ユーザーロールをアサインしました:", - "xpack.securitySolution.auditd.assignedVmIdDescription": "vm id が割り当てられました", - "xpack.securitySolution.auditd.assignedVMResourceDescription": "割り当てられた vm リソース", + "xpack.securitySolution.auditd.assignedUserRoleToDescription": "ユーザーロールをアサインしました。", + "xpack.securitySolution.auditd.assignedVmIdDescription": "vm idが割り当てられました", + "xpack.securitySolution.auditd.assignedVMResourceDescription": "割り当てられたvmリソース", "xpack.securitySolution.auditd.attemptedLoginDescription": "以下を経由してログインを試行しました:", "xpack.securitySolution.auditd.attemptedLoginFromUnusalPlaceDescription": "通常と異なる場所からログインを試行しました", "xpack.securitySolution.auditd.attemptedLoginFromUnusualHourDescription": "通常と異なる時間にログインを試行しました", "xpack.securitySolution.auditd.auditErrorDescription": "監査エラー", "xpack.securitySolution.auditd.authenticatedToGroupDescription": "グループに認証しました", - "xpack.securitySolution.auditd.authenticatedUsingDescription": "次の手段で認証しました:", + "xpack.securitySolution.auditd.authenticatedUsingDescription": "次の手段で認証しました。", "xpack.securitySolution.auditd.bootedSystemDescription": "システムを起動しました", - "xpack.securitySolution.auditd.boundSocketFromDescription": "次からソケットをバインドしました:", + "xpack.securitySolution.auditd.boundSocketFromDescription": "次からソケットをバインドしました。", "xpack.securitySolution.auditd.causedMacPolicyErrorDescription": "がmacポリシーエラーを発生させました", "xpack.securitySolution.auditd.changedAuditConfigurationDescription": "監査設定を変更しました", "xpack.securitySolution.auditd.changedAuditFeatureDescription": "監査機能を変更しました", - "xpack.securitySolution.auditd.changedConfigurationWIthDescription": "次の設定を変更しました:", - "xpack.securitySolution.auditd.ChangedFileAttributesOfDescription": "次のファイル属性を変更しました:", - "xpack.securitySolution.auditd.changedFilePermissionOfDescription": "次のファイル権限を変更しました:", + "xpack.securitySolution.auditd.changedConfigurationWIthDescription": "次の設定を変更しました。", + "xpack.securitySolution.auditd.ChangedFileAttributesOfDescription": "次のファイル属性を変更しました。", + "xpack.securitySolution.auditd.changedFilePermissionOfDescription": "次のファイル権限を変更しました。", "xpack.securitySolution.auditd.changedGroupDescription": "グループを変更しました", "xpack.securitySolution.auditd.changedGroupPasswordDescription": "グループのパスワードを変更しました", - "xpack.securitySolution.auditd.changedIdentityUsingDescription": "以下を使用してIDを変更しました:", - "xpack.securitySolution.auditd.changedLoginIdToDescription": "ログインIDを次に変更しました:", + "xpack.securitySolution.auditd.changedIdentityUsingDescription": "以下を使用してIDを変更しました。", + "xpack.securitySolution.auditd.changedLoginIdToDescription": "ログインIDを次に変更しました。", "xpack.securitySolution.auditd.changedMacConfigurationDescription": "mac構成を変更しました", - "xpack.securitySolution.auditd.changedPasswordWithDescription": "次のパスワードを変更しました:", - "xpack.securitySolution.auditd.changedRoleUsingDescription": "以下を使用してロールを変更しました:", + "xpack.securitySolution.auditd.changedPasswordWithDescription": "次のパスワードを変更しました。", + "xpack.securitySolution.auditd.changedRoleUsingDescription": "以下を使用してロールを変更しました。", "xpack.securitySolution.auditd.changedSeLinuxBooleanDescription": "selinuxブールを変更しました", "xpack.securitySolution.auditd.changedSelinuxEnforcementDescription": "selinux執行を変更しました", "xpack.securitySolution.auditd.changedSystemNameDescription": "システム名を変更しました", - "xpack.securitySolution.auditd.changedSystemTimeWithDescription": "次のシステム時刻を変更しました:", - "xpack.securitySolution.auditd.changedTimeStampOfDescription": "次のタイムスタンプを変更しました:", - "xpack.securitySolution.auditd.changedToRunLevelWithDescription": "次の実行レベルを変更しました:", + "xpack.securitySolution.auditd.changedSystemTimeWithDescription": "次のシステム時刻を変更しました。", + "xpack.securitySolution.auditd.changedTimeStampOfDescription": "次のタイムスタンプを変更しました。", + "xpack.securitySolution.auditd.changedToRunLevelWithDescription": "次の実行レベルを変更しました。", "xpack.securitySolution.auditd.changedUserIdDescription": "ユーザー ID が変更されました", - "xpack.securitySolution.auditd.changeidleOwernshipOfDescription": "次のファイルの所有者を変更:", - "xpack.securitySolution.auditd.checkedFileSystemMetadataOfDescription": "次のファイルシステムメタデータを確認しました:", - "xpack.securitySolution.auditd.checkedIntegrityOfDescription": "次の整合性を確認しました:", - "xpack.securitySolution.auditd.chedckedMetaDataOfDescription": "次のメタデータを確認しました:", - "xpack.securitySolution.auditd.connectedUsingDescription": "以下を使用して接続しました:", + "xpack.securitySolution.auditd.changeidleOwernshipOfDescription": "次のファイルの所有者を変更。", + "xpack.securitySolution.auditd.checkedFileSystemMetadataOfDescription": "次のファイルシステムメタデータを確認しました。", + "xpack.securitySolution.auditd.checkedIntegrityOfDescription": "次の整合性を確認しました。", + "xpack.securitySolution.auditd.chedckedMetaDataOfDescription": "次のメタデータを確認しました。", + "xpack.securitySolution.auditd.connectedUsingDescription": "以下を使用して接続しました。", "xpack.securitySolution.auditd.crashedProgramDescription": "がプログラムをクラッシュさせました", "xpack.securitySolution.auditd.createdDirectoryDescription": "ディレクトリを作成しました", "xpack.securitySolution.auditd.createdVmImageDescription": "仮想マシンイメージを作成しました", @@ -13119,52 +15283,52 @@ "xpack.securitySolution.auditd.cryptoOfficerLoggedOutDescription": "クリプトオフィサーがログアウト", "xpack.securitySolution.auditd.deletedDescription": "削除されました", "xpack.securitySolution.auditd.deletedGroupAccountUsingDescription": "次の手段でグループアカウントを削除", - "xpack.securitySolution.auditd.deletedUserAccountUsingDescription": "以下を使用してユーザーアカウントを削除しました:", + "xpack.securitySolution.auditd.deletedUserAccountUsingDescription": "以下を使用してユーザーアカウントを削除しました。", "xpack.securitySolution.auditd.deletedVmImageDescription": "仮想マシンイメージを削除しました", - "xpack.securitySolution.auditd.disposedCredentialsDescription": "次のアカウント認証情報を処理しました:", + "xpack.securitySolution.auditd.disposedCredentialsDescription": "次のアカウント認証情報を処理しました。", "xpack.securitySolution.auditd.endedFromDescription": "終了:", "xpack.securitySolution.auditd.errorFromDescription": "エラー:", "xpack.securitySolution.auditd.executedDescription": "実行", "xpack.securitySolution.auditd.executionOfForbiddenProgramDescription": "禁止されたプログラムの実行", "xpack.securitySolution.auditd.failedLoginTooManyTimesDescription": "ログイン回数超過によりログインに失敗", - "xpack.securitySolution.auditd.inDescription": "次に含まれる:", + "xpack.securitySolution.auditd.inDescription": "in", "xpack.securitySolution.auditd.initializedAuditSubsystemDescription": "監査サブシステムを初期化しました", "xpack.securitySolution.auditd.issuedVmControlDescription": "仮想マシンコントロールを発行しました", - "xpack.securitySolution.auditd.killedProcessIdDescription": "プロセスIDを強制終了しました:", - "xpack.securitySolution.auditd.ListeningForConnectionsUsingDescription": "以下を使用して接続をlistenしています:", + "xpack.securitySolution.auditd.killedProcessIdDescription": "プロセスIDを強制終了しました。", + "xpack.securitySolution.auditd.ListeningForConnectionsUsingDescription": "以下を使用して接続をlistenしています。", "xpack.securitySolution.auditd.loadedFirewallRuleDescription": "ファイアウォールルールを読み込みました", "xpack.securitySolution.auditd.loadedMacPolicyDescription": "macポリシーを読み込みました", "xpack.securitySolution.auditd.loadedSeLinuxPolicyDescription": "selinuxポリシーを読み込みました", - "xpack.securitySolution.auditd.loaedKernelModuleOfDescription": "次のカーネルモジュールを読み込みました:", + "xpack.securitySolution.auditd.loaedKernelModuleOfDescription": "次のカーネルモジュールを読み込みました。", "xpack.securitySolution.auditd.lockedAccountDescription": "アカウントをロック", "xpack.securitySolution.auditd.loggedOutDescription": "ログアウト", "xpack.securitySolution.auditd.macPermissionDescription": "mac権限", - "xpack.securitySolution.auditd.madeDeviceWithDescription": "デバイスを作成しました:", - "xpack.securitySolution.auditd.migratedVmFromDescription": "仮想マシンを以下から移行しました:", - "xpack.securitySolution.auditd.migratedVmToDescription": "仮想マシンを以下に移行しました:", + "xpack.securitySolution.auditd.madeDeviceWithDescription": "デバイスを作成しました。", + "xpack.securitySolution.auditd.migratedVmFromDescription": "仮想マシンを以下から移行しました。", + "xpack.securitySolution.auditd.migratedVmToDescription": "仮想マシンを以下に移行しました。", "xpack.securitySolution.auditd.modifiedGroupAccountDescription": "グループアカウントを修正", - "xpack.securitySolution.auditd.modifiedLevelOfDescription": "次のレベルを修正:", - "xpack.securitySolution.auditd.modifiedRoleDescription": "ロールを修正:", + "xpack.securitySolution.auditd.modifiedLevelOfDescription": "次のレベルを修正", + "xpack.securitySolution.auditd.modifiedRoleDescription": "ロールを修正", "xpack.securitySolution.auditd.modifiedUserAccountDescription": "ユーザーアカウントを修正", "xpack.securitySolution.auditd.mountedDescription": "マウントしました", "xpack.securitySolution.auditd.negotiatedCryptoKeyDescription": "暗号キーを交渉しました", "xpack.securitySolution.auditd.nonExistentDescription": "不明なプロセスに", "xpack.securitySolution.auditd.OpenedFileDescription": "ファイルを開きました", "xpack.securitySolution.auditd.openedTooManySessionsDescription": "開いたセッション数が多すぎました", - "xpack.securitySolution.auditd.overrodeLabelOfDescription": "次のラベルを上書き:", - "xpack.securitySolution.auditd.promiscuousModeDescription": "以下を使用してデバイスの無差別モードを変更しました:", + "xpack.securitySolution.auditd.overrodeLabelOfDescription": "次のラベルを上書き", + "xpack.securitySolution.auditd.promiscuousModeDescription": "以下を使用してデバイスの無差別モードを変更しました。", "xpack.securitySolution.auditd.ranCommandDescription": "コマンドを実行しました", - "xpack.securitySolution.auditd.receivedFromDescription": "以下より受信しました:", + "xpack.securitySolution.auditd.receivedFromDescription": "以下より受信しました。", "xpack.securitySolution.auditd.reconfiguredAuditDescription": "監査を再構成しました", "xpack.securitySolution.auditd.refreshedCredentialsForDescription": "認証情報をリフレッシュしました", "xpack.securitySolution.auditd.relabeledFileSystemDescription": "ファイルシステムのラベルを変更しました", "xpack.securitySolution.auditd.remoteAuditConnectedDescription": "リモート監査を接続", "xpack.securitySolution.auditd.remoteAuditDisconnectedDescription": "リモート監査を切断", - "xpack.securitySolution.auditd.removedUserRoleFromDescription": "以下からユーザーロールを削除しました:", + "xpack.securitySolution.auditd.removedUserRoleFromDescription": "以下からユーザーロールを削除しました。", "xpack.securitySolution.auditd.renamedDescription": "名前を変更しました", "xpack.securitySolution.auditd.resumedAuditLoggingDescription": "監査ログを再開しました", "xpack.securitySolution.auditd.rotatedAuditLogsDescription": "rotated-audit-logs", - "xpack.securitySolution.auditd.scheduledPolicyOFDescription": "次のポリシーをスケジュール設定しました:", + "xpack.securitySolution.auditd.scheduledPolicyOFDescription": "次のポリシーをスケジュール設定しました。", "xpack.securitySolution.auditd.sentMessageDescription": "メッセージを送信しました", "xpack.securitySolution.auditd.sentTestDescription": "テストを送信しました", "xpack.securitySolution.auditd.sentToDescription": "送信先:", @@ -13180,14 +15344,14 @@ "xpack.securitySolution.auditd.symLinkedDescription": "シンボルでリンクしました", "xpack.securitySolution.auditd.testedFileSystemIntegrityDescription": "ファイルシステムの完全性をテスト", "xpack.securitySolution.auditd.unknownDescription": "不明", - "xpack.securitySolution.auditd.unloadedKernelModuleOfDescription": "次のカーネルモジュールをアンロードしました:", - "xpack.securitySolution.auditd.unlockedAccountDescription": "アカウントのロックを解除しました:", + "xpack.securitySolution.auditd.unloadedKernelModuleOfDescription": "次のカーネルモジュールをアンロードしました。", + "xpack.securitySolution.auditd.unlockedAccountDescription": "アカウントのロックを解除しました。", "xpack.securitySolution.auditd.unmountedDescription": "マウント解除しました", "xpack.securitySolution.auditd.usingDescription": "using", - "xpack.securitySolution.auditd.violatedAppArmorPolicyFromDescription": "以下からのAppArmorポリシーに違反しました:", - "xpack.securitySolution.auditd.violatedSeccompPolicyWithDescription": "以下からのseccompポリシーに違反しました:", + "xpack.securitySolution.auditd.violatedAppArmorPolicyFromDescription": "以下からのAppArmorポリシーに違反しました。", + "xpack.securitySolution.auditd.violatedSeccompPolicyWithDescription": "以下からのseccompポリシーに違反しました。", "xpack.securitySolution.auditd.violatedSeLinuxPolicyDescription": "selinuxポリシーに違反しました", - "xpack.securitySolution.auditd.wasAuthorizedToUseDescription": "が以下の使用を承認されました:", + "xpack.securitySolution.auditd.wasAuthorizedToUseDescription": "が以下の使用を承認されました。", "xpack.securitySolution.auditd.withResultDescription": "結果付き", "xpack.securitySolution.authenticationsTable.authenticationFailures": "認証", "xpack.securitySolution.authenticationsTable.failures": "失敗", @@ -13197,14 +15361,18 @@ "xpack.securitySolution.authenticationsTable.lastSuccessfulDestination": "前回成功したデスティネーション", "xpack.securitySolution.authenticationsTable.lastSuccessfulSource": "前回成功したソース", "xpack.securitySolution.authenticationsTable.lastSuccessfulTime": "前回の成功", - "xpack.securitySolution.authenticationsTable.rows": "{numRows} {numRows, plural, =0 {rows} =1 {row} other {rows}}", + "xpack.securitySolution.authenticationsTable.rows": "{numRows} {numRows, plural, =0 {行} =1 {行} other {行}}", "xpack.securitySolution.authenticationsTable.successes": "成功", "xpack.securitySolution.authenticationsTable.uncommonProcessTable": "非共通プロセス", - "xpack.securitySolution.authenticationsTable.unit": "{totalCount, plural, =1 {user} other {users}}", + "xpack.securitySolution.authenticationsTable.unit": "{totalCount, plural, =1 {ユーザー} other {ユーザー}}", "xpack.securitySolution.authenticationsTable.user": "ユーザー", + "xpack.securitySolution.authz.mlUnavailable": "機械学習プラグインが使用できません。プラグインを有効にしてください。", + "xpack.securitySolution.authz.userIsNotMlAdminMessage": "現在のユーザーは機械学習管理者ではありません。", + "xpack.securitySolution.autocomplete.loadingDescription": "読み込み中…", "xpack.securitySolution.case.allCases.actions": "アクション", "xpack.securitySolution.case.allCases.comments": "コメント", "xpack.securitySolution.case.allCases.noTagsAvailable": "利用可能なタグがありません", + "xpack.securitySolution.case.caseModal.title": "タイムラインに添付するケースを選択", "xpack.securitySolution.case.caseSavedObjectNoPermissionsMessage": "ケースを表示するには、Kibanaスペースで保存されたオブジェクト管理機能の権限が必要です。詳細については、Kibana管理者に連絡してください。", "xpack.securitySolution.case.caseSavedObjectNoPermissionsTitle": "Kibana機能権限が必要です", "xpack.securitySolution.case.caseTable.addNewCase": "新規ケースの追加", @@ -13229,7 +15397,7 @@ "xpack.securitySolution.case.caseTable.serviceNowLinkAria": "クリックすると、servicenowでインシデントを表示します", "xpack.securitySolution.case.caseTable.showingCasesTitle": "{totalRules} {totalRules, plural, =1 {ケース} other {ケース}} を表示中", "xpack.securitySolution.case.caseTable.snIncident": "外部インシデント", - "xpack.securitySolution.case.caseTable.unit": "{totalCount, plural, =1 {case} other {cases}}", + "xpack.securitySolution.case.caseTable.unit": "{totalCount, plural, =1 {ケース} other {ケース}}", "xpack.securitySolution.case.caseTable.upToDate": " は最新です", "xpack.securitySolution.case.caseView.actionHeadline": "{actionDate} の {userName} {actionName}", "xpack.securitySolution.case.caseView.actionLabel.addComment": "コメントを追加しました", @@ -13244,7 +15412,7 @@ "xpack.securitySolution.case.caseView.actionLabel.selectedThirdParty": "インシデント管理システムとして{ thirdParty }を選択しました", "xpack.securitySolution.case.caseView.actionLabel.updateIncident": "インシデントを更新しました", "xpack.securitySolution.case.caseView.actionLabel.viewIncident": "{incidentNumber}を表示", - "xpack.securitySolution.case.caseView.alreadyPushedToExternalService": "既に{ externalService }インシデントにプッシュしました", + "xpack.securitySolution.case.caseView.alreadyPushedToExternalService": "すでに{ externalService }インシデントにプッシュしました", "xpack.securitySolution.case.caseView.backLabel": "ケースに戻る", "xpack.securitySolution.case.caseView.breadcrumb": "作成", "xpack.securitySolution.case.caseView.cancel": "キャンセル", @@ -13271,12 +15439,12 @@ "xpack.securitySolution.case.caseView.edit": "編集", "xpack.securitySolution.case.caseView.edit.comment": "コメントを編集", "xpack.securitySolution.case.caseView.edit.description": "説明を編集", - "xpack.securitySolution.case.caseView.edit.quote": "お客様の声", + "xpack.securitySolution.case.caseView.edit.quote": "お客様の声", "xpack.securitySolution.case.caseView.editActionsLinkAria": "クリックすると、すべてのアクションを表示します", "xpack.securitySolution.case.caseView.editConnector": "外部インシデント管理システムを変更", "xpack.securitySolution.case.caseView.editTagsLinkAria": "クリックすると、タグを編集します", "xpack.securitySolution.case.caseView.emailBody": "ケースリファレンス: {caseUrl}", - "xpack.securitySolution.case.caseView.emailSubject": "Security ケース - {caseTitle}", + "xpack.securitySolution.case.caseView.emailSubject": "セキュリティケース - {caseTitle}", "xpack.securitySolution.case.caseView.errorsPushServiceCallOutTitle": "ケースを外部システムにプッシュするには、以下が必要です。", "xpack.securitySolution.case.caseView.fieldRequiredError": "必須フィールド", "xpack.securitySolution.case.caseView.goToDocumentationButton": "ドキュメンテーションを表示", @@ -13287,18 +15455,21 @@ "xpack.securitySolution.case.caseView.openedOn": "開始日", "xpack.securitySolution.case.caseView.optional": "オプション", "xpack.securitySolution.case.caseView.pageBadgeLabel": "ベータ", - "xpack.securitySolution.case.caseView.pageBadgeTooltip": "ケースワークフローはまだベータです。Kibana repo で問題や不具合を報告して製品の改善にご協力ください。", + "xpack.securitySolution.case.caseView.pageBadgeTooltip": "ケースワークフローはまだベータです。Kibana repoで問題や不具合を報告して製品の改善にご協力ください。", "xpack.securitySolution.case.caseView.particpantsLabel": "参加者", "xpack.securitySolution.case.caseView.pushNamedIncident": "{ thirdParty }インシデントとしてプッシュ", - "xpack.securitySolution.case.caseView.pushThirdPartyIncident": "サードパーティインシデントとしてプッシュ", + "xpack.securitySolution.case.caseView.pushThirdPartyIncident": "外部インシデントとしてプッシュ", "xpack.securitySolution.case.caseView.pushToServiceDisableBecauseCaseClosedDescription": "終了したケースは外部システムに送信できません。外部システムでケースを開始または更新したい場合にはケースを再開します。", "xpack.securitySolution.case.caseView.pushToServiceDisableBecauseCaseClosedTitle": "ケースを再開する", - "xpack.securitySolution.case.caseView.pushToServiceDisableByConfigDescription": "kibana.yml ファイルは、特定のコネクターのみを許可するように構成されています。外部システムでケースを開けるようにするには、xpack.actions.enabled Actiontypes 設定に .servicenow を追加します。詳細は {link} をご覧ください。", - "xpack.securitySolution.case.caseView.pushToServiceDisableByConfigTitle": "Kibana の構成ファイルで ServiceNow を有効にする", - "xpack.securitySolution.case.caseView.pushToServiceDisableByLicenseDescription": "外部システムでケースを開くには、ライセンスをプラチナに更新するか、30 日間の無料トライアルを開始するか、AWS、GCP、または Azure で {link} にサインアップする必要があります。", - "xpack.securitySolution.case.caseView.pushToServiceDisableByLicenseTitle": "E lastic Platinum へのアップグレード", + "xpack.securitySolution.case.caseView.pushToServiceDisableByConfigDescription": "kibana.ymlファイルは、特定のコネクターのみを許可するように構成されています。外部システムでケースを開けるようにするには、xpack.actions.enabledActiontypes設定に.[actionTypeId](例:.servicenow | .jira)を追加します。詳細は{link}をご覧ください。", + "xpack.securitySolution.case.caseView.pushToServiceDisableByConfigTitle": "Kibanaの構成ファイルで外部サービスを有効にする", + "xpack.securitySolution.case.caseView.pushToServiceDisableByInvalidConnector": "外部サービスに更新を送信するために使用されるコネクターが削除されました。外部システムでケースを更新するには、別のコネクターを選択するか、新しいコネクターを作成してください。", + "xpack.securitySolution.case.caseView.pushToServiceDisableByLicenseDescription": "外部システムでケースを開くには、ライセンスをプラチナに更新するか、30日間の無料トライアルを開始するか、AWS、GCP、またはAzureで{link}にサインアップする必要があります。", + "xpack.securitySolution.case.caseView.pushToServiceDisableByLicenseTitle": "E lastic Platinumへのアップグレード", + "xpack.securitySolution.case.caseView.pushToServiceDisableByNoCaseConfigDescription": "外部システムでケースを開いて更新するには、このケースの外部インシデント管理システムを選択する必要があります。", "xpack.securitySolution.case.caseView.pushToServiceDisableByNoCaseConfigTitle": "外部コネクターを選択", "xpack.securitySolution.case.caseView.pushToServiceDisableByNoConfigTitle": "外部コネクターを構成", + "xpack.securitySolution.case.caseView.pushToServiceDisableByNoConnectors": "外部システムでケースを開いて更新するには、{link}を設定する必要があります。", "xpack.securitySolution.case.caseView.reopenCase": "ケースを再開", "xpack.securitySolution.case.caseView.reopenedCase": "ケースを再開する", "xpack.securitySolution.case.caseView.reporterLabel": "報告者", @@ -13309,31 +15480,32 @@ "xpack.securitySolution.case.caseView.to": "に", "xpack.securitySolution.case.caseView.unknown": "不明", "xpack.securitySolution.case.caseView.updateNamedIncident": "{ thirdParty }インシデントを更新", - "xpack.securitySolution.case.caseView.updateThirdPartyIncident": "サードパーティインシデントを更新", + "xpack.securitySolution.case.caseView.updateThirdPartyIncident": "外部インシデントを更新", "xpack.securitySolution.case.configure.errorPushingToService": "サービスへのプッシュエラー", "xpack.securitySolution.case.configure.successSaveToast": "保存された外部接続設定", "xpack.securitySolution.case.configureCases.addNewConnector": "新しいコネクターを追加", "xpack.securitySolution.case.configureCases.cancelButton": "キャンセル", - "xpack.securitySolution.case.configureCases.caseClosureOptionsClosedIncident": "新しいインシデントが外部システムで閉じたときにSIEMケースを自動的に閉じる", - "xpack.securitySolution.case.configureCases.caseClosureOptionsDesc": "SIEMケースの終了のしかたを定義します。自動ケース終了のためには、外部のインシデント管理システムへの接続を確立する必要がいります。", + "xpack.securitySolution.case.configureCases.caseClosureOptionsClosedIncident": "新しいインシデントが外部システムで閉じたときにセキュリティケースを自動的に閉じる", + "xpack.securitySolution.case.configureCases.caseClosureOptionsDesc": "セキュリティケースの終了のしかたを定義します。自動ケース終了のためには、外部のインシデント管理システムへの接続を確立する必要がいります。", "xpack.securitySolution.case.configureCases.caseClosureOptionsLabel": "ケース終了オプション", - "xpack.securitySolution.case.configureCases.caseClosureOptionsManual": "Security ケースを手動で閉じる", - "xpack.securitySolution.case.configureCases.caseClosureOptionsNewIncident": "新しいインシデントを外部システムにプッシュするときにSIEMケースを自動的に閉じる", + "xpack.securitySolution.case.configureCases.caseClosureOptionsManual": "セキュリティケースを手動で閉じる", + "xpack.securitySolution.case.configureCases.caseClosureOptionsNewIncident": "新しいインシデントを外部システムにプッシュするときにセキュリティケースを自動的に閉じる", "xpack.securitySolution.case.configureCases.caseClosureOptionsTitle": "ケースのクローズ", - "xpack.securitySolution.case.configureCases.fieldMappingDesc": "データをサードパーティにプッシュするときにSIEMケースフィールドをマップします。フィールドマッピングのためには、外部のインシデント管理システムへの接続を確立する必要があります。", + "xpack.securitySolution.case.configureCases.fieldMappingDesc": "データをサードパーティにプッシュするときにセキュリティケースフィールドをマップします。フィールドマッピングのためには、外部のインシデント管理システムへの接続を確立する必要があります。", "xpack.securitySolution.case.configureCases.fieldMappingEditAppend": "末尾に追加", "xpack.securitySolution.case.configureCases.fieldMappingEditNothing": "何もしない", "xpack.securitySolution.case.configureCases.fieldMappingEditOverwrite": "上書き", - "xpack.securitySolution.case.configureCases.fieldMappingFirstCol": "Security ケースフィールド", + "xpack.securitySolution.case.configureCases.fieldMappingFirstCol": "セキュリティケースフィールド", "xpack.securitySolution.case.configureCases.fieldMappingSecondCol": "外部インシデントフィールド", "xpack.securitySolution.case.configureCases.fieldMappingThirdCol": "編集時と更新時", "xpack.securitySolution.case.configureCases.fieldMappingTitle": "フィールドマッピング", "xpack.securitySolution.case.configureCases.headerTitle": "ケースを構成", - "xpack.securitySolution.case.configureCases.incidentManagementSystemDesc": "オプションとして、SIEMケースを選択した外部のインシデント管理システムに接続できます。そうすると、選択したサードパーティシステム内でケースデータをインシデントとしてプッシュできます。", + "xpack.securitySolution.case.configureCases.incidentManagementSystemDesc": "オプションとして、セキュリティケースを選択した外部のインシデント管理システムに接続できます。そうすると、選択したサードパーティシステム内でケースデータをインシデントとしてプッシュできます。", "xpack.securitySolution.case.configureCases.incidentManagementSystemLabel": "インシデント管理システム", "xpack.securitySolution.case.configureCases.incidentManagementSystemTitle": "外部のインシデント管理システムに接続", "xpack.securitySolution.case.configureCases.mappingFieldComments": "コメント", "xpack.securitySolution.case.configureCases.mappingFieldDescription": "説明", + "xpack.securitySolution.case.configureCases.mappingFieldName": "名前", "xpack.securitySolution.case.configureCases.mappingFieldNotMapped": "マップされません", "xpack.securitySolution.case.configureCases.mappingFieldSummary": "まとめ", "xpack.securitySolution.case.configureCases.noConnector": "コネクターを選択していません", @@ -13360,22 +15532,34 @@ "xpack.securitySolution.case.connectors.common.requiredUsernameTextField": "ユーザー名が必要です", "xpack.securitySolution.case.connectors.common.usernameTextFieldLabel": "ユーザー名", "xpack.securitySolution.case.connectors.jira.actionTypeTitle": "Jira", + "xpack.securitySolution.case.connectors.jira.apiTokenTextFieldLabel": "APIトークンまたはパスワード", + "xpack.securitySolution.case.connectors.jira.emailTextFieldLabel": "電子メールアドレスまたはユーザー名", "xpack.securitySolution.case.connectors.jira.projectKey": "プロジェクトキー", + "xpack.securitySolution.case.connectors.jira.requiredApiTokenTextField": "APIトークンまたはパスワードが必要です", + "xpack.securitySolution.case.connectors.jira.requiredEmailTextField": "電子メールアドレスまたはユーザー名が必要です", "xpack.securitySolution.case.connectors.jira.requiredProjectKeyTextField": "プロジェクトキーが必要です", - "xpack.securitySolution.case.connectors.jira.selectMessageText": "JiraでSIEMケースデータを更新するか、新しいインシデントにプッシュ", + "xpack.securitySolution.case.connectors.jira.selectMessageText": "Jiraでセキュリティケースデータを更新するか、新しいインシデントにプッシュ", + "xpack.securitySolution.case.connectors.resilient.actionTypeTitle": "IBM Resilient", + "xpack.securitySolution.case.connectors.resilient.apiKeyId": "APIキーID", + "xpack.securitySolution.case.connectors.resilient.apiKeySecret": "APIキーシークレット", + "xpack.securitySolution.case.connectors.resilient.orgId": "組織ID", + "xpack.securitySolution.case.connectors.resilient.requiredApiKeyIdTextField": "APIキーIDが必要です", + "xpack.securitySolution.case.connectors.resilient.requiredApiKeySecretTextField": "APIキーシークレットが必要です", + "xpack.securitySolution.case.connectors.resilient.requiredOrgIdTextField": "組織ID", + "xpack.securitySolution.case.connectors.resilient.selectMessageText": "resilientでSIEMケースデータを更新するか、新しいインシデントにプッシュ", "xpack.securitySolution.case.createCase.descriptionFieldRequiredError": "説明が必要です。", - "xpack.securitySolution.case.createCase.fieldTagsHelpText": "このケースの 1 つ以上のカスタム識別タグを入力します。新しいタグを開始するには、各タグの後でEnterを押します。", + "xpack.securitySolution.case.createCase.fieldTagsHelpText": "このケースの1つ以上のカスタム識別タグを入力します。新しいタグを開始するには、各タグの後でEnterを押します。", "xpack.securitySolution.case.createCase.titleFieldRequiredError": "タイトルが必要です。", "xpack.securitySolution.case.dismissErrorsPushServiceCallOutTitle": "閉じる", "xpack.securitySolution.case.pageTitle": "ケース", - "xpack.securitySolution.case.readOnlySavedObjectDescription": "ケースの表示のみが許可されています。ケースを開いて更新する必要がある場合は、Kibana管理者に連絡してください。", - "xpack.securitySolution.case.readOnlySavedObjectTitle": "読み取り専用機能権限が割り当てられています。", + "xpack.securitySolution.case.readOnlySavedObjectDescription": "ケースを表示する権限のみが付与されています。ケースを開いて更新する必要がある場合は、Kibana管理者に連絡してください。", + "xpack.securitySolution.case.readOnlySavedObjectTitle": "新しいケースを開いたり、既存のケースを更新したりすることはできません", "xpack.securitySolution.certificate.fingerprint.clientCertLabel": "クライアント証明書", "xpack.securitySolution.certificate.fingerprint.serverCertLabel": "サーバー証明書", "xpack.securitySolution.chart.allOthersGroupingLabel": "その他すべて", "xpack.securitySolution.chart.dataAllValuesZerosTitle": "すべての値はゼロを返します", "xpack.securitySolution.chart.dataNotAvailableTitle": "チャートデータが利用できません", - "xpack.securitySolution.chrome.help.appName": "Security", + "xpack.securitySolution.chrome.help.appName": "SIEM", "xpack.securitySolution.chrome.helpMenu.documentation": "SIEMドキュメンテーション", "xpack.securitySolution.chrome.helpMenu.documentation.ecs": "ECSドキュメンテーション", "xpack.securitySolution.clipboard.copied": "コピー完了", @@ -13387,7 +15571,7 @@ "xpack.securitySolution.components.embeddables.embeddedMap.embeddableHeaderHelp": "マップ構成ヘルプ", "xpack.securitySolution.components.embeddables.embeddedMap.embeddableHeaderTitle": "ネットワーク マップ", "xpack.securitySolution.components.embeddables.embeddedMap.embeddablePanelTitle": "ソース -> デスティネーション ポイントツーポイントマップ", - "xpack.securitySolution.components.embeddables.embeddedMap.errorConfiguringEmbeddableApiTitle": "埋め込み可能な API の構成中にエラーが発生", + "xpack.securitySolution.components.embeddables.embeddedMap.errorConfiguringEmbeddableApiTitle": "埋め込み可能なAPIの構成中にエラーが発生", "xpack.securitySolution.components.embeddables.embeddedMap.errorCreatingMapEmbeddableTitle": "マップに’埋め込み可能なアイテムの作成中にエラーが発生", "xpack.securitySolution.components.embeddables.embeddedMap.lineLayerLabel": "折れ線", "xpack.securitySolution.components.embeddables.embeddedMap.serverLayerLabel": "サーバーポイント", @@ -13397,8 +15581,8 @@ "xpack.securitySolution.components.embeddables.indexPatternsMissingPrompt.errorDescription2": "Kibanaで手動でインデックスパターンを構成することもできます。", "xpack.securitySolution.components.embeddables.indexPatternsMissingPrompt.errorTitle": "必要なインデックスパターンが構成されていません", "xpack.securitySolution.components.embeddables.mapToolTip.errorTitle": "マップ機能の読み込み中にエラーが発生", - "xpack.securitySolution.components.embeddables.mapToolTip.filterForValueHoverAction": "値でフィルターします", - "xpack.securitySolution.components.embeddables.mapToolTip.footerLabel": "{totalFeatures} 件中 {currentFeature} 件 {totalFeatures, plural, =1 {feature} other {features}}", + "xpack.securitySolution.components.embeddables.mapToolTip.filterForValueHoverAction": "値でフィルター", + "xpack.securitySolution.components.embeddables.mapToolTip.footerLabel": "{currentFeature}/{totalFeatures} {totalFeatures, plural, =1 {機能} other {機能}}", "xpack.securitySolution.components.embeddables.mapToolTip.lineContent.clientLabel": "クライアント", "xpack.securitySolution.components.embeddables.mapToolTip.lineContent.destinationLabel": "送信先", "xpack.securitySolution.components.embeddables.mapToolTip.lineContent.serverLabel": "サーバー", @@ -13431,26 +15615,26 @@ "xpack.securitySolution.components.mlPopover.jobsTable.filters.searchFilterPlaceholder": "例: rare_process_linux", "xpack.securitySolution.components.mlPopover.jobsTable.filters.showAllJobsLabel": "Elastic ジョブ", "xpack.securitySolution.components.mlPopover.jobsTable.filters.showSiemJobsLabel": "カスタムジョブ", - "xpack.securitySolution.components.mlPopup.anomalyDetectionDescription": "以下の機械学習ジョブのいずれかを実行して、検知された異常の信号を生成する信号検知ルールを作成する準備をし、SIEMアプリケーションで異常イベントを表示します。基本操作として、いくつかの一般的な検出ジョブが提供されています。独自のカスタムMLジョブを追加する場合は、{machineLearning}アプリケーションからMLジョブを作成して、「SIEM」グループに追加します。", + "xpack.securitySolution.components.mlPopup.anomalyDetectionDescription": "以下の機械学習ジョブのいずれかを実行して、検知された異常のアラートを生成する検知ルールを作成する準備をし、セキュリティアプリケーションで異常イベントを表示します。基本操作として、いくつかの一般的な検出ジョブが提供されています。独自のカスタムMLジョブを追加する場合は、{machineLearning}アプリケーションからMLジョブを作成して、「セキュリティ」グループに追加します。", "xpack.securitySolution.components.mlPopup.cloudLink": "クラウド展開", "xpack.securitySolution.components.mlPopup.errors.createJobFailureTitle": "ジョブ作成エラー", "xpack.securitySolution.components.mlPopup.errors.startJobFailureTitle": "ジョブ開始エラー", "xpack.securitySolution.components.mlPopup.hooks.errors.indexPatternFetchFailureTitle": "インデックスパターン取得エラー", - "xpack.securitySolution.components.mlPopup.hooks.errors.siemJobFetchFailureTitle": "Security ジョブ取得エラー", + "xpack.securitySolution.components.mlPopup.hooks.errors.siemJobFetchFailureTitle": "SIEMジョブ取得エラー", "xpack.securitySolution.components.mlPopup.jobsTable.createCustomJobButtonLabel": "カスタムジョブを作成", "xpack.securitySolution.components.mlPopup.jobsTable.jobNameColumn": "ジョブ名", - "xpack.securitySolution.components.mlPopup.jobsTable.noItemsDescription": "Security 機械学習ジョブが見つかりませんでした", + "xpack.securitySolution.components.mlPopup.jobsTable.noItemsDescription": "SIEM機械学習ジョブが見つかりませんでした", "xpack.securitySolution.components.mlPopup.jobsTable.runJobColumn": "ジョブを実行", "xpack.securitySolution.components.mlPopup.jobsTable.tagsColumn": "グループ", "xpack.securitySolution.components.mlPopup.licenseButtonLabel": "ライセンスの管理", "xpack.securitySolution.components.mlPopup.machineLearningLink": "機械学習", "xpack.securitySolution.components.mlPopup.mlJobSettingsButtonLabel": "MLジョブ設定", "xpack.securitySolution.components.mlPopup.moduleNotCompatibleDescription": "データが見つかりませんでした。機械学習ジョブ要件の詳細については、{mlDocs}を参照してください。", - "xpack.securitySolution.components.mlPopup.moduleNotCompatibleTitle": "{incompatibleJobCount} 件が {incompatibleJobCount, plural, =1 {job} other {jobs}} 現在利用できません", + "xpack.securitySolution.components.mlPopup.moduleNotCompatibleTitle": "{incompatibleJobCount} {incompatibleJobCount, plural, =1 {件のジョブ} other {件のジョブ}}が現在使用できません。", "xpack.securitySolution.components.mlPopup.showingLabel": "{filterResultsLength} 件の{filterResultsLength, plural, one {ジョブ} other {ジョブ}}を表示中", "xpack.securitySolution.components.mlPopup.upgradeButtonLabel": "サブスクリプションオプション", - "xpack.securitySolution.components.mlPopup.upgradeDescription": "Security の異常検出機能にアクセスするには、ライセンスをプラチナに更新するか、30 日間の無料トライアルを開始するか、AWS、GCP、または Azure で{cloudLink} にサインアップしてください。その後、機械学習ジョブを実行して異常を表示できます。", - "xpack.securitySolution.components.mlPopup.upgradeTitle": "E lastic Platinum へのアップグレード", + "xpack.securitySolution.components.mlPopup.upgradeDescription": "SIEMの異常検出機能にアクセスするには、ライセンスをプラチナに更新するか、30日間の無料トライアルを開始するか、AWS、GCP、またはAzureで{cloudLink}にサインアップしてください。その後、機械学習ジョブを実行して異常を表示できます。", + "xpack.securitySolution.components.mlPopup.upgradeTitle": "E lastic Platinumへのアップグレード", "xpack.securitySolution.components.stepDefineRule.ruleTypeField.subscriptionsLink": "プラチナサブスクリプション", "xpack.securitySolution.containers.anomalies.errorFetchingAnomaliesData": "異常データをクエリできませんでした", "xpack.securitySolution.containers.anomalies.stackByJobId": "ジョブ", @@ -13459,14 +15643,33 @@ "xpack.securitySolution.containers.case.deletedCases": "{totalCases, plural, =1 {\"{caseTitle}\"} other {{totalCases}件のケース}}を削除しました", "xpack.securitySolution.containers.case.errorDeletingTitle": "データの削除エラー", "xpack.securitySolution.containers.case.errorTitle": "データの取得中にエラーが発生", + "xpack.securitySolution.containers.case.pushToExternalService": "{ serviceName }への送信が正常に完了しました", "xpack.securitySolution.containers.case.reopenedCases": "{totalCases, plural, =1 {\"{caseTitle}\"} other {{totalCases}件のケース}}を再オープンしました", "xpack.securitySolution.containers.case.updatedCase": "\"{caseTitle}\"を更新しました", "xpack.securitySolution.containers.detectionEngine.addRuleFailDescription": "ルールを追加できませんでした", + "xpack.securitySolution.containers.detectionEngine.alerts.createListsIndex.errorDescription": "リストインデックスを作成できませんでした", + "xpack.securitySolution.containers.detectionEngine.alerts.errorFetchingAlertsDescription": "アラートをクエリできませんでした", + "xpack.securitySolution.containers.detectionEngine.alerts.errorGetAlertDescription": "シグナルインデックス名を取得できませんでした", + "xpack.securitySolution.containers.detectionEngine.alerts.errorPostAlertDescription": "シグナルインデックスを作成できませんでした", + "xpack.securitySolution.containers.detectionEngine.alerts.fetchListsIndex.errorDescription": "リストインデックスを取得できませんでした", + "xpack.securitySolution.containers.detectionEngine.alerts.readListsPrivileges.errorDescription": "リスト権限を取得できませんでした", + "xpack.securitySolution.containers.detectionEngine.createPrePackagedRuleAndTimelineFailDescription": "Elasticから事前にパッケージ化されているルールとタイムラインをインストールすることができませんでした", + "xpack.securitySolution.containers.detectionEngine.createPrePackagedRuleAndTimelineSuccesDescription": "Elasticから事前にパッケージ化されているルールとタイムラインをインストールしました", + "xpack.securitySolution.containers.detectionEngine.rulesAndTimelines": "ルールとタイムラインを取得できませんでした", "xpack.securitySolution.containers.detectionEngine.tagFetchFailDescription": "タグを取得できませんでした", "xpack.securitySolution.containers.errors.dataFetchFailureTitle": "データの取得に失敗", "xpack.securitySolution.containers.errors.networkFailureTitle": "ネットワーク障害", "xpack.securitySolution.containers.errors.stopJobFailureTitle": "ジョブ停止エラー", + "xpack.securitySolution.customizeEventRenderers.customizeEventRenderersDescription": "イベントレンダラーは、イベントで最も関連性が高い詳細情報を自動的に表示し、ストーリーを明らかにします", + "xpack.securitySolution.customizeEventRenderers.customizeEventRenderersTitle": "イベントレンダラーのカスタマイズ", + "xpack.securitySolution.customizeEventRenderers.disableAllRenderersButtonLabel": "すべて無効にする", + "xpack.securitySolution.customizeEventRenderers.enableAllRenderersButtonLabel": "すべて有効にする", + "xpack.securitySolution.customizeEventRenderers.eventRenderersTitle": "イベントレンダラー", + "xpack.securitySolution.dataProviders.addFieldPopoverButtonLabel": "フィールドの追加", + "xpack.securitySolution.dataProviders.addTemplateFieldPopoverButtonLabel": "テンプレートフィールドの追加", "xpack.securitySolution.dataProviders.and": "AND", + "xpack.securitySolution.dataProviders.convertToFieldLabel": "フィールドに変換", + "xpack.securitySolution.dataProviders.convertToTemplateFieldLabel": "テンプレートフィールドに変換", "xpack.securitySolution.dataProviders.copyToClipboardTooltip": "クリップボードにコピー", "xpack.securitySolution.dataProviders.deleteDataProvider": "削除", "xpack.securitySolution.dataProviders.dropAnything": "何でもドロップできます", @@ -13478,7 +15681,7 @@ "xpack.securitySolution.dataProviders.excludeDataProvider": "結果を除外", "xpack.securitySolution.dataProviders.existsLabel": "存在する", "xpack.securitySolution.dataProviders.fieldLabel": "フィールド", - "xpack.securitySolution.dataProviders.filterForFieldPresentLabel": "現在のフィールドのフィルター", + "xpack.securitySolution.dataProviders.filterForFieldPresentLabel": "フィールド表示のフィルター", "xpack.securitySolution.dataProviders.hereToBuildAn": "して開発", "xpack.securitySolution.dataProviders.highlighted": "ハイライト", "xpack.securitySolution.dataProviders.includeDataProvider": "結果を含める", @@ -13488,43 +15691,106 @@ "xpack.securitySolution.dataProviders.reEnableDataProvider": "再度有効にする", "xpack.securitySolution.dataProviders.removeDataProvider": "データプロバイダーを削除", "xpack.securitySolution.dataProviders.showOptionsDataProvider": "次のオプションを表示:", + "xpack.securitySolution.dataProviders.templateFieldLabel": "テンプレートフィールド", "xpack.securitySolution.dataProviders.temporaryDisableDataProvider": "一時的に無効にする", "xpack.securitySolution.dataProviders.toBuildAn": "して開発", "xpack.securitySolution.dataProviders.toggle": "切り替え", "xpack.securitySolution.dataProviders.valueAriaLabel": "値", "xpack.securitySolution.dataProviders.valuePlaceholder": "値", + "xpack.securitySolution.detectionEngine.alerts.actions.addEndpointException": "エンドポイント例外の追加", + "xpack.securitySolution.detectionEngine.alerts.actions.addException": "例外の追加", + "xpack.securitySolution.detectionEngine.alerts.actions.closeAlertTitle": "アラートを閉じる", + "xpack.securitySolution.detectionEngine.alerts.actions.inProgressAlertTitle": "実行中に設定", + "xpack.securitySolution.detectionEngine.alerts.actions.investigateInTimelineTitle": "タイムラインで調査", + "xpack.securitySolution.detectionEngine.alerts.actions.openAlertTitle": "アラートを開く", + "xpack.securitySolution.detectionEngine.alerts.closedAlertFailedToastMessage": "アラートをクローズできませんでした。", + "xpack.securitySolution.detectionEngine.alerts.closedAlertsTitle": "終了", + "xpack.securitySolution.detectionEngine.alerts.closedAlertSuccessToastMessage": "{totalAlerts} {totalAlerts, plural, =1 {件のアラート} other {件のアラート}}を正常にクローズしました。", + "xpack.securitySolution.detectionEngine.alerts.documentTypeTitle": "アラート", + "xpack.securitySolution.detectionEngine.alerts.histogram.allOthersGroupingLabel": "その他すべて", + "xpack.securitySolution.detectionEngine.alerts.histogram.headerTitle": "傾向", + "xpack.securitySolution.detectionEngine.alerts.histogram.showingAlertsTitle": "{modifier}{totalAlertsFormatted} {totalAlerts, plural, =1 {件のアラート} other {件のアラート}}を表示しています", + "xpack.securitySolution.detectionEngine.alerts.histogram.stackByOptions.destinationIpsDropDown": "上位のデスティネーションIP", + "xpack.securitySolution.detectionEngine.alerts.histogram.stackByOptions.eventActionsDropDown": "上位のイベントアクション", + "xpack.securitySolution.detectionEngine.alerts.histogram.stackByOptions.eventCategoriesDropDown": "上位のイベントカテゴリー", + "xpack.securitySolution.detectionEngine.alerts.histogram.stackByOptions.hostNamesDropDown": "上位のホスト名", + "xpack.securitySolution.detectionEngine.alerts.histogram.stackByOptions.riskScoresDropDown": "リスクスコア", + "xpack.securitySolution.detectionEngine.alerts.histogram.stackByOptions.rulesDropDown": "上位のルール", + "xpack.securitySolution.detectionEngine.alerts.histogram.stackByOptions.ruleTypesDropDown": "上位のルールタイプ", + "xpack.securitySolution.detectionEngine.alerts.histogram.stackByOptions.severitiesDropDown": "重要度", + "xpack.securitySolution.detectionEngine.alerts.histogram.stackByOptions.sourceIpsDropDown": "上位のソースIP", + "xpack.securitySolution.detectionEngine.alerts.histogram.stackByOptions.stackByLabel": "積み上げ", + "xpack.securitySolution.detectionEngine.alerts.histogram.stackByOptions.usersDropDown": "上位のユーザー", + "xpack.securitySolution.detectionEngine.alerts.histogram.topNLabel": "トップ{fieldName}", + "xpack.securitySolution.detectionEngine.alerts.histogram.viewAlertsButtonLabel": "アラートを表示", + "xpack.securitySolution.detectionEngine.alerts.inProgressAlertFailedToastMessage": "アラートを実行中に設定できませんでした", + "xpack.securitySolution.detectionEngine.alerts.inProgressAlertsTitle": "進行中", + "xpack.securitySolution.detectionEngine.alerts.inProgressAlertSuccessToastMessage": "{totalAlerts} {totalAlerts, plural, =1 {件のアラート} other {件のアラート}}を実行中に設定しました。", + "xpack.securitySolution.detectionEngine.alerts.loadingAlertsTitle": "アラートを読み込んでいます", + "xpack.securitySolution.detectionEngine.alerts.openAlertsTitle": "開く", + "xpack.securitySolution.detectionEngine.alerts.openedAlertFailedToastMessage": "アラートを開けませんでした", + "xpack.securitySolution.detectionEngine.alerts.openedAlertSuccessToastMessage": "{totalAlerts} {totalAlerts, plural, =1 {件のアラート} other {件のアラート}}を正常に開きました。", + "xpack.securitySolution.detectionEngine.alerts.totalCountOfAlertsTitle": "アラートが検索条件に一致します", + "xpack.securitySolution.detectionEngine.alerts.utilityBar.additionalFiltersActions.showBuildingBlockTitle": "基本アラートを含める", + "xpack.securitySolution.detectionEngine.alerts.utilityBar.additionalFiltersTitle": "追加のフィルター", + "xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.closeSelectedTitle": "選択した項目を閉じる", + "xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.inProgressSelectedTitle": "実行中に設定", + "xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.openSelectedTitle": "選択した項目を開く", + "xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.viewSelectedInHostsTitle": "ホストで選択した項目を表示", + "xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.viewSelectedInNetworkTitle": "ネットワークで選択した項目を表示", + "xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.viewSelectedInTimelineTitle": "タイムラインで選択した項目を表示", + "xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActionsTitle": "バッチ処理", + "xpack.securitySolution.detectionEngine.alerts.utilityBar.clearSelectionTitle": "選択した項目をクリア", + "xpack.securitySolution.detectionEngine.alerts.utilityBar.selectAllAlertsTitle": "すべての{totalAlertsFormatted} {totalAlerts, plural, =1 {件のアラート} other {件のアラート}}を選択", + "xpack.securitySolution.detectionEngine.alerts.utilityBar.selectedAlertsTitle": "Selected {selectedAlertsFormatted} {selectedAlerts, plural, =1 {件のアラート} other {件のアラート}}", + "xpack.securitySolution.detectionEngine.alerts.utilityBar.showingAlertsTitle": "すべての{totalAlertsFormatted} {totalAlerts, plural, =1 {件のアラート} other {件のアラート}}を表示しています", + "xpack.securitySolution.detectionEngine.alerts.utilityBar.takeActionTitle": "アクションを実行", "xpack.securitySolution.detectionEngine.alertTitle": "外部アラート", - "xpack.securitySolution.detectionEngine.buttonManageRules": "シグナル検出ルールの管理", + "xpack.securitySolution.detectionEngine.buttonManageRules": "検出ルールの管理", "xpack.securitySolution.detectionEngine.components.importRuleModal.cancelTitle": "キャンセル", "xpack.securitySolution.detectionEngine.components.importRuleModal.importFailedDetailedTitle": "ルールID: {ruleId}\n ステータスコード: {statusCode}\n メッセージ: {message}", "xpack.securitySolution.detectionEngine.components.importRuleModal.importFailedTitle": "ルールをインポートできませんでした", "xpack.securitySolution.detectionEngine.components.importRuleModal.importRuleTitle": "ルールのインポート", "xpack.securitySolution.detectionEngine.components.importRuleModal.initialPromptTextDescription": "有効なrules_export.ndjsonファイルを選択するか、ドラッグしてドロップします", "xpack.securitySolution.detectionEngine.components.importRuleModal.overwriteDescription": "保存されたオブジェクトを同じルールIDで自動的に上書きします", - "xpack.securitySolution.detectionEngine.components.importRuleModal.selectRuleDescription": "インポートする Security ルール (検出エンジンビューからエクスポートしたもの) を選択します", + "xpack.securitySolution.detectionEngine.components.importRuleModal.selectRuleDescription": "インポートするセキュリティルール(検出エンジンビューからエクスポートしたもの)を選択します", "xpack.securitySolution.detectionEngine.components.importRuleModal.successfullyImportedRulesTitle": "{totalRules} {totalRules, plural, =1 {ルール} other {ルール}}を正常にインポートしました", "xpack.securitySolution.detectionEngine.createRule. stepScheduleRule.completeWithActivatingTitle": "ルールの作成と有効化", "xpack.securitySolution.detectionEngine.createRule. stepScheduleRule.completeWithoutActivatingTitle": "有効化せずにルールを作成", - "xpack.securitySolution.detectionEngine.createRule.backToRulesDescription": "シグナル検出ルールに戻る", + "xpack.securitySolution.detectionEngine.createRule.backToRulesDescription": "検出ルールに戻る", "xpack.securitySolution.detectionEngine.createRule.editRuleButton": "編集", "xpack.securitySolution.detectionEngine.createRule.filtersLabel": "フィルター", "xpack.securitySolution.detectionEngine.createRule.mlRuleTypeDescription": "機械学習", - "xpack.securitySolution.detectionEngine.createRule.pageTitle": "新規ジョブを作成", + "xpack.securitySolution.detectionEngine.createRule.pageTitle": "新規ルールを作成", "xpack.securitySolution.detectionEngine.createRule.QueryLabel": "カスタムクエリ", "xpack.securitySolution.detectionEngine.createRule.queryRuleTypeDescription": "クエリ", + "xpack.securitySolution.detectionEngine.createRule.ruleActionsField.ruleActionsFormErrorsTitle": "次の一覧の問題を解決してください", "xpack.securitySolution.detectionEngine.createRule.savedIdLabel": "保存されたクエリ名", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.descriptionFieldRequiredError": "説明が必要です。", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fiedIndexPatternsLabel": "インデックスパターン", + "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldAssociatedToEndpointListLabel": "ルールをグローバルエンドポイント例外リストに関連付ける", + "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldAuthorHelpText": "このルールの作成者を1つ以上入力します。新しい作成者を追加するには、各作成者の後でEnterを押します。", + "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldAuthorLabel": "作成者", + "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldBuildingBlockLabel": "すべての生成されたアラートを「基本」アラートに設定", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldDescriptionLabel": "説明", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldFalsePositiveLabel": "誤検出の例", + "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldLicenseHelpText": "ライセンス名を追加", + "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldLicenseLabel": "ライセンス", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldMitreThreatLabel": "MITRE ATT&CK\\u2122", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldNameLabel": "名前", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldReferenceUrlsLabel": "参照URL", + "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldRuleNameOverrideHelpText": "ソースイベントからフィールドを選択し、アラートリストのルール名を入力します。", + "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldRuleNameOverrideLabel": "ルール名無効化", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldTagsHelpText": "このルールの1つ以上のカスタム識別タグを入力します。新しいタグを開始するには、各タグの後でEnterを押します。", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldTagsLabel": "タグ", - "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldTimelineTemplateHelpText": "生成されたシグナルを調査するときにテンプレートとして使用する既存のタイムラインを選択します。", + "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldThresholdFieldHelpText": "結果をグループ化するフィールドを選択します", + "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldThresholdFieldLabel": "フィールド", + "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldThresholdValueLabel": "しきい値", + "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldTimelineTemplateHelpText": "生成されたアラートを調査するときに使用するタイムラインを選択します。", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldTimelineTemplateLabel": "タイムラインテンプレート", - "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.guideHelpText": "シグナル調査を実施するアナリストに役立つ情報を提供します。このガイドは、ルールの詳細ページとこのルールで生成されたシグナルから作成されたタイムラインの両方に表示されます。", + "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldTimestampOverrideHelpText": "ルールを実行するときに使用されるタイムスタンプフィールドを選択します。入力時間(例:event.ingested)に最も近いタイムスタンプのフィールドを選択します。", + "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldTimestampOverrideLabel": "タイムスタンプ無効化", + "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.guideHelpText": "シグナル調査を実施するアナリストに役立つ情報を提供します。このガイドは、ルールの詳細ページとこのルールで生成されたアラートから作成されたタイムラインの両方に表示されます。", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.guideLabel": "調査ガイド", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.nameFieldRequiredError": "名前が必要です。", "xpack.securitySolution.detectionEngine.createRule.stepAboutrule.noteHelpText": "ルール調査ガイドを追加...", @@ -13532,6 +15798,8 @@ "xpack.securitySolution.detectionEngine.createRule.stepAboutRuleForm.addFalsePositiveDescription": "誤検出の例を追加します", "xpack.securitySolution.detectionEngine.createRule.stepAboutRuleForm.addReferenceDescription": "参照URLを追加します", "xpack.securitySolution.detectionEngine.createRule.stepAboutRuleForm.advancedSettingsButton": "高度な設定", + "xpack.securitySolution.detectionEngine.createRule.stepAboutRuleForm.buildingBlockLabel": "基本", + "xpack.securitySolution.detectionEngine.createRule.stepAboutRuleForm.endpointExceptionListLabel": "グローバルエンドポイント例外リスト", "xpack.securitySolution.detectionEngine.createRule.stepAboutRuleForm.severityOptionCriticalDescription": "重大", "xpack.securitySolution.detectionEngine.createRule.stepAboutRuleForm.severityOptionHighDescription": "高", "xpack.securitySolution.detectionEngine.createRule.stepAboutRuleForm.severityOptionLowDescription": "低", @@ -13543,11 +15811,12 @@ "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.fieldMachineLearningJobIdLabel": "機械学習ジョブ", "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.fieldQuerBarLabel": "カスタムクエリ", "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.fieldRuleTypeLabel": "ルールタイプ", + "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.fieldThresholdLabel": "しきい値", "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.importTimelineModalTitle": "保存されたタイムラインからクエリをインポート", "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.importTimelineQueryButton": "保存されたタイムラインからクエリをインポート", "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.indicesCustomDescription": "インデックスのカスタムリストを入力します", - "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.indicesFromConfigDescription": "SIEM詳細設定からElasticsearchインデックスを使用します", - "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.indicesHelperDescription": "このルールを実行するElasticsearchインデックスのパターンを入力しますデフォルトでは、SIEM詳細設定で定義されたインデックスパターンが含まれます。", + "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.indicesFromConfigDescription": "セキュリティソリューション詳細設定からElasticsearchインデックスを使用します", + "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.indicesHelperDescription": "このルールを実行するElasticsearchインデックスのパターンを入力しますデフォルトでは、セキュリティソリューション詳細設定で定義されたインデックスパターンが含まれます。", "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.machineLearningJobIdHelpText": "手始めに使えるように、一般的なジョブがいくつか提供されています。独自のカスタムジョブを追加するには、{machineLearning} アプリケーションでジョブに「siem」のグループを割り当て、ここに表示されるようにします。", "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.machineLearningJobIdRequired": "機械学習ジョブが必要です。", "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.mlEnableJobWarningTitle": "このMLジョブは現在実行されていません。このルールを有効にする前に、このジョブを「MLジョブ設定」で実行するように設定してください。", @@ -13560,33 +15829,42 @@ "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.ruleTypeField.mlTypeTitle": "機械学習", "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.ruleTypeField.queryTypeDescription": "KQL または Lucene を使用して、インデックス全体にわたる問題を検出します。", "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.ruleTypeField.queryTypeTitle": "カスタムクエリ", + "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.ruleTypeField.thresholdTypeDescription": "クエリ結果を集約し、いつ一致数がしきい値を超えるのかを検出します。", + "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.ruleTypeField.thresholdTypeTitle": "しきい値", + "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.thresholdField.thresholdFieldPlaceholderText": "すべての結果", "xpack.securitySolution.detectionEngine.createRule.stepRuleActions.fieldThrottleHelpText": "ルールが true であると評価された場合に自動アクションを実行するタイミングを選択します。", "xpack.securitySolution.detectionEngine.createRule.stepRuleActions.fieldThrottleLabel": "アクション頻度", - "xpack.securitySolution.detectionEngine.createRule.stepScheduleRule.fieldAdditionalLookBackHelpText": "ルックバック期間に時間を追加してシグナルの見落としを防ぐ。", + "xpack.securitySolution.detectionEngine.createRule.stepRuleActions.invalidMustacheTemplateErrorMessage": "{key}は有効なmustacheテンプレートではありません", + "xpack.securitySolution.detectionEngine.createRule.stepRuleActions.noConnectorSelectedErrorMessage": "コネクターを選択していません", + "xpack.securitySolution.detectionEngine.createRule.stepScheduleRule.completeWithActivatingTitle": "ルールの作成と有効化", + "xpack.securitySolution.detectionEngine.createRule.stepScheduleRule.completeWithoutActivatingTitle": "有効化せずにルールを作成", + "xpack.securitySolution.detectionEngine.createRule.stepScheduleRule.fieldAdditionalLookBackHelpText": "ルックバック期間に時間を追加してアラートの見落としを防ぎます。", "xpack.securitySolution.detectionEngine.createRule.stepScheduleRule.fieldAdditionalLookBackLabel": "追加のルックバック時間", - "xpack.securitySolution.detectionEngine.createRule.stepScheduleRule.fieldIntervalHelpText": "ルールは定期的に実行し、指定の時間枠内でシグナルを検出する。", + "xpack.securitySolution.detectionEngine.createRule.stepScheduleRule.fieldIntervalHelpText": "ルールを定期的に実行し、指定の時間枠内でアラートを検出します。", "xpack.securitySolution.detectionEngine.createRule.stepScheduleRule.fieldIntervalLabel": "次の間隔で実行", "xpack.securitySolution.detectionEngine.createRule.stepScheduleRuleForm.hoursOptionDescription": "時間", "xpack.securitySolution.detectionEngine.createRule.stepScheduleRuleForm.invalidTimeMessageDescription": "時間が必要です。", "xpack.securitySolution.detectionEngine.createRule.stepScheduleRuleForm.minutesOptionDescription": "分", "xpack.securitySolution.detectionEngine.createRule.stepScheduleRuleForm.secondsOptionDescription": "秒", + "xpack.securitySolution.detectionEngine.createRule.thresholdRuleTypeDescription": "しきい値", "xpack.securitySolution.detectionEngine.details.stepAboutRule.aboutText": "概要", "xpack.securitySolution.detectionEngine.details.stepAboutRule.detailsLabel": "詳細", "xpack.securitySolution.detectionEngine.details.stepAboutRule.investigationGuideLabel": "調査ガイド", - "xpack.securitySolution.detectionEngine.detectionsPageTitle": "検出", + "xpack.securitySolution.detectionEngine.detectionsPageTitle": "検出アラート", "xpack.securitySolution.detectionEngine.dismissButton": "閉じる", "xpack.securitySolution.detectionEngine.dismissNoApiIntegrationKeyButton": "閉じる", + "xpack.securitySolution.detectionEngine.dismissNoWriteAlertButton": "閉じる", "xpack.securitySolution.detectionEngine.editRule.backToDescription": "戻る", "xpack.securitySolution.detectionEngine.editRule.cancelTitle": "キャンセル", "xpack.securitySolution.detectionEngine.editRule.errorMsgDescription": "申し訳ありません", "xpack.securitySolution.detectionEngine.editRule.pageTitle": "ルール設定の編集", "xpack.securitySolution.detectionEngine.editRule.saveChangeTitle": "変更を保存", - "xpack.securitySolution.detectionEngine.emptyActionPrimary": "セットアップの手順を表示", "xpack.securitySolution.detectionEngine.emptyActionSecondary": "ドキュメントに移動", - "xpack.securitySolution.detectionEngine.emptyTitle": "Securityアプリケーションの検出エンジンに関連したインデックスがないようです", + "xpack.securitySolution.detectionEngine.emptyTitle": "セキュリティアプリケーションの検出エンジンに関連したインデックスがないようです", "xpack.securitySolution.detectionEngine.goToDocumentationButton": "ドキュメンテーションを表示", "xpack.securitySolution.detectionEngine.headerPage.pageBadgeLabel": "ベータ", - "xpack.securitySolution.detectionEngine.headerPage.pageBadgeTooltip": "検出はまだベータ段階です。Kibana repoで問題やバグを報告して、製品の改善にご協力ください。", + "xpack.securitySolution.detectionEngine.headerPage.pageBadgeTooltip": "アラートはまだベータ段階です。Kibana repoで問題や不具合を報告して製品の改善にご協力ください。", + "xpack.securitySolution.detectionEngine.lastSignalTitle": "前回のアラート", "xpack.securitySolution.detectionEngine.mitreAttack.addTitle": "MITRE ATT&CK\\u2122脅威を追加", "xpack.securitySolution.detectionEngine.mitreAttack.tacticPlaceHolderDescription": "Tacticを追加...", "xpack.securitySolution.detectionEngine.mitreAttack.tacticsDescription": "Tactic", @@ -13609,8 +15887,8 @@ "xpack.securitySolution.detectionEngine.mitreAttackTechniques.accountAccessRemovalDescription": "アカウントアクセス削除(T1531)", "xpack.securitySolution.detectionEngine.mitreAttackTechniques.accountDiscoveryDescription": "アカウント検出(T1087)", "xpack.securitySolution.detectionEngine.mitreAttackTechniques.accountManipulationDescription": "アカウント操作(T1098)", - "xpack.securitySolution.detectionEngine.mitreAttackTechniques.appCertDlLsDescription": "AppCert DLL (T1182)", - "xpack.securitySolution.detectionEngine.mitreAttackTechniques.appInitDlLsDescription": "AppInit DLL (T1103)", + "xpack.securitySolution.detectionEngine.mitreAttackTechniques.appCertDlLsDescription": "AppCert DLLs (T1182)", + "xpack.securitySolution.detectionEngine.mitreAttackTechniques.appInitDlLsDescription": "AppInit DLLs (T1103)", "xpack.securitySolution.detectionEngine.mitreAttackTechniques.appleScriptDescription": "AppleScript (T1155)", "xpack.securitySolution.detectionEngine.mitreAttackTechniques.applicationAccessTokenDescription": "アプリケーションアクセストークン(T1527)", "xpack.securitySolution.detectionEngine.mitreAttackTechniques.applicationDeploymentSoftwareDescription": "アプリケーション開発ソフトウェア(T1017)", @@ -13621,7 +15899,7 @@ "xpack.securitySolution.detectionEngine.mitreAttackTechniques.automatedCollectionDescription": "自動収集(T1119)", "xpack.securitySolution.detectionEngine.mitreAttackTechniques.automatedExfiltrationDescription": "自動抽出(T1020)", "xpack.securitySolution.detectionEngine.mitreAttackTechniques.bashHistoryDescription": "Bash履歴(T1139)", - "xpack.securitySolution.detectionEngine.mitreAttackTechniques.bashProfileAndBashrcDescription": ".bash_profileおよび.bashrc (T1156)", + "xpack.securitySolution.detectionEngine.mitreAttackTechniques.bashProfileAndBashrcDescription": ".bash_profile and .bashrc (T1156)", "xpack.securitySolution.detectionEngine.mitreAttackTechniques.binaryPaddingDescription": "バイナリパディング(T1009)", "xpack.securitySolution.detectionEngine.mitreAttackTechniques.bitsJobsDescription": "BITSジョブ(T1197)", "xpack.securitySolution.detectionEngine.mitreAttackTechniques.bootkitDescription": "Bootkit (T1067)", @@ -13632,9 +15910,9 @@ "xpack.securitySolution.detectionEngine.mitreAttackTechniques.changeDefaultFileAssociationDescription": "デフォルトファイル関連付けの変更(T1042)", "xpack.securitySolution.detectionEngine.mitreAttackTechniques.clearCommandHistoryDescription": "コマンド履歴の消去(T1146)", "xpack.securitySolution.detectionEngine.mitreAttackTechniques.clipboardDataDescription": "クリップボードデータ(T1115)", - "xpack.securitySolution.detectionEngine.mitreAttackTechniques.cloudInstanceMetadataApiDescription": "クラウドインスタンスメタデータAPI (T1522)", + "xpack.securitySolution.detectionEngine.mitreAttackTechniques.cloudInstanceMetadataApiDescription": "Cloud Instance Metadata API (T1522)", "xpack.securitySolution.detectionEngine.mitreAttackTechniques.cloudServiceDashboardDescription": "クラウドサービスダッシュボード(T1538)", - "xpack.securitySolution.detectionEngine.mitreAttackTechniques.cloudServiceDiscoveryDescription": "クラウドサービス検出(T1526)", + "xpack.securitySolution.detectionEngine.mitreAttackTechniques.cloudServiceDiscoveryDescription": "Cloud Service Discovery (T1526)", "xpack.securitySolution.detectionEngine.mitreAttackTechniques.cmstpDescription": "CMSTP (T1191)", "xpack.securitySolution.detectionEngine.mitreAttackTechniques.codeSigningDescription": "コード署名(T1116)", "xpack.securitySolution.detectionEngine.mitreAttackTechniques.commandLineInterfaceDescription": "コマンドラインインターフェース(T1059)", @@ -13737,7 +16015,7 @@ "xpack.securitySolution.detectionEngine.mitreAttackTechniques.launchctlDescription": "Launchctl (T1152)", "xpack.securitySolution.detectionEngine.mitreAttackTechniques.launchDaemonDescription": "デーモンの起動(T1160)", "xpack.securitySolution.detectionEngine.mitreAttackTechniques.lcLoadDylibAdditionDescription": "LC_LOAD_DYLIB追加(T1161)", - "xpack.securitySolution.detectionEngine.mitreAttackTechniques.lcMainHijackingDescription": "LC_MAINハイジャック(T1149)", + "xpack.securitySolution.detectionEngine.mitreAttackTechniques.lcMainHijackingDescription": "LC_MAIN Hijacking (T1149)", "xpack.securitySolution.detectionEngine.mitreAttackTechniques.llmnrNbtNsPoisoningAndRelayDescription": "LLMNR/NBT-NSポイズニングおよびリレー(T1171)", "xpack.securitySolution.detectionEngine.mitreAttackTechniques.localJobSchedulingDescription": "ローカルジョブスケジュール(T1168)", "xpack.securitySolution.detectionEngine.mitreAttackTechniques.loginItemDescription": "ログイン項目(T1162)", @@ -13874,8 +16152,9 @@ "xpack.securitySolution.detectionEngine.mlUnavailableTitle": "{totalRules} {totalRules, plural, =1 {個のルール} other {個のルール}}で機械学習を有効にする必要があります。", "xpack.securitySolution.detectionEngine.noApiIntegrationKeyCallOutMsg": "Kibanaを起動するごとに保存されたオブジェクトの新しい暗号化キーを作成します。永続キーがないと、Kibanaの再起動後にルールを削除または修正することができません。永続キーを設定するには、kibana.ymlファイルに32文字以上のテキスト値を付けてxpack.encryptedSavedObjects.encryptionKey設定を追加してください。", "xpack.securitySolution.detectionEngine.noApiIntegrationKeyCallOutTitle": "API統合キーが必要です", - "xpack.securitySolution.detectionEngine.noIndexMsgBody": "検出エンジンを使用するには、必要なクラスターとインデックス権限のユーザーが最初にこのページにアクセスする必要があります。ヘルプについては、管理者にお問い合わせください。", "xpack.securitySolution.detectionEngine.noIndexTitle": "検出エンジンを設定しましょう", + "xpack.securitySolution.detectionEngine.noWriteAlertsCallOutMsg": "アラートを表示する権限のみが付与されています。アラート状態を更新(アラートを開く、アラートを閉じる)必要がある場合は、Kibana管理者に連絡してください。", + "xpack.securitySolution.detectionEngine.noWriteAlertsCallOutTitle": "アラート状態を変更することはできません", "xpack.securitySolution.detectionEngine.pageTitle": "検出エンジン", "xpack.securitySolution.detectionEngine.panelSubtitleShowing": "表示中", "xpack.securitySolution.detectionEngine.readOnlyCallOutMsg": "現在、検出エンジンルールを作成/編集するための必要な権限がありません。サポートについては、管理者にお問い合わせください。", @@ -13883,9 +16162,12 @@ "xpack.securitySolution.detectionEngine.rule.editRule.errorMsgDescription": "{countError, plural, one {このタブ} other {これらのタブ}}に無効な入力があります: {tabHasError}", "xpack.securitySolution.detectionEngine.ruleDescription.mlJobStartedDescription": "開始", "xpack.securitySolution.detectionEngine.ruleDescription.mlJobStoppedDescription": "停止", + "xpack.securitySolution.detectionEngine.ruleDescription.thresholdResultsAggregatedByDescription": "結果集約条件", + "xpack.securitySolution.detectionEngine.ruleDescription.thresholdResultsAllDescription": "すべての結果", "xpack.securitySolution.detectionEngine.ruleDetails.activateRuleLabel": "有効化", - "xpack.securitySolution.detectionEngine.ruleDetails.backToRulesDescription": "シグナル検出ルールに戻る", + "xpack.securitySolution.detectionEngine.ruleDetails.backToRulesDescription": "検出ルールに戻る", "xpack.securitySolution.detectionEngine.ruleDetails.errorCalloutTitle": "ルール失敗", + "xpack.securitySolution.detectionEngine.ruleDetails.exceptionsTab": "例外", "xpack.securitySolution.detectionEngine.ruleDetails.experimentalDescription": "実験的", "xpack.securitySolution.detectionEngine.ruleDetails.failureHistoryTab": "エラー履歴", "xpack.securitySolution.detectionEngine.ruleDetails.lastFiveErrorsTitle": "最後の5件のエラー", @@ -13947,6 +16229,7 @@ "xpack.securitySolution.detectionEngine.rules.allRules.tabs.monitoring": "監視", "xpack.securitySolution.detectionEngine.rules.allRules.tabs.rules": "ルール", "xpack.securitySolution.detectionEngine.rules.backOptionsHeader": "検出に戻る", + "xpack.securitySolution.detectionEngine.rules.components.genericDownloader.exportFailureTitle": "データをエクスポートできませんでした...", "xpack.securitySolution.detectionEngine.rules.components.ruleActionsOverflow.allActionsTitle": "すべてのアクション", "xpack.securitySolution.detectionEngine.rules.continueButtonTitle": "続行", "xpack.securitySolution.detectionEngine.rules.create.successfullyCreatedRuleTitle": "{ruleName}が作成されました", @@ -13954,15 +16237,17 @@ "xpack.securitySolution.detectionEngine.rules.deleteDescription": "削除", "xpack.securitySolution.detectionEngine.rules.editPageTitle": "編集", "xpack.securitySolution.detectionEngine.rules.importRuleTitle": "ルールのインポート...", - "xpack.securitySolution.detectionEngine.rules.loadPrePackagedRulesButton": "Elastic事前構築済みルールを読み込む", + "xpack.securitySolution.detectionEngine.rules.loadPrePackagedRulesButton": "Elastic事前構築済みルールおよびタイムラインテンプレートを読み込む", "xpack.securitySolution.detectionEngine.rules.optionalFieldDescription": "オプション", - "xpack.securitySolution.detectionEngine.rules.pageTitle": "シグナル検出ルール", + "xpack.securitySolution.detectionEngine.rules.pageTitle": "検出ルール", "xpack.securitySolution.detectionEngine.rules.prePackagedRules.createOwnRuletButton": "独自のルールの作成", - "xpack.securitySolution.detectionEngine.rules.prePackagedRules.emptyPromptMessage": "Elastic SIEMには、バックグラウンドで実行され、条件が合うとシグナルを作成する事前構築済み検出ルールがあります。デフォルトでは、すべての事前構築済みルールが無効化されていて、有効化したいルールを選択します。", + "xpack.securitySolution.detectionEngine.rules.prePackagedRules.emptyPromptMessage": "Elasticセキュリティには、バックグラウンドで実行され、条件が合うとアラートを作成する事前構築済み検出ルールがあります。デフォルトでは、すべての事前構築済みルールが無効化されていて、有効化したいルールを選択します。", "xpack.securitySolution.detectionEngine.rules.prePackagedRules.emptyPromptTitle": "Elastic事前構築済み検出ルールを読み込む", "xpack.securitySolution.detectionEngine.rules.prePackagedRules.loadPreBuiltButton": "事前構築済み検知ルールを読み込む", "xpack.securitySolution.detectionEngine.rules.releaseNotesHelp": "リリースノート", - "xpack.securitySolution.detectionEngine.rules.reloadMissingPrePackagedRulesButton": "{missingRules} Elasticのあらかじめ構築された{missingRules, plural, =1 {個のルール} other {個のルール}}をインストール ", + "xpack.securitySolution.detectionEngine.rules.reloadMissingPrePackagedRulesAndTimelinesButton": "{missingRules} Elastic事前構築済み{missingRules, plural, =1 {ルール} other {ルール}}と{missingTimelines} Elastic事前構築済み{missingTimelines, plural, =1 {タイムライン} other {タイムライン}}をインストール ", + "xpack.securitySolution.detectionEngine.rules.reloadMissingPrePackagedRulesButton": "{missingRules} Elasticの事前構築済みの{missingRules, plural, =1 {個のルール} other {個のルール}}をインストール ", + "xpack.securitySolution.detectionEngine.rules.reloadMissingPrePackagedTimelinesButton": "{missingTimelines} Elasticの事前構築済みの{missingTimelines, plural, =1 {個のタイムライン} other {個のタイムライン}}をインストール ", "xpack.securitySolution.detectionEngine.rules.ruleActionsTitle": "ルールアクション", "xpack.securitySolution.detectionEngine.rules.scheduleRuleTitle": "ルールのスケジュール", "xpack.securitySolution.detectionEngine.rules.stepAboutTitle": "概要", @@ -13971,14 +16256,20 @@ "xpack.securitySolution.detectionEngine.rules.stepScheduleTitle": "スケジュール", "xpack.securitySolution.detectionEngine.rules.update.successfullySavedRuleTitle": "{ruleName}が保存されました", "xpack.securitySolution.detectionEngine.rules.updateButtonTitle": "更新", - "xpack.securitySolution.detectionEngine.rules.updatePrePackagedRulesButton": "{updateRules} Elastic事前再構築済み{updateRules, plural, =1 {rule} other {rules}}を更新する ", - "xpack.securitySolution.detectionEngine.rules.updatePrePackagedRulesMsg": "{updateRules} Elastic事前再構築済み{updateRules, plural, =1 {rule} other {rules}}を更新することができます。これにより、削除されたElastic事前再構築済みルールが再読み込みされます。", - "xpack.securitySolution.detectionEngine.rules.updatePrePackagedRulesTitle": "Elastic事前構築済みルールを更新することができません", + "xpack.securitySolution.detectionEngine.rules.updatePrePackagedRulesAndTimelinesButton": "{updateRules} Elasticの事前構築済みの{updateRules, plural, =1 {個のルール} other {個のルール}}と{updateTimelines} Elasticの事前構築済みの{updateTimelines, plural, =1 {個のタイムライン} other {個のタイムライン}}を更新", + "xpack.securitySolution.detectionEngine.rules.updatePrePackagedRulesAndTimelinesMsg": "{updateRules} Elasticの事前構築済みの{updateRules, plural, =1 {個のルール} other {個のルール}}と{updateTimelines} Elasticの事前構築済みの{updateTimelines, plural, =1 {個のタイムライン} other {個のタイムライン}}を更新できます。これにより、削除されたElastic事前構築済みルールが再読み込みされます。", + "xpack.securitySolution.detectionEngine.rules.updatePrePackagedRulesButton": "{updateRules} Elastic事前構築済み{updateRules, plural, =1 {rule} other {rules}}を更新する", + "xpack.securitySolution.detectionEngine.rules.updatePrePackagedRulesMsg": "{updateRules} Elastic事前構築済み{updateRules, plural, =1 {ルール} other {ルール}}を更新することができます", + "xpack.securitySolution.detectionEngine.rules.updatePrePackagedRulesTitle": "Elastic事前構築済みルールまたはタイムラインテンプレートを更新", + "xpack.securitySolution.detectionEngine.rules.updatePrePackagedTimelinesButton": "{updateTimelines} Elastic事前構築済み{updateTimelines, plural, =1 {タイムライン} other {タイムライン}}を更新", + "xpack.securitySolution.detectionEngine.rules.updatePrePackagedTimelinesMsg": "{updateTimelines} Elastic事前構築済み{updateTimelines, plural, =1 {タイムライン} other {タイムライン}}を更新できます。", "xpack.securitySolution.detectionEngine.ruleStatus.refreshButton": "更新", "xpack.securitySolution.detectionEngine.ruleStatus.statusAtDescription": "に", "xpack.securitySolution.detectionEngine.ruleStatus.statusDateDescription": "ステータス日付", "xpack.securitySolution.detectionEngine.ruleStatus.statusDescription": "前回の応答", "xpack.securitySolution.detectionEngine.signalRuleAlert.actionGroups.default": "デフォルト", + "xpack.securitySolution.detectionEngine.signalTitle": "検出されたアラート", + "xpack.securitySolution.detectionEngine.totalSignalTitle": "合計", "xpack.securitySolution.detectionEngine.userUnauthenticatedMsgBody": "検出エンジンを表示するための必要なアクセス権がありません。ヘルプについては、管理者にお問い合わせください。", "xpack.securitySolution.detectionEngine.userUnauthenticatedTitle": "検出エンジンアクセス権が必要です", "xpack.securitySolution.dragAndDrop.addToTimeline": "タイムライン調査に追加", @@ -13991,10 +16282,10 @@ "xpack.securitySolution.draggables.field.fieldLabel": "フィールド", "xpack.securitySolution.draggables.field.typeLabel": "タイプ", "xpack.securitySolution.draggables.field.viewCategoryTooltip": "カテゴリーを表示します", - "xpack.securitySolution.editDataProvider.doesNotExistLabel": "存在しません", + "xpack.securitySolution.editDataProvider.doesNotExistLabel": "存在しない", "xpack.securitySolution.editDataProvider.existsLabel": "存在する", "xpack.securitySolution.editDataProvider.fieldLabel": "フィールド", - "xpack.securitySolution.editDataProvider.isLabel": "が", + "xpack.securitySolution.editDataProvider.isLabel": "is", "xpack.securitySolution.editDataProvider.isNotLabel": "is not", "xpack.securitySolution.editDataProvider.operatorLabel": "演算子", "xpack.securitySolution.editDataProvider.placeholder": "フィールドを選択", @@ -14002,7 +16293,201 @@ "xpack.securitySolution.editDataProvider.selectAnOperatorPlaceholder": "演算子を選択", "xpack.securitySolution.editDataProvider.valueLabel": "値", "xpack.securitySolution.editDataProvider.valuePlaceholder": "値", + "xpack.securitySolution.emptyMessage": "Elastic セキュリティは無料かつオープンのElastic SIEMに、Elastic Endpointを搭載。脅威の防御と検知、脅威への対応を支援します。開始するには、セキュリティソリューション関連データをElastic Stackに追加する必要があります。詳細については、ご覧ください ", "xpack.securitySolution.emptyString.emptyStringDescription": "空の文字列", + "xpack.securitySolution.endpoint.host.details.endpointVersion": "エンドポイントバージョン", + "xpack.securitySolution.endpoint.host.details.errorBody": "フライアウトを終了して、利用可能なホストを選択してください。", + "xpack.securitySolution.endpoint.host.details.errorTitle": "ホストが見つかりませんでした", + "xpack.securitySolution.endpoint.host.details.hostname": "ホスト名", + "xpack.securitySolution.endpoint.host.details.ipAddress": "IP アドレス", + "xpack.securitySolution.endpoint.host.details.lastSeen": "前回の認識", + "xpack.securitySolution.endpoint.host.details.linkToIngestTitle": "ポリシーの再割り当て", + "xpack.securitySolution.endpoint.host.details.os": "OS", + "xpack.securitySolution.endpoint.host.details.policy": "ポリシー", + "xpack.securitySolution.endpoint.host.details.policyStatus": "ポリシーステータス", + "xpack.securitySolution.endpoint.host.details.policyStatusValue": "{policyStatus, select, success {成功} warning {警告} failure {失敗} other {不明}}", + "xpack.securitySolution.endpoint.host.policyResponse.backLinkTitle": "エンドポイント詳細", + "xpack.securitySolution.endpoint.host.policyResponse.title": "ポリシー応答", + "xpack.securitySolution.endpoint.hostDetails.noPolicyResponse": "ポリシー応答がありません", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_dns_events": "DNSイベントの構成", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_elasticsearch_connection": "Elastic Search接続の構成", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_file_events": "ファイルイベントの構成", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_imageload_events": "画像読み込みイベントの構成", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_kernel": "カーネルの構成", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_logging": "ロギングの構成", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_malware": "マルウェアの構成", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_network_events": "ネットワークイベントの構成", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_process_events": "プロセスイベントの構成", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_registry_events": "レジストリイベントの構成", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_security_events": "セキュリティイベントの構成", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.connect_kernel": "カーネルを接続", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.detect_async_image_load_events": "非同期画像読み込みイベントを検出", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.detect_file_open_events": "ファイルオープンイベントを検出", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.detect_file_write_events": "ファイル書き込みイベントを検出", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.detect_network_events": "ネットワークイベントを検出", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.detect_process_events": "プロセスイベントを検出", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.detect_registry_events": "レジストリイベントを検出", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.detect_sync_image_load_events": "同期画像読み込みイベントを検出", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.download_global_artifacts": "グローバルアーチファクトをダウンロード", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.download_user_artifacts": "ユーザーアーチファクトをダウンロード", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.events": "イベント", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.failed": "失敗", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.load_config": "構成の読み込み", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.load_malware_model": "マルウェアモデルの読み込み", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.logging": "ログ", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.malware": "マルウェア", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.read_elasticsearch_config": "Elasticsearch構成を読み取る", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.read_events_config": "イベント構成を読み取る", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.read_kernel_config": "カーネル構成を読み取る", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.read_logging_config": "ロギング構成を読み取る", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.read_malware_config": "マルウェア構成を読み取る", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.streaming": "ストリーム中…", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.success": "成功", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.warning": "警告", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.workflow": "ワークフロー", + "xpack.securitySolution.endpoint.hostList.beta": "ベータ", + "xpack.securitySolution.endpoint.hostList.loadingPolicies": "ポリシー構成を読み込んでいます…", + "xpack.securitySolution.endpoint.hostList.noEndpointsInstructions": "セキュリティポリシーを作成しました。以下のステップに従い、エージェントでElastic Endpoint Security機能を有効にする必要があります。", + "xpack.securitySolution.endpoint.hostList.noEndpointsPrompt": "エージェントでElastic Endpoint Securityを有効にする", + "xpack.securitySolution.endpoint.hostList.noPolicies": "ポリシーがありません。", + "xpack.securitySolution.endpoint.hostList.stepOne": "既存のポリシーは以下のリストのとおりです。これは後から変更できます。", + "xpack.securitySolution.endpoint.hostList.stepOneTitle": "ホストの保護で使用するポリシーを選択", + "xpack.securitySolution.endpoint.hostList.stepTwo": "開始するために必要なコマンドが提供されます。", + "xpack.securitySolution.endpoint.hostList.stepTwoTitle": "Ingest Manager経由でEndpoint Securityによって有効にされたエージェントを登録", + "xpack.securitySolution.endpoint.ingestManager.createPackageConfig.endpointConfiguration": "このエージェント構成を使用するすべてのエージェントは基本ポリシーを使用します。セキュリティアプリでこのポリシーを変更できます。Fleetはこれらの変更をエージェントにデプロイします。", + "xpack.securitySolution.endpoint.ingestToastMessage": "Ingest Managerが設定中に失敗しました。", + "xpack.securitySolution.endpoint.ingestToastTitle": "アプリを初期化できませんでした", + "xpack.securitySolution.endpoint.policy.details.backToListTitle": "ポリシーリストに戻る", + "xpack.securitySolution.endpoint.policy.details.cancel": "キャンセル", + "xpack.securitySolution.endpoint.policy.details.detect": "検知", + "xpack.securitySolution.endpoint.policy.details.eventCollection": "イベント収集", + "xpack.securitySolution.endpoint.policy.details.eventCollectionsEnabled": "{selected} / {total}件のイベント収集が有効です", + "xpack.securitySolution.endpoint.policy.details.linux": "Linux", + "xpack.securitySolution.endpoint.policy.details.mac": "Mac", + "xpack.securitySolution.endpoint.policy.details.malware": "マルウェア", + "xpack.securitySolution.endpoint.policy.details.malwareProtectionsEnabled": "マルウェア保護{mode, select, true {有効} false {無効}}", + "xpack.securitySolution.endpoint.policy.details.prevent": "防御", + "xpack.securitySolution.endpoint.policy.details.protections": "保護", + "xpack.securitySolution.endpoint.policy.details.save": "保存", + "xpack.securitySolution.endpoint.policy.details.settings": "設定", + "xpack.securitySolution.endpoint.policy.details.updateConfirm.cancelButtonTitle": "キャンセル", + "xpack.securitySolution.endpoint.policy.details.updateConfirm.confirmButtonTitle": "変更を保存してデプロイ", + "xpack.securitySolution.endpoint.policy.details.updateConfirm.message": "この操作は元に戻すことができません。続行していいですか?", + "xpack.securitySolution.endpoint.policy.details.updateConfirm.title": "変更を保存してデプロイ", + "xpack.securitySolution.endpoint.policy.details.updateConfirm.warningMessage": "これらの変更を保存すると、このポリシーに割り当てられたすべての有効なエンドポイントに更新が適用されます。", + "xpack.securitySolution.endpoint.policy.details.updateErrorTitle": "失敗しました。", + "xpack.securitySolution.endpoint.policy.details.updateSuccessMessage": "ポリシー{name}が更新されました。", + "xpack.securitySolution.endpoint.policy.details.updateSuccessTitle": "成功!", + "xpack.securitySolution.endpoint.policy.details.windows": "Windows", + "xpack.securitySolution.endpoint.policy.details.windowsAndMac": "Windows、Mac", + "xpack.securitySolution.endpoint.policyDetailOS": "オペレーティングシステム", + "xpack.securitySolution.endpoint.policyDetails.agentsSummary.errorTitle": "エラー", + "xpack.securitySolution.endpoint.policyDetails.agentsSummary.offlineTitle": "オフライン", + "xpack.securitySolution.endpoint.policyDetails.agentsSummary.onlineTitle": "オンライン", + "xpack.securitySolution.endpoint.policyDetails.agentsSummary.totalTitle": "ホスト", + "xpack.securitySolution.endpoint.policyDetailsConfig.eventingEvents": "イベント", + "xpack.securitySolution.endpoint.policyDetailsConfig.linux.events.file": "ファイル", + "xpack.securitySolution.endpoint.policyDetailsConfig.linux.events.network": "ネットワーク", + "xpack.securitySolution.endpoint.policyDetailsConfig.linux.events.process": "プロセス", + "xpack.securitySolution.endpoint.policyDetailsConfig.mac.events.file": "ファイル", + "xpack.securitySolution.endpoint.policyDetailsConfig.mac.events.network": "ネットワーク", + "xpack.securitySolution.endpoint.policyDetailsConfig.mac.events.process": "プロセス", + "xpack.securitySolution.endpoint.policyDetailsConfig.protectionLevel": "保護レベル", + "xpack.securitySolution.endpoint.policyDetailsConfig.windows.events.dllDriverLoad": "DLLとドライバーの読み込み", + "xpack.securitySolution.endpoint.policyDetailsConfig.windows.events.dns": "DNS", + "xpack.securitySolution.endpoint.policyDetailsConfig.windows.events.file": "ファイル", + "xpack.securitySolution.endpoint.policyDetailsConfig.windows.events.network": "ネットワーク", + "xpack.securitySolution.endpoint.policyDetailsConfig.windows.events.process": "プロセス", + "xpack.securitySolution.endpoint.policyDetailsConfig.windows.events.registry": "レジストリ", + "xpack.securitySolution.endpoint.policyDetailsConfig.windows.events.security": "セキュリティ", + "xpack.securitySolution.endpoint.policyDetailType": "タイプ", + "xpack.securitySolution.endpoint.policyList.actionButtonText": "Endpoint Securityを追加", + "xpack.securitySolution.endpoint.policyList.actionMenu": "開く", + "xpack.securitySolution.endpoint.policyList.agentConfigAction": "エージェント構成を表示", + "xpack.securitySolution.endpoint.policyList.beta": "ベータ", + "xpack.securitySolution.endpoint.policyList.createdAt": "作成日時", + "xpack.securitySolution.endpoint.policyList.createdBy": "作成者", + "xpack.securitySolution.endpoint.policyList.createNewButton": "新しいポリシーを作成", + "xpack.securitySolution.endpoint.policyList.deleteConfirm.cancelButtonTitle": "キャンセル", + "xpack.securitySolution.endpoint.policyList.deleteConfirm.confirmDeleteButton": "ポリシーを削除", + "xpack.securitySolution.endpoint.policyList.deleteConfirm.deletingButton": "削除中…", + "xpack.securitySolution.endpoint.policyList.deleteConfirm.message": "この操作は元に戻すことができません。続行していいですか?", + "xpack.securitySolution.endpoint.policyList.deleteConfirm.title": "ポリシーを削除し、変更をデプロイ", + "xpack.securitySolution.endpoint.policyList.deleteConfirm.warningMessage": "このポリシーを削除すると、これらのホストからEndpoint Securityが削除されます", + "xpack.securitySolution.endpoint.policyList.deleteConfirm.warningTitle": "このアクションにより、{hostCount, plural, one {個のホスト} other {個のホスト}}からEndpoint Securityが削除されます", + "xpack.securitySolution.endpoint.policyList.deleteFailedToast": "失敗しました。", + "xpack.securitySolution.endpoint.policyList.deleteFailedToastBody": "ポリシーを削除できませんでした", + "xpack.securitySolution.endpoint.policyList.deleteSuccessToast": "成功!", + "xpack.securitySolution.endpoint.policyList.deleteSuccessToastDetails": "ポリシーが削除されました。", + "xpack.securitySolution.endpoint.policyList.emptyCreateNewButton": "エージェントの登録", + "xpack.securitySolution.endpoint.policyList.nameField": "ポリシー名", + "xpack.securitySolution.endpoint.policyList.onboardingDocsLink": "セキュリティアプリドキュメントを表示", + "xpack.securitySolution.endpoint.policyList.onboardingSectionOne": "Elastic Endpoint Securityでは、脅威防御、検出、深いセキュリティデータの可視化を実現し、ホストを保護します。", + "xpack.securitySolution.endpoint.policyList.onboardingSectionThree": "開始するには、Elastic Endpoint Security統合をエージェントに追加します。詳細については、 ", + "xpack.securitySolution.endpoint.policyList.onboardingSectionTwo": "このページでは、Elastic Endpoint Securityを実行している環境でホストを表示して管理できます。", + "xpack.securitySolution.endpoint.policyList.onboardingTitle": "Elastic Endpoint Securityの基本", + "xpack.securitySolution.endpoint.policyList.policyDeleteAction": "ポリシーを削除", + "xpack.securitySolution.endpoint.policyList.revision": "rev. {revNumber}", + "xpack.securitySolution.endpoint.policyList.updatedAt": "最終更新", + "xpack.securitySolution.endpoint.policyList.updatedBy": "最終更新者", + "xpack.securitySolution.endpoint.policyList.versionFieldLabel": "バージョン", + "xpack.securitySolution.endpoint.policyList.viewTitleTotalCount": "{totalItemCount, plural, one {# ポリシー} other {# ポリシー}}", + "xpack.securitySolution.endpoint.resolver.eitherLineageLimitExceeded": "以下のビジュアライゼーションとイベントリストの一部のプロセスイベントを表示できませんでした。データの上限に達しました。", + "xpack.securitySolution.endpoint.resolver.elapsedTime": "{duration} {durationType}", + "xpack.securitySolution.endpoint.resolver.loadingError": "データの読み込み中にエラーが発生しました。", + "xpack.securitySolution.endpoint.resolver.panel.error.error": "エラー", + "xpack.securitySolution.endpoint.resolver.panel.error.events": "イベント", + "xpack.securitySolution.endpoint.resolver.panel.error.goBack": "このリンクをクリックすると、すべてのプロセスのリストに戻ります。", + "xpack.securitySolution.endpoint.resolver.panel.processDescList.events": "イベント", + "xpack.securitySolution.endpoint.resolver.panel.processEventCounts.events": "イベント", + "xpack.securitySolution.endpoint.resolver.panel.processEventListByType.eventDescriptiveName": "{descriptor} {subject}", + "xpack.securitySolution.endpoint.resolver.panel.processEventListByType.events": "イベント", + "xpack.securitySolution.endpoint.resolver.panel.processEventListByType.wait": "イベントを待機しています...", + "xpack.securitySolution.endpoint.resolver.panel.processListWithCounts.events": "すべてのプロセスイベント", + "xpack.securitySolution.endpoint.resolver.panel.relatedCounts.numberOfEventsInCrumb": "{totalCount}件のイベント", + "xpack.securitySolution.endpoint.resolver.panel.relatedDetail.missing": "関連イベントが見つかりません。", + "xpack.securitySolution.endpoint.resolver.panel.relatedDetail.wait": "イベントを待機しています...", + "xpack.securitySolution.endpoint.resolver.panel.relatedEventDetail.atTime": "@ {date}", + "xpack.securitySolution.endpoint.resolver.panel.relatedEventDetail.categoryAndType": "{category} {eventType}", + "xpack.securitySolution.endpoint.resolver.panel.relatedEventDetail.countByCategory": "{count} {category}", + "xpack.securitySolution.endpoint.resolver.panel.relatedEventDetail.detailsForProcessName": "詳細:{processName}", + "xpack.securitySolution.endpoint.resolver.panel.relatedEventDetail.eventDescriptiveName": "{descriptor} {subject}", + "xpack.securitySolution.endpoint.resolver.panel.relatedEventDetail.eventDescriptiveNameInTitle": "{descriptor} {subject}", + "xpack.securitySolution.endpoint.resolver.panel.relatedEventDetail.events": "イベント", + "xpack.securitySolution.endpoint.resolver.panel.relatedEventDetail.NA": "N/A", + "xpack.securitySolution.endpoint.resolver.panel.relatedEventDetail.numberOfEvents": "{totalCount}件のイベント", + "xpack.securitySolution.endpoint.resolver.panel.relatedEventList.countByCategory": "{count} {category}", + "xpack.securitySolution.endpoint.resolver.panel.relatedEventList.numberOfEvents": "{totalCount}件のイベント", + "xpack.securitySolution.endpoint.resolver.panel.table.row.count": "カウント", + "xpack.securitySolution.endpoint.resolver.panel.table.row.eventType": "イベントタイプ", + "xpack.securitySolution.endpoint.resolver.panel.table.row.processNameTitle": "プロセス名", + "xpack.securitySolution.endpoint.resolver.panel.table.row.timestampInvalidLabel": "無効", + "xpack.securitySolution.endpoint.resolver.panel.table.row.timestampTitle": "タイムスタンプ", + "xpack.securitySolution.endpoint.resolver.panel.table.row.valueMissingDescription": "値が見つかりません", + "xpack.securitySolution.endpoint.resolver.relatedEventLimitExceeded": "{numberOfEventsMissing} {category}件のイベントを表示できませんでした。データの上限に達しました。", + "xpack.securitySolution.endpoint.resolver.relatedEventLimitTitle": "このリストには、{numberOfEntries}件のプロセスイベントが含まれています。", + "xpack.securitySolution.endpoint.resolver.relatedEvents": "イベント", + "xpack.securitySolution.endpoint.resolver.relatedLimitsExceededTitle": "このリストには、{numberOfEventsDisplayed} {category}件のイベントが含まれます。", + "xpack.securitySolution.endpoint.resolver.relatedNotRetrieved": "関連するイベントがまだ取得されていません。", + "xpack.securitySolution.endpoint.resolver.relatedRetrievalError": "関連するイベントの取得中にエラーが発生しました。", + "xpack.securitySolution.endpoint.resolver.runningProcess": "プロセスの実行中", + "xpack.securitySolution.endpoint.resolver.runningTrigger": "トリガーの実行中", + "xpack.securitySolution.endpoint.resolver.terminatedProcess": "プロセスを中断しました", + "xpack.securitySolution.endpoint.resolver.terminatedTrigger": "トリガーを中断しました", + "xpack.securitySolution.endpointList.endpointVersion": "バージョン", + "xpack.securitySolution.endpointList.hostname": "ホスト名", + "xpack.securitySolution.endpointList.hostStatus": "ホストステータス", + "xpack.securitySolution.endpointList.hostStatusValue": "{hostStatus, select, online {オンライン} error {エラー} other {オフライン}}", + "xpack.securitySolution.endpointList.ip": "IP アドレス", + "xpack.securitySolution.endpointList.lastActive": "前回のアーカイブ", + "xpack.securitySolution.endpointList.os": "オペレーティングシステム", + "xpack.securitySolution.endpointList.policy": "ポリシー", + "xpack.securitySolution.endpointList.policyStatus": "ポリシーステータス", + "xpack.securitySolution.endpointList.totalCount": "{totalItemCount, plural, one {# ホスト} other {# ホスト}}", + "xpack.securitySolution.endpointManagement.noPermissionsSubText": "Ingest Managerが無効である可能性があります。この機能を使用するには、Ingest Managerを有効にする必要があります。Ingest Managerを有効にする権限がない場合は、Kibana管理者に連絡してください。", + "xpack.securitySolution.endpointManagemnet.noPermissionsText": "Elastic Security Administrationを使用するために必要なKibana権限がありません。", + "xpack.securitySolution.enpdoint.resolver.panelutils.betaBadgeLabel": "BETA", + "xpack.securitySolution.enpdoint.resolver.panelutils.invaliddate": "無効な日付", "xpack.securitySolution.event.module.linkToElasticEndpointSecurityDescription": "Elastic Endpoint Securityで開く", "xpack.securitySolution.eventDetails.blank": " ", "xpack.securitySolution.eventDetails.copyToClipboard": "クリップボードにコピー", @@ -14014,23 +16499,122 @@ "xpack.securitySolution.eventDetails.table": "表", "xpack.securitySolution.eventDetails.toggleColumnTooltip": "列を切り替えます", "xpack.securitySolution.eventDetails.value": "値", + "xpack.securitySolution.eventRenderers.auditdDescriptionPart1": "監査イベントは、Linux Audit Frameworkからセキュリティ関連ログを通知します。", + "xpack.securitySolution.eventRenderers.auditdFileDescriptionPart1": "ファイルイベントは、特定のプロセス経由で、ファイルに対してCRUD処理を実行しているユーザー(およびシステムアカウント)を示します。", + "xpack.securitySolution.eventRenderers.auditdFileName": "監査されたファイル", + "xpack.securitySolution.eventRenderers.auditdName": "Auditd", + "xpack.securitySolution.eventRenderers.authenticationDescriptionPart1": "認証イベントは、ホストへのログインが成功または失敗したユーザー(およびシステムアカウント)を示します。", + "xpack.securitySolution.eventRenderers.authenticationDescriptionPart2": "一部の認証イベントには、ユーザーが他のユーザーの代わりに認証するときの詳細情報が含まれることがあります。", + "xpack.securitySolution.eventRenderers.authenticationName": "認証", + "xpack.securitySolution.eventRenderers.dnsDescriptionPart1": "ドメインネームシステム(DNS)イベントは、ホスト名からIPアドレスに変換するために特定のプロセス経由で要求を行うユーザー(およびシステムアカウント)を示します。", + "xpack.securitySolution.eventRenderers.dnsName": "ドメインネームシステム(DNS)", + "xpack.securitySolution.eventRenderers.fileDescriptionPart1": "ファイルイベントは、特定のプロセス経由で、ファイルに対してCRUD処理を実行しているユーザー(およびシステムアカウント)を示します。", + "xpack.securitySolution.eventRenderers.fileName": "ファイル", + "xpack.securitySolution.eventRenderers.fimDescriptionPart1": "File Integrityモジュール(FIM)は、特定のプロセス経由で、ファイルに対してCRUD処理を実行しているユーザー(およびシステムアカウント)を示します。", + "xpack.securitySolution.eventRenderers.fimName": "File Integrityモジュール(FIM)", + "xpack.securitySolution.eventRenderers.flowDescriptionPart1": "フローレンダラーは、送信元と送信先の間のデータフローを可視化します。これは多くの種類のイベントに適用されます。", + "xpack.securitySolution.eventRenderers.flowDescriptionPart2": "ホスト、ポート、プロトコル、方向、期間、転送量、プロセス、地理的位置情報、およびその他の詳細が利用可能であれば可視化されます。", + "xpack.securitySolution.eventRenderers.flowName": "フロー", + "xpack.securitySolution.eventRenderers.processDescriptionPart1": "プロセスイベントは、プロセスを開始および停止するユーザー(およびシステムアカウント)を示します。", + "xpack.securitySolution.eventRenderers.processDescriptionPart2": "コマンドライン引数、親プロセス、ファイルハッシュ(該当する場合)を含む詳細情報があれば表示されます。", + "xpack.securitySolution.eventRenderers.processName": "プロセス", + "xpack.securitySolution.eventRenderers.socketDescriptionPart1": "ソケット(ネットワーク)イベントは、リスニング、許可、接続終了プロセスを示します。", + "xpack.securitySolution.eventRenderers.socketDescriptionPart2": "単一のフローに関連するすべてのネットワークイベントを関連付けるプロトコル、ポート、コミュニティIDを含む詳細が使用可能であれば表示されます。", + "xpack.securitySolution.eventRenderers.socketName": "ソケット(ネットワーク)", + "xpack.securitySolution.eventRenderers.suricataDescriptionPart1": "要約", + "xpack.securitySolution.eventRenderers.suricataDescriptionPart2": "侵入検出(IDS)、インライン侵入防止(IPS)、ネットワークセキュリティ監視(NSM)イベント", + "xpack.securitySolution.eventRenderers.suricataName": "Suricata", + "xpack.securitySolution.eventRenderers.systemDescriptionPart1": "Auditbeat", + "xpack.securitySolution.eventRenderers.systemDescriptionPart2": "モジュールはシステムに関するさまざまなセキュリティ関連情報を収集します。", + "xpack.securitySolution.eventRenderers.systemDescriptionPart3": "すべてのデータセットは定期的な状態情報(現在実行中のすべてのプロセスなど)とリアルタイム変更(新しいプロセスが開始または停止するときなど)の両方を送信します。", + "xpack.securitySolution.eventRenderers.systemName": "システム", + "xpack.securitySolution.eventRenderers.zeekDescriptionPart1": "イベントを要約します", + "xpack.securitySolution.eventRenderers.zeekDescriptionPart2": "ネットワークセキュリティ(NSM)ツール", + "xpack.securitySolution.eventRenderers.zeekName": "Zeek(旧Bro)", + "xpack.securitySolution.eventsViewer.alerts.defaultHeaders.methodTitle": "メソド", + "xpack.securitySolution.eventsViewer.alerts.defaultHeaders.riskScoreTitle": "リスクスコア", + "xpack.securitySolution.eventsViewer.alerts.defaultHeaders.ruleTitle": "ルール", + "xpack.securitySolution.eventsViewer.alerts.defaultHeaders.severityTitle": "深刻度", + "xpack.securitySolution.eventsViewer.alerts.defaultHeaders.versionTitle": "バージョン", "xpack.securitySolution.eventsViewer.errorFetchingEventsData": "イベントデータをクエリできませんでした", "xpack.securitySolution.eventsViewer.eventsLabel": "イベント", "xpack.securitySolution.eventsViewer.footer.loadingEventsDataLabel": "イベントを読み込み中", "xpack.securitySolution.eventsViewer.showingLabel": "表示中", - "xpack.securitySolution.eventsViewer.unit": "{totalCount, plural, =1 {event} other {events}}", + "xpack.securitySolution.eventsViewer.unit": "{totalCount, plural, =1 {イベント} other {イベント}}", + "xpack.securitySolution.exceptions.addException.addException": "例外の追加", + "xpack.securitySolution.exceptions.addException.bulkCloseLabel": "この例外の属性と一致するすべてのアラートを閉じる", + "xpack.securitySolution.exceptions.addException.bulkCloseLabel.disabled": "この例外の属性と一致するすべてのアラートを閉じる(リストと非ECSフィールドはサポートされません)", + "xpack.securitySolution.exceptions.addException.cancel": "キャンセル", + "xpack.securitySolution.exceptions.addException.endpointQuarantineText": "選択した属性と一致する任意のエンドポイントの隔離にあるファイルは、自動的に元の場所に復元されます。", + "xpack.securitySolution.exceptions.addException.error": "例外を追加できませんでした", + "xpack.securitySolution.exceptions.addException.fetchError": "例外リストの取得エラー", + "xpack.securitySolution.exceptions.addException.fetchError.title": "エラー", + "xpack.securitySolution.exceptions.addException.infoLabel": "ルールの条件が満たされるときにアラートが生成されます。例外:", + "xpack.securitySolution.exceptions.addException.success": "正常に例外を追加しました", + "xpack.securitySolution.exceptions.andDescription": "AND", + "xpack.securitySolution.exceptions.commentEventLabel": "コメントを追加しました", + "xpack.securitySolution.exceptions.commentLabel": "コメント", + "xpack.securitySolution.exceptions.createdByLabel": "作成者", + "xpack.securitySolution.exceptions.dateCreatedLabel": "日付が作成されました", + "xpack.securitySolution.exceptions.detectionListLabel": "検出リスト", + "xpack.securitySolution.exceptions.doesNotExistOperatorLabel": "存在しない", + "xpack.securitySolution.exceptions.editButtonLabel": "編集", + "xpack.securitySolution.exceptions.editException.bulkCloseLabel": "この例外の属性と一致するすべてのアラートを閉じる", + "xpack.securitySolution.exceptions.editException.bulkCloseLabel.disabled": "この例外の属性と一致するすべてのアラートを閉じる(リストと非ECSフィールドはサポートされません)", + "xpack.securitySolution.exceptions.editException.cancel": "キャンセル", + "xpack.securitySolution.exceptions.editException.editExceptionSaveButton": "保存", + "xpack.securitySolution.exceptions.editException.editExceptionTitle": "例外の編集", + "xpack.securitySolution.exceptions.editException.endpointQuarantineText": "選択した属性と一致する任意のエンドポイントの隔離にあるファイルは、自動的に元の場所に復元されます。", + "xpack.securitySolution.exceptions.editException.error": "例外を更新できませんでした", + "xpack.securitySolution.exceptions.editException.infoLabel": "ルールの条件が満たされるときにアラートが生成されます。例外:", + "xpack.securitySolution.exceptions.editException.success": "正常に例外を更新しました", + "xpack.securitySolution.exceptions.endpointListLabel": "エンドポイントリスト", + "xpack.securitySolution.exceptions.exceptionsPaginationLabel": "ページごとの項目数: {items}", + "xpack.securitySolution.exceptions.existsOperatorLabel": "存在する", + "xpack.securitySolution.exceptions.fieldDescription": "フィールド", + "xpack.securitySolution.exceptions.hideCommentsLabel": "({comments}) {comments, plural, =1 {件のコメント} other {件のコメント}}を非表示", + "xpack.securitySolution.exceptions.isInListOperatorLabel": "リストにある", + "xpack.securitySolution.exceptions.isNotInListOperatorLabel": "リストにない", + "xpack.securitySolution.exceptions.isNotOneOfOperatorLabel": "is not one of", + "xpack.securitySolution.exceptions.isNotOperatorLabel": "is not", + "xpack.securitySolution.exceptions.isOneOfOperatorLabel": "is one of", + "xpack.securitySolution.exceptions.isOperatorLabel": "is", + "xpack.securitySolution.exceptions.operatingSystemLabel": "OS", + "xpack.securitySolution.exceptions.operatorDescription": "演算子", + "xpack.securitySolution.exceptions.orDescription": "OR", + "xpack.securitySolution.exceptions.paginationNumberOfItemsLabel": "{items}個の項目", + "xpack.securitySolution.exceptions.removeButtonLabel": "削除", + "xpack.securitySolution.exceptions.showCommentsLabel": "({comments}) {comments, plural, =1 {件のコメント} other {件のコメント}}を表示", + "xpack.securitySolution.exceptions.utilityNumberExceptionsLabel": "{items} {items, plural, =1 {件の例外} other {件の例外}}を表示しています", + "xpack.securitySolution.exceptions.utilityRefreshLabel": "更新", + "xpack.securitySolution.exceptions.valueDescription": "値", + "xpack.securitySolution.exceptions.viewer.addCommentPlaceholder": "新しいコメントを追加...", + "xpack.securitySolution.exceptions.viewer.addExceptionLabel": "新しい例外を追加", + "xpack.securitySolution.exceptions.viewer.addToClipboard": "クリップボードに追加", + "xpack.securitySolution.exceptions.viewer.addToDetectionsListLabel": "検出リストに追加", + "xpack.securitySolution.exceptions.viewer.addToEndpointListLabel": "エンドポイントリストに追加", + "xpack.securitySolution.exceptions.viewer.deleteExceptionError": "例外の削除エラー", + "xpack.securitySolution.exceptions.viewer.emptyPromptBody": "例外を追加してルールを微調整し、例外条件が満たされたときに検出アラートが作成されないようにすることができます。例外により検出の精度が改善します。これにより、誤検出数が減ります。", + "xpack.securitySolution.exceptions.viewer.emptyPromptTitle": "このルールには例外がありません", + "xpack.securitySolution.exceptions.viewer.exceptionDetectionDetailsDescription": "このルールのすべての例外は、エンドポイントではなく、検出ルールに適用されます。詳細については、{ruleSettings}を確認してください。", + "xpack.securitySolution.exceptions.viewer.exceptionDetectionDetailsDescription.ruleSettingsLink": "ルール設定", + "xpack.securitySolution.exceptions.viewer.exceptionEndpointDetailsDescription": "このルールのすべての例外は、エンドポイントと検出ルールに適用されます。詳細については、{ruleSettings}を確認してください。", + "xpack.securitySolution.exceptions.viewer.exceptionEndpointDetailsDescription.ruleSettingsLink": "ルール設定", + "xpack.securitySolution.exceptions.viewer.fetchingListError": "例外の取得エラー", + "xpack.securitySolution.exceptions.viewer.searchDefaultPlaceholder": "検索フィールド(例:host.name)", + "xpack.securitySolution.exitFullScreenButton": "全画面を終了", "xpack.securitySolution.featureCatalogue.description": "セキュリティメトリクスとログのイベントとアラートを確認します", - "xpack.securitySolution.featureCatalogue.title": "Security", - "xpack.securitySolution.featureRegistry.linkSecuritySolutionTitle": "Security", - "xpack.securitySolution.fieldBrowser.categoriesCountTitle": "{totalCount} {totalCount, plural, =1 {category} other {categories}}", + "xpack.securitySolution.featureCatalogue.title": "セキュリティ", + "xpack.securitySolution.featureRegistry.linkSecuritySolutionTitle": "セキュリティ", + "xpack.securitySolution.fieldBrowser.categoriesCountTitle": "{totalCount} {totalCount, plural, =1 {カテゴリ} other {カテゴリ}}", "xpack.securitySolution.fieldBrowser.categoriesTitle": "カテゴリー", "xpack.securitySolution.fieldBrowser.categoryLabel": "カテゴリー", "xpack.securitySolution.fieldBrowser.copyToClipboard": "クリップボードにコピー", "xpack.securitySolution.fieldBrowser.customizeColumnsTitle": "列のカスタマイズ", "xpack.securitySolution.fieldBrowser.descriptionLabel": "説明", "xpack.securitySolution.fieldBrowser.fieldLabel": "フィールド", - "xpack.securitySolution.fieldBrowser.fieldsCountTitle": "{totalCount} {totalCount, plural, =1 {field} other {fields}}", - "xpack.securitySolution.fieldBrowser.fieldsTitle": "フィールド", + "xpack.securitySolution.fieldBrowser.fieldsCountTitle": "{totalCount} {totalCount, plural, =1 {フィールド} other {フィールド}}", + "xpack.securitySolution.fieldBrowser.fieldsTitle": "列", "xpack.securitySolution.fieldBrowser.filterPlaceholder": "フィールド名", "xpack.securitySolution.fieldBrowser.noFieldsMatchInputLabel": "{searchInput} に一致するフィールドがありません", "xpack.securitySolution.fieldBrowser.noFieldsMatchLabel": "一致するフィールドがありません", @@ -14038,7 +16622,7 @@ "xpack.securitySolution.fieldBrowser.toggleColumnTooltip": "列を切り替えます", "xpack.securitySolution.fieldBrowser.viewCategoryTooltip": "すべての {categoryId} フィールドを表示します", "xpack.securitySolution.fieldRenderers.moreLabel": "もっと", - "xpack.securitySolution.flyout.button.text": "タイムライン", + "xpack.securitySolution.flyout.button.text": "Timeline", "xpack.securitySolution.flyout.button.timeline": "タイムライン", "xpack.securitySolution.footer.autoRefreshActiveDescription": "自動更新アクション", "xpack.securitySolution.footer.autoRefreshActiveTooltip": "自動更新が有効な間、タイムラインはクエリに一致する最新の {numberOfItems} 件のイベントを表示します。", @@ -14070,11 +16654,14 @@ "xpack.securitySolution.headerPage.pageSubtitle": "前回のイベント: {beat}", "xpack.securitySolution.hooks.useAddToTimeline.addedFieldMessage": "{fieldOrValue}をタイムラインに追加しました", "xpack.securitySolution.host.details.architectureLabel": "アーキテクチャー", + "xpack.securitySolution.host.details.endpoint.endpointPolicy": "エンドポイントポリシー", + "xpack.securitySolution.host.details.endpoint.policyStatus": "ポリシーステータス", + "xpack.securitySolution.host.details.endpoint.sensorversion": "センサーバージョン", "xpack.securitySolution.host.details.firstSeenTitle": "初回の認識", "xpack.securitySolution.host.details.lastSeenTitle": "前回の認識", "xpack.securitySolution.host.details.overview.cloudProviderTitle": "クラウドプロバイダー", "xpack.securitySolution.host.details.overview.familyTitle": "ファミリー", - "xpack.securitySolution.host.details.overview.hostIdTitle": "ホスト ID", + "xpack.securitySolution.host.details.overview.hostIdTitle": "ホストID", "xpack.securitySolution.host.details.overview.inspectTitle": "ホスト概要", "xpack.securitySolution.host.details.overview.instanceIdTitle": "インスタンス ID", "xpack.securitySolution.host.details.overview.ipAddressesTitle": "IP アドレス", @@ -14085,7 +16672,9 @@ "xpack.securitySolution.host.details.overview.platformTitle": "プラットフォーム", "xpack.securitySolution.host.details.overview.regionTitle": "地域", "xpack.securitySolution.host.details.versionLabel": "バージョン", - "xpack.securitySolution.hosts.kqlPlaceholder": "例: host.name: \"foo\"", + "xpack.securitySolution.hostList.pageSubTitle": "Elastic Endpoint Securityを実行しているホスト", + "xpack.securitySolution.hostList.pageTitle": "ホスト", + "xpack.securitySolution.hosts.kqlPlaceholder": "例:host.name: \"foo\"", "xpack.securitySolution.hosts.navigation.alertsTitle": "外部アラート", "xpack.securitySolution.hosts.navigation.allHostsTitle": "すべてのホスト", "xpack.securitySolution.hosts.navigation.anomaliesTitle": "異常", @@ -14095,19 +16684,21 @@ "xpack.securitySolution.hosts.navigation.uncommonProcessesTitle": "非共通プロセス", "xpack.securitySolution.hosts.navigaton.matrixHistogram.errorFetchingAuthenticationsData": "認証データをクエリできませんでした", "xpack.securitySolution.hosts.navigaton.matrixHistogram.errorFetchingEventsData": "イベントデータをクエリできませんでした", - "xpack.securitySolution.hosts.pageTitle": "すべてのホスト", + "xpack.securitySolution.hosts.pageTitle": "ホスト", + "xpack.securitySolution.hostsTab": "ホスト", "xpack.securitySolution.hostsTable.firstLastSeenToolTip": "選択された日付範囲との相関付けです", "xpack.securitySolution.hostsTable.hostsTitle": "すべてのホスト", "xpack.securitySolution.hostsTable.lastSeenTitle": "前回の認識", - "xpack.securitySolution.hostsTable.nameTitle": "名前", + "xpack.securitySolution.hostsTable.nameTitle": "ホスト名", "xpack.securitySolution.hostsTable.osTitle": "オペレーティングシステム", - "xpack.securitySolution.hostsTable.rows": "{numRows} {numRows, plural, =0 {rows} =1 {row} other {rows}}", - "xpack.securitySolution.hostsTable.unit": "{totalCount, plural, =1 {host} other {hosts}}", + "xpack.securitySolution.hostsTable.rows": "{numRows} {numRows, plural, =0 {行} =1 {行} other {行}}", + "xpack.securitySolution.hostsTable.unit": "{totalCount, plural, =1 {ホスト} other {ホスト}}", "xpack.securitySolution.hostsTable.versionTitle": "バージョン", "xpack.securitySolution.insert.timeline.insertTimelineButton": "タイムラインリンクの挿入", "xpack.securitySolution.inspect.modal.closeTitle": "閉じる", "xpack.securitySolution.inspect.modal.indexPatternDescription": "Elasticsearch インデックスに接続したインデックスパターンです。これらのインデックスは Kibana > 高度な設定で構成できます。", "xpack.securitySolution.inspect.modal.indexPatternLabel": "インデックスパターン", + "xpack.securitySolution.inspect.modal.noAlertIndexFound": "アラートインデックスが見つかりません", "xpack.securitySolution.inspect.modal.queryTimeDescription": "クエリの処理の所要時間です。リクエストの送信やブラウザでのパースの時間は含まれません。", "xpack.securitySolution.inspect.modal.queryTimeLabel": "クエリ時間", "xpack.securitySolution.inspect.modal.reqTimestampDescription": "リクエストの開始が記録された時刻です", @@ -14115,7 +16706,7 @@ "xpack.securitySolution.inspect.modal.somethingWentWrongDescription": "申し訳ございませんが、何か問題が発生しました。", "xpack.securitySolution.inspectDescription": "検査", "xpack.securitySolution.ja3.fingerprint.ja3.fingerprintLabel": "ja3", - "xpack.securitySolution.kpiHosts.hosts.title": "すべてのホスト", + "xpack.securitySolution.kpiHosts.hosts.title": "ホスト", "xpack.securitySolution.kpiHosts.uniqueIps.destinationChartLabel": "Dest.", "xpack.securitySolution.kpiHosts.uniqueIps.destinationUnitLabel": "デスティネーション", "xpack.securitySolution.kpiHosts.uniqueIps.sourceChartLabel": "Src.", @@ -14136,21 +16727,44 @@ "xpack.securitySolution.kpiNetwork.uniquePrivateIps.sourceUnitLabel": "ソース", "xpack.securitySolution.kpiNetwork.uniquePrivateIps.title": "固有のプライベート IP", "xpack.securitySolution.licensing.unsupportedMachineLearningMessage": "ご使用のライセンスは機械翻訳をサポートしていません。ライセンスをアップグレードしてください。", + "xpack.securitySolution.lists.cancelValueListsUploadTitle": "アップロードのキャンセル", + "xpack.securitySolution.lists.closeValueListsModalTitle": "閉じる", + "xpack.securitySolution.lists.detectionEngine.rules.uploadValueListsButton": "値リストのアップロード", + "xpack.securitySolution.lists.uploadValueListDescription": "ルールまたはルール例外の書き込み中に使用する単一値リストをアップロードします。", + "xpack.securitySolution.lists.uploadValueListPrompt": "ファイルを選択するかドラッグ &amp; ドロップしてください", + "xpack.securitySolution.lists.uploadValueListTitle": "値リストのアップロード", + "xpack.securitySolution.lists.valueListsForm.ipRadioLabel": "IP アドレス", + "xpack.securitySolution.lists.valueListsForm.keywordsRadioLabel": "キーワード", + "xpack.securitySolution.lists.valueListsForm.listTypesRadioLabel": "値リストのタイプ", + "xpack.securitySolution.lists.valueListsTable.actionsColumn": "アクション", + "xpack.securitySolution.lists.valueListsTable.createdByColumn": "作成者", + "xpack.securitySolution.lists.valueListsTable.deleteActionDescription": "値リストの削除", + "xpack.securitySolution.lists.valueListsTable.deleteActionName": "削除", + "xpack.securitySolution.lists.valueListsTable.exportActionDescription": "値リストのエクスポート", + "xpack.securitySolution.lists.valueListsTable.exportActionName": "エクスポート", + "xpack.securitySolution.lists.valueListsTable.fileNameColumn": "ファイル名", + "xpack.securitySolution.lists.valueListsTable.title": "値リスト", + "xpack.securitySolution.lists.valueListsTable.uploadDateColumn": "アップロード日", + "xpack.securitySolution.lists.valueListsUploadButton": "リストのアップロード", + "xpack.securitySolution.lists.valueListsUploadError": "値リストのアップロードエラーが発生しました。", + "xpack.securitySolution.lists.valueListsUploadSuccess": "値リスト「{fileName}」はアップロードされませんでした", + "xpack.securitySolution.lists.valueListsUploadSuccessTitle": "値リストがアップロードされました", "xpack.securitySolution.markdown.hint.boldLabel": "**太字**", "xpack.securitySolution.markdown.hint.bulletLabel": "* ビュレット", - "xpack.securitySolution.markdown.hint.codeLabel": "「コード」", + "xpack.securitySolution.markdown.hint.codeLabel": "`code`", "xpack.securitySolution.markdown.hint.headingLabel": "# 見出し", "xpack.securitySolution.markdown.hint.imageUrlLabel": "![image](url)", - "xpack.securitySolution.markdown.hint.italicsLabel": "_斜体_", - "xpack.securitySolution.markdown.hint.preformattedLabel": "```プリフォーマット```", + "xpack.securitySolution.markdown.hint.italicsLabel": "_italics_", + "xpack.securitySolution.markdown.hint.preformattedLabel": "```preformatted```", "xpack.securitySolution.markdown.hint.quoteLabel": ">引用", "xpack.securitySolution.markdown.hint.strikethroughLabel": "取り消し線", "xpack.securitySolution.markdown.hint.urlLabel": "[link](url)", + "xpack.securitySolution.markdown.toolTip.timelineId": "タイムラインID:{ timelineId }", "xpack.securitySolution.markdownEditor.markdown": "マークダウン", "xpack.securitySolution.markdownEditor.markdownInputHelp": "Markdown 構文ヘルプ", "xpack.securitySolution.markdownEditor.preview": "プレビュー", "xpack.securitySolution.ml.score.anomalousEntityTitle": "異常エンティティ", - "xpack.securitySolution.ml.score.anomalyJobTitle": "ジョブ", + "xpack.securitySolution.ml.score.anomalyJobTitle": "ジョブ名", "xpack.securitySolution.ml.score.detectedTitle": "検出", "xpack.securitySolution.ml.score.influencedByTitle": "影響因子", "xpack.securitySolution.ml.score.maxAnomalyScoreTitle": "最高異常スコア", @@ -14166,9 +16780,11 @@ "xpack.securitySolution.modalAllErrors.close.button": "閉じる", "xpack.securitySolution.modalAllErrors.seeAllErrors.button": "完全なエラーを表示", "xpack.securitySolution.modalAllErrors.title": "ビジュアライゼーションにエラーがあります", + "xpack.securitySolution.navigation.administration": "管理", + "xpack.securitySolution.navigation.alerts": "アラート", "xpack.securitySolution.navigation.case": "ケース", "xpack.securitySolution.navigation.detectionEngine": "検出", - "xpack.securitySolution.navigation.hosts": "すべてのホスト", + "xpack.securitySolution.navigation.hosts": "ホスト", "xpack.securitySolution.navigation.network": "ネットワーク", "xpack.securitySolution.navigation.overview": "概要", "xpack.securitySolution.navigation.timelines": "タイムライン", @@ -14177,7 +16793,7 @@ "xpack.securitySolution.network.ipDetails.ipOverview.asSourceDropDownOptionLabel": "送信元として", "xpack.securitySolution.network.ipDetails.ipOverview.autonomousSystemTitle": "自動システム", "xpack.securitySolution.network.ipDetails.ipOverview.firstSeenTitle": "初回の認識", - "xpack.securitySolution.network.ipDetails.ipOverview.hostIdTitle": "ホスト ID", + "xpack.securitySolution.network.ipDetails.ipOverview.hostIdTitle": "ホストID", "xpack.securitySolution.network.ipDetails.ipOverview.hostNameTitle": "ホスト名", "xpack.securitySolution.network.ipDetails.ipOverview.inspectTitle": "IP概要", "xpack.securitySolution.network.ipDetails.ipOverview.ipReputationTitle": "評判", @@ -14192,8 +16808,8 @@ "xpack.securitySolution.network.ipDetails.tlsTable.columns.ja3FingerPrintTitle": "JA3 フィンガープリント", "xpack.securitySolution.network.ipDetails.tlsTable.columns.sha1FingerPrintTitle": "SHA1フィンガープリント", "xpack.securitySolution.network.ipDetails.tlsTable.columns.subjectTitle": "件名", - "xpack.securitySolution.network.ipDetails.tlsTable.columns.validUntilTitle": "有効期限:", - "xpack.securitySolution.network.ipDetails.tlsTable.rows": "{numRows} {numRows, plural, =0 {rows} =1 {row} other {rows}}", + "xpack.securitySolution.network.ipDetails.tlsTable.columns.validUntilTitle": "有効期限:", + "xpack.securitySolution.network.ipDetails.tlsTable.rows": "{numRows} {numRows, plural, =0 {行} =1 {行} other {行}}", "xpack.securitySolution.network.ipDetails.tlsTable.transportLayerSecurityTitle": "トランスポートレイヤーセキュリティ", "xpack.securitySolution.network.ipDetails.tlsTable.unit": "{totalCount, plural, =1 {サーバー証明書} other {サーバー証明書}}", "xpack.securitySolution.network.ipDetails.usersTable.columns.documentCountTitle": "ドキュメントカウント", @@ -14201,10 +16817,10 @@ "xpack.securitySolution.network.ipDetails.usersTable.columns.groupNameTitle": "グループ名", "xpack.securitySolution.network.ipDetails.usersTable.columns.userIdTitle": "ID", "xpack.securitySolution.network.ipDetails.usersTable.columns.userNameTitle": "ユーザー", - "xpack.securitySolution.network.ipDetails.usersTable.rows": "{numRows} {numRows, plural, =0 {rows} =1 {row} other {rows}}", - "xpack.securitySolution.network.ipDetails.usersTable.unit": "{totalCount, plural, =1 {user} other {users}}", + "xpack.securitySolution.network.ipDetails.usersTable.rows": "{numRows} {numRows, plural, =0 {行} =1 {行} other {行}}", + "xpack.securitySolution.network.ipDetails.usersTable.unit": "{totalCount, plural, =1 {ユーザー} other {ユーザー}}", "xpack.securitySolution.network.ipDetails.usersTable.usersTitle": "ユーザー", - "xpack.securitySolution.network.kqlPlaceholder": "例: source.ip: \"foo\"", + "xpack.securitySolution.network.kqlPlaceholder": "例:source.ip: \"foo\"", "xpack.securitySolution.network.navigation.alertsTitle": "外部アラート", "xpack.securitySolution.network.navigation.anomaliesTitle": "異常", "xpack.securitySolution.network.navigation.dnsTitle": "DNS", @@ -14218,10 +16834,10 @@ "xpack.securitySolution.networkDnsTable.column.TotalQueriesTitle": "クエリ合計", "xpack.securitySolution.networkDnsTable.column.uniqueDomainsTitle": "固有のドメイン", "xpack.securitySolution.networkDnsTable.helperTooltip": "これは DNS プロトコルトラフィックのみを示しており、DNS データ逆浸出に使用されたドメインの調査に役立ちます。", - "xpack.securitySolution.networkDnsTable.rows": "{numRows} {numRows, plural, =0 {rows} =1 {row} other {rows}}", + "xpack.securitySolution.networkDnsTable.rows": "{numRows} {numRows, plural, =0 {行} =1 {行} other {行}}", "xpack.securitySolution.networkDnsTable.select.includePtrRecords": "PTR 記録を含める", "xpack.securitySolution.networkDnsTable.title": "トップ DNS ドメイン", - "xpack.securitySolution.networkDnsTable.unit": "{totalCount, plural, =1 {domain} other {domains}}", + "xpack.securitySolution.networkDnsTable.unit": "{totalCount, plural, =1 {ドメイン} other {ドメイン}}", "xpack.securitySolution.networkHttpTable.column.domainTitle": "ドメイン", "xpack.securitySolution.networkHttpTable.column.lastHostTitle": "最後のホスト", "xpack.securitySolution.networkHttpTable.column.lastSourceIpTitle": "最後のソースIP", @@ -14229,7 +16845,7 @@ "xpack.securitySolution.networkHttpTable.column.pathTitle": "パス", "xpack.securitySolution.networkHttpTable.column.requestsTitle": "リクエスト", "xpack.securitySolution.networkHttpTable.column.statusTitle": "ステータス", - "xpack.securitySolution.networkHttpTable.rows": "{numRows} {numRows, plural, =0 {rows} =1 {行} other {行}}", + "xpack.securitySolution.networkHttpTable.rows": "{numRows} {numRows, plural, =0 {行} =1 {行} other {行}}", "xpack.securitySolution.networkHttpTable.title": "HTTPリクエスト", "xpack.securitySolution.networkHttpTable.unit": "{totalCount, plural, =1 {リクエスト} other {リクエスト}}", "xpack.securitySolution.networkTopCountriesTable.column.bytesInTitle": "受信バイト", @@ -14240,8 +16856,8 @@ "xpack.securitySolution.networkTopCountriesTable.column.sourceIps": "ソース IP", "xpack.securitySolution.networkTopCountriesTable.heading.destinationCountries": "デスティネーションの国", "xpack.securitySolution.networkTopCountriesTable.heading.sourceCountries": "ソースの国", - "xpack.securitySolution.networkTopCountriesTable.heading.unit": "{totalCount, plural, =1 {Country} other {Countries}}", - "xpack.securitySolution.networkTopCountriesTable.rows": "{numRows} {numRows, plural, =0 {rows} =1 {row} other {rows}}", + "xpack.securitySolution.networkTopCountriesTable.heading.unit": "{totalCount, plural, =1 {国} other {国}}", + "xpack.securitySolution.networkTopCountriesTable.rows": "{numRows} {numRows, plural, =0 {行} =1 {行} other {行}}", "xpack.securitySolution.networkTopNFlowTable.column.asTitle": "自動システム", "xpack.securitySolution.networkTopNFlowTable.column.bytesInTitle": "受信バイト", "xpack.securitySolution.networkTopNFlowTable.column.bytesOutTitle": "送信バイト", @@ -14251,9 +16867,9 @@ "xpack.securitySolution.networkTopNFlowTable.column.sourceIpTitle": "ソース IP", "xpack.securitySolution.networkTopNFlowTable.destinationIps": "デスティネーション IP", "xpack.securitySolution.networkTopNFlowTable.flows": "Flow", - "xpack.securitySolution.networkTopNFlowTable.rows": "{numRows} {numRows, plural, =0 {rows} =1 {row} other {rows}}", + "xpack.securitySolution.networkTopNFlowTable.rows": "{numRows} {numRows, plural, =0 {行} =1 {行} other {行}}", "xpack.securitySolution.networkTopNFlowTable.sourceIps": "ソース IP", - "xpack.securitySolution.networkTopNFlowTable.unit": "{totalCount, plural, =1 {IP} other {IPs}}", + "xpack.securitySolution.networkTopNFlowTable.unit": "{totalCount, plural, =1 {IP} other {IP}}", "xpack.securitySolution.newsFeed.advancedSettingsLinkTitle": "SIEM高度な設定", "xpack.securitySolution.newsFeed.noNewsMessage": "現在のニュースフィードURLは最新のニュースを返しませんでした。URLを更新するか、セキュリティニュースを無効にすることができます", "xpack.securitySolution.notes.addANotePlaceholder": "メモを追加", @@ -14269,8 +16885,10 @@ "xpack.securitySolution.open.timeline.batchActionsTitle": "一斉アクション", "xpack.securitySolution.open.timeline.cancelButton": "キャンセル", "xpack.securitySolution.open.timeline.collapseButton": "縮小", + "xpack.securitySolution.open.timeline.createTemplateFromTimelineTooltip": "タイムラインからテンプレ―tを作成", + "xpack.securitySolution.open.timeline.createTimelineFromTemplateTooltip": "テンプレートからタイムラインを作成", "xpack.securitySolution.open.timeline.deleteButton": "削除", - "xpack.securitySolution.open.timeline.deleteSelectedButton": "選択項目を削除", + "xpack.securitySolution.open.timeline.deleteSelectedButton": "選択した項目を削除", "xpack.securitySolution.open.timeline.deleteTimelineModalTitle": "「{title}」を削除しますか?", "xpack.securitySolution.open.timeline.deleteWarningLabel": "削除すると、このタイムライン自体またはそのメモを復元することはできません。", "xpack.securitySolution.open.timeline.descriptionTableHeader": "説明", @@ -14285,18 +16903,27 @@ "xpack.securitySolution.open.timeline.modifiedByTableHeader": "変更者:", "xpack.securitySolution.open.timeline.notesTooltip": "メモ", "xpack.securitySolution.open.timeline.onlyFavoritesButtonLabel": "お気に入りのみ", + "xpack.securitySolution.open.timeline.openAsDuplicateTemplateTooltip": "重複するテンプレート", "xpack.securitySolution.open.timeline.openAsDuplicateTooltip": "重複タイムライン", "xpack.securitySolution.open.timeline.openTimelineButton": "タイムラインを開く…", "xpack.securitySolution.open.timeline.openTimelineTitle": "タイムラインを開く", "xpack.securitySolution.open.timeline.pinnedEventsTooltip": "ピン付けされたイベント", + "xpack.securitySolution.open.timeline.pluralTemplatesLabel": "テンプレート", + "xpack.securitySolution.open.timeline.pluralTimelinesLabel": "タイムライン", "xpack.securitySolution.open.timeline.postedLabel": "投稿:", "xpack.securitySolution.open.timeline.refreshTitle": "更新", "xpack.securitySolution.open.timeline.searchPlaceholder": "例:タイムライン名、または説明", + "xpack.securitySolution.open.timeline.searchTemplatePlaceholder": "例:テンプレート名または説明", + "xpack.securitySolution.open.timeline.selectedTemplatesTitle": "{selectedTemplates} {selectedTemplates, plural, =1 {個のテンプレート} other {個のテンプレート}}を選択しました", "xpack.securitySolution.open.timeline.selectedTimelinesTitle": "{selectedTimelines} {selectedTimelines, plural, =1 {タイムライン} other {タイムライン}}を選択しました", "xpack.securitySolution.open.timeline.showingLabel": "表示中:", - "xpack.securitySolution.open.timeline.showingNTimelinesLabel": "{totalSearchResultsCount} 件の {totalSearchResultsCount, plural, one {タイムライン} other {タイムライン}} {with}", + "xpack.securitySolution.open.timeline.showingNTemplatesLabel": "{totalSearchResultsCount}件の{totalSearchResultsCount, plural, one {個のテンプレート} other {個のテンプレート}} {with}", + "xpack.securitySolution.open.timeline.showingNTimelinesLabel": "{totalSearchResultsCount}件の {totalSearchResultsCount, plural, one {タイムライン} other {タイムライン}} {with}", + "xpack.securitySolution.open.timeline.singleTemplateLabel": "テンプレート", + "xpack.securitySolution.open.timeline.singleTimelineLabel": "タイムライン", "xpack.securitySolution.open.timeline.successfullyExportedTimelinesTitle": "{totalTimelines, plural, =0 {all timelines} =1 {{totalTimelines} タイムライン} other {{totalTimelines} タイムライン}}のエクスポートが正常に完了しました", "xpack.securitySolution.open.timeline.timelineNameTableHeader": "タイムライン名", + "xpack.securitySolution.open.timeline.timelineTemplateNameTableHeader": "テンプレート名", "xpack.securitySolution.open.timeline.untitledTimelineLabel": "無題のタイムライン", "xpack.securitySolution.open.timeline.withLabel": "With", "xpack.securitySolution.open.timeline.zeroTimelinesMatchLabel": "0 件のタイムラインが検索条件に一致", @@ -14314,8 +16941,13 @@ "xpack.securitySolution.overview.endgameProcessTitle": "プロセス", "xpack.securitySolution.overview.endgameRegistryTitle": "レジストリ", "xpack.securitySolution.overview.endgameSecurityTitle": "セキュリティ", + "xpack.securitySolution.overview.endpointNotice.dismiss": "メッセージを消去", + "xpack.securitySolution.overview.endpointNotice.introducing": "導入: ", + "xpack.securitySolution.overview.endpointNotice.message": "脅威防御、検出、深いセキュリティデータの可視化を実現し、ホストを保護します。", + "xpack.securitySolution.overview.endpointNotice.title": "Elastic Endpoint Securityベータ", + "xpack.securitySolution.overview.endpointNotice.tryButton": "Elastic Endpoint Securityベータを試す", "xpack.securitySolution.overview.eventsTitle": "イベント数", - "xpack.securitySolution.overview.feedbackText": "Elastic Security に関するご意見やご提案は、お気軽に {feedback}", + "xpack.securitySolution.overview.feedbackText": "Elastic SIEM に関するご意見やご提案は、お気軽に {feedback}", "xpack.securitySolution.overview.feedbackText.feedbackLinkText": "フィードバックをオンラインで送信", "xpack.securitySolution.overview.feedbackTitle": "フィードバック", "xpack.securitySolution.overview.filebeatCiscoTitle": "Cisco", @@ -14343,32 +16975,39 @@ "xpack.securitySolution.overview.packetBeatFlowTitle": "フロー", "xpack.securitySolution.overview.packetbeatTLSTitle": "TLS", "xpack.securitySolution.overview.pageSubtitle": "Elastic Stackによるセキュリティ情報とイベント管理", - "xpack.securitySolution.overview.pageTitle": "Security", + "xpack.securitySolution.overview.pageTitle": "セキュリティ", "xpack.securitySolution.overview.recentCasesSidebarTitle": "最近のケース", "xpack.securitySolution.overview.recentlyCreatedCasesButtonLabel": "最近作成したケース", "xpack.securitySolution.overview.recentTimelinesSidebarTitle": "最近のタイムライン", "xpack.securitySolution.overview.showTopTooltip": "上位の{fieldName}を表示", - "xpack.securitySolution.overview.startedText": "セキュリティ情報およびイベント管理(SIEM)へようこそ。はじめに{docs}や{data}をご参照ください。今後の機能に関する情報やチュートリアルは、{siemSolution} ページをお見逃しなく。", + "xpack.securitySolution.overview.signalCountTitle": "検出アラート傾向", + "xpack.securitySolution.overview.startedText": "セキュリティ情報およびイベント管理(SIEM)へようこそ。はじめに{docs}や{data}をご参照ください。今後の機能に関する情報やチュートリアルは、{siemSolution}ページをご覧ください。", "xpack.securitySolution.overview.startedText.dataLinkText": "投入データ", "xpack.securitySolution.overview.startedText.docsLinkText": "ドキュメンテーション", - "xpack.securitySolution.overview.startedText.siemSolutionLinkText": "Security ソリューション", + "xpack.securitySolution.overview.startedText.siemSolutionLinkText": "SIEM ソリューション", "xpack.securitySolution.overview.startedTitle": "はじめて使う", "xpack.securitySolution.overview.topNLabel": "トップ{fieldName}", "xpack.securitySolution.overview.viewAlertsButtonLabel": "アラートを表示", "xpack.securitySolution.overview.viewEventsButtonLabel": "イベントを表示", "xpack.securitySolution.overview.winlogbeatMWSysmonOperational": "Microsoft-Windows-Sysmon/Operational", "xpack.securitySolution.overview.winlogbeatSecurityTitle": "セキュリティ", - "xpack.securitySolution.pages.common.emptyActionPrimary": "Beatsでデータを表示", - "xpack.securitySolution.pages.common.emptyActionSecondary": "入門ガイドを表示", - "xpack.securitySolution.pages.common.emptyTitle": "SIEMへようこそ。始めましょう。", + "xpack.securitySolution.pages.common.emptyActionEndpoint": "Elasticエージェント(ベータ)でデータを追加", + "xpack.securitySolution.pages.common.emptyActionSecondary": "入門ガイドを表示します。", + "xpack.securitySolution.pages.common.emptyTitle": "セキュリティソリューションへようこそ。始めましょう。", "xpack.securitySolution.pages.fourohfour.noContentFoundDescription": "コンテンツがありません", "xpack.securitySolution.paginatedTable.rowsButtonLabel": "ページごとの行数", "xpack.securitySolution.paginatedTable.showingSubtitle": "表示中", "xpack.securitySolution.paginatedTable.tooManyResultsToastText": "クエリ範囲を縮めて結果をさらにフィルタリングしてください", "xpack.securitySolution.paginatedTable.tooManyResultsToastTitle": " - 結果が多すぎます", + "xpack.securitySolution.policiesTab": "ポリシー", + "xpack.securitySolution.policyList.pageSubTitle": "保護の表示と構成", + "xpack.securitySolution.policyList.pageTitle": "ポリシー", + "xpack.securitySolution.policyStatusText.failure": "失敗", + "xpack.securitySolution.policyStatusText.success": "成功", + "xpack.securitySolution.policyStatusText.warning": "警告", "xpack.securitySolution.recentCases.commentsTooltip": "コメント", - "xpack.securitySolution.recentCases.noCasesMessage": "まだケースを作成していません。探偵帽をかぶって新しいケースを開始します", - "xpack.securitySolution.recentCases.startNewCaseLink": "", + "xpack.securitySolution.recentCases.noCasesMessage": "まだケースを作成していません。準備して", + "xpack.securitySolution.recentCases.startNewCaseLink": "新しいケースの開始", "xpack.securitySolution.recentCases.viewAllCasesLink": "すべてのケースを表示", "xpack.securitySolution.recentTimelines.errorRetrievingUserDetailsMessage": "最近のタイムライン:ユーザー詳細の取得中にエラーが発生しました", "xpack.securitySolution.recentTimelines.favoritesButtonLabel": "お気に入り", @@ -14376,13 +17015,15 @@ "xpack.securitySolution.recentTimelines.noFavoriteTimelinesMessage": "まだタイムラインをお気に入りに登録していません。脅威の検出を開始しましょう。", "xpack.securitySolution.recentTimelines.notesTooltip": "メモ", "xpack.securitySolution.recentTimelines.noTimelinesMessage": "まだタイムラインを作成していません。脅威の検出を開始しましょう。", - "xpack.securitySolution.recentTimelines.openAsDuplicateTooltip": "重複タイムラインとして開く", + "xpack.securitySolution.recentTimelines.openAsDuplicateTemplateTooltip": "テンプレート重複として開く", + "xpack.securitySolution.recentTimelines.openAsDuplicateTooltip": "タイムライン重複として開く", "xpack.securitySolution.recentTimelines.pinnedEventsTooltip": "ピン付けされたイベント", "xpack.securitySolution.recentTimelines.untitledTimelineLabel": "無題のタイムライン", "xpack.securitySolution.recentTimelines.viewAllTimelinesLink": "すべてのタイムラインを表示", + "xpack.securitySolution.security.title": "セキュリティ", "xpack.securitySolution.source.destination.packetsLabel": "パケット", - "xpack.securitySolution.system.acceptedAConnectionViaDescription": "次の手段で接続を受け付けました:", - "xpack.securitySolution.system.acceptedDescription": "以下を経由してユーザーを受け入れました:", + "xpack.securitySolution.system.acceptedAConnectionViaDescription": "次の手段で接続を受け付けました。", + "xpack.securitySolution.system.acceptedDescription": "以下を経由してユーザーを受け入れました。", "xpack.securitySolution.system.attemptedLoginDescription": "以下を経由してログインを試行しました:", "xpack.securitySolution.system.createdFileDescription": "ファイルを作成しました", "xpack.securitySolution.system.deletedFileDescription": "ファイルを削除しました", @@ -14402,8 +17043,8 @@ "xpack.securitySolution.system.processErrorDescription": "次に関するプロセスエラーが発生:", "xpack.securitySolution.system.processStartedDescription": "プロセスを開始しました", "xpack.securitySolution.system.processStoppedDescription": "プロセスを停止しました", - "xpack.securitySolution.system.socketClosedDescription": "以下とのソケットをクローズしました:", - "xpack.securitySolution.system.socketOpenedDescription": "以下とソケットを開きました:", + "xpack.securitySolution.system.socketClosedDescription": "以下とのソケットをクローズしました。", + "xpack.securitySolution.system.socketOpenedDescription": "以下とソケットを開きました。", "xpack.securitySolution.system.systemDescription": "システム", "xpack.securitySolution.system.terminatedProcessDescription": "プロセスを中断しました", "xpack.securitySolution.system.userAddedDescription": "ユーザーが追加されました", @@ -14412,17 +17053,21 @@ "xpack.securitySolution.system.usingDescription": "using", "xpack.securitySolution.system.viaDescription": "経由", "xpack.securitySolution.system.viaParentProcessDescription": "親プロセスで", - "xpack.securitySolution.system.wasAuthorizedToUseDescription": "が以下の使用を承認されました:", + "xpack.securitySolution.system.wasAuthorizedToUseDescription": "が以下の使用を承認されました。", "xpack.securitySolution.system.withExitCodeDescription": "終了コードで", "xpack.securitySolution.system.withResultDescription": "結果付き", "xpack.securitySolution.tables.rowItemHelper.moreDescription": "行は表示されていません", - "xpack.securitySolution.timeline.autosave.warning.description": "別のユーザーがこのタイムラインに変更を加えました。このタイムラインを更新してこれらの変更を取り入れるまで、ユーザーによる変更は自動的に保存されません。", + "xpack.securitySolution.timeline.autosave.warning.description": "別のユーザーがこのタイムラインに変更を加えました。このタイムラインを更新してこれらの変更を反映させるまで、ユーザーによる変更は自動的に保存されません。", "xpack.securitySolution.timeline.autosave.warning.refresh.title": "タイムラインを更新", "xpack.securitySolution.timeline.autosave.warning.title": "更新されるまで自動保存は無効です", "xpack.securitySolution.timeline.body.actions.collapseAriaLabel": "縮小", + "xpack.securitySolution.timeline.body.actions.collapseEventTooltip": "イベントを折りたたむ", "xpack.securitySolution.timeline.body.actions.expandAriaLabel": "拡張", + "xpack.securitySolution.timeline.body.actions.investigateInResolverTooltip": "イベントを分析します", "xpack.securitySolution.timeline.body.copyToClipboardButtonLabel": "クリップボードにコピー", - "xpack.securitySolution.timeline.body.notes.addOrViewNotesForThisEventTooltip": "このイベントのメモを追加または表示します", + "xpack.securitySolution.timeline.body.notes.addOrViewNotesForThisEventTooltip": "このイベントのメモを追加します", + "xpack.securitySolution.timeline.body.notes.disableEventTooltip": "テンプレートタイムラインの編集中には、メモが追加されない場合があります", + "xpack.securitySolution.timeline.body.pinning.disablePinnnedTooltip": "テンプレートタイムラインの編集中には、このイベントがピン留めされない場合があります", "xpack.securitySolution.timeline.body.pinning.pinnedTooltip": "ピン付けされたイベント", "xpack.securitySolution.timeline.body.pinning.pinnnedWithNotesTooltip": "イベントにメモがあり、ピンを外すことができません", "xpack.securitySolution.timeline.body.pinning.unpinnedTooltip": "ピン付け解除されたイベント", @@ -14432,7 +17077,7 @@ "xpack.securitySolution.timeline.body.renderers.dns.whichResolvedToDescription": "で解決する", "xpack.securitySolution.timeline.body.renderers.dns.withQuestionTypeDescription": "質問タイプで", "xpack.securitySolution.timeline.body.renderers.endgame.aLoginWasAttemptedUsingExplicitCredentialsDescription": "明示認証情報でログインが試みられました", - "xpack.securitySolution.timeline.body.renderers.endgame.asRequestedBySubjectDescription": "サブジェクトにリクエストされた通り", + "xpack.securitySolution.timeline.body.renderers.endgame.asRequestedBySubjectDescription": "サブジェクトにリクエストされたとおり", "xpack.securitySolution.timeline.body.renderers.endgame.loggedOffDescription": "ログオフ", "xpack.securitySolution.timeline.body.renderers.endgame.logonTypeBatchDescription": "一斉", "xpack.securitySolution.timeline.body.renderers.endgame.logonTypeCachedInteractiveDescription": "キャッシュインタラクティブ", @@ -14450,10 +17095,13 @@ "xpack.securitySolution.timeline.body.renderers.endgame.usingLogonTypeDescription": "ログオンタイプを使用して", "xpack.securitySolution.timeline.body.renderers.endgame.viaDescription": "経由", "xpack.securitySolution.timeline.body.renderers.endgame.withSpecialPrivilegesDescription": "割り当てられた特別な権限", - "xpack.securitySolution.timeline.callOut.unauthorized.message.description": "Security アプリケーションでタイムラインを自動保存するにはパーミッションが必要ですが、引き続きタイムラインを使用してセキュリティイベントの検索とフィルタリングを行うことはできます。", + "xpack.securitySolution.timeline.body.sort.sortedAscendingTooltip": "昇順で並べ替えます", + "xpack.securitySolution.timeline.body.sort.sortedDescendingTooltip": "降順で並べ替えます", + "xpack.securitySolution.timeline.callOut.immutable.message.description": "タイムラインを引き続き使用して、セキュリティイベントの検索とフィルターはできますが、このタイムラインは変わらないため、セキュリティアプリケーションで保存することはできません。", + "xpack.securitySolution.timeline.callOut.unauthorized.message.description": "タイムラインを使用すると、イベントを調査することができますが、今後使用する目的でタイムラインを保存するために必要な権限がありません。タイムラインを保存する必要がある場合は、Kibana管理者に連絡してください。", "xpack.securitySolution.timeline.categoryTooltip": "カテゴリー", "xpack.securitySolution.timeline.defaultTimelineDescription": "新しいタイムラインを作成するときにデフォルトで提供されるタイムライン。", - "xpack.securitySolution.timeline.defaultTimelineTitle": "デフォルトの空白タイムライン", + "xpack.securitySolution.timeline.defaultTimelineTitle": "なし", "xpack.securitySolution.timeline.descriptionTooltip": "説明", "xpack.securitySolution.timeline.destination": "送信先", "xpack.securitySolution.timeline.eventsSelect.actions.pinSelected": "選択項目にピン付け", @@ -14468,8 +17116,14 @@ "xpack.securitySolution.timeline.flyout.header.closeTimelineButtonLabel": "タイムラインを閉じる", "xpack.securitySolution.timeline.flyout.pane.removeColumnButtonLabel": "列を削除", "xpack.securitySolution.timeline.flyout.pane.timelinePropertiesAriaLabel": "タイムラインのプロパティ", + "xpack.securitySolution.timeline.flyoutTimelineTemplateLabel": "タイムラインテンプレート", + "xpack.securitySolution.timeline.fullScreenButton": "全画面", + "xpack.securitySolution.timeline.graphOverlay.backToEventsButton": "< イベントに戻る", + "xpack.securitySolution.timeline.properties.attachToExistingCaseButtonLabel": "既存のケースに添付...", + "xpack.securitySolution.timeline.properties.attachToNewCaseButtonLabel": "新しいケースに添付", "xpack.securitySolution.timeline.properties.descriptionPlaceholder": "説明", "xpack.securitySolution.timeline.properties.descriptionTooltip": "このタイムラインのイベントのサマリーとメモ", + "xpack.securitySolution.timeline.properties.existingCaseButtonLabel": "タイムラインを既存のケースに添付...", "xpack.securitySolution.timeline.properties.favoriteTooltip": "お気に入り", "xpack.securitySolution.timeline.properties.historyLabel": "履歴", "xpack.securitySolution.timeline.properties.historyToolTip": "このタイムラインに関連したアクションの履歴", @@ -14478,6 +17132,7 @@ "xpack.securitySolution.timeline.properties.lockDatePickerDescription": "日付ピッカーをグローバル日付ピッカーにロック", "xpack.securitySolution.timeline.properties.lockDatePickerTooltip": "現在表示中のページとタイムラインの間の日付/時刻範囲の同期を無効にします", "xpack.securitySolution.timeline.properties.newCaseButtonLabel": "タイムラインを新しいケースに接続する", + "xpack.securitySolution.timeline.properties.newTemplateTimelineButtonLabel": "新規タイムラインテンプレートを作成", "xpack.securitySolution.timeline.properties.newTimelineButtonLabel": "新規タイムラインを作成", "xpack.securitySolution.timeline.properties.notAFavoriteTooltip": "お気に入りではありません", "xpack.securitySolution.timeline.properties.notesButtonLabel": "メモ", @@ -14489,13 +17144,16 @@ "xpack.securitySolution.timeline.properties.titleTitle": "タイトル", "xpack.securitySolution.timeline.properties.unlockDatePickerDescription": "日付ピッカーのグローバル日付ピッカーへのロックを解除", "xpack.securitySolution.timeline.properties.unlockDatePickerTooltip": "現在表示中のページとタイムラインの間の日付/時刻範囲の同期を有効にします", + "xpack.securitySolution.timeline.properties.untitledTemplatePlaceholder": "無題のテンプレート", "xpack.securitySolution.timeline.properties.untitledTimelinePlaceholder": "無題のタイムライン", "xpack.securitySolution.timeline.protocol": "プロトコル", "xpack.securitySolution.timeline.rangePicker.oneDay": "1 日", "xpack.securitySolution.timeline.rangePicker.oneMonth": "1 か月", "xpack.securitySolution.timeline.rangePicker.oneWeek": "1 週間", "xpack.securitySolution.timeline.rangePicker.oneYear": "1 年", - "xpack.securitySolution.timeline.searchOrFilter.eventTypeAllEvent": "すべてのイベント", + "xpack.securitySolution.timeline.searchBoxPlaceholder": "例:{timeline}名、または説明", + "xpack.securitySolution.timeline.searchOrFilter.eventTypeAllEvent": "すべて", + "xpack.securitySolution.timeline.searchOrFilter.eventTypeDetectionAlertsEvent": "検出アラート", "xpack.securitySolution.timeline.searchOrFilter.eventTypeRawEvent": "未加工イベント", "xpack.securitySolution.timeline.searchOrFilter.filterDescription": "上のデータプロバイダーからのイベントは、隣接の KQL でフィルターされます", "xpack.securitySolution.timeline.searchOrFilter.filterKqlPlaceholder": "イベントをフィルター", @@ -14518,21 +17176,26 @@ "xpack.securitySolution.timelines.components.importTimelineModal.importTitle": "タイムラインをインポート...", "xpack.securitySolution.timelines.components.importTimelineModal.initialPromptTextDescription": "有効な timelines_export.ndjson ファイルを選択するか、またはドラッグアンドドロップします", "xpack.securitySolution.timelines.components.importTimelineModal.overwriteDescription": "保存されたオブジェクトを同じタイムライン ID で自動的に上書きします", - "xpack.securitySolution.timelines.components.importTimelineModal.selectTimelineDescription": "インポートする Security ルール (タイムラインビューからエクスポートしたもの) を選択します", + "xpack.securitySolution.timelines.components.importTimelineModal.selectTimelineDescription": "インポートするセキュリティルール(タイムラインビューからエクスポートしたもの)を選択します", "xpack.securitySolution.timelines.components.importTimelineModal.successfullyImportedTimelinesTitle": "{totalCount} {totalCount, plural, =1 {タイムライン} other {タイムライン}}のインポートが正常に完了しました", "xpack.securitySolution.timelines.components.tabs.templatesTitle": "テンプレート", "xpack.securitySolution.timelines.components.tabs.timelinesTitle": "タイムライン", + "xpack.securitySolution.timelines.components.templateFilter.customizedTitle": "カスタムテンプレート", + "xpack.securitySolution.timelines.components.templateFilter.elasticTitle": "Elasticテンプレート", "xpack.securitySolution.timelines.pageTitle": "タイムライン", + "xpack.securitySolution.timelines.updateTimelineErrorText": "問題が発生しました", + "xpack.securitySolution.timelines.updateTimelineErrorTitle": "タイムラインエラー", + "xpack.securitySolution.topN.alertEventsSelectLabel": "アラートイベント", "xpack.securitySolution.topN.allEventsSelectLabel": "すべてのイベント", "xpack.securitySolution.topN.closeButtonLabel": "閉じる", "xpack.securitySolution.topN.rawEventsSelectLabel": "未加工イベント", - "xpack.securitySolution.uiSettings.defaultAnomalyScoreDescription": "

      機械学習ジョブの異常がこの値を超えると Security アプリに表示されます。

      有効な値:0 ~ 100。

      ", + "xpack.securitySolution.uiSettings.defaultAnomalyScoreDescription": "

      機械学習ジョブの異常がこの値を超えると、セキュリティアプリに表示されます。

      有効な値:0 ~ 100。

      ", "xpack.securitySolution.uiSettings.defaultAnomalyScoreLabel": "デフォルトの異常しきい値", - "xpack.securitySolution.uiSettings.defaultIndexDescription": "

      Security アプリがイベントを収集する Elasticsearch インデックスのコンマ区切りのリストです。

      ", + "xpack.securitySolution.uiSettings.defaultIndexDescription": "

      セキュリティアプリがイベントを収集するElasticsearchインデックスのコンマ区切りのリストです。

      ", "xpack.securitySolution.uiSettings.defaultIndexLabel": "デフォルトのインデックス", - "xpack.securitySolution.uiSettings.defaultRefreshIntervalDescription": "

      Security 時間フィルターのミリ単位のデフォルトの更新間隔です。

      ", + "xpack.securitySolution.uiSettings.defaultRefreshIntervalDescription": "

      セキュリティ時間フィルターのミリ単位のデフォルトの更新間隔です。

      ", "xpack.securitySolution.uiSettings.defaultRefreshIntervalLabel": "タイムピッカーの更新間隔", - "xpack.securitySolution.uiSettings.defaultTimeRangeDescription": "

      Security 時間フィルダーのデフォルトの期間です。

      ", + "xpack.securitySolution.uiSettings.defaultTimeRangeDescription": "

      セキュリティ時間フィルダーのデフォルトの期間です。

      ", "xpack.securitySolution.uiSettings.defaultTimeRangeLabel": "デフォルトのタイムピッカー", "xpack.securitySolution.uiSettings.enableNewsFeedDescription": "

      ニュースフィードを有効にします

      ", "xpack.securitySolution.uiSettings.enableNewsFeedLabel": "ニュースフィード", @@ -14544,10 +17207,10 @@ "xpack.securitySolution.uncommonProcessTable.lastCommandTitle": "前回のコマンド", "xpack.securitySolution.uncommonProcessTable.lastUserTitle": "前回のユーザー", "xpack.securitySolution.uncommonProcessTable.nameTitle": "名前", - "xpack.securitySolution.uncommonProcessTable.numberOfHostsTitle": "ホスト数", + "xpack.securitySolution.uncommonProcessTable.numberOfHostsTitle": "ホスト", "xpack.securitySolution.uncommonProcessTable.numberOfInstances": "インスタンス", - "xpack.securitySolution.uncommonProcessTable.rows": "{numRows} {numRows, plural, =0 {rows} =1 {row} other {rows}}", - "xpack.securitySolution.uncommonProcessTable.unit": "{totalCount, plural, =1 {process} other {processes}}", + "xpack.securitySolution.uncommonProcessTable.rows": "{numRows} {numRows, plural, =0 {行} =1 {行} other {行}}", + "xpack.securitySolution.uncommonProcessTable.unit": "{totalCount, plural, =1 {プロセス} other {プロセス}}", "xpack.securitySolution.zeek.othDescription": "SYNが検出されません。ミッドストリームトラフィックのみです", "xpack.securitySolution.zeek.rejDescription": "接続試行が拒否されました", "xpack.securitySolution.zeek.rstoODescription": "接続が確立され、接続元が中断しました(RSTを送信)", @@ -14561,6 +17224,9 @@ "xpack.securitySolution.zeek.sfDescription": "通常のSYN/FIN完了", "xpack.securitySolution.zeek.shDescription": "接続元がFINに続きSYNを送信しました。レスポンダーからSYN-ACKはありません", "xpack.securitySolution.zeek.shrDescription": "レスポンダーがFINに続きSYNを送信しました。接続元からSYN-ACKはありません", + "xpack.server.checkLicense.errorExpiredMessage": "{licenseType} ライセンスが期限切れのため {pluginName} を使用できません", + "xpack.server.checkLicense.errorUnavailableMessage": "現在ライセンス情報が利用できないため {pluginName} を使用できません。", + "xpack.server.checkLicense.errorUnsupportedMessage": "ご使用の {licenseType} ライセンスは {pluginName} をサポートしていません。ライセンスをアップグレードしてください。", "xpack.snapshotRestore.addPolicy.breadcrumbTitle": "ポリシーを追加", "xpack.snapshotRestore.addPolicy.loadingIndicesDescription": "利用可能なインデックスを読み込み中…", "xpack.snapshotRestore.addPolicy.LoadingIndicesErrorMessage": "利用可能なインデックスを読み込み中にエラーが発生", @@ -14578,6 +17244,9 @@ "xpack.snapshotRestore.appTitle": "スナップショットリポジドリ", "xpack.snapshotRestore.createPolicyButton": "ポリシーを作成", "xpack.snapshotRestore.dataPlaceholderLabel": "-", + "xpack.snapshotRestore.dataStreamsList.allDataStreamsValue": "すべてのデータストリーム", + "xpack.snapshotRestore.dataStreamsList.dataStreamsCollapseAllLink": "{count, plural, one {# 件のデータストリーム} other {# 件のデータストリーム}}を非表示", + "xpack.snapshotRestore.dataStreamsList.dataStreamsExpandAllLink": "{count, plural, one {# 件のデータストリーム} other {# 件のデータストリーム}}を表示", "xpack.snapshotRestore.deletePolicy.confirmModal.cancelButtonLabel": "キャンセル", "xpack.snapshotRestore.deletePolicy.confirmModal.confirmButtonLabel": "{count, plural, one {ポリシー} other {ポリシー}}を削除", "xpack.snapshotRestore.deletePolicy.confirmModal.deleteMultipleListDescription": "これらのポリシーを削除しようとしています:", @@ -14653,6 +17322,7 @@ "xpack.snapshotRestore.licenseCheckErrorMessage": "ライセンス確認失敗", "xpack.snapshotRestore.policies.breadcrumbTitle": "ポリシー", "xpack.snapshotRestore.policyDetails.closeButtonLabel": "閉じる", + "xpack.snapshotRestore.policyDetails.dataStreamsAndIndicesLabel": "データストリームとインデックス", "xpack.snapshotRestore.policyDetails.deleteButtonLabel": "削除", "xpack.snapshotRestore.policyDetails.editButtonLabel": "編集", "xpack.snapshotRestore.policyDetails.executeButtonLabel": "今すぐ実行", @@ -14715,6 +17385,7 @@ "xpack.snapshotRestore.policyForm.reloadRepositoriesButtonLabel": "レポジトリを再読み込み", "xpack.snapshotRestore.policyForm.saveButtonLabel": "ポリシーを保存", "xpack.snapshotRestore.policyForm.savingButtonLabel": "保存中…", + "xpack.snapshotRestore.policyForm.setSettings.dataStreamBadgeContent": "データストリーム", "xpack.snapshotRestore.policyForm.stepLogistics.docsButtonLabel": "ロジスティクスドキュメント", "xpack.snapshotRestore.policyForm.stepLogistics.nameDescription": "このポリシーの固有の識別子です。", "xpack.snapshotRestore.policyForm.stepLogistics.nameDescriptionTitle": "ポリシー名", @@ -14765,6 +17436,7 @@ "xpack.snapshotRestore.policyForm.stepReview.retentionTab.maxCountLabel": "最高カウント", "xpack.snapshotRestore.policyForm.stepReview.retentionTab.minCountLabel": "最低カウント", "xpack.snapshotRestore.policyForm.stepReview.retentionTab.sectionRetentionTitle": "スナップショットの保存", + "xpack.snapshotRestore.policyForm.stepReview.summaryTab.dataStreamsAndIndicesLabel": "データストリームとインデックス", "xpack.snapshotRestore.policyForm.stepReview.summaryTab.editStepTooltip": "編集", "xpack.snapshotRestore.policyForm.stepReview.summaryTab.ignoreUnavailableFalseLabel": "いいえ", "xpack.snapshotRestore.policyForm.stepReview.summaryTab.ignoreUnavailableLabel": "利用不可能なインデックスを無視", @@ -14774,6 +17446,7 @@ "xpack.snapshotRestore.policyForm.stepReview.summaryTab.includeGlobalStateTrueLabel": "はい", "xpack.snapshotRestore.policyForm.stepReview.summaryTab.nameLabel": "ポリシー名", "xpack.snapshotRestore.policyForm.stepReview.summaryTab.partialFalseLabel": "いいえ", + "xpack.snapshotRestore.policyForm.stepReview.summaryTab.partialIndicesLabel": "部分インデックスを許可", "xpack.snapshotRestore.policyForm.stepReview.summaryTab.partialTrueLabel": "はい", "xpack.snapshotRestore.policyForm.stepReview.summaryTab.repositoryLabel": "レポジトリ", "xpack.snapshotRestore.policyForm.stepReview.summaryTab.scheduleLabel": "スケジュール", @@ -14782,23 +17455,29 @@ "xpack.snapshotRestore.policyForm.stepReview.summaryTab.snapshotNameLabel": "スナップショット名", "xpack.snapshotRestore.policyForm.stepReview.summaryTabTitle": "まとめ", "xpack.snapshotRestore.policyForm.stepReviewTitle": "レビューポリシー", + "xpack.snapshotRestore.policyForm.stepSettings.allDataStreamsAndIndicesLabel": "システムインデックスを含むすべてのデータストリームとインデックス", + "xpack.snapshotRestore.policyForm.stepSettings.dataStreamsAndIndicesDescription": "インデックスとデータストリームをバックアップするには、それらを手動で選択するか、それらと一致するインデックスパターンを定義します。", + "xpack.snapshotRestore.policyForm.stepSettings.dataStreamsAndIndicesTitle": "データストリームとインデックス", + "xpack.snapshotRestore.policyForm.stepSettings.dataStreamsAndIndicesToggleListLink": "データストリームとインデックスを選択", "xpack.snapshotRestore.policyForm.stepSettings.deselectAllIndicesLink": "すべて選択解除", "xpack.snapshotRestore.policyForm.stepSettings.docsButtonLabel": "スナップショット設定ドキュメント", "xpack.snapshotRestore.policyForm.stepSettings.ignoreUnavailableDescription": "スナップショットの撮影時に利用不可能なインデックスを無視します。これが設定されていない場合、スナップショット全体がエラーになります。", "xpack.snapshotRestore.policyForm.stepSettings.ignoreUnavailableDescriptionTitle": "利用不可能なインデックスを無視", "xpack.snapshotRestore.policyForm.stepSettings.ignoreUnavailableLabel": "利用不可能なインデックスを無視", - "xpack.snapshotRestore.policyForm.stepSettings.includeGlobalStateDescription": "スナップショットの一部としてクラスターのグローバルステータスを格納します。", + "xpack.snapshotRestore.policyForm.stepSettings.includeGlobalStateDescription": "スナップショットの一部としてグローバルクラスター状態を格納します。", "xpack.snapshotRestore.policyForm.stepSettings.includeGlobalStateDescriptionTitle": "グローバルステータスを含める", "xpack.snapshotRestore.policyForm.stepSettings.indicesPatternLabel": "インデックスパターン", "xpack.snapshotRestore.policyForm.stepSettings.indicesPatternPlaceholder": "logstash-* などのインデックスパターンを入力", "xpack.snapshotRestore.policyForm.stepSettings.indicesToggleCustomLink": "インデックスパターンを使用", "xpack.snapshotRestore.policyForm.stepSettings.indicesTooltip": "クラウドで管理されたポリシーにはすべてのインデックスが必要です。", + "xpack.snapshotRestore.policyForm.stepSettings.noDataStreamsOrIndicesHelpText": "何もバックアップされません。{selectAllLink}", "xpack.snapshotRestore.policyForm.stepSettings.partialDescription": "利用不可能なプライマリシャードのインデックスのスナップショットを許可します。これが設定されていない場合、スナップショット全体がエラーになります。", "xpack.snapshotRestore.policyForm.stepSettings.partialDescriptionTitle": "部分インデックスを許可", "xpack.snapshotRestore.policyForm.stepSettings.partialIndicesToggleSwitch": "部分インデックスを許可", "xpack.snapshotRestore.policyForm.stepSettings.policyIncludeGlobalStateLabel": "グローバルステータスを含める", "xpack.snapshotRestore.policyForm.stepSettings.selectAllIndicesLink": "すべて選択", - "xpack.snapshotRestore.policyForm.stepSettings.selectIndicesLabel": "インデックスを選択", + "xpack.snapshotRestore.policyForm.stepSettings.selectDataStreamsIndicesHelpText": "{indicesCount} {indicesCount, plural, one {個のインデックス} other {個のインデックス}} and {dataStreamsCount} {dataStreamsCount, plural, one {個のデータストリーム} other {個のデータストリーム}}がバックアップされます。{deselectAllLink}", + "xpack.snapshotRestore.policyForm.stepSettings.selectIndicesLabel": "インデックスとデータストリームを選択", "xpack.snapshotRestore.policyForm.stepSettingsTitle": "スナップショット設定", "xpack.snapshotRestore.policyList.deniedPrivilegeDescription": "スナップショットライフサイクルポリシーを管理するには、{privilegesCount, plural, one {このクラスター特権} other {これらのクラスター特権}}が必要です: {missingPrivileges}。", "xpack.snapshotRestore.policyList.deniedPrivilegeTitle": "クラスター特権が足りません", @@ -14846,7 +17525,7 @@ "xpack.snapshotRestore.policyScheduleWarningDescription": "一度に 1 つのスナップショットしか撮影できません。スナップショットのエラーを避けるために、ポリシーを編集または削除してください。", "xpack.snapshotRestore.policyScheduleWarningTitle": "2 つ以上のポリシーに同じスケジュールが設定されています", "xpack.snapshotRestore.policyValidation.indexPatternRequiredErrorMessage": "インデックスパターンが最低 1 つ必要です。", - "xpack.snapshotRestore.policyValidation.indicesRequiredErrorMessage": "インデックスを最低 1 つ選択する必要があります。", + "xpack.snapshotRestore.policyValidation.indicesRequiredErrorMessage": "1つ以上のデータストリームまたはインデックスを選択する必要があります。", "xpack.snapshotRestore.policyValidation.invalidMinCountErrorMessage": "最低カウントは最高カウントよりも大きい値にできません。", "xpack.snapshotRestore.policyValidation.invalidNegativeDeleteAfterErrorMessage": "次の期間後削除は負数にすることができません。", "xpack.snapshotRestore.policyValidation.invalidNegativeMaxCountErrorMessage": "最大カウントは負数にすることができません。", @@ -15139,11 +17818,18 @@ "xpack.snapshotRestore.repositoryWarningLinkText": "レポジトリ", "xpack.snapshotRestore.repositoryWarningTitle": "一部のレポジトリにエラーがあります", "xpack.snapshotRestore.restoreForm.backButtonLabel": "戻る", + "xpack.snapshotRestore.restoreForm.dataStreamsWarningCallOut.body": "各データストリームには、一致するインデックステンプレートが必要です。復元されたすべてのデータストリームに一致するインデックステンプレートがあることを確認してください。インデックステンプレートを復元するには、グローバルクラスター状態を復元します。ただし、既存のテンプレート、クラスター設定、入力パイプライン、ライフサイクルポリシーが上書きされる場合があります。データストリームを含むスナップショットの復元については、{learnMoreLink}。", + "xpack.snapshotRestore.restoreForm.dataStreamsWarningCallOut.body.learnMoreLink": "詳細", + "xpack.snapshotRestore.restoreForm.dataStreamsWarningCallOut.title": "このスナップショットには、{count, plural, one {件のデータストリーム} other {件のデータストリーム}}が含まれます", "xpack.snapshotRestore.restoreForm.navigation.stepLogisticsName": "ロジスティクス", "xpack.snapshotRestore.restoreForm.navigation.stepReviewName": "確認", "xpack.snapshotRestore.restoreForm.navigation.stepSettingsName": "インデックス設定", "xpack.snapshotRestore.restoreForm.nextButtonLabel": "次へ", "xpack.snapshotRestore.restoreForm.savingButtonLabel": "復元中...", + "xpack.snapshotRestore.restoreForm.stepLogistics.allDataStreamsAndIndicesLabel": "システムインデックスを含むすべてのデータストリームとインデックス", + "xpack.snapshotRestore.restoreForm.stepLogistics.dataStreamsAndIndicesDescription": "存在しない場合は、新しいデータストリームを作成します。閉じていて、スナップショットインデックスと同じ数のシャードがある場合は、データストリームのバッキングインデックスを含む既存のインデックスを開きます。", + "xpack.snapshotRestore.restoreForm.stepLogistics.dataStreamsAndIndicesTitle": "データストリームとインデックス", + "xpack.snapshotRestore.restoreForm.stepLogistics.dataStreamsAndIndicesToggleListLink": "データストリームとインデックスを選択", "xpack.snapshotRestore.restoreForm.stepLogistics.deselectAllIndicesLink": "すべて選択解除", "xpack.snapshotRestore.restoreForm.stepLogistics.docsButtonLabel": "スナップショットと復元ドキュメント", "xpack.snapshotRestore.restoreForm.stepLogistics.includeGlobalStateDescription": "現在クラスターに存在しないテンプレートを復元し、テンプレートを同じ名前で上書きします。永続的な設定も復元します。", @@ -15153,16 +17839,23 @@ "xpack.snapshotRestore.restoreForm.stepLogistics.indicesPatternLabel": "インデックスパターン", "xpack.snapshotRestore.restoreForm.stepLogistics.indicesPatternPlaceholder": "logstash-* などのインデックスパターンを入力", "xpack.snapshotRestore.restoreForm.stepLogistics.indicesToggleCustomLink": "インデックスパターンを使用", + "xpack.snapshotRestore.restoreForm.stepLogistics.noDataStreamsOrIndicesHelpText": "何も復元されません。{selectAllLink}", "xpack.snapshotRestore.restoreForm.stepLogistics.partialDescription": "すべてのシャードのスナップショットがないインデックスを復元できます。", "xpack.snapshotRestore.restoreForm.stepLogistics.partialLabel": "部分復元", "xpack.snapshotRestore.restoreForm.stepLogistics.partialTitle": "部分復元", + "xpack.snapshotRestore.restoreForm.stepLogistics.renameDataStreamsAndIndicesDescription": "復元時にデータストリームとインデックスの名前を変更します。名前が変更されたデータストリームに一致するインデックステンプレートが存在することを確認してください。", + "xpack.snapshotRestore.restoreForm.stepLogistics.renameDataStreamsAndIndicesLabel": "データストリームとインデックスの名前を変更", + "xpack.snapshotRestore.restoreForm.stepLogistics.renameDataStreamsAndIndicesTitle": "データストリームとインデックスの名前を変更", "xpack.snapshotRestore.restoreForm.stepLogistics.renamePatternHelpText": "正規表現を使用", "xpack.snapshotRestore.restoreForm.stepLogistics.renamePatternLabel": "取り込みパターン", "xpack.snapshotRestore.restoreForm.stepLogistics.renameReplacementLabel": "置換パターン", "xpack.snapshotRestore.restoreForm.stepLogistics.selectAllIndicesLink": "すべて選択", + "xpack.snapshotRestore.restoreForm.stepLogistics.selectDataStreamsAndIndicesHelpText": "{indicesCount} {indicesCount, plural, one {個のインデックス} other {個のインデックス}} and {dataStreamsCount} {dataStreamsCount, plural, one {個のデータストリーム} other {個のデータストリーム}}が復元されます。{deselectAllLink}", + "xpack.snapshotRestore.restoreForm.stepLogistics.selectDataStreamsAndIndicesLabel": "データストリームとインデックスを選択", "xpack.snapshotRestore.restoreForm.stepLogisticsTitle": "詳細を復元", "xpack.snapshotRestore.restoreForm.stepReview.jsonTab.jsonAriaLabel": "実行する設定を復元", "xpack.snapshotRestore.restoreForm.stepReview.jsonTabTitle": "JSON", + "xpack.snapshotRestore.restoreForm.stepReview.summaryTab.dataStreamsAndIndicesLabel": "データストリームとインデックス", "xpack.snapshotRestore.restoreForm.stepReview.summaryTab.editStepTooltip": "編集", "xpack.snapshotRestore.restoreForm.stepReview.summaryTab.ignoreIndexSettingsLabel": "リセット", "xpack.snapshotRestore.restoreForm.stepReview.summaryTab.includeGlobalStateFalseValue": "いいえ", @@ -15180,6 +17873,8 @@ "xpack.snapshotRestore.restoreForm.stepReview.summaryTab.sectionSettingsTitle": "インデックス設定", "xpack.snapshotRestore.restoreForm.stepReview.summaryTabTitle": "まとめ", "xpack.snapshotRestore.restoreForm.stepReviewTitle": "復元詳細を確認", + "xpack.snapshotRestore.restoreForm.stepSettings.dataStreamsCallout.description": "これらの設定はデータストリームのバッキングインデックスにも適用されます。", + "xpack.snapshotRestore.restoreForm.stepSettings.dataStreamsCallout.title": "バッキングインデックス", "xpack.snapshotRestore.restoreForm.stepSettings.docsButtonLabel": "インデックス設定ドキュメント", "xpack.snapshotRestore.restoreForm.stepSettings.ignoreIndexSettingsDescription": "復元中に、選択した設定を既定値にリセットします。{docLink}", "xpack.snapshotRestore.restoreForm.stepSettings.ignoreIndexSettingsLabel": "インデックス設定のリセット", @@ -15242,7 +17937,7 @@ "xpack.snapshotRestore.restoreValidation.indexSettingsNotModifiableError": "修正できません:{settings}", "xpack.snapshotRestore.restoreValidation.indexSettingsNotRemovableError": "リセットできません:{settings}", "xpack.snapshotRestore.restoreValidation.indexSettingsRequiredError": "設定が最低1つ必要です", - "xpack.snapshotRestore.restoreValidation.indicesRequiredError": "インデックスを最低1つ選択する必要があります。", + "xpack.snapshotRestore.restoreValidation.indicesRequiredError": "1つ以上のデータストリームまたはインデックスを選択する必要があります。", "xpack.snapshotRestore.restoreValidation.renamePatternRequiredError": "取り込みパターンが必要です。", "xpack.snapshotRestore.restoreValidation.renameReplacementRequiredError": "置換パターンが必要です。", "xpack.snapshotRestore.snapshotDetails.closeButtonLabel": "閉じる", @@ -15253,6 +17948,7 @@ "xpack.snapshotRestore.snapshotDetails.errorSnapshotNotFound": "スナップショット「{snapshotId}」がレポジトリ「{repositoryName}」に存在しないか、レポジトリが存在しません。", "xpack.snapshotRestore.snapshotDetails.failureShardTitle": "ャード {shardId}", "xpack.snapshotRestore.snapshotDetails.failuresTabTitle": "失敗したインデックス ({failuresCount})", + "xpack.snapshotRestore.snapshotDetails.itemDataStreamsLabel": "データストリーム ({dataStreamsCount})", "xpack.snapshotRestore.snapshotDetails.itemDurationLabel": "期間", "xpack.snapshotRestore.snapshotDetails.itemDurationValueLabel": "{seconds} {seconds, plural, one {秒} other {秒}}", "xpack.snapshotRestore.snapshotDetails.itemEndTimeLabel": "終了時刻", @@ -15460,10 +18156,19 @@ "xpack.spaces.spaceSelector.noSpacesMatchSearchCriteriaDescription": "検索条件に一致するスペースがありません", "xpack.spaces.spaceSelector.selectSpacesTitle": "スペースの選択", "xpack.spaces.spacesTitle": "スペース", + "xpack.transform.actionDeleteTransform.bulkDeleteDestinationIndexTitle": "ディスティネーションインデックスの削除", + "xpack.transform.actionDeleteTransform.bulkDeleteDestIndexPatternTitle": "ディスティネーションインデックスパターンの削除", + "xpack.transform.actionDeleteTransform.deleteDestinationIndexTitle": "ディスティネーションインデックス{destinationIndex}の削除", + "xpack.transform.actionDeleteTransform.deleteDestIndexPatternTitle": "インデックスパターン{destinationIndex}の削除", "xpack.transform.agg.popoverForm.aggLabel": "集約", "xpack.transform.agg.popoverForm.aggNameAlreadyUsedError": "別の集約で既に同じ名前が使用されています。", "xpack.transform.agg.popoverForm.aggNameInvalidCharError": "無効な名前です。「[」、「]」「>」は使用できず、名前の始めと終わりにはスペースを使用できません。", "xpack.transform.agg.popoverForm.fieldLabel": "フィールド", + "xpack.transform.agg.popoverForm.filerAgg.range.greaterThanLabel": "より大きい", + "xpack.transform.agg.popoverForm.filerAgg.range.lessThanLabel": "より小さい", + "xpack.transform.agg.popoverForm.filerAgg.term.errorFetchSuggestions": "候補を取得できません", + "xpack.transform.agg.popoverForm.filerAgg.term.valueLabel": "値", + "xpack.transform.agg.popoverForm.filerAggLabel": "フィルタークエリ", "xpack.transform.agg.popoverForm.nameLabel": "集約名", "xpack.transform.agg.popoverForm.percentsLabel": "パーセント", "xpack.transform.agg.popoverForm.submitButtonLabel": "適用", @@ -15484,6 +18189,11 @@ "xpack.transform.clone.errorPromptTitle": "変換構成の取得中にエラーが発生しました。", "xpack.transform.cloneTransform.breadcrumbTitle": "クローン変換", "xpack.transform.createTransform.breadcrumbTitle": "変換の作成", + "xpack.transform.deleteTransform.deleteAnalyticsWithIndexErrorMessage": "ディスティネーションインデックス{destinationIndex}の削除中にエラーが発生しました", + "xpack.transform.deleteTransform.deleteAnalyticsWithIndexPatternErrorMessage": "インデックスパターン{destinationIndex}の削除中にエラーが発生しました", + "xpack.transform.deleteTransform.deleteAnalyticsWithIndexPatternSuccessMessage": "インデックスパターン{destinationIndex}を削除する要求が確認されました。", + "xpack.transform.deleteTransform.deleteAnalyticsWithIndexSuccessMessage": "ディスティネーションインデックス{destinationIndex}を削除する要求が確認されました。", + "xpack.transform.deleteTransform.errorWithCheckingIfIndexPatternExistsNotificationErrorMessage": "インデックスパターン{indexPattern}が存在するかどうかを確認するときにエラーが発生しました。{error}", "xpack.transform.description": "説明", "xpack.transform.groupby.popoverForm.aggLabel": "集約", "xpack.transform.groupBy.popoverForm.aggNameAlreadyUsedError": "別のグループ分けの構成が既にこの名前を使用しています。", @@ -15550,6 +18260,7 @@ "xpack.transform.stepCreateForm.startTransformSuccessMessage": "変換 {transformId} の開始リクエストが受け付けられました。", "xpack.transform.stepCreateForm.transformListCardDescription": "データフレームジョブの管理ページに戻ります。", "xpack.transform.stepCreateForm.transformListCardTitle": "データフレームジョブ", + "xpack.transform.stepDefineForm.addSubAggregationPlaceholder": "下位集約を追加...", "xpack.transform.stepDefineForm.advancedEditorApplyButtonText": "変更を適用", "xpack.transform.stepDefineForm.advancedEditorAriaLabel": "高度なピボットエディター", "xpack.transform.stepDefineForm.advancedEditorHelpText": "詳細エディターでは、変換のピボット構成を編集できます。", @@ -15576,6 +18287,7 @@ "xpack.transform.stepDefineForm.indexPatternHelpText": "このインデックスパターンのオプションのクエリはサポートされていません。サポートされているインデックスフィールドの数は {maxIndexFields} で、このインデックスには {numIndexFields} 個のフィールドがあります。", "xpack.transform.stepDefineForm.indexPatternLabel": "インデックスパターン", "xpack.transform.stepDefineForm.invalidKuerySyntaxErrorMessageQueryBar": "無効なクエリ:{errorMessage}", + "xpack.transform.stepDefineForm.maxSubAggsLevelsLimitMessage": "フォームで追加できる下位集約の最大レベル数に達しました。別のレベルを追加する場合は、JSON構成を編集してください。", "xpack.transform.stepDefineForm.nestedAggListConflictErrorMessage": "「{aggListName}」とネスティングの矛盾があるため、構成「{aggName}」を追加できませんでした。", "xpack.transform.stepDefineForm.nestedConflictErrorMessage": "「{aggNameCheck}」とネスティングの矛盾があるため、構成「{aggName}」を追加できませんでした。", "xpack.transform.stepDefineForm.nestedGroupByListConflictErrorMessage": "「{groupByListName}」とネスティングの矛盾があるため、構成「{aggName}」を追加できませんでした。", @@ -15603,7 +18315,11 @@ "xpack.transform.stepDetailsForm.errorGettingIndexNames": "既存のインデックス名の取得中にエラーが発生しました:", "xpack.transform.stepDetailsForm.errorGettingIndexPatternTitles": "既存のインデックスパターンのタイトルの取得中にエラーが発生しました:", "xpack.transform.stepDetailsForm.errorGettingTransformList": "既存の変換 ID の取得中にエラーが発生しました:", + "xpack.transform.stepDetailsForm.errorGettingTransformPreview": "変換プレビューの取得中にエラーが発生しました。", + "xpack.transform.stepDetailsForm.indexPatternTimeFilterHelpText": "時間フィルターはこのフィールドを使って時間でフィールドを絞ります。時間フィールドを使わないこともできますが、その場合データを時間範囲で絞ることができません。", + "xpack.transform.stepDetailsForm.indexPatternTimeFilterLabel": "時間フィルターのフィールド名", "xpack.transform.stepDetailsForm.indexPatternTitleError": "このタイトルのインデックスパターンが既に存在します。", + "xpack.transform.stepDetailsForm.noTimeFieldOptionLabel": "時間フィルターを使用しない", "xpack.transform.stepDetailsForm.transformDescriptionInputAriaLabel": "オプションの変換の説明を選択してください。", "xpack.transform.stepDetailsForm.transformDescriptionLabel": "変換の説明", "xpack.transform.stepDetailsForm.transformDescriptionPlaceholderText": "説明(オプション)", @@ -15614,6 +18330,7 @@ "xpack.transform.stepDetailsSummary.continuousModeDateFieldLabel": "連続モード日付フィールド", "xpack.transform.stepDetailsSummary.createIndexPatternMessage": "このジョブの Kibana インデックスパターンが作成されます。", "xpack.transform.stepDetailsSummary.destinationIndexLabel": "デスティネーションインデックス", + "xpack.transform.stepDetailsSummary.indexPatternTimeFilterLabel": "時間フィルター", "xpack.transform.stepDetailsSummary.transformDescriptionLabel": "変換の説明", "xpack.transform.stepDetailsSummary.transformIdLabel": "ジョブ ID", "xpack.transform.tableActionLabel": "アクション", @@ -15621,8 +18338,12 @@ "xpack.transform.toastText.modalTitle": "詳細を入力", "xpack.transform.toastText.openModalButtonText": "詳細を表示", "xpack.transform.transformForm.sizeNotationPlaceholder": "例: {example1}、{example2}、{example3}、{example4}", - "xpack.transform.transformList.bulkDeleteModalBody": "{count, plural, one {この} other {これらの}} {count} 件の{count, plural, one {変換} other {変換}}を削除してよろしいですか?変換の送信先インデックスとオプションの Kibana インデックスパターンは削除されません。", + "xpack.transform.transformList.bulkDeleteDestIndexPatternSuccessMessage": "{count}個のディスティネーションインデックス{count, plural, one {パターン} other {パターン}}を正常に削除しました。", + "xpack.transform.transformList.bulkDeleteDestIndexSuccessMessage": "{count}個のディスティネーション{count, plural, one {インデックス} other {インデックス}}を正常に削除しました。", + "xpack.transform.transformList.bulkDeleteModalBody": "{count, plural, one {この} other {これらの}} {count} {count, plural, one {変換} other {変換}}を削除しますか?", "xpack.transform.transformList.bulkDeleteModalTitle": "{count} 件の{count, plural, one {変換} other {変換}}を削除", + "xpack.transform.transformList.bulkDeleteTransformSuccessMessage": "{count} {count, plural, one {個の変換} other {個の変換}}を正常に削除しました。", + "xpack.transform.transformList.bulkForceDeleteModalBody": "{count, plural, one {この} other {これらの}} {count} {count, plural, one {変換} other {変換}}を強制的に削除しますか?{count, plural, one {} other {}}現在の状態に関係なく、{count, plural, one {個の変換} other {個の変換}}は削除されます。", "xpack.transform.transformList.bulkStartModalTitle": "{count} 件の{count, plural, one {変換} other {変換}}を開始", "xpack.transform.transformList.cloneActionName": "クローンを作成", "xpack.transform.transformList.completeBatchTransformBulkActionToolTip": "1 つまたは複数の変換が完了済みの一斉変換で、再度開始できません。", @@ -15631,7 +18352,7 @@ "xpack.transform.transformList.deleteActionDisabledToolTipContent": "削除するにはデータフレームジョブを停止してください。", "xpack.transform.transformList.deleteActionName": "削除", "xpack.transform.transformList.deleteBulkActionDisabledToolTipContent": "削除するには、選択された変換のうちの 1 つまたは複数を停止する必要があります。", - "xpack.transform.transformList.deleteModalBody": "この変換を削除してよろしいですか?変換の送信先インデックスとオプションの Kibana インデックスパターンは削除されません。", + "xpack.transform.transformList.deleteModalBody": "この変換を削除してよろしいですか?", "xpack.transform.transformList.deleteModalCancelButton": "キャンセル", "xpack.transform.transformList.deleteModalDeleteButton": "削除", "xpack.transform.transformList.deleteModalTitle": "{transformId} 削除", @@ -15654,6 +18375,8 @@ "xpack.transform.transformList.editFlyoutUpdateButtonText": "更新", "xpack.transform.transformList.editTransformGenericErrorMessage": "変換を削除するためのAPIエンドポイントの呼び出し中にエラーが発生しました。", "xpack.transform.transformList.editTransformSuccessMessage": "変換{transformId}が更新されました。", + "xpack.transform.transformList.errorWithCheckingIfUserCanDeleteIndexNotificationErrorMessage": "ユーザーがディスティネーションインデックスを削除できるかどうかを確認するときにエラーが発生しました。", + "xpack.transform.transformList.forceDeleteModalBody": "この変換を強制的に削除しますか?現在の状態に関係なく、変換が削除されます。", "xpack.transform.transformList.refreshButtonLabel": "更新", "xpack.transform.transformList.rowCollapse": "{transformId} の詳細を非表示", "xpack.transform.transformList.rowExpand": "{transformId} の詳細を表示", @@ -15677,8 +18400,10 @@ "xpack.transform.transformList.transformDetails.messagesPane.messageLabel": "メッセージ", "xpack.transform.transformList.transformDetails.messagesPane.nodeLabel": "ノード", "xpack.transform.transformList.transformDetails.messagesPane.timeLabel": "時間", + "xpack.transform.transformList.transformDetails.tabs.transformDetailsLabel": "詳細", "xpack.transform.transformList.transformDetails.tabs.transformMessagesLabel": "メッセージ", "xpack.transform.transformList.transformDetails.tabs.transformPreviewLabel": "プレビュー", + "xpack.transform.transformList.transformDetails.tabs.transformStatsLabel": "統計", "xpack.transform.transformList.transformDocsLinkText": "変換ドキュメント", "xpack.transform.transformList.transformTitle": "データフレームジョブ", "xpack.transform.transformsDescription": "変換を使用して、集約されたインデックスまたはエンティティ中心のインデックスに、既存のElasticsearchインデックスをインデックスします。", @@ -15722,7 +18447,18 @@ "xpack.triggersActionsUI.common.expressionItems.threshold.popoverTitle": "タイミング", "xpack.triggersActionsUI.components.addMessageVariables.addVariablePopoverButton": "変数を追加", "xpack.triggersActionsUI.components.addMessageVariables.addVariableTitle": "アラート変数を追加", + "xpack.triggersActionsUI.components.builtinActionTypes.addNewConnector": "新しいコネクターを追加", + "xpack.triggersActionsUI.components.builtinActionTypes.cancelButton": "キャンセル", + "xpack.triggersActionsUI.components.builtinActionTypes.caseClosureOptionsClosedIncident": "新しいインシデントが外部システムで閉じたときにセキュリティケースを自動的に閉じる", + "xpack.triggersActionsUI.components.builtinActionTypes.caseClosureOptionsDesc": "セキュリティケースの終了のしかたを定義します。自動ケース終了のためには、外部のインシデント管理システムへの接続を確立する必要がいります。", + "xpack.triggersActionsUI.components.builtinActionTypes.caseClosureOptionsLabel": "ケース終了オプション", + "xpack.triggersActionsUI.components.builtinActionTypes.caseClosureOptionsManual": "セキュリティケースを手動で閉じる", + "xpack.triggersActionsUI.components.builtinActionTypes.caseClosureOptionsNewIncident": "新しいインシデントを外部システムにプッシュするときにセキュリティケースを自動的に閉じる", + "xpack.triggersActionsUI.components.builtinActionTypes.caseClosureOptionsTitle": "ケースのクローズ", + "xpack.triggersActionsUI.components.builtinActionTypes.common.requiredDescriptionTextField": "説明が必要です。", + "xpack.triggersActionsUI.components.builtinActionTypes.common.requiredTitleTextField": "タイトルが必要です。", "xpack.triggersActionsUI.components.builtinActionTypes.emailAction.actionTypeTitle": "メールに送信", + "xpack.triggersActionsUI.components.builtinActionTypes.emailAction.configureAccountsHelpLabel": "電子メールアカウントを構成しています。", "xpack.triggersActionsUI.components.builtinActionTypes.emailAction.selectMessageText": "サーバーからメールを送信します。", "xpack.triggersActionsUI.components.builtinActionTypes.error.formatFromText": "送信元は有効なメールアドレスではありません。", "xpack.triggersActionsUI.components.builtinActionTypes.error.requiredEntryText": "To、Cc、または Bcc のエントリーがありません。 1 つ以上のエントリーが必要です。", @@ -15736,8 +18472,20 @@ "xpack.triggersActionsUI.components.builtinActionTypes.error.requiredSubjectText": "件名が必要です。", "xpack.triggersActionsUI.components.builtinActionTypes.error.requiredUserText": "パスワードの使用時にはユーザー名が必要です。", "xpack.triggersActionsUI.components.builtinActionTypes.error.requiredWebhookBodyText": "本文が必要です。", + "xpack.triggersActionsUI.components.builtinActionTypes.fieldMappingDesc": "データをサードパーティにプッシュするときにセキュリティケースフィールドをマップします。フィールドマッピングのためには、外部のインシデント管理システムへの接続を確立する必要があります。", + "xpack.triggersActionsUI.components.builtinActionTypes.fieldMappingEditAppend": "末尾に追加", + "xpack.triggersActionsUI.components.builtinActionTypes.fieldMappingEditNothing": "何もしない", + "xpack.triggersActionsUI.components.builtinActionTypes.fieldMappingEditOverwrite": "上書き", + "xpack.triggersActionsUI.components.builtinActionTypes.fieldMappingFirstCol": "セキュリティケースフィールド", + "xpack.triggersActionsUI.components.builtinActionTypes.fieldMappingSecondCol": "外部インシデントフィールド", + "xpack.triggersActionsUI.components.builtinActionTypes.fieldMappingThirdCol": "編集時と更新時", + "xpack.triggersActionsUI.components.builtinActionTypes.fieldMappingTitle": "フィールドマッピング", + "xpack.triggersActionsUI.components.builtinActionTypes.incidentManagementSystemDesc": "オプションとして、セキュリティケースを選択した外部のインシデント管理システムに接続できます。そうすると、選択したサードパーティシステム内でケースデータをインシデントとしてプッシュできます。", + "xpack.triggersActionsUI.components.builtinActionTypes.incidentManagementSystemLabel": "インシデント管理システム", + "xpack.triggersActionsUI.components.builtinActionTypes.incidentManagementSystemTitle": "外部のインシデント管理システムに接続", "xpack.triggersActionsUI.components.builtinActionTypes.indexAction.actionTypeTitle": "データをインデックスする", "xpack.triggersActionsUI.components.builtinActionTypes.indexAction.chooseLabel": "選択...", + "xpack.triggersActionsUI.components.builtinActionTypes.indexAction.configureIndexHelpLabel": "インデックスコネクターを構成しています。", "xpack.triggersActionsUI.components.builtinActionTypes.indexAction.connectorSectionTitle": "インデックスを書き出す", "xpack.triggersActionsUI.components.builtinActionTypes.indexAction.definedateFieldTooltip": "インデックスされるときに自動的に各ドキュメントに時刻フィールドを追加します。", "xpack.triggersActionsUI.components.builtinActionTypes.indexAction.defineTimeFieldLabel": "各ドキュメントの時刻フィールドを定義", @@ -15745,12 +18493,15 @@ "xpack.triggersActionsUI.components.builtinActionTypes.indexAction.error.requiredIndexText": "インデックスが必要です。", "xpack.triggersActionsUI.components.builtinActionTypes.indexAction.executionTimeFieldLabel": "時間フィールド", "xpack.triggersActionsUI.components.builtinActionTypes.indexAction.howToBroadenSearchQueryDescription": "* で検索クエリの範囲を広げます。", + "xpack.triggersActionsUI.components.builtinActionTypes.indexAction.indexDocumentHelpLabel": "インデックスドキュメントの例。", "xpack.triggersActionsUI.components.builtinActionTypes.indexAction.indicesAndIndexPatternsLabel": "インデックスパターンに基づく", "xpack.triggersActionsUI.components.builtinActionTypes.indexAction.indicesToQueryLabel": "インデックス", "xpack.triggersActionsUI.components.builtinActionTypes.indexAction.jsonDocAriaLabel": "コードエディター", "xpack.triggersActionsUI.components.builtinActionTypes.indexAction.refreshLabel": "更新インデックス", "xpack.triggersActionsUI.components.builtinActionTypes.indexAction.refreshTooltip": "影響を受けるシャードを更新し、この処理を検索できるようにします。", "xpack.triggersActionsUI.components.builtinActionTypes.indexAction.selectMessageText": "データを Elasticsearch にインデックスしてください。", + "xpack.triggersActionsUI.components.builtinActionTypes.mappingFieldNotMapped": "マップされません", + "xpack.triggersActionsUI.components.builtinActionTypes.noConnector": "コネクターを選択していません", "xpack.triggersActionsUI.components.builtinActionTypes.pagerDutyAction.actionTypeTitle": "PagerDuty に送信", "xpack.triggersActionsUI.components.builtinActionTypes.pagerDutyAction.apiUrlTextFieldLabel": "API URL(任意)", "xpack.triggersActionsUI.components.builtinActionTypes.pagerDutyAction.classFieldLabel": "クラス (任意)", @@ -15779,18 +18530,48 @@ "xpack.triggersActionsUI.components.builtinActionTypes.serverLogAction.logLevelFieldLabel": "レベル", "xpack.triggersActionsUI.components.builtinActionTypes.serverLogAction.logMessageFieldLabel": "メッセージ", "xpack.triggersActionsUI.components.builtinActionTypes.serverLogAction.selectMessageText": "Kibana ログにメッセージを追加します。", + "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.actionTypeTitle": "ServiceNow", + "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.apiTokenTextFieldLabel": "APIトークン", + "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.apiUrlTextFieldLabel": "URL", + "xpack.triggersActionsUI.components.builtinActionTypes.serviceNow.commentsTextAreaFieldLabel": "追加のコメント(任意)", + "xpack.triggersActionsUI.components.builtinActionTypes.serviceNow.descriptionTextAreaFieldLabel": "説明(オプション)", + "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.emailTextFieldLabel": "メール", + "xpack.triggersActionsUI.components.builtinActionTypes.serviceNow.impactSelectFieldLabel": "インパクト", + "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.invalidApiUrlTextField": "URLが無効です", + "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.mappingFieldComments": "コメント", + "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.mappingFieldDescription": "説明", + "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.mappingFieldShortDescription": "短い説明", + "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.passwordTextFieldLabel": "パスワード", + "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.requiredApiTokenTextField": "APIトークンが必要です。", + "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.requiredApiUrlTextField": "URL が必要です。", + "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.requiredEmailTextField": "電子メールが必要です。", + "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.requiredPasswordTextField": "パスワードが必要です。", + "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.requiredUsernameTextField": "ユーザー名が必要です。", + "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.selectMessageText": "ServiceNowでデータを更新するか、または新しいインシデントにプッシュします。", + "xpack.triggersActionsUI.components.builtinActionTypes.serviceNow.severitySelectFieldLabel": "深刻度", + "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.severitySelectHighOptionLabel": "高", + "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.severitySelectLawOptionLabel": "低", + "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.severitySelectMediumOptionLabel": "中", + "xpack.triggersActionsUI.components.builtinActionTypes.serviceNow.titleFieldLabel": "短い説明", + "xpack.triggersActionsUI.components.builtinActionTypes.serviceNow.urgencySelectFieldLabel": "緊急", + "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.usernameTextFieldLabel": "ユーザー名", "xpack.triggersActionsUI.components.builtinActionTypes.slackAction.actionTypeTitle": "Slack に送信", "xpack.triggersActionsUI.components.builtinActionTypes.slackAction.error.requiredWebhookUrlText": "Web フック URL が必要です。", "xpack.triggersActionsUI.components.builtinActionTypes.slackAction.messageTextAreaFieldLabel": "メッセージ", "xpack.triggersActionsUI.components.builtinActionTypes.slackAction.selectMessageText": "Slack チャネルにメッセージを送信します。", "xpack.triggersActionsUI.components.builtinActionTypes.slackAction.webhookUrlHelpLabel": "Slack Web フック URL を作成", "xpack.triggersActionsUI.components.builtinActionTypes.slackAction.webhookUrlTextFieldLabel": "Web フック URL", + "xpack.triggersActionsUI.components.builtinActionTypes.updateConnector": "コネクターを更新", + "xpack.triggersActionsUI.components.builtinActionTypes.updateSelectedConnector": "{ connectorName }を更新", + "xpack.triggersActionsUI.components.builtinActionTypes.warningMessage": "選択したコネクターが削除されました。別のコネクターを選択するか、新しいコネクターを作成してください。", + "xpack.triggersActionsUI.components.builtinActionTypes.warningTitle": "警告", "xpack.triggersActionsUI.components.builtinActionTypes.webhookAction.actionTypeTitle": "Web フックデータ", "xpack.triggersActionsUI.components.builtinActionTypes.webhookAction.addHeader": "ヘッダーを追加", "xpack.triggersActionsUI.components.builtinActionTypes.webhookAction.addHeaderButton": "追加", "xpack.triggersActionsUI.components.builtinActionTypes.webhookAction.bodyCodeEditorAriaLabel": "コードエディター", "xpack.triggersActionsUI.components.builtinActionTypes.webhookAction.bodyFieldLabel": "本文", "xpack.triggersActionsUI.components.builtinActionTypes.webhookAction.deleteHeaderButton": "削除", + "xpack.triggersActionsUI.components.builtinActionTypes.webhookAction.error.invalidUrlTextField": "URLが無効です。", "xpack.triggersActionsUI.components.builtinActionTypes.webhookAction.error.requiredUrlText": "URL が必要です。", "xpack.triggersActionsUI.components.builtinActionTypes.webhookAction.httpHeadersTitle": "使用中のヘッダー", "xpack.triggersActionsUI.components.builtinActionTypes.webhookAction.keyTextFieldLabel": "キー", @@ -16023,8 +18804,47 @@ "xpack.triggersActionsUI.timeUnits.secondLabel": "{timeValue, plural, one {秒} other {秒}}", "xpack.triggersActionsUI.typeRegistry.get.missingActionTypeErrorMessage": "オブジェクトタイプ「{id}」は登録されていません。", "xpack.triggersActionsUI.typeRegistry.register.duplicateObjectTypeErrorMessage": "オブジェクトタイプ「{id}」は既に登録されています。", + "xpack.uiActionsEnhanced.components.actionWizard.changeButton": "変更", + "xpack.uiActionsEnhanced.components.actionWizard.insufficientLicenseLevelTooltip": "不十分なライセンスレベル", "xpack.uiActionsEnhanced.components.DiscoverDrilldownConfig.chooseIndexPattern": "対象インデックスパターンを選択", + "xpack.uiActionsEnhanced.customizePanelTimeRange.modal.addToPanelButtonTitle": "パネルに追加", + "xpack.uiActionsEnhanced.customizePanelTimeRange.modal.cancelButtonTitle": "キャンセル", + "xpack.uiActionsEnhanced.customizePanelTimeRange.modal.optionsMenuForm.panelTitleFormRowLabel": "時間範囲", + "xpack.uiActionsEnhanced.customizePanelTimeRange.modal.removeButtonTitle": "削除", + "xpack.uiActionsEnhanced.customizePanelTimeRange.modal.updatePanelTimeRangeButtonTitle": "更新", + "xpack.uiActionsEnhanced.customizeTimeRange.modal.headerTitle": "パネルの時間範囲のカスタマイズ", + "xpack.uiActionsEnhanced.customizeTimeRangeMenuItem.displayName": "時間範囲のカスタマイズ", "xpack.uiActionsEnhanced.drilldown.goToDiscover": "Discoverに移動(例)", + "xpack.uiActionsEnhanced.drilldowns.components.DrilldownHelloBar.helpText": "ドリルダウンにより、パネルと連携する新しい動作を定義できます。複数のアクションを追加し、デフォルトフィルターを無効化できます。", + "xpack.uiActionsEnhanced.drilldowns.components.DrilldownHelloBar.hideHelpButtonLabel": "非表示", + "xpack.uiActionsEnhanced.drilldowns.components.DrilldownHelloBar.viewDocsLinkLabel": "ドキュメントを表示", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.createDrilldownButtonLabel": "ドリルダウンを作成", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.createDrilldownTitle": "ドリルダウンを作成", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.deleteDrilldownButtonLabel": "ドリルダウンを削除", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.editDrilldownButtonLabel": "保存", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.editDrilldownTitle": "ドリルダウンを編集", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.insufficientLicenseLevelError": "不十分なライセンスレベル", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.invalidDrilldownType": "ドリルダウンタイプ{type}が存在しません", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.toast.drilldownCreatedText": "テストする前にダッシュボードを保存してください。", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.toast.drilldownCreatedTitle": "ドリルダウン「{drilldownName}」が作成されました", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.toast.drilldownDeletedText": "テストする前にダッシュボードを保存してください。", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.toast.drilldownDeletedTitle": "ドリルダウンが削除されました", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.toast.drilldownEditedText": "テストする前にダッシュボードを保存してください。", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.toast.drilldownEditedTitle": "ドリルダウン「{drilldownName}」が更新されました", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.toast.drilldownsCRUDErrorTitle": "ドリルダウンの保存エラー", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.toast.drilldownsDeletedText": "テストする前にダッシュボードを保存してください。", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.toast.drilldownsDeletedTitle": "{n}個のドリルダウンが削除されました", + "xpack.uiActionsEnhanced.drilldowns.components.FlyoutFrame.BackButtonLabel": "戻る", + "xpack.uiActionsEnhanced.drilldowns.components.FlyoutFrame.CloseButtonLabel": "閉じる", + "xpack.uiActionsEnhanced.drilldowns.components.FlyoutListManageDrilldowns.manageDrilldownsTitle": "ドリルダウンを管理", + "xpack.uiActionsEnhanced.drilldowns.components.FormCreateDrilldown.drilldownAction": "アクション", + "xpack.uiActionsEnhanced.drilldowns.components.FormCreateDrilldown.nameOfDrilldown": "名前", + "xpack.uiActionsEnhanced.drilldowns.components.FormCreateDrilldown.untitledDrilldown": "無題のドリルダウン", + "xpack.uiActionsEnhanced.drilldowns.components.FormDrilldownWizard.getMoreActionsLinkLabel": "さらにアクションを表示", + "xpack.uiActionsEnhanced.drilldowns.components.ListManageDrilldowns.createDrilldownButtonLabel": "新規作成...", + "xpack.uiActionsEnhanced.drilldowns.components.ListManageDrilldowns.deleteDrilldownsButtonLabel": "削除({count})", + "xpack.uiActionsEnhanced.drilldowns.components.ListManageDrilldowns.editDrilldownButtonLabel": "編集", + "xpack.uiActionsEnhanced.drilldowns.components.ListManageDrilldowns.selectThisDrilldownCheckboxLabel": "このドリルダウンを選択", "xpack.upgradeAssistant.appTitle": "{version} アップグレードアシスタント", "xpack.upgradeAssistant.checkupTab.backUpCallout.calloutBody.calloutDetail": "{snapshotRestoreDocsButton} でデータをバックアップします。", "xpack.upgradeAssistant.checkupTab.backUpCallout.calloutBody.snapshotRestoreDocsButtonLabel": "API のスナップショットと復元", @@ -16146,6 +18966,27 @@ "xpack.upgradeAssistant.tabs.upgradingInterstitial.upgradeCompleteTitle": "クラスターがアップグレードされました", "xpack.upgradeAssistant.tabs.upgradingInterstitial.upgradingDescription": "1 つまたは複数の Elasticsearch ノードに、 Kibana よりも新しいバージョンの Elasticsearch があります。すべてのノードがアップグレードされた後で Kibana をアップグレードしてください。", "xpack.upgradeAssistant.tabs.upgradingInterstitial.upgradingTitle": "クラスターをアップグレード中です", + "xpack.uptime.addDataButtonLabel": "データの追加", + "xpack.uptime.alerts.anomaly.criteriaExpression.ariaLabel": "選択したモニターの条件を表示する式。", + "xpack.uptime.alerts.anomaly.criteriaExpression.description": "監視するとき", + "xpack.uptime.alerts.anomaly.scoreExpression.ariaLabel": "異常アラートしきい値の条件を表示する式。", + "xpack.uptime.alerts.anomaly.scoreExpression.description": "異常と重要度があります", + "xpack.uptime.alerts.availability.emptyMessage": "可用性しきい値({threshold} %)未満のモニターはありません", + "xpack.uptime.alerts.availability.monitorSummary": "{nameOrId}({url}): {availabilityRatio}%", + "xpack.uptime.alerts.availability.multiItemTitle": "可用性しきい値({threshold} %)未満の上位{monitorCount}個のモニター:\n", + "xpack.uptime.alerts.availability.singleItemTitle": "可用性しきい値({threshold} %)未満のモニター:\n", + "xpack.uptime.alerts.durationAnomaly": "アップタイム期間異常", + "xpack.uptime.alerts.durationAnomaly.actionVariables.state.anomalyStartTimestamp": "異常の開始のISO8601タイムスタンプ", + "xpack.uptime.alerts.durationAnomaly.actionVariables.state.expectedResponseTime": "想定応答時間", + "xpack.uptime.alerts.durationAnomaly.actionVariables.state.monitor": "名前、IDS、優先名の人間にとってわかりやすい表示(My Monitorなど)", + "xpack.uptime.alerts.durationAnomaly.actionVariables.state.monitorId": "モニターのID。", + "xpack.uptime.alerts.durationAnomaly.actionVariables.state.monitorUrl": "モニターのURL。", + "xpack.uptime.alerts.durationAnomaly.actionVariables.state.observerLocation": "Heartbeatチェックが実行されるオブサーバーの位置情報。", + "xpack.uptime.alerts.durationAnomaly.actionVariables.state.severity": "異常の重要度。", + "xpack.uptime.alerts.durationAnomaly.actionVariables.state.severityScore": "異常重要度スコア。", + "xpack.uptime.alerts.durationAnomaly.actionVariables.state.slowestAnomalyResponse": "単位(ミリ秒、秒)が関連付けられた異常バケット中の最も遅い応答時間。", + "xpack.uptime.alerts.durationAnomaly.clientName": "アップタイム期間異常", + "xpack.uptime.alerts.durationAnomaly.defaultActionMessage": "{anomalyStartTimestamp}に、{monitor}、url {monitorUrl}で異常({severity}レベル)応答時間が検出されました。異常重要度スコアは{severityScore}です。\n位置情報{observerLocation}から高い応答時間{slowestAnomalyResponse}が検出されました。想定された応答時間は{expectedResponseTime}です。", "xpack.uptime.alerts.message.emptyTitle": "停止状況監視 ID を受信していません。", "xpack.uptime.alerts.message.fullListOverflow": "... とその他 {overflowCount} {pluralizedMonitor}", "xpack.uptime.alerts.message.multipleTitle": "停止状況監視: ", @@ -16166,7 +19007,18 @@ "xpack.uptime.alerts.monitorStatus.addFilter.port": "ポート", "xpack.uptime.alerts.monitorStatus.addFilter.tag": "タグ", "xpack.uptime.alerts.monitorStatus.addFilter.type": "タイプ", + "xpack.uptime.alerts.monitorStatus.availability.isEnabledCheckbox.label": "可用性", + "xpack.uptime.alerts.monitorStatus.availability.threshold.ariaLabel": "このアラートの可用性しきい値を指定", + "xpack.uptime.alerts.monitorStatus.availability.threshold.description": "一致するモニターがアップしています", + "xpack.uptime.alerts.monitorStatus.availability.threshold.input.ariaLabel": "このアラートで確認する可用性しきい値を入力", + "xpack.uptime.alerts.monitorStatus.availability.threshold.value": "< チェックの{value}%", + "xpack.uptime.alerts.monitorStatus.availability.timerangeValueField.ariaLabel": "アラートの可用性チェックの時間単位の数を入力", + "xpack.uptime.alerts.monitorStatus.availability.timerangeValueField.expression": "最後内", + "xpack.uptime.alerts.monitorStatus.availability.timerangeValueField.popover.ariaLabel": "可用性追跡時間範囲を指定", + "xpack.uptime.alerts.monitorStatus.availability.unit.headline": "時間範囲単位を選択します", + "xpack.uptime.alerts.monitorStatus.availability.unit.selectable": "この選択を使用して、このアラートの可用性範囲単位を設定", "xpack.uptime.alerts.monitorStatus.clientName": "稼働状況の監視ステータス", + "xpack.uptime.alerts.monitorStatus.defaultActionMessage": "{contextMessage}\n前回トリガー日時:{lastTriggered}\n", "xpack.uptime.alerts.monitorStatus.filterBar.ariaLabel": "監視状態アラートのフィルター基準を許可するインプット", "xpack.uptime.alerts.monitorStatus.filters.anyLocation": "任意の場所", "xpack.uptime.alerts.monitorStatus.filters.anyPort": "任意のポート", @@ -16185,21 +19037,30 @@ "xpack.uptime.alerts.monitorStatus.numTimesExpression.ariaLabel": "ダウンカウントインプットのポップオーバーを開く", "xpack.uptime.alerts.monitorStatus.numTimesExpression.matchingMonitors.description": "一致するモニターがダウン >", "xpack.uptime.alerts.monitorStatus.numTimesField.ariaLabel": "アラートのトリガーに必要な停止回数を入力します", - "xpack.uptime.alerts.monitorStatus.oldAlertCallout.title": "古いアラートを編集しています。一部のフィールドは自動入力されない場合があります。", + "xpack.uptime.alerts.monitorStatus.oldAlertCallout.title": "古いアラートを編集している可能性があります。一部のフィールドは自動入力されない場合があります。", + "xpack.uptime.alerts.monitorStatus.statusEnabledCheck.label": "ステータス確認", "xpack.uptime.alerts.monitorStatus.timerangeOption.days": "日", "xpack.uptime.alerts.monitorStatus.timerangeOption.hours": "時間", "xpack.uptime.alerts.monitorStatus.timerangeOption.minutes": "分", + "xpack.uptime.alerts.monitorStatus.timerangeOption.months": "月", "xpack.uptime.alerts.monitorStatus.timerangeOption.seconds": "秒", + "xpack.uptime.alerts.monitorStatus.timerangeOption.weeks": "週", + "xpack.uptime.alerts.monitorStatus.timerangeOption.years": "年", "xpack.uptime.alerts.monitorStatus.timerangeSelectionHeader": "時間範囲単位を選択します", "xpack.uptime.alerts.monitorStatus.timerangeUnitExpression.ariaLabel": "時間範囲単位選択フィールドのポップオーバーを開く", "xpack.uptime.alerts.monitorStatus.timerangeUnitSelectable": "アラートで使用する時間範囲単位の選択可能フィールド", "xpack.uptime.alerts.monitorStatus.timerangeValueExpression.ariaLabel": "時間範囲値フィールドのポップオーバーを開く", "xpack.uptime.alerts.monitorStatus.timerangeValueField.ariaLabel": "アラートの範囲のための時間単位の数を入力してください", + "xpack.uptime.alerts.monitorStatus.timerangeValueField.expression": "within", + "xpack.uptime.alerts.monitorStatus.timerangeValueField.value": "最終{value}", "xpack.uptime.alerts.monitorStatus.title.label": "稼働状況の監視ステータス", "xpack.uptime.alerts.timerangeUnitSelectable.daysOption.ariaLabel": "「日」の時間範囲選択項目", "xpack.uptime.alerts.timerangeUnitSelectable.hoursOption.ariaLabel": "「時間」の時間範囲選択項目", "xpack.uptime.alerts.timerangeUnitSelectable.minutesOption.ariaLabel": "「分」の時間範囲選択項目", + "xpack.uptime.alerts.timerangeUnitSelectable.monthsOption.ariaLabel": "「月」の時間範囲選択項目", "xpack.uptime.alerts.timerangeUnitSelectable.secondsOption.ariaLabel": "「秒」の時間範囲選択項目", + "xpack.uptime.alerts.timerangeUnitSelectable.weeksOption.ariaLabel": "「週」の時間範囲選択項目", + "xpack.uptime.alerts.timerangeUnitSelectable.yearsOption.ariaLabel": "「年」の時間範囲選択項目", "xpack.uptime.alerts.tls": "アップタイムTLS", "xpack.uptime.alerts.tls.actionVariables.state.agingCommonNameAndDate": "検出された証明書の共通名と有効期限日時。", "xpack.uptime.alerts.tls.actionVariables.state.agingCount": "検出された古くなりすぎた証明書数。", @@ -16213,7 +19074,7 @@ "xpack.uptime.alerts.tls.criteriaExpression.ariaLabel": "このアラートで監視されるモニターの条件を示す式", "xpack.uptime.alerts.tls.criteriaExpression.description": "タイミング", "xpack.uptime.alerts.tls.criteriaExpression.value": "任意のモニター", - "xpack.uptime.alerts.tls.defaultActionMessage": "期限切れになるか古くなりすぎた{count} TLS個のTLS証明書証明書を検知しました。\n\n{expiringConditionalOpen}\n期限切れになる証明書数:{expiringCount}\n期限切れになる証明書:{expiringCommonNameAndDate}\n{expiringConditionalClose} \n\n{agingConditionalOpen}\n古い証明書数:{agingCount}\n古い証明書:{agingCommonNameAndDate}\n{agingConditionalClose}\n", + "xpack.uptime.alerts.tls.defaultActionMessage": "期限切れになるか古くなりすぎた{count} TLS個のTLS証明書証明書を検知しました。\n\n{expiringConditionalOpen}\n期限切れになる証明書数:{expiringCount}\n期限切れになる証明書:{expiringCommonNameAndDate}\n{expiringConditionalClose}\n\n{agingConditionalOpen}\n古い証明書数:{agingCount}\n古い証明書:{agingCommonNameAndDate}\n{agingConditionalClose}\n", "xpack.uptime.alerts.tls.expirationExpression.ariaLabel": "証明書有効期限のTLSアラートをトリガーするしきい値を示す式", "xpack.uptime.alerts.tls.expirationExpression.description": "証明書が", "xpack.uptime.alerts.tls.expirationExpression.value": "{value}日以内に期限切れになる", @@ -16226,6 +19087,7 @@ "xpack.uptime.alertsPopover.toggleButton.ariaLabel": "アラートコンテキストメニューを開く", "xpack.uptime.apmIntegrationAction.description": "このモニターの検索 APM", "xpack.uptime.apmIntegrationAction.text": "ドメインでAPMを確認", + "xpack.uptime.availabilityLabelText": "{value} %", "xpack.uptime.badge.readOnly.text": "読み込み専用", "xpack.uptime.badge.readOnly.tooltip": "を保存できませんでした", "xpack.uptime.breadcrumbs.overviewBreadcrumbText": "アップタイム", @@ -16234,6 +19096,7 @@ "xpack.uptime.certificates.returnToOverviewLinkLabel": "概要に戻る", "xpack.uptime.certificates.settingsLinkLabel": "設定", "xpack.uptime.certs.expired": "期限切れ", + "xpack.uptime.certs.expires": "有効期限", "xpack.uptime.certs.expireSoon": "まもなく期限切れ", "xpack.uptime.certs.list.ageCol": "年齢", "xpack.uptime.certs.list.commonName": "共通名", @@ -16247,9 +19110,15 @@ "xpack.uptime.certs.list.validUntil": "有効期限:", "xpack.uptime.certs.ok": "OK", "xpack.uptime.certs.searchCerts": "証明書を検索", + "xpack.uptime.certs.status.ok.label": " {okRelativeDate}", "xpack.uptime.charts.mlAnnotation.header": "スコア: {score}", "xpack.uptime.charts.mlAnnotation.severity": "深刻度: {severity}", "xpack.uptime.components.embeddables.embeddedMap.embeddablePanelTitle": "オブザーバー位置情報マップを監視", + "xpack.uptime.controls.selectSeverity.criticalLabel": "致命的", + "xpack.uptime.controls.selectSeverity.majorLabel": "メジャー", + "xpack.uptime.controls.selectSeverity.minorLabel": "マイナー", + "xpack.uptime.controls.selectSeverity.scoreDetailsDescription": "スコア {value} 以上", + "xpack.uptime.controls.selectSeverity.warningLabel": "警告", "xpack.uptime.durationChart.emptyPrompt.description": "このモニターは選択された時間範囲で一度も {emphasizedText} していません。", "xpack.uptime.durationChart.emptyPrompt.title": "利用可能な期間データがありません", "xpack.uptime.emptyState.configureHeartbeatIndexSettings": "Heartbeatを設定し、確認されたデータがElasticsearchに送信されている場合は、インデックスパターン設定を更新し、必ずHeartbeat構成と一致していることを確認します。", @@ -16280,12 +19149,15 @@ "xpack.uptime.locationMap.locations.missing.message1": "詳細については、ドキュメンテーションを参照してください。", "xpack.uptime.locationMap.locations.missing.title": "地理情報の欠測", "xpack.uptime.locationName.helpLinkAnnotation": "場所を追加", + "xpack.uptime.mapToolTip.AvailabilityStat.title": "{value} %", "xpack.uptime.ml.durationChart.exploreInMlApp": "ML アプリで探索", "xpack.uptime.ml.enableAnomalyDetectionPanel.anomalyDetectionTitle": "異常検知", "xpack.uptime.ml.enableAnomalyDetectionPanel.cancelLabel": "キャンセル", "xpack.uptime.ml.enableAnomalyDetectionPanel.createMLJobDescription": "ここでは稼働状況監視の応答時間について異常スコアを計算する機械学習ジョブを作成できます。\n 有効にすると、詳細ページの監視期間チャートに予想範囲が表示され、グラフに異常の注釈が付きます。\n 地理的な地域にわたって遅延が増える期間を特定することもできます。", "xpack.uptime.ml.enableAnomalyDetectionPanel.createNewJobButtonLabel": "新規ジョブを作成", + "xpack.uptime.ml.enableAnomalyDetectionPanel.disableAnomalyAlert": "異常アラートを無効にする", "xpack.uptime.ml.enableAnomalyDetectionPanel.disableAnomalyDetectionTitle": "異常検知を無効にする", + "xpack.uptime.ml.enableAnomalyDetectionPanel.enableAnomalyAlert": "異常アラートを有効にする", "xpack.uptime.ml.enableAnomalyDetectionPanel.enableAnomalyDetectionTitle": "異常検知を有効にする", "xpack.uptime.ml.enableAnomalyDetectionPanel.jobCreatedNotificationText": "これで応答時間グラフについての分析が実行されます。応答時間グラフに結果が追加されるまで、しばらく時間がかかる可能性があります。", "xpack.uptime.ml.enableAnomalyDetectionPanel.jobCreatedNotificationText.viewJobLinkText": "ジョブを表示", @@ -16305,6 +19177,7 @@ "xpack.uptime.monitorCharts.durationChart.leftAxis.title": "期間ms", "xpack.uptime.monitorCharts.monitorDuration.titleLabel": "監視期間", "xpack.uptime.monitorCharts.monitorDuration.titleLabelWithAnomaly": "監視期間 (異常: {noOfAnomalies})", + "xpack.uptime.monitorDetails.ml.confirmAlertDeleteMessage": "異常のアラートを削除しますか?", "xpack.uptime.monitorDetails.ml.confirmDeleteMessage": "このジョブを削除してよろしいですか?", "xpack.uptime.monitorDetails.ml.deleteJobWarning": "ジョブの削除に時間がかかる可能性があります。削除はバックグラウンドで実行され、データの表示がすぐに消えないことがあります。", "xpack.uptime.monitorDetails.ml.deleteMessage": "ジョブを削除中...", @@ -16362,8 +19235,16 @@ "xpack.uptime.monitorStatusBar.loadingMessage": "読み込み中…", "xpack.uptime.monitorStatusBar.locations.oneLocStatus": "{loc}場所での{status}", "xpack.uptime.monitorStatusBar.locations.upStatus": "{loc}場所での{status}", + "xpack.uptime.monitorStatusBar.monitor.availability": "全体的な可用性", + "xpack.uptime.monitorStatusBar.monitor.availabilityReport.availability": "可用性", + "xpack.uptime.monitorStatusBar.monitor.availabilityReport.lastCheck": "最終確認", + "xpack.uptime.monitorStatusBar.monitor.availabilityReport.location": "場所", + "xpack.uptime.monitorStatusBar.monitor.id": "監視ID", + "xpack.uptime.monitorStatusBar.monitor.monitoringFrom": "監視元", + "xpack.uptime.monitorStatusBar.monitor.monitoringFrom.listToMap": "マップビューに変更し、場所別に可用性を確認します。", + "xpack.uptime.monitorStatusBar.monitor.monitoringFrom.MapToList": "リストビューに変更し、場所別に可用性を確認します。", "xpack.uptime.monitorStatusBar.monitorUrlLinkAriaLabel": "監視 URL リンク", - "xpack.uptime.monitorStatusBar.sslCertificate.title": "証明書:", + "xpack.uptime.monitorStatusBar.sslCertificate.title": "TLS証明書", "xpack.uptime.monitorStatusBar.timestampFromNowTextAriaLabel": "最終確認からの経過時間", "xpack.uptime.navigateToAlertingButton.content": "アラートを管理", "xpack.uptime.navigateToAlertingUi": "Uptime を離れてアラート管理ページに移動します", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 7a311b7622865..f7dfac7e7b1bf 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -87,6 +87,7 @@ "advancedSettings.categoryNames.notificationsLabel": "通知", "advancedSettings.categoryNames.reportingLabel": "Reporting", "advancedSettings.categoryNames.searchLabel": "搜索", + "advancedSettings.categoryNames.securitySolutionLabel": "安全解决方案", "advancedSettings.categoryNames.timelionLabel": "Timelion", "advancedSettings.categoryNames.visualizationsLabel": "可视化", "advancedSettings.categorySearchLabel": "类别", @@ -236,6 +237,8 @@ "apmOss.tutorial.startServer.title": "启动 APM Server", "apmOss.tutorial.windowsServerInstructions.textPost": "注意:如果您的系统禁用了脚本执行,则需要为当前会话设置执行策略,以允许脚本运行。示例:{command}。", "apmOss.tutorial.windowsServerInstructions.textPre": "1.从[下载页面]({downloadPageLink})下载 APM Server Windows zip 文件。\n2.将 zip 文件的内容解压缩到 {zipFileExtractFolder}。\n3.将 {apmServerDirectory} 目录重命名为 `APM-Server`。\n4.以管理员身份打开 PowerShell 提示符(右键单击 PowerShell 图标,然后选择**以管理员身份运行**)。如果您正在运行 Windows XP,您可能需要下载并安装 PowerShell。\n5.从 PowerShell 提示符处,运行以下命令以将 APM Server 安装为 Windows 服务:", + "charts.advancedSettings.visualization.colorMappingText": "将值映射到可视化内的指定颜色", + "charts.advancedSettings.visualization.colorMappingTitle": "颜色映射", "charts.colormaps.bluesText": "蓝色", "charts.colormaps.greensText": "绿色", "charts.colormaps.greenToRedText": "绿到红", @@ -353,6 +356,7 @@ "console.welcomePage.supportedRequestFormatTitle": "Console 理解紧凑格式的请求,类似于 cURL:", "core.application.appNotFound.pageDescription": "在此 URL 未找到任何应用程序。尝试返回或从菜单中选择应用。", "core.application.appNotFound.title": "未找到应用程序", + "core.application.appRenderError.defaultTitle": "应用程序错误", "core.chrome.browserDeprecationLink": "我们网站上的支持矩阵", "core.chrome.browserDeprecationWarning": "本软件的未来版本将放弃对 Internet Explorer 的支持,请查看{link}。", "core.chrome.legacyBrowserWarning": "您的浏览器不满足 Kibana 的安全要求。", @@ -489,6 +493,16 @@ "core.ui.chrome.sideGlobalNav.viewRecentItemsFlyoutTitle": "最近项", "core.ui.chrome.sideGlobalNav.viewRecentItemsLabel": "最近查看", "core.ui.EmptyRecentlyViewed": "没有最近查看的项目", + "core.ui.enterpriseSearchNavList.label": "企业搜索", + "core.ui.errorUrlOverflow.bigUrlWarningNotificationMessage": "在{advancedSettingsLink}中启用“{storeInSessionStorageParam}”选项或简化屏幕视觉效果。", + "core.ui.errorUrlOverflow.bigUrlWarningNotificationMessage.advancedSettingsLinkText": "高级设置", + "core.ui.errorUrlOverflow.bigUrlWarningNotificationTitle": "URL 过长,Kibana 可能无法工作", + "core.ui.errorUrlOverflow.errorTitle": "此对象的 URL 过长,我们无法显示它", + "core.ui.errorUrlOverflow.optionsToFixError.doNotUseIEText": "升级到现代浏览器。我们了解的所有其他受支持浏览器都没有这个限制。", + "core.ui.errorUrlOverflow.optionsToFixError.enableOptionText": "在“{kibanaSettingsLink}”中启用“{storeInSessionStorageConfig}”选项。", + "core.ui.errorUrlOverflow.optionsToFixError.enableOptionText.advancedSettingsLinkText": "高级设置", + "core.ui.errorUrlOverflow.optionsToFixError.removeStuffFromDashboardText": "通过删除内容或筛选来简化正在编辑的对象。", + "core.ui.errorUrlOverflow.optionsToFixErrorDescription": "试用一下:", "core.ui.kibanaNavList.label": "Kibana", "core.ui.legacyBrowserMessage": "此 Elastic 安装启用了当前浏览器未满足的严格安全要求。", "core.ui.legacyBrowserTitle": "请升级您的浏览器", @@ -531,8 +545,14 @@ "dashboard.dashboardAppBreadcrumbsTitle": "仪表板", "dashboard.dashboardBreadcrumbsTitle": "仪表板", "dashboard.dashboardGrid.toast.unableToLoadDashboardDangerMessage": "无法加载仪表板。", + "dashboard.dashboardPageTitle": "仪表板", "dashboard.dashboardWasNotSavedDangerMessage": "仪表板“{dashTitle}”未保存。错误:{errorMessage}", "dashboard.dashboardWasSavedSuccessMessage": "仪表板“{dashTitle}”已保存", + "dashboard.embedUrlParamExtension.filterBar": "筛选栏", + "dashboard.embedUrlParamExtension.include": "包括", + "dashboard.embedUrlParamExtension.query": "查询", + "dashboard.embedUrlParamExtension.timeFilter": "时间筛选", + "dashboard.embedUrlParamExtension.topMenu": "顶部菜单", "dashboard.emptyDashboardAdditionalPrivilege": "您还需要其他权限,才能编辑此仪表板。", "dashboard.emptyDashboardTitle": "此仪表板是空的。", "dashboard.factory.displayName": "仪表板", @@ -600,6 +620,85 @@ "dashboard.topNave.viewConfigDescription": "取消编辑并切换到仅查看模式", "dashboard.urlWasRemovedInSixZeroWarningMessage": "6.0 中已移除 url“dashboard/create”。请更新您的书签。", "dashboard.visitVisualizeAppLinkText": "访问 Visualize 应用", + "data.advancedSettings.courier.batchSearchesText": "禁用时,仪表板面板将分别加载,用户离开时或更新查询时,\n 搜索请求将终止。如果启用,加载所有数据时,仪表板面板将一起加载,并且\n 搜索将不会终止。", + "data.advancedSettings.courier.batchSearchesTextDeprecation": "此设置已过时,将在 Kibana 8.0 中移除。", + "data.advancedSettings.courier.batchSearchesTitle": "批量并发搜索", + "data.advancedSettings.courier.customRequestPreference.requestPreferenceLinkText": "请求首选项", + "data.advancedSettings.courier.customRequestPreferenceText": "将“{setRequestReferenceSetting}”设置为“{customSettingValue}”时,将使用“{requestPreferenceLink}”。", + "data.advancedSettings.courier.customRequestPreferenceTitle": "定制请求首选项", + "data.advancedSettings.courier.ignoreFilterText": "此配置增强对包含可视化的仪表板访问不同索引的支持。禁用时,将向所有可视化应用所有筛选。启用时,如果可视化的索引不包含筛选字段,则会为该可视化忽略筛选。", + "data.advancedSettings.courier.ignoreFilterTitle": "忽略筛选", + "data.advancedSettings.courier.maxRequestsText": "控制用于 Kibana 发送的 _msearch 请求的“{maxRequestsLink}”设置。设置为 0 可禁用此配置并使用 Elasticsearch 默认值。", + "data.advancedSettings.courier.maxRequestsTitle": "最大并发分片请求数", + "data.advancedSettings.courier.requestPreferenceCustom": "定制", + "data.advancedSettings.courier.requestPreferenceNone": "无", + "data.advancedSettings.courier.requestPreferenceSessionId": "会话 ID", + "data.advancedSettings.courier.requestPreferenceText": "允许您设置用于处理搜索请求的分片。
        \n
      • {sessionId}:限制操作在相同分片上执行所有搜索请求。\n 这有利于在各个请求之间复用分片缓存。
      • \n
      • {custom}:允许您定义自己的首选项。\n 使用 'courier:customRequestPreference' 定制首选项值。
      • \n
      • {none}:表示不设置首选项。\n 这可能会提供更佳的性能,因为请求可以在所有分片副本上进行分配。\n 不过,结果可能会不一致,因为不同的分片可能处于不同的刷新状态。
      • \n
      ", + "data.advancedSettings.courier.requestPreferenceTitle": "请求首选项", + "data.advancedSettings.defaultIndexText": "未设置索引时要访问的索引", + "data.advancedSettings.defaultIndexTitle": "默认索引", + "data.advancedSettings.docTableHighlightText": "在 Discover 和已保存搜索仪表板中突出显示结果。处理大文档时,突出显示会使请求变慢。", + "data.advancedSettings.docTableHighlightTitle": "突出显示结果", + "data.advancedSettings.format.bytesFormat.numeralFormatLinkText": "数值格式", + "data.advancedSettings.format.bytesFormatText": "“字节”格式的默认{numeralFormatLink}", + "data.advancedSettings.format.bytesFormatTitle": "字节格式", + "data.advancedSettings.format.currencyFormat.numeralFormatLinkText": "数值格式", + "data.advancedSettings.format.currencyFormatText": "“货币”格式的默认{numeralFormatLink}", + "data.advancedSettings.format.currencyFormatTitle": "货币格式", + "data.advancedSettings.format.defaultTypeMapText": "要默认用于每个字段类型的格式名称的映射。如果未显式提及字段类型,则将使用{defaultFormat}", + "data.advancedSettings.format.defaultTypeMapTitle": "字段类型格式名称", + "data.advancedSettings.format.formattingLocale.numeralLanguageLinkText": "数值语言", + "data.advancedSettings.format.formattingLocaleText": "{numeralLanguageLink}区域设置", + "data.advancedSettings.format.formattingLocaleTitle": "格式区域设置", + "data.advancedSettings.format.numberFormat.numeralFormatLinkText": "数值格式", + "data.advancedSettings.format.numberFormatText": "“数字”格式的默认{numeralFormatLink}", + "data.advancedSettings.format.numberFormatTitle": "数字格式", + "data.advancedSettings.format.percentFormat.numeralFormatLinkText": "数值格式", + "data.advancedSettings.format.percentFormatText": "“百分比”格式的默认{numeralFormatLink}", + "data.advancedSettings.format.percentFormatTitle": "百分比格式", + "data.advancedSettings.histogram.barTargetText": "在日期直方图中使用“auto”时尝试生成大约此数目的条形", + "data.advancedSettings.histogram.barTargetTitle": "目标条形数", + "data.advancedSettings.histogram.maxBarsText": "在日期直方图中不要显示超过该数目的条形,需要时显示刻度值", + "data.advancedSettings.histogram.maxBarsTitle": "最大条形数", + "data.advancedSettings.historyLimitText": "在具有历史记录(例如查询输入)的字段中,显示此数目的最近值", + "data.advancedSettings.historyLimitTitle": "历史记录限制", + "data.advancedSettings.indexPatternPlaceholderText": "在“管理”>“索引模式”>“创建索引模式”中“索引模式名称”字段的占位符。", + "data.advancedSettings.indexPatternPlaceholderTitle": "索引模式占位符", + "data.advancedSettings.metaFieldsText": "_source 之外存在的、在显示我们的文档时将合并进其中的字段", + "data.advancedSettings.metaFieldsTitle": "元字段", + "data.advancedSettings.pinFiltersText": "筛选是否应默认有全局状态(置顶)", + "data.advancedSettings.pinFiltersTitle": "默认置顶筛选", + "data.advancedSettings.query.allowWildcardsText": "设置后,将允许 * 用作查询语句的第一个字符。当前仅在查询栏中启用实验性查询功能时才会应用。要在基本 Lucene 查询中禁用前导通配符,请使用 {queryStringOptionsPattern}。", + "data.advancedSettings.query.allowWildcardsTitle": "在查询中允许前导通配符", + "data.advancedSettings.query.queryStringOptions.optionsLinkText": "选项", + "data.advancedSettings.query.queryStringOptionsText": "Lucene 查询字符串解析器的{optionsLink}。仅在将“{queryLanguage}”设置为 {luceneLanguage} 时使用。", + "data.advancedSettings.query.queryStringOptionsTitle": "查询字符串选项", + "data.advancedSettings.searchQueryLanguageKql": "KQL", + "data.advancedSettings.searchQueryLanguageLucene": "Lucene", + "data.advancedSettings.searchQueryLanguageText": "查询栏使用的查询语言。KQL 是专为 Kibana 打造的新型语言。", + "data.advancedSettings.searchQueryLanguageTitle": "查询语言", + "data.advancedSettings.shortenFieldsText": "缩短长字段,例如,不显示 foo.bar.baz,而显示 f.b.baz", + "data.advancedSettings.shortenFieldsTitle": "缩短字段", + "data.advancedSettings.sortOptions.optionsLinkText": "选项", + "data.advancedSettings.sortOptionsText": "Elasticsearch 排序参数的{optionsLink}", + "data.advancedSettings.sortOptionsTitle": "排序选项", + "data.advancedSettings.suggestFilterValuesText": "将此属性设置为 false 以阻止筛选编辑器建议字段的值。", + "data.advancedSettings.suggestFilterValuesTitle": "筛选编辑器建议值", + "data.advancedSettings.timepicker.last15Minutes": "过去 15 分钟", + "data.advancedSettings.timepicker.last1Hour": "过去 1 小时", + "data.advancedSettings.timepicker.last1Year": "过去 1 年", + "data.advancedSettings.timepicker.last24Hours": "过去 24 小时", + "data.advancedSettings.timepicker.last30Days": "过去 30 天", + "data.advancedSettings.timepicker.last30Minutes": "过去 30 分钟", + "data.advancedSettings.timepicker.last7Days": "过去 7 天", + "data.advancedSettings.timepicker.last90Days": "过去 90 天", + "data.advancedSettings.timepicker.quickRanges.acceptedFormatsLinkText": "接受的格式", + "data.advancedSettings.timepicker.quickRangesText": "要在时间筛选的“速选”部分中显示的范围列表。这应该是对象数组,每个对象包含“from”、“to”(请参阅“ {acceptedFormatsLink}”)和“display”(要显示的标题)。", + "data.advancedSettings.timepicker.quickRangesTitle": "时间筛选速选范围", + "data.advancedSettings.timepicker.refreshIntervalDefaultsText": "时间筛选的默认刷新时间间隔。需要使用毫秒单位指定“值”。", + "data.advancedSettings.timepicker.refreshIntervalDefaultsTitle": "时间筛选刷新时间间隔", + "data.advancedSettings.timepicker.thisWeek": "本周", + "data.advancedSettings.timepicker.today": "今日", "data.aggTypes.buckets.ranges.rangesFormatMessage": "{gte} {from} 和 {lt} {to}", "data.common.kql.errors.endOfInputText": "输入结束", "data.common.kql.errors.fieldNameText": "字段名称", @@ -668,7 +767,10 @@ "data.filter.filterBar.filterItemBadgeIconAriaLabel": "删除", "data.filter.filterBar.includeFilterButtonLabel": "包括结果", "data.filter.filterBar.indexPatternSelectPlaceholder": "选择索引模式", + "data.filter.filterBar.labelErrorInfo": "找不到索引模式 {indexPattern}", "data.filter.filterBar.labelErrorText": "错误", + "data.filter.filterBar.labelWarningInfo": "当前视图中不存在字段 {fieldName}", + "data.filter.filterBar.labelWarningText": "警告", "data.filter.filterBar.moreFilterActionsMessage": "筛选:{innerText}。选择以获取更多筛选操作。", "data.filter.filterBar.negatedFilterPrefix": "非 ", "data.filter.filterBar.pinFilterButtonLabel": "在所有应用上固定", @@ -718,6 +820,8 @@ "data.functions.esaggs.help": "运行 AggConfig 聚合", "data.functions.esaggs.inspector.dataRequest.description": "此请求将查询 Elasticsearch 以获取用于可视化的数据。", "data.functions.esaggs.inspector.dataRequest.title": "数据", + "data.functions.indexPatternLoad.help": "加载索引模式", + "data.functions.indexPatternLoad.id.help": "要加载的索引模式 id", "data.indexPatterns.editIndexPattern": "编辑索引模式", "data.indexPatterns.ensureDefaultIndexPattern.bannerLabel": "若要在 Kibana 中可视化和浏览数据,您需要创建索引模式,以从 Elasticsearch 检索数据。", "data.indexPatterns.fetchFieldErrorTitle": "提取索引模式 {title} (ID: {id}) 的字段时出错", @@ -726,6 +830,10 @@ "data.indexPatterns.unknownFieldHeader": "未知字段类型 {type}", "data.indexPatterns.warningText": "当前正在查询所有匹配 {index} 的索引。{title} 应迁移到基于通配符的索引模式。", "data.indexPatterns.warningTitle": "已移除对时间间隔索引模式的支持", + "data.noDataPopover.content": "此时间范围不包含任何数据。增大或调整时间范围,以查看更多的字段并创建图表。", + "data.noDataPopover.dismissAction": "不再显示", + "data.noDataPopover.subtitle": "提示", + "data.noDataPopover.title": "空数据集", "data.parseEsInterval.invalidEsCalendarIntervalErrorMessage": "无效的日历时间间隔:{interval},值必须为 1", "data.parseEsInterval.invalidEsIntervalFormatErrorMessage": "时间间隔格式无效:{interval}", "data.query.queryBar.comboboxAriaLabel": "搜索并筛选 {pageType} 页面", @@ -825,14 +933,14 @@ "data.search.aggs.buckets.histogram.schema.help": "要用于此聚合的方案", "data.search.aggs.buckets.histogramTitle": "Histogram", "data.search.aggs.buckets.intervalOptions.autoDisplayName": "自动", - "data.search.aggs.buckets.intervalOptions.dailyDisplayName": "每日", - "data.search.aggs.buckets.intervalOptions.hourlyDisplayName": "每小时", + "data.search.aggs.buckets.intervalOptions.dailyDisplayName": "天", + "data.search.aggs.buckets.intervalOptions.hourlyDisplayName": "小时", "data.search.aggs.buckets.intervalOptions.millisecondDisplayName": "毫秒", "data.search.aggs.buckets.intervalOptions.minuteDisplayName": "分钟", - "data.search.aggs.buckets.intervalOptions.monthlyDisplayName": "每月", + "data.search.aggs.buckets.intervalOptions.monthlyDisplayName": "月", "data.search.aggs.buckets.intervalOptions.secondDisplayName": "秒", - "data.search.aggs.buckets.intervalOptions.weeklyDisplayName": "每周", - "data.search.aggs.buckets.intervalOptions.yearlyDisplayName": "每年", + "data.search.aggs.buckets.intervalOptions.weeklyDisplayName": "周", + "data.search.aggs.buckets.intervalOptions.yearlyDisplayName": "年", "data.search.aggs.buckets.ipRange.customLabel.help": "表示此聚合的定制标签", "data.search.aggs.buckets.ipRange.enabled.help": "指定是否启用此聚合", "data.search.aggs.buckets.ipRange.field.help": "要用于此聚合的字段", @@ -1191,7 +1299,86 @@ "data.search.unableToGetSavedQueryToastTitle": "无法加载已保存查询 {savedQueryId}", "devTools.badge.readOnly.text": "只读", "devTools.badge.readOnly.tooltip": "无法保存", + "devTools.devToolsTitle": "开发工具", "devTools.k7BreadcrumbsDevToolsLabel": "开发工具", + "devTools.pageTitle": "开发工具", + "discover.advancedSettings.aggsTermsSizeText": "确定在单击“可视化”按钮时将在发现侧边栏的字段下拉列表中可视化多少个词。", + "discover.advancedSettings.aggsTermsSizeTitle": "词数目", + "discover.advancedSettings.context.defaultSizeText": "要在上下文视图中显示的周围条目数目", + "discover.advancedSettings.context.defaultSizeTitle": "上下文大小", + "discover.advancedSettings.context.sizeStepText": "递增或递减上下文大小的步进大小", + "discover.advancedSettings.context.sizeStepTitle": "上下文大小步进", + "discover.advancedSettings.context.tieBreakerFieldsText": "要在具有相同时间戳值的文档之间用于平分决胜的字段逗号分隔列表。将使用此列表上存在且在当前索引模式下可排序的第一个字段。", + "discover.advancedSettings.context.tieBreakerFieldsTitle": "平分决胜字段", + "discover.advancedSettings.defaultColumnsText": "“发现”选项卡中默认显示的列", + "discover.advancedSettings.defaultColumnsTitle": "默认列", + "discover.advancedSettings.docTableHideTimeColumnText": "在 Discover 中和仪表板上的所有已保存搜索中隐藏“时间”列。", + "discover.advancedSettings.docTableHideTimeColumnTitle": "隐藏“时间”列", + "discover.advancedSettings.fieldsPopularLimitText": "要显示的排名前 N 最常见字段", + "discover.advancedSettings.fieldsPopularLimitTitle": "常见字段限制", + "discover.advancedSettings.sampleSizeText": "要在表中显示的行数目", + "discover.advancedSettings.sampleSizeTitle": "行数目", + "discover.advancedSettings.searchOnPageLoadText": "控制在 Discover 首次加载时是否执行搜索。加载已保存搜索时,此设置无效。", + "discover.advancedSettings.searchOnPageLoadTitle": "在页面加载时搜索", + "discover.advancedSettings.sortDefaultOrderText": "在 Discover 应用中控制基于时间的索引模式的默认排序方向。", + "discover.advancedSettings.sortDefaultOrderTitle": "默认排序方向", + "discover.advancedSettings.sortOrderAsc": "升序", + "discover.advancedSettings.sortOrderDesc": "降序", + "discover.backToTopLinkText": "返回顶部。", + "discover.badge.readOnly.text": "只读", + "discover.badge.readOnly.tooltip": "无法保存搜索", + "discover.bucketIntervalTooltip": "此时间间隔创建的{bucketsDescription},无法在选定时间范围中显示,因此已调整为{bucketIntervalDescription}。", + "discover.bucketIntervalTooltip.tooLargeBucketsText": "存储桶过大", + "discover.bucketIntervalTooltip.tooManyBucketsText": "存储桶过多", + "discover.context.breadcrumb": "{indexPatternTitle}#{docId} 的上下文", + "discover.context.failedToLoadAnchorDocumentDescription": "无法加载定位点文档", + "discover.context.failedToLoadAnchorDocumentErrorDescription": "无法加载定位点文档。", + "discover.context.loadButtonLabel": "加载", + "discover.context.loadingDescription": "正在加载……", + "discover.context.newerDocumentsAriaLabel": "较新文档数目", + "discover.context.newerDocumentsDescription": "较新文档", + "discover.context.newerDocumentsWarning": "仅可以找到 {docCount} 个比定位标记新的文档。", + "discover.context.newerDocumentsWarningZero": "找不到比定位标记新的文档。", + "discover.context.olderDocumentsAriaLabel": "较旧文档数目", + "discover.context.olderDocumentsDescription": "较旧文档", + "discover.context.olderDocumentsWarning": "仅可以找到 {docCount} 个比定位标记旧的文档。", + "discover.context.olderDocumentsWarningZero": "找不到比定位标记旧的文档。", + "discover.context.reloadPageDescription.reloadOrVisitTextMessage": "请重新加载或前往文档列表以选择有效的定位点文档。", + "discover.context.unableToLoadAnchorDocumentDescription": "无法加载该定位点文档", + "discover.context.unableToLoadDocumentDescription": "无法加载文档", + "discover.discoverBreadcrumbTitle": "Discover", + "discover.discoverDescription": "通过查询和筛选原始文档来以交互方式浏览您的数据。", + "discover.discoverTitle": "Discover", + "discover.doc.couldNotFindDocumentsDescription": "无文档匹配该 ID。", + "discover.doc.failedToExecuteQueryDescription": "无法执行搜索", + "discover.doc.failedToLocateDocumentDescription": "无法找到文档", + "discover.doc.failedToLocateIndexPattern": "无索引模式匹配 ID {indexPatternId}", + "discover.doc.loadingDescription": "正在加载……", + "discover.doc.somethingWentWrongDescription": "{indexName} 缺失。", + "discover.doc.somethingWentWrongDescriptionAddon": "请确保索引存在。", + "discover.docTable.limitedSearchResultLabel": "仅限于 {resultCount} 个结果。优化您的搜索。", + "discover.docTable.noResultsTitle": "找不到结果", + "discover.docTable.pager.toolbarPagerButtons.nextButtonAriaLabel": "表中下一页", + "discover.docTable.pager.toolbarPagerButtons.previousButtonAriaLabel": "表中上一页", + "discover.docTable.pagerControl.pagesCountLabel": "{startItem}–{endItem}/{totalItems}", + "discover.docTable.tableHeader.moveColumnLeftButtonAriaLabel": "向左移动“{columnName}”列", + "discover.docTable.tableHeader.moveColumnLeftButtonTooltip": "向左移动列", + "discover.docTable.tableHeader.moveColumnRightButtonAriaLabel": "向右移动“{columnName}”列", + "discover.docTable.tableHeader.moveColumnRightButtonTooltip": "向右移动列", + "discover.docTable.tableHeader.removeColumnButtonAriaLabel": "移除“{columnName}”列", + "discover.docTable.tableHeader.removeColumnButtonTooltip": "移除列", + "discover.docTable.tableHeader.sortByColumnAscendingAriaLabel": "按“{columnName}”升序排序", + "discover.docTable.tableHeader.sortByColumnDescendingAriaLabel": "按“{columnName}”降序排序", + "discover.docTable.tableHeader.sortByColumnUnsortedAriaLabel": "停止按“{columnName}”排序", + "discover.docTable.tableRow.detailHeading": "已展开文档", + "discover.docTable.tableRow.filterForValueButtonAriaLabel": "筛留值", + "discover.docTable.tableRow.filterForValueButtonTooltip": "筛留值", + "discover.docTable.tableRow.filterOutValueButtonAriaLabel": "筛除值", + "discover.docTable.tableRow.filterOutValueButtonTooltip": "筛除值", + "discover.docTable.tableRow.toggleRowDetailsButtonAriaLabel": "切换行详细信息", + "discover.docTable.tableRow.viewSingleDocumentLinkText": "查看单个文档", + "discover.docTable.tableRow.viewSurroundingDocumentsLinkText": "查看周围文档", + "discover.documentsAriaLabel": "文档", "discover.docViews.json.codeEditorAriaLabel": "Elasticsearch 文档的只读 JSON 视图", "discover.docViews.json.jsonTitle": "JSON", "discover.docViews.table.fieldNamesBeginningWithUnderscoreUnsupportedAriaLabel": "警告", @@ -1211,6 +1398,46 @@ "discover.docViews.table.unableToFilterForPresenceOfMetaFieldsTooltip": "无法筛选元数据字段是否存在", "discover.docViews.table.unableToFilterForPresenceOfScriptedFieldsTooltip": "无法筛选脚本字段是否存在", "discover.docViews.table.unindexedFieldsCanNotBeSearchedTooltip": "无法搜索未索引字段", + "discover.embeddable.inspectorRequestDataTitle": "数据", + "discover.embeddable.inspectorRequestDescription": "此请求将查询 Elasticsearch 以获取搜索的数据。", + "discover.embeddable.search.displayName": "搜索", + "discover.errorLoadingData": "加载数据时出错", + "discover.fetchError.howToAddressErrorDescription": "您可以通过编辑{managementLink}中{scriptedFields}选项卡下的“{fetchErrorScript}”字段来解决此错误。", + "discover.fetchError.managmentLinkText": "“管理”>“索引模式”", + "discover.fetchError.scriptedFieldsText": "“脚本字段”", + "discover.fieldChooser.detailViews.emptyStringText": "空字符串", + "discover.fieldChooser.detailViews.filterOutValueButtonAriaLabel": "筛除 {field}:“{value}”", + "discover.fieldChooser.detailViews.filterValueButtonAriaLabel": "筛留 {field}:“{value}”", + "discover.fieldChooser.detailViews.recordsText": "个记录", + "discover.fieldChooser.detailViews.topValuesInRecordsDescription": "排名前 5 值 - 范围", + "discover.fieldChooser.detailViews.visualizeLinkText": "可视化", + "discover.fieldChooser.discoverField.addButtonAriaLabel": "将 {field} 添加到表中", + "discover.fieldChooser.discoverField.addButtonLabel": "添加", + "discover.fieldChooser.discoverField.removeButtonAriaLabel": "从表中移除 {field}", + "discover.fieldChooser.discoverField.removeButtonLabel": "移除", + "discover.fieldChooser.discoverField.scriptedFieldsTakeLongExecuteDescription": "脚本字段执行时间会很长。", + "discover.fieldChooser.fieldCalculator.analysisIsNotAvailableForGeoFieldsErrorMessage": "分析不适用于地理字段。", + "discover.fieldChooser.fieldCalculator.analysisIsNotAvailableForObjectFieldsErrorMessage": "分析不适用于对象字段。", + "discover.fieldChooser.fieldCalculator.fieldIsNotPresentInDocumentsErrorMessage": "此字段在您的 Elasticsearch 映射中,但不在文档表中显示的 {hitsLength} 个文档中。您可能仍能够基于它可视化或搜索。", + "discover.fieldChooser.fieldFilterFacetButtonLabel": "按类型筛选", + "discover.fieldChooser.filter.aggregatableLabel": "可聚合", + "discover.fieldChooser.filter.availableFieldsTitle": "可用字段", + "discover.fieldChooser.filter.fieldSelectorLabel": "{id} 筛选选项的选择", + "discover.fieldChooser.filter.filterByTypeLabel": "按类型筛选", + "discover.fieldChooser.filter.hideMissingFieldsLabel": "隐藏缺失字段", + "discover.fieldChooser.filter.indexAndFieldsSectionAriaLabel": "索引和字段", + "discover.fieldChooser.filter.indexAndFieldsSectionHideAriaLabel": "隐藏字段", + "discover.fieldChooser.filter.indexAndFieldsSectionShowAriaLabel": "显示字段", + "discover.fieldChooser.filter.popularTitle": "常见", + "discover.fieldChooser.filter.searchableLabel": "可搜索", + "discover.fieldChooser.filter.selectedFieldsTitle": "选定字段", + "discover.fieldChooser.filter.typeLabel": "类型", + "discover.fieldChooser.indexPattern.changeIndexPatternTitle": "更改索引模式", + "discover.fieldChooser.indexPattern.changeLinkAriaLabel": "更改当前索引模式", + "discover.fieldChooser.indexPattern.changeLinkTooltip": "更改当前索引模式", + "discover.fieldChooser.searchPlaceHolder": "搜索字段名称", + "discover.fieldChooser.toggleFieldFilterButtonHideAriaLabel": "隐藏字段筛选设置", + "discover.fieldChooser.toggleFieldFilterButtonShowAriaLabel": "显示字段筛选设置", "discover.fieldNameIcons.booleanAriaLabel": "布尔字段", "discover.fieldNameIcons.conflictFieldAriaLabel": "冲突字段", "discover.fieldNameIcons.dateFieldAriaLabel": "日期字段", @@ -1223,6 +1450,61 @@ "discover.fieldNameIcons.sourceFieldAriaLabel": "源字段", "discover.fieldNameIcons.stringFieldAriaLabel": "字符串字段", "discover.fieldNameIcons.unknownFieldAriaLabel": "未知字段", + "discover.helpMenu.appName": "Discover", + "discover.histogram.partialData.bucketTooltipText": "选定的时间范围不包括此整个存储桶,其可能包含部分数据。", + "discover.histogramOfFoundDocumentsAriaLabel": "已找到文档的直方图", + "discover.hitsPluralTitle": "{hits, plural, one {次命中} other {次命中}}", + "discover.howToChangeTheTimeTooltip": "要更改时间,请使用上面的全局时间筛选", + "discover.howToSeeOtherMatchingDocumentsDescription": "以下是匹配您的搜索的前 {sampleSize} 个文档,请优化您的搜索以查看其他文档。 ", + "discover.inspectorRequestDataTitle": "数据", + "discover.inspectorRequestDescription": "此请求将查询 Elasticsearch 以获取搜索的数据。", + "discover.localMenu.inspectTitle": "检查", + "discover.localMenu.localMenu.newSearchTitle": "新建", + "discover.localMenu.newSearchDescription": "新搜索", + "discover.localMenu.openInspectorForSearchDescription": "打开 Inspector 以进行搜索", + "discover.localMenu.openSavedSearchDescription": "打开已保存搜索", + "discover.localMenu.openTitle": "打开", + "discover.localMenu.saveSaveSearchDescription": "保存您的 Discover 搜索,以便可以在可视化和仪表板中使用该搜索", + "discover.localMenu.saveSearchDescription": "保存搜索", + "discover.localMenu.saveTitle": "保存", + "discover.localMenu.shareSearchDescription": "共享搜索", + "discover.localMenu.shareTitle": "共享", + "discover.noResults.addressShardFailuresTitle": "解决分片错误", + "discover.noResults.expandYourTimeRangeTitle": "展开时间范围", + "discover.noResults.indexFailureIndexText": "索引 {failureIndex}", + "discover.noResults.indexFailureShardText": "{index},分片 {failureShard}", + "discover.noResults.queryMayNotMatchTitle": "您正在查看的一个或多个索引包含日期字段。您的查询在当前时间范围内可能不匹配任何数据,也可能在当前选定的时间范围内没有任何数据。您可以尝试将时间范围更改为包含数据的时间范围。", + "discover.noResults.searchExamples.400to499StatusCodeExampleTitle": "查找所有介于 400-499 之间的状态代码", + "discover.noResults.searchExamples.400to499StatusCodeWithPhpExtensionExampleTitle": "查找状态代码 400-499 以及扩展名 php", + "discover.noResults.searchExamples.400to499StatusCodeWithPhpOrHtmlExtensionExampleTitle": "查找状态代码 400-499 以及扩展名 php 或 html", + "discover.noResults.searchExamples.anyField200StatusCodeExampleTitle": "查找任意字段包含数字 200 的请求", + "discover.noResults.searchExamples.howTosearchForWebServerLogsDescription": "顶部的搜索栏使用 Elasticsearch 对 Lucene {queryStringSyntaxLink} 的支持。以下是一些示例,说明如何搜索已解析成若干字段的 Web 服务器日志。", + "discover.noResults.searchExamples.noResultsMatchSearchCriteriaTitle": "没有任何结果匹配您的搜索条件", + "discover.noResults.searchExamples.queryStringSyntaxLinkText": "查询字符串语法", + "discover.noResults.searchExamples.refineYourQueryTitle": "优化您的查询", + "discover.noResults.searchExamples.statusField200StatusCodeExampleTitle": "在状态字段中查找 200", + "discover.noResults.shardFailuresDescription": "发生了以下分片错误:", + "discover.notifications.invalidTimeRangeText": "提供的时间范围无效。(起始:“{from}”,结束:“{to}”)", + "discover.notifications.invalidTimeRangeTitle": "时间范围无效", + "discover.notifications.notSavedSearchTitle": "搜索“{savedSearchTitle}”未保存。", + "discover.notifications.savedSearchTitle": "搜索“{savedSearchTitle}”已保存", + "discover.painlessError.painlessScriptedFieldErrorMessage": "Painless 脚本字段“{script}”有错误。", + "discover.reloadSavedSearchButton": "重置搜索", + "discover.rootBreadcrumb": "Discover", + "discover.savedSearch.savedObjectName": "已保存搜索", + "discover.searchingTitle": "正在搜索", + "discover.showingDefaultIndexPatternWarningDescription": "正在显示默认索引模式:“{loadedIndexPatternTitle}”({loadedIndexPatternId})", + "discover.showingSavedIndexPatternWarningDescription": "正在显示已保存索引模式:“{ownIndexPatternTitle}”({ownIndexPatternId})", + "discover.skipToBottomButtonLabel": "跳到表尾", + "discover.timechartHeader.timeIntervalSelect.ariaLabel": "时间间隔", + "discover.timechartHeader.timeIntervalSelect.per": "每", + "discover.topNav.openSearchPanel.manageSearchesButtonLabel": "管理搜索", + "discover.topNav.openSearchPanel.noSearchesFoundDescription": "未找到匹配的搜索。", + "discover.topNav.openSearchPanel.openSearchTitle": "打开搜索", + "discover.uninitializedRefreshButtonText": "刷新数据", + "discover.uninitializedText": "编写查询,添加一些筛选,或只需单击“刷新”来检索当前查询的结果。", + "discover.uninitializedTitle": "开始搜索", + "discover.valueIsNotConfiguredIndexPatternIDWarningTitle": "{stateVal} 不是配置的索引模式 ID", "embeddableApi.actions.applyFilterActionTitle": "将筛选应用于当前视图", "embeddableApi.addPanel.createNewDefaultOption": "新建", "embeddableApi.addPanel.displayName": "添加面板", @@ -1245,6 +1527,8 @@ "embeddableApi.panel.editPanel.displayName": "编辑 {value}", "embeddableApi.panel.enhancedDashboardPanelAriaLabel": "仪表板面板:{title}", "embeddableApi.panel.inspectPanel.displayName": "检查", + "embeddableApi.panel.labelAborted": "已中止", + "embeddableApi.panel.labelError": "错误", "embeddableApi.panel.optionsMenu.panelOptionsButtonAriaLabel": "面板选项", "embeddableApi.panel.optionsMenu.panelOptionsButtonEnhancedAriaLabel": "{title} 的面板选项", "embeddableApi.panel.removePanel.displayName": "从仪表板删除", @@ -1304,6 +1588,10 @@ "esUi.forms.fieldValidation.indexNameStartsWithDotError": "索引名称不能以点 (.) 开头。", "esUi.forms.fieldValidation.indexPatternInvalidCharactersError": "索引模式包含无效的{characterListLength, plural, one {字符} other {字符}} { characterList }。", "esUi.forms.fieldValidation.indexPatternSpacesError": "索引模式不能包含空格。", + "esUi.formWizard.backButtonLabel": "上一步", + "esUi.formWizard.nextButtonLabel": "下一步", + "esUi.formWizard.saveButtonLabel": "保存", + "esUi.formWizard.savingButtonLabel": "正在保存......", "esUi.validation.string.invalidJSONError": "JSON 无效", "expressions.defaultErrorRenderer.errorTitle": "可视化错误", "expressions.functions.font.args.alignHelpText": "水平文本对齐。", @@ -1340,6 +1628,9 @@ "home.addData.metrics.nameTitle": "指标", "home.addData.sampleDataLink": "加载数据集和 Kibana 仪表板", "home.addData.sampleDataTitle": "添加样例数据", + "home.addData.securitySolution.addSecurityEventsButtonLabel": "添加事件", + "home.addData.securitySolution.nameDescription": "集中安全事件,以通过即用型可视化实现交互式调查。", + "home.addData.securitySolution.nameTitle": "安全", "home.addData.title.observability": "可观测性", "home.addData.title.security": "安全", "home.addData.uploadFileLink": "导入 CSV、NDJSON 或日志文件", @@ -1369,6 +1660,7 @@ "home.letsStartTitle": "开始使用", "home.loadTutorials.requestFailedErrorMessage": "请求失败,状态代码:{status}", "home.loadTutorials.unableToLoadErrorMessage": "无法加载教程", + "home.pageTitle": "主页", "home.recentlyAccessed.recentlyViewedTitle": "最近查看", "home.sampleData.ecommerceSpec.averageSalesPerRegionTitle": "[电子商务] 每地区平均销售额", "home.sampleData.ecommerceSpec.averageSalesPriceTitle": "[电子商务] 平均销售价格", @@ -1471,6 +1763,7 @@ "home.tutorial.tabs.loggingTitle": "日志", "home.tutorial.tabs.metricsTitle": "指标", "home.tutorial.tabs.sampleDataTitle": "样例数据", + "home.tutorial.tabs.securitySolutionTitle": "安全", "home.tutorial.unexpectedStatusCheckStateErrorDescription": "意外的状态检查状态 {statusCheckState}", "home.tutorial.unhandledInstructionTypeErrorDescription": "未处理的指令类型 {visibleInstructions}", "home.tutorials.activemqLogs.artifacts.dashboards.linkLabel": "ActiveMQ 应用程序事件", @@ -1493,7 +1786,7 @@ "home.tutorials.apacheMetrics.longDescription": "Metricbeat 模块 `apache` 从 Apache 2 HTTP 服务器提取内部指标。[了解详情]({learnMoreLink})。", "home.tutorials.apacheMetrics.nameTitle": "Apache 指标", "home.tutorials.apacheMetrics.shortDescription": "从 Apache 2 HTTP 服务器提取内部指标。", - "home.tutorials.auditbeat.artifacts.dashboards.linkLabel": "SIEM 应用", + "home.tutorials.auditbeat.artifacts.dashboards.linkLabel": "安全性 API", "home.tutorials.auditbeat.longDescription": "使用 Auditbeat 从主机收集审计数据。其中包括进程、用户、登录、套接字信息、文件访问等等。[了解详情]({learnMoreLink})。", "home.tutorials.auditbeat.nameTitle": "Auditbeat", "home.tutorials.auditbeat.shortDescription": "从主机收集审计数据。", @@ -1505,6 +1798,11 @@ "home.tutorials.awsMetrics.longDescription": "Metricbeat 模块 `aws` 从 AWS API 和 Cloudwatch 提取监测指标。[了解详情]({learnMoreLink})。", "home.tutorials.awsMetrics.nameTitle": "AWS 指标", "home.tutorials.awsMetrics.shortDescription": "从 AWS API 和 Cloudwatch 提取 EC2 实例的监测指标。", + "home.tutorials.azureLogs.artifacts.dashboards.linkLabel": "Azure 日志仪表板", + "home.tutorials.azureLogs.longDescription": "Filebeat 模块 `azure` 收集 Azure 活动和审计相关日志。[了解详情]({learnMoreLink})。", + "home.tutorials.azureLogs.nameTitle": "Azure 日志", + "home.tutorials.azureLogs.shortDescription": "收集 Azure 活动和审计相关日志。", + "home.tutorials.azureMetrics.artifacts.dashboards.linkLabel": "Azure 指标仪表板", "home.tutorials.azureMetrics.longDescription": "Metricbeat 模块 `azure` 提取 Azure Monitor 指标。[了解详情]({learnMoreLink})。", "home.tutorials.azureMetrics.nameTitle": "Azure 指标", "home.tutorials.azureMetrics.shortDescription": "提取 Azure Monitor 指标。", @@ -1512,7 +1810,7 @@ "home.tutorials.cephMetrics.longDescription": "Metricbeat 模块 `ceph` 从 Ceph 提取内部指标。[了解详情]({learnMoreLink})。", "home.tutorials.cephMetrics.nameTitle": "Ceph 指标", "home.tutorials.cephMetrics.shortDescription": "从 Ceph 服务器提取内部指标。", - "home.tutorials.ciscoLogs.artifacts.dashboards.linkLabel": "SIEM 应用", + "home.tutorials.ciscoLogs.artifacts.dashboards.linkLabel": "安全性 API", "home.tutorials.ciscoLogs.longDescription": "这是用于 Cisco 网络设备日志的模块。当前支持“asa”文件集,该文件集用于通过 Syslog 接收或从文件读取的 Cisco ASA 防火墙日志。[了解详情]({learnMoreLink})。", "home.tutorials.ciscoLogs.nameTitle": "Cisco", "home.tutorials.ciscoLogs.shortDescription": "收集并解析从 Cisco ASA 防火墙接收的日志。", @@ -1842,7 +2140,7 @@ "home.tutorials.elasticsearchMetrics.longDescription": "Metricbeat 模块 `elasticsearch` 从 Elasticsearch 提取内部指标。[了解详情]({learnMoreLink})。", "home.tutorials.elasticsearchMetrics.nameTitle": "Elasticsearch 指标", "home.tutorials.elasticsearchMetrics.shortDescription": "从 Elasticsearch 提取内部指标。", - "home.tutorials.envoyproxyLogs.artifacts.dashboards.linkLabel": "SIEM 应用", + "home.tutorials.envoyproxyLogs.artifacts.dashboards.linkLabel": "安全性 API", "home.tutorials.envoyproxyLogs.longDescription": "这是用于 [Envoy 代理访问日志](https://www.envoyproxy.io/docs/envoy/v1.10.0/configuration/access_log)的 Filebeat 模块。其在 Kubernetes 中既支持独立部署,又支持 Envoy 代理部署。[了解详情]({learnMoreLink})。", "home.tutorials.envoyproxyLogs.nameTitle": "Envoyproxy", "home.tutorials.envoyproxyLogs.shortDescription": "收集并解析从 Envoy 代理接收的日志。", @@ -1857,6 +2155,10 @@ "home.tutorials.golangMetrics.longDescription": "Metricbeat 模块 `{moduleName}` 从 Golang 应用提取内部指标。[了解详情]({learnMoreLink})。", "home.tutorials.golangMetrics.nameTitle": "Golang 指标", "home.tutorials.golangMetrics.shortDescription": "从 Golang 应用提取内部指标。", + "home.tutorials.googlecloudMetrics.artifacts.dashboards.linkLabel": "Google Cloud 指标仪表板", + "home.tutorials.googlecloudMetrics.longDescription": "Metricbeat 模块 `googlecloud` 使用 Stackdriver 监测 API 从 Google Cloud Platform 提取监测指标。[了解详情]({learnMoreLink})。", + "home.tutorials.googlecloudMetrics.nameTitle": "Google Cloud 指标", + "home.tutorials.googlecloudMetrics.shortDescription": "使用 Stackdriver 监测 API 从 Google Cloud Platform 提取监测指标。", "home.tutorials.haproxyMetrics.artifacts.application.label": "Discover", "home.tutorials.haproxyMetrics.longDescription": "Metricbeat 模块 `haproxy` 从 HAProxy 提取内部指标。[了解详情]({learnMoreLink})。", "home.tutorials.haproxyMetrics.nameTitle": "HAProxy 指标", @@ -1873,7 +2175,11 @@ "home.tutorials.iisLogs.longDescription": "Filebeat 模块 `iis` 解析 IIS HTTP 服务器创建的访问和错误日志。[了解详情]({learnMoreLink})。", "home.tutorials.iisLogs.nameTitle": "IIS 日志", "home.tutorials.iisLogs.shortDescription": "收集并解析 IIS HTTP 服务器创建的访问和错误日志。", - "home.tutorials.iptablesLogs.artifacts.dashboards.linkLabel": "SIEM 应用", + "home.tutorials.iisMetrics.artifacts.dashboards.linkLabel": "IIS 指标仪表板", + "home.tutorials.iisMetrics.longDescription": "Metricbeat 模板 `iis` 从运行的 IIS 服务器以及应用程序池和网站收集指标。[了解详情]({learnMoreLink})。", + "home.tutorials.iisMetrics.nameTitle": "IIS 指标", + "home.tutorials.iisMetrics.shortDescription": "收集 IIS 服务器相关指标。", + "home.tutorials.iptablesLogs.artifacts.dashboards.linkLabel": "安全性 API", "home.tutorials.iptablesLogs.longDescription": "这是用于 iptables 和 ip6tables 日志的模块。其解析在网络上通过 Syslog 或从文件中接收的日志。另外,其识别某些 Ubiquiti 防火墙添加的前缀,该前缀包含规则集名称、规则编号和对流量执行的操作 (allow/deny)。[了解详情]({learnMoreLink})。", "home.tutorials.iptablesLogs.nameTitle": "Iptables / Ubiquiti", "home.tutorials.iptablesLogs.shortDescription": "从 Ubiqiti 防火墙收集并解析 iptables 和 ip6tables 日志。", @@ -1973,6 +2279,10 @@ "home.tutorials.openmetricsMetrics.longDescription": "Metricbeat 模块 `openmetrics` 从提供 OpenMetrics 格式指标的终端提取指标。[了解详情]({learnMoreLink})。", "home.tutorials.openmetricsMetrics.nameTitle": "OpenMetrics 指标", "home.tutorials.openmetricsMetrics.shortDescription": "从提供 OpenMetrics 格式指标的终端提取指标。", + "home.tutorials.oracleMetrics.artifacts.application.label": "Discover", + "home.tutorials.oracleMetrics.longDescription": "Metricbeat 模块 `{moduleName}` 从 Oracle 服务器提取内部指标。[了解详情]({learnMoreLink})。", + "home.tutorials.oracleMetrics.nameTitle": "oracle 指标", + "home.tutorials.oracleMetrics.shortDescription": "从 Oracle 服务器提取内部指标。", "home.tutorials.osqueryLogs.artifacts.dashboards.linkLabel": "Osquery 日志仪表板", "home.tutorials.osqueryLogs.longDescription": "Filebeat 模块 `osquery` 收集 `osqueryd` 收集的 JSON 结果日志。[了解详情]({learnMoreLink})。", "home.tutorials.osqueryLogs.nameTitle": "Osquery 日志", @@ -2063,10 +2373,306 @@ "home.tutorials.zookeeperMetrics.shortDescription": "从 Zookeeper 服务器提取内部指标。", "home.welcomeHomePageHeader": "Kibana 主页", "home.welcomeTitle": "欢迎使用 Elastic", + "indexPatternManagement.actions.cancelButton": "取消", + "indexPatternManagement.actions.createButton": "创建字段", + "indexPatternManagement.actions.deleteButton": "删除", + "indexPatternManagement.actions.saveButton": "保存字段", + "indexPatternManagement.aliasLabel": "别名", + "indexPatternManagement.color.actions": "操作", + "indexPatternManagement.color.addColorButton": "添加颜色", + "indexPatternManagement.color.backgroundLabel": "背景色", + "indexPatternManagement.color.deleteAria": "删除", + "indexPatternManagement.color.deleteTitle": "删除颜色格式", + "indexPatternManagement.color.exampleLabel": "示例", + "indexPatternManagement.color.patternLabel": "模式(正则表达式)", + "indexPatternManagement.color.rangeLabel": "范围(最小值:最大值)", + "indexPatternManagement.color.textColorLabel": "文本颜色", + "indexPatternManagement.createHeader": "创建脚本字段", + "indexPatternManagement.createIndexPattern.betaLabel": "公测版", + "indexPatternManagement.createIndexPattern.description": "索引模式可以匹配单个源,例如 {single} 或 {multiple} 个数据源、{star}。", + "indexPatternManagement.createIndexPattern.documentation": "阅读文档", + "indexPatternManagement.createIndexPattern.emptyState.checkDataButton": "检查新数据", + "indexPatternManagement.createIndexPattern.emptyStateHeader": "找不到任何 Elasticsearch 数据", + "indexPatternManagement.createIndexPattern.emptyStateLabel.emptyStateDetail": "{needToIndex}{learnHowLink}或{getStartedLink}", + "indexPatternManagement.createIndexPattern.emptyStateLabel.getStartedLink": "开始使用一些样例数据集。", + "indexPatternManagement.createIndexPattern.emptyStateLabel.learnHowLink": "了解操作方法", + "indexPatternManagement.createIndexPattern.emptyStateLabel.needToIndexLabel": "您需要在 Elasticsearch 中索引一些数据后,才能创建索引模式。", + "indexPatternManagement.createIndexPattern.includeSystemIndicesToggleSwitchLabel": "包括系统和隐藏索引", + "indexPatternManagement.createIndexPattern.loadClustersFailMsg": "无法加载远程集群", + "indexPatternManagement.createIndexPattern.loadIndicesFailMsg": "无法加载索引", + "indexPatternManagement.createIndexPattern.loadingState.checkingLabel": "正在检查 Elasticsearch 数据", + "indexPatternManagement.createIndexPattern.step.indexPattern.allowLabel": "使用星号 ({asterisk}) 匹配多个索引。", + "indexPatternManagement.createIndexPattern.step.indexPattern.disallowLabel": "不允许使用空格和字符 {characterList}。", + "indexPatternManagement.createIndexPattern.step.indexPatternLabel": "索引模式名称", + "indexPatternManagement.createIndexPattern.step.indexPatternPlaceholder": "index-name-*", + "indexPatternManagement.createIndexPattern.step.invalidCharactersErrorMessage": "{indexPatternName} 不能包含空格或字符:{characterList}", + "indexPatternManagement.createIndexPattern.step.loadingHeader": "正在寻找匹配的索引......", + "indexPatternManagement.createIndexPattern.step.loadingLabel": "请稍候......", + "indexPatternManagement.createIndexPattern.step.nextStepButton": "下一步", + "indexPatternManagement.createIndexPattern.step.pagingLabel": "每页行数:{perPage}", + "indexPatternManagement.createIndexPattern.step.status.matchAnyLabel.matchAnyDetail": "您的索引模式可以匹配{sourceCount, plural, one {您的 # 个源} other {您的 # 个源中的任何一个} }。", + "indexPatternManagement.createIndexPattern.step.status.noSystemIndicesLabel": "没有 Elasticsearch 索引匹配您的模式。", + "indexPatternManagement.createIndexPattern.step.status.noSystemIndicesWithPromptLabel": "没有 Elasticsearch 索引匹配您的模式。要查看匹配的系统索引,请切换上面的开关。", + "indexPatternManagement.createIndexPattern.step.status.notMatchLabel.allIndicesLabel": "{indicesLength, plural, one {# 个索引} other {# 个索引} }", + "indexPatternManagement.createIndexPattern.step.status.notMatchLabel.notMatchDetail": "输入的索引模式不匹配任何索引。您可以在下面匹配您的 {strongIndices}{indicesLength, plural, one {} other {中任何一个} }。", + "indexPatternManagement.createIndexPattern.step.status.partialMatchLabel.partialMatchDetail": "您的索引模式不匹配任何索引,但您的 {strongIndices}{matchedIndicesLength, plural, one {看起来} other {看起来} }类似。", + "indexPatternManagement.createIndexPattern.step.status.partialMatchLabel.strongIndicesLabel": "{matchedIndicesLength, plural, one {索引} other {# 个索引} }", + "indexPatternManagement.createIndexPattern.step.status.successLabel.successDetail": "您的索引模式匹配 {sourceCount} 个{sourceCount, plural, one {源} other {源} }。", + "indexPatternManagement.createIndexPattern.step.warningHeader": "已有称作“{query}”的索引模式", + "indexPatternManagement.createIndexPattern.stepHeader": "第 1 步(共 2 步):定义索引模式", + "indexPatternManagement.createIndexPattern.stepTime.backButton": "上一步", + "indexPatternManagement.createIndexPattern.stepTime.createPatternButton": "创建索引模式", + "indexPatternManagement.createIndexPattern.stepTime.creatingLabel": "正在创建索引模式……", + "indexPatternManagement.createIndexPattern.stepTime.error": "错误", + "indexPatternManagement.createIndexPattern.stepTime.field.loadingDropDown": "正在加载……", + "indexPatternManagement.createIndexPattern.stepTime.field.noTimeFieldsLabel": "匹配此索引模式的索引不包含任何时间字段。", + "indexPatternManagement.createIndexPattern.stepTime.fieldLabel": "时间字段", + "indexPatternManagement.createIndexPattern.stepTime.noTimeFieldOptionLabel": "我不想使用时间筛选", + "indexPatternManagement.createIndexPattern.stepTime.noTimeFieldsLabel": "匹配此索引模式的索引不包含任何时间字段。", + "indexPatternManagement.createIndexPattern.stepTime.options.hideButton": "隐藏高级选项", + "indexPatternManagement.createIndexPattern.stepTime.options.patternHeader": "定制索引模式 ID", + "indexPatternManagement.createIndexPattern.stepTime.options.patternLabel": "Kibana 将为每个索引模式提供唯一的标识符。如果不想使用此唯一 ID,请输入定制 ID。", + "indexPatternManagement.createIndexPattern.stepTime.options.patternPlaceholder": "custom-index-pattern-id", + "indexPatternManagement.createIndexPattern.stepTime.options.showButton": "显示高级选项", + "indexPatternManagement.createIndexPattern.stepTime.patterAlreadyExists": "自定义索引模式 ID 已存在。", + "indexPatternManagement.createIndexPattern.stepTime.refreshButton": "刷新", + "indexPatternManagement.createIndexPattern.stepTime.timeDescription": "选择用于全局时间筛选的主要时间字段。", + "indexPatternManagement.createIndexPattern.stepTimeHeader": "第 2 步(共 2 步):配置设置", + "indexPatternManagement.createIndexPatternHeader": "创建 {indexPatternName}", + "indexPatternManagement.dataStreamLabel": "数据流", + "indexPatternManagement.date.documentationLabel": "文档", + "indexPatternManagement.date.momentLabel": "Moment.js 格式模式(默认值:{defaultPattern})", + "indexPatternManagement.defaultErrorMessage": "尝试使用此格式配置时发生错误:{message}", + "indexPatternManagement.defaultFormatDropDown": "- 默认值 -", + "indexPatternManagement.defaultFormatHeader": "格式(默认值:{defaultFormat})", + "indexPatternManagement.deleteField.cancelButton": "取消", + "indexPatternManagement.deleteField.deleteButton": "删除", + "indexPatternManagement.deleteField.deletedHeader": "已删除“{fieldName}”", + "indexPatternManagement.deleteField.savedHeader": "已保存“{fieldName}”", + "indexPatternManagement.deleteFieldHeader": "删除字段“{fieldName}”", + "indexPatternManagement.deleteFieldLabel": "您无法恢复已删除字段。{separator}确定要执行此操作?", + "indexPatternManagement.disabledCallOutHeader": "脚本已禁用", + "indexPatternManagement.disabledCallOutLabel": "所有内联脚本在 Elasticsearch 中已禁用。必须至少为一种语言启用内联脚本,才能在 Kibana 中使用脚本字段。", + "indexPatternManagement.duration.decimalPlacesLabel": "小数位数", + "indexPatternManagement.duration.inputFormatLabel": "输入格式", + "indexPatternManagement.duration.outputFormatLabel": "输出格式", + "indexPatternManagement.durationErrorMessage": "小数位数必须介于 0 和 20 之间", + "indexPatternManagement.editHeader": "编辑 {fieldName}", "indexPatternManagement.editIndexPattern.createIndex.defaultButtonDescription": "对任何数据执行完全聚合", "indexPatternManagement.editIndexPattern.createIndex.defaultButtonText": "标准索引模式", "indexPatternManagement.editIndexPattern.createIndex.defaultTypeName": "索引模式", + "indexPatternManagement.editIndexPattern.deleteButton": "删除", + "indexPatternManagement.editIndexPattern.deleteHeader": "删除索引模式?", + "indexPatternManagement.editIndexPattern.detailsAria": "索引模式详细信息", + "indexPatternManagement.editIndexPattern.fields.allLangsDropDown": "所有语言", + "indexPatternManagement.editIndexPattern.fields.allTypesDropDown": "所有字段类型", + "indexPatternManagement.editIndexPattern.fields.filterAria": "筛选字段类型", + "indexPatternManagement.editIndexPattern.fields.filterPlaceholder": "搜索", + "indexPatternManagement.editIndexPattern.fields.searchAria": "搜索字段", + "indexPatternManagement.editIndexPattern.fields.table.additionalInfoAriaLabel": "其他字段信息", + "indexPatternManagement.editIndexPattern.fields.table.aggregatableDescription": "这些字段可用在可视化聚合中", + "indexPatternManagement.editIndexPattern.fields.table.aggregatableLabel": "可聚合", + "indexPatternManagement.editIndexPattern.fields.table.editDescription": "编辑", + "indexPatternManagement.editIndexPattern.fields.table.editLabel": "编辑", + "indexPatternManagement.editIndexPattern.fields.table.excludedDescription": "提取 _source 时从其中排除的字段", + "indexPatternManagement.editIndexPattern.fields.table.excludedLabel": "已排除", + "indexPatternManagement.editIndexPattern.fields.table.formatHeader": "格式", + "indexPatternManagement.editIndexPattern.fields.table.isAggregatableAria": "可聚合", + "indexPatternManagement.editIndexPattern.fields.table.isExcludedAria": "已排除", + "indexPatternManagement.editIndexPattern.fields.table.isSearchableAria": "可搜索", + "indexPatternManagement.editIndexPattern.fields.table.multiTypeAria": "多类型字段", + "indexPatternManagement.editIndexPattern.fields.table.multiTypeTooltip": "此字段的类型在不同的索引中会有所不同。其不可用于许多分析功能。", + "indexPatternManagement.editIndexPattern.fields.table.nameHeader": "名称", + "indexPatternManagement.editIndexPattern.fields.table.primaryTimeAriaLabel": "主要时间字段", + "indexPatternManagement.editIndexPattern.fields.table.primaryTimeTooltip": "此字段表示事件发生的时间。", + "indexPatternManagement.editIndexPattern.fields.table.searchableDescription": "这些字段可用于筛选栏", + "indexPatternManagement.editIndexPattern.fields.table.searchableHeader": "可搜索", + "indexPatternManagement.editIndexPattern.fields.table.typeHeader": "类型", "indexPatternManagement.editIndexPattern.list.defaultIndexPatternListName": "默认值", + "indexPatternManagement.editIndexPattern.mappingConflictHeader": "映射冲突", + "indexPatternManagement.editIndexPattern.mappingConflictLabel": "{conflictFieldsLength, plural, one {一个字段} other {# 个字段}}已在匹配此模式的各个索引中定义为多个类型(字符串、整数等)。您也许仍能够在 Kibana 的各个部分中使用这些冲突类型,但它们将无法用于需要 Kibana 知道其类型的函数。要解决此问题,需要重新索引您的数据。", + "indexPatternManagement.editIndexPattern.refreshAria": "重新加载字段列表。", + "indexPatternManagement.editIndexPattern.refreshButton": "刷新", + "indexPatternManagement.editIndexPattern.refreshHeader": "刷新字段列表?", + "indexPatternManagement.editIndexPattern.refreshLabel": "此操作重置每个字段的常见度计数器。", + "indexPatternManagement.editIndexPattern.refreshTooltip": "刷新字段列表。", + "indexPatternManagement.editIndexPattern.removeAria": "移除索引模式。", + "indexPatternManagement.editIndexPattern.removeTooltip": "移除索引模式。", + "indexPatternManagement.editIndexPattern.scripted.addFieldButton": "添加脚本字段", + "indexPatternManagement.editIndexPattern.scripted.deleteField.cancelButton": "取消", + "indexPatternManagement.editIndexPattern.scripted.deleteField.deleteButton": "删除", + "indexPatternManagement.editIndexPattern.scripted.deleteFieldLabel": "删除脚本字段“{fieldName}”?", + "indexPatternManagement.editIndexPattern.scripted.deprecationLangHeader": "在用的过时语言", + "indexPatternManagement.editIndexPattern.scripted.deprecationLangLabel.deprecationLangDetail": "以下过时的语言仍在使用:{deprecatedLangsInUse}。Kibana 和 Elasticsearch 的下一主要版本将移除对这些语言的支持。将您的脚本字段转换成 {link} 以避免问题。", + "indexPatternManagement.editIndexPattern.scripted.deprecationLangLabel.painlessDescription": "Painless", + "indexPatternManagement.editIndexPattern.scripted.newFieldPlaceholder": "新建脚本字段", + "indexPatternManagement.editIndexPattern.scripted.noFieldLabel": "“{indexPatternTitle}”索引模式没有称作“{fieldName}”的脚本字段", + "indexPatternManagement.editIndexPattern.scripted.table.deleteDescription": "删除此字段", + "indexPatternManagement.editIndexPattern.scripted.table.deleteHeader": "删除", + "indexPatternManagement.editIndexPattern.scripted.table.editDescription": "编辑此字段", + "indexPatternManagement.editIndexPattern.scripted.table.editHeader": "编辑", + "indexPatternManagement.editIndexPattern.scripted.table.formatDescription": "用于该字段的格式", + "indexPatternManagement.editIndexPattern.scripted.table.formatHeader": "格式", + "indexPatternManagement.editIndexPattern.scripted.table.langDescription": "用于该字段的语言", + "indexPatternManagement.editIndexPattern.scripted.table.langHeader": "语言", + "indexPatternManagement.editIndexPattern.scripted.table.nameDescription": "字段的名称", + "indexPatternManagement.editIndexPattern.scripted.table.nameHeader": "名称", + "indexPatternManagement.editIndexPattern.scripted.table.scriptDescription": "字段的脚本", + "indexPatternManagement.editIndexPattern.scripted.table.scriptHeader": "脚本", + "indexPatternManagement.editIndexPattern.scriptedHeader": "脚本字段", + "indexPatternManagement.editIndexPattern.scriptedLabel": "可以在可视化中使用脚本字段,并在您的文档中显示它们。但是,您不能搜索脚本字段。", + "indexPatternManagement.editIndexPattern.setDefaultAria": "设置为默认索引。", + "indexPatternManagement.editIndexPattern.setDefaultTooltip": "设置为默认索引。", + "indexPatternManagement.editIndexPattern.source.addButtonLabel": "添加", + "indexPatternManagement.editIndexPattern.source.deleteFilter.cancelButtonLabel": "取消", + "indexPatternManagement.editIndexPattern.source.deleteFilter.deleteButtonLabel": "删除", + "indexPatternManagement.editIndexPattern.source.deleteSourceFilterLabel": "删除源筛选“{value}”?", + "indexPatternManagement.editIndexPattern.source.noteLabel": "请注意,多字段将错误地显示为下表中的匹配。这些筛选仅应用于原始源文档中的字段,因此实际未筛选匹配的多字段。", + "indexPatternManagement.editIndexPattern.source.table.cancelAria": "取消", + "indexPatternManagement.editIndexPattern.source.table.deleteAria": "删除", + "indexPatternManagement.editIndexPattern.source.table.editAria": "编辑", + "indexPatternManagement.editIndexPattern.source.table.filterDescription": "筛选名称", + "indexPatternManagement.editIndexPattern.source.table.filterHeader": "筛选", + "indexPatternManagement.editIndexPattern.source.table.matchesDescription": "用于该字段的语言", + "indexPatternManagement.editIndexPattern.source.table.matchesHeader": "匹配", + "indexPatternManagement.editIndexPattern.source.table.notMatchedLabel": "源筛选不匹配任何已知字段。", + "indexPatternManagement.editIndexPattern.source.table.saveAria": "保存", + "indexPatternManagement.editIndexPattern.sourceHeader": "源筛选", + "indexPatternManagement.editIndexPattern.sourceLabel": "提取文档源时,源筛选可用于排除一个或多个字段。在 Discover 应用中查看文档时会发生此问题,表在 Dashboard 应用中显示已保存搜索的结果时也会发生此问题。将使用单个文档的源生成每行,如果您的文档含有较大或不重要字段的文档,则通过在此较低层级筛除这些字段可能会更好。", + "indexPatternManagement.editIndexPattern.sourcePlaceholder": "源筛选,接受通配符(例如“user*”用于筛选以“user”开头的字段)", + "indexPatternManagement.editIndexPattern.tabs.fieldsHeader": "字段", + "indexPatternManagement.editIndexPattern.tabs.scriptedHeader": "脚本字段", + "indexPatternManagement.editIndexPattern.tabs.sourceHeader": "源筛选", + "indexPatternManagement.editIndexPattern.timeFilterHeader": "时间筛选字段名称:“{timeFieldName}”", + "indexPatternManagement.editIndexPattern.timeFilterLabel.mappingAPILink": "映射 API", + "indexPatternManagement.editIndexPattern.timeFilterLabel.timeFilterDetail": "此页根据 Elasticsearch 的记录列出“{indexPatternTitle}”索引中的每个字段以及字段的关联核心类型。要更改字段类型,请使用 Elasticsearch", + "indexPatternManagement.editIndexPatternLiveRegionAriaLabel": "索引模式", + "indexPatternManagement.fieldTypeConflict": "字段类型冲突", + "indexPatternManagement.formatHeader": "格式", + "indexPatternManagement.formatLabel": "设置格式允许您控制特定值的显示方式。其还会导致值完全更改,并阻止 Discover 中的突出显示起作用。", + "indexPatternManagement.frozenLabel": "已冻结", + "indexPatternManagement.indexLabel": "索引", + "indexPatternManagement.indexNameLabel": "索引名称", + "indexPatternManagement.indexPattern.goToPatternButtonLabel": "前往现有模式", + "indexPatternManagement.indexPattern.sectionsHeader": "索引模式", + "indexPatternManagement.indexPattern.titleExistsLabel": "具有标题“{title}”的索引模式已存在。", + "indexPatternManagement.indexPatternList.createButton.betaLabel": "公测版", + "indexPatternManagement.indexPatternPrompt.exampleOne": "索引单个称作 log-west-001 的数据源,以便可以快速地构建图表或查询其内容。", + "indexPatternManagement.indexPatternPrompt.exampleOneTitle": "单数据源", + "indexPatternManagement.indexPatternPrompt.examplesTitle": "索引模式示例", + "indexPatternManagement.indexPatternPrompt.exampleThree": "具体而言,将这些日志每月存档的汇总/打包指标分组成不同的索引模式,从而可以聚合历史趋势以进行比较。", + "indexPatternManagement.indexPatternPrompt.exampleThreeTitle": "定制分组", + "indexPatternManagement.indexPatternPrompt.exampleTwo": "分组以 log-west* 开头的所有传入数据源,以便可以查询所有西海岸服务器日志。", + "indexPatternManagement.indexPatternPrompt.exampleTwoTitle": "多数据源", + "indexPatternManagement.indexPatternPrompt.subtitle": "索引模式允许您将异类的数据源一起装入存储桶,从而可以在 Kibana 中查询它们共享的字段。", + "indexPatternManagement.indexPatternPrompt.title": "关于索引模式", + "indexPatternManagement.indexPatterns.badge.readOnly.text": "只读", + "indexPatternManagement.indexPatterns.badge.readOnly.tooltip": "无法保存索引模式", + "indexPatternManagement.indexPatterns.createBreadcrumb": "创建索引模式", + "indexPatternManagement.indexPatterns.createFieldBreadcrumb": "创建字段", + "indexPatternManagement.indexPatterns.listBreadcrumb": "索引模式", + "indexPatternManagement.indexPatternTable.createBtn": "创建索引模式", + "indexPatternManagement.indexPatternTable.title": "索引模式", + "indexPatternManagement.labelTemplate.example.idLabel": "用户 #{value}", + "indexPatternManagement.labelTemplate.example.output.idLabel": "用户", + "indexPatternManagement.labelTemplate.example.output.pathLabel": "查看资产", + "indexPatternManagement.labelTemplate.example.pathLabel": "查看资产", + "indexPatternManagement.labelTemplate.examplesHeader": "示例", + "indexPatternManagement.labelTemplate.inputHeader": "输入", + "indexPatternManagement.labelTemplate.labelHeader": "标签模板", + "indexPatternManagement.labelTemplate.outputHeader": "输出", + "indexPatternManagement.labelTemplate.urlHeader": "URL 模板", + "indexPatternManagement.labelTemplate.urlLabel": "格式化 URL", + "indexPatternManagement.labelTemplate.valueLabel": "字段值", + "indexPatternManagement.labelTemplateHeader": "标签模板", + "indexPatternManagement.labelTemplateLabel": "如果此字段中的 URL 很长,为 URL 的文本版本提供备选模板可能会很有用。该文本将会显示,而非显示该 url,但仍会链接到该 URL。该格式是使用双大括号表示法 {doubleCurlyBraces} 来注入值的字符串。可以访问以下值:", + "indexPatternManagement.languageLabel": "语言", + "indexPatternManagement.mappingConflictLabel.mappingConflictDetail": "{mappingConflict}您已经有名称为 {fieldName} 的字段。使用相同的名称命名您的脚本字段意味着您将无法同时查找两个字段。", + "indexPatternManagement.mappingConflictLabel.mappingConflictLabel": "映射冲突:", + "indexPatternManagement.multiTypeLabelDesc": "此字段的类型在不同的索引中会有所不同。其不可用于许多分析功能。每个类型的索引如下所示:", + "indexPatternManagement.nameErrorMessage": "“名称”必填", + "indexPatternManagement.nameLabel": "名称", + "indexPatternManagement.namePlaceholder": "新建脚本字段", + "indexPatternManagement.number.documentationLabel": "文档", + "indexPatternManagement.number.numeralLabel": "Numeral.js 格式模式(默认值:{defaultPattern})", + "indexPatternManagement.popularityLabel": "常见度", + "indexPatternManagement.samples.inputHeader": "输入", + "indexPatternManagement.samples.outputHeader": "输出", + "indexPatternManagement.samplesHeader": "样例", + "indexPatternManagement.script.accessWithLabel": "使用 {code} 访问字段。", + "indexPatternManagement.script.getHelpLabel": "获取该语法的帮助,预览脚本的结果。", + "indexPatternManagement.scriptingLanguages.errorFetchingToastDescription": "从 Elasticsearch 获取可用的脚本语言时出错", + "indexPatternManagement.scriptInvalidErrorMessage": "脚本无效。查看脚本预览以了解详情", + "indexPatternManagement.scriptLabel": "脚本", + "indexPatternManagement.scriptRequiredErrorMessage": "“脚本”必填", + "indexPatternManagement.staticLookup.actions": "操作", + "indexPatternManagement.staticLookup.addEntryButton": "添加条目", + "indexPatternManagement.staticLookup.deleteAria": "删除", + "indexPatternManagement.staticLookup.deleteTitle": "删除条目", + "indexPatternManagement.staticLookup.keyLabel": "键", + "indexPatternManagement.staticLookup.leaveBlankPlaceholder": "留空可使值保持原样", + "indexPatternManagement.staticLookup.unknownKeyLabel": "未知键的值", + "indexPatternManagement.staticLookup.valueLabel": "值", + "indexPatternManagement.string.transformLabel": "转换", + "indexPatternManagement.syntax.default.formatLabel": "doc['some_field'].value", + "indexPatternManagement.syntax.defaultLabel.defaultDetail": "默认情况下,Kibana 脚本字段使用 {painless}(一种简单且安全的脚本语言,专用于 Elasticsearch)通过以下格式访问文档中的值:", + "indexPatternManagement.syntax.defaultLabel.painlessLink": "Painless", + "indexPatternManagement.syntax.kibanaLabel": "Kibana 当前对您编写的 Painless 脚本强加一个特殊限制。它们不能包含命名函数。", + "indexPatternManagement.syntax.lucene.commonLabel.commonDetail": "来自较旧的 Kibana 版本?您了解并喜爱的 {lucene} 仍可用。Lucene 表达式很像 JavaScript,但仅限于基本的算术、位和比较运算。", + "indexPatternManagement.syntax.lucene.commonLabel.luceneLink": "Lucene 表达式", + "indexPatternManagement.syntax.lucene.limits.fieldsLabel": "存储字段不可用", + "indexPatternManagement.syntax.lucene.limits.sparseLabel": "如果字段为稀疏字段(仅某些文档包含值),则缺失该字段的文档将具有 0 值", + "indexPatternManagement.syntax.lucene.limits.typesLabel": "仅数值、布尔值、日期和 geo_point 字段可以访问", + "indexPatternManagement.syntax.lucene.limitsLabel": "使用 Lucene 表达式时有一些限制:", + "indexPatternManagement.syntax.lucene.operations.arithmeticLabel": "算术运算符:{operators}", + "indexPatternManagement.syntax.lucene.operations.bitwiseLabel": "位运算符:{operators}", + "indexPatternManagement.syntax.lucene.operations.booleanLabel": "布尔运算符(包括三元运算符):{operators}", + "indexPatternManagement.syntax.lucene.operations.comparisonLabel": "比较运算符:{operators}", + "indexPatternManagement.syntax.lucene.operations.distanceLabel": "距离函数:{operators}", + "indexPatternManagement.syntax.lucene.operations.mathLabel": "常用数学函数:{operators}", + "indexPatternManagement.syntax.lucene.operations.miscellaneousLabel": "其他函数:{operators}", + "indexPatternManagement.syntax.lucene.operations.trigLabel": "三角库函数:{operators}", + "indexPatternManagement.syntax.lucene.operationsLabel": "以下是可用于 lucene 表达式的所有运算:", + "indexPatternManagement.syntax.painlessLabel.javaAPIsLink": "原生 Java API", + "indexPatternManagement.syntax.painlessLabel.painlessDetail": "Painless 功能强大但却易于使用。其提供对许多 {javaAPIs} 的访问。研读其 {syntax},您将很快上手!", + "indexPatternManagement.syntax.painlessLabel.syntaxLink": "语法", + "indexPatternManagement.syntaxHeader": "语法", + "indexPatternManagement.testScript.errorMessage": "您的脚本中有错误", + "indexPatternManagement.testScript.fieldsLabel": "其他字段", + "indexPatternManagement.testScript.fieldsPlaceholder": "选择......", + "indexPatternManagement.testScript.instructions": "运行您的脚本以预览前 10 个结果。还可以选择其他字段包括在您的结果中,以获取更多上下文,或添加查询以在特定文档上进行筛选。", + "indexPatternManagement.testScript.resultsLabel": "前 10 个结果", + "indexPatternManagement.testScript.resultsTitle": "预览结果", + "indexPatternManagement.testScript.submitButtonLabel": "运行脚本", + "indexPatternManagement.truncate.lengthLabel": "字段长度", + "indexPatternManagement.typeLabel": "类型", + "indexPatternManagement.url.heightLabel": "高", + "indexPatternManagement.url.labelTemplateHelpText": "标签模板帮助", + "indexPatternManagement.url.labelTemplateLabel": "标签模板", + "indexPatternManagement.url.offLabel": "关闭", + "indexPatternManagement.url.onLabel": "开启", + "indexPatternManagement.url.openTabLabel": "在新选项卡中打开", + "indexPatternManagement.url.template.helpLinkText": "URL 模板帮助", + "indexPatternManagement.url.typeLabel": "类型", + "indexPatternManagement.url.urlTemplateLabel": "URL 模板", + "indexPatternManagement.url.widthLabel": "宽", + "indexPatternManagement.urlTemplate.examplesHeader": "示例", + "indexPatternManagement.urlTemplate.inputHeader": "输入", + "indexPatternManagement.urlTemplate.outputHeader": "输出", + "indexPatternManagement.urlTemplate.rawValueLabel": "非转义值", + "indexPatternManagement.urlTemplate.templateHeader": "模板", + "indexPatternManagement.urlTemplate.valueLabel": "URI 转义值", + "indexPatternManagement.urlTemplateHeader": "Url 模板", + "indexPatternManagement.urlTemplateLabel.fieldDetail": "如果字段仅包含 URL 的一部分,则 {strongUrlTemplate} 可用于将该值格式化为完整的 URL。该格式是使用双大括号表示法 {doubleCurlyBraces} 来注入值的字符串。可以访问以下值:", + "indexPatternManagement.urlTemplateLabel.strongUrlTemplateLabel": "Url 模板", + "indexPatternManagement.warningCallOut.descriptionLabel": "脚本字段可用于显示并聚合计算值。因此,它们会很慢,如果操作不当,会导致 Kibana 不可用。此处没有安全网。如果拼写错误,则在任何地方都会引发异常!", + "indexPatternManagement.warningCallOutHeader": "谨慎操作", + "indexPatternManagement.warningCallOutLabel.callOutDetail": "请先熟悉{scripFields}以及{scriptsInAggregation},然后再使用脚本字段。", + "indexPatternManagement.warningCallOutLabel.scripFieldsLink": "脚本字段", + "indexPatternManagement.warningCallOutLabel.scriptsInAggregationLink": "聚合中的脚本", + "indexPatternManagement.warningHeader": "过时警告:", + "indexPatternManagement.warningLabel.painlessLinkLabel": "Painless", + "indexPatternManagement.warningLabel.warningDetail": "{language} 已过时,Kibana 和 Elasticsearch 下一主要版本将移除支持。建议将 {painlessLink} 用于新的脚本字段。", "inputControl.control.noIndexPatternTooltip": "找不到索引模式 ID:{indexPatternId}。", "inputControl.control.notInitializedTooltip": "尚未初始化控件", "inputControl.control.noValuesDisableTooltip": "按 “{fieldName}” 字段进行了筛选,但 “{indexPatternName}” 索引模式的任何文档中都不存在该字段。选择不同的字段或索引包含此字段的值的文档。", @@ -2189,6 +2795,8 @@ "kbn.advancedSettings.pageNavigationName": "侧边导航样式", "kbn.advancedSettings.storeUrlText": "URL 有时会变得过长,以使得某些浏览器无法处理。为此,我们正在测试将 URL 的各个组成部分存储在会话存储中是否会有帮助。请告知我们这样做的效果!", "kbn.advancedSettings.storeUrlTitle": "将 URL 存储在会话存储中", + "kbn.advancedSettings.themeVersionText": "在用于 Kibana 当前和下一版本的主题间切换。需要刷新页面,才能应用设置。", + "kbn.advancedSettings.themeVersionTitle": "主题版本", "kbn.advancedSettings.timepicker.timeDefaultsText": "未使用时间筛选启动 Kibana 时要使用的时间筛选选择", "kbn.advancedSettings.timepicker.timeDefaultsTitle": "时间筛选默认值", "kbn.advancedSettings.visualization.showRegionMapWarningsText": "词无法联接到地图上的形状时,区域地图是否显示警告。", @@ -2226,6 +2834,8 @@ "kibana-react.tableListView.listing.deleteSelectedItemsConfirmModal.cancelButtonLabel": "取消", "kibana-react.tableListView.listing.deleteSelectedItemsConfirmModal.confirmButtonLabel": "删除", "kibana-react.tableListView.listing.deleteSelectedItemsConfirmModal.confirmButtonLabelDeleting": "正在删除", + "kibana-react.tableListView.listing.fetchErrorDescription": "无法提取 {entityName} 列表:{message}。", + "kibana-react.tableListView.listing.fetchErrorTitle": "提取列表失败", "kibana-react.tableListView.listing.listingLimitExceeded.advancedSettingsLinkText": "高级设置", "kibana-react.tableListView.listing.listingLimitExceededDescription": "您有 {totalItems} 个{entityNamePlural},但您的“{listingLimitText}”设置阻止下表显示 {listingLimitValue} 个以上。您可以在“{advancedSettingsLink}”下更改此设置。", "kibana-react.tableListView.listing.listingLimitExceededTitle": "已超过列表限制", @@ -2236,10 +2846,26 @@ "kibana-react.tableListView.listing.table.editActionName": "编辑", "kibana-react.tableListView.listing.unableToDeleteDangerMessage": "无法删除{entityName}", "management.breadcrumb": "Stack Management", + "management.landing.header": "欢迎使用 Stack Management {version}", + "management.landing.subhead": "管理您的索引、索引模式、已保存对象、Kibana 设置等等。", + "management.landing.text": "应用的完整列表位于左侧菜单中。", "management.nav.label": "管理", "management.nav.menu": "管理菜单", + "management.sections.dataTip": "管理您的集群数据和备份", + "management.sections.dataTitle": "数据", + "management.sections.ingestTip": "管理如何转换数据并将其加载到集群中", + "management.sections.ingestTitle": "采集", + "management.sections.insightsAndAlertingTip": "管理如何检测数据变化", + "management.sections.insightsAndAlertingTitle": "告警和洞见", + "management.sections.kibanaTip": "定制 Kibana 和管理已保存对象", + "management.sections.kibanaTitle": "Kibana", + "management.sections.section.tip": "控制对功能和数据的访问", + "management.sections.section.title": "安全", + "management.sections.stackTip": "管理您的许可并升级 Stack", + "management.sections.stackTitle": "Stack", "management.stackManagement.managementDescription": "您用于管理 Elastic Stack 的中心控制台。", "management.stackManagement.managementLabel": "Stack Management", + "management.stackManagement.title": "Stack Management", "maps_legacy.baseMapsVisualization.childShouldImplementMethodErrorMessage": "子对象应实现此方法以响应数据更新", "maps_legacy.kibanaMap.leaflet.fitDataBoundsAriaLabel": "适应数据边界", "maps_legacy.kibanaMap.zoomWarning": "已达到缩放级别数目上限。要一直放大,请升级到 Elasticsearch 和 Kibana 的{defaultDistribution}。您可以通过 {ems} 免费使用其他缩放级别。或者,您可以配置自己的地图服务器。请前往 { wms } 或 { configSettings} 以获取详细信息。", @@ -2291,6 +2917,10 @@ "regionMap.visParams.vectorMapLabel": "矢量地图", "regionMap.visualization.unableToShowMismatchesWarningText": "确保每个字词与该形状的联接字段匹配:{mismatches}", "regionMap.visualization.unableToShowMismatchesWarningTitle": "无法在地图上显示 {mismatchesLength} {oneMismatch, plural, one { 个结果} other { 个结果}}", + "savedObjects.advancedSettings.listingLimitText": "要为列表页面提取的对象数目", + "savedObjects.advancedSettings.listingLimitTitle": "对象列表限制", + "savedObjects.advancedSettings.perPageText": "加载对话框中每页要显示的对象数目", + "savedObjects.advancedSettings.perPageTitle": "每页对象数", "savedObjects.confirmModal.cancelButtonLabel": "取消", "savedObjects.confirmModal.overwriteButtonLabel": "覆盖", "savedObjects.confirmModal.overwriteConfirmationMessage": "确定要覆盖“{title}”?", @@ -2446,6 +3076,10 @@ "server.status.redTitle": "红", "server.status.uninitializedTitle": "未初始化", "server.status.yellowTitle": "黄", + "share.advancedSettings.csv.quoteValuesText": "在 CSV 导出中是否应使用引号引起值?", + "share.advancedSettings.csv.quoteValuesTitle": "使用引号引起 CSV 值", + "share.advancedSettings.csv.separatorText": "使用此字符串分隔导出的值", + "share.advancedSettings.csv.separatorTitle": "CSV 分隔符", "share.contextMenu.embedCodeLabel": "嵌入代码", "share.contextMenu.embedCodePanelTitle": "嵌入代码", "share.contextMenu.permalinkPanelTitle": "固定链接", @@ -3110,6 +3744,8 @@ "visTypeTimeseries.addDeleteButtons.deleteButtonDefaultTooltip": "删除", "visTypeTimeseries.addDeleteButtons.reEnableTooltip": "重新启用", "visTypeTimeseries.addDeleteButtons.temporarilyDisableTooltip": "暂时禁用", + "visTypeTimeseries.advancedSettings.maxBucketsText": "单个数据源可以返回的最大存储桶数目", + "visTypeTimeseries.advancedSettings.maxBucketsTitle": "最大存储桶数", "visTypeTimeseries.aggLookup.averageLabel": "平均值", "visTypeTimeseries.aggLookup.calculationLabel": "计算", "visTypeTimeseries.aggLookup.cardinalityLabel": "基数", @@ -3557,6 +4193,7 @@ "visTypeTimeseries.timeseries.optionsTab.panelOptionsButtonLabel": "面板选项", "visTypeTimeseries.timeseries.optionsTab.showLegendLabel": "显示图例?", "visTypeTimeseries.timeseries.optionsTab.styleLabel": "样式", + "visTypeTimeseries.timeseries.optionsTab.tooltipMode": "工具提示", "visTypeTimeseries.timeSeries.overrideIndexPatternLabel": "覆盖索引模式?", "visTypeTimeseries.timeSeries.percentLabel": "百分比", "visTypeTimeseries.timeseries.positionOptions.leftLabel": "左", @@ -3574,6 +4211,8 @@ "visTypeTimeseries.timeSeries.templateHelpText": "例如,{templateExample}", "visTypeTimeseries.timeSeries.templateLabel": "模板", "visTypeTimeseries.timeSeries.toggleSeriesEditorAriaLabel": "切换序列编辑器", + "visTypeTimeseries.timeseries.tooltipOptions.showAll": "显示所有值", + "visTypeTimeseries.timeseries.tooltipOptions.showFocused": "显示聚焦值", "visTypeTimeseries.topHit.aggregateWith.selectPlaceholder": "选择......", "visTypeTimeseries.topHit.aggregateWithLabel": "聚合对象", "visTypeTimeseries.topHit.aggregationLabel": "聚合", @@ -3615,6 +4254,7 @@ "visTypeTimeseries.unsupportedAgg.aggIsNotSupportedDescription": "不再支持 {modelType} 聚合。", "visTypeTimeseries.unsupportedAgg.aggIsTemporaryUnsupportedDescription": "当前不支持 {modelType} 聚合。", "visTypeTimeseries.unsupportedSplit.splitIsUnsupportedDescription": "不支持拆分依据 {modelType}。", + "visTypeTimeseries.validateInterval.notifier.maxBucketsExceededErrorMessage": "您的查询尝试提取过多的数据。缩短时间范围或更改所用的时间间隔通常可解决问题。", "visTypeTimeseries.vars.variableNameAriaLabel": "变量名称", "visTypeTimeseries.vars.variableNamePlaceholder": "变量名称", "visTypeTimeseries.visEditorVisualization.applyChangesLabel": "应用更改", @@ -3683,6 +4323,10 @@ "visTypeVega.visualization.renderErrorTitle": "Vega 错误", "visTypeVega.visualization.unableToFindDefaultIndexErrorMessage": "找不到默认索引", "visTypeVega.visualization.unableToRenderWithoutDataWarningMessage": "没有数据时无法渲染", + "visTypeVislib.advancedSettings.visualization.dimmingOpacityText": "突出显示图表的其他元素时变暗图表项的透明度。此数字越低,突出显示的元素越突出。必须是介于 0 和 1 之间的数字。", + "visTypeVislib.advancedSettings.visualization.dimmingOpacityTitle": "变暗透明度", + "visTypeVislib.advancedSettings.visualization.heatmap.maxBucketsText": "单个数据源可以返回的最大存储桶数目。较高的数目可能对浏览器呈现性能有负面影响", + "visTypeVislib.advancedSettings.visualization.heatmap.maxBucketsTitle": "热图最大存储桶数", "visTypeVislib.aggResponse.allDocsTitle": "所有文档", "visTypeVislib.area.areaDescription": "突出折线图下方的数量", "visTypeVislib.area.areaTitle": "面积图", @@ -3864,6 +4508,8 @@ "visTypeVislib.vislib.legend.toggleOptionsButtonAriaLabel": "{legendDataLabel}, 切换选项", "visTypeVislib.vislib.tooltip.fieldLabel": "字段", "visTypeVislib.vislib.tooltip.valueLabel": "值", + "visualizations.advancedSettings.visualizeEnableLabsText": "允许用户创建、查看和编辑实验性可视化。如果禁用,\n 仅被视为生产就绪的可视化可供用户使用。", + "visualizations.advancedSettings.visualizeEnableLabsTitle": "启用实验性可视化", "visualizations.disabledLabVisualizationMessage": "请在高级设置中打开实验室模式,以查看实验室可视化。", "visualizations.disabledLabVisualizationTitle": "{title} 为实验室可视化。", "visualizations.displayName": "可视化", @@ -3876,6 +4522,7 @@ "visualizations.function.visDimension.formatParams.help": "格式参数", "visualizations.function.visDimension.help": "生成 visConfig 维度对象", "visualizations.functions.visualization.help": "简单可视化", + "visualizations.initializeWithoutIndexPatternErrorMessage": "正在尝试在不使用索引模式的情况下初始化聚合", "visualizations.newVisWizard.betaDescription": "此可视化为公测版,可能会进行更改。设计和代码相对于正式发行版功能还不够成熟,将按原样提供,且不提供任何保证。公测版功能不受正式发行版功能支持 SLA 的约束", "visualizations.newVisWizard.betaTitle": "公测版", "visualizations.newVisWizard.chooseSourceTitle": "选择源", @@ -3895,11 +4542,15 @@ "visualizations.newVisWizard.visTypeAliasDescription": "打开 Visualize 外部的 Kibana 应用程序。", "visualizations.newVisWizard.visTypeAliasTitle": "Kibana 应用程序", "visualizations.savedObjectName": "可视化", + "visualizations.visualizationTypeInvalidMessage": "无效的可视化类型“{visType}”", "visualize.badge.readOnly.text": "只读", "visualize.badge.readOnly.tooltip": "无法保存可视化", + "visualize.createVisualization.failedToLoadErrorMessage": "无法加载可视化", "visualize.createVisualization.noIndexPatternOrSavedSearchIdErrorMessage": "必须提供 indexPattern 或 savedSearchId", + "visualize.createVisualization.noVisTypeErrorMessage": "必须提供有效的可视化类型", "visualize.editor.createBreadcrumb": "创建", - "visualize.experimentalVisInfoText": "此可视化标记为“实验性”。", + "visualize.error.title": "可视化错误", + "visualize.experimentalVisInfoText": "此可视化标记为“实验性”。想反馈?请在以下位置创建问题:", "visualize.helpMenu.appName": "Visualize", "visualize.linkedToSearch.unlinkSuccessNotificationText": "已取消与已保存搜索“{searchTitle}”的链接", "visualize.listing.betaTitle": "公测版", @@ -3916,6 +4567,9 @@ "visualize.listing.table.listTitle": "可视化", "visualize.listing.table.titleColumnName": "标题", "visualize.listing.table.typeColumnName": "类型", + "visualize.listingPageTitle": "可视化", + "visualize.noMatchRoute.bannerText": "Visualize 应用程序无法识别此路由:{route}。", + "visualize.noMatchRoute.bannerTitleText": "未找到页面", "visualize.pageHeading": "{chartName} {chartType} 可视化", "visualize.topNavMenu.openInspectorButtonAriaLabel": "打开检查器查看可视化", "visualize.topNavMenu.openInspectorButtonLabel": "检查", @@ -3931,6 +4585,7 @@ "visualize.topNavMenu.saveVisualizationDisabledButtonTooltip": "保存前应用或放弃所做更改", "visualize.topNavMenu.shareVisualizationButtonAriaLabel": "共享可视化", "visualize.topNavMenu.shareVisualizationButtonLabel": "共享", + "visualize.visualizationLoadingFailedErrorMessage": "无法加载可视化", "visualize.visualizeDescription": "创建可视化并聚合在 Elasticsearch 索引中的数据存储。", "visualize.visualizeListingBreadcrumbsTitle": "Visualize", "visualize.visualizeListingDeleteErrorTitle": "删除可视化时出错", @@ -3945,6 +4600,8 @@ "xpack.actions.builtin.case.configuration.emptyMapping": "[casesConfiguration.mapping]:应为非空,但却为空", "xpack.actions.builtin.case.connectorApiNullError": "需要指定连接器 [apiUrl]", "xpack.actions.builtin.case.jiraTitle": "Jira", + "xpack.actions.builtin.case.resilientTitle": "IBM Resilient", + "xpack.actions.builtin.configuration.apiWhitelistError": "配置连接器操作时出错:{message}", "xpack.actions.builtin.email.errorSendingErrorMessage": "发送电子邮件时出错", "xpack.actions.builtin.emailTitle": "电子邮件", "xpack.actions.builtin.esIndex.errorIndexingErrorMessage": "索引文档时出错", @@ -3958,6 +4615,8 @@ "xpack.actions.builtin.pagerdutyTitle": "PagerDuty", "xpack.actions.builtin.serverLog.errorLoggingErrorMessage": "记录消息时出错", "xpack.actions.builtin.serverLogTitle": "服务器日志", + "xpack.actions.builtin.servicenow.configuration.emptyMapping": "[incidentConfiguration.mapping]:应为非空,但却为空", + "xpack.actions.builtin.servicenowTitle": "ServiceNow", "xpack.actions.builtin.slack.errorPostingErrorMessage": "发布 slack 消息时出错", "xpack.actions.builtin.slack.errorPostingRetryDateErrorMessage": "发布 slack 消息时出错,在 {retryString} 重试", "xpack.actions.builtin.slack.errorPostingRetryLaterErrorMessage": "发布 slack 消息时出错,稍后重试", @@ -3972,6 +4631,7 @@ "xpack.actions.builtin.webhook.invalidUsernamePassword": "必须指定用户及密码", "xpack.actions.builtin.webhook.unreachableErrorMessage": "调用时 webhook 出错,非预期错误", "xpack.actions.builtin.webhook.webhookConfigurationError": "配置 Webhook 操作时出错:{message}", + "xpack.actions.builtin.webhook.webhookConfigurationErrorNoHostname": "配置 Webhook 操作时出错:无法解析 url:{err}", "xpack.actions.builtin.webhookTitle": "Webhook", "xpack.actions.disabledActionTypeError": "操作类型“{actionType}”在 Kibana 配置 xpack.actions.enabledActionTypes 中未启用", "xpack.actions.serverSideErrors.expirerdLicenseErrorMessage": "操作类型 {actionTypeId} 已禁用,因为您的{licenseType}许可证已过期。", @@ -4005,6 +4665,17 @@ "xpack.alertingBuiltins.indexThreshold.maxIntervalsErrorMessage": "时间间隔 {intervals} 的计算数目大于最大值 {maxIntervals}", "xpack.alertingBuiltins.indexThreshold.termFieldRequiredErrorMessage": "[termField]:[groupBy] 为 top 时,必需 termField", "xpack.alertingBuiltins.indexThreshold.termSizeRequiredErrorMessage": "[termSize]:[groupBy] 为 top 时,必需 termSize", + "xpack.alerts.alertNavigationRegistry.get.missingNavigationError": "在“{consumer}”内针对告警类型“{alertType}”的导航未注册。", + "xpack.alerts.alertNavigationRegistry.register.duplicateDefaultError": "“{consumer}”内的默认导航已注册。", + "xpack.alerts.alertNavigationRegistry.register.duplicateNavigationError": "在“{consumer}”内针对告警类型“{alertType}”的导航已注册。", + "xpack.alerts.alertsClient.validateActions.invalidGroups": "无效操作组:{groups}", + "xpack.alerts.alertTypeRegistry.get.missingAlertTypeError": "未注册告警类型“{id}”。", + "xpack.alerts.alertTypeRegistry.register.duplicateAlertTypeError": "已注册告警类型“{id}”。", + "xpack.alerts.api.error.disabledApiKeys": "Alerting 依赖的 API 密钥似乎已禁用", + "xpack.alerts.appName": "告警", + "xpack.alerts.loadAlertType.missingAlertTypeError": "未注册告警类型“{id}”。", + "xpack.alerts.serverSideErrors.unavailableLicenseInformationErrorMessage": "告警不可用 - 许可信息当前不可用。", + "xpack.apm.addDataButtonLabel": "添加数据", "xpack.apm.agentConfig.allOptionLabel": "全部", "xpack.apm.agentConfig.apiRequestSize.description": "通过块编码(HTTP 流)发送到 APM Server 摄入 API 的请求正文最大压缩总大小。\n注意,有可能出现小幅的过冲。\n\n允许使用的字节单位包括 `b`、`kb` 和 `mb`。`1kb` 等于 `1024b`。", "xpack.apm.agentConfig.apiRequestSize.label": "API 请求大小", @@ -4115,6 +4786,13 @@ "xpack.apm.agentMetrics.java.threadCountMax": "最大计数", "xpack.apm.alertTypes.errorRate": "错误率", "xpack.apm.alertTypes.transactionDuration": "事务持续时间", + "xpack.apm.anomalyDetection.createJobs.failed.text": "为 APM 服务环境 [{environments}] 创建一个或多个异常检测作业时出现问题。错误:“{errorMessage}”", + "xpack.apm.anomalyDetection.createJobs.failed.title": "无法创建异常检测作业", + "xpack.apm.anomalyDetection.createJobs.succeeded.text": "APM 服务环境 [{environments}] 的异常检测作业已成功创建。Machine Learning 要过一些时间才会开始分析流量以发现异常。", + "xpack.apm.anomalyDetection.createJobs.succeeded.title": "异常检测作业已创建", + "xpack.apm.anomalyDetectionSetup.linkLabel": "异常检测", + "xpack.apm.anomalyDetectionSetup.notEnabledForEnvironmentText": "还没有为“{currentEnvironment}”环境启用异常检测。单击以继续设置。", + "xpack.apm.anomalyDetectionSetup.notEnabledText": "异常检测尚未启用。单击以继续设置。", "xpack.apm.apmDescription": "自动从您的应用程序内收集深入全面的性能指标和错误。", "xpack.apm.applyFilter": "应用 {title} 筛选", "xpack.apm.applyOptions": "应用选项", @@ -4125,6 +4803,7 @@ "xpack.apm.breadcrumb.serviceMapTitle": "服务地图", "xpack.apm.breadcrumb.servicesTitle": "服务", "xpack.apm.breadcrumb.settings.agentConfigurationTitle": "代理配置", + "xpack.apm.breadcrumb.settings.anomalyDetection": "异常检测", "xpack.apm.breadcrumb.settings.createAgentConfigurationTitle": "创建代理配置", "xpack.apm.breadcrumb.settings.customizeUI": "定制 UI", "xpack.apm.breadcrumb.settings.editAgentConfigurationTitle": "编辑代理配置", @@ -4147,6 +4826,7 @@ "xpack.apm.environment.allLabel": "全部", "xpack.apm.error.prompt.body": "有关详情,请查看您的浏览器开发者控制台。", "xpack.apm.error.prompt.title": "抱歉,发生错误 :(", + "xpack.apm.errorGroupDetails.avgLabel": "平均", "xpack.apm.errorGroupDetails.culpritLabel": "原因", "xpack.apm.errorGroupDetails.errorGroupTitle": "错误组 {errorGroupId}", "xpack.apm.errorGroupDetails.errorOccurrenceTitle": "错误发生", @@ -4164,6 +4844,9 @@ "xpack.apm.errorRateAlertTrigger.environment": "环境", "xpack.apm.errorRateAlertTrigger.errors": "错误", "xpack.apm.errorRateAlertTrigger.isAbove": "高于", + "xpack.apm.errorRateChart.avgLabel": "平均", + "xpack.apm.errorRateChart.rateLabel": "比率", + "xpack.apm.errorRateChart.title": "事务错误率", "xpack.apm.errorsTable.errorMessageAndCulpritColumnLabel": "错误消息和原因", "xpack.apm.errorsTable.groupIdColumnDescription": "堆栈跟踪的哈希。将类似错误分组在一起,即使因动态参数造成错误消息不同。", "xpack.apm.errorsTable.groupIdColumnLabel": "组 ID", @@ -4190,6 +4873,8 @@ "xpack.apm.header.badge.readOnly.text": "只读", "xpack.apm.header.badge.readOnly.tooltip": "无法保存", "xpack.apm.helpMenu.upgradeAssistantLink": "升级助手", + "xpack.apm.histogram.plot.noDataLabel": "此时间范围内没有数据。", + "xpack.apm.home.rumOverview.title": "真实用户监测", "xpack.apm.home.serviceMapTabLabel": "服务地图", "xpack.apm.home.servicesTabLabel": "服务", "xpack.apm.home.tracesTabLabel": "追溯", @@ -4204,7 +4889,7 @@ "xpack.apm.jvmsTable.noJvmsLabel": "未找到任何 JVM", "xpack.apm.jvmsTable.nonHeapMemoryColumnLabel": "非堆内存平均值", "xpack.apm.jvmsTable.threadCountColumnLabel": "线程计数最大值", - "xpack.apm.kueryBar.disabledPlaceholder": "搜索不适用于服务地图", + "xpack.apm.kueryBar.disabledPlaceholder": "搜索在此不可用", "xpack.apm.kueryBar.placeholder": "搜索{event, select,\n transaction {事务}\n metric {指标}\n error {错误}\n other {事务、错误和指标}\n }(例如 {queryExample})", "xpack.apm.license.betaBadge": "公测版", "xpack.apm.license.betaTooltipMessage": "此功能当前为公测版。如果遇到任何错误或有任何反馈,请报告问题或访问我们的论坛。", @@ -4212,12 +4897,18 @@ "xpack.apm.license.title": "开始为期 30 天的免费试用", "xpack.apm.loadingServiceMap": "正在加载服务地图......这可能需要一会儿时间。", "xpack.apm.localFilters.titles.agentName": "代理名称", + "xpack.apm.localFilters.titles.browser": "浏览器", "xpack.apm.localFilters.titles.containerId": "容器 ID", + "xpack.apm.localFilters.titles.device": "设备", "xpack.apm.localFilters.titles.host": "主机", + "xpack.apm.localFilters.titles.location": "位置", + "xpack.apm.localFilters.titles.os": "OS", "xpack.apm.localFilters.titles.podName": "Kubernetes Pod", + "xpack.apm.localFilters.titles.serviceName": "服务名称", "xpack.apm.localFilters.titles.serviceVersion": "服务版本", "xpack.apm.localFilters.titles.transactionResult": "事务结果", "xpack.apm.localFilters.titles.transactionType": "事务类型", + "xpack.apm.localFilters.titles.transactionUrl": "URL", "xpack.apm.localFiltersTitle": "筛选", "xpack.apm.metadataTable.section.agentLabel": "代理", "xpack.apm.metadataTable.section.clientLabel": "客户端", @@ -4243,7 +4934,7 @@ "xpack.apm.metrics.pageLoadCharts.avgPageLoadByBrowser": "平均页面加载持续时间分布 - 按浏览器", "xpack.apm.metrics.plot.noDataLabel": "此时间范围内没有数据。", "xpack.apm.metrics.transactionChart.machineLearningLabel": "Machine Learning", - "xpack.apm.metrics.transactionChart.machineLearningTooltip": "环绕平均持续时间的流显示预期边界。对 >= 75 的异常分数显示标注。", + "xpack.apm.metrics.transactionChart.machineLearningTooltip": "环绕平均持续时间的流显示预期边界。对 ≥ 75 的异常分数显示标注。", "xpack.apm.metrics.transactionChart.pageLoadTimesLabel": "页面加载时间", "xpack.apm.metrics.transactionChart.requestsPerMinuteLabel": "每分钟请求数", "xpack.apm.metrics.transactionChart.routeChangeTimesLabel": "路由更改时间", @@ -4260,6 +4951,20 @@ "xpack.apm.registerErrorRateAlertType.variables.serviceName": "服务名称", "xpack.apm.registerTransactionDurationAlertType.variables.serviceName": "服务名称", "xpack.apm.registerTransactionDurationAlertType.variables.transactionType": "事务类型", + "xpack.apm.rum.dashboard.backend": "后端", + "xpack.apm.rum.dashboard.dateTime.label": "日期 / 时间", + "xpack.apm.rum.dashboard.frontend": "前端", + "xpack.apm.rum.dashboard.overall.label": "总体", + "xpack.apm.rum.dashboard.pageLoadDistribution.label": "页面加载分布", + "xpack.apm.rum.dashboard.pageLoadTime.label": "页面加载时间(秒)", + "xpack.apm.rum.dashboard.pageLoadTimes.label": "页面加载时间", + "xpack.apm.rum.dashboard.pagesLoaded.label": "已加载页面", + "xpack.apm.rum.dashboard.pageViews": "页面查看次数", + "xpack.apm.rum.dashboard.resetZoom.label": "重置缩放比例", + "xpack.apm.rum.filterGroup.breakdown": "细目", + "xpack.apm.rum.filterGroup.seconds": "秒", + "xpack.apm.rum.filterGroup.selectBreakdown": "选择细分", + "xpack.apm.rum.visitorBreakdown": "访问者细分", "xpack.apm.searchInput.filter": "筛选...", "xpack.apm.selectPlaceholder": "选择选项:", "xpack.apm.serviceDetails.alertsMenu.alerts": "告警", @@ -4274,14 +4979,23 @@ "xpack.apm.serviceDetails.metricsTabLabel": "指标", "xpack.apm.serviceDetails.nodesTabLabel": "JVM", "xpack.apm.serviceDetails.transactionsTabLabel": "事务", + "xpack.apm.serviceMap.anomalyDetectionPopoverDisabled": "通过在 APM 设置中启用异常检测来显示服务运行状况指标。", + "xpack.apm.serviceMap.anomalyDetectionPopoverLink": "查看异常", + "xpack.apm.serviceMap.anomalyDetectionPopoverNoData": "在选定时间范围内找不到异常分数。请在 Anomaly Explorer 中查看详情。", + "xpack.apm.serviceMap.anomalyDetectionPopoverScoreMetric": "分数(最大)", + "xpack.apm.serviceMap.anomalyDetectionPopoverTitle": "异常检测", + "xpack.apm.serviceMap.anomalyDetectionPopoverTooltip": "服务运行状况指示由 Machine Learning 中的异常检测功能提供", + "xpack.apm.serviceMap.avgReqPerMinutePopoverMetric": "每分钟请求数(平均)", "xpack.apm.serviceMap.betaBadge": "公测版", "xpack.apm.serviceMap.betaTooltipMessage": "此功能当前为公测版。如果遇到任何错误或有任何反馈,请报告问题或访问我们的论坛。", "xpack.apm.serviceMap.center": "中", + "xpack.apm.serviceMap.download": "下载", "xpack.apm.serviceMap.emptyBanner.docsLink": "在文档中了解详情", "xpack.apm.serviceMap.emptyBanner.message": "如果可以检测到连接的服务和外部请求,便将在地图上绘出它们。请确保运行最新版本的 APM 代理。", "xpack.apm.serviceMap.emptyBanner.title": "似乎仅有一个服务。", "xpack.apm.serviceMap.focusMapButtonText": "聚焦地图", "xpack.apm.serviceMap.invalidLicenseMessage": "要访问服务地图,必须订阅 Elastic 白金级许可证。使用该许可证,您将能够可视化整个应用程序堆栈以及 APM 数据。", + "xpack.apm.serviceMap.popoverMetrics.noDataText": "选定的环境没有数据。请尝试切换到其他环境。", "xpack.apm.serviceMap.serviceDetailsButtonText": "服务详情", "xpack.apm.serviceMap.viewFullMap": "查看完整的服务地图", "xpack.apm.serviceMap.zoomIn": "放大", @@ -4312,6 +5026,28 @@ "xpack.apm.servicesTable.UpgradeAssistantLink": "通过访问 Kibana 升级助手来了解详情", "xpack.apm.serviceVersion": "服务版本", "xpack.apm.settings.agentConfig": "代理配置", + "xpack.apm.settings.anomaly_detection.legacy_jobs.body": "我们在以前的集成中发现 APM 应用中不再使用的旧版 Machine Learning 作业", + "xpack.apm.settings.anomaly_detection.legacy_jobs.button": "复查作业", + "xpack.apm.settings.anomaly_detection.legacy_jobs.title": "旧版 ML 作业不再用于 APM 应用", + "xpack.apm.settings.anomaly_detection.license.text": "要使用异常检测,必须订阅 Elastic 白金级许可。使用该许可,您将能够借助 Machine Learning 监测服务。", + "xpack.apm.settings.anomalyDetection": "异常检测", + "xpack.apm.settings.anomalyDetection.addEnvironments.cancelButtonText": "取消", + "xpack.apm.settings.anomalyDetection.addEnvironments.createJobsButtonText": "创建作业", + "xpack.apm.settings.anomalyDetection.addEnvironments.descriptionText": "选择要启用异常检测的服务环境。选定环境内所有服务和事务类型的异常将会浮现。", + "xpack.apm.settings.anomalyDetection.addEnvironments.selectorLabel": "环境", + "xpack.apm.settings.anomalyDetection.addEnvironments.selectorPlaceholder": "选择或添加环境", + "xpack.apm.settings.anomalyDetection.addEnvironments.titleText": "选择环境", + "xpack.apm.settings.anomalyDetection.descriptionText": "Machine Learning 异常检测集成通过识别事务持续时间异常来在服务地图中为每个已配置环境提供应用程序运行状况状态指标。", + "xpack.apm.settings.anomalyDetection.jobList.actionColumnLabel": "操作", + "xpack.apm.settings.anomalyDetection.jobList.addEnvironments": "创建 ML 作业", + "xpack.apm.settings.anomalyDetection.jobList.emptyListText": "无异常检测作业。", + "xpack.apm.settings.anomalyDetection.jobList.environmentColumnLabel": "环境", + "xpack.apm.settings.anomalyDetection.jobList.environments": "环境", + "xpack.apm.settings.anomalyDetection.jobList.failedFetchText": "无法提取异常检测作业。", + "xpack.apm.settings.anomalyDetection.jobList.mlDescriptionText": "要将异常检测添加到新环境,请创建 Machine Learning 作业。现有 Machine Learning 作业可在 {mlJobsLink} 中进行管理。", + "xpack.apm.settings.anomalyDetection.jobList.mlDescriptionText.mlJobsLinkText": "Machine Learning", + "xpack.apm.settings.anomalyDetection.jobList.mlJobLinkText": "在 ML 中查看作业", + "xpack.apm.settings.anomalyDetection.titleText": "异常检测", "xpack.apm.settings.apmIndices.applyButton": "应用更改", "xpack.apm.settings.apmIndices.applyChanges.failed.text": "应用索引时出现问题。错误:{errorMessage}", "xpack.apm.settings.apmIndices.applyChanges.failed.title": "无法应用索引。", @@ -4418,6 +5154,9 @@ "xpack.apm.transactionActionMenu.viewSampleDocumentLinkLabel": "查看样例文档", "xpack.apm.transactionBreakdown.chartTitle": "跨度类型花费的时间", "xpack.apm.transactionBreakdown.noData": "此时间范围内没有数据。", + "xpack.apm.transactionCardinalityWarning.body": "唯一事务名称的数目超过 {bucketSize} 的已配置值。尝试重新配置您的代理以对类似的事务分组或增大 {codeBlock} 的值", + "xpack.apm.transactionCardinalityWarning.docsLink": "在文档中了解详情", + "xpack.apm.transactionCardinalityWarning.title": "此视图显示已报告事务的子集。", "xpack.apm.transactionDetails.errorCount": "{errorCount, number} 个 {errorCount, plural, one {错误} other {错误}}", "xpack.apm.transactionDetails.errorsOverviewLinkTooltip": "{errorCount, plural, one {查看 1 个相关错误} other {查看 # 个相关错误}}", "xpack.apm.transactionDetails.notFoundLabel": "未找到任何事务。", @@ -4549,7 +5288,7 @@ "xpack.beatsManagement.breadcrumb.beatTags": "{beatId} 的 Beat 标记", "xpack.beatsManagement.breadcrumb.configurationTags": "配置标记", "xpack.beatsManagement.breadcrumb.enrolledBeats": "已注册 Beats", - "xpack.beatsManagement.centralManagementLinkLabel": "集中管理", + "xpack.beatsManagement.centralManagementLinkLabel": "Beats 集中管理", "xpack.beatsManagement.config.other.error": "使用有效的 YAML 格式", "xpack.beatsManagement.config.otherConfigDescription": "使用 YAML 格式指定 Filebeat 输入的其他设置", "xpack.beatsManagement.config.otherConfigLabel": "其他配置", @@ -5195,10 +5934,25 @@ "xpack.canvas.keyboardShortcutsDoc.flyout.closeButtonAriaLabel": "关闭快捷键参考", "xpack.canvas.keyboardShortcutsDoc.flyoutHeaderTitle": "快捷键", "xpack.canvas.keyboardShortcutsDoc.shortcutListSeparator": "或", + "xpack.canvas.lib.palettes.canvasLabel": "{CANVAS}", + "xpack.canvas.lib.palettes.colorBlindLabel": "色盲", + "xpack.canvas.lib.palettes.earthTonesLabel": "泥土色调", + "xpack.canvas.lib.palettes.elasticBlueLabel": "Elastic 蓝", + "xpack.canvas.lib.palettes.elasticGreenLabel": "Elastic 绿", + "xpack.canvas.lib.palettes.elasticOrangeLabel": "Elastic 橙", + "xpack.canvas.lib.palettes.elasticPinkLabel": "Elastic 粉", + "xpack.canvas.lib.palettes.elasticPurpleLabel": "Elastic 紫", + "xpack.canvas.lib.palettes.elasticTealLabel": "Elastic 蓝绿", + "xpack.canvas.lib.palettes.elasticYellowLabel": "Elastic 黄", + "xpack.canvas.lib.palettes.greenBlueRedLabel": "绿、蓝、红", + "xpack.canvas.lib.palettes.instagramLabel": "{INSTAGRAM}", + "xpack.canvas.lib.palettes.yellowBlueLabel": "黄、蓝", + "xpack.canvas.lib.palettes.yellowGreenLabel": "黄、绿", + "xpack.canvas.lib.palettes.yellowRedLabel": "黄、红", "xpack.canvas.link.errorMessage": "链接错误:{message}", "xpack.canvas.pageConfig.backgroundColorDescription": "接受 HEX、RGB 或 HTML 颜色名称", "xpack.canvas.pageConfig.backgroundColorLabel": "背景", - "xpack.canvas.pageConfig.title": "页面样式", + "xpack.canvas.pageConfig.title": "页面设置", "xpack.canvas.pageConfig.transitionLabel": "切换", "xpack.canvas.pageConfig.transitionPreviewLabel": "预览", "xpack.canvas.pageConfig.transitions.noneDropDownOptionLabel": "无", @@ -5207,6 +5961,8 @@ "xpack.canvas.pagePreviewPageControls.clonePageTooltip": "克隆", "xpack.canvas.pagePreviewPageControls.deletePageAriaLabel": "删除页面", "xpack.canvas.pagePreviewPageControls.deletePageTooltip": "删除", + "xpack.canvas.palettePicker.emptyPaletteLabel": "无", + "xpack.canvas.palettePicker.noPaletteFoundErrorTitle": "未找到调色板", "xpack.canvas.renderer.advancedFilter.applyButtonLabel": "应用", "xpack.canvas.renderer.advancedFilter.displayName": "高级筛选", "xpack.canvas.renderer.advancedFilter.helpDescription": "呈现 Canvas 筛选表达式", @@ -5330,6 +6086,7 @@ "xpack.canvas.uis.arguments.axisConfigDisabledText": "打开以查看坐标轴设置", "xpack.canvas.uis.arguments.axisConfigLabel": "可视化轴配置", "xpack.canvas.uis.arguments.axisConfigTitle": "轴配置", + "xpack.canvas.uis.arguments.customPaletteLabel": "定制", "xpack.canvas.uis.arguments.dataColumn.options.averageDropDown": "平均值", "xpack.canvas.uis.arguments.dataColumn.options.countDropDown": "计数", "xpack.canvas.uis.arguments.dataColumn.options.firstDropDown": "第一", @@ -5366,7 +6123,7 @@ "xpack.canvas.uis.arguments.numberFormatTitle": "数字格式", "xpack.canvas.uis.arguments.numberLabel": "输入数字", "xpack.canvas.uis.arguments.numberTitle": "数字", - "xpack.canvas.uis.arguments.paletteLabel": "选择调色板", + "xpack.canvas.uis.arguments.paletteLabel": "用于呈现元素的颜色集合", "xpack.canvas.uis.arguments.paletteTitle": "调色板", "xpack.canvas.uis.arguments.percentageLabel": "百分比滑块 ", "xpack.canvas.uis.arguments.percentageTitle": "百分比", @@ -5574,6 +6331,38 @@ "xpack.canvas.units.time.hours": "{hours, plural, one {# 小时} other {# 小时}}", "xpack.canvas.units.time.minutes": "{minutes, plural, one {# 分钟} other {# 分钟}}", "xpack.canvas.units.time.seconds": "{seconds, plural, one {# 秒} other {# 秒}}", + "xpack.canvas.varConfig.addButtonLabel": "添加变量", + "xpack.canvas.varConfig.addTooltipLabel": "添加变量", + "xpack.canvas.varConfig.copyActionButtonLabel": "复制代码片段", + "xpack.canvas.varConfig.copyActionTooltipLabel": "将变量语法复制到剪贴板", + "xpack.canvas.varConfig.copyNotificationDescription": "变量语法已复制到剪贴板", + "xpack.canvas.varConfig.deleteActionButtonLabel": "删除变量", + "xpack.canvas.varConfig.deleteNotificationDescription": "变量已成功删除", + "xpack.canvas.varConfig.editActionButtonLabel": "编辑变量", + "xpack.canvas.varConfig.emptyDescription": "此 Workpad 当前没有变量。您可以添加变量以存储和编辑公用值。这样,便可以在元素中或表达式编辑器中使用这些变量。", + "xpack.canvas.varConfig.tableNameLabel": "名称", + "xpack.canvas.varConfig.tableTypeLabel": "类型", + "xpack.canvas.varConfig.tableValueLabel": "值", + "xpack.canvas.varConfig.titleLabel": "变量", + "xpack.canvas.varConfig.titleTooltip": "添加变量以存储和编辑公用值", + "xpack.canvas.varConfigDeleteVar.cancelButtonLabel": "取消", + "xpack.canvas.varConfigDeleteVar.deleteButtonLabel": "删除变量", + "xpack.canvas.varConfigDeleteVar.titleLabel": "删除变量?", + "xpack.canvas.varConfigDeleteVar.warningDescription": "删除此变量可能对 Workpad 造成不良影响。是否确定要继续?", + "xpack.canvas.varConfigEditVar.addTitleLabel": "添加变量", + "xpack.canvas.varConfigEditVar.cancelButtonLabel": "取消", + "xpack.canvas.varConfigEditVar.duplicateNameError": "变量名称已被使用", + "xpack.canvas.varConfigEditVar.editTitleLabel": "编辑变量", + "xpack.canvas.varConfigEditVar.editWarning": "编辑在用的变量可能对 Workpad 造成不良影响", + "xpack.canvas.varConfigEditVar.nameFieldLabel": "名称", + "xpack.canvas.varConfigEditVar.saveButtonLabel": "保存更改", + "xpack.canvas.varConfigEditVar.typeBooleanLabel": "布尔", + "xpack.canvas.varConfigEditVar.typeFieldLabel": "类型", + "xpack.canvas.varConfigEditVar.typeNumberLabel": "数字", + "xpack.canvas.varConfigEditVar.typeStringLabel": "字符串", + "xpack.canvas.varConfigEditVar.valueFieldLabel": "值", + "xpack.canvas.varConfigVarValueField.falseOption": "False", + "xpack.canvas.varConfigVarValueField.trueOption": "True", "xpack.canvas.workpadConfig.applyStylesheetButtonLabel": "应用样式表", "xpack.canvas.workpadConfig.backgroundColorLabel": "背景色", "xpack.canvas.workpadConfig.globalCSSLabel": "全局 CSS 覆盖", @@ -5710,10 +6499,12 @@ "xpack.canvas.workpadManager.workpadTemplatesTabLabel": "模板", "xpack.canvas.workpadSearch.searchPlaceholder": "查找 Workpad", "xpack.canvas.workpadTemplate.cloneTemplateLinkAriaLabel": "克隆 Workpad 模板“{templateName}”", + "xpack.canvas.workpadTemplate.creatingTemplateLabel": "正在从模板“{templateName}”创建", "xpack.canvas.workpadTemplate.searchPlaceholder": "查找模板", "xpack.canvas.workpadTemplates.table.descriptionColumnTitle": "描述", "xpack.canvas.workpadTemplates.table.nameColumnTitle": "模板名称", "xpack.canvas.workpadTemplates.table.tagsColumnTitle": "标记", + "xpack.cloud.deploymentLinkLabel": "管理此部署", "xpack.crossClusterReplication.addAutoFollowPatternButtonLabel": "创建自动跟随模式", "xpack.crossClusterReplication.addBreadcrumbTitle": "添加", "xpack.crossClusterReplication.addFollowerButtonLabel": "创建 Follower 索引", @@ -6052,6 +6843,73 @@ "xpack.data.kueryAutocomplete.orOperatorDescription.oneOrMoreArgumentsText": "一个或多个参数", "xpack.data.query.queryBar.cancelLongQuery": "取消", "xpack.data.query.queryBar.runBeyond": "运行超时", + "xpack.discover.FlyoutCreateDrilldownAction.displayName": "浏览底层数据", + "xpack.embeddableEnhanced.actions.panelNotifications.manyDrilldowns": "面板有 {count} 个向下钻取", + "xpack.embeddableEnhanced.actions.panelNotifications.oneDrilldown": "面板有 1 个向下钻取", + "xpack.enterpriseSearch.appSearch.emptyState.createFirstEngineCta": "创建引擎", + "xpack.enterpriseSearch.appSearch.emptyState.description1": "App Search 引擎存储文档以提升您的搜索体验。", + "xpack.enterpriseSearch.appSearch.emptyState.title": "创建您的首个引擎", + "xpack.enterpriseSearch.appSearch.enginesOverview.engines": "引擎", + "xpack.enterpriseSearch.appSearch.enginesOverview.metaEngines": "元引擎", + "xpack.enterpriseSearch.appSearch.enginesOverview.table.action.manage": "管理", + "xpack.enterpriseSearch.appSearch.enginesOverview.table.column.actions": "操作", + "xpack.enterpriseSearch.appSearch.enginesOverview.table.column.createdAt": "创建于", + "xpack.enterpriseSearch.appSearch.enginesOverview.table.column.documentCount": "文档计数", + "xpack.enterpriseSearch.appSearch.enginesOverview.table.column.fieldCount": "字段计数", + "xpack.enterpriseSearch.appSearch.enginesOverview.table.column.name": "名称", + "xpack.enterpriseSearch.appSearch.enginesOverview.title": "引擎概览", + "xpack.enterpriseSearch.appSearch.productCta": "启动 App Search", + "xpack.enterpriseSearch.appSearch.productName": "App Search", + "xpack.enterpriseSearch.appSearch.setupGuide.description": "Elastic App Search 提供的工具用于设计强大的搜索并将其部署到您的网站和移动应用程序。", + "xpack.enterpriseSearch.appSearch.setupGuide.notConfigured": "App Search 在您的 Kibana 实例中尚未得到配置。", + "xpack.enterpriseSearch.appSearch.setupGuide.videoAlt": "App Search 入门 - 在此视频中,我们将指导您如何开始使用 App Search", + "xpack.enterpriseSearch.errorConnectingState.description1": "我们无法与以下主机 URL 的企业搜索建立连接:{enterpriseSearchUrl}", + "xpack.enterpriseSearch.errorConnectingState.description2": "确保在 {configFile} 中已正确配置主机 URL。", + "xpack.enterpriseSearch.errorConnectingState.description3": "确认企业搜索服务器响应。", + "xpack.enterpriseSearch.errorConnectingState.description4": "阅读设置指南或查看服务器日志中的 {pluginLog} 日志消息。", + "xpack.enterpriseSearch.errorConnectingState.setupGuideCta": "阅读设置指南", + "xpack.enterpriseSearch.errorConnectingState.title": "无法连接", + "xpack.enterpriseSearch.setupGuide.step1.instruction1": "在 {configFile} 文件中,将 {configSetting} 设置为 {productName} 实例的 URL。例如:", + "xpack.enterpriseSearch.setupGuide.step1.title": "将 {productName} 主机 URL 添加到 Kibana 配置", + "xpack.enterpriseSearch.setupGuide.step2.instruction1": "重新启动 Kibana 以应用上一步骤中的配置更改。", + "xpack.enterpriseSearch.setupGuide.step2.instruction2": "如果正在 {productName} 中使用 {elasticsearchNativeAuthLink},则全部就绪。您的用户现在可以使用自己当前的 {productName} 访问权限在 Kibana 中访问 {productName}。", + "xpack.enterpriseSearch.setupGuide.step2.title": "重新加载 Kibana 实例", + "xpack.enterpriseSearch.setupGuide.step3.title": "解决问题", + "xpack.enterpriseSearch.setupGuide.title": "设置指南", + "xpack.enterpriseSearch.troubleshooting.differentAuth.description": "此插件当前不支持使用不同身份验证方法的 {productName} 和 Kibana,例如 {productName} 使用与 Kibana 不同的 SAML 提供程序。", + "xpack.enterpriseSearch.troubleshooting.differentAuth.title": "{productName} 和 Kibana 使用不同的身份验证方法", + "xpack.enterpriseSearch.troubleshooting.differentEsClusters.description": "此插件当前不支持在不同集群中运行的 {productName} 和 Kibana。", + "xpack.enterpriseSearch.troubleshooting.differentEsClusters.title": "{productName} 和 Kibana 在不同的 Elasticsearch 集群中", + "xpack.enterpriseSearch.troubleshooting.standardAuth.description": "此插件不完全支持使用 {standardAuthLink} 的 {productName}。{productName} 中创建的用户必须具有 Kibana 访问权限。Kibana 中创建的用户在导航菜单中将看不到 {productName}。", + "xpack.enterpriseSearch.troubleshooting.standardAuth.title": "不支持使用标准身份验证的 {productName}", + "xpack.enterpriseSearch.workplaceSearch.activityFeedEmptyDefault.title": "您的组织最近无活动", + "xpack.enterpriseSearch.workplaceSearch.activityFeedNamedDefault.title": "{name} 最近无活动", + "xpack.enterpriseSearch.workplaceSearch.organizationStats.activeUsers": "活动用户", + "xpack.enterpriseSearch.workplaceSearch.organizationStats.invitations": "邀请", + "xpack.enterpriseSearch.workplaceSearch.organizationStats.privateSources": "专用源", + "xpack.enterpriseSearch.workplaceSearch.organizationStats.sharedSources": "共享源", + "xpack.enterpriseSearch.workplaceSearch.organizationStats.title": "使用统计", + "xpack.enterpriseSearch.workplaceSearch.orgNameOnboarding.buttonLabel": "命名您的组织", + "xpack.enterpriseSearch.workplaceSearch.orgNameOnboarding.description": "在邀请同事之前,请命名您的组织以提升辨识度。", + "xpack.enterpriseSearch.workplaceSearch.overviewHeader.description": "您的组织的统计信息和活动", + "xpack.enterpriseSearch.workplaceSearch.overviewHeader.title": "组织概览", + "xpack.enterpriseSearch.workplaceSearch.overviewOnboardingHeader.description": "完成以下配置以设置您的组织。", + "xpack.enterpriseSearch.workplaceSearch.overviewOnboardingHeader.title": "开始使用 Workplace Search", + "xpack.enterpriseSearch.workplaceSearch.overviewOnboardingSourcesCard.description": "添加共享源,以便您的组织可以开始搜索。", + "xpack.enterpriseSearch.workplaceSearch.overviewOnboardingSourcesCard.title": "共享源", + "xpack.enterpriseSearch.workplaceSearch.overviewOnboardingUsersCard.description": "邀请同事加入此组织以便一同搜索。", + "xpack.enterpriseSearch.workplaceSearch.overviewOnboardingUsersCard.title": "用户和邀请", + "xpack.enterpriseSearch.workplaceSearch.overviewUsersCard.title": "很好,您已邀请同事一同搜索。", + "xpack.enterpriseSearch.workplaceSearch.productCta": "启动 Workplace Search", + "xpack.enterpriseSearch.workplaceSearch.productName": "Workplace Search", + "xpack.enterpriseSearch.workplaceSearch.recentActivity.title": "最近活动", + "xpack.enterpriseSearch.workplaceSearch.recentActivitySourceLink.linkLabel": "查看源", + "xpack.enterpriseSearch.workplaceSearch.setupGuide.description": "Elastic Workplace Search 将您的内容平台(Google 云端硬盘、Salesforce)整合到个性化的搜索体验中。", + "xpack.enterpriseSearch.workplaceSearch.setupGuide.imageAlt": "Workplace Search 入门 - 指导您如何开始使用 Workplace Search 的指南", + "xpack.enterpriseSearch.workplaceSearch.setupGuide.notConfigured": "Workplace Search 在 Kibana 中未配置。请按照本页上的说明执行操作。", + "xpack.enterpriseSearch.workplaceSearch.sourcesOnboardingCard.buttonLabel": "添加 {label} 源", + "xpack.enterpriseSearch.workplaceSearch.sourcesOnboardingCard.description": "您已添加 {sourcesCount, number} 个共享{sourcesCount, plural, one {源} other {源}}。祝您搜索愉快。", + "xpack.enterpriseSearch.workplaceSearch.usersOnboardingCard.buttonLabel": "邀请 {label} 用户", "xpack.features.advancedSettingsFeatureName": "高级设置", "xpack.features.dashboardFeatureName": "仪表板", "xpack.features.devToolsFeatureName": "开发工具", @@ -6119,6 +6977,7 @@ "xpack.fileUpload.jsonUploadAndParse.writingToIndex": "正在写入索引", "xpack.fileUpload.noIndexSuppliedErrorMessage": "未提供任何索引。", "xpack.fileUpload.patternReader.featuresOmitted": "不具有几何形状的一些特征已省略", + "xpack.globalSearch.find.invalidLicenseError": "GlobalSearch API 已禁用,因为许可状态无效:{errorMessage}", "xpack.graph.badge.readOnly.text": "只读", "xpack.graph.badge.readOnly.tooltip": "无法保存 Graph 工作空间", "xpack.graph.bar.exploreLabel": "Graph", @@ -6238,6 +7097,7 @@ "xpack.graph.outlinkEncoders.textLuceneTitle": "Lucene 转义文本", "xpack.graph.outlinkEncoders.textPlainDescription": "所选顶点标签的文本,采用纯 URL 编码的字符串形式", "xpack.graph.outlinkEncoders.textPlainTitle": "纯文本", + "xpack.graph.pageTitle": "图表", "xpack.graph.pluginDescription": "显示并分析 Elasticsearch 数据中的相关关系。", "xpack.graph.sampleData.label": "图表", "xpack.graph.savedWorkspace.workspaceNameTitle": "新建 Graph 工作空间", @@ -6308,6 +7168,7 @@ "xpack.graph.sidebar.selectionsTitle": "选择的内容", "xpack.graph.sidebar.styleVerticesTitle": "样式选择的顶点", "xpack.graph.sidebar.topMenu.addLinksButtonTooltip": "在现有字词之间添加链接", + "xpack.graph.sidebar.topMenu.blocklistButtonTooltip": "阻止选择显示在工作空间中", "xpack.graph.sidebar.topMenu.customStyleButtonTooltip": "定制样式选择的顶点", "xpack.graph.sidebar.topMenu.drillDownButtonTooltip": "向下钻取", "xpack.graph.sidebar.topMenu.expandSelectionButtonTooltip": "展开选择内容", @@ -6358,6 +7219,7 @@ "xpack.grokDebugger.simulateButtonLabel": "模拟", "xpack.grokDebugger.structuredDataLabel": "结构化数据", "xpack.grokDebugger.trialLicenseTitle": "试用", + "xpack.idxMgmt.aliasesTab.noAliasesTitle": "未定义任何别名。", "xpack.idxMgmt.appTitle": "索引管理", "xpack.idxMgmt.badgeAriaLabel": "{label}。选择以基于此选项进行筛选。", "xpack.idxMgmt.breadcrumb.cloneTemplateLabel": "克隆模板", @@ -6367,9 +7229,157 @@ "xpack.idxMgmt.breadcrumb.templatesLabel": "模板", "xpack.idxMgmt.clearCacheIndicesAction.successMessage": "已成功清除缓存:[{indexNames}]", "xpack.idxMgmt.closeIndicesAction.successfullyClosedIndicesMessage": "已成功关闭:[{indexNames}]", + "xpack.idxMgmt.componentTemplate.breadcrumb.componentTemplatesLabel": "组件模板", + "xpack.idxMgmt.componentTemplate.breadcrumb.createComponentTemplateLabel": "创建组件模板", + "xpack.idxMgmt.componentTemplate.breadcrumb.editComponentTemplateLabel": "编辑组件模板", + "xpack.idxMgmt.componentTemplate.breadcrumb.homeLabel": "索引管理", + "xpack.idxMgmt.componentTemplateClone.loadComponentTemplateTitle": "加载组件模板“{sourceComponentTemplateName}”时出错。", + "xpack.idxMgmt.componentTemplateDetails.aliasesTabTitle": "别名", + "xpack.idxMgmt.componentTemplateDetails.cloneActionLabel": "克隆", + "xpack.idxMgmt.componentTemplateDetails.closeButtonLabel": "关闭", + "xpack.idxMgmt.componentTemplateDetails.deleteButtonLabel": "删除", + "xpack.idxMgmt.componentTemplateDetails.editButtonLabel": "编辑", + "xpack.idxMgmt.componentTemplateDetails.loadingErrorMessage": "加载组件模板时出错", + "xpack.idxMgmt.componentTemplateDetails.loadingIndexTemplateDescription": "正在加载组件模板……", + "xpack.idxMgmt.componentTemplateDetails.manageButtonDisabledTooltipLabel": "模板正在使用中,无法删除", + "xpack.idxMgmt.componentTemplateDetails.manageButtonLabel": "管理", + "xpack.idxMgmt.componentTemplateDetails.manageContextMenuPanelTitle": "选项", + "xpack.idxMgmt.componentTemplateDetails.managedBadgeLabel": "托管", + "xpack.idxMgmt.componentTemplateDetails.mappingsTabTitle": "映射", + "xpack.idxMgmt.componentTemplateDetails.settingsTabTitle": "设置", + "xpack.idxMgmt.componentTemplateDetails.summaryTab.createTemplateLink": "创建", + "xpack.idxMgmt.componentTemplateDetails.summaryTab.metaDescriptionListTitle": "元数据", + "xpack.idxMgmt.componentTemplateDetails.summaryTab.notInUseDescription": "{createLink}搜索模板或{editLink}现有搜索模板。", + "xpack.idxMgmt.componentTemplateDetails.summaryTab.notInUseTitle": "没有任何索引模板使用此组件模板。", + "xpack.idxMgmt.componentTemplateDetails.summaryTab.updateTemplateLink": "更新", + "xpack.idxMgmt.componentTemplateDetails.summaryTab.usedByDescriptionListTitle": "使用者", + "xpack.idxMgmt.componentTemplateDetails.summaryTab.versionDescriptionListTitle": "版本", + "xpack.idxMgmt.componentTemplateDetails.summaryTabTitle": "摘要", + "xpack.idxMgmt.componentTemplateEdit.editPageTitle": "编辑组件模板“{name}”", + "xpack.idxMgmt.componentTemplateEdit.loadComponentTemplateError": "加载组件模板时出错", + "xpack.idxMgmt.componentTemplateEdit.loadingDescription": "正在加载组件模板……", + "xpack.idxMgmt.componentTemplateForm.createButtonLabel": "创建组件模板", + "xpack.idxMgmt.componentTemplateForm.saveButtonLabel": "保存组件模板", + "xpack.idxMgmt.componentTemplateForm.saveTemplateError": "无法创建组件模板", + "xpack.idxMgmt.componentTemplateForm.stepLogistics.docsButtonLabel": "组件模板文档", + "xpack.idxMgmt.componentTemplateForm.stepLogistics.metaAriaLabel": "_meta 字段数据编辑器", + "xpack.idxMgmt.componentTemplateForm.stepLogistics.metadataDescription": "添加元数据", + "xpack.idxMgmt.componentTemplateForm.stepLogistics.metaDescription": "有关模板的任意信息,以集群状态存储。{learnMoreLink}", + "xpack.idxMgmt.componentTemplateForm.stepLogistics.metaDocumentionLink": "了解详情。", + "xpack.idxMgmt.componentTemplateForm.stepLogistics.metaFieldLabel": "_meta 字段数据(可选)", + "xpack.idxMgmt.componentTemplateForm.stepLogistics.metaHelpText": "使用 JSON 格式:{code}", + "xpack.idxMgmt.componentTemplateForm.stepLogistics.metaTitle": "元数据", + "xpack.idxMgmt.componentTemplateForm.stepLogistics.nameDescription": "此组件模板的唯一名称。", + "xpack.idxMgmt.componentTemplateForm.stepLogistics.nameFieldLabel": "名称", + "xpack.idxMgmt.componentTemplateForm.stepLogistics.nameTitle": "名称", + "xpack.idxMgmt.componentTemplateForm.stepLogistics.stepTitle": "运筹", + "xpack.idxMgmt.componentTemplateForm.stepLogistics.validation.metaJsonError": "输入无效。", + "xpack.idxMgmt.componentTemplateForm.stepLogistics.validation.nameSpacesError": "组件模板名称不允许包含空格。", + "xpack.idxMgmt.componentTemplateForm.stepLogistics.versionDescription": "外部管理系统用于标识组件模板的编号。", + "xpack.idxMgmt.componentTemplateForm.stepLogistics.versionFieldLabel": "版本(可选)", + "xpack.idxMgmt.componentTemplateForm.stepLogistics.versionTitle": "版本", + "xpack.idxMgmt.componentTemplateForm.stepReview.requestTab.descriptionText": "此请求将创建以下组件模板。", + "xpack.idxMgmt.componentTemplateForm.stepReview.requestTabTitle": "请求", + "xpack.idxMgmt.componentTemplateForm.stepReview.stepTitle": "查看“{templateName}”的详情", + "xpack.idxMgmt.componentTemplateForm.stepReview.summaryTab.aliasesLabel": "别名", + "xpack.idxMgmt.componentTemplateForm.stepReview.summaryTab.mappingLabel": "映射", + "xpack.idxMgmt.componentTemplateForm.stepReview.summaryTab.noDescriptionText": "否", + "xpack.idxMgmt.componentTemplateForm.stepReview.summaryTab.settingsLabel": "索引设置", + "xpack.idxMgmt.componentTemplateForm.stepReview.summaryTab.yesDescriptionText": "是", + "xpack.idxMgmt.componentTemplateForm.stepReview.summaryTabTitle": "摘要", + "xpack.idxMgmt.componentTemplateForm.steps.aliasesStepName": "别名", + "xpack.idxMgmt.componentTemplateForm.steps.logisticsStepName": "运筹", + "xpack.idxMgmt.componentTemplateForm.steps.mappingsStepName": "映射", + "xpack.idxMgmt.componentTemplateForm.steps.settingsStepName": "索引设置", + "xpack.idxMgmt.componentTemplateForm.steps.summaryStepName": "复查", + "xpack.idxMgmt.componentTemplateForm.validation.nameRequiredError": "组件模板名称必填。", + "xpack.idxMgmt.componentTemplates.createRoute.duplicateErrorMessage": "已有名称为“{name}”的组件模板。", + "xpack.idxMgmt.componentTemplates.list.learnMoreLinkText": "了解详情。", + "xpack.idxMgmt.componentTemplatesFlyout.createComponentTemplateFromExistingButtonLabel": "从现有索引模板", + "xpack.idxMgmt.componentTemplatesFlyout.createComponentTemplateFromScratchButtonLabel": "从头开始", + "xpack.idxMgmt.componentTemplatesFlyout.createContextMenuPanelTitle": "新建组件模板", + "xpack.idxMgmt.componentTemplatesFlyout.manageButtonLabel": "创建", + "xpack.idxMgmt.componentTemplatesList.table.actionCloneDecription": "克隆此组件模板", + "xpack.idxMgmt.componentTemplatesList.table.actionCloneText": "克隆", + "xpack.idxMgmt.componentTemplatesList.table.actionColumnTitle": "操作", + "xpack.idxMgmt.componentTemplatesList.table.actionEditDecription": "编辑此组件模板", + "xpack.idxMgmt.componentTemplatesList.table.actionEditText": "编辑", + "xpack.idxMgmt.componentTemplatesList.table.aliasesColumnTitle": "别名", + "xpack.idxMgmt.componentTemplatesList.table.createButtonLabel": "创建组件模板", + "xpack.idxMgmt.componentTemplatesList.table.deleteActionDescription": "删除此组件模板", + "xpack.idxMgmt.componentTemplatesList.table.deleteActionLabel": "删除", + "xpack.idxMgmt.componentTemplatesList.table.deleteComponentTemplatesButtonLabel": "删除{count, plural, one {组件模板} other {组件模板} }", + "xpack.idxMgmt.componentTemplatesList.table.disabledSelectionLabel": "组件模板正在使用中,无法删除", + "xpack.idxMgmt.componentTemplatesList.table.inUseFilterOptionLabel": "在使用中", + "xpack.idxMgmt.componentTemplatesList.table.isInUseColumnTitle": "使用计数", + "xpack.idxMgmt.componentTemplatesList.table.isManagedFilterLabel": "托管", + "xpack.idxMgmt.componentTemplatesList.table.managedBadgeLabel": "托管", + "xpack.idxMgmt.componentTemplatesList.table.mappingsColumnTitle": "映射", + "xpack.idxMgmt.componentTemplatesList.table.nameColumnTitle": "名称", + "xpack.idxMgmt.componentTemplatesList.table.notInUseCellDescription": "未在使用中", + "xpack.idxMgmt.componentTemplatesList.table.notInUseFilterOptionLabel": "未在使用中", + "xpack.idxMgmt.componentTemplatesList.table.reloadButtonLabel": "重新加载", + "xpack.idxMgmt.componentTemplatesList.table.selectionLabel": "选择此组件模板", + "xpack.idxMgmt.componentTemplatesList.table.settingsColumnTitle": "设置", + "xpack.idxMgmt.componentTemplatesSelector.emptyPromptDescription": "组件模板允许您保存索引设置、映射和别名并在索引模板中继承它们。", + "xpack.idxMgmt.componentTemplatesSelector.emptyPromptLearnMoreLinkText": "了解详情。", + "xpack.idxMgmt.componentTemplatesSelector.emptyPromptTitle": "您尚未有任何组件", + "xpack.idxMgmt.componentTemplatesSelector.filters.aliasesLabel": "别名", + "xpack.idxMgmt.componentTemplatesSelector.filters.indexSettingsLabel": "索引设置", + "xpack.idxMgmt.componentTemplatesSelector.filters.mappingsLabel": "映射", + "xpack.idxMgmt.componentTemplatesSelector.loadingComponentsDescription": "正在加载组件模板……", + "xpack.idxMgmt.componentTemplatesSelector.loadingComponentsErrorMessage": "加载组件时出错", + "xpack.idxMgmt.componentTemplatesSelector.noComponentSelectedLabel": "未选择任何组件模板。", + "xpack.idxMgmt.componentTemplatesSelector.removeItemIconLabel": "移除", + "xpack.idxMgmt.componentTemplatesSelector.searchBox.placeholder": "搜索组件模板", + "xpack.idxMgmt.componentTemplatesSelector.searchResult.emptyPrompt.clearSearchButtonLabel": "清除搜索", + "xpack.idxMgmt.componentTemplatesSelector.searchResult.emptyPromptTitle": "没有任何组件匹配您的搜索", + "xpack.idxMgmt.componentTemplatesSelector.selectionHeader.componentsSelectedLabel": "选择的组件:{count}", + "xpack.idxMgmt.componentTemplatesSelector.selectItemIconLabel": "选择", + "xpack.idxMgmt.componentTemplatesSelector.viewItemIconLabel": "查看", + "xpack.idxMgmt.createComponentTemplate.pageTitle": "创建组件模板", "xpack.idxMgmt.createRoute.duplicateTemplateIdErrorMessage": "已有名称为“{name}”的模板。", "xpack.idxMgmt.createTemplate.cloneTemplatePageTitle": "克隆模板“{name}”", + "xpack.idxMgmt.createTemplate.createLegacyTemplatePageTitle": "创建旧版模板", "xpack.idxMgmt.createTemplate.createTemplatePageTitle": "创建模板", + "xpack.idxMgmt.dataStreamDetailPanel.closeButtonLabel": "关闭", + "xpack.idxMgmt.dataStreamDetailPanel.deleteButtonLabel": "删除数据流", + "xpack.idxMgmt.dataStreamDetailPanel.generationTitle": "世代", + "xpack.idxMgmt.dataStreamDetailPanel.generationToolTip": "为数据流创建的后备索引的累积计数", + "xpack.idxMgmt.dataStreamDetailPanel.indicesTitle": "索引", + "xpack.idxMgmt.dataStreamDetailPanel.indicesToolTip": "数据流当前的后备索引", + "xpack.idxMgmt.dataStreamDetailPanel.loadingDataStreamDescription": "正在加载数据流", + "xpack.idxMgmt.dataStreamDetailPanel.loadingDataStreamErrorMessage": "加载数据流时出错", + "xpack.idxMgmt.dataStreamDetailPanel.timestampFieldTitle": "时间戳字段", + "xpack.idxMgmt.dataStreamDetailPanel.timestampFieldToolTip": "时间戳字段由数据流中的所有文档共享", + "xpack.idxMgmt.dataStreamList.dataStreamsDescription": "数据流在多个索引上存储时序数据。{learnMoreLink}", + "xpack.idxMgmt.dataStreamList.emptyPrompt.noDataStreamsCtaIndexTemplateLink": "可组合索引模板", + "xpack.idxMgmt.dataStreamList.emptyPrompt.noDataStreamsCtaIndexTemplateMessage": "通过创建 {link} 来开始使用数据流。", + "xpack.idxMgmt.dataStreamList.emptyPrompt.noDataStreamsCtaIngestManagerLink": "采集管理器", + "xpack.idxMgmt.dataStreamList.emptyPrompt.noDataStreamsCtaIngestManagerMessage": "开始使用 {link} 中的数据流。", + "xpack.idxMgmt.dataStreamList.emptyPrompt.noDataStreamsDescription": "数据流存储多个索引的时序数据。", + "xpack.idxMgmt.dataStreamList.emptyPrompt.noDataStreamsTitle": "您尚未有任何数据流", + "xpack.idxMgmt.dataStreamList.loadingDataStreamsDescription": "正在加载数据流……", + "xpack.idxMgmt.dataStreamList.loadingDataStreamsErrorMessage": "加载数据流时出错", + "xpack.idxMgmt.dataStreamList.reloadDataStreamsButtonLabel": "重新加载", + "xpack.idxMgmt.dataStreamList.table.actionColumnTitle": "操作", + "xpack.idxMgmt.dataStreamList.table.actionDeleteDecription": "删除此数据流", + "xpack.idxMgmt.dataStreamList.table.actionDeleteText": "删除", + "xpack.idxMgmt.dataStreamList.table.deleteDataStreamsButtonLabel": "删除{count, plural, one {数据流} other {数据流} }", + "xpack.idxMgmt.dataStreamList.table.indicesColumnTitle": "索引", + "xpack.idxMgmt.dataStreamList.table.nameColumnTitle": "名称", + "xpack.idxMgmt.dataStreamList.table.noDataStreamsMessage": "找不到任何数据流", + "xpack.idxMgmt.dataStreamListDescription.learnMoreLinkText": "了解详情。", + "xpack.idxMgmt.deleteDataStreamsConfirmationModal.cancelButtonLabel": "取消", + "xpack.idxMgmt.deleteDataStreamsConfirmationModal.confirmButtonLabel": "删除{dataStreamsCount, plural, one {数据流} other {数据流} }", + "xpack.idxMgmt.deleteDataStreamsConfirmationModal.deleteDescription": "您即将删除{dataStreamsCount, plural, one {以下数据流} other {以下数据流} }:", + "xpack.idxMgmt.deleteDataStreamsConfirmationModal.errorNotificationMessageText": "删除数据流“{name}”时出错", + "xpack.idxMgmt.deleteDataStreamsConfirmationModal.modalTitleText": "删除{dataStreamsCount, plural, one {数据流} other { # 个数据流}}", + "xpack.idxMgmt.deleteDataStreamsConfirmationModal.multipleErrorsNotificationMessageText": "删除 {count} 个数据流时出错", + "xpack.idxMgmt.deleteDataStreamsConfirmationModal.successDeleteMultipleNotificationMessageText": "已删除 {numSuccesses, plural, one {# 个数据流} other {# 个数据流}}", + "xpack.idxMgmt.deleteDataStreamsConfirmationModal.successDeleteSingleNotificationMessageText": "已删除数据流“{dataStreamName}”", + "xpack.idxMgmt.deleteDataStreamsConfirmationModal.warningMessage": "数据流是时序索引的集合。删除数据流也将会删除其索引。", + "xpack.idxMgmt.deleteDataStreamsConfirmationModal.warningTitle": "删除数据流也将会删除索引", "xpack.idxMgmt.deleteIndicesAction.successfullyDeletedIndicesMessage": "已成功删除:[{indexNames}]", "xpack.idxMgmt.deleteTemplatesModal.cancelButtonLabel": "取消", "xpack.idxMgmt.deleteTemplatesModal.confirmButtonLabel": "删除{numTemplatesToDelete, plural, one {模板} other {模板} }", @@ -6398,12 +7408,56 @@ "xpack.idxMgmt.editTemplate.editTemplatePageTitle": "编辑模板“{name}”", "xpack.idxMgmt.flushIndicesAction.successfullyFlushedIndicesMessage": "已成功清空:[{indexNames}]", "xpack.idxMgmt.forceMergeIndicesAction.successfullyForceMergedIndicesMessage": "已成功强制合并:[{indexNames}]", + "xpack.idxMgmt.formWizard.stepAliases.aliasesDescription": "设置要与索引关联的别名。", + "xpack.idxMgmt.formWizard.stepAliases.aliasesEditorHelpText": "使用 JSON 格式:{code}", + "xpack.idxMgmt.formWizard.stepAliases.docsButtonLabel": "索引别名文档", + "xpack.idxMgmt.formWizard.stepAliases.fieldAliasesAriaLabel": "别名代码编辑器", + "xpack.idxMgmt.formWizard.stepAliases.fieldAliasesLabel": "别名", + "xpack.idxMgmt.formWizard.stepAliases.stepTitle": "别名(可选)", + "xpack.idxMgmt.formWizard.stepComponents.componentsDescription": "组件模板允许您保存索引设置、映射和别名并在索引模板中继承它们。", + "xpack.idxMgmt.formWizard.stepComponents.docsButtonLabel": "组件模板文档", + "xpack.idxMgmt.formWizard.stepComponents.stepTitle": "组件模板(可选)", + "xpack.idxMgmt.formWizard.stepMappings.docsButtonLabel": "映射文档", + "xpack.idxMgmt.formWizard.stepMappings.mappingsDescription": "定义如何存储和索引文档。", + "xpack.idxMgmt.formWizard.stepMappings.stepTitle": "映射(可选)", + "xpack.idxMgmt.formWizard.stepSettings.docsButtonLabel": "索引设置文档", + "xpack.idxMgmt.formWizard.stepSettings.fieldIndexSettingsAriaLabel": "索引设置编辑器", + "xpack.idxMgmt.formWizard.stepSettings.fieldIndexSettingsLabel": "索引设置", + "xpack.idxMgmt.formWizard.stepSettings.settingsDescription": "定义索引的行为。", + "xpack.idxMgmt.formWizard.stepSettings.settingsEditorHelpText": "使用 JSON 格式:{code}", + "xpack.idxMgmt.formWizard.stepSettings.stepTitle": "索引设置(可选)", "xpack.idxMgmt.freezeIndicesAction.successfullyFrozeIndicesMessage": "成功冻结:[{indexNames}]", "xpack.idxMgmt.frozenBadgeLabel": "已冻结", "xpack.idxMgmt.home.appTitle": "索引管理", + "xpack.idxMgmt.home.componentTemplates.checkingPrivilegesDescription": "正在检查权限……", + "xpack.idxMgmt.home.componentTemplates.checkingPrivilegesErrorMessage": "从服务器获取用户权限时出错。", + "xpack.idxMgmt.home.componentTemplates.confirmButtonLabel": "删除{numComponentTemplatesToDelete, plural, one {组件模板} other {组件模板} }", + "xpack.idxMgmt.home.componentTemplates.deleteModal.cancelButtonLabel": "取消", + "xpack.idxMgmt.home.componentTemplates.deleteModal.deleteDescription": "您即将删除{numComponentTemplatesToDelete, plural, one {以下组件模板} other {以下组件模板} }:", + "xpack.idxMgmt.home.componentTemplates.deleteModal.errorNotificationMessageText": "删除组件模板“{name}”时出错", + "xpack.idxMgmt.home.componentTemplates.deleteModal.modalTitleText": "删除{numComponentTemplatesToDelete, plural, one {组件模板} other { # 个组件模板}}", + "xpack.idxMgmt.home.componentTemplates.deleteModal.multipleErrorsNotificationMessageText": "删除 {count} 个组件模板时出错", + "xpack.idxMgmt.home.componentTemplates.deleteModal.successDeleteMultipleNotificationMessageText": "已删除 {numSuccesses, plural, one {# 个组件模板} other {# 组件模板}}", + "xpack.idxMgmt.home.componentTemplates.deleteModal.successDeleteSingleNotificationMessageText": "已删除组件模板“{componentTemplateName}”", + "xpack.idxMgmt.home.componentTemplates.deniedPrivilegeDescription": "要使用“组件模板”,必须具有{privilegesCount, plural, one {以下集群权限} other {以下集群权限}}:{missingPrivileges}。", + "xpack.idxMgmt.home.componentTemplates.deniedPrivilegeTitle": "需要集群权限", + "xpack.idxMgmt.home.componentTemplates.emptyPromptButtonLabel": "创建组件模板", + "xpack.idxMgmt.home.componentTemplates.emptyPromptDescription": "例如,您可以为可在多个索引模板上重复使用的索引设置创建组件模板。", + "xpack.idxMgmt.home.componentTemplates.emptyPromptDocumentionLink": "了解详情。", + "xpack.idxMgmt.home.componentTemplates.emptyPromptTitle": "首先创建组件模板", + "xpack.idxMgmt.home.componentTemplates.list.componentTemplatesDescription": "使用组件模板可在多个索引模板中重复使用设置、映射和别名。{learnMoreLink}", + "xpack.idxMgmt.home.componentTemplates.list.loadErrorReloadLinkLabel": "请重试。", + "xpack.idxMgmt.home.componentTemplates.list.loadErrorTitle": "无法加载组件模板。{reloadLink}", + "xpack.idxMgmt.home.componentTemplates.list.loadingMessage": "正在加载组件模板……", + "xpack.idxMgmt.home.componentTemplatesTabTitle": "组件模板", + "xpack.idxMgmt.home.dataStreamsTabTitle": "数据流", + "xpack.idxMgmt.home.idxMgmtDescription": "分别或批量更新您的 Elasticsearch 索引。{learnMoreLink}", "xpack.idxMgmt.home.idxMgmtDocsLinkText": "索引管理文档", + "xpack.idxMgmt.home.indexTemplatesDescription": "使用索引模板可将设置、映射和别名自动应用到索引。{learnMoreLink}", + "xpack.idxMgmt.home.indexTemplatesDescription.learnMoreLinkText": "了解详情。", "xpack.idxMgmt.home.indexTemplatesTabTitle": "索引模板", "xpack.idxMgmt.home.indicesTabTitle": "索引", + "xpack.idxMgmt.home.legacyIndexTemplatesTitle": "旧版索引模板", "xpack.idxMgmt.indexActionsMenu.clearIndexCacheLabel": "清除 {selectedIndexCount, plural, one { 个索引} other { 个索引} } 缓存", "xpack.idxMgmt.indexActionsMenu.closeIndex.checkboxLabel": "我了解关闭系统索引的后果", "xpack.idxMgmt.indexActionsMenu.closeIndex.closeDescription": "您将要关闭{selectedIndexCount, plural, one {以下索引} other {以下索引} }:", @@ -6460,6 +7514,7 @@ "xpack.idxMgmt.indexStatusLabels.openingStatusLabel": "正在打开...", "xpack.idxMgmt.indexStatusLabels.refreshingStatusLabel": "正在刷新...", "xpack.idxMgmt.indexTable.captionText": "下面是包含 {count, plural, one {# 行} other {# 行}}(共 {total} 行)的索引表。", + "xpack.idxMgmt.indexTable.headers.dataStreamHeader": "数据流", "xpack.idxMgmt.indexTable.headers.documentsHeader": "文档计数", "xpack.idxMgmt.indexTable.headers.healthHeader": "运行状况", "xpack.idxMgmt.indexTable.headers.nameHeader": "名称", @@ -6467,6 +7522,7 @@ "xpack.idxMgmt.indexTable.headers.replicaHeader": "副本分片", "xpack.idxMgmt.indexTable.headers.statusHeader": "状态", "xpack.idxMgmt.indexTable.headers.storageSizeHeader": "存储大小", + "xpack.idxMgmt.indexTable.hiddenIndicesSwitchLabel": "包括隐藏的索引", "xpack.idxMgmt.indexTable.invalidSearchErrorMessage": "无效搜索:{errorMessage}", "xpack.idxMgmt.indexTable.reloadIndicesButton": "重载索引", "xpack.idxMgmt.indexTable.selectAllIndicesAriaLabel": "选择所有行", @@ -6474,9 +7530,15 @@ "xpack.idxMgmt.indexTable.serverErrorTitle": "加载索引时出错", "xpack.idxMgmt.indexTable.systemIndicesSearchIndicesAriaLabel": "搜索索引", "xpack.idxMgmt.indexTable.systemIndicesSearchInputPlaceholder": "搜索", + "xpack.idxMgmt.indexTableDescription.learnMoreLinkText": "了解详情。", "xpack.idxMgmt.indexTemplatesList.emptyPrompt.noIndexTemplatesTitle": "您尚未有任何模板", + "xpack.idxMgmt.indexTemplatesList.filterButtonLabel": "筛选", "xpack.idxMgmt.indexTemplatesList.loadingIndexTemplatesDescription": "正在加载模板……", "xpack.idxMgmt.indexTemplatesList.loadingIndexTemplatesErrorMessage": "加载模板时出错", + "xpack.idxMgmt.indexTemplatesList.viewButtonLabel": "查看", + "xpack.idxMgmt.indexTemplatesList.viewCloudManagedTemplateLabel": "云托管模板", + "xpack.idxMgmt.indexTemplatesList.viewManagedTemplateLabel": "托管模板", + "xpack.idxMgmt.indexTemplatesList.viewSystemTemplateLabel": "系统模板", "xpack.idxMgmt.licenseCheckErrorMessage": "许可证检查失败", "xpack.idxMgmt.mappingsEditor.addFieldButtonLabel": "添加字段", "xpack.idxMgmt.mappingsEditor.addMultiFieldTooltipLabel": "添加多字段以使用不同的方式索引相同的字段。", @@ -6959,11 +8021,13 @@ "xpack.idxMgmt.mappingsEditor.updateField.confirmationModal.title": "确认将“{fieldName}”类型更改为“{fieldType}”。", "xpack.idxMgmt.mappingsEditor.useNormsFieldDescription": "对查询评分时解释字段长度。Norms 需要很大的内存,对于仅用于筛选或聚合的字段,其不是必需的。", "xpack.idxMgmt.mappingsEditor.useNormsFieldTitle": "使用 norms", + "xpack.idxMgmt.mappingsTab.noMappingsTitle": "未定义任何映射。", "xpack.idxMgmt.noMatch.noIndicesDescription": "没有要显示的索引", "xpack.idxMgmt.openIndicesAction.successfullyOpenedIndicesMessage": "已成功打开:[{indexNames}]", "xpack.idxMgmt.pageErrorForbidden.title": "您无权使用“索引管理”", "xpack.idxMgmt.refreshIndicesAction.successfullyRefreshedIndicesMessage": "已成功刷新:[{indexNames}]", "xpack.idxMgmt.reloadIndicesAction.indicesPageRefreshFailureMessage": "无法刷新当前页面的索引。", + "xpack.idxMgmt.settingsTab.noIndexSettingsTitle": "未定义任何设置。", "xpack.idxMgmt.summary.headers.aliases": "别名", "xpack.idxMgmt.summary.headers.deletedDocumentsHeader": "文档已删除", "xpack.idxMgmt.summary.headers.documentsHeader": "文档计数", @@ -6974,11 +8038,19 @@ "xpack.idxMgmt.summary.headers.statusHeader": "状态", "xpack.idxMgmt.summary.headers.storageSizeHeader": "存储大小", "xpack.idxMgmt.summary.summaryTitle": "常规", + "xpack.idxMgmt.templateBadgeType.cloudManaged": "云托管", + "xpack.idxMgmt.templateBadgeType.managed": "托管", + "xpack.idxMgmt.templateBadgeType.system": "系统", + "xpack.idxMgmt.templateContentIndicator.aliasesTooltipLabel": "别名", + "xpack.idxMgmt.templateContentIndicator.indexSettingsTooltipLabel": "索引设置", + "xpack.idxMgmt.templateContentIndicator.mappingsTooltipLabel": "映射", "xpack.idxMgmt.templateCreate.loadingTemplateToCloneDescription": "正在加载要克隆的模板……", "xpack.idxMgmt.templateCreate.loadingTemplateToCloneErrorMessage": "加载要克隆的模板时出错", "xpack.idxMgmt.templateDetails.aliasesTabTitle": "别名", "xpack.idxMgmt.templateDetails.cloneButtonLabel": "克隆", "xpack.idxMgmt.templateDetails.closeButtonLabel": "关闭", + "xpack.idxMgmt.templateDetails.cloudManagedTemplateInfoDescription": "云托管模板对内部操作至关重要。", + "xpack.idxMgmt.templateDetails.cloudManagedTemplateInfoTitle": "不允许编辑云托管模板。", "xpack.idxMgmt.templateDetails.deleteButtonLabel": "删除", "xpack.idxMgmt.templateDetails.editButtonLabel": "编辑", "xpack.idxMgmt.templateDetails.loadingIndexTemplateDescription": "正在加载模板……", @@ -6987,11 +8059,17 @@ "xpack.idxMgmt.templateDetails.manageContextMenuPanelTitle": "模板选项", "xpack.idxMgmt.templateDetails.mappingsTabTitle": "映射", "xpack.idxMgmt.templateDetails.settingsTabTitle": "设置", + "xpack.idxMgmt.templateDetails.summaryTab.componentsDescriptionListTitle": "组件模板", + "xpack.idxMgmt.templateDetails.summaryTab.dataStreamDescriptionListTitle": "数据流", "xpack.idxMgmt.templateDetails.summaryTab.ilmPolicyDescriptionListTitle": "ILM 策略", "xpack.idxMgmt.templateDetails.summaryTab.indexPatternsDescriptionListTitle": "索引{numIndexPatterns, plural, one {模式} other {模式}}", + "xpack.idxMgmt.templateDetails.summaryTab.metaDescriptionListTitle": "元数据", + "xpack.idxMgmt.templateDetails.summaryTab.noDescriptionText": "否", "xpack.idxMgmt.templateDetails.summaryTab.noneDescriptionText": "无", "xpack.idxMgmt.templateDetails.summaryTab.orderDescriptionListTitle": "顺序", + "xpack.idxMgmt.templateDetails.summaryTab.priorityDescriptionListTitle": "优先级", "xpack.idxMgmt.templateDetails.summaryTab.versionDescriptionListTitle": "版本", + "xpack.idxMgmt.templateDetails.summaryTab.yesDescriptionText": "是", "xpack.idxMgmt.templateDetails.summaryTabTitle": "总结", "xpack.idxMgmt.templateEdit.loadingIndexTemplateDescription": "正在加载模板……", "xpack.idxMgmt.templateEdit.loadingIndexTemplateErrorMessage": "加载模板时出错", @@ -7002,18 +8080,32 @@ "xpack.idxMgmt.templateForm.createButtonLabel": "创建模板", "xpack.idxMgmt.templateForm.saveButtonLabel": "保存模板", "xpack.idxMgmt.templateForm.saveTemplateError": "无法创建模板", + "xpack.idxMgmt.templateForm.stepLogistics.addMetadataLabel": "添加元数据", + "xpack.idxMgmt.templateForm.stepLogistics.dataStreamDescription": "该模板创建数据流,而非索引。{docsLink}", + "xpack.idxMgmt.templateForm.stepLogistics.dataStreamDocumentionLink": "了解详情。", + "xpack.idxMgmt.templateForm.stepLogistics.datastreamLabel": "创建数据流", + "xpack.idxMgmt.templateForm.stepLogistics.dataStreamTitle": "数据流", "xpack.idxMgmt.templateForm.stepLogistics.docsButtonLabel": "索引模板文档", "xpack.idxMgmt.templateForm.stepLogistics.fieldIndexPatternsHelpText": "不允许使用空格和字符 {invalidCharactersList}。", "xpack.idxMgmt.templateForm.stepLogistics.fieldIndexPatternsLabel": "索引模式", "xpack.idxMgmt.templateForm.stepLogistics.fieldNameLabel": "名称", "xpack.idxMgmt.templateForm.stepLogistics.fieldOrderLabel": "顺序(可选)", + "xpack.idxMgmt.templateForm.stepLogistics.fieldPriorityLabel": "优先级(可选)", "xpack.idxMgmt.templateForm.stepLogistics.fieldVersionLabel": "版本(可选)", "xpack.idxMgmt.templateForm.stepLogistics.indexPatternsDescription": "要应用于模板的索引模式。", "xpack.idxMgmt.templateForm.stepLogistics.indexPatternsTitle": "索引模式", + "xpack.idxMgmt.templateForm.stepLogistics.metaFieldDescription": "使用 _meta 字段存储您需要的元数据。", + "xpack.idxMgmt.templateForm.stepLogistics.metaFieldEditorAriaLabel": "_meta 字段数据编辑器", + "xpack.idxMgmt.templateForm.stepLogistics.metaFieldEditorHelpText": "使用 JSON 格式:{code}", + "xpack.idxMgmt.templateForm.stepLogistics.metaFieldEditorJsonError": "_meta 字段 JSON 无效。", + "xpack.idxMgmt.templateForm.stepLogistics.metaFieldEditorLabel": "_meta 字段数据(可选)", + "xpack.idxMgmt.templateForm.stepLogistics.metaFieldTitle": "_meta 字段", "xpack.idxMgmt.templateForm.stepLogistics.nameDescription": "此模板的唯一标识符。", "xpack.idxMgmt.templateForm.stepLogistics.nameTitle": "名称", "xpack.idxMgmt.templateForm.stepLogistics.orderDescription": "多个模板匹配一个索引时的合并顺序。", "xpack.idxMgmt.templateForm.stepLogistics.orderTitle": "合并顺序", + "xpack.idxMgmt.templateForm.stepLogistics.priorityDescription": "仅将应用最高优先级模板。", + "xpack.idxMgmt.templateForm.stepLogistics.priorityTitle": "优先级", "xpack.idxMgmt.templateForm.stepLogistics.stepTitle": "运筹", "xpack.idxMgmt.templateForm.stepLogistics.versionDescription": "在外部管理系统中标识该模板的编号。", "xpack.idxMgmt.templateForm.stepLogistics.versionTitle": "版本", @@ -7021,23 +8113,43 @@ "xpack.idxMgmt.templateForm.stepReview.requestTabTitle": "请求", "xpack.idxMgmt.templateForm.stepReview.stepTitle": "查看 “{templateName}” 的详情", "xpack.idxMgmt.templateForm.stepReview.summaryTab.aliasesLabel": "别名", + "xpack.idxMgmt.templateForm.stepReview.summaryTab.componentsLabel": "组件模板", "xpack.idxMgmt.templateForm.stepReview.summaryTab.indexPatternsLabel": "索引{numIndexPatterns, plural, one {模式} other {模式}}", "xpack.idxMgmt.templateForm.stepReview.summaryTab.indexPatternsWarningDescription": "您创建的所有新索引将使用此模板。", "xpack.idxMgmt.templateForm.stepReview.summaryTab.indexPatternsWarningLinkText": "编辑索引模式。", "xpack.idxMgmt.templateForm.stepReview.summaryTab.indexPatternsWarningTitle": "此模板将通配符 (*) 用作索引模式。", "xpack.idxMgmt.templateForm.stepReview.summaryTab.mappingLabel": "映射", + "xpack.idxMgmt.templateForm.stepReview.summaryTab.metaLabel": "元数据", "xpack.idxMgmt.templateForm.stepReview.summaryTab.noDescriptionText": "否", "xpack.idxMgmt.templateForm.stepReview.summaryTab.noneDescriptionText": "无", "xpack.idxMgmt.templateForm.stepReview.summaryTab.orderLabel": "顺序", + "xpack.idxMgmt.templateForm.stepReview.summaryTab.priorityLabel": "优先级", "xpack.idxMgmt.templateForm.stepReview.summaryTab.settingsLabel": "索引设置", "xpack.idxMgmt.templateForm.stepReview.summaryTab.versionLabel": "版本", "xpack.idxMgmt.templateForm.stepReview.summaryTab.yesDescriptionText": "是", "xpack.idxMgmt.templateForm.stepReview.summaryTabTitle": "总结", "xpack.idxMgmt.templateForm.steps.aliasesStepName": "别名", + "xpack.idxMgmt.templateForm.steps.componentsStepName": "组件模板", "xpack.idxMgmt.templateForm.steps.logisticsStepName": "运筹", "xpack.idxMgmt.templateForm.steps.mappingsStepName": "映射", "xpack.idxMgmt.templateForm.steps.settingsStepName": "索引设置", "xpack.idxMgmt.templateForm.steps.summaryStepName": "复查模板", + "xpack.idxMgmt.templateList.legacyTable.actionCloneDescription": "克隆此模板", + "xpack.idxMgmt.templateList.legacyTable.actionCloneTitle": "克隆", + "xpack.idxMgmt.templateList.legacyTable.actionColumnTitle": "操作", + "xpack.idxMgmt.templateList.legacyTable.actionDeleteDecription": "删除此模板", + "xpack.idxMgmt.templateList.legacyTable.actionDeleteText": "删除", + "xpack.idxMgmt.templateList.legacyTable.actionEditDecription": "编辑此模板", + "xpack.idxMgmt.templateList.legacyTable.actionEditText": "编辑", + "xpack.idxMgmt.templateList.legacyTable.contentColumnTitle": "内容", + "xpack.idxMgmt.templateList.legacyTable.createLegacyTemplatesButtonLabel": "创建旧版模板", + "xpack.idxMgmt.templateList.legacyTable.deleteCloudManagedTemplateTooltip": "您无法删除云托管模板。", + "xpack.idxMgmt.templateList.legacyTable.deleteTemplatesButtonLabel": "删除{count, plural, one {模板} other {模板} }", + "xpack.idxMgmt.templateList.legacyTable.ilmPolicyColumnDescription": "“{policyName}”索引生命周期策略", + "xpack.idxMgmt.templateList.legacyTable.ilmPolicyColumnTitle": "ILM 策略", + "xpack.idxMgmt.templateList.legacyTable.indexPatternsColumnTitle": "索引模式", + "xpack.idxMgmt.templateList.legacyTable.nameColumnTitle": "名称", + "xpack.idxMgmt.templateList.legacyTable.noLegacyIndexTemplatesMessage": "未找到任何旧版索引模板", "xpack.idxMgmt.templateList.table.actionCloneDescription": "克隆此模板", "xpack.idxMgmt.templateList.table.actionCloneTitle": "克隆", "xpack.idxMgmt.templateList.table.actionColumnTitle": "操作", @@ -7045,11 +8157,16 @@ "xpack.idxMgmt.templateList.table.actionDeleteText": "删除", "xpack.idxMgmt.templateList.table.actionEditDecription": "编辑此模板", "xpack.idxMgmt.templateList.table.actionEditText": "编辑", + "xpack.idxMgmt.templateList.table.componentsColumnTitle": "组件", + "xpack.idxMgmt.templateList.table.contentColumnTitle": "内容", "xpack.idxMgmt.templateList.table.createTemplatesButtonLabel": "创建模板", + "xpack.idxMgmt.templateList.table.dataStreamColumnTitle": "数据流", + "xpack.idxMgmt.templateList.table.deleteCloudManagedTemplateTooltip": "您无法删除云托管模板。", "xpack.idxMgmt.templateList.table.deleteTemplatesButtonLabel": "删除{count, plural, one {模板} other {模板} }", "xpack.idxMgmt.templateList.table.indexPatternsColumnTitle": "索引模式", "xpack.idxMgmt.templateList.table.nameColumnTitle": "名称", "xpack.idxMgmt.templateList.table.noIndexTemplatesMessage": "未找到任何索引模板", + "xpack.idxMgmt.templateList.table.noneDescriptionText": "无", "xpack.idxMgmt.templateList.table.reloadTemplatesButtonLabel": "重新加载", "xpack.idxMgmt.templateValidation.indexPatternsRequiredError": "至少需要一个索引模式。", "xpack.idxMgmt.templateValidation.templateNameInvalidaCharacterError": "模板名称不得包含字符“{invalidChar}”", @@ -7089,8 +8206,18 @@ "xpack.indexLifecycleMgmt.editPolicy.creationNanoSecondsOptionLabel": "纳秒(自索引创建)", "xpack.indexLifecycleMgmt.editPolicy.creationSecondsOptionLabel": "秒(自索引创建)", "xpack.indexLifecycleMgmt.editPolicy.deletePhase.activateWarmPhaseSwitchLabel": "激活删除阶段", + "xpack.indexLifecycleMgmt.editPolicy.deletePhase.customPolicyMessage": "输入现有快照策略的名称或使用此名称创建新策略。", + "xpack.indexLifecycleMgmt.editPolicy.deletePhase.customPolicyTitle": "未找到策略名称", "xpack.indexLifecycleMgmt.editPolicy.deletePhase.deletePhaseDescriptionText": "您不再需要自己的索引。 您可以定义安全删除它的时间。", "xpack.indexLifecycleMgmt.editPolicy.deletePhase.deletePhaseLabel": "删除阶段", + "xpack.indexLifecycleMgmt.editPolicy.deletePhase.noPoliciesCreatedMessage": "创建快照生命周期策略,以自动集群快照的创建和删除。", + "xpack.indexLifecycleMgmt.editPolicy.deletePhase.noPoliciesCreatedTitle": "找不到快照策略", + "xpack.indexLifecycleMgmt.editPolicy.deletePhase.noPoliciesLoadedMessage": "刷新此字段并输入现有快照策略的名称。", + "xpack.indexLifecycleMgmt.editPolicy.deletePhase.noPoliciesLoadedTitle": "无法加载现有策略", + "xpack.indexLifecycleMgmt.editPolicy.deletePhase.reloadPoliciesLabel": "重新加载策略", + "xpack.indexLifecycleMgmt.editPolicy.deletePhase.waitForSnapshotDescription": "指定在删除索引之前要执行的快照策略。这确保已删除索引的快照可用。", + "xpack.indexLifecycleMgmt.editPolicy.deletePhase.waitForSnapshotLabel": "快照策略名称", + "xpack.indexLifecycleMgmt.editPolicy.deletePhase.waitForSnapshotTitle": "等候快照策略", "xpack.indexLifecycleMgmt.editPolicy.differentPolicyNameRequiredError": "策略名称必须不同。", "xpack.indexLifecycleMgmt.editPolicy.editingExistingPolicyExplanationMessage": "所做的任何更改将影响附加到此策略的索引。或者,您可以在新策略中保存这些更改。", "xpack.indexLifecycleMgmt.editPolicy.editingExistingPolicyMessage": "您正在编辑现有策略", @@ -7274,6 +8401,8 @@ "xpack.indexLifecycleMgmt.warmPhase.numberOfSegmentsLabel": "段数目", "xpack.indexLifecycleMgmt.warmPhase.replicaCountHelpText": "默认情况下,副本分片数目仍一样。", "xpack.indexLifecycleMgmt.warmPhase.shrinkIndexLabel": "缩小索引", + "xpack.infra.alerting.alertFlyout.groupBy.placeholder": "无内容(未分组)", + "xpack.infra.alerting.alertFlyout.groupByLabel": "分组依据", "xpack.infra.alerting.alertsButton": "告警", "xpack.infra.alerting.createAlertButton": "创建告警", "xpack.infra.alerting.logs.alertsButton": "告警", @@ -7284,6 +8413,7 @@ "xpack.infra.analysisSetup.configurationStepTitle": "配置", "xpack.infra.analysisSetup.createMlJobButton": "创建 ML 作业", "xpack.infra.analysisSetup.deleteAnalysisResultsWarning": "这将移除以前检测到的异常。", + "xpack.infra.analysisSetup.endTimeAfterStartTimeErrorMessage": "结束时间必须晚于开始时间。", "xpack.infra.analysisSetup.endTimeDefaultDescription": "无限期", "xpack.infra.analysisSetup.endTimeLabel": "结束时间", "xpack.infra.analysisSetup.indexDatasetFilterIncludeAllButtonLabel": "{includeType, select, includeAll {所有数据集} includeSome {{includedDatasetCount, plural, one {# 个数据集} other {# 个数据集}}}}", @@ -7296,6 +8426,7 @@ "xpack.infra.analysisSetup.indicesSelectionTitle": "选择索引", "xpack.infra.analysisSetup.indicesSelectionTooFewSelectedIndicesDescription": "至少选择一个索引名称。", "xpack.infra.analysisSetup.recreateMlJobButton": "重新创建 ML 作业", + "xpack.infra.analysisSetup.startTimeBeforeEndTimeErrorMessage": "开始时间必须早于结束时间。", "xpack.infra.analysisSetup.startTimeDefaultDescription": "日志索引的开始时间", "xpack.infra.analysisSetup.startTimeLabel": "开始时间", "xpack.infra.analysisSetup.steps.initialConfigurationStep.errorCalloutTitle": "您的索引配置无效", @@ -7387,12 +8518,24 @@ "xpack.infra.kibanaMetrics.nodeDoesNotExistErrorMessage": "{nodeId} 不存在。", "xpack.infra.legendControls.applyButton": "应用", "xpack.infra.legendControls.buttonLabel": "配置图例", + "xpack.infra.legendControls.cancelButton": "取消", + "xpack.infra.legendControls.colorPaletteLabel": "调色板", "xpack.infra.legendControls.maxLabel": "最大值", "xpack.infra.legendControls.minLabel": "最小值", + "xpack.infra.legendControls.palettes.cool": "冷", + "xpack.infra.legendControls.palettes.negative": "负", + "xpack.infra.legendControls.palettes.positive": "正", + "xpack.infra.legendControls.palettes.status": "状态", + "xpack.infra.legendControls.palettes.temperature": "温度", + "xpack.infra.legendControls.palettes.warm": "暖", + "xpack.infra.legendControls.reverseDirectionLabel": "反向", + "xpack.infra.legendControls.stepsLabel": "颜色个数", "xpack.infra.legendControls.switchLabel": "自动计算范围", + "xpack.infra.legnedControls.boundRangeError": "最小值必须小于最大值", "xpack.infra.linkTo.hostWithIp.error": "未找到 IP 地址为“{hostIp}”的主机。", "xpack.infra.linkTo.hostWithIp.loading": "正在加载 IP 地址为“{hostIp}”的主机。", "xpack.infra.lobs.logEntryActionsViewInContextButton": "在上下文中查看", + "xpack.infra.logAnomalies.logEntryExamplesMenuLabel": "查看日志条目的操作", "xpack.infra.logEntryActionsMenu.apmActionLabel": "在 APM 中查看", "xpack.infra.logEntryActionsMenu.buttonLabel": "操作", "xpack.infra.logEntryActionsMenu.uptimeActionLabel": "查看监测状态", @@ -7408,6 +8551,7 @@ "xpack.infra.logs.alertFlyout.criterionComparatorValueTitle": "对比:值", "xpack.infra.logs.alertFlyout.criterionFieldTitle": "字段", "xpack.infra.logs.alertFlyout.documentCountPrefix": "当", + "xpack.infra.logs.alertFlyout.documentCountSuffix": "{value, plural, one {发生} other {发生}}", "xpack.infra.logs.alertFlyout.documentCountValue": "{value, plural, one {日志条目} other {log 日志条目}}", "xpack.infra.logs.alertFlyout.error.criterionComparatorRequired": "比较运算符必填。", "xpack.infra.logs.alertFlyout.error.criterionFieldRequired": "“字段”必填。", @@ -7432,16 +8576,45 @@ "xpack.infra.logs.alerting.comparator.notMatch": "不匹配", "xpack.infra.logs.alerting.comparator.notMatchPhrase": "不匹配短语", "xpack.infra.logs.alerting.threshold.conditionsActionVariableDescription": "日志条目需要满足的条件", - "xpack.infra.logs.alerting.threshold.defaultActionMessage": "\\{\\{context.matchingDocuments\\}\\} 日志条目已匹配以下条件:\\{\\{context.conditions\\}\\}", + "xpack.infra.logs.alerting.threshold.defaultActionMessage": "\\{\\{#context.group\\}\\}\\{\\{context.group\\}\\} - \\{\\{/context.group\\}\\}\\{\\{context.matchingDocuments\\}\\} 个日志条目满足以下条件:\\{\\{context.conditions\\}\\}", "xpack.infra.logs.alerting.threshold.documentCountActionVariableDescription": "匹配所提供条件的日志条目数", "xpack.infra.logs.alerting.threshold.fired": "已触发", + "xpack.infra.logs.alerting.threshold.groupByActionVariableDescription": "负责触发告警的组的名称", "xpack.infra.logs.analysis.analyzeInMlButtonLabel": "在 ML 中分析", + "xpack.infra.logs.analysis.anomaliesExpandedRowActualRateDescription": "实际", + "xpack.infra.logs.analysis.anomaliesExpandedRowActualRateTitle": "{actualCount, plural, one {消息} other {消息}}", + "xpack.infra.logs.analysis.anomaliesExpandedRowTypicalRateDescription": "典型", + "xpack.infra.logs.analysis.anomaliesExpandedRowTypicalRateTitle": "{typicalCount, plural, one {消息} other {消息}}", "xpack.infra.logs.analysis.anomaliesSectionLineSeriesName": "每 15 分钟日志条目数(平均值)", + "xpack.infra.logs.analysis.anomaliesSectionLoadingAriaLabel": "正在加载异常", "xpack.infra.logs.analysis.anomaliesSectionTitle": "异常", + "xpack.infra.logs.analysis.anomaliesTableAnomalyDatasetName": "数据集", + "xpack.infra.logs.analysis.anomaliesTableAnomalyMessageName": "移除", + "xpack.infra.logs.analysis.anomaliesTableAnomalyScoreColumnName": "异常分数", + "xpack.infra.logs.analysis.anomaliesTableAnomalyStartTime": "开始时间", + "xpack.infra.logs.analysis.anomaliesTableExamplesTitle": "日志条目示例", + "xpack.infra.logs.analysis.anomaliesTableFewerThanExpectedAnomalyMessage": "此{type, select, logRate {数据集} logCategory {类别}}中的日志消息少于预期", + "xpack.infra.logs.analysis.anomaliesTableMoreThanExpectedAnomalyMessage": "此{type, select, logRate {数据集} logCategory {类别}}中的日志消息多于预期", + "xpack.infra.logs.analysis.anomaliesTableNextPageLabel": "下一页", + "xpack.infra.logs.analysis.anomaliesTablePreviousPageLabel": "上一页", + "xpack.infra.logs.analysis.anomalySectionLogRateChartNoData": "没有要显示的日志速率数据。", "xpack.infra.logs.analysis.anomalySectionNoDataBody": "您可能想调整时间范围。", "xpack.infra.logs.analysis.anomalySectionNoDataTitle": "没有可显示的数据。", + "xpack.infra.logs.analysis.datasetFilterPlaceholder": "按数据集筛选", + "xpack.infra.logs.analysis.enableAnomalyDetectionButtonLabel": "启用异常检测", + "xpack.infra.logs.analysis.jobConfigurationOutdatedCalloutMessage": "创建 {moduleName} ML 作业时所使用的源配置不同。重新创建作业以应用当前配置。这将移除以前检测到的异常。", + "xpack.infra.logs.analysis.jobConfigurationOutdatedCalloutTitle": "{moduleName} ML 作业配置已过时", + "xpack.infra.logs.analysis.jobDefinitionOutdatedCalloutMessage": "{moduleName} ML 作业有更新的版本可用。重新创建作业以部署更新的版本。这将移除以前检测到的异常。", + "xpack.infra.logs.analysis.jobDefinitionOutdatedCalloutTitle": "{moduleName} ML 作业定义已过时", "xpack.infra.logs.analysis.jobStoppedCalloutMessage": "ML 作业已手动停止或由于缺乏资源而停止。作业重新启动后,才会处理新的日志条目。", "xpack.infra.logs.analysis.jobStoppedCalloutTitle": "ML 作业已停止", + "xpack.infra.logs.analysis.logEntryCategoriesModuleDescription": "使用 Machine Learning 自动归类日志消息。", + "xpack.infra.logs.analysis.logEntryCategoriesModuleName": "归类", + "xpack.infra.logs.analysis.logEntryExamplesViewAnomalyInMlLabel": "在 Machine Learning 中查看异常", + "xpack.infra.logs.analysis.logEntryExamplesViewInStreamLabel": "在流中查看", + "xpack.infra.logs.analysis.logEntryRateModuleDescription": "使用 Machine Learning 自动检测异常日志条目速率。", + "xpack.infra.logs.analysis.logEntryRateModuleName": "日志速率", + "xpack.infra.logs.analysis.manageMlJobsButtonLabel": "管理 ML 作业", "xpack.infra.logs.analysis.mlAppButton": "打开 Machine Learning", "xpack.infra.logs.analysis.mlUnavailableBody": "查看 {machineLearningAppLink} 以获取更多信息。", "xpack.infra.logs.analysis.mlUnavailableTitle": "此功能需要 Machine Learning", @@ -7450,11 +8623,15 @@ "xpack.infra.logs.analysis.overallAnomalyChartMaxScoresLabel": "最大异常分数:", "xpack.infra.logs.analysis.partitionMaxAnomalyScoreAnnotationLabel": "最大异常分数:{maxAnomalyScore}", "xpack.infra.logs.analysis.recreateJobButtonLabel": "重新创建 ML 作业", + "xpack.infra.logs.analysis.setupFlyoutGotoListButtonLabel": "所有 Machine Learning 作业", + "xpack.infra.logs.analysis.setupFlyoutTitle": "通过 Machine Learning 检测异常", "xpack.infra.logs.analysis.setupStatusTryAgainButton": "重试", "xpack.infra.logs.analysis.setupStatusUnknownTitle": "我们无法确定您的 ML 作业的状态。", "xpack.infra.logs.analysis.userManagementButtonLabel": "管理用户", "xpack.infra.logs.analysisPage.loadingMessage": "正在检查分析作业的状态......", "xpack.infra.logs.analysisPage.unavailable.mlAppLink": "Machine Learning 应用", + "xpack.infra.logs.categoryExample.viewInContextText": "在上下文中查看", + "xpack.infra.logs.categoryExample.viewInStreamText": "在流中查看", "xpack.infra.logs.customizeLogs.customizeButtonLabel": "定制", "xpack.infra.logs.customizeLogs.lineWrappingFormRowLabel": "换行", "xpack.infra.logs.customizeLogs.textSizeFormRowLabel": "文本大小", @@ -7476,12 +8653,23 @@ "xpack.infra.logs.highlights.goToPreviousHighlightButtonLabel": "跳转到上一高亮条目", "xpack.infra.logs.highlights.highlightsPopoverButtonLabel": "突出显示", "xpack.infra.logs.highlights.highlightTermsFieldLabel": "要突出显示的词", + "xpack.infra.logs.index.anomaliesTabTitle": "异常", "xpack.infra.logs.index.logCategoriesBetaBadgeTitle": "类别", "xpack.infra.logs.index.settingsTabTitle": "设置", "xpack.infra.logs.index.streamTabTitle": "流式传输", "xpack.infra.logs.jumpToTailText": "跳到最近的条目", "xpack.infra.logs.lastUpdate": "上次更新时间 {timestamp}", "xpack.infra.logs.loadingNewEntriesText": "正在加载新条目", + "xpack.infra.logs.logAnalysis.splash.learnMoreLink": "阅读文档", + "xpack.infra.logs.logAnalysis.splash.learnMoreTitle": "希望了解详情?", + "xpack.infra.logs.logAnalysis.splash.loadingMessage": "正在检查许可证......", + "xpack.infra.logs.logAnalysis.splash.splashImageAlt": "占位符图像", + "xpack.infra.logs.logAnalysis.splash.startTrialCta": "开始试用", + "xpack.infra.logs.logAnalysis.splash.startTrialDescription": "我们为期 14 天的免费试用包含 Machine Learning 功能,允许您在日志中检测异常。", + "xpack.infra.logs.logAnalysis.splash.startTrialTitle": "要使用异常检测,请开始免费的试用", + "xpack.infra.logs.logAnalysis.splash.updateSubscriptionCta": "升级订阅", + "xpack.infra.logs.logAnalysis.splash.updateSubscriptionDescription": "必须具有白金级订阅,才能使用 Machine Learning 功能。", + "xpack.infra.logs.logAnalysis.splash.updateSubscriptionTitle": "要使用异常检测,请升级到白金级订阅", "xpack.infra.logs.logEntryActionsDetailsButton": "查看详情", "xpack.infra.logs.logEntryCategories.analyzeCategoryInMlButtonLabel": "在 ML 中分析", "xpack.infra.logs.logEntryCategories.analyzeCategoryInMlTooltipDescription": "在 ML 应用中分析此类别。", @@ -7498,13 +8686,21 @@ "xpack.infra.logs.logEntryCategories.maximumAnomalyScoreColumnTitle": "最大异常分数", "xpack.infra.logs.logEntryCategories.newCategoryTrendLabel": "新建", "xpack.infra.logs.logEntryCategories.noFrequentCategoryWarningReasonDescription": "不会为已提取类别频繁分配消息。", - "xpack.infra.logs.logEntryCategories.setupDescription": "使用 Machine Learning 自动归类日志消息。", - "xpack.infra.logs.logEntryCategories.setupTitle": "启用 Machine Learning 分析", + "xpack.infra.logs.logEntryCategories.setupDescription": "要启用日志类别分析,请设置 Machine Learning 作业。", + "xpack.infra.logs.logEntryCategories.setupTitle": "设置日志类别分析", + "xpack.infra.logs.logEntryCategories.showAnalysisSetupButtonLabel": "ML 设置", "xpack.infra.logs.logEntryCategories.singleCategoryWarningReasonDescription": "分析只能从日志消息中提取单个类别。", "xpack.infra.logs.logEntryCategories.topCategoriesSectionLoadingAriaLabel": "正在加载消息类别", "xpack.infra.logs.logEntryCategories.topCategoriesSectionTitle": "日志消息类别", "xpack.infra.logs.logEntryCategories.trendColumnTitle": "趋势", "xpack.infra.logs.logEntryCategories.truncatedPatternSegmentDescription": "{extraSegmentCount, plural, one {另一个分段} other {另 # 个分段}}", + "xpack.infra.logs.logEntryExamples.exampleEmptyDescription": "选定时间范围内未找到任何示例。增大日志条目保留期限以改善消息样例可用性。", + "xpack.infra.logs.logEntryExamples.exampleEmptyReloadButtonLabel": "重新加载", + "xpack.infra.logs.logEntryExamples.exampleLoadingFailureDescription": "无法加载示例。", + "xpack.infra.logs.logEntryExamples.exampleLoadingFailureRetryButtonLabel": "重试", + "xpack.infra.logs.logEntryRate.setupDescription": "要启用日志异常分析,请设置 Machine Learning 作业", + "xpack.infra.logs.logEntryRate.setupTitle": "设置日志异常分析", + "xpack.infra.logs.logEntryRate.showAnalysisSetupButtonLabel": "ML 设置", "xpack.infra.logs.pluginTitle": "日志", "xpack.infra.logs.scrollableLogTextStreamView.loadingEntriesLabel": "正在加载条目", "xpack.infra.logs.search.nextButtonLabel": "下一个", @@ -7512,6 +8708,9 @@ "xpack.infra.logs.search.searchInLogsAriaLabel": "搜索", "xpack.infra.logs.search.searchInLogsPlaceholder": "搜索", "xpack.infra.logs.searchResultTooltip": "{bucketCount, plural, one {# 个高亮条目} other {# 个高亮条目}}", + "xpack.infra.logs.setupFlyout.logCategoriesDescription": "使用 Machine Learning 自动归类日志消息。", + "xpack.infra.logs.setupFlyout.logCategoriesTitle": "日志类别", + "xpack.infra.logs.setupFlyout.setupFlyoutTitle": "通过 Machine Learning 检测异常", "xpack.infra.logs.showingEntriesFromTimestamp": "正在显示自 {timestamp} 起的条目", "xpack.infra.logs.showingEntriesUntilTimestamp": "正在显示截止于 {timestamp} 的条目", "xpack.infra.logs.startStreamingButtonLabel": "实时流式传输", @@ -7519,6 +8718,9 @@ "xpack.infra.logs.streamingNewEntriesText": "正在流式传输新条目", "xpack.infra.logs.streamLive": "实时流式传输", "xpack.infra.logs.streamPage.documentTitle": "{previousTitle} | 流式传输", + "xpack.infra.logs.viewInContext.logsFromContainerTitle": "显示的日志来自容器 {container}", + "xpack.infra.logs.viewInContext.logsFromFileTitle": "显示的日志来自文件 {file} 和主机 {host}", + "xpack.infra.logsHeaderAddDataButtonLabel": "添加数据", "xpack.infra.logSourceConfiguration.unsavedFormPromptMessage": "是否确定要离开?更改将丢失", "xpack.infra.logsPage.noLoggingIndicesDescription": "让我们添加一些!", "xpack.infra.logsPage.noLoggingIndicesInstructionsActionLabel": "查看设置说明", @@ -7661,9 +8863,17 @@ "xpack.infra.metrics.alertFlyout.aggregationText.sum": "求和", "xpack.infra.metrics.alertFlyout.alertName": "指标阈值", "xpack.infra.metrics.alertFlyout.alertOnNoData": "没数据时提醒我", + "xpack.infra.metrics.alertFlyout.alertPreviewError": "尝试预览此告警条件时发生错误", + "xpack.infra.metrics.alertFlyout.alertPreviewErrorResult": "尝试评估部分数据时发生错误。", + "xpack.infra.metrics.alertFlyout.alertPreviewGroups": "{numberOfGroups} 个{groupName}{plural}", + "xpack.infra.metrics.alertFlyout.alertPreviewGroupsAcross": "在", + "xpack.infra.metrics.alertFlyout.alertPreviewNoDataResult": "存在{were} {noData} 个无数据结果{plural}。", + "xpack.infra.metrics.alertFlyout.alertPreviewResult": "此告警将发生 {firedTimes}", + "xpack.infra.metrics.alertFlyout.alertPreviewResultLookback": "在过去 {lookback}。", "xpack.infra.metrics.alertFlyout.conditions": "条件", "xpack.infra.metrics.alertFlyout.createAlertPerHelpText": "为每个唯一值创建告警。例如:“host.id”或“cloud.region”。", "xpack.infra.metrics.alertFlyout.createAlertPerText": "创建告警时间间隔(可选)", + "xpack.infra.metrics.alertFlyout.dayLabel": "天", "xpack.infra.metrics.alertFlyout.error.aggregationRequired": "“聚合”必填。", "xpack.infra.metrics.alertFlyout.error.metricRequired": "指标必填。", "xpack.infra.metrics.alertFlyout.error.thresholdRequired": "“阈值”必填。", @@ -7677,19 +8887,36 @@ "xpack.infra.metrics.alertFlyout.expression.metric.whenLabel": "当", "xpack.infra.metrics.alertFlyout.filterHelpText": "使用 KQL 表达式限制告警触发器的范围。", "xpack.infra.metrics.alertFlyout.filterLabel": "筛选(可选)", + "xpack.infra.metrics.alertFlyout.firedTime": "次", + "xpack.infra.metrics.alertFlyout.firedTimes": "次", + "xpack.infra.metrics.alertFlyout.hourLabel": "小时", + "xpack.infra.metrics.alertFlyout.lastDayLabel": "昨天", + "xpack.infra.metrics.alertFlyout.lastHourLabel": "上一小时", + "xpack.infra.metrics.alertFlyout.lastMonthLabel": "上个月", + "xpack.infra.metrics.alertFlyout.lastWeekLabel": "上周", + "xpack.infra.metrics.alertFlyout.monthLabel": "个月", "xpack.infra.metrics.alertFlyout.noDataHelpText": "启用此选项可在指标在预期的时间段中未报告任何数据时或告警无法查询 Elasticsearch 时触发操作", "xpack.infra.metrics.alertFlyout.outsideRangeLabel": "不介于", + "xpack.infra.metrics.alertFlyout.previewIntervalTooShortDescription": "尝试选择较长的预览长度或在“{checkEvery}”字段增大时间量。", + "xpack.infra.metrics.alertFlyout.previewIntervalTooShortTitle": "没有足够的数据", + "xpack.infra.metrics.alertFlyout.previewLabel": "预览", "xpack.infra.metrics.alertFlyout.removeCondition": "删除条件", - "xpack.infra.metrics.alerting.inventory.threshold.defaultActionMessage": "\\{\\{alertName\\}\\} - \\{\\{context.group\\}\\}\n\n\\{\\{context.metricOf.condition0\\}\\} 已超过阈值 \\{\\{context.thresholdOf.condition0\\}\\}\n当前值为 \\{\\{context.valueOf.condition0\\}\\}\n", + "xpack.infra.metrics.alertFlyout.testAlertCondition": "测试告警条件", + "xpack.infra.metrics.alertFlyout.tooManyBucketsErrorDescription": "尝试选择较短的预览长度或在“{forTheLast}”字段中增大时间量。", + "xpack.infra.metrics.alertFlyout.tooManyBucketsErrorTitle": "数据过多(>{maxBuckets} 个结果)", + "xpack.infra.metrics.alertFlyout.weekLabel": "周", + "xpack.infra.metrics.alerting.inventory.threshold.defaultActionMessage": "\\{\\{alertName\\}\\} - \\{\\{context.group\\}\\} 处于 \\{\\{context.alertState\\}\\} 状态\n\n原因:\n\\{\\{context.reason\\}\\}\n", "xpack.infra.metrics.alerting.inventory.threshold.fired": "已触发", - "xpack.infra.metrics.alerting.threshold.alerting.alertStateActionVariableDescription": "告警的当前状态", - "xpack.infra.metrics.alerting.threshold.alerting.groupActionVariableDescription": "报告数据的组名称", - "xpack.infra.metrics.alerting.threshold.alerting.metricOfActionVariableDescription": "受监视指标的记录;按条件分组,例如按 metricOf.condition0、metricOf.condition1 等。", - "xpack.infra.metrics.alerting.threshold.alerting.reasonActionVariableDescription": "告警处于此状态的原因描述,包括哪个指标超过哪个阈值", - "xpack.infra.metrics.alerting.threshold.alerting.thresholdOfActionVariableDescription": "告警阈值的记录;按条件分组,例如按thresholdOf.condition0、thresholdOf.condition1 等。", - "xpack.infra.metrics.alerting.threshold.alerting.valueOfActionVariableDescription": "受监视指标当前值的记录;按条件分组,例如按 valueOf.condition0、valueOf.condition1 等。", + "xpack.infra.metrics.alerting.alertStateActionVariableDescription": "告警的当前状态", + "xpack.infra.metrics.alerting.groupActionVariableDescription": "报告数据的组名称", + "xpack.infra.metrics.alerting.metricActionVariableDescription": "受监视指标的记录;按条件分组,例如按 metric.condition0、metric.condition1 等。", + "xpack.infra.metrics.alerting.reasonActionVariableDescription": "告警处于此状态的原因描述,包括哪个指标超过哪个阈值", + "xpack.infra.metrics.alerting.thresholdActionVariableDescription": "告警阈值的记录;按条件分组,例如按threshold.condition0、threshold.condition1 等。", + "xpack.infra.metrics.alerting.valueActionVariableDescription": "受监视指标当前值的记录;按条件分组,例如按 value.condition0、value.condition1 等。", "xpack.infra.metrics.alerting.threshold.alertState": "告警", + "xpack.infra.metrics.alerting.threshold.belowRecovery": "低于", "xpack.infra.metrics.alerting.threshold.betweenComparator": "介于", + "xpack.infra.metrics.alerting.threshold.betweenRecovery": "介于", "xpack.infra.metrics.alerting.threshold.defaultActionMessage": "\\{\\{alertName\\}\\} - \\{\\{context.group\\}\\} 处于 \\{\\{context.alertState\\}\\} 状态\n\n原因:\n\\{\\{context.reason\\}\\}\n", "xpack.infra.metrics.alerting.threshold.documentCount": "文档计数", "xpack.infra.metrics.alerting.threshold.eqComparator": "等于", @@ -7703,6 +8930,7 @@ "xpack.infra.metrics.alerting.threshold.noDataState": "无数据", "xpack.infra.metrics.alerting.threshold.okState": "正常 [已恢复]", "xpack.infra.metrics.alerting.threshold.outsideRangeComparator": "不介于", + "xpack.infra.metrics.alerting.threshold.recoveredAlertReason": "{metric} 现在{comparator}阈值 {threshold}(当前值为 {currentValue})", "xpack.infra.metrics.alerting.threshold.thresholdRange": "{a} 和 {b}", "xpack.infra.metrics.alerts.dataTimeRangeLabel": "过去 {lookback} {timeLabel}", "xpack.infra.metrics.alerts.dataTimeRangeLabelWithGrouping": "{id} 过去 {lookback} {timeLabel}的数据", @@ -7722,6 +8950,7 @@ "xpack.infra.metrics.missingTSVBModelError": "{nodeType} 的 {metricId} TSVB 模型不存在", "xpack.infra.metrics.pluginTitle": "指标", "xpack.infra.metrics.refetchButtonLabel": "检查新数据", + "xpack.infra.metricsExploer.everything": "所有内容", "xpack.infra.metricsExplorer.actionsLabel.aria": "适用于 {grouping} 的操作", "xpack.infra.metricsExplorer.actionsLabel.button": "操作", "xpack.infra.metricsExplorer.aggregationLabel": "的", @@ -7736,6 +8965,7 @@ "xpack.infra.metricsExplorer.aggregationLables.sum": "求和", "xpack.infra.metricsExplorer.aggregationSelectLabel": "选择聚合", "xpack.infra.metricsExplorer.alerts.createAlertButton": "创建告警", + "xpack.infra.metricsExplorer.andLabel": "\" 且 \"", "xpack.infra.metricsExplorer.chartOptions.areaLabel": "面积图", "xpack.infra.metricsExplorer.chartOptions.autoLabel": "自动(最小值到最大值)", "xpack.infra.metricsExplorer.chartOptions.barLabel": "条形图", @@ -7764,6 +8994,7 @@ "xpack.infra.metricsExplorer.noMetrics.title": "缺失指标", "xpack.infra.metricsExplorer.openInTSVB": "在 Visualize 中打开", "xpack.infra.metricsExplorer.viewNodeDetail": "查看 {name} 的指标", + "xpack.infra.metricsHeaderAddDataButtonLabel": "添加数据", "xpack.infra.node.ariaLabel": "{nodeName},单击打开菜单", "xpack.infra.nodeContextMenu.createAlertLink": "创建告警", "xpack.infra.nodeContextMenu.description": "查看 {label} {value} 的详情", @@ -7792,7 +9023,8 @@ "xpack.infra.openView.cancelButton": "取消", "xpack.infra.openView.columnNames.actions": "操作", "xpack.infra.openView.columnNames.name": "名称", - "xpack.infra.openView.flyoutHeader": "加载视图", + "xpack.infra.openView.flyoutHeader": "管理已保存视图", + "xpack.infra.openView.loadButton": "加载视图", "xpack.infra.parseInterval.errorMessage": "{value} 不是时间间隔字符串", "xpack.infra.redirectToNodeLogs.loadingNodeLogsMessage": "正在加载 {nodeType} 日志", "xpack.infra.registerFeatures.infraOpsDescription": "浏览常用服务器、容器和服务的基础设施指标和日志。", @@ -7800,9 +9032,18 @@ "xpack.infra.registerFeatures.logsDescription": "实时流式传输日志或在类似控制台的工具中滚动浏览历史视图。", "xpack.infra.registerFeatures.logsTitle": "日志", "xpack.infra.sampleDataLinkLabel": "日志", + "xpack.infra.savedView.changeView": "更改视图", + "xpack.infra.savedView.currentView": "当前视图", + "xpack.infra.savedView.defaultViewNameHosts": "默认视图", "xpack.infra.savedView.errorOnCreate.duplicateViewName": "具有该名称的视图已存在。", "xpack.infra.savedView.errorOnCreate.title": "保存视图时出错。", "xpack.infra.savedView.findError.title": "加载视图时出错。", + "xpack.infra.savedView.loadView": "加载视图", + "xpack.infra.savedView.manageViews": "管理视图", + "xpack.infra.savedView.saveNewView": "保存新视图", + "xpack.infra.savedView.searchPlaceholder": "搜索已保存视图", + "xpack.infra.savedView.unknownView": "未知", + "xpack.infra.savedView.updateView": "更新视图", "xpack.infra.snapshot.missingSnapshotMetricError": "{nodeType} 的 {metric} 聚合不可用。", "xpack.infra.sourceConfiguration.addLogColumnButtonLabel": "添加列", "xpack.infra.sourceConfiguration.applySettingsButtonLabel": "应用", @@ -7828,7 +9069,7 @@ "xpack.infra.sourceConfiguration.logIndicesRecommendedValue": "推荐值为 {defaultValue}", "xpack.infra.sourceConfiguration.logIndicesTitle": "日志索引", "xpack.infra.sourceConfiguration.messageLogColumnDescription": "此系统字段显示派生自文档字段的日志条目消息。", - "xpack.infra.sourceConfiguration.metricIndicesDescription": "用于匹配包含 Metricbeat 数据的索引的索引模式", + "xpack.infra.sourceConfiguration.metricIndicesDescription": "用于匹配包含指标数据的索引的索引模式", "xpack.infra.sourceConfiguration.metricIndicesLabel": "指标索引", "xpack.infra.sourceConfiguration.metricIndicesRecommendedValue": "推荐值为 {defaultValue}", "xpack.infra.sourceConfiguration.metricIndicesTitle": "指标索引", @@ -7858,6 +9099,7 @@ "xpack.infra.tableView.columnName.last1m": "过去 1 分钟", "xpack.infra.tableView.columnName.max": "最大值", "xpack.infra.tableView.columnName.name": "名称", + "xpack.infra.trialStatus.trialStatusNetworkErrorMessage": "我们无法确定试用许可证是否可用", "xpack.infra.useHTTPRequest.error.status": "错误", "xpack.infra.useHTTPRequest.error.title": "提取资源时出错", "xpack.infra.useHTTPRequest.error.url": "URL", @@ -7865,6 +9107,7 @@ "xpack.infra.viewSwitcher.mapViewLabel": "地图视图", "xpack.infra.viewSwitcher.tableViewLabel": "表视图", "xpack.infra.waffle.accountAllTitle": "全部", + "xpack.infra.waffle.accountLabel": "帐户", "xpack.infra.waffle.aggregationNames.avg": "“{field}”的平均值", "xpack.infra.waffle.aggregationNames.max": "“{field}”的最大值", "xpack.infra.waffle.aggregationNames.min": "“{field}”的最小值", @@ -7900,8 +9143,10 @@ "xpack.infra.waffle.customMetrics.modeSwitcher.saveButtonAriaLabel": "保存定制指标的更改", "xpack.infra.waffle.customMetrics.submitLabel": "保存", "xpack.infra.waffle.groupByAllTitle": "全部", + "xpack.infra.waffle.groupByLabel": "分组依据", "xpack.infra.waffle.loadingDataText": "正在加载数据", "xpack.infra.waffle.maxGroupByTooltip": "一次只能选择两个分组", + "xpack.infra.waffle.metriclabel": "指标", "xpack.infra.waffle.metricOptions.countText": "计数", "xpack.infra.waffle.metricOptions.cpuUsageText": "CPU 使用", "xpack.infra.waffle.metricOptions.diskIOReadBytes": "磁盘读取", @@ -7928,7 +9173,10 @@ "xpack.infra.waffle.noDataDescription": "尝试调整您的时间或筛选。", "xpack.infra.waffle.noDataTitle": "没有可显示的数据。", "xpack.infra.waffle.region": "全部", + "xpack.infra.waffle.regionLabel": "地区", "xpack.infra.waffle.savedView.createHeader": "保存视图", + "xpack.infra.waffle.savedView.selectViewHeader": "选择要加载的视图", + "xpack.infra.waffle.savedView.updateHeader": "更新视图", "xpack.infra.waffle.savedViews.cancel": "取消", "xpack.infra.waffle.savedViews.cancelButton": "取消", "xpack.infra.waffle.savedViews.includeTimeFilterLabel": "将时间与视图一起存储", @@ -7936,6 +9184,11 @@ "xpack.infra.waffle.savedViews.saveButton": "保存", "xpack.infra.waffle.savedViews.viewNamePlaceholder": "名称", "xpack.infra.waffle.selectTwoGroupingsTitle": "选择最多两个分组", + "xpack.infra.waffle.showLabel": "显示", + "xpack.infra.waffle.sort.valueLabel": "指标值", + "xpack.infra.waffle.sortDirectionLabel": "反向", + "xpack.infra.waffle.sortLabel": "排序依据", + "xpack.infra.waffle.sortNameLabel": "名称", "xpack.infra.waffle.unableToSelectGroupErrorMessage": "无法选择 {nodeType} 的分组依据选项", "xpack.infra.waffle.unableToSelectMetricErrorTitle": "无法选择指标选项或指标值。", "xpack.infra.waffleTime.autoRefreshButtonLabel": "自动刷新", @@ -7946,6 +9199,10 @@ "xpack.ingestManager.agentConfig.confirmModalDescription": "此操作无法撤消。是否确定要继续?", "xpack.ingestManager.agentConfig.confirmModalTitle": "保存并部署更改", "xpack.ingestManager.agentConfig.linkedAgentCountText": "{count, plural, one {# 个代理} other {# 个代理}}", + "xpack.ingestManager.agentConfigActionMenu.buttonText": "操作", + "xpack.ingestManager.agentConfigActionMenu.copyConfigActionText": "复制配置", + "xpack.ingestManager.agentConfigActionMenu.enrollAgentActionText": "添加代理", + "xpack.ingestManager.agentConfigActionMenu.viewConfigText": "查看配置", "xpack.ingestManager.agentConfigForm.advancedOptionsToggleLabel": "高级选项", "xpack.ingestManager.agentConfigForm.descriptionFieldLabel": "描述", "xpack.ingestManager.agentConfigForm.descriptionFieldPlaceholder": "此配置将如何使用?", @@ -7956,11 +9213,12 @@ "xpack.ingestManager.agentConfigForm.nameFieldLabel": "名称", "xpack.ingestManager.agentConfigForm.nameFieldPlaceholder": "选择名称", "xpack.ingestManager.agentConfigForm.nameRequiredErrorMessage": "“代理配置名称”必填", - "xpack.ingestManager.agentConfigForm.namespaceFieldDescription": "将默认命名空间应用于使用此配置的数据源。数据源可以指定自己的命名空间。", + "xpack.ingestManager.agentConfigForm.namespaceFieldDescription": "将默认命名空间应用于使用此配置的集成。集成可以指定自己的命名空间。", "xpack.ingestManager.agentConfigForm.namespaceFieldLabel": "默认命名空间", + "xpack.ingestManager.agentConfigForm.namespaceRequiredErrorMessage": "命名空间必填", "xpack.ingestManager.agentConfigForm.systemMonitoringFieldLabel": "可选", "xpack.ingestManager.agentConfigForm.systemMonitoringText": "收集系统指标", - "xpack.ingestManager.agentConfigForm.systemMonitoringTooltipText": "启用此选项可使用收集系统指标和信息的数据源启动您的配置。", + "xpack.ingestManager.agentConfigForm.systemMonitoringTooltipText": "启用此选项可使用收集系统指标和信息的集成启动您的配置。", "xpack.ingestManager.agentConfigList.actionsColumnTitle": "操作", "xpack.ingestManager.agentConfigList.addButton": "创建代理配置", "xpack.ingestManager.agentConfigList.agentsColumnTitle": "代理", @@ -7970,6 +9228,7 @@ "xpack.ingestManager.agentConfigList.nameColumnTitle": "名称", "xpack.ingestManager.agentConfigList.noAgentConfigsPrompt": "无代理配置", "xpack.ingestManager.agentConfigList.noFilteredAgentConfigsPrompt": "找不到代理配置。{clearFiltersLink}", + "xpack.ingestManager.agentConfigList.packageConfigsCountColumnTitle": "集成", "xpack.ingestManager.agentConfigList.pageSubtitle": "使用代理配置管理代理和它们收集的数据。", "xpack.ingestManager.agentConfigList.pageTitle": "代理配置", "xpack.ingestManager.agentConfigList.reloadAgentConfigsButtonText": "重新加载", @@ -7992,16 +9251,30 @@ "xpack.ingestManager.agentDetails.unexceptedErrorTitle": "加载代理时出错", "xpack.ingestManager.agentDetails.userProvidedMetadataSectionSubtitle": "用户提供的元数据", "xpack.ingestManager.agentDetails.versionLabel": "代理版本", - "xpack.ingestManager.agentDetails.viewAgentListTitle": "查看所有代理配置", + "xpack.ingestManager.agentDetails.viewAgentListTitle": "查看所有代理", "xpack.ingestManager.agentEnrollment.cancelButtonLabel": "取消", "xpack.ingestManager.agentEnrollment.continueButtonLabel": "继续", - "xpack.ingestManager.agentEnrollment.downloadLink": "下载页面", + "xpack.ingestManager.agentEnrollment.copyConfigurationButton": "复制到剪贴板", + "xpack.ingestManager.agentEnrollment.copyRunInstructionsButton": "复制到剪贴板", + "xpack.ingestManager.agentEnrollment.downloadConfigurationButton": "下载配置", + "xpack.ingestManager.agentEnrollment.downloadDescription": "在主机计算机上下载 Elastic 代理。可以从 Elastic 代理下载页面访问代理二进制文件及其验证签名。", + "xpack.ingestManager.agentEnrollment.downloadLink": "前往 elastic.co/downloads", + "xpack.ingestManager.agentEnrollment.enrollFleetTabLabel": "注册到 Fleet", + "xpack.ingestManager.agentEnrollment.enrollStandaloneTabLabel": "独立模式", "xpack.ingestManager.agentEnrollment.fleetNotInitializedText": "注册代理前需要设置 Fleet。{link}", - "xpack.ingestManager.agentEnrollment.flyoutTitle": "注册新代理", + "xpack.ingestManager.agentEnrollment.flyoutTitle": "添加代理", "xpack.ingestManager.agentEnrollment.goToFleetButton": "前往 Fleet。", + "xpack.ingestManager.agentEnrollment.managedDescription": "无论是需要一个代理还是需要数以千计的代理,Fleet 允许您轻松地集中管理并部署代理的更新。按照下面的说明下载 Elastic 代理并将代理注册到 Fleet。", + "xpack.ingestManager.agentEnrollment.standaloneDescription": "如果希望对以独立模式运行的代理进行配置更改,则需要手动更新。按照下面的说明下载并设置独立模式的 Elastic 代理。", + "xpack.ingestManager.agentEnrollment.stepCheckForDataDescription": "启动代理后,代理应开始发送数据。您可以在采集管理器的数据集页面查看此数据。", + "xpack.ingestManager.agentEnrollment.stepCheckForDataTitle": "检查数据", "xpack.ingestManager.agentEnrollment.stepChooseAgentConfigTitle": "选择代理配置", + "xpack.ingestManager.agentEnrollment.stepConfigureAgentDescription": "在安装 Elastic 代理的系统上复制此配置并将其放入名为 {fileName} 的文件中。切勿忘记修改配置文件中 {outputSection} 部分的{ESUsernameVariable} 和 {ESPasswordVariable},以便其使用您的实际 Elasticsearch 凭据。", + "xpack.ingestManager.agentEnrollment.stepConfigureAgentTitle": "配置代理", "xpack.ingestManager.agentEnrollment.stepDownloadAgentTitle": "下载 Elastic 代理", - "xpack.ingestManager.agentEnrollment.stepRunAgentTitle": "注册并运行 Elastic 代理", + "xpack.ingestManager.agentEnrollment.stepEnrollAndRunAgentTitle": "注册并启动 Elastic 代理", + "xpack.ingestManager.agentEnrollment.stepRunAgentDescription": "从代理的目录中,运行以下命令以启动代理。", + "xpack.ingestManager.agentEnrollment.stepRunAgentTitle": "启动代理", "xpack.ingestManager.agentEventsList.collapseDetailsAriaLabel": "隐藏详情", "xpack.ingestManager.agentEventsList.expandDetailsAriaLabel": "显示详情", "xpack.ingestManager.agentEventsList.messageColumnTitle": "消息", @@ -8027,18 +9300,21 @@ "xpack.ingestManager.agentEventType.errorLabel": "错误", "xpack.ingestManager.agentEventType.stateLabel": "状态", "xpack.ingestManager.agentHealth.checkInTooltipText": "上次签入时间 {lastCheckIn}", + "xpack.ingestManager.agentHealth.degradedStatusText": "已降级", + "xpack.ingestManager.agentHealth.enrollingStatusText": "正在注册", "xpack.ingestManager.agentHealth.errorStatusText": "错误", "xpack.ingestManager.agentHealth.inactiveStatusText": "非活动", "xpack.ingestManager.agentHealth.noCheckInTooltipText": "未签入", "xpack.ingestManager.agentHealth.offlineStatusText": "脱机", "xpack.ingestManager.agentHealth.onlineStatusText": "联机", + "xpack.ingestManager.agentHealth.unenrollingStatusText": "正在取消注册", "xpack.ingestManager.agentHealth.warningStatusText": "错误", "xpack.ingestManager.agentList.actionsColumnTitle": "操作", - "xpack.ingestManager.agentList.addButton": "注册新代理", + "xpack.ingestManager.agentList.addButton": "添加代理", "xpack.ingestManager.agentList.clearFiltersLinkText": "清除筛选", - "xpack.ingestManager.agentList.configColumnTitle": "配置", - "xpack.ingestManager.agentList.configFilterText": "配置", - "xpack.ingestManager.agentList.enrollButton": "注册新代理", + "xpack.ingestManager.agentList.configColumnTitle": "代理配置", + "xpack.ingestManager.agentList.configFilterText": "代理配置", + "xpack.ingestManager.agentList.enrollButton": "添加代理", "xpack.ingestManager.agentList.hostColumnTitle": "主机", "xpack.ingestManager.agentList.lastCheckinTitle": "上次活动", "xpack.ingestManager.agentList.loadingAgentsMessage": "正在加载代理……", @@ -8061,70 +9337,118 @@ "xpack.ingestManager.agentListStatus.onlineLabel": "联机", "xpack.ingestManager.agentListStatus.totalLabel": "代理", "xpack.ingestManager.agentReassignConfig.cancelButtonLabel": "取消", - "xpack.ingestManager.agentReassignConfig.configDescription": "选定代理配置将收集 {count, plural, one {{countValue} 个数据源} other {{countValue} 个数据源}}的数据:", + "xpack.ingestManager.agentReassignConfig.configDescription": "选定代理配置将收集 {count, plural, one {{countValue} 个集成} other {{countValue} 个集成}}的数据:", "xpack.ingestManager.agentReassignConfig.continueButtonLabel": "分配配置", "xpack.ingestManager.agentReassignConfig.flyoutDescription": "选择要为选定代理分配的新代理配置。", "xpack.ingestManager.agentReassignConfig.flyoutTitle": "分配新代理配置", "xpack.ingestManager.agentReassignConfig.selectConfigLabel": "代理配置", "xpack.ingestManager.agentReassignConfig.successSingleNotificationTitle": "代理配置已重新分配", - "xpack.ingestManager.alphaMessageDescription": "Ingest Manager 仍处于开发状态,不适用于生产用途。", - "xpack.ingestManager.alphaMessageTitle": "实验性", + "xpack.ingestManager.alphaMessageDescription": "不推荐在生产环境中使用采集管理器。", + "xpack.ingestManager.alphaMessageLinkText": "查看更多详情。", + "xpack.ingestManager.alphaMessageTitle": "公测版", "xpack.ingestManager.alphaMessaging.docsLink": "文档", "xpack.ingestManager.alphaMessaging.feedbackText": "建议您阅读我们的“{docsLink}”或在我们的{forumLink}提问题或发送反馈。", "xpack.ingestManager.alphaMessaging.flyoutTitle": "关于本版本", "xpack.ingestManager.alphaMessaging.forumLink": "讨论论坛", - "xpack.ingestManager.alphaMessaging.introText": "本版本为实验性版本,不受支持 SLA 的约束。其用于用户测试 Ingest Manager 和新 Elastic 代理并提供相关反馈。因为在未来版本中可能更改或移除某些功能,所以不适用于生产环境。", + "xpack.ingestManager.alphaMessaging.introText": "采集管理器仍处于开发状态,不适用于生产环境。此公测版用于用户测试采集管理器和新 Elastic 代理并提供相关反馈。此插件不受支持 SLA 的约束。", "xpack.ingestManager.alphaMessging.closeFlyoutLabel": "关闭", "xpack.ingestManager.appNavigation.configurationsLinkText": "配置", - "xpack.ingestManager.appNavigation.dataStreamsLinkText": "数据流", + "xpack.ingestManager.appNavigation.dataStreamsLinkText": "数据集", "xpack.ingestManager.appNavigation.epmLinkText": "集成", "xpack.ingestManager.appNavigation.fleetLinkText": "Fleet", "xpack.ingestManager.appNavigation.overviewLinkText": "概览", "xpack.ingestManager.appNavigation.sendFeedbackButton": "发送反馈", "xpack.ingestManager.appNavigation.settingsButton": "设置", "xpack.ingestManager.appTitle": "Ingest Manager", + "xpack.ingestManager.betaBadge.labelText": "公测版", + "xpack.ingestManager.betaBadge.tooltipText": "不推荐在生产环境中使用此插件。请在我们讨论论坛中报告错误。", + "xpack.ingestManager.breadcrumbs.addPackageConfigPageTitle": "添加集成", + "xpack.ingestManager.breadcrumbs.allIntegrationsPageTitle": "全部", + "xpack.ingestManager.breadcrumbs.appTitle": "采集管理器", + "xpack.ingestManager.breadcrumbs.configurationsPageTitle": "配置", + "xpack.ingestManager.breadcrumbs.datastreamsPageTitle": "数据集", + "xpack.ingestManager.breadcrumbs.editPackageConfigPageTitle": "编辑集成", + "xpack.ingestManager.breadcrumbs.fleetAgentsPageTitle": "代理", + "xpack.ingestManager.breadcrumbs.fleetEnrollmentTokensPageTitle": "注册令牌", + "xpack.ingestManager.breadcrumbs.fleetPageTitle": "Fleet", + "xpack.ingestManager.breadcrumbs.installedIntegrationsPageTitle": "已安装", + "xpack.ingestManager.breadcrumbs.integrationsPageTitle": "集成", + "xpack.ingestManager.breadcrumbs.overviewPageTitle": "概览", + "xpack.ingestManager.configDetails.addPackageConfigButtonText": "添加集成", "xpack.ingestManager.configDetails.configDetailsTitle": "配置“{id}”", "xpack.ingestManager.configDetails.configNotFoundErrorTitle": "未找到配置“{id}”", + "xpack.ingestManager.configDetails.packageConfigsTable.actionsColumnTitle": "操作", + "xpack.ingestManager.configDetails.packageConfigsTable.deleteActionTitle": "删除集成", + "xpack.ingestManager.configDetails.packageConfigsTable.descriptionColumnTitle": "描述", + "xpack.ingestManager.configDetails.packageConfigsTable.editActionTitle": "编辑集成", + "xpack.ingestManager.configDetails.packageConfigsTable.nameColumnTitle": "名称", + "xpack.ingestManager.configDetails.packageConfigsTable.namespaceColumnTitle": "命名空间", + "xpack.ingestManager.configDetails.packageConfigsTable.packageNameColumnTitle": "集成", + "xpack.ingestManager.configDetails.subTabs.packageConfigsTabText": "集成", "xpack.ingestManager.configDetails.subTabs.settingsTabText": "设置", "xpack.ingestManager.configDetails.summary.lastUpdated": "最后更新时间", + "xpack.ingestManager.configDetails.summary.package_configs": "集成", "xpack.ingestManager.configDetails.summary.revision": "修订", "xpack.ingestManager.configDetails.summary.usedBy": "使用者", "xpack.ingestManager.configDetails.unexceptedErrorTitle": "加载配置时发生错误", "xpack.ingestManager.configDetails.viewAgentListTitle": "查看所有代理配置", + "xpack.ingestManager.configDetails.yamlDownloadButtonLabel": "下载配置", + "xpack.ingestManager.configDetails.yamlFlyoutCloseButtonLabel": "关闭", + "xpack.ingestManager.configDetails.yamlflyoutTitleWithName": "“{name}”代理配置", + "xpack.ingestManager.configDetails.yamlflyoutTitleWithoutName": "代理配置", + "xpack.ingestManager.configDetailsPackageConfigs.createFirstButtonText": "添加集成", + "xpack.ingestManager.configDetailsPackageConfigs.createFirstMessage": "此配置尚未有任何集成。", + "xpack.ingestManager.configDetailsPackageConfigs.createFirstTitle": "添加您的首个集成", "xpack.ingestManager.configForm.deleteConfigActionText": "删除配置", "xpack.ingestManager.configForm.deleteConfigGroupDescription": "将不会删除现有数据。", "xpack.ingestManager.configForm.deleteConfigGroupTitle": "删除配置", "xpack.ingestManager.configForm.generalSettingsGroupDescription": "为您的代理配置选择名称和描述。", "xpack.ingestManager.configForm.generalSettingsGroupTitle": "常规设置", "xpack.ingestManager.configForm.unableToDeleteDefaultConfigText": "无法删除默认配置", + "xpack.ingestManager.copyAgentConfig.confirmModal.cancelButtonLabel": "取消", + "xpack.ingestManager.copyAgentConfig.confirmModal.confirmButtonLabel": "复制配置", + "xpack.ingestManager.copyAgentConfig.confirmModal.copyConfigPrompt": "为您的新代理配置选择名称和描述。", + "xpack.ingestManager.copyAgentConfig.confirmModal.copyConfigTitle": "复制“{name}”代理配置", + "xpack.ingestManager.copyAgentConfig.confirmModal.defaultNewConfigName": "{name}(副本)", + "xpack.ingestManager.copyAgentConfig.confirmModal.newDescriptionLabel": "描述", + "xpack.ingestManager.copyAgentConfig.confirmModal.newNameLabel": "新配置名称", + "xpack.ingestManager.copyAgentConfig.failureNotificationTitle": "复制代理配置“{id}”时出错", + "xpack.ingestManager.copyAgentConfig.fatalErrorNotificationTitle": "复制代理配置时出错", + "xpack.ingestManager.copyAgentConfig.successNotificationTitle": "代理配置已复制", "xpack.ingestManager.createAgentConfig.cancelButtonLabel": "取消", "xpack.ingestManager.createAgentConfig.errorNotificationTitle": "无法创建代理配置", "xpack.ingestManager.createAgentConfig.flyoutTitle": "创建代理配置", - "xpack.ingestManager.createAgentConfig.flyoutTitleDescription": "代理配置用于管理整个代理组的设置。您可以将数据源添加到代理配置以指定代理收集的数据。编辑代理配置时,可以使用 Fleet 将更新部署到指定的代理组。", + "xpack.ingestManager.createAgentConfig.flyoutTitleDescription": "代理配置用于管理整个代理组的设置。您可以将集成添加到代理配置以指定代理收集的数据。编辑代理配置时,可以使用 Fleet 将更新部署到指定的代理组。", "xpack.ingestManager.createAgentConfig.submitButtonLabel": "创建代理配置", "xpack.ingestManager.createAgentConfig.successNotificationTitle": "代理配置“{name}”已创建", "xpack.ingestManager.createPackageConfig.addedNotificationMessage": "Fleet 会将更新部署到所有使用配置“{agentConfigName}”的代理", "xpack.ingestManager.createPackageConfig.addedNotificationTitle": "已成功添加“{packageConfigName}”", - "xpack.ingestManager.createPackageConfig.agentConfigurationNameLabel": "配置", + "xpack.ingestManager.createPackageConfig.agentConfigurationNameLabel": "代理配置", "xpack.ingestManager.createPackageConfig.cancelButton": "取消", "xpack.ingestManager.createPackageConfig.cancelLinkText": "取消", - "xpack.ingestManager.createPackageConfig.pageDescriptionfromConfig": "按照下面的说明将集成添加此代理配置。", - "xpack.ingestManager.createPackageConfig.pageDescriptionfromPackage": "按照下面的说明将此集成添加代理配置。", - "xpack.ingestManager.createPackageConfig.pageTitle": "添加数据源", - "xpack.ingestManager.createPackageConfig.saveButton": "保存数据源", - "xpack.ingestManager.createPackageConfig.stepConfigurePackageConfigTitle": "选择要收集的数据", + "xpack.ingestManager.createPackageConfig.errorOnSaveText": "您的集成配置有错误。请在保存前进行修复。", + "xpack.ingestManager.createPackageConfig.pageDescriptionfromConfig": "配置选定代理配置的集成。", + "xpack.ingestManager.createPackageConfig.pageDescriptionfromPackage": "按照下面的说明将此集成添加到代理配置。", + "xpack.ingestManager.createPackageConfig.pageTitle": "添加集成", + "xpack.ingestManager.createPackageConfig.pageTitleWithPackageName": "添加 {packageName} 集成", + "xpack.ingestManager.createPackageConfig.saveButton": "保存集成", "xpack.ingestManager.createPackageConfig.stepConfigure.advancedOptionsToggleLinkText": "高级选项", - "xpack.ingestManager.createPackageConfig.stepConfigure.packageConfigDescriptionInputLabel": "描述", - "xpack.ingestManager.createPackageConfig.stepConfigure.packageConfigNameInputLabel": "数据源名称", - "xpack.ingestManager.createPackageConfig.stepConfigure.packageConfigNamespaceInputLabel": "命名空间", - "xpack.ingestManager.createPackageConfig.stepConfigure.hideStreamsAriaLabel": "隐藏 {type} 流", - "xpack.ingestManager.createPackageConfig.stepConfigure.inputSettingsDescription": "以下设置适用于所有流。", + "xpack.ingestManager.createPackageConfig.stepConfigure.errorCountText": "{count, plural, one {# 个错误} other {# 个错误}}", + "xpack.ingestManager.createPackageConfig.stepConfigure.hideStreamsAriaLabel": "隐藏 {type} 输入", + "xpack.ingestManager.createPackageConfig.stepConfigure.inputSettingsDescription": "以下设置适用于下面的所有输入。", "xpack.ingestManager.createPackageConfig.stepConfigure.inputSettingsTitle": "设置", "xpack.ingestManager.createPackageConfig.stepConfigure.inputVarFieldOptionalLabel": "可选", + "xpack.ingestManager.createPackageConfig.stepConfigure.integrationSettingsSectionDescription": "选择有助于确定如何使用此集成的名称和描述。", + "xpack.ingestManager.createPackageConfig.stepConfigure.integrationSettingsSectionTitle": "集成设置", "xpack.ingestManager.createPackageConfig.stepConfigure.noConfigOptionsMessage": "没有可配置的内容", - "xpack.ingestManager.createPackageConfig.stepConfigure.showStreamsAriaLabel": "显示 {type} 流", + "xpack.ingestManager.createPackageConfig.stepConfigure.packageConfigDescriptionInputLabel": "描述", + "xpack.ingestManager.createPackageConfig.stepConfigure.packageConfigNameInputLabel": "集成名称", + "xpack.ingestManager.createPackageConfig.stepConfigure.packageConfigNamespaceInputLabel": "命名空间", + "xpack.ingestManager.createPackageConfig.stepConfigure.showStreamsAriaLabel": "显示 {type} 输入", "xpack.ingestManager.createPackageConfig.stepConfigure.toggleAdvancedOptionsButtonText": "高级选项", + "xpack.ingestManager.createPackageConfig.stepConfigurePackageConfigTitle": "配置集成", "xpack.ingestManager.createPackageConfig.stepSelectAgentConfigTitle": "选择代理配置", + "xpack.ingestManager.createPackageConfig.StepSelectConfig.addButton": "新建代理配置", "xpack.ingestManager.createPackageConfig.StepSelectConfig.agentConfigAgentsCountText": "{count, plural, one {# 个代理} other {# 个代理}}", "xpack.ingestManager.createPackageConfig.StepSelectConfig.errorLoadingAgentConfigsTitle": "加载代理配置时出错", "xpack.ingestManager.createPackageConfig.StepSelectConfig.errorLoadingPackageTitle": "加载软件包信息时出错", @@ -8135,22 +9459,18 @@ "xpack.ingestManager.createPackageConfig.stepSelectPackage.errorLoadingSelectedPackageTitle": "加载选定集成时出错", "xpack.ingestManager.createPackageConfig.stepSelectPackage.filterPackagesInputPlaceholder": "搜索集成", "xpack.ingestManager.createPackageConfig.stepSelectPackageTitle": "选择集成", - "xpack.ingestManager.packageConfigValidation.invalidArrayErrorMessage": "格式无效", - "xpack.ingestManager.packageConfigValidation.invalidYamlFormatErrorMessage": "YAML 格式无效", - "xpack.ingestManager.packageConfigValidation.nameRequiredErrorMessage": "“名称”必填", - "xpack.ingestManager.packageConfigValidation.requiredErrorMessage": "“{fieldName}”必填", "xpack.ingestManager.dataStreamList.actionsColumnTitle": "操作", "xpack.ingestManager.dataStreamList.datasetColumnTitle": "数据集", "xpack.ingestManager.dataStreamList.integrationColumnTitle": "集成", "xpack.ingestManager.dataStreamList.lastActivityColumnTitle": "上次活动", - "xpack.ingestManager.dataStreamList.loadingDataStreamsMessage": "正在加载数据流……", + "xpack.ingestManager.dataStreamList.loadingDataStreamsMessage": "正在加载数据集……", "xpack.ingestManager.dataStreamList.namespaceColumnTitle": "命名空间", - "xpack.ingestManager.dataStreamList.noDataStreamsPrompt": "无数据流", - "xpack.ingestManager.dataStreamList.noFilteredDataStreamsMessage": "找不到匹配的数据流", + "xpack.ingestManager.dataStreamList.noDataStreamsPrompt": "无数据集", + "xpack.ingestManager.dataStreamList.noFilteredDataStreamsMessage": "找不到匹配的数据集", "xpack.ingestManager.dataStreamList.pageSubtitle": "管理您的代理创建的数据。", - "xpack.ingestManager.dataStreamList.pageTitle": "数据流", + "xpack.ingestManager.dataStreamList.pageTitle": "数据集", "xpack.ingestManager.dataStreamList.reloadDataStreamsButtonText": "重新加载", - "xpack.ingestManager.dataStreamList.searchPlaceholderTitle": "筛选数据流", + "xpack.ingestManager.dataStreamList.searchPlaceholderTitle": "筛选数据集", "xpack.ingestManager.dataStreamList.sizeColumnTitle": "大小", "xpack.ingestManager.dataStreamList.typeColumnTitle": "类型", "xpack.ingestManager.dataStreamList.viewDashboardActionText": "查看仪表板", @@ -8168,6 +9488,19 @@ "xpack.ingestManager.deleteAgentConfig.failureSingleNotificationTitle": "删除代理配置“{id}”时出错", "xpack.ingestManager.deleteAgentConfig.fatalErrorNotificationTitle": "删除代理配置时出错", "xpack.ingestManager.deleteAgentConfig.successSingleNotificationTitle": "已删除代理配置“{id}”", + "xpack.ingestManager.deletePackageConfig.confirmModal.affectedAgentsMessage": "Fleet 已检测到 {agentConfigName} 已由您的部分代理使用。", + "xpack.ingestManager.deletePackageConfig.confirmModal.affectedAgentsTitle": "此操作将影响 {agentsCount} 个{agentsCount, plural, one {代理} other {代理}}。", + "xpack.ingestManager.deletePackageConfig.confirmModal.cancelButtonLabel": "取消", + "xpack.ingestManager.deletePackageConfig.confirmModal.confirmButtonLabel": "删除{agentConfigsCount, plural, one {集成} other {集成}}", + "xpack.ingestManager.deletePackageConfig.confirmModal.deleteMultipleTitle": "删除{count, plural, one {集成} other {# 个集成}}?", + "xpack.ingestManager.deletePackageConfig.confirmModal.generalMessage": "此操作无法撤消。是否确定要继续?", + "xpack.ingestManager.deletePackageConfig.confirmModal.loadingAgentsCountMessage": "正在检查受影响的代理……", + "xpack.ingestManager.deletePackageConfig.confirmModal.loadingButtonLabel": "正在加载……", + "xpack.ingestManager.deletePackageConfig.failureMultipleNotificationTitle": "删除 {count} 个集成时出错", + "xpack.ingestManager.deletePackageConfig.failureSingleNotificationTitle": "删除集成“{id}”时出错", + "xpack.ingestManager.deletePackageConfig.fatalErrorNotificationTitle": "删除集成时出错", + "xpack.ingestManager.deletePackageConfig.successMultipleNotificationTitle": "已删除 {count} 个集成", + "xpack.ingestManager.deletePackageConfig.successSingleNotificationTitle": "已删除集成“{id}”", "xpack.ingestManager.disabledSecurityDescription": "必须在 Kibana 和 Elasticsearch 启用安全性,才能使用 Elastic Fleet。", "xpack.ingestManager.disabledSecurityTitle": "安全性未启用", "xpack.ingestManager.editAgentConfig.cancelButtonText": "取消", @@ -8177,17 +9510,18 @@ "xpack.ingestManager.editAgentConfig.successNotificationTitle": "已成功更新“{name}”设置", "xpack.ingestManager.editAgentConfig.unsavedChangesText": "您有未保存更改", "xpack.ingestManager.editPackageConfig.cancelButton": "取消", - "xpack.ingestManager.editPackageConfig.errorLoadingDataMessage": "加载此数据源信息时出错", + "xpack.ingestManager.editPackageConfig.errorLoadingDataMessage": "加载此集成信息时出错", "xpack.ingestManager.editPackageConfig.errorLoadingDataTitle": "加载数据时出错", - "xpack.ingestManager.editPackageConfig.pageDescription": "按照下面的说明编辑此数据源。", - "xpack.ingestManager.editPackageConfig.pageTitle": "编辑数据源", - "xpack.ingestManager.editPackageConfig.saveButton": "保存数据源", + "xpack.ingestManager.editPackageConfig.failedConflictNotificationMessage": "数据已过时。刷新页面以获取最新的配置。", + "xpack.ingestManager.editPackageConfig.failedNotificationTitle": "更新“{packageConfigName}”时出错", + "xpack.ingestManager.editPackageConfig.pageDescription": "修改集成设置并将更改部署到选定代理配置。", + "xpack.ingestManager.editPackageConfig.pageTitle": "编辑集成", + "xpack.ingestManager.editPackageConfig.pageTitleWithPackageName": "编辑 {packageName} 集成", + "xpack.ingestManager.editPackageConfig.saveButton": "保存集成", "xpack.ingestManager.editPackageConfig.updatedNotificationMessage": "Fleet 会将更新部署到所有使用配置“{agentConfigName}”的代理", "xpack.ingestManager.editPackageConfig.updatedNotificationTitle": "已成功更新“{packageConfigName}”", "xpack.ingestManager.enrollemntAPIKeyList.emptyMessage": "未找到任何注册令牌。", "xpack.ingestManager.enrollemntAPIKeyList.loadingTokensMessage": "正在加载注册令牌......", - "xpack.ingestManager.enrollmentInstructions.copyButton": "复制命令", - "xpack.ingestManager.enrollmentInstructions.descriptionText": "从代理的目录,运行这些命令以注册并启动 Elastic 代理。{enrollCommand} 将写入代理的配置文件,以便其具有正确的设置。可以使用此命令在多个主机上设置代理。", "xpack.ingestManager.enrollmentStepAgentConfig.configSelectAriaLabel": "代理配置", "xpack.ingestManager.enrollmentStepAgentConfig.configSelectLabel": "代理配置", "xpack.ingestManager.enrollmentStepAgentConfig.enrollmentTokenSelectLabel": "注册令牌", @@ -8198,22 +9532,32 @@ "xpack.ingestManager.enrollmentTokenDeleteModal.title": "删除注册令牌", "xpack.ingestManager.enrollmentTokensList.actionsTitle": "操作", "xpack.ingestManager.enrollmentTokensList.activeTitle": "活动", - "xpack.ingestManager.enrollmentTokensList.configTitle": "配置", + "xpack.ingestManager.enrollmentTokensList.configTitle": "代理配置", "xpack.ingestManager.enrollmentTokensList.createdAtTitle": "创建日期", "xpack.ingestManager.enrollmentTokensList.nameTitle": "名称", "xpack.ingestManager.enrollmentTokensList.newKeyButton": "新建注册令牌", "xpack.ingestManager.enrollmentTokensList.pageDescription": "这是可用于注册代理的注册令牌列表。", "xpack.ingestManager.enrollmentTokensList.secretTitle": "密钥", + "xpack.ingestManager.epm.addPackageConfigButtonText": "添加 {packageName}", "xpack.ingestManager.epm.browseAllButtonText": "浏览所有集成", - "xpack.ingestManager.epm.illustrationAltText": "Elastic 集成的图示", + "xpack.ingestManager.epm.illustrationAltText": "集成的图示", + "xpack.ingestManager.epm.loadingIntegrationErrorTitle": "加载集成详情时出错", "xpack.ingestManager.epm.packageDetailsNav.overviewLinkText": "概览", + "xpack.ingestManager.epm.packageDetailsNav.packageConfigsLinkText": "使用情况", "xpack.ingestManager.epm.packageDetailsNav.settingsLinkText": "设置", "xpack.ingestManager.epm.pageSubtitle": "浏览集成以了解热门应用和服务。", - "xpack.ingestManager.epm.pageTitle": "Elastic 集成", + "xpack.ingestManager.epm.pageTitle": "集成", + "xpack.ingestManager.epm.releaseBadge.betaDescription": "在生产环境中不推荐使用此集成。", + "xpack.ingestManager.epm.releaseBadge.betaLabel": "公测版", + "xpack.ingestManager.epm.releaseBadge.experimentalDescription": "此集成可能有重大更改或将在未来版本中移除。", + "xpack.ingestManager.epm.releaseBadge.experimentalLabel": "实验性", + "xpack.ingestManager.epm.screenshotsTitle": "屏幕截图", + "xpack.ingestManager.epm.updateAvailableTooltip": "有可用更新", + "xpack.ingestManager.epm.versionLabel": "版本", "xpack.ingestManager.epmList.allFilterLinkText": "全部", "xpack.ingestManager.epmList.allPackagesFilterLinkText": "全部", "xpack.ingestManager.epmList.allTabText": "所有集成", - "xpack.ingestManager.epmList.allTitle": "所有集成", + "xpack.ingestManager.epmList.allTitle": "按类别浏览", "xpack.ingestManager.epmList.installedTabText": "已安装集成", "xpack.ingestManager.epmList.installedTitle": "已安装集成", "xpack.ingestManager.epmList.noPackagesFoundPlaceholder": "未找到任何软件包", @@ -8222,6 +9566,16 @@ "xpack.ingestManager.fleet.pageSubtitle": "管理配置更新并将其部署到一组任意大小的代理。", "xpack.ingestManager.fleet.pageTitle": "Fleet", "xpack.ingestManager.genericActionsMenuText": "打开", + "xpack.ingestManager.homeIntegration.tutorialDirectory.dismissNoticeButtonText": "关闭消息", + "xpack.ingestManager.homeIntegration.tutorialDirectory.ingestManagerAppButtonText": "试用采集管理器公测版", + "xpack.ingestManager.homeIntegration.tutorialDirectory.noticeText": "通过 Elastic 代理,您能够以简单统一的方式将日志、指标和其他类型数据的监测添加到主机。不再需要安装多个 Beats 和其他代理,这样在整个基础设施中部署配置会更轻松更快速。有关更多信息,请阅读我们的{blogPostLink}。", + "xpack.ingestManager.homeIntegration.tutorialDirectory.noticeText.blogPostLink": "公告博客", + "xpack.ingestManager.homeIntegration.tutorialDirectory.noticeTitle": "{newPrefix}Elastic 代理和采集管理器公测版", + "xpack.ingestManager.homeIntegration.tutorialDirectory.noticeTitle.newPrefix": "新通告:", + "xpack.ingestManager.homeIntegration.tutorialModule.noticeText": "{notePrefix}此模块的较新版本在采集管理器公测版中{availableAsIntegrationLink}。要详细了解代理配置和新 Elastic 代理,请阅读我们的{blogPostLink}。", + "xpack.ingestManager.homeIntegration.tutorialModule.noticeText.blogPostLink": "公告博客", + "xpack.ingestManager.homeIntegration.tutorialModule.noticeText.integrationLink": "作为集成提供", + "xpack.ingestManager.homeIntegration.tutorialModule.noticeText.notePrefix": "注意:", "xpack.ingestManager.initializationErrorMessageTitle": "无法初始化 Ingest Manager", "xpack.ingestManager.integrations.installPackage.installingPackageButtonLabel": "正在安装 {title} 资产", "xpack.ingestManager.integrations.installPackage.installPackageButtonLabel": "安装 {title} 资产", @@ -8248,7 +9602,7 @@ "xpack.ingestManager.integrations.settings.packageInstallTitle": "安装 {title}", "xpack.ingestManager.integrations.settings.packageSettingsTitle": "设置", "xpack.ingestManager.integrations.settings.packageUninstallDescription": "移除此集成安装的 Kibana 和 Elasticsearch 资产。", - "xpack.ingestManager.integrations.settings.packageUninstallNoteDescription.packageUninstallNoteDetail": "{strongNote} {title} 无法卸载,因为有使用此集成的活动代理。要卸载,请从您的代理配置中移除所有 {title} 数据源。", + "xpack.ingestManager.integrations.settings.packageUninstallNoteDescription.packageUninstallNoteDetail": "{strongNote}{title} 无法卸载,因为有使用此集成的活动代理。要卸载,请从您的代理配置中移除所有 {title} 集成。", "xpack.ingestManager.integrations.settings.packageUninstallNoteDescription.packageUninstallNoteLabel": "注意:", "xpack.ingestManager.integrations.settings.packageUninstallNoteDescription.packageUninstallUninstallableNoteDetail": "{strongNote} {title} 集成默认安装,无法移除。", "xpack.ingestManager.integrations.settings.packageUninstallTitle": "卸载 {title}", @@ -8279,48 +9633,81 @@ "xpack.ingestManager.overviewAgentErrorTitle": "错误", "xpack.ingestManager.overviewAgentOfflineTitle": "脱机", "xpack.ingestManager.overviewAgentTotalTitle": "代理总数", - "xpack.ingestManager.overviewConfigTotalTitle": "配置总数", + "xpack.ingestManager.overviewConfigTotalTitle": "可用总计", "xpack.ingestManager.overviewDatastreamNamespacesTitle": "命名空间", "xpack.ingestManager.overviewDatastreamSizeTitle": "总大小", - "xpack.ingestManager.overviewDatastreamTotalTitle": "数据流", + "xpack.ingestManager.overviewDatastreamTotalTitle": "数据集", "xpack.ingestManager.overviewIntegrationsInstalledTitle": "安装时间", "xpack.ingestManager.overviewIntegrationsTotalTitle": "可用总计", "xpack.ingestManager.overviewIntegrationsUpdatesAvailableTitle": "可用更新", + "xpack.ingestManager.overviewPackageConfigTitle": "已配置集成", "xpack.ingestManager.overviewPageConfigurationsPanelAction": "查看配置", - "xpack.ingestManager.overviewPageConfigurationsPanelTitle": "配置", - "xpack.ingestManager.overviewPageDataStreamsPanelAction": "查看数据流", - "xpack.ingestManager.overviewPageDataStreamsPanelTitle": "数据流", - "xpack.ingestManager.overviewPageEnrollAgentButton": "注册新代理", + "xpack.ingestManager.overviewPageConfigurationsPanelTitle": "代理配置", + "xpack.ingestManager.overviewPageConfigurationsPanelTooltip": "使用代理配置控制您的代理收集的数据。", + "xpack.ingestManager.overviewPageDataStreamsPanelAction": "查看数据集", + "xpack.ingestManager.overviewPageDataStreamsPanelTitle": "数据集", + "xpack.ingestManager.overviewPageDataStreamsPanelTooltip": "您的代理收集的数据组织到各种数据集中。", + "xpack.ingestManager.overviewPageEnrollAgentButton": "添加代理", "xpack.ingestManager.overviewPageFleetPanelAction": "查看代理", "xpack.ingestManager.overviewPageFleetPanelTitle": "Fleet", + "xpack.ingestManager.overviewPageFleetPanelTooltip": "使用 Fleet 注册代理并从集中位置管理其配置。", "xpack.ingestManager.overviewPageIntegrationsPanelAction": "查看集成", "xpack.ingestManager.overviewPageIntegrationsPanelTitle": "集成", - "xpack.ingestManager.overviewPageSubtitle": "Elastic 代理和配置的集中管理。", + "xpack.ingestManager.overviewPageIntegrationsPanelTooltip": "浏览并安装 Elastic Stack 的集成。将集成添加到您的代理配置以开始发送数据。", + "xpack.ingestManager.overviewPageSubtitle": "Elastic 代理和代理配置的集中管理。", "xpack.ingestManager.overviewPageTitle": "Ingest Manager", + "xpack.ingestManager.packageConfigValidation.invalidArrayErrorMessage": "格式无效", + "xpack.ingestManager.packageConfigValidation.invalidYamlFormatErrorMessage": "YAML 格式无效", + "xpack.ingestManager.packageConfigValidation.nameRequiredErrorMessage": "“名称”必填", + "xpack.ingestManager.packageConfigValidation.namespaceRequiredErrorMessage": "命名空间必填", + "xpack.ingestManager.packageConfigValidation.requiredErrorMessage": "“{fieldName}”必填", "xpack.ingestManager.permissionDeniedErrorMessage": "您无权访问 Ingest Manager。Ingest Manager 需要{roleName}权限。", "xpack.ingestManager.permissionDeniedErrorTitle": "权限被拒绝", "xpack.ingestManager.permissionsRequestErrorMessageDescription": "检查 Ingest Manager 权限时出现问题", "xpack.ingestManager.permissionsRequestErrorMessageTitle": "无法检查权限", "xpack.ingestManager.securityRequiredErrorMessage": "必须在 Kibana 和 Elasticsearch 启用安全性,才能使用 Ingest Manager。", "xpack.ingestManager.securityRequiredErrorTitle": "安全性未启用", + "xpack.ingestManager.settings.autoUpgradeDisabledLabel": "手动管理代理二进制文件版本。需要黄金级许可证。", + "xpack.ingestManager.settings.autoUpgradeEnabledLabel": "自动更新代理二进制文件以使用最新的次要版本。", + "xpack.ingestManager.settings.autoUpgradeFieldLabel": "Elastic 代理二进制文件版本", "xpack.ingestManager.settings.cancelButtonLabel": "取消", + "xpack.ingestManager.settings.elasticHostError": "URL 无效", "xpack.ingestManager.settings.elasticsearchUrlLabel": "Elasticsearch URL", "xpack.ingestManager.settings.flyoutTitle": "Ingest Manager 设置", "xpack.ingestManager.settings.globalOutputDescription": "全局输出将应用于所有代理配置,并指定将数据发送到哪里。", "xpack.ingestManager.settings.globalOutputTitle": "全局输出", + "xpack.ingestManager.settings.integrationUpgradeDisabledFieldLabel": "自行手动管理集成版本。", + "xpack.ingestManager.settings.integrationUpgradeEnabledFieldLabel": "自动将集成更新到最新版本以接收最新的资产。要使用新功能,可能需要更新代理配置。", + "xpack.ingestManager.settings.integrationUpgradeFieldLabel": "集成版本", + "xpack.ingestManager.settings.kibanaUrlError": "URL 无效", "xpack.ingestManager.settings.kibanaUrlLabel": "Kibana URL", "xpack.ingestManager.settings.saveButtonLabel": "保存设置", "xpack.ingestManager.settings.success.message": "设置已保存", + "xpack.ingestManager.setupPage.apiKeyServiceLink": "API 密钥服务", + "xpack.ingestManager.setupPage.elasticsearchApiKeyFlagText": "{apiKeyLink}。将 {apiKeyFlag} 设置为 {true}。", + "xpack.ingestManager.setupPage.elasticsearchSecurityFlagText": "{esSecurityLink}。将 {securityFlag} 设置为 {true}。", + "xpack.ingestManager.setupPage.elasticsearchSecurityLink": "Elasticsearch 安全", "xpack.ingestManager.setupPage.enableFleet": "创建用户并启用 Fleet", "xpack.ingestManager.setupPage.enableText": "要使用 Fleet,必须创建 Elastic 用户。此用户可以创建 API 密钥并写入到 logs-* and metrics-*。", "xpack.ingestManager.setupPage.enableTitle": "启用 Fleet", + "xpack.ingestManager.setupPage.encryptionKeyFlagText": "{encryptionKeyLink}。将 {keyFlag} 设置为至少 32 个字符的字母数字值。", + "xpack.ingestManager.setupPage.gettingStartedLink": "入门", + "xpack.ingestManager.setupPage.gettingStartedText": "有关更多信息,请阅读我们的{link}指南。", + "xpack.ingestManager.setupPage.kibanaEncryptionLink": "Kibana 加密密钥", + "xpack.ingestManager.setupPage.kibanaSecurityLink": "Kibana 安全性", + "xpack.ingestManager.setupPage.missingRequirementsCalloutDescription": "要使用 Fleet,必须启用以下 Elasticsearch 和 Kibana 安全性功能。", + "xpack.ingestManager.setupPage.missingRequirementsCalloutTitle": "缺失安全性要求", + "xpack.ingestManager.setupPage.missingRequirementsElasticsearchTitle": "在您的 Elasticsearch 配置中,启用:", + "xpack.ingestManager.setupPage.missingRequirementsKibanaTitle": "在您的 Kibana 配置中,启用:", + "xpack.ingestManager.setupPage.tlsFlagText": "{kibanaSecurityLink}。将 {securityFlag} 设置为 {true}。出于开发目的,作为非安全的备用方案可以通过将 {tlsFlag} 设置为 {true} 来禁用 {tlsLink}。", + "xpack.ingestManager.setupPage.tlsLink": "TLS", "xpack.ingestManager.unenrollAgents.confirmModal.cancelButtonLabel": "取消", "xpack.ingestManager.unenrollAgents.confirmModal.confirmButtonLabel": "取消注册", "xpack.ingestManager.unenrollAgents.confirmModal.deleteMultipleTitle": "取消注册 {count, plural, one {# 个代理} other {# 个代理}}?", "xpack.ingestManager.unenrollAgents.confirmModal.deleteSingleTitle": "取消注册“{id}”?", "xpack.ingestManager.unenrollAgents.confirmModal.loadingButtonLabel": "正在加载……", "xpack.ingestManager.unenrollAgents.fatalErrorNotificationTitle": "取消注册代理时出错", - "xpack.ingestManager.unenrollAgents.successSingleNotificationTitle": "已取消注册代理“{id}”", + "xpack.ingestManager.unenrollAgents.successSingleNotificationTitle": "取消注册代理“{id}”", "xpack.ingestPipelines.app.checkingPrivilegesDescription": "正在检查权限……", "xpack.ingestPipelines.app.checkingPrivilegesErrorMessage": "从服务器获取用户权限时出错。", "xpack.ingestPipelines.app.deniedPrivilegeDescription": "要使用“采集管道”,必须具有{privilegesCount, plural, one {以下集群权限} other {以下集群权限}}:{missingPrivileges}。", @@ -8358,9 +9745,13 @@ "xpack.ingestPipelines.form.onFailureFieldHelpText": "使用 JSON 格式:{code}", "xpack.ingestPipelines.form.pipelineNameRequiredError": "“名称”必填。", "xpack.ingestPipelines.form.saveButtonLabel": "保存管道", + "xpack.ingestPipelines.form.savePip10mbelineError.showFewerButton": "隐藏 {hiddenErrorsCount, plural, one {# 个错误} other {# 个错误}}", "xpack.ingestPipelines.form.savePipelineError": "无法创建管道", + "xpack.ingestPipelines.form.savePipelineError.processorLabel": "{type} 处理器", + "xpack.ingestPipelines.form.savePipelineError.showAllButton": "再显示 {hiddenErrorsCount, plural, one {# 个错误} other {# 个错误}}", "xpack.ingestPipelines.form.savingButtonLabel": "正在保存......", "xpack.ingestPipelines.form.showRequestButtonLabel": "显示请求", + "xpack.ingestPipelines.form.unknownError": "发生了未知错误。", "xpack.ingestPipelines.form.versionFieldLabel": "版本(可选)", "xpack.ingestPipelines.form.versionToggleDescription": "添加版本号", "xpack.ingestPipelines.licenseCheckErrorMessage": "许可证检查失败", @@ -8397,10 +9788,104 @@ "xpack.ingestPipelines.list.table.emptyPromptTitle": "首先创建管道", "xpack.ingestPipelines.list.table.nameColumnTitle": "名称", "xpack.ingestPipelines.list.table.reloadButtonLabel": "重新加载", + "xpack.ingestPipelines.pipelineEditor.addProcessorButtonLabel": "添加处理器", + "xpack.ingestPipelines.pipelineEditor.commonFields.ifFieldLabel": "条件(可选)", + "xpack.ingestPipelines.pipelineEditor.commonFields.ignoreFailureFieldLabel": "忽略失败", + "xpack.ingestPipelines.pipelineEditor.commonFields.tagFieldLabel": "标记(可选)", + "xpack.ingestPipelines.pipelineEditor.customForm.configurationRequiredError": "配置必填。", + "xpack.ingestPipelines.pipelineEditor.customForm.invalidJsonError": "输入无效。", + "xpack.ingestPipelines.pipelineEditor.customForm.optionsFieldAriaLabel": "配置 JSON 编辑器", + "xpack.ingestPipelines.pipelineEditor.customForm.optionsFieldLabel": "配置", + "xpack.ingestPipelines.pipelineEditor.deleteModal.deleteDescription": "删除此处理器和其失败时处理程序。", + "xpack.ingestPipelines.pipelineEditor.dropZoneButton.moveHereToolTip": "移到此处", + "xpack.ingestPipelines.pipelineEditor.dropZoneButton.unavailableToolTip": "无法移到此处", + "xpack.ingestPipelines.pipelineEditor.gsubForm.fieldFieldLabel": "字段", + "xpack.ingestPipelines.pipelineEditor.gsubForm.fieldRequiredError": "字段值必填。", + "xpack.ingestPipelines.pipelineEditor.gsubForm.ignoreMissingFieldLabel": "忽略缺失", + "xpack.ingestPipelines.pipelineEditor.gsubForm.patternFieldLabel": "模式", + "xpack.ingestPipelines.pipelineEditor.gsubForm.patternRequiredError": "模式值必填。", + "xpack.ingestPipelines.pipelineEditor.gsubForm.replacementFieldLabel": "替换", + "xpack.ingestPipelines.pipelineEditor.gsubForm.replacementRequiredError": "替换值必填。", + "xpack.ingestPipelines.pipelineEditor.gsubForm.targetFieldLabel": "目标字段(可选)", + "xpack.ingestPipelines.pipelineEditor.item.cancelMoveButtonAriaLabel": "取消移动", + "xpack.ingestPipelines.pipelineEditor.item.descriptionPlaceholder": "无描述", + "xpack.ingestPipelines.pipelineEditor.item.editButtonAriaLabel": "编辑此处理器", + "xpack.ingestPipelines.pipelineEditor.item.moreButtonAriaLabel": "显示此处理器的更多操作", + "xpack.ingestPipelines.pipelineEditor.item.moreMenu.addOnFailureHandlerButtonLabel": "添加失败时处理程序", + "xpack.ingestPipelines.pipelineEditor.item.moreMenu.deleteButtonLabel": "删除", + "xpack.ingestPipelines.pipelineEditor.item.moreMenu.duplicateButtonLabel": "复制此处理器", + "xpack.ingestPipelines.pipelineEditor.item.moveButtonLabel": "移动此处理器", + "xpack.ingestPipelines.pipelineEditor.item.textInputAriaLabel": "为此 {type} 处理器提供描述", + "xpack.ingestPipelines.pipelineEditor.loadFromJson.buttonLabel": "加载 JSON", + "xpack.ingestPipelines.pipelineEditor.loadFromJson.buttons.cancel": "取消", + "xpack.ingestPipelines.pipelineEditor.loadFromJson.buttons.confirm": "加载并覆盖", + "xpack.ingestPipelines.pipelineEditor.loadFromJson.editor": "管道对象", + "xpack.ingestPipelines.pipelineEditor.loadFromJson.error.body": "请确保 JSON 是有效的管道对象。", + "xpack.ingestPipelines.pipelineEditor.loadFromJson.error.title": "管道无效", + "xpack.ingestPipelines.pipelineEditor.loadFromJson.modalTitle": "加载 JSON", + "xpack.ingestPipelines.pipelineEditor.loadJsonModal.jsonEditorHelpText": "提供管道对象。这将覆盖现有管道处理器和失败时处理器。", + "xpack.ingestPipelines.pipelineEditor.onFailureProcessorsDocumentationLink": "了解详情。", + "xpack.ingestPipelines.pipelineEditor.onFailureProcessorsLabel": "失败处理程序", + "xpack.ingestPipelines.pipelineEditor.onFailureTreeDescription": "用于处理此管道中的异常的处理器。{learnMoreLink}", + "xpack.ingestPipelines.pipelineEditor.onFailureTreeTitle": "失败处理器", + "xpack.ingestPipelines.pipelineEditor.processorsDocumentationLink": "了解详情。", + "xpack.ingestPipelines.pipelineEditor.processorsTreeDescription": "用于在索引之前预处理文档的处理器。{learnMoreLink}", + "xpack.ingestPipelines.pipelineEditor.processorsTreeTitle": "处理器", + "xpack.ingestPipelines.pipelineEditor.removeProcessorModal.cancelButtonLabel": "取消", + "xpack.ingestPipelines.pipelineEditor.removeProcessorModal.confirmationButtonLabel": "删除处理器", + "xpack.ingestPipelines.pipelineEditor.removeProcessorModal.titleText": "删除 {type} 处理器", + "xpack.ingestPipelines.pipelineEditor.setForm.fieldFieldLabel": "字段", + "xpack.ingestPipelines.pipelineEditor.setForm.fieldRequiredError": "字段值必填。", + "xpack.ingestPipelines.pipelineEditor.setForm.overrideFieldLabel": "覆盖", + "xpack.ingestPipelines.pipelineEditor.setForm.valueFieldLabel": "值", + "xpack.ingestPipelines.pipelineEditor.setForm.valueRequiredError": "需要设置值。", + "xpack.ingestPipelines.pipelineEditor.settingsForm.learnMoreLabelLink.processor": "{processorLabel}文档", + "xpack.ingestPipelines.pipelineEditor.testPipelineButtonLabel": "测试管道", + "xpack.ingestPipelines.pipelineEditor.typeField.fieldRequiredError": "类型必填。", + "xpack.ingestPipelines.pipelineEditor.typeField.typeFieldLabel": "处理器", + "xpack.ingestPipelines.processors.label.append": "追加", + "xpack.ingestPipelines.processors.label.bytes": "字节", + "xpack.ingestPipelines.processors.label.circle": "圆形", + "xpack.ingestPipelines.processors.label.convert": "转换", + "xpack.ingestPipelines.processors.label.csv": "CSV", + "xpack.ingestPipelines.processors.label.date": "日期", + "xpack.ingestPipelines.processors.label.dateIndexName": "日期索引名称", + "xpack.ingestPipelines.processors.label.dissect": "分解", + "xpack.ingestPipelines.processors.label.dotExpander": "点扩展器", + "xpack.ingestPipelines.processors.label.drop": "丢弃", + "xpack.ingestPipelines.processors.label.enrich": "扩充", + "xpack.ingestPipelines.processors.label.fail": "失败", + "xpack.ingestPipelines.processors.label.foreach": "Foreach", + "xpack.ingestPipelines.processors.label.geoip": "GeoIP", + "xpack.ingestPipelines.processors.label.grok": "Grok", + "xpack.ingestPipelines.processors.label.gsub": "Gsub", + "xpack.ingestPipelines.processors.label.htmlStrip": "HTML 剥离", + "xpack.ingestPipelines.processors.label.inference": "推理", + "xpack.ingestPipelines.processors.label.join": "联接", + "xpack.ingestPipelines.processors.label.json": "JSON", + "xpack.ingestPipelines.processors.label.kv": "KV", + "xpack.ingestPipelines.processors.label.lowercase": "小写", + "xpack.ingestPipelines.processors.label.pipeline": "管道", + "xpack.ingestPipelines.processors.label.remove": "移除", + "xpack.ingestPipelines.processors.label.rename": "重命名", + "xpack.ingestPipelines.processors.label.script": "脚本", + "xpack.ingestPipelines.processors.label.set": "设置", + "xpack.ingestPipelines.processors.label.setSecurityUser": "设置安全用户", + "xpack.ingestPipelines.processors.label.sort": "排序", + "xpack.ingestPipelines.processors.label.split": "拆分", + "xpack.ingestPipelines.processors.label.trim": "剪裁", + "xpack.ingestPipelines.processors.label.uppercase": "大写", + "xpack.ingestPipelines.processors.label.urldecode": "URL 解码", + "xpack.ingestPipelines.processors.label.userAgent": "用户代理", "xpack.ingestPipelines.requestFlyout.closeButtonLabel": "关闭", "xpack.ingestPipelines.requestFlyout.descriptionText": "此 Elasticsearch 请求将创建或更新管道。", "xpack.ingestPipelines.requestFlyout.namedTitle": "对“{name}”的请求", "xpack.ingestPipelines.requestFlyout.unnamedTitle": "请求", + "xpack.ingestPipelines.settingsFormFlyout.title": "配置处理器", + "xpack.ingestPipelines.settingsFormOnFailureFlyout.addButtonLabel": "添加", + "xpack.ingestPipelines.settingsFormOnFailureFlyout.cancelButtonLabel": "取消", + "xpack.ingestPipelines.settingsFormOnFailureFlyout.title": "配置失败时处理器", + "xpack.ingestPipelines.settingsFormOnFailureFlyout.updateButtonLabel": "更新", "xpack.ingestPipelines.tabs.documentsTabTitle": "文档", "xpack.ingestPipelines.tabs.outputTabTitle": "输出", "xpack.ingestPipelines.testPipelineFlyout.documentsForm.documentsFieldLabel": "文档", @@ -8427,11 +9912,17 @@ "xpack.lens.app.saveAndReturn": "保存并返回", "xpack.lens.app.saveAs": "另存为", "xpack.lens.app.saveModalType": "Lens 可视化", + "xpack.lens.app.unsavedWorkMessage": "离开 Lens,不保存工作?", + "xpack.lens.app.unsavedWorkTitle": "未保存更改", "xpack.lens.app404": "404 找不到", "xpack.lens.breadcrumbsCreate": "创建", "xpack.lens.breadcrumbsTitle": "可视化", "xpack.lens.chartSwitch.dataLossDescription": "切换到此图表将会丢失部分配置", "xpack.lens.chartSwitch.dataLossLabel": "数据丢失", + "xpack.lens.chartTitle.unsaved": "未保存", + "xpack.lens.configPanel.color.tooltip.auto": "Lens 自动为您选取颜色,除非您指定定制颜色。", + "xpack.lens.configPanel.color.tooltip.custom": "清除定制颜色以返回到“自动”模式。", + "xpack.lens.configPanel.color.tooltip.disabled": "当图层包括“细分依据”,各个系列无法定制颜色。", "xpack.lens.configPanel.selectVisualization": "选择可视化", "xpack.lens.configure.addConfig": "添加配置", "xpack.lens.configure.editConfig": "编辑配置", @@ -8458,8 +9949,10 @@ "xpack.lens.editorFrame.emptyWorkspaceHeading": "Lens 是用于创建可视化的新工具", "xpack.lens.editorFrame.expandRenderingErrorButton": "显示错误的详情", "xpack.lens.editorFrame.expressionFailure": "无法成功执行表达式", + "xpack.lens.editorFrame.formatStyleLabel": "格式和样式", "xpack.lens.editorFrame.goToForums": "提出请求并提供反馈", "xpack.lens.editorFrame.previewErrorLabel": "预览呈现失败", + "xpack.lens.editorFrame.quickFunctionsLabel": "快选函数", "xpack.lens.editorFrame.requiredDimensionWarningLabel": "所需尺寸", "xpack.lens.editorFrame.suggestionPanelTitle": "建议", "xpack.lens.editorFrame.tooltipContent": "Lens 为公测版,可能会进行更改。 设计和代码相对于正式发行版功能还不够成熟,将按原样提供,且不提供任何保证。公测版功能不受正式发行版功能支持 SLA 的约束", @@ -8467,11 +9960,22 @@ "xpack.lens.embeddableDisplayName": "lens", "xpack.lens.excludeValueButtonAriaLabel": "排除 {value}", "xpack.lens.excludeValueButtonTooltip": "排除值", + "xpack.lens.fittingFunctionsDescription.carry": "使用最后一个值填充空距", + "xpack.lens.fittingFunctionsDescription.linear": "使用线填充空距", + "xpack.lens.fittingFunctionsDescription.lookahead": "使用下一个值填充空距", + "xpack.lens.fittingFunctionsDescription.none": "不填充空距", + "xpack.lens.fittingFunctionsDescription.zero": "使用零填充空距", + "xpack.lens.fittingFunctionsTitle.carry": "上一", + "xpack.lens.fittingFunctionsTitle.linear": "线性", + "xpack.lens.fittingFunctionsTitle.lookahead": "下一", + "xpack.lens.fittingFunctionsTitle.none": "隐藏", + "xpack.lens.fittingFunctionsTitle.zero": "零", "xpack.lens.functions.mergeTables.help": "将任何数目的 kibana 表合并成单个表的助手", "xpack.lens.functions.renameColumns.help": "用于重命名数据表列的助手", "xpack.lens.functions.renameColumns.idMap.help": "旧列 ID 为键且相应新列 ID 为值的 JSON 编码对象。所有其他列 ID 都将保留。", "xpack.lens.includeValueButtonAriaLabel": "包括 {value}", "xpack.lens.includeValueButtonTooltip": "包括值", + "xpack.lens.indexPattern.availableFieldsLabel": "可用字段", "xpack.lens.indexPattern.avg": "平均值", "xpack.lens.indexPattern.avgOf": "{name} 的平均值", "xpack.lens.indexPattern.bytesFormatLabel": "字节 (1024)", @@ -8496,6 +10000,7 @@ "xpack.lens.indexPattern.dateHistogram.year": "年", "xpack.lens.indexPattern.decimalPlacesLabel": "小数", "xpack.lens.indexPattern.defaultFormatLabel": "默认值", + "xpack.lens.indexPattern.emptyFieldsLabel": "空字段", "xpack.lens.indexpattern.emptyTextColumnValue": "(空)", "xpack.lens.indexPattern.fieldDistributionLabel": "分布", "xpack.lens.indexPattern.fieldItemTooltip": "拖放以可视化。", @@ -8545,16 +10050,21 @@ "xpack.lens.indexPattern.termsOf": "{name} 的排名最前值", "xpack.lens.indexPattern.uniqueLabel": "{label} [{num}]", "xpack.lens.indexPatterns.clearFiltersLabel": "清除名称和类型筛选", + "xpack.lens.indexPatterns.fieldFiltersLabel": "自动筛选", "xpack.lens.indexPatterns.filterByNameAriaLabel": "搜索字段", "xpack.lens.indexPatterns.filterByNameLabel": "搜索字段", + "xpack.lens.indexPatterns.noDataLabel": "没有包含数据的可用字段。", "xpack.lens.indexPatterns.noFields.extendTimeBullet": "延伸时间范围", + "xpack.lens.indexPatterns.noFields.fieldTypeFilterBullet": "使用不同的字段筛选", + "xpack.lens.indexPatterns.noFields.globalFiltersBullet": "更改全局筛选", "xpack.lens.indexPatterns.noFields.tryText": "尝试:", "xpack.lens.indexPatterns.noFieldsLabel": "在此索引模式中不存在任何字段。", - "xpack.lens.indexPatterns.noFilteredFieldsLabel": "没有任何字段匹配当前筛选。", + "xpack.lens.indexPatterns.noFilteredFieldsLabel": "没有字段匹配选定筛选。", "xpack.lens.indexPatternSuggestion.removeLayerLabel": "仅显示 {indexPatternTitle}", "xpack.lens.indexPatternSuggestion.removeLayerPositionLabel": "仅显示图层 {layerNumber}", "xpack.lens.lensSavedObjectLabel": "Lens 可视化", "xpack.lens.metric.label": "指标", + "xpack.lens.pageTitle": "Lens", "xpack.lens.pie.donutLabel": "圆环图", "xpack.lens.pie.expressionHelpLabel": "饼图呈现器", "xpack.lens.pie.groupsizeLabel": "大小调整依据", @@ -8593,14 +10103,24 @@ "xpack.lens.visTypeAlias.type": "Lens", "xpack.lens.xyChart.addLayerButton": "添加图层", "xpack.lens.xyChart.addLayerTooltip": "使用多个图层以组合图表类型或可视化不同的索引模式。", + "xpack.lens.xyChart.axisSide.auto": "自动", + "xpack.lens.xyChart.axisSide.label": "轴侧", + "xpack.lens.xyChart.axisSide.left": "左", + "xpack.lens.xyChart.axisSide.right": "右", "xpack.lens.xyChart.chartTypeLabel": "图表类型", "xpack.lens.xyChart.chartTypeLegend": "图表类型", + "xpack.lens.xyChart.fittingDisabledHelpText": "此设置仅适用于折线图和非堆叠面积图。", + "xpack.lens.xyChart.fittingFunction.help": "定义处理缺失值的方式", + "xpack.lens.xyChart.fittingLabel": "填充缺失值", "xpack.lens.xyChart.help": "X/Y 图表", "xpack.lens.xyChart.isVisible.help": "指定图例是否可见。", "xpack.lens.xyChart.legend.help": "配置图表图例。", "xpack.lens.xyChart.nestUnderRoot": "整个数据集", "xpack.lens.xyChart.position.help": "指定图例位置。", "xpack.lens.xyChart.renderer.help": "X/Y 图表呈现器", + "xpack.lens.xyChart.seriesColor.auto": "自动", + "xpack.lens.xyChart.seriesColor.label": "系列颜色", + "xpack.lens.xyChart.settingsLabel": "设置", "xpack.lens.xyChart.splitSeries": "拆分序列", "xpack.lens.xyChart.title.help": "轴标题", "xpack.lens.xyChart.xAxisLabel": "X 轴", @@ -8642,23 +10162,31 @@ "xpack.licenseMgmt.licenseDashboard.licenseStatus.permanentActiveLicenseStatusDescription": "您的许可永不会过期。", "xpack.licenseMgmt.licenseDashboard.requestTrialExtension.extendTrialButtonLabel": "延期试用", "xpack.licenseMgmt.licenseDashboard.requestTrialExtension.extendYourTrialTitle": "延期您的试用", + "xpack.licenseMgmt.licenseDashboard.requestTrialExtension.howToContinueUsingPluginsDescription": "如果您想继续使用 Machine Learning、高级安全性以及我们其他超卓的{subscriptionFeaturesLinkText},请立即申请延期。", + "xpack.licenseMgmt.licenseDashboard.requestTrialExtension.subscriptionFeaturesLinkText": "订阅功能", "xpack.licenseMgmt.licenseDashboard.revertToBasic.acknowledgeModal.revertToBasicButtonLabel": "恢复为基础级", "xpack.licenseMgmt.licenseDashboard.revertToBasic.acknowledgeModalTitle": "恢复为基础级许可", "xpack.licenseMgmt.licenseDashboard.revertToBasic.confirmModal.cancelButtonLabel": "取消", "xpack.licenseMgmt.licenseDashboard.revertToBasic.confirmModal.confirmButtonLabel": "确认", "xpack.licenseMgmt.licenseDashboard.revertToBasic.confirmModalTitle": "确认恢复为基础级许可", + "xpack.licenseMgmt.licenseDashboard.revertToBasic.revertToFreeFeaturesDescription": "您将恢复到我们的免费功能,并失去对 Machine Learning、高级安全性和其他{subscriptionFeaturesLinkText}的访问权限。", + "xpack.licenseMgmt.licenseDashboard.revertToBasic.subscriptionFeaturesLinkText": "订阅功能", "xpack.licenseMgmt.licenseDashboard.startTrial.confirmModal.cancelButtonLabel": "取消", "xpack.licenseMgmt.licenseDashboard.startTrial.confirmModal.startTrialButtonLabel": "开始我的试用", + "xpack.licenseMgmt.licenseDashboard.startTrial.confirmModalDescription": "此试用适用于 Elastic Stack 的整套{subscriptionFeaturesLinkText}。您立即可以访问:", "xpack.licenseMgmt.licenseDashboard.startTrial.confirmModalDescription.alertingFeatureTitle": "告警", "xpack.licenseMgmt.licenseDashboard.startTrial.confirmModalDescription.dataBaseConnectivityFeatureTitle": "{sqlDataBase} 的 {jdbcStandard} 和 {odbcStandard} 连接性", "xpack.licenseMgmt.licenseDashboard.startTrial.confirmModalDescription.graphCapabilitiesFeatureTitle": "图表功能", "xpack.licenseMgmt.licenseDashboard.startTrial.confirmModalDescription.mashingLearningFeatureTitle": "Machine Learning", "xpack.licenseMgmt.licenseDashboard.startTrial.confirmModalDescription.securityDocumentationLinkText": "文档", "xpack.licenseMgmt.licenseDashboard.startTrial.confirmModalDescription.securityFeaturesConfigurationDescription": "诸如身份验证 ({authenticationTypeList})、字段级和文档级安全以及审计等高级安全功能需要配置。有关说明,请参阅 {securityDocumentationLinkText}。", + "xpack.licenseMgmt.licenseDashboard.startTrial.confirmModalDescription.subscriptionFeaturesLinkText": "订阅功能", "xpack.licenseMgmt.licenseDashboard.startTrial.confirmModalDescription.termsAndConditionsDescription": "通过开始此试用,您同意其受这些{termsAndConditionsLinkText}约束。", "xpack.licenseMgmt.licenseDashboard.startTrial.confirmModalDescription.termsAndConditionsLinkText": "条款和条件", "xpack.licenseMgmt.licenseDashboard.startTrial.confirmModalTitle": "立即开始为期 30 天的免费试用", "xpack.licenseMgmt.licenseDashboard.startTrial.startTrialButtonLabel": "开始试用", + "xpack.licenseMgmt.licenseDashboard.startTrial.subscriptionFeaturesExperienceDescription": "体验 Machine Learning、高级安全性以及我们所有其他{subscriptionFeaturesLinkText}能帮您做什么。", + "xpack.licenseMgmt.licenseDashboard.startTrial.subscriptionFeaturesLinkText": "订阅功能", "xpack.licenseMgmt.licenseDashboard.startTrialTitle": "开始为期 30 天的试用", "xpack.licenseMgmt.managementSectionDisplayName": "许可管理", "xpack.licenseMgmt.replacingCurrentLicenseWithBasicLicenseWarningMessage": "如果将您的{currentLicenseType}许可替换成基础级许可,将会失去部分功能。查看下面的功能列表。", @@ -8718,7 +10246,7 @@ "xpack.logstash.managementSection.licenseDoesNotSupportDescription": "您的{licenseType}许可不支持 Logstash 管道管理功能。请升级您的许可。", "xpack.logstash.managementSection.notPossibleToManagePipelinesMessage": "您不能管理 Logstash 管道,因为许可信息当前不可用。", "xpack.logstash.managementSection.pipelineCrudOperationsNotAllowedDescription": "您不能编辑、创建或删除您的 Logstash 管道,因为您的{licenseType}许可已过期。", - "xpack.logstash.managementSection.pipelinesTitle": "管道", + "xpack.logstash.managementSection.pipelinesTitle": "Logstash 管道", "xpack.logstash.manualUpgradeButtonLabel": "重试", "xpack.logstash.newPipelineMessage": "在您可以添加管道之前,我们需要升级您的配置。", "xpack.logstash.notManualUpgradeButtonLabel": "升级", @@ -8786,6 +10314,7 @@ "xpack.logstash.upgradeFailureActions.goBackButtonLabel": "返回", "xpack.logstash.upstreamPipelineArgumentMustContainAnIdPropertyErrorMessage": "upstreamPipeline 参数必须包含 id 属性", "xpack.logstash.workersTooltip": "并行执行管道的筛选和输出阶段的工作线程数目。如果您发现事件出现积压或 CPU 未饱和,请考虑增大此数值,以更好地利用机器处理能力。\n\n默认值:主机的 CPU 核心数", + "xpack.main.uiSettings.adminEmailDeprecation": "此设置已过时,在 Kibana 8.0 中将不受支持。请在 kibana.yml 设置中配置 `monitoring.cluster_alerts.email_notifications.email_address`。", "xpack.main.uiSettings.adminEmailDescription": "X-Pack 管理操作的接收人电子邮件地址,例如来自 Monitoring 的集群告警通知。", "xpack.main.uiSettings.adminEmailTitle": "管理电子邮件", "xpack.maps.addLayerPanel.addLayer": "添加图层", @@ -8794,6 +10323,18 @@ "xpack.maps.aggs.defaultCountLabel": "计数", "xpack.maps.appTitle": "Maps", "xpack.maps.blendedVectorLayer.clusteredLayerName": "集群 {displayName}", + "xpack.maps.breadCrumbs.unsavedChangesWarning": "可能不会保存您未保存的更改", + "xpack.maps.choropleth.boundaries.elasticsearch": "Elasticsearch 的点、线和多边形", + "xpack.maps.choropleth.boundaries.ems": "来自 Elastic Maps Service 的管理边界", + "xpack.maps.choropleth.boundariesLabel": "边界源", + "xpack.maps.choropleth.desc": "用于跨边界比较统计的阴影区域", + "xpack.maps.choropleth.geofieldLabel": "地理空间字段", + "xpack.maps.choropleth.geofieldPlaceholder": "选择地理字段", + "xpack.maps.choropleth.joinFieldLabel": "联接字段", + "xpack.maps.choropleth.joinFieldPlaceholder": "选择字段", + "xpack.maps.choropleth.rightSourceLabel": "索引模式", + "xpack.maps.choropleth.statisticsLabel": "统计源", + "xpack.maps.choropleth.title": "分级统计图", "xpack.maps.common.esSpatialRelation.containsLabel": "contains", "xpack.maps.common.esSpatialRelation.disjointLabel": "disjoint", "xpack.maps.common.esSpatialRelation.intersectsLabel": "intersects", @@ -8803,6 +10344,7 @@ "xpack.maps.drawTooltip.distanceInstructions": "单击以设置点。移动鼠标以调整距离。单击以完成。", "xpack.maps.drawTooltip.polygonInstructions": "单击以开始绘制形状。单击以添加顶点。双击以完成。", "xpack.maps.embeddableDisplayName": "地图", + "xpack.maps.emsFileSelect.selectPlaceholder": "选择 EMS 图层", "xpack.maps.emsSource.tooltipsTitle": "工具提示字段", "xpack.maps.es_geo_utils.convert.unsupportedGeometryTypeErrorMessage": "无法将 {geometryType} 几何图形转换成 geojson,不支持", "xpack.maps.es_geo_utils.distanceFilterAlias": "{pointLabel} {distanceKm}km 内的 {geoFieldName}", @@ -8820,15 +10362,23 @@ "xpack.maps.esSearch.topHitsSizeMsg": "显示每个实体排名前 {topHitsSize} 的文档。", "xpack.maps.feature.appDescription": "从 Elasticsearch 和 Elastic 地图服务浏览地理空间数据", "xpack.maps.featureRegistry.mapsFeatureName": "Maps", + "xpack.maps.fileUploadWizard.description": "在 Elasticsearch 中索引 GeoJSON 数据", + "xpack.maps.fileUploadWizard.importFileSetupLabel": "导入文件", + "xpack.maps.fileUploadWizard.indexingLabel": "正在导入文件", + "xpack.maps.fileUploadWizard.title": "上传 GeoJSON", "xpack.maps.filterEditor.applyGlobalQueryCheckboxLabel": "将全局筛选应用到图层数据", "xpack.maps.fitToData.fitAriaLabel": "适应数据边界", "xpack.maps.fitToData.fitButtonLabel": "适应数据边界", "xpack.maps.geoGrid.resolutionLabel": "网格分辨率", "xpack.maps.geometryFilterForm.geometryLabelLabel": "几何标签", "xpack.maps.geometryFilterForm.relationLabel": "空间关系", + "xpack.maps.geoTileAgg.disabled.docValues": "集群需要聚合。通过将 doc_values 设置为 true 来启用聚合。", + "xpack.maps.geoTileAgg.disabled.license": "Geo_shape 集群需要黄金级许可。", "xpack.maps.heatmap.colorRampLabel": "颜色范围", "xpack.maps.heatmapLegend.coldLabel": "冷", "xpack.maps.heatmapLegend.hotLabel": "热", + "xpack.maps.indexPatternSelectLabel": "索引模式", + "xpack.maps.indexPatternSelectPlaceholder": "选择索引模式", "xpack.maps.indexSettings.fetchErrorMsg": "无法提取索引模式“{indexPatternTitle}”的索引设置。\n 确保您具有“{viewIndexMetaRole}”角色。", "xpack.maps.initialLayers.unableToParseMessage": "无法解析“initialLayers”参数的内容。错误:{errorMsg}", "xpack.maps.initialLayers.unableToParseTitle": "初始图层未添加到地图", @@ -8888,6 +10438,7 @@ "xpack.maps.layerPanel.metricsExpression.joinMustBeSetErrorMessage": "必须设置联接", "xpack.maps.layerPanel.metricsExpression.metricsPopoverTitle": "指标", "xpack.maps.layerPanel.metricsExpression.useMetricsDescription": "{metricsLength, plural, one {并使用指标} other {并使用指标}}", + "xpack.maps.layerPanel.settingsPanel.labelsOnTop": "在顶部显示标签", "xpack.maps.layerPanel.settingsPanel.layerNameLabel": "名称", "xpack.maps.layerPanel.settingsPanel.layerTransparencyLabel": "图层透明度", "xpack.maps.layerPanel.settingsPanel.percentageLabel": "%", @@ -8908,6 +10459,11 @@ "xpack.maps.layerTocActions.noFitSupportTooltip": "图层不支持适应数据", "xpack.maps.layerTocActions.removeLayerTitle": "移除图层", "xpack.maps.layerTocActions.showLayerTitle": "显示图层", + "xpack.maps.layerWizardSelect.allCategories": "全部", + "xpack.maps.layerWizardSelect.elasticsearchCategoryLabel": "Elasticsearch", + "xpack.maps.layerWizardSelect.referenceCategoryLabel": "参考", + "xpack.maps.layerWizardSelect.solutionsCategoryLabel": "解决方案", + "xpack.maps.loadMap.errorAttemptingToLoadSavedMap": "无法加载地图", "xpack.maps.map.initializeErrorTitle": "无法初始化地图", "xpack.maps.mapController.fullScreenButtonLabel": "全屏", "xpack.maps.mapController.fullScreenDescription": "全屏", @@ -8931,6 +10487,7 @@ "xpack.maps.mapListing.deleteTitle": "删除", "xpack.maps.mapListing.deleteWarning": "您无法恢复已删除项。", "xpack.maps.mapListing.descriptionFieldTitle": "描述", + "xpack.maps.mapListing.errorAttemptingToLoadSavedMaps": "无法加载地图", "xpack.maps.mapListing.limitExceededTitle": "已超过列表限制", "xpack.maps.mapListing.limitHelpDescription": "您有 {totalItems} 项,但您的 listingLimit 设置阻止下表显示 {listingLimit} 项以上。此设置可在以下选项下更改: ", "xpack.maps.mapListing.listingTableTitle": "Maps", @@ -8940,6 +10497,7 @@ "xpack.maps.mapListing.searchPlaceholder": "搜索......", "xpack.maps.mapListing.titleFieldTitle": "标题", "xpack.maps.mapListing.unableToDeleteToastTitle": "无法删除地图", + "xpack.maps.maps.choropleth.rightSourcePlaceholder": "选择索引模式", "xpack.maps.mapSavedObjectLabel": "地图", "xpack.maps.mapSettingsPanel.browserLocationLabel": "浏览器位置", "xpack.maps.mapSettingsPanel.cancelLabel": "取消", @@ -8974,6 +10532,14 @@ "xpack.maps.metricSelect.sumDropDownOptionLabel": "和", "xpack.maps.metricSelect.termsDropDownOptionLabel": "热门词", "xpack.maps.multiIndexFieldSelect.fieldLabel": "筛选字段", + "xpack.maps.mvtSource.addFieldLabel": "添加", + "xpack.maps.mvtSource.fieldPlaceholderText": "字段名称", + "xpack.maps.mvtSource.numberFieldLabel": "数字", + "xpack.maps.mvtSource.sourceSettings": "源设置", + "xpack.maps.mvtSource.stringFieldLabel": "字符串", + "xpack.maps.mvtSource.tooltipsTitle": "工具提示字段", + "xpack.maps.mvtSource.trashButtonAriaLabel": "移除字段", + "xpack.maps.mvtSource.trashButtonTitle": "移除字段", "xpack.maps.noIndexPattern.doThisLinkTextDescription": "创建索引模式", "xpack.maps.noIndexPattern.doThisPrefixDescription": "您将需要 ", "xpack.maps.noIndexPattern.doThisSuffixDescription": " 使用地理空间字段。", @@ -9003,6 +10569,12 @@ "xpack.maps.sampleData.flightaSpec.logsTitle": "[日志] 请求和字节总数", "xpack.maps.sampleData.flightaSpec.mapsTitle": "[航班] 始发地和到达地航班时间", "xpack.maps.sampleDataLinkLabel": "地图", + "xpack.maps.security.desc": "安全层", + "xpack.maps.security.indexPatternLabel": "索引模式", + "xpack.maps.security.title": "安全", + "xpack.maps.sescurity.destinationLayerLabel": "{indexPatternTitle} | 目标点", + "xpack.maps.sescurity.lineLayerLabel": "{indexPatternTitle} | 线", + "xpack.maps.sescurity.sourceLayerLabel": "{indexPatternTitle} | 源点", "xpack.maps.setViewControl.goToButtonLabel": "前往", "xpack.maps.setViewControl.latitudeLabel": "纬度", "xpack.maps.setViewControl.longitudeLabel": "经度", @@ -9016,6 +10588,7 @@ "xpack.maps.source.emsFile.layerLabel": "图层", "xpack.maps.source.emsFile.unableToFindIdErrorMessage": "找不到 ID {id} 的 EMS 矢量形状", "xpack.maps.source.emsFileDescription": "来自 Elastic 地图服务的管理边界的矢量形状", + "xpack.maps.source.emsFileSelect.selectLabel": "图层", "xpack.maps.source.emsFileTitle": "矢量形状", "xpack.maps.source.emsTile.autoLabel": "基于 Kibana 主题自动选择", "xpack.maps.source.emsTile.errorMessage": "找不到 ID {id} 的 EMS 磁贴配置", @@ -9059,6 +10632,7 @@ "xpack.maps.source.esSearch.geoFieldLabel": "地理空间字段", "xpack.maps.source.esSearch.geoFieldTypeLabel": "地理空间字段类型", "xpack.maps.source.esSearch.indexPatternLabel": "索引模式", + "xpack.maps.source.esSearch.joinsDisabledReason": "按集群缩放时不支持联接", "xpack.maps.source.esSearch.limitScalingLabel": "将结果数限制到 {maxResultWindow}。", "xpack.maps.source.esSearch.loadErrorMessage": "找不到索引模式 {id}", "xpack.maps.source.esSearch.loadTooltipPropertiesErrorMsg": "找不到文档,_id:{docId}", @@ -9070,7 +10644,7 @@ "xpack.maps.source.esSearch.topHitsSplitFieldLabel": "实体", "xpack.maps.source.esSearch.topHitsSplitFieldSelectPlaceholder": "选择实体字段", "xpack.maps.source.esSearch.useTopHitsLabel": "显示每个实体最高命中结果。", - "xpack.maps.source.esSearchDescription": "Kibana 索引模式的地理空间数据", + "xpack.maps.source.esSearchDescription": "Elasticsearch 的点、线和多边形", "xpack.maps.source.esSearchTitle": "文档", "xpack.maps.source.esSource.noGeoFieldErrorMessage": "索引模式“{indexPatternTitle}”不再包含地理字段 {geoField}", "xpack.maps.source.esSource.noIndexPatternErrorMessage": "找不到 ID {indexPatternId} 的索引模式", @@ -9089,11 +10663,17 @@ "xpack.maps.source.kbnTMSDescription": "在 kibana.yml 中配置的地图磁贴", "xpack.maps.source.kbnTMSTitle": "定制磁贴地图服务", "xpack.maps.source.mapSettingsPanel.initialLocationLabel": "初始地图位置", - "xpack.maps.source.MVTSingleLayerVectorSource.sourceTitle": "矢量磁贴图层", - "xpack.maps.source.MVTSingleLayerVectorSourceEditor.dataZoomRangeMessage": "缩放级别", - "xpack.maps.source.MVTSingleLayerVectorSourceEditor.layerNameMessage": "图层名称", + "xpack.maps.source.MVTSingleLayerVectorSource.sourceTitle": ".pbf 矢量磁贴", + "xpack.maps.source.MVTSingleLayerVectorSourceEditor.dataZoomRangeMessage": "缩放", + "xpack.maps.source.MVTSingleLayerVectorSourceEditor.fieldsMessage": "字段", + "xpack.maps.source.MVTSingleLayerVectorSourceEditor.fieldsPostHelpMessage": "这可以用于工具提示和动态样式。", + "xpack.maps.source.MVTSingleLayerVectorSourceEditor.fieldsPreHelpMessage": "可用的字段,于 ", + "xpack.maps.source.MVTSingleLayerVectorSourceEditor.layerNameMessage": "磁帖图层", + "xpack.maps.source.MVTSingleLayerVectorSourceEditor.urlHelpMessage": ".mvt 矢量磁帖服务的 URL。例如 {url}", "xpack.maps.source.MVTSingleLayerVectorSourceEditor.urlMessage": "URL", - "xpack.maps.source.mvtVectorSourceWizard": "矢量源向导", + "xpack.maps.source.MVTSingleLayerVectorSourceEditor.zoomRangeHelpMessage": "磁帖中存在该图层的缩放级别。这不直接对应于可见性。较低级别的图层数据始终可以显示在较高缩放级别(反之却不然)。", + "xpack.maps.source.MVTSingleLayerVectorSourceEditor.zoomRangeTopMessage": "可用级别", + "xpack.maps.source.mvtVectorSourceWizard": "实施 Mapbox 矢量文件规范的数据服务", "xpack.maps.source.pewPew.destGeoFieldLabel": "目标", "xpack.maps.source.pewPew.destGeoFieldPlaceholder": "选择目标地理位置字段", "xpack.maps.source.pewPew.indexPatternLabel": "索引模式", @@ -9230,12 +10810,21 @@ "xpack.ml.accessDenied.description": "您无权访问 ML 插件", "xpack.ml.accessDenied.label": "权限不足", "xpack.ml.accessDeniedLabel": "访问被拒绝", + "xpack.ml.actions.applyInfluencersFiltersTitle": "筛留值", + "xpack.ml.actions.applyTimeRangeSelectionTitle": "应用时间范围选择", "xpack.ml.actions.editSwimlaneTitle": "编辑泳道", + "xpack.ml.actions.influencerFilterAliasLabel": "影响因素 {labelValue}", + "xpack.ml.actions.openInAnomalyExplorerTitle": "在 Anomaly Explorer 中打开", + "xpack.ml.annotationFlyout.applyToPartitionTextLabel": "将标注应用到此系列", "xpack.ml.annotationsTable.actionsColumnName": "操作", "xpack.ml.annotationsTable.annotationColumnName": "注释", "xpack.ml.annotationsTable.annotationsNotCreatedTitle": "没有为此作业创建注释", + "xpack.ml.annotationsTable.byAEColumnName": "依据", + "xpack.ml.annotationsTable.byColumnSMVName": "依据", + "xpack.ml.annotationsTable.detectorColumnName": "检测工具", "xpack.ml.annotationsTable.editAnnotationsTooltip": "编辑注释", "xpack.ml.annotationsTable.editAnnotationsTooltipAriaLabel": "编辑注释", + "xpack.ml.annotationsTable.eventColumnName": "事件", "xpack.ml.annotationsTable.fromColumnName": "从", "xpack.ml.annotationsTable.howToCreateAnnotationDescription": "要创建注释,请打开 {linkToSingleMetricView}", "xpack.ml.annotationsTable.howToCreateAnnotationDescription.singleMetricViewerLinkText": "Single Metric Viewer", @@ -9247,6 +10836,11 @@ "xpack.ml.annotationsTable.lastModifiedDateColumnName": "上次修改日期", "xpack.ml.annotationsTable.openInSingleMetricViewerAriaLabel": "在 Single Metric Viewer 中打开", "xpack.ml.annotationsTable.openInSingleMetricViewerTooltip": "在 Single Metric Viewer 中打开", + "xpack.ml.annotationsTable.overAEColumnName": "范围", + "xpack.ml.annotationsTable.overColumnSMVName": "范围", + "xpack.ml.annotationsTable.partitionAEColumnName": "分区", + "xpack.ml.annotationsTable.partitionSMVColumnName": "分区", + "xpack.ml.annotationsTable.seriesOnlyFilterName": "仅筛选系列", "xpack.ml.annotationsTable.toColumnName": "到", "xpack.ml.anomaliesTable.actionsColumnName": "操作", "xpack.ml.anomaliesTable.actualSortColumnName": "实际", @@ -9318,6 +10912,10 @@ "xpack.ml.anomalyDetection.singleMetricViewerLabel": "Single Metric Viewer", "xpack.ml.anomalyDetectionBreadcrumbLabel": "异常检测", "xpack.ml.anomalyExplorerPageLabel": "Anomaly Explorer", + "xpack.ml.anomalyResultsViewSelector.anomalyExplorerLabel": "在 Anomaly Explorer 中查看结果", + "xpack.ml.anomalyResultsViewSelector.buttonGroupLegend": "异常结果视图选择器", + "xpack.ml.anomalyResultsViewSelector.singleMetricViewerLabel": "在 Single Metric Viewer 中查看结果", + "xpack.ml.anomalySwimLane.noOverallDataMessage": "找不到总体数据", "xpack.ml.anomalyUtils.multiBucketImpact.highLabel": "高", "xpack.ml.anomalyUtils.multiBucketImpact.lowLabel": "低", "xpack.ml.anomalyUtils.multiBucketImpact.mediumLabel": "中", @@ -9447,6 +11045,9 @@ "xpack.ml.dataframe.analytics.classificationExploration.showActions": "显示操作", "xpack.ml.dataframe.analytics.classificationExploration.showAllColumns": "显示所有列", "xpack.ml.dataframe.analytics.classificationExploration.tableJobIdTitle": "分类作业 ID {jobId} 的目标索引", + "xpack.ml.dataframe.analytics.create.advancedConfigDetailsTitle": "高级配置", + "xpack.ml.dataframe.analytics.create.advancedConfigSectionTitle": "高级配置", + "xpack.ml.dataframe.analytics.create.advancedDetails.editButtonText": "编辑", "xpack.ml.dataframe.analytics.create.advancedEditor.codeEditorAriaLabel": "高级分析作业编辑器", "xpack.ml.dataframe.analytics.create.advancedEditor.configRequestBody": "配置请求正文", "xpack.ml.dataframe.analytics.create.advancedEditor.jobIdExistsError": "已存在具有此 ID 的分析作业。", @@ -9457,12 +11058,63 @@ "xpack.ml.dataframe.analytics.create.advancedEditorMessage.destinationIndexNameEmpty": "目标索引名称不得为空。", "xpack.ml.dataframe.analytics.create.advancedEditorMessage.destinationIndexNameExistsWarn": "具有此目标索引名称的索引已存在。请注意,运行此分析作业将会修改此目标索引。", "xpack.ml.dataframe.analytics.create.advancedEditorMessage.destinationIndexNameValid": "目标索引名称无效。", + "xpack.ml.dataframe.analytics.create.advancedEditorMessage.includesInvalid": "必须包括因变量。", "xpack.ml.dataframe.analytics.create.advancedEditorMessage.modelMemoryLimitEmpty": "模型内存限制字段不得为空。", "xpack.ml.dataframe.analytics.create.advancedEditorMessage.numTopFeatureImportanceValuesInvalid": "num_top_feature_importance_values 的值必须是 {min} 或更高的整数。", + "xpack.ml.dataframe.analytics.create.advancedEditorMessage.resultsFieldEmptyString": "结果字段不得为空字符串。", "xpack.ml.dataframe.analytics.create.advancedEditorMessage.sourceIndexNameEmpty": "源索引名称不得为空。", "xpack.ml.dataframe.analytics.create.advancedEditorMessage.sourceIndexNameValid": "源索引名称无效。", "xpack.ml.dataframe.analytics.create.advancedEditorMessage.trainingPercentInvalid": "训练百分比必须是介于 {min} 和 {max} 之间的整数。", + "xpack.ml.dataframe.analytics.create.allDocsMissingFieldsErrorMessage": "无法估计内存使用量。源索引 [{index}] 具有在任何已索引文档中不存在的已映射字段。您将需要切换到 JSON 编辑器以显式选择字段并仅包括索引文档中存在的字段。", + "xpack.ml.dataframe.analytics.create.analysisFieldsTable.fieldNameColumn": "字段名称", + "xpack.ml.dataframe.analytics.create.analysisFieldsTable.minimumFieldsMessage": "必须至少选择一个字段。", + "xpack.ml.dataframe.analytics.create.analyticsListCardDescription": "返回到分析管理页面。", + "xpack.ml.dataframe.analytics.create.analyticsListCardTitle": "数据帧分析", + "xpack.ml.dataframe.analytics.create.analyticsProgressCalloutMessage": "分析作业 {jobId} 失败。", + "xpack.ml.dataframe.analytics.create.analyticsProgressCalloutTitle": "作业失败", + "xpack.ml.dataframe.analytics.create.analyticsProgressErrorMessage": "获取分析作业 {jobId} 的进度统计时发生错误", + "xpack.ml.dataframe.analytics.create.analyticsProgressPhaseTitle": "阶段", + "xpack.ml.dataframe.analytics.create.analyticsProgressTitle": "进度", + "xpack.ml.dataframe.analytics.create.analyticsTable.isIncludedColumn": "已包括", + "xpack.ml.dataframe.analytics.create.analyticsTable.isRequiredColumn": "必填", + "xpack.ml.dataframe.analytics.create.analyticsTable.mappingColumn": "映射", + "xpack.ml.dataframe.analytics.create.analyticsTable.reasonColumn": "原因", + "xpack.ml.dataframe.analytics.create.calloutMessage": "加载分析字段的其他数据。", + "xpack.ml.dataframe.analytics.create.calloutTitle": "分析字段不可用", + "xpack.ml.dataframe.analytics.create.chooseSourceTitle": "选择源索引模式", "xpack.ml.dataframe.analytics.create.classificationHelpText": "分类作业需要映射为表状数据结构的源索引,并支持数值、布尔、文本、关键字或 IP 字段。使用高级编辑器来应用定制选项,如预测字段名称。", + "xpack.ml.dataframe.analytics.create.computeFeatureInfluenceFalseValue": "False", + "xpack.ml.dataframe.analytics.create.computeFeatureInfluenceLabel": "计算功能影响", + "xpack.ml.dataframe.analytics.create.computeFeatureInfluenceLabelHelpText": "指定是否启用功能影响计算。默认为 true。", + "xpack.ml.dataframe.analytics.create.computeFeatureInfluenceTrueValue": "True", + "xpack.ml.dataframe.analytics.create.configDetails.computeFeatureInfluence": "计算功能影响", + "xpack.ml.dataframe.analytics.create.configDetails.dependentVariable": "因变量", + "xpack.ml.dataframe.analytics.create.configDetails.destIndex": "目标索引", + "xpack.ml.dataframe.analytics.create.configDetails.editButtonText": "编辑", + "xpack.ml.dataframe.analytics.create.configDetails.eta": "Eta", + "xpack.ml.dataframe.analytics.create.configDetails.featureBagFraction": "特征袋比例", + "xpack.ml.dataframe.analytics.create.configDetails.featureInfluenceThreshold": "特征影响阈值", + "xpack.ml.dataframe.analytics.create.configDetails.gamma": "Gamma", + "xpack.ml.dataframe.analytics.create.configDetails.includedFields": "已包括字段", + "xpack.ml.dataframe.analytics.create.configDetails.jobDescription": "作业描述", + "xpack.ml.dataframe.analytics.create.configDetails.jobId": "作业 ID", + "xpack.ml.dataframe.analytics.create.configDetails.jobType": "作业类型", + "xpack.ml.dataframe.analytics.create.configDetails.lambdaFields": "Lambda", + "xpack.ml.dataframe.analytics.create.configDetails.maxNumThreads": "最大线程数", + "xpack.ml.dataframe.analytics.create.configDetails.maxTreesFields": "最大树数", + "xpack.ml.dataframe.analytics.create.configDetails.method": "方法", + "xpack.ml.dataframe.analytics.create.configDetails.modelMemoryLimit": "模型内存限制", + "xpack.ml.dataframe.analytics.create.configDetails.nNeighbors": "N 个邻居", + "xpack.ml.dataframe.analytics.create.configDetails.numTopClasses": "排名靠前类", + "xpack.ml.dataframe.analytics.create.configDetails.numTopFeatureImportanceValues": "排名靠前特征重要性值", + "xpack.ml.dataframe.analytics.create.configDetails.outlierFraction": "离群值比例", + "xpack.ml.dataframe.analytics.create.configDetails.predictionFieldName": "预测字段名称", + "xpack.ml.dataframe.analytics.create.configDetails.Query": "查询", + "xpack.ml.dataframe.analytics.create.configDetails.randomizedSeed": "随机种子", + "xpack.ml.dataframe.analytics.create.configDetails.resultsField": "结果字段", + "xpack.ml.dataframe.analytics.create.configDetails.sourceIndex": "源索引", + "xpack.ml.dataframe.analytics.create.configDetails.standardizationEnabled": "标准化已启用", + "xpack.ml.dataframe.analytics.create.configDetails.trainingPercent": "训练百分比", "xpack.ml.dataframe.analytics.create.createIndexPatternErrorMessage": "创建 Kibana 索引模式时发生错误:", "xpack.ml.dataframe.analytics.create.createIndexPatternLabel": "创建索引模式", "xpack.ml.dataframe.analytics.create.createIndexPatternSuccessMessage": "Kibana 索引模式 {indexPatternName} 已创建。", @@ -9476,14 +11128,33 @@ "xpack.ml.dataframe.analytics.create.destinationIndexInputAriaLabel": "选择唯一目标索引名称。", "xpack.ml.dataframe.analytics.create.destinationIndexInvalidError": "目标索引名称无效。", "xpack.ml.dataframe.analytics.create.destinationIndexLabel": "目标 IP", + "xpack.ml.dataframe.analytics.create.detailsDetails.editButtonText": "编辑", "xpack.ml.dataframe.analytics.create.duplicateIndexPatternErrorMessage": "创建 Kibana 索引模式时发生错误:", "xpack.ml.dataframe.analytics.create.duplicateIndexPatternErrorMessageError": "索引模式 {indexPatternName} 已存在。", + "xpack.ml.dataframe.analytics.create.enableJsonEditorHelpText": "您不能从 json 编辑器切回到此表单。", "xpack.ml.dataframe.analytics.create.errorCreatingDataFrameAnalyticsJob": "创建数据帧分析作业时发生错误:", "xpack.ml.dataframe.analytics.create.errorGettingDataFrameAnalyticsList": "获取现有数据帧分析作业 ID 时发生错误:", "xpack.ml.dataframe.analytics.create.errorGettingIndexPatternTitles": "获取现有索引模式标题时发生错误:", "xpack.ml.dataframe.analytics.create.errorStartingDataFrameAnalyticsJob": "启动数据帧分析作业时发生错误:", + "xpack.ml.dataframe.analytics.create.etaInputAriaLabel": "缩小量已应用于权重", + "xpack.ml.dataframe.analytics.create.etaLabel": "Eta", + "xpack.ml.dataframe.analytics.create.etaText": "缩小量已应用于权重。必须介于 0.001 和 1 之间。", + "xpack.ml.dataframe.analytics.create.featureBagFractionInputAriaLabel": "选择为每个候选拆分选择随机袋时使用的特征比例", + "xpack.ml.dataframe.analytics.create.featureBagFractionLabel": "特征袋比例", + "xpack.ml.dataframe.analytics.create.featureBagFractionText": "选择为每个候选拆分选择随机袋时使用的特征比例。", + "xpack.ml.dataframe.analytics.create.featureInfluenceThresholdHelpText": "为了计算文档特征影响分数,文档需要具有的最小离群值分数。值范围:0-1。默认为 0.1。", + "xpack.ml.dataframe.analytics.create.featureInfluenceThresholdLabel": "特征影响阈值", + "xpack.ml.dataframe.analytics.create.gammaInputAriaLabel": "乘与森林中的各个树的大小关联的线性罚分", + "xpack.ml.dataframe.analytics.create.gammaLabel": "Gamma", + "xpack.ml.dataframe.analytics.create.gammaText": "乘与森林中的各个树的大小关联的线性罚分。必须为非负值。", + "xpack.ml.dataframe.analytics.create.hyperParametersDetailsTitle": "超参数", + "xpack.ml.dataframe.analytics.create.hyperParametersSectionTitle": "超参数", + "xpack.ml.dataframe.analytics.create.includedFieldsCount": "分析中包括了{numFields, plural, one {# 个字段} other {# 个字段}}", + "xpack.ml.dataframe.analytics.create.includedFieldsLabel": "已包括字段", "xpack.ml.dataframe.analytics.create.indexPatternAlreadyExistsError": "具有此名称的索引模式已存在。", "xpack.ml.dataframe.analytics.create.indexPatternExistsError": "具有此名称的索引模式已存在。", + "xpack.ml.dataframe.analytics.create.isIncludedOption": "已包括", + "xpack.ml.dataframe.analytics.create.isNotIncludedOption": "未包括", "xpack.ml.dataframe.analytics.create.jobDescription.helpText": "可选的描述文本", "xpack.ml.dataframe.analytics.create.jobDescription.label": "作业描述", "xpack.ml.dataframe.analytics.create.jobIdExistsError": "已存在具有此 ID 的分析作业。", @@ -9493,18 +11164,78 @@ "xpack.ml.dataframe.analytics.create.jobIdLabel": "作业 ID", "xpack.ml.dataframe.analytics.create.jobIdPlaceholder": "作业 ID", "xpack.ml.dataframe.analytics.create.jobTypeLabel": "作业类型", + "xpack.ml.dataframe.analytics.create.lambdaHelpText": "在训练数据集上防止过度拟合的正则化参数。必须为非负值。", + "xpack.ml.dataframe.analytics.create.lambdaInputAriaLabel": "在训练数据集上防止过度拟合的正则化参数。", + "xpack.ml.dataframe.analytics.create.lambdaLabel": "Lambda", + "xpack.ml.dataframe.analytics.create.maxNumThreadsError": "最小值为 1。", + "xpack.ml.dataframe.analytics.create.maxNumThreadsHelpText": "分析要使用的最大线程数。默认值为 1", + "xpack.ml.dataframe.analytics.create.maxNumThreadsInputAriaLabel": "分析要使用的最大线程数。", + "xpack.ml.dataframe.analytics.create.maxNumThreadsLabel": "最大线程数", + "xpack.ml.dataframe.analytics.create.maxTreesInputAriaLabel": "允许森林包含的最大树数。", + "xpack.ml.dataframe.analytics.create.maxTreesLabel": "最大树数", + "xpack.ml.dataframe.analytics.create.maxTreesText": "允许森林包含的最大树数。", + "xpack.ml.dataframe.analytics.create.methodHelpText": "设置离群值检测使用的方法。如果未设置,请组合使用不同的方法并标准化和组合各自的离群值分数以获取整体离群值分数。我们建议使用组合方法", + "xpack.ml.dataframe.analytics.create.methodLabel": "方法", + "xpack.ml.dataframe.analytics.create.modelMemoryEmptyError": "模型内存限制不得为空", + "xpack.ml.dataframe.analytics.create.modelMemoryLimitHelpText": "允许用于分析处理的近似最大内存资源量。", "xpack.ml.dataframe.analytics.create.modelMemoryLimitLabel": "模型内存限制", "xpack.ml.dataframe.analytics.create.modelMemoryUnitsInvalidError": "无法识别模型内存限制数据单元。必须为 {str}", "xpack.ml.dataframe.analytics.create.modelMemoryUnitsMinError": "模型内存限制不能低于 {mml}", + "xpack.ml.dataframe.analytics.create.newAnalyticsTitle": "新建分析作业", + "xpack.ml.dataframe.analytics.create.nNeighborsHelpText": "每个离群值检测方法用于计算其离群值分数的近邻数目值。未设置时,不同的值将用于不同组合成员。必须为正整数", + "xpack.ml.dataframe.analytics.create.nNeighborsInputAriaLabel": "每个离群值检测方法用于计算其离群值分数的近邻数目值。", + "xpack.ml.dataframe.analytics.create.nNeighborsLabel": "N 个邻居", + "xpack.ml.dataframe.analytics.create.numTopClassesHelpText": "报告预测概率的类别数目。", + "xpack.ml.dataframe.analytics.create.numTopClassesInputAriaLabel": "报告预测概率的类别数目", + "xpack.ml.dataframe.analytics.create.numTopClassesLabel": "排名靠前类", "xpack.ml.dataframe.analytics.create.numTopFeatureImportanceValuesErrorText": "功能重要性值最大数目无效。", "xpack.ml.dataframe.analytics.create.numTopFeatureImportanceValuesHelpText": "指定要返回的每文档功能重要性值最大数目。", "xpack.ml.dataframe.analytics.create.numTopFeatureImportanceValuesInputAriaLabel": "每文档功能重要性值最大数目。", "xpack.ml.dataframe.analytics.create.numTopFeatureImportanceValuesLabel": "功能重要性值", "xpack.ml.dataframe.analytics.create.outlierDetectionHelpText": "离群值检测作业需要映射为表状数据结构的源索引,并仅分析数值和布尔值字段。使用高级编辑器将定制选项添加到配置。", + "xpack.ml.dataframe.analytics.create.outlierFractionHelpText": "设置在离群值检测之前被假设为离群的数据集比例。", + "xpack.ml.dataframe.analytics.create.outlierFractionInputAriaLabel": "设置在离群值检测之前被假设为离群的数据集比例。", + "xpack.ml.dataframe.analytics.create.outlierFractionLabel": "离群值比例", "xpack.ml.dataframe.analytics.create.outlierRegressionHelpText": "回归作业仅分析数值字段。使用高级编辑器来应用定制选项,如预测字段名称。", + "xpack.ml.dataframe.analytics.create.predictionFieldNameHelpText": "定义结果中预测字段的名称。默认为 _prediction。", + "xpack.ml.dataframe.analytics.create.predictionFieldNameLabel": "预测字段名称", + "xpack.ml.dataframe.analytics.create.randomizeSeedInputAriaLabel": "用于选取哪个文档用于训练的随机生成器种子", + "xpack.ml.dataframe.analytics.create.randomizeSeedLabel": "随机种子", + "xpack.ml.dataframe.analytics.create.randomizeSeedText": "用于选取哪个文档用于训练的随机生成器种子。", "xpack.ml.dataframe.analytics.create.requiredFieldsError": "无效。{message}", + "xpack.ml.dataframe.analytics.create.resultsFieldHelpText": "定义用于存储分析结果的字段的名称。默认为 ml。", + "xpack.ml.dataframe.analytics.create.resultsFieldLabel": "结果字段", + "xpack.ml.dataframe.analytics.create.savedSearchLabel": "已保存搜索", + "xpack.ml.dataFrame.analytics.create.searchSelection.notFoundLabel": "未找到匹配的索引或已保存搜索。", + "xpack.ml.dataFrame.analytics.create.searchSelection.savedObjectType.indexPattern": "索引模式", + "xpack.ml.dataFrame.analytics.create.searchSelection.savedObjectType.search": "已保存搜索", + "xpack.ml.dataframe.analytics.create.shouldCreateIndexPatternMessage": "如果没有为目标索引创建索引模式,则可能无法查看作业结果。", + "xpack.ml.dataframe.analytics.create.sourceIndexFieldsCheckError": "检查作业类型支持的字段时出现问题。请刷新页面并重试。", + "xpack.ml.dataframe.analytics.create.sourceObjectClassificationHelpText": "此索引模式不包含任何支持字段。分类作业需要类别、数值或布尔值字段。", + "xpack.ml.dataframe.analytics.create.sourceObjectHelpText": "此索引模式不包含任何数值类型字段。分析作业可能无法生成任何离群值。", + "xpack.ml.dataframe.analytics.create.sourceObjectRegressionHelpText": "此索引模式不包含任何支持字段。回归作业需要数值字段。", + "xpack.ml.dataframe.analytics.create.sourceQueryLabel": "查询", + "xpack.ml.dataframe.analytics.create.standardizationEnabledFalseValue": "False", + "xpack.ml.dataframe.analytics.create.standardizationEnabledHelpText": "如果为 true,在计算离群值分数之前将对列执行以下操作:(x_i - mean(x_i)) / sd(x_i)。", + "xpack.ml.dataframe.analytics.create.standardizationEnabledInputAriaLabel": "设置启用标准化的设置。", + "xpack.ml.dataframe.analytics.create.standardizationEnabledLabel": "标准化已启用", + "xpack.ml.dataframe.analytics.create.standardizationEnabledTrueValue": "True", + "xpack.ml.dataframe.analytics.create.startCheckboxHelpText": "如果未选择,可以之后通过返还到作业列表来启动作业。", "xpack.ml.dataframe.analytics.create.startDataFrameAnalyticsSuccessMessage": "数据帧分析 {jobId} 启动请求已确认。", + "xpack.ml.dataframe.analytics.create.switchToJsonEditorSwitch": "切换到 json 编辑器", + "xpack.ml.dataframe.analytics.create.trainingPercentHelpText": "定义用于训练的合格文档的百分比。", "xpack.ml.dataframe.analytics.create.trainingPercentLabel": "训练百分比", + "xpack.ml.dataframe.analytics.create.unsupportedFieldsError": "无效。{message}", + "xpack.ml.dataframe.analytics.create.wizardCreateButton": "创建", + "xpack.ml.dataframe.analytics.create.wizardStartCheckbox": "立即启动", + "xpack.ml.dataframe.analytics.createWizard.requiredFieldsErrorMessage": "除了因变量之外,还必须在分析中至少包括一个字段。", + "xpack.ml.dataframe.analytics.creation.advancedStepTitle": "其他选项", + "xpack.ml.dataframe.analytics.creation.configurationStepTitle": "配置", + "xpack.ml.dataframe.analytics.creation.continueButtonText": "继续", + "xpack.ml.dataframe.analytics.creation.createStepTitle": "创建", + "xpack.ml.dataframe.analytics.creation.detailsStepTitle": "作业详情", + "xpack.ml.dataframe.analytics.creationPageSourceIndexTitle": "源索引模式:{indexTitle}", + "xpack.ml.dataframe.analytics.creationPageTitle": "创建作业", "xpack.ml.dataframe.analytics.errorCallout.evaluateErrorTitle": "加载数据时出错。", "xpack.ml.dataframe.analytics.errorCallout.generalErrorTitle": "加载数据时出错。", "xpack.ml.dataframe.analytics.errorCallout.noDataCalloutBody": "该索引的查询未返回结果。请确保作业已完成且索引包含文档。", @@ -9521,15 +11252,21 @@ "xpack.ml.dataframe.analytics.explorationResults.documentsShownHelpText": "正在显示有相关预测存在的文档", "xpack.ml.dataframe.analytics.explorationResults.fieldSelection": "已选择 {docFieldsCount, number} 个{docFieldsCount, plural, one {字段} other {字段}}中的 {selectedFieldsLength, number} 个", "xpack.ml.dataframe.analytics.explorationResults.firstDocumentsShownHelpText": "正在显示有相关预测存在的前 {searchSize} 个文档", + "xpack.ml.dataframe.analytics.indexPatternPromptLinkText": "创建索引模式", + "xpack.ml.dataframe.analytics.indexPatternPromptMessage": "不存在索引 {destIndex} 的索引模式。{destIndex} 的{linkToIndexPatternManagement}。", "xpack.ml.dataframe.analytics.jobCaps.errorTitle": "无法提取结果。加载索引的字段数据时发生错误。", "xpack.ml.dataframe.analytics.jobConfig.errorTitle": "无法提取结果。加载作业配置数据时发生错误。", "xpack.ml.dataframe.analytics.regressionExploration.evaluateJobIdTitle": "回归作业 ID {jobId} 的评估", "xpack.ml.dataframe.analytics.regressionExploration.generalizationDocsCount": "{docsCount, plural, one {# 个文档} other {# 个文档}}已评估", "xpack.ml.dataframe.analytics.regressionExploration.generalizationErrorTitle": "泛化误差", "xpack.ml.dataframe.analytics.regressionExploration.generalizationFilterText": ".筛留训练数据。", + "xpack.ml.dataframe.analytics.regressionExploration.huberLinkText": "Pseudo Huber 损失函数", + "xpack.ml.dataframe.analytics.regressionExploration.huberText": "{wikiLink}", "xpack.ml.dataframe.analytics.regressionExploration.indexError": "加载索引数据时出错。", "xpack.ml.dataframe.analytics.regressionExploration.meanSquaredErrorText": "均方误差", "xpack.ml.dataframe.analytics.regressionExploration.meanSquaredErrorTooltipContent": "度量回归分析模型的表现。真实值与预测值之差的平均平方和。", + "xpack.ml.dataframe.analytics.regressionExploration.msleText": "均方根对数误差", + "xpack.ml.dataframe.analytics.regressionExploration.msleTooltipContent": "预测值对数和实际值对数和实际(真实)值对数的均方差", "xpack.ml.dataframe.analytics.regressionExploration.regressionDocsLink": "回归评估文档 ", "xpack.ml.dataframe.analytics.regressionExploration.rSquaredText": "R 平方", "xpack.ml.dataframe.analytics.regressionExploration.rSquaredTooltipContent": "表示拟合优度。度量模型复制被观察结果的优良性。", @@ -9540,19 +11277,49 @@ "xpack.ml.dataframe.analyticsList.analyticsDetails.tabs.analyticsMessagesLabel": "作业消息", "xpack.ml.dataframe.analyticsList.cloneJobButtonLabel": "克隆作业", "xpack.ml.dataframe.analyticsList.completeBatchAnalyticsToolTip": "{analyticsId} 为已完成的分析作业,无法重新启动。", - "xpack.ml.dataframe.analyticsList.createDataFrameAnalyticsButton": "创建分析作业", - "xpack.ml.dataframe.analyticsList.deleteActionDisabledToolTipContent": "停止数据帧分析,才能将其删除。", + "xpack.ml.dataframe.analyticsList.createDataFrameAnalyticsButton": "创建作业", + "xpack.ml.dataframe.analyticsList.deleteActionDisabledToolTipContent": "停止数据帧分析作业,以便将其删除。", "xpack.ml.dataframe.analyticsList.deleteActionName": "删除", - "xpack.ml.dataframe.analyticsList.deleteAnalyticsSuccessMessage": "数据帧分析 {analyticsId} 删除请求已确认。", - "xpack.ml.dataframe.analyticsList.deleteModalBody": "是否确定要删除此分析作业?分析作业的目标索引和可选 Kibana 索引模式将不会删除。", + "xpack.ml.dataframe.analyticsList.deleteAnalyticsErrorMessage": "删除数据帧分析作业 {analyticsId} 时发生错误", + "xpack.ml.dataframe.analyticsList.deleteAnalyticsPrivilegeErrorMessage": "用户无权删除索引 {indexName}:{error}", + "xpack.ml.dataframe.analyticsList.deleteAnalyticsSuccessMessage": "删除的数据帧分析作业 {analyticsId} 的请求已确认。", + "xpack.ml.dataframe.analyticsList.deleteAnalyticsWithIndexErrorMessage": "删除目标索引 {destinationIndex} 时发生错误:{error}", + "xpack.ml.dataframe.analyticsList.deleteAnalyticsWithIndexPatternErrorMessage": "删除索引模式 {destinationIndex} 时发生错误:{error}", + "xpack.ml.dataframe.analyticsList.deleteAnalyticsWithIndexPatternSuccessMessage": "删除索引模式 {destinationIndex} 的请求已确认。", + "xpack.ml.dataframe.analyticsList.deleteAnalyticsWithIndexSuccessMessage": "删除目标索引 {destinationIndex} 的请求已确认。", + "xpack.ml.dataframe.analyticsList.deleteDestinationIndexTitle": "删除目标索引 {indexName}", + "xpack.ml.dataframe.analyticsList.deleteModalBody": "是否确定要删除此分析作业?", "xpack.ml.dataframe.analyticsList.deleteModalCancelButton": "取消", "xpack.ml.dataframe.analyticsList.deleteModalDeleteButton": "删除", "xpack.ml.dataframe.analyticsList.deleteModalTitle": "删除 {analyticsId}", + "xpack.ml.dataframe.analyticsList.deleteTargetIndexPatternTitle": "删除索引模式 {indexPattern}", "xpack.ml.dataframe.analyticsList.description": "描述", "xpack.ml.dataframe.analyticsList.destinationIndex": "目标 IP", + "xpack.ml.dataframe.analyticsList.editActionName": "编辑", + "xpack.ml.dataframe.analyticsList.editActionPermissionTooltip": "您无权编辑分析作业。", + "xpack.ml.dataframe.analyticsList.editFlyout.allowLazyStartAriaLabel": "更新允许惰性启动。", + "xpack.ml.dataframe.analyticsList.editFlyout.allowLazyStartFalseValue": "False", + "xpack.ml.dataframe.analyticsList.editFlyout.allowLazyStartLabel": "允许惰性启动", + "xpack.ml.dataframe.analyticsList.editFlyout.allowLazyStartTrueValue": "True", + "xpack.ml.dataframe.analyticsList.editFlyout.descriptionAriaLabel": "更新作业描述。", + "xpack.ml.dataframe.analyticsList.editFlyout.descriptionLabel": "描述", + "xpack.ml.dataframe.analyticsList.editFlyout.maxNumThreadsAriaLabel": "更新分析要使用的最大线程数。", + "xpack.ml.dataframe.analyticsList.editFlyout.maxNumThreadsError": "最小值为 1。", + "xpack.ml.dataframe.analyticsList.editFlyout.maxNumThreadsHelpText": "停止作业后才能编辑最大线程数。", + "xpack.ml.dataframe.analyticsList.editFlyout.maxNumThreadsLabel": "最大线程数", + "xpack.ml.dataframe.analyticsList.editFlyout.modelMemoryHelpText": "停止作业后才能编辑模型内存限制。", + "xpack.ml.dataframe.analyticsList.editFlyout.modelMemoryLimitAriaLabel": "更新模型内存限制。", + "xpack.ml.dataframe.analyticsList.editFlyout.modelMemoryLimitLabel": "模型内存限制", + "xpack.ml.dataframe.analyticsList.editFlyoutCancelButtonText": "取消", + "xpack.ml.dataframe.analyticsList.editFlyoutErrorMessage": "无法保存分析作业 {jobId} 的更改", + "xpack.ml.dataframe.analyticsList.editFlyoutSuccessMessage": "分析作业 {jobId} 已更新。", + "xpack.ml.dataframe.analyticsList.editFlyoutTitle": "编辑 {jobId}", + "xpack.ml.dataframe.analyticsList.editFlyoutUpdateButtonText": "更新", "xpack.ml.dataFrame.analyticsList.emptyPromptButtonText": "创建您的首个数据帧分析作业", "xpack.ml.dataFrame.analyticsList.emptyPromptTitle": "未找到任何数据帧分析作业", "xpack.ml.dataFrame.analyticsList.errorPromptTitle": "获取数据帧分析列表时发生错误。", + "xpack.ml.dataframe.analyticsList.errorWithCheckingIfIndexPatternExistsNotificationErrorMessage": "检查索引模式 {indexPattern} 是否存在时发生错误:{error}", + "xpack.ml.dataframe.analyticsList.errorWithCheckingIfUserCanDeleteIndexNotificationErrorMessage": "检查用户是否能够删除 {destinationIndex} 时发生错误:{error}", "xpack.ml.dataframe.analyticsList.expandedRow.tabs.jobSettings.phase": "阶段", "xpack.ml.dataframe.analyticsList.expandedRow.tabs.jobSettings.progress": "进度", "xpack.ml.dataframe.analyticsList.expandedRow.tabs.jobSettings.state": "状态", @@ -9560,6 +11327,7 @@ "xpack.ml.dataframe.analyticsList.expandedRow.tabs.jobSettingsLabel": "作业详情", "xpack.ml.dataframe.analyticsList.experimentalBadgeLabel": "实验性", "xpack.ml.dataframe.analyticsList.experimentalBadgeTooltipContent": "数据帧分析为实验功能。我们很乐意听取您的反馈意见。", + "xpack.ml.dataframe.analyticsList.fetchSourceIndexPatternForCloneErrorMessage": "检查索引模式 {indexPattern} 是否存在时发生错误:{error}", "xpack.ml.dataframe.analyticsList.progress": "进度", "xpack.ml.dataframe.analyticsList.progressOfPhase": "阶段 {currentPhase} 的进度:{progress}%", "xpack.ml.dataframe.analyticsList.refreshButtonLabel": "刷新", @@ -9568,6 +11336,7 @@ "xpack.ml.dataframe.analyticsList.showDetailsColumn.screenReaderDescription": "此列包含可单击控件,用于显示每个作业的更多详情", "xpack.ml.dataframe.analyticsList.sourceIndex": "源索引", "xpack.ml.dataframe.analyticsList.startActionName": "开始", + "xpack.ml.dataframe.analyticsList.startAnalyticsErrorTitle": "启动作业时出错", "xpack.ml.dataframe.analyticsList.startAnalyticsSuccessMessage": "数据帧分析 {analyticsId} 启动请求已确认。", "xpack.ml.dataframe.analyticsList.startModalBody": "数据帧分析作业将增加集群的搜索和索引负荷。如果负荷超载,请停止分析作业。是否确定要启动此分析作业?", "xpack.ml.dataframe.analyticsList.startModalCancelButton": "取消", @@ -9579,19 +11348,29 @@ "xpack.ml.dataframe.analyticsList.stopAnalyticsErrorMessage": "停止数据帧分析 {analyticsId} 时发生错误:{error}", "xpack.ml.dataframe.analyticsList.stopAnalyticsSuccessMessage": "数据帧分析 {analyticsId} 停止请求已确认。", "xpack.ml.dataframe.analyticsList.tableActionLabel": "操作", - "xpack.ml.dataframe.analyticsList.title": "分析作业", + "xpack.ml.dataframe.analyticsList.title": "数据帧分析作业", "xpack.ml.dataframe.analyticsList.type": "类型", + "xpack.ml.dataframe.analyticsList.typeFilter": "类型", "xpack.ml.dataframe.analyticsList.viewActionName": "查看", "xpack.ml.dataframe.stepCreateForm.createDataFrameAnalyticsSuccessMessage": "数据帧分析 {jobId} 创建请求已确认。", "xpack.ml.dataframe.stepDetailsForm.destinationIndexInvalidErrorLink": "详细了解索引名称限制。", - "xpack.ml.dataFrameAnalyticsBreadcrumbs.dataFrameExplorationLabel": "数据帧分析", - "xpack.ml.dataFrameAnalyticsBreadcrumbs.dataFrameListLabel": "数据帧分析", + "xpack.ml.dataFrameAnalyticsBreadcrumbs.dataFrameExplorationLabel": "探查", + "xpack.ml.dataFrameAnalyticsBreadcrumbs.dataFrameListLabel": "作业管理", + "xpack.ml.dataFrameAnalyticsBreadcrumbs.dataFrameManagementLabel": "数据帧分析", "xpack.ml.dataFrameAnalyticsBreadcrumbs.indexLabel": "索引", + "xpack.ml.dataFrameAnalyticsLabel": "数据帧分析", + "xpack.ml.dataGrid.columnChart.ErrorMessageToast": "提取直方图数据时发生错误:{error}", "xpack.ml.dataGrid.dataGridNoDataCalloutTitle": "索引预览不可用", + "xpack.ml.dataGrid.histogramButtonText": "直方图", + "xpack.ml.dataGrid.histogramButtonToolTipContent": "为提取直方图数据而运行的查询将使用 {samplerShardSize} 个文档的每分片样本大小。", "xpack.ml.dataGrid.indexDataError": "加载索引数据时出错。", "xpack.ml.dataGrid.IndexNoDataCalloutBody": "该索引的查询未返回结果。请确保您有足够的权限、索引包含文档且您的查询限制不过于严格。", "xpack.ml.dataGrid.IndexNoDataCalloutTitle": "空的索引查询结果。", "xpack.ml.dataGrid.invalidSortingColumnError": "列“{columnId}”无法用于排序。", + "xpack.ml.dataGridChart.histogramNotAvailable": "不支持图表。", + "xpack.ml.dataGridChart.notEnoughData": "0 个文档包含字段。", + "xpack.ml.dataGridChart.singleCategoryLegend": "{cardinality, plural, one {# 个类别} other {# 个类别}}", + "xpack.ml.dataGridChart.topCategoriesLegend": "{cardinality} 个类别中的排名前 {MAX_CHART_COLUMNS}", "xpack.ml.datavisualizer.actionsPanel.advancedDescription": "使用全部选项为更高级的用例创建作业", "xpack.ml.datavisualizer.actionsPanel.advancedTitle": "高级", "xpack.ml.datavisualizer.actionsPanel.createJobDescription": "使用“高级作业”向导创建作业,以查找此数据中的异常:", @@ -9634,6 +11413,25 @@ "xpack.ml.datavisualizerBreadcrumbLabel": "数据可视化工具", "xpack.ml.dataVisualizerPageLabel": "数据可视化工具", "xpack.ml.dfAnalyticsList.analyticsDetails.messagesPane.errorMessage": "无法加载消息", + "xpack.ml.editModelSnapshotFlyout.calloutText": "这是作业 {jobId} 当前正在使用的快照,因此无法删除。", + "xpack.ml.editModelSnapshotFlyout.calloutTitle": "当前快照", + "xpack.ml.editModelSnapshotFlyout.cancelButton": "取消", + "xpack.ml.editModelSnapshotFlyout.closeButton": "关闭", + "xpack.ml.editModelSnapshotFlyout.deleteButton": "删除", + "xpack.ml.editModelSnapshotFlyout.deleteErrorTitle": "模型快照删除失败", + "xpack.ml.editModelSnapshotFlyout.deleteTitle": "删除快照?", + "xpack.ml.editModelSnapshotFlyout.descriptionTitle": "描述", + "xpack.ml.editModelSnapshotFlyout.retainSwitchLabel": "自动快照清除过程期间保留快照", + "xpack.ml.editModelSnapshotFlyout.saveButton": "保存", + "xpack.ml.editModelSnapshotFlyout.saveErrorTitle": "模型快照更新失败", + "xpack.ml.editModelSnapshotFlyout.title": "编辑快照 {ssId}", + "xpack.ml.editModelSnapshotFlyout.useDefaultButton": "删除", + "xpack.ml.explorer.addToDashboard.cancelButtonLabel": "取消", + "xpack.ml.explorer.addToDashboard.selectDashboardsLabel": "选择仪表板:", + "xpack.ml.explorer.addToDashboard.selectSwimlanesLabel": "选择泳道视图:", + "xpack.ml.explorer.addToDashboardLabel": "添加到仪表板", + "xpack.ml.explorer.annotationsTitle": "标注 {badge}", + "xpack.ml.explorer.annotationsTitleTotalCount": "总计:{count}", "xpack.ml.explorer.anomaliesTitle": "异常", "xpack.ml.explorer.anomalyTimelineTitle": "异常时间线", "xpack.ml.explorer.charts.detectorLabel": "{detectorLabel}{br}y 轴事件分布按 “{fieldName}” 分割", @@ -9646,6 +11444,12 @@ "xpack.ml.explorer.charts.tooManyBucketsDescription": "此选项包含太多要显示的时段。最好设置一个较短的时间范围来查看仪表板。", "xpack.ml.explorer.charts.viewLabel": "查看", "xpack.ml.explorer.createNewJobLinkText": "创建作业", + "xpack.ml.explorer.dashboardsTable.addAndEditDashboardLabel": "添加并编辑仪表板", + "xpack.ml.explorer.dashboardsTable.addToDashboardLabel": "添加到仪表板", + "xpack.ml.explorer.dashboardsTable.descriptionColumnHeader": "描述", + "xpack.ml.explorer.dashboardsTable.savedSuccessfullyTitle": "仪表板“{dashboardTitle}”已成功更新", + "xpack.ml.explorer.dashboardsTable.titleColumnHeader": "标题", + "xpack.ml.explorer.dashboardsTitle": "将泳道添加到仪表板", "xpack.ml.explorer.distributionChart.anomalyScoreLabel": "异常分数", "xpack.ml.explorer.distributionChart.entityLabel": "实体", "xpack.ml.explorer.distributionChart.typicalLabel": "典型", @@ -9662,6 +11466,7 @@ "xpack.ml.explorer.noInfluencersFoundTitle": "未找到任何 {viewBySwimlaneFieldName} 影响因素", "xpack.ml.explorer.noInfluencersFoundTitleFilterMessage": "对于指定筛选找不到任何 {viewBySwimlaneFieldName} 影响因素", "xpack.ml.explorer.noJobsFoundLabel": "找不到作业", + "xpack.ml.explorer.noResultForSelectedJobsMessage": "找不到选定{jobsCount, plural, one {作业} other {作业}}的结果", "xpack.ml.explorer.noResultsFoundLabel": "找不到结果", "xpack.ml.explorer.overallLabel": "总体", "xpack.ml.explorer.overallSwimlaneUnfilteredLabel": "{label}(未筛选)", @@ -9677,8 +11482,13 @@ "xpack.ml.explorer.sortedByMaxAnomalyScoreForTimeFormattedLabel": "(按 {viewByLoadedForTimeFormatted} 的异常分数最大值排序)", "xpack.ml.explorer.sortedByMaxAnomalyScoreLabel": "(按异常分数最大值排序)", "xpack.ml.explorer.swimlane.maxAnomalyScoreLabel": "最大异常分数", + "xpack.ml.explorer.swimlaneActions": "操作", + "xpack.ml.explorer.swimLanePagination": "异常泳道分页", + "xpack.ml.explorer.swimLaneRowsPerPage": "每页行数:{rowsCount}", + "xpack.ml.explorer.swimLaneSelectRowsPerPage": "{rowsCount} 行", "xpack.ml.explorer.topInfuencersTitle": "排名最前的影响因素", "xpack.ml.explorer.tryWideningTimeSelectionLabel": "请尝试扩大时间选择范围或进一步向前追溯", + "xpack.ml.explorer.viewByFieldLabel": "按 {viewByField} 查看", "xpack.ml.explorer.viewByLabel": "查看者", "xpack.ml.feature.reserved.description": "要向用户授予访问权限,还应分配 machine_learning_user 或 machine_learning_admin 角色。", "xpack.ml.featureRegistry.mlFeatureName": "机器学习", @@ -9902,6 +11712,8 @@ "xpack.ml.itemsGrid.noMatchingItemsTitle": "没有匹配的项", "xpack.ml.jobMessages.messageLabel": "消息", "xpack.ml.jobMessages.nodeLabel": "节点", + "xpack.ml.jobMessages.refreshAriaLabel": "刷新", + "xpack.ml.jobMessages.refreshLabel": "刷新", "xpack.ml.jobMessages.timeLabel": "时间", "xpack.ml.jobsBreadcrumbs.advancedConfigurationLabel": "高级配置", "xpack.ml.jobsBreadcrumbs.categorizationLabel": "归类", @@ -9948,6 +11760,8 @@ "xpack.ml.jobService.openJobsLabel": "打开的作业", "xpack.ml.jobService.requestMayHaveTimedOutErrorMessage": "请求可能已超时,并可能仍在后台运行。", "xpack.ml.jobService.totalJobsLabel": "总计作业数", + "xpack.ml.jobService.updateJobErrorTitle": "无法更新作业:{jobId}", + "xpack.ml.jobService.validateJobErrorTitle": "作业验证错误", "xpack.ml.jobsList.actionExecuteSuccessfullyNotificationMessage": "{successesJobsCount, plural, one{{successJob}} other{# 个作业}}{actionTextPT}已成功", "xpack.ml.jobsList.actionFailedNotificationMessage": "{failureId} 未能{actionText}", "xpack.ml.jobsList.actionsLabel": "操作", @@ -10000,11 +11814,13 @@ "xpack.ml.jobsList.editJobFlyout.datafeedTitle": "数据馈送", "xpack.ml.jobsList.editJobFlyout.detectorsTitle": "检测工具", "xpack.ml.jobsList.editJobFlyout.groupsAndJobsHasSameIdErrorMessage": "已存在具有此 ID 的作业。组和作业不能使用相同的 ID。", + "xpack.ml.jobsList.editJobFlyout.jobDetails.dailyModelSnapshotRetentionAfterDaysLabel": "每日模型快照保留开始前天数", "xpack.ml.jobsList.editJobFlyout.jobDetails.jobDescriptionLabel": "作业描述", "xpack.ml.jobsList.editJobFlyout.jobDetails.jobGroupsLabel": "作业组", "xpack.ml.jobsList.editJobFlyout.jobDetails.jobGroupsPlaceholder": "选择或创建组", "xpack.ml.jobsList.editJobFlyout.jobDetails.modelMemoryLimitLabel": "模型内存限制", "xpack.ml.jobsList.editJobFlyout.jobDetails.modelMemoryLimitLabelHelp": "数据馈送正在运行时,不能编辑模型内存限制。", + "xpack.ml.jobsList.editJobFlyout.jobDetails.modelSnapshotRetentionDaysLabel": "模型快照保留天数", "xpack.ml.jobsList.editJobFlyout.jobDetailsTitle": "作业详情", "xpack.ml.jobsList.editJobFlyout.leaveAnywayButtonLabel": "离开", "xpack.ml.jobsList.editJobFlyout.pageTitle": "编辑 {jobId}", @@ -10055,6 +11871,7 @@ "xpack.ml.jobsList.jobDetails.tabs.jobMessagesLabel": "作业消息", "xpack.ml.jobsList.jobDetails.tabs.jobSettingsLabel": "作业设置", "xpack.ml.jobsList.jobDetails.tabs.jsonLabel": "JSON", + "xpack.ml.jobsList.jobDetails.tabs.modelSnapshotsLabel": "模块快照", "xpack.ml.jobsList.jobFilterBar.closedLabel": "已关闭", "xpack.ml.jobsList.jobFilterBar.failedLabel": "失败", "xpack.ml.jobsList.jobFilterBar.groupLabel": "组", @@ -10145,7 +11962,7 @@ "xpack.ml.management.jobsList.jobsListTitle": "Machine Learning", "xpack.ml.management.jobsList.noGrantedPrivilegesDescription": "您无权管理 ML 作业", "xpack.ml.management.jobsList.noPermissionToAccessLabel": "您需要访问 ML 作业的权限", - "xpack.ml.management.jobsListTitle": "作业列表", + "xpack.ml.management.jobsListTitle": "Machine Learning", "xpack.ml.maxFileSizeSettingsDescription": "设置在文件数据可视化工具中导入数据时的文件大小限制。此设置支持的最高值为 1GB。", "xpack.ml.maxFileSizeSettingsError": "应为有效的数据大小。如 200MB、1GB", "xpack.ml.maxFileSizeSettingsName": "文件数据可视化工具最大文件上传大小", @@ -10168,6 +11985,7 @@ "xpack.ml.models.jobService.deletingJob": "正在删除", "xpack.ml.models.jobService.jobHasNoDatafeedErrorMessage": "作业没有数据馈送", "xpack.ml.models.jobService.requestToActionTimedOutErrorMessage": "对 {action} “{id}” 的请求超时。{extra}", + "xpack.ml.models.jobService.revertModelSnapshot.autoCreatedCalendar.description": "自动创建", "xpack.ml.models.jobValidation.messages.bucketSpanEmptyMessage": "必须指定存储桶跨度字段。", "xpack.ml.models.jobValidation.messages.bucketSpanEstimationMismatchHeading": "存储桶跨度", "xpack.ml.models.jobValidation.messages.bucketSpanEstimationMismatchMessage": "当前存储桶跨度为 {currentBucketSpan},但存储桶跨度估计返回 {estimateBucketSpan}。", @@ -10236,6 +12054,24 @@ "xpack.ml.models.jobValidation.validateJobObject.influencersAreNotArrayErrorMessage": "无效的 {invalidParamName}:需要是数组。", "xpack.ml.models.jobValidation.validateJobObject.jobIsNotObjectErrorMessage": "无效的 {invalidParamName}:需要是对象。", "xpack.ml.models.jobValidation.validateJobObject.timeFieldIsNotStringErrorMessage": "无效的 {invalidParamName}:需要是字符串。", + "xpack.ml.modelSnapshotTable.actions": "操作", + "xpack.ml.modelSnapshotTable.actions.edit.description": "编辑此快照", + "xpack.ml.modelSnapshotTable.actions.edit.name": "编辑", + "xpack.ml.modelSnapshotTable.actions.revert.description": "恢复为此快照", + "xpack.ml.modelSnapshotTable.actions.revert.name": "恢复", + "xpack.ml.modelSnapshotTable.closeJobConfirm.cancelButton": "取消", + "xpack.ml.modelSnapshotTable.closeJobConfirm.close.button": "强制关闭", + "xpack.ml.modelSnapshotTable.closeJobConfirm.close.title": "关闭作业?", + "xpack.ml.modelSnapshotTable.closeJobConfirm.content": "快照恢复仅会发生在关闭的作业上。", + "xpack.ml.modelSnapshotTable.closeJobConfirm.contentOpen": "作业当前处于打开状态。", + "xpack.ml.modelSnapshotTable.closeJobConfirm.contentOpenAndRunning": "作业当前处于打开并运行状态。", + "xpack.ml.modelSnapshotTable.closeJobConfirm.stopAndClose.button": "强制停止并关闭", + "xpack.ml.modelSnapshotTable.closeJobConfirm.stopAndClose.title": "停止数据馈送和关闭作业?", + "xpack.ml.modelSnapshotTable.description": "描述", + "xpack.ml.modelSnapshotTable.id": "ID", + "xpack.ml.modelSnapshotTable.latestTimestamp": "最新时间戳", + "xpack.ml.modelSnapshotTable.retain": "保留", + "xpack.ml.modelSnapshotTable.time": "创建日期", "xpack.ml.navMenu.anomalyDetectionTabLinkText": "异常检测", "xpack.ml.navMenu.dataFrameAnalyticsTabLinkText": "分析", "xpack.ml.navMenu.dataVisualizerTabLinkText": "数据可视化工具", @@ -10262,6 +12098,7 @@ "xpack.ml.newJob.recognize.jobLabelAllowedCharactersDescription": "作业标签可以包含小写字母数字(a-z 和 0-9)、连字符或下划线;必须以字母数字字符开头和结尾", "xpack.ml.newJob.recognize.jobPrefixInvalidMaxLengthErrorMessage": "作业 ID 前缀的长度不得超过 {maxLength, plural, one {# 个字符} other {# 个字符}}。", "xpack.ml.newJob.recognize.jobsCreatedTitle": "已创建作业", + "xpack.ml.newJob.recognize.jobsCreationFailed.resetButtonAriaLabel": "重置", "xpack.ml.newJob.recognize.jobSettingsTitle": "作业设置", "xpack.ml.newJob.recognize.jobsTitle": "作业", "xpack.ml.newJob.recognize.moduleCheckJobsExistWarningDescription": "尝试检查模块中的作业是否已创建时出错。", @@ -10340,8 +12177,11 @@ "xpack.ml.newJob.wizard.jobDetailsStep.additionalSection.customUrlsSelection.description": "提供异常到 Kibana 仪表板、Discovery 页面或其他网页的链接。{learnMoreLink}", "xpack.ml.newJob.wizard.jobDetailsStep.additionalSection.customUrlsSelection.learnMoreLinkText": "了解详情", "xpack.ml.newJob.wizard.jobDetailsStep.additionalSectionButton": "其他设置", + "xpack.ml.newJob.wizard.jobDetailsStep.advancedSection.annotationsSwitchCallout.title": "如果使用此配置启用模型绘图,则我们建议也启用标注。", "xpack.ml.newJob.wizard.jobDetailsStep.advancedSection.enableModelPlot.description": "选择以存储用于绘制模型边境的其他模型信息。这会增加系统的性能开销,不建议用于高基数数据。", "xpack.ml.newJob.wizard.jobDetailsStep.advancedSection.enableModelPlot.title": "启用模型绘图", + "xpack.ml.newJob.wizard.jobDetailsStep.advancedSection.enableModelPlotAnnotations.description": "选择以在模型大幅更改时生成标注。例如,步骤更改时,将检测频率或趋势。", + "xpack.ml.newJob.wizard.jobDetailsStep.advancedSection.enableModelPlotAnnotations.title": "启用模型更改标注", "xpack.ml.newJob.wizard.jobDetailsStep.advancedSection.mmlWarning.message": "创建模型绘图非常消耗资源,不建议在选定字段的基数大于 100 时执行。此作业的预估基数为 {highCardinality}。如果使用此配置启用模型绘图,建议使用专用结果索引。", "xpack.ml.newJob.wizard.jobDetailsStep.advancedSection.mmlWarning.title": "谨慎操作!", "xpack.ml.newJob.wizard.jobDetailsStep.advancedSection.modelMemoryLimit.description": "设置分析模型可使用的内存量预计上限。", @@ -10452,6 +12292,21 @@ "xpack.ml.newJob.wizard.pickFieldsStep.summaryCountField.title": "汇总计数字段", "xpack.ml.newJob.wizard.previewJsonButton": "预览 JSON", "xpack.ml.newJob.wizard.previousStepButton": "上一页", + "xpack.ml.newJob.wizard.revertModelSnapshotFlyout.cancelButton": "取消", + "xpack.ml.newJob.wizard.revertModelSnapshotFlyout.changeSnapshotLabel": "更改快照", + "xpack.ml.newJob.wizard.revertModelSnapshotFlyout.closeButton": "关闭", + "xpack.ml.newJob.wizard.revertModelSnapshotFlyout.createCalendarSwitchHelp": "创建新日历和事件以在分析数据时跳过一段时间。", + "xpack.ml.newJob.wizard.revertModelSnapshotFlyout.createCalendarSwitchLabel": "创建日历以跳过一段时间", + "xpack.ml.newJob.wizard.revertModelSnapshotFlyout.deleteButton": "应用", + "xpack.ml.newJob.wizard.revertModelSnapshotFlyout.deleteTitle": "应用快照恢复", + "xpack.ml.newJob.wizard.revertModelSnapshotFlyout.realTimeSwitchHelp": "作业将继续运行,直至手动停止。将分析添加索引的所有新数据。", + "xpack.ml.newJob.wizard.revertModelSnapshotFlyout.realTimeSwitchLabel": "实时运行作业", + "xpack.ml.newJob.wizard.revertModelSnapshotFlyout.replaySwitchHelp": "应用恢复后重新打开作业并重放分析。", + "xpack.ml.newJob.wizard.revertModelSnapshotFlyout.replaySwitchLabel": "重放分析", + "xpack.ml.newJob.wizard.revertModelSnapshotFlyout.saveButton": "应用", + "xpack.ml.newJob.wizard.revertModelSnapshotFlyout.title": "恢复到模型快照 {ssId}", + "xpack.ml.newJob.wizard.revertModelSnapshotFlyout.warningCallout.contents": "将删除 {date} 后的所有异常检测结果。", + "xpack.ml.newJob.wizard.revertModelSnapshotFlyout.warningCallout.title": "将删除异常数据", "xpack.ml.newJob.wizard.searchSelection.notFoundLabel": "未找到匹配的索引或已保存搜索。", "xpack.ml.newJob.wizard.searchSelection.savedObjectType.indexPattern": "索引模式", "xpack.ml.newJob.wizard.searchSelection.savedObjectType.search": "已保存搜索", @@ -10512,6 +12367,7 @@ "xpack.ml.newJob.wizard.timeRangeStep.timeRangePicker.startDateLabel": "开始日期", "xpack.ml.newJob.wizard.validateJob.bucketSpanMustBeSetErrorMessage": "必须设置存储桶跨度", "xpack.ml.newJob.wizard.validateJob.duplicatedDetectorsErrorMessage": "找到重复的检测工具。", + "xpack.ml.newJob.wizard.validateJob.frequencyInvalidTimeIntervalFormatErrorMessage": "{value} 不是有效地时间间隔格式,例如 {thirtySeconds}、{tenMinutes}、{oneHour}、{sevenDays}。还需要大于零。", "xpack.ml.newJob.wizard.validateJob.groupNameAlreadyExists": "组 ID 已存在。组 ID 不能与现有作业或组相同。", "xpack.ml.newJob.wizard.validateJob.jobGroupAllowedCharactersDescription": "作业组名称可以包含小写字母数字(a-z 和 0-9)、连字符或下划线;必须以字母数字字符开头和结尾", "xpack.ml.newJob.wizard.validateJob.jobGroupMaxLengthDescription": "作业组名称的长度不得超过 {maxLength, plural, one {# 个字符} other {# 个字符}}。", @@ -10524,7 +12380,7 @@ "xpack.ml.newJob.wizard.validateJob.queryIsInvalidEsQuery": "数据馈送查询必须是有效的 Elasticsearch 查询。", "xpack.ml.overview.analyticsList.createFirstJobMessage": "创建您的首个数据帧分析作业", "xpack.ml.overview.analyticsList.createJobButtonText": "创建作业", - "xpack.ml.overview.analyticsList.emptyPromptText": "数据帧分析允许您对数据执行不同的分析,并使用结果标注数据。该作业会将标注的数据以及源数据的副本置于新的索引中。", + "xpack.ml.overview.analyticsList.emptyPromptText": "数据帧分析允许您对数据执行离群值检测、回归或分类分析并使用结果标注数据。该作业会将标注的数据以及源数据的副本置于新的索引中。", "xpack.ml.overview.analyticsList.errorPromptTitle": "获取数据帧分析列表时发生错误。", "xpack.ml.overview.analyticsList.id": "ID", "xpack.ml.overview.analyticsList.manageJobsButtonText": "管理作业", @@ -10580,6 +12436,13 @@ "xpack.ml.privilege.noPermission.runForecastsTooltip": "您没有权限运行预测。", "xpack.ml.privilege.noPermission.startOrStopDatafeedsTooltip": "您没有权限开始或停止数据馈送。", "xpack.ml.privilege.pleaseContactAdministratorTooltip": "{message}请联系您的管理员。", + "xpack.ml.revertModelSnapshotFlyout.createCalendar.defaultEventDescription": "自动创建的事件 {index}", + "xpack.ml.revertModelSnapshotFlyout.createCalendar.deleteLabel": "删除事件", + "xpack.ml.revertModelSnapshotFlyout.createCalendar.descriptionLabel": "描述", + "xpack.ml.revertModelSnapshotFlyout.createCalendar.fromLabel": "自", + "xpack.ml.revertModelSnapshotFlyout.createCalendar.title": "选择日历事件的事件范围。", + "xpack.ml.revertModelSnapshotFlyout.createCalendar.toLabel": "至", + "xpack.ml.revertModelSnapshotFlyout.revertErrorTitle": "模型快照恢复失败", "xpack.ml.routes.annotations.annotationsFeatureUnavailableErrorMessage": "尚未创建或当前用户无法访问注释功能所需的索引和别名。", "xpack.ml.ruleEditor.actionsSection.chooseActionsDescription": "选择在规则匹配异常时要采取的操作。", "xpack.ml.ruleEditor.actionsSection.resultWillNotBeCreatedTooltip": "将不会创建结果。", @@ -10660,6 +12523,19 @@ "xpack.ml.ruleEditor.selectRuleAction.orText": "或 ", "xpack.ml.ruleEditor.typicalAppliesTypeText": "典型", "xpack.ml.sampleDataLinkLabel": "ML 作业", + "xpack.ml.settings.anomalyDetection.anomalyDetectionTitle": "异常检测", + "xpack.ml.settings.anomalyDetection.calendarsSummaryCount": "您有 {calendarsCountBadge} 个{calendarsCount, plural, one {日历} other {日历}}", + "xpack.ml.settings.anomalyDetection.calendarsText": "日志包含不应生成异常的已计划事件列表,例如已计划系统中断或公共假期。", + "xpack.ml.settings.anomalyDetection.calendarsTitle": "日历", + "xpack.ml.settings.anomalyDetection.createCalendarLink": "创建", + "xpack.ml.settings.anomalyDetection.createFilterListsLink": "创建", + "xpack.ml.settings.anomalyDetection.filterListsSummaryCount": "您有 {filterListsCountBadge} 个{filterListsCount, plural, one {筛选列表} other {筛选列表}}", + "xpack.ml.settings.anomalyDetection.filterListsText": " 筛选列表包含可用于在 Machine Learning 分析中包括或排除事件的值。", + "xpack.ml.settings.anomalyDetection.filterListsTitle": "筛选列表", + "xpack.ml.settings.anomalyDetection.loadingCalendarsCountErrorMessage": "获取日历的计数时发生错误", + "xpack.ml.settings.anomalyDetection.loadingFilterListCountErrorMessage": "获取筛选列表的计数时发生错误", + "xpack.ml.settings.anomalyDetection.manageCalendarsLink": "管理", + "xpack.ml.settings.anomalyDetection.manageFilterListsLink": "管理", "xpack.ml.settings.breadcrumbs.calendarManagement.createLabel": "创建", "xpack.ml.settings.breadcrumbs.calendarManagement.editLabel": "编辑", "xpack.ml.settings.breadcrumbs.calendarManagementLabel": "日历管理", @@ -10715,12 +12591,14 @@ "xpack.ml.settings.filterLists.table.noFiltersCreatedTitle": "未创建任何筛选", "xpack.ml.settings.filterLists.table.notInUseAriaLabel": "未在使用", "xpack.ml.settings.filterLists.toolbar.deleteItemButtonLabel": "删除项", + "xpack.ml.settings.title": "设置", "xpack.ml.settingsBreadcrumbLabel": "设置", "xpack.ml.singleMetricViewerPageLabel": "Single Metric Viewer", "xpack.ml.stepDefineForm.invalidQuery": "无效查询", "xpack.ml.stepDefineForm.queryPlaceholderKql": "例如,{example}", "xpack.ml.stepDefineForm.queryPlaceholderLucene": "例如,{example}", "xpack.ml.swimlaneEmbeddable.errorMessage": "无法加载 ML 泳道数据", + "xpack.ml.swimlaneEmbeddable.noDataFound": "找不到异常", "xpack.ml.swimlaneEmbeddable.panelTitleLabel": "面板标题", "xpack.ml.swimlaneEmbeddable.setupModal.cancelButtonLabel": "取消", "xpack.ml.swimlaneEmbeddable.setupModal.confirmButtonLabel": "确认", @@ -10730,6 +12608,7 @@ "xpack.ml.timeSeriesExplorer.allPartitionValuesLabel": "全部", "xpack.ml.timeSeriesExplorer.annotationDescriptionList.createdByTitle": "创建者", "xpack.ml.timeSeriesExplorer.annotationDescriptionList.createdTitle": "创建于", + "xpack.ml.timeSeriesExplorer.annotationDescriptionList.detectorTitle": "检测工具", "xpack.ml.timeSeriesExplorer.annotationDescriptionList.endTitle": "结束", "xpack.ml.timeSeriesExplorer.annotationDescriptionList.jobIdTitle": "作业 ID", "xpack.ml.timeSeriesExplorer.annotationDescriptionList.lastModifiedTitle": "最后修改时间", @@ -10746,6 +12625,7 @@ "xpack.ml.timeSeriesExplorer.annotationFlyout.noAnnotationTextError": "输入注释文本", "xpack.ml.timeSeriesExplorer.annotationFlyout.updateButtonLabel": "更新", "xpack.ml.timeSeriesExplorer.annotationsLabel": "注释", + "xpack.ml.timeSeriesExplorer.annotationsTitle": "标注 {badge}", "xpack.ml.timeSeriesExplorer.anomaliesTitle": "异常", "xpack.ml.timeSeriesExplorer.autoSelectingFirstJobText": ",自动选择第一个作业", "xpack.ml.timeSeriesExplorer.canNotViewRequestedJobsWarningMessage": "您无法在此仪表板中查看请求的 {invalidIdsCount, plural, one {作业} other {作业}} {invalidIds}", @@ -10852,9 +12732,168 @@ "xpack.monitoring.ajaxErrorHandler.requestErrorNotificationTitle": "Monitoring 请求错误", "xpack.monitoring.ajaxErrorHandler.requestFailedNotification.retryButtonLabel": "重试", "xpack.monitoring.ajaxErrorHandler.requestFailedNotificationTitle": "Monitoring 请求失败", - "xpack.monitoring.alerts.licenseExpiration.ui.firingMessage": "此集群的许可证将于 #relative后,即 #absolute过期。 #start_link请更新您的许可证。#end_link", + "xpack.monitoring.alerts.actionGroups.default": "默认值", + "xpack.monitoring.alerts.badge.panelTitle": "告警", + "xpack.monitoring.alerts.callout.dangerLabel": "危险告警", + "xpack.monitoring.alerts.callout.warningLabel": "警告告警", + "xpack.monitoring.alerts.clusterHealth.action.danger": "分配缺失的主分片和副本分片。", + "xpack.monitoring.alerts.clusterHealth.action.warning": "分配缺失的副本分片。", + "xpack.monitoring.alerts.clusterHealth.actionVariables.action": "此告警的建议操作。", + "xpack.monitoring.alerts.clusterHealth.actionVariables.actionPlain": "此告警的建议操作,无任何 Markdown。", + "xpack.monitoring.alerts.clusterHealth.actionVariables.clusterHealth": "集群的运行状况。", + "xpack.monitoring.alerts.clusterHealth.actionVariables.clusterName": "节点所属的集群。", + "xpack.monitoring.alerts.clusterHealth.actionVariables.internalFullMessage": "Elastic 生成的完整内部消息。", + "xpack.monitoring.alerts.clusterHealth.actionVariables.internalShortMessage": "Elastic 生成的简短内部消息。", + "xpack.monitoring.alerts.clusterHealth.actionVariables.state": "告警的当前状态。", + "xpack.monitoring.alerts.clusterHealth.firing": "触发", + "xpack.monitoring.alerts.clusterHealth.firing.internalFullMessage": "为 {clusterName} 触发了集群运行状况告警。当前运行状况为 {health}。{action}", + "xpack.monitoring.alerts.clusterHealth.firing.internalShortMessage": "为 {clusterName} 触发了集群运行状况告警。当前运行状况为 {health}。{actionText}", + "xpack.monitoring.alerts.clusterHealth.label": "集群运行状况", + "xpack.monitoring.alerts.clusterHealth.redMessage": "分配缺失的主分片和副本分片", + "xpack.monitoring.alerts.clusterHealth.resolved": "已解决", + "xpack.monitoring.alerts.clusterHealth.resolved.internalFullMessage": "已为 {clusterName} 解决集群运行状况告警。", + "xpack.monitoring.alerts.clusterHealth.resolved.internalShortMessage": "已为 {clusterName} 解决集群运行状况告警。", + "xpack.monitoring.alerts.clusterHealth.ui.firingMessage": "Elasticsearch 集群运行状况为 {health}。", + "xpack.monitoring.alerts.clusterHealth.ui.nextSteps.message1": "{message}。#start_linkView now#end_link", + "xpack.monitoring.alerts.clusterHealth.ui.resolvedMessage": "Elasticsearch 集群运行状况为绿色。", + "xpack.monitoring.alerts.clusterHealth.yellowMessage": "分配缺失的副本分片", + "xpack.monitoring.alerts.cpuUsage.actionVariables.action": "此告警的建议操作。", + "xpack.monitoring.alerts.cpuUsage.actionVariables.actionPlain": "此告警的建议操作,无任何 Markdown。", + "xpack.monitoring.alerts.cpuUsage.actionVariables.clusterName": "节点所属的集群。", + "xpack.monitoring.alerts.cpuUsage.actionVariables.count": "报告高 CPU 使用率的节点数目。", + "xpack.monitoring.alerts.cpuUsage.actionVariables.internalFullMessage": "Elastic 生成的完整内部消息。", + "xpack.monitoring.alerts.cpuUsage.actionVariables.internalShortMessage": "Elastic 生成的简短内部消息。", + "xpack.monitoring.alerts.cpuUsage.actionVariables.nodes": "报告高 CPU 使用率的节点列表。", + "xpack.monitoring.alerts.cpuUsage.actionVariables.state": "告警的当前状态。", + "xpack.monitoring.alerts.cpuUsage.firing": "触发", + "xpack.monitoring.alerts.cpuUsage.firing.internalFullMessage": "为集群 {clusterName} 中 {count} 个节点触发了 CPU 使用率告警。{action}", + "xpack.monitoring.alerts.cpuUsage.firing.internalShortMessage": "为集群 {clusterName} 中 {count} 个节点触发了 CPU 使用率告警。{shortActionText}", + "xpack.monitoring.alerts.cpuUsage.fullAction": "查看节点", + "xpack.monitoring.alerts.cpuUsage.label": "CPU 使用率", + "xpack.monitoring.alerts.cpuUsage.paramDetails.duration.label": "查看以下范围的平均值:", + "xpack.monitoring.alerts.cpuUsage.paramDetails.threshold.label": "CPU 超过以下值时通知:", + "xpack.monitoring.alerts.cpuUsage.resolved": "已解决", + "xpack.monitoring.alerts.cpuUsage.resolved.internalFullMessage": "已为集群 {clusterName} 中的 {count} 个节点解决 CPU 使用率告警。", + "xpack.monitoring.alerts.cpuUsage.resolved.internalShortMessage": "已为集群 {clusterName} 中的 {count} 个节点解决 CPU 使用率告警。", + "xpack.monitoring.alerts.cpuUsage.shortAction": "跨受影响节点验证 CPU 级别。", + "xpack.monitoring.alerts.cpuUsage.ui.firingMessage": "节点 #start_link{nodeName}#end_link 于 #absolute报告 cpu 使用率为 {cpuUsage}%", + "xpack.monitoring.alerts.cpuUsage.ui.nextSteps.hotThreads": "#start_link检查热线程#end_link", + "xpack.monitoring.alerts.cpuUsage.ui.nextSteps.runningTasks": "#start_link检查长时间运行的任务#end_link", + "xpack.monitoring.alerts.cpuUsage.ui.resolvedMessage": "节点 {nodeName} 上的 cpu 使用率现在低于阈值,当前报告截止到 #resolved 为 {cpuUsage}%", + "xpack.monitoring.alerts.cpuUsage.validation.duration": "必须指定有效的持续时间。", + "xpack.monitoring.alerts.cpuUsage.validation.threshold": "必须指定有效数字。", + "xpack.monitoring.alerts.elasticsearchVersionMismatch.actionVariables.action": "此告警的建议操作。", + "xpack.monitoring.alerts.elasticsearchVersionMismatch.actionVariables.actionPlain": "此告警的建议操作,无任何 Markdown。", + "xpack.monitoring.alerts.elasticsearchVersionMismatch.actionVariables.clusterHealth": "在此集群中运行的 Elasticsearch 版本。", + "xpack.monitoring.alerts.elasticsearchVersionMismatch.actionVariables.clusterName": "节点所属的集群。", + "xpack.monitoring.alerts.elasticsearchVersionMismatch.actionVariables.internalFullMessage": "Elastic 生成的完整内部消息。", + "xpack.monitoring.alerts.elasticsearchVersionMismatch.actionVariables.internalShortMessage": "Elastic 生成的简短内部消息。", + "xpack.monitoring.alerts.elasticsearchVersionMismatch.actionVariables.state": "告警的当前状态。", + "xpack.monitoring.alerts.elasticsearchVersionMismatch.firing": "触发", + "xpack.monitoring.alerts.elasticsearchVersionMismatch.firing.internalFullMessage": "为 {clusterName} 触发了 Elasticsearch 版本不匹配告警。Elasticsearch 正在运行 {versions}。{action}", + "xpack.monitoring.alerts.elasticsearchVersionMismatch.firing.internalShortMessage": "为 {clusterName} 触发了 Elasticsearch 版本不匹配告警。{shortActionText}", + "xpack.monitoring.alerts.elasticsearchVersionMismatch.fullAction": "查看节点", + "xpack.monitoring.alerts.elasticsearchVersionMismatch.label": "Elasticsearch 版本不匹配", + "xpack.monitoring.alerts.elasticsearchVersionMismatch.resolved": "已解决", + "xpack.monitoring.alerts.elasticsearchVersionMismatch.resolved.internalFullMessage": "为 {clusterName} 解决了 Elasticsearch 版本不匹配告警。", + "xpack.monitoring.alerts.elasticsearchVersionMismatch.resolved.internalShortMessage": "为 {clusterName} 解决了 Elasticsearch 版本不匹配告警。", + "xpack.monitoring.alerts.elasticsearchVersionMismatch.shortAction": "确认所有节点具有相同的版本。", + "xpack.monitoring.alerts.elasticsearchVersionMismatch.ui.firingMessage": "在此集群中运行的多个 Elasticsearch ({versions}) 版本。", + "xpack.monitoring.alerts.elasticsearchVersionMismatch.ui.resolvedMessage": "在此集群中所有 Elasticsearch 版本都相同。", + "xpack.monitoring.alerts.flyoutExpressions.timeUnits.dayLabel": "{timeValue, plural, one {天} other {天}}", + "xpack.monitoring.alerts.flyoutExpressions.timeUnits.hourLabel": "{timeValue, plural, one {小时} other {小时}}", + "xpack.monitoring.alerts.flyoutExpressions.timeUnits.minuteLabel": "{timeValue, plural, one {分钟} other {分钟}}", + "xpack.monitoring.alerts.flyoutExpressions.timeUnits.secondLabel": "{timeValue, plural, one {秒} other {秒}}", + "xpack.monitoring.alerts.kibanaVersionMismatch.actionVariables.action": "此告警的建议操作。", + "xpack.monitoring.alerts.kibanaVersionMismatch.actionVariables.actionPlain": "此告警的建议操作,无任何 Markdown。", + "xpack.monitoring.alerts.kibanaVersionMismatch.actionVariables.clusterHealth": "此集群中运行的 Kibana 版本。", + "xpack.monitoring.alerts.kibanaVersionMismatch.actionVariables.clusterName": "实例所属的集群。", + "xpack.monitoring.alerts.kibanaVersionMismatch.actionVariables.internalFullMessage": "Elastic 生成的完整内部消息。", + "xpack.monitoring.alerts.kibanaVersionMismatch.actionVariables.internalShortMessage": "Elastic 生成的简短内部消息。", + "xpack.monitoring.alerts.kibanaVersionMismatch.actionVariables.state": "告警的当前状态。", + "xpack.monitoring.alerts.kibanaVersionMismatch.firing": "触发", + "xpack.monitoring.alerts.kibanaVersionMismatch.firing.internalFullMessage": "为 {clusterName} 触发了 Kibana 版本不匹配告警。Kibana 正在运行 {versions}。{action}", + "xpack.monitoring.alerts.kibanaVersionMismatch.firing.internalShortMessage": "为 {clusterName} 触发了 Kibana 版本不匹配告警。{shortActionText}", + "xpack.monitoring.alerts.kibanaVersionMismatch.fullAction": "查看实例", + "xpack.monitoring.alerts.kibanaVersionMismatch.label": "Kibana 版本不匹配", + "xpack.monitoring.alerts.kibanaVersionMismatch.resolved": "已解决", + "xpack.monitoring.alerts.kibanaVersionMismatch.resolved.internalFullMessage": "为 {clusterName} 解决了 Kibana 版本不匹配告警。", + "xpack.monitoring.alerts.kibanaVersionMismatch.resolved.internalShortMessage": "为 {clusterName} 解决了 Kibana 版本不匹配告警。", + "xpack.monitoring.alerts.kibanaVersionMismatch.shortAction": "确认所有实例具有相同的版本。", + "xpack.monitoring.alerts.kibanaVersionMismatch.ui.firingMessage": "在此集群中运行着多个 Kibana ({versions}) 版本。", + "xpack.monitoring.alerts.kibanaVersionMismatch.ui.resolvedMessage": "在此集群中所有 Kibana 版本都相同。", + "xpack.monitoring.alerts.legacyAlert.expressionText": "没有可配置的内容。", + "xpack.monitoring.alerts.licenseExpiration.action": "请更新您的许可证。", + "xpack.monitoring.alerts.licenseExpiration.actionVariables.action": "此告警的建议操作。", + "xpack.monitoring.alerts.licenseExpiration.actionVariables.actionPlain": "此告警的建议操作,无任何 Markdown。", + "xpack.monitoring.alerts.licenseExpiration.actionVariables.clusterName": "许可证所属的集群。", + "xpack.monitoring.alerts.licenseExpiration.actionVariables.expiredDate": "许可证过期日期。", + "xpack.monitoring.alerts.licenseExpiration.actionVariables.internalFullMessage": "Elastic 生成的完整内部消息。", + "xpack.monitoring.alerts.licenseExpiration.actionVariables.internalShortMessage": "Elastic 生成的简短内部消息。", + "xpack.monitoring.alerts.licenseExpiration.actionVariables.state": "告警的当前状态。", + "xpack.monitoring.alerts.licenseExpiration.firing": "触发", + "xpack.monitoring.alerts.licenseExpiration.firing.internalFullMessage": "为 {clusterName} 触发了许可证到期告警。您的许可证将于 {expiredDate}到期。{action}", + "xpack.monitoring.alerts.licenseExpiration.firing.internalShortMessage": "为 {clusterName} 触发了许可证到期告警。您的许可证将于 {expiredDate}到期。{actionText}", + "xpack.monitoring.alerts.licenseExpiration.label": "许可证到期", + "xpack.monitoring.alerts.licenseExpiration.resolved": "已解决", + "xpack.monitoring.alerts.licenseExpiration.resolved.internalFullMessage": "为 {clusterName} 解决了许可证到期告警。", + "xpack.monitoring.alerts.licenseExpiration.resolved.internalShortMessage": "为 {clusterName} 解决了许可证到期告警。", + "xpack.monitoring.alerts.licenseExpiration.ui.firingMessage": "此集群的许可证将于 #relative后,即 #absolute到期。 #start_link请更新您的许可证。#end_link", "xpack.monitoring.alerts.licenseExpiration.ui.resolvedMessage": "此集群的许可证处于活动状态。", + "xpack.monitoring.alerts.logstashVersionMismatch.actionVariables.action": "此告警的建议操作。", + "xpack.monitoring.alerts.logstashVersionMismatch.actionVariables.actionPlain": "此告警的建议操作,无任何 Markdown。", + "xpack.monitoring.alerts.logstashVersionMismatch.actionVariables.clusterHealth": "此集群中运行的 Logstash 版本。", + "xpack.monitoring.alerts.logstashVersionMismatch.actionVariables.clusterName": "节点所属的集群。", + "xpack.monitoring.alerts.logstashVersionMismatch.actionVariables.internalFullMessage": "Elastic 生成的完整内部消息。", + "xpack.monitoring.alerts.logstashVersionMismatch.actionVariables.internalShortMessage": "Elastic 生成的简短内部消息。", + "xpack.monitoring.alerts.logstashVersionMismatch.actionVariables.state": "告警的当前状态。", + "xpack.monitoring.alerts.logstashVersionMismatch.firing": "触发", + "xpack.monitoring.alerts.logstashVersionMismatch.firing.internalFullMessage": "为 {clusterName} 触发了 Logstash 版本不匹配告警。Logstash 正在运行 {versions}。{action}", + "xpack.monitoring.alerts.logstashVersionMismatch.firing.internalShortMessage": "为 {clusterName} 触发了 Logstash 版本不匹配告警。{shortActionText}", + "xpack.monitoring.alerts.logstashVersionMismatch.fullAction": "查看节点", + "xpack.monitoring.alerts.logstashVersionMismatch.label": "Logstash 版本不匹配", + "xpack.monitoring.alerts.logstashVersionMismatch.resolved": "已解决", + "xpack.monitoring.alerts.logstashVersionMismatch.resolved.internalFullMessage": "为 {clusterName} 解决了 Logstash 版本不匹配告警。", + "xpack.monitoring.alerts.logstashVersionMismatch.resolved.internalShortMessage": "为 {clusterName} 解决了 Logstash 版本不匹配告警。", + "xpack.monitoring.alerts.logstashVersionMismatch.shortAction": "确认所有节点具有相同的版本。", + "xpack.monitoring.alerts.logstashVersionMismatch.ui.firingMessage": "在此集群中运行着多个 Logstash ({versions}) 版本。", + "xpack.monitoring.alerts.logstashVersionMismatch.ui.resolvedMessage": "在此集群中所有 Logstash 版本都相同。", "xpack.monitoring.alerts.migrate.manageAction.requiredFieldError": "{field} 是必填字段。", + "xpack.monitoring.alerts.nodesChanged.actionVariables.action": "此告警的建议操作。", + "xpack.monitoring.alerts.nodesChanged.actionVariables.actionPlain": "此告警的建议操作,无任何 Markdown。", + "xpack.monitoring.alerts.nodesChanged.actionVariables.added": "添加到集群的节点列表。", + "xpack.monitoring.alerts.nodesChanged.actionVariables.clusterName": "节点所属的集群。", + "xpack.monitoring.alerts.nodesChanged.actionVariables.internalFullMessage": "Elastic 生成的完整内部消息。", + "xpack.monitoring.alerts.nodesChanged.actionVariables.internalShortMessage": "Elastic 生成的简短内部消息。", + "xpack.monitoring.alerts.nodesChanged.actionVariables.removed": "从集群中移除的节点列表。", + "xpack.monitoring.alerts.nodesChanged.actionVariables.restarted": "在集群中重新启动的节点列表。", + "xpack.monitoring.alerts.nodesChanged.actionVariables.state": "告警的当前状态。", + "xpack.monitoring.alerts.nodesChanged.firing": "触发", + "xpack.monitoring.alerts.nodesChanged.firing.internalFullMessage": "为 {clusterName} 触发了节点已更改告警。以下 Elasticsearch 节点已添加:{added},以下已移除:{removed},以下已重新启动:{restarted}。{action}", + "xpack.monitoring.alerts.nodesChanged.firing.internalShortMessage": "为 {clusterName} 触发了节点已更改告警。{shortActionText}", + "xpack.monitoring.alerts.nodesChanged.fullAction": "查看节点", + "xpack.monitoring.alerts.nodesChanged.label": "已更改节点", + "xpack.monitoring.alerts.nodesChanged.resolved": "已解决", + "xpack.monitoring.alerts.nodesChanged.resolved.internalFullMessage": "已为 {clusterName} 解决 Elasticsearch 节点已更改告警。", + "xpack.monitoring.alerts.nodesChanged.resolved.internalShortMessage": "已为 {clusterName} 解决 Elasticsearch 节点已更改告警。", + "xpack.monitoring.alerts.nodesChanged.shortAction": "确认您已添加、移除或重新启动节点。", + "xpack.monitoring.alerts.nodesChanged.ui.addedFiringMessage": "Elasticsearch 节点“{added}”已添加到此集群。", + "xpack.monitoring.alerts.nodesChanged.ui.removedFiringMessage": "Elasticsearch 节点“{removed}”已从此集群中移除。", + "xpack.monitoring.alerts.nodesChanged.ui.resolvedMessage": "此集群的 Elasticsearch 节点中没有更改。", + "xpack.monitoring.alerts.nodesChanged.ui.restartedFiringMessage": "此集群中 Elasticsearch 节点“{restarted}”已重新启动。", + "xpack.monitoring.alerts.panel.disableAlert.errorTitle": "无法禁用告警", + "xpack.monitoring.alerts.panel.disableTitle": "禁用", + "xpack.monitoring.alerts.panel.editAlert": "编辑告警", + "xpack.monitoring.alerts.panel.enableAlert.errorTitle": "无法启用告警", + "xpack.monitoring.alerts.panel.muteAlert.errorTitle": "无法静音告警", + "xpack.monitoring.alerts.panel.muteTitle": "静音", + "xpack.monitoring.alerts.panel.ummuteAlert.errorTitle": "无法取消告警静音", + "xpack.monitoring.alerts.status.alertsTooltip": "告警", + "xpack.monitoring.alerts.status.clearText": "清除", + "xpack.monitoring.alerts.status.clearToolip": "无告警触发", + "xpack.monitoring.alerts.status.highSeverityTooltip": "有一些紧急问题需要您立即关注!", + "xpack.monitoring.alerts.status.lowSeverityTooltip": "存在一些低紧急问题。", + "xpack.monitoring.alerts.status.mediumSeverityTooltip": "有一些问题可能会影响您的堆栈。", "xpack.monitoring.apm.healthStatusLabel": "运行状况:{status}", "xpack.monitoring.apm.instance.routeTitle": "{apm} - 实例", "xpack.monitoring.apm.instance.status.lastEventDescription": "{timeOfLastEvent}前", @@ -10990,12 +13029,15 @@ "xpack.monitoring.cluster.overview.esPanel.diskUsageLabel": "磁盘使用", "xpack.monitoring.cluster.overview.esPanel.documentsLabel": "文档", "xpack.monitoring.cluster.overview.esPanel.errorLogsTooltipText": "错误日志数", + "xpack.monitoring.cluster.overview.esPanel.expireDateText": "于 {expiryDate} 到期", "xpack.monitoring.cluster.overview.esPanel.fatalLogsTooltipText": "严重日志数", + "xpack.monitoring.cluster.overview.esPanel.healthLabel": "运行状况", "xpack.monitoring.cluster.overview.esPanel.indicesCountLinkAriaLabel": "Elasticsearch 索引:{indicesCount}", "xpack.monitoring.cluster.overview.esPanel.indicesCountLinkLabel": "索引:{indicesCount}", "xpack.monitoring.cluster.overview.esPanel.infoLogsTooltipText": "信息日志数", "xpack.monitoring.cluster.overview.esPanel.jobsLabel": "作业", "xpack.monitoring.cluster.overview.esPanel.jvmHeapLabel": "{javaVirtualMachine} 堆", + "xpack.monitoring.cluster.overview.esPanel.licenseLabel": "许可证", "xpack.monitoring.cluster.overview.esPanel.logsLinkAriaLabel": "Elasticsearch 日志", "xpack.monitoring.cluster.overview.esPanel.logsLinkLabel": "日志", "xpack.monitoring.cluster.overview.esPanel.nodesTotalLinkLabel": "节点:{nodesTotal}", @@ -11125,11 +13167,13 @@ "xpack.monitoring.elasticsearch.nodeDetailStatus.shardsLabel": "分片", "xpack.monitoring.elasticsearch.nodeDetailStatus.transportAddress": "传输地址", "xpack.monitoring.elasticsearch.nodeDetailStatus.typeLabel": "类型", + "xpack.monitoring.elasticsearch.nodes.alertsColumnTitle": "告警", "xpack.monitoring.elasticsearch.nodes.cells.maxText": "{metric} 最大值", "xpack.monitoring.elasticsearch.nodes.cells.minText": "{metric} 最小值", "xpack.monitoring.elasticsearch.nodes.cpuThrottlingColumnTitle": "CPU 限制", "xpack.monitoring.elasticsearch.nodes.cpuUsageColumnTitle": "CPU 使用", "xpack.monitoring.elasticsearch.nodes.diskFreeSpaceColumnTitle": "磁盘可用空间", + "xpack.monitoring.elasticsearch.nodes.healthAltIcon": "状态:{status}", "xpack.monitoring.elasticsearch.nodes.jvmMemoryColumnTitle": "{javaVirtualMachine} 堆", "xpack.monitoring.elasticsearch.nodes.loadAverageColumnTitle": "负载平均值", "xpack.monitoring.elasticsearch.nodes.metricbeatMigration.detectedNodeDescription": "以下节点未受监测。单击下面的“使用 Metricbeat 监测”以开始监测。", @@ -11231,6 +13275,7 @@ "xpack.monitoring.kibana.detailStatus.versionLabel": "版本", "xpack.monitoring.kibana.instances.metricbeatMigration.detectedNodeDescription": "以下实例未受监测。\n 单击下面的“使用 Metricbeat 监测”以开始监测。", "xpack.monitoring.kibana.instances.metricbeatMigration.detectedNodeTitle": "检测到 Kibana 实例", + "xpack.monitoring.kibana.listing.alertsColumnTitle": "告警", "xpack.monitoring.kibana.listing.filterInstancesPlaceholder": "筛选实例……", "xpack.monitoring.kibana.listing.loadAverageColumnTitle": "负载平均值", "xpack.monitoring.kibana.listing.memorySizeColumnTitle": "内存大小", @@ -11309,6 +13354,7 @@ "xpack.monitoring.logstash.node.pipelines.notAvailableDescription": "仅 Logstash 版本 6.0.0 或更高版本提供管道监测功能。此节点正在运行版本 {logstashVersion}。", "xpack.monitoring.logstash.node.pipelines.routeTitle": "Logstash - {nodeName} - 管道", "xpack.monitoring.logstash.node.routeTitle": "Logstash - {nodeName}", + "xpack.monitoring.logstash.nodes.alertsColumnTitle": "告警", "xpack.monitoring.logstash.nodes.configReloadsFailuresCountLabel": "{reloadsFailures} 失败", "xpack.monitoring.logstash.nodes.configReloadsSuccessCountLabel": "{reloadsSuccesses} 成功", "xpack.monitoring.logstash.nodes.configReloadsTitle": "配置重载", @@ -11431,6 +13477,36 @@ "xpack.monitoring.metricbeatMigration.partiallyMigratedStatusTitle": "数据仍来自于内部收集", "xpack.monitoring.metricbeatMigration.securitySetup": "如果启用了安全,可能需要{link}。", "xpack.monitoring.metricbeatMigration.securitySetupLinkText": "其他设置", + "xpack.monitoring.metrics.apm.acmRequest.countTitle": "请求 - 代理配置管理", + "xpack.monitoring.metrics.apm.acmRequest.countTitleDescription": "代理配置管理接收的 HTTP 请求", + "xpack.monitoring.metrics.apm.acmRequest.countTitleLabel": "计数", + "xpack.monitoring.metrics.apm.acmResponse.countDescription": "APM 服务器响应的 HTTP 请求", + "xpack.monitoring.metrics.apm.acmResponse.countLabel": "计数", + "xpack.monitoring.metrics.apm.acmResponse.countTitle": "响应计数 - 代理配置管理", + "xpack.monitoring.metrics.apm.acmResponse.errorCountDescription": "HTTP 错误计数", + "xpack.monitoring.metrics.apm.acmResponse.errorCountLabel": "错误计数", + "xpack.monitoring.metrics.apm.acmResponse.errorCountTitle": "响应错误计数 - 代理配置管理", + "xpack.monitoring.metrics.apm.acmResponse.errors.forbiddenDescription": "已禁止 HTTP 请求已拒绝计数", + "xpack.monitoring.metrics.apm.acmResponse.errors.forbiddenLabel": "计数", + "xpack.monitoring.metrics.apm.acmResponse.errors.forbiddenTitle": "响应错误 - 代理配置管理", + "xpack.monitoring.metrics.apm.acmResponse.errors.invalidqueryDescription": "无效 HTTP 查询", + "xpack.monitoring.metrics.apm.acmResponse.errors.invalidqueryLabel": "无效查询", + "xpack.monitoring.metrics.apm.acmResponse.errors.invalidqueryTitle": "响应无效查询错误 - 代理配置管理", + "xpack.monitoring.metrics.apm.acmResponse.errors.methodDescription": "由于 HTTP 方法错误而拒绝的 HTTP 请求", + "xpack.monitoring.metrics.apm.acmResponse.errors.methodLabel": "方法", + "xpack.monitoring.metrics.apm.acmResponse.errors.methodTitle": "响应方法错误 - 代理配置管理", + "xpack.monitoring.metrics.apm.acmResponse.errors.unauthorizedDescription": "未授权 HTTP 请求已拒绝计数", + "xpack.monitoring.metrics.apm.acmResponse.errors.unauthorizedLabel": "未授权", + "xpack.monitoring.metrics.apm.acmResponse.errors.unauthorizedTitle": "响应未授权错误 - 代理配置管理", + "xpack.monitoring.metrics.apm.acmResponse.errors.unavailableDescription": "不可用 HTTP 响应计数。有可能配置错误或 Kibana 版本不受支持", + "xpack.monitoring.metrics.apm.acmResponse.errors.unavailableLabel": "不可用", + "xpack.monitoring.metrics.apm.acmResponse.errors.unavailableTitle": "响应不可用错误 - 代理配置管理", + "xpack.monitoring.metrics.apm.acmResponse.validNotModifiedDescription": "304 未修改响应计数", + "xpack.monitoring.metrics.apm.acmResponse.validNotModifiedLabel": "未修改", + "xpack.monitoring.metrics.apm.acmResponse.validNotModifiedTitle": "响应未修改 - 代理配置管理", + "xpack.monitoring.metrics.apm.acmResponse.validOkDescription": "200 正常响应计数", + "xpack.monitoring.metrics.apm.acmResponse.validOkLabel": "正常", + "xpack.monitoring.metrics.apm.acmResponse.validOkTitle": "响应正常计数 - 代理配置管理", "xpack.monitoring.metrics.apm.outputAckedEventsRate.ackedDescription": "输出处理的事件(包括重试)", "xpack.monitoring.metrics.apm.outputAckedEventsRate.ackedLabel": "已确认", "xpack.monitoring.metrics.apm.outputAckedEventsRateTitle": "输出已确认事件速率", @@ -11446,6 +13522,7 @@ "xpack.monitoring.metrics.apm.outputFailedEventsRate.failedDescription": "输出处理的事件(包括重试)", "xpack.monitoring.metrics.apm.outputFailedEventsRate.failedLabel": "失败", "xpack.monitoring.metrics.apm.outputFailedEventsRateTitle": "输出失败事件速率", + "xpack.monitoring.metrics.apm.perSecondUnitLabel": "/s", "xpack.monitoring.metrics.apm.processedEvents.transactionDescription": "已处理事务事件", "xpack.monitoring.metrics.apm.processedEvents.transactionLabel": "事务", "xpack.monitoring.metrics.apm.processedEventsTitle": "已处理事件", @@ -11983,6 +14060,7 @@ "xpack.monitoring.noData.setupMetricbeatInstead": "或,使用 Metricbeat 设置(推荐)", "xpack.monitoring.novLabel": "十一月", "xpack.monitoring.octLabel": "十月", + "xpack.monitoring.overview.heading": "堆栈监测概览", "xpack.monitoring.pageLoadingTitle": "正在加载……", "xpack.monitoring.permanentActiveLicenseStatusDescription": "您的许可证永不会过期。", "xpack.monitoring.pie.unableToDrawLabelsInsideCanvasErrorMessage": "无法用画布内包含的标签绘制饼图", @@ -12025,6 +14103,7 @@ "xpack.monitoring.setupMode.usingMetricbeatCollection": "已使用 Metricbeat 监测", "xpack.monitoring.stackMonitoringDocTitle": "堆栈监测 {clusterName} {suffix}", "xpack.monitoring.stackMonitoringTitle": "堆栈监测", + "xpack.monitoring.summaryStatus.alertsDescription": "告警", "xpack.monitoring.summaryStatus.statusDescription": "状态", "xpack.monitoring.summaryStatus.statusIconLabel": "状态:{status}", "xpack.monitoring.summaryStatus.statusIconTitle": "状态:{statusIcon}", @@ -12035,6 +14114,78 @@ "xpack.monitoring.updateLicenseTitle": "更新您的许可证", "xpack.monitoring.useAvailableLicenseDescription": "如果已有新的许可证,请立即上传。", "xpack.monitoring.wedLabel": "周三", + "xpack.observability.beta": "公测版", + "xpack.observability.emptySection.apps.alert.description": "503 错误是否越来越多?服务是否响应?CPU 和 RAM 利用率是否激增?实时查看警告,而不是事后再进行剖析。", + "xpack.observability.emptySection.apps.alert.link": "创建告警", + "xpack.observability.emptySection.apps.alert.title": "未找到告警。", + "xpack.observability.emptySection.apps.apm.description": "通过分布式体系结构跟踪事务并映射服务的交互以轻松发现性能瓶颈。", + "xpack.observability.emptySection.apps.apm.link": "安装代理", + "xpack.observability.emptySection.apps.apm.title": "APM", + "xpack.observability.emptySection.apps.logs.description": "集中任何源的日志。搜索、跟踪、自动化异常检测并可视化趋势,以便您可以更迅速地采取操作。", + "xpack.observability.emptySection.apps.logs.link": "安装 Filebeat", + "xpack.observability.emptySection.apps.logs.title": "日志", + "xpack.observability.emptySection.apps.metrics.description": "分析您的基础设施、应用和服务的指标。发现趋势、预测行为、接收异常告警等等。", + "xpack.observability.emptySection.apps.metrics.link": "安装指标模块", + "xpack.observability.emptySection.apps.metrics.title": "指标", + "xpack.observability.emptySection.apps.uptime.description": "主动监测站点和服务的可用性。接收告警并更快地解决问题,从而优化用户体验。", + "xpack.observability.emptySection.apps.uptime.link": "安装 Heartbeat", + "xpack.observability.emptySection.apps.uptime.title": "运行时间", + "xpack.observability.home.addData": "添加数据", + "xpack.observability.home.breadcrumb": "概览", + "xpack.observability.home.feedback": "提供反馈", + "xpack.observability.home.getStatedButton": "开始使用", + "xpack.observability.home.sectionsubtitle": "通过根据需要将日志、指标和跟踪都置于单个堆栈上,来监测、分析和响应环境中任何位置发生的事件。", + "xpack.observability.home.sectionTitle": "整个生态系统的统一可见性", + "xpack.observability.home.title": "可观测性", + "xpack.observability.ingestManafer.beta": "公测版", + "xpack.observability.ingestManafer.button": "试用采集管理器公测版", + "xpack.observability.ingestManafer.text": "通过 Elastic 代理,您能够以简单统一的方式将日志、指标和其他类型数据的监测添加到主机。不再需要安装多个 Beats 和其他代理,这样在整个基础设施中部署配置会更轻松更快速。", + "xpack.observability.ingestManafer.title": "是否了解我们全新的采集管理器?", + "xpack.observability.landing.breadcrumb": "入门", + "xpack.observability.news.readFullStory": "详细了解", + "xpack.observability.news.title": "最近的新闻", + "xpack.observability.observability.breadcrumb.": "可观测性", + "xpack.observability.overview.alert.allTypes": "所有类型", + "xpack.observability.overview.alert.appLink": "管理告警", + "xpack.observability.overview.alert.view": "查看", + "xpack.observability.overview.alerts.muted": "已静音", + "xpack.observability.overview.alerts.title": "告警", + "xpack.observability.overview.apm.appLink": "在应用中查看", + "xpack.observability.overview.apm.services": "服务", + "xpack.observability.overview.apm.title": "APM", + "xpack.observability.overview.apm.transactionsPerMinute": "每分钟事务数", + "xpack.observability.overview.breadcrumb": "概览", + "xpack.observability.overview.loadingObservability": "正在加载可观测性", + "xpack.observability.overview.logs.appLink": "在应用中查看", + "xpack.observability.overview.logs.subtitle": "每分钟日志速率", + "xpack.observability.overview.logs.title": "日志", + "xpack.observability.overview.metrics.appLink": "在应用中查看", + "xpack.observability.overview.metrics.cpuUsage": "CPU 使用率", + "xpack.observability.overview.metrics.hosts": "主机", + "xpack.observability.overview.metrics.inboundTraffic": "入站流量", + "xpack.observability.overview.metrics.memoryUsage": "内存使用", + "xpack.observability.overview.metrics.outboundTraffic": "出站流量", + "xpack.observability.overview.metrics.title": "指标", + "xpack.observability.overview.uptime.appLink": "在应用中查看", + "xpack.observability.overview.uptime.chart.down": "关闭", + "xpack.observability.overview.uptime.chart.up": "运行", + "xpack.observability.overview.uptime.down": "关闭", + "xpack.observability.overview.uptime.monitors": "监测", + "xpack.observability.overview.uptime.title": "运行时间", + "xpack.observability.overview.uptime.up": "运行", + "xpack.observability.resources.documentation": "文档", + "xpack.observability.resources.forum": "讨论论坛", + "xpack.observability.resources.title": "资源", + "xpack.observability.resources.training": "可观测性基础", + "xpack.observability.section.apps.apm.description": "通过分布式体系结构跟踪事务并映射服务的交互以轻松发现性能瓶颈。", + "xpack.observability.section.apps.apm.title": "APM", + "xpack.observability.section.apps.logs.description": "集中任何源的日志。搜索、跟踪、自动化异常检测并可视化趋势,以便您可以更迅速地采取操作。", + "xpack.observability.section.apps.logs.title": "日志", + "xpack.observability.section.apps.metrics.description": "分析您的基础设施、应用和服务的指标。发现趋势、预测行为、接收异常告警等等。", + "xpack.observability.section.apps.metrics.title": "指标", + "xpack.observability.section.apps.uptime.description": "主动监测站点和服务的可用性。接收告警并更快地解决问题,从而优化用户体验。", + "xpack.observability.section.apps.uptime.title": "运行时间", + "xpack.observability.section.errorPanel": "尝试提取数据时发生错误。请重试", "xpack.painlessLab.apiReferenceButtonLabel": "API 参考", "xpack.painlessLab.context.defaultLabel": "脚本结果将转换成字符串", "xpack.painlessLab.context.filterLabel": "使用筛选脚本查询的上下文", @@ -13051,27 +15202,40 @@ "xpack.security.roles.createBreadcrumb": "创建", "xpack.security.users.breadcrumb": "用户", "xpack.security.users.createBreadcrumb": "创建", - "xpack.server.checkLicense.errorExpiredMessage": "您不能使用 {pluginName},因为您的{licenseType}许可证已过期", - "xpack.server.checkLicense.errorUnavailableMessage": "您不能使用 {pluginName},因为许可证信息当前不可用。", - "xpack.server.checkLicense.errorUnsupportedMessage": "您的{licenseType}许可证不支持 {pluginName}。请升级您的许可证。", "xpack.securitySolution.add_filter_to_global_search_bar.filterForValueHoverAction": "筛留值", "xpack.securitySolution.add_filter_to_global_search_bar.filterOutValueHoverAction": "筛除值", + "xpack.securitySolution.alerts.riskScoreMapping.defaultDescriptionLabel": "选择此规则生成的所有告警的风险分数。", + "xpack.securitySolution.alerts.riskScoreMapping.defaultRiskScoreTitle": "默认风险分数", + "xpack.securitySolution.alerts.riskScoreMapping.mappingDescriptionLabel": "将字段从源事件(刻度值 1-100)映射到风险分数。", + "xpack.securitySolution.alerts.riskScoreMapping.mappingDetailsLabel": "如果值超出范围,或字段不存在,将使用默认风险分数。", + "xpack.securitySolution.alerts.riskScoreMapping.riskScoreFieldTitle": "signal.rule.risk_score", + "xpack.securitySolution.alerts.riskScoreMapping.riskScoreMappingTitle": "风险分数覆盖", + "xpack.securitySolution.alerts.riskScoreMapping.riskScoreTitle": "风险分数", + "xpack.securitySolution.alerts.riskScoreMapping.sourceFieldTitle": "源字段", + "xpack.securitySolution.alerts.severityMapping.defaultDescriptionLabel": "选择此规则生成的所有告警的严重性级别。", + "xpack.securitySolution.alerts.severityMapping.defaultSeverityTitle": "严重性", + "xpack.securitySolution.alerts.severityMapping.mappingDescriptionLabel": "将值从源事件映射到特定严重性。", + "xpack.securitySolution.alerts.severityMapping.mappingDetailsLabel": "对于多匹配,最高严重性匹配将适用。如果未找到匹配,将使用默认严重性。", + "xpack.securitySolution.alerts.severityMapping.severityMappingTitle": "严重性覆盖", + "xpack.securitySolution.alerts.severityMapping.severityTitle": "默认严重性", + "xpack.securitySolution.alerts.severityMapping.sourceFieldTitle": "源字段", + "xpack.securitySolution.alerts.severityMapping.sourceValueTitle": "源值", "xpack.securitySolution.alertsView.alertsDocumentType": "外部告警", - "xpack.securitySolution.alertsView.alertsGraphTitle": "外部告警计数", + "xpack.securitySolution.alertsView.alertsGraphTitle": "外部告警趋势", "xpack.securitySolution.alertsView.alertsStackByOptions.module": "模块", "xpack.securitySolution.alertsView.alertsTableTitle": "外部告警", "xpack.securitySolution.alertsView.categoryLabel": "类别", "xpack.securitySolution.alertsView.errorFetchingAlertsData": "无法查询告警数据", "xpack.securitySolution.alertsView.moduleLabel": "模块", - "xpack.securitySolution.alertsView.showing": "显示", + "xpack.securitySolution.alertsView.showing": "正在显示", "xpack.securitySolution.alertsView.totalCountOfAlerts": "个外部告警匹配搜索条件", "xpack.securitySolution.alertsView.unit": "个外部{totalCount, plural, =1 {告警} other {告警}}", - "xpack.securitySolution.andOrBadge.and": "AND", - "xpack.securitySolution.andOrBadge.or": "OR", + "xpack.securitySolution.andOrBadge.and": "且", + "xpack.securitySolution.andOrBadge.or": "或", "xpack.securitySolution.anomaliesTable.table.anomaliesDescription": "异常", - "xpack.securitySolution.anomaliesTable.table.anomaliesTooltip": "异常表无法通过 Security 全局 KQL 搜索进行筛选。", - "xpack.securitySolution.anomaliesTable.table.showingDescription": "显示", - "xpack.securitySolution.anomaliesTable.table.unit": "{totalCount, plural, =1 {个异常} other {个异常}}", + "xpack.securitySolution.anomaliesTable.table.anomaliesTooltip": "异常表无法通过 SIEM 全局 KQL 搜索进行筛选。", + "xpack.securitySolution.anomaliesTable.table.showingDescription": "正在显示", + "xpack.securitySolution.anomaliesTable.table.unit": "{totalCount, plural, =1 {异常} other {异常}}", "xpack.securitySolution.auditd.abortedAuditStartupDescription": "已中止审计启动", "xpack.securitySolution.auditd.accessErrorDescription": "访问错误", "xpack.securitySolution.auditd.accessPermissionDescription": "访问权限", @@ -13085,8 +15249,8 @@ "xpack.securitySolution.auditd.assignedVmIdDescription": "已分配 vm id", "xpack.securitySolution.auditd.assignedVMResourceDescription": "已分配 vm 资源", "xpack.securitySolution.auditd.attemptedLoginDescription": "已尝试登录 - 通过", - "xpack.securitySolution.auditd.attemptedLoginFromUnusalPlaceDescription": "尝试异常位置的登录", - "xpack.securitySolution.auditd.attemptedLoginFromUnusualHourDescription": "尝试异常时段的登录", + "xpack.securitySolution.auditd.attemptedLoginFromUnusalPlaceDescription": "尝试的登录来自异常位置", + "xpack.securitySolution.auditd.attemptedLoginFromUnusualHourDescription": "尝试的登录来自异常时段", "xpack.securitySolution.auditd.auditErrorDescription": "审计错误", "xpack.securitySolution.auditd.authenticatedToGroupDescription": "已验证到组", "xpack.securitySolution.auditd.authenticatedUsingDescription": "已验证 - 使用", @@ -13095,7 +15259,7 @@ "xpack.securitySolution.auditd.causedMacPolicyErrorDescription": "已导致 mac 策略错误", "xpack.securitySolution.auditd.changedAuditConfigurationDescription": "已更改审计配置", "xpack.securitySolution.auditd.changedAuditFeatureDescription": "已更改审计功能", - "xpack.securitySolution.auditd.changedConfigurationWIthDescription": "已更改配置", + "xpack.securitySolution.auditd.changedConfigurationWIthDescription": "已更改配置 -", "xpack.securitySolution.auditd.ChangedFileAttributesOfDescription": "已更改文件属性 -", "xpack.securitySolution.auditd.changedFilePermissionOfDescription": "已更改文件权限 -", "xpack.securitySolution.auditd.changedGroupDescription": "已更改组", @@ -13126,13 +15290,13 @@ "xpack.securitySolution.auditd.deletedGroupAccountUsingDescription": "已删除组帐户 - 使用", "xpack.securitySolution.auditd.deletedUserAccountUsingDescription": "已删除用户帐户 - 使用", "xpack.securitySolution.auditd.deletedVmImageDescription": "已删除 vm 映像", - "xpack.securitySolution.auditd.disposedCredentialsDescription": "已将凭据处置到", + "xpack.securitySolution.auditd.disposedCredentialsDescription": "已处置凭据 - 至", "xpack.securitySolution.auditd.endedFromDescription": "结束自", "xpack.securitySolution.auditd.errorFromDescription": "错误来自", "xpack.securitySolution.auditd.executedDescription": "已执行", "xpack.securitySolution.auditd.executionOfForbiddenProgramDescription": "已禁止程序的执行", "xpack.securitySolution.auditd.failedLoginTooManyTimesDescription": "由于登录次数过多,登录失败", - "xpack.securitySolution.auditd.inDescription": "传入", + "xpack.securitySolution.auditd.inDescription": "于", "xpack.securitySolution.auditd.initializedAuditSubsystemDescription": "已初始化审计子系统", "xpack.securitySolution.auditd.issuedVmControlDescription": "已签发 vm 控制", "xpack.securitySolution.auditd.killedProcessIdDescription": "已终止进程 id -", @@ -13153,7 +15317,7 @@ "xpack.securitySolution.auditd.modifiedUserAccountDescription": "已修改用户帐户", "xpack.securitySolution.auditd.mountedDescription": "已安装", "xpack.securitySolution.auditd.negotiatedCryptoKeyDescription": "已协商加密密钥", - "xpack.securitySolution.auditd.nonExistentDescription": "至未知进程", + "xpack.securitySolution.auditd.nonExistentDescription": "未知进程", "xpack.securitySolution.auditd.OpenedFileDescription": "已打开文件", "xpack.securitySolution.auditd.openedTooManySessionsDescription": "已打开过多会话", "xpack.securitySolution.auditd.overrodeLabelOfDescription": "已覆盖标签 -", @@ -13185,17 +15349,17 @@ "xpack.securitySolution.auditd.symLinkedDescription": "已象征性链接", "xpack.securitySolution.auditd.testedFileSystemIntegrityDescription": "已测试文件系统完整性", "xpack.securitySolution.auditd.unknownDescription": "未知", - "xpack.securitySolution.auditd.unloadedKernelModuleOfDescription": "已加载内核模块", + "xpack.securitySolution.auditd.unloadedKernelModuleOfDescription": "已加载内核模块 -", "xpack.securitySolution.auditd.unlockedAccountDescription": "已解锁帐户", "xpack.securitySolution.auditd.unmountedDescription": "已卸载", - "xpack.securitySolution.auditd.usingDescription": "使用", + "xpack.securitySolution.auditd.usingDescription": "正在使用", "xpack.securitySolution.auditd.violatedAppArmorPolicyFromDescription": "已违反应用防护策略 - 来自", "xpack.securitySolution.auditd.violatedSeccompPolicyWithDescription": "已违反 seccomp 策略 -", "xpack.securitySolution.auditd.violatedSeLinuxPolicyDescription": "已违反 selinux 策略", "xpack.securitySolution.auditd.wasAuthorizedToUseDescription": "有权使用", "xpack.securitySolution.auditd.withResultDescription": ",结果为", "xpack.securitySolution.authenticationsTable.authenticationFailures": "身份验证", - "xpack.securitySolution.authenticationsTable.failures": "失败", + "xpack.securitySolution.authenticationsTable.failures": "错误", "xpack.securitySolution.authenticationsTable.lastFailedDestination": "上一失败目标", "xpack.securitySolution.authenticationsTable.lastFailedSource": "上一失败源", "xpack.securitySolution.authenticationsTable.lastFailedTime": "上次失败", @@ -13205,18 +15369,22 @@ "xpack.securitySolution.authenticationsTable.rows": "{numRows} {numRows, plural, =0 {行} =1 {行} other {行}}", "xpack.securitySolution.authenticationsTable.successes": "成功", "xpack.securitySolution.authenticationsTable.uncommonProcessTable": "不常见进程", - "xpack.securitySolution.authenticationsTable.unit": "{totalCount, plural, =1 {个用户} other {个用户}}", + "xpack.securitySolution.authenticationsTable.unit": "{totalCount, plural, =1 {用户} other {用户}}", "xpack.securitySolution.authenticationsTable.user": "用户", + "xpack.securitySolution.authz.mlUnavailable": "Machine Learning 插件不可用。请尝试启用插件。", + "xpack.securitySolution.authz.userIsNotMlAdminMessage": "当前用户不是 Machine Learning 管理员。", + "xpack.securitySolution.autocomplete.loadingDescription": "正在加载……", "xpack.securitySolution.case.allCases.actions": "操作", "xpack.securitySolution.case.allCases.comments": "注释", "xpack.securitySolution.case.allCases.noTagsAvailable": "没有可用标记", + "xpack.securitySolution.case.caseModal.title": "选择要附加到时间线的案例", "xpack.securitySolution.case.caseSavedObjectNoPermissionsMessage": "要查看案例,必须对 Kibana 工作区中的已保存对象管理功能有权限。有关详细信息,请联系您的 Kibana 管理员。", "xpack.securitySolution.case.caseSavedObjectNoPermissionsTitle": "需要 Kibana 功能权限", "xpack.securitySolution.case.caseTable.addNewCase": "添加新案例", "xpack.securitySolution.case.caseTable.bulkActions": "批处理操作", - "xpack.securitySolution.case.caseTable.bulkActions.closeSelectedTitle": "关闭选定", - "xpack.securitySolution.case.caseTable.bulkActions.deleteSelectedTitle": "删除选定", - "xpack.securitySolution.case.caseTable.bulkActions.openSelectedTitle": "重新打开选定", + "xpack.securitySolution.case.caseTable.bulkActions.closeSelectedTitle": "关闭所选", + "xpack.securitySolution.case.caseTable.bulkActions.deleteSelectedTitle": "删除所选", + "xpack.securitySolution.case.caseTable.bulkActions.openSelectedTitle": "重新打开所选", "xpack.securitySolution.case.caseTable.caseDetailsLinkAria": "单击以访问标题为 {detailName} 的案例", "xpack.securitySolution.case.caseTable.closed": "已关闭", "xpack.securitySolution.case.caseTable.closedCases": "已关闭案例", @@ -13260,7 +15428,7 @@ "xpack.securitySolution.case.caseView.caseRefresh": "刷新案例", "xpack.securitySolution.case.caseView.closeCase": "关闭案例", "xpack.securitySolution.case.caseView.closedCase": "已关闭案例", - "xpack.securitySolution.case.caseView.closedOn": "关闭时间", + "xpack.securitySolution.case.caseView.closedOn": "关闭于", "xpack.securitySolution.case.caseView.cloudDeploymentLink": "云部署", "xpack.securitySolution.case.caseView.comment": "注释", "xpack.securitySolution.case.caseView.comment.addComment": "添加注释", @@ -13268,7 +15436,7 @@ "xpack.securitySolution.case.caseView.commentFieldRequiredError": "注释必填。", "xpack.securitySolution.case.caseView.connectorConfigureLink": "连接器", "xpack.securitySolution.case.caseView.connectors": "外部事件管理系统", - "xpack.securitySolution.case.caseView.copyCommentLinkAria": "复制引用链接", + "xpack.securitySolution.case.caseView.copyCommentLinkAria": "复制参考链接", "xpack.securitySolution.case.caseView.create": "创建新案例", "xpack.securitySolution.case.caseView.createCase": "创建案例", "xpack.securitySolution.case.caseView.description": "描述", @@ -13295,15 +15463,18 @@ "xpack.securitySolution.case.caseView.pageBadgeTooltip": "案例工作流仍为公测版。请通过在 Kibana 存储库中报告问题或错误,帮助我们改进产品。", "xpack.securitySolution.case.caseView.particpantsLabel": "参与者", "xpack.securitySolution.case.caseView.pushNamedIncident": "推送为 { thirdParty } 事件", - "xpack.securitySolution.case.caseView.pushThirdPartyIncident": "推送为第三方事件", + "xpack.securitySolution.case.caseView.pushThirdPartyIncident": "推送为外部事件", "xpack.securitySolution.case.caseView.pushToServiceDisableBecauseCaseClosedDescription": "关闭的案例无法发送到外部系统。如果希望在外部系统中打开或更新案例,请重新打开案例。", "xpack.securitySolution.case.caseView.pushToServiceDisableBecauseCaseClosedTitle": "重新打开案例", - "xpack.securitySolution.case.caseView.pushToServiceDisableByConfigDescription": "kibana.yml 文件已配置为仅允许特定连接器。要在外部系统中打开案例,请将 .servicenow 添加到 xpack.actions.enabledActiontypes 设置。有关更多信息,请参阅 {link}。", - "xpack.securitySolution.case.caseView.pushToServiceDisableByConfigTitle": "在 Kibana 配置文件中启用 ServiceNow", + "xpack.securitySolution.case.caseView.pushToServiceDisableByConfigDescription": "kibana.yml 文件已配置为仅允许特定连接器。要在外部系统中打开案例,请将 .[actionTypeId](例如:.servicenow | .jira)添加到 xpack.actions.enabledActiontypes 设置。有关更多信息,请参阅{link}。", + "xpack.securitySolution.case.caseView.pushToServiceDisableByConfigTitle": "在 Kibana 配置文件中启用外部服务", + "xpack.securitySolution.case.caseView.pushToServiceDisableByInvalidConnector": "用于将更新发送到外部服务的连接器已删除。要在外部系统中更新案例,请选择不同的连接器或创建新的连接器。", "xpack.securitySolution.case.caseView.pushToServiceDisableByLicenseDescription": "要在外部系统中打开案例,必须将许可证更新到白金级,开始为期 30 天的免费试用,或在 AWS、GCP 或 Azure 上快速部署 {link}。", "xpack.securitySolution.case.caseView.pushToServiceDisableByLicenseTitle": "升级到 Elastic 白金级", + "xpack.securitySolution.case.caseView.pushToServiceDisableByNoCaseConfigDescription": "要在外部系统中打开和更新案例,必须为此案例选择外部事件管理系统。", "xpack.securitySolution.case.caseView.pushToServiceDisableByNoCaseConfigTitle": "选择外部连接器", "xpack.securitySolution.case.caseView.pushToServiceDisableByNoConfigTitle": "配置外部连接器", + "xpack.securitySolution.case.caseView.pushToServiceDisableByNoConnectors": "要在外部系统上打开和更新案例,必须配置{link}。", "xpack.securitySolution.case.caseView.reopenCase": "重新打开案例", "xpack.securitySolution.case.caseView.reopenedCase": "重新打开的案例", "xpack.securitySolution.case.caseView.reporterLabel": "报告者", @@ -13314,7 +15485,7 @@ "xpack.securitySolution.case.caseView.to": "到", "xpack.securitySolution.case.caseView.unknown": "未知", "xpack.securitySolution.case.caseView.updateNamedIncident": "更新 { thirdParty } 事件", - "xpack.securitySolution.case.caseView.updateThirdPartyIncident": "更新第三方事件", + "xpack.securitySolution.case.caseView.updateThirdPartyIncident": "更新外部事件", "xpack.securitySolution.case.configure.errorPushingToService": "推送到服务时出错", "xpack.securitySolution.case.configure.successSaveToast": "已保存外部连接设置", "xpack.securitySolution.case.configureCases.addNewConnector": "添加新连接器", @@ -13325,7 +15496,7 @@ "xpack.securitySolution.case.configureCases.caseClosureOptionsManual": "手动关闭 Security 案例", "xpack.securitySolution.case.configureCases.caseClosureOptionsNewIncident": "将新事件推送到外部系统时自动关闭 Security 案例", "xpack.securitySolution.case.configureCases.caseClosureOptionsTitle": "案例关闭", - "xpack.securitySolution.case.configureCases.fieldMappingDesc": "将数据推送到第三方时映射 Security 案例字段。字段映射需要与外部事件管理系统建立连接。", + "xpack.securitySolution.case.configureCases.fieldMappingDesc": "将数据推送到第三方时映射 Security 案例字段。要映射字段,需要与外部事件管理系统建立连接。", "xpack.securitySolution.case.configureCases.fieldMappingEditAppend": "追加", "xpack.securitySolution.case.configureCases.fieldMappingEditNothing": "无内容", "xpack.securitySolution.case.configureCases.fieldMappingEditOverwrite": "覆盖", @@ -13339,6 +15510,7 @@ "xpack.securitySolution.case.configureCases.incidentManagementSystemTitle": "连接到外部事件管理系统", "xpack.securitySolution.case.configureCases.mappingFieldComments": "注释", "xpack.securitySolution.case.configureCases.mappingFieldDescription": "描述", + "xpack.securitySolution.case.configureCases.mappingFieldName": "名称", "xpack.securitySolution.case.configureCases.mappingFieldNotMapped": "未映射", "xpack.securitySolution.case.configureCases.mappingFieldSummary": "摘要", "xpack.securitySolution.case.configureCases.noConnector": "未选择连接器", @@ -13347,41 +15519,53 @@ "xpack.securitySolution.case.configureCases.warningMessage": "选定的连接器已删除。选择不同的连接器或创建新的连接器。", "xpack.securitySolution.case.configureCases.warningTitle": "警告", "xpack.securitySolution.case.configureCasesButton": "编辑外部连接", - "xpack.securitySolution.case.confirmDeleteCase.confirmQuestion": "通过删除此案例,将会永久移除所有相关案例数据,您将无法再将数据推送到外部事件管理系统。是否确定要继续?", - "xpack.securitySolution.case.confirmDeleteCase.confirmQuestionPlural": "通过删除这些案例,将会永久移除所有相关案例数据,您将无法再将数据推送到外部事件管理系统。是否确定要继续?", + "xpack.securitySolution.case.confirmDeleteCase.confirmQuestion": "删除此案例即会永久移除所有相关案例数据,而且您将无法再将数据推送到外部事件管理系统。是否确定要继续?", + "xpack.securitySolution.case.confirmDeleteCase.confirmQuestionPlural": "删除这些案例即会永久移除所有相关案例数据,而且您将无法再将数据推送到外部事件管理系统。是否确定要继续?", "xpack.securitySolution.case.confirmDeleteCase.deleteCase": "删除案例", "xpack.securitySolution.case.confirmDeleteCase.deleteCases": "删除案例", "xpack.securitySolution.case.confirmDeleteCase.deleteTitle": "删除“{caseTitle}”", "xpack.securitySolution.case.confirmDeleteCase.selectedCases": "删除选定案例", - "xpack.securitySolution.case.connectors.common.apiTokenTextFieldLabel": "Api 令牌", + "xpack.securitySolution.case.connectors.common.apiTokenTextFieldLabel": "API 令牌", "xpack.securitySolution.case.connectors.common.apiUrlTextFieldLabel": "URL", "xpack.securitySolution.case.connectors.common.emailTextFieldLabel": "电子邮件", "xpack.securitySolution.case.connectors.common.invalidApiUrlTextField": "URL 无效", "xpack.securitySolution.case.connectors.common.passwordTextFieldLabel": "密码", - "xpack.securitySolution.case.connectors.common.requiredApiTokenTextField": "“Api 令牌”必填", + "xpack.securitySolution.case.connectors.common.requiredApiTokenTextField": "“API 令牌”必填", "xpack.securitySolution.case.connectors.common.requiredApiUrlTextField": "“URL”必填", - "xpack.securitySolution.case.connectors.common.requiredEmailTextField": "“URL”必填", + "xpack.securitySolution.case.connectors.common.requiredEmailTextField": "“电子邮件”必填", "xpack.securitySolution.case.connectors.common.requiredPasswordTextField": "“密码”必填", "xpack.securitySolution.case.connectors.common.requiredUsernameTextField": "“用户名”必填", "xpack.securitySolution.case.connectors.common.usernameTextFieldLabel": "用户名", "xpack.securitySolution.case.connectors.jira.actionTypeTitle": "Jira", + "xpack.securitySolution.case.connectors.jira.apiTokenTextFieldLabel": "API 令牌或密码", + "xpack.securitySolution.case.connectors.jira.emailTextFieldLabel": "电子邮件或用户名", "xpack.securitySolution.case.connectors.jira.projectKey": "项目键", - "xpack.securitySolution.case.connectors.jira.requiredProjectKeyTextField": "项目键必填。", + "xpack.securitySolution.case.connectors.jira.requiredApiTokenTextField": "“API 令牌或密码”必填", + "xpack.securitySolution.case.connectors.jira.requiredEmailTextField": "“电子邮件或用户名”必填", + "xpack.securitySolution.case.connectors.jira.requiredProjectKeyTextField": "“项目键”必填", "xpack.securitySolution.case.connectors.jira.selectMessageText": "将 Security 案例数据推送或更新到 Jira 中的新问题", + "xpack.securitySolution.case.connectors.resilient.actionTypeTitle": "IBM Resilient", + "xpack.securitySolution.case.connectors.resilient.apiKeyId": "API 密钥 ID", + "xpack.securitySolution.case.connectors.resilient.apiKeySecret": "API 密钥密码", + "xpack.securitySolution.case.connectors.resilient.orgId": "组织 Id", + "xpack.securitySolution.case.connectors.resilient.requiredApiKeyIdTextField": "“API 密钥 ID”必填", + "xpack.securitySolution.case.connectors.resilient.requiredApiKeySecretTextField": "“API 密钥密码”必填", + "xpack.securitySolution.case.connectors.resilient.requiredOrgIdTextField": "组织 Id", + "xpack.securitySolution.case.connectors.resilient.selectMessageText": "将 SIEM 案例数据推送或更新到 Resilient 中的新问题", "xpack.securitySolution.case.createCase.descriptionFieldRequiredError": "描述必填。", "xpack.securitySolution.case.createCase.fieldTagsHelpText": "为此案例键入一个或多个定制识别标记。在每个标记后按 Enter 键可开始新的标记。", "xpack.securitySolution.case.createCase.titleFieldRequiredError": "标题必填。", "xpack.securitySolution.case.dismissErrorsPushServiceCallOutTitle": "关闭", "xpack.securitySolution.case.pageTitle": "案例", - "xpack.securitySolution.case.readOnlySavedObjectDescription": "您仅有权查看案例。如果需要创建和更新案例,请联系您的 Kibana 管理员", - "xpack.securitySolution.case.readOnlySavedObjectTitle": "您具有只读功能权限", + "xpack.securitySolution.case.readOnlySavedObjectDescription": "您仅有权查看案例。如果需要创建和更新案例,请联系您的 Kibana 管理员。", + "xpack.securitySolution.case.readOnlySavedObjectTitle": "您无法创建新案例或更新现有案例", "xpack.securitySolution.certificate.fingerprint.clientCertLabel": "客户端证书", "xpack.securitySolution.certificate.fingerprint.serverCertLabel": "服务器证书", "xpack.securitySolution.chart.allOthersGroupingLabel": "所有其他", - "xpack.securitySolution.chart.dataAllValuesZerosTitle": "所有值返回零", + "xpack.securitySolution.chart.dataAllValuesZerosTitle": "所有值返回了零", "xpack.securitySolution.chart.dataNotAvailableTitle": "图表数据不可用", - "xpack.securitySolution.chrome.help.appName": "Security", - "xpack.securitySolution.chrome.helpMenu.documentation": "Security 文档", + "xpack.securitySolution.chrome.help.appName": "SIEM", + "xpack.securitySolution.chrome.helpMenu.documentation": "SIEM 文档", "xpack.securitySolution.chrome.helpMenu.documentation.ecs": "ECS 文档", "xpack.securitySolution.clipboard.copied": "已复制", "xpack.securitySolution.clipboard.copy": "复制", @@ -13398,12 +15582,12 @@ "xpack.securitySolution.components.embeddables.embeddedMap.serverLayerLabel": "服务器点", "xpack.securitySolution.components.embeddables.embeddedMap.sourceLayerLabel": "源点", "xpack.securitySolution.components.embeddables.indexPatternsMissingPrompt.errorButtonLabel": "配置索引模式", - "xpack.securitySolution.components.embeddables.indexPatternsMissingPrompt.errorDescription1": "要显示地图数据,必须使用匹配的全局模式定义 Security 索引 ({defaultIndex}) 和 Kibana 索引模式。使用 {beats} 时,可以在主机上运行 {setup} 命令,以自动创建索引模式。例如:{example}。", - "xpack.securitySolution.components.embeddables.indexPatternsMissingPrompt.errorDescription2": "还可以在 Kibana 中配置索引模式。", + "xpack.securitySolution.components.embeddables.indexPatternsMissingPrompt.errorDescription1": "要显示地图数据,必须使用匹配的全局模式定义 SIEM 索引 ({defaultIndex}) 和 Kibana 索引模式。使用 {beats} 时,可以在主机上运行 {setup} 命令,以自动创建索引模式。例如:{example}。", + "xpack.securitySolution.components.embeddables.indexPatternsMissingPrompt.errorDescription2": "还可以在 Kibana 中手动配置索引模式。", "xpack.securitySolution.components.embeddables.indexPatternsMissingPrompt.errorTitle": "未配置所需的索引模式", "xpack.securitySolution.components.embeddables.mapToolTip.errorTitle": "加载地图特征时出错", "xpack.securitySolution.components.embeddables.mapToolTip.filterForValueHoverAction": "筛留值", - "xpack.securitySolution.components.embeddables.mapToolTip.footerLabel": "{currentFeature} / {totalFeatures} {totalFeatures, plural, =1 {feature} other {features}}", + "xpack.securitySolution.components.embeddables.mapToolTip.footerLabel": "{totalFeatures, plural, =1 {特征} other {特征}}中的 {currentFeature} 个", "xpack.securitySolution.components.embeddables.mapToolTip.lineContent.clientLabel": "客户端", "xpack.securitySolution.components.embeddables.mapToolTip.lineContent.destinationLabel": "目标", "xpack.securitySolution.components.embeddables.mapToolTip.lineContent.serverLabel": "服务器", @@ -13436,42 +15620,61 @@ "xpack.securitySolution.components.mlPopover.jobsTable.filters.searchFilterPlaceholder": "例如 rare_process_linux", "xpack.securitySolution.components.mlPopover.jobsTable.filters.showAllJobsLabel": "Elastic 作业", "xpack.securitySolution.components.mlPopover.jobsTable.filters.showSiemJobsLabel": "定制作业", - "xpack.securitySolution.components.mlPopup.anomalyDetectionDescription": "运行下面的任意 Machine Learning 作业以准备创建将产生已检测异常信号的信号检测规则以及查看整个 Security 应用程序内的异常事件。我们提供一系列常见检测作业帮助您入门。如果您希望添加自己的定制 ML 作业,请从 {machineLearning} 应用程序中创建并将它们添加到“SIEM”组。", + "xpack.securitySolution.components.mlPopup.anomalyDetectionDescription": "运行下面的任意 Machine Learning 作业以准备创建为检测到的异常生成告警的检测规则以及查看整个 Security 应用程序内的异常事件。我们提供一系列常见检测作业帮助您入门。如果您希望添加自己的定制 ML 作业,请从 {machineLearning} 应用程序中创建并将它们添加到“Security”组。", "xpack.securitySolution.components.mlPopup.cloudLink": "云部署", "xpack.securitySolution.components.mlPopup.errors.createJobFailureTitle": "创建作业失败", "xpack.securitySolution.components.mlPopup.errors.startJobFailureTitle": "启动作业失败", "xpack.securitySolution.components.mlPopup.hooks.errors.indexPatternFetchFailureTitle": "索引模式提取失败", - "xpack.securitySolution.components.mlPopup.hooks.errors.siemJobFetchFailureTitle": "Security 作业提取失败", + "xpack.securitySolution.components.mlPopup.hooks.errors.siemJobFetchFailureTitle": "SIEM 作业提取失败", "xpack.securitySolution.components.mlPopup.jobsTable.createCustomJobButtonLabel": "创建定制作业", "xpack.securitySolution.components.mlPopup.jobsTable.jobNameColumn": "作业名称", - "xpack.securitySolution.components.mlPopup.jobsTable.noItemsDescription": "未找到任何 Security Machine Learning 作业", + "xpack.securitySolution.components.mlPopup.jobsTable.noItemsDescription": "未找到任何 SIEM Machine Learning 作业", "xpack.securitySolution.components.mlPopup.jobsTable.runJobColumn": "运行作业", "xpack.securitySolution.components.mlPopup.jobsTable.tagsColumn": "组", - "xpack.securitySolution.components.mlPopup.licenseButtonLabel": "管理许可", + "xpack.securitySolution.components.mlPopup.licenseButtonLabel": "管理许可证", "xpack.securitySolution.components.mlPopup.machineLearningLink": "Machine Learning", "xpack.securitySolution.components.mlPopup.mlJobSettingsButtonLabel": "ML 作业设置", "xpack.securitySolution.components.mlPopup.moduleNotCompatibleDescription": "我们找不到任何数据,有关 Machine Learning 作业要求的详细信息,请参阅 {mlDocs}。", - "xpack.securitySolution.components.mlPopup.moduleNotCompatibleTitle": "{incompatibleJobCount} {incompatibleJobCount, plural, =1 {job} other {jobs}}当前不可用。", - "xpack.securitySolution.components.mlPopup.showingLabel": "显示:{filterResultsLength} 个 {filterResultsLength, plural, one {作业} other {作业}}", - "xpack.securitySolution.components.mlPopup.upgradeButtonLabel": "订阅选项", - "xpack.securitySolution.components.mlPopup.upgradeDescription": "要访问 Security 的异常检测功能,必须将您的许可更新到白金级、开始 30 天免费试用或在 AWS、GCP 或 Azurein 实施{cloudLink}。然后便可以运行 Machine Learning 作业并查看异常。", - "xpack.securitySolution.components.mlPopup.upgradeTitle": "升级 Elastic 白金级", + "xpack.securitySolution.components.mlPopup.moduleNotCompatibleTitle": "{incompatibleJobCount} 个{incompatibleJobCount, plural, =1 {作业} other {作业}}当前不可用", + "xpack.securitySolution.components.mlPopup.showingLabel": "正在显示:{filterResultsLength} 个{filterResultsLength, plural, one {作业} other {作业}}", + "xpack.securitySolution.components.mlPopup.upgradeButtonLabel": "订阅计划", + "xpack.securitySolution.components.mlPopup.upgradeDescription": "要访问 SIEM 的异常检测功能,必须将您的许可证更新到白金级、开始 30 天免费试用或在 AWS、GCP 或 Azure 中实施{cloudLink}。然后便可以运行 Machine Learning 作业并查看异常。", + "xpack.securitySolution.components.mlPopup.upgradeTitle": "升级到 Elastic 白金级", "xpack.securitySolution.components.stepDefineRule.ruleTypeField.subscriptionsLink": "白金级订阅", "xpack.securitySolution.containers.anomalies.errorFetchingAnomaliesData": "无法查询异常数据", "xpack.securitySolution.containers.anomalies.stackByJobId": "作业", "xpack.securitySolution.containers.anomalies.title": "异常", - "xpack.securitySolution.containers.case.closedCases": "已关闭 {totalCases, plural, =1 {\"{caseTitle}\"} other {{totalCases} 个案例}}", - "xpack.securitySolution.containers.case.deletedCases": "已删除 {totalCases, plural, =1 {\"{caseTitle}\"} other {{totalCases} 个案例}}", + "xpack.securitySolution.containers.case.closedCases": "已关闭{totalCases, plural, =1 {“{caseTitle}”} other { {totalCases} 个案例}}", + "xpack.securitySolution.containers.case.deletedCases": "已删除{totalCases, plural, =1 {“{caseTitle}”} other { {totalCases} 个案例}}", "xpack.securitySolution.containers.case.errorDeletingTitle": "删除数据时出错", "xpack.securitySolution.containers.case.errorTitle": "提取数据时出错", - "xpack.securitySolution.containers.case.reopenedCases": "已重新打开 {totalCases, plural, =1 {\"{caseTitle}\"} other {{totalCases} 个案例}}", + "xpack.securitySolution.containers.case.pushToExternalService": "已成功发送到 { serviceName }", + "xpack.securitySolution.containers.case.reopenedCases": "已重新打开{totalCases, plural, =1 {“{caseTitle}”} other { {totalCases} 个案例}}", "xpack.securitySolution.containers.case.updatedCase": "已更新“{caseTitle}”", "xpack.securitySolution.containers.detectionEngine.addRuleFailDescription": "无法添加规则", + "xpack.securitySolution.containers.detectionEngine.alerts.createListsIndex.errorDescription": "无法创建列表索引", + "xpack.securitySolution.containers.detectionEngine.alerts.errorFetchingAlertsDescription": "无法查询告警", + "xpack.securitySolution.containers.detectionEngine.alerts.errorGetAlertDescription": "无法获取信号索引名称", + "xpack.securitySolution.containers.detectionEngine.alerts.errorPostAlertDescription": "无法创建信号索引", + "xpack.securitySolution.containers.detectionEngine.alerts.fetchListsIndex.errorDescription": "无法检索列表索引", + "xpack.securitySolution.containers.detectionEngine.alerts.readListsPrivileges.errorDescription": "无法检索列表权限", + "xpack.securitySolution.containers.detectionEngine.createPrePackagedRuleAndTimelineFailDescription": "无法安装 elastic 的预打包规则和时间线", + "xpack.securitySolution.containers.detectionEngine.createPrePackagedRuleAndTimelineSuccesDescription": "已安装 elastic 的预打包规则和时间线", + "xpack.securitySolution.containers.detectionEngine.rulesAndTimelines": "无法提取规则和时间线", "xpack.securitySolution.containers.detectionEngine.tagFetchFailDescription": "无法提取标记", "xpack.securitySolution.containers.errors.dataFetchFailureTitle": "数据提取失败", "xpack.securitySolution.containers.errors.networkFailureTitle": "网络故障", "xpack.securitySolution.containers.errors.stopJobFailureTitle": "停止作业失败", - "xpack.securitySolution.dataProviders.and": "AND", + "xpack.securitySolution.customizeEventRenderers.customizeEventRenderersDescription": "事件呈现器自动在事件中传送最相关的详情,以揭示其故事", + "xpack.securitySolution.customizeEventRenderers.customizeEventRenderersTitle": "定制事件呈现器", + "xpack.securitySolution.customizeEventRenderers.disableAllRenderersButtonLabel": "全部禁用", + "xpack.securitySolution.customizeEventRenderers.enableAllRenderersButtonLabel": "全部启用", + "xpack.securitySolution.customizeEventRenderers.eventRenderersTitle": "事件呈现器", + "xpack.securitySolution.dataProviders.addFieldPopoverButtonLabel": "添加字段", + "xpack.securitySolution.dataProviders.addTemplateFieldPopoverButtonLabel": "添加模板字段", + "xpack.securitySolution.dataProviders.and": "且", + "xpack.securitySolution.dataProviders.convertToFieldLabel": "转换为字段", + "xpack.securitySolution.dataProviders.convertToTemplateFieldLabel": "转换为模板字段", "xpack.securitySolution.dataProviders.copyToClipboardTooltip": "复制到剪贴板", "xpack.securitySolution.dataProviders.deleteDataProvider": "删除", "xpack.securitySolution.dataProviders.dropAnything": "放置任何内容", @@ -13483,8 +15686,8 @@ "xpack.securitySolution.dataProviders.excludeDataProvider": "排除结果", "xpack.securitySolution.dataProviders.existsLabel": "存在", "xpack.securitySolution.dataProviders.fieldLabel": "字段", - "xpack.securitySolution.dataProviders.filterForFieldPresentLabel": "筛留存在的字段", - "xpack.securitySolution.dataProviders.hereToBuildAn": "在此处以构建", + "xpack.securitySolution.dataProviders.filterForFieldPresentLabel": "字段是否存在筛选", + "xpack.securitySolution.dataProviders.hereToBuildAn": "此处以构建", "xpack.securitySolution.dataProviders.highlighted": "已突出显示", "xpack.securitySolution.dataProviders.includeDataProvider": "包括结果", "xpack.securitySolution.dataProviders.not": "非", @@ -13493,43 +15696,106 @@ "xpack.securitySolution.dataProviders.reEnableDataProvider": "重新启用", "xpack.securitySolution.dataProviders.removeDataProvider": "移除数据提供程序", "xpack.securitySolution.dataProviders.showOptionsDataProvider": "显示选项 - 适用于", + "xpack.securitySolution.dataProviders.templateFieldLabel": "模板字段", "xpack.securitySolution.dataProviders.temporaryDisableDataProvider": "暂时禁用", "xpack.securitySolution.dataProviders.toBuildAn": "以构建", "xpack.securitySolution.dataProviders.toggle": "切换", "xpack.securitySolution.dataProviders.valueAriaLabel": "值", "xpack.securitySolution.dataProviders.valuePlaceholder": "值", + "xpack.securitySolution.detectionEngine.alerts.actions.addEndpointException": "添加终端例外", + "xpack.securitySolution.detectionEngine.alerts.actions.addException": "添加例外", + "xpack.securitySolution.detectionEngine.alerts.actions.closeAlertTitle": "关闭告警", + "xpack.securitySolution.detectionEngine.alerts.actions.inProgressAlertTitle": "标记为进行中", + "xpack.securitySolution.detectionEngine.alerts.actions.investigateInTimelineTitle": "在时间线中调查", + "xpack.securitySolution.detectionEngine.alerts.actions.openAlertTitle": "打开告警", + "xpack.securitySolution.detectionEngine.alerts.closedAlertFailedToastMessage": "无法关闭告警。", + "xpack.securitySolution.detectionEngine.alerts.closedAlertsTitle": "已关闭", + "xpack.securitySolution.detectionEngine.alerts.closedAlertSuccessToastMessage": "已成功关闭 {totalAlerts} 个{totalAlerts, plural, =1 {告警} other {告警}}。", + "xpack.securitySolution.detectionEngine.alerts.documentTypeTitle": "告警", + "xpack.securitySolution.detectionEngine.alerts.histogram.allOthersGroupingLabel": "所有其他", + "xpack.securitySolution.detectionEngine.alerts.histogram.headerTitle": "趋势", + "xpack.securitySolution.detectionEngine.alerts.histogram.showingAlertsTitle": "正在显示:{modifier}{totalAlertsFormatted} 个{totalAlerts, plural, =1 {告警} other {告警}}", + "xpack.securitySolution.detectionEngine.alerts.histogram.stackByOptions.destinationIpsDropDown": "排名靠前的目标 IP", + "xpack.securitySolution.detectionEngine.alerts.histogram.stackByOptions.eventActionsDropDown": "排名靠前的事件操作", + "xpack.securitySolution.detectionEngine.alerts.histogram.stackByOptions.eventCategoriesDropDown": "排名靠前的事件类别", + "xpack.securitySolution.detectionEngine.alerts.histogram.stackByOptions.hostNamesDropDown": "排名靠前的主机名", + "xpack.securitySolution.detectionEngine.alerts.histogram.stackByOptions.riskScoresDropDown": "风险分数", + "xpack.securitySolution.detectionEngine.alerts.histogram.stackByOptions.rulesDropDown": "排名靠前的规则", + "xpack.securitySolution.detectionEngine.alerts.histogram.stackByOptions.ruleTypesDropDown": "排名靠前的规则类型", + "xpack.securitySolution.detectionEngine.alerts.histogram.stackByOptions.severitiesDropDown": "严重性", + "xpack.securitySolution.detectionEngine.alerts.histogram.stackByOptions.sourceIpsDropDown": "排名靠前的源 IP", + "xpack.securitySolution.detectionEngine.alerts.histogram.stackByOptions.stackByLabel": "堆叠依据", + "xpack.securitySolution.detectionEngine.alerts.histogram.stackByOptions.usersDropDown": "排名靠前的用户", + "xpack.securitySolution.detectionEngine.alerts.histogram.topNLabel": "排名靠前的{fieldName}", + "xpack.securitySolution.detectionEngine.alerts.histogram.viewAlertsButtonLabel": "查看告警", + "xpack.securitySolution.detectionEngine.alerts.inProgressAlertFailedToastMessage": "无法将告警标记为进行中", + "xpack.securitySolution.detectionEngine.alerts.inProgressAlertsTitle": "进行中", + "xpack.securitySolution.detectionEngine.alerts.inProgressAlertSuccessToastMessage": "已成功将 {totalAlerts} 个{totalAlerts, plural, =1 {告警} other {告警}}标记为进行中。", + "xpack.securitySolution.detectionEngine.alerts.loadingAlertsTitle": "正在加载告警", + "xpack.securitySolution.detectionEngine.alerts.openAlertsTitle": "打开", + "xpack.securitySolution.detectionEngine.alerts.openedAlertFailedToastMessage": "无法打开告警", + "xpack.securitySolution.detectionEngine.alerts.openedAlertSuccessToastMessage": "已成功打开 {totalAlerts} 个{totalAlerts, plural, =1 {告警} other {告警}}。", + "xpack.securitySolution.detectionEngine.alerts.totalCountOfAlertsTitle": "个告警匹配搜索条件", + "xpack.securitySolution.detectionEngine.alerts.utilityBar.additionalFiltersActions.showBuildingBlockTitle": "包括构建块告警", + "xpack.securitySolution.detectionEngine.alerts.utilityBar.additionalFiltersTitle": "其他筛选", + "xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.closeSelectedTitle": "关闭所选", + "xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.inProgressSelectedTitle": "标记为进行中", + "xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.openSelectedTitle": "打开所选", + "xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.viewSelectedInHostsTitle": "查看主机中所选", + "xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.viewSelectedInNetworkTitle": "查看网络中所选", + "xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActions.viewSelectedInTimelineTitle": "查看时间线中所选", + "xpack.securitySolution.detectionEngine.alerts.utilityBar.batchActionsTitle": "批量操作", + "xpack.securitySolution.detectionEngine.alerts.utilityBar.clearSelectionTitle": "清除选择", + "xpack.securitySolution.detectionEngine.alerts.utilityBar.selectAllAlertsTitle": "选择全部 {totalAlertsFormatted} 个{totalAlerts, plural, =1 {告警} other {告警}}", + "xpack.securitySolution.detectionEngine.alerts.utilityBar.selectedAlertsTitle": "已选择 {selectedAlertsFormatted} 个{selectedAlerts, plural, =1 {告警} other {告警}}", + "xpack.securitySolution.detectionEngine.alerts.utilityBar.showingAlertsTitle": "正在显示 {totalAlertsFormatted} 个{totalAlerts, plural, =1 {告警} other {告警}}", + "xpack.securitySolution.detectionEngine.alerts.utilityBar.takeActionTitle": "采取操作", "xpack.securitySolution.detectionEngine.alertTitle": "外部告警", - "xpack.securitySolution.detectionEngine.buttonManageRules": "管理信号检测规则", + "xpack.securitySolution.detectionEngine.buttonManageRules": "管理检测规则", "xpack.securitySolution.detectionEngine.components.importRuleModal.cancelTitle": "取消", "xpack.securitySolution.detectionEngine.components.importRuleModal.importFailedDetailedTitle": "规则 ID:{ruleId}\n 状态代码:{statusCode}\n 消息:{message}", "xpack.securitySolution.detectionEngine.components.importRuleModal.importFailedTitle": "无法导入规则", "xpack.securitySolution.detectionEngine.components.importRuleModal.importRuleTitle": "导入规则", - "xpack.securitySolution.detectionEngine.components.importRuleModal.initialPromptTextDescription": "选择或拖放有效的 rules_export.ndjson 文件", + "xpack.securitySolution.detectionEngine.components.importRuleModal.initialPromptTextDescription": "选择或拖放有效 rules_export.ndjson 文件", "xpack.securitySolution.detectionEngine.components.importRuleModal.overwriteDescription": "自动覆盖具有相同规则 ID 的已保存对象", - "xpack.securitySolution.detectionEngine.components.importRuleModal.selectRuleDescription": "选择要导入的 Security 规则(如从检测引擎视图导出的)", + "xpack.securitySolution.detectionEngine.components.importRuleModal.selectRuleDescription": "选择要导入的安全规则(如从检测引擎视图导出的)", "xpack.securitySolution.detectionEngine.components.importRuleModal.successfullyImportedRulesTitle": "已成功导入 {totalRules} 个{totalRules, plural, =1 {规则} other {规则}}", "xpack.securitySolution.detectionEngine.createRule. stepScheduleRule.completeWithActivatingTitle": "创建并激活规则", "xpack.securitySolution.detectionEngine.createRule. stepScheduleRule.completeWithoutActivatingTitle": "创建规则但不激活", - "xpack.securitySolution.detectionEngine.createRule.backToRulesDescription": "返回到信号检测规则", + "xpack.securitySolution.detectionEngine.createRule.backToRulesDescription": "返回到检测规则", "xpack.securitySolution.detectionEngine.createRule.editRuleButton": "编辑", "xpack.securitySolution.detectionEngine.createRule.filtersLabel": "筛选", "xpack.securitySolution.detectionEngine.createRule.mlRuleTypeDescription": "Machine Learning", "xpack.securitySolution.detectionEngine.createRule.pageTitle": "创建新规则", "xpack.securitySolution.detectionEngine.createRule.QueryLabel": "定制查询", "xpack.securitySolution.detectionEngine.createRule.queryRuleTypeDescription": "查询", + "xpack.securitySolution.detectionEngine.createRule.ruleActionsField.ruleActionsFormErrorsTitle": "请修复下面所列的问题", "xpack.securitySolution.detectionEngine.createRule.savedIdLabel": "已保存查询名称", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.descriptionFieldRequiredError": "描述必填。", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fiedIndexPatternsLabel": "索引模式", + "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldAssociatedToEndpointListLabel": "将规则关联到全局终端异常列表", + "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldAuthorHelpText": "为此规则键入一个或多个作者。键入每个作者后按 Enter 键以添加新作者。", + "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldAuthorLabel": "作者", + "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldBuildingBlockLabel": "将所有生成的告警标记为“构建块”告警", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldDescriptionLabel": "描述", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldFalsePositiveLabel": "误报示例", + "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldLicenseHelpText": "添加许可证名称", + "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldLicenseLabel": "许可证", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldMitreThreatLabel": "MITRE ATT&CK\\u2122", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldNameLabel": "名称", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldReferenceUrlsLabel": "引用 URL", + "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldRuleNameOverrideHelpText": "从源事件中选择字段来填充告警列表中的规则名称。", + "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldRuleNameOverrideLabel": "规则名称覆盖", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldTagsHelpText": "为此规则键入一个或多个定制识别标记。在每个标记后按 Enter 键可开始新的标记。", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldTagsLabel": "标记", - "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldTimelineTemplateHelpText": "选择现有时间线以将其用作调查生成的信号时的模板。", + "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldThresholdFieldHelpText": "选择分组结果所要依据的字段", + "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldThresholdFieldLabel": "字段", + "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldThresholdValueLabel": "阈值", + "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldTimelineTemplateHelpText": "选择调查生成的告警时要使用的时间线。", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldTimelineTemplateLabel": "时间线模板", - "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.guideHelpText": "为执行信号调查的分析师提供有用信息。此指南将显示在规则详情页面上以及从此规则所生成的信号创建的时间线中。", + "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldTimestampOverrideHelpText": "选择执行规则时使用的时间戳字段。选取时间戳最接近于采集时间的字段(例如 event.ingested)。", + "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldTimestampOverrideLabel": "时间戳覆盖", + "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.guideHelpText": "为执行信号调查的分析师提供有用信息。此指南将显示在规则详情页面上以及从此规则所生成的告警创建的时间线中。", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.guideLabel": "调查指南", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.nameFieldRequiredError": "名称必填。", "xpack.securitySolution.detectionEngine.createRule.stepAboutrule.noteHelpText": "添加规则调查指南......", @@ -13537,6 +15803,8 @@ "xpack.securitySolution.detectionEngine.createRule.stepAboutRuleForm.addFalsePositiveDescription": "添加误报示例", "xpack.securitySolution.detectionEngine.createRule.stepAboutRuleForm.addReferenceDescription": "添加引用 URL", "xpack.securitySolution.detectionEngine.createRule.stepAboutRuleForm.advancedSettingsButton": "高级设置", + "xpack.securitySolution.detectionEngine.createRule.stepAboutRuleForm.buildingBlockLabel": "构建块", + "xpack.securitySolution.detectionEngine.createRule.stepAboutRuleForm.endpointExceptionListLabel": "全局终端异常列表", "xpack.securitySolution.detectionEngine.createRule.stepAboutRuleForm.severityOptionCriticalDescription": "紧急", "xpack.securitySolution.detectionEngine.createRule.stepAboutRuleForm.severityOptionHighDescription": "高", "xpack.securitySolution.detectionEngine.createRule.stepAboutRuleForm.severityOptionLowDescription": "低", @@ -13548,12 +15816,13 @@ "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.fieldMachineLearningJobIdLabel": "Machine Learning 作业", "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.fieldQuerBarLabel": "定制查询", "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.fieldRuleTypeLabel": "规则类型", + "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.fieldThresholdLabel": "阈值", "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.importTimelineModalTitle": "从已保存时间线导入查询", "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.importTimelineQueryButton": "从已保存时间线导入查询", "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.indicesCustomDescription": "提供定制的索引列表", - "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.indicesFromConfigDescription": "使用 Security 高级设置的 Elasticsearch 索引", - "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.indicesHelperDescription": "输入要运行此规则的 Elasticsearch 索引的模式。默认情况下,将包括 Security 高级设置中定义的索引模式。", - "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.machineLearningJobIdHelpText": "我们提供若干可让您入门的常规作业。要添加自己的定制规则,在 {machineLearning} 应用程序中请将一组“siem”分配给这些作业,以使它们显示在此处。", + "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.indicesFromConfigDescription": "使用 Security Solution 高级设置中的 Elasticsearch 索引", + "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.indicesHelperDescription": "输入要运行此规则的 Elasticsearch 索引的模式。默认情况下,将包括 Security Solution 高级设置中定义的索引模式。", + "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.machineLearningJobIdHelpText": "我们提供若干帮助您入门的常规作业。要添加自己的定制规则,请在 {machineLearning} 应用程序中将一组“siem”分配给这些作业,以使它们显示在此处。", "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.machineLearningJobIdRequired": "Machine Learning 作业必填。", "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.mlEnableJobWarningTitle": "此 ML 作业当前未运行。在激活此规则之前请通过“ML 作业设置”设置此作业以使其运行。", "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.mlJobSelectPlaceholderText": "选择作业", @@ -13563,35 +15832,44 @@ "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.ruleTypeField.mlTypeDescription": "选择 ML 作业以检测异常活动。", "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.ruleTypeField.mlTypeDisabledDescription": "要访问 ML,需要{subscriptionsLink}。", "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.ruleTypeField.mlTypeTitle": "Machine Learning", - "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.ruleTypeField.queryTypeDescription": "使用 KQL 或 Lucene 跨索引检测问题。", + "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.ruleTypeField.queryTypeDescription": "使用 KQL 或 Lucene 检测所有索引的问题。", "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.ruleTypeField.queryTypeTitle": "定制查询", + "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.ruleTypeField.thresholdTypeDescription": "聚合查询结果以检测匹配数目何时超过阈值。", + "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.ruleTypeField.thresholdTypeTitle": "阈值", + "xpack.securitySolution.detectionEngine.createRule.stepDefineRule.thresholdField.thresholdFieldPlaceholderText": "所有结果", "xpack.securitySolution.detectionEngine.createRule.stepRuleActions.fieldThrottleHelpText": "选择在规则评估为 true 时应执行自动操作的时间。", "xpack.securitySolution.detectionEngine.createRule.stepRuleActions.fieldThrottleLabel": "操作频率", - "xpack.securitySolution.detectionEngine.createRule.stepScheduleRule.fieldAdditionalLookBackHelpText": "增加回查时段的时间以防止信号缺失。", + "xpack.securitySolution.detectionEngine.createRule.stepRuleActions.invalidMustacheTemplateErrorMessage": "{key} 不是有效的 Mustache 模板", + "xpack.securitySolution.detectionEngine.createRule.stepRuleActions.noConnectorSelectedErrorMessage": "未选择连接器", + "xpack.securitySolution.detectionEngine.createRule.stepScheduleRule.completeWithActivatingTitle": "创建并激活规则", + "xpack.securitySolution.detectionEngine.createRule.stepScheduleRule.completeWithoutActivatingTitle": "创建规则但不激活", + "xpack.securitySolution.detectionEngine.createRule.stepScheduleRule.fieldAdditionalLookBackHelpText": "增加回查时段的时间以防止错过告警。", "xpack.securitySolution.detectionEngine.createRule.stepScheduleRule.fieldAdditionalLookBackLabel": "更多回查时间", - "xpack.securitySolution.detectionEngine.createRule.stepScheduleRule.fieldIntervalHelpText": "规则定期运行并检测指定时间范围内的信号。", - "xpack.securitySolution.detectionEngine.createRule.stepScheduleRule.fieldIntervalLabel": "运行间隔:", + "xpack.securitySolution.detectionEngine.createRule.stepScheduleRule.fieldIntervalHelpText": "规则定期运行并检测指定时间范围内的告警。", + "xpack.securitySolution.detectionEngine.createRule.stepScheduleRule.fieldIntervalLabel": "运行间隔", "xpack.securitySolution.detectionEngine.createRule.stepScheduleRuleForm.hoursOptionDescription": "小时", "xpack.securitySolution.detectionEngine.createRule.stepScheduleRuleForm.invalidTimeMessageDescription": "时间必填。", "xpack.securitySolution.detectionEngine.createRule.stepScheduleRuleForm.minutesOptionDescription": "分钟", "xpack.securitySolution.detectionEngine.createRule.stepScheduleRuleForm.secondsOptionDescription": "秒", + "xpack.securitySolution.detectionEngine.createRule.thresholdRuleTypeDescription": "阈值", "xpack.securitySolution.detectionEngine.details.stepAboutRule.aboutText": "关于", "xpack.securitySolution.detectionEngine.details.stepAboutRule.detailsLabel": "详情", "xpack.securitySolution.detectionEngine.details.stepAboutRule.investigationGuideLabel": "调查指南", - "xpack.securitySolution.detectionEngine.detectionsPageTitle": "检测", + "xpack.securitySolution.detectionEngine.detectionsPageTitle": "检测告警", "xpack.securitySolution.detectionEngine.dismissButton": "关闭", "xpack.securitySolution.detectionEngine.dismissNoApiIntegrationKeyButton": "关闭", + "xpack.securitySolution.detectionEngine.dismissNoWriteAlertButton": "关闭", "xpack.securitySolution.detectionEngine.editRule.backToDescription": "返回到", "xpack.securitySolution.detectionEngine.editRule.cancelTitle": "取消", "xpack.securitySolution.detectionEngine.editRule.errorMsgDescription": "抱歉", "xpack.securitySolution.detectionEngine.editRule.pageTitle": "编辑规则设置", "xpack.securitySolution.detectionEngine.editRule.saveChangeTitle": "保存更改", - "xpack.securitySolution.detectionEngine.emptyActionPrimary": "查看设置说明", "xpack.securitySolution.detectionEngine.emptyActionSecondary": "前往文档", - "xpack.securitySolution.detectionEngine.emptyTitle": "似乎您没有与 Security 应用程序的检测引擎相关的索引", + "xpack.securitySolution.detectionEngine.emptyTitle": "似乎在 Security 应用程序中没有与检测引擎相关的索引", "xpack.securitySolution.detectionEngine.goToDocumentationButton": "查看文档", "xpack.securitySolution.detectionEngine.headerPage.pageBadgeLabel": "公测版", - "xpack.securitySolution.detectionEngine.headerPage.pageBadgeTooltip": "“检测”仍为公测版。请通过在 Kibana 存储库中报告问题或错误,帮助我们改进产品。", + "xpack.securitySolution.detectionEngine.headerPage.pageBadgeTooltip": "告警仍为公测版。请通过在 Kibana 存储库中报告问题或错误,帮助我们改进产品。", + "xpack.securitySolution.detectionEngine.lastSignalTitle": "上一告警", "xpack.securitySolution.detectionEngine.mitreAttack.addTitle": "添加 MITRE ATT&CK\\u2122 威胁", "xpack.securitySolution.detectionEngine.mitreAttack.tacticPlaceHolderDescription": "选择策略......", "xpack.securitySolution.detectionEngine.mitreAttack.tacticsDescription": "策略", @@ -13876,11 +16154,12 @@ "xpack.securitySolution.detectionEngine.mitreAttackTechniques.winlogonHelperDllDescription": "Winlogon Helper DLL (T1004)", "xpack.securitySolution.detectionEngine.mitreAttackTechniques.xslScriptProcessingDescription": "XSL Script Processing (T1220)", "xpack.securitySolution.detectionEngine.mlRulesDisabledMessageTitle": "ML 规则需要白金级许可证以及 ML 管理员权限", - "xpack.securitySolution.detectionEngine.mlUnavailableTitle": "{totalRules} 个 {totalRules, plural, =1 {规则需要} other {规则需要}}启用 Machine Learning。", + "xpack.securitySolution.detectionEngine.mlUnavailableTitle": "{totalRules} 个{totalRules, plural, =1 {规则需要} other {规则需要}}启用 Machine Learning。", "xpack.securitySolution.detectionEngine.noApiIntegrationKeyCallOutMsg": "每次启动 Kibana,都会为已保存对象生成新的加密密钥。没有持久性密钥,在 Kibana 重新启动后,将无法删除或修改规则。要设置持久性密钥,请将文本值为 32 个或更多任意字符的 xpack.encryptedSavedObjects.encryptionKey 设置添加到 kibana.yml 文件。", "xpack.securitySolution.detectionEngine.noApiIntegrationKeyCallOutTitle": "需要 API 集成密钥", - "xpack.securitySolution.detectionEngine.noIndexMsgBody": "要使用检测引擎,具有所需集群和索引权限的用户必须首先访问此页面。若需要更多帮助,请联系您的管理员。", "xpack.securitySolution.detectionEngine.noIndexTitle": "让我们来设置您的检测引擎", + "xpack.securitySolution.detectionEngine.noWriteAlertsCallOutMsg": "您仅有权查看告警。如果您需要更新告警状态(打开或关闭告警),请联系您的 Kibana 管理员。", + "xpack.securitySolution.detectionEngine.noWriteAlertsCallOutTitle": "您无法更改告警状态", "xpack.securitySolution.detectionEngine.pageTitle": "检测引擎", "xpack.securitySolution.detectionEngine.panelSubtitleShowing": "正在显示", "xpack.securitySolution.detectionEngine.readOnlyCallOutMsg": "您当前缺少所需的权限,无法创建/编辑检测引擎规则。有关进一步帮助,请联系您的管理员。", @@ -13888,9 +16167,12 @@ "xpack.securitySolution.detectionEngine.rule.editRule.errorMsgDescription": "您在{countError, plural, one {以下选项卡} other {以下选项卡}}中的输入无效:{tabHasError}", "xpack.securitySolution.detectionEngine.ruleDescription.mlJobStartedDescription": "已启动", "xpack.securitySolution.detectionEngine.ruleDescription.mlJobStoppedDescription": "已停止", + "xpack.securitySolution.detectionEngine.ruleDescription.thresholdResultsAggregatedByDescription": "结果聚合依据", + "xpack.securitySolution.detectionEngine.ruleDescription.thresholdResultsAllDescription": "所有结果", "xpack.securitySolution.detectionEngine.ruleDetails.activateRuleLabel": "激活", - "xpack.securitySolution.detectionEngine.ruleDetails.backToRulesDescription": "返回到信号检测规则", - "xpack.securitySolution.detectionEngine.ruleDetails.errorCalloutTitle": "规则故障位置", + "xpack.securitySolution.detectionEngine.ruleDetails.backToRulesDescription": "返回到检测规则", + "xpack.securitySolution.detectionEngine.ruleDetails.errorCalloutTitle": "规则错误位置", + "xpack.securitySolution.detectionEngine.ruleDetails.exceptionsTab": "例外", "xpack.securitySolution.detectionEngine.ruleDetails.experimentalDescription": "实验性", "xpack.securitySolution.detectionEngine.ruleDetails.failureHistoryTab": "失败历史记录", "xpack.securitySolution.detectionEngine.ruleDetails.lastFiveErrorsTitle": "上五个错误", @@ -13912,15 +16194,15 @@ "xpack.securitySolution.detectionEngine.rules.allRules.actions.editRuleSettingsDescription": "编辑规则设置", "xpack.securitySolution.detectionEngine.rules.allRules.actions.exportRuleDescription": "导出规则", "xpack.securitySolution.detectionEngine.rules.allRules.activeRuleDescription": "活动", - "xpack.securitySolution.detectionEngine.rules.allRules.batchActions.activateSelectedErrorTitle": "激活 {totalRules, plural, =1 {个规则} other {个规则}}时出错……", - "xpack.securitySolution.detectionEngine.rules.allRules.batchActions.activateSelectedTitle": "激活选定", - "xpack.securitySolution.detectionEngine.rules.allRules.batchActions.deactivateSelectedErrorTitle": "停用 {totalRules, plural, =1 {个规则} other {个规则}}时出错……", - "xpack.securitySolution.detectionEngine.rules.allRules.batchActions.deactivateSelectedTitle": "停用选定", - "xpack.securitySolution.detectionEngine.rules.allRules.batchActions.deleteSelectedErrorTitle": "删除 {totalRules, plural, =1 {个规则} other {个规则}}时出错……", + "xpack.securitySolution.detectionEngine.rules.allRules.batchActions.activateSelectedErrorTitle": "激活{totalRules, plural, =1 {规则} other {规则}}时出错……", + "xpack.securitySolution.detectionEngine.rules.allRules.batchActions.activateSelectedTitle": "激活所选", + "xpack.securitySolution.detectionEngine.rules.allRules.batchActions.deactivateSelectedErrorTitle": "停用{totalRules, plural, =1 {规则} other {规则}}时出错……", + "xpack.securitySolution.detectionEngine.rules.allRules.batchActions.deactivateSelectedTitle": "停用所选", + "xpack.securitySolution.detectionEngine.rules.allRules.batchActions.deleteSelectedErrorTitle": "删除{totalRules, plural, =1 {规则} other {规则}}时出错……", "xpack.securitySolution.detectionEngine.rules.allRules.batchActions.deleteSelectedImmutableTitle": "选择内容包含无法删除的不可变规则", - "xpack.securitySolution.detectionEngine.rules.allRules.batchActions.deleteSelectedTitle": "删除选定……", - "xpack.securitySolution.detectionEngine.rules.allRules.batchActions.duplicateSelectedTitle": "复制选定……", - "xpack.securitySolution.detectionEngine.rules.allRules.batchActions.exportSelectedTitle": "导出选定", + "xpack.securitySolution.detectionEngine.rules.allRules.batchActions.deleteSelectedTitle": "删除所选……", + "xpack.securitySolution.detectionEngine.rules.allRules.batchActions.duplicateSelectedTitle": "复制所选……", + "xpack.securitySolution.detectionEngine.rules.allRules.batchActions.exportSelectedTitle": "导出所选", "xpack.securitySolution.detectionEngine.rules.allRules.batchActionsTitle": "批处理操作", "xpack.securitySolution.detectionEngine.rules.allRules.columns.activateTitle": "已激活", "xpack.securitySolution.detectionEngine.rules.allRules.columns.gap": "缺口(如果有)", @@ -13943,7 +16225,7 @@ "xpack.securitySolution.detectionEngine.rules.allRules.inactiveRuleDescription": "非活动", "xpack.securitySolution.detectionEngine.rules.allRules.refreshTitle": "刷新", "xpack.securitySolution.detectionEngine.rules.allRules.searchAriaLabel": "搜索规则", - "xpack.securitySolution.detectionEngine.rules.allRules.searchPlaceholder": "例如规则名", + "xpack.securitySolution.detectionEngine.rules.allRules.searchPlaceholder": "例如,规则名", "xpack.securitySolution.detectionEngine.rules.allRules.selectedRulesTitle": "已选择 {selectedRules} 个{selectedRules, plural, =1 {规则} other {规则}}", "xpack.securitySolution.detectionEngine.rules.allRules.showingRulesTitle": "正在显示 {totalRules} 个{totalRules, plural, =1 {规则} other {规则}}", "xpack.securitySolution.detectionEngine.rules.allRules.successfullyDuplicatedRulesTitle": "已成功复制 {totalRules, plural, =1 {{totalRules} 个规则} other {{totalRules} 个规则}}", @@ -13952,6 +16234,7 @@ "xpack.securitySolution.detectionEngine.rules.allRules.tabs.monitoring": "监测", "xpack.securitySolution.detectionEngine.rules.allRules.tabs.rules": "规则", "xpack.securitySolution.detectionEngine.rules.backOptionsHeader": "返回到检测", + "xpack.securitySolution.detectionEngine.rules.components.genericDownloader.exportFailureTitle": "无法导出数据……", "xpack.securitySolution.detectionEngine.rules.components.ruleActionsOverflow.allActionsTitle": "所有操作", "xpack.securitySolution.detectionEngine.rules.continueButtonTitle": "继续", "xpack.securitySolution.detectionEngine.rules.create.successfullyCreatedRuleTitle": "{ruleName} 已创建", @@ -13959,15 +16242,17 @@ "xpack.securitySolution.detectionEngine.rules.deleteDescription": "删除", "xpack.securitySolution.detectionEngine.rules.editPageTitle": "编辑", "xpack.securitySolution.detectionEngine.rules.importRuleTitle": "导入规则……", - "xpack.securitySolution.detectionEngine.rules.loadPrePackagedRulesButton": "加载 Elastic 预构建规则", + "xpack.securitySolution.detectionEngine.rules.loadPrePackagedRulesButton": "加载 Elastic 预构建规则和时间线模板", "xpack.securitySolution.detectionEngine.rules.optionalFieldDescription": "可选", - "xpack.securitySolution.detectionEngine.rules.pageTitle": "信号检测规则", + "xpack.securitySolution.detectionEngine.rules.pageTitle": "检测规则", "xpack.securitySolution.detectionEngine.rules.prePackagedRules.createOwnRuletButton": "创建自己的规则", - "xpack.securitySolution.detectionEngine.rules.prePackagedRules.emptyPromptMessage": "Elastic Security 提供预构建检测规则,它们运行在后台并在条件满足时创建信号。默认情况下,所有预构建规则处于禁用状态,请选择您要激活的规则。", + "xpack.securitySolution.detectionEngine.rules.prePackagedRules.emptyPromptMessage": "Elastic Security 提供预构建检测规则,它们运行在后台并在条件满足时创建告警。默认情况下,所有预构建规则处于禁用状态,请选择您要激活的规则。", "xpack.securitySolution.detectionEngine.rules.prePackagedRules.emptyPromptTitle": "加载 Elastic 预构建检测规则", "xpack.securitySolution.detectionEngine.rules.prePackagedRules.loadPreBuiltButton": "加载预构建检测规则", "xpack.securitySolution.detectionEngine.rules.releaseNotesHelp": "发行说明", + "xpack.securitySolution.detectionEngine.rules.reloadMissingPrePackagedRulesAndTimelinesButton": "安装 {missingRules} 个 Elastic 预构建{missingRules, plural, =1 {规则} other {规则}}以及 {missingTimelines} 个 Elastic 预构建{missingTimelines, plural, =1 {时间线} other {时间线}} ", "xpack.securitySolution.detectionEngine.rules.reloadMissingPrePackagedRulesButton": "安装 {missingRules} 个 Elastic 预构建{missingRules, plural, =1 {规则} other {规则}} ", + "xpack.securitySolution.detectionEngine.rules.reloadMissingPrePackagedTimelinesButton": "安装 {missingTimelines} 个 Elastic 预构建{missingTimelines, plural, =1 {时间线} other {时间线}} ", "xpack.securitySolution.detectionEngine.rules.ruleActionsTitle": "规则操作", "xpack.securitySolution.detectionEngine.rules.scheduleRuleTitle": "计划规则", "xpack.securitySolution.detectionEngine.rules.stepAboutTitle": "关于", @@ -13976,14 +16261,20 @@ "xpack.securitySolution.detectionEngine.rules.stepScheduleTitle": "计划", "xpack.securitySolution.detectionEngine.rules.update.successfullySavedRuleTitle": "{ruleName} 已保存", "xpack.securitySolution.detectionEngine.rules.updateButtonTitle": "更新", - "xpack.securitySolution.detectionEngine.rules.updatePrePackagedRulesButton": "更新 {updateRules} 个 Elastic 预构建{updateRules, plural, =1 {规则} other {规则}} ", - "xpack.securitySolution.detectionEngine.rules.updatePrePackagedRulesMsg": "您可更新 {updateRules} 个 Elastic 预构建{updateRules, plural, =1 {规则} other {规则}}。注意,这将重新加载删除的 Elastic 预构建规则。", - "xpack.securitySolution.detectionEngine.rules.updatePrePackagedRulesTitle": "有 Elastic 预构建规则的更新", + "xpack.securitySolution.detectionEngine.rules.updatePrePackagedRulesAndTimelinesButton": "更新 {updateRules} 个 Elastic 预构建{updateRules, plural, =1 {规则} other {规则}}及 {updateTimelines} 个 Elastic 预构建{updateTimelines, plural, =1 {时间线} other {时间线}}", + "xpack.securitySolution.detectionEngine.rules.updatePrePackagedRulesAndTimelinesMsg": "您可以更新 {updateRules} 个 Elastic 预构建{updateRules, plural, =1 {规则} other {规则}}和 {updateTimelines} 个 Elastic 预构建{updateTimelines, plural, =1 {时间线} other {时间线}}。注意,这将重新加载删除的 Elastic 预构建规则。", + "xpack.securitySolution.detectionEngine.rules.updatePrePackagedRulesButton": "更新 {updateRules} 个 Elastic 预构建{updateRules, plural, =1 {规则} other {规则}}", + "xpack.securitySolution.detectionEngine.rules.updatePrePackagedRulesMsg": "您可以更新 {updateRules} 个 Elastic 预构建{updateRules, plural, =1 {规则} other {规则}}", + "xpack.securitySolution.detectionEngine.rules.updatePrePackagedRulesTitle": "更新可用于 Elastic 预构建规则或时间线模板", + "xpack.securitySolution.detectionEngine.rules.updatePrePackagedTimelinesButton": "更新 {updateTimelines} 个 Elastic 预构建{updateTimelines, plural, =1 {时间线} other {时间线}}", + "xpack.securitySolution.detectionEngine.rules.updatePrePackagedTimelinesMsg": "您可以更新 {updateTimelines} 个 Elastic 预构建{updateTimelines, plural, =1 {时间线} other {时间线}}", "xpack.securitySolution.detectionEngine.ruleStatus.refreshButton": "刷新", "xpack.securitySolution.detectionEngine.ruleStatus.statusAtDescription": "处于", "xpack.securitySolution.detectionEngine.ruleStatus.statusDateDescription": "状态日期", "xpack.securitySolution.detectionEngine.ruleStatus.statusDescription": "上次响应", "xpack.securitySolution.detectionEngine.signalRuleAlert.actionGroups.default": "默认值", + "xpack.securitySolution.detectionEngine.signalTitle": "检测到的告警", + "xpack.securitySolution.detectionEngine.totalSignalTitle": "合计", "xpack.securitySolution.detectionEngine.userUnauthenticatedMsgBody": "您没有所需的权限,无法查看检测引擎。若需要更多帮助,请联系您的管理员。", "xpack.securitySolution.detectionEngine.userUnauthenticatedTitle": "需要检测引擎权限", "xpack.securitySolution.dragAndDrop.addToTimeline": "添加到时间线调查", @@ -14007,7 +16298,202 @@ "xpack.securitySolution.editDataProvider.selectAnOperatorPlaceholder": "选择运算符", "xpack.securitySolution.editDataProvider.valueLabel": "值", "xpack.securitySolution.editDataProvider.valuePlaceholder": "值", + "xpack.securitySolution.emptyMessage": "Elastic Security 将免费且开放的 Elastic SIEM 和 Elastic Endpoint Security 整合在一起,从而防御、检测并响应威胁。首先,您需要将安全解决方案相关数据添加到 Elastic Stack。有关更多信息,请查看我们的 ", "xpack.securitySolution.emptyString.emptyStringDescription": "空字符串", + "xpack.securitySolution.endpoint.host.details.endpointVersion": "Endpoint 版本", + "xpack.securitySolution.endpoint.host.details.errorBody": "请退出浮出控件并选择可用主机。", + "xpack.securitySolution.endpoint.host.details.errorTitle": "找不到主机", + "xpack.securitySolution.endpoint.host.details.hostname": "主机名", + "xpack.securitySolution.endpoint.host.details.ipAddress": "IP 地址", + "xpack.securitySolution.endpoint.host.details.lastSeen": "最后看到时间", + "xpack.securitySolution.endpoint.host.details.linkToIngestTitle": "重新分配策略", + "xpack.securitySolution.endpoint.host.details.os": "OS", + "xpack.securitySolution.endpoint.host.details.policy": "政策", + "xpack.securitySolution.endpoint.host.details.policyStatus": "策略状态", + "xpack.securitySolution.endpoint.host.details.policyStatusValue": "{policyStatus, select, success {成功} warning {警告} failure {失败} other {未知}}", + "xpack.securitySolution.endpoint.host.policyResponse.backLinkTitle": "终端详情", + "xpack.securitySolution.endpoint.host.policyResponse.title": "策略响应", + "xpack.securitySolution.endpoint.hostDetails.noPolicyResponse": "没有可用的策略响应", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_dns_events": "配置 DNS 事件", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_elasticsearch_connection": "配置 Elastic 搜索连接", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_file_events": "配置文件事件", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_imageload_events": "配置映像加载事件", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_kernel": "配置内核", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_logging": "配置日志记录", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_malware": "配置恶意软件", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_network_events": "配置网络事件", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_process_events": "配置进程事件", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_registry_events": "配置注册表事件", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.configure_security_events": "配置安全事件", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.connect_kernel": "连接内核", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.detect_async_image_load_events": "检测异步映像加载事件", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.detect_file_open_events": "检测文件打开事件", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.detect_file_write_events": "检测文件写入事件", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.detect_network_events": "检测网络事件", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.detect_process_events": "检测进程事件", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.detect_registry_events": "检测注册表事件", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.detect_sync_image_load_events": "检测同步映像加载事件", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.download_global_artifacts": "下载全局项目", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.download_user_artifacts": "下面用户项目", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.events": "事件", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.failed": "失败", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.load_config": "加载配置", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.load_malware_model": "加载恶意软件模型", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.logging": "日志", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.malware": "恶意软件", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.read_elasticsearch_config": "读取 ElasticSearch 配置", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.read_events_config": "读取时间配置", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.read_kernel_config": "读取内核配置", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.read_logging_config": "读取日志配置", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.read_malware_config": "读取恶意软件配置", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.streaming": "流式传输", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.success": "成功", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.warning": "警告", + "xpack.securitySolution.endpoint.hostDetails.policyResponse.workflow": "工作流", + "xpack.securitySolution.endpoint.hostList.beta": "公测版", + "xpack.securitySolution.endpoint.hostList.loadingPolicies": "正在加载政策配置", + "xpack.securitySolution.endpoint.hostList.noEndpointsInstructions": "您已创建安全策略。现在您需要按照下面的步骤在代理上启用 Elastic Endpoint Security 功能。", + "xpack.securitySolution.endpoint.hostList.noEndpointsPrompt": "在您的代理上启用 Elastic Endpoint Security", + "xpack.securitySolution.endpoint.hostList.noPolicies": "没有策略。", + "xpack.securitySolution.endpoint.hostList.stepOne": "现有策略在下面列出。之后可以对其进行更改。", + "xpack.securitySolution.endpoint.hostList.stepOneTitle": "选择要用于保护主机的策略", + "xpack.securitySolution.endpoint.hostList.stepTwo": "为了让您入门,将会为您提供必要的命令。", + "xpack.securitySolution.endpoint.hostList.stepTwoTitle": "通过采集管理器注册启用 Endpoint Security 的代理", + "xpack.securitySolution.endpoint.ingestManager.createPackageConfig.endpointConfiguration": "使用此代理配置的任何代理都会使用基本策略。可以在 Security 应用中对此策略进行更改,Fleet 会将这些更改部署到代理。", + "xpack.securitySolution.endpoint.ingestToastMessage": "采集管理器在其设置期间失败。", + "xpack.securitySolution.endpoint.ingestToastTitle": "应用无法初始化", + "xpack.securitySolution.endpoint.policy.details.backToListTitle": "返回到策略列表", + "xpack.securitySolution.endpoint.policy.details.cancel": "取消", + "xpack.securitySolution.endpoint.policy.details.detect": "检测", + "xpack.securitySolution.endpoint.policy.details.eventCollection": "事件收集", + "xpack.securitySolution.endpoint.policy.details.eventCollectionsEnabled": "{selected} / {total} 事件收集已启用", + "xpack.securitySolution.endpoint.policy.details.linux": "Linux", + "xpack.securitySolution.endpoint.policy.details.mac": "Mac", + "xpack.securitySolution.endpoint.policy.details.malware": "恶意软件", + "xpack.securitySolution.endpoint.policy.details.malwareProtectionsEnabled": "恶意软件防护{mode, select, true {已启用} false {已禁用}}", + "xpack.securitySolution.endpoint.policy.details.prevent": "防御", + "xpack.securitySolution.endpoint.policy.details.protections": "防护", + "xpack.securitySolution.endpoint.policy.details.save": "保存", + "xpack.securitySolution.endpoint.policy.details.settings": "设置", + "xpack.securitySolution.endpoint.policy.details.updateConfirm.cancelButtonTitle": "取消", + "xpack.securitySolution.endpoint.policy.details.updateConfirm.confirmButtonTitle": "保存并部署更改", + "xpack.securitySolution.endpoint.policy.details.updateConfirm.message": "此操作无法撤消。是否确定要继续?", + "xpack.securitySolution.endpoint.policy.details.updateConfirm.title": "保存并部署更改", + "xpack.securitySolution.endpoint.policy.details.updateConfirm.warningMessage": "保存这些更改会将更新应用到分配给此策略的所有活动终端", + "xpack.securitySolution.endpoint.policy.details.updateConfirm.warningTitle": "此操作将更新 {hostCount, plural, one {# 个主机} other {# 个主机}}", + "xpack.securitySolution.endpoint.policy.details.updateErrorTitle": "失败!", + "xpack.securitySolution.endpoint.policy.details.updateSuccessMessage": "策略 {name} 已更新。", + "xpack.securitySolution.endpoint.policy.details.updateSuccessTitle": "成功!", + "xpack.securitySolution.endpoint.policy.details.windows": "Windows", + "xpack.securitySolution.endpoint.policy.details.windowsAndMac": "Windows、Mac", + "xpack.securitySolution.endpoint.policyDetailOS": "操作系统", + "xpack.securitySolution.endpoint.policyDetails.agentsSummary.errorTitle": "错误", + "xpack.securitySolution.endpoint.policyDetails.agentsSummary.offlineTitle": "脱机", + "xpack.securitySolution.endpoint.policyDetails.agentsSummary.onlineTitle": "联机", + "xpack.securitySolution.endpoint.policyDetails.agentsSummary.totalTitle": "主机", + "xpack.securitySolution.endpoint.policyDetailsConfig.eventingEvents": "事件", + "xpack.securitySolution.endpoint.policyDetailsConfig.linux.events.file": "文件", + "xpack.securitySolution.endpoint.policyDetailsConfig.linux.events.network": "网络", + "xpack.securitySolution.endpoint.policyDetailsConfig.linux.events.process": "进程", + "xpack.securitySolution.endpoint.policyDetailsConfig.mac.events.file": "文件", + "xpack.securitySolution.endpoint.policyDetailsConfig.mac.events.network": "网络", + "xpack.securitySolution.endpoint.policyDetailsConfig.mac.events.process": "进程", + "xpack.securitySolution.endpoint.policyDetailsConfig.protectionLevel": "防护级别", + "xpack.securitySolution.endpoint.policyDetailsConfig.windows.events.dllDriverLoad": "DLL 和驱动程序加载", + "xpack.securitySolution.endpoint.policyDetailsConfig.windows.events.dns": "DNS", + "xpack.securitySolution.endpoint.policyDetailsConfig.windows.events.file": "文件", + "xpack.securitySolution.endpoint.policyDetailsConfig.windows.events.network": "网络", + "xpack.securitySolution.endpoint.policyDetailsConfig.windows.events.process": "进程", + "xpack.securitySolution.endpoint.policyDetailsConfig.windows.events.registry": "注册表", + "xpack.securitySolution.endpoint.policyDetailsConfig.windows.events.security": "安全", + "xpack.securitySolution.endpoint.policyDetailType": "类型", + "xpack.securitySolution.endpoint.policyList.actionButtonText": "添加 Endpoint Security", + "xpack.securitySolution.endpoint.policyList.actionMenu": "打开", + "xpack.securitySolution.endpoint.policyList.agentConfigAction": "查看代理配置", + "xpack.securitySolution.endpoint.policyList.beta": "公测版", + "xpack.securitySolution.endpoint.policyList.createdAt": "创建日期", + "xpack.securitySolution.endpoint.policyList.createdBy": "创建者", + "xpack.securitySolution.endpoint.policyList.createNewButton": "创建新策略", + "xpack.securitySolution.endpoint.policyList.deleteConfirm.cancelButtonTitle": "取消", + "xpack.securitySolution.endpoint.policyList.deleteConfirm.confirmDeleteButton": "删除策略", + "xpack.securitySolution.endpoint.policyList.deleteConfirm.deletingButton": "正在删除……", + "xpack.securitySolution.endpoint.policyList.deleteConfirm.message": "此操作无法撤消。是否确定要继续?", + "xpack.securitySolution.endpoint.policyList.deleteConfirm.title": "删除策略并部署更改", + "xpack.securitySolution.endpoint.policyList.deleteConfirm.warningMessage": "删除此策略将从这些主机上移除 Endpoint Security", + "xpack.securitySolution.endpoint.policyList.deleteConfirm.warningTitle": "此操作将从 {hostCount, plural, one {# 个主机} other {# 个主机}}上删除 Endpoint Security", + "xpack.securitySolution.endpoint.policyList.deleteFailedToast": "失败!", + "xpack.securitySolution.endpoint.policyList.deleteFailedToastBody": "无法删除策略", + "xpack.securitySolution.endpoint.policyList.deleteSuccessToast": "成功!", + "xpack.securitySolution.endpoint.policyList.deleteSuccessToastDetails": "策略已删除。", + "xpack.securitySolution.endpoint.policyList.emptyCreateNewButton": "注册代理", + "xpack.securitySolution.endpoint.policyList.nameField": "策略名称", + "xpack.securitySolution.endpoint.policyList.onboardingDocsLink": "查看 Security 应用文档", + "xpack.securitySolution.endpoint.policyList.onboardingSectionOne": "Elastic Endpoint Security 使用威胁防御、检测和深度安全数据可见性来保护您的主机。", + "xpack.securitySolution.endpoint.policyList.onboardingSectionThree": "首先,将 Elastic Endpoint Security 集成添加到您的代理。有关更多信息, ", + "xpack.securitySolution.endpoint.policyList.onboardingSectionTwo": "从此页面,您将能够查看环境中运行 Elastic Endpoint Security 的主机。", + "xpack.securitySolution.endpoint.policyList.onboardingTitle": "开始使用 Elastic Endpoint Security", + "xpack.securitySolution.endpoint.policyList.policyDeleteAction": "删除策略", + "xpack.securitySolution.endpoint.policyList.revision": "修订 {revNumber}", + "xpack.securitySolution.endpoint.policyList.updatedAt": "最后更新时间", + "xpack.securitySolution.endpoint.policyList.updatedBy": "最后更新者", + "xpack.securitySolution.endpoint.policyList.versionFieldLabel": "版本", + "xpack.securitySolution.endpoint.policyList.viewTitleTotalCount": "{totalItemCount, plural, one {# 个策略} other {# 个策略}}", + "xpack.securitySolution.endpoint.resolver.eitherLineageLimitExceeded": "下面可视化和事件列表中的一些进程事件无法显示,因为已达到数据限制。", + "xpack.securitySolution.endpoint.resolver.elapsedTime": "{duration} {durationType}", + "xpack.securitySolution.endpoint.resolver.loadingError": "加载数据时出错。", + "xpack.securitySolution.endpoint.resolver.panel.error.error": "错误", + "xpack.securitySolution.endpoint.resolver.panel.error.events": "事件", + "xpack.securitySolution.endpoint.resolver.panel.error.goBack": "单击此链接以返回到所有进程的列表。", + "xpack.securitySolution.endpoint.resolver.panel.processDescList.events": "事件", + "xpack.securitySolution.endpoint.resolver.panel.processEventCounts.events": "事件", + "xpack.securitySolution.endpoint.resolver.panel.processEventListByType.eventDescriptiveName": "{descriptor} {subject}", + "xpack.securitySolution.endpoint.resolver.panel.processEventListByType.events": "事件", + "xpack.securitySolution.endpoint.resolver.panel.processEventListByType.wait": "等候事件......", + "xpack.securitySolution.endpoint.resolver.panel.processListWithCounts.events": "所有进程事件", + "xpack.securitySolution.endpoint.resolver.panel.relatedCounts.numberOfEventsInCrumb": "{totalCount} 个事件", + "xpack.securitySolution.endpoint.resolver.panel.relatedDetail.missing": "找不到相关事件。", + "xpack.securitySolution.endpoint.resolver.panel.relatedDetail.wait": "等候事件......", + "xpack.securitySolution.endpoint.resolver.panel.relatedEventDetail.atTime": "@ {date}", + "xpack.securitySolution.endpoint.resolver.panel.relatedEventDetail.categoryAndType": "{category} {eventType}", + "xpack.securitySolution.endpoint.resolver.panel.relatedEventDetail.countByCategory": "{count} 个{category}", + "xpack.securitySolution.endpoint.resolver.panel.relatedEventDetail.detailsForProcessName": "{processName} 的详情", + "xpack.securitySolution.endpoint.resolver.panel.relatedEventDetail.eventDescriptiveName": "{descriptor} {subject}", + "xpack.securitySolution.endpoint.resolver.panel.relatedEventDetail.eventDescriptiveNameInTitle": "{descriptor} {subject}", + "xpack.securitySolution.endpoint.resolver.panel.relatedEventDetail.events": "事件", + "xpack.securitySolution.endpoint.resolver.panel.relatedEventDetail.NA": "不可用", + "xpack.securitySolution.endpoint.resolver.panel.relatedEventDetail.numberOfEvents": "{totalCount} 个事件", + "xpack.securitySolution.endpoint.resolver.panel.relatedEventList.countByCategory": "{count} 个{category}", + "xpack.securitySolution.endpoint.resolver.panel.relatedEventList.numberOfEvents": "{totalCount} 个事件", + "xpack.securitySolution.endpoint.resolver.panel.table.row.count": "计数", + "xpack.securitySolution.endpoint.resolver.panel.table.row.eventType": "事件类型", + "xpack.securitySolution.endpoint.resolver.panel.table.row.processNameTitle": "进程名称", + "xpack.securitySolution.endpoint.resolver.panel.table.row.timestampInvalidLabel": "无效", + "xpack.securitySolution.endpoint.resolver.panel.table.row.timestampTitle": "时间戳", + "xpack.securitySolution.endpoint.resolver.panel.table.row.valueMissingDescription": "值缺失", + "xpack.securitySolution.endpoint.resolver.relatedEventLimitExceeded": "{numberOfEventsMissing} 个{category}事件无法显示,因为已达到数据限制。", + "xpack.securitySolution.endpoint.resolver.relatedEventLimitTitle": "此列表包括 {numberOfEntries} 个进程事件。", + "xpack.securitySolution.endpoint.resolver.relatedEvents": "事件", + "xpack.securitySolution.endpoint.resolver.relatedLimitsExceededTitle": "此列表包括 {numberOfEventsDisplayed} 个{category}事件。", + "xpack.securitySolution.endpoint.resolver.relatedNotRetrieved": "尚未检索相关事件。", + "xpack.securitySolution.endpoint.resolver.relatedRetrievalError": "检索相关事件时出现错误。", + "xpack.securitySolution.endpoint.resolver.runningProcess": "正在运行的进程", + "xpack.securitySolution.endpoint.resolver.runningTrigger": "正在运行的触发器", + "xpack.securitySolution.endpoint.resolver.terminatedProcess": "已终止进程", + "xpack.securitySolution.endpoint.resolver.terminatedTrigger": "已终止触发器", + "xpack.securitySolution.endpointList.endpointVersion": "版本", + "xpack.securitySolution.endpointList.hostname": "主机名", + "xpack.securitySolution.endpointList.hostStatus": "主机状态", + "xpack.securitySolution.endpointList.hostStatusValue": "{hostStatus, select, online {联机} error {错误} other {脱机}}", + "xpack.securitySolution.endpointList.ip": "IP 地址", + "xpack.securitySolution.endpointList.lastActive": "上次活动时间", + "xpack.securitySolution.endpointList.os": "操作系统", + "xpack.securitySolution.endpointList.policy": "政策", + "xpack.securitySolution.endpointList.policyStatus": "策略状态", + "xpack.securitySolution.endpointList.totalCount": "{totalItemCount, plural, one {# 个主机} other {# 个主机}}", + "xpack.securitySolution.endpointManagement.noPermissionsSubText": "似乎采集管理器已禁用。必须启用采集管理器,才能使用此功能。如果您无权启用采集管理器,请联系您的 Kibana 管理员。", + "xpack.securitySolution.endpointManagemnet.noPermissionsText": "您没有所需的 Kibana 权限,无法使用 Elastic Security 管理", + "xpack.securitySolution.enpdoint.resolver.panelutils.betaBadgeLabel": "公测版", + "xpack.securitySolution.enpdoint.resolver.panelutils.invaliddate": "日期无效", "xpack.securitySolution.event.module.linkToElasticEndpointSecurityDescription": "在 Elastic Endpoint Security 中打开", "xpack.securitySolution.eventDetails.blank": " ", "xpack.securitySolution.eventDetails.copyToClipboard": "复制到剪贴板", @@ -14019,25 +16505,124 @@ "xpack.securitySolution.eventDetails.table": "表", "xpack.securitySolution.eventDetails.toggleColumnTooltip": "切换列", "xpack.securitySolution.eventDetails.value": "值", + "xpack.securitySolution.eventRenderers.auditdDescriptionPart1": "审计事件传送 Linux 审计框架的安全相关日志。", + "xpack.securitySolution.eventRenderers.auditdFileDescriptionPart1": "文件事件显示通过特定进程对文件执行 CRUD 操作的用户(和系统帐户)。", + "xpack.securitySolution.eventRenderers.auditdFileName": "Auditd 文件", + "xpack.securitySolution.eventRenderers.auditdName": "Auditd", + "xpack.securitySolution.eventRenderers.authenticationDescriptionPart1": "身份验证显示成功或未成功登录主机的用户(和系统帐户)。", + "xpack.securitySolution.eventRenderers.authenticationDescriptionPart2": "用户代表其他用户进行身份验证时,某些身份验证事件可能包含其他详情。", + "xpack.securitySolution.eventRenderers.authenticationName": "身份验证", + "xpack.securitySolution.eventRenderers.dnsDescriptionPart1": "域名系统 (DNS) 事件显示通过特定进程请求从主机名向 IP 地址进行转换的用户(和系统帐户)。", + "xpack.securitySolution.eventRenderers.dnsName": "域名系统 (DNS)", + "xpack.securitySolution.eventRenderers.fileDescriptionPart1": "文件事件显示通过特定进程对文件执行 CRUD 操作的用户(和系统帐户)。", + "xpack.securitySolution.eventRenderers.fileName": "文件", + "xpack.securitySolution.eventRenderers.fimDescriptionPart1": "文件完整性模块 (FIM) 事件显示通过特定进程对文件执行 CRUD 操作的用户(和系统帐户)。", + "xpack.securitySolution.eventRenderers.fimName": "文件完整性模块 (FIM)", + "xpack.securitySolution.eventRenderers.flowDescriptionPart1": "流呈现器可视化源和目标之间的数据流。其适用于许多事件类型。", + "xpack.securitySolution.eventRenderers.flowDescriptionPart2": "可用时,将可视化主机、端口、协议、方向、持续时间、传输量、进程、地理位置和其他详情。", + "xpack.securitySolution.eventRenderers.flowName": "流", + "xpack.securitySolution.eventRenderers.processDescriptionPart1": "进程事件显示启动和停止进程的用户(和系统帐户)。", + "xpack.securitySolution.eventRenderers.processDescriptionPart2": "可用时,将显示包括命令行参数、父进程、文件哈希(如果适用)的详情。", + "xpack.securitySolution.eventRenderers.processName": "进程", + "xpack.securitySolution.eventRenderers.socketDescriptionPart1": "套接字(网络)事件显示侦听、接受和关闭连接的进程。", + "xpack.securitySolution.eventRenderers.socketDescriptionPart2": "可用时,将显示包括协议、端口和用于关联与单流相关的所有网络事件的社区 ID。", + "xpack.securitySolution.eventRenderers.socketName": "套接字(网络)", + "xpack.securitySolution.eventRenderers.suricataDescriptionPart1": "汇总", + "xpack.securitySolution.eventRenderers.suricataDescriptionPart2": "入侵检测 (IDS)、内联入侵防御 (IPS) 和网络安全监测 (NSM) 事件", + "xpack.securitySolution.eventRenderers.suricataName": "Suricata", + "xpack.securitySolution.eventRenderers.systemDescriptionPart1": "Auditbeat", + "xpack.securitySolution.eventRenderers.systemDescriptionPart2": "模块收集系统的各种安全相关信息。", + "xpack.securitySolution.eventRenderers.systemDescriptionPart3": "所有数据集发送定期状态信息(例如所有当前运行的进程)和实时更改(例如在新进程启动或停止时)。", + "xpack.securitySolution.eventRenderers.systemName": "系统", + "xpack.securitySolution.eventRenderers.zeekDescriptionPart1": "汇总该", + "xpack.securitySolution.eventRenderers.zeekDescriptionPart2": "网络安全监测 (NSM) 工具的事件", + "xpack.securitySolution.eventRenderers.zeekName": "Zeek(之前的 Bro)", + "xpack.securitySolution.eventsViewer.alerts.defaultHeaders.methodTitle": "方法", + "xpack.securitySolution.eventsViewer.alerts.defaultHeaders.riskScoreTitle": "风险分数", + "xpack.securitySolution.eventsViewer.alerts.defaultHeaders.ruleTitle": "规则", + "xpack.securitySolution.eventsViewer.alerts.defaultHeaders.severityTitle": "严重性", + "xpack.securitySolution.eventsViewer.alerts.defaultHeaders.versionTitle": "版本", "xpack.securitySolution.eventsViewer.errorFetchingEventsData": "无法查询事件数据", "xpack.securitySolution.eventsViewer.eventsLabel": "事件", "xpack.securitySolution.eventsViewer.footer.loadingEventsDataLabel": "正在加载事件", - "xpack.securitySolution.eventsViewer.showingLabel": "显示", - "xpack.securitySolution.eventsViewer.unit": "{totalCount, plural, =1 {个事件} other {个事件}}", + "xpack.securitySolution.eventsViewer.showingLabel": "正在显示", + "xpack.securitySolution.eventsViewer.unit": "{totalCount, plural, =1 {事件} other {事件}}", + "xpack.securitySolution.exceptions.addException.addException": "添加例外", + "xpack.securitySolution.exceptions.addException.bulkCloseLabel": "关闭匹配此例外中的属性的所有告警", + "xpack.securitySolution.exceptions.addException.bulkCloseLabel.disabled": "关闭匹配此例外中的属性的所有告警(不支持列表和非 ECS 字段)", + "xpack.securitySolution.exceptions.addException.cancel": "取消", + "xpack.securitySolution.exceptions.addException.endpointQuarantineText": "在任何终端上匹配选定属性的任何隔离文件将自动还原到其原始位置", + "xpack.securitySolution.exceptions.addException.error": "添加例外失败", + "xpack.securitySolution.exceptions.addException.fetchError": "提取例外列表时出错", + "xpack.securitySolution.exceptions.addException.fetchError.title": "错误", + "xpack.securitySolution.exceptions.addException.infoLabel": "满足规则的条件时生成告警,但以下情况除外:", + "xpack.securitySolution.exceptions.addException.success": "已成功添加例外", + "xpack.securitySolution.exceptions.andDescription": "且", + "xpack.securitySolution.exceptions.commentEventLabel": "已添加注释", + "xpack.securitySolution.exceptions.commentLabel": "注释", + "xpack.securitySolution.exceptions.createdByLabel": "创建者", + "xpack.securitySolution.exceptions.dateCreatedLabel": "创建日期", + "xpack.securitySolution.exceptions.detectionListLabel": "检测列表", + "xpack.securitySolution.exceptions.doesNotExistOperatorLabel": "不存在", + "xpack.securitySolution.exceptions.editButtonLabel": "编辑", + "xpack.securitySolution.exceptions.editException.bulkCloseLabel": "关闭匹配此例外中的属性的所有告警", + "xpack.securitySolution.exceptions.editException.bulkCloseLabel.disabled": "关闭匹配此例外中的属性的所有告警(不支持列表和非 ECS 字段)", + "xpack.securitySolution.exceptions.editException.cancel": "取消", + "xpack.securitySolution.exceptions.editException.editExceptionSaveButton": "保存", + "xpack.securitySolution.exceptions.editException.editExceptionTitle": "编辑例外", + "xpack.securitySolution.exceptions.editException.endpointQuarantineText": "在任何终端上匹配选定属性的任何隔离文件将自动还原到其原始位置", + "xpack.securitySolution.exceptions.editException.error": "更新例外失败", + "xpack.securitySolution.exceptions.editException.infoLabel": "满足规则的条件时生成告警,但以下情况除外:", + "xpack.securitySolution.exceptions.editException.success": "已成功更新例外", + "xpack.securitySolution.exceptions.endpointListLabel": "终端列表", + "xpack.securitySolution.exceptions.exceptionsPaginationLabel": "每页项数:{items}", + "xpack.securitySolution.exceptions.existsOperatorLabel": "存在", + "xpack.securitySolution.exceptions.fieldDescription": "字段", + "xpack.securitySolution.exceptions.hideCommentsLabel": "隐藏 ({comments}) 个{comments, plural, =1 {注释} other {注释}}", + "xpack.securitySolution.exceptions.isInListOperatorLabel": "在列表中", + "xpack.securitySolution.exceptions.isNotInListOperatorLabel": "不在列表中", + "xpack.securitySolution.exceptions.isNotOneOfOperatorLabel": "不属于", + "xpack.securitySolution.exceptions.isNotOperatorLabel": "不是", + "xpack.securitySolution.exceptions.isOneOfOperatorLabel": "属于", + "xpack.securitySolution.exceptions.isOperatorLabel": "是", + "xpack.securitySolution.exceptions.operatingSystemLabel": "OS", + "xpack.securitySolution.exceptions.operatorDescription": "运算符", + "xpack.securitySolution.exceptions.orDescription": "或", + "xpack.securitySolution.exceptions.paginationNumberOfItemsLabel": "{items} 项", + "xpack.securitySolution.exceptions.removeButtonLabel": "移除", + "xpack.securitySolution.exceptions.showCommentsLabel": "显示 ({comments}) 个{comments, plural, =1 {注释} other {注释}}", + "xpack.securitySolution.exceptions.utilityNumberExceptionsLabel": "正在显示 {items} 个{items, plural, =1 {例外} other {例外}}", + "xpack.securitySolution.exceptions.utilityRefreshLabel": "刷新", + "xpack.securitySolution.exceptions.valueDescription": "值", + "xpack.securitySolution.exceptions.viewer.addCommentPlaceholder": "添加新注释......", + "xpack.securitySolution.exceptions.viewer.addExceptionLabel": "添加新例外", + "xpack.securitySolution.exceptions.viewer.addToClipboard": "添加到剪贴板", + "xpack.securitySolution.exceptions.viewer.addToDetectionsListLabel": "添加到检测列表", + "xpack.securitySolution.exceptions.viewer.addToEndpointListLabel": "添加到终端列表", + "xpack.securitySolution.exceptions.viewer.deleteExceptionError": "删除例外时出错", + "xpack.securitySolution.exceptions.viewer.emptyPromptBody": "可以添加例外以微调规则,以便在满足例外条件时不创建检测告警。例外提升检测精确性,从而可以减少误报数。", + "xpack.securitySolution.exceptions.viewer.emptyPromptTitle": "此规则没有例外", + "xpack.securitySolution.exceptions.viewer.exceptionDetectionDetailsDescription": "此规则的所有例外将应用到检测规则,而非终端。查看{ruleSettings}以了解详情。", + "xpack.securitySolution.exceptions.viewer.exceptionDetectionDetailsDescription.ruleSettingsLink": "规则设置", + "xpack.securitySolution.exceptions.viewer.exceptionEndpointDetailsDescription": "此规则的所有例外将应用到终端和检测规则。查看{ruleSettings}以了解详情。", + "xpack.securitySolution.exceptions.viewer.exceptionEndpointDetailsDescription.ruleSettingsLink": "规则设置", + "xpack.securitySolution.exceptions.viewer.fetchingListError": "提取例外时出错", + "xpack.securitySolution.exceptions.viewer.searchDefaultPlaceholder": "搜索字段(例如:host.name)", + "xpack.securitySolution.exitFullScreenButton": "退出全屏", "xpack.securitySolution.featureCatalogue.description": "浏览安全指标和日志以了解事件和告警", - "xpack.securitySolution.featureCatalogue.title": "Security", - "xpack.securitySolution.featureRegistry.linkSecuritySolutionTitle": "Security", - "xpack.securitySolution.fieldBrowser.categoriesCountTitle": "{totalCount} {totalCount, plural, =1 {个类别} other {个类别}}", + "xpack.securitySolution.featureCatalogue.title": "安全", + "xpack.securitySolution.featureRegistry.linkSecuritySolutionTitle": "安全", + "xpack.securitySolution.fieldBrowser.categoriesCountTitle": "{totalCount} 个{totalCount, plural, =1 {类别} other {类别}}", "xpack.securitySolution.fieldBrowser.categoriesTitle": "类别", "xpack.securitySolution.fieldBrowser.categoryLabel": "类别", "xpack.securitySolution.fieldBrowser.copyToClipboard": "复制到剪贴板", "xpack.securitySolution.fieldBrowser.customizeColumnsTitle": "定制列", "xpack.securitySolution.fieldBrowser.descriptionLabel": "描述", "xpack.securitySolution.fieldBrowser.fieldLabel": "字段", - "xpack.securitySolution.fieldBrowser.fieldsCountTitle": "{totalCount} {totalCount, plural, =1 {个字段} other {个字段}}", - "xpack.securitySolution.fieldBrowser.fieldsTitle": "字段", + "xpack.securitySolution.fieldBrowser.fieldsCountTitle": "{totalCount} {totalCount, plural, =1 {字段} other {字段}}", + "xpack.securitySolution.fieldBrowser.fieldsTitle": "列", "xpack.securitySolution.fieldBrowser.filterPlaceholder": "字段名称", - "xpack.securitySolution.fieldBrowser.noFieldsMatchInputLabel": "没有字段匹配 {searchInput}", + "xpack.securitySolution.fieldBrowser.noFieldsMatchInputLabel": "没有字段匹配“{searchInput}”", "xpack.securitySolution.fieldBrowser.noFieldsMatchLabel": "没有字段匹配", "xpack.securitySolution.fieldBrowser.resetFieldsLink": "重置字段", "xpack.securitySolution.fieldBrowser.toggleColumnTooltip": "切换列", @@ -14051,11 +16636,11 @@ "xpack.securitySolution.footer.events": "事件", "xpack.securitySolution.footer.live": "实时", "xpack.securitySolution.footer.loadingLabel": "正在加载", - "xpack.securitySolution.footer.loadingTimelineData": "正在加载 Timeline 数据", + "xpack.securitySolution.footer.loadingTimelineData": "正在加载时间线数据", "xpack.securitySolution.footer.loadMoreLabel": "加载更多", - "xpack.securitySolution.footer.of": "的", + "xpack.securitySolution.footer.of": "/", "xpack.securitySolution.footer.rows": "行", - "xpack.securitySolution.footer.totalCountOfEvents": "匹配搜索条件的事件", + "xpack.securitySolution.footer.totalCountOfEvents": "个事件匹配搜索条件", "xpack.securitySolution.footer.updated": "已更新", "xpack.securitySolution.formatted.duration.aFewMillisecondsTooltip": "几毫秒", "xpack.securitySolution.formatted.duration.aFewNanosecondsTooltip": "几纳秒", @@ -14072,9 +16657,12 @@ "xpack.securitySolution.header.editableTitle.editButtonAria": "通过单击,可以编辑 {title}", "xpack.securitySolution.header.editableTitle.save": "保存", "xpack.securitySolution.headerGlobal.buttonAddData": "添加数据", - "xpack.securitySolution.headerPage.pageSubtitle": "最后事件:{beat}", + "xpack.securitySolution.headerPage.pageSubtitle": "上一事件:{beat}", "xpack.securitySolution.hooks.useAddToTimeline.addedFieldMessage": "已将 {fieldOrValue} 添加到时间线", "xpack.securitySolution.host.details.architectureLabel": "架构", + "xpack.securitySolution.host.details.endpoint.endpointPolicy": "终端策略", + "xpack.securitySolution.host.details.endpoint.policyStatus": "策略状态", + "xpack.securitySolution.host.details.endpoint.sensorversion": "感应器版本", "xpack.securitySolution.host.details.firstSeenTitle": "首次看到时间", "xpack.securitySolution.host.details.lastSeenTitle": "最后看到时间", "xpack.securitySolution.host.details.overview.cloudProviderTitle": "云服务提供商", @@ -14090,6 +16678,8 @@ "xpack.securitySolution.host.details.overview.platformTitle": "平台", "xpack.securitySolution.host.details.overview.regionTitle": "地区", "xpack.securitySolution.host.details.versionLabel": "版本", + "xpack.securitySolution.hostList.pageSubTitle": "运行 Elastic Endpoint Security 的主机", + "xpack.securitySolution.hostList.pageTitle": "主机", "xpack.securitySolution.hosts.kqlPlaceholder": "例如 host.name:“foo”", "xpack.securitySolution.hosts.navigation.alertsTitle": "外部告警", "xpack.securitySolution.hosts.navigation.allHostsTitle": "所有主机", @@ -14101,18 +16691,20 @@ "xpack.securitySolution.hosts.navigaton.matrixHistogram.errorFetchingAuthenticationsData": "无法查询身份验证数据", "xpack.securitySolution.hosts.navigaton.matrixHistogram.errorFetchingEventsData": "无法查询事件数据", "xpack.securitySolution.hosts.pageTitle": "主机", + "xpack.securitySolution.hostsTab": "主机", "xpack.securitySolution.hostsTable.firstLastSeenToolTip": "相对于选定日期范围", "xpack.securitySolution.hostsTable.hostsTitle": "所有主机", "xpack.securitySolution.hostsTable.lastSeenTitle": "最后看到时间", - "xpack.securitySolution.hostsTable.nameTitle": "名称", + "xpack.securitySolution.hostsTable.nameTitle": "主机名", "xpack.securitySolution.hostsTable.osTitle": "操作系统", "xpack.securitySolution.hostsTable.rows": "{numRows} {numRows, plural, =0 {行} =1 {行} other {行}}", - "xpack.securitySolution.hostsTable.unit": "{totalCount, plural, =1 {个主机} other {个主机}}", + "xpack.securitySolution.hostsTable.unit": "{totalCount, plural, =1 {主机} other {主机}}", "xpack.securitySolution.hostsTable.versionTitle": "版本", "xpack.securitySolution.insert.timeline.insertTimelineButton": "插入时间线链接", - "xpack.securitySolution.inspect.modal.closeTitle": "鍏抽棴", + "xpack.securitySolution.inspect.modal.closeTitle": "关闭", "xpack.securitySolution.inspect.modal.indexPatternDescription": "连接到 Elasticsearch 索引的索引模式。可以在“Kibana”>“高级设置”中配置这些索引。", "xpack.securitySolution.inspect.modal.indexPatternLabel": "索引模式", + "xpack.securitySolution.inspect.modal.noAlertIndexFound": "未找到告警索引", "xpack.securitySolution.inspect.modal.queryTimeDescription": "处理查询所花费的时间。不包括发送请求或在浏览器中解析它的时间。", "xpack.securitySolution.inspect.modal.queryTimeLabel": "查询时间", "xpack.securitySolution.inspect.modal.reqTimestampDescription": "记录请求启动的时间", @@ -14141,16 +16733,39 @@ "xpack.securitySolution.kpiNetwork.uniquePrivateIps.sourceUnitLabel": "源", "xpack.securitySolution.kpiNetwork.uniquePrivateIps.title": "唯一专用 IP", "xpack.securitySolution.licensing.unsupportedMachineLearningMessage": "您的许可证不支持 Machine Learning。请升级您的许可证。", + "xpack.securitySolution.lists.cancelValueListsUploadTitle": "取消上传", + "xpack.securitySolution.lists.closeValueListsModalTitle": "关闭", + "xpack.securitySolution.lists.detectionEngine.rules.uploadValueListsButton": "上传值列表", + "xpack.securitySolution.lists.uploadValueListDescription": "上传编写规则或规则例外时要使用的单值列表。", + "xpack.securitySolution.lists.uploadValueListPrompt": "选择或拖放文件", + "xpack.securitySolution.lists.uploadValueListTitle": "上传值列表", + "xpack.securitySolution.lists.valueListsForm.ipRadioLabel": "IP 地址", + "xpack.securitySolution.lists.valueListsForm.keywordsRadioLabel": "关键字", + "xpack.securitySolution.lists.valueListsForm.listTypesRadioLabel": "值列表类型", + "xpack.securitySolution.lists.valueListsTable.actionsColumn": "操作", + "xpack.securitySolution.lists.valueListsTable.createdByColumn": "创建者", + "xpack.securitySolution.lists.valueListsTable.deleteActionDescription": "删除值列表", + "xpack.securitySolution.lists.valueListsTable.deleteActionName": "移除", + "xpack.securitySolution.lists.valueListsTable.exportActionDescription": "导出值列表", + "xpack.securitySolution.lists.valueListsTable.exportActionName": "导出", + "xpack.securitySolution.lists.valueListsTable.fileNameColumn": "文件名", + "xpack.securitySolution.lists.valueListsTable.title": "值列表", + "xpack.securitySolution.lists.valueListsTable.uploadDateColumn": "上传数据", + "xpack.securitySolution.lists.valueListsUploadButton": "上传列表", + "xpack.securitySolution.lists.valueListsUploadError": "上传值列表时出错。", + "xpack.securitySolution.lists.valueListsUploadSuccess": "值列表“{fileName}”已上传", + "xpack.securitySolution.lists.valueListsUploadSuccessTitle": "值列表已上传", "xpack.securitySolution.markdown.hint.boldLabel": "**粗体**", "xpack.securitySolution.markdown.hint.bulletLabel": "* 项目符号", "xpack.securitySolution.markdown.hint.codeLabel": "`code`", "xpack.securitySolution.markdown.hint.headingLabel": "# 标题", - "xpack.securitySolution.markdown.hint.imageUrlLabel": "![image](url)", - "xpack.securitySolution.markdown.hint.italicsLabel": "_italics_", - "xpack.securitySolution.markdown.hint.preformattedLabel": "```preformatted```", - "xpack.securitySolution.markdown.hint.quoteLabel": ">引用", + "xpack.securitySolution.markdown.hint.imageUrlLabel": "![图](url)", + "xpack.securitySolution.markdown.hint.italicsLabel": "_斜体_", + "xpack.securitySolution.markdown.hint.preformattedLabel": "```预设格式```", + "xpack.securitySolution.markdown.hint.quoteLabel": ">引文", "xpack.securitySolution.markdown.hint.strikethroughLabel": "删除线", "xpack.securitySolution.markdown.hint.urlLabel": "[链接](url)", + "xpack.securitySolution.markdown.toolTip.timelineId": "时间线 id:{ timelineId }", "xpack.securitySolution.markdownEditor.markdown": "Markdown", "xpack.securitySolution.markdownEditor.markdownInputHelp": "Markdown 语法帮助", "xpack.securitySolution.markdownEditor.preview": "预览", @@ -14161,7 +16776,7 @@ "xpack.securitySolution.ml.score.maxAnomalyScoreTitle": "最大异常分数", "xpack.securitySolution.ml.score.narrowToThisDateRangeLink": "缩小至此日期范围", "xpack.securitySolution.ml.score.viewInMachineLearningLink": "在 Machine Learning 中查看", - "xpack.securitySolution.ml.table.detectorTitle": "作业名称", + "xpack.securitySolution.ml.table.detectorTitle": "作业", "xpack.securitySolution.ml.table.entityTitle": "实体", "xpack.securitySolution.ml.table.hostNameTitle": "主机名", "xpack.securitySolution.ml.table.influencedByTitle": "影响因素", @@ -14171,6 +16786,8 @@ "xpack.securitySolution.modalAllErrors.close.button": "关闭", "xpack.securitySolution.modalAllErrors.seeAllErrors.button": "请参阅完整的错误信息", "xpack.securitySolution.modalAllErrors.title": "您的可视化有错误", + "xpack.securitySolution.navigation.administration": "管理", + "xpack.securitySolution.navigation.alerts": "告警", "xpack.securitySolution.navigation.case": "案例", "xpack.securitySolution.navigation.detectionEngine": "检测", "xpack.securitySolution.navigation.hosts": "主机", @@ -14196,7 +16813,7 @@ "xpack.securitySolution.network.ipDetails.tlsTable.columns.issuerTitle": "颁发者", "xpack.securitySolution.network.ipDetails.tlsTable.columns.ja3FingerPrintTitle": "JA3 指纹", "xpack.securitySolution.network.ipDetails.tlsTable.columns.sha1FingerPrintTitle": "SHA1 指纹", - "xpack.securitySolution.network.ipDetails.tlsTable.columns.subjectTitle": "主题", + "xpack.securitySolution.network.ipDetails.tlsTable.columns.subjectTitle": "使用者", "xpack.securitySolution.network.ipDetails.tlsTable.columns.validUntilTitle": "失效日期", "xpack.securitySolution.network.ipDetails.tlsTable.rows": "{numRows} {numRows, plural, =0 {行} =1 {行} other {行}}", "xpack.securitySolution.network.ipDetails.tlsTable.transportLayerSecurityTitle": "传输层安全", @@ -14207,13 +16824,13 @@ "xpack.securitySolution.network.ipDetails.usersTable.columns.userIdTitle": "ID", "xpack.securitySolution.network.ipDetails.usersTable.columns.userNameTitle": "用户", "xpack.securitySolution.network.ipDetails.usersTable.rows": "{numRows} {numRows, plural, =0 {行} =1 {行} other {行}}", - "xpack.securitySolution.network.ipDetails.usersTable.unit": "{totalCount, plural, =1 {个用户} other {个用户}}", + "xpack.securitySolution.network.ipDetails.usersTable.unit": "{totalCount, plural, =1 {用户} other {用户}}", "xpack.securitySolution.network.ipDetails.usersTable.usersTitle": "用户", "xpack.securitySolution.network.kqlPlaceholder": "例如 source.ip:“foo”", "xpack.securitySolution.network.navigation.alertsTitle": "外部告警", "xpack.securitySolution.network.navigation.anomaliesTitle": "异常", "xpack.securitySolution.network.navigation.dnsTitle": "DNS", - "xpack.securitySolution.network.navigation.flowsTitle": "Flows", + "xpack.securitySolution.network.navigation.flowsTitle": "流", "xpack.securitySolution.network.navigation.httpTitle": "HTTP", "xpack.securitySolution.network.navigation.tlsTitle": "TLS", "xpack.securitySolution.network.pageTitle": "网络", @@ -14226,7 +16843,7 @@ "xpack.securitySolution.networkDnsTable.rows": "{numRows} {numRows, plural, =0 {行} =1 {行} other {行}}", "xpack.securitySolution.networkDnsTable.select.includePtrRecords": "包括 PTR 记录", "xpack.securitySolution.networkDnsTable.title": "排名靠前的 DNS 域", - "xpack.securitySolution.networkDnsTable.unit": "{totalCount, plural, =1 {个域} other {个域}}", + "xpack.securitySolution.networkDnsTable.unit": "{totalCount, plural, =1 {域} other {域}}", "xpack.securitySolution.networkHttpTable.column.domainTitle": "域", "xpack.securitySolution.networkHttpTable.column.lastHostTitle": "上一主机", "xpack.securitySolution.networkHttpTable.column.lastSourceIpTitle": "上一源 IP", @@ -14234,18 +16851,18 @@ "xpack.securitySolution.networkHttpTable.column.pathTitle": "路径", "xpack.securitySolution.networkHttpTable.column.requestsTitle": "请求", "xpack.securitySolution.networkHttpTable.column.statusTitle": "状态", - "xpack.securitySolution.networkHttpTable.rows": "{numRows} {numRows, plural, =0 {rows} =1 {行} other {行}}", + "xpack.securitySolution.networkHttpTable.rows": "{numRows} {numRows, plural, =0 {行} =1 {行} other {行}}", "xpack.securitySolution.networkHttpTable.title": "HTTP 请求", - "xpack.securitySolution.networkHttpTable.unit": "{totalCount, plural, =1 {个请求} other {个请求}}", + "xpack.securitySolution.networkHttpTable.unit": "{totalCount, plural, =1 {请求} other {请求}}", "xpack.securitySolution.networkTopCountriesTable.column.bytesInTitle": "传入字节", "xpack.securitySolution.networkTopCountriesTable.column.bytesOutTitle": "传出字节", "xpack.securitySolution.networkTopCountriesTable.column.countryTitle": "国家/地区", "xpack.securitySolution.networkTopCountriesTable.column.destinationIps": "目标 IP", - "xpack.securitySolution.networkTopCountriesTable.column.flows": "Flows", + "xpack.securitySolution.networkTopCountriesTable.column.flows": "流", "xpack.securitySolution.networkTopCountriesTable.column.sourceIps": "源 IP", "xpack.securitySolution.networkTopCountriesTable.heading.destinationCountries": "目标国家/地区", "xpack.securitySolution.networkTopCountriesTable.heading.sourceCountries": "源国家/地区", - "xpack.securitySolution.networkTopCountriesTable.heading.unit": "{totalCount, plural, =1 {个国家或地区} other {个国家或地区}}", + "xpack.securitySolution.networkTopCountriesTable.heading.unit": "{totalCount, plural, =1 {国家或地区} other {国家或地区}}", "xpack.securitySolution.networkTopCountriesTable.rows": "{numRows} {numRows, plural, =0 {行} =1 {行} other {行}}", "xpack.securitySolution.networkTopNFlowTable.column.asTitle": "自治系统", "xpack.securitySolution.networkTopNFlowTable.column.bytesInTitle": "传入字节", @@ -14255,18 +16872,18 @@ "xpack.securitySolution.networkTopNFlowTable.column.IpTitle": "IP", "xpack.securitySolution.networkTopNFlowTable.column.sourceIpTitle": "源 IP", "xpack.securitySolution.networkTopNFlowTable.destinationIps": "目标 IP", - "xpack.securitySolution.networkTopNFlowTable.flows": "Flows", + "xpack.securitySolution.networkTopNFlowTable.flows": "流", "xpack.securitySolution.networkTopNFlowTable.rows": "{numRows} {numRows, plural, =0 {行} =1 {行} other {行}}", "xpack.securitySolution.networkTopNFlowTable.sourceIps": "源 IP", - "xpack.securitySolution.networkTopNFlowTable.unit": "{totalCount, plural, =1 {个 IP} other {个 IP}}", - "xpack.securitySolution.newsFeed.advancedSettingsLinkTitle": "Security 高级设置", + "xpack.securitySolution.networkTopNFlowTable.unit": "{totalCount, plural, =1 {IP} other {IP}}", + "xpack.securitySolution.newsFeed.advancedSettingsLinkTitle": "SIEM 高级设置", "xpack.securitySolution.newsFeed.noNewsMessage": "您当前的新闻源 URL 未返回最近的新闻。要更新 URL 或禁用安全新闻,您可以通过", "xpack.securitySolution.notes.addANotePlaceholder": "添加备注", "xpack.securitySolution.notes.addedANoteLabel": "已添加备注", "xpack.securitySolution.notes.addNoteButtonLabel": "添加备注", "xpack.securitySolution.notes.cancelButtonLabel": "取消", "xpack.securitySolution.notes.copyToClipboardButtonLabel": "复制到剪贴板", - "xpack.securitySolution.notes.noteLabel": "注释", + "xpack.securitySolution.notes.noteLabel": "备注", "xpack.securitySolution.notes.notesTitle": "备注", "xpack.securitySolution.notes.previewMarkdownTitle": "预览 (Markdown)", "xpack.securitySolution.notes.search.FilterByUserOrNotePlaceholder": "按用户或备注筛选", @@ -14274,14 +16891,16 @@ "xpack.securitySolution.open.timeline.batchActionsTitle": "批处理操作", "xpack.securitySolution.open.timeline.cancelButton": "取消", "xpack.securitySolution.open.timeline.collapseButton": "折叠", + "xpack.securitySolution.open.timeline.createTemplateFromTimelineTooltip": "从时间线创建模板", + "xpack.securitySolution.open.timeline.createTimelineFromTemplateTooltip": "从模板创建时间线", "xpack.securitySolution.open.timeline.deleteButton": "删除", - "xpack.securitySolution.open.timeline.deleteSelectedButton": "删除选定", + "xpack.securitySolution.open.timeline.deleteSelectedButton": "删除所选", "xpack.securitySolution.open.timeline.deleteTimelineModalTitle": "删除“{title}”?", "xpack.securitySolution.open.timeline.deleteWarningLabel": "一旦删除,将无法恢复此时间线或其备注。", "xpack.securitySolution.open.timeline.descriptionTableHeader": "描述", "xpack.securitySolution.open.timeline.expandButton": "展开", "xpack.securitySolution.open.timeline.exportFileNameTitle": "timelines_export", - "xpack.securitySolution.open.timeline.exportSelectedButton": "导出选定", + "xpack.securitySolution.open.timeline.exportSelectedButton": "导出所选", "xpack.securitySolution.open.timeline.favoriteSelectedButton": "收藏所选", "xpack.securitySolution.open.timeline.favoritesTooltip": "收藏夹", "xpack.securitySolution.open.timeline.filterByTimelineTypesTitle": "仅 {timelineType}", @@ -14290,21 +16909,30 @@ "xpack.securitySolution.open.timeline.modifiedByTableHeader": "修改者", "xpack.securitySolution.open.timeline.notesTooltip": "备注", "xpack.securitySolution.open.timeline.onlyFavoritesButtonLabel": "仅收藏夹", + "xpack.securitySolution.open.timeline.openAsDuplicateTemplateTooltip": "复制模板", "xpack.securitySolution.open.timeline.openAsDuplicateTooltip": "复制时间线", "xpack.securitySolution.open.timeline.openTimelineButton": "打开时间线......", "xpack.securitySolution.open.timeline.openTimelineTitle": "打开时间线", "xpack.securitySolution.open.timeline.pinnedEventsTooltip": "置顶事件", + "xpack.securitySolution.open.timeline.pluralTemplatesLabel": "模板", + "xpack.securitySolution.open.timeline.pluralTimelinesLabel": "时间线", "xpack.securitySolution.open.timeline.postedLabel": "已发表:", "xpack.securitySolution.open.timeline.refreshTitle": "刷新", "xpack.securitySolution.open.timeline.searchPlaceholder": "例如时间线名称或描述", + "xpack.securitySolution.open.timeline.searchTemplatePlaceholder": "例如模板名称或描述", + "xpack.securitySolution.open.timeline.selectedTemplatesTitle": "已选择 {selectedTemplates} 个{selectedTemplates, plural, =1 {模板} other {模板}}", "xpack.securitySolution.open.timeline.selectedTimelinesTitle": "已选择 {selectedTimelines} 条{selectedTimelines, plural, =1 {时间线} other {时间线}}", "xpack.securitySolution.open.timeline.showingLabel": "正在显示:", - "xpack.securitySolution.open.timeline.showingNTimelinesLabel": "{totalSearchResultsCount} 条 {totalSearchResultsCount, plural, one {时间线} other {时间线}} {with}", + "xpack.securitySolution.open.timeline.showingNTemplatesLabel": "{totalSearchResultsCount} 个{totalSearchResultsCount, plural, one {模板} other {模板}} {with}", + "xpack.securitySolution.open.timeline.showingNTimelinesLabel": "{totalSearchResultsCount} 条{totalSearchResultsCount, plural, one {时间线} other {时间线}} {with}", + "xpack.securitySolution.open.timeline.singleTemplateLabel": "模板", + "xpack.securitySolution.open.timeline.singleTimelineLabel": "时间线", "xpack.securitySolution.open.timeline.successfullyExportedTimelinesTitle": "已成功导出{totalTimelines, plural, =0 {全部时间线} =1 { {totalTimelines} 条时间线} other { {totalTimelines} 条时间线}}", "xpack.securitySolution.open.timeline.timelineNameTableHeader": "时间线名称", + "xpack.securitySolution.open.timeline.timelineTemplateNameTableHeader": "模板名称", "xpack.securitySolution.open.timeline.untitledTimelineLabel": "未命名时间线", "xpack.securitySolution.open.timeline.withLabel": "具有", - "xpack.securitySolution.open.timeline.zeroTimelinesMatchLabel": "0 个时间线匹配搜索条件", + "xpack.securitySolution.open.timeline.zeroTimelinesMatchLabel": "0 条时间线匹配搜索条件", "xpack.securitySolution.overview.auditBeatAuditTitle": "审计", "xpack.securitySolution.overview.auditBeatFimTitle": "文件完整性模块", "xpack.securitySolution.overview.auditBeatLoginTitle": "登录", @@ -14318,9 +16946,14 @@ "xpack.securitySolution.overview.endgameNetworkTitle": "网络", "xpack.securitySolution.overview.endgameProcessTitle": "进程", "xpack.securitySolution.overview.endgameRegistryTitle": "注册表", - "xpack.securitySolution.overview.endgameSecurityTitle": "安全性", + "xpack.securitySolution.overview.endgameSecurityTitle": "安全", + "xpack.securitySolution.overview.endpointNotice.dismiss": "关闭消息", + "xpack.securitySolution.overview.endpointNotice.introducing": "即将引入: ", + "xpack.securitySolution.overview.endpointNotice.message": "使用威胁防御、检测和深度安全数据可见性来保护您的主机。", + "xpack.securitySolution.overview.endpointNotice.title": "Elastic Endpoint Security 公测版", + "xpack.securitySolution.overview.endpointNotice.tryButton": "试用 Elastic Endpoint Security 公测版", "xpack.securitySolution.overview.eventsTitle": "事件计数", - "xpack.securitySolution.overview.feedbackText": "如果您对 Elastic Security 体验有任何建议,请随时{feedback}。", + "xpack.securitySolution.overview.feedbackText": "如果您对 Elastic SIEM 体验有任何建议,请随时{feedback}。", "xpack.securitySolution.overview.feedbackText.feedbackLinkText": "在线提交反馈", "xpack.securitySolution.overview.feedbackTitle": "反馈", "xpack.securitySolution.overview.filebeatCiscoTitle": "Cisco", @@ -14348,29 +16981,36 @@ "xpack.securitySolution.overview.packetBeatFlowTitle": "流", "xpack.securitySolution.overview.packetbeatTLSTitle": "TLS", "xpack.securitySolution.overview.pageSubtitle": "Elastic Stack 的安全信息和事件管理功能", - "xpack.securitySolution.overview.pageTitle": "Security", + "xpack.securitySolution.overview.pageTitle": "安全", "xpack.securitySolution.overview.recentCasesSidebarTitle": "最近案例", "xpack.securitySolution.overview.recentlyCreatedCasesButtonLabel": "最近创建的案例", "xpack.securitySolution.overview.recentTimelinesSidebarTitle": "最近的时间线", - "xpack.securitySolution.overview.showTopTooltip": "显示热门{fieldName}", - "xpack.securitySolution.overview.startedText": "欢迎使用安全信息和事件管理 (Security)。首先,查看我们的 {docs} 或 {data}。有关即将推出的功能和教程,确保查看我们的{siemSolution}页。", + "xpack.securitySolution.overview.showTopTooltip": "显示排名靠前的{fieldName}", + "xpack.securitySolution.overview.signalCountTitle": "检测告警趋势", + "xpack.securitySolution.overview.startedText": "欢迎使用安全信息和事件管理 (SIEM)。首先阅读我们的{docs}或{data}。要了解即将推出的功能和教程,请访问我们的 {siemSolution}页面。", "xpack.securitySolution.overview.startedText.dataLinkText": "正在采集数据", "xpack.securitySolution.overview.startedText.docsLinkText": "文档", - "xpack.securitySolution.overview.startedText.siemSolutionLinkText": "Security 解决方案", + "xpack.securitySolution.overview.startedText.siemSolutionLinkText": "SIEM 解决方案", "xpack.securitySolution.overview.startedTitle": "入门", - "xpack.securitySolution.overview.topNLabel": "热门{fieldName}", + "xpack.securitySolution.overview.topNLabel": "排名靠前的{fieldName}", "xpack.securitySolution.overview.viewAlertsButtonLabel": "查看告警", "xpack.securitySolution.overview.viewEventsButtonLabel": "查看事件", "xpack.securitySolution.overview.winlogbeatMWSysmonOperational": "Microsoft-Windows-Sysmon/Operational", "xpack.securitySolution.overview.winlogbeatSecurityTitle": "安全", - "xpack.securitySolution.pages.common.emptyActionPrimary": "使用 Beats 添加数据", - "xpack.securitySolution.pages.common.emptyActionSecondary": "查看入门指南", - "xpack.securitySolution.pages.common.emptyTitle": "欢迎使用 SIEM。让我们教您如何入门。", + "xpack.securitySolution.pages.common.emptyActionEndpoint": "使用 Elastic 代理添加数据(公测版)", + "xpack.securitySolution.pages.common.emptyActionSecondary": "入门指南。", + "xpack.securitySolution.pages.common.emptyTitle": "欢迎使用安全解决方案。让我们教您如何入门。", "xpack.securitySolution.pages.fourohfour.noContentFoundDescription": "未找到任何内容", "xpack.securitySolution.paginatedTable.rowsButtonLabel": "每页行数", - "xpack.securitySolution.paginatedTable.showingSubtitle": "显示", + "xpack.securitySolution.paginatedTable.showingSubtitle": "正在显示", "xpack.securitySolution.paginatedTable.tooManyResultsToastText": "缩减您的查询范围,以更好地筛选结果", "xpack.securitySolution.paginatedTable.tooManyResultsToastTitle": " - 结果过多", + "xpack.securitySolution.policiesTab": "策略", + "xpack.securitySolution.policyList.pageSubTitle": "查看并配置防护", + "xpack.securitySolution.policyList.pageTitle": "策略", + "xpack.securitySolution.policyStatusText.failure": "失败", + "xpack.securitySolution.policyStatusText.success": "成功", + "xpack.securitySolution.policyStatusText.warning": "警告", "xpack.securitySolution.recentCases.commentsTooltip": "注释", "xpack.securitySolution.recentCases.noCasesMessage": "尚未创建任何案例。以侦探的眼光", "xpack.securitySolution.recentCases.startNewCaseLink": "建立新案例", @@ -14381,21 +17021,23 @@ "xpack.securitySolution.recentTimelines.noFavoriteTimelinesMessage": "您尚未收藏任何时间线。实际操练一下,开始狩猎威胁!", "xpack.securitySolution.recentTimelines.notesTooltip": "备注", "xpack.securitySolution.recentTimelines.noTimelinesMessage": "您尚未创建任何时间线。实际操练一下,开始狩猎威胁!", + "xpack.securitySolution.recentTimelines.openAsDuplicateTemplateTooltip": "作为模板副本打开", "xpack.securitySolution.recentTimelines.openAsDuplicateTooltip": "作为时间线副本打开", "xpack.securitySolution.recentTimelines.pinnedEventsTooltip": "置顶事件", "xpack.securitySolution.recentTimelines.untitledTimelineLabel": "未命名时间线", "xpack.securitySolution.recentTimelines.viewAllTimelinesLink": "查看所有时间线", + "xpack.securitySolution.security.title": "安全", "xpack.securitySolution.source.destination.packetsLabel": "pkts", - "xpack.securitySolution.system.acceptedAConnectionViaDescription": "已接受连接,通过", + "xpack.securitySolution.system.acceptedAConnectionViaDescription": "已接受连接 - 通过", "xpack.securitySolution.system.acceptedDescription": "已接受该用户 - 通过", "xpack.securitySolution.system.attemptedLoginDescription": "已尝试登录 - 通过", "xpack.securitySolution.system.createdFileDescription": "已创建文件", "xpack.securitySolution.system.deletedFileDescription": "已删除文件", - "xpack.securitySolution.system.disconnectedViaDescription": "已断开连接,通过", + "xpack.securitySolution.system.disconnectedViaDescription": "已断开连接 - 通过", "xpack.securitySolution.system.errorDescription": "遇到错误 -", "xpack.securitySolution.system.existingPackageDescription": "正在使用现有软件包", "xpack.securitySolution.system.existingProcessDescription": "正在运行进程", - "xpack.securitySolution.system.existingSocketDescription": "正在使用现有套接字 - 来自", + "xpack.securitySolution.system.existingSocketDescription": "正在使用现有套接字,其来自", "xpack.securitySolution.system.existingUserDescription": "是现有用户", "xpack.securitySolution.system.hostDescription": "主机信息", "xpack.securitySolution.system.invalidDescription": "已尝试无效使用", @@ -14414,7 +17056,7 @@ "xpack.securitySolution.system.userAddedDescription": "用户已添加", "xpack.securitySolution.system.userChangedDescription": "用户已更改", "xpack.securitySolution.system.userRemovedDescription": "已移除", - "xpack.securitySolution.system.usingDescription": "使用", + "xpack.securitySolution.system.usingDescription": "正在使用", "xpack.securitySolution.system.viaDescription": "通过", "xpack.securitySolution.system.viaParentProcessDescription": "通过父进程", "xpack.securitySolution.system.wasAuthorizedToUseDescription": "有权使用", @@ -14425,12 +17067,16 @@ "xpack.securitySolution.timeline.autosave.warning.refresh.title": "刷新时间线", "xpack.securitySolution.timeline.autosave.warning.title": "刷新后才会启用自动保存", "xpack.securitySolution.timeline.body.actions.collapseAriaLabel": "折叠", + "xpack.securitySolution.timeline.body.actions.collapseEventTooltip": "折叠事件", "xpack.securitySolution.timeline.body.actions.expandAriaLabel": "展开", + "xpack.securitySolution.timeline.body.actions.investigateInResolverTooltip": "分析事件", "xpack.securitySolution.timeline.body.copyToClipboardButtonLabel": "复制到剪贴板", - "xpack.securitySolution.timeline.body.notes.addOrViewNotesForThisEventTooltip": "添加或查看此事件的备注", + "xpack.securitySolution.timeline.body.notes.addOrViewNotesForThisEventTooltip": "为此事件添加备注", + "xpack.securitySolution.timeline.body.notes.disableEventTooltip": "编辑模板时间线时无法在此处添加备注", + "xpack.securitySolution.timeline.body.pinning.disablePinnnedTooltip": "编辑模板时间线时无法置顶此事件", "xpack.securitySolution.timeline.body.pinning.pinnedTooltip": "置顶事件", - "xpack.securitySolution.timeline.body.pinning.pinnnedWithNotesTooltip": "此事件无法固定,因为其有备注", - "xpack.securitySolution.timeline.body.pinning.unpinnedTooltip": "非置顶事件", + "xpack.securitySolution.timeline.body.pinning.pinnnedWithNotesTooltip": "此事件无法取消置顶,因为其有备注", + "xpack.securitySolution.timeline.body.pinning.unpinnedTooltip": "取消置顶的事件", "xpack.securitySolution.timeline.body.renderers.dns.askedForDescription": "请求过", "xpack.securitySolution.timeline.body.renderers.dns.responseCodeDescription": "响应代码:", "xpack.securitySolution.timeline.body.renderers.dns.viaDescription": "通过", @@ -14455,62 +17101,75 @@ "xpack.securitySolution.timeline.body.renderers.endgame.usingLogonTypeDescription": "使用登录类型", "xpack.securitySolution.timeline.body.renderers.endgame.viaDescription": "通过", "xpack.securitySolution.timeline.body.renderers.endgame.withSpecialPrivilegesDescription": "使用特殊权限,", - "xpack.securitySolution.timeline.callOut.unauthorized.message.description": "您需要在 Security 内自动保存时间线的权限,但您可以继续使用该时间线搜索和筛选安全事件", + "xpack.securitySolution.timeline.body.sort.sortedAscendingTooltip": "已升序", + "xpack.securitySolution.timeline.body.sort.sortedDescendingTooltip": "已降序", + "xpack.securitySolution.timeline.callOut.immutable.message.description": "此时间线不可变,因此不允许在 Security 应用程序中进行保存,但您可以继续使用该时间线搜索并筛选安全事件", + "xpack.securitySolution.timeline.callOut.unauthorized.message.description": "可以使用“时间线”调查事件,但您没有所需的权限来保存时间线以供将来使用。如果需要保存时间线,请联系您的 Kibana 管理员。", "xpack.securitySolution.timeline.categoryTooltip": "类别", - "xpack.securitySolution.timeline.defaultTimelineDescription": "创建新时间线时默认提供的时间线。", - "xpack.securitySolution.timeline.defaultTimelineTitle": "默认空白时间线", + "xpack.securitySolution.timeline.defaultTimelineDescription": "创建新的时间线时默认提供的时间线。", + "xpack.securitySolution.timeline.defaultTimelineTitle": "无", "xpack.securitySolution.timeline.descriptionTooltip": "描述", "xpack.securitySolution.timeline.destination": "目标", - "xpack.securitySolution.timeline.eventsSelect.actions.pinSelected": "固定所选", + "xpack.securitySolution.timeline.eventsSelect.actions.pinSelected": "置顶所选", "xpack.securitySolution.timeline.eventsSelect.actions.selectAll": "全部", "xpack.securitySolution.timeline.eventsSelect.actions.selectNone": "无", - "xpack.securitySolution.timeline.eventsSelect.actions.selectPinned": "已固定", - "xpack.securitySolution.timeline.eventsSelect.actions.selectUnpinned": "取消固定", - "xpack.securitySolution.timeline.eventsSelect.actions.unpinSelected": "取消固定所选", + "xpack.securitySolution.timeline.eventsSelect.actions.selectPinned": "已置顶", + "xpack.securitySolution.timeline.eventsSelect.actions.selectUnpinned": "已取消置顶", + "xpack.securitySolution.timeline.eventsSelect.actions.unpinSelected": "取消置顶所选", "xpack.securitySolution.timeline.expandableEvent.copyToClipboardToolTip": "复制到剪贴板", - "xpack.securitySolution.timeline.expandableEvent.eventToolTipTitle": "时间", + "xpack.securitySolution.timeline.expandableEvent.eventToolTipTitle": "事件", "xpack.securitySolution.timeline.fieldTooltip": "字段", "xpack.securitySolution.timeline.flyout.header.closeTimelineButtonLabel": "关闭时间线", - "xpack.securitySolution.timeline.flyout.pane.removeColumnButtonLabel": "删除列", + "xpack.securitySolution.timeline.flyout.pane.removeColumnButtonLabel": "移除列", "xpack.securitySolution.timeline.flyout.pane.timelinePropertiesAriaLabel": "时间线属性", + "xpack.securitySolution.timeline.flyoutTimelineTemplateLabel": "时间线模板", + "xpack.securitySolution.timeline.fullScreenButton": "全屏", + "xpack.securitySolution.timeline.graphOverlay.backToEventsButton": "< 返回至事件", + "xpack.securitySolution.timeline.properties.attachToExistingCaseButtonLabel": "附加到现有案例......", + "xpack.securitySolution.timeline.properties.attachToNewCaseButtonLabel": "附加到新案例", "xpack.securitySolution.timeline.properties.descriptionPlaceholder": "描述", - "xpack.securitySolution.timeline.properties.descriptionTooltip": "此时间线中事件和备注的摘要", + "xpack.securitySolution.timeline.properties.descriptionTooltip": "此时间线中的事件和备注摘要", + "xpack.securitySolution.timeline.properties.existingCaseButtonLabel": "将时间线附加到现有案例......", "xpack.securitySolution.timeline.properties.favoriteTooltip": "收藏", "xpack.securitySolution.timeline.properties.historyLabel": "历史记录", - "xpack.securitySolution.timeline.properties.historyToolTip": "与此时间线相关的操作历史记录(按时间顺序排列)", - "xpack.securitySolution.timeline.properties.inspectTimelineTitle": "鏃堕棿绾", + "xpack.securitySolution.timeline.properties.historyToolTip": "按时间顺序排列的与此时间线相关的操作历史记录", + "xpack.securitySolution.timeline.properties.inspectTimelineTitle": "时间线", "xpack.securitySolution.timeline.properties.isViewingTooltip": "正在查看此时间线", "xpack.securitySolution.timeline.properties.lockDatePickerDescription": "将日期选取器锁定到全局日期选取器", - "xpack.securitySolution.timeline.properties.lockDatePickerTooltip": "禁用当前查看的页面和您的时间线之间的日期/时间范围同步", + "xpack.securitySolution.timeline.properties.lockDatePickerTooltip": "禁用当前查看的页面与您的时间线之间的日期/时间范围同步", "xpack.securitySolution.timeline.properties.newCaseButtonLabel": "将时间线附加到新案例", - "xpack.securitySolution.timeline.properties.newTimelineButtonLabel": "创建新的时间线", + "xpack.securitySolution.timeline.properties.newTemplateTimelineButtonLabel": "创建新时间线模板", + "xpack.securitySolution.timeline.properties.newTimelineButtonLabel": "创建新时间线", "xpack.securitySolution.timeline.properties.notAFavoriteTooltip": "取消收藏", "xpack.securitySolution.timeline.properties.notesButtonLabel": "备注", - "xpack.securitySolution.timeline.properties.notesToolTip": "添加并复查此时间线的备注。也可以向事件添加备注。", + "xpack.securitySolution.timeline.properties.notesToolTip": "添加并审核此时间线的备注。也可以向事件添加备注。", "xpack.securitySolution.timeline.properties.streamLiveButtonLabel": "实时流式传输", "xpack.securitySolution.timeline.properties.streamLiveToolTip": "新数据到达时更新时间线", "xpack.securitySolution.timeline.properties.timelineDescription": "时间线描述", "xpack.securitySolution.timeline.properties.timelineTitleAriaLabel": "时间线标题", "xpack.securitySolution.timeline.properties.titleTitle": "标题", - "xpack.securitySolution.timeline.properties.unlockDatePickerDescription": "从全局日期选取器解除锁定日期选取器", - "xpack.securitySolution.timeline.properties.unlockDatePickerTooltip": "启用当前查看的页面和您的时间线之间的日期/时间范围同步", + "xpack.securitySolution.timeline.properties.unlockDatePickerDescription": "解除日期选取器与全局日期选取器的锁定", + "xpack.securitySolution.timeline.properties.unlockDatePickerTooltip": "启用当前查看的页面与您的时间线之间的日期/时间范围同步", + "xpack.securitySolution.timeline.properties.untitledTemplatePlaceholder": "未命名模板", "xpack.securitySolution.timeline.properties.untitledTimelinePlaceholder": "未命名时间线", "xpack.securitySolution.timeline.protocol": "协议", - "xpack.securitySolution.timeline.rangePicker.oneDay": "1 日", + "xpack.securitySolution.timeline.rangePicker.oneDay": "1 天", "xpack.securitySolution.timeline.rangePicker.oneMonth": "1 个月", "xpack.securitySolution.timeline.rangePicker.oneWeek": "1 周", "xpack.securitySolution.timeline.rangePicker.oneYear": "1 年", - "xpack.securitySolution.timeline.searchOrFilter.eventTypeAllEvent": "所有事件", + "xpack.securitySolution.timeline.searchBoxPlaceholder": "例如 {timeline} 名称或描述", + "xpack.securitySolution.timeline.searchOrFilter.eventTypeAllEvent": "全部", + "xpack.securitySolution.timeline.searchOrFilter.eventTypeDetectionAlertsEvent": "检测告警", "xpack.securitySolution.timeline.searchOrFilter.eventTypeRawEvent": "原始事件", - "xpack.securitySolution.timeline.searchOrFilter.filterDescription": "来自上述数据提供程序的事件按相邻 KQL 进行筛选", + "xpack.securitySolution.timeline.searchOrFilter.filterDescription": "上述数据提供程序的事件按相邻 KQL 进行筛选", "xpack.securitySolution.timeline.searchOrFilter.filterKqlPlaceholder": "筛选事件", "xpack.securitySolution.timeline.searchOrFilter.filterKqlSelectedText": "筛选", - "xpack.securitySolution.timeline.searchOrFilter.filterKqlTooltip": "来自上述数据提供程序的事件按此 KQL 进行筛选", + "xpack.securitySolution.timeline.searchOrFilter.filterKqlTooltip": "上述数据提供程序的事件按此 KQL 进行筛选", "xpack.securitySolution.timeline.searchOrFilter.filterOrSearchWithKql": "使用 KQL 筛选或搜索", - "xpack.securitySolution.timeline.searchOrFilter.searchDescription": "来自上述数据提供程序的事件与来自相邻 KQL 的结果合并", + "xpack.securitySolution.timeline.searchOrFilter.searchDescription": "上述数据提供程序的事件与相邻 KQL 的结果进行组合", "xpack.securitySolution.timeline.searchOrFilter.searchKqlPlaceholder": "搜索事件", "xpack.securitySolution.timeline.searchOrFilter.searchKqlSelectedText": "搜索", - "xpack.securitySolution.timeline.searchOrFilter.searchKqlTooltip": "来自上述数据提供程序的事件与来自此 KQL 的结果合并", + "xpack.securitySolution.timeline.searchOrFilter.searchKqlTooltip": "上述数据提供程序的事件与此 KQL 的结果进行组合", "xpack.securitySolution.timeline.source": "源", "xpack.securitySolution.timeline.tcp": "TCP", "xpack.securitySolution.timeline.typeTooltip": "类型", @@ -14521,44 +17180,49 @@ "xpack.securitySolution.timelines.components.importTimelineModal.importFailedTitle": "无法导入时间线", "xpack.securitySolution.timelines.components.importTimelineModal.importTimelineTitle": "导入时间线", "xpack.securitySolution.timelines.components.importTimelineModal.importTitle": "导入时间线……", - "xpack.securitySolution.timelines.components.importTimelineModal.initialPromptTextDescription": "选择或拖放有效的 rules_export.ndjson 文件", - "xpack.securitySolution.timelines.components.importTimelineModal.overwriteDescription": "自动覆盖具有相同时间线 ID 的已保存对象", - "xpack.securitySolution.timelines.components.importTimelineModal.selectTimelineDescription": "选择要导入的 Security 时间线(如从“时间线”视图导出的)", - "xpack.securitySolution.timelines.components.importTimelineModal.successfullyImportedTimelinesTitle": "已成功导入 {totalCount} 条{totalCount, plural, =1 {时间线} other {时间线}}", + "xpack.securitySolution.timelines.components.importTimelineModal.initialPromptTextDescription": "搜索或拖放有效的 timelines_export.ndjson 文件", + "xpack.securitySolution.timelines.components.importTimelineModal.overwriteDescription": "自动覆盖时间线 ID 相同的已保存对象", + "xpack.securitySolution.timelines.components.importTimelineModal.selectTimelineDescription": "选择 Security 时间线(格式如从“时间线”视图导出的格式)以进行导入", + "xpack.securitySolution.timelines.components.importTimelineModal.successfullyImportedTimelinesTitle": "已成功导入 {totalCount} 个{totalCount, plural, =1 {时间线} other {时间线}}", "xpack.securitySolution.timelines.components.tabs.templatesTitle": "模板", "xpack.securitySolution.timelines.components.tabs.timelinesTitle": "时间线", + "xpack.securitySolution.timelines.components.templateFilter.customizedTitle": "定制模板", + "xpack.securitySolution.timelines.components.templateFilter.elasticTitle": "Elastic 模板", "xpack.securitySolution.timelines.pageTitle": "时间线", + "xpack.securitySolution.timelines.updateTimelineErrorText": "出问题了", + "xpack.securitySolution.timelines.updateTimelineErrorTitle": "时间线错误", + "xpack.securitySolution.topN.alertEventsSelectLabel": "告警事件", "xpack.securitySolution.topN.allEventsSelectLabel": "所有事件", "xpack.securitySolution.topN.closeButtonLabel": "关闭", "xpack.securitySolution.topN.rawEventsSelectLabel": "原始事件", - "xpack.securitySolution.uiSettings.defaultAnomalyScoreDescription": "

      在显示异常之前要超过的默认异常分数阈值。

      有效值:0 到 100。

      ", - "xpack.securitySolution.uiSettings.defaultAnomalyScoreLabel": "默认异常阈值", - "xpack.securitySolution.uiSettings.defaultIndexDescription": "

      Security 应用要从其中搜索事件的 Elasticsearch 索引逗号分隔列表。

      ", - "xpack.securitySolution.uiSettings.defaultIndexLabel": "默认索引", + "xpack.securitySolution.uiSettings.defaultAnomalyScoreDescription": "

      要在 Security 应用中显示的 Machine Learning 作业异常所需超过的值。

      有效值:0 到 100。

      ", + "xpack.securitySolution.uiSettings.defaultAnomalyScoreLabel": "异常阈值", + "xpack.securitySolution.uiSettings.defaultIndexDescription": "

      Security 应用要从中收集事件的 Elasticsearch 索引逗号分隔列表。

      ", + "xpack.securitySolution.uiSettings.defaultIndexLabel": "Elasticsearch 索引", "xpack.securitySolution.uiSettings.defaultRefreshIntervalDescription": "

      Security 时间筛选的默认刷新时间间隔(毫秒)。

      ", "xpack.securitySolution.uiSettings.defaultRefreshIntervalLabel": "时间筛选刷新时间间隔", - "xpack.securitySolution.uiSettings.defaultTimeRangeDescription": "

      Security 时间筛选中的默认时间期间。

      ", - "xpack.securitySolution.uiSettings.defaultTimeRangeLabel": "时间筛选默认值", + "xpack.securitySolution.uiSettings.defaultTimeRangeDescription": "

      Security 时间筛选中的默认时段。

      ", + "xpack.securitySolution.uiSettings.defaultTimeRangeLabel": "时间筛选时段", "xpack.securitySolution.uiSettings.enableNewsFeedDescription": "

      启用新闻源

      ", "xpack.securitySolution.uiSettings.enableNewsFeedLabel": "新闻源", "xpack.securitySolution.uiSettings.ipReputationLinks": "IP 信誉链接", - "xpack.securitySolution.uiSettings.ipReputationLinksDescription": "用于构建要显示在“IP 详细信息”页面上的信誉 URL 列表的 URL 模板数组。", + "xpack.securitySolution.uiSettings.ipReputationLinksDescription": "用于构建要在“IP 详细信息”页面上显示的信誉 URL 列表的 URL 模板数组。", "xpack.securitySolution.uiSettings.newsFeedUrl": "新闻源 URL", "xpack.securitySolution.uiSettings.newsFeedUrlDescription": "

      将从此 URL 检索新闻源内容

      ", - "xpack.securitySolution.uncommonProcessTable.hostsTitle": "主机", + "xpack.securitySolution.uncommonProcessTable.hostsTitle": "主机名", "xpack.securitySolution.uncommonProcessTable.lastCommandTitle": "上一命令", "xpack.securitySolution.uncommonProcessTable.lastUserTitle": "上一用户", - "xpack.securitySolution.uncommonProcessTable.nameTitle": "名称", - "xpack.securitySolution.uncommonProcessTable.numberOfHostsTitle": "主机数目", + "xpack.securitySolution.uncommonProcessTable.nameTitle": "进程名称", + "xpack.securitySolution.uncommonProcessTable.numberOfHostsTitle": "主机", "xpack.securitySolution.uncommonProcessTable.numberOfInstances": "实例", "xpack.securitySolution.uncommonProcessTable.rows": "{numRows} {numRows, plural, =0 {行} =1 {行} other {行}}", - "xpack.securitySolution.uncommonProcessTable.unit": "{totalCount, plural, =1 {个进程} other {个进程}}", + "xpack.securitySolution.uncommonProcessTable.unit": "{totalCount, plural, =1 {进程} other {进程}}", "xpack.securitySolution.zeek.othDescription": "未看到 SYN,仅中游流量", "xpack.securitySolution.zeek.rejDescription": "已拒绝连接尝试", "xpack.securitySolution.zeek.rstoODescription": "连接已建立,发起方已中止(已发送 RST)", "xpack.securitySolution.zeek.rstosoDescription": "发起方已发送 SYN,后跟 RST,响应方未发送 SYN-ACK", "xpack.securitySolution.zeek.rstrDescription": "已建立,响应方已中止", - "xpack.securitySolution.zeek.rstrhDescription": "响应方已发送 SYN ACK,后跟 RST,(假设)发起方未发送 SYN", + "xpack.securitySolution.zeek.rstrhDescription": "响应方已发送 SYN ACK,后跟 RST,(假定的)发起方未发送 SYN", "xpack.securitySolution.zeek.s0Description": "已看到连接尝试,无答复", "xpack.securitySolution.zeek.s1Description": "连接已建立,未终止", "xpack.securitySolution.zeek.s2Description": "连接已建立,已看到发起方的关闭尝试(但没有响应方的答复)", @@ -14566,6 +17230,9 @@ "xpack.securitySolution.zeek.sfDescription": "正常 SYN/FIN 完成", "xpack.securitySolution.zeek.shDescription": "发起方已发送 SYN,后跟 FIN,响应方未发送 SYN ACK", "xpack.securitySolution.zeek.shrDescription": "响应方已发送 SYN ACK,后跟 FIN,发起方未发送 SYN", + "xpack.server.checkLicense.errorExpiredMessage": "您不能使用 {pluginName},因为您的{licenseType}许可证已过期", + "xpack.server.checkLicense.errorUnavailableMessage": "您不能使用 {pluginName},因为许可证信息当前不可用。", + "xpack.server.checkLicense.errorUnsupportedMessage": "您的{licenseType}许可证不支持 {pluginName}。请升级您的许可证。", "xpack.snapshotRestore.addPolicy.breadcrumbTitle": "添加策略", "xpack.snapshotRestore.addPolicy.loadingIndicesDescription": "正在加载可用索引……", "xpack.snapshotRestore.addPolicy.LoadingIndicesErrorMessage": "加载可用索引时出错", @@ -14583,6 +17250,9 @@ "xpack.snapshotRestore.appTitle": "拍取快照并还原", "xpack.snapshotRestore.createPolicyButton": "创建策略", "xpack.snapshotRestore.dataPlaceholderLabel": "-", + "xpack.snapshotRestore.dataStreamsList.allDataStreamsValue": "所有数据流", + "xpack.snapshotRestore.dataStreamsList.dataStreamsCollapseAllLink": "隐藏 {count, plural, one {# 个数据流} other {# 个数据流}}", + "xpack.snapshotRestore.dataStreamsList.dataStreamsExpandAllLink": "显示 {count, plural, one {# 个数据流} other {# 个数据流}}", "xpack.snapshotRestore.deletePolicy.confirmModal.cancelButtonLabel": "取消", "xpack.snapshotRestore.deletePolicy.confirmModal.confirmButtonLabel": "删除{count, plural, one {策略} other {策略}}", "xpack.snapshotRestore.deletePolicy.confirmModal.deleteMultipleListDescription": "您即将删除以下策略:", @@ -14658,6 +17328,7 @@ "xpack.snapshotRestore.licenseCheckErrorMessage": "许可证检查失败", "xpack.snapshotRestore.policies.breadcrumbTitle": "策略", "xpack.snapshotRestore.policyDetails.closeButtonLabel": "关闭", + "xpack.snapshotRestore.policyDetails.dataStreamsAndIndicesLabel": "数据流和索引", "xpack.snapshotRestore.policyDetails.deleteButtonLabel": "删除", "xpack.snapshotRestore.policyDetails.editButtonLabel": "编辑", "xpack.snapshotRestore.policyDetails.executeButtonLabel": "立即运行", @@ -14720,6 +17391,7 @@ "xpack.snapshotRestore.policyForm.reloadRepositoriesButtonLabel": "重新加载存储库", "xpack.snapshotRestore.policyForm.saveButtonLabel": "保存策略", "xpack.snapshotRestore.policyForm.savingButtonLabel": "正在保存……", + "xpack.snapshotRestore.policyForm.setSettings.dataStreamBadgeContent": "数据流", "xpack.snapshotRestore.policyForm.stepLogistics.docsButtonLabel": "运筹文档", "xpack.snapshotRestore.policyForm.stepLogistics.nameDescription": "此策略的唯一标识符。", "xpack.snapshotRestore.policyForm.stepLogistics.nameDescriptionTitle": "策略名称", @@ -14770,6 +17442,7 @@ "xpack.snapshotRestore.policyForm.stepReview.retentionTab.maxCountLabel": "最大计数", "xpack.snapshotRestore.policyForm.stepReview.retentionTab.minCountLabel": "最小计数", "xpack.snapshotRestore.policyForm.stepReview.retentionTab.sectionRetentionTitle": "快照保留", + "xpack.snapshotRestore.policyForm.stepReview.summaryTab.dataStreamsAndIndicesLabel": "数据流和索引", "xpack.snapshotRestore.policyForm.stepReview.summaryTab.editStepTooltip": "编辑", "xpack.snapshotRestore.policyForm.stepReview.summaryTab.ignoreUnavailableFalseLabel": "否", "xpack.snapshotRestore.policyForm.stepReview.summaryTab.ignoreUnavailableLabel": "忽略不可用索引", @@ -14779,6 +17452,7 @@ "xpack.snapshotRestore.policyForm.stepReview.summaryTab.includeGlobalStateTrueLabel": "是", "xpack.snapshotRestore.policyForm.stepReview.summaryTab.nameLabel": "策略名称", "xpack.snapshotRestore.policyForm.stepReview.summaryTab.partialFalseLabel": "否", + "xpack.snapshotRestore.policyForm.stepReview.summaryTab.partialIndicesLabel": "允许部分索引", "xpack.snapshotRestore.policyForm.stepReview.summaryTab.partialTrueLabel": "是", "xpack.snapshotRestore.policyForm.stepReview.summaryTab.repositoryLabel": "存储库", "xpack.snapshotRestore.policyForm.stepReview.summaryTab.scheduleLabel": "计划", @@ -14787,23 +17461,29 @@ "xpack.snapshotRestore.policyForm.stepReview.summaryTab.snapshotNameLabel": "快照名称", "xpack.snapshotRestore.policyForm.stepReview.summaryTabTitle": "总结", "xpack.snapshotRestore.policyForm.stepReviewTitle": "复查策略", + "xpack.snapshotRestore.policyForm.stepSettings.allDataStreamsAndIndicesLabel": "所有数据流和索引,包括系统索引", + "xpack.snapshotRestore.policyForm.stepSettings.dataStreamsAndIndicesDescription": "要备份索引和数据流,请手动选择它们,以定义用于动态匹配它们的索引模式。", + "xpack.snapshotRestore.policyForm.stepSettings.dataStreamsAndIndicesTitle": "数据流和索引", + "xpack.snapshotRestore.policyForm.stepSettings.dataStreamsAndIndicesToggleListLink": "选择数据流和索引", "xpack.snapshotRestore.policyForm.stepSettings.deselectAllIndicesLink": "取消全选", "xpack.snapshotRestore.policyForm.stepSettings.docsButtonLabel": "快照设置文档", "xpack.snapshotRestore.policyForm.stepSettings.ignoreUnavailableDescription": "拍取快照时忽略不可用的索引。否则,整个快照将失败。", "xpack.snapshotRestore.policyForm.stepSettings.ignoreUnavailableDescriptionTitle": "忽略不可用索引", "xpack.snapshotRestore.policyForm.stepSettings.ignoreUnavailableLabel": "忽略不可用索引", - "xpack.snapshotRestore.policyForm.stepSettings.includeGlobalStateDescription": "将集群的全局状态存储为快照的一部分。", + "xpack.snapshotRestore.policyForm.stepSettings.includeGlobalStateDescription": "将全局集群状态存储为快照的一部分。", "xpack.snapshotRestore.policyForm.stepSettings.includeGlobalStateDescriptionTitle": "包括全局状态", "xpack.snapshotRestore.policyForm.stepSettings.indicesPatternLabel": "索引模式", "xpack.snapshotRestore.policyForm.stepSettings.indicesPatternPlaceholder": "输入索引模式,例如 logstash-*", "xpack.snapshotRestore.policyForm.stepSettings.indicesToggleCustomLink": "使用索引模式", "xpack.snapshotRestore.policyForm.stepSettings.indicesTooltip": "云托管的策略需要所有索引。", + "xpack.snapshotRestore.policyForm.stepSettings.noDataStreamsOrIndicesHelpText": "将不备份任何内容。{selectAllLink}", "xpack.snapshotRestore.policyForm.stepSettings.partialDescription": "允许具有不可用主分片的索引的快照。否则,整个快照将失败。", "xpack.snapshotRestore.policyForm.stepSettings.partialDescriptionTitle": "允许部分索引", "xpack.snapshotRestore.policyForm.stepSettings.partialIndicesToggleSwitch": "允许部分索引", "xpack.snapshotRestore.policyForm.stepSettings.policyIncludeGlobalStateLabel": "包括全局状态", "xpack.snapshotRestore.policyForm.stepSettings.selectAllIndicesLink": "全选", - "xpack.snapshotRestore.policyForm.stepSettings.selectIndicesLabel": "选择索引", + "xpack.snapshotRestore.policyForm.stepSettings.selectDataStreamsIndicesHelpText": "将备份 {indicesCount} 个{indicesCount, plural, one {索引} other {索引}}和 {dataStreamsCount} 个{dataStreamsCount, plural, one {数据流} other {数据流}}。{deselectAllLink}", + "xpack.snapshotRestore.policyForm.stepSettings.selectIndicesLabel": "选择索引和数据流", "xpack.snapshotRestore.policyForm.stepSettingsTitle": "快照设置", "xpack.snapshotRestore.policyList.deniedPrivilegeDescription": "要管理快照生命周期策略,必须具有{privilegesCount, plural, one {以下集群权限} other {以下集群权限}}:{missingPrivileges}。", "xpack.snapshotRestore.policyList.deniedPrivilegeTitle": "您缺少集群权限", @@ -14851,7 +17531,7 @@ "xpack.snapshotRestore.policyScheduleWarningDescription": "一次仅可以拍取一个快照。要避免快照失败,请编辑或删除策略。", "xpack.snapshotRestore.policyScheduleWarningTitle": "两个或更多策略有相同的计划", "xpack.snapshotRestore.policyValidation.indexPatternRequiredErrorMessage": "至少需要一个索引模式。", - "xpack.snapshotRestore.policyValidation.indicesRequiredErrorMessage": "必须至少选择一个索引。", + "xpack.snapshotRestore.policyValidation.indicesRequiredErrorMessage": "必须至少选择一个数据流或索引。", "xpack.snapshotRestore.policyValidation.invalidMinCountErrorMessage": "最小计数不能大于最大计数。", "xpack.snapshotRestore.policyValidation.invalidNegativeDeleteAfterErrorMessage": "“在指定时间后删除”不能为负。", "xpack.snapshotRestore.policyValidation.invalidNegativeMaxCountErrorMessage": "“最大计数”不能为负。", @@ -15144,11 +17824,18 @@ "xpack.snapshotRestore.repositoryWarningLinkText": "存储库", "xpack.snapshotRestore.repositoryWarningTitle": "一些存储库包含错误", "xpack.snapshotRestore.restoreForm.backButtonLabel": "上一步", + "xpack.snapshotRestore.restoreForm.dataStreamsWarningCallOut.body": "每个数据流需要匹配的索引模板。请确保任何存储的数据流有匹配的索引模板。可以通过存储全局集群状态来存储索引模板。不过,这可能会覆盖现有模板、集群设置、采集管道和生命周期策略。{learnMoreLink}如何存储包含数据流的快照。", + "xpack.snapshotRestore.restoreForm.dataStreamsWarningCallOut.body.learnMoreLink": "详细了解", + "xpack.snapshotRestore.restoreForm.dataStreamsWarningCallOut.title": "此快照包含{count, plural, one {数据流} other {数据流}}", "xpack.snapshotRestore.restoreForm.navigation.stepLogisticsName": "运筹", "xpack.snapshotRestore.restoreForm.navigation.stepReviewName": "复查", "xpack.snapshotRestore.restoreForm.navigation.stepSettingsName": "索引设置", "xpack.snapshotRestore.restoreForm.nextButtonLabel": "下一步", "xpack.snapshotRestore.restoreForm.savingButtonLabel": "正在还原……", + "xpack.snapshotRestore.restoreForm.stepLogistics.allDataStreamsAndIndicesLabel": "所有数据流和索引,包括系统索引", + "xpack.snapshotRestore.restoreForm.stepLogistics.dataStreamsAndIndicesDescription": "如果数据流和索引不存在,创建新的。打开现有索引,包括数据流的后备索引,前提是它们已关闭且具有与快照索引相同的分片数目。", + "xpack.snapshotRestore.restoreForm.stepLogistics.dataStreamsAndIndicesTitle": "数据流和索引", + "xpack.snapshotRestore.restoreForm.stepLogistics.dataStreamsAndIndicesToggleListLink": "选择数据流和索引", "xpack.snapshotRestore.restoreForm.stepLogistics.deselectAllIndicesLink": "取消全选", "xpack.snapshotRestore.restoreForm.stepLogistics.docsButtonLabel": "快照和还原文档", "xpack.snapshotRestore.restoreForm.stepLogistics.includeGlobalStateDescription": "还原当前在集群中不存在的模板并覆盖同名模板。同时还原永久性设置。", @@ -15158,16 +17845,23 @@ "xpack.snapshotRestore.restoreForm.stepLogistics.indicesPatternLabel": "索引模式", "xpack.snapshotRestore.restoreForm.stepLogistics.indicesPatternPlaceholder": "输入索引模式,例如 logstash-*", "xpack.snapshotRestore.restoreForm.stepLogistics.indicesToggleCustomLink": "使用索引模式", + "xpack.snapshotRestore.restoreForm.stepLogistics.noDataStreamsOrIndicesHelpText": "将不还原任何内容。{selectAllLink}", "xpack.snapshotRestore.restoreForm.stepLogistics.partialDescription": "允许还原不具有所有分片的快照的索引。", "xpack.snapshotRestore.restoreForm.stepLogistics.partialLabel": "部分还原", "xpack.snapshotRestore.restoreForm.stepLogistics.partialTitle": "部分还原", + "xpack.snapshotRestore.restoreForm.stepLogistics.renameDataStreamsAndIndicesDescription": "还原时重命名数据流和索引。确保存在重命名数据流的匹配索引模板。", + "xpack.snapshotRestore.restoreForm.stepLogistics.renameDataStreamsAndIndicesLabel": "重命名数据流和索引", + "xpack.snapshotRestore.restoreForm.stepLogistics.renameDataStreamsAndIndicesTitle": "重命名数据流和索引", "xpack.snapshotRestore.restoreForm.stepLogistics.renamePatternHelpText": "使用正则表达式", "xpack.snapshotRestore.restoreForm.stepLogistics.renamePatternLabel": "捕获模式", "xpack.snapshotRestore.restoreForm.stepLogistics.renameReplacementLabel": "替换模式", "xpack.snapshotRestore.restoreForm.stepLogistics.selectAllIndicesLink": "全选", + "xpack.snapshotRestore.restoreForm.stepLogistics.selectDataStreamsAndIndicesHelpText": "将还原 {indicesCount} 个{indicesCount, plural, one {索引} other {索引}}和 {dataStreamsCount} 个{dataStreamsCount, plural, one {数据流} other {数据流}}。{deselectAllLink}", + "xpack.snapshotRestore.restoreForm.stepLogistics.selectDataStreamsAndIndicesLabel": "选择数据流和索引", "xpack.snapshotRestore.restoreForm.stepLogisticsTitle": "还原详情", "xpack.snapshotRestore.restoreForm.stepReview.jsonTab.jsonAriaLabel": "还原要执行的设置", "xpack.snapshotRestore.restoreForm.stepReview.jsonTabTitle": "JSON", + "xpack.snapshotRestore.restoreForm.stepReview.summaryTab.dataStreamsAndIndicesLabel": "数据流和索引", "xpack.snapshotRestore.restoreForm.stepReview.summaryTab.editStepTooltip": "缂栬緫", "xpack.snapshotRestore.restoreForm.stepReview.summaryTab.ignoreIndexSettingsLabel": "重置", "xpack.snapshotRestore.restoreForm.stepReview.summaryTab.includeGlobalStateFalseValue": "否", @@ -15185,6 +17879,8 @@ "xpack.snapshotRestore.restoreForm.stepReview.summaryTab.sectionSettingsTitle": "索引设置", "xpack.snapshotRestore.restoreForm.stepReview.summaryTabTitle": "摘要", "xpack.snapshotRestore.restoreForm.stepReviewTitle": "复查还原详情", + "xpack.snapshotRestore.restoreForm.stepSettings.dataStreamsCallout.description": "这些设置还适用于数据流的后备索引。", + "xpack.snapshotRestore.restoreForm.stepSettings.dataStreamsCallout.title": "后备索引", "xpack.snapshotRestore.restoreForm.stepSettings.docsButtonLabel": "索引设置文档", "xpack.snapshotRestore.restoreForm.stepSettings.ignoreIndexSettingsDescription": "在还原期间将选定设置重置为默认值。{docLink}", "xpack.snapshotRestore.restoreForm.stepSettings.ignoreIndexSettingsLabel": "重置索引设置", @@ -15247,7 +17943,7 @@ "xpack.snapshotRestore.restoreValidation.indexSettingsNotModifiableError": "无法修改:{settings}", "xpack.snapshotRestore.restoreValidation.indexSettingsNotRemovableError": "无法重置:{settings}", "xpack.snapshotRestore.restoreValidation.indexSettingsRequiredError": "至少需要一个设置。", - "xpack.snapshotRestore.restoreValidation.indicesRequiredError": "必须至少选择一个索引。", + "xpack.snapshotRestore.restoreValidation.indicesRequiredError": "必须至少选择一个数据流或索引。", "xpack.snapshotRestore.restoreValidation.renamePatternRequiredError": "捕获模式必填。", "xpack.snapshotRestore.restoreValidation.renameReplacementRequiredError": "替换模式必填。", "xpack.snapshotRestore.snapshotDetails.closeButtonLabel": "关闭", @@ -15258,6 +17954,7 @@ "xpack.snapshotRestore.snapshotDetails.errorSnapshotNotFound": "快照“{snapshotId}”在存储库“{repositoryName}”中不存在或该存储库不存在。", "xpack.snapshotRestore.snapshotDetails.failureShardTitle": "分片 {shardId}", "xpack.snapshotRestore.snapshotDetails.failuresTabTitle": "失败的索引 ({failuresCount})", + "xpack.snapshotRestore.snapshotDetails.itemDataStreamsLabel": "数据流 ({dataStreamsCount})", "xpack.snapshotRestore.snapshotDetails.itemDurationLabel": "持续时间", "xpack.snapshotRestore.snapshotDetails.itemDurationValueLabel": "{seconds} {seconds, plural, one {秒} other {秒}}", "xpack.snapshotRestore.snapshotDetails.itemEndTimeLabel": "结束时间", @@ -15465,10 +18162,19 @@ "xpack.spaces.spaceSelector.noSpacesMatchSearchCriteriaDescription": "没有匹配搜索条件的空间", "xpack.spaces.spaceSelector.selectSpacesTitle": "选择您的空间", "xpack.spaces.spacesTitle": "工作区", + "xpack.transform.actionDeleteTransform.bulkDeleteDestinationIndexTitle": "删除目标索引", + "xpack.transform.actionDeleteTransform.bulkDeleteDestIndexPatternTitle": "删除目标索引模式", + "xpack.transform.actionDeleteTransform.deleteDestinationIndexTitle": "删除目标索引 {destinationIndex}", + "xpack.transform.actionDeleteTransform.deleteDestIndexPatternTitle": "删除索引模式 {destinationIndex}", "xpack.transform.agg.popoverForm.aggLabel": "聚合", "xpack.transform.agg.popoverForm.aggNameAlreadyUsedError": "其他聚合已使用该名称。", "xpack.transform.agg.popoverForm.aggNameInvalidCharError": "名称无效。不允许使用字符“[”、“]”和“>”,且名称不得以空格字符开头或结束。", "xpack.transform.agg.popoverForm.fieldLabel": "字段", + "xpack.transform.agg.popoverForm.filerAgg.range.greaterThanLabel": "大于", + "xpack.transform.agg.popoverForm.filerAgg.range.lessThanLabel": "小于", + "xpack.transform.agg.popoverForm.filerAgg.term.errorFetchSuggestions": "无法获取建议", + "xpack.transform.agg.popoverForm.filerAgg.term.valueLabel": "值", + "xpack.transform.agg.popoverForm.filerAggLabel": "筛选查询", "xpack.transform.agg.popoverForm.nameLabel": "聚合名称", "xpack.transform.agg.popoverForm.percentsLabel": "百分数", "xpack.transform.agg.popoverForm.submitButtonLabel": "应用", @@ -15489,6 +18195,11 @@ "xpack.transform.clone.errorPromptTitle": "获取转换配置时发生错误。", "xpack.transform.cloneTransform.breadcrumbTitle": "克隆转换", "xpack.transform.createTransform.breadcrumbTitle": "创建转换", + "xpack.transform.deleteTransform.deleteAnalyticsWithIndexErrorMessage": "删除目标索引 {destinationIndex} 时发生错误", + "xpack.transform.deleteTransform.deleteAnalyticsWithIndexPatternErrorMessage": "删除索引模式 {destinationIndex} 时发生错误", + "xpack.transform.deleteTransform.deleteAnalyticsWithIndexPatternSuccessMessage": "删除索引模式 {destinationIndex} 的请求已确认。", + "xpack.transform.deleteTransform.deleteAnalyticsWithIndexSuccessMessage": "删除目标索引 {destinationIndex} 的请求已确认。", + "xpack.transform.deleteTransform.errorWithCheckingIfIndexPatternExistsNotificationErrorMessage": "检查索引模式 {indexPattern} 是否存在时发生错误:{error}", "xpack.transform.description": "描述", "xpack.transform.groupby.popoverForm.aggLabel": "聚合", "xpack.transform.groupBy.popoverForm.aggNameAlreadyUsedError": "其他分组依据配置已使用该名称。", @@ -15555,6 +18266,7 @@ "xpack.transform.stepCreateForm.startTransformSuccessMessage": "启动转换 {transformId} 的请求已确认。", "xpack.transform.stepCreateForm.transformListCardDescription": "返回数据帧作业管理页面。", "xpack.transform.stepCreateForm.transformListCardTitle": "数据帧作业", + "xpack.transform.stepDefineForm.addSubAggregationPlaceholder": "添加子聚合......", "xpack.transform.stepDefineForm.advancedEditorApplyButtonText": "应用更改", "xpack.transform.stepDefineForm.advancedEditorAriaLabel": "高级数据透视表编辑器", "xpack.transform.stepDefineForm.advancedEditorHelpText": "高级编辑器允许您编辑数据帧转换的数据透视表配置。", @@ -15581,6 +18293,7 @@ "xpack.transform.stepDefineForm.indexPatternHelpText": "不支持此索引模式的可选查询。受支持索引字段数目为 {maxIndexFields},而此索引有 {numIndexFields} 个字段。", "xpack.transform.stepDefineForm.indexPatternLabel": "索引模式", "xpack.transform.stepDefineForm.invalidKuerySyntaxErrorMessageQueryBar": "查询无效:{errorMessage}", + "xpack.transform.stepDefineForm.maxSubAggsLevelsLimitMessage": "您已达到可在表单中添加的最大子聚合级别数。如果想再添加一个级别,请编辑 JSON 配置。", "xpack.transform.stepDefineForm.nestedAggListConflictErrorMessage": "无法添加配置“{aggName}”,因为与“{aggListName}”有嵌套冲突。", "xpack.transform.stepDefineForm.nestedConflictErrorMessage": "无法添加配置“{aggName}”,因为与“{aggNameCheck}”有嵌套冲突。", "xpack.transform.stepDefineForm.nestedGroupByListConflictErrorMessage": "无法添加配置“{aggName}”,因为与“{groupByListName}”有嵌套冲突。", @@ -15608,7 +18321,11 @@ "xpack.transform.stepDetailsForm.errorGettingIndexNames": "获取现有索引名称时发生错误:", "xpack.transform.stepDetailsForm.errorGettingIndexPatternTitles": "获取现有索引模式标题时发生错误:", "xpack.transform.stepDetailsForm.errorGettingTransformList": "获取现有转换 ID 时发生错误:", + "xpack.transform.stepDetailsForm.errorGettingTransformPreview": "获取转换预览时发生错误", + "xpack.transform.stepDetailsForm.indexPatternTimeFilterHelpText": "时间筛选将使用此字段按时间筛选您的数据。您可以选择不使用时间字段,但将无法通过时间范围缩小您的数据范围。", + "xpack.transform.stepDetailsForm.indexPatternTimeFilterLabel": "时间筛选字段名称", "xpack.transform.stepDetailsForm.indexPatternTitleError": "具有此名称的索引模式已存在。", + "xpack.transform.stepDetailsForm.noTimeFieldOptionLabel": "我不想使用时间筛选", "xpack.transform.stepDetailsForm.transformDescriptionInputAriaLabel": "选择可选的转换描述。", "xpack.transform.stepDetailsForm.transformDescriptionLabel": "转换描述", "xpack.transform.stepDetailsForm.transformDescriptionPlaceholderText": "描述(可选)", @@ -15619,6 +18336,7 @@ "xpack.transform.stepDetailsSummary.continuousModeDateFieldLabel": "连续模式日期字段", "xpack.transform.stepDetailsSummary.createIndexPatternMessage": "将为此作业创建 Kibana 索引模式。", "xpack.transform.stepDetailsSummary.destinationIndexLabel": "目标 IP", + "xpack.transform.stepDetailsSummary.indexPatternTimeFilterLabel": "时间筛选", "xpack.transform.stepDetailsSummary.transformDescriptionLabel": "转换描述", "xpack.transform.stepDetailsSummary.transformIdLabel": "作业 ID", "xpack.transform.tableActionLabel": "操作", @@ -15626,8 +18344,12 @@ "xpack.transform.toastText.modalTitle": "错误详细信息", "xpack.transform.toastText.openModalButtonText": "查看详情", "xpack.transform.transformForm.sizeNotationPlaceholder": "示例:{example1}、{example2}、{example3}、{example4}", - "xpack.transform.transformList.bulkDeleteModalBody": "是否确定要删除{count, plural, one {这} other {这}} {count} 个 {count, plural, one {转换} other {转换}}?转换的目标索引和可选 Kibana 索引模式将不会删除。", + "xpack.transform.transformList.bulkDeleteDestIndexPatternSuccessMessage": "已成功删除 {count} 个目标索引{count, plural, one {模式} other {模式}}。", + "xpack.transform.transformList.bulkDeleteDestIndexSuccessMessage": "已成功删除 {count} 个目标{count, plural, one {索引} other {索引}}。", + "xpack.transform.transformList.bulkDeleteModalBody": "确定要删除{count, plural, one {这} other {这}} {count} 个{count, plural, one {转换} other {转换}}?", "xpack.transform.transformList.bulkDeleteModalTitle": "删除 {count} 个 {count, plural, one {转换} other {转换}}?", + "xpack.transform.transformList.bulkDeleteTransformSuccessMessage": "已成功删除 {count} 个{count, plural, one {转换} other {转换}}。", + "xpack.transform.transformList.bulkForceDeleteModalBody": "确定要强制删除{count, plural, one {这} other {这}} {count} 个{count, plural, one {转换} other {转换}}?无论{count, plural, one {转换} other {转换}}的当前状态如何,都将删除{count, plural, one {} other {}}。", "xpack.transform.transformList.bulkStartModalTitle": "启动 {count} 个 {count, plural, one {转换} other {转换}}?", "xpack.transform.transformList.cloneActionName": "克隆", "xpack.transform.transformList.completeBatchTransformBulkActionToolTip": "一个或多个转换为已完成批量转换,无法重新启动。", @@ -15636,7 +18358,7 @@ "xpack.transform.transformList.deleteActionDisabledToolTipContent": "停止数据帧作业,以便将其删除。", "xpack.transform.transformList.deleteActionName": "删除", "xpack.transform.transformList.deleteBulkActionDisabledToolTipContent": "一个或多个选定数据帧转换必须停止,才能删除。", - "xpack.transform.transformList.deleteModalBody": "是否确定要删除此转换?转换的目标索引和可选 Kibana 索引模式将不会删除。", + "xpack.transform.transformList.deleteModalBody": "是否确定要删除此转换?", "xpack.transform.transformList.deleteModalCancelButton": "取消", "xpack.transform.transformList.deleteModalDeleteButton": "删除", "xpack.transform.transformList.deleteModalTitle": "删除 {transformId}", @@ -15659,6 +18381,8 @@ "xpack.transform.transformList.editFlyoutUpdateButtonText": "更新", "xpack.transform.transformList.editTransformGenericErrorMessage": "调用用于更新转换的 API 终端时发生错误。", "xpack.transform.transformList.editTransformSuccessMessage": "转换 {transformId} 已更新。", + "xpack.transform.transformList.errorWithCheckingIfUserCanDeleteIndexNotificationErrorMessage": "检查用户是否可以删除目标索引时发生错误", + "xpack.transform.transformList.forceDeleteModalBody": "确定要强制删除此索引?无论转换的当前状态如何,都将删除。", "xpack.transform.transformList.refreshButtonLabel": "刷新", "xpack.transform.transformList.rowCollapse": "隐藏 {transformId} 的详情", "xpack.transform.transformList.rowExpand": "显示 {transformId} 的详情", @@ -15682,8 +18406,10 @@ "xpack.transform.transformList.transformDetails.messagesPane.messageLabel": "消息", "xpack.transform.transformList.transformDetails.messagesPane.nodeLabel": "节点", "xpack.transform.transformList.transformDetails.messagesPane.timeLabel": "时间", + "xpack.transform.transformList.transformDetails.tabs.transformDetailsLabel": "详情", "xpack.transform.transformList.transformDetails.tabs.transformMessagesLabel": "消息", "xpack.transform.transformList.transformDetails.tabs.transformPreviewLabel": "预览", + "xpack.transform.transformList.transformDetails.tabs.transformStatsLabel": "统计", "xpack.transform.transformList.transformDocsLinkText": "转换文档", "xpack.transform.transformList.transformTitle": "数据帧作业", "xpack.transform.transformsDescription": "使用转换将现有 Elasticsearch 索引透视成摘要式或以实体为中心的索引。", @@ -15727,7 +18453,18 @@ "xpack.triggersActionsUI.common.expressionItems.threshold.popoverTitle": "当", "xpack.triggersActionsUI.components.addMessageVariables.addVariablePopoverButton": "添加变量", "xpack.triggersActionsUI.components.addMessageVariables.addVariableTitle": "添加告警变量", + "xpack.triggersActionsUI.components.builtinActionTypes.addNewConnector": "添加新连接器", + "xpack.triggersActionsUI.components.builtinActionTypes.cancelButton": "取消", + "xpack.triggersActionsUI.components.builtinActionTypes.caseClosureOptionsClosedIncident": "在外部系统中关闭事件时自动关闭 Security 案例", + "xpack.triggersActionsUI.components.builtinActionTypes.caseClosureOptionsDesc": "定义关闭 Security 案例的方式。要自动关闭案例,需要与外部事件管理系统建立连接。", + "xpack.triggersActionsUI.components.builtinActionTypes.caseClosureOptionsLabel": "案例关闭选项", + "xpack.triggersActionsUI.components.builtinActionTypes.caseClosureOptionsManual": "手动关闭 Security 案例", + "xpack.triggersActionsUI.components.builtinActionTypes.caseClosureOptionsNewIncident": "将新事件推送到外部系统时自动关闭 Security 案例", + "xpack.triggersActionsUI.components.builtinActionTypes.caseClosureOptionsTitle": "案例关闭", + "xpack.triggersActionsUI.components.builtinActionTypes.common.requiredDescriptionTextField": "描述必填。", + "xpack.triggersActionsUI.components.builtinActionTypes.common.requiredTitleTextField": "标题必填。", "xpack.triggersActionsUI.components.builtinActionTypes.emailAction.actionTypeTitle": "发送到电子邮件", + "xpack.triggersActionsUI.components.builtinActionTypes.emailAction.configureAccountsHelpLabel": "配置电子邮件帐户。", "xpack.triggersActionsUI.components.builtinActionTypes.emailAction.selectMessageText": "从您的服务器发送电子邮件。", "xpack.triggersActionsUI.components.builtinActionTypes.error.formatFromText": "发送者电子邮件地址无效。", "xpack.triggersActionsUI.components.builtinActionTypes.error.requiredEntryText": "未输入收件人、抄送、密送。 至少需要输入一个。", @@ -15741,8 +18478,20 @@ "xpack.triggersActionsUI.components.builtinActionTypes.error.requiredSubjectText": "“主题”必填。", "xpack.triggersActionsUI.components.builtinActionTypes.error.requiredUserText": "使用密码时,“用户名”必填。", "xpack.triggersActionsUI.components.builtinActionTypes.error.requiredWebhookBodyText": "“正文”必填。", + "xpack.triggersActionsUI.components.builtinActionTypes.fieldMappingDesc": "将数据推送到第三方时映射 Security 案例字段。要映射字段,需要与外部事件管理系统建立连接。", + "xpack.triggersActionsUI.components.builtinActionTypes.fieldMappingEditAppend": "追加", + "xpack.triggersActionsUI.components.builtinActionTypes.fieldMappingEditNothing": "无内容", + "xpack.triggersActionsUI.components.builtinActionTypes.fieldMappingEditOverwrite": "覆盖", + "xpack.triggersActionsUI.components.builtinActionTypes.fieldMappingFirstCol": "Security 案例字段", + "xpack.triggersActionsUI.components.builtinActionTypes.fieldMappingSecondCol": "外部事件字段", + "xpack.triggersActionsUI.components.builtinActionTypes.fieldMappingThirdCol": "编辑和更新时", + "xpack.triggersActionsUI.components.builtinActionTypes.fieldMappingTitle": "字段映射", + "xpack.triggersActionsUI.components.builtinActionTypes.incidentManagementSystemDesc": "您可能会根据需要将 Security 案例连接到选择的外部事件管理系统。这将允许您将案例数据作为事件推送到所选第三方系统。", + "xpack.triggersActionsUI.components.builtinActionTypes.incidentManagementSystemLabel": "事件管理系统", + "xpack.triggersActionsUI.components.builtinActionTypes.incidentManagementSystemTitle": "连接到外部事件管理系统", "xpack.triggersActionsUI.components.builtinActionTypes.indexAction.actionTypeTitle": "索引数据", "xpack.triggersActionsUI.components.builtinActionTypes.indexAction.chooseLabel": "选择……", + "xpack.triggersActionsUI.components.builtinActionTypes.indexAction.configureIndexHelpLabel": "配置索引连接器。", "xpack.triggersActionsUI.components.builtinActionTypes.indexAction.connectorSectionTitle": "写入到索引", "xpack.triggersActionsUI.components.builtinActionTypes.indexAction.definedateFieldTooltip": "索引每个文档时自动向其添加时间字段。", "xpack.triggersActionsUI.components.builtinActionTypes.indexAction.defineTimeFieldLabel": "为每个文档定义时间字段", @@ -15750,12 +18499,15 @@ "xpack.triggersActionsUI.components.builtinActionTypes.indexAction.error.requiredIndexText": "“索引”必填。", "xpack.triggersActionsUI.components.builtinActionTypes.indexAction.executionTimeFieldLabel": "时间字段", "xpack.triggersActionsUI.components.builtinActionTypes.indexAction.howToBroadenSearchQueryDescription": "使用 * 可扩大您的查询范围。", + "xpack.triggersActionsUI.components.builtinActionTypes.indexAction.indexDocumentHelpLabel": "索引文档示例。", "xpack.triggersActionsUI.components.builtinActionTypes.indexAction.indicesAndIndexPatternsLabel": "基于索引模式", "xpack.triggersActionsUI.components.builtinActionTypes.indexAction.indicesToQueryLabel": "索引", "xpack.triggersActionsUI.components.builtinActionTypes.indexAction.jsonDocAriaLabel": "代码编辑器", "xpack.triggersActionsUI.components.builtinActionTypes.indexAction.refreshLabel": "刷新索引", "xpack.triggersActionsUI.components.builtinActionTypes.indexAction.refreshTooltip": "刷新影响的分片以使此操作对搜索可见。", "xpack.triggersActionsUI.components.builtinActionTypes.indexAction.selectMessageText": "将数据索引到 Elasticsearch 中。", + "xpack.triggersActionsUI.components.builtinActionTypes.mappingFieldNotMapped": "未映射", + "xpack.triggersActionsUI.components.builtinActionTypes.noConnector": "未选择连接器", "xpack.triggersActionsUI.components.builtinActionTypes.pagerDutyAction.actionTypeTitle": "发送到 PagerDuty", "xpack.triggersActionsUI.components.builtinActionTypes.pagerDutyAction.apiUrlTextFieldLabel": "API URL(可选)", "xpack.triggersActionsUI.components.builtinActionTypes.pagerDutyAction.classFieldLabel": "类(可选)", @@ -15784,18 +18536,48 @@ "xpack.triggersActionsUI.components.builtinActionTypes.serverLogAction.logLevelFieldLabel": "级别", "xpack.triggersActionsUI.components.builtinActionTypes.serverLogAction.logMessageFieldLabel": "消息", "xpack.triggersActionsUI.components.builtinActionTypes.serverLogAction.selectMessageText": "将消息添加到 Kibana 日志。", + "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.actionTypeTitle": "ServiceNow", + "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.apiTokenTextFieldLabel": "Api 令牌", + "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.apiUrlTextFieldLabel": "URL", + "xpack.triggersActionsUI.components.builtinActionTypes.serviceNow.commentsTextAreaFieldLabel": "其他备注(可选)", + "xpack.triggersActionsUI.components.builtinActionTypes.serviceNow.descriptionTextAreaFieldLabel": "描述(可选)", + "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.emailTextFieldLabel": "电子邮件", + "xpack.triggersActionsUI.components.builtinActionTypes.serviceNow.impactSelectFieldLabel": "影响", + "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.invalidApiUrlTextField": "URL 无效。", + "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.mappingFieldComments": "注释", + "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.mappingFieldDescription": "描述", + "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.mappingFieldShortDescription": "简短描述", + "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.passwordTextFieldLabel": "密码", + "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.requiredApiTokenTextField": "“Api 令牌”必填。", + "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.requiredApiUrlTextField": "“URL”必填。", + "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.requiredEmailTextField": "“电子邮件”必填。", + "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.requiredPasswordTextField": "“密码”必填。", + "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.requiredUsernameTextField": "“用户名”必填。", + "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.selectMessageText": "将数据推送或更新到 ServiceNow 中的新事件。", + "xpack.triggersActionsUI.components.builtinActionTypes.serviceNow.severitySelectFieldLabel": "严重性", + "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.severitySelectHighOptionLabel": "高", + "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.severitySelectLawOptionLabel": "低", + "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.severitySelectMediumOptionLabel": "中", + "xpack.triggersActionsUI.components.builtinActionTypes.serviceNow.titleFieldLabel": "简短描述", + "xpack.triggersActionsUI.components.builtinActionTypes.serviceNow.urgencySelectFieldLabel": "紧急度", + "xpack.triggersActionsUI.components.builtinActionTypes.servicenow.usernameTextFieldLabel": "用户名", "xpack.triggersActionsUI.components.builtinActionTypes.slackAction.actionTypeTitle": "发送到 Slack", "xpack.triggersActionsUI.components.builtinActionTypes.slackAction.error.requiredWebhookUrlText": "Webhook URL 必填。", "xpack.triggersActionsUI.components.builtinActionTypes.slackAction.messageTextAreaFieldLabel": "消息", "xpack.triggersActionsUI.components.builtinActionTypes.slackAction.selectMessageText": "向 Slack 频道或用户发送消息。", "xpack.triggersActionsUI.components.builtinActionTypes.slackAction.webhookUrlHelpLabel": "创建 Slack webhook URL", "xpack.triggersActionsUI.components.builtinActionTypes.slackAction.webhookUrlTextFieldLabel": "Webhook URL", + "xpack.triggersActionsUI.components.builtinActionTypes.updateConnector": "更新连接器", + "xpack.triggersActionsUI.components.builtinActionTypes.updateSelectedConnector": "更新 { connectorName }", + "xpack.triggersActionsUI.components.builtinActionTypes.warningMessage": "选定的连接器已删除。选择不同的连接器或创建新的连接器。", + "xpack.triggersActionsUI.components.builtinActionTypes.warningTitle": "警告", "xpack.triggersActionsUI.components.builtinActionTypes.webhookAction.actionTypeTitle": "Webhook 数据", "xpack.triggersActionsUI.components.builtinActionTypes.webhookAction.addHeader": "添加标头", "xpack.triggersActionsUI.components.builtinActionTypes.webhookAction.addHeaderButton": "添加", "xpack.triggersActionsUI.components.builtinActionTypes.webhookAction.bodyCodeEditorAriaLabel": "代码编辑器", "xpack.triggersActionsUI.components.builtinActionTypes.webhookAction.bodyFieldLabel": "正文", "xpack.triggersActionsUI.components.builtinActionTypes.webhookAction.deleteHeaderButton": "删除", + "xpack.triggersActionsUI.components.builtinActionTypes.webhookAction.error.invalidUrlTextField": "URL 无效。", "xpack.triggersActionsUI.components.builtinActionTypes.webhookAction.error.requiredUrlText": "“URL”必填。", "xpack.triggersActionsUI.components.builtinActionTypes.webhookAction.httpHeadersTitle": "使用的标头", "xpack.triggersActionsUI.components.builtinActionTypes.webhookAction.keyTextFieldLabel": "键", @@ -16029,8 +18811,47 @@ "xpack.triggersActionsUI.timeUnits.secondLabel": "{timeValue, plural, one {秒} other {秒}}", "xpack.triggersActionsUI.typeRegistry.get.missingActionTypeErrorMessage": "未注册对象类型“{id}”。", "xpack.triggersActionsUI.typeRegistry.register.duplicateObjectTypeErrorMessage": "已注册对象类型“{id}”。", + "xpack.uiActionsEnhanced.components.actionWizard.changeButton": "更改", + "xpack.uiActionsEnhanced.components.actionWizard.insufficientLicenseLevelTooltip": "许可证级别不够", "xpack.uiActionsEnhanced.components.DiscoverDrilldownConfig.chooseIndexPattern": "选择目标索引模式", + "xpack.uiActionsEnhanced.customizePanelTimeRange.modal.addToPanelButtonTitle": "添加到面板", + "xpack.uiActionsEnhanced.customizePanelTimeRange.modal.cancelButtonTitle": "取消", + "xpack.uiActionsEnhanced.customizePanelTimeRange.modal.optionsMenuForm.panelTitleFormRowLabel": "时间范围", + "xpack.uiActionsEnhanced.customizePanelTimeRange.modal.removeButtonTitle": "移除", + "xpack.uiActionsEnhanced.customizePanelTimeRange.modal.updatePanelTimeRangeButtonTitle": "更新", + "xpack.uiActionsEnhanced.customizeTimeRange.modal.headerTitle": "定制面板时间范围", + "xpack.uiActionsEnhanced.customizeTimeRangeMenuItem.displayName": "定制时间范围", "xpack.uiActionsEnhanced.drilldown.goToDiscover": "前往 Discover(示例)", + "xpack.uiActionsEnhanced.drilldowns.components.DrilldownHelloBar.helpText": "向下钻取允许您定义与面板交互的新行为。您可以添加多个操作并覆盖默认筛选。", + "xpack.uiActionsEnhanced.drilldowns.components.DrilldownHelloBar.hideHelpButtonLabel": "隐藏", + "xpack.uiActionsEnhanced.drilldowns.components.DrilldownHelloBar.viewDocsLinkLabel": "查看文档", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.createDrilldownButtonLabel": "创建向下钻取", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.createDrilldownTitle": "创建向下钻取", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.deleteDrilldownButtonLabel": "删除向下钻取", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.editDrilldownButtonLabel": "保存", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.editDrilldownTitle": "编辑向下钻取", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.insufficientLicenseLevelError": "许可证级别不够", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.invalidDrilldownType": "向下钻取类型 {type} 不存在", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.toast.drilldownCreatedText": "在测试前保存仪表板。", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.toast.drilldownCreatedTitle": "向下钻取“{drilldownName}”已创建", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.toast.drilldownDeletedText": "在测试前保存仪表板。", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.toast.drilldownDeletedTitle": "向下钻取已删除", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.toast.drilldownEditedText": "在测试前保存仪表板。", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.toast.drilldownEditedTitle": "向下钻取“{drilldownName}”已更新", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.toast.drilldownsCRUDErrorTitle": "保存向下钻取时出错", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.toast.drilldownsDeletedText": "在测试前保存仪表板。", + "xpack.uiActionsEnhanced.drilldowns.components.flyoutDrilldownWizard.toast.drilldownsDeletedTitle": "{n} 个向下钻取已删除", + "xpack.uiActionsEnhanced.drilldowns.components.FlyoutFrame.BackButtonLabel": "上一步", + "xpack.uiActionsEnhanced.drilldowns.components.FlyoutFrame.CloseButtonLabel": "关闭", + "xpack.uiActionsEnhanced.drilldowns.components.FlyoutListManageDrilldowns.manageDrilldownsTitle": "管理向下钻取", + "xpack.uiActionsEnhanced.drilldowns.components.FormCreateDrilldown.drilldownAction": "操作", + "xpack.uiActionsEnhanced.drilldowns.components.FormCreateDrilldown.nameOfDrilldown": "名称", + "xpack.uiActionsEnhanced.drilldowns.components.FormCreateDrilldown.untitledDrilldown": "未命名向下钻取", + "xpack.uiActionsEnhanced.drilldowns.components.FormDrilldownWizard.getMoreActionsLinkLabel": "获取更多的操作", + "xpack.uiActionsEnhanced.drilldowns.components.ListManageDrilldowns.createDrilldownButtonLabel": "新建", + "xpack.uiActionsEnhanced.drilldowns.components.ListManageDrilldowns.deleteDrilldownsButtonLabel": "删除 ({count})", + "xpack.uiActionsEnhanced.drilldowns.components.ListManageDrilldowns.editDrilldownButtonLabel": "编辑", + "xpack.uiActionsEnhanced.drilldowns.components.ListManageDrilldowns.selectThisDrilldownCheckboxLabel": "选择此向下钻取", "xpack.upgradeAssistant.appTitle": "{version} 升级助手", "xpack.upgradeAssistant.checkupTab.backUpCallout.calloutBody.calloutDetail": "使用 {snapshotRestoreDocsButton} 备份您的数据。", "xpack.upgradeAssistant.checkupTab.backUpCallout.calloutBody.snapshotRestoreDocsButtonLabel": "快照和还原 API", @@ -16152,6 +18973,27 @@ "xpack.upgradeAssistant.tabs.upgradingInterstitial.upgradeCompleteTitle": "您的集群已升级", "xpack.upgradeAssistant.tabs.upgradingInterstitial.upgradingDescription": "一个或多个 Elasticsearch 节点的 Elasticsearch 版本比 Kibana 版本新。所有节点升级后,请升级 Kibana。", "xpack.upgradeAssistant.tabs.upgradingInterstitial.upgradingTitle": "您的集群正在升级", + "xpack.uptime.addDataButtonLabel": "添加数据", + "xpack.uptime.alerts.anomaly.criteriaExpression.ariaLabel": "显示选定监测的条件的表达式。", + "xpack.uptime.alerts.anomaly.criteriaExpression.description": "当监测", + "xpack.uptime.alerts.anomaly.scoreExpression.ariaLabel": "显示异常告警阈值的条件的表达式。", + "xpack.uptime.alerts.anomaly.scoreExpression.description": "具有异常,严重性为", + "xpack.uptime.alerts.availability.emptyMessage": "没有监测低于可用性阈值 ({threshold} %)", + "xpack.uptime.alerts.availability.monitorSummary": "{nameOrId}({url}):{availabilityRatio}%", + "xpack.uptime.alerts.availability.multiItemTitle": "低于可用性阈值 ({threshold} %) 的排名前 {monitorCount} 监测:\n", + "xpack.uptime.alerts.availability.singleItemTitle": "低于可用性阈值 ({threshold} %) 的监测:\n", + "xpack.uptime.alerts.durationAnomaly": "Uptime 持续时间异常", + "xpack.uptime.alerts.durationAnomaly.actionVariables.state.anomalyStartTimestamp": "异常开始的 ISO8601 时间戳。", + "xpack.uptime.alerts.durationAnomaly.actionVariables.state.expectedResponseTime": "预期响应时间", + "xpack.uptime.alerts.durationAnomaly.actionVariables.state.monitor": "名称或 ID 的友好呈现,建议类似于 My Monitor 的名称", + "xpack.uptime.alerts.durationAnomaly.actionVariables.state.monitorId": "监测的 ID。", + "xpack.uptime.alerts.durationAnomaly.actionVariables.state.monitorUrl": "监测的 URL。", + "xpack.uptime.alerts.durationAnomaly.actionVariables.state.observerLocation": "执行 Heartbeat 检查的观察者位置。", + "xpack.uptime.alerts.durationAnomaly.actionVariables.state.severity": "异常的严重性。", + "xpack.uptime.alerts.durationAnomaly.actionVariables.state.severityScore": "异常严重性分数", + "xpack.uptime.alerts.durationAnomaly.actionVariables.state.slowestAnomalyResponse": "在附加单位(ms、s)的异常存储桶期间最慢的响应时间。", + "xpack.uptime.alerts.durationAnomaly.clientName": "Uptime 持续时间异常", + "xpack.uptime.alerts.durationAnomaly.defaultActionMessage": "{anomalyStartTimestamp} 在 url {monitorUrl} 的 {monitor} 上检测到异常({severity} 级别)响应时间。异常严重性分数为 {severityScore}。\n从位置 {observerLocation} 检测到高达 {slowestAnomalyResponse} 的响应时间。预期响应时间为 {expectedResponseTime}。", "xpack.uptime.alerts.message.emptyTitle": "未接收到已关闭监测 ID", "xpack.uptime.alerts.message.fullListOverflow": "...以及 {overflowCount} 个其他{pluralizedMonitor}", "xpack.uptime.alerts.message.multipleTitle": "已关闭监测: ", @@ -16172,7 +19014,18 @@ "xpack.uptime.alerts.monitorStatus.addFilter.port": "端口", "xpack.uptime.alerts.monitorStatus.addFilter.tag": "标记", "xpack.uptime.alerts.monitorStatus.addFilter.type": "类型", + "xpack.uptime.alerts.monitorStatus.availability.isEnabledCheckbox.label": "可用性", + "xpack.uptime.alerts.monitorStatus.availability.threshold.ariaLabel": "指定此告警的可用性阈值", + "xpack.uptime.alerts.monitorStatus.availability.threshold.description": "匹配的监测运行于", + "xpack.uptime.alerts.monitorStatus.availability.threshold.input.ariaLabel": "输入用于检查此告警的可用性阈值", + "xpack.uptime.alerts.monitorStatus.availability.threshold.value": "< {value}% 的检查", + "xpack.uptime.alerts.monitorStatus.availability.timerangeValueField.ariaLabel": "输入告警可用性检查的单位数。", + "xpack.uptime.alerts.monitorStatus.availability.timerangeValueField.expression": "(之内)过去", + "xpack.uptime.alerts.monitorStatus.availability.timerangeValueField.popover.ariaLabel": "指定跟踪时间范围的可用性", + "xpack.uptime.alerts.monitorStatus.availability.unit.headline": "选择时间范围单位", + "xpack.uptime.alerts.monitorStatus.availability.unit.selectable": "使用此选择来设置此告警的可用性范围单位", "xpack.uptime.alerts.monitorStatus.clientName": "运行时间监测状态", + "xpack.uptime.alerts.monitorStatus.defaultActionMessage": "{contextMessage}\n上次触发时间:{lastTriggered}\n", "xpack.uptime.alerts.monitorStatus.filterBar.ariaLabel": "允许对监测状态告警使用筛选条件的输入", "xpack.uptime.alerts.monitorStatus.filters.anyLocation": "任意位置", "xpack.uptime.alerts.monitorStatus.filters.anyPort": "任意端口", @@ -16191,21 +19044,30 @@ "xpack.uptime.alerts.monitorStatus.numTimesExpression.ariaLabel": "打开弹出框以输入已关闭计数", "xpack.uptime.alerts.monitorStatus.numTimesExpression.matchingMonitors.description": "匹配的监测关闭 >", "xpack.uptime.alerts.monitorStatus.numTimesField.ariaLabel": "输入触发告警的已关闭计数", - "xpack.uptime.alerts.monitorStatus.oldAlertCallout.title": "您正在编辑较旧的告警,某些字段可能不自动填充。", + "xpack.uptime.alerts.monitorStatus.oldAlertCallout.title": "您可能正在编辑较旧的告警,某些字段可能不自动填充。", + "xpack.uptime.alerts.monitorStatus.statusEnabledCheck.label": "状态检查", "xpack.uptime.alerts.monitorStatus.timerangeOption.days": "天", "xpack.uptime.alerts.monitorStatus.timerangeOption.hours": "小时", "xpack.uptime.alerts.monitorStatus.timerangeOption.minutes": "分钟", + "xpack.uptime.alerts.monitorStatus.timerangeOption.months": "个月", "xpack.uptime.alerts.monitorStatus.timerangeOption.seconds": "秒", + "xpack.uptime.alerts.monitorStatus.timerangeOption.weeks": "周", + "xpack.uptime.alerts.monitorStatus.timerangeOption.years": "年", "xpack.uptime.alerts.monitorStatus.timerangeSelectionHeader": "选择时间范围单位", "xpack.uptime.alerts.monitorStatus.timerangeUnitExpression.ariaLabel": "打开时间范围单位选择字段的弹出框", "xpack.uptime.alerts.monitorStatus.timerangeUnitSelectable": "告警应使用的时间范围单位的可选择字段", "xpack.uptime.alerts.monitorStatus.timerangeValueExpression.ariaLabel": "打开时间范围值字段的弹出框", "xpack.uptime.alerts.monitorStatus.timerangeValueField.ariaLabel": "输入告警范围的时间单位数目", + "xpack.uptime.alerts.monitorStatus.timerangeValueField.expression": "之内", + "xpack.uptime.alerts.monitorStatus.timerangeValueField.value": "上一 {value}", "xpack.uptime.alerts.monitorStatus.title.label": "运行时间监测状态", "xpack.uptime.alerts.timerangeUnitSelectable.daysOption.ariaLabel": "“天”时间范围选择项", "xpack.uptime.alerts.timerangeUnitSelectable.hoursOption.ariaLabel": "“小时”时间范围选择项", "xpack.uptime.alerts.timerangeUnitSelectable.minutesOption.ariaLabel": "“分钟”时间范围选择项", + "xpack.uptime.alerts.timerangeUnitSelectable.monthsOption.ariaLabel": "“月”时间范围选择项", "xpack.uptime.alerts.timerangeUnitSelectable.secondsOption.ariaLabel": "“秒”时间范围选择项", + "xpack.uptime.alerts.timerangeUnitSelectable.weeksOption.ariaLabel": "“周”时间范围选择项", + "xpack.uptime.alerts.timerangeUnitSelectable.yearsOption.ariaLabel": "“年”时间范围选择项", "xpack.uptime.alerts.tls": "Uptime TLS", "xpack.uptime.alerts.tls.actionVariables.state.agingCommonNameAndDate": "检测到的证书的常见名称和到期日期/时间。", "xpack.uptime.alerts.tls.actionVariables.state.agingCount": "检测到即将过时的证书数目。", @@ -16219,7 +19081,7 @@ "xpack.uptime.alerts.tls.criteriaExpression.ariaLabel": "显示此告警监视的监测条件的表达式", "xpack.uptime.alerts.tls.criteriaExpression.description": "当", "xpack.uptime.alerts.tls.criteriaExpression.value": "任意监测", - "xpack.uptime.alerts.tls.defaultActionMessage": "已检测到 {count} 个即将过期或即将过时的 TLS 证书。\n\n{expiringConditionalOpen}\n即将过期的证书计数:{expiringCount}\n即将过期的证书:{expiringCommonNameAndDate}\n{expiringConditionalClose} \n\n{agingConditionalOpen}\n过时的证书计数:{agingCount}\n过时的证书:{agingCommonNameAndDate}\n{agingConditionalClose}\n", + "xpack.uptime.alerts.tls.defaultActionMessage": "检测到 {count} 个 TLS 证书即将过期或即将过时。\n\n{expiringConditionalOpen}\n即将过期的证书计数:{expiringCount}\n即将过期的证书:{expiringCommonNameAndDate}\n{expiringConditionalClose}\n\n{agingConditionalOpen}\n过时的证书计数:{agingCount}\n过时的证书:{agingCommonNameAndDate}\n{agingConditionalClose}\n", "xpack.uptime.alerts.tls.expirationExpression.ariaLabel": "显示将触发证书过期 TLS 告警的阈值的表达式", "xpack.uptime.alerts.tls.expirationExpression.description": "具有将在", "xpack.uptime.alerts.tls.expirationExpression.value": "{value} 天内的证书", @@ -16232,6 +19094,7 @@ "xpack.uptime.alertsPopover.toggleButton.ariaLabel": "打开告警上下文菜单", "xpack.uptime.apmIntegrationAction.description": "在 APM 中搜索此监测", "xpack.uptime.apmIntegrationAction.text": "在 APM 中查找域", + "xpack.uptime.availabilityLabelText": "{value} %", "xpack.uptime.badge.readOnly.text": "只读", "xpack.uptime.badge.readOnly.tooltip": "无法保存", "xpack.uptime.breadcrumbs.overviewBreadcrumbText": "运行时间", @@ -16240,6 +19103,7 @@ "xpack.uptime.certificates.returnToOverviewLinkLabel": "返回到概览", "xpack.uptime.certificates.settingsLinkLabel": "设置", "xpack.uptime.certs.expired": "已过期", + "xpack.uptime.certs.expires": "过期", "xpack.uptime.certs.expireSoon": "即将过期", "xpack.uptime.certs.list.ageCol": "使用时间", "xpack.uptime.certs.list.commonName": "常见名称", @@ -16253,9 +19117,15 @@ "xpack.uptime.certs.list.validUntil": "失效日期", "xpack.uptime.certs.ok": "正常", "xpack.uptime.certs.searchCerts": "搜索证书", + "xpack.uptime.certs.status.ok.label": " 对于 {okRelativeDate}", "xpack.uptime.charts.mlAnnotation.header": "分数:{score}", "xpack.uptime.charts.mlAnnotation.severity": "严重性:{severity}", "xpack.uptime.components.embeddables.embeddedMap.embeddablePanelTitle": "监测观察者位置地图", + "xpack.uptime.controls.selectSeverity.criticalLabel": "紧急", + "xpack.uptime.controls.selectSeverity.majorLabel": "重大", + "xpack.uptime.controls.selectSeverity.minorLabel": "轻微", + "xpack.uptime.controls.selectSeverity.scoreDetailsDescription": "分数 {value} 及以上", + "xpack.uptime.controls.selectSeverity.warningLabel": "警告", "xpack.uptime.durationChart.emptyPrompt.description": "在选定时间范围内此监测从未{emphasizedText}。", "xpack.uptime.durationChart.emptyPrompt.title": "没有持续时间数据", "xpack.uptime.emptyState.configureHeartbeatIndexSettings": "如果您已设置 Heartbeat 并已确认将数据发送到 Elasticsearch,则请更新您的索引模式设置并确保它们符合您的 Heartbeat 配置。", @@ -16286,12 +19156,15 @@ "xpack.uptime.locationMap.locations.missing.message1": "在我们的文档中获取更多的信息。", "xpack.uptime.locationMap.locations.missing.title": "地理信息缺失", "xpack.uptime.locationName.helpLinkAnnotation": "添加位置", + "xpack.uptime.mapToolTip.AvailabilityStat.title": "{value} %", "xpack.uptime.ml.durationChart.exploreInMlApp": "在 ML 应用中浏览", "xpack.uptime.ml.enableAnomalyDetectionPanel.anomalyDetectionTitle": "异常检测", "xpack.uptime.ml.enableAnomalyDetectionPanel.cancelLabel": "取消", "xpack.uptime.ml.enableAnomalyDetectionPanel.createMLJobDescription": "在此处可以创建 Machine Learning 作业,以便为运行时间监测计算\n 响应持续时间的异常分数。启用后,详情页面上的监测持续时间图表\n 将显示预期边界并使用异常标注图表。您还可能\n 识别在所有地理区域的延迟增长时段。", "xpack.uptime.ml.enableAnomalyDetectionPanel.createNewJobButtonLabel": "创建新作业", + "xpack.uptime.ml.enableAnomalyDetectionPanel.disableAnomalyAlert": "禁用异常告警", "xpack.uptime.ml.enableAnomalyDetectionPanel.disableAnomalyDetectionTitle": "禁用异常检测", + "xpack.uptime.ml.enableAnomalyDetectionPanel.enableAnomalyAlert": "启用异常告警", "xpack.uptime.ml.enableAnomalyDetectionPanel.enableAnomalyDetectionTitle": "启用异常检测", "xpack.uptime.ml.enableAnomalyDetectionPanel.jobCreatedNotificationText": "现在正在运行响应持续时间图表的分析。可能要花费点时间,才会将结果添加到响应时间图表。", "xpack.uptime.ml.enableAnomalyDetectionPanel.jobCreatedNotificationText.viewJobLinkText": "查看作业", @@ -16311,6 +19184,7 @@ "xpack.uptime.monitorCharts.durationChart.leftAxis.title": "持续时间 (ms)", "xpack.uptime.monitorCharts.monitorDuration.titleLabel": "监测持续时间(毫秒)", "xpack.uptime.monitorCharts.monitorDuration.titleLabelWithAnomaly": "监测持续时间(异常:{noOfAnomalies})", + "xpack.uptime.monitorDetails.ml.confirmAlertDeleteMessage": "确定要删除异常告警?", "xpack.uptime.monitorDetails.ml.confirmDeleteMessage": "是否确定要删除此作业?", "xpack.uptime.monitorDetails.ml.deleteJobWarning": "删除作业可能会非常耗时。删除将在后台进行,数据可能不会马上消失。", "xpack.uptime.monitorDetails.ml.deleteMessage": "正在删除作业......", @@ -16368,8 +19242,16 @@ "xpack.uptime.monitorStatusBar.loadingMessage": "正在加载……", "xpack.uptime.monitorStatusBar.locations.oneLocStatus": "在 {loc} 位置{status}", "xpack.uptime.monitorStatusBar.locations.upStatus": "在 {loc} 位置{status}", + "xpack.uptime.monitorStatusBar.monitor.availability": "总体可用性", + "xpack.uptime.monitorStatusBar.monitor.availabilityReport.availability": "可用性", + "xpack.uptime.monitorStatusBar.monitor.availabilityReport.lastCheck": "上次检查", + "xpack.uptime.monitorStatusBar.monitor.availabilityReport.location": "位置", + "xpack.uptime.monitorStatusBar.monitor.id": "监测 ID", + "xpack.uptime.monitorStatusBar.monitor.monitoringFrom": "正监测自", + "xpack.uptime.monitorStatusBar.monitor.monitoringFrom.listToMap": "更改到地图视图以按位置检查可用性。", + "xpack.uptime.monitorStatusBar.monitor.monitoringFrom.MapToList": "更改到列表视图以按位置检查可用性。", "xpack.uptime.monitorStatusBar.monitorUrlLinkAriaLabel": "监测 URL 链接", - "xpack.uptime.monitorStatusBar.sslCertificate.title": "证书:", + "xpack.uptime.monitorStatusBar.sslCertificate.title": "TLS 证书", "xpack.uptime.monitorStatusBar.timestampFromNowTextAriaLabel": "自上次检查以来经过的时间", "xpack.uptime.navigateToAlertingButton.content": "管理告警", "xpack.uptime.navigateToAlertingUi": "离开 Uptime 并前往“Alerting 管理”页面", diff --git a/x-pack/plugins/uptime/public/components/common/charts/__tests__/ping_histogram.test.tsx b/x-pack/plugins/uptime/public/components/common/charts/__tests__/ping_histogram.test.tsx index 57a38f2a949e7..73c6ee43ccd07 100644 --- a/x-pack/plugins/uptime/public/components/common/charts/__tests__/ping_histogram.test.tsx +++ b/x-pack/plugins/uptime/public/components/common/charts/__tests__/ping_histogram.test.tsx @@ -7,8 +7,13 @@ import React from 'react'; import { PingHistogramComponent, PingHistogramComponentProps } from '../ping_histogram'; import { renderWithRouter, shallowWithRouter, MountWithReduxProvider } from '../../../../lib'; +import moment from 'moment'; describe('PingHistogram component', () => { + beforeAll(() => { + moment.prototype.fromNow = jest.fn(() => 'a year ago'); + }); + const props: PingHistogramComponentProps = { absoluteStartDate: 1548697920000, absoluteEndDate: 1548700920000, diff --git a/x-pack/plugins/uptime/server/lib/requests/get_ping_histogram.ts b/x-pack/plugins/uptime/server/lib/requests/get_ping_histogram.ts index a74b55c24e227..970d9ad166982 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_ping_histogram.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_ping_histogram.ts @@ -8,6 +8,7 @@ import { UMElasticsearchQueryFn } from '../adapters'; import { getFilterClause } from '../helper'; import { HistogramResult, HistogramQueryResult } from '../../../common/runtime_types'; import { QUERY } from '../../../common/constants'; +import { getHistogramInterval } from '../helper/get_histogram_interval'; export interface GetPingHistogramParams { /** @member dateRangeStart timestamp bounds */ @@ -36,22 +37,6 @@ export const getPingHistogram: UMElasticsearchQueryFn< } const filter = getFilterClause(from, to, additionalFilters); - const seriesHistogram: any = {}; - - if (bucketSize) { - seriesHistogram.date_histogram = { - field: '@timestamp', - fixed_interval: bucketSize, - missing: 0, - }; - } else { - seriesHistogram.auto_date_histogram = { - field: '@timestamp', - buckets: QUERY.DEFAULT_BUCKET_COUNT, - missing: 0, - }; - } - const params = { index: dynamicSettings.heartbeatIndices, body: { @@ -63,7 +48,12 @@ export const getPingHistogram: UMElasticsearchQueryFn< size: 0, aggs: { timeseries: { - ...seriesHistogram, + date_histogram: { + field: '@timestamp', + fixed_interval: + bucketSize || getHistogramInterval(from, to, QUERY.DEFAULT_BUCKET_COUNT) + 'ms', + missing: 0, + }, aggs: { down: { filter: { diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/index.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/index.ts index 0970738b630c4..a23f0fa835313 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/index.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/index.ts @@ -27,8 +27,5 @@ export default function alertingTests({ loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./alerts_space1')); loadTestFile(require.resolve('./alerts_default_space')); loadTestFile(require.resolve('./builtin_alert_types')); - - // note that this test will destroy existing spaces - loadTestFile(require.resolve('./migrations')); }); } diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/migrations.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/migrations.ts deleted file mode 100644 index fc61f59d129d7..0000000000000 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/migrations.ts +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import expect from '@kbn/expect'; -import { getUrlPrefix } from '../../../common/lib'; -import { FtrProviderContext } from '../../../common/ftr_provider_context'; - -// eslint-disable-next-line import/no-default-export -export default function createGetTests({ getService }: FtrProviderContext) { - const supertest = getService('supertest'); - const esArchiver = getService('esArchiver'); - - describe('migrations', () => { - before(async () => { - await esArchiver.load('alerts'); - }); - - after(async () => { - await esArchiver.unload('alerts'); - }); - - it('7.9.0 migrates the `alerting` consumer to be the `alerts`', async () => { - const response = await supertest.get( - `${getUrlPrefix(``)}/api/alerts/alert/74f3e6d7-b7bb-477d-ac28-92ee22728e6e` - ); - - expect(response.status).to.eql(200); - expect(response.body.consumer).to.equal('alerts'); - }); - }); -} diff --git a/x-pack/test/api_integration/apis/management/ingest_pipelines/ingest_pipelines.ts b/x-pack/test/api_integration/apis/management/ingest_pipelines/ingest_pipelines.ts index 6a827298521dd..b3fab42a46114 100644 --- a/x-pack/test/api_integration/apis/management/ingest_pipelines/ingest_pipelines.ts +++ b/x-pack/test/api_integration/apis/management/ingest_pipelines/ingest_pipelines.ts @@ -14,16 +14,26 @@ const API_BASE_PATH = '/api/ingest_pipelines'; export default function ({ getService }: FtrProviderContext) { const supertest = getService('supertest'); - const { createPipeline, deletePipeline } = registerEsHelpers(getService); + const { createPipeline, deletePipeline, cleanupPipelines } = registerEsHelpers(getService); + + describe('Pipelines', function () { + after(async () => { + await cleanupPipelines(); + }); - describe.skip('Pipelines', function () { describe('Create', () => { const PIPELINE_ID = 'test_create_pipeline'; const REQUIRED_FIELDS_PIPELINE_ID = 'test_create_required_fields_pipeline'; - after(() => { - deletePipeline(PIPELINE_ID); - deletePipeline(REQUIRED_FIELDS_PIPELINE_ID); + after(async () => { + // Clean up any pipelines created in test cases + await Promise.all([PIPELINE_ID, REQUIRED_FIELDS_PIPELINE_ID].map(deletePipeline)).catch( + (err) => { + // eslint-disable-next-line no-console + console.log(`[Cleanup error] Error deleting pipelines: ${err.message}`); + throw err; + } + ); }); it('should create a pipeline', async () => { @@ -127,8 +137,16 @@ export default function ({ getService }: FtrProviderContext) { ], }; - before(() => createPipeline({ body: PIPELINE, id: PIPELINE_ID })); - after(() => deletePipeline(PIPELINE_ID)); + before(async () => { + // Create pipeline that can be used to test PUT request + try { + await createPipeline({ body: PIPELINE, id: PIPELINE_ID }, true); + } catch (err) { + // eslint-disable-next-line no-console + console.log('[Setup error] Error creating ingest node pipeline'); + throw err; + } + }); it('should allow an existing pipeline to be updated', async () => { const uri = `${API_BASE_PATH}/${PIPELINE_ID}`; @@ -185,7 +203,7 @@ export default function ({ getService }: FtrProviderContext) { }); describe('Get', () => { - const PIPELINE_ID = 'test_pipeline'; + const PIPELINE_ID = 'test_get_pipeline'; const PIPELINE = { description: 'test pipeline description', processors: [ @@ -198,8 +216,16 @@ export default function ({ getService }: FtrProviderContext) { version: 1, }; - before(() => createPipeline({ body: PIPELINE, id: PIPELINE_ID })); - after(() => deletePipeline(PIPELINE_ID)); + before(async () => { + // Create pipeline that can be used to test GET request + try { + await createPipeline({ body: PIPELINE, id: PIPELINE_ID }, true); + } catch (err) { + // eslint-disable-next-line no-console + console.log('[Setup error] Error creating ingest node pipeline'); + throw err; + } + }); describe('all pipelines', () => { it('should return an array of pipelines', async () => { @@ -245,29 +271,40 @@ export default function ({ getService }: FtrProviderContext) { version: 1, }; + const pipelineA = { body: PIPELINE, id: 'test_delete_pipeline_a' }; + const pipelineB = { body: PIPELINE, id: 'test_delete_pipeline_b' }; + const pipelineC = { body: PIPELINE, id: 'test_delete_pipeline_c' }; + const pipelineD = { body: PIPELINE, id: 'test_delete_pipeline_d' }; + + before(async () => { + // Create several pipelines that can be used to test deletion + await Promise.all( + [pipelineA, pipelineB, pipelineC, pipelineD].map((pipeline) => createPipeline(pipeline)) + ).catch((err) => { + // eslint-disable-next-line no-console + console.log(`[Setup error] Error creating pipelines: ${err.message}`); + throw err; + }); + }); + it('should delete a pipeline', async () => { - // Create pipeline to be deleted - const PIPELINE_ID = 'test_delete_pipeline'; - createPipeline({ body: PIPELINE, id: PIPELINE_ID }); + const { id } = pipelineA; - const uri = `${API_BASE_PATH}/${PIPELINE_ID}`; + const uri = `${API_BASE_PATH}/${id}`; const { body } = await supertest.delete(uri).set('kbn-xsrf', 'xxx').expect(200); expect(body).to.eql({ - itemsDeleted: [PIPELINE_ID], + itemsDeleted: [id], errors: [], }); }); it('should delete multiple pipelines', async () => { - // Create pipelines to be deleted - const PIPELINE_ONE_ID = 'test_delete_pipeline_1'; - const PIPELINE_TWO_ID = 'test_delete_pipeline_2'; - createPipeline({ body: PIPELINE, id: PIPELINE_ONE_ID }); - createPipeline({ body: PIPELINE, id: PIPELINE_TWO_ID }); + const { id: pipelineBId } = pipelineB; + const { id: pipelineCId } = pipelineC; - const uri = `${API_BASE_PATH}/${PIPELINE_ONE_ID},${PIPELINE_TWO_ID}`; + const uri = `${API_BASE_PATH}/${pipelineBId},${pipelineCId}`; const { body: { itemsDeleted, errors }, @@ -276,24 +313,21 @@ export default function ({ getService }: FtrProviderContext) { expect(errors).to.eql([]); // The itemsDeleted array order isn't guaranteed, so we assert against each pipeline name instead - [PIPELINE_ONE_ID, PIPELINE_TWO_ID].forEach((pipelineName) => { + [pipelineBId, pipelineCId].forEach((pipelineName) => { expect(itemsDeleted.includes(pipelineName)).to.be(true); }); }); it('should return an error for any pipelines not sucessfully deleted', async () => { const PIPELINE_DOES_NOT_EXIST = 'pipeline_does_not_exist'; + const { id: existingPipelineId } = pipelineD; - // Create pipeline to be deleted - const PIPELINE_ONE_ID = 'test_delete_pipeline_1'; - createPipeline({ body: PIPELINE, id: PIPELINE_ONE_ID }); - - const uri = `${API_BASE_PATH}/${PIPELINE_ONE_ID},${PIPELINE_DOES_NOT_EXIST}`; + const uri = `${API_BASE_PATH}/${existingPipelineId},${PIPELINE_DOES_NOT_EXIST}`; const { body } = await supertest.delete(uri).set('kbn-xsrf', 'xxx').expect(200); expect(body).to.eql({ - itemsDeleted: [PIPELINE_ONE_ID], + itemsDeleted: [existingPipelineId], errors: [ { name: PIPELINE_DOES_NOT_EXIST, diff --git a/x-pack/test/api_integration/apis/management/ingest_pipelines/lib/elasticsearch.ts b/x-pack/test/api_integration/apis/management/ingest_pipelines/lib/elasticsearch.ts index 2f42596a66b54..6de91e1154a85 100644 --- a/x-pack/test/api_integration/apis/management/ingest_pipelines/lib/elasticsearch.ts +++ b/x-pack/test/api_integration/apis/management/ingest_pipelines/lib/elasticsearch.ts @@ -26,14 +26,33 @@ interface Pipeline { * @param {ElasticsearchClient} es The Elasticsearch client instance */ export const registerEsHelpers = (getService: FtrProviderContext['getService']) => { + let pipelinesCreated: string[] = []; + const es = getService('legacyEs'); - const createPipeline = (pipeline: Pipeline) => es.ingest.putPipeline(pipeline); + const createPipeline = (pipeline: Pipeline, cachePipeline?: boolean) => { + if (cachePipeline) { + pipelinesCreated.push(pipeline.id); + } + + return es.ingest.putPipeline(pipeline); + }; const deletePipeline = (pipelineId: string) => es.ingest.deletePipeline({ id: pipelineId }); + const cleanupPipelines = () => + Promise.all(pipelinesCreated.map(deletePipeline)) + .then(() => { + pipelinesCreated = []; + }) + .catch((err) => { + // eslint-disable-next-line no-console + console.log(`[Cleanup error] Error deleting ES resources: ${err.message}`); + }); + return { createPipeline, deletePipeline, + cleanupPipelines, }; }; diff --git a/x-pack/test/api_integration/apis/security/privileges.ts b/x-pack/test/api_integration/apis/security/privileges.ts index 59fcfae5db3cf..b3de255ce874a 100644 --- a/x-pack/test/api_integration/apis/security/privileges.ts +++ b/x-pack/test/api_integration/apis/security/privileges.ts @@ -41,7 +41,7 @@ export default function ({ getService }: FtrProviderContext) { }, global: ['all', 'read'], space: ['all', 'read'], - reserved: ['ml_user', 'ml_admin', 'monitoring'], + reserved: ['ml_user', 'ml_admin', 'ml_apm_user', 'monitoring'], }; await supertest diff --git a/x-pack/test/api_integration/apis/security/privileges_basic.ts b/x-pack/test/api_integration/apis/security/privileges_basic.ts index 5c2a2875852d6..4bbdb644fec90 100644 --- a/x-pack/test/api_integration/apis/security/privileges_basic.ts +++ b/x-pack/test/api_integration/apis/security/privileges_basic.ts @@ -39,7 +39,7 @@ export default function ({ getService }: FtrProviderContext) { }, global: ['all', 'read'], space: ['all', 'read'], - reserved: ['ml_user', 'ml_admin', 'monitoring'], + reserved: ['ml_user', 'ml_admin', 'ml_apm_user', 'monitoring'], }; await supertest diff --git a/x-pack/test/api_integration/apis/uptime/rest/fixtures/ping_histogram.json b/x-pack/test/api_integration/apis/uptime/rest/fixtures/ping_histogram.json index 562ba64c24b0b..85ce545ed92b0 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/fixtures/ping_histogram.json +++ b/x-pack/test/api_integration/apis/uptime/rest/fixtures/ping_histogram.json @@ -1,121 +1,157 @@ { "histogram": [ { - "x": 1568172664000, + "x": 1568172657286, "downCount": 7, "upCount": 93, "y": 1 }, { - "x": 1568172694000, + "x": 1568172680087, "downCount": 7, "upCount": 93, "y": 1 }, { - "x": 1568172724000, + "x": 1568172702888, "downCount": 7, "upCount": 93, "y": 1 }, { - "x": 1568172754000, + "x": 1568172725689, + "downCount": 0, + "upCount": 0, + "y": 1 + }, + { + "x": 1568172748490, "downCount": 7, "upCount": 93, "y": 1 }, { - "x": 1568172784000, + "x": 1568172771291, "downCount": 7, "upCount": 93, "y": 1 }, { - "x": 1568172814000, + "x": 1568172794092, "downCount": 8, "upCount": 92, "y": 1 }, { - "x": 1568172844000, + "x": 1568172816893, + "downCount": 0, + "upCount": 0, + "y": 1 + }, + { + "x": 1568172839694, "downCount": 7, "upCount": 93, "y": 1 }, { - "x": 1568172874000, + "x": 1568172862495, "downCount": 7, "upCount": 93, "y": 1 }, { - "x": 1568172904000, + "x": 1568172885296, "downCount": 7, "upCount": 93, "y": 1 }, { - "x": 1568172934000, + "x": 1568172908097, + "downCount": 0, + "upCount": 0, + "y": 1 + }, + { + "x": 1568172930898, "downCount": 7, "upCount": 93, "y": 1 }, { - "x": 1568172964000, + "x": 1568172953699, "downCount": 7, "upCount": 93, "y": 1 }, { - "x": 1568172994000, + "x": 1568172976500, "downCount": 8, "upCount": 92, "y": 1 }, { - "x": 1568173024000, + "x": 1568172999301, + "downCount": 0, + "upCount": 0, + "y": 1 + }, + { + "x": 1568173022102, "downCount": 7, "upCount": 93, "y": 1 }, { - "x": 1568173054000, + "x": 1568173044903, "downCount": 7, "upCount": 93, "y": 1 }, { - "x": 1568173084000, + "x": 1568173067704, "downCount": 7, "upCount": 93, "y": 1 }, { - "x": 1568173114000, + "x": 1568173090505, + "downCount": 0, + "upCount": 0, + "y": 1 + }, + { + "x": 1568173113306, "downCount": 7, "upCount": 93, "y": 1 }, { - "x": 1568173144000, + "x": 1568173136107, "downCount": 7, "upCount": 93, "y": 1 }, { - "x": 1568173174000, + "x": 1568173158908, "downCount": 8, "upCount": 92, "y": 1 }, { - "x": 1568173204000, + "x": 1568173181709, "downCount": 7, "upCount": 93, "y": 1 }, { - "x": 1568173234000, + "x": 1568173204510, + "downCount": 0, + "upCount": 0, + "y": 1 + }, + { + "x": 1568173227311, "downCount": 7, "upCount": 93, "y": 1 diff --git a/x-pack/test/api_integration/apis/uptime/rest/fixtures/ping_histogram_by_filter.json b/x-pack/test/api_integration/apis/uptime/rest/fixtures/ping_histogram_by_filter.json index 42be715c4acd4..fe5dc9dd3da3f 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/fixtures/ping_histogram_by_filter.json +++ b/x-pack/test/api_integration/apis/uptime/rest/fixtures/ping_histogram_by_filter.json @@ -1,121 +1,157 @@ { "histogram": [ { - "x": 1568172664000, + "x": 1568172657286, "downCount": 0, "upCount": 93, "y": 1 }, { - "x": 1568172694000, + "x": 1568172680087, "downCount": 0, "upCount": 93, "y": 1 }, { - "x": 1568172724000, + "x": 1568172702888, "downCount": 0, "upCount": 93, "y": 1 }, { - "x": 1568172754000, + "x": 1568172725689, + "downCount": 0, + "upCount": 0, + "y": 1 + }, + { + "x": 1568172748490, "downCount": 0, "upCount": 93, "y": 1 }, { - "x": 1568172784000, + "x": 1568172771291, "downCount": 0, "upCount": 93, "y": 1 }, { - "x": 1568172814000, + "x": 1568172794092, "downCount": 0, "upCount": 92, "y": 1 }, { - "x": 1568172844000, + "x": 1568172816893, + "downCount": 0, + "upCount": 0, + "y": 1 + }, + { + "x": 1568172839694, "downCount": 0, "upCount": 93, "y": 1 }, { - "x": 1568172874000, + "x": 1568172862495, "downCount": 0, "upCount": 93, "y": 1 }, { - "x": 1568172904000, + "x": 1568172885296, "downCount": 0, "upCount": 93, "y": 1 }, { - "x": 1568172934000, + "x": 1568172908097, + "downCount": 0, + "upCount": 0, + "y": 1 + }, + { + "x": 1568172930898, "downCount": 0, "upCount": 93, "y": 1 }, { - "x": 1568172964000, + "x": 1568172953699, "downCount": 0, "upCount": 93, "y": 1 }, { - "x": 1568172994000, + "x": 1568172976500, "downCount": 0, "upCount": 92, "y": 1 }, { - "x": 1568173024000, + "x": 1568172999301, + "downCount": 0, + "upCount": 0, + "y": 1 + }, + { + "x": 1568173022102, "downCount": 0, "upCount": 93, "y": 1 }, { - "x": 1568173054000, + "x": 1568173044903, "downCount": 0, "upCount": 93, "y": 1 }, { - "x": 1568173084000, + "x": 1568173067704, "downCount": 0, "upCount": 93, "y": 1 }, { - "x": 1568173114000, + "x": 1568173090505, + "downCount": 0, + "upCount": 0, + "y": 1 + }, + { + "x": 1568173113306, "downCount": 0, "upCount": 93, "y": 1 }, { - "x": 1568173144000, + "x": 1568173136107, "downCount": 0, "upCount": 93, "y": 1 }, { - "x": 1568173174000, + "x": 1568173158908, "downCount": 0, "upCount": 92, "y": 1 }, { - "x": 1568173204000, + "x": 1568173181709, "downCount": 0, "upCount": 93, "y": 1 }, { - "x": 1568173234000, + "x": 1568173204510, + "downCount": 0, + "upCount": 0, + "y": 1 + }, + { + "x": 1568173227311, "downCount": 0, "upCount": 93, "y": 1 diff --git a/x-pack/test/api_integration/apis/uptime/rest/fixtures/ping_histogram_by_id.json b/x-pack/test/api_integration/apis/uptime/rest/fixtures/ping_histogram_by_id.json index 9a726db616325..e54738cf5dbd7 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/fixtures/ping_histogram_by_id.json +++ b/x-pack/test/api_integration/apis/uptime/rest/fixtures/ping_histogram_by_id.json @@ -1,121 +1,157 @@ { "histogram": [ { - "x": 1568172664000, + "x": 1568172657286, "downCount": 0, "upCount": 1, "y": 1 }, { - "x": 1568172694000, + "x": 1568172680087, "downCount": 0, "upCount": 1, "y": 1 }, { - "x": 1568172724000, + "x": 1568172702888, "downCount": 0, "upCount": 1, "y": 1 }, { - "x": 1568172754000, + "x": 1568172725689, + "downCount": 0, + "upCount": 0, + "y": 1 + }, + { + "x": 1568172748490, "downCount": 0, "upCount": 1, "y": 1 }, { - "x": 1568172784000, + "x": 1568172771291, "downCount": 0, "upCount": 1, "y": 1 }, { - "x": 1568172814000, + "x": 1568172794092, "downCount": 0, "upCount": 1, "y": 1 }, { - "x": 1568172844000, + "x": 1568172816893, + "downCount": 0, + "upCount": 0, + "y": 1 + }, + { + "x": 1568172839694, "downCount": 0, "upCount": 1, "y": 1 }, { - "x": 1568172874000, + "x": 1568172862495, "downCount": 0, "upCount": 1, "y": 1 }, { - "x": 1568172904000, + "x": 1568172885296, "downCount": 0, "upCount": 1, "y": 1 }, { - "x": 1568172934000, + "x": 1568172908097, + "downCount": 0, + "upCount": 0, + "y": 1 + }, + { + "x": 1568172930898, "downCount": 0, "upCount": 1, "y": 1 }, { - "x": 1568172964000, + "x": 1568172953699, "downCount": 0, "upCount": 1, "y": 1 }, { - "x": 1568172994000, + "x": 1568172976500, "downCount": 0, "upCount": 1, "y": 1 }, { - "x": 1568173024000, + "x": 1568172999301, + "downCount": 0, + "upCount": 0, + "y": 1 + }, + { + "x": 1568173022102, "downCount": 0, "upCount": 1, "y": 1 }, { - "x": 1568173054000, + "x": 1568173044903, "downCount": 0, "upCount": 1, "y": 1 }, { - "x": 1568173084000, + "x": 1568173067704, "downCount": 0, "upCount": 1, "y": 1 }, { - "x": 1568173114000, + "x": 1568173090505, + "downCount": 0, + "upCount": 0, + "y": 1 + }, + { + "x": 1568173113306, "downCount": 0, "upCount": 1, "y": 1 }, { - "x": 1568173144000, + "x": 1568173136107, "downCount": 0, "upCount": 1, "y": 1 }, { - "x": 1568173174000, + "x": 1568173158908, "downCount": 0, "upCount": 1, "y": 1 }, { - "x": 1568173204000, + "x": 1568173181709, "downCount": 0, "upCount": 1, "y": 1 }, { - "x": 1568173234000, + "x": 1568173204510, + "downCount": 0, + "upCount": 0, + "y": 1 + }, + { + "x": 1568173227311, "downCount": 0, "upCount": 1, "y": 1 diff --git a/x-pack/test/api_integration/apis/uptime/rest/ping_histogram.ts b/x-pack/test/api_integration/apis/uptime/rest/ping_histogram.ts index ffcb1a829f0f8..b2504e3b921f7 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/ping_histogram.ts +++ b/x-pack/test/api_integration/apis/uptime/rest/ping_histogram.ts @@ -6,7 +6,6 @@ import { expectFixtureEql } from './helper/expect_fixture_eql'; import { FtrProviderContext } from '../../../ftr_provider_context'; -import { assertCloseTo } from '../../../../../plugins/uptime/server/lib/helper'; export default function ({ getService }: FtrProviderContext) { describe('pingHistogram', () => { @@ -21,10 +20,6 @@ export default function ({ getService }: FtrProviderContext) { ); const data = apiResponse.body; - // manually testing this value and then removing it to avoid flakiness - const { interval } = data; - assertCloseTo(interval, 22801, 100); - delete data.interval; expectFixtureEql(data, 'ping_histogram'); }); @@ -38,9 +33,6 @@ export default function ({ getService }: FtrProviderContext) { ); const data = apiResponse.body; - const { interval } = data; - assertCloseTo(interval, 22801, 100); - delete data.interval; expectFixtureEql(data, 'ping_histogram_by_id'); }); @@ -55,9 +47,6 @@ export default function ({ getService }: FtrProviderContext) { ); const data = apiResponse.body; - const { interval } = data; - assertCloseTo(interval, 22801, 100); - delete data.interval; expectFixtureEql(data, 'ping_histogram_by_filter'); }); }); diff --git a/x-pack/test/functional/apps/infra/feature_controls/infrastructure_security.ts b/x-pack/test/functional/apps/infra/feature_controls/infrastructure_security.ts index bc639bb4c0c65..a9fd7472a253c 100644 --- a/x-pack/test/functional/apps/infra/feature_controls/infrastructure_security.ts +++ b/x-pack/test/functional/apps/infra/feature_controls/infrastructure_security.ts @@ -423,19 +423,19 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { expect(navLinks).to.not.contain(['Metrics']); }); - it(`metrics app is inaccessible and Application Not Found message is rendered`, async () => { - await PageObjects.common.navigateToApp('infraOps'); - await testSubjects.existOrFail('~appNotFoundPageContent'); - await PageObjects.common.navigateToUrlWithBrowserHistory( - 'infraOps', - '/inventory', - undefined, - { - ensureCurrentUrl: false, - shouldLoginIfPrompted: false, - } + it(`metrics app is inaccessible and returns a 404`, async () => { + await PageObjects.common.navigateToActualUrl('infraOps', '', { + ensureCurrentUrl: false, + shouldLoginIfPrompted: false, + }); + const messageText = await PageObjects.common.getBodyText(); + expect(messageText).to.eql( + JSON.stringify({ + statusCode: 404, + error: 'Not Found', + message: 'Not Found', + }) ); - await testSubjects.existOrFail('~appNotFoundPageContent'); }); }); }); diff --git a/x-pack/test/functional/apps/infra/feature_controls/infrastructure_spaces.ts b/x-pack/test/functional/apps/infra/feature_controls/infrastructure_spaces.ts index 211a9ce718b56..1bf8ded69016b 100644 --- a/x-pack/test/functional/apps/infra/feature_controls/infrastructure_spaces.ts +++ b/x-pack/test/functional/apps/infra/feature_controls/infrastructure_spaces.ts @@ -79,21 +79,19 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { }); it(`metrics app is inaccessible and Application Not Found message is rendered`, async () => { - await PageObjects.common.navigateToApp('infraOps', { + await PageObjects.common.navigateToActualUrl('infraOps', '', { + ensureCurrentUrl: false, + shouldLoginIfPrompted: false, basePath: '/s/custom_space', }); - await testSubjects.existOrFail('~appNotFoundPageContent'); - await PageObjects.common.navigateToUrlWithBrowserHistory( - 'infraOps', - '/inventory', - undefined, - { - basePath: '/s/custom_space', - ensureCurrentUrl: false, - shouldLoginIfPrompted: false, - } + const messageText = await PageObjects.common.getBodyText(); + expect(messageText).to.eql( + JSON.stringify({ + statusCode: 404, + error: 'Not Found', + message: 'Not Found', + }) ); - await testSubjects.existOrFail('~appNotFoundPageContent'); }); }); diff --git a/x-pack/test/functional/apps/infra/feature_controls/logs_security.ts b/x-pack/test/functional/apps/infra/feature_controls/logs_security.ts index 3879ab7713530..6daa530261456 100644 --- a/x-pack/test/functional/apps/infra/feature_controls/logs_security.ts +++ b/x-pack/test/functional/apps/infra/feature_controls/logs_security.ts @@ -187,19 +187,19 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { expect(navLinks).to.not.contain('Logs'); }); - it(`logs app is inaccessible and Application Not Found message is rendered`, async () => { - await PageObjects.common.navigateToApp('infraLogs'); - await testSubjects.existOrFail('~appNotFoundPageContent'); - await PageObjects.common.navigateToUrlWithBrowserHistory( - 'infraLogs', - '/stream', - undefined, - { - ensureCurrentUrl: false, - shouldLoginIfPrompted: false, - } + it(`logs app is inaccessible and returns a 404`, async () => { + await PageObjects.common.navigateToActualUrl('infraLogs', '', { + ensureCurrentUrl: false, + shouldLoginIfPrompted: false, + }); + const messageText = await PageObjects.common.getBodyText(); + expect(messageText).to.eql( + JSON.stringify({ + statusCode: 404, + error: 'Not Found', + message: 'Not Found', + }) ); - await testSubjects.existOrFail('~appNotFoundPageContent'); }); }); }); diff --git a/x-pack/test/functional/apps/infra/feature_controls/logs_spaces.ts b/x-pack/test/functional/apps/infra/feature_controls/logs_spaces.ts index 76037c09bdb3f..d8b1f0d119c52 100644 --- a/x-pack/test/functional/apps/infra/feature_controls/logs_spaces.ts +++ b/x-pack/test/functional/apps/infra/feature_controls/logs_spaces.ts @@ -80,21 +80,19 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { }); it(`logs app is inaccessible and Application Not Found message is rendered`, async () => { - await PageObjects.common.navigateToApp('infraLogs', { + await PageObjects.common.navigateToActualUrl('infraLogs', '', { + ensureCurrentUrl: false, + shouldLoginIfPrompted: false, basePath: '/s/custom_space', }); - await testSubjects.existOrFail('~appNotFoundPageContent'); - await PageObjects.common.navigateToUrlWithBrowserHistory( - 'infraLogs', - '/stream', - undefined, - { - basePath: '/s/custom_space', - ensureCurrentUrl: false, - shouldLoginIfPrompted: false, - } + const messageText = await PageObjects.common.getBodyText(); + expect(messageText).to.eql( + JSON.stringify({ + statusCode: 404, + error: 'Not Found', + message: 'Not Found', + }) ); - await testSubjects.existOrFail('~appNotFoundPageContent'); }); }); }); diff --git a/x-pack/test/functional/apps/maps/es_pew_pew_source.js b/x-pack/test/functional/apps/maps/es_pew_pew_source.js index ec02dd2901c7d..382bde510170f 100644 --- a/x-pack/test/functional/apps/maps/es_pew_pew_source.js +++ b/x-pack/test/functional/apps/maps/es_pew_pew_source.js @@ -35,5 +35,14 @@ export default function ({ getPageObjects, getService }) { expect(features.length).to.equal(2); expect(features[0].geometry.type).to.equal('LineString'); }); + + it('should fit to bounds', async () => { + // Set view to other side of world so no matching results + await PageObjects.maps.setView(-70, 0, 6); + await PageObjects.maps.clickFitToBounds('connections'); + const { lat, lon } = await PageObjects.maps.getView(); + expect(Math.round(lat)).to.equal(41); + expect(Math.round(lon)).to.equal(-70); + }); }); } diff --git a/x-pack/test/functional/es_archives/endpoint/artifacts/api_feature/data.json b/x-pack/test/functional/es_archives/endpoint/artifacts/api_feature/data.json index 47390f0428742..3af1070597671 100644 --- a/x-pack/test/functional/es_archives/endpoint/artifacts/api_feature/data.json +++ b/x-pack/test/functional/es_archives/endpoint/artifacts/api_feature/data.json @@ -1,28 +1,3 @@ -{ - "type": "doc", - "value": { - "id": "endpoint:user-artifact:endpoint-exceptionlist-linux-v1-d2a9c760005b08d43394e59a8701ae75c80881934ccf15a006944452b80f7f9f", - "index": ".kibana", - "source": { - "references": [ - ], - "endpoint:user-artifact": { - "body": "eJylkM8KwjAMxl9Fci59gN29iicvMqR02QjUbiSpKGPvbiw6ETwpuX1/fh9kBszKhALNcQa9TQgNCJ2nhOA+vJ4wdWaGqJSHPY8RRXxPCb3QkJEtP07IQUe2GOWYSoedqU8qXq16ikGqeAmpPNRtCqIU3WbnDx4WN38d/WvhQqmCXzDlIlojP9CsjLC0bqWtHwhaGN/1jHVkae3u+6N6Sg==", - "created": 1593016187465, - "compressionAlgorithm": "zlib", - "encryptionAlgorithm": "none", - "identifier": "endpoint-exceptionlist-linux-v1", - "encodedSha256": "5caaeabcb7864d47157fc7c28d5a7398b4f6bbaaa565d789c02ee809253b7613", - "encodedSize": 160, - "decodedSha256": "d2a9c760005b08d43394e59a8701ae75c80881934ccf15a006944452b80f7f9f", - "decodedSize": 358 - }, - "type": "endpoint:user-artifact", - "updated_at": "2020-06-24T16:29:47.584Z" - } - } -} - { "type": "doc", "value": { @@ -83,8 +58,9 @@ ], "endpoint:user-artifact-manifest": { "created": 1593183699663, + "schemaVersion": "v1", + "semanticVersion": "1.0.1", "ids": [ - "endpoint-exceptionlist-linux-v1-d2a9c760005b08d43394e59a8701ae75c80881934ccf15a006944452b80f7f9f", "endpoint-exceptionlist-macos-v1-d801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658", "endpoint-exceptionlist-windows-v1-8d2bcc37e82fad5d06e2c9e4bd96793ea8905ace1d528a57d0d0579ecc8c647e" ] diff --git a/x-pack/test/security_solution_cypress/config.ts b/x-pack/test/security_solution_cypress/config.ts index 1ad3a36cc57ae..83290a60a17a6 100644 --- a/x-pack/test/security_solution_cypress/config.ts +++ b/x-pack/test/security_solution_cypress/config.ts @@ -46,8 +46,6 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { '--csp.strict=false', // define custom kibana server args here `--elasticsearch.ssl.certificateAuthorities=${CA_CERT_PATH}`, - '--xpack.ingestManager.enabled=true', - '--xpack.ingestManager.fleet.enabled=true', ], }, }; diff --git a/x-pack/test/security_solution_cypress/es_archives/export_rule/data.json.gz b/x-pack/test/security_solution_cypress/es_archives/export_rule/data.json.gz index 8c981e0012daf..7a870c86e6b23 100644 Binary files a/x-pack/test/security_solution_cypress/es_archives/export_rule/data.json.gz and b/x-pack/test/security_solution_cypress/es_archives/export_rule/data.json.gz differ diff --git a/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_list.ts b/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_list.ts index 07667a140d090..85d0e56231643 100644 --- a/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_list.ts +++ b/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_list.ts @@ -36,8 +36,8 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { [ 'Hostname', 'Host Status', - 'Policy', - 'Policy Status', + 'Integration', + 'Configuration Status', 'Operating System', 'IP Address', 'Version', @@ -119,7 +119,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { }); // The integration does not work properly yet. Skipping this test for now. - it.skip('navigates to ingest fleet when the Reassign Policy link is clicked', async () => { + it.skip('navigates to ingest fleet when the Reassign Configuration link is clicked', async () => { await (await testSubjects.find('hostnameCellLink')).click(); await (await testSubjects.find('hostDetailsLinkToIngest')).click(); await testSubjects.existOrFail('fleetAgentListTable'); @@ -145,8 +145,8 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { 'OS', 'Last Seen', 'Alerts', - 'Policy', - 'Policy Status', + 'Integration', + 'Configuration Status', 'IP Address', 'Hostname', 'Sensor Version', diff --git a/x-pack/test/security_solution_endpoint/apps/endpoint/index.ts b/x-pack/test/security_solution_endpoint/apps/endpoint/index.ts index eec3da4ce1c5e..7962ec60ff57e 100644 --- a/x-pack/test/security_solution_endpoint/apps/endpoint/index.ts +++ b/x-pack/test/security_solution_endpoint/apps/endpoint/index.ts @@ -29,7 +29,6 @@ export default function (providerContext: FtrProviderContext) { await ingestManager.setup(); }); loadTestFile(require.resolve('./endpoint_list')); - loadTestFile(require.resolve('./policy_list')); loadTestFile(require.resolve('./policy_details')); }); } diff --git a/x-pack/test/security_solution_endpoint/apps/endpoint/policy_details.ts b/x-pack/test/security_solution_endpoint/apps/endpoint/policy_details.ts index cf76f297d83be..62ffd15e1488f 100644 --- a/x-pack/test/security_solution_endpoint/apps/endpoint/policy_details.ts +++ b/x-pack/test/security_solution_endpoint/apps/endpoint/policy_details.ts @@ -73,7 +73,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await testSubjects.existOrFail('policyDetailsSuccessMessage'); expect(await testSubjects.getVisibleText('policyDetailsSuccessMessage')).to.equal( - `Policy ${policyInfo.packageConfig.name} has been updated.` + `Integration ${policyInfo.packageConfig.name} has been updated.` ); }); it('should persist update on the screen', async () => { @@ -81,7 +81,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await pageObjects.policy.confirmAndSave(); await testSubjects.existOrFail('policyDetailsSuccessMessage'); - await pageObjects.policy.navigateToPolicyList(); + await pageObjects.endpoint.navigateToHostList(); await pageObjects.policy.navigateToPolicyDetails(policyInfo.packageConfig.id); expect(await (await testSubjects.find('policyWindowsEvent_process')).isSelected()).to.equal( @@ -118,18 +118,6 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { }, artifact_manifest: { artifacts: { - 'endpoint-exceptionlist-linux-v1': { - compression_algorithm: 'zlib', - decoded_sha256: - 'd801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', - decoded_size: 14, - encoded_sha256: - 'f8e6afa1d5662f5b37f83337af774b5785b5b7f1daee08b7b00c2d6813874cda', - encoded_size: 22, - encryption_algorithm: 'none', - relative_url: - '/api/endpoint/artifacts/download/endpoint-exceptionlist-linux-v1/d801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', - }, 'endpoint-exceptionlist-macos-v1': { compression_algorithm: 'zlib', decoded_sha256: diff --git a/x-pack/test/security_solution_endpoint_api_int/apis/artifacts/index.ts b/x-pack/test/security_solution_endpoint_api_int/apis/artifacts/index.ts index a4a8de418157f..d5106f5549924 100644 --- a/x-pack/test/security_solution_endpoint_api_int/apis/artifacts/index.ts +++ b/x-pack/test/security_solution_endpoint_api_int/apis/artifacts/index.ts @@ -83,24 +83,24 @@ export default function (providerContext: FtrProviderContext) { it('should download an artifact with list items', async () => { await supertestWithoutAuth .get( - '/api/endpoint/artifacts/download/endpoint-exceptionlist-linux-v1/d2a9c760005b08d43394e59a8701ae75c80881934ccf15a006944452b80f7f9f' + '/api/endpoint/artifacts/download/endpoint-exceptionlist-windows-v1/8d2bcc37e82fad5d06e2c9e4bd96793ea8905ace1d528a57d0d0579ecc8c647e' ) .set('kbn-xsrf', 'xxx') .set('authorization', `ApiKey ${agentAccessAPIKey}`) .send() .expect(200) .expect((response) => { - expect(response.body.byteLength).to.equal(160); + expect(response.body.byteLength).to.equal(191); const encodedHash = createHash('sha256').update(response.body).digest('hex'); expect(encodedHash).to.equal( - '5caaeabcb7864d47157fc7c28d5a7398b4f6bbaaa565d789c02ee809253b7613' + '73015ee5131dabd1b48aa4776d3e766d836f8dd8c9fa8999c9b931f60027f07f' ); const decodedBody = inflateSync(response.body); const decodedHash = createHash('sha256').update(decodedBody).digest('hex'); expect(decodedHash).to.equal( - 'd2a9c760005b08d43394e59a8701ae75c80881934ccf15a006944452b80f7f9f' + '8d2bcc37e82fad5d06e2c9e4bd96793ea8905ace1d528a57d0d0579ecc8c647e' ); - expect(decodedBody.byteLength).to.equal(358); + expect(decodedBody.byteLength).to.equal(704); const artifactJson = JSON.parse(decodedBody.toString()); expect(artifactJson).to.eql({ entries: [ @@ -113,6 +113,35 @@ export default function (providerContext: FtrProviderContext) { type: 'exact_cased', value: 'Elastic, N.V.', }, + { + entries: [ + { + field: 'signer', + operator: 'included', + type: 'exact_cased', + value: '😈', + }, + { + field: 'trusted', + operator: 'included', + type: 'exact_cased', + value: 'true', + }, + ], + field: 'file.signature', + type: 'nested', + }, + ], + }, + { + type: 'simple', + entries: [ + { + field: 'actingProcess.file.signer', + operator: 'included', + type: 'exact_cased', + value: 'Another signer', + }, { entries: [ { @@ -280,7 +309,7 @@ export default function (providerContext: FtrProviderContext) { it('should download an artifact from cache', async () => { await supertestWithoutAuth .get( - '/api/endpoint/artifacts/download/endpoint-exceptionlist-linux-v1/d2a9c760005b08d43394e59a8701ae75c80881934ccf15a006944452b80f7f9f' + '/api/endpoint/artifacts/download/endpoint-exceptionlist-windows-v1/8d2bcc37e82fad5d06e2c9e4bd96793ea8905ace1d528a57d0d0579ecc8c647e' ) .set('kbn-xsrf', 'xxx') .set('authorization', `ApiKey ${agentAccessAPIKey}`) @@ -292,22 +321,24 @@ export default function (providerContext: FtrProviderContext) { .then(async () => { await supertestWithoutAuth .get( - '/api/endpoint/artifacts/download/endpoint-exceptionlist-linux-v1/d2a9c760005b08d43394e59a8701ae75c80881934ccf15a006944452b80f7f9f' + '/api/endpoint/artifacts/download/endpoint-exceptionlist-windows-v1/8d2bcc37e82fad5d06e2c9e4bd96793ea8905ace1d528a57d0d0579ecc8c647e' ) .set('kbn-xsrf', 'xxx') .set('authorization', `ApiKey ${agentAccessAPIKey}`) .send() .expect(200) .expect((response) => { + expect(response.body.byteLength).to.equal(191); const encodedHash = createHash('sha256').update(response.body).digest('hex'); expect(encodedHash).to.equal( - '5caaeabcb7864d47157fc7c28d5a7398b4f6bbaaa565d789c02ee809253b7613' + '73015ee5131dabd1b48aa4776d3e766d836f8dd8c9fa8999c9b931f60027f07f' ); const decodedBody = inflateSync(response.body); const decodedHash = createHash('sha256').update(decodedBody).digest('hex'); expect(decodedHash).to.equal( - 'd2a9c760005b08d43394e59a8701ae75c80881934ccf15a006944452b80f7f9f' + '8d2bcc37e82fad5d06e2c9e4bd96793ea8905ace1d528a57d0d0579ecc8c647e' ); + expect(decodedBody.byteLength).to.equal(704); const artifactJson = JSON.parse(decodedBody.toString()); expect(artifactJson).to.eql({ entries: [ @@ -320,6 +351,35 @@ export default function (providerContext: FtrProviderContext) { type: 'exact_cased', value: 'Elastic, N.V.', }, + { + entries: [ + { + field: 'signer', + operator: 'included', + type: 'exact_cased', + value: '😈', + }, + { + field: 'trusted', + operator: 'included', + type: 'exact_cased', + value: 'true', + }, + ], + field: 'file.signature', + type: 'nested', + }, + ], + }, + { + type: 'simple', + entries: [ + { + field: 'actingProcess.file.signer', + operator: 'included', + type: 'exact_cased', + value: 'Another signer', + }, { entries: [ { diff --git a/x-pack/test/security_solution_endpoint_api_int/apis/index.ts b/x-pack/test/security_solution_endpoint_api_int/apis/index.ts index fb11a7c52fd35..56adc2382e234 100644 --- a/x-pack/test/security_solution_endpoint_api_int/apis/index.ts +++ b/x-pack/test/security_solution_endpoint_api_int/apis/index.ts @@ -26,7 +26,8 @@ export default function endpointAPIIntegrationTests(providerContext: FtrProvider before(async () => { await ingestManager.setup(); }); - loadTestFile(require.resolve('./resolver')); + loadTestFile(require.resolve('./resolver/entity_id')); + loadTestFile(require.resolve('./resolver/tree')); loadTestFile(require.resolve('./metadata')); loadTestFile(require.resolve('./policy')); loadTestFile(require.resolve('./artifacts')); diff --git a/x-pack/test/security_solution_endpoint_api_int/apis/resolver/entity_id.ts b/x-pack/test/security_solution_endpoint_api_int/apis/resolver/entity_id.ts new file mode 100644 index 0000000000000..4f2a801377204 --- /dev/null +++ b/x-pack/test/security_solution_endpoint_api_int/apis/resolver/entity_id.ts @@ -0,0 +1,156 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import expect from '@kbn/expect'; +import { SearchResponse } from 'elasticsearch'; +import { eventsIndexPattern } from '../../../../plugins/security_solution/common/endpoint/constants'; +import { + ResolverTree, + ResolverEntityIndex, +} from '../../../../plugins/security_solution/common/endpoint/types'; +import { FtrProviderContext } from '../../ftr_provider_context'; +import { + EndpointDocGenerator, + Event, +} from '../../../../plugins/security_solution/common/endpoint/generate_data'; +import { InsertedEvents } from '../../services/resolver'; + +export default function resolverAPIIntegrationTests({ getService }: FtrProviderContext) { + const supertest = getService('supertest'); + const resolver = getService('resolverGenerator'); + const es = getService('es'); + const generator = new EndpointDocGenerator('resolver'); + + describe('Resolver handling of entity ids', () => { + describe('entity api', () => { + let origin: Event; + let genData: InsertedEvents; + before(async () => { + origin = generator.generateEvent({ parentEntityID: 'a' }); + origin.process.entity_id = ''; + genData = await resolver.insertEvents([origin]); + }); + + after(async () => { + await resolver.deleteData(genData); + }); + + it('excludes events that have an empty entity_id field', async () => { + // first lets get the _id of the document using the parent.process.entity_id + // then we'll use the API to search for that specific document + const res = await es.search>({ + index: genData.indices[0], + body: { + query: { + bool: { + filter: [ + { + term: { 'process.parent.entity_id': origin.process.parent!.entity_id }, + }, + ], + }, + }, + }, + }); + const { body }: { body: ResolverEntityIndex } = await supertest.get( + // using the same indices value here twice to force the query parameter to be an array + // for some reason using supertest's query() function doesn't construct a parsable array + `/api/endpoint/resolver/entity?_id=${res.body.hits.hits[0]._id}&indices=${eventsIndexPattern}&indices=${eventsIndexPattern}` + ); + expect(body).to.be.empty(); + }); + }); + + describe('children', () => { + let origin: Event; + let childNoEntityID: Event; + let childWithEntityID: Event; + let events: Event[]; + let genData: InsertedEvents; + + before(async () => { + // construct a tree with an origin and two direct children. One child will not have an entity_id. That child + // should not be returned by the backend. + origin = generator.generateEvent({ entityID: 'a' }); + childNoEntityID = generator.generateEvent({ + parentEntityID: origin.process.entity_id, + ancestry: [origin.process.entity_id], + }); + // force it to be empty + childNoEntityID.process.entity_id = ''; + + childWithEntityID = generator.generateEvent({ + entityID: 'b', + parentEntityID: origin.process.entity_id, + ancestry: [origin.process.entity_id], + }); + events = [origin, childNoEntityID, childWithEntityID]; + genData = await resolver.insertEvents(events); + }); + + after(async () => { + await resolver.deleteData(genData); + }); + + it('does not find children without a process entity_id', async () => { + const { body }: { body: ResolverTree } = await supertest + .get(`/api/endpoint/resolver/${origin.process.entity_id}`) + .expect(200); + expect(body.children.childNodes.length).to.be(1); + expect(body.children.childNodes[0].entityID).to.be(childWithEntityID.process.entity_id); + }); + }); + + describe('ancestors', () => { + let origin: Event; + let ancestor1: Event; + let ancestor2: Event; + let ancestorNoEntityID: Event; + let events: Event[]; + let genData: InsertedEvents; + + before(async () => { + // construct a tree with an origin that has two ancestors. The origin will have an empty string as one of the + // entity_ids in the ancestry array. This is to make sure that the backend will not query for that event. + ancestor2 = generator.generateEvent({ + entityID: '2', + }); + ancestor1 = generator.generateEvent({ + entityID: '1', + parentEntityID: ancestor2.process.entity_id, + ancestry: [ancestor2.process.entity_id], + }); + + // we'll insert an event that doesn't have an entity id so if the backend does search for it, it should be + // returned and our test should fail + ancestorNoEntityID = generator.generateEvent({ + ancestry: [ancestor2.process.entity_id], + }); + ancestorNoEntityID.process.entity_id = ''; + + origin = generator.generateEvent({ + entityID: 'a', + parentEntityID: ancestor1.process.entity_id, + ancestry: ['', ancestor2.process.entity_id], + }); + + events = [origin, ancestor1, ancestor2, ancestorNoEntityID]; + genData = await resolver.insertEvents(events); + }); + + after(async () => { + await resolver.deleteData(genData); + }); + + it('does not query for ancestors that have an empty string for the entity_id', async () => { + const { body }: { body: ResolverTree } = await supertest + .get(`/api/endpoint/resolver/${origin.process.entity_id}`) + .expect(200); + expect(body.ancestry.ancestors.length).to.be(1); + expect(body.ancestry.ancestors[0].entityID).to.be(ancestor2.process.entity_id); + }); + }); + }); +} diff --git a/x-pack/test/security_solution_endpoint_api_int/apis/resolver.ts b/x-pack/test/security_solution_endpoint_api_int/apis/resolver/tree.ts similarity index 98% rename from x-pack/test/security_solution_endpoint_api_int/apis/resolver.ts rename to x-pack/test/security_solution_endpoint_api_int/apis/resolver/tree.ts index 3b515f86c6761..3527e7e575c99 100644 --- a/x-pack/test/security_solution_endpoint_api_int/apis/resolver.ts +++ b/x-pack/test/security_solution_endpoint_api_int/apis/resolver/tree.ts @@ -16,12 +16,12 @@ import { LegacyEndpointEvent, ResolverNodeStats, ResolverRelatedAlerts, -} from '../../../plugins/security_solution/common/endpoint/types'; +} from '../../../../plugins/security_solution/common/endpoint/types'; import { parentEntityId, eventId, -} from '../../../plugins/security_solution/common/endpoint/models/event'; -import { FtrProviderContext } from '../ftr_provider_context'; +} from '../../../../plugins/security_solution/common/endpoint/models/event'; +import { FtrProviderContext } from '../../ftr_provider_context'; import { Event, Tree, @@ -29,8 +29,8 @@ import { RelatedEventCategory, RelatedEventInfo, categoryMapping, -} from '../../../plugins/security_solution/common/endpoint/generate_data'; -import { Options, GeneratedTrees } from '../services/resolver'; +} from '../../../../plugins/security_solution/common/endpoint/generate_data'; +import { Options, GeneratedTrees } from '../../services/resolver'; /** * Check that the given lifecycle is in the resolver tree's corresponding map @@ -256,7 +256,7 @@ export default function resolverAPIIntegrationTests({ getService }: FtrProviderC ancestryArraySize: 2, }; - describe('Resolver', () => { + describe('Resolver tree', () => { before(async () => { await esArchiver.load('endpoint/resolver/api_feature'); resolverTrees = await resolver.createTrees(treeOptions); @@ -264,7 +264,7 @@ export default function resolverAPIIntegrationTests({ getService }: FtrProviderC tree = resolverTrees.trees[0]; }); after(async () => { - await resolver.deleteTrees(resolverTrees); + await resolver.deleteData(resolverTrees); // this unload is for an endgame-* index so it does not use data streams await esArchiver.unload('endpoint/resolver/api_feature'); }); diff --git a/x-pack/test/security_solution_endpoint_api_int/services/resolver.ts b/x-pack/test/security_solution_endpoint_api_int/services/resolver.ts index 750d2f702fb84..e560a88d2f67f 100644 --- a/x-pack/test/security_solution_endpoint_api_int/services/resolver.ts +++ b/x-pack/test/security_solution_endpoint_api_int/services/resolver.ts @@ -7,9 +7,12 @@ import { TreeOptions, Tree, EndpointDocGenerator, + Event, } from '../../../plugins/security_solution/common/endpoint/generate_data'; import { FtrProviderContext } from '../ftr_provider_context'; +const processIndex = 'logs-endpoint.events.process-default'; + /** * Options for build a resolver tree */ @@ -26,17 +29,41 @@ export interface Options extends TreeOptions { */ export interface GeneratedTrees { trees: Tree[]; - eventsIndex: string; - alertsIndex: string; + indices: string[]; +} + +/** + * Structure containing the events inserted into ES and the index they live in + */ +export interface InsertedEvents { + events: Event[]; + indices: string[]; +} + +interface BulkCreateHeader { + create: { + _index: string; + }; } export function ResolverGeneratorProvider({ getService }: FtrProviderContext) { const client = getService('es'); return { + async insertEvents( + events: Event[], + eventsIndex: string = processIndex + ): Promise { + const body = events.reduce((array: Array, doc) => { + array.push({ create: { _index: eventsIndex } }, doc); + return array; + }, []); + await client.bulk({ body, refresh: 'true' }); + return { events, indices: [eventsIndex] }; + }, async createTrees( options: Options, - eventsIndex: string = 'logs-endpoint.events.process-default', + eventsIndex: string = processIndex, alertsIndex: string = 'logs-endpoint.alerts-default' ): Promise { const seed = options.seed || 'resolver-seed'; @@ -45,7 +72,7 @@ export function ResolverGeneratorProvider({ getService }: FtrProviderContext) { const numTrees = options.numTrees ?? 1; for (let j = 0; j < numTrees; j++) { const tree = generator.generateTree(options); - const body = tree.allEvents.reduce((array: Array>, doc) => { + const body = tree.allEvents.reduce((array: Array, doc) => { let index = eventsIndex; if (doc.event.kind === 'alert') { index = alertsIndex; @@ -60,23 +87,21 @@ export function ResolverGeneratorProvider({ getService }: FtrProviderContext) { await client.bulk({ body, refresh: 'true' }); allTrees.push(tree); } - return { trees: allTrees, eventsIndex, alertsIndex }; + return { trees: allTrees, indices: [eventsIndex, alertsIndex] }; }, - async deleteTrees(trees: GeneratedTrees) { - /** - * The ingest manager handles creating the template for the endpoint's indices. It is using a V2 template - * with data streams. Data streams aren't included in the javascript elasticsearch client in kibana yet so we - * need to do raw requests here. Delete a data stream is slightly different than that of a regular index which - * is why we're using _data_stream here. - */ - await client.transport.request({ - method: 'DELETE', - path: `_data_stream/${trees.eventsIndex}`, - }); - await client.transport.request({ - method: 'DELETE', - path: `_data_stream/${trees.alertsIndex}`, - }); + async deleteData(genData: { indices: string[] }) { + for (const index of genData.indices) { + /** + * The ingest manager handles creating the template for the endpoint's indices. It is using a V2 template + * with data streams. Data streams aren't included in the javascript elasticsearch client in kibana yet so we + * need to do raw requests here. Delete a data stream is slightly different than that of a regular index which + * is why we're using _data_stream here. + */ + await client.transport.request({ + method: 'DELETE', + path: `_data_stream/${index}`, + }); + } }, }; } diff --git a/x-pack/test/ui_capabilities/common/features.ts b/x-pack/test/ui_capabilities/common/features.ts index 3c015bc21e937..e3febc945c299 100644 --- a/x-pack/test/ui_capabilities/common/features.ts +++ b/x-pack/test/ui_capabilities/common/features.ts @@ -5,7 +5,7 @@ */ interface Feature { - navLinkId: string; + app: string[]; } export interface Features { diff --git a/x-pack/test/ui_capabilities/common/fixtures/plugins/foo_plugin/server/index.ts b/x-pack/test/ui_capabilities/common/fixtures/plugins/foo_plugin/server/index.ts index bff794801119a..5c80b4283a69b 100644 --- a/x-pack/test/ui_capabilities/common/fixtures/plugins/foo_plugin/server/index.ts +++ b/x-pack/test/ui_capabilities/common/fixtures/plugins/foo_plugin/server/index.ts @@ -19,11 +19,11 @@ class FooPlugin implements Plugin { name: 'Foo', icon: 'upArrow', navLinkId: 'foo_plugin', - app: ['kibana'], + app: ['foo_plugin', 'kibana'], catalogue: ['foo'], privileges: { all: { - app: ['kibana'], + app: ['foo_plugin', 'kibana'], catalogue: ['foo'], savedObject: { all: ['foo'], @@ -32,7 +32,7 @@ class FooPlugin implements Plugin { ui: ['create', 'edit', 'delete', 'show'], }, read: { - app: ['kibana'], + app: ['foo_plugin', 'kibana'], catalogue: ['foo'], savedObject: { all: [], diff --git a/x-pack/test/ui_capabilities/common/nav_links_builder.ts b/x-pack/test/ui_capabilities/common/nav_links_builder.ts index b20a499ba7e20..04ab08e08a2ba 100644 --- a/x-pack/test/ui_capabilities/common/nav_links_builder.ts +++ b/x-pack/test/ui_capabilities/common/nav_links_builder.ts @@ -13,11 +13,14 @@ export class NavLinksBuilder { ...features, // management isn't a first-class "feature", but it makes our life easier here to pretend like it is management: { - navLinkId: 'kibana:stack_management', + app: ['kibana:stack_management'], }, // TODO: Temp until navLinkIds fix is merged in appSearch: { - navLinkId: 'appSearch', + app: ['appSearch', 'workplaceSearch'], + }, + kibana: { + app: ['kibana'], }, }; } @@ -38,9 +41,9 @@ export class NavLinksBuilder { private build(callback: buildCallback): Record { const navLinks = {} as Record; for (const [featureId, feature] of Object.entries(this.features)) { - if (feature.navLinkId) { - navLinks[feature.navLinkId] = callback(featureId); - } + feature.app.forEach((app) => { + navLinks[app] = callback(featureId); + }); } return navLinks; diff --git a/x-pack/test/ui_capabilities/common/services/features.ts b/x-pack/test/ui_capabilities/common/services/features.ts index 0f796c1d0a0cc..5f6ec0ad050c7 100644 --- a/x-pack/test/ui_capabilities/common/services/features.ts +++ b/x-pack/test/ui_capabilities/common/services/features.ts @@ -40,7 +40,7 @@ export class FeaturesService { (acc: Features, feature: any) => ({ ...acc, [feature.id]: { - navLinkId: feature.navLinkId, + app: feature.app, }, }), {} diff --git a/x-pack/test/ui_capabilities/common/services/ui_capabilities.ts b/x-pack/test/ui_capabilities/common/services/ui_capabilities.ts index bb1f3b6eefe4a..7f831973aea5c 100644 --- a/x-pack/test/ui_capabilities/common/services/ui_capabilities.ts +++ b/x-pack/test/ui_capabilities/common/services/ui_capabilities.ts @@ -52,7 +52,7 @@ export class UICapabilitiesService { }): Promise { const features = await this.featureService.get(); const applications = Object.values(features) - .map((feature) => feature.navLinkId) + .flatMap((feature) => feature.app) .filter((link) => !!link); const spaceUrlPrefix = spaceId ? `/s/${spaceId}` : ''; diff --git a/x-pack/test/ui_capabilities/security_only/tests/nav_links.ts b/x-pack/test/ui_capabilities/security_only/tests/nav_links.ts index 18838e536cf96..d7a0dfa1cf80a 100644 --- a/x-pack/test/ui_capabilities/security_only/tests/nav_links.ts +++ b/x-pack/test/ui_capabilities/security_only/tests/nav_links.ts @@ -57,7 +57,7 @@ export default function navLinksTests({ getService }: FtrProviderContext) { expect(uiCapabilities.success).to.be(true); expect(uiCapabilities.value).to.have.property('navLinks'); expect(uiCapabilities.value!.navLinks).to.eql( - navLinksBuilder.only('management', 'foo') + navLinksBuilder.only('management', 'foo', 'kibana') ); break; case 'legacy_all': diff --git a/yarn.lock b/yarn.lock index 27c7624db634e..9d07162d92bdb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2850,26 +2850,24 @@ "@types/yargs" "^15.0.0" chalk "^3.0.0" -"@jimp/bmp@^0.9.6": - version "0.9.6" - resolved "https://registry.yarnpkg.com/@jimp/bmp/-/bmp-0.9.6.tgz#379e261615d7c1f3b52af4d5a0f324666de53d7d" - integrity sha512-T2Fh/k/eN6cDyOx0KQ4y56FMLo8+mKNhBh7GXMQXLK2NNZ0ckpFo3VHDBZ3HnaFeVTZXF/atLiR9CfnXH+rLxA== +"@jimp/bmp@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/bmp/-/bmp-0.14.0.tgz#6df246026554f276f7b354047c6fff9f5b2b5182" + integrity sha512-5RkX6tSS7K3K3xNEb2ygPuvyL9whjanhoaB/WmmXlJS6ub4DjTqrapu8j4qnIWmO4YYtFeTbDTXV6v9P1yMA5A== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.6" + "@jimp/utils" "^0.14.0" bmp-js "^0.1.0" - core-js "^3.4.1" -"@jimp/core@^0.9.6": - version "0.9.6" - resolved "https://registry.yarnpkg.com/@jimp/core/-/core-0.9.6.tgz#a553f801bd436526d36e8982b99e58e8afc3d17a" - integrity sha512-sQO04S+HZNid68a9ehb4BC2lmW6iZ5JgU9tC+thC2Lhix+N/XKDJcBJ6HevbLgeTzuIAw24C5EKuUeO3C+rE5w== +"@jimp/core@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/core/-/core-0.14.0.tgz#870c9ca25b40be353ebda1d2abb48723d9010055" + integrity sha512-S62FcKdtLtj3yWsGfJRdFXSutjvHg7aQNiFogMbwq19RP4XJWqS2nOphu7ScB8KrSlyy5nPF2hkWNhLRLyD82w== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.6" + "@jimp/utils" "^0.14.0" any-base "^1.1.0" buffer "^5.2.0" - core-js "^3.4.1" exif-parser "^0.1.12" file-type "^9.0.0" load-bmfont "^1.3.1" @@ -2878,256 +2876,269 @@ pixelmatch "^4.0.2" tinycolor2 "^1.4.1" -"@jimp/custom@^0.9.6": - version "0.9.6" - resolved "https://registry.yarnpkg.com/@jimp/custom/-/custom-0.9.6.tgz#3d8a19d6ed717f0f1aa3f1b8f42fa374f43bc715" - integrity sha512-ZYKgrBZVoQwvIGlQSO7MFmn7Jn8a9X5g1g+KOTDO9Q0s4vnxdPTtr/qUjG9QYX6zW/6AK4LaIsDinDrrKDnOag== +"@jimp/custom@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/custom/-/custom-0.14.0.tgz#1dbbf0094df7403f4e03bc984ed92e7458842f74" + integrity sha512-kQJMeH87+kWJdVw8F9GQhtsageqqxrvzg7yyOw3Tx/s7v5RToe8RnKyMM+kVtBJtNAG+Xyv/z01uYQ2jiZ3GwA== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/core" "^0.9.6" - core-js "^3.4.1" + "@jimp/core" "^0.14.0" -"@jimp/gif@^0.9.6": - version "0.9.6" - resolved "https://registry.yarnpkg.com/@jimp/gif/-/gif-0.9.6.tgz#0a7b1e521daca635b02259f941bdb3600569d8e6" - integrity sha512-Z2muC2On8KHEVrWKCCM0L2eua9kw4bQETzT7gmVsizc8MXAKdS8AyVV9T3ZrImiI0o5UkAN/u0cPi1U2pSiD8Q== +"@jimp/gif@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/gif/-/gif-0.14.0.tgz#db159f57c3cfd1566bbe8b124958791998614960" + integrity sha512-DHjoOSfCaCz72+oGGEh8qH0zE6pUBaBxPxxmpYJjkNyDZP7RkbBkZJScIYeQ7BmJxmGN4/dZn+MxamoQlr+UYg== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.6" - core-js "^3.4.1" + "@jimp/utils" "^0.14.0" + gifwrap "^0.9.2" omggif "^1.0.9" -"@jimp/jpeg@^0.9.6": - version "0.9.6" - resolved "https://registry.yarnpkg.com/@jimp/jpeg/-/jpeg-0.9.6.tgz#fb90bdc0111966987c5ba59cdca7040be86ead41" - integrity sha512-igSe0pIX3le/CKdvqW4vLXMxoFjTLjEaW6ZHt/h63OegaEa61TzJ2OM7j7DxrEHcMCMlkhUc9Bapk57MAefCTQ== +"@jimp/jpeg@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/jpeg/-/jpeg-0.14.0.tgz#8a687a6a653bbbae38c522edef8f84bb418d9461" + integrity sha512-561neGbr+87S/YVQYnZSTyjWTHBm9F6F1obYHiyU3wVmF+1CLbxY3FQzt4YolwyQHIBv36Bo0PY2KkkU8BEeeQ== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.6" - core-js "^3.4.1" - jpeg-js "^0.3.4" + "@jimp/utils" "^0.14.0" + jpeg-js "^0.4.0" -"@jimp/plugin-blit@^0.9.6": - version "0.9.6" - resolved "https://registry.yarnpkg.com/@jimp/plugin-blit/-/plugin-blit-0.9.6.tgz#7937e02e3514b95dbe4c70d444054847f6e9ce3c" - integrity sha512-zp7X6uDU1lCu44RaSY88aAvsSKbgqUrfDyWRX1wsamJvvZpRnp1WekWlGyydRtnlUBAGIpiHCHmyh/TJ2I4RWA== +"@jimp/plugin-blit@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-blit/-/plugin-blit-0.14.0.tgz#5eb374be1201313b2113899fb842232d8fcfd345" + integrity sha512-YoYOrnVHeX3InfgbJawAU601iTZMwEBZkyqcP1V/S33Qnz9uzH1Uj1NtC6fNgWzvX6I4XbCWwtr4RrGFb5CFrw== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.6" - core-js "^3.4.1" + "@jimp/utils" "^0.14.0" -"@jimp/plugin-blur@^0.9.6": - version "0.9.6" - resolved "https://registry.yarnpkg.com/@jimp/plugin-blur/-/plugin-blur-0.9.6.tgz#3d74b18c27e9eae11b956ffe26290ece6d250813" - integrity sha512-xEi63hvzewUp7kzw+PI3f9CIrgZbphLI4TDDHWNYuS70RvhTuplbR6RMHD/zFhosrANCkJGr5OZJlrJnsCg6ug== +"@jimp/plugin-blur@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-blur/-/plugin-blur-0.14.0.tgz#fe07e4932d5a2f5d8c9831e245561553224bfc60" + integrity sha512-9WhZcofLrT0hgI7t0chf7iBQZib//0gJh9WcQMUt5+Q1Bk04dWs8vTgLNj61GBqZXgHSPzE4OpCrrLDBG8zlhQ== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.6" - core-js "^3.4.1" + "@jimp/utils" "^0.14.0" -"@jimp/plugin-color@^0.9.6": - version "0.9.6" - resolved "https://registry.yarnpkg.com/@jimp/plugin-color/-/plugin-color-0.9.6.tgz#d0fca0ed4c2c48fd6f929ef4a03cebf9c1342e14" - integrity sha512-o1HSoqBVUUAsWbqSXnpiHU0atKWy/Q1GUbZ3F5GWt/0OSDyl9RWM82V9axT2vePZHInKjIaimhnx1gGj8bfxkQ== +"@jimp/plugin-circle@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-circle/-/plugin-circle-0.14.0.tgz#82c0e904a34e90fa672fb9c286bc892e92088ddf" + integrity sha512-o5L+wf6QA44tvTum5HeLyLSc5eVfIUd5ZDVi5iRfO4o6GT/zux9AxuTSkKwnjhsG8bn1dDmywAOQGAx7BjrQVA== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.14.0" + +"@jimp/plugin-color@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-color/-/plugin-color-0.14.0.tgz#772bd2d80a88bc66ea1331d010207870f169a74b" + integrity sha512-JJz512SAILYV0M5LzBb9sbOm/XEj2fGElMiHAxb7aLI6jx+n0agxtHpfpV/AePTLm1vzzDxx6AJxXbKv355hBQ== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.6" - core-js "^3.4.1" + "@jimp/utils" "^0.14.0" tinycolor2 "^1.4.1" -"@jimp/plugin-contain@^0.9.6": - version "0.9.6" - resolved "https://registry.yarnpkg.com/@jimp/plugin-contain/-/plugin-contain-0.9.6.tgz#7d7bbd5e9c2fa4391a3d63620e13a28f51e1e7e8" - integrity sha512-Xz467EN1I104yranET4ff1ViVKMtwKLg1uRe8j3b5VOrjtiXpDbjirNZjP3HTlv8IEUreWNz4BK7ZtfHSptufA== +"@jimp/plugin-contain@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-contain/-/plugin-contain-0.14.0.tgz#c68115420d182e696f81bbe76fb5e704909b2b6a" + integrity sha512-RX2q233lGyaxiMY6kAgnm9ScmEkNSof0hdlaJAVDS1OgXphGAYAeSIAwzESZN4x3ORaWvkFefeVH9O9/698Evg== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.6" - core-js "^3.4.1" + "@jimp/utils" "^0.14.0" -"@jimp/plugin-cover@^0.9.6": - version "0.9.6" - resolved "https://registry.yarnpkg.com/@jimp/plugin-cover/-/plugin-cover-0.9.6.tgz#2853de7f8302f655ae8e95f51ab25a0ed77e3756" - integrity sha512-Ocr27AvtvH4ZT/9EWZgT3+HQV9fG5njwh2CYMHbdpx09O62Asj6pZ4QI0kKzOcux1oLgv59l7a93pEfMOfkfwQ== +"@jimp/plugin-cover@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-cover/-/plugin-cover-0.14.0.tgz#4755322589c5885e44e14e31b86b542e907297ce" + integrity sha512-0P/5XhzWES4uMdvbi3beUgfvhn4YuQ/ny8ijs5kkYIw6K8mHcl820HahuGpwWMx56DJLHRl1hFhJwo9CeTRJtQ== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.6" - core-js "^3.4.1" + "@jimp/utils" "^0.14.0" -"@jimp/plugin-crop@^0.9.6": - version "0.9.6" - resolved "https://registry.yarnpkg.com/@jimp/plugin-crop/-/plugin-crop-0.9.6.tgz#82e539af2a2417783abbd143124a57672ff4cc31" - integrity sha512-d9rNdmz3+eYLbSKcTyyp+b8Nmhf6HySnimDXlTej4UP6LDtkq2VAyVaJ12fz9x6dfd8qcXOBXMozSfNCcgpXYA== +"@jimp/plugin-crop@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-crop/-/plugin-crop-0.14.0.tgz#4cbd856ca84ffc37230fad2534906f2f75aa3057" + integrity sha512-Ojtih+XIe6/XSGtpWtbAXBozhCdsDMmy+THUJAGu2x7ZgKrMS0JotN+vN2YC3nwDpYkM+yOJImQeptSfZb2Sug== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.6" - core-js "^3.4.1" + "@jimp/utils" "^0.14.0" -"@jimp/plugin-displace@^0.9.6": - version "0.9.6" - resolved "https://registry.yarnpkg.com/@jimp/plugin-displace/-/plugin-displace-0.9.6.tgz#67564d081dc6b19007248ca222d025fd6f90c03b" - integrity sha512-SWpbrxiHmUYBVWtDDMjaG3eRDBASrTPaad7l07t73/+kmU6owAKWQW6KtVs05MYSJgXz7Ggdr0fhEn9AYLH1Rg== +"@jimp/plugin-displace@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-displace/-/plugin-displace-0.14.0.tgz#b0e6a57d00cb1f893f541413fe9d737d23c3b70c" + integrity sha512-c75uQUzMgrHa8vegkgUvgRL/PRvD7paFbFJvzW0Ugs8Wl+CDMGIPYQ3j7IVaQkIS+cAxv+NJ3TIRBQyBrfVEOg== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.6" - core-js "^3.4.1" + "@jimp/utils" "^0.14.0" -"@jimp/plugin-dither@^0.9.6": - version "0.9.6" - resolved "https://registry.yarnpkg.com/@jimp/plugin-dither/-/plugin-dither-0.9.6.tgz#dc48669cf51f3933761aa9137e99ebfa000b8cce" - integrity sha512-abm1GjfYK7ru/PoxH9fAUmhl+meHhGEClbVvjjMMe5g2S0BSTvMJl3SrkQD/FMkRLniaS/Qci6aQhIi+8rZmSw== +"@jimp/plugin-dither@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-dither/-/plugin-dither-0.14.0.tgz#9185ec4c38e02edc9e5831f5d709f6ba891e1b93" + integrity sha512-g8SJqFLyYexXQQsoh4dc1VP87TwyOgeTElBcxSXX2LaaMZezypmxQfLTzOFzZoK8m39NuaoH21Ou1Ftsq7LzVQ== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.6" - core-js "^3.4.1" + "@jimp/utils" "^0.14.0" -"@jimp/plugin-flip@^0.9.6": - version "0.9.6" - resolved "https://registry.yarnpkg.com/@jimp/plugin-flip/-/plugin-flip-0.9.6.tgz#f81f9b886da8cd56e23dd04d5aa359f2b94f939e" - integrity sha512-KFZTzAzQQ5bct3ii7gysOhWrTKVdUOghkkoSzLi+14nO3uS/dxiu8fPeH1m683ligbdnuM/b22OuLwEwrboTHA== +"@jimp/plugin-fisheye@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-fisheye/-/plugin-fisheye-0.14.0.tgz#9f26346cf2fbc660cc2008cd7fd30a83b5029e78" + integrity sha512-BFfUZ64EikCaABhCA6mR3bsltWhPpS321jpeIQfJyrILdpFsZ/OccNwCgpW1XlbldDHIoNtXTDGn3E+vCE7vDg== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.6" - core-js "^3.4.1" + "@jimp/utils" "^0.14.0" -"@jimp/plugin-gaussian@^0.9.6": - version "0.9.6" - resolved "https://registry.yarnpkg.com/@jimp/plugin-gaussian/-/plugin-gaussian-0.9.6.tgz#6c93897ee0ff979466184d7d0ec0fbc95c679be4" - integrity sha512-WXKLtJKWchXfWHT5HIOq1HkPKpbH7xBLWPgVRxw00NV/6I8v4xT63A7/Nag78m00JgjwwiE7eK2tLGDbbrPYig== +"@jimp/plugin-flip@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-flip/-/plugin-flip-0.14.0.tgz#7966d6aa3b5fe1aa4d2d561ff12b8ef5ccb9b071" + integrity sha512-WtL1hj6ryqHhApih+9qZQYA6Ye8a4HAmdTzLbYdTMrrrSUgIzFdiZsD0WeDHpgS/+QMsWwF+NFmTZmxNWqKfXw== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.6" - core-js "^3.4.1" + "@jimp/utils" "^0.14.0" -"@jimp/plugin-invert@^0.9.6": - version "0.9.6" - resolved "https://registry.yarnpkg.com/@jimp/plugin-invert/-/plugin-invert-0.9.6.tgz#4b3fa7b81ea976b09b82b3db59ee00ac3093d2fd" - integrity sha512-Pab/cupZrYxeRp07N4L5a4C/3ksTN9k6Knm/o2G5C789OF0rYsGGLcnBR/6h69nPizRZHBYdXCEyXYgujlIFiw== +"@jimp/plugin-gaussian@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-gaussian/-/plugin-gaussian-0.14.0.tgz#452bc1971a4467ad9b984aa67f4c200bf941bb65" + integrity sha512-uaLwQ0XAQoydDlF9tlfc7iD9drYPriFe+jgYnWm8fbw5cN+eOIcnneEX9XCOOzwgLPkNCxGox6Kxjn8zY6GxtQ== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.6" - core-js "^3.4.1" + "@jimp/utils" "^0.14.0" -"@jimp/plugin-mask@^0.9.6": - version "0.9.6" - resolved "https://registry.yarnpkg.com/@jimp/plugin-mask/-/plugin-mask-0.9.6.tgz#d70be0030ab3294b191f5b487fb655d776820b19" - integrity sha512-ikypRoDJkbxXlo6gW+EZOcTiLDIt0DrPwOFMt1bvL8UV2QPgX+GJ685IYwhIfEhBf/GSNFgB/NYsVvuSufTGeg== +"@jimp/plugin-invert@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-invert/-/plugin-invert-0.14.0.tgz#cd31a555860e9f821394936d15af161c09c42921" + integrity sha512-UaQW9X9vx8orQXYSjT5VcITkJPwDaHwrBbxxPoDG+F/Zgv4oV9fP+udDD6qmkgI9taU+44Fy+zm/J/gGcMWrdg== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.6" - core-js "^3.4.1" + "@jimp/utils" "^0.14.0" -"@jimp/plugin-normalize@^0.9.6": - version "0.9.6" - resolved "https://registry.yarnpkg.com/@jimp/plugin-normalize/-/plugin-normalize-0.9.6.tgz#c9128412a53485d91236a1da241f3166e572be4a" - integrity sha512-V3GeuAJ1NeL7qsLoDjnypJq24RWDCwbXpKhtxB+Yg9zzgOCkmb041p7ysxbcpkuJsRpKLNABZeNCCqd83bRawA== +"@jimp/plugin-mask@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-mask/-/plugin-mask-0.14.0.tgz#52619643ac6222f85e6b27dee33c771ca3a6a4c9" + integrity sha512-tdiGM69OBaKtSPfYSQeflzFhEpoRZ+BvKfDEoivyTjauynbjpRiwB1CaiS8En1INTDwzLXTT0Be9SpI3LkJoEA== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.6" - core-js "^3.4.1" + "@jimp/utils" "^0.14.0" -"@jimp/plugin-print@^0.9.6": - version "0.9.6" - resolved "https://registry.yarnpkg.com/@jimp/plugin-print/-/plugin-print-0.9.6.tgz#fea31ffeafee18ae7b5cfd6fa131bb205abfee51" - integrity sha512-gKkqZZPQtMSufHOL0mtJm5d/KI2O6+0kUpOBVSYdGedtPXA61kmVnsOd3wwajIMlXA3E0bDxLXLdAguWqjjGgw== +"@jimp/plugin-normalize@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-normalize/-/plugin-normalize-0.14.0.tgz#bf39e356b6d473f582ce95633ad49c9cdb82492b" + integrity sha512-AfY8sqlsbbdVwFGcyIPy5JH/7fnBzlmuweb+Qtx2vn29okq6+HelLjw2b+VT2btgGUmWWHGEHd86oRGSoWGyEQ== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.14.0" + +"@jimp/plugin-print@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-print/-/plugin-print-0.14.0.tgz#1c43c2a92a7adc05b464863882cb89ce486d63e6" + integrity sha512-MwP3sH+VS5AhhSTXk7pui+tEJFsxnTKFY3TraFJb8WFbA2Vo2qsRCZseEGwpTLhENB7p/JSsLvWoSSbpmxhFAQ== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.6" - core-js "^3.4.1" + "@jimp/utils" "^0.14.0" load-bmfont "^1.4.0" -"@jimp/plugin-resize@^0.9.6": - version "0.9.6" - resolved "https://registry.yarnpkg.com/@jimp/plugin-resize/-/plugin-resize-0.9.6.tgz#7fb939c8a42e2a3639d661cc7ab24057598693bd" - integrity sha512-r5wJcVII7ZWMuY2l6WSbHPG6gKMFemtCHmJRXGUu+/ZhPGBz3IFluycBpHkWW3OB+jfvuyv1EGQWHU50N1l8Og== +"@jimp/plugin-resize@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-resize/-/plugin-resize-0.14.0.tgz#ef7fc6c2e45f8bcab62456baf8fd3bc415b02b64" + integrity sha512-qFeMOyXE/Bk6QXN0GQo89+CB2dQcXqoxUcDb2Ah8wdYlKqpi53skABkgVy5pW3EpiprDnzNDboMltdvDslNgLQ== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.6" - core-js "^3.4.1" + "@jimp/utils" "^0.14.0" -"@jimp/plugin-rotate@^0.9.6": - version "0.9.6" - resolved "https://registry.yarnpkg.com/@jimp/plugin-rotate/-/plugin-rotate-0.9.6.tgz#06d725155e5cdb615133f57a52f5a860a9d03f3e" - integrity sha512-B2nm/eO2nbvn1DgmnzMd79yt3V6kffhRNrKoo2VKcKFiVze1vGP3MD3fVyw5U1PeqwAFu7oTICFnCf9wKDWSqg== +"@jimp/plugin-rotate@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-rotate/-/plugin-rotate-0.14.0.tgz#3632bc159bf1c3b9ec9f459d9c05d02a11781ee7" + integrity sha512-aGaicts44bvpTcq5Dtf93/8TZFu5pMo/61lWWnYmwJJU1RqtQlxbCLEQpMyRhKDNSfPbuP8nyGmaqXlM/82J0Q== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.6" - core-js "^3.4.1" + "@jimp/utils" "^0.14.0" -"@jimp/plugin-scale@^0.9.6": - version "0.9.6" - resolved "https://registry.yarnpkg.com/@jimp/plugin-scale/-/plugin-scale-0.9.6.tgz#3fa939c1a4f44383e12afeb7c434eb41f20e4a1c" - integrity sha512-DLsLB5S3mh9+TZY5ycwfLgOJvUcoS7bP0Mi3I8vE1J91qmA+TXoWFFgrIVgnEPw5jSKzNTt8WhykQ0x2lKXncw== +"@jimp/plugin-scale@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-scale/-/plugin-scale-0.14.0.tgz#d30f0cd1365b8e68f43fa423300ae7f124e9bf10" + integrity sha512-ZcJk0hxY5ZKZDDwflqQNHEGRblgaR+piePZm7dPwPUOSeYEH31P0AwZ1ziceR74zd8N80M0TMft+e3Td6KGBHw== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.6" - core-js "^3.4.1" + "@jimp/utils" "^0.14.0" -"@jimp/plugins@^0.9.6": - version "0.9.6" - resolved "https://registry.yarnpkg.com/@jimp/plugins/-/plugins-0.9.6.tgz#a1cfdf9f3e1adf5b124686486343888a16c8fd27" - integrity sha512-eQI29e+K+3L/fb5GbPgsBdoftvaYetSOO2RL5z+Gjk6R4EF4QFRo63YcFl+f72Kc1b0JTOoDxClvn/s5GMV0tg== +"@jimp/plugin-shadow@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-shadow/-/plugin-shadow-0.14.0.tgz#471fdb9f109ff2d9e20d533d45e1e18e0b48c749" + integrity sha512-p2igcEr/iGrLiTu0YePNHyby0WYAXM14c5cECZIVnq/UTOOIQ7xIcWZJ1lRbAEPxVVXPN1UibhZAbr3HAb5BjQ== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/plugin-blit" "^0.9.6" - "@jimp/plugin-blur" "^0.9.6" - "@jimp/plugin-color" "^0.9.6" - "@jimp/plugin-contain" "^0.9.6" - "@jimp/plugin-cover" "^0.9.6" - "@jimp/plugin-crop" "^0.9.6" - "@jimp/plugin-displace" "^0.9.6" - "@jimp/plugin-dither" "^0.9.6" - "@jimp/plugin-flip" "^0.9.6" - "@jimp/plugin-gaussian" "^0.9.6" - "@jimp/plugin-invert" "^0.9.6" - "@jimp/plugin-mask" "^0.9.6" - "@jimp/plugin-normalize" "^0.9.6" - "@jimp/plugin-print" "^0.9.6" - "@jimp/plugin-resize" "^0.9.6" - "@jimp/plugin-rotate" "^0.9.6" - "@jimp/plugin-scale" "^0.9.6" - core-js "^3.4.1" + "@jimp/utils" "^0.14.0" + +"@jimp/plugin-threshold@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-threshold/-/plugin-threshold-0.14.0.tgz#ebd72721c7d1d518c5bb6e494e55d97ac3351d3b" + integrity sha512-N4BlDgm/FoOMV/DQM2rSpzsgqAzkP0DXkWZoqaQrlRxQBo4zizQLzhEL00T/YCCMKnddzgEhnByaocgaaa0fKw== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.14.0" + +"@jimp/plugins@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugins/-/plugins-0.14.0.tgz#41dba85f15ab8dadb4162100eb54e5f27b93ee2c" + integrity sha512-vDO3XT/YQlFlFLq5TqNjQkISqjBHT8VMhpWhAfJVwuXIpilxz5Glu4IDLK6jp4IjPR6Yg2WO8TmRY/HI8vLrOw== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/plugin-blit" "^0.14.0" + "@jimp/plugin-blur" "^0.14.0" + "@jimp/plugin-circle" "^0.14.0" + "@jimp/plugin-color" "^0.14.0" + "@jimp/plugin-contain" "^0.14.0" + "@jimp/plugin-cover" "^0.14.0" + "@jimp/plugin-crop" "^0.14.0" + "@jimp/plugin-displace" "^0.14.0" + "@jimp/plugin-dither" "^0.14.0" + "@jimp/plugin-fisheye" "^0.14.0" + "@jimp/plugin-flip" "^0.14.0" + "@jimp/plugin-gaussian" "^0.14.0" + "@jimp/plugin-invert" "^0.14.0" + "@jimp/plugin-mask" "^0.14.0" + "@jimp/plugin-normalize" "^0.14.0" + "@jimp/plugin-print" "^0.14.0" + "@jimp/plugin-resize" "^0.14.0" + "@jimp/plugin-rotate" "^0.14.0" + "@jimp/plugin-scale" "^0.14.0" + "@jimp/plugin-shadow" "^0.14.0" + "@jimp/plugin-threshold" "^0.14.0" timm "^1.6.1" -"@jimp/png@^0.9.6": - version "0.9.6" - resolved "https://registry.yarnpkg.com/@jimp/png/-/png-0.9.6.tgz#00ed7e6fb783b94f2f1a9fadf9a42bd75f70cc7f" - integrity sha512-9vhOG2xylcDqPbBf4lzpa2Sa1WNJrEZNGvPvWcM+XVhqYa8+DJBLYkoBlpI/qWIYA+eVWDnLF3ygtGj8CElICw== +"@jimp/png@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/png/-/png-0.14.0.tgz#0f2dddb5125c0795ca7e67c771204c5437fcda4b" + integrity sha512-0RV/mEIDOrPCcNfXSPmPBqqSZYwGADNRVUTyMt47RuZh7sugbYdv/uvKmQSiqRdR0L1sfbCBMWUEa5G/8MSbdA== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.9.6" - core-js "^3.4.1" + "@jimp/utils" "^0.14.0" pngjs "^3.3.3" -"@jimp/tiff@^0.9.6": - version "0.9.6" - resolved "https://registry.yarnpkg.com/@jimp/tiff/-/tiff-0.9.6.tgz#9ff12122e727ee15f27f40a710516102a636f66b" - integrity sha512-pKKEMqPzX9ak8mek2iVVoW34+h/TSWUyI4NjbYWJMQ2WExfuvEJvLocy9Q9xi6HqRuJmUxgNIiC5iZM1PDEEfg== +"@jimp/tiff@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/tiff/-/tiff-0.14.0.tgz#a5b25bbe7c43fc3b07bad4e2ab90e0e164c1967f" + integrity sha512-zBYDTlutc7j88G/7FBCn3kmQwWr0rmm1e0FKB4C3uJ5oYfT8645lftUsvosKVUEfkdmOaMAnhrf4ekaHcb5gQw== dependencies: "@babel/runtime" "^7.7.2" - core-js "^3.4.1" utif "^2.0.1" -"@jimp/types@^0.9.6": - version "0.9.6" - resolved "https://registry.yarnpkg.com/@jimp/types/-/types-0.9.6.tgz#7be7f415ad93be733387c03b8a228c587a868a18" - integrity sha512-PSjdbLZ8d50En+Wf1XkWFfrXaf/GqyrxxgIwFWPbL+wrW4pmbYovfxSLCY61s8INsOFOft9dzzllhLBtg1aQ6A== +"@jimp/types@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/types/-/types-0.14.0.tgz#ef681ff702883c5f105b5e4e30d49abf39ee9e34" + integrity sha512-hx3cXAW1KZm+b+XCrY3LXtdWy2U+hNtq0rPyJ7NuXCjU7lZR3vIkpz1DLJ3yDdS70hTi5QDXY3Cd9kd6DtloHQ== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/bmp" "^0.9.6" - "@jimp/gif" "^0.9.6" - "@jimp/jpeg" "^0.9.6" - "@jimp/png" "^0.9.6" - "@jimp/tiff" "^0.9.6" - core-js "^3.4.1" + "@jimp/bmp" "^0.14.0" + "@jimp/gif" "^0.14.0" + "@jimp/jpeg" "^0.14.0" + "@jimp/png" "^0.14.0" + "@jimp/tiff" "^0.14.0" timm "^1.6.1" -"@jimp/utils@^0.9.6": - version "0.9.6" - resolved "https://registry.yarnpkg.com/@jimp/utils/-/utils-0.9.6.tgz#a3e6c29e835e2b9ea9f3899c9d3d230dc63bd518" - integrity sha512-kzxcp0i4ecSdMXFEmtH+NYdBQysINEUTsrjm7v0zH8t/uwaEMOG46I16wo/iPBXJkUeNdL2rbXoGoxxoeSfrrA== +"@jimp/utils@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/utils/-/utils-0.14.0.tgz#296254e63118554c62c31c19ac6b8c4bfe6490e5" + integrity sha512-MY5KFYUru0y74IsgM/9asDwb3ERxWxXEu3CRCZEvE7DtT86y1bR1XgtlSliMrptjz4qbivNGMQSvUBpEFJDp1A== dependencies: "@babel/runtime" "^7.7.2" - core-js "^3.4.1" + regenerator-runtime "^0.13.3" "@mapbox/extent@0.4.0": version "0.4.0" @@ -4800,21 +4811,11 @@ resolved "https://registry.yarnpkg.com/@types/base64-js/-/base64-js-1.2.5.tgz#582b2476169a6cba460a214d476c744441d873d5" integrity sha1-WCskdhaabLpGCiFNR2x0REHYc9U= -"@types/blob-util@1.3.3": - version "1.3.3" - resolved "https://registry.yarnpkg.com/@types/blob-util/-/blob-util-1.3.3.tgz#adba644ae34f88e1dd9a5864c66ad651caaf628a" - integrity sha512-4ahcL/QDnpjWA2Qs16ZMQif7HjGP2cw3AGjHabybjw7Vm1EKu+cfQN1D78BaZbS1WJNa1opSMF5HNMztx7lR0w== - "@types/bluebird@*", "@types/bluebird@^3.1.1": version "3.5.30" resolved "https://registry.yarnpkg.com/@types/bluebird/-/bluebird-3.5.30.tgz#ee034a0eeea8b84ed868b1aa60d690b08a6cfbc5" integrity sha512-8LhzvcjIoqoi1TghEkRMkbbmM+jhHnBokPGkJWjclMK+Ks0MxEBow3/p2/iFTZ+OIbJHQDSfpgdZEb+af3gfVw== -"@types/bluebird@3.5.29": - version "3.5.29" - resolved "https://registry.yarnpkg.com/@types/bluebird/-/bluebird-3.5.29.tgz#7cd933c902c4fc83046517a1bef973886d00bdb6" - integrity sha512-kmVtnxTuUuhCET669irqQmPAez4KFnFVKvpleVRyfC3g+SHD1hIkFZcWLim9BVcwUBLO59o8VZE4yGCmTif8Yw== - "@types/boom@*", "@types/boom@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@types/boom/-/boom-7.2.0.tgz#19c36cbb5811a7493f0f2e37f31d42b28df1abc1" @@ -4845,15 +4846,7 @@ resolved "https://registry.yarnpkg.com/@types/catbox/-/catbox-10.0.1.tgz#266679017749041fe9873fee1131dd2aaa04a07e" integrity sha512-ECuJ+f5gGHiLeiE4RlE/xdqv/0JVDToegPV1aTb10tQStYa0Ycq2OJfQukDv3IFaw3B+CMV46jHc5bXe6QXEQg== -"@types/chai-jquery@1.1.40": - version "1.1.40" - resolved "https://registry.yarnpkg.com/@types/chai-jquery/-/chai-jquery-1.1.40.tgz#445bedcbbb2ae4e3027f46fa2c1733c43481ffa1" - integrity sha512-mCNEZ3GKP7T7kftKeIs7QmfZZQM7hslGSpYzKbOlR2a2HCFf9ph4nlMRA9UnuOETeOQYJVhJQK7MwGqNZVyUtQ== - dependencies: - "@types/chai" "*" - "@types/jquery" "*" - -"@types/chai@*", "@types/chai@4.2.7", "@types/chai@^4.2.11": +"@types/chai@^4.2.11": version "4.2.11" resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.2.11.tgz#d3614d6c5f500142358e6ed24e1bf16657536c50" integrity sha512-t7uW6eFafjO+qJ3BIV2gGUyZs27egcNRkUdalkud+Qa3+kg//f129iuOFivHDXQ+vnU3fDXuwgv0cqMCbcE8sw== @@ -5338,7 +5331,7 @@ resolved "https://registry.yarnpkg.com/@types/joi/-/joi-13.6.1.tgz#325486a397504f8e22c8c551dc8b0e1d41d5d5ae" integrity sha512-JxZ0NP8NuB0BJOXi1KvAA6rySLTPmhOy4n2gzSFq/IFM3LNFm0h+2Vn/bPPgEYlWqzS2NPeLgKqfm75baX+Hog== -"@types/jquery@*", "@types/jquery@3.3.31", "@types/jquery@^3.3.31": +"@types/jquery@*", "@types/jquery@^3.3.31": version "3.3.31" resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-3.3.31.tgz#27c706e4bf488474e1cb54a71d8303f37c93451b" integrity sha512-Lz4BAJihoFw5nRzKvg4nawXPzutkv7wmfQ5121avptaSIXlDNJCUuxZxX/G+9EVidZGuO0UBlk+YjKbwRKJigg== @@ -5424,11 +5417,6 @@ "@types/node" "*" "@types/webpack" "*" -"@types/lodash@4.14.149", "@types/lodash@^4.14.155": - version "4.14.156" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.156.tgz#cbe30909c89a1feeb7c60803e785344ea0ec82d1" - integrity sha512-l2AgHXcKUwx2DsvP19wtRPqZ4NkONjmorOdq4sMcxIjqdIuuV/ULo2ftuv4NUpevwfW7Ju/UKLqo0ZXuEt/8lQ== - "@types/lodash@^3.10.1": version "3.10.3" resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-3.10.3.tgz#aaddec6a3c93bf03b402db3acf5d4c77bce8bdff" @@ -5439,6 +5427,11 @@ resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.150.tgz#649fe44684c3f1fcb6164d943c5a61977e8cf0bd" integrity sha512-kMNLM5JBcasgYscD9x/Gvr6lTAv2NVgsKtet/hm93qMyf/D1pt+7jeEZklKJKxMVmXjxbRVQQGfqDSfipYCO6w== +"@types/lodash@^4.14.155": + version "4.14.156" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.156.tgz#cbe30909c89a1feeb7c60803e785344ea0ec82d1" + integrity sha512-l2AgHXcKUwx2DsvP19wtRPqZ4NkONjmorOdq4sMcxIjqdIuuV/ULo2ftuv4NUpevwfW7Ju/UKLqo0ZXuEt/8lQ== + "@types/log-symbols@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@types/log-symbols/-/log-symbols-2.0.0.tgz#7919e2ec3c8d13879bfdcab310dd7a3f7fc9466d" @@ -5497,7 +5490,7 @@ dependencies: "@types/mime-db" "*" -"@types/minimatch@*", "@types/minimatch@3.0.3", "@types/minimatch@^3.0.3": +"@types/minimatch@*", "@types/minimatch@^3.0.3": version "3.0.3" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== @@ -5519,11 +5512,6 @@ dependencies: "@types/node" "*" -"@types/mocha@5.2.7": - version "5.2.7" - resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-5.2.7.tgz#315d570ccb56c53452ff8638738df60726d5b6ea" - integrity sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ== - "@types/mocha@^7.0.2": version "7.0.2" resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-7.0.2.tgz#b17f16cf933597e10d6d78eae3251e692ce8b0ce" @@ -5944,32 +5932,12 @@ dependencies: "@types/node" "*" -"@types/sinon-chai@3.2.3": - version "3.2.3" - resolved "https://registry.yarnpkg.com/@types/sinon-chai/-/sinon-chai-3.2.3.tgz#afe392303dda95cc8069685d1e537ff434fa506e" - integrity sha512-TOUFS6vqS0PVL1I8NGVSNcFaNJtFoyZPXZ5zur+qlhDfOmQECZZM4H4kKgca6O8L+QceX/ymODZASfUfn+y4yQ== - dependencies: - "@types/chai" "*" - "@types/sinon" "*" - -"@types/sinon@*": - version "9.0.4" - resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-9.0.4.tgz#e934f904606632287a6e7f7ab0ce3f08a0dad4b1" - integrity sha512-sJmb32asJZY6Z2u09bl0G2wglSxDlROlAejCjsnor+LzBMz17gu8IU7vKC/vWDnv9zEq2wqADHVXFjf4eE8Gdw== - dependencies: - "@types/sinonjs__fake-timers" "*" - -"@types/sinon@7.5.1": - version "7.5.1" - resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-7.5.1.tgz#d27b81af0d1cfe1f9b24eebe7a24f74ae40f5b7c" - integrity sha512-EZQUP3hSZQyTQRfiLqelC9NMWd1kqLcmQE0dMiklxBkgi84T+cHOhnKpgk4NnOWpGX863yE6+IaGnOXUNFqDnQ== - "@types/sinon@^7.0.13": version "7.0.13" resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-7.0.13.tgz#ca039c23a9e27ebea53e0901ef928ea2a1a6d313" integrity sha512-d7c/C/+H/knZ3L8/cxhicHUiTDxdgap0b/aNJfsmLwFu/iOP17mdgbQsbHA3SJmrzsjD0l3UEE5SN4xxuz5ung== -"@types/sinonjs__fake-timers@*": +"@types/sinonjs__fake-timers@6.0.1": version "6.0.1" resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.1.tgz#681df970358c82836b42f989188d133e218c458e" integrity sha512-yYezQwGWty8ziyYLdZjwxyMb0CZR49h8JALHGrxjQHWlqGgc8kLdHEgWrgL0uZ29DMvEVBDnHU2Wg36zKSIUtA== @@ -7473,10 +7441,10 @@ aproba@^1.0.3, aproba@^1.1.1: resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== -arch@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/arch/-/arch-2.1.1.tgz#8f5c2731aa35a30929221bb0640eed65175ec84e" - integrity sha512-BLM56aPo9vLLFVa8+/+pJLnrZ7QGGTVHWsCwieAWT9o9K8UeGaQbzZbGoabWLOo2ksBCztoXdqBZBplqLDDCSg== +arch@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/arch/-/arch-2.1.2.tgz#0c52bbe7344bb4fa260c443d2cbad9c00ff2f0bf" + integrity sha512-NTBIIbAfkJeIletyABbVtdPgeKfDafR+1mZV/AyyfC1UkVkp9iUjV+wwmqtUgphHYajbI86jejBJp5e+jkGTiQ== archiver-utils@^2.1.0: version "2.1.0" @@ -7931,7 +7899,7 @@ async@^2.6.2, async@^2.6.3: dependencies: lodash "^4.17.14" -async@^3.1.0: +async@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720" integrity sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw== @@ -10646,10 +10614,10 @@ commander@3.0.2: resolved "https://registry.yarnpkg.com/commander/-/commander-3.0.2.tgz#6837c3fb677ad9933d1cfba42dd14d5117d6b39e" integrity sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow== -commander@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.0.tgz#545983a0603fe425bc672d66c9e3c89c42121a83" - integrity sha512-NIQrwvv9V39FHgGFm36+U9SMQzbiHvU79k+iADraJTpmrFFfx7Ds0IvDoAdZsDrknlkRk14OYoWXb57uTh7/sw== +commander@4.1.1, commander@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" + integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== commander@^2.13.0, commander@^2.15.1, commander@^2.16.0, commander@^2.19.0: version "2.20.0" @@ -10666,11 +10634,6 @@ commander@^2.8.1: resolved "https://registry.yarnpkg.com/commander/-/commander-2.18.0.tgz#2bf063ddee7c7891176981a2cc798e5754bc6970" integrity sha512-6CYPa+JP2ftfRU2qkDK+UTVeQYosOg/2GbcjIcKPHfinyOLPVGXu/ovN86RP49Re5ndJK1N0kuiidFFuepc4ZQ== -commander@^4.0.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" - integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== - commander@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/commander/-/commander-5.0.0.tgz#dbf1909b49e5044f8fdaf0adc809f0c0722bdfd0" @@ -11134,7 +11097,7 @@ core-js@^2.4.0, core-js@^2.5.0, core-js@^2.5.1, core-js@^2.5.3, core-js@^2.6.5, resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.9.tgz#6b4b214620c834152e179323727fc19741b084f2" integrity sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A== -core-js@^3.0.1, core-js@^3.0.4, core-js@^3.4.1, core-js@^3.6.4: +core-js@^3.0.1, core-js@^3.0.4, core-js@^3.6.4: version "3.6.4" resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.6.4.tgz#440a83536b458114b9cb2ac1580ba377dc470647" integrity sha512-4paDGScNgZP2IXXilaffL9X7968RuvwlkK3xWtZRVqgd8SYNiVKRJvkFd1aqqEuPfN7E68ZHEp9hDj6lHj4Hyw== @@ -11672,48 +11635,39 @@ cypress-multi-reporters@^1.2.3: debug "^4.1.1" lodash "^4.17.11" -cypress@4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/cypress/-/cypress-4.5.0.tgz#01940d085f6429cec3c87d290daa47bb976a7c7b" - integrity sha512-2A4g5FW5d2fHzq8HKUGAMVTnW6P8nlWYQALiCoGN4bqBLvgwhYM/oG9oKc2CS6LnvgHFiKivKzpm9sfk3uU3zQ== +cypress@4.11.0: + version "4.11.0" + resolved "https://registry.yarnpkg.com/cypress/-/cypress-4.11.0.tgz#054b0b85fd3aea793f186249ee1216126d5f0a7e" + integrity sha512-6Yd598+KPATM+dU1Ig0g2hbA+R/o1MAKt0xIejw4nZBVLSplCouBzqeKve6XsxGU6n4HMSt/+QYsWfFcoQeSEw== dependencies: "@cypress/listr-verbose-renderer" "0.4.1" "@cypress/request" "2.88.5" "@cypress/xvfb" "1.2.4" - "@types/blob-util" "1.3.3" - "@types/bluebird" "3.5.29" - "@types/chai" "4.2.7" - "@types/chai-jquery" "1.1.40" - "@types/jquery" "3.3.31" - "@types/lodash" "4.14.149" - "@types/minimatch" "3.0.3" - "@types/mocha" "5.2.7" - "@types/sinon" "7.5.1" - "@types/sinon-chai" "3.2.3" + "@types/sinonjs__fake-timers" "6.0.1" "@types/sizzle" "2.3.2" - arch "2.1.1" + arch "2.1.2" bluebird "3.7.2" cachedir "2.3.0" chalk "2.4.2" check-more-types "2.24.0" cli-table3 "0.5.1" - commander "4.1.0" + commander "4.1.1" common-tags "1.8.0" debug "4.1.1" - eventemitter2 "4.1.2" + eventemitter2 "6.4.2" execa "1.0.0" executable "4.1.1" extract-zip "1.7.0" fs-extra "8.1.0" - getos "3.1.4" + getos "3.2.1" is-ci "2.0.0" - is-installed-globally "0.1.0" + is-installed-globally "0.3.2" lazy-ass "1.6.0" listr "0.14.3" - lodash "4.17.15" + lodash "4.17.19" log-symbols "3.0.0" minimist "1.2.5" - moment "2.24.0" + moment "2.26.0" ospath "1.2.2" pretty-bytes "5.3.0" ramda "0.26.1" @@ -14164,10 +14118,10 @@ event-target-shim@^5.0.0: resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== -eventemitter2@4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-4.1.2.tgz#0e1a8477af821a6ef3995b311bf74c23a5247f15" - integrity sha1-DhqEd6+CGm7zmVsxG/dMI6UkfxU= +eventemitter2@6.4.2: + version "6.4.2" + resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-6.4.2.tgz#f31f8b99d45245f0edbc5b00797830ff3b388970" + integrity sha512-r/Pwupa5RIzxIHbEKCkNXqpEQIIT4uQDxmP4G/Lug/NokVUWj0joz/WzWl3OxRpC5kDrH/WdiUJoR+IrwvXJEw== eventemitter2@~0.4.13: version "0.4.14" @@ -15799,12 +15753,12 @@ getopts@^2.2.5: resolved "https://registry.yarnpkg.com/getopts/-/getopts-2.2.5.tgz#67a0fe471cacb9c687d817cab6450b96dde8313b" integrity sha512-9jb7AW5p3in+IiJWhQiZmmwkpLaR/ccTWdWQCtZM66HJcHHLegowh4q4tSD7gouUyeNvFWRavfK9GXosQHDpFA== -getos@3.1.4: - version "3.1.4" - resolved "https://registry.yarnpkg.com/getos/-/getos-3.1.4.tgz#29cdf240ed10a70c049add7b6f8cb08c81876faf" - integrity sha512-UORPzguEB/7UG5hqiZai8f0vQ7hzynMQyJLxStoQ8dPGAcmgsfXOPA4iE/fGtweHYkK+z4zc9V0g+CIFRf5HYw== +getos@3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/getos/-/getos-3.2.1.tgz#0134d1f4e00eb46144c5a9c0ac4dc087cbb27dc5" + integrity sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q== dependencies: - async "^3.1.0" + async "^3.2.0" getos@^3.1.0: version "3.1.0" @@ -15828,6 +15782,14 @@ gh-got@^5.0.0: got "^6.2.0" is-plain-obj "^1.1.0" +gifwrap@^0.9.2: + version "0.9.2" + resolved "https://registry.yarnpkg.com/gifwrap/-/gifwrap-0.9.2.tgz#348e286e67d7cf57942172e1e6f05a71cee78489" + integrity sha512-fcIswrPaiCDAyO8xnWvHSZdWChjKXUanKKpAiWWJ/UTkEi/aYKn5+90e7DE820zbEaVR9CE2y4z9bzhQijZ0BA== + dependencies: + image-q "^1.1.1" + omggif "^1.0.10" + git-clone@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/git-clone/-/git-clone-0.1.0.tgz#0d76163778093aef7f1c30238f2a9ef3f07a2eb9" @@ -17735,6 +17697,11 @@ ignore@^5.1.1, ignore@^5.1.4: resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== +image-q@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/image-q/-/image-q-1.1.1.tgz#fc84099664460b90ca862d9300b6bfbbbfbf8056" + integrity sha1-/IQJlmRGC5DKhi2TALa/u7+/gFY= + image-size@^0.8.2: version "0.8.3" resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.8.3.tgz#f0b568857e034f29baffd37013587f2c0cad8b46" @@ -18560,15 +18527,7 @@ is-hexadecimal@^1.0.0: resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.1.tgz#6e084bbc92061fbb0971ec58b6ce6d404e24da69" integrity sha1-bghLvJIGH7sJcexYts5tQE4k2mk= -is-installed-globally@0.1.0, is-installed-globally@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80" - integrity sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA= - dependencies: - global-dirs "^0.1.0" - is-path-inside "^1.0.0" - -is-installed-globally@^0.3.1: +is-installed-globally@0.3.2, is-installed-globally@^0.3.1: version "0.3.2" resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.3.2.tgz#fd3efa79ee670d1187233182d5b0a1dd00313141" integrity sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g== @@ -18576,6 +18535,14 @@ is-installed-globally@^0.3.1: global-dirs "^2.0.1" is-path-inside "^3.0.1" +is-installed-globally@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80" + integrity sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA= + dependencies: + global-dirs "^0.1.0" + is-path-inside "^1.0.0" + is-integer@^1.0.6: version "1.0.7" resolved "https://registry.yarnpkg.com/is-integer/-/is-integer-1.0.7.tgz#6bde81aacddf78b659b6629d629cadc51a886d5c" @@ -19821,16 +19788,15 @@ jest@^25.5.4: import-local "^3.0.2" jest-cli "^25.5.4" -jimp@^0.9.6: - version "0.9.6" - resolved "https://registry.yarnpkg.com/jimp/-/jimp-0.9.6.tgz#abf381daf193a4fa335cb4ee0e22948049251eb9" - integrity sha512-DBDHYeNVqVpoPkcvo0PKTNGvD+i7NYvkKTsl0I3k7ql36uN8wGTptRg0HtgQyYE/bhGSLI6Lq5qLwewaOPXNfg== +jimp@^0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/jimp/-/jimp-0.14.0.tgz#fde55f69bdb918c1b01ac633d89a25853af85625" + integrity sha512-8BXU+J8+SPmwwyq9ELihpSV4dWPTiOKBWCEgtkbnxxAVMjXdf3yGmyaLSshBfXc8sP/JQ9OZj5R8nZzz2wPXgA== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/custom" "^0.9.6" - "@jimp/plugins" "^0.9.6" - "@jimp/types" "^0.9.6" - core-js "^3.4.1" + "@jimp/custom" "^0.14.0" + "@jimp/plugins" "^0.14.0" + "@jimp/types" "^0.14.0" regenerator-runtime "^0.13.3" jit-grunt@0.10.0: @@ -19852,10 +19818,10 @@ joi@13.x.x, joi@^13.5.2: isemail "3.x.x" topo "3.x.x" -jpeg-js@^0.3.4: - version "0.3.4" - resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.3.4.tgz#dc2ba501ee3d58b7bb893c5d1fab47294917e7e7" - integrity sha512-6IzjQxvnlT8UlklNmDXIJMWxijULjqGrzgqc0OG7YadZdvm7KPQ1j0ehmQQHckgEWOfgpptzcnWgESovxudpTA== +jpeg-js@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.4.1.tgz#937a3ae911eb6427f151760f8123f04c8bfe6ef7" + integrity sha512-jA55yJiB5tCXEddos8JBbvW+IMrqY0y1tjjx9KNVtA+QPmu7ND5j0zkKopClpUTsaETL135uOM2XfcYG4XRjmw== jquery@^3.5.0: version "3.5.0" @@ -21231,7 +21197,12 @@ lodash.uniq@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= -lodash@4.17.11, lodash@4.17.15, lodash@>4.17.4, lodash@^4, lodash@^4.0.0, lodash@^4.0.1, lodash@^4.10.0, lodash@^4.11.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.6.1, lodash@~4.17.10, lodash@~4.17.15, lodash@~4.17.5: +lodash@4.17.11, lodash@4.17.19, lodash@>4.17.4, lodash@^4, lodash@^4.0.0, lodash@^4.0.1, lodash@^4.10.0, lodash@^4.11.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.16, lodash@^4.17.19, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.6.1, lodash@~4.17.10, lodash@~4.17.15, lodash@~4.17.5: + version "4.17.19" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b" + integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ== + +lodash@4.17.15: version "4.17.15" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== @@ -21241,11 +21212,6 @@ lodash@^3.10.1: resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" integrity sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y= -lodash@^4.17.16, lodash@^4.17.19: - version "4.17.19" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b" - integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ== - "lodash@npm:@elastic/lodash@3.10.1-kibana4": version "3.10.1-kibana4" resolved "https://registry.yarnpkg.com/@elastic/lodash/-/lodash-3.10.1-kibana4.tgz#d491228fd659b4a1b0dfa08ba9c67a4979b9746d" @@ -22423,7 +22389,12 @@ moment-timezone@^0.5.27: dependencies: moment ">= 2.9.0" -moment@2.24.0, "moment@>= 2.9.0", moment@>=1.6.0, moment@>=2.14.0, moment@^2.10.6, moment@^2.24.0: +moment@2.26.0: + version "2.26.0" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.26.0.tgz#5e1f82c6bafca6e83e808b30c8705eed0dcbd39a" + integrity sha512-oIixUO+OamkUkwjhAVE18rAMfRJNsNe/Stid/gwHSOfHrOtw9EhAY2AHvdKZ/k/MggcYELFCJz/Sn2pL8b8JMw== + +"moment@>= 2.9.0", moment@>=1.6.0, moment@>=2.14.0, moment@^2.10.6, moment@^2.24.0: version "2.24.0" resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b" integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg== @@ -23566,6 +23537,11 @@ octokit-pagination-methods@^1.1.0: resolved "https://registry.yarnpkg.com/octokit-pagination-methods/-/octokit-pagination-methods-1.1.0.tgz#cf472edc9d551055f9ef73f6e42b4dbb4c80bea4" integrity sha512-fZ4qZdQ2nxJvtcasX7Ghl+WlWS/d9IgnBIwFZXVNNZUmzpno91SX5bc5vuxiuKoCtK78XxGGNuSCrDC7xYB3OQ== +omggif@^1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/omggif/-/omggif-1.0.10.tgz#ddaaf90d4a42f532e9e7cb3a95ecdd47f17c7b19" + integrity sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw== + omggif@^1.0.9: version "1.0.9" resolved "https://registry.yarnpkg.com/omggif/-/omggif-1.0.9.tgz#dcb7024dacd50c52b4d303f04802c91c057c765f"