diff --git a/DEVELOPING.md b/DEVELOPING.md
deleted file mode 100644
index 9f9e3fe..0000000
--- a/DEVELOPING.md
+++ /dev/null
@@ -1,28 +0,0 @@
-## Developing addon builders
-
-In order to load this module properly into the Splunk Add-On builder for development, the following needs to happen:
-
-- Checkout the branch you want to work on
-- tar.gz the directory
-- Go to the splunk addon builder
-- Delete a previous version of the add-on if it exists
-- Import this version
-
-```
-$ git checkout -b 'my working branch'
-$ tar -C .. --exclude=".git" --exclude="tmpdir" -czvf tmpdir/TA-puppet-report-viewer.tar.gz TA-puppet-report-viewer
-```
-
-To add your finished work back to the repo:
-- Export the build from the Splunk Add-On tool
-- Move the downloaded tar.gz to tmpdir
-- Expand the export the export in tmpdir
-- sync the local repo with the tmpdir contents
-- proceed with git commits as needed, etc
-
-```
-$ cd tmpdir
-$ tar xzvf TA-puppet-report-viewer_2_0_1_export.tgz
-$ cd ..
-$ rsync -vr tmpdir/TA-puppet-report-viewer_2_0_1_export/* ./
-```
diff --git a/README.md b/README.md
index dfa9dd0..7bbcdec 100644
--- a/README.md
+++ b/README.md
@@ -29,8 +29,38 @@ For detailed report generation, a feature for Puppet Enterprise Users, there are
![Report Builder](https://raw.githubusercontent.com/puppetlabs/TA-puppet-report-viewer/master/README/img/report_builder.png)
-More information
+Advanced Configuration
----------------
+All report views support using custom indexes for storing event data. They accomplish this with a series of advanced search macros. The queries assume each sourcetype can be stored in it's own index (facts, summary reports, detailed reports, bolt events, action events, Puppet Enterprise metrics).
+
+There is one top level macro, `puppet_index` which defaults to "", if you configure the HEC to use a different index and want all Puppet in that index, change that value here to be `index=puppetindexname`.
+
+If you are using [puppetlabs/splunk_hec](https://forge.puppet.com/puppetlabs/splunk_hec/readme) version 0.5.0 or later, you can specify different HEC tokens for Summary Reports, Facts, and Metrics. Then create an index and an associated HEC token associated with those sourcetypes, and configure both the splunk_hec module in Puppet with those new values. Actions, Bolt Events, and Detailed Reports are all submitted via different tools and would need ot be changed according to use a different HEC token. Then the corresponding macro's updated to use those indexes.
+
+For example, if you want most Puppet data to go to one index, but Facts, Metrics, and Detailed Reports to go to their own indexes, one would follow these steps:
+- Create four indexes: puppet_data, puppet_facts_data, puppet_metrics_data, and puppet_detailed_data (or whatever name makes sense), each with their desired timespan, retention, etc.
+- Create four HEC's (example names):
+1. `puppet` with sourcetype of `puppet:summary` and the index `puppet_data`
+2. `puppet_facts` with sourcetype of `puppet:facts` and the index of `puppet_facts_data`
+3. `puppet_metrics` with sourcetype of `puppet:metrics` and the index of `puppet_metrics_data`
+4. `puppet_detailed` with sourcetype of `puppet:detailed` and the index of `puppet_detailed_data`
+- Configure the `splunk_hec` module with the corresponding tokens
+1. `splunk_hec::token` with the value from the `puppet` HEC (since you want all Puppet using splunk_hec plugin to go here, except for facts and metrics)
+2. `splunk_hec::token_facts` with the value from the `puppet_facts` HEC
+3. `splunk_hec::token_metrics` with the value from the `puppet_metrics` HEC
+- Update the Puppet Report Viewer's configuration to use the `puppet_detailed` HEC token, because detailed reports are pulled from Puppet and generated by the alert action in this application
+- Update the advanced search macros to use the new values:
+1. Open Advanced Search under the Settings -> Knowledge menu
+2. Select `Search Macros`
+3. Select `puppet_index` and change the definition to `index=puppet_data`, click save
+4. Select `puppet_facts_index` and change the definition to `index=puppet_facts_data`, click save
+5. Select `puppet_metrics_index` and change the definition to `index=puppet_metrics_data`, click save
+6. Select `puppet_detailed_index` and change the definition to `index=puppet_detailed_data`, click save
+- Reload the main view of the Puppet Report Viewer app, and you should see data, or perform the following search:
+```
+`puppet_all_index` sourcetype=puppet:*
+```
+
More information
----------------
diff --git a/README.txt b/README.txt
deleted file mode 100644
index a81c062..0000000
--- a/README.txt
+++ /dev/null
@@ -1 +0,0 @@
-This is an add-on powered by the Splunk Add-on Builder.
diff --git a/README/DEVELOPING.md b/README/DEVELOPING.md
index 5722e80..c0d2b01 100644
--- a/README/DEVELOPING.md
+++ b/README/DEVELOPING.md
@@ -10,7 +10,7 @@ In order to load this module properly into the Splunk Add-On builder for develop
```
$ git checkout -b 'my working branch'
-$ tar -C .. --exclude=".git" --exclude="tmpdir" -czvf tmpdir/TA-puppet-report-viewer.tar.gz TA-puppet-report-viewer
+$ COPYFILE_DISABLE=1 tar -C .. --exclude=".git" --exclude="local/" --exclude="metadata/local.meta" --exclude="tmpdir" -czvf tmpdir/TA-puppet-report-viewer.tar.gz TA-puppet-report-viewer
```
To add your finished work back to the repo:
@@ -22,7 +22,7 @@ To add your finished work back to the repo:
```
$ cd tmpdir
-$ tar xzvf TA-puppet-tasks-actionable_2_0_1_export.tgz
+$ tar xzvf TA-puppet-report-viewer_2_0_1_export.tgz
$ cd ..
-$ rsync -vr tmpdir/TA-puppet-tasks-actionable_2_0_1_export/* ./
+$ rsync -vr tmpdir/TA-puppet-report-viewer_2_0_1_export/* ./
```
diff --git a/README/publishing.md b/README/publishing.md
new file mode 100644
index 0000000..ecab97d
--- /dev/null
+++ b/README/publishing.md
@@ -0,0 +1,13 @@
+Puppet Report Viewer Publishing Guide
+==============
+
+This documents how this plugin is published.
+
+- Finalize testing
+- Bundle this app up using the export options in the developing.md guide
+- Import tar.gz into Splunk AddOn Builder for final validation preflight check
+- Complete and fix validation steps if needed
+- Make needed changes, tag build with final release number and publish a release in GitHub adding notes from releasenotes.md
+- Rename file name to be .spl instead of .tar.gz
+- Import .spl version to Splunk to verify that package installs properly
+- Upload .spl to Splunkbase
\ No newline at end of file
diff --git a/README/releasenotes.md b/README/releasenotes.md
new file mode 100644
index 0000000..281372b
--- /dev/null
+++ b/README/releasenotes.md
@@ -0,0 +1,16 @@
+Release Notes
+==============
+
+1.5.1:
+New Features:
+- Full dashboard updates
+- Support for Facts sourcetype (puppet:facts), and dashboards to use it
+- Introduces "Report Builder" page to help a user build reports and then craft custom search from the iterface to use for alerts or their own uses
+- Introduces Advanced Search macros to allow for customized indexs without requiring to modify the app. See Advanced Configuration section of the readme
+- Add's sourcetypes of puppet:action, puppet:metrics, for future use
+- Example Alert added, the search to generate a detailed report for any summary report that isn't "unchanged" has been added to the app, but set as disabled
+
+Fixes:
+- Duplicate item entry fixed, sourcetype's are now configured to extract KV from json only once
+- [Updated documentation](https://github.com/puppetlabs/ta-puppet-report-viewer)
+
diff --git a/TA-puppet-report-viewer.aob_meta b/TA-puppet-report-viewer.aob_meta
index 8161b9e..cd7c93b 100644
--- a/TA-puppet-report-viewer.aob_meta
+++ b/TA-puppet-report-viewer.aob_meta
@@ -1 +1 @@
-{"global_settings_builder": {"global_settings": {"customized_settings": [{"default_value": "puppet.company.com", "value": "puppet.c.splunk-217321.internal", "format_type": "text", "required": true, "help_string": "Hostname of PuppetDB server, usually the same as the Puppet Enterprise console.", "name": "puppet_db_server", "internal_name": "", "label": "Puppet DB Server", "type": "text"}, {"default_value": "", "value": "", "format_type": "password", "required": true, "help_string": "https://puppet.com/docs/pe/2019.0/rbac_token_auth_intro.html#generate-a-token-using-the-api-endpoint", "name": "auth_token", "internal_name": "", "label": "Puppet Auth Token", "type": "password"}, {"default_value": "splunk.company.com", "value": "splunk-dev.c.splunk-217321.internal", "format_type": "text", "required": true, "help_string": "Hostname of the Splunk HEC endpoint", "name": "splunk_server", "internal_name": "", "label": "Splunk Server", "type": "text"}, {"default_value": "", "value": "", "format_type": "password", "required": true, "help_string": "HEC Token with puppet:detailed sourcetype - https://docs.splunk.com/Documentation/Splunk/latest/Data/UsetheHTTPEventCollector", "name": "splunk_hec_token", "internal_name": "", "label": "Splunk HEC Token", "type": "password"}, {"default_value": "", "value": "", "format_type": "text", "required": false, "help_string": "User facing hostname for PE Console, defaults to PuppetDB value if none provided", "name": "pe_console", "internal_name": "", "label": "PE Console Hostname", "type": "text"}]}}, "validation": {"progress": 1.0, "status": "job_finished", "validation_id": "v_1549419514_51", "validators": ["best_practice_validation", "data_model_mapping_validation", "field_extract_validation", "app_cert_validation"]}, "field_extraction_builder": {"puppet:detailed": {"data_format": "json", "is_parsed": true}, "puppet:facts": {"data_format": "json", "is_parsed": true}, "puppet:bolt": {"data_format": "json", "is_parsed": true}, "puppet:summary": {"data_format": "json", "is_parsed": true}}, "sourcetype_builder": {"puppet:detailed": {"metadata": {"cims_count": 0, "event_count": 0, "extractions_count": 0, "data_input_name": null}}, "puppet:summary": {"metadata": {"cims_count": 0, "event_count": 0, "extractions_count": 0, "data_input_name": null}}, "puppet:bolt": {"metadata": {"cims_count": 0, "event_count": 0, "extractions_count": 0, "data_input_name": null}}}, "basic_builder": {"version": "1.4.0", "appname": "TA-puppet-report-viewer", "description": "", "theme": "#000000", "author": "Puppet, Inc.", "small_icon": "iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAAEyklEQVRYR+2YTWxUVRiGn3Pu/Hb+agKREmMqi2KaSE1IKBAJCwmkBBdoV5p0gYk/daGpLZTEGjGGOpZaSbpQNo1FEExIoCYVg6ZQQE1kwYrGYiIqIVhr0U5/Zu69M8ecMx0Z6kynNLRhwdnM3Dtz5zz3/d7ve2dGVFdXq3Q6zf2wLMtCrF69WjmOcz/w4PV6HwDNWYk5FFIoxMzFuUdljnNHi1HjIkAKS1o8ttwGF5QhyOL9PS35MyEQUi4GT2EPaR0ejXkZ6E6hJkAKF5BgQe8ZScunHsJB3ZX3XquiJauISM53uIz+Jbg4HGLVcpsnHklyeABajnsIBzT2EgKtjArOxx0Gfw6x+fUEbzwj6XpV0Xvaw+5jEArcexjtgaIKrYgKLsYdro1YHPlGsq5KsuXJCT4+7WffCZdQwLd0HtI7VcTgwocOKuEi/C7K9aJsxbXxENvfcUkhkTNm/z/ZwtUrqlDQL3lpSznplINAkEwrttTYrK38h1+nQ2xvcRlxFZ7MjJOUIhD0IqWe+NaC1SsKpJTCTkFGZttdCYFKpTn5bhnrVo7z+1SUb7/L4PNmM1AEPXSfTDIy6UcJDbUwlUoMxtkfK0gmXPr2+Vm7IqHnwYwSEqIW2/d6+WlEs2QH6ELWXWaZIuVavPyUTdvzaUjlWl9AxENdm8Xw0gJlsB0vjU+n2VufglQmOzB1eaIWdW95lhZIp9tUUtG0FXY/50BKswhQCqJe6tokwyNicUp22wUzgaoESQdqVyk+a4YyZYPPYzLOrKiPHW8qhv647aHx8XHzks/nw7Ztli1bhv7edevWLcrLywtarKCHzBYqw/RU7m4lTsZl8+MWh1sFQTVNZ3+II2dSeP3S9JMWamzKIq2rCAbg3LlzZvIODAxQVVXF+vXrzfmzZ8/S1NTE5OQkclZIFwWqCFsc2xckPaWDVYErqXhoEp90+eh0hPZjDuFYGjEDkO39262uNx4aGiIcDhdU4ubNm2zcuBGRd82c0VERFVz4wMFN6FmUNp3sERlO/BjixU9slsc8uWIV3DAfaGxsjMbGRq5cuUJzczMNDQ3mms7OTg4cOEBZWdl/n1E87TVQ3OHiLxY79ghe2wHvNaTo+SpE6xduybTPB9KbdnR0EIlEGB0d5fLly1RWVnL16lU2bNhALBabJ9D7Dj/8Jnm2LckrW728/YKk92vB7uOiZNrnAx08eJB4PE4wGDSGPnToEPX19SQSCaqrq43pc6uoQisjksG4bb6gCZ9AZXSEuBwe9LDnc4uyoDFN0WE8W6Guri4CgYAB6u/vp7a2Fu2jmpoao9ycQLrLHo5IevdaONrU2bZDeKDvew+dX6aJ+LWb5wd06dIldu7cycTEBHV1dRw9etTs39fXx65du+ZTMkUmI0hM2Xd0geYKWBJf0CoZV/kK6aDWyly/fp01a9agj3V3bdq0iRs3btyh8l1m2fzjMh9It782sS6ZBtEDs7W1lVOnTplz+WtJgNrb2+np6WHbtm2mbHowauDZMHPOoflrUfidhbrM3L0Q6N/vxdaiKjQ8PGxavbu7m/3795vnpdaiAel/U1paWkxZBgcHTZ7pzUqtRQPSG+vwzPkif/jNBbWoQKXUKPT6A6BSqhmF7re/9P4FOOuQpa0DAR0AAAAASUVORK5CYII=", "friendly_name": "Puppet Report Viewer", "visible": true, "tab_build_no": "12", "tab_version": "2.2.0", "build_no": 3, "large_icon": "iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAYAAABV7bNHAAANlklEQVR4Xu2cfYxVZX7HP885576/zAzzBjMwFBhoBKw2JVZUrLLCtrL8QbIx7R9q0xq1WdG6G5cdtNjKi0LqCuxSu4ZVqmss3UhbYo0moBu6UaJGa0xbEBjeX2SY97lv555znuZ37lwchhnmXl6KjPMjwMy9zz33ns/5/l6fM6Pmzp2r+/r6GLPzCcTjcdTUqVP1GJzhCajrr79ep1KpMUZDEIjFYowBuoA0xgCN4DdjgMYAXVpoHVPQmIL+XxVUKJc0JgpN4Ts1zCcoPG/4/xbXXHvlVhkupglYAdp6HDra0xAIg/ZAu6AGQuqH4BmgDZrGh4iEcuRd4Wj5eK8lKwMQdKQ9bmsOc9cchZ3qwsoHcU1jwEkXNaVRARNX22z9reJEl0kkGATlU7qmrCxArcczrP6ziSxfEYATe4BqMMwCIN+TBqgj5EHOYOGPsvzn/1o0VgbRRu4CLvnN5FYyIDn1gyc9li+qYvVjHej2DI6OEdB9YDi+O/nmBQv/hzQ6H+Su1fBRq0ltZQBFfvQCknNuPemybHGS5/46jz6VwstnMZPVEKsGtxuIQsdpPEdhxEECzx+vzLPrcJj6ZBADe5QDOuXwk++FefZRBWc6oKKS7b9x2boToskQViBNyxKLpnoPvAzk43xnlcPuQ5rGhIk7XML7ZnqX/6lKdjFfQT6gKM8+CrSdgaYGntmQ5ulXO8CoImB28OmGGmbPtCGTh1yUu1bl+fAQNCQsvIEx6hsMZeBHuwRA7TCpiud+HqRlSydGVYBx2uU368LMmpGDPgWOxYJVDh8cNGlIqm8HoB8vjrL2EQ3tHVBXyaY3bJ7+VYbKmgQx4I2fWMxsSoPt4tkh/uhZg//ZZ1NTYZE31TmJ7loQUdkKemJxlHUC6Ewnng7QJVjSBqY28cwg8eBpTMPCiPage6uY8VSe1jMpplRVgCd19SguFFtPufx4cZi1Sz0404XOx1AhG8JpIOHXQToD2lYYZg6iFSzfDM/+2qZ2UoDKoMaV6tu3/rJgSBnJGono8vfqAi1PQSdsWr4fZ80PRUFnwAuBlwNDWggH/EI5BiqHnTEJSg05vpq1m7O0vNJLfWOUiDzoCR5J+WKF1PY1Bo2iUHxqWeh/ffWsDECKQ6f7+KvvTuT5v6wl292G6yk8v3GVPx62Ujh5lwk1eUzVhe52UZUpqJvMMz9N8fTrKSY1VBCMp3FcC0tauUGVkTTBHiGUyoHKogn1F6FXR0klA5LrnNcQsAySoSA2JkEnj5IKWoHWCpRHVxamVBj82zMGibpe9H4HVWNDVTVrN2laftWLToSJWXlZjrxMnE2+9gtx1yOesIglwmjHwdAOnrqQO15ZdZUMSD6GaXjkbIe+dABtOv5ZBV255v3OovKkrBB9Z/LMv87g39c1EY+dRB91UJUmVCV5bovBr3d4TKhIo03X1568XkAJ6aClONWZ4US3iRVKYnkZXGOwzq4slIuugwpNaRDLE7XkyJoSH/q7eVGCH1sCuGaew/tt5s3K89bzNSRjWbyjxzCSSYjU4qWyGAPL6n44fhybOI71m3P8aPNXTGkcB36De/VCdVkKKpDVaKmItdGfh87qpz+eeL4qXCPAwSO9fLc5xL/8fQXJQBd05iHgQGBQhpJ5kmuCkYGJdfzDZsUPfpFiemMIxxQ3u3rlwUUAKkHeoiatcY0EBw8cZ/EfRPnnv40TpQNykvEGmfDyTD8o01jL+i0eP3y5j2kNEV+Now+QH04KcaM3a2Fl03y0CibO0NA1BOCzgHLQWPNtAFSAIxVNKmNQHcmx46kADZNy0CPPScoanJkkG2ahQRSkR7+CFC5Kh+nOOVRHbHY+GaNhUi/0+Ml8DJCBh9YherMuVbEsO5cnaJzU0w9ISu7BFXJRQXWj38WUVmjDQWmTLscgksvx4d+ZTJzhQGexvxpYGRc2iFA2NFT3u1hq9AZpQeAYmog22XOsl9+fFOe3a12iURvSUnZLiCrGIFnt+p0+yoHGKjb8k8fjL49iQFoqbB1l7+kcN9Zm2PpkPTOaU3C6B8z+inLghqPfc0j6z/uAfvaK4tHNGZobw0OmecdxzkuFlmVhGAbZbJauri7S6TTBYJBEIuH/VUqhdfn9XNl1kGSmYsF4Tn3rn7eBUh7aMjlwOMvv1qf5YON0xtWewTv+FUagAqrCYITALXbz/Y2YDhQATa7mlz/L8MCGTpqbYucAEgCe59HW1obrfr3HJnDkVrkTJ04wbtw4Zs2axYQJE+jt7eXAgQN8+eWXyJqmpiYfohyjVCsZkICxcJFjp70YQXJo5aCRbZ5ir+SCpTh+0qG52uE/VjXQPPMIzmEHKxSG2gjbtsPWD3PUxSVOFWD7BYHfjGmsSID/PmLwX4ds4mEpHr++6qIKAfHCCy/4IIrW3t7Ovffey4IFC1i2bBlz5sw5+9ypU6fYsWMHW7ZsYefOndTV1VFVVUU+L1tQI1vJgORQhmGRtlPk+7KgK/rnNXIlC62DNmzauxRzfifKOz9VVNe4eEfSGEkbkuN4Zovlj2fJ51DhMNoo6PEc4ec9qipN6ipN8k7/hmT/eYjrVFdX+4oYbLt37+bmm2++4Blv2rSJxx57jIqKCv84A1U43AtLBiQn8VW7zff/sI5Hl8To60mjpR/z+zKFxB3LNUj3BZk9u5cJDV+h2/pQwSporuGVX6T4i4056uoTVCQccuT8pneoqCC93FDW09PjX/1du3Yxfvz4kS//ECteffVV7r//ft/dxO1GsjIAKQ4eS7PyT2t56kkD2k4VJor+QKcAyS8AlQk5B69NYURMqA+x4eUIf/N6J/GkQSJqkTdyGK7hN7VDmRxqKHCXA5C830MPPcRLL71Ec3PziPGoZEBy4MJMOsLapS60d5H3LAIy8oj2bz3ng5BOo5XhcyJWwerXPZ7a0kdlo0V9JIytpT4qdvPDXb+hs81IgI4ePcqaNWs4duwYkydP5uGHH2b27NnnvcnevXu54YYbqK2t9TPdhaxMQA7LvhfluaWy7dOFpw3sbBWenUVbWX/EEQ1nMVQQQwK4E+DGJyLsaXdpqnPw3EubDF4I0LvvvusHaslwA2379u0sXrz4PAb33HMPb775JlOmTLlg+r8EQO1QX8nGN1zWvJKluipOLGiz9YkKpkzrg1wPOlXDvHUenx/MUZ+MFO7uKIwOL8qGAyS1z3XXXcehQ4eYMWOGH3wlnbe2tlJTU8MXX3zhq2Wgvfbaa9x3331MnTr1CijoEaCzA8ZHWPmSyYpfGhhVJuFghg9XGvzeNClpcuhsgu+s1Ow+bDMhKcP9S5sMDgdI6h1J7ZLuJUMVzTRN9u3bx4svvui720D75JNPmD9/PpWVlQQCUoMNbRenIH9ntQuaYqx80WbF5pzs8hMxs3y0LsLsGQZkbbADLFiV54NDBo0JC/cS9+aHAyQ/JTB37lw/9kiWK5pUz1IoStaSOmigydp58+b5FbfUVlcAUCfUJdnyr3nWbuujtjJI3ND844MJmprswu15Wbk/yOGDQ/iALvXmhXIB+YmltZUlS5awbdu2cxicPn3aB9TR0UFSZuWXS0Eti2KseURBZw+e46J1JYQUhtGLp6Nopw9Te6iQCfkgC1bK7S+KCckAbnFv56IiEJQLqKigpUuXsnHjxnPedf/+/dx+++3+Y5FI5DIBOunRsjjOmh+kcLq6Me0gygqCNeAOM9vfxIGwRjtBFq52+eiAQW1FGK0u7Q6z4QDJ49J/ZTKZszGo2JyKgt566y0WLVrkQ5CGVZ6TYlNaE+nZJFZdBgUpWo9mePL+CaxabsKZ4+DE8e+KKkbf/qq6cFmAXJz5T7Sza6/LpIogpgzRLlI98rLhAElfdffdd/s9l1TIUtvIY4cPH+aOO+7g/fffP+9d169fz+OPP375spicWHuXy5/cGODP5wdxejP+VrNH/ryKWDgZYY2TjfL82yn2tcVIRF1MXH9OfbF2oTpI+rQHHnjAr22KdueddyLpvLGx8by3vOWWW/j8889HbFnKyGIaywwjP5nY2d2NaUT8/THJTINbBqU1eaUIO1BXHYZwGEfbWJ55Sbe/DAeo6DZC4Z133mHPnj3MnDmThQsXnuNWRUpvv/2273JSJIq7XcjKAOR7MB4GrjbPtmACYyhRyF69VgpLOf6NDcPfkV+6nkZqNUo90k033eSrR9xxpNlQmYBK/QhXZt1wgOQkpXIu2kBFDf4kUj2L202fPv3yjjuuzCmXd9ThAMlQTILugw8+OGzQ/fjjj1mxYoXvguJaArSUEeyoUJCAk5ZBZs8tLS3ceuut/veSyaRzlzQvTavEz2nTpA8qpPtSbFQAknbhtttu47PPPvPPORqN+vc327ZNd7fc4A4TJ070C8JSpogDwY0KQMVe7Pjx436hKLseAkIylDSiUgiWqpjBqhpVgAY3q6W40EhrxgCNQOiaAiTxRLZ7Pv300/NGFDJCPXLkyDnbQSOpo5TnrylAMhiTGPPee+/5QbdY78jjEqS/9S5WBCJjVAm+xe+lUJT5TnHUWooySl1zTSmoOMKQ0erAdC2PCzTJViO1DqWCKa67pgCVe3KXY/0YoNGUxS6HIso9xpiCxhRUrmbOXT+moDEFXQYFjf2StwtDVGO/JnB4QLIt/X/QcXpolFEl9wAAAABJRU5ErkJggg=="}, "alert_action_builder": {"modular_alerts": [{"parameters": [{"default_value": "", "value": "4e5d808f-60fb-4edc-ac1f-f4d3ae4b1e68", "format_type": "text", "required": false, "help_string": "Used for testing, don't use in deployments.", "name": "transaction_uuid", "label": "Transaction UUID", "type": ""}], "smallIcon": "iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAACC0lEQVRYR+2YTWsTURiFz0lnmiYoYrRpK0oX/RWiSJduRE1DJaIrd4L/pTtXioJFCaYVBEEouNEfUAqlGzeKtYmlXZQaDc49kpREG3JzJ01ipphZDu9973PP+3E/CMunQuo86GcgxGw2jf+VIM/c9qbTLoQBrUDLk7MwXAE54vQjXObc5genXQiDYwwklQAEtUUSPsCzjQUPRCG/PM1ru5+qECqkL4He+yHQoaSOnELSI8SwVwuTdA6IzQ82ZO1K1gS3mS0+D1HVTpPelD20B5kM54orzhkdBj0CqoYRZfDXRWZKq91A2YHeII5KKg2Mtfb/o5LAqL8A4CrAAz/SdyjIMFt6e1QoK1AYh1o6eQY6UQBxpQFVDR90DzL2vS3QR85/22o1R1dAdYd6OfUOMc6GWcRBpzf3eXPrYf+A8pPj8Pj0UPja0fUbqJY+y+kZGG8NRMKp1D8BepW6ABPfAJgcArVSQEOFHImhF+kZ+BFJai2eOo2x5GMQ1/80yDYr6HeVRaYx1pRJJBeb9rN9UA9gaN86vJ/rvLHzuaNOrTxGgfGUVfgRLw5goSlMZZjgFrPF185eZDE4RsePji6K2odMrhtl6oL1RiGju8x+fXbUMP09LjxQ5A75kbsGDYGaMlLNVSZ8AVR/bIgDnGgMGchjQ7sS+j+BClPTIO5ACvGkV3nCXOu9qdPe9BvCCFQ0gPAA5gAAAABJRU5ErkJggg==", "code": "# encoding = utf-8\nimport json\nimport requests\nimport collections\nfrom datetime import datetime\nfrom requests.packages.urllib3.exceptions import InsecureRequestWarning\n\nrequests.packages.urllib3.disable_warnings(InsecureRequestWarning)\n\ndef get_resource_events(uuid, server, token):\n \n # setup the headers\n headers = {'X-Authentication': token}\n #setup the url\n url = 'https://{}:8081/pdb/query/v4'.format(server)\n\n report_elements = [\n 'hash', \n 'status', \n 'puppet_version', \n 'report_format', \n 'catalog_uuid', \n 'job_id', \n 'cached_catalog_status', \n 'configuration_version', \n 'environment', \n 'corrective_change', \n 'noop', \n 'noop_pending', \n 'certname', \n 'transaction_uuid', \n 'code_id', \n 'resource_events', \n 'producer_timestamp', \n 'producer', \n 'start_time', \n 'end_time', \n 'receive_time', \n 'logs', \n 'metrics'\n ]\n\n joined_elements = ', '.join(report_elements)\n\n query_string = {}\n query_string['query'] = 'reports[{}] {{ transaction_uuid = \"{}\" }}'.format(joined_elements, uuid)\n \n resource_events = json.loads(requests.post(url, json=query_string, headers=headers, verify=False).text)\n\n return resource_events\n\ndef submit_to_splunk(detailed_report, splunk, hec):\n # setup the headers\n headers = {\"Authorization\" : 'Splunk {} '.format(hec) }\n #setup the url\n url = 'https://{}:8088/services/collector'.format(splunk)\n \n # cleanup start_time\n # start_time = 2019-04-03T12:41:27.481Z\n utc_time = datetime.strptime(detailed_report['start_time'], \"%Y-%m-%dT%H:%M:%S.%fZ\")\n epoch = (utc_time - datetime(1970, 1, 1)).total_seconds()\n\n report = {\n 'host': detailed_report['certname'],\n 'time': epoch,\n 'sourcetype': 'puppet:detailed',\n 'event': detailed_report\n }\n\n requests.post(url, json=report, headers=headers, verify=False)\n\ndef is_json(myjson):\n try:\n json_object = json.loads(myjson)\n except ValueError as e:\n return False\n return True\n\ndef process_event(helper, *args, **kwargs):\n \"\"\"\n # IMPORTANT\n # Do not remove the anchor macro:start and macro:end lines.\n # These lines are used to generate sample code. If they are\n # removed, the sample code will not be updated when configurations\n # are updated.\n\n [sample_code_macro:start]\n\n # The following example gets the setup parameters and prints them to the log\n puppet_db_server = helper.get_global_setting(\"puppet_db_server\")\n helper.log_info(\"puppet_db_server={}\".format(puppet_db_server))\n auth_token = helper.get_global_setting(\"auth_token\")\n helper.log_info(\"auth_token={}\".format(auth_token))\n splunk_server = helper.get_global_setting(\"splunk_server\")\n helper.log_info(\"splunk_server={}\".format(splunk_server))\n splunk_hec_token = helper.get_global_setting(\"splunk_hec_token\")\n helper.log_info(\"splunk_hec_token={}\".format(splunk_hec_token))\n pe_console = helper.get_global_setting(\"pe_console\")\n helper.log_info(\"pe_console={}\".format(pe_console))\n\n # The following example gets the alert action parameters and prints them to the log\n transaction_uuid = helper.get_param(\"transaction_uuid\")\n helper.log_info(\"transaction_uuid={}\".format(transaction_uuid))\n\n\n # The following example adds two sample events (\"hello\", \"world\")\n # and writes them to Splunk\n # NOTE: Call helper.writeevents() only once after all events\n # have been added\n helper.addevent(\"hello\", sourcetype=\"sample_sourcetype\")\n helper.addevent(\"world\", sourcetype=\"sample_sourcetype\")\n helper.writeevents(index=\"summary\", host=\"localhost\", source=\"localhost\")\n\n # The following example gets the events that trigger the alert\n events = helper.get_events()\n for event in events:\n helper.log_info(\"event={}\".format(event))\n\n # helper.settings is a dict that includes environment configuration\n # Example usage: helper.settings[\"server_uri\"]\n helper.log_info(\"server_uri={}\".format(helper.settings[\"server_uri\"]))\n [sample_code_macro:end]\n \"\"\"\n\n #helper.log_info(\"Alert action generate_detailed_report started.\")\n \n events = helper.get_events()\n for event in events:\n event_dict = event\n\n #helper.log_info(event_dict)\n\n # attempt to parse the event store to see if it's json\n if is_json(event_dict[\"_raw\"]):\n event_content = json.loads(event_dict[\"_raw\"])\n event_uuid = event_content['transaction_uuid']\n event_pe_console = event_content['pe_console']\n else:\n event_uuid = None\n event_pe_console = \"\"\n\n uuid = helper.get_param(\"transaction_uuid\") or event_uuid\n\n pe_console = helper.get_param(\"pe_console\") or event_pe_console\n\n #helper.log_info('uuid={}'.format(uuid))\n\n puppet_db_server = helper.get_global_setting(\"puppet_db_server\")\n auth_token = helper.get_global_setting(\"auth_token\")\n splunk_server = helper.get_global_setting(\"splunk_server\")\n hec_token = helper.get_global_setting(\"splunk_hec_token\")\n\n resource_response = get_resource_events(uuid, puppet_db_server, auth_token)\n\n detailed_report = resource_response[0]\n\n mdict = collections.defaultdict(dict)\n\n for m in detailed_report['metrics']['data']:\n mdict[m['category']][m['name']] = m['value']\n \n detailed_report['metrics'] = dict(mdict)\n\n detailed_report['url'] = 'https://{}/#/inspect/report/{}/events'.format(pe_console, detailed_report[\"hash\"])\n\n detailed_report[\"pe_console\"] = pe_console\n\n submit_to_splunk(detailed_report, splunk_server, hec_token)\n\n helper.writeevents(host=\"localhost\", source=\"localhost\")\n\n return 0", "description": "Generates a detailed report from a puppet:summary event", "short_name": "generate_detailed_report", "largeIcon": "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", "label": "Generate detailed report", "uuid": "1f0457025dbb43979505cabeb469594a"}]}}
\ No newline at end of file
+{"global_settings_builder": {"global_settings": {"customized_settings": [{"default_value": "puppet.company.com", "value": "puppet.c.splunk-217321.internal", "format_type": "text", "required": true, "help_string": "Hostname of PuppetDB server, usually the same as the Puppet Enterprise console.", "name": "puppet_db_server", "internal_name": "", "label": "Puppet DB Server", "type": "text"}, {"default_value": "", "value": "", "format_type": "password", "required": true, "help_string": "https://puppet.com/docs/pe/latest/rbac_token_auth_intro.html#generate-a-token-using-the-api-endpoint", "name": "auth_token", "internal_name": "", "label": "Puppet Auth Token", "type": "password"}, {"default_value": "splunk.company.com", "value": "splunk-dev.c.splunk-217321.internal", "format_type": "text", "required": true, "help_string": "Hostname of the Splunk HEC endpoint", "name": "splunk_server", "internal_name": "", "label": "Splunk Server", "type": "text"}, {"default_value": "", "value": "", "format_type": "password", "required": true, "help_string": "HEC Token - https://docs.splunk.com/Documentation/Splunk/latest/Data/UsetheHTTPEventCollector", "name": "splunk_hec_token", "internal_name": "", "label": "Splunk HEC Token", "type": "password"}, {"default_value": "", "value": "", "format_type": "text", "required": false, "help_string": "User facing hostname for PE Console, defaults to PuppetDB value if none provided", "name": "pe_console", "internal_name": "", "label": "PE Console Hostname", "type": "text"}]}}, "validation": {"progress": 1.0, "status": "job_finished", "validation_id": "v_1549419514_51", "validators": ["best_practice_validation", "data_model_mapping_validation", "field_extract_validation", "app_cert_validation"]}, "field_extraction_builder": {"puppet:detailed": {"data_format": "json", "is_parsed": true}, "puppet:facts": {"data_format": "json", "is_parsed": true}, "puppet:bolt": {"data_format": "json", "is_parsed": true}, "puppet:summary": {"data_format": "json", "is_parsed": true}}, "sourcetype_builder": {"puppet:detailed": {"metadata": {"cims_count": 0, "event_count": 0, "extractions_count": 0, "data_input_name": null}}, "puppet:summary": {"metadata": {"cims_count": 0, "event_count": 0, "extractions_count": 0, "data_input_name": null}}, "puppet:bolt": {"metadata": {"cims_count": 0, "event_count": 0, "extractions_count": 0, "data_input_name": null}}}, "basic_builder": {"version": "1.5.1", "appname": "TA-puppet-report-viewer", "description": "", "theme": "#000000", "author": "Puppet, Inc.", "small_icon": "iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAAEyklEQVRYR+2YTWxUVRiGn3Pu/Hb+agKREmMqi2KaSE1IKBAJCwmkBBdoV5p0gYk/daGpLZTEGjGGOpZaSbpQNo1FEExIoCYVg6ZQQE1kwYrGYiIqIVhr0U5/Zu69M8ecMx0Z6kynNLRhwdnM3Dtz5zz3/d7ve2dGVFdXq3Q6zf2wLMtCrF69WjmOcz/w4PV6HwDNWYk5FFIoxMzFuUdljnNHi1HjIkAKS1o8ttwGF5QhyOL9PS35MyEQUi4GT2EPaR0ejXkZ6E6hJkAKF5BgQe8ZScunHsJB3ZX3XquiJauISM53uIz+Jbg4HGLVcpsnHklyeABajnsIBzT2EgKtjArOxx0Gfw6x+fUEbzwj6XpV0Xvaw+5jEArcexjtgaIKrYgKLsYdro1YHPlGsq5KsuXJCT4+7WffCZdQwLd0HtI7VcTgwocOKuEi/C7K9aJsxbXxENvfcUkhkTNm/z/ZwtUrqlDQL3lpSznplINAkEwrttTYrK38h1+nQ2xvcRlxFZ7MjJOUIhD0IqWe+NaC1SsKpJTCTkFGZttdCYFKpTn5bhnrVo7z+1SUb7/L4PNmM1AEPXSfTDIy6UcJDbUwlUoMxtkfK0gmXPr2+Vm7IqHnwYwSEqIW2/d6+WlEs2QH6ELWXWaZIuVavPyUTdvzaUjlWl9AxENdm8Xw0gJlsB0vjU+n2VufglQmOzB1eaIWdW95lhZIp9tUUtG0FXY/50BKswhQCqJe6tokwyNicUp22wUzgaoESQdqVyk+a4YyZYPPYzLOrKiPHW8qhv647aHx8XHzks/nw7Ztli1bhv7edevWLcrLywtarKCHzBYqw/RU7m4lTsZl8+MWh1sFQTVNZ3+II2dSeP3S9JMWamzKIq2rCAbg3LlzZvIODAxQVVXF+vXrzfmzZ8/S1NTE5OQkclZIFwWqCFsc2xckPaWDVYErqXhoEp90+eh0hPZjDuFYGjEDkO39262uNx4aGiIcDhdU4ubNm2zcuBGRd82c0VERFVz4wMFN6FmUNp3sERlO/BjixU9slsc8uWIV3DAfaGxsjMbGRq5cuUJzczMNDQ3mms7OTg4cOEBZWdl/n1E87TVQ3OHiLxY79ghe2wHvNaTo+SpE6xduybTPB9KbdnR0EIlEGB0d5fLly1RWVnL16lU2bNhALBabJ9D7Dj/8Jnm2LckrW728/YKk92vB7uOiZNrnAx08eJB4PE4wGDSGPnToEPX19SQSCaqrq43pc6uoQisjksG4bb6gCZ9AZXSEuBwe9LDnc4uyoDFN0WE8W6Guri4CgYAB6u/vp7a2Fu2jmpoao9ycQLrLHo5IevdaONrU2bZDeKDvew+dX6aJ+LWb5wd06dIldu7cycTEBHV1dRw9etTs39fXx65du+ZTMkUmI0hM2Xd0geYKWBJf0CoZV/kK6aDWyly/fp01a9agj3V3bdq0iRs3btyh8l1m2fzjMh9It782sS6ZBtEDs7W1lVOnTplz+WtJgNrb2+np6WHbtm2mbHowauDZMHPOoflrUfidhbrM3L0Q6N/vxdaiKjQ8PGxavbu7m/3795vnpdaiAel/U1paWkxZBgcHTZ7pzUqtRQPSG+vwzPkif/jNBbWoQKXUKPT6A6BSqhmF7re/9P4FOOuQpa0DAR0AAAAASUVORK5CYII=", "friendly_name": "Puppet Report Viewer", "visible": true, "tab_build_no": "12", "tab_version": "2.2.0", "build_no": 3, "large_icon": "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"}, "alert_action_builder": {"modular_alerts": [{"parameters": [{"default_value": "", "value": "4e5d808f-60fb-4edc-ac1f-f4d3ae4b1e68", "format_type": "text", "required": false, "help_string": "Used for testing, don't use in deployments.", "name": "transaction_uuid", "label": "Transaction UUID", "type": ""}], "smallIcon": "iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAACC0lEQVRYR+2YTWsTURiFz0lnmiYoYrRpK0oX/RWiSJduRE1DJaIrd4L/pTtXioJFCaYVBEEouNEfUAqlGzeKtYmlXZQaDc49kpREG3JzJ01ipphZDu9973PP+3E/CMunQuo86GcgxGw2jf+VIM/c9qbTLoQBrUDLk7MwXAE54vQjXObc5genXQiDYwwklQAEtUUSPsCzjQUPRCG/PM1ru5+qECqkL4He+yHQoaSOnELSI8SwVwuTdA6IzQ82ZO1K1gS3mS0+D1HVTpPelD20B5kM54orzhkdBj0CqoYRZfDXRWZKq91A2YHeII5KKg2Mtfb/o5LAqL8A4CrAAz/SdyjIMFt6e1QoK1AYh1o6eQY6UQBxpQFVDR90DzL2vS3QR85/22o1R1dAdYd6OfUOMc6GWcRBpzf3eXPrYf+A8pPj8Pj0UPja0fUbqJY+y+kZGG8NRMKp1D8BepW6ABPfAJgcArVSQEOFHImhF+kZ+BFJai2eOo2x5GMQ1/80yDYr6HeVRaYx1pRJJBeb9rN9UA9gaN86vJ/rvLHzuaNOrTxGgfGUVfgRLw5goSlMZZjgFrPF185eZDE4RsePji6K2odMrhtl6oL1RiGju8x+fXbUMP09LjxQ5A75kbsGDYGaMlLNVSZ8AVR/bIgDnGgMGchjQ7sS+j+BClPTIO5ACvGkV3nCXOu9qdPe9BvCCFQ0gPAA5gAAAABJRU5ErkJggg==", "code": "# encoding = utf-8\nimport json\nimport requests\nimport collections\nfrom datetime import datetime\nfrom requests.packages.urllib3.exceptions import InsecureRequestWarning\n\nrequests.packages.urllib3.disable_warnings(InsecureRequestWarning)\n\ndef get_resource_events(uuid, server, token):\n \n # setup the headers\n headers = {'X-Authentication': token}\n #setup the url\n url = 'https://{}:8081/pdb/query/v4'.format(server)\n\n report_elements = [\n 'hash', \n 'status', \n 'puppet_version', \n 'report_format', \n 'catalog_uuid', \n 'job_id', \n 'cached_catalog_status', \n 'configuration_version', \n 'environment', \n 'corrective_change', \n 'noop', \n 'noop_pending', \n 'certname', \n 'transaction_uuid', \n 'code_id', \n 'resource_events', \n 'producer_timestamp', \n 'producer', \n 'start_time', \n 'end_time', \n 'receive_time', \n 'logs', \n 'metrics'\n ]\n\n joined_elements = ', '.join(report_elements)\n\n query_string = {}\n query_string['query'] = 'reports[{}] {{ transaction_uuid = \"{}\" }}'.format(joined_elements, uuid)\n \n resource_events = json.loads(requests.post(url, json=query_string, headers=headers, verify=False).text)\n\n return resource_events\n\ndef submit_to_splunk(detailed_report, splunk, hec):\n # setup the headers\n headers = {\"Authorization\" : 'Splunk {} '.format(hec) }\n #setup the url\n url = 'https://{}:8088/services/collector'.format(splunk)\n \n # cleanup start_time\n # start_time = 2019-04-03T12:41:27.481Z\n utc_time = datetime.strptime(detailed_report['start_time'], \"%Y-%m-%dT%H:%M:%S.%fZ\")\n epoch = (utc_time - datetime(1970, 1, 1)).total_seconds()\n\n report = {\n 'host': detailed_report['certname'],\n 'time': epoch,\n 'sourcetype': 'puppet:detailed',\n 'event': detailed_report\n }\n\n requests.post(url, json=report, headers=headers, verify=False)\n\ndef is_json(myjson):\n try:\n json_object = json.loads(myjson)\n except ValueError as e:\n return False\n return True\n\ndef process_event(helper, *args, **kwargs):\n \"\"\"\n # IMPORTANT\n # Do not remove the anchor macro:start and macro:end lines.\n # These lines are used to generate sample code. If they are\n # removed, the sample code will not be updated when configurations\n # are updated.\n\n [sample_code_macro:start]\n\n # The following example gets the setup parameters and prints them to the log\n puppet_db_server = helper.get_global_setting(\"puppet_db_server\")\n helper.log_info(\"puppet_db_server={}\".format(puppet_db_server))\n auth_token = helper.get_global_setting(\"auth_token\")\n helper.log_info(\"auth_token={}\".format(auth_token))\n splunk_server = helper.get_global_setting(\"splunk_server\")\n helper.log_info(\"splunk_server={}\".format(splunk_server))\n splunk_hec_token = helper.get_global_setting(\"splunk_hec_token\")\n helper.log_info(\"splunk_hec_token={}\".format(splunk_hec_token))\n pe_console = helper.get_global_setting(\"pe_console\")\n helper.log_info(\"pe_console={}\".format(pe_console))\n\n # The following example gets the alert action parameters and prints them to the log\n transaction_uuid = helper.get_param(\"transaction_uuid\")\n helper.log_info(\"transaction_uuid={}\".format(transaction_uuid))\n\n\n # The following example adds two sample events (\"hello\", \"world\")\n # and writes them to Splunk\n # NOTE: Call helper.writeevents() only once after all events\n # have been added\n helper.addevent(\"hello\", sourcetype=\"sample_sourcetype\")\n helper.addevent(\"world\", sourcetype=\"sample_sourcetype\")\n helper.writeevents(index=\"summary\", host=\"localhost\", source=\"localhost\")\n\n # The following example gets the events that trigger the alert\n events = helper.get_events()\n for event in events:\n helper.log_info(\"event={}\".format(event))\n\n # helper.settings is a dict that includes environment configuration\n # Example usage: helper.settings[\"server_uri\"]\n helper.log_info(\"server_uri={}\".format(helper.settings[\"server_uri\"]))\n [sample_code_macro:end]\n \"\"\"\n\n #helper.log_info(\"Alert action generate_detailed_report started.\")\n \n events = helper.get_events()\n for event in events:\n event_dict = event\n\n #helper.log_info(event_dict)\n\n # attempt to parse the event store to see if it's json\n if is_json(event_dict[\"_raw\"]):\n event_content = json.loads(event_dict[\"_raw\"])\n event_uuid = event_content['transaction_uuid']\n event_pe_console = event_content['pe_console']\n else:\n event_uuid = None\n event_pe_console = \"\"\n\n uuid = helper.get_param(\"transaction_uuid\") or event_uuid\n\n pe_console = helper.get_param(\"pe_console\") or event_pe_console\n\n #helper.log_info('uuid={}'.format(uuid))\n\n puppet_db_server = helper.get_global_setting(\"puppet_db_server\")\n auth_token = helper.get_global_setting(\"auth_token\")\n splunk_server = helper.get_global_setting(\"splunk_server\")\n hec_token = helper.get_global_setting(\"splunk_hec_token\")\n\n resource_response = get_resource_events(uuid, puppet_db_server, auth_token)\n\n detailed_report = resource_response[0]\n\n mdict = collections.defaultdict(dict)\n\n for m in detailed_report['metrics']['data']:\n mdict[m['category']][m['name']] = m['value']\n \n detailed_report['metrics'] = dict(mdict)\n\n detailed_report['url'] = 'https://{}/#/inspect/report/{}/events'.format(pe_console, detailed_report[\"hash\"])\n\n detailed_report[\"pe_console\"] = pe_console\n\n submit_to_splunk(detailed_report, splunk_server, hec_token)\n\n helper.writeevents(host=\"localhost\", source=\"localhost\")\n\n return 0", "description": "Generates a detailed report from a puppet:summary event", "short_name": "generate_detailed_report", "largeIcon": "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", "label": "Generate detailed report", "uuid": "1f0457025dbb43979505cabeb469594a"}]}}
\ No newline at end of file
diff --git a/app.manifest b/app.manifest
index db7f199..a74113c 100644
--- a/app.manifest
+++ b/app.manifest
@@ -5,7 +5,7 @@
"id": {
"group": null,
"name": "TA-puppet-report-viewer",
- "version": "1.4.0"
+ "version": "1.5.1"
},
"author": [
{
diff --git a/default/app.conf b/default/app.conf
index 738e798..9f2d8df 100644
--- a/default/app.conf
+++ b/default/app.conf
@@ -7,7 +7,7 @@ build = 3
[launcher]
author = Puppet, Inc.
-version = 1.4.0
+version = 1.5.1
[ui]
is_visible = 1
diff --git a/default/data/ui/views/all_reports.xml b/default/data/ui/views/all_reports.xml
index ba69848..c8d4124 100644
--- a/default/data/ui/views/all_reports.xml
+++ b/default/data/ui/views/all_reports.xml
@@ -13,7 +13,7 @@
os.familyos.family
- sourcetype="puppet:facts"
+ `puppet_facts_index` sourcetype="puppet:facts"
| top os.family limit=100$reportTimeRange.earliest$$reportTimeRange.latest$
@@ -24,7 +24,7 @@
environmentenvironment
- sourcetype="puppet:facts"
+ `puppet_facts_index` sourcetype="puppet:facts"
| top environment limit=100$reportTimeRange.earliest$$reportTimeRange.latest$
@@ -35,7 +35,7 @@
networking.domainnetworking.domain
- sourcetype="puppet:facts"
+ `puppet_facts_index` sourcetype="puppet:facts"
| top networking.domain limit=100$reportTimeRange.earliest$$reportTimeRange.latest$
@@ -46,7 +46,7 @@