Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Initial Codebase for Integrations CLI #1488

Closed
wants to merge 41 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
5253511
Move schema folder to resources
Swiddis Mar 28, 2023
43e374b
Move schema documentation to docs
Swiddis Mar 28, 2023
18d71a7
Move rest of schema documentation to docs
Swiddis Mar 28, 2023
ea46eb9
Pull CLI from 2.x
Swiddis Mar 30, 2023
472508d
Commit CLI project to Poetry
Swiddis Mar 31, 2023
3c11c47
Use returns Result for validation
Swiddis Mar 31, 2023
1766927
Pylint maintenance
Swiddis Mar 31, 2023
d0cf5c1
Add catalog selection support
Swiddis Mar 31, 2023
5d86173
Tweak catalog schema to pass validation for catalog
Swiddis Mar 31, 2023
9265e58
Refactor validation logic
Swiddis Apr 3, 2023
15f7a13
Reformat
Swiddis Apr 3, 2023
d5d1dd1
Add poetry to CI
Swiddis Apr 3, 2023
861d573
Merge remote-tracking branch 'upstream/main' into cli-main
Swiddis Apr 3, 2023
99c72e9
Refresh poetry lock
Swiddis Apr 3, 2023
b921d94
Add install to poetry steps
Swiddis Apr 3, 2023
a7fa6f8
Refactor project with builds and scripts
Swiddis Apr 4, 2023
7592d2f
Fix catalog schema
Swiddis Apr 10, 2023
74747bb
Add better component handling
Swiddis Apr 10, 2023
baf1edb
Modify template http dashboard
Swiddis Apr 10, 2023
00cc117
Modify dashboards and add upload script
Swiddis Apr 11, 2023
f3dfc4c
Fix update.sh
Swiddis Apr 11, 2023
6e4ea43
Fix broken dashboard
Swiddis Apr 11, 2023
9775001
Switch from poetry
Swiddis Apr 11, 2023
c144a2b
Add helper script and update readme
Swiddis Apr 11, 2023
6801fd5
Update readme with workflow
Swiddis Apr 12, 2023
c4a482f
Fix shell scripts and make upload dynamic
Swiddis Apr 12, 2023
082a3fc
Switch to Pytest
Swiddis Apr 12, 2023
693cc82
Tweak CI
Swiddis Apr 12, 2023
c1b917d
Fix CI attempt
Swiddis Apr 13, 2023
10971b3
Use CI from SQL cli
Swiddis Apr 13, 2023
abd0692
Switch to lru_cache for compatibility
Swiddis Apr 13, 2023
67ef7d6
Add integrations to branch
Swiddis Apr 13, 2023
86209e3
Handle get-mapping failures
Swiddis Apr 13, 2023
0f7a629
Simplify test docker
Swiddis Apr 13, 2023
1a178f3
Add work on adding subcomponent validation to integrations
Swiddis Apr 13, 2023
cdc62a7
Revert "Add work on adding subcomponent validation to integrations"
Swiddis Apr 14, 2023
fc1836e
Add dependency management and clean handling of unnecessary fields
Swiddis Apr 14, 2023
92d9917
Remove dependence on nginx
Swiddis Apr 14, 2023
f6a8385
Setting path doesn't set url
Swiddis Apr 14, 2023
81ea966
Fix zipping
Swiddis Apr 15, 2023
bbe3232
Remove testing integrations folder
Swiddis Apr 17, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions .github/workflows/python-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Integrations CLI Test and Build

on:
workflow_dispatch:
pull_request:
push:
branches-ignore:
- 'dependabot/**'
paths:
- 'scripts/integrations-cli'
- '.github/workflows/python-ci.yml'

jobs:
build:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./scripts/integrations-cli
strategy:
matrix:
python-version: [3.8]
opensearch-version: [ latest ]

steps:
- name: Checkout Integrations CLI
uses: actions/checkout@v3

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}

- name: Install Python Dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install setuptools wheel

- name: Run Tests
run: pytest
180 changes: 180 additions & 0 deletions scripts/integrations-cli/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
# Directories used by CLI
artifacts
integrations

# Created by https://www.toptal.com/developers/gitignore/api/python
# Edit at https://www.toptal.com/developers/gitignore?templates=python

### Python ###
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
.pybuilder/
target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version

# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock

# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock

# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml

# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/

# Celery stuff
celerybeat-schedule
celerybeat.pid

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/

# pytype static type analyzer
.pytype/

# Cython debug symbols
cython_debug/

# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/

### Python Patch ###
# Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration
poetry.toml

# ruff
.ruff_cache/

# LSP config files
pyrightconfig.json

# End of https://www.toptal.com/developers/gitignore/api/python
143 changes: 143 additions & 0 deletions scripts/integrations-cli/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
# Integrations CLI

## Description

This is a CLI tool for creating, validating, and maintaining OpenSearch Dashboard Integrations.
The tool has three main functions:

- `create` a new integration with a specified configuration.
- `check` an integration for validity
- `package` an integration to be upload to an OpenSearch Integrations instance

Further information is provided in the `Usage` section.

## Installation

The project requires Python 3.7 or better.
As the project is not yet a full Python package, it must be installed manually.
To manually install, create a virtual environment and install the requirements.

On Unix:

```bash
$ python3 -m venv venv
$ source ./venv/bin/activate
$ pip install -r requirements.txt
```

On Windows:

```ps1
> python -m venv venv
> ./venv/Scripts/activate.ps1
> pip install -r requirements.txt
```

On Unix, the script `integ-cli` that will automatically install necessary dependencies.

```bash
$ ./integ-cli
```

## Usage

On Unix, the CLI is callable with the included `integ-cli` script.
The simplest way to start making an integration is via `create`.

```bash
$ ./integ-cli --help
```

Further development instructions are provided below.

### What's in an Integration?

An integration typically consists of three components:

- A Config file
- Schemas
- Assets

The Config file `config.json` defines parameters for the integration.
Most notably, the versions of all involved dependencies.
It also has information like a description,
which is used when presenting the integration in the catalog.

The Schemas `/schema` are the rules for the data, and define the permitted fields and types.
During integration creation, they are provided based on the selected components.
These are typically not meant to be changed.

The Assets `/assets` are the "heart" of the integration.
They contain the bulk of what you develop.
All developed Assets should be compatible with the provided components.
Saved Objects, such as schemas and dashboards, are saved under `/assets/display`.

### How to Install an Integration

First, generate a template with desired defaults.

```bash
$ ./integ-cli create [NAME]
```

To begin using the integration, first load the templates in `schema`.
The loading order generally depends on dependencies, look for a `composed_of` field.
Dependencies are loaded by uploading them to a running OpenSearch cluster.
For example, to load the `http` component under an `nginx` integration:

```bash
$ curl -XPUT localhost:9200/_component_template/http_template -H "Content-Type: application/json" --data-binary "@integrations/nginx/schema/http.mapping"
```

If the component contains an `index_mapping`,
then instead post it as an index template, e.g. with `logs`:

```bash
$ curl -XPUT localhost:9200/_index_template/logs -H "Content-Type: application/json" --data-binary "@integrations/nginx/schema/logs.mapping"
```

Now we turn to OpenSearch Dashboards.
First is an index pattern, which defines where to find the data.
This should generally match the pattern `ss4o_*`.

```bash
$ curl -XPOST localhost:5601/api/saved_objects/index-pattern/sso_logs -H 'osd-xsrf: true' -H 'Content-Type: application/json' -d '{ "attributes": { "title": "sso_logs-*-*", "timeFieldName": "@timestamp" } }'
```

Finally, load the saved objects under `/assets/display`:

```bash
curl -XPOST "localhost:5601/api/saved_objects/_import?overwrite=true" -H "osd-xsrf: true" --form file=@integrations/nginx/assets/display/http.ndjson
```

We are aware that this is a complicated process.
We're working on it.

### How to Develop an Integration

Once the saved objects have been loaded,
you can freely change the relevant dashboards within the OpenSearch Dashboards UI.
To update the Display Assets,
export the new dashboards and replace the `.ndjson` files as desired.

If you need to add another `schema`,
add it to the `config.json` and add the mapping to the `/schema` directory.
This is also going to be automated in the future.

## Development

Running the tests:

```bash
$ python -m unittest
```

Formatting:

```bash
$ black .
```

## License

This project, like the rest of the OpenSearch projects, is licensed under the [Apache 2.0 License](https://www.apache.org/licenses/LICENSE-2.0.html).
2 changes: 2 additions & 0 deletions scripts/integrations-cli/integ-cli
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/usr/bin/bash
python3 integrations_cli/main.py "$@"
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from . import constants, validate
from .catalog import CatalogManager
from .create import IntegrationBuilder
22 changes: 22 additions & 0 deletions scripts/integrations-cli/integrations_cli/helpers/catalog.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import json
import os
from functools import lru_cache

from returns.io import impure_safe

from . import constants, validate


@impure_safe
def _load_catalog_file() -> dict:
catalog_path = os.path.join(constants.SCHEMA_ROOT, "observability/catalog.json")
with open(catalog_path, "r", encoding="utf-8") as catalog_file:
return json.load(catalog_file)


class CatalogManager:
@lru_cache
def __init__(self):
catalog = _load_catalog_file().bind_result(validate.validate_catalog)
# For now just re-throw exceptions on catalog load failure
self.catalog = catalog.unwrap()._inner_value
Loading
Loading