Skip to content

Commit

Permalink
[Docs] Update "Alert and action settings" docs to be generated from Y…
Browse files Browse the repository at this point in the history
…AML source (elastic#191787)

This PR:
- Updates the Kibana [Alert and action
settings](https://www.elastic.co/guide/en/kibana/current/alert-action-settings-kb.html)
page to be based off of a YAML source file
(`/docs/settings-gen/source/kibana-alert-action-settings.yml`) that is
manually converted to Asciidoc format
(`kibana-alert-action-settings.asciidoc`) by means of a Perl script
(`docs/settings-gen/parse-settings.pl`). A preview of the new, generated
page is
[here](https://kibana_bk_191787.docs-preview.app.elstc.co/guide/en/kibana/master/alert-action-settings-kb.html).
- Adds the `docs/settings-gen/parse-settings.pl` script which does the
YAML → Asciidoc conversion.

All new files are added to the `/docs/source-gen` folder. 

This is a trial run updating only one page of settings in the docs.
Later, in separate PRs, we plan to convert other pages. After all Kibana
settings pages have been converted, we would ask that the Perl script be
run automatically as part of the CI whenever the YAML files in
`/docs/source-gen` are added or updated.

**Notes:**
- The Docs team is happy to own and maintain the Perl script (sorry to
use Perl - it's the only scripting language that I know).
- In time we also plan to convert all of these files from Asciidoc to
Markdown.
- When we eventually/hopefully get the rest of the Kibana settings files
converted, we will announce the settings doc process to the Kibana team
by email and/or in the Kibana newsletter.

Big thanks to the amazing @lukeelmers and @KOTungseth for guiding this!

---
Why are we doing this? We aim to:
- Create a more consistent appearance for settings across all of the
docs.
- Make it easier for people to contribute, since all Asciidoc/Markdown
formatting is handled by a script.
- Make it more apparent which settings may be missing info, such as the
default values, available options, etc.
---

P.S. I haven't worked in the Kibana repo very much and would appreciate
any help navigating the CI checks.

Rel: elastic/docs-projects#239
  • Loading branch information
kilfoyle authored and viduni94 committed Jan 23, 2025
1 parent 347b0f1 commit 2693a65
Show file tree
Hide file tree
Showing 7 changed files with 3,870 additions and 623 deletions.
3 changes: 3 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -2640,6 +2640,9 @@ oas_docs/.spectral.yaml @elastic/platform-docs
oas_docs/kibana.info.serverless.yaml @elastic/platform-docs
oas_docs/kibana.info.yaml @elastic/platform-docs

# Documentation settings files
docs/settings-gen @elastic/platform-docs

# Plugin manifests
/src/plugins/**/kibana.jsonc @elastic/kibana-core
/src/platform/plugins/shared/**/kibana.jsonc @elastic/kibana-core
Expand Down
227 changes: 227 additions & 0 deletions docs/settings-gen/parse-settings.pl
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
#!/usr/bin/perl

# This script takes all .yml files in the /source directory and, for each, generates an asciidoc file of the same name.
# Run the script: perl parse-settings.pl

use strict;
use warnings;
use YAML::Tiny;
use File::Find;
use File::Copy;

my $file;
# I'm hardcoding these directories just temporarily for testing
my $sourcedir = './source';
my $asciidocdir = 'source/';
my $count;

find(\&iteratefiles, $sourcedir);
print "\n\nProcessed ".$count. " files.\n";
exit;

sub iteratefiles {
$file = $_;
# ignore any non-yaml files
if (!($file =~ /\.yml$/)) {return;}
print "\nParsed file: ".$file;
my $testslice = parsefile($file);
return;
}

sub parsefile {
# Create an output file based on yaml filename
my $outputfile = my $outputfileorig = $file;
$outputfile =~ s/.yml/.asciidoc/g;
# We'll use this to store the contents of the generated asciidoc file

# Read in the yaml file
my $yaml = YAML::Tiny->read( $file );

# Get a reference to the first document
#my $config = $yaml->[0];

my $collection = $yaml->[0]->{collection};
my $product = $yaml->[0]->{product};

# This variable is used to capture all the content that will become our output asciidoc file
my $asciidocoutput = "\n".'// '."This is a generated file; please don't update it directly.\n".'//'." Instead, the updatable source for these settings can be found in ".$outputfileorig;
$asciidocoutput .= "\n".'// '."Collection: ".$collection;
$asciidocoutput .= "\n".'// '."Product: ".$product."\n\n";

# build the page preamble paragraphs
my $page_description = $yaml->[0]->{page_description};
if ($page_description) {
# preserve newlines
$page_description =~ s/\n/\n\n/g;
$asciidocoutput .= $page_description;
}

my $groups = $yaml->[0]{groups};
for my $group (@$groups) {

# Grab the group name, description, and other properties
my $group_id = $group->{id};
my $group_name = $group->{group};
my $group_description = $group->{description};
my $group_example = $group->{example};

# Add the group info to the asciidoc file contents
$asciidocoutput .= "\n\n";
if ($group_id) {
$asciidocoutput .= "[float]\n[[".$group_id."]]\n=== ".$group_name."\n\n";
}
else {
$asciidocoutput .= "[float]\n=== ".$group_name."\n\n";
}
if ($group_description) {
# preserve newlines
$group_description =~ s/\n/\n\n/g;
$asciidocoutput .= "\n$group_description\n";
}


# Add an example if there is one, like this: include::../examples/example-logging-root-level.asciidoc[]
if ($group_example) {
$asciidocoutput .= "\n\n$group_example\n\n";
}

my $settings = $group->{settings};
for my $setting (@$settings) {

# Grab the setting name, description, and other properties
my $setting_name = $setting->{setting};
my $setting_id = $setting->{id};
my $setting_description = $setting->{description};
my $setting_note = $setting->{note};
my $setting_warning = $setting->{warning};
my $setting_important = $setting->{important};
my $setting_tip = $setting->{tip};
my $setting_datatype = $setting->{datatype};
my $setting_default = $setting->{default};
my $setting_type = $setting->{type};
my $setting_options = $setting->{options};
my $setting_platforms = $setting->{platforms};
my $setting_example = $setting->{example};
my $setting_state = $setting->{state};
my $deprecation_details = $setting->{deprecation_details};

# skip settings that are flagged as "hidden"
if (($setting_state) && ($setting_state =~ /hidden/i)) {next;}

# Get the setting options and option descriptions and build the string
my $options = $setting->{options};
my $setting_options_string = "";
if ($options) {
for my $option (@$options) {
my $option_name = $option->{option};
# if ($option_name) {print "\nOPTION = ".$option_name;}
if ($option_name) {$setting_options_string .= '* `'.$option_name.'`';}
my $option_description = $option->{description};
# if ($option_description) {print "\nDESCRIPTION = ".$option_description;}
if ($option_description) {$setting_options_string .= ' - '.$option_description;}
$setting_options_string .= "\n";
}
}

# check if supported on Cloud (these settings are marked with a Cloud icon)
my $supported_cloud = 0;
for my $platform (@$setting_platforms) {
if ($platform =~ /cloud/) {$supported_cloud = 1;}
}

# Add the settings info to the asciidoc file contents
$asciidocoutput .= "\n";
if ($setting_id) {
$asciidocoutput .= "\n".'[['.$setting_id.']]'."\n";
}
$asciidocoutput .= '`'.$setting_name.'`';
if ($supported_cloud) {
$asciidocoutput .= ' {ess-icon}';
}
$asciidocoutput .= "::\n+\n====\n";

if ($setting_state) {
# Add a standard disclaimer for technical preview settings
if ($setting_state =~ /technical-preview/i)
{
$asciidocoutput .= "\n\npreview::[]\n\n";
}

# Mark deprecated settings and add guidance (such as when it was deprecated) if there is any
elsif ($setting_state =~ /deprecated/i)
{
$asciidocoutput .= "**Deprecated:** ";
if ($deprecation_details) {
$asciidocoutput .= $deprecation_details."\n\n";
}
}
# known setting_states are 'technical-preview', 'deprecated' and 'hidden'. Anything else is ignored.
else {
print "\nUnknown setting state: ".$setting_state."\n";
}
}

#if ($setting_description_string) {
# $asciidocoutput .= $setting_description_string;
#}
if ($setting_description) {
# preserve newlines
$setting_description =~ s/\n/\n\n/g;
$asciidocoutput .= "$setting_description";
}

if ($setting_note) {
$asciidocoutput .= "\nNOTE: ".$setting_note."\n";
}
if ($setting_warning) {
$asciidocoutput .= "\nWARNING: ".$setting_warning."\n";
}
if ($setting_important) {
$asciidocoutput .= "\nIMPORTANT: ".$setting_important."\n";
}
if ($setting_tip) {
$asciidocoutput .= "\nTIP: ".$setting_tip."\n";
}

# If any of these are defined (setting options, setting default value, settting type...) add those inside a box.
# We put a " +" at the end of each line to to achieve single spacing inside the box.

if (($setting_options_string) || ($setting_datatype) || ($setting_default) || ($setting_type)) {
if ($setting_datatype) {
$asciidocoutput .= "Data type: ".'`'.$setting_datatype.'`'.' +'."\n";
}
if ($setting_options_string) {
$asciidocoutput .= "\nOptions:\n\n".$setting_options_string."\n";
}
if ($setting_default) {
$asciidocoutput .= "Default: ".'`'.$setting_default.'`'.' +'."\n";
}
if ($setting_type) {
$asciidocoutput .= 'Type: `'.$setting_type.'` +'."\n";
}
}

# Add an example if there is one, like this: include::../examples/example-logging-root-level.asciidoc[]
if ($setting_example) {
$asciidocoutput .= "\n\n$setting_example\n\n";
}

$asciidocoutput .= "====\n";
}
}

# Just in case we need to grab all of the keys, this is how:
# foreach my $key (keys %hash) { ... }

$asciidocoutput .= "\n\n";

# write the contents into the generated asciidoc file
open (WRITE, "> $outputfile") or die("$!");
print WRITE $asciidocoutput;
close WRITE;
print "\nGenerated file: ".$outputfile;
++$count;

return;
}

57 changes: 57 additions & 0 deletions docs/settings-gen/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# YAML-based settings documentation

We're aiming to update the Kibana configuration settings pages to be based off of YAML-formatted source files. The approach has the advantages that:
- The YAML format makes it easier to add new settings and update existing ones. The setting data is separate from almost all formatting, whether Asciidoc or (future) Markdown.
- The HTML files will have a more consistent and user-friendly appearance.
- The YAML format makes it easier for teams to identify missing settings or settings that are lacking details that should be made available in the docs.

The YAML settings files in the `settings-gen/source` folder are converted to Asciidoc source, located in the same directory, by means of the `parse-settings.pl` Perl script. Please do not update the generated Asciidoc files directly as your changes will be overwritten. Please make any required docs changes in the `<name>-settings.yml` files.

Following is a schema for all available properties in a YAML settings file.

## Schema

```
product: REQUIRED e.g. Elasticsearch, Kibana, Enterprise Search
collection: REQUIRED e.g. Alerting and action settings in Kibana
page_description: |
OPTIONAL
Multiline string. Can include tables, lists, code examples, etc.
groups:
- group: REQUIRED e.g. Preconfigured connector settings
id: REQUIRED The ID used for documentation links, e.g., general-alert-action-settings
# description: |
OPTIONAL
Multiline string. Can include tables, lists, code examples, etc.
# example: |
OPTIONAL
Multiline string.
Can include tables, lists, code examples, etc.
settings:
- setting: REQUIRED e.g. xpack.encryptedSavedObjects.encryptionKey
# id: OPTIONAL ID used for documentation links, e.g., xpack-encryptedsavedobjects-encryptionkey
description: |
REQUIRED
Multiline string. Can include tables, lists, code examples, etc.
# state: OPTIONAL One of deprecated/hidden/tech-preview
# deprecation_details: "" OPTIONAL
# note: "" OPTIONAL
# tip: "" OPTIONAL
# warning: "" OPTIONAL
# important: "" OPTIONAL
# datatype: REQUIRED One of string/bool/int/float/enum. For enum include the supported 'options', below.
# default: OPTIONAL
# options:
# - option: OPTIONAL
# description: "" OPTIONAL
# type: OPTIONAL ONe of static/dynamic
# platforms: OPTIONAL, list each supported platform
# - cloud
# - serverless
# - self-managed
# example: |
OPTIONAL
Multiline string. Can include tables, lists, code examples, etc.
```
Loading

0 comments on commit 2693a65

Please sign in to comment.