SA-OpenSearchTool
2026.3.1.9-dev.416
dotnet tool install --global SA-OpenSearchTool --version 2026.3.1.9-dev.416
dotnet new tool-manifest
dotnet tool install --local SA-OpenSearchTool --version 2026.3.1.9-dev.416
#tool dotnet:?package=SA-OpenSearchTool&version=2026.3.1.9-dev.416&prerelease
nuke :add-package SA-OpenSearchTool --version 2026.3.1.9-dev.416
SA-OpenSearchTool
A CLI and TUI tool for managing OpenSearch clusters — snapshots, connections, index operations, and cluster configuration. Built for system administrators at Tyler Technologies Public Safety.
Installation
# Install as a .NET global tool
dotnet tool install -g SA-OpenSearchTool
# Install prerelease version
dotnet tool install -g SA-OpenSearchTool --prerelease
# Update to latest version
dotnet tool update -g SA-OpenSearchTool
# Uninstall
dotnet tool uninstall -g SA-OpenSearchTool
Quick Start
# Launch the interactive TUI
sa-ost
# Launch the CLI interactive mode
sa-ost --no-gui
# Show help and available commands
sa-ost --help
# Display version
sa-ost --version
# Show terminal capability info
sa-ost --terminal-info
Two Modes
SA-OpenSearchTool offers two interfaces. Both are feature-complete — choose based on your workflow.
TUI (Terminal User Interface) — Launch with sa-ost. A full interactive experience with menus, dialogs, and a step-by-step snapshot wizard. Best for interactive use when you want visual feedback and guided workflows.
CLI (Command Line Interface) — Launch with sa-ost --no-gui for an interactive menu, or use subcommands directly (e.g., sa-ost snapshot list). Best for scripting, automation, or when you know exactly what command you need.
| TUI | CLI | |
|---|---|---|
| Launch | sa-ost |
sa-ost --no-gui or sa-ost <command> |
| Navigation | Menus, dialogs, keyboard shortcuts | Interactive prompts or flags |
| Snapshot wizard | F5 or Snapshots menu | Select from interactive menu |
| Scriptable | No | Yes |
Connection Management
Connections store your OpenSearch cluster credentials so you don't re-enter them each time.
CLI
# Add a connection interactively
sa-ost connection add
# Add with all options specified
sa-ost connection add \
--name "Production" \
--host os-prod-01.agency.local \
--port 9200 \
--user admin \
--nodes "os-prod-01.agency.local,os-prod-02.agency.local,os-prod-03.agency.local" \
--default
# List all saved connections
sa-ost connection list
sa-ost connection list --json
# Test a connection
sa-ost connection test # Test default connection
sa-ost connection test "Production" # Test by name
sa-ost connection test 1 # Test by ID
# Set the default connection
sa-ost connection set-default "Production"
# Delete a connection
sa-ost connection delete "Production"
sa-ost connection delete 1 --force # Skip confirmation
TUI
- Add/Edit/Delete: Connections > Manage Connections (Ctrl+M)
- Quick connect (without saving): Connections > Quick Connect
- Test connection: Connections > Test Connection (Ctrl+T)
Connection Options
| Option | Description |
|---|---|
-n, --name |
Display name for the connection |
--host |
OpenSearch host address |
-p, --port |
OpenSearch port (default: 9200) |
-u, --user |
Username for authentication |
--default |
Set as the default connection |
--nodes |
Comma-separated cluster node hostnames |
Snapshot Wizard
The snapshot wizard walks you through the full prod-to-test migration in 6 steps: connect to source, configure a snapshot repository, create a snapshot, copy the snapshot files, connect to target, and restore.
Launching the Wizard
- TUI: Launch
sa-ost, then press F5 or go to Snapshots > Snapshot Wizard - CLI: Launch
sa-ost --no-guiand select Snapshot Wizard from the menu
Step 1: Select Source Connection
Pick the OpenSearch cluster you want to snapshot from. You can select an existing saved connection or add a new one on the spot. The wizard tests the connection before proceeding.
Step 2: Configure Repository
A snapshot repository is a named location where OpenSearch stores snapshot data — typically a shared filesystem path accessible to all cluster nodes.
Enter a repository name (e.g., prod_to_test_backup) and the path on the cluster nodes (e.g., \\os-prod-01\ElasticSnapshots). If the repository doesn't exist yet, the wizard creates it.
Step 3: Create Snapshot
Choose a name for the snapshot (a timestamped default is suggested) and an index pattern to include. The default pattern *ps-* captures all Public Safety indices. The wizard monitors snapshot progress and waits for completion.
Step 4: Copy Files
Enter the destination path where snapshot files should be copied — typically a location accessible to the target cluster (e.g., E:\Elastic\SnapShots). The wizard copies files inline with a progress bar showing file count, percentage, and transfer speed. In the TUI, the path is validated before copy begins.
Step 5: Select Target Connection
Pick the target cluster to restore into. This is usually a test or staging environment.
Step 6: Restore Snapshot
The wizard configures a repository on the target cluster pointing to the copied files, then restores the snapshot. You can configure:
- Index pattern — which indices to restore (default: all)
- Delete existing indices — hard-delete matching indices on the target before restoring, instead of the safe default of closing them (default: no). By default the restore closes each matching index and lets the restore reopen it with the restored data; if a close fails for an index, that index is deleted so the restore can proceed. Enable this option only to force a hard delete up front.
- Include global state — restore cluster-wide settings like templates (default: no)
- Rename pattern/replacement — rename indices during restore (e.g., add a
restored_prefix)
The restore always monitors progress to completion via cluster-health polling (there is no wait/no-wait toggle on restore — a long restore would otherwise time out the HTTP request).
Each step supports Back/Next navigation, and the wizard remembers your inputs if you need to go back and change something.
Snapshot Operations — Standalone
For scripting or one-off operations outside the wizard, use these commands directly.
Repositories
A repository must be configured before you can create or restore snapshots.
# List all snapshot repositories
sa-ost snapshot repos
sa-ost snapshot repos --json
# Create a new repository
sa-ost snapshot create-repo --name prod-backup --path /mnt/elastic/snapshots
# Create without compression
sa-ost snapshot create-repo --name prod-backup --path /mnt/elastic/snapshots --no-compress
Snapshots
# List snapshots in a repository
sa-ost snapshot list
sa-ost snapshot list --repo prod-backup
sa-ost snapshot list --repo prod-backup --json
# Create a snapshot
sa-ost snapshot create --repo prod-backup --name snapshot-20260412
sa-ost snapshot create --repo prod-backup --name snapshot-20260412 --indices "*ps-cad-*"
sa-ost snapshot create --repo prod-backup --name snapshot-20260412 --no-wait
# Check snapshot status
sa-ost snapshot status snapshot-20260412 --repo prod-backup
sa-ost snapshot status snapshot-20260412 --repo prod-backup --json
Copy
Copy snapshot files between locations — typically from a production cluster's shared storage to a path accessible by the target cluster.
sa-ost snapshot copy \
--source "\\os-prod-01\ElasticSnapshots" \
--dest "E:\Elastic\SnapShots"
Restore
Restore a snapshot to the currently active connection.
# Basic restore
sa-ost snapshot restore snapshot-20260412 --repo prod-backup
# Restore specific indices
sa-ost snapshot restore snapshot-20260412 --repo prod-backup --indices "ps-cad-*,ps-rms-*"
# Restore with renaming
sa-ost snapshot restore snapshot-20260412 --repo prod-backup \
--rename-pattern "(.+)" \
--rename-replacement "restored_$1"
# Force a hard delete of matching indices before restore (instead of the default close).
# --delete-existing requires a specific --indices pattern (it is rejected for a wildcard).
sa-ost snapshot restore snapshot-20260412 --repo prod-backup --indices "ps-cad-*" --delete-existing
# Restore to a different connection
sa-ost snapshot restore snapshot-20260412 --repo prod-backup --connection "Test"
By default, restore closes each matching target index and lets the restore reopen it with the restored data (a failed close falls back to deleting that index). The restore always polls cluster health to completion — there is no wait/no-wait option on restore. Pass --delete-existing only to hard-delete matching indices up front.
Snapshot Command Options
| Option | Description |
|---|---|
-c, --connection |
Connection name or ID (uses default if not specified) |
-r, --repo |
Repository name |
-n, --name |
Snapshot name |
-i, --indices |
Index pattern to include (default: *ps-*) |
--include-global-state |
Include global cluster state (templates, settings) |
--delete-existing |
(restore only) Hard-delete matching indices before restore instead of closing them |
--no-wait |
(create only) Don't wait for the snapshot to complete — restore always polls to completion and has no such option |
--no-compress |
Disable snapshot compression (create-repo only) |
--rename-pattern |
Regex pattern for renaming indices during restore |
--rename-replacement |
Replacement string for index renaming |
--json |
Output as JSON |
Index Management
List, delete, or clear indices on a cluster — useful for cleanup before restores or diagnosing storage issues.
CLI
# List indices matching a pattern
sa-ost index list -p "*ps-*"
sa-ost index list -p "*" --connection "Test"
# Delete indices (permanently removes indices and all data)
sa-ost index delete -p "ps-cad-*"
# Clear index data (removes all documents but preserves mappings and settings)
sa-ost index delete -p "ps-cad-*" --clear-data
Both delete and --clear-data show matching indices in a table first and require you to type DELETE or CLEAR to confirm — there is no --force flag for these operations.
TUI
From the Snapshots view, click Delete Indices. The dialog lets you:
- Enter an index pattern and search
- Choose between Delete (remove entirely) or Clear Data (preserve structure)
- Review matching indices before confirming
Index Options
| Option | Description |
|---|---|
-p, --pattern |
Index pattern (required) — e.g., *ps-*, specific-index |
-c, --connection |
Connection name or ID (uses default if not specified) |
--clear-data |
Clear all documents instead of deleting the index |
Cluster Operations
Configure OpenSearch cluster nodes for snapshot repository access and manage services. Some commands are Windows-only.
Single-node clusters are supported — if no cluster nodes are configured on a connection, the tool uses the connection host as the sole node.
CLI
# List cluster nodes and their configuration paths
sa-ost cluster list-nodes
sa-ost cluster list-nodes --json
# Verify access to cluster node configuration files
sa-ost cluster verify-nodes
sa-ost cluster verify-nodes --nodes "os-prod-01.agency.local,os-prod-02.agency.local"
# Configure repository path on all cluster nodes (Windows only)
# Updates opensearch.yml and restarts services on each node
sa-ost cluster configure-repo --path "E:\Elastic\SnapShots"
sa-ost cluster configure-repo --path "E:\Elastic\SnapShots" --no-restart
sa-ost cluster configure-repo --path "E:\Elastic\SnapShots" --nodes "os-prod-01.agency.local"
# Check OpenSearch service status on cluster nodes (Windows only)
sa-ost cluster service-status
sa-ost cluster service-status --json
# Restart OpenSearch services on cluster nodes (Windows only)
sa-ost cluster restart-services
sa-ost cluster restart-services --delay 10 --continue-on-failure
TUI
Configure Repository (Snapshots > Configure Repository) combines multiple steps into one dialog:
- Select which connection's nodes to configure
- Updates the
path.reposetting in each node'sopensearch.yml - Restarts OpenSearch services on each node (Windows only)
- Registers the repository in OpenSearch via API
Cluster Command Options
| Option | Description |
|---|---|
-c, --connection |
Connection name or ID (uses default if not specified) |
--nodes |
Override cluster nodes (comma-separated hostnames) |
-p, --path |
Repository path to configure on nodes |
--no-restart |
Do not restart services after configuration |
--stop-timeout |
Timeout in seconds for stopping services (default: 60) |
--start-timeout |
Timeout in seconds for starting services (default: 120) |
--continue-on-failure |
Continue with remaining nodes if one fails |
--delay |
Delay in seconds between node restarts (default: 5) |
--json |
Output as JSON |
TUI Reference
Keyboard Shortcuts
| Key | Action |
|---|---|
| F1 | Show help / documentation |
| F5 | Open Snapshot Wizard |
| F9 | Activate menu bar |
| Ctrl+M | Manage Connections |
| Ctrl+T | Test Connection |
| Ctrl+Q | Quit application |
Menu Structure
| Menu | Items |
|---|---|
| File | Quit |
| Connections | Manage Connections, Test Connection, Quick Connect |
| Snapshots | Snapshot Wizard, List Snapshots, Create Snapshot, Copy Snapshot Files, Restore Snapshot, Configure Repository |
| Settings | Preferences, Default Snapshot Path |
| Help | Documentation, Submit Feedback, About |
The Snapshots view (accessible via Snapshots > List Snapshots or by selecting a connection and viewing its snapshots) also provides buttons for Create Snapshot, Copy, Restore, and Delete Indices directly on the view.
Configuration
Data Locations
Windows:
C:\ProgramData\Tyler Technologies\Public Safety\Utilities\SA-OpenSearchTool\
+-- config.db # SQLite database (connections, settings)
+-- sa-opensearchtool.log # Application log
+-- appsettings.local.json # Local settings overrides (optional)
Linux/macOS:
~/.local/share/SA-OpenSearchTool/
+-- config.db
+-- sa-opensearchtool.log
+-- appsettings.local.json
Default Snapshot Paths
The tool checks these locations in order when suggesting a default snapshot path:
E:\Elastic\SnapShotsD:\Elastic\SnapShotsC:\ProgramData\Tyler Technologies\Elastic\Elasticsearch\SnapShots
Cluster Node Configuration
When configuring repository paths on cluster nodes, the tool expects opensearch.yml at:
\\<hostname>\c$\ProgramData\Tyler Technologies\Elastic\Elasticsearch\config\opensearch.yml
Logging
Logs are written in JSON format using Serilog. To adjust log levels, create or edit appsettings.local.json in the data directory:
{
"Serilog": {
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"System": "Warning"
}
}
}
}
Requirements
- .NET 10.0 or later
- OpenSearch 2.x cluster
- Windows: Administrative access for service management commands
- Network access to OpenSearch API endpoints (port 9200 by default)
- For cluster operations: Admin share access to cluster nodes (
\\hostname\c$)
Documentation
- Troubleshooting Guide — common problems and solutions
- Frequently Asked Questions
- Security — credential storage, SSL, and access recommendations
Building from Source
git clone https://github.com/tyler-technologies/EPS.Utility.SA.git
cd EPS.Utility.SA/SA-OpenSearchTool
dotnet build
dotnet test Tests/SA-OpenSearchTool.Tests.csproj
For more details, see the developer documentation:
- Contributing — branch strategy, PR process, commit conventions
- Architecture — project structure, layering, key patterns
- Development Guide — local setup, testing, debugging, adding features
License
MIT License — Tyler Technologies
Support
For issues and feature requests, please contact the Tyler Technologies Public Safety team or open an issue in the repository.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
This package has no dependencies.
| Version | Downloads | Last Updated |
|---|