├── .github └── workflows │ ├── js-examples-test.yml │ └── python-test.yml ├── .gitignore ├── LICENSE.txt ├── Makefile ├── README.md ├── THIRD_PARTY_CREDITS.MD ├── custom_alert_actions ├── README.md └── slack_alerts │ ├── README.md │ ├── appserver │ ├── static │ │ ├── appIcon.png │ │ ├── pages │ │ │ ├── common.js │ │ │ └── slack_alerts_setup.js │ │ └── slack.png │ └── templates │ │ └── setup.html │ ├── bin │ ├── safe_fmt.py │ ├── safe_fmt_tests.py │ ├── six.py │ ├── slack.py │ └── slack_tests.py │ ├── default │ ├── alert_actions.conf │ ├── app.conf │ ├── data │ │ └── ui │ │ │ ├── alerts │ │ │ └── slack.html │ │ │ ├── nav │ │ │ └── default.xml │ │ │ └── views │ │ │ └── slack_alerts_setup.xml │ └── restmap.conf │ ├── metadata │ └── default.meta │ └── static │ ├── appIcon.png │ └── appIcon_2x.png ├── custom_endpoints ├── README.md └── hello-world │ ├── README.md │ ├── bin │ ├── README │ ├── hello_templates.py │ └── hello_world.py │ ├── default │ ├── app.conf │ ├── data │ │ └── ui │ │ │ ├── nav │ │ │ └── default.xml │ │ │ └── views │ │ │ └── README │ ├── restmap.conf │ └── web.conf │ ├── local │ └── app.conf │ └── metadata │ ├── default.meta │ └── local.meta ├── custom_search_commands ├── README.md └── python │ ├── README.md │ ├── customsearchcommands_app │ ├── README.md │ ├── bin │ │ ├── _pydebug_conf.py │ │ ├── app.py │ │ ├── countmatches.py │ │ ├── filter.py │ │ ├── generatehello.py │ │ ├── generatetext.py │ │ ├── simulate.py │ │ └── sum.py │ ├── default │ │ ├── app.conf │ │ ├── commands.conf │ │ ├── data │ │ │ ├── population.csv │ │ │ └── ui │ │ │ │ └── nav │ │ │ │ └── default.xml │ │ ├── distsearch.conf │ │ ├── logging.conf │ │ ├── searchbnf.conf │ │ └── transforms.conf │ ├── lookups │ │ └── tweets.csv.gz │ └── metadata │ │ └── default.meta │ ├── customsearchcommands_template │ ├── bin │ │ ├── filter.py │ │ ├── generate.py │ │ ├── report.py │ │ └── stream.py │ ├── default │ │ ├── app.conf │ │ ├── commands-scpv1.conf │ │ ├── commands-scpv2.conf │ │ ├── commands.conf │ │ ├── data │ │ │ └── ui │ │ │ │ └── nav │ │ │ │ └── default.xml │ │ ├── distsearch.conf │ │ └── logging.conf │ └── metadata │ │ └── default.meta │ ├── eventingsearchcommands_app │ ├── README.md │ ├── bin │ │ └── eventingcsc.py │ ├── default │ │ ├── app.conf │ │ └── commands.conf │ └── metadata │ │ └── default.meta │ ├── generatingsearchcommands_app │ ├── README.md │ ├── bin │ │ └── generatingcsc.py │ ├── default │ │ ├── app.conf │ │ └── commands.conf │ └── metadata │ │ └── default.meta │ ├── reportingsearchcommands_app │ ├── README.md │ ├── bin │ │ └── reportingcsc.py │ ├── default │ │ ├── app.conf │ │ └── commands.conf │ └── metadata │ │ └── default.meta │ └── streamingsearchcommands_app │ ├── README.md │ ├── bin │ └── streamingcsc.py │ ├── default │ ├── app.conf │ └── commands.conf │ └── metadata │ └── default.meta ├── docker-compose.yml ├── javascript ├── README.md ├── browser │ ├── create-splunk-react-app │ │ ├── .gitignore │ │ ├── README.md │ │ ├── create-splunk-react-app.gif │ │ ├── package.json │ │ ├── public │ │ │ ├── favicon.ico │ │ │ ├── index.html │ │ │ ├── logo192.png │ │ │ ├── logo512.png │ │ │ ├── manifest.json │ │ │ └── robots.txt │ │ └── src │ │ │ ├── App.css │ │ │ ├── App.js │ │ │ ├── App.test.js │ │ │ ├── Inputs.css │ │ │ ├── Inputs.js │ │ │ ├── SplunkJsExample.css │ │ │ ├── SplunkJsExample.js │ │ │ ├── index.css │ │ │ ├── index.js │ │ │ ├── serviceWorker.js │ │ │ ├── setupProxy.js │ │ │ ├── setupTests.js │ │ │ └── splunkConfig.js │ ├── helloworld │ │ └── index.html │ ├── index.html │ ├── minisplunk │ │ ├── backbone.js │ │ ├── bootstrap-1.1.1.css │ │ ├── bootstrap.modal.js │ │ ├── date.format.js │ │ ├── index.html │ │ ├── jquery.fn.gmap.js │ │ ├── less.js │ │ ├── models.js │ │ ├── site.js │ │ ├── underscore.js │ │ └── views.js │ ├── resources │ │ ├── bootstrap.css │ │ ├── bootstrap.dropdown.js │ │ ├── bootstrap.tabs.js │ │ ├── images │ │ │ ├── 3viz.png │ │ │ ├── minisplunk.png │ │ │ ├── simple.png │ │ │ ├── splunk.png │ │ │ └── ui.png │ │ ├── jquery.min.js │ │ ├── jquery.placeholder.min.js │ │ ├── json2.js │ │ ├── prettify.css │ │ ├── prettify.js │ │ ├── rickshaw │ │ │ ├── d3.layout.min.js │ │ │ ├── d3.min.js │ │ │ ├── detail.css │ │ │ ├── extensions.css │ │ │ ├── graph.css │ │ │ ├── legend.css │ │ │ ├── rickshaw.min.css │ │ │ └── rickshaw.min.js │ │ └── timeline.css │ ├── ui │ │ └── index.html │ └── viz │ │ └── index.html ├── node │ ├── README.md │ ├── cmdline.js │ ├── helloworld │ │ ├── README.md │ │ ├── apps.js │ │ ├── endpoint_instantiation.js │ │ ├── firedalerts.js │ │ ├── firedalerts_create.js │ │ ├── firedalerts_delete.js │ │ ├── get_job.js │ │ ├── log.js │ │ ├── pivot.js │ │ ├── savedsearches.js │ │ ├── savedsearches_create.js │ │ ├── savedsearches_delete.js │ │ ├── search_blocking.js │ │ ├── search_normal.js │ │ ├── search_oneshot.js │ │ └── search_realtime.js │ ├── jobs.js │ ├── login.js │ ├── results.js │ └── search.js ├── package.json ├── test_browser_examples.js └── test_examples.js ├── modularinputs ├── README.md └── python │ ├── github_commits │ ├── README.md │ ├── README │ │ └── inputs.conf.spec │ ├── bin │ │ └── github_commits.py │ └── default │ │ ├── app.conf │ │ └── inputs.conf │ ├── github_forks │ ├── README.md │ ├── README │ │ └── inputs.conf.spec │ ├── bin │ │ └── github_forks.py │ └── default │ │ ├── app.conf │ │ └── inputs.conf │ └── random_numbers │ ├── README.md │ ├── README │ └── inputs.conf.spec │ ├── bin │ └── random_numbers.py │ └── default │ ├── app.conf │ └── inputs.conf ├── python ├── .env ├── README.md ├── analytics │ ├── README.md │ ├── __init__.py │ ├── bottle.py │ ├── css │ │ ├── analytics.css │ │ ├── jquery.ui.selectmenu.css │ │ └── showLoading.css │ ├── images │ │ └── loading.gif │ ├── input.py │ ├── js │ │ ├── date.format.js │ │ ├── jquery.flot.js │ │ ├── jquery.flot.selection.js │ │ ├── jquery.showLoading.js │ │ └── jquery.ui.selectmenu.js │ ├── output.py │ ├── server.py │ └── templates │ │ ├── application.tpl │ │ ├── applications.tpl │ │ └── make_table.tpl ├── apicalls_binding.py ├── apicalls_client.py ├── apicalls_httplib.py ├── binding1.py ├── conf.py ├── dashboard │ ├── README.md │ └── feed.py ├── event_types.py ├── explorer │ ├── README.md │ ├── endpoints.js │ ├── explorer.css │ ├── explorer.html │ ├── explorer.py │ ├── prettify │ │ ├── lang-apollo.js │ │ ├── lang-clj.js │ │ ├── lang-css.js │ │ ├── lang-go.js │ │ ├── lang-hs.js │ │ ├── lang-lisp.js │ │ ├── lang-lua.js │ │ ├── lang-ml.js │ │ ├── lang-n.js │ │ ├── lang-proto.js │ │ ├── lang-scala.js │ │ ├── lang-sql.js │ │ ├── lang-tex.js │ │ ├── lang-vb.js │ │ ├── lang-vhdl.js │ │ ├── lang-wiki.js │ │ ├── lang-xq.js │ │ ├── lang-yaml.js │ │ ├── prettify.css │ │ └── prettify.js │ └── server.py ├── export.py ├── fired_alerts.py ├── follow.py ├── genevents.py ├── get_job.py ├── handlers │ ├── README.md │ ├── cacert.bad.pem │ ├── cacert.pem │ ├── handler_certs.py │ ├── handler_debug.py │ ├── handler_proxy.py │ ├── handler_urllib2.py │ └── tiny-proxy.py ├── index.py ├── info.py ├── inputs.py ├── job.py ├── kvstore.py ├── loggers.py ├── oneshot.py ├── results.py ├── saved_search.py ├── saved_searches.py ├── search.py ├── search_modes.py ├── spcmd.py ├── spurl.py ├── stail.py ├── submit.py ├── tests │ ├── test_examples.py │ └── testlib.py ├── tox.ini ├── twitted │ ├── README.md │ ├── input.py │ └── twitted │ │ ├── README.md │ │ ├── bin │ │ ├── hashtags.py │ │ └── tophashtags.py │ │ ├── default │ │ ├── app.conf │ │ └── commands.conf │ │ └── metadata │ │ └── default.meta ├── upload.py └── utils.py ├── requirements.txt ├── setup_pages ├── README.md ├── SUIT-setup-page-example │ ├── .editorconfig │ ├── .gitignore │ ├── .prettierrc │ ├── LICENSE.md │ ├── NOTICE.csv │ ├── README.md │ ├── babel.config.js │ ├── lerna.json │ ├── package.json │ ├── packages │ │ ├── setup-component │ │ │ ├── .babelrc.js │ │ │ ├── .eslintrc.js │ │ │ ├── .gitignore │ │ │ ├── .npmignore │ │ │ ├── CHANGELOG.md │ │ │ ├── README.md │ │ │ ├── demo │ │ │ │ ├── demo.jsx │ │ │ │ ├── splunk-app │ │ │ │ │ ├── appserver │ │ │ │ │ │ └── templates │ │ │ │ │ │ │ └── demo.html │ │ │ │ │ └── default │ │ │ │ │ │ ├── app.conf │ │ │ │ │ │ └── data │ │ │ │ │ │ └── ui │ │ │ │ │ │ ├── nav │ │ │ │ │ │ └── default.xml │ │ │ │ │ │ └── views │ │ │ │ │ │ └── demo.xml │ │ │ │ ├── standalone │ │ │ │ │ └── index.html │ │ │ │ ├── webpack.splunkapp.config.js │ │ │ │ └── webpack.standalone.config.js │ │ │ ├── jest.config.js │ │ │ ├── package.json │ │ │ ├── src │ │ │ │ ├── DependencyCheck.jsx │ │ │ │ ├── SetupComponent.jsx │ │ │ │ ├── SetupComponentStyles.js │ │ │ │ └── tests │ │ │ │ │ └── SetupComponent.unit.jsx │ │ │ ├── stylelint.config.js │ │ │ └── webpack.config.js │ │ └── setup-example-app │ │ │ ├── .babelrc.js │ │ │ ├── .eslintrc.js │ │ │ ├── .gitignore │ │ │ ├── .npmignore │ │ │ ├── CHANGELOG.md │ │ │ ├── README.md │ │ │ ├── package.json │ │ │ ├── src │ │ │ └── main │ │ │ │ ├── resources │ │ │ │ └── splunk │ │ │ │ │ ├── appserver │ │ │ │ │ └── templates │ │ │ │ │ │ └── start.html │ │ │ │ │ └── default │ │ │ │ │ ├── app.conf │ │ │ │ │ └── data │ │ │ │ │ └── ui │ │ │ │ │ ├── nav │ │ │ │ │ └── default.xml │ │ │ │ │ └── views │ │ │ │ │ └── start.xml │ │ │ │ └── webapp │ │ │ │ └── pages │ │ │ │ └── start │ │ │ │ ├── StartStyles.js │ │ │ │ └── index.jsx │ │ │ ├── stylelint.config.js │ │ │ └── webpack.config.js │ └── yarn.lock ├── dependency_checking_app_example │ ├── README.md │ ├── appserver │ │ └── static │ │ │ ├── javascript │ │ │ ├── setup_page.js │ │ │ ├── vendor │ │ │ │ ├── react-dom.production.min.js │ │ │ │ └── react.production.min.js │ │ │ └── views │ │ │ │ ├── app.js │ │ │ │ ├── setup_configuration.js │ │ │ │ ├── setup_page.js │ │ │ │ ├── splunk_helpers.js │ │ │ │ ├── storage_passwords.js │ │ │ │ └── util.js │ │ │ └── styles │ │ │ └── setup_page.css │ ├── bin │ │ └── weather.py │ ├── default │ │ ├── app.conf │ │ ├── commands.conf │ │ └── data │ │ │ └── ui │ │ │ ├── nav │ │ │ └── default.xml │ │ │ └── views │ │ │ └── setup_page_dashboard.xml │ ├── metadata │ │ └── default.meta │ └── static │ │ ├── appIcon.png │ │ └── appIcon_2x.png ├── developer_guidance_setup_page │ ├── README.md │ ├── appserver │ │ └── static │ │ │ ├── javascript │ │ │ ├── setup_page.js │ │ │ └── views │ │ │ │ ├── setup_configuration.js │ │ │ │ ├── setup_page_example.js │ │ │ │ ├── setup_page_example_template.js │ │ │ │ └── splunk_helpers.js │ │ │ └── styles │ │ │ └── setup_page.css │ ├── default │ │ ├── app.conf │ │ └── data │ │ │ └── ui │ │ │ ├── nav │ │ │ └── default.xml │ │ │ └── views │ │ │ └── setup_page_dashboard.xml │ ├── metadata │ │ └── default.meta │ └── static │ │ ├── appIcon.png │ │ └── appIcon_2x.png ├── react_setup_page_example │ ├── README.md │ ├── appserver │ │ └── static │ │ │ ├── javascript │ │ │ ├── setup_page.js │ │ │ ├── vendor │ │ │ │ ├── react-dom.production.min.js │ │ │ │ └── react.production.min.js │ │ │ └── views │ │ │ │ ├── app.js │ │ │ │ ├── setup_configuration.js │ │ │ │ ├── setup_page.js │ │ │ │ └── splunk_helpers.js │ │ │ └── styles │ │ │ └── setup_page.css │ ├── default │ │ ├── app.conf │ │ └── data │ │ │ └── ui │ │ │ ├── nav │ │ │ └── default.xml │ │ │ └── views │ │ │ └── setup_page_dashboard.xml │ ├── metadata │ │ └── default.meta │ └── static │ │ ├── appIcon.png │ │ └── appIcon_2x.png ├── setup_page_simple │ ├── README.md │ ├── appserver │ │ └── static │ │ │ ├── javascript │ │ │ └── setup_page.js │ │ │ └── styles │ │ │ └── setup_page.css │ ├── default │ │ ├── app.conf │ │ └── data │ │ │ └── ui │ │ │ └── views │ │ │ └── setup_page_dashboard.xml │ └── static │ │ ├── appIcon.png │ │ └── appIcon_2x.png └── weather_app_example │ ├── README.md │ ├── appserver │ └── static │ │ ├── javascript │ │ ├── setup_page.js │ │ ├── vendor │ │ │ ├── react-dom.production.min.js │ │ │ └── react.production.min.js │ │ └── views │ │ │ ├── app.js │ │ │ ├── setup_configuration.js │ │ │ ├── setup_page.js │ │ │ ├── splunk_helpers.js │ │ │ ├── storage_passwords.js │ │ │ └── util.js │ │ └── styles │ │ └── setup_page.css │ ├── bin │ └── weather.py │ ├── default │ ├── app.conf │ ├── commands.conf │ └── data │ │ └── ui │ │ ├── nav │ │ └── default.xml │ │ └── views │ │ └── setup_page_dashboard.xml │ ├── metadata │ └── default.meta │ └── static │ ├── appIcon.png │ └── appIcon_2x.png ├── spl2-sample-apps ├── sample_spl2_buttercup │ ├── README.md │ ├── default │ │ ├── app.conf │ │ ├── data │ │ │ ├── spl2 │ │ │ │ ├── _default.spl2 │ │ │ │ ├── functions.spl2 │ │ │ │ ├── sample_data.spl2 │ │ │ │ ├── setup.spl2 │ │ │ │ └── testing.spl2 │ │ │ └── ui │ │ │ │ ├── nav │ │ │ │ └── default.xml │ │ │ │ └── views │ │ │ │ └── buttercup_games.xml │ │ └── transforms.conf │ ├── lookups │ │ ├── sample_products.csv │ │ └── sample_suppliers.csv │ └── metadata │ │ └── default.meta └── sample_spl2_pii_masking │ ├── README.md │ ├── default │ ├── app.conf │ └── data │ │ ├── spl2 │ │ ├── _default.spl2 │ │ ├── functions.spl2 │ │ ├── masking.spl2 │ │ └── sample_data.spl2 │ │ └── ui │ │ └── nav │ │ └── default.xml │ └── metadata │ └── default.meta └── tutorials ├── Module-01_GetStarted └── devtutorial │ ├── bin │ └── README │ ├── default │ ├── app.conf │ ├── data │ │ └── ui │ │ │ ├── nav │ │ │ └── default.xml │ │ │ └── views │ │ │ └── welcome.xml │ └── savedsearches.conf │ └── metadata │ └── default.meta ├── Module-02_SetupPage ├── appserver.zip └── devtutorial │ ├── appserver │ └── static │ │ ├── javascript │ │ ├── setup_page.js │ │ └── views │ │ │ ├── app.js │ │ │ ├── setup_configuration.js │ │ │ ├── splunk_helpers.js │ │ │ ├── store_secret.js │ │ │ └── util.js │ │ └── styles │ │ └── setup_page.css │ ├── bin │ └── README │ ├── default │ ├── app.conf │ ├── data │ │ └── ui │ │ │ ├── nav │ │ │ └── default.xml │ │ │ └── views │ │ │ ├── setup_page_dashboard.xml │ │ │ └── welcome.xml │ └── savedsearches.conf │ └── metadata │ └── default.meta ├── Module-03_ExternalLookup └── devtutorial │ ├── README │ ├── bin │ ├── README │ └── dns_external_lookup.py │ ├── default │ ├── app.conf │ ├── data │ │ └── ui │ │ │ ├── nav │ │ │ └── default.xml │ │ │ └── views │ │ │ ├── README │ │ │ └── welcome.xml │ ├── savedsearches.conf │ └── transforms.conf │ ├── metadata │ └── default.meta │ └── static │ ├── appIcon.png │ ├── appIconAlt.png │ ├── appIconAlt_2x.png │ └── appIcon_2x.png └── Module-04_Validate └── devtutorial ├── README ├── default ├── app.conf ├── data │ └── ui │ │ ├── nav │ │ └── default.xml │ │ └── views │ │ ├── README │ │ └── welcome.xml └── savedsearches.conf ├── metadata └── default.meta └── static ├── appIcon.png ├── appIconAlt.png ├── appIconAlt_2x.png └── appIcon_2x.png /.github/workflows/js-examples-test.yml: -------------------------------------------------------------------------------- 1 | name: JS Examples CI 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | paths: 7 | - "javascript/**" 8 | 9 | jobs: 10 | build: 11 | runs-on: ${{ matrix.os }} 12 | strategy: 13 | matrix: 14 | os: 15 | - ubuntu-latest 16 | node: 17 | - 14 18 | - 8.17.0 19 | - 22 20 | splunk-version: 21 | - "8.0" 22 | - "latest" 23 | 24 | services: 25 | splunk: 26 | image: splunk/splunk:${{matrix.splunk-version}} 27 | env: 28 | SPLUNK_START_ARGS: --accept-license 29 | SPLUNK_HEC_TOKEN: 11111111-1111-1111-1111-1111111111113 30 | SPLUNK_PASSWORD: changed! 31 | SPLUNK_APPS_URL: https://github.com/splunk/sdk-app-collection/releases/download/v1.1.0/sdkappcollection.tgz 32 | ports: 33 | - 8000:8000 34 | - 8088:8088 35 | - 8089:8089 36 | 37 | steps: 38 | - uses: actions/checkout@v2 39 | - uses: actions/setup-node@v2 40 | with: 41 | node-version: ${{ matrix.node }} 42 | 43 | - name: Create .splunkrc file 44 | run: | 45 | cd ~ 46 | echo host=localhost > .splunkrc 47 | echo port=8089 >> .splunkrc 48 | echo username=admin >> .splunkrc 49 | echo password=changed! >> .splunkrc 50 | echo scheme=https >> .splunkrc 51 | echo version=${{ matrix.splunk }} >> .splunkrc 52 | - name: Run npm install 53 | working-directory: ./javascript 54 | run: npm install 55 | - name: Test Execution 56 | working-directory: ./javascript 57 | run: ./node_modules/mocha/bin/mocha test_examples.js 58 | shell: sh 59 | -------------------------------------------------------------------------------- /.github/workflows/python-test.yml: -------------------------------------------------------------------------------- 1 | name: Python CI 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | paths: 7 | - 'python/**' 8 | 9 | jobs: 10 | build: 11 | runs-on: ${{ matrix.os }} 12 | strategy: 13 | matrix: 14 | os: 15 | - ubuntu-latest 16 | python: [3.9, 3.13 ] 17 | splunk-version: 18 | - "8.0" 19 | - "latest" 20 | fail-fast: false 21 | 22 | services: 23 | splunk: 24 | image: splunk/splunk:${{matrix.splunk-version}} 25 | env: 26 | SPLUNK_START_ARGS: --accept-license 27 | SPLUNK_HEC_TOKEN: 11111111-1111-1111-1111-1111111111113 28 | SPLUNK_PASSWORD: changed! 29 | SPLUNK_APPS_URL: https://github.com/splunk/sdk-app-collection/releases/download/v1.1.0/sdkappcollection.tgz 30 | ports: 31 | - 8000:8000 32 | - 8088:8088 33 | - 8089:8089 34 | 35 | steps: 36 | - uses: actions/checkout@v2 37 | - name: Setup Python 38 | uses: actions/setup-python@v2 39 | with: 40 | python-version: ${{ matrix.python }} 41 | - name: Install tox 42 | working-directory: ./python 43 | run: pip install tox 44 | - name: Install splunk-sdk 45 | working-directory: ./python 46 | run: pip install splunk-sdk 47 | - name: Test Execution 48 | working-directory: ./python 49 | run: tox -e py 50 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # text reset 2 | NO_COLOR=\033[0m 3 | # green 4 | OK_COLOR=\033[32;01m 5 | # red 6 | ERROR_COLOR=\033[31;01m 7 | # cyan 8 | WARN_COLOR=\033[36;01m 9 | # yellow 10 | ATTN_COLOR=\033[33;01m 11 | 12 | ROOT_DIR := $(shell git rev-parse --show-toplevel) 13 | 14 | VERSION := `git describe --tags --dirty 2>/dev/null` 15 | COMMITHASH := `git rev-parse --short HEAD 2>/dev/null` 16 | DATE := `date "+%FT%T%z"` 17 | 18 | CONTAINER_NAME := 'splunk-app-examples' 19 | 20 | .PHONY: all 21 | all: restart 22 | 23 | init: 24 | @echo "$(ATTN_COLOR)==> init $(NO_COLOR)" 25 | 26 | .PHONY: up 27 | up: 28 | @echo "$(ATTN_COLOR)==> up $(NO_COLOR)" 29 | @pip install -r requirements.txt -t lib --upgrade 30 | @docker-compose up -d 31 | 32 | .PHONY: remove 33 | remove: 34 | @echo "$(ATTN_COLOR)==> rm $(NO_COLOR)" 35 | @docker-compose rm -f -s 36 | 37 | .PHONY: wait_up 38 | wait_up: 39 | @echo "$(ATTN_COLOR)==> wait_up $(NO_COLOR)" 40 | @for i in `seq 0 180`; do if docker exec -it $(CONTAINER_NAME) /sbin/checkstate.sh &> /dev/null; then break; fi; printf "\rWaiting for Splunk for %s seconds..." $$i; sleep 1; done 41 | 42 | .PHONY: down 43 | down: 44 | @echo "$(ATTN_COLOR)==> down $(NO_COLOR)" 45 | @docker-compose stop 46 | 47 | .PHONY: start 48 | start: up wait_up 49 | 50 | .PHONY: restart 51 | restart: down start 52 | 53 | .PHONY: refresh 54 | refresh: remove start 55 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # splunk-app-examples 2 | 3 | ## Examples Docker Container 4 | 5 | ### Requirements 6 | 7 | - Python 8 | - Docker 9 | 10 | ### Starting up 11 | 12 | ``` 13 | make up 14 | ``` 15 | 16 | ### Run app examples on Splunk Cloud Platform 17 | The Splunk App Example repository contains several examples, such as Custom Search Commands, Modular Inputs, and more. For information about running these examples in a Splunk Cloud Platform environment, see [Deploy and manage private apps in Splunk Cloud Platform](https://dev.splunk.com/enterprise/docs/releaseapps/manageprivatecloud/). 18 | -------------------------------------------------------------------------------- /custom_alert_actions/slack_alerts/appserver/static/appIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/custom_alert_actions/slack_alerts/appserver/static/appIcon.png -------------------------------------------------------------------------------- /custom_alert_actions/slack_alerts/appserver/static/slack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/custom_alert_actions/slack_alerts/appserver/static/slack.png -------------------------------------------------------------------------------- /custom_alert_actions/slack_alerts/appserver/templates/setup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Slack Alerts Setup 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | <% 17 | page_path = "/static/app/slack_alerts/pages/slack_alerts_setup.js" 18 | common_path = "/static/app/slack_alerts/pages/common.js" 19 | %> 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /custom_alert_actions/slack_alerts/bin/safe_fmt.py: -------------------------------------------------------------------------------- 1 | from string import Formatter 2 | from collections import Mapping 3 | import json 4 | 5 | try: 6 | from _string import formatter_field_name_split 7 | except ImportError: 8 | formatter_field_name_split = lambda x: x._formatter_field_name_split() 9 | 10 | class MagicFormatMapping(Mapping): 11 | def __init__(self, args, kwargs): 12 | self._args = args 13 | self._kwargs = kwargs 14 | self._last_index = 0 15 | 16 | def __getitem__(self, key): 17 | if key == '': 18 | idx = self._last_index 19 | self._last_index += 1 20 | try: 21 | return self._args[idx] 22 | except LookupError: 23 | pass 24 | key = str(idx) 25 | return self._kwargs[key] 26 | 27 | def __iter__(self): 28 | return iter(self._kwargs) 29 | 30 | def __len__(self): 31 | return len(self._kwargs) 32 | 33 | class SafeFormatter(Formatter): 34 | def get_field(self, field_name, args, kwargs): 35 | try: 36 | first, rest = formatter_field_name_split(field_name) 37 | obj = self.get_value(first, args, kwargs) 38 | for _, i in rest: 39 | if isinstance(i, int): 40 | obj = obj[str(i)] 41 | else: 42 | obj = obj[i] 43 | return obj, first 44 | except: 45 | return '{%s}' % field_name, first 46 | 47 | def format_field(self, value, spec): 48 | if isinstance(value, dict) or isinstance(value, list): 49 | return json.dumps(value) 50 | return Formatter.format_field(self, value, spec) 51 | 52 | def safe_format(_string, kwargs=dict()): 53 | return SafeFormatter().vformat(_string, [], MagicFormatMapping([], kwargs)) 54 | -------------------------------------------------------------------------------- /custom_alert_actions/slack_alerts/default/alert_actions.conf: -------------------------------------------------------------------------------- 1 | [slack] 2 | is_custom = 1 3 | label = Slack 4 | description = Send a message to a Slack channel 5 | icon_path = slack.png 6 | python.version = python3 7 | payload_format = json 8 | param.slack_app_oauth_token = 9 | param.webhook_url = 10 | param.from_user = Splunk 11 | param.from_user_icon = https://s3-us-west-1.amazonaws.com/ziegfried-apps/slack-alerts/splunk-icon.png 12 | param.attachment = none 13 | param.view_link = $view_link$ 14 | param.info_trigger_time = $trigger_time$ 15 | param.info_severity = $alert.severity$ 16 | param.fields = 17 | param.attachment_alert_title = :bell: {search_name} 18 | param.attachment_adhoc_title = :zap: Ad-hoc search 19 | param.attachment_results_link = <{results_link}|Show results in Splunk> :mag: 20 | param.attachment_footer_text = Splunk Alert 21 | param.attachment_fallback = Alert generated by Splunk: {results_link} -------------------------------------------------------------------------------- /custom_alert_actions/slack_alerts/default/app.conf: -------------------------------------------------------------------------------- 1 | [ui] 2 | is_visible = 1 3 | show_in_nav = 0 4 | label = Slack Alerts 5 | setup_view = slack_alerts_setup 6 | 7 | [launcher] 8 | author = Siegfried Puchbauer 9 | description = Custom alert action to send messages to Slack channels 10 | version = 2.3.0 11 | 12 | [package] 13 | id = slack_alerts 14 | 15 | [install] 16 | build = 166822895 -------------------------------------------------------------------------------- /custom_alert_actions/slack_alerts/default/data/ui/nav/default.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /custom_alert_actions/slack_alerts/default/data/ui/views/slack_alerts_setup.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /custom_alert_actions/slack_alerts/default/restmap.conf: -------------------------------------------------------------------------------- 1 | [validation:savedsearch] 2 | action.slack = case('action.slack' != "1", null(), 'action.slack.param.channel' == "action.slack.param.channel" OR 'action.slack.param.channel' == "", "Channel cannot be empty", 1==1, null()) -------------------------------------------------------------------------------- /custom_alert_actions/slack_alerts/metadata/default.meta: -------------------------------------------------------------------------------- 1 | [] 2 | export = system 3 | -------------------------------------------------------------------------------- /custom_alert_actions/slack_alerts/static/appIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/custom_alert_actions/slack_alerts/static/appIcon.png -------------------------------------------------------------------------------- /custom_alert_actions/slack_alerts/static/appIcon_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/custom_alert_actions/slack_alerts/static/appIcon_2x.png -------------------------------------------------------------------------------- /custom_endpoints/hello-world/bin/README: -------------------------------------------------------------------------------- 1 | This is where you put any scripts you want to add to this app. 2 | -------------------------------------------------------------------------------- /custom_endpoints/hello-world/bin/hello_world.py: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Splunk Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from splunk.persistconn.application import PersistentServerConnectionApplication 16 | 17 | 18 | class HelloWorld(PersistentServerConnectionApplication): 19 | def __init__(self, _command_line, _command_arg): 20 | super(PersistentServerConnectionApplication, self).__init__() 21 | 22 | # Handle a syncronous from splunkd. 23 | def handle(self, in_string): 24 | """ 25 | Called for a simple synchronous request. 26 | @param in_string: request data passed in 27 | @rtype: string or dict 28 | @return: String to return in response. If a dict was passed in, 29 | it will automatically be JSON encoded before being returned. 30 | """ 31 | payload = { 32 | "text": "Hello world!" 33 | } 34 | return {'payload': payload, 'status': 200} 35 | 36 | def handleStream(self, handle, in_string): 37 | """ 38 | For future use 39 | """ 40 | raise NotImplementedError( 41 | "PersistentServerConnectionApplication.handleStream") 42 | 43 | def done(self): 44 | """ 45 | Virtual method which can be optionally overridden to receive a 46 | callback after the request completes. 47 | """ 48 | pass 49 | -------------------------------------------------------------------------------- /custom_endpoints/hello-world/default/app.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Splunk app configuration file 3 | # 4 | 5 | [install] 6 | is_configured = 0 7 | 8 | [ui] 9 | is_visible = 1 10 | label = Hello World 11 | 12 | [launcher] 13 | author = 14 | description = 15 | version = 1.0.0 16 | 17 | -------------------------------------------------------------------------------- /custom_endpoints/hello-world/default/data/ui/nav/default.xml: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /custom_endpoints/hello-world/default/data/ui/views/README: -------------------------------------------------------------------------------- 1 | Add all the views that your app needs in this directory 2 | -------------------------------------------------------------------------------- /custom_endpoints/hello-world/default/restmap.conf: -------------------------------------------------------------------------------- 1 | [script:hello-world] 2 | match = /say-hello 3 | script = hello_world.py 4 | scripttype = persist 5 | handler = application.HelloWorld 6 | 7 | [admin:hello-templates] 8 | match = /hello-templates 9 | members = say-hello-templates 10 | 11 | [admin_external:say-hello-templates] 12 | handlertype = python 13 | handlerfile = hello_templates.py 14 | handleractions = list, create 15 | handlerpersistentmode = true 16 | -------------------------------------------------------------------------------- /custom_endpoints/hello-world/default/web.conf: -------------------------------------------------------------------------------- 1 | [expose:hello-world] 2 | pattern = say-hello 3 | methods = GET, POST 4 | 5 | [expose:hello-templates] 6 | pattern = hello-templates 7 | methods = GET, POST 8 | 9 | [expose:hello-templates_elements] 10 | pattern = hello-templates/* 11 | methods = GET, POST 12 | -------------------------------------------------------------------------------- /custom_endpoints/hello-world/local/app.conf: -------------------------------------------------------------------------------- 1 | [ui] 2 | 3 | [launcher] 4 | version = 5 | -------------------------------------------------------------------------------- /custom_endpoints/hello-world/metadata/default.meta: -------------------------------------------------------------------------------- 1 | 2 | # Application-level permissions 3 | 4 | [] 5 | access = read : [ * ], write : [ admin, power ] 6 | 7 | ### EVENT TYPES 8 | 9 | [eventtypes] 10 | export = system 11 | 12 | 13 | ### PROPS 14 | 15 | [props] 16 | export = system 17 | 18 | 19 | ### TRANSFORMS 20 | 21 | [transforms] 22 | export = system 23 | 24 | 25 | ### LOOKUPS 26 | 27 | [lookups] 28 | export = system 29 | 30 | 31 | ### VIEWSTATES: even normal users should be able to create shared viewstates 32 | 33 | [viewstates] 34 | access = read : [ * ], write : [ * ] 35 | export = system 36 | -------------------------------------------------------------------------------- /custom_endpoints/hello-world/metadata/local.meta: -------------------------------------------------------------------------------- 1 | [app/ui] 2 | version = 8.1.0 3 | modtime = 1582334314.821079000 4 | 5 | [app/launcher] 6 | version = 8.1.0 7 | modtime = 1582334314.821897000 8 | -------------------------------------------------------------------------------- /custom_search_commands/python/customsearchcommands_app/bin/_pydebug_conf.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | # 3 | # Copyright © 2011-2015 Splunk, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"): you may 6 | # not use this file except in compliance with the License. You may obtain 7 | # a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | # License for the specific language governing permissions and limitations 15 | # under the License. 16 | 17 | host = 'localhost' 18 | port = 5678 19 | suspend = False 20 | is_enabled = {} 21 | -------------------------------------------------------------------------------- /custom_search_commands/python/customsearchcommands_app/bin/generatehello.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | # 4 | # Copyright © 2011-2015 Splunk, Inc. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"): you may 7 | # not use this file except in compliance with the License. You may obtain 8 | # a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 14 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 15 | # License for the specific language governing permissions and limitations 16 | # under the License. 17 | 18 | 19 | import os 20 | import sys 21 | import time 22 | 23 | splunkhome = os.environ['SPLUNK_HOME'] 24 | sys.path.append(os.path.join(splunkhome, 'etc', 'apps', 'customsearchcommands_app', 'lib')) 25 | from splunklib.searchcommands import dispatch, GeneratingCommand, Configuration, Option, validators 26 | 27 | 28 | @Configuration() 29 | class GenerateHelloCommand(GeneratingCommand): 30 | count = Option(require=True, validate=validators.Integer(0)) 31 | 32 | def generate(self): 33 | self.logger.debug("Generating %s events" % self.count) 34 | for i in range(1, self.count + 1): 35 | text = f'Hello World {i}' 36 | yield {'_time': time.time(), 'event_no': i, '_raw': text} 37 | 38 | 39 | dispatch(GenerateHelloCommand, sys.argv, sys.stdin, sys.stdout, __name__) 40 | -------------------------------------------------------------------------------- /custom_search_commands/python/customsearchcommands_app/bin/generatetext.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | # 4 | # Copyright © 2011-2015 Splunk, Inc. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"): you may 7 | # not use this file except in compliance with the License. You may obtain 8 | # a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 14 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 15 | # License for the specific language governing permissions and limitations 16 | # under the License. 17 | 18 | import os 19 | import sys 20 | import time 21 | 22 | splunkhome = os.environ['SPLUNK_HOME'] 23 | sys.path.append(os.path.join(splunkhome, 'etc', 'apps', 'customsearchcommands_app', 'lib')) 24 | from splunklib.searchcommands import dispatch, GeneratingCommand, Configuration, Option, validators 25 | 26 | 27 | @Configuration() 28 | class GenerateTextCommand(GeneratingCommand): 29 | count = Option(require=True, validate=validators.Integer(0)) 30 | text = Option(require=True) 31 | 32 | def generate(self): 33 | text = self.text 34 | self.logger.debug("Generating %d events with text %s" % (self.count, self.text)) 35 | for i in range(1, self.count + 1): 36 | yield {'_serial': i, '_time': time.time(), '_raw': str(i) + '. ' + text} 37 | 38 | 39 | dispatch(GenerateTextCommand, sys.argv, sys.stdin, sys.stdout, __name__) 40 | -------------------------------------------------------------------------------- /custom_search_commands/python/customsearchcommands_app/default/app.conf: -------------------------------------------------------------------------------- 1 | [launcher] 2 | description = {description} 3 | author = Splunk, Inc. 4 | version = 1.0 5 | 6 | [package] 7 | check_for_updates = false 8 | 9 | [ui] 10 | label = Custom search command examples 11 | is_visible = 1 12 | 13 | [triggers] 14 | reload.logging = simple 15 | -------------------------------------------------------------------------------- /custom_search_commands/python/customsearchcommands_app/default/commands.conf: -------------------------------------------------------------------------------- 1 | # [commands.conf]($SPLUNK_HOME/etc/system/README/commands.conf.spec) 2 | # Configuration for Search Commands Protocol version 2 3 | 4 | [countmatches] 5 | filename = countmatches.py 6 | chunked = true 7 | python.version = python3 8 | 9 | [filter] 10 | filename = filter.py 11 | chunked = true 12 | python.version = python3 13 | 14 | [generatetext] 15 | filename = generatetext.py 16 | chunked = true 17 | python.version = python3 18 | 19 | [simulate] 20 | filename = simulate.py 21 | chunked = true 22 | python.version = python3 23 | 24 | [sum] 25 | filename = sum.py 26 | chunked = true 27 | python.version = python3 28 | -------------------------------------------------------------------------------- /custom_search_commands/python/customsearchcommands_app/default/data/ui/nav/default.xml: -------------------------------------------------------------------------------- 1 | 19 | -------------------------------------------------------------------------------- /custom_search_commands/python/customsearchcommands_app/default/distsearch.conf: -------------------------------------------------------------------------------- 1 | # Valid in <=8.2 2 | [replicationWhitelist] 3 | searchcommands_app = apps/searchcommands_app/lib/... 4 | 5 | # Valid in >=8.3 6 | [replicationAllowlist] 7 | searchcommands_app = apps/searchcommands_app/lib/... 8 | -------------------------------------------------------------------------------- /custom_search_commands/python/customsearchcommands_app/default/transforms.conf: -------------------------------------------------------------------------------- 1 | [tweets] 2 | filename = tweets.csv.gz -------------------------------------------------------------------------------- /custom_search_commands/python/customsearchcommands_app/lookups/tweets.csv.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/custom_search_commands/python/customsearchcommands_app/lookups/tweets.csv.gz -------------------------------------------------------------------------------- /custom_search_commands/python/customsearchcommands_app/metadata/default.meta: -------------------------------------------------------------------------------- 1 | [] 2 | access = read: [ * ], write : [ admin ] 3 | -------------------------------------------------------------------------------- /custom_search_commands/python/customsearchcommands_template/bin/filter.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | import os 5 | 6 | sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "lib")) 7 | from splunklib.searchcommands import \ 8 | dispatch, EventingCommand, Configuration, Option, validators 9 | 10 | 11 | @Configuration() 12 | class %(command.title())Command(EventingCommand): 13 | """ %(synopsis) 14 | 15 | ##Syntax 16 | 17 | %(syntax) 18 | 19 | ##Description 20 | 21 | %(description) 22 | 23 | """ 24 | def transform(self, events): 25 | # Put your event transformation code here 26 | 27 | # To connect with Splunk, use the instantiated service object which is created using the server-uri and 28 | # other meta details and can be accessed as shown below 29 | # Example:- 30 | # service = self.service 31 | 32 | pass 33 | 34 | dispatch(%(command.title())Command, sys.argv, sys.stdin, sys.stdout, __name__) 35 | -------------------------------------------------------------------------------- /custom_search_commands/python/customsearchcommands_template/bin/generate.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | import os 5 | 6 | sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "lib")) 7 | from splunklib.searchcommands import \ 8 | dispatch, GeneratingCommand, Configuration, Option, validators 9 | 10 | @Configuration() 11 | class %(command.title())Command(GeneratingCommand): 12 | """ %(synopsis) 13 | 14 | ##Syntax 15 | 16 | %(syntax) 17 | 18 | ##Description 19 | 20 | %(description) 21 | 22 | """ 23 | def generate(self): 24 | # Put your event code here 25 | 26 | # To connect with Splunk, use the instantiated service object which is created using the server-uri and 27 | # other meta details and can be accessed as shown below 28 | # Example:- 29 | # service = self.service 30 | 31 | pass 32 | 33 | dispatch(%(command.title())Command, sys.argv, sys.stdin, sys.stdout, __name__) 34 | -------------------------------------------------------------------------------- /custom_search_commands/python/customsearchcommands_template/bin/report.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | import os 5 | 6 | sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "lib")) 7 | from splunklib.searchcommands import \ 8 | dispatch, ReportingCommand, Configuration, Option, validators 9 | 10 | 11 | @Configuration() 12 | class %(command.title())Command(ReportingCommand): 13 | """ %(synopsis) 14 | 15 | ##Syntax 16 | 17 | %(syntax) 18 | 19 | ##Description 20 | 21 | %(description) 22 | 23 | """ 24 | @Configuration() 25 | def map(self, events): 26 | # Put your streaming preop implementation here, or remove the map method, 27 | # if you have no need for a streaming preop 28 | 29 | # To connect with Splunk, use the instantiated service object which is created using the server-uri and 30 | # other meta details and can be accessed as shown below 31 | # Example:- 32 | # service = self.service 33 | 34 | pass 35 | 36 | def reduce(self, events): 37 | # To connect with Splunk, use the instantiated service object which is created using the server-uri and 38 | # other meta details and can be accessed as shown below 39 | # Example:- 40 | # service = self.service 41 | 42 | # Put your reporting implementation 43 | pass 44 | 45 | dispatch(%(command.title())Command, sys.argv, sys.stdin, sys.stdout, __name__) 46 | -------------------------------------------------------------------------------- /custom_search_commands/python/customsearchcommands_template/bin/stream.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | import os 5 | 6 | sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "lib")) 7 | from splunklib.searchcommands import \ 8 | dispatch, StreamingCommand, Configuration, Option, validators 9 | 10 | 11 | @Configuration() 12 | class %(command.title())Command(StreamingCommand): 13 | """ %(synopsis) 14 | 15 | ##Syntax 16 | 17 | %(syntax) 18 | 19 | ##Description 20 | 21 | %(description) 22 | 23 | """ 24 | def stream(self, events): 25 | 26 | # To connect with Splunk, use the instantiated service object which is created using the server-uri and 27 | # other meta details and can be accessed as shown below 28 | # Example:- 29 | # service = self.service 30 | 31 | # Put your event transformation code here 32 | for event in events: 33 | yield event 34 | 35 | dispatch(%(command.title())Command, sys.argv, sys.stdin, sys.stdout, __name__) 36 | -------------------------------------------------------------------------------- /custom_search_commands/python/customsearchcommands_template/default/app.conf: -------------------------------------------------------------------------------- 1 | # Splunk app configuration file 2 | 3 | [ui] 4 | label = %(app_label) 5 | is_visible = 1 6 | 7 | [launcher] 8 | description = %(app_description) 9 | author = %(app_author) 10 | version = %(app_version) 11 | 12 | [package] 13 | id = %(app_id) 14 | 15 | [install] 16 | is_configured = 0 17 | -------------------------------------------------------------------------------- /custom_search_commands/python/customsearchcommands_template/default/commands-scpv1.conf: -------------------------------------------------------------------------------- 1 | # [commands.conf]($SPLUNK_HOME/etc/system/README/commands.conf.spec) 2 | # Configuration for Search Commands Protocol version 1 3 | 4 | [%(command.lower()] 5 | filename = %(command.lower()).py 6 | enableheader = true 7 | outputheader = true 8 | requires_srinfo = true 9 | stderr_dest = message 10 | supports_getinfo = true 11 | supports_rawargs = true 12 | supports_multivalues = true 13 | -------------------------------------------------------------------------------- /custom_search_commands/python/customsearchcommands_template/default/commands-scpv2.conf: -------------------------------------------------------------------------------- 1 | # [commands.conf]($SPLUNK_HOME/etc/system/README/commands.conf.spec) 2 | # Configuration for Search Commands Protocol version 2 3 | 4 | [%(command.lower()] 5 | filename = %(command.lower()).py 6 | chunked = true 7 | -------------------------------------------------------------------------------- /custom_search_commands/python/customsearchcommands_template/default/commands.conf: -------------------------------------------------------------------------------- 1 | # [commands.conf]($SPLUNK_HOME/etc/system/README/commands.conf.spec) 2 | # Configured for Search Command Protocol version 1 by default 3 | # Replace the contents of this file with commands-scpv2.conf to enable Search Command Protocol version 2 4 | 5 | [%(command.lower()] 6 | filename = %(command.lower()).py 7 | enableheader = true 8 | outputheader = true 9 | requires_srinfo = true 10 | stderr_dest = message 11 | supports_getinfo = true 12 | supports_rawargs = true 13 | supports_multivalues = true 14 | -------------------------------------------------------------------------------- /custom_search_commands/python/customsearchcommands_template/default/data/ui/nav/default.xml: -------------------------------------------------------------------------------- 1 | 19 | -------------------------------------------------------------------------------- /custom_search_commands/python/customsearchcommands_template/default/distsearch.conf: -------------------------------------------------------------------------------- 1 | # Valid in <=8.2 2 | [replicationWhitelist] 3 | searchcommands_template = apps/searchcommands_template/lib/... 4 | 5 | # Valid in >=8.3 6 | [replicationAllowlist] 7 | searchcommands_template = apps/searchcommands_template/lib/... 8 | -------------------------------------------------------------------------------- /custom_search_commands/python/customsearchcommands_template/metadata/default.meta: -------------------------------------------------------------------------------- 1 | [] 2 | access = read: [ * ], write : [ admin ] 3 | -------------------------------------------------------------------------------- /custom_search_commands/python/eventingsearchcommands_app/README.md: -------------------------------------------------------------------------------- 1 | splunk-sdk-python eventingsearchcommands_app example 2 | ======================================== 3 | 4 | Eventing/Dataset processing commands require the entire dataset in place before the command can run. These commands are not transforming, not distributable, not streaming, and not orchestrating. Some of these commands fit into other types in specific situations or when specific arguments are used. 5 | 6 | Applies a transformation to search results as they travel through the events pipeline. 7 | 8 | Eventing commands typically filter, group, order, and/or or augment event records. Examples of eventing commands from Splunk’s built-in command set include sort, dedup, and cluster. Each execution of an eventing command should produce a set of event records that is independently usable by downstream processors. 9 | 10 | 11 | This app provides an example of Eventing Custom search commands which will only returns events having a same status mentioned in query. 12 | 13 | ### To run this example locally, follow the below steps. 14 | 15 | ### Step 1 16 | Execute the following command from the root of this repository. 17 | ```shell 18 | make up 19 | ``` 20 | 21 | ### Step 2 22 | Make sure the Splunk is in `healthy` state., run: 23 | ```shell 24 | docker ps 25 | ``` 26 | Log in into the Splunk UI. 27 | 28 | Go to http://localhost:8000/en-US/app/eventingsearchcommands_app/search page and run the following search query: 29 | ``` 30 | index="_internal" | head 4000 | eventingcsc status=200 31 | ``` 32 | Results: 33 | - We'll see events having status value 200 as mentioned in query 34 | -------------------------------------------------------------------------------- /custom_search_commands/python/eventingsearchcommands_app/default/app.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Splunk app configuration file 3 | # 4 | 5 | [install] 6 | is_configured = 0 7 | 8 | [ui] 9 | is_visible = 1 10 | label = Eventing CSC 11 | 12 | [launcher] 13 | description = Eventing custom search commands example 14 | version = 1.0.0 15 | 16 | [package] 17 | check_for_updates = false 18 | -------------------------------------------------------------------------------- /custom_search_commands/python/eventingsearchcommands_app/default/commands.conf: -------------------------------------------------------------------------------- 1 | [eventingcsc] 2 | filename = eventingcsc.py 3 | chunked = true 4 | python.version = python3 -------------------------------------------------------------------------------- /custom_search_commands/python/eventingsearchcommands_app/metadata/default.meta: -------------------------------------------------------------------------------- 1 | 2 | # Application-level permissions 3 | 4 | [] 5 | access = read : [ * ], write : [ admin, power ] 6 | 7 | ### EVENT TYPES 8 | 9 | [eventtypes] 10 | export = system 11 | 12 | 13 | ### PROPS 14 | 15 | [props] 16 | export = system 17 | 18 | 19 | ### TRANSFORMS 20 | 21 | [transforms] 22 | export = system 23 | 24 | 25 | ### LOOKUPS 26 | 27 | [lookups] 28 | export = system 29 | 30 | 31 | ### VIEWSTATES: even normal users should be able to create shared viewstates 32 | 33 | [viewstates] 34 | access = read : [ * ], write : [ * ] 35 | export = system 36 | -------------------------------------------------------------------------------- /custom_search_commands/python/generatingsearchcommands_app/README.md: -------------------------------------------------------------------------------- 1 | splunk-sdk-python generatingsearchcommands_app example 2 | ======================================== 3 | 4 | Generating commands fetch information from one or more indexes without performing any transformations. Generating commands are either event-generating or report-generating. These commands do not require any input and appear at the beginning of a search after a leading pipe. 5 | 6 | This app provides an example of Generating Custom search commands which will returns generated events equal to count mentioned in query. 7 | 8 | ### To run this example locally, follow the below steps. 9 | 10 | ### Step 1 11 | Execute the following command from the root of this repository. 12 | ```shell 13 | make up 14 | ``` 15 | 16 | ### Step 2 17 | Make sure the Splunk is in `healthy` state., run: 18 | ```shell 19 | docker ps 20 | ``` 21 | Log in into the Splunk UI. 22 | 23 | Go to http://localhost:8000/en-US/app/generatingsearchcommands_app/search page and run the following search query: 24 | ``` 25 | | generatingcsc count=4 26 | ``` 27 | Results: 28 | 29 | Event | 30 | :-----| 31 | Test Event 1 | 32 | Test Event 2 | 33 | Test Event 3 | 34 | Test Event 4 | 35 | -------------------------------------------------------------------------------- /custom_search_commands/python/generatingsearchcommands_app/default/app.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Splunk app configuration file 3 | # 4 | 5 | [install] 6 | is_configured = 0 7 | 8 | [ui] 9 | is_visible = 1 10 | label = Generating CSC 11 | 12 | [launcher] 13 | description = Generating custom search commands example 14 | version = 1.0.0 15 | 16 | [package] 17 | check_for_updates = false 18 | -------------------------------------------------------------------------------- /custom_search_commands/python/generatingsearchcommands_app/default/commands.conf: -------------------------------------------------------------------------------- 1 | [generatingcsc] 2 | filename = generatingcsc.py 3 | chunked = true 4 | python.version = python3 -------------------------------------------------------------------------------- /custom_search_commands/python/generatingsearchcommands_app/metadata/default.meta: -------------------------------------------------------------------------------- 1 | 2 | # Application-level permissions 3 | 4 | [] 5 | access = read : [ * ], write : [ admin, power ] 6 | 7 | ### EVENT TYPES 8 | 9 | [eventtypes] 10 | export = system 11 | 12 | 13 | ### PROPS 14 | 15 | [props] 16 | export = system 17 | 18 | 19 | ### TRANSFORMS 20 | 21 | [transforms] 22 | export = system 23 | 24 | 25 | ### LOOKUPS 26 | 27 | [lookups] 28 | export = system 29 | 30 | 31 | ### VIEWSTATES: even normal users should be able to create shared viewstates 32 | 33 | [viewstates] 34 | access = read : [ * ], write : [ * ] 35 | export = system 36 | -------------------------------------------------------------------------------- /custom_search_commands/python/reportingsearchcommands_app/README.md: -------------------------------------------------------------------------------- 1 | splunk-sdk-python reportingsearchcommands_app example 2 | ======================================== 3 | 4 | Transforming commands order search results into a data table. These commands "transform" the specified cell values for each event into numerical values that Splunk software can use for statistical purposes. 5 | 6 | This app provides an example of Reporting Custom search commands which will returns a count of students having higher total marks than cutoff marks. 7 | 8 | ### To run this example locally, follow the below steps. 9 | 10 | ### Step 1 11 | Execute the following command from the root of this repository. 12 | ```shell 13 | make up 14 | ``` 15 | 16 | ### Step 2 17 | Make sure the Splunk is in `healthy` state., run: 18 | ```shell 19 | docker ps 20 | ``` 21 | Log in into the Splunk UI. 22 | 23 | Go to http://localhost:8000/en-US/app/reportingsearchcommands_app/search page and run the following search query: 24 | ``` 25 | | makeresults count=10 26 | | eval math=random()%100, eng=random()%100, cs=random()%100 27 | | reportingcsc cutoff=150 math eng cs 28 | ``` 29 | Results: 30 | 31 | student having total marks greater than cutoff| 32 | :-----| 33 | 3 | 34 | 35 | Note: Here total may vary per query, so we'll get result value between 0<=ans<=count. 36 | -------------------------------------------------------------------------------- /custom_search_commands/python/reportingsearchcommands_app/default/app.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Splunk app configuration file 3 | # 4 | 5 | [install] 6 | is_configured = 0 7 | 8 | [ui] 9 | is_visible = 1 10 | label = Reporting CSC 11 | 12 | [launcher] 13 | description = Reporting custom search commands example 14 | version = 1.0.0 15 | 16 | [package] 17 | check_for_updates = false 18 | -------------------------------------------------------------------------------- /custom_search_commands/python/reportingsearchcommands_app/default/commands.conf: -------------------------------------------------------------------------------- 1 | [reportingcsc] 2 | filename = reportingcsc.py 3 | chunked = true 4 | python.version = python3 -------------------------------------------------------------------------------- /custom_search_commands/python/reportingsearchcommands_app/metadata/default.meta: -------------------------------------------------------------------------------- 1 | 2 | # Application-level permissions 3 | 4 | [] 5 | access = read : [ * ], write : [ admin, power ] 6 | 7 | ### EVENT TYPES 8 | 9 | [eventtypes] 10 | export = system 11 | 12 | 13 | ### PROPS 14 | 15 | [props] 16 | export = system 17 | 18 | 19 | ### TRANSFORMS 20 | 21 | [transforms] 22 | export = system 23 | 24 | 25 | ### LOOKUPS 26 | 27 | [lookups] 28 | export = system 29 | 30 | 31 | ### VIEWSTATES: even normal users should be able to create shared viewstates 32 | 33 | [viewstates] 34 | access = read : [ * ], write : [ * ] 35 | export = system 36 | -------------------------------------------------------------------------------- /custom_search_commands/python/streamingsearchcommands_app/README.md: -------------------------------------------------------------------------------- 1 | splunk-sdk-python streamingsearchcommands_app example 2 | ======================================== 3 | 4 | Streaming commands process search results one-by-one, applying one transformation to each event that a search returns. 5 | 6 | This app provides an example of Streaming Custom search commands which will returns events with a one new field 'fahrenheit'. 7 | 8 | ### To run this example locally, follow the below steps. 9 | 10 | ### Step 1 11 | Execute the following command from the root of this repository. 12 | ```shell 13 | make up 14 | ``` 15 | 16 | ### Step 2 17 | Make sure the Splunk is in `healthy` state., run: 18 | ```shell 19 | docker ps 20 | ``` 21 | Log in into the Splunk UI. 22 | 23 | Go to http://localhost:8000/en-US/app/streamingsearchcommands_app/search page and run the following search query: 24 | ``` 25 | | makeresults count=5 | eval celsius = random()%100 | streamingcsc 26 | ``` 27 | Results: 28 | 29 | celsius| fahrenheit | 30 | :-----|:-----| 31 | 98 | 208.4 | 32 | 96| 204.8 | 33 | 66| 150.8 | 34 | 58| 136.4 | 35 | 33| 91.4 | 36 | 37 | Note: Here celsius value may vary per query, so fahrenheit value will change according to celsius value. 38 | -------------------------------------------------------------------------------- /custom_search_commands/python/streamingsearchcommands_app/bin/streamingcsc.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | # 4 | # Copyright © 2011-2015 Splunk, Inc. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"): you may 7 | # not use this file except in compliance with the License. You may obtain 8 | # a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 14 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 15 | # License for the specific language governing permissions and limitations 16 | # under the License. 17 | 18 | import os, sys 19 | 20 | sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "lib")) 21 | from splunklib.searchcommands import dispatch, StreamingCommand, Configuration, Option, validators 22 | 23 | 24 | @Configuration() 25 | class StreamingCSC(StreamingCommand): 26 | """ 27 | The streamingcsc command returns events with a one new field 'fahrenheit'. 28 | 29 | Example: 30 | 31 | ``| makeresults count=5 | eval celsius = random()%100 | streamingcsc`` 32 | 33 | returns a records with one new filed 'fahrenheit'. 34 | """ 35 | 36 | def stream(self, records): 37 | # To connect with Splunk, use the instantiated service object which is created using the server-uri and 38 | # other meta details and can be accessed as shown below 39 | # Example:- 40 | # service = self.service 41 | # info = service.info //access the Splunk Server info 42 | 43 | for record in records: 44 | record["fahrenheit"] = (float(record["celsius"]) * 1.8) + 32 45 | yield record 46 | 47 | 48 | dispatch(StreamingCSC, sys.argv, sys.stdin, sys.stdout, __name__) 49 | -------------------------------------------------------------------------------- /custom_search_commands/python/streamingsearchcommands_app/default/app.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Splunk app configuration file 3 | # 4 | 5 | [install] 6 | is_configured = 0 7 | 8 | [ui] 9 | is_visible = 1 10 | label = Streaming CSC 11 | 12 | [launcher] 13 | description = Streaming custom search commands example 14 | version = 1.0.0 15 | 16 | [package] 17 | check_for_updates = false 18 | -------------------------------------------------------------------------------- /custom_search_commands/python/streamingsearchcommands_app/default/commands.conf: -------------------------------------------------------------------------------- 1 | [streamingcsc] 2 | filename = streamingcsc.py 3 | chunked = true 4 | python.version = python3 -------------------------------------------------------------------------------- /custom_search_commands/python/streamingsearchcommands_app/metadata/default.meta: -------------------------------------------------------------------------------- 1 | 2 | # Application-level permissions 3 | 4 | [] 5 | access = read : [ * ], write : [ admin, power ] 6 | 7 | ### EVENT TYPES 8 | 9 | [eventtypes] 10 | export = system 11 | 12 | 13 | ### PROPS 14 | 15 | [props] 16 | export = system 17 | 18 | 19 | ### TRANSFORMS 20 | 21 | [transforms] 22 | export = system 23 | 24 | 25 | ### LOOKUPS 26 | 27 | [lookups] 28 | export = system 29 | 30 | 31 | ### VIEWSTATES: even normal users should be able to create shared viewstates 32 | 33 | [viewstates] 34 | access = read : [ * ], write : [ * ] 35 | export = system 36 | -------------------------------------------------------------------------------- /javascript/browser/create-splunk-react-app/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | package-lock.json 4 | 5 | # dependencies 6 | /node_modules 7 | /.pnp 8 | .pnp.js 9 | 10 | # testing 11 | /coverage 12 | 13 | # production 14 | /build 15 | 16 | # misc 17 | .DS_Store 18 | .env.local 19 | .env.development.local 20 | .env.test.local 21 | .env.production.local 22 | 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | -------------------------------------------------------------------------------- /javascript/browser/create-splunk-react-app/create-splunk-react-app.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/javascript/browser/create-splunk-react-app/create-splunk-react-app.gif -------------------------------------------------------------------------------- /javascript/browser/create-splunk-react-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "splunk-create-react-app", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^4.2.4", 7 | "@testing-library/react": "^9.3.2", 8 | "@testing-library/user-event": "^7.1.2", 9 | "assert": "^2.0.0", 10 | "jquery": "^3.6.0", 11 | "nodeunit": "^0.11.3", 12 | "react": "^16.13.1", 13 | "react-dom": "^16.13.1", 14 | "react-scripts": "3.4.1", 15 | "splunk-sdk": "^1.10.0" 16 | }, 17 | "scripts": { 18 | "start": "HTTPS=true react-scripts start --no-cache", 19 | "build": "react-scripts build", 20 | "test": "react-scripts test", 21 | "eject": "react-scripts eject" 22 | }, 23 | "eslintConfig": { 24 | "extends": "react-app" 25 | }, 26 | "browserslist": { 27 | "production": [ 28 | ">0.2%", 29 | "not dead", 30 | "not op_mini all" 31 | ], 32 | "development": [ 33 | "last 1 chrome version", 34 | "last 1 firefox version", 35 | "last 1 safari version" 36 | ] 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /javascript/browser/create-splunk-react-app/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/javascript/browser/create-splunk-react-app/public/favicon.ico -------------------------------------------------------------------------------- /javascript/browser/create-splunk-react-app/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | React App 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /javascript/browser/create-splunk-react-app/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/javascript/browser/create-splunk-react-app/public/logo192.png -------------------------------------------------------------------------------- /javascript/browser/create-splunk-react-app/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/javascript/browser/create-splunk-react-app/public/logo512.png -------------------------------------------------------------------------------- /javascript/browser/create-splunk-react-app/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /javascript/browser/create-splunk-react-app/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /javascript/browser/create-splunk-react-app/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-header { 6 | background-color: #282c34; 7 | min-height: 100vh; 8 | display: flex; 9 | flex-direction: column; 10 | align-items: center; 11 | justify-content: center; 12 | font-size: calc(10px + 2vmin); 13 | color: white; 14 | } 15 | 16 | .App-link { 17 | color: #61dafb; 18 | } 19 | -------------------------------------------------------------------------------- /javascript/browser/create-splunk-react-app/src/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import './App.css'; 3 | import SplunkJsExample from './SplunkJsExample'; 4 | 5 | function App() { 6 | return ( 7 |
8 |
9 |

10 | 1. Edit src/splunkConfig.js to input your Splunk host/port information and restart this project using npm start. 11 |

12 | 13 |

14 | 2. Enter credentials below and click Search to login, run a sample search, and display the results. 15 |

16 | 17 | 18 | 19 |
20 |
21 | ); 22 | } 23 | 24 | export default App; 25 | -------------------------------------------------------------------------------- /javascript/browser/create-splunk-react-app/src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render } from '@testing-library/react'; 3 | import App from './App'; 4 | 5 | test('renders learn react link', () => { 6 | const { getByText } = render(); 7 | const linkElement = getByText(/learn react/i); 8 | expect(linkElement).toBeInTheDocument(); 9 | }); 10 | -------------------------------------------------------------------------------- /javascript/browser/create-splunk-react-app/src/Inputs.css: -------------------------------------------------------------------------------- 1 | label { 2 | padding: 10px; 3 | } 4 | 5 | input { 6 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 7 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 8 | sans-serif; 9 | -webkit-font-smoothing: antialiased; 10 | -moz-osx-font-smoothing: grayscale; 11 | padding: 5px; 12 | margin: 5px; 13 | border: 2px solid #ccc; 14 | -webkit-border-radius: 5px; 15 | border-radius: 5px; 16 | } 17 | 18 | textarea { 19 | resize: none; 20 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace; 21 | padding: 5px; 22 | outline: none; 23 | overflow: auto; 24 | } 25 | 26 | button { 27 | cursor: pointer; 28 | font-size: calc(10px + 2vmin); 29 | background-color: black; 30 | color: #61dafb; 31 | -webkit-border-radius: 5px; 32 | border-radius: 5px; 33 | padding: 10px; 34 | margin: 10px; 35 | } -------------------------------------------------------------------------------- /javascript/browser/create-splunk-react-app/src/Inputs.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import './Inputs.css'; 3 | 4 | class Inputs extends React.Component { 5 | constructor(props) { 6 | super(props); 7 | this.handleUsernameChange = this.handleUsernameChange.bind(this); 8 | this.handlePasswordChange = this.handlePasswordChange.bind(this); 9 | this.handleQueryChange = this.handleQueryChange.bind(this); 10 | this.handleClickSearch = this.handleClickSearch.bind(this); 11 | } 12 | 13 | handleUsernameChange(e) { 14 | this.props.onUsernameChange(e.target.value); 15 | } 16 | 17 | handlePasswordChange(e) { 18 | this.props.onPasswordChange(e.target.value); 19 | } 20 | 21 | handleQueryChange(e) { 22 | this.props.onQueryChange(e.target.value); 23 | } 24 | 25 | handleClickSearch(e) { 26 | this.props.onClickSearch(); 27 | } 28 | 29 | render() { 30 | return ( 31 |
32 | 33 |
34 | 35 |
36 |
37 |
38 |
39 | 40 |
41 |
42 |
43 |
44 | ); 45 | } 46 | } 47 | 48 | export default Inputs; -------------------------------------------------------------------------------- /javascript/browser/create-splunk-react-app/src/SplunkJsExample.css: -------------------------------------------------------------------------------- 1 | table.Results { 2 | border: 1px solid rgb(45, 45, 45); 3 | background-color: rgb(175, 175, 175); 4 | width: calc(100% - 50px); 5 | text-align: left; 6 | border-collapse: collapse; 7 | margin: 25px; 8 | } 9 | 10 | table.Results td, table.Results th { 11 | border: 1px solid rgb(175, 175, 175); 12 | padding: 3px 2px; 13 | } 14 | 15 | table.Results tbody td { 16 | font-size: 14px; 17 | } 18 | 19 | table.Results tr:nth-child(odd) { 20 | color: black; 21 | } 22 | 23 | table.Results tr:nth-child(even) { 24 | background: rgb(75, 75, 75); 25 | color: white; 26 | } 27 | 28 | table.Results thead { 29 | background: rgb(50, 50, 50); 30 | border-bottom: 2px solid rgb(225, 225, 225); 31 | } 32 | 33 | table.Results thead th { 34 | font-size: 15px; 35 | font-weight: bold; 36 | color: white; 37 | } 38 | -------------------------------------------------------------------------------- /javascript/browser/create-splunk-react-app/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /javascript/browser/create-splunk-react-app/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import * as serviceWorker from './serviceWorker'; 6 | 7 | ReactDOM.render( 8 | 9 | 10 | , 11 | document.getElementById('root') 12 | ); 13 | 14 | // If you want your app to work offline and load faster, you can change 15 | // unregister() to register() below. Note this comes with some pitfalls. 16 | // Learn more about service workers: https://bit.ly/CRA-PWA 17 | serviceWorker.unregister(); 18 | -------------------------------------------------------------------------------- /javascript/browser/create-splunk-react-app/src/setupProxy.js: -------------------------------------------------------------------------------- 1 | const { splunkConfig } = require('./splunkConfig'); 2 | const proxy = require('http-proxy-middleware'); 3 | 4 | /** 5 | * This file configures a proxy for proxying requests 6 | * from https://localhost:3000/proxy/... 7 | * to https://:/... 8 | * 9 | * This is necessary to avoid CORS issues with splunkd. 10 | */ 11 | module.exports = app => { 12 | app.use( 13 | '/proxy', 14 | proxy({ 15 | target: 'https://' + splunkConfig.host + ':' + splunkConfig.port, 16 | changeOrigin: true, 17 | secure: false, 18 | pathRewrite: {'^/proxy' : ''}, // remove /proxy prefix 19 | logLevel: 'debug' 20 | }) 21 | ); 22 | }; -------------------------------------------------------------------------------- /javascript/browser/create-splunk-react-app/src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom/extend-expect'; 6 | -------------------------------------------------------------------------------- /javascript/browser/create-splunk-react-app/src/splunkConfig.js: -------------------------------------------------------------------------------- 1 | const splunkConfig = { 2 | host: 'localhost', 3 | port: '8089' 4 | }; 5 | 6 | module.exports = { splunkConfig }; -------------------------------------------------------------------------------- /javascript/browser/resources/images/3viz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/javascript/browser/resources/images/3viz.png -------------------------------------------------------------------------------- /javascript/browser/resources/images/minisplunk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/javascript/browser/resources/images/minisplunk.png -------------------------------------------------------------------------------- /javascript/browser/resources/images/simple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/javascript/browser/resources/images/simple.png -------------------------------------------------------------------------------- /javascript/browser/resources/images/splunk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/javascript/browser/resources/images/splunk.png -------------------------------------------------------------------------------- /javascript/browser/resources/images/ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/javascript/browser/resources/images/ui.png -------------------------------------------------------------------------------- /javascript/browser/resources/jquery.placeholder.min.js: -------------------------------------------------------------------------------- 1 | /*! http://mths.be/placeholder v1.8.6 by @mathias */ 2 | (function(e,g,$){var a='placeholder' in g.createElement('input'),c='placeholder' in g.createElement('textarea'),h=$.fn,i;if(a&&c){i=h.placeholder=function(){return this};i.input=i.textarea=true}else{i=h.placeholder=function(){return this.filter((a?'textarea':':input')+'[placeholder]').not('.placeholder').bind('focus.placeholder',b).bind('blur.placeholder',d).trigger('blur.placeholder').end()};i.input=a;i.textarea=c;$(function(){$('form').bind('submit.placeholder',function(){var j=$('.placeholder',this).each(b);setTimeout(function(){j.each(d)},10)})});$(e).bind('unload.placeholder',function(){$('.placeholder').val('')})}function f(k){var j={},l=/^jQuery\d+$/;$.each(k.attributes,function(n,m){if(m.specified&&!l.test(m.name)){j[m.name]=m.value}});return j}function b(){var j=$(this);if(j.val()===j.attr('placeholder')&&j.hasClass('placeholder')){if(j.data('placeholder-password')){j.hide().next().show().focus().attr('id',j.removeAttr('id').data('placeholder-id'))}else{j.val('').removeClass('placeholder')}}}function d(){var n,m=$(this),j=m,l=this.id;if(m.val()===''){if(m.is(':password')){if(!m.data('placeholder-textinput')){try{n=m.clone().attr({type:'text'})}catch(k){n=$('').attr($.extend(f(this),{type:'text'}))}n.removeAttr('name').data('placeholder-password',true).data('placeholder-id',l).bind('focus.placeholder',b);m.data('placeholder-textinput',n).data('placeholder-id',l).before(n)}m=m.removeAttr('id').hide().prev().attr('id',l).show()}m.addClass('placeholder').val(m.attr('placeholder'))}else{m.removeClass('placeholder')}}}(this,document,jQuery)); -------------------------------------------------------------------------------- /javascript/browser/resources/rickshaw/detail.css: -------------------------------------------------------------------------------- 1 | .rickshaw_graph .detail { 2 | pointer-events: none; 3 | position: absolute; 4 | top: 0; 5 | z-index: 2; 6 | background: rgba(0, 0, 0, 0.1); 7 | bottom: 0; 8 | width: 1px; 9 | transition: opacity 0.25s linear; 10 | -moz-transition: opacity 0.25s linear; 11 | -o-transition: opacity 0.25s linear; 12 | -webkit-transition: opacity 0.25s linear; 13 | } 14 | .rickshaw_graph .detail.inactive { 15 | opacity: 0; 16 | } 17 | .rickshaw_graph .detail .item.active { 18 | opacity: 1; 19 | } 20 | .rickshaw_graph .detail .x_label { 21 | font-family: Arial, sans-serif; 22 | border-radius: 3px; 23 | padding: 6px; 24 | opacity: 0.5; 25 | border: 1px solid #e0e0e0; 26 | font-size: 12px; 27 | position: absolute; 28 | background: white; 29 | white-space: nowrap; 30 | } 31 | .rickshaw_graph .detail .item { 32 | position: absolute; 33 | z-index: 2; 34 | border-radius: 3px; 35 | padding: 0.25em; 36 | font-size: 12px; 37 | font-family: Arial, sans-serif; 38 | opacity: 0; 39 | background: rgba(0, 0, 0, 0.4); 40 | color: white; 41 | border: 1px solid rgba(0, 0, 0, 0.4); 42 | margin-left: 1em; 43 | margin-top: -1em; 44 | white-space: nowrap; 45 | } 46 | .rickshaw_graph .detail .item.active { 47 | opacity: 1; 48 | background: rgba(0, 0, 0, 0.8); 49 | } 50 | .rickshaw_graph .detail .item:before { 51 | content: "\25c2"; 52 | position: absolute; 53 | left: -0.5em; 54 | color: rgba(0, 0, 0, 0.7); 55 | width: 0; 56 | } 57 | .rickshaw_graph .detail .dot { 58 | width: 5px; 59 | height: 5px; 60 | margin-left: -2px; 61 | margin-top: -3px; 62 | border-radius: 3px; 63 | position: absolute; 64 | } 65 | .rickshaw_graph .detail .dot.active { 66 | background: rgba(255, 255, 255, 0.8); 67 | box-shadow: 0 0 1px rgba(0, 0, 0, 0.5); 68 | } -------------------------------------------------------------------------------- /javascript/browser/resources/rickshaw/legend.css: -------------------------------------------------------------------------------- 1 | .rickshaw_legend { 2 | font-family: Arial; 3 | font-size: 12px; 4 | color: white; 5 | background: #404040; 6 | display: inline-block; 7 | padding: 12px 5px; 8 | border-radius: 2px; 9 | position: relative; 10 | } 11 | .rickshaw_legend:hover { 12 | z-index: 10; 13 | } 14 | .rickshaw_legend .swatch { 15 | width: 10px; 16 | height: 10px; 17 | border: 1px solid rgba(0, 0, 0, 0.2); 18 | } 19 | .rickshaw_legend .line { 20 | clear: both; 21 | line-height: 140%; 22 | padding-right: 15px; 23 | } 24 | .rickshaw_legend .line .swatch { 25 | display: inline-block; 26 | margin-right: 3px; 27 | border-radius: 2px; 28 | } 29 | .rickshaw_legend .label { 30 | white-space: nowrap; 31 | display: inline; 32 | } 33 | .rickshaw_legend .action:hover { 34 | opacity: 0.6; 35 | } 36 | .rickshaw_legend .action { 37 | margin-right: 0.2em; 38 | font-size: 10px; 39 | opacity: 0.2; 40 | cursor: pointer; 41 | font-size: 14px; 42 | } 43 | .rickshaw_legend .line.disabled { 44 | opacity: 0.4; 45 | } 46 | .rickshaw_legend ul { 47 | list-style-type: none; 48 | margin: 0; 49 | padding: 0; 50 | margin: 2px; 51 | cursor: pointer; 52 | } 53 | .rickshaw_legend li { 54 | padding: 0 0 0 2px; 55 | min-width: 80px; 56 | white-space: nowrap; 57 | } 58 | .rickshaw_legend li:hover { 59 | background: rgba(255, 255, 255, 0.08); 60 | border-radius: 3px; 61 | } 62 | .rickshaw_legend li:active { 63 | background: rgba(255, 255, 255, 0.2); 64 | border-radius: 3px; 65 | } -------------------------------------------------------------------------------- /javascript/browser/resources/timeline.css: -------------------------------------------------------------------------------- 1 | .Timeline .label { 2 | font-family: Arial,Helvetica,sans-serif; 3 | font-size: 12px; 4 | cursor: default; 5 | } 6 | .Timeline .TimeAxisLabels .label { 7 | margin-left: 5px; 8 | margin-right: 5px; 9 | margin-top: 4px; 10 | margin-bottom: 4px; 11 | } 12 | .Timeline .NumericAxisLabels .label { 13 | margin-left: 5px; 14 | margin-right: 5px; 15 | margin-top: 3px; 16 | margin-bottom: 3px; 17 | } 18 | .Timeline .ClickDragRangeMarker .label { 19 | color: #000000; 20 | margin-left: 7px; 21 | margin-right: 7px; 22 | } 23 | .Timeline .Tooltip .label { 24 | color: #FFFFFF; 25 | margin-left: 7px; 26 | margin-right: 7px; 27 | margin-top: 4px; 28 | margin-bottom: 4px; 29 | } -------------------------------------------------------------------------------- /javascript/node/login.js: -------------------------------------------------------------------------------- 1 | let splunkjs = require('splunk-sdk'); 2 | 3 | /* 4 | ################ Login with sessionKey ################# 5 | Execute following command to create sessionKey manually: 6 | curl -k -u : ://:/services/auth/login -d username= -d password= 7 | */ 8 | let serviceWithSessionKey = new splunkjs.Service( 9 | { 10 | // Replace the host if you are accessing remote host 11 | scheme: 'https', 12 | host: 'localhost', 13 | port: '8089', 14 | sessionKey: 'SESSION_KEY', // Add your session key 15 | version: '8', 16 | }); 17 | 18 | serviceWithSessionKey.get("search/jobs", { count: 2 }).then((res) => { 19 | console.log("Login successful with sessionKey"); 20 | }).catch ((err) => { 21 | console.log(err); 22 | }); 23 | 24 | /* 25 | ################ Login with token ################# 26 | Execute following command to enable token authentication: 27 | curl -k -u : -X POST ://:/services/admin/token-auth/tokens_auth -d disabled=false 28 | 29 | Execute following command to create bearer token manually: 30 | curl -k -u : -X POST ://:/services/authorization/tokens?output_mode=json --data name= --data audience=Users --data-urlencode expires_on=+30d 31 | */ 32 | let serviceWithBearerToken = new splunkjs.Service( 33 | { 34 | // Replace the host if you are accessing remote host 35 | scheme: 'https', 36 | host: 'localhost', 37 | port: '8089', 38 | sessionKey: 'TOKEN', // Add your token here 39 | version: '8', 40 | }); 41 | 42 | serviceWithBearerToken.get("search/jobs", { count: 2 }).then((res) => { 43 | console.log("Login successful with bearer token"); 44 | }).catch ((err) => { 45 | console.log(err); 46 | }); 47 | -------------------------------------------------------------------------------- /javascript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test_examples", 3 | "version": "0.0.1", 4 | "description": "Splunk test examples", 5 | "main": "test_examples.js", 6 | "dependencies": { 7 | "splunk-sdk": ">=1.4.0", 8 | "needle": "3.0.0" 9 | }, 10 | "devDependencies": { 11 | "browserify": "^17.0.0", 12 | "chai": "^4.3.4", 13 | "mocha": "7.2.0", 14 | "mustache": "4.2.0" 15 | }, 16 | "author": "Splunk", 17 | "engine": { 18 | "node": ">=0.8.0" 19 | }, 20 | "scripts": { 21 | "test": "mocha test_examples.js", 22 | "browser-examples": "node test_browser_examples" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /modularinputs/python/github_commits/README/inputs.conf.spec: -------------------------------------------------------------------------------- 1 | [github_commits://] 2 | *This example modular input retrieves GitHub commits and indexes them in Splunk. 3 | 4 | owner = 5 | repo_name = 6 | token = 7 | -------------------------------------------------------------------------------- /modularinputs/python/github_commits/default/app.conf: -------------------------------------------------------------------------------- 1 | [install] 2 | is_configured = 0 3 | 4 | [ui] 5 | is_visible = 1 6 | label = GitHub Commits Modular Input 7 | 8 | [launcher] 9 | author=Splunk 10 | description=This example modular input retrieves GitHub commits and indexes them in Splunk. 11 | version = 1.0 12 | 13 | [package] 14 | check_for_updates = false 15 | -------------------------------------------------------------------------------- /modularinputs/python/github_commits/default/inputs.conf: -------------------------------------------------------------------------------- 1 | [github_commits] 2 | python.version = python3 3 | -------------------------------------------------------------------------------- /modularinputs/python/github_forks/README.md: -------------------------------------------------------------------------------- 1 | splunk-sdk-python github_forks example 2 | ======================================== 3 | 4 | This app provides an example of a modular input that generates the number of repository forks according to the Github API based on the owner and repo_name provided by the user during setup of the input. 5 | 6 | ### To run this example locally, follow the below steps. 7 | 8 | ### Step 1 9 | Execute the following command from the root of this repository. 10 | ```shell 11 | make up 12 | ``` 13 | 14 | ### Step 2 15 | Make sure the Splunk is in `healthy` state., run: 16 | ```shell 17 | docker ps 18 | ``` 19 | 20 | Log in into the Splunk UI, Go to `Settings > DATA > Data inputs` 21 | 22 | Search for `Github Repository Forks` (as per the `default/app.conf` file) 23 | 24 | Click on the `+Add new` button in front of the `Github Repository Fork` which opens a configuration page for `Github Repository Fork` app. 25 | 26 | `name`: Name of your choice to refer to this modularinput later. i.e. pythonforks 27 | 28 | `Owner`: Github user or organization that created the repository. i.e. Splunk 29 | 30 | `Repo Name`: Name of the Github repository. i.e. splunk-sdk-python 31 | 32 | Once the details are filled, click on `Next` and then click on `Start Searching` 33 | 34 | 35 | ## Awesome! 36 | 37 | The setup is done. Try the following commands to see some results. 38 | 39 | To get github forks for the `pythonforks` input that we configured above. Search 40 | ```markdown 41 | source="github_forks://pythonforks" 42 | ``` 43 | 44 | To get forks for all the searches in `github_forks` app. Search 45 | ```markdown 46 | source="github_forks://*" 47 | ``` 48 | 49 | > NOTE: If no Github Forks input appears then the script is likely not running properly, see https://docs.splunk.com/Documentation/SplunkCloud/latest/AdvancedDev/ModInputsDevTools for more details on debugging the modular input using the command line and relevant logs. 50 | -------------------------------------------------------------------------------- /modularinputs/python/github_forks/README/inputs.conf.spec: -------------------------------------------------------------------------------- 1 | [github_forks://] 2 | *Streams events giving the number of forks of a GitHub repository 3 | 4 | owner = 5 | repo_name = 6 | -------------------------------------------------------------------------------- /modularinputs/python/github_forks/default/app.conf: -------------------------------------------------------------------------------- 1 | [install] 2 | is_configured = 0 3 | 4 | [ui] 5 | is_visible = 1 6 | label = Github Repository Forks 7 | 8 | [launcher] 9 | author=Splunk 10 | description=Streams events giving the number of forks of a GitHub repository 11 | version = 1.0 12 | 13 | [package] 14 | check_for_updates = false 15 | -------------------------------------------------------------------------------- /modularinputs/python/github_forks/default/inputs.conf: -------------------------------------------------------------------------------- 1 | [github_forks] 2 | python.version = python3 3 | -------------------------------------------------------------------------------- /modularinputs/python/random_numbers/README.md: -------------------------------------------------------------------------------- 1 | splunk-sdk-python random_numbers example 2 | ======================================== 3 | 4 | This app provides an example of a modular input that generates a random number between the min and max values provided by the user during setup of the input. 5 | 6 | ### To run this example locally, follow the below steps. 7 | 8 | ### Step 1 9 | Execute the following command from the root of this repository. 10 | ```shell 11 | make up 12 | ``` 13 | 14 | ### Step 2 15 | Make sure the Splunk is in `healthy` state., run: 16 | ```shell 17 | docker ps 18 | ``` 19 | 20 | Log in into the Splunk UI, Go to ``Settings > DATA > Data inputs`` 21 | 22 | Search for `Random Numbers` (as per the `default/app.conf` file) 23 | 24 | Click on the `+Add new` button in front of the `Random Numbers` which opens a configuration page for `Random Numbers` app. 25 | 26 | `name`: Name of your choice to refer to this modularinput later. i.e. randomnumber 27 | 28 | `Minimum`: Minimum random number to be produced by this input. i.e. 1 29 | 30 | `Maximum`: Maximum random number to be produced by this input. i.e. 5 31 | 32 | Once the details are filled, click on `Next` and then click on `Start Searching` 33 | 34 | ## Awesome! 35 | 36 | The setup is done. Try the following commands to see some results. 37 | 38 | To get a random number for the `randomnumber` input that we configured above. Search 39 | ```markdown 40 | source="random_numbers://randomnumber" 41 | ``` 42 | 43 | To get random numbers for all the inputs in `random_numbers` app. Search 44 | ```markdown 45 | source="random_numbers://*" 46 | ``` 47 | 48 | > NOTE: If no Random Numbers input appears then the script is likely not running properly, see https://docs.splunk.com/Documentation/SplunkCloud/latest/AdvancedDev/ModInputsDevTools for more details on debugging the modular input using the command line and relevant logs. 49 | 50 | -------------------------------------------------------------------------------- /modularinputs/python/random_numbers/README/inputs.conf.spec: -------------------------------------------------------------------------------- 1 | [random_numbers://] 2 | *Generates events containing a random floating point number. 3 | 4 | min = 5 | max = 6 | -------------------------------------------------------------------------------- /modularinputs/python/random_numbers/default/app.conf: -------------------------------------------------------------------------------- 1 | [install] 2 | is_configured = 0 3 | 4 | [ui] 5 | is_visible = 1 6 | label = Random Numbers 7 | 8 | [launcher] 9 | author=Splunk 10 | description=Streams events containing a random number 11 | version = 1.0 12 | 13 | [package] 14 | check_for_updates = false 15 | -------------------------------------------------------------------------------- /modularinputs/python/random_numbers/default/inputs.conf: -------------------------------------------------------------------------------- 1 | [random_numbers] 2 | python.version = python3 3 | -------------------------------------------------------------------------------- /python/.env: -------------------------------------------------------------------------------- 1 | # Splunk host (default: localhost) 2 | host=localhost 3 | # Splunk admin port (default: 8089) 4 | port=8089 5 | # Splunk username 6 | username=admin 7 | # Splunk password 8 | password=changed! 9 | # Access scheme (default: https) 10 | scheme=https 11 | # Your version of Splunk (default: 6.2) 12 | version=8.0 13 | # Bearer token for authentication 14 | #splunkToken="" 15 | # Session key for authentication 16 | #token="" 17 | -------------------------------------------------------------------------------- /python/analytics/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2011-2015 Splunk, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"): you may 6 | # not use this file except in compliance with the License. You may obtain 7 | # a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | # License for the specific language governing permissions and limitations 15 | # under the License. 16 | 17 | from . import input 18 | from . import output 19 | -------------------------------------------------------------------------------- /python/analytics/css/showLoading.css: -------------------------------------------------------------------------------- 1 | .loading-indicator { 2 | height: 80px; 3 | width: 80px; 4 | background: url( '/static/images/loading.gif' ); 5 | background-repeat: no-repeat; 6 | background-position: center center; 7 | } 8 | 9 | .loading-indicator-overlay { 10 | background-color: #FFFFFF; 11 | opacity: 0.6; 12 | filter: alpha(opacity = 60); 13 | } -------------------------------------------------------------------------------- /python/analytics/images/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/python/analytics/images/loading.gif -------------------------------------------------------------------------------- /python/analytics/templates/make_table.tpl: -------------------------------------------------------------------------------- 1 | %#template to generate a HTML table from a list of tuples (or list of lists, or tuple of tuples or ...) 2 |

The open items are as follows:

3 | 4 | %for row in rows: 5 | 6 | %for col in row: 7 | 8 | %end 9 | 10 | %end 11 |
{{col}}
-------------------------------------------------------------------------------- /python/apicalls_client.py: -------------------------------------------------------------------------------- 1 | # Copyright 2011-2015 Splunk, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"): you may 4 | # not use this file except in compliance with the License. You may obtain 5 | # a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations 13 | # under the License. 14 | 15 | """ 16 | This example ses the SDK client module, which abstracts away most most of the 17 | wire level details of invoking the Splunk REST API, but that still presents a 18 | stateless interface to Splunk the attempts to faithfully represent the 19 | semantics of the underlying REST API. 20 | 21 | The example happens to retrieve a list of installed apps from a given 22 | Splunk instance, but they could apply as easily to any other area of the REST 23 | API.""" 24 | 25 | import sys 26 | import os 27 | sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "lib")) 28 | from splunklib import client 29 | 30 | 31 | def main(): 32 | HOST = "localhost" 33 | PORT = 8089 34 | USERNAME = "admin" 35 | PASSWORD = "changed!" 36 | 37 | service = client.connect( 38 | host=HOST, 39 | port=PORT, 40 | username=USERNAME, 41 | password=PASSWORD) 42 | 43 | for app in service.apps: 44 | print(app.name) 45 | 46 | 47 | if __name__ == "__main__": 48 | main() 49 | -------------------------------------------------------------------------------- /python/dashboard/README.md: -------------------------------------------------------------------------------- 1 | # Example on how to generate chart 2 | 3 | This sample shows how to use the Python SDK and Splunk to generate chart for the statistical data. 4 | In this specific case, we use a plot the statistics for the data that we are indexing using the `twitted` example. 5 | 6 | ## How It Works 7 | 8 | There are two logical components to the sample: getting data from Splunk and 9 | generating charts. 10 | 11 | 1. We fetch the data from Twitter and index it in Splunk. 12 | 2. We create various search jobs based on user input, and generate charts. 13 | 14 | ## How To Run It 15 | 16 | Follow the instruction written in **`twitted/README.md`** and `twitted/twitted/README.md` files. 17 | 18 | Once you run the twitted example successfully. 19 | 20 | Also install `pandas` and `matplotlib` 21 | 22 | Open the terminal in dashboard directory and run: 23 | ```shell 24 | python feed.py 25 | ``` 26 | 27 | You'll be asked to provide one of the predefined values as a commandline argument. 28 | 29 | i.e 30 | ```shell 31 | python feed.py tophashtags 32 | ``` -------------------------------------------------------------------------------- /python/event_types.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2011-2015 Splunk, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"): you may 6 | # not use this file except in compliance with the License. You may obtain 7 | # a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | # License for the specific language governing permissions and limitations 15 | # under the License. 16 | 17 | """A command line utility that lists Splunk event types.""" 18 | 19 | import sys 20 | import os 21 | sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "lib")) 22 | 23 | from splunklib.client import connect 24 | from utils import parse 25 | 26 | 27 | def main(): 28 | opts = parse(sys.argv[1:], {}, ".env") 29 | service = connect(**opts.kwargs) 30 | 31 | for item in service.event_types: 32 | print(item.name) 33 | print('=' * len(item.name)) 34 | content = item.content 35 | for key in sorted(content.keys()): 36 | value = content[key] 37 | print(f"{key}: {value}") 38 | print() 39 | 40 | 41 | if __name__ == "__main__": 42 | main() 43 | -------------------------------------------------------------------------------- /python/explorer/prettify/lang-apollo.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/python/explorer/prettify/lang-apollo.js -------------------------------------------------------------------------------- /python/explorer/prettify/lang-clj.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2011 Google Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | var a=null; 17 | PR.registerLangHandler(PR.createSimpleLexer([["opn",/^[([{]+/,a,"([{"],["clo",/^[)\]}]+/,a,")]}"],["com",/^;[^\n\r]*/,a,";"],["pln",/^[\t\n\r \xa0]+/,a,"\t\n\r \xa0"],["str",/^"(?:[^"\\]|\\[\S\s])*(?:"|$)/,a,'"']],[["kwd",/^(?:def|if|do|let|quote|var|fn|loop|recur|throw|try|monitor-enter|monitor-exit|defmacro|defn|defn-|macroexpand|macroexpand-1|for|doseq|dosync|dotimes|and|or|when|not|assert|doto|proxy|defstruct|first|rest|cons|defprotocol|deftype|defrecord|reify|defmulti|defmethod|meta|with-meta|ns|in-ns|create-ns|import|intern|refer|alias|namespace|resolve|ref|deref|refset|new|set!|memfn|to-array|into-array|aset|gen-class|reduce|map|filter|find|nil?|empty?|hash-map|hash-set|vec|vector|seq|flatten|reverse|assoc|dissoc|list|list?|disj|get|union|difference|intersection|extend|extend-type|extend-protocol|prn)\b/,a], 18 | ["typ",/^:[\dA-Za-z-]+/]]),["clj"]); 19 | -------------------------------------------------------------------------------- /python/explorer/prettify/lang-css.js: -------------------------------------------------------------------------------- 1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n "]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]*)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["com", 2 | /^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]); 3 | -------------------------------------------------------------------------------- /python/explorer/prettify/lang-go.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/python/explorer/prettify/lang-go.js -------------------------------------------------------------------------------- /python/explorer/prettify/lang-hs.js: -------------------------------------------------------------------------------- 1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t-\r ]+/,null,"\t\n \r "],["str",/^"(?:[^\n\f\r"\\]|\\[\S\s])*(?:"|$)/,null,'"'],["str",/^'(?:[^\n\f\r'\\]|\\[^&])'?/,null,"'"],["lit",/^(?:0o[0-7]+|0x[\da-f]+|\d+(?:\.\d+)?(?:e[+-]?\d+)?)/i,null,"0123456789"]],[["com",/^(?:--+[^\n\f\r]*|{-(?:[^-]|-+[^}-])*-})/],["kwd",/^(?:case|class|data|default|deriving|do|else|if|import|in|infix|infixl|infixr|instance|let|module|newtype|of|then|type|where|_)(?=[^\d'A-Za-z]|$)/, 2 | null],["pln",/^(?:[A-Z][\w']*\.)*[A-Za-z][\w']*/],["pun",/^[^\d\t-\r "'A-Za-z]+/]]),["hs"]); 3 | -------------------------------------------------------------------------------- /python/explorer/prettify/lang-lisp.js: -------------------------------------------------------------------------------- 1 | var a=null; 2 | PR.registerLangHandler(PR.createSimpleLexer([["opn",/^\(+/,a,"("],["clo",/^\)+/,a,")"],["com",/^;[^\n\r]*/,a,";"],["pln",/^[\t\n\r \xa0]+/,a,"\t\n\r \xa0"],["str",/^"(?:[^"\\]|\\[\S\s])*(?:"|$)/,a,'"']],[["kwd",/^(?:block|c[ad]+r|catch|con[ds]|def(?:ine|un)|do|eq|eql|equal|equalp|eval-when|flet|format|go|if|labels|lambda|let|load-time-value|locally|macrolet|multiple-value-call|nil|progn|progv|quote|require|return-from|setq|symbol-macrolet|t|tagbody|the|throw|unwind)\b/,a], 3 | ["lit",/^[+-]?(?:[#0]x[\da-f]+|\d+\/\d+|(?:\.\d+|\d+(?:\.\d*)?)(?:[de][+-]?\d+)?)/i],["lit",/^'(?:-*(?:\w|\\[!-~])(?:[\w-]*|\\[!-~])[!=?]?)?/],["pln",/^-*(?:[_a-z]|\\[!-~])(?:[\w-]*|\\[!-~])[!=?]?/i],["pun",/^[^\w\t\n\r "'-);\\\xa0]+/]]),["cl","el","lisp","scm"]); 4 | -------------------------------------------------------------------------------- /python/explorer/prettify/lang-lua.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/python/explorer/prettify/lang-lua.js -------------------------------------------------------------------------------- /python/explorer/prettify/lang-ml.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/python/explorer/prettify/lang-ml.js -------------------------------------------------------------------------------- /python/explorer/prettify/lang-n.js: -------------------------------------------------------------------------------- 1 | var a=null; 2 | PR.registerLangHandler(PR.createSimpleLexer([["str",/^(?:'(?:[^\n\r'\\]|\\.)*'|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,a,'"'],["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,a,"#"],["pln",/^\s+/,a," \r\n\t\xa0"]],[["str",/^@"(?:[^"]|"")*(?:"|$)/,a],["str",/^<#[^#>]*(?:#>|$)/,a],["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,a],["com",/^\/\/[^\n\r]*/,a],["com",/^\/\*[\S\s]*?(?:\*\/|$)/, 3 | a],["kwd",/^(?:abstract|and|as|base|catch|class|def|delegate|enum|event|extern|false|finally|fun|implements|interface|internal|is|macro|match|matches|module|mutable|namespace|new|null|out|override|params|partial|private|protected|public|ref|sealed|static|struct|syntax|this|throw|true|try|type|typeof|using|variant|virtual|volatile|when|where|with|assert|assert2|async|break|checked|continue|do|else|ensures|for|foreach|if|late|lock|new|nolate|otherwise|regexp|repeat|requires|return|surroundwith|unchecked|unless|using|while|yield)\b/, 4 | a],["typ",/^(?:array|bool|byte|char|decimal|double|float|int|list|long|object|sbyte|short|string|ulong|uint|ufloat|ulong|ushort|void)\b/,a],["lit",/^@[$_a-z][\w$@]*/i,a],["typ",/^@[A-Z]+[a-z][\w$@]*/,a],["pln",/^'?[$_a-z][\w$@]*/i,a],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,a,"0123456789"],["pun",/^.[^\s\w"-$'./@`]*/,a]]),["n","nemerle"]); 5 | -------------------------------------------------------------------------------- /python/explorer/prettify/lang-proto.js: -------------------------------------------------------------------------------- 1 | PR.registerLangHandler(PR.sourceDecorator({keywords:"bytes,default,double,enum,extend,extensions,false,group,import,max,message,option,optional,package,repeated,required,returns,rpc,service,syntax,to,true",types:/^(bool|(double|s?fixed|[su]?int)(32|64)|float|string)\b/,cStyleComments:!0}),["proto"]); 2 | -------------------------------------------------------------------------------- /python/explorer/prettify/lang-scala.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/python/explorer/prettify/lang-scala.js -------------------------------------------------------------------------------- /python/explorer/prettify/lang-sql.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/python/explorer/prettify/lang-sql.js -------------------------------------------------------------------------------- /python/explorer/prettify/lang-tex.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/python/explorer/prettify/lang-tex.js -------------------------------------------------------------------------------- /python/explorer/prettify/lang-vb.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/python/explorer/prettify/lang-vb.js -------------------------------------------------------------------------------- /python/explorer/prettify/lang-vhdl.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/python/explorer/prettify/lang-vhdl.js -------------------------------------------------------------------------------- /python/explorer/prettify/lang-wiki.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/python/explorer/prettify/lang-wiki.js -------------------------------------------------------------------------------- /python/explorer/prettify/lang-yaml.js: -------------------------------------------------------------------------------- 1 | var a=null; 2 | PR.registerLangHandler(PR.createSimpleLexer([["pun",/^[:>?|]+/,a,":|>?"],["dec",/^%(?:YAML|TAG)[^\n\r#]+/,a,"%"],["typ",/^&\S+/,a,"&"],["typ",/^!\S*/,a,"!"],["str",/^"(?:[^"\\]|\\.)*(?:"|$)/,a,'"'],["str",/^'(?:[^']|'')*(?:'|$)/,a,"'"],["com",/^#[^\n\r]*/,a,"#"],["pln",/^\s+/,a," \t\r\n"]],[["dec",/^(?:---|\.\.\.)(?:[\n\r]|$)/],["pun",/^-/],["kwd",/^\w+:[\n\r ]/],["pln",/^\w+/]]),["yaml","yml"]); 3 | -------------------------------------------------------------------------------- /python/explorer/prettify/prettify.css: -------------------------------------------------------------------------------- 1 | .pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} -------------------------------------------------------------------------------- /python/fired_alerts.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2011-2015 Splunk, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"): you may 6 | # not use this file except in compliance with the License. You may obtain 7 | # a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | # License for the specific language governing permissions and limitations 15 | # under the License. 16 | 17 | """A command line utility that prints out fired alerts.""" 18 | 19 | import sys 20 | import os 21 | sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "lib")) 22 | 23 | from splunklib.client import connect 24 | 25 | from utils import parse 26 | 27 | 28 | def main(): 29 | opts = parse(sys.argv[1:], {}, ".env") 30 | service = connect(**opts.kwargs) 31 | 32 | for group in service.fired_alerts: 33 | header = f"{group.name} (count: {group.count})" 34 | print(header) 35 | print('=' * len(header)) 36 | alerts = group.alerts 37 | for alert in alerts.list(): 38 | content = alert.content 39 | for key in sorted(content.keys()): 40 | value = content[key] 41 | print(f"{key}: {value}") 42 | print() 43 | 44 | 45 | if __name__ == "__main__": 46 | main() 47 | -------------------------------------------------------------------------------- /python/get_job.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2011-2015 Splunk, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"): you may 6 | # not use this file except in compliance with the License. You may obtain 7 | # a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | # License for the specific language governing permissions and limitations 15 | # under the License. 16 | 17 | """A simple example showing to use the Service.job method to retrieve 18 | a search Job by its sid. 19 | """ 20 | 21 | import sys 22 | import os 23 | sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "lib")) 24 | import time 25 | 26 | from splunklib import client 27 | 28 | from utils import parse 29 | 30 | 31 | def main(argv): 32 | opts = parse(argv, {}, ".env") 33 | service = client.connect(**opts.kwargs) 34 | 35 | # Execute a simple search, and store the sid 36 | sid = service.search("search index=_internal | head 5").sid 37 | 38 | # Now, we can get the `Job` 39 | job = service.job(sid) 40 | 41 | # Wait for the job to complete 42 | while not job.is_done(): 43 | time.sleep(1) 44 | 45 | print(f"Number of events found: {int(job['eventCount'])}") 46 | 47 | 48 | if __name__ == "__main__": 49 | main(sys.argv[1:]) 50 | -------------------------------------------------------------------------------- /python/handlers/README.md: -------------------------------------------------------------------------------- 1 | # Pluggable HTTP Request Handlers 2 | 3 | The Splunk SDK library supports pluggable HTTP request handlers that enable 4 | the library to be used with alternate HTTP request implementations. 5 | 6 | This feature can be used to supply implementations with support for features 7 | not included in the default request handler (which is based on httplib), such 8 | as support for HTTP proxies and server certificate validation. It can also be 9 | used to provide implementations with additional logging or diagnostic output 10 | for debugging. 11 | 12 | This directory contains a collection of examples that demonstrate various 13 | alternative HTTP request handlers. 14 | 15 | * **handler_urllib2.py** is a simple request handler implemented using urllib2. 16 | 17 | * **handler_debug.py** wraps the default request handler and prints some 18 | simple request information to stdout. 19 | 20 | * **handler_proxy.py** implements support for HTTP requests via a proxy. 21 | 22 | * **handler_certs.py** implements a hander that validates server certs. 23 | 24 | -------------------------------------------------------------------------------- /python/handlers/cacert.bad.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 3 | UzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xDzANBgNVBAoT 4 | BlNwbHVuazEXMBUGA1UEAxMOU3BsdW5rQ29tbW9uQ0ExITAfBgkqhkiG9w0BCQEW 5 | EnN1cHBvcnRAc3BsdW5rLmNvbTAeFw0wNjA3MjQxNzEyMTlaFw0xNjA3MjExNzEy 6 | MTlaMH8xCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNU2FuIEZy 7 | YW5jaXNjbzEPMA0GA1UEChMGU3BsdW5rMRcwFQYDVQQDEw5TcGx1bmtDb21tb25D 8 | QTEhMB8GCSqGSIb3DQEJARYSc3VwcG9ydEBzcGx1bmsuY29tMIGfMA0GCSqGSIb3 9 | DQEBAQUAA4GNADCBiQKBgQDJmb55yvam1GqGgTK0dfHXWJiB0Fh8fsdJFRc5dxBJ 10 | PFaC/klmtbLFLbYuXdC2Jh4cm/uhj1/FWmA0Wbhb02roAV03Z3SX0pHyFa3Udyqr 11 | 9f5ERJ0AYFA+y5UhbMnD9zlhs7J8ucub3XvA8rn79ejkYtDX2rMQWPNZYPcrxUEh 12 | iwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAKW37NFwTikJOMo9Z8cjmJDz9wa4yckB 13 | MlEA1/s6k6OmzZH0gkAssLstRkBavlr1uIBPZ2Jfse6FjoJ5ekC1AoXkInwmCspW 14 | GTVCoe8rwhU0xaj0GsC+wA3ykL+UKuXz6iE3oDcnLr0qxiNT2OxdTxz+EB9T0ynR 15 | x/F2KL1hdfCR 16 | -----END CERTIFICATE----- 17 | -------------------------------------------------------------------------------- /python/handlers/cacert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDejCCAmICCQCNHBN8tj/FwzANBgkqhkiG9w0BAQsFADB/MQswCQYDVQQGEwJV 3 | UzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xDzANBgNVBAoM 4 | BlNwbHVuazEXMBUGA1UEAwwOU3BsdW5rQ29tbW9uQ0ExITAfBgkqhkiG9w0BCQEW 5 | EnN1cHBvcnRAc3BsdW5rLmNvbTAeFw0xNzAxMzAyMDI2NTRaFw0yNzAxMjgyMDI2 6 | NTRaMH8xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEWMBQGA1UEBwwNU2FuIEZy 7 | YW5jaXNjbzEPMA0GA1UECgwGU3BsdW5rMRcwFQYDVQQDDA5TcGx1bmtDb21tb25D 8 | QTEhMB8GCSqGSIb3DQEJARYSc3VwcG9ydEBzcGx1bmsuY29tMIIBIjANBgkqhkiG 9 | 9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzB9ltVEGk73QvPlxXtA0qMW/SLDQlQMFJ/C/ 10 | tXRVJdQsmcW4WsaETteeWZh8AgozO1LqOa3I6UmrWLcv4LmUAh/T3iZWXzHLIqFN 11 | WLSVU+2g0Xkn43xSgQEPSvEK1NqZRZv1SWvx3+oGHgu03AZrqTj0HyLujqUDARFX 12 | sRvBPW/VfDkomHj9b8IuK3qOUwQtIOUr+oKx1tM1J7VNN5NflLw9NdHtlfblw0Ys 13 | 5xI5Qxu3rcCxkKQuwz9KRe4iijOIRMAKX28pbakxU9Nk38Ac3PNadgIk0s7R829k 14 | 980sqGWkd06+C17OxgjpQbvLOR20FtmQybttUsXGR7Bp07YStwIDAQABMA0GCSqG 15 | SIb3DQEBCwUAA4IBAQCxhQd6KXP2VzK2cwAqdK74bGwl5WnvsyqdPWkdANiKksr4 16 | ZybJZNfdfRso3fA2oK1R8i5Ca8LK3V/UuAsXvG6/ikJtWsJ9jf+eYLou8lS6NVJO 17 | xDN/gxPcHrhToGqi1wfPwDQrNVofZcuQNklcdgZ1+XVuotfTCOXHrRoNmZX+HgkY 18 | gEtPG+r1VwSFowfYqyFXQ5CUeRa3JB7/ObF15WfGUYplbd3wQz/M3PLNKLvz5a1z 19 | LMNXDwN5Pvyb2epyO8LPJu4dGTB4jOGpYLUjG1UUqJo9Oa6D99rv6sId+8qjERtl 20 | ZZc1oaC0PKSzBmq+TpbR27B8Zra3gpoA+gavdRZj 21 | -----END CERTIFICATE----- 22 | -------------------------------------------------------------------------------- /python/handlers/handler_debug.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2011-2015 Splunk, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"): you may 6 | # not use this file except in compliance with the License. You may obtain 7 | # a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | # License for the specific language governing permissions and limitations 15 | # under the License. 16 | 17 | """Example of a debug request handler that wraps the default request handler 18 | and prints debugging information to stdout.""" 19 | 20 | import os 21 | import sys 22 | from pprint import pprint 23 | 24 | sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "..", "lib")) 25 | from splunklib import binding 26 | from splunklib import client 27 | from python import utils 28 | 29 | 30 | def handler(): 31 | default = binding.handler() 32 | 33 | def request(url, message, **kwargs): 34 | response = default(url, message, **kwargs) 35 | print(f"{message['method']} {url} => {response['status']} ({response['reason']})") 36 | return response 37 | 38 | return request 39 | 40 | 41 | opts = utils.parse(sys.argv[1:], {}, ".env") 42 | service = client.connect(handler=handler(), **opts.kwargs) 43 | pprint([app.name for app in service.apps]) 44 | -------------------------------------------------------------------------------- /python/info.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2011-2015 Splunk, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"): you may 6 | # not use this file except in compliance with the License. You may obtain 7 | # a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | # License for the specific language governing permissions and limitations 15 | # under the License. 16 | 17 | """An example that prints Splunk service info & settings.""" 18 | 19 | import sys 20 | import os 21 | sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "lib")) 22 | 23 | from splunklib import client 24 | 25 | from utils import parse 26 | 27 | if __name__ == "__main__": 28 | opts = parse(sys.argv[1:], {}, ".env") 29 | service = client.connect(**opts.kwargs) 30 | 31 | content = service.info 32 | for key in sorted(content.keys()): 33 | value = content[key] 34 | if isinstance(value, list): 35 | print(f"{key}:") 36 | for item in value: 37 | print(f" {item}") 38 | else: 39 | print(f"{key}: {value}") 40 | 41 | print("Settings:") 42 | content = service.settings.content 43 | for key in sorted(content.keys()): 44 | value = content[key] 45 | print(f" {key}: {value}") 46 | -------------------------------------------------------------------------------- /python/inputs.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2011-2015 Splunk, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"): you may 6 | # not use this file except in compliance with the License. You may obtain 7 | # a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | # License for the specific language governing permissions and limitations 15 | # under the License. 16 | 17 | """A command line utility for interacting with Splunk inputs.""" 18 | 19 | import sys 20 | import os 21 | sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "lib")) 22 | 23 | from splunklib.client import connect 24 | 25 | from utils import parse 26 | 27 | 28 | def main(): 29 | opts = parse(sys.argv[1:], {}, ".env") 30 | service = connect(**opts.kwargs) 31 | 32 | for item in service.inputs: 33 | header = f"{item.name} ({item.kind})" 34 | print(header) 35 | print('=' * len(header)) 36 | content = item.content 37 | for key in sorted(content.keys()): 38 | value = content[key] 39 | print(f"{key}: {value}") 40 | print() 41 | 42 | 43 | if __name__ == "__main__": 44 | main() 45 | -------------------------------------------------------------------------------- /python/loggers.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2011-2015 Splunk, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"): you may 6 | # not use this file except in compliance with the License. You may obtain 7 | # a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | # License for the specific language governing permissions and limitations 15 | # under the License. 16 | 17 | """A command line tool lists out the Splunk logging categories and their 18 | current logging level.""" 19 | import sys 20 | import os 21 | sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "lib")) 22 | 23 | from splunklib import client 24 | 25 | from utils import parse 26 | 27 | 28 | def main(argv): 29 | usage = "usage: %prog [options]" 30 | opts = parse(argv, {}, ".env", usage=usage) 31 | service = client.connect(**opts.kwargs) 32 | 33 | for logger in service.loggers: 34 | print(f"{logger.name} ({logger['level']})") 35 | 36 | 37 | if __name__ == "__main__": 38 | main(sys.argv[1:]) 39 | -------------------------------------------------------------------------------- /python/oneshot.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2011-2015 Splunk, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"): you may 6 | # not use this file except in compliance with the License. You may obtain 7 | # a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | # License for the specific language governing permissions and limitations 15 | # under the License. 16 | 17 | """A command line utility for executing oneshot Splunk searches.""" 18 | import sys 19 | import os 20 | sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "lib")) 21 | 22 | from pprint import pprint 23 | import socket 24 | 25 | from splunklib.client import connect 26 | from splunklib.results import JSONResultsReader 27 | 28 | import utils 29 | 30 | 31 | def pretty(response): 32 | reader = JSONResultsReader(response) 33 | for result in reader: 34 | if isinstance(result, dict): 35 | pprint(result) 36 | 37 | 38 | def main(): 39 | usage = "usage: oneshot.py " 40 | opts = utils.parse(sys.argv[1:], {}, ".env", usage=usage) 41 | if len(opts.args) != 1: 42 | utils.error("Search expression required", 2) 43 | 44 | search = opts.args[0] 45 | service = connect(**opts.kwargs) 46 | socket.setdefaulttimeout(None) 47 | response = service.jobs.oneshot(search, output_mode="json") 48 | 49 | pretty(response) 50 | 51 | 52 | if __name__ == "__main__": 53 | main() 54 | -------------------------------------------------------------------------------- /python/results.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2011-2015 Splunk, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"): you may 6 | # not use this file except in compliance with the License. You may obtain 7 | # a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | # License for the specific language governing permissions and limitations 15 | # under the License. 16 | 17 | """A script that reads XML search results from stdin and pretty-prints them 18 | back to stdout. The script is designed to be used with the search.py 19 | example, eg: './search.py "search 404" | ./results.py'""" 20 | import sys 21 | import os 22 | sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "lib")) 23 | 24 | from pprint import pprint 25 | 26 | from splunklib import results 27 | 28 | 29 | def pretty(): 30 | reader = results.ResultsReader(sys.stdin) 31 | for event in reader: 32 | pprint(event) 33 | 34 | 35 | if __name__ == "__main__": 36 | pretty() 37 | -------------------------------------------------------------------------------- /python/saved_searches.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2011-2015 Splunk, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"): you may 6 | # not use this file except in compliance with the License. You may obtain 7 | # a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | # License for the specific language governing permissions and limitations 15 | # under the License. 16 | 17 | """A command line utility that lists saved searches.""" 18 | import sys 19 | import os 20 | sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "lib")) 21 | 22 | from splunklib.client import connect 23 | 24 | from utils import parse 25 | 26 | 27 | def main(): 28 | opts = parse(sys.argv[1:], {}, ".env") 29 | service = connect(**opts.kwargs) 30 | 31 | for saved_search in service.saved_searches: 32 | header = saved_search.name 33 | print(header) 34 | print('=' * len(header)) 35 | content = saved_search.content 36 | for key in sorted(content.keys()): 37 | value = content[key] 38 | print(f"{key}: {value}") 39 | history = saved_search.history() 40 | if len(history) > 0: 41 | print("history:") 42 | for job in history: 43 | print(f" {job.name}") 44 | print() 45 | 46 | 47 | if __name__ == "__main__": 48 | main() 49 | -------------------------------------------------------------------------------- /python/search_modes.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "lib")) 4 | 5 | import time 6 | from utils import * 7 | from splunklib.client import connect 8 | from splunklib import results 9 | 10 | 11 | def cmdline(argv, flags, **kwargs): 12 | """A cmdopts wrapper that takes a list of flags and builds the 13 | corresponding cmdopts rules to match those flags.""" 14 | rules = {flag: {'flags': [f"--{flag}"]} for flag in flags} 15 | return parse(argv, rules, ".env", **kwargs) 16 | 17 | 18 | def modes(argv): 19 | opts = cmdline(argv, []) 20 | kwargs_splunk = dslice(opts.kwargs, FLAGS_SPLUNK) 21 | service = connect(**kwargs_splunk) 22 | 23 | # By default the job will run in 'smart' mode which will omit events for transforming commands 24 | job = service.jobs.create('search index=_internal | head 10 | top host') 25 | while not job.is_ready(): 26 | time.sleep(0.5) 27 | 28 | reader = results.JSONResultsReader(job.events(output_mode="json")) 29 | # Events found: 0 30 | print(f'Events found with adhoc_search_level="smart": {len(list(reader))}') 31 | 32 | # Now set the adhoc_search_level to 'verbose' to see the events 33 | job = service.jobs.create('search index=_internal | head 10 | top host', adhoc_search_level='verbose') 34 | while not job.is_ready(): 35 | time.sleep(0.5) 36 | 37 | reader = results.JSONResultsReader(job.events(output_mode="json")) 38 | # Events found: 10 39 | print(f'Events found with adhoc_search_level="verbose": {len(list(reader))}') 40 | 41 | 42 | if __name__ == "__main__": 43 | modes(sys.argv[1:]) 44 | -------------------------------------------------------------------------------- /python/spurl.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2011-2015 Splunk, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"): you may 6 | # not use this file except in compliance with the License. You may obtain 7 | # a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | # License for the specific language governing permissions and limitations 15 | # under the License. 16 | 17 | """A simple command line interface for the Splunk REST APIs.""" 18 | import sys 19 | import os 20 | sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "lib")) 21 | print(sys.path) 22 | from xml.etree import ElementTree 23 | 24 | from splunklib import binding 25 | 26 | import utils 27 | 28 | 29 | # Invoke the url using the given opts parameters 30 | def invoke(path, **kwargs): 31 | method = kwargs.get("method", "GET") 32 | return binding.connect(**kwargs).request(path, method=method) 33 | 34 | 35 | def print_response(response): 36 | if response.status != 200: 37 | print(f"{response.status} {response.reason}") 38 | return 39 | body = response.body.read() 40 | try: 41 | root = ElementTree.XML(body) 42 | print(ElementTree.tostring(root)) 43 | except Exception: 44 | print(body) 45 | 46 | 47 | def main(): 48 | opts = utils.parse(sys.argv[1:], {}, ".env") 49 | for arg in opts.args: 50 | print_response(invoke(arg, **opts.kwargs)) 51 | 52 | 53 | if __name__ == "__main__": 54 | main() 55 | -------------------------------------------------------------------------------- /python/tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | envlist = clean,docs,py39,313 3 | skipsdist = {env:TOXBUILD:true} 4 | 5 | [testenv:pep8] 6 | deps = flake8 7 | flake8-import-order 8 | flake8-blind-except 9 | flake8-builtins 10 | flake8-docstrings 11 | flake8-rst-docstrings 12 | flake8-logging-format 13 | six 14 | commands = flake8 15 | 16 | [flake8] 17 | exclude = .tox 18 | # If you need to ignore some error codes in the whole source code 19 | # you can write them here 20 | # ignore = D100,D101 21 | show-source = true 22 | enable-extensions=G 23 | 24 | [testenv] 25 | passenv = LANG 26 | setenv = SPLUNK_HOME=/opt/splunk 27 | INPUT_EXAMPLE_UPLOAD=/opt/splunk/var/log/splunk/splunkd_ui_access.log 28 | allowlist_externals = make 29 | deps = pytest 30 | pytest-cov 31 | python-dotenv 32 | analytics 33 | splunk-sdk 34 | deprecation 35 | 36 | distdir = build 37 | commands = 38 | {env:TOXBUILD:python -m pytest --junitxml=test-reports/junit-{envname}.xml --cov --cov-config=.coveragerc} {posargs} 39 | 40 | [testenv:clean] 41 | deps = coverage 42 | skip_install = true 43 | commands = coverage erase 44 | 45 | [testenv:docs] 46 | description = invoke sphinx-build to build the HTML docs 47 | basepython = python3.7 48 | deps = sphinx >= 1.7.5, < 2 49 | commands = make -C docs/ html -------------------------------------------------------------------------------- /python/twitted/twitted/README.md: -------------------------------------------------------------------------------- 1 | splunk-sdk-python twitted example 2 | ======================================== 3 | 4 | This app provides an example of Reporting Custom search commands. 5 | 1. `hashtags` will list out all the hashtags from the tweets 6 | 2. `tophashtags` will list out top _**n**_ hashtags where _**n**_ is passed as an option. _(i.e. top=5)_ 7 | 8 | ### To run this example locally, follow the below steps. 9 | 10 | ### Step 1 11 | Execute the following command from the root of this repository. 12 | ```shell 13 | make up 14 | ``` 15 | 16 | ### Step 2 17 | 18 | Make sure the Splunk is in `healthy` state., run: 19 | ```shell 20 | docker ps 21 | ``` 22 | 23 | Log in into the Splunk UI, Go to http://localhost:8000/en-US/app/twitted/search page and run the following search queries: 24 | 25 | Results: 26 | 27 | ```shell 28 | index="twitter" | hashtags 29 | ``` 30 | 31 | ```shell 32 | index="twitter" | tophashtags top=10 33 | ``` 34 | -------------------------------------------------------------------------------- /python/twitted/twitted/default/app.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Splunk app configuration file 3 | # 4 | 5 | [install] 6 | is_configured = 0 7 | 8 | [ui] 9 | is_visible = 1 10 | label = Twitted Hashtag V2 CSC 11 | 12 | [launcher] 13 | description = Fetch the hashtags from tweets 14 | version = 1.0.0 15 | 16 | -------------------------------------------------------------------------------- /python/twitted/twitted/default/commands.conf: -------------------------------------------------------------------------------- 1 | [hashtags] 2 | filename = hashtags.py 3 | chunked = false 4 | streaming = false 5 | maxinputs = 0 6 | run_in_preview = false 7 | enableheader = true 8 | outputheader = true 9 | requires_srinfo = true 10 | supports_getinfo = true 11 | supports_multivalues = false 12 | 13 | [tophashtags] 14 | filename = tophashtags.py 15 | chunked = false 16 | streaming = false 17 | maxinputs = 0 18 | run_in_preview = false 19 | enableheader = true 20 | outputheader = true 21 | requires_srinfo = true 22 | supports_getinfo = true 23 | supports_multivalues = false -------------------------------------------------------------------------------- /python/twitted/twitted/metadata/default.meta: -------------------------------------------------------------------------------- 1 | 2 | # Application-level permissions 3 | 4 | [] 5 | access = read : [ * ], write : [ admin, power ] 6 | 7 | ### EVENT TYPES 8 | 9 | [eventtypes] 10 | export = system 11 | 12 | 13 | ### PROPS 14 | 15 | [props] 16 | export = system 17 | 18 | 19 | ### TRANSFORMS 20 | 21 | [transforms] 22 | export = system 23 | 24 | 25 | ### LOOKUPS 26 | 27 | [lookups] 28 | export = system 29 | 30 | 31 | ### VIEWSTATES: even normal users should be able to create shared viewstates 32 | 33 | [viewstates] 34 | access = read : [ * ], write : [ * ] 35 | export = system 36 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | requests 2 | splunk-sdk 3 | python-dotenv 4 | -------------------------------------------------------------------------------- /setup_pages/SUIT-setup-page-example/.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # http://editorconfig.org 4 | 5 | root = true 6 | 7 | [*] 8 | 9 | # Change these settings to your own preference 10 | indent_style = space 11 | indent_size = 4 12 | 13 | # We recommend you to keep these unchanged 14 | end_of_line = lf 15 | charset = utf-8 16 | trim_trailing_whitespace = true 17 | insert_final_newline = true 18 | 19 | [*.md] 20 | trim_trailing_whitespace = false 21 | 22 | [*.json] 23 | indent_size = 2 24 | -------------------------------------------------------------------------------- /setup_pages/SUIT-setup-page-example/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea/ 3 | lerna-debug.log 4 | node_modules 5 | npm-debug.log 6 | test-reports 7 | coverage_report 8 | yarn-error.log 9 | licenses.json 10 | functional-temp 11 | splunktional-temp 12 | -------------------------------------------------------------------------------- /setup_pages/SUIT-setup-page-example/.prettierrc: -------------------------------------------------------------------------------- 1 | printWidth: 100 2 | singleQuote: true 3 | tabWidth: 4 4 | overrides: 5 | - files: "*.json" 6 | options: 7 | tabWidth: 2 8 | -------------------------------------------------------------------------------- /setup_pages/SUIT-setup-page-example/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | babelrcRoots: ['./packages/*'], 3 | }; 4 | -------------------------------------------------------------------------------- /setup_pages/SUIT-setup-page-example/lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "lerna": "2.0.0", 3 | "commands": { 4 | "publish": { 5 | "ignore": ["*.md"] 6 | } 7 | }, 8 | "npmClient": "yarn", 9 | "useWorkspaces": true 10 | } 11 | -------------------------------------------------------------------------------- /setup_pages/SUIT-setup-page-example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@splunk/setup-example", 3 | "license": "UNLICENSED", 4 | "private": true, 5 | "scripts": { 6 | "build": "lerna run build", 7 | "format": "git ls-files | grep -E \"\\.(jsx?|css)$\" | xargs prettier --write", 8 | "format:verify": "git ls-files | grep -E \"\\.(jsx?|css)$\" | xargs prettier --list-different", 9 | "lint": "lerna run lint --no-sort", 10 | "setup": "yarn && lerna run build", 11 | "start": "lerna run start --stream --no-sort --concurrency 100", 12 | "test": "lerna run test --stream --no-sort" 13 | }, 14 | "devDependencies": { 15 | "lerna": "^2.9.0", 16 | "prettier": "^2.0.5" 17 | }, 18 | "workspaces": [ 19 | "packages/*" 20 | ], 21 | "engines": { 22 | "node": ">=8" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /setup_pages/SUIT-setup-page-example/packages/setup-component/.babelrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['@splunk/babel-preset'], 3 | }; 4 | -------------------------------------------------------------------------------- /setup_pages/SUIT-setup-page-example/packages/setup-component/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: '@splunk/eslint-config/browser-prettier', 3 | }; 4 | -------------------------------------------------------------------------------- /setup_pages/SUIT-setup-page-example/packages/setup-component/.gitignore: -------------------------------------------------------------------------------- 1 | demo/splunk-app/appserver/static/pages 2 | 3 | /*.js 4 | !/.babelrc.js 5 | !/.eslintrc.js 6 | !/jest.config.js 7 | !/*.config.js 8 | -------------------------------------------------------------------------------- /setup_pages/SUIT-setup-page-example/packages/setup-component/.npmignore: -------------------------------------------------------------------------------- 1 | # Source code 2 | /src/ 3 | /test/ 4 | /demo/ 5 | 6 | # Tools 7 | /.babelrc* 8 | .eslintrc.* 9 | .eslintignore 10 | /stylelint.config.js 11 | .stylelintignore 12 | /webpack.config.js 13 | 14 | # Testing 15 | /coverage_report/ 16 | /functional.settings.js 17 | /functional.*.conf.js 18 | /functional-temp 19 | /splunktional.settings.js 20 | /splunktional.*.conf.js 21 | /splunktional-temp 22 | /test-reports/ 23 | /karma.conf.js 24 | /jest.config.js 25 | /webpack.test.config.js 26 | /*hooks.js 27 | /test-app 28 | 29 | # Misc 30 | /docs.manifest.json 31 | /docs 32 | /docs.gen* 33 | /.npmignore 34 | npm-debug.log 35 | yarn-error.log 36 | /licenses.json 37 | /*.tgz 38 | -------------------------------------------------------------------------------- /setup_pages/SUIT-setup-page-example/packages/setup-component/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | 0.0.1 – Release date: TBA 4 | ------- 5 | 6 | * Initial version 7 | -------------------------------------------------------------------------------- /setup_pages/SUIT-setup-page-example/packages/setup-component/README.md: -------------------------------------------------------------------------------- 1 | # SetupComponent 2 | 3 | Add all information required to get started with @splunk/setup-component here. 4 | -------------------------------------------------------------------------------- /setup_pages/SUIT-setup-page-example/packages/setup-component/demo/demo.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render } from 'react-dom'; 3 | 4 | import { SplunkThemeProvider } from '@splunk/themes'; 5 | import { defaultTheme, getThemeOptions } from '@splunk/splunk-utils/themes'; 6 | 7 | import SetupComponent from '../src/SetupComponent'; 8 | 9 | const themeProviderSettings = getThemeOptions(defaultTheme() || 'enterprise'); 10 | 11 | const containerEl = document.getElementById('main-component-container'); 12 | render( 13 | 14 | 15 | , 16 | containerEl 17 | ); 18 | -------------------------------------------------------------------------------- /setup_pages/SUIT-setup-page-example/packages/setup-component/demo/splunk-app/appserver/templates/demo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | SetupComponent Demo App 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 23 | 24 | <% 25 | page_path = "/static/app/setup-component/pages/" + page + ".js" 26 | %> 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /setup_pages/SUIT-setup-page-example/packages/setup-component/demo/splunk-app/default/app.conf: -------------------------------------------------------------------------------- 1 | [ui] 2 | is_visible = 1 3 | label = SetupComponent Demo App 4 | 5 | [launcher] 6 | author = Splunk 7 | description = SetupComponent Demo App 8 | version = 0.1.0 9 | 10 | [package] 11 | check_for_updates = 0 12 | 13 | [install] 14 | is_configured = 1 15 | build = 1 16 | -------------------------------------------------------------------------------- /setup_pages/SUIT-setup-page-example/packages/setup-component/demo/splunk-app/default/data/ui/nav/default.xml: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /setup_pages/SUIT-setup-page-example/packages/setup-component/demo/splunk-app/default/data/ui/views/demo.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /setup_pages/SUIT-setup-page-example/packages/setup-component/demo/standalone/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | SetupComponent 7 | 8 | 9 | 10 |
11 | 12 | 13 | -------------------------------------------------------------------------------- /setup_pages/SUIT-setup-page-example/packages/setup-component/demo/webpack.splunkapp.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const webpackMerge = require('webpack-merge'); 3 | const baseConfig = require('@splunk/webpack-configs/base.config').default; 4 | 5 | module.exports = webpackMerge(baseConfig, { 6 | entry: path.join(__dirname, 'demo'), 7 | output: { 8 | path: path.join(__dirname, 'splunk-app/appserver/static/pages/'), 9 | filename: 'demo.js', 10 | }, 11 | devtool: 'eval-source-map', 12 | }); 13 | -------------------------------------------------------------------------------- /setup_pages/SUIT-setup-page-example/packages/setup-component/demo/webpack.standalone.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 3 | const webpackMerge = require('webpack-merge'); 4 | const baseConfig = require('@splunk/webpack-configs/base.config').default; 5 | 6 | module.exports = webpackMerge(baseConfig, { 7 | entry: path.join(__dirname, 'demo'), 8 | plugins: [ 9 | new HtmlWebpackPlugin({ 10 | hash: true, 11 | template: path.join(__dirname, 'standalone/index.html'), 12 | }), 13 | ], 14 | devtool: 'eval-source-map', 15 | }); 16 | -------------------------------------------------------------------------------- /setup_pages/SUIT-setup-page-example/packages/setup-component/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | testMatch: ['**/*.unit.[jt]s?(x)'], 3 | }; 4 | -------------------------------------------------------------------------------- /setup_pages/SUIT-setup-page-example/packages/setup-component/src/SetupComponentStyles.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import { variables, mixins } from '@splunk/themes'; 3 | 4 | const StyledContainer = styled.div` 5 | ${mixins.reset('inline-block')}; 6 | font-size: ${variables.fontSizeLarge}; 7 | line-height: 200%; 8 | margin: ${variables.spacing} ${variables.spacingHalf}; 9 | padding: ${variables.spacing} calc(${variables.spacing} * 2); 10 | border-radius: ${variables.borderRadius}; 11 | box-shadow: ${variables.overlayShadow}; 12 | background-color: ${variables.backgroundColor}; 13 | `; 14 | 15 | const StyledGreeting = styled.div` 16 | font-weight: bold; 17 | color: ${variables.brandColor}; 18 | font-size: ${variables.fontSizeXXLarge}; 19 | `; 20 | 21 | export { StyledContainer, StyledGreeting }; 22 | -------------------------------------------------------------------------------- /setup_pages/SUIT-setup-page-example/packages/setup-component/src/tests/SetupComponent.unit.jsx: -------------------------------------------------------------------------------- 1 | /* eslint-env jest */ 2 | 3 | import React from 'react'; 4 | import { assert } from 'chai'; 5 | import Enzyme, { mount } from 'enzyme'; 6 | import EnzymeAdapterReact16 from 'enzyme-adapter-react-16'; 7 | import SetupComponent from '../SetupComponent'; 8 | 9 | // This sets up the enzyme adapter 10 | const adapter = new EnzymeAdapterReact16(); 11 | Enzyme.configure({ adapter }); 12 | 13 | describe('SetupComponent', () => { 14 | it('renders with default name', () => { 15 | const wrapper = mount(); 16 | assert.include(wrapper.text(), 'Hello, User!'); 17 | wrapper.unmount(); 18 | }); 19 | 20 | it('renders with custom name', () => { 21 | const wrapper = mount(); 22 | assert.include(wrapper.text(), 'Hello, World!'); 23 | wrapper.unmount(); 24 | }); 25 | 26 | it('increases the counter when button is clicked', () => { 27 | const wrapper = mount(); 28 | assert.equal(wrapper.state('counter'), 0); 29 | wrapper.find('button').simulate('click'); 30 | assert.equal(wrapper.state('counter'), 1); 31 | wrapper.unmount(); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /setup_pages/SUIT-setup-page-example/packages/setup-component/stylelint.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: '@splunk/stylelint-config', 3 | }; 4 | -------------------------------------------------------------------------------- /setup_pages/SUIT-setup-page-example/packages/setup-component/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const webpackMerge = require('webpack-merge'); 3 | const baseComponentConfig = require('@splunk/webpack-configs/component.config').default; 4 | 5 | module.exports = webpackMerge(baseComponentConfig, { 6 | entry: { 7 | SetupComponent: path.join(__dirname, 'src/SetupComponent.jsx'), 8 | }, 9 | output: { 10 | path: path.join(__dirname), 11 | }, 12 | }); 13 | -------------------------------------------------------------------------------- /setup_pages/SUIT-setup-page-example/packages/setup-example-app/.babelrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['@splunk/babel-preset'], 3 | }; 4 | -------------------------------------------------------------------------------- /setup_pages/SUIT-setup-page-example/packages/setup-example-app/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: '@splunk/eslint-config/browser-prettier', 3 | }; 4 | -------------------------------------------------------------------------------- /setup_pages/SUIT-setup-page-example/packages/setup-example-app/.gitignore: -------------------------------------------------------------------------------- 1 | stage/ 2 | -------------------------------------------------------------------------------- /setup_pages/SUIT-setup-page-example/packages/setup-example-app/.npmignore: -------------------------------------------------------------------------------- 1 | # Source code 2 | /src/ 3 | /test/ 4 | /demo/ 5 | 6 | # Tools 7 | /.babelrc* 8 | .eslintrc.* 9 | .eslintignore 10 | /stylelint.config.js 11 | .stylelintignore 12 | /webpack.config.js 13 | 14 | # Testing 15 | /coverage_report/ 16 | /functional.settings.js 17 | /functional.*.conf.js 18 | /functional-temp 19 | /splunktional.settings.js 20 | /splunktional.*.conf.js 21 | /splunktional-temp 22 | /test-reports/ 23 | /karma.conf.js 24 | /jest.config.js 25 | /webpack.test.config.js 26 | /*hooks.js 27 | /test-app 28 | 29 | # Misc 30 | /docs.manifest.json 31 | /docs 32 | /docs.gen* 33 | /.npmignore 34 | npm-debug.log 35 | yarn-error.log 36 | /licenses.json 37 | /*.tgz 38 | -------------------------------------------------------------------------------- /setup_pages/SUIT-setup-page-example/packages/setup-example-app/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | 0.0.1 – Release date: TBA 4 | ------- 5 | 6 | * Initial version 7 | -------------------------------------------------------------------------------- /setup_pages/SUIT-setup-page-example/packages/setup-example-app/README.md: -------------------------------------------------------------------------------- 1 | # SetupExampleApp 2 | 3 | Add all information required to get started with @splunk/setup-example-app here. 4 | -------------------------------------------------------------------------------- /setup_pages/SUIT-setup-page-example/packages/setup-example-app/src/main/resources/splunk/appserver/templates/start.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | SetupExampleApp Demo App 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 21 | 22 | <% 23 | page_path = "/static/app/setup-example-app/pages/" + page + ".js" 24 | %> 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /setup_pages/SUIT-setup-page-example/packages/setup-example-app/src/main/resources/splunk/default/app.conf: -------------------------------------------------------------------------------- 1 | [ui] 2 | is_visible = 1 3 | setup_view = start 4 | label = Splunk UI Setup Example 5 | 6 | [launcher] 7 | author = Splunk 8 | description = Splunk UI Setup Example 9 | version = 0.1.0 10 | 11 | [package] 12 | check_for_updates = 0 13 | 14 | [install] 15 | is_configured = 0 16 | build = 1 17 | -------------------------------------------------------------------------------- /setup_pages/SUIT-setup-page-example/packages/setup-example-app/src/main/resources/splunk/default/data/ui/nav/default.xml: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /setup_pages/SUIT-setup-page-example/packages/setup-example-app/src/main/resources/splunk/default/data/ui/views/start.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /setup_pages/SUIT-setup-page-example/packages/setup-example-app/src/main/webapp/pages/start/StartStyles.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import { variables, mixins } from '@splunk/themes'; 3 | 4 | const StyledContainer = styled.div` 5 | ${mixins.reset('inline')}; 6 | display: block; 7 | font-size: ${variables.fontSizeLarge}; 8 | line-height: 200%; 9 | margin: calc(${variables.spacing} * 2) calc(${variables.spacing} * 2); 10 | `; 11 | 12 | const StyledGreeting = styled.div` 13 | font-weight: bold; 14 | color: ${variables.infoColor}; 15 | font-size: ${variables.fontSizeXXLarge}; 16 | `; 17 | 18 | export { StyledContainer, StyledGreeting }; 19 | -------------------------------------------------------------------------------- /setup_pages/SUIT-setup-page-example/packages/setup-example-app/src/main/webapp/pages/start/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import layout from '@splunk/react-page'; 4 | import SetupComponent from '@splunk/setup-component'; 5 | import DependencyCheck from '@splunk/setup-component/src/DependencyCheck'; 6 | import { SplunkThemeProvider } from '@splunk/themes'; 7 | 8 | import { defaultTheme, getThemeOptions } from '@splunk/splunk-utils/themes'; 9 | 10 | import { StyledContainer } from './StartStyles'; 11 | 12 | const themeProviderSettings = getThemeOptions(defaultTheme() || 'enterprise'); 13 | 14 | layout( 15 | 16 | 17 | 18 | 19 | 20 | ); 21 | -------------------------------------------------------------------------------- /setup_pages/SUIT-setup-page-example/packages/setup-example-app/stylelint.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: '@splunk/stylelint-config', 3 | }; 4 | -------------------------------------------------------------------------------- /setup_pages/SUIT-setup-page-example/packages/setup-example-app/webpack.config.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | const CopyWebpackPlugin = require('copy-webpack-plugin'); 4 | const webpackMerge = require('webpack-merge'); 5 | const baseConfig = require('@splunk/webpack-configs/base.config').default; 6 | 7 | // Set up an entry config by iterating over the files in the pages directory. 8 | const entries = fs 9 | .readdirSync(path.join(__dirname, 'src/main/webapp/pages')) 10 | .filter((pageFile) => !/^\./.test(pageFile)) 11 | .reduce((accum, page) => { 12 | accum[page] = path.join(__dirname, 'src/main/webapp/pages', page); 13 | return accum; 14 | }, {}); 15 | 16 | module.exports = webpackMerge(baseConfig, { 17 | entry: entries, 18 | output: { 19 | path: path.join(__dirname, 'stage/appserver/static/pages/'), 20 | filename: '[name].js', 21 | }, 22 | plugins: [ 23 | new CopyWebpackPlugin([ 24 | { 25 | from: path.join(__dirname, 'src/main/resources/splunk'), 26 | to: path.join(__dirname, 'stage'), 27 | }, 28 | ]), 29 | ], 30 | devtool: 'eval-source-map', 31 | }); 32 | -------------------------------------------------------------------------------- /setup_pages/dependency_checking_app_example/appserver/static/javascript/setup_page.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var app_name = "dependency_checking_app_example"; 4 | 5 | // This is an undocumented Splunk solution for how to include javascript logic 6 | // from other files. 7 | // Declare a require.config() and proviade a dictionary that has a `paths` keys. 8 | // In the `paths` key provide another dictionary that declares custom classes. 9 | // Each key should be the class name, and the value the path to the javascript file 10 | // ../app//(no extension) 11 | // Then include those in the require method's array, and function. 12 | 13 | // Common gotchas: 14 | // 1) The path to the script autmatically appends .js, so don't include it 15 | // 2) This only provides supprt for JavaScript files, plain-text html files won't work 16 | // 3) The "../app" is required as a prefix and your app name is required to follow it 17 | // 4) After the app name, the path is provided as though it were from the 18 | // $SPLUNK_HOME/etc/apps/appserver/static/* directory 19 | 20 | require.config({ 21 | paths: { 22 | // $SPLUNK_HOME/etc/apps/SPLUNK_APP_NAME/appserver/static/javascript/views/setup_page_example 23 | myApp: "../app/" + app_name + "/javascript/views/app", 24 | // React v16.13.1 25 | react: "../app/" + app_name + "/javascript/vendor/react.production.min", 26 | ReactDOM: "../app/" + app_name + "/javascript/vendor/react-dom.production.min", 27 | }, 28 | scriptType: "module", 29 | }); 30 | 31 | require([ 32 | // Splunk Web Framework Provided files 33 | // Custom files 34 | "react", // this needs to be lowercase because ReactDOM refers to it as lowercase 35 | "ReactDOM", 36 | "myApp", 37 | ], function(react, ReactDOM, myApp) { 38 | ReactDOM.render(myApp, document.getElementById('main_container')); 39 | }); 40 | -------------------------------------------------------------------------------- /setup_pages/dependency_checking_app_example/appserver/static/javascript/views/app.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * This is an example using pure react, with no JSX 4 | * If you would like to use JSX, you will need to use Babel to transpile your code 5 | * from JSK to JS. You will also need to use a task runner/module bundler to 6 | * help build your app before it can be used in the browser. 7 | * Some task runners/module bundlers are : gulp, grunt, webpack, and Parcel 8 | */ 9 | 10 | import * as Setup from "./setup_page.js"; 11 | 12 | define(["react", "splunkjs/splunk"], function(react, splunk_js_sdk){ 13 | const e = react.createElement; 14 | 15 | class SetupPage extends react.Component { 16 | constructor(props) { 17 | super(props); 18 | 19 | this.state = { 20 | token: '' 21 | }; 22 | 23 | this.handleChange = this.handleChange.bind(this); 24 | this.handleSubmit = this.handleSubmit.bind(this); 25 | } 26 | 27 | handleChange(event) { 28 | this.setState({ ...this.state, [event.target.name]: event.target.value}) 29 | } 30 | 31 | async handleSubmit(event) { 32 | event.preventDefault(); 33 | 34 | await Setup.perform(splunk_js_sdk, this.state) 35 | } 36 | 37 | render() { 38 | return e("div", null, [ 39 | e("h2", null, "This app requires you to configure the weather-app-example version 1.0 or above in order to complete the setup process. If this dependency requirement is satisfied, then app setup completes and you are directed to the app home page. If this dependency requirement is not satisfied, then you are prompted to configure or upgrade the weather-app-example."), 40 | e("div", null, [ 41 | e("form", { onSubmit: this.handleSubmit }, [ 42 | e("input", { type: "submit", value: "Check dependencies and complete setup." }) 43 | ]) 44 | ]) 45 | ]); 46 | } 47 | } 48 | 49 | return e(SetupPage); 50 | }); 51 | -------------------------------------------------------------------------------- /setup_pages/dependency_checking_app_example/appserver/static/javascript/views/setup_configuration.js: -------------------------------------------------------------------------------- 1 | import { promisify } from './util.js' 2 | import * as SplunkHelpers from './splunk_helpers.js' 3 | 4 | async function complete_setup(splunk_js_sdk_service) { 5 | var configuration_file_name = "app"; 6 | var stanza_name = "install"; 7 | var properties_to_update = { 8 | is_configured: "true", 9 | }; 10 | 11 | await SplunkHelpers.update_configuration_file( 12 | splunk_js_sdk_service, 13 | configuration_file_name, 14 | stanza_name, 15 | properties_to_update, 16 | ); 17 | }; 18 | 19 | async function list_apps( 20 | splunk_js_sdk_service, 21 | ) { 22 | var splunk_js_sdk_apps = splunk_js_sdk_service.apps(); 23 | return await promisify(splunk_js_sdk_apps.fetch)(); 24 | }; 25 | 26 | async function reload_splunk_app( 27 | splunk_js_sdk_service, 28 | app_name, 29 | ) { 30 | var splunk_js_sdk_apps = splunk_js_sdk_service.apps(); 31 | await promisify(splunk_js_sdk_apps.fetch)(); 32 | 33 | var current_app = splunk_js_sdk_apps.item(app_name); 34 | await promisify(current_app.reload)(); 35 | }; 36 | 37 | function redirect_to_splunk_app_homepage( 38 | app_name, 39 | ) { 40 | var redirect_url = "/app/" + app_name; 41 | 42 | window.location.href = redirect_url; 43 | }; 44 | 45 | 46 | function create_splunk_js_sdk_service( 47 | splunk_js_sdk, 48 | application_name_space, 49 | ) { 50 | var http = new splunk_js_sdk.SplunkWebHttp(); 51 | 52 | var splunk_js_sdk_service = new splunk_js_sdk.Service( 53 | http, 54 | application_name_space, 55 | ); 56 | 57 | return splunk_js_sdk_service; 58 | }; 59 | 60 | export { 61 | complete_setup, 62 | reload_splunk_app, 63 | redirect_to_splunk_app_homepage, 64 | create_splunk_js_sdk_service, 65 | list_apps, 66 | } 67 | -------------------------------------------------------------------------------- /setup_pages/dependency_checking_app_example/appserver/static/javascript/views/util.js: -------------------------------------------------------------------------------- 1 | function promisify(fn) { 2 | console.log("promisify: Don't use this in production! Use a proper promisify library instead.") 3 | 4 | // return a new promisified function 5 | return (...args) => { 6 | return new Promise((resolve, reject) => { 7 | // create a callback that resolves and rejects 8 | function callback(err, result) { 9 | if (err) { 10 | reject(err); 11 | } else { 12 | resolve(result); 13 | } 14 | } 15 | 16 | args.push(callback) 17 | 18 | // pass the callback into the function 19 | fn.call(this, ...args); 20 | }) 21 | } 22 | } 23 | 24 | export { 25 | promisify, 26 | } 27 | -------------------------------------------------------------------------------- /setup_pages/dependency_checking_app_example/default/app.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Splunk app configuration file 3 | # 4 | 5 | [install] 6 | is_configured = 0 7 | 8 | [package] 9 | id = dependency_checking_app_example 10 | 11 | [ui] 12 | is_visible = 1 13 | label = Dependency Checking App Example 14 | # Points to a file in: 15 | # $SPLUNK_HOME/etc/apps//default/data/ui/views/* 16 | # It does not need the extension of the file name provided 17 | setup_view = setup_page_dashboard 18 | 19 | [launcher] 20 | author = Logan Knecht, Amy Sutedja, Ulina Small and Shilpa Bijam 21 | description = This is an example Splunk App that demonstrates how to use a setup page that has dependencies to configure your Splunk App. This Splunk App adheres to Splunk's Application Certification Standards. 22 | version = 1.0.0 23 | -------------------------------------------------------------------------------- /setup_pages/dependency_checking_app_example/default/commands.conf: -------------------------------------------------------------------------------- 1 | [weather] 2 | filename = weather.py 3 | chunked = true 4 | python.version = python3 5 | -------------------------------------------------------------------------------- /setup_pages/dependency_checking_app_example/default/data/ui/nav/default.xml: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /setup_pages/dependency_checking_app_example/default/data/ui/views/setup_page_dashboard.xml: -------------------------------------------------------------------------------- 1 | 8 | 12 | 13 | 14 | 15 |
16 | 17 |
18 |
19 |
20 | -------------------------------------------------------------------------------- /setup_pages/dependency_checking_app_example/metadata/default.meta: -------------------------------------------------------------------------------- 1 | 2 | # Application-level permissions 3 | 4 | [] 5 | access = read : [ * ], write : [ admin, power ] 6 | 7 | ### EVENT TYPES 8 | 9 | [eventtypes] 10 | export = system 11 | 12 | 13 | ### PROPS 14 | 15 | [props] 16 | export = system 17 | 18 | 19 | ### TRANSFORMS 20 | 21 | [transforms] 22 | export = system 23 | 24 | 25 | ### LOOKUPS 26 | 27 | [lookups] 28 | export = system 29 | 30 | 31 | ### VIEWSTATES: even normal users should be able to create shared viewstates 32 | 33 | [viewstates] 34 | access = read : [ * ], write : [ * ] 35 | export = system 36 | 37 | 38 | ################################################################################ 39 | # Custom generated by Splunk 40 | ################################################################################ 41 | [app/ui] 42 | version = 6.6.2 43 | modtime = 1502229741.512085000 44 | 45 | [app/launcher] 46 | version = 6.6.2 47 | modtime = 1502229741.514537000 48 | -------------------------------------------------------------------------------- /setup_pages/dependency_checking_app_example/static/appIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/setup_pages/dependency_checking_app_example/static/appIcon.png -------------------------------------------------------------------------------- /setup_pages/dependency_checking_app_example/static/appIcon_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/setup_pages/dependency_checking_app_example/static/appIcon_2x.png -------------------------------------------------------------------------------- /setup_pages/developer_guidance_setup_page/appserver/static/javascript/setup_page.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var app_name = "./developer_guidance_setup_page"; 4 | 5 | // This is an undocumented Splunk solution for how to include javascript logic 6 | // from other files. 7 | // Declare a require.config() and proviade a dictionary that has a `paths` keys. 8 | // In the `paths` key provide another dictionary that declares custom classes. 9 | // Each key should be the class name, and the value the path to the javascript file 10 | // ../app//(no extension) 11 | // Then include those in the require method's array, and function. 12 | 13 | // Common gotchas: 14 | // 1) The path to the script autmatically appends .js, so don't include it 15 | // 2) This only provides supprt for JavaScript files, plain-text html files won't work 16 | // 3) The "../app" is required as a prefix and your app name is required to follow it 17 | // 4) After the app name, the path is provided as though it were from the 18 | // $SPLUK_HOME/etc/apps/appserver/static/* directory 19 | require.config({ 20 | paths: { 21 | // $SPLUNK_HOME/etc/apps/SPLUNK_APP_NAME/appserver/static/javascript/views/setup_page_example 22 | SetupPageExample: "../app/" + app_name + "/javascript/views/setup_page_example", 23 | }, 24 | scriptType: "module", 25 | }); 26 | 27 | require([ 28 | // Splunk Web Framework Provided files 29 | "backbone", // From the SplunkJS stack 30 | "jquery", // From the SplunkJS stack 31 | // Custom files 32 | "SetupPageExample", 33 | ], function(Backbone, jquery, SetupPageExample) { 34 | var example_setup_page = new SetupPageExample({ 35 | // Sets the element that will be used for rendering 36 | el: jquery("#main_container"), 37 | }); 38 | 39 | example_setup_page.render(); 40 | }); 41 | -------------------------------------------------------------------------------- /setup_pages/developer_guidance_setup_page/default/app.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Splunk app configuration file 3 | # 4 | 5 | [install] 6 | is_configured = 0 7 | 8 | [package] 9 | id = developer_guidance_setup_page 10 | 11 | [ui] 12 | is_visible = 1 13 | label = Developer Guidance - Setup Page 14 | # Points to a file in: 15 | # $SPLUNK_HOME/etc/apps//default/data/ui/views/* 16 | # It does not need the extension of the file name provided 17 | setup_view = setup_page_dashboard 18 | 19 | [launcher] 20 | author = Logan Knecht 21 | description = This is an example Splunk App that demonstrates how to use a setup page to configure your Splunk App. This Splunk App adheres to Splunk's Application Certification Standards. 22 | version = 1.0.0 23 | -------------------------------------------------------------------------------- /setup_pages/developer_guidance_setup_page/default/data/ui/nav/default.xml: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /setup_pages/developer_guidance_setup_page/default/data/ui/views/setup_page_dashboard.xml: -------------------------------------------------------------------------------- 1 | 8 | 11 | 12 | 13 | 14 |
15 | 16 |
17 |
18 |
19 | -------------------------------------------------------------------------------- /setup_pages/developer_guidance_setup_page/metadata/default.meta: -------------------------------------------------------------------------------- 1 | 2 | # Application-level permissions 3 | 4 | [] 5 | access = read : [ * ], write : [ admin, power ] 6 | 7 | ### EVENT TYPES 8 | 9 | [eventtypes] 10 | export = system 11 | 12 | 13 | ### PROPS 14 | 15 | [props] 16 | export = system 17 | 18 | 19 | ### TRANSFORMS 20 | 21 | [transforms] 22 | export = system 23 | 24 | 25 | ### LOOKUPS 26 | 27 | [lookups] 28 | export = system 29 | 30 | 31 | ### VIEWSTATES: even normal users should be able to create shared viewstates 32 | 33 | [viewstates] 34 | access = read : [ * ], write : [ * ] 35 | export = system 36 | 37 | 38 | ################################################################################ 39 | # Custom generated by Splunk 40 | ################################################################################ 41 | [app/ui] 42 | version = 6.6.2 43 | modtime = 1502229741.512085000 44 | 45 | [app/launcher] 46 | version = 6.6.2 47 | modtime = 1502229741.514537000 48 | -------------------------------------------------------------------------------- /setup_pages/developer_guidance_setup_page/static/appIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/setup_pages/developer_guidance_setup_page/static/appIcon.png -------------------------------------------------------------------------------- /setup_pages/developer_guidance_setup_page/static/appIcon_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/setup_pages/developer_guidance_setup_page/static/appIcon_2x.png -------------------------------------------------------------------------------- /setup_pages/react_setup_page_example/appserver/static/javascript/setup_page.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var app_name = "./react_setup_page_example"; 4 | 5 | // This is an undocumented Splunk solution for how to include javascript logic 6 | // from other files. 7 | // Declare a require.config() and proviade a dictionary that has a `paths` keys. 8 | // In the `paths` key provide another dictionary that declares custom classes. 9 | // Each key should be the class name, and the value the path to the javascript file 10 | // ../app//(no extension) 11 | // Then include those in the require method's array, and function. 12 | 13 | // Common gotchas: 14 | // 1) The path to the script autmatically appends .js, so don't include it 15 | // 2) This only provides supprt for JavaScript files, plain-text html files won't work 16 | // 3) The "../app" is required as a prefix and your app name is required to follow it 17 | // 4) After the app name, the path is provided as though it were from the 18 | // $SPLUNK_HOME/etc/apps/appserver/static/* directory 19 | 20 | require.config({ 21 | paths: { 22 | // $SPLUNK_HOME/etc/apps/SPLUNK_APP_NAME/appserver/static/javascript/views/setup_page_example 23 | myApp: "../app/" + app_name + "/javascript/views/app", 24 | // React v16.13.1 25 | react: "../app/" + app_name + "/javascript/vendor/react.production.min", 26 | ReactDOM: "../app/" + app_name + "/javascript/vendor/react-dom.production.min", 27 | }, 28 | scriptType: "module", 29 | }); 30 | 31 | require([ 32 | // Splunk Web Framework Provided files 33 | // Custom files 34 | "react", // this needs to be lowercase because ReactDOM refers to it as lowercase 35 | "ReactDOM", 36 | "myApp", 37 | ], function(react, ReactDOM, myApp) { 38 | ReactDOM.render(myApp, document.getElementById('main_container')); 39 | }); 40 | -------------------------------------------------------------------------------- /setup_pages/react_setup_page_example/appserver/static/javascript/views/setup_page.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | import * as Splunk from './splunk_helpers.js' 4 | import * as Config from './setup_configuration.js' 5 | 6 | const MACROS_CONF = 'macros' 7 | 8 | export async function perform(splunk_js_sdk, setup_options) { 9 | var app_name = "react_setup_page_example"; 10 | 11 | var application_name_space = { 12 | owner: "nobody", 13 | app: app_name, 14 | sharing: "app", 15 | }; 16 | 17 | try { 18 | // Create the Splunk JS SDK Service object 19 | 20 | const splunk_js_sdk_service = Config.create_splunk_js_sdk_service( 21 | splunk_js_sdk, 22 | application_name_space, 23 | ); 24 | 25 | let { stanza, ...properties } = setup_options; 26 | 27 | // Get macros.conf and do stuff to it 28 | await Splunk.update_configuration_file( 29 | splunk_js_sdk_service, 30 | MACROS_CONF, 31 | stanza, 32 | properties 33 | ) 34 | 35 | // Completes the setup, by access the app.conf's [install] 36 | // stanza and then setting the `is_configured` to true 37 | await Config.complete_setup(splunk_js_sdk_service); 38 | 39 | // Reloads the splunk app so that splunk is aware of the 40 | // updates made to the file system 41 | await Config.reload_splunk_app(splunk_js_sdk_service, app_name); 42 | 43 | // Redirect to the Splunk App's home page 44 | Config.redirect_to_splunk_app_homepage(app_name); 45 | } catch (error) { 46 | // This could be better error catching. 47 | // Usually, error output that is ONLY relevant to the user 48 | // should be displayed. This will return output that the 49 | // user does not understand, causing them to be confused. 50 | alert('Error:' + error); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /setup_pages/react_setup_page_example/default/app.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Splunk app configuration file 3 | # 4 | 5 | [install] 6 | is_configured = 0 7 | 8 | [package] 9 | id = react_setup_page_example 10 | 11 | [ui] 12 | is_visible = 1 13 | label = React Example - Setup Page 14 | # Points to a file in: 15 | # $SPLUNK_HOME/etc/apps//default/data/ui/views/* 16 | # It does not need the extension of the file name provided 17 | setup_view = setup_page_dashboard 18 | 19 | [launcher] 20 | author = Logan Knecht, Amy Sutedja, and Ulina Small 21 | description = This is an example Splunk App that demonstrates how to use a setup page to configure your Splunk App. This Splunk App adheres to Splunk's Application Certification Standards. 22 | version = 1.0.0 23 | -------------------------------------------------------------------------------- /setup_pages/react_setup_page_example/default/data/ui/nav/default.xml: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /setup_pages/react_setup_page_example/default/data/ui/views/setup_page_dashboard.xml: -------------------------------------------------------------------------------- 1 | 8 | 11 | 12 | 13 | 14 |
15 | 16 |
17 |
18 |
-------------------------------------------------------------------------------- /setup_pages/react_setup_page_example/metadata/default.meta: -------------------------------------------------------------------------------- 1 | 2 | # Application-level permissions 3 | 4 | [] 5 | access = read : [ * ], write : [ admin, power ] 6 | 7 | ### EVENT TYPES 8 | 9 | [eventtypes] 10 | export = system 11 | 12 | 13 | ### PROPS 14 | 15 | [props] 16 | export = system 17 | 18 | 19 | ### TRANSFORMS 20 | 21 | [transforms] 22 | export = system 23 | 24 | 25 | ### LOOKUPS 26 | 27 | [lookups] 28 | export = system 29 | 30 | 31 | ### VIEWSTATES: even normal users should be able to create shared viewstates 32 | 33 | [viewstates] 34 | access = read : [ * ], write : [ * ] 35 | export = system 36 | 37 | 38 | ################################################################################ 39 | # Custom generated by Splunk 40 | ################################################################################ 41 | [app/ui] 42 | version = 6.6.2 43 | modtime = 1502229741.512085000 44 | 45 | [app/launcher] 46 | version = 6.6.2 47 | modtime = 1502229741.514537000 48 | -------------------------------------------------------------------------------- /setup_pages/react_setup_page_example/static/appIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/setup_pages/react_setup_page_example/static/appIcon.png -------------------------------------------------------------------------------- /setup_pages/react_setup_page_example/static/appIcon_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/setup_pages/react_setup_page_example/static/appIcon_2x.png -------------------------------------------------------------------------------- /setup_pages/setup_page_simple/appserver/static/styles/setup_page.css: -------------------------------------------------------------------------------- 1 | #main_container { 2 | padding: 10px; 3 | } 4 | 5 | input { 6 | margin-left: 20px; 7 | } 8 | 9 | #setup_button { 10 | margin-top: 15px; 11 | } 12 | 13 | .success { 14 | margin-top: 15px; 15 | color: green; 16 | display: none; 17 | } 18 | 19 | .error { 20 | margin-top: 15px; 21 | color: darkred; 22 | display: none; 23 | } 24 | 25 | #error_details { 26 | margin-top: 15px; 27 | display: none; 28 | } -------------------------------------------------------------------------------- /setup_pages/setup_page_simple/default/app.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Splunk app configuration file 3 | # 4 | 5 | [install] 6 | is_configured = 0 7 | 8 | [package] 9 | id = setup_page_simple 10 | 11 | [ui] 12 | is_visible = 1 13 | label = Simple Setup Page 14 | # Points to a file in: 15 | # $SPLUNK_HOME/etc/apps//default/data/ui/views/* 16 | # It does not need the extension of the file name provided 17 | setup_view = setup_page_dashboard 18 | 19 | [launcher] 20 | author = Tim Pavlik 21 | description = This is a simplified example Splunk App that demonstrates how to use a setup page to configure your Splunk App and store a credential with storage/passwords. 22 | version = 1.0.0 23 | -------------------------------------------------------------------------------- /setup_pages/setup_page_simple/default/data/ui/views/setup_page_dashboard.xml: -------------------------------------------------------------------------------- 1 | 8 | 13 | 14 | 15 | 16 |
17 |

Simple Setup Page

18 |
19 |
20 | Enter password: 21 | 22 |
23 | 25 | 26 |
Password saved successfully, redirecting to app...
27 |
Issue encountered during setup, details below:
28 | 29 |
30 |
31 | 32 |
33 |
34 |
35 | -------------------------------------------------------------------------------- /setup_pages/setup_page_simple/static/appIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/setup_pages/setup_page_simple/static/appIcon.png -------------------------------------------------------------------------------- /setup_pages/setup_page_simple/static/appIcon_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/setup_pages/setup_page_simple/static/appIcon_2x.png -------------------------------------------------------------------------------- /setup_pages/weather_app_example/appserver/static/javascript/setup_page.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var app_name = "./weather_app_example"; 4 | 5 | // This is an undocumented Splunk solution for how to include javascript logic 6 | // from other files. 7 | // Declare a require.config() and proviade a dictionary that has a `paths` keys. 8 | // In the `paths` key provide another dictionary that declares custom classes. 9 | // Each key should be the class name, and the value the path to the javascript file 10 | // ../app//(no extension) 11 | // Then include those in the require method's array, and function. 12 | 13 | // Common gotchas: 14 | // 1) The path to the script autmatically appends .js, so don't include it 15 | // 2) This only provides supprt for JavaScript files, plain-text html files won't work 16 | // 3) The "../app" is required as a prefix and your app name is required to follow it 17 | // 4) After the app name, the path is provided as though it were from the 18 | // $SPLUNK_HOME/etc/apps/appserver/static/* directory 19 | 20 | require.config({ 21 | paths: { 22 | // $SPLUNK_HOME/etc/apps/SPLUNK_APP_NAME/appserver/static/javascript/views/setup_page_example 23 | myApp: "../app/" + app_name + "/javascript/views/app", 24 | // React v16.13.1 25 | react: "../app/" + app_name + "/javascript/vendor/react.production.min", 26 | ReactDOM: "../app/" + app_name + "/javascript/vendor/react-dom.production.min", 27 | }, 28 | scriptType: "module", 29 | }); 30 | 31 | require([ 32 | // Splunk Web Framework Provided files 33 | // Custom files 34 | "react", // this needs to be lowercase because ReactDOM refers to it as lowercase 35 | "ReactDOM", 36 | "myApp", 37 | ], function(react, ReactDOM, myApp) { 38 | ReactDOM.render(myApp, document.getElementById('main_container')); 39 | }); 40 | -------------------------------------------------------------------------------- /setup_pages/weather_app_example/appserver/static/javascript/views/app.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * This is an example using pure react, with no JSX 4 | * If you would like to use JSX, you will need to use Babel to transpile your code 5 | * from JSK to JS. You will also need to use a task runner/module bundler to 6 | * help build your app before it can be used in the browser. 7 | * Some task runners/module bundlers are : gulp, grunt, webpack, and Parcel 8 | */ 9 | 10 | import * as Setup from "./setup_page.js"; 11 | 12 | define(["react", "splunkjs/splunk"], function(react, splunk_js_sdk){ 13 | const e = react.createElement; 14 | 15 | class SetupPage extends react.Component { 16 | constructor(props) { 17 | super(props); 18 | 19 | this.state = { 20 | token: '' 21 | }; 22 | 23 | this.handleChange = this.handleChange.bind(this); 24 | this.handleSubmit = this.handleSubmit.bind(this); 25 | } 26 | 27 | handleChange(event) { 28 | this.setState({ ...this.state, [event.target.name]: event.target.value}) 29 | } 30 | 31 | async handleSubmit(event) { 32 | event.preventDefault(); 33 | 34 | await Setup.perform(splunk_js_sdk, this.state) 35 | } 36 | 37 | render() { 38 | return e("div", null, [ 39 | e("h2", null, "Weather Setup Page"), 40 | e("div", null, [ 41 | e("form", { onSubmit: this.handleSubmit }, [ 42 | e("label", null, [ 43 | "Token", 44 | e("input", { type: "text", name: "token", value: this.state.token, onChange: this.handleChange }) 45 | ]), 46 | e("input", { type: "submit", value: "Submit" }) 47 | ]) 48 | ]) 49 | ]); 50 | } 51 | } 52 | 53 | return e(SetupPage); 54 | }); 55 | -------------------------------------------------------------------------------- /setup_pages/weather_app_example/appserver/static/javascript/views/setup_configuration.js: -------------------------------------------------------------------------------- 1 | import { promisify } from './util.js' 2 | import * as SplunkHelpers from './splunk_helpers.js' 3 | 4 | async function complete_setup(splunk_js_sdk_service) { 5 | var configuration_file_name = "app"; 6 | var stanza_name = "install"; 7 | var properties_to_update = { 8 | is_configured: "true", 9 | }; 10 | 11 | await SplunkHelpers.update_configuration_file( 12 | splunk_js_sdk_service, 13 | configuration_file_name, 14 | stanza_name, 15 | properties_to_update, 16 | ); 17 | }; 18 | 19 | async function reload_splunk_app( 20 | splunk_js_sdk_service, 21 | app_name, 22 | ) { 23 | var splunk_js_sdk_apps = splunk_js_sdk_service.apps(); 24 | await promisify(splunk_js_sdk_apps.fetch)(); 25 | 26 | var current_app = splunk_js_sdk_apps.item(app_name); 27 | await promisify(current_app.reload)(); 28 | }; 29 | 30 | function redirect_to_splunk_app_homepage( 31 | app_name, 32 | ) { 33 | var redirect_url = "/app/" + app_name; 34 | 35 | window.location.href = redirect_url; 36 | }; 37 | 38 | 39 | function create_splunk_js_sdk_service( 40 | splunk_js_sdk, 41 | application_name_space, 42 | ) { 43 | var http = new splunk_js_sdk.SplunkWebHttp(); 44 | 45 | var splunk_js_sdk_service = new splunk_js_sdk.Service( 46 | http, 47 | application_name_space, 48 | ); 49 | 50 | return splunk_js_sdk_service; 51 | }; 52 | 53 | export { 54 | complete_setup, 55 | reload_splunk_app, 56 | redirect_to_splunk_app_homepage, 57 | create_splunk_js_sdk_service, 58 | } 59 | -------------------------------------------------------------------------------- /setup_pages/weather_app_example/appserver/static/javascript/views/util.js: -------------------------------------------------------------------------------- 1 | function promisify(fn) { 2 | console.log("promisify: Don't use this in production! Use a proper promisify library instead.") 3 | 4 | // return a new promisified function 5 | return (...args) => { 6 | return new Promise((resolve, reject) => { 7 | // create a callback that resolves and rejects 8 | function callback(err, result) { 9 | if (err) { 10 | reject(err); 11 | } else { 12 | resolve(result); 13 | } 14 | } 15 | 16 | args.push(callback) 17 | 18 | // pass the callback into the function 19 | fn.call(this, ...args); 20 | }) 21 | } 22 | } 23 | 24 | export { 25 | promisify, 26 | } 27 | -------------------------------------------------------------------------------- /setup_pages/weather_app_example/default/app.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Splunk app configuration file 3 | # 4 | 5 | [install] 6 | is_configured = 0 7 | 8 | [package] 9 | id = weather_app_example 10 | 11 | [ui] 12 | is_visible = 1 13 | label = Weather Example - Setup Page 14 | # Points to a file in: 15 | # $SPLUNK_HOME/etc/apps//default/data/ui/views/* 16 | # It does not need the extension of the file name provided 17 | setup_view = setup_page_dashboard 18 | 19 | [launcher] 20 | author = Logan Knecht, Amy Sutedja, and Ulina Small 21 | description = This is an example Splunk App that demonstrates how to use a setup page to configure your Splunk App. This Splunk App adheres to Splunk's Application Certification Standards. 22 | version = 1.0.0 23 | -------------------------------------------------------------------------------- /setup_pages/weather_app_example/default/commands.conf: -------------------------------------------------------------------------------- 1 | [weather] 2 | filename = weather.py 3 | chunked = true 4 | python.version = python3 5 | -------------------------------------------------------------------------------- /setup_pages/weather_app_example/default/data/ui/nav/default.xml: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /setup_pages/weather_app_example/default/data/ui/views/setup_page_dashboard.xml: -------------------------------------------------------------------------------- 1 | 8 | 12 | 13 | 14 | 15 |
16 | 17 |
18 |
19 |
20 | -------------------------------------------------------------------------------- /setup_pages/weather_app_example/metadata/default.meta: -------------------------------------------------------------------------------- 1 | 2 | # Application-level permissions 3 | 4 | [] 5 | access = read : [ * ], write : [ admin, power ] 6 | 7 | ### EVENT TYPES 8 | 9 | [eventtypes] 10 | export = system 11 | 12 | 13 | ### PROPS 14 | 15 | [props] 16 | export = system 17 | 18 | 19 | ### TRANSFORMS 20 | 21 | [transforms] 22 | export = system 23 | 24 | 25 | ### LOOKUPS 26 | 27 | [lookups] 28 | export = system 29 | 30 | 31 | ### VIEWSTATES: even normal users should be able to create shared viewstates 32 | 33 | [viewstates] 34 | access = read : [ * ], write : [ * ] 35 | export = system 36 | 37 | ### PASSWORDS 38 | 39 | [passwords] 40 | export = system 41 | 42 | 43 | ################################################################################ 44 | # Custom generated by Splunk 45 | ################################################################################ 46 | [app/ui] 47 | version = 6.6.2 48 | modtime = 1502229741.512085000 49 | 50 | [app/launcher] 51 | version = 6.6.2 52 | modtime = 1502229741.514537000 53 | -------------------------------------------------------------------------------- /setup_pages/weather_app_example/static/appIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/setup_pages/weather_app_example/static/appIcon.png -------------------------------------------------------------------------------- /setup_pages/weather_app_example/static/appIcon_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/setup_pages/weather_app_example/static/appIcon_2x.png -------------------------------------------------------------------------------- /spl2-sample-apps/sample_spl2_buttercup/default/app.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Splunk app configuration file 3 | # 4 | 5 | [install] 6 | is_configured = 0 7 | 8 | [ui] 9 | is_visible = 1 10 | label = sample SPL2 buttercup games 11 | 12 | [launcher] 13 | author = admin 14 | description = A basic SPL2-based application. This app shows how to organize your app modules for customization and reuse, import and export resources, and export views. 15 | version = 1.0.0 16 | 17 | -------------------------------------------------------------------------------- /spl2-sample-apps/sample_spl2_buttercup/default/data/spl2/functions.spl2: -------------------------------------------------------------------------------- 1 | // FUNCTION MODULE FOR THE APP "sample_spl2_buttercup" 2 | 3 | // This function generates a string that identifies the ID and name for each product. 4 | // In SPL2, the concatenation operator is the plus ( + ) symbol. 5 | function prodnames ($pid: string, $product_name: string): string { 6 | return "The product ID "+$pid+" "+"corresponds to the "+$product_name+" "+"product." 7 | } 8 | 9 | // EXPORTS 10 | export prodnames -------------------------------------------------------------------------------- /spl2-sample-apps/sample_spl2_buttercup/default/data/spl2/sample_data.spl2: -------------------------------------------------------------------------------- 1 | // SAMPLE DATA FOR THE APP "sample_spl2_buttercup" 2 | 3 | // DATASET LITERAL 4 | // This sample uses a dataset literal as the dataset for some of the searches. 5 | $data = from 6 | [{_time: "2024/04/19 12:00", host: "www1", clientip: "192.0.2.0", method: "POST", action: "purchase", pid: "DC-SG-G02", status: "200", quantity: 1, price: 39.99}, 7 | {_time: "2024/04/19 11:58", host: "www4", clientip:"198.51.100.0", method: "GET", action: "addtochart", pid: "MB-AG-G07", status: "200", quantity: 3, price: 27.99}, 8 | {_time: "2024/04/19 11:58", host: "www3", clientip:"203.0.113.0", method: "POST", action: "purchase", pid: "WC-SH-A01", status: "200", quantity: 1, price: 25.99}, 9 | {_time: "2024/04/19 11:56", host: "www2", clientip:"198.51.100.255", method: "POST", action: "changequantity", pid: "PZ-SG-G05", status: "200", quantity: 2, price: 4.99}, 10 | {_time: "2024/04/19 11:51", host: "www1", clientip:"192.0.2.0", method: "POST", action: "purchase", pid: "SF-BVS-01", status: "404", quantity: 1, price: 49.99}, 11 | {_time: "2024/04/19 11:47", host: "www3", clientip:"198.51.100.0", method: "POST", action: "purchase", pid: "SF-BVS-G01", status: "200", quantity: 1, price: 26.99}, 12 | {_time: "2024/04/19 11:42", host: "www1", clientip:"192.0.2.0", method: "POST", action: "purchase", pid: "WC-SH-T02", status: "200", quantity: 2, price: 19.99}, 13 | {_time: "2024/04/19 11:39", host: "www1", clientip:"198.51.100.0", method: "POST", action: "purchase", pid: "PZ-SG-G05", status: "200", quantity: 1, price: 4.99}, 14 | {_time: "2024/04/19 11:31", host: "www2", clientip:"198.51.100.255", method: "GET", action: "view", pid: "MB-AG-G07", status: "200", quantity: 1, price: 27.99}, 15 | {_time: "2024/04/19 11:27", host: "www3", clientip:"203.0.113.0", method: "POST", action: "purchase", pid: "WC-SH-A01", status: "404", quantity: 1, price: 25.99}] 16 | 17 | // EXPORTS 18 | export $data -------------------------------------------------------------------------------- /spl2-sample-apps/sample_spl2_buttercup/default/data/spl2/setup.spl2: -------------------------------------------------------------------------------- 1 | // SETUP MODULE FOR THE APP "sample_spl2_buttercup" 2 | 3 | // IMPORTS 4 | import _internal from ../../../../indexes // AN INDEX 5 | 6 | // FUNCTION - ADMIN - Change the "$splunk_home" value to match your system 7 | // For the Beta, this value includes "SplunkNeta" to match the pre-reslease version 8 | // This function specifies a variable for $SPLUNK_HOME and returns events from the 9 | // internal "metric.log" file 10 | function get_metrics($splunk_home="/Applications/SplunkBeta"):dataset{ 11 | return | from _internal where source="${$splunk_home}/var/log/splunk/metrics.log" 12 | } 13 | // This search tests the "get_metrics" function, converts the "_time" field, 14 | // and returns specific fields from the log file 15 | $metrics = | get_metrics 16 | | eval time=strftime(_time,"%Y-%m-%d %H:%M:%S.%Q") // Converts _time from an internal field to a regular field 17 | | fields time, component, event_message, instantaneous_kbps 18 | 19 | // EXPORTS 20 | export get_metrics -------------------------------------------------------------------------------- /spl2-sample-apps/sample_spl2_buttercup/default/data/ui/nav/default.xml: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /spl2-sample-apps/sample_spl2_buttercup/default/transforms.conf: -------------------------------------------------------------------------------- 1 | [buttercup_products_lookup] 2 | batch_index_query = 0 3 | case_sensitive_match = 1 4 | filename = sample_products.csv 5 | 6 | [buttercup_suppliers_lookup] 7 | batch_index_query = 0 8 | case_sensitive_match = 1 9 | filename = sample_suppliers.csv 10 | -------------------------------------------------------------------------------- /spl2-sample-apps/sample_spl2_buttercup/lookups/sample_products.csv: -------------------------------------------------------------------------------- 1 | productID,product_name,supplierID,categoryID 2 | DB-SG-G01,Mediocre Kingdoms,MHG-USA,STRATEGY 3 | DC-SG-G02,Dream Crusher,PMG-KOR,STRATEGY 4 | FS-SG-G03,Final Sequel,A51G-USA,STRATEGY 5 | WC-SH-G04,World of Cheese,EG-GER,SHOOTER 6 | WC-SH-T02,World of Cheese Tee,EG-GER,TEE 7 | PZ-SG-G05,Puppies vs. Zombies,TF-JAP,STRATEGY 8 | CU-PG-G06,Curling 2014,BG-IRE,SPORTS 9 | MB-AG-G07,Manganiello Bros.,TF-JAP,ARCADE 10 | MB-AG-T01,Manganiello Bros. Tee,TF-JAP,TEE 11 | FI-AG-G08,Orvil the Wolverine,BG-IRE,ARCADE 12 | BS-AG-G09,Benign Space Debris,A51G-USA,ARCADE 13 | SC-MG-G10,SIM Cubicle,PMG-KOR,SIMULATION 14 | WC-SH-A01,Holy Blade of Gouda,EG-GER,ACCESSORIES 15 | WC-SH-A02,Fire Resistance Suit of Provolone,EG-GER,ACCESSORIES 16 | SF-BVS-G01,Grand Theft Scooter,IP-PAN,ARCADE 17 | SF-BVS-01,Pony Run,BG-IRE,STRATEGY 18 | 19 | -------------------------------------------------------------------------------- /spl2-sample-apps/sample_spl2_buttercup/lookups/sample_suppliers.csv: -------------------------------------------------------------------------------- 1 | supplierId,supplier_name,contact_name,email, address 2 | MHG-USA,Mile High Games,Nyah Aamadu,nyah@sample.com,123 Main St Denver CO United States 12345 3 | PMG-KOR,Play More Games,Vanya Patel,vanya@sample.com,234 Sejong-daero Sejongno Jongno-gu Seoul South Korea 4 | A51G-USA,Area 51 Games,Ikraam Rahat,ikraam@sample.com,456 Main St Rachel NM United States 23456 5 | EG-GER,Euro Games,David Mayer,david@sample.com,567 Pariser Platz 2 10117 Berlin Germany 6 | TF-JAP,Tiger Fun,Wei Zhang,wei@sample.com,678 Chome-10-5 Akasaka Minato City Tokyo 107-8420 Japan 7 | BG-IRE,Blarney Games,Rutherford Sullivan,rutherford@sample.com,789 Market St Sleveen Kinsale Co. Cork P17 E068 Ireland 8 | IP-PAN,Isthmus Pastimes,Celestino Paulo,celestino@sample.com, edificio 890 Avenida Demetrio Basilio Lakas Panama Panama -------------------------------------------------------------------------------- /spl2-sample-apps/sample_spl2_buttercup/metadata/default.meta: -------------------------------------------------------------------------------- 1 | [default] 2 | [] 3 | access = read : [ * ], write : [ admin, power ] 4 | 5 | [app/launcher] 6 | version = 9.2.02.20240415 7 | modtime = 1713851385.498681000 8 | 9 | [app/ui] 10 | version = 9.2.02.20240415 11 | modtime = 1713851385.497017000 12 | 13 | [eventtypes] 14 | export = system 15 | 16 | [lookups] 17 | export = system 18 | 19 | [props] 20 | export = system 21 | 22 | [transforms] 23 | export = system 24 | 25 | [transforms/buttercup_products_lookup] 26 | access = read : [ * ], write : [ admin, power ] 27 | export = none 28 | owner = admin 29 | version = 9.2.02.20240415 30 | modtime = 1713906119.283339000 31 | 32 | [transforms/buttercup_suppliers_lookup] 33 | access = read : [ * ], write : [ admin, power ] 34 | export = none 35 | owner = admin 36 | version = 9.2.02.20240415 37 | modtime = 1713906195.562876000 38 | 39 | [views/buttercup_games] 40 | access = read : [ * ], write : [ admin, power ] 41 | export = none 42 | owner = admin 43 | version = 9.2.2.20240415 44 | modtime = 1715189435.671056000 45 | 46 | [viewstates] 47 | access = read : [ * ], write : [ * ] 48 | export = system 49 | 50 | -------------------------------------------------------------------------------- /spl2-sample-apps/sample_spl2_pii_masking/default/app.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Splunk app configuration file 3 | # 4 | 5 | [install] 6 | is_configured = 0 7 | 8 | [ui] 9 | is_visible = 1 10 | label = sample SPL2 pii masking 11 | 12 | [launcher] 13 | author = admin 14 | description = This sample app shows how to use a function to mask Personally Identifiable Information (PII) or sensitive data, and generate a masked view for others to use. 15 | version = 1.0.0 16 | 17 | -------------------------------------------------------------------------------- /spl2-sample-apps/sample_spl2_pii_masking/default/data/spl2/_default.spl2: -------------------------------------------------------------------------------- 1 | // DEFAULT MODULE FOR THE APP "sample_spl2_pii_masking" 2 | 3 | // IMPORTS 4 | import data from sample_data // A DATASET LITERAL, WITH DATAA FROM Azure Active Directory. 5 | import masked_view from masking // A VIEW THAT CONTAINS THE MASKED DATA 6 | 7 | // SEARCHES 8 | // This search returns specific fields from a dataset literal 9 | // The results are shown in a table in the dashboard. 10 | $failed_logins_unmasked = from data where ResultStatus="failed" 11 | 12 | // This search returns specific fields from a dataset literal 13 | // The results are shown in a table in the dashboard. 14 | $failed_logins_masked = from masked_view where ResultStatus="failed" 15 | 16 | // EXPORTS 17 | // This line exports the searches as views 18 | export {$failed_logins_unmasked, $failed_logins_masked} 19 | // This line exports the masked_view 20 | export masked_view 21 | // This line exports the dataset used in this app 22 | export data -------------------------------------------------------------------------------- /spl2-sample-apps/sample_spl2_pii_masking/default/data/spl2/functions.spl2: -------------------------------------------------------------------------------- 1 | // FUNCTION MODULE FOR THE APP sample_spl2_pii_masking 2 | 3 | // This command function masks the values in the UserKey field 4 | function pii_mask($source: dataset, $start_delimiter: string="", $end_delimiter: string="", $field: any=UserKey): dataset { 5 | return 6 | | from $source 7 | | eval userkey_regex="(?P[[:alnum:]]+)@(?P\\w+)\\.(?P\\w+).com" 8 | | eval userkey_regex=$start_delimiter + userkey_regex + $end_delimiter 9 | | eval masked_userkey_str = "xxxx@xxxx.example.com" 10 | | eval masked_userkey_str=$start_delimiter + masked_userkey_str + $end_delimiter 11 | | eval $field=replace($field, userkey_regex, masked_userkey_str) 12 | | fields -userkey_regex,masked_userkey_str 13 | } 14 | 15 | // EXPORTS 16 | export pii_mask -------------------------------------------------------------------------------- /spl2-sample-apps/sample_spl2_pii_masking/default/data/spl2/masking.spl2: -------------------------------------------------------------------------------- 1 | //@run_as_owner 2 | 3 | // MASKING MODULE FOR THE APP sample_spl2_pii_masking 4 | 5 | // IMPORTS 6 | import data from sample_pii_data // A DATASET LITERAL 7 | import pii_mask from functions // A COMMAND FUNCTION THAT MASKS EMAIL ADDRESSES 8 | 9 | $masked_view = from data | pii_mask 10 | 11 | // EXPORTS 12 | export $masked_view 13 | export pii_mask -------------------------------------------------------------------------------- /spl2-sample-apps/sample_spl2_pii_masking/default/data/ui/nav/default.xml: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /spl2-sample-apps/sample_spl2_pii_masking/metadata/default.meta: -------------------------------------------------------------------------------- 1 | [default] 2 | [] 3 | access = read : [ * ], write : [ admin, power ] 4 | 5 | [app/launcher] 6 | version = 9.2.02.20240415 7 | modtime = 1713937802.229783000 8 | 9 | [app/ui] 10 | version = 9.2.02.20240415 11 | modtime = 1713937802.227981000 12 | 13 | [eventtypes] 14 | export = system 15 | 16 | [lookups] 17 | export = system 18 | 19 | [props] 20 | export = system 21 | 22 | [transforms] 23 | export = system 24 | 25 | [viewstates] 26 | access = read : [ * ], write : [ * ] 27 | export = system 28 | 29 | -------------------------------------------------------------------------------- /tutorials/Module-01_GetStarted/devtutorial/bin/README: -------------------------------------------------------------------------------- 1 | This is where you put any scripts you want to add to this app. 2 | -------------------------------------------------------------------------------- /tutorials/Module-01_GetStarted/devtutorial/default/app.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Splunk app configuration file 3 | # 4 | 5 | [install] 6 | is_configured = 0 7 | 8 | [ui] 9 | is_visible = 1 10 | label = Dev Tutorial 11 | 12 | [launcher] 13 | author = 14 | description = Dev tutorial app 15 | version = 1.0.0 16 | 17 | -------------------------------------------------------------------------------- /tutorials/Module-01_GetStarted/devtutorial/default/data/ui/nav/default.xml: -------------------------------------------------------------------------------- 1 | 17 | -------------------------------------------------------------------------------- /tutorials/Module-01_GetStarted/devtutorial/default/data/ui/views/welcome.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |

7 | Hello! You created this app using the 8 | Module 1: Get Started 9 | tutorial on the Splunk Developer Portal. 10 |

11 | 12 |
13 |
14 |
15 | -------------------------------------------------------------------------------- /tutorials/Module-01_GetStarted/devtutorial/default/savedsearches.conf: -------------------------------------------------------------------------------- 1 | [Movies By Rating] 2 | description = Example search by editing savedsearches.conf 3 | dispatch.earliest_time = 0 4 | search = index=devtutorial | stats count by RATING 5 | 6 | [Top Rental Rates] 7 | action.email.useNSSubject = 1 8 | alert.track = 0 9 | description = Example search using Splunk Web 10 | dispatch.earliest_time = 0 11 | display.general.type = statistics 12 | display.page.search.tab = statistics 13 | display.visualizations.show = 0 14 | request.ui_dispatch_app = devtutorial 15 | request.ui_dispatch_view = search 16 | search = index=devtutorial | top RENTAL_RATE 17 | 18 | [Top Replacement Costs] 19 | description = Example search using REST 20 | search = index=devtutorial | top limit=20 REPLACEMENT_COST 21 | -------------------------------------------------------------------------------- /tutorials/Module-01_GetStarted/devtutorial/metadata/default.meta: -------------------------------------------------------------------------------- 1 | 2 | # Application-level permissions 3 | 4 | [] 5 | access = read : [ * ], write : [ admin, power ] 6 | 7 | ### EVENT TYPES 8 | 9 | [eventtypes] 10 | export = system 11 | 12 | 13 | ### PROPS 14 | 15 | [props] 16 | export = system 17 | 18 | 19 | ### TRANSFORMS 20 | 21 | [transforms] 22 | export = system 23 | 24 | 25 | ### LOOKUPS 26 | 27 | [lookups] 28 | export = system 29 | 30 | 31 | ### VIEWSTATES: even normal users should be able to create shared viewstates 32 | 33 | [viewstates] 34 | access = read : [ * ], write : [ * ] 35 | export = system 36 | 37 | ### Saved searches 38 | 39 | [savedsearches] 40 | access = read : [ * ], write : [ admin ] 41 | export = none 42 | -------------------------------------------------------------------------------- /tutorials/Module-02_SetupPage/appserver.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/tutorials/Module-02_SetupPage/appserver.zip -------------------------------------------------------------------------------- /tutorials/Module-02_SetupPage/devtutorial/appserver/static/javascript/setup_page.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var app_name = "./devtutorial"; 4 | 5 | // This is a Splunk solution for how to include javascript logic 6 | // from other files. 7 | // Declare a require.config() and provide a dictionary that has a `paths` keys. 8 | // In the `paths` key provide another dictionary that declares custom classes. 9 | // Each key should be the class name, and the value the path to the javascript file 10 | // ../app//(no extension) 11 | // Then include those in the require method's array, and function. 12 | 13 | // Common gotchas: 14 | // 1) The path to the script autmatically appends .js, so don't include it 15 | // 2) This only provides supprt for JavaScript files, plain-text html files won't work 16 | // 3) The "../app" is required as a prefix and your app name is required to follow it 17 | // 4) After the app name, the path is provided as though it were from the 18 | // $SPLUNK_HOME/etc/apps/appserver/static/* directory 19 | 20 | require.config({ 21 | paths: { 22 | // $SPLUNK_HOME/etc/apps/SPLUNK_APP_NAME/appserver/static/javascript/views/setup_page_example 23 | myApp: "../app/" + app_name + "/javascript/views/app", 24 | // React v16.13.1 25 | react: "../app/" + app_name + "/javascript/vendor/react.production.min", 26 | ReactDOM: "../app/" + app_name + "/javascript/vendor/react-dom.production.min", 27 | }, 28 | scriptType: "module", 29 | }); 30 | 31 | require([ 32 | // Splunk Web Framework Provided files 33 | // Custom files 34 | "react", // this needs to be lowercase because ReactDOM refers to it as lowercase 35 | "ReactDOM", 36 | "myApp", 37 | ], function(react, ReactDOM, myApp) { 38 | ReactDOM.render(myApp, document.getElementById('main_container')); 39 | }); 40 | -------------------------------------------------------------------------------- /tutorials/Module-02_SetupPage/devtutorial/appserver/static/javascript/views/app.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * This is an example using pure react, with no JSX 4 | * If you would like to use JSX, you will need to use Babel to transpile your code 5 | * from JSK to JS. You will also need to use a task runner/module bundler to 6 | * help build your app before it can be used in the browser. 7 | * Some task runners/module bundlers are : gulp, grunt, webpack, and Parcel 8 | */ 9 | 10 | import * as Setup from "./store_secret.js"; 11 | 12 | define(["react", "splunkjs/splunk"], function(react, splunk_js_sdk){ 13 | const e = react.createElement; 14 | 15 | class SetupPage extends react.Component { 16 | constructor(props) { 17 | super(props); 18 | 19 | this.state = { 20 | password: '' 21 | }; 22 | 23 | this.handleChange = this.handleChange.bind(this); 24 | this.handleSubmit = this.handleSubmit.bind(this); 25 | } 26 | 27 | handleChange(event) { 28 | this.setState({ ...this.state, [event.target.name]: event.target.value}) 29 | } 30 | 31 | async handleSubmit(event) { 32 | event.preventDefault(); 33 | 34 | await Setup.perform(splunk_js_sdk, this.state) 35 | } 36 | 37 | render() { 38 | return e("div", null, [ 39 | e("h2", null, "Create a password to complete app setup."), 40 | e("div", null, [ 41 | e("form", { onSubmit: this.handleSubmit }, [ 42 | e("label", null, [ 43 | "Password ", 44 | e("input", { type: "text", name: "password", value: this.state.password, onChange: this.handleChange }) 45 | ]), 46 | e("input", { type: "submit", value: "Submit" }) 47 | ]) 48 | ]) 49 | ]); 50 | } 51 | } 52 | 53 | return e(SetupPage); 54 | }); 55 | -------------------------------------------------------------------------------- /tutorials/Module-02_SetupPage/devtutorial/appserver/static/javascript/views/setup_configuration.js: -------------------------------------------------------------------------------- 1 | import { promisify } from './util.js' 2 | import * as SplunkHelpers from './splunk_helpers.js' 3 | 4 | async function complete_setup(splunk_js_sdk_service) { 5 | var configuration_file_name = "app"; 6 | var stanza_name = "install"; 7 | var properties_to_update = { 8 | is_configured: "true", 9 | }; 10 | 11 | await SplunkHelpers.update_configuration_file( 12 | splunk_js_sdk_service, 13 | configuration_file_name, 14 | stanza_name, 15 | properties_to_update, 16 | ); 17 | }; 18 | 19 | async function reload_splunk_app( 20 | splunk_js_sdk_service, 21 | app_name, 22 | ) { 23 | var splunk_js_sdk_apps = splunk_js_sdk_service.apps(); 24 | await promisify(splunk_js_sdk_apps.fetch)(); 25 | 26 | var current_app = splunk_js_sdk_apps.item(app_name); 27 | await promisify(current_app.reload)(); 28 | }; 29 | 30 | function redirect_to_splunk_app_homepage( 31 | app_name, 32 | ) { 33 | var redirect_url = "/app/" + app_name; 34 | 35 | window.location.href = redirect_url; 36 | }; 37 | 38 | 39 | function create_splunk_js_sdk_service( 40 | splunk_js_sdk, 41 | application_name_space, 42 | ) { 43 | var http = new splunk_js_sdk.SplunkWebHttp(); 44 | 45 | var splunk_js_sdk_service = new splunk_js_sdk.Service( 46 | http, 47 | application_name_space, 48 | ); 49 | 50 | return splunk_js_sdk_service; 51 | }; 52 | 53 | export { 54 | complete_setup, 55 | reload_splunk_app, 56 | redirect_to_splunk_app_homepage, 57 | create_splunk_js_sdk_service, 58 | } 59 | -------------------------------------------------------------------------------- /tutorials/Module-02_SetupPage/devtutorial/appserver/static/javascript/views/util.js: -------------------------------------------------------------------------------- 1 | function promisify(fn) { 2 | console.log("promisify: Don't use this in production! Use a proper promisify library instead.") 3 | 4 | // return a new promisified function 5 | return (...args) => { 6 | return new Promise((resolve, reject) => { 7 | // create a callback that resolves and rejects 8 | function callback(err, result) { 9 | if (err) { 10 | reject(err); 11 | } else { 12 | resolve(result); 13 | } 14 | } 15 | 16 | args.push(callback) 17 | 18 | // pass the callback into the function 19 | fn.call(this, ...args); 20 | }) 21 | } 22 | } 23 | 24 | export { 25 | promisify, 26 | } 27 | -------------------------------------------------------------------------------- /tutorials/Module-02_SetupPage/devtutorial/bin/README: -------------------------------------------------------------------------------- 1 | This is where you put any scripts you want to add to this app. 2 | -------------------------------------------------------------------------------- /tutorials/Module-02_SetupPage/devtutorial/default/app.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Splunk app configuration file 3 | # 4 | 5 | [install] 6 | is_configured = 0 7 | 8 | [ui] 9 | is_visible = 1 10 | label = Dev Tutorial 11 | # Points to a file in: 12 | # $SPLUNK_HOME/etc/apps//default/data/ui/views/* 13 | # It does not need the extension of the file name provided 14 | setup_view = setup_page_dashboard 15 | 16 | [launcher] 17 | author = 18 | description = Dev tutorial app 19 | version = 1.0.0 -------------------------------------------------------------------------------- /tutorials/Module-02_SetupPage/devtutorial/default/data/ui/nav/default.xml: -------------------------------------------------------------------------------- 1 | 17 | -------------------------------------------------------------------------------- /tutorials/Module-02_SetupPage/devtutorial/default/data/ui/views/setup_page_dashboard.xml: -------------------------------------------------------------------------------- 1 | 8 | 11 | 12 | 13 | 14 | 15 |
16 | 17 |
18 |
19 |
20 | -------------------------------------------------------------------------------- /tutorials/Module-02_SetupPage/devtutorial/default/data/ui/views/welcome.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |

7 | Hello! You created this app using the 8 | Module 1: Get Started 9 | tutorial on the Splunk Developer Portal. 10 |

11 | 12 |
13 |
14 |
15 | -------------------------------------------------------------------------------- /tutorials/Module-02_SetupPage/devtutorial/default/savedsearches.conf: -------------------------------------------------------------------------------- 1 | [Movies By Rating] 2 | description = Example search by editing savedsearches.conf 3 | dispatch.earliest_time = 0 4 | search = index=devtutorial | stats count by RATING 5 | 6 | [Top Rental Rates] 7 | action.email.useNSSubject = 1 8 | alert.track = 0 9 | description = Example search using Splunk Web 10 | dispatch.earliest_time = 0 11 | display.general.type = statistics 12 | display.page.search.tab = statistics 13 | display.visualizations.show = 0 14 | request.ui_dispatch_app = devtutorial 15 | request.ui_dispatch_view = search 16 | search = index=devtutorial | top RENTAL_RATE 17 | 18 | [Top Replacement Costs] 19 | description = Example search using REST 20 | search = index=devtutorial | top limit=20 REPLACEMENT_COST 21 | -------------------------------------------------------------------------------- /tutorials/Module-02_SetupPage/devtutorial/metadata/default.meta: -------------------------------------------------------------------------------- 1 | 2 | # Application-level permissions 3 | 4 | [] 5 | access = read : [ * ], write : [ admin, power ] 6 | 7 | ### EVENT TYPES 8 | 9 | [eventtypes] 10 | export = system 11 | 12 | 13 | ### PROPS 14 | 15 | [props] 16 | export = system 17 | 18 | 19 | ### TRANSFORMS 20 | 21 | [transforms] 22 | export = system 23 | 24 | 25 | ### LOOKUPS 26 | 27 | [lookups] 28 | export = system 29 | 30 | 31 | ### VIEWSTATES: even normal users should be able to create shared viewstates 32 | 33 | [viewstates] 34 | access = read : [ * ], write : [ * ] 35 | export = system 36 | 37 | ### Saved searches 38 | 39 | [savedsearches] 40 | access = read : [ * ], write : [ admin ] 41 | export = none 42 | -------------------------------------------------------------------------------- /tutorials/Module-03_ExternalLookup/devtutorial/README: -------------------------------------------------------------------------------- 1 | This is where you put any scripts you want to add to this app. 2 | -------------------------------------------------------------------------------- /tutorials/Module-03_ExternalLookup/devtutorial/bin/README: -------------------------------------------------------------------------------- 1 | This is where you put any scripts you want to add to this app. 2 | -------------------------------------------------------------------------------- /tutorials/Module-03_ExternalLookup/devtutorial/default/app.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Splunk app configuration file 3 | # 4 | 5 | [install] 6 | is_configured = 0 7 | 8 | [ui] 9 | is_visible = 1 10 | label = Dev Tutorial 11 | 12 | [launcher] 13 | author = 14 | description = Dev tutorial app 15 | version = 1.0.0 16 | 17 | [package] 18 | id = devtutorial 19 | 20 | -------------------------------------------------------------------------------- /tutorials/Module-03_ExternalLookup/devtutorial/default/data/ui/nav/default.xml: -------------------------------------------------------------------------------- 1 | 17 | 18 | -------------------------------------------------------------------------------- /tutorials/Module-03_ExternalLookup/devtutorial/default/data/ui/views/README: -------------------------------------------------------------------------------- 1 | Add all the views that your app needs in this directory 2 | -------------------------------------------------------------------------------- /tutorials/Module-03_ExternalLookup/devtutorial/default/data/ui/views/welcome.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |

7 | Hello! You created this app using the 8 | Module 01: Get Started 9 | tutorial on the Splunk Developer Portal. 10 |

11 | 12 |
13 |
14 |
15 | -------------------------------------------------------------------------------- /tutorials/Module-03_ExternalLookup/devtutorial/default/savedsearches.conf: -------------------------------------------------------------------------------- 1 | [Movies By Rating] 2 | description = Example search by editing savedsearches.conf 3 | dispatch.earliest_time = 0 4 | search = index=devtutorial | stats count by RATING 5 | 6 | [Top Rental Rates] 7 | action.email.useNSSubject = 1 8 | alert.track = 0 9 | description = Example search using Splunk Web 10 | dispatch.earliest_time = 0 11 | display.general.type = statistics 12 | display.page.search.tab = statistics 13 | display.visualizations.show = 0 14 | request.ui_dispatch_app = devtutorial 15 | request.ui_dispatch_view = search 16 | search = index=devtutorial | top RENTAL_RATE 17 | 18 | [Top Replacement Costs] 19 | description = Example search using REST 20 | search = index=devtutorial | top limit=20 REPLACEMENT_COST -------------------------------------------------------------------------------- /tutorials/Module-03_ExternalLookup/devtutorial/default/transforms.conf: -------------------------------------------------------------------------------- 1 | [dnslookup] 2 | external_cmd = dns_external_lookup.py host ip 3 | fields_list = host, ip 4 | python.version = python3 -------------------------------------------------------------------------------- /tutorials/Module-03_ExternalLookup/devtutorial/metadata/default.meta: -------------------------------------------------------------------------------- 1 | 2 | # Application-level permissions 3 | 4 | [] 5 | access = read : [ * ], write : [ admin, power ] 6 | 7 | ### EVENT TYPES 8 | 9 | [eventtypes] 10 | export = system 11 | 12 | 13 | ### PROPS 14 | 15 | [props] 16 | export = system 17 | 18 | 19 | ### TRANSFORMS 20 | 21 | [transforms] 22 | export = system 23 | 24 | 25 | ### LOOKUPS 26 | 27 | [lookups] 28 | export = system 29 | 30 | 31 | ### VIEWSTATES: even normal users should be able to create shared viewstates 32 | 33 | [viewstates] 34 | access = read : [ * ], write : [ * ] 35 | export = system 36 | 37 | ### Saved searches 38 | 39 | [savedsearches] 40 | access = read : [ * ], write : [ admin ] 41 | export = none -------------------------------------------------------------------------------- /tutorials/Module-03_ExternalLookup/devtutorial/static/appIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/tutorials/Module-03_ExternalLookup/devtutorial/static/appIcon.png -------------------------------------------------------------------------------- /tutorials/Module-03_ExternalLookup/devtutorial/static/appIconAlt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/tutorials/Module-03_ExternalLookup/devtutorial/static/appIconAlt.png -------------------------------------------------------------------------------- /tutorials/Module-03_ExternalLookup/devtutorial/static/appIconAlt_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/tutorials/Module-03_ExternalLookup/devtutorial/static/appIconAlt_2x.png -------------------------------------------------------------------------------- /tutorials/Module-03_ExternalLookup/devtutorial/static/appIcon_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/tutorials/Module-03_ExternalLookup/devtutorial/static/appIcon_2x.png -------------------------------------------------------------------------------- /tutorials/Module-04_Validate/devtutorial/README: -------------------------------------------------------------------------------- 1 | This is where you put any scripts you want to add to this app. 2 | -------------------------------------------------------------------------------- /tutorials/Module-04_Validate/devtutorial/default/app.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Splunk app configuration file 3 | # 4 | 5 | [install] 6 | is_configured = 0 7 | 8 | [ui] 9 | is_visible = 1 10 | label = Dev Tutorial 11 | 12 | [launcher] 13 | author = 14 | description = Dev tutorial app 15 | version = 1.0.0 16 | 17 | [package] 18 | id = devtutorial 19 | 20 | -------------------------------------------------------------------------------- /tutorials/Module-04_Validate/devtutorial/default/data/ui/nav/default.xml: -------------------------------------------------------------------------------- 1 | 17 | 18 | -------------------------------------------------------------------------------- /tutorials/Module-04_Validate/devtutorial/default/data/ui/views/README: -------------------------------------------------------------------------------- 1 | Add all the views that your app needs in this directory 2 | -------------------------------------------------------------------------------- /tutorials/Module-04_Validate/devtutorial/default/data/ui/views/welcome.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |

7 | Hello! You created this app using the 8 | Module 01: Get Started 9 | tutorial on the Splunk Developer Portal. 10 |

11 | 12 |
13 |
14 |
15 | -------------------------------------------------------------------------------- /tutorials/Module-04_Validate/devtutorial/default/savedsearches.conf: -------------------------------------------------------------------------------- 1 | [Movies By Rating] 2 | description = Example search by editing savedsearches.conf 3 | dispatch.earliest_time = 0 4 | search = index=devtutorial | stats count by RATING 5 | 6 | [Top Rental Rates] 7 | action.email.useNSSubject = 1 8 | alert.track = 0 9 | description = Example search using Splunk Web 10 | dispatch.earliest_time = 0 11 | display.general.type = statistics 12 | display.page.search.tab = statistics 13 | display.visualizations.show = 0 14 | request.ui_dispatch_app = devtutorial 15 | request.ui_dispatch_view = search 16 | search = index=devtutorial | top RENTAL_RATE 17 | 18 | [Top Replacement Costs] 19 | description = Example search using REST 20 | search = index=devtutorial | top limit=20 REPLACEMENT_COST -------------------------------------------------------------------------------- /tutorials/Module-04_Validate/devtutorial/metadata/default.meta: -------------------------------------------------------------------------------- 1 | 2 | # Application-level permissions 3 | 4 | [] 5 | access = read : [ * ], write : [ admin, power ] 6 | 7 | ### EVENT TYPES 8 | 9 | [eventtypes] 10 | export = system 11 | 12 | 13 | ### PROPS 14 | 15 | [props] 16 | export = system 17 | 18 | 19 | ### TRANSFORMS 20 | 21 | [transforms] 22 | export = system 23 | 24 | 25 | ### LOOKUPS 26 | 27 | [lookups] 28 | export = system 29 | 30 | 31 | ### VIEWSTATES: even normal users should be able to create shared viewstates 32 | 33 | [viewstates] 34 | access = read : [ * ], write : [ * ] 35 | export = system 36 | 37 | ### Saved searches 38 | 39 | [savedsearches] 40 | access = read : [ * ], write : [ admin ] 41 | export = none -------------------------------------------------------------------------------- /tutorials/Module-04_Validate/devtutorial/static/appIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/tutorials/Module-04_Validate/devtutorial/static/appIcon.png -------------------------------------------------------------------------------- /tutorials/Module-04_Validate/devtutorial/static/appIconAlt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/tutorials/Module-04_Validate/devtutorial/static/appIconAlt.png -------------------------------------------------------------------------------- /tutorials/Module-04_Validate/devtutorial/static/appIconAlt_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/tutorials/Module-04_Validate/devtutorial/static/appIconAlt_2x.png -------------------------------------------------------------------------------- /tutorials/Module-04_Validate/devtutorial/static/appIcon_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/splunk/splunk-app-examples/65aca5e3336cdf86acc09e1395aef1243b8ca925/tutorials/Module-04_Validate/devtutorial/static/appIcon_2x.png --------------------------------------------------------------------------------