diff --git a/.ai/dashboard-ui.md b/.ai/dashboard-ui.md new file mode 100644 index 00000000..de6ebb60 --- /dev/null +++ b/.ai/dashboard-ui.md @@ -0,0 +1,250 @@ +# Dashboard UI (React/TypeScript) + +## Tech Stack + +- **React 18** with TypeScript 4.5, built via **Craco** (CRA override) +- **State**: React Context + `useReducer` (no Redux) +- **Routing**: `react-router-dom` v6 +- **WebSocket**: `react-use-websocket` +- **Charts**: ECharts (`echarts-for-react`) +- **Tables**: `@tanstack/react-table` + `@tanstack/react-virtual` +- **Graphs**: React Flow (`reactflow`) + dagre layout +- **Styling**: Tailwind CSS 3 with custom CSS variable themes +- **Storybook**: Available for component development (`yarn storybook`) +- **Node**: >= 20 required + +## Source Tree + +``` +ui/dashboard/src/ +├── index.tsx Entry point (provider tree) +├── App.tsx Routes + DashboardProvider +├── hooks/ State management & side effects +│ ├── useDashboard.tsx Root provider composition (7 nested providers) +│ ├── useDashboardState.tsx Main reducer (IDashboardContext) +│ ├── useDashboardExecution.tsx WebSocket lifecycle + snapshot loading +│ ├── useDashboardWebSocket.ts WebSocket connection (react-use-websocket) +│ ├── useDashboardWebSocketEventHandler.ts Event buffering (500ms flush) +│ ├── useDashboardInputs.tsx Input/filter state +│ ├── useDashboardSearchPath.tsx Search path state +│ ├── useDashboardDatetimeRange.tsx DateTime range state +│ ├── useDashboardPanelDetail.tsx Side panel state +│ ├── useDashboardSearch.tsx Global search state +│ ├── useTheme.tsx Light/dark theme +│ ├── useBreakpoint.tsx Responsive breakpoints +│ └── useAnalytics.tsx Analytics tracking +├── components/ +│ ├── dashboards/ Dashboard-specific components +│ │ ├── charts/ AreaChart, BarChart, ColumnChart, DonutChart, etc. +│ │ ├── flows/ Sankey, Flow +│ │ ├── graphs/ ForceDirectedGraph, Graph +│ │ ├── hierarchies/ Tree, Hierarchy +│ │ ├── inputs/ DateInput, SelectInput, ComboInput, etc. +│ │ ├── layout/ Dashboard, Container, Panel, Grid +│ │ ├── grouping/ Benchmark, CheckPanel, DetectionBenchmark +│ │ ├── Card/, Table/, Text/, Image/, Error/ +│ │ └── index.ts Component registry (getComponent/registerComponent) +│ └── DashboardHeader, DashboardList, DashboardSearch, etc. +├── utils/ +│ ├── registerComponents.ts Registers all panel types in registry +│ ├── dashboardEventHandlers.ts WebSocket event processing + schema migration +│ ├── state.ts State builders +│ └── data.ts, color.ts, url.ts, snapshot.ts, ... +├── types/ TypeScript type definitions +├── constants/ Schema versions, icon mappings +└── styles/ Tailwind config, CSS themes +``` + +## Provider Hierarchy (outermost to innermost) + +``` +BrowserRouter + └─ ThemeProvider (light/dark) + └─ ErrorBoundary + └─ BreakpointProvider (responsive) + └─ AnalyticsProvider + └─ DashboardProvider (composes 7 inner providers): + ├─ DashboardThemeProvider + ├─ DashboardSearchProvider + ├─ DashboardStateProvider ← main reducer + ├─ DashboardInputsProvider + ├─ DashboardSearchPathProvider + ├─ DashboardDatetimeRangeProvider + ├─ DashboardPanelDetailProvider + └─ DashboardExecutionProvider ← WebSocket +``` + +## State Management + +`useDashboardState.tsx` defines the main reducer with `IDashboardContext` state type. + +Key state fields: +- `dataMode`: `"live"` | `"cli_snapshot"` | `"cloud_snapshot"` +- `state`: `"running"` | `"complete"` | `"error"` +- `panelsMap`: All panel data keyed by name +- `panelsLog`: Execution logs per panel +- `dashboard`: Current dashboard definition +- `selectedDashboard`: Currently selected dashboard +- `dashboards` / `dashboardsMap`: Available dashboards +- `snapshot`: Execution snapshot for completed runs +- `execution_id`: Current execution UUID +- `progress`: Execution progress (0-100) +- `metadata`: Server metadata +- `error`: Current error state + +Key dispatch actions (in `DashboardActions` enum): +- `SERVER_METADATA` - Server metadata received +- `DASHBOARD_METADATA` - Dashboard-specific metadata +- `AVAILABLE_DASHBOARDS` - List of runnable dashboards +- `EXECUTION_STARTED` - Execution begins, panel structure received +- `EXECUTION_COMPLETE` - All panels done, snapshot ready +- `CONTROLS_UPDATED` - Batch of control updates +- `LEAF_NODES_COMPLETE` - Batch of completed leaf nodes +- `LEAF_NODES_UPDATED` - Batch of updated leaf nodes + +## WebSocket Event Handling + +### Event Buffering (`useDashboardWebSocketEventHandler.ts`) + +Rapid events from server are buffered to prevent UI thrashing: +- `CONTROL_COMPLETE` / `CONTROL_ERROR` events → buffered in array +- `LEAF_NODE_COMPLETE` events → buffered with timestamp +- `LEAF_NODE_UPDATED` events → buffered +- Buffer flushed every **500ms** via `setInterval` +- Other events (`execution_started`, `execution_complete`) → dispatched immediately + +### WebSocket Connection (`useDashboardWebSocket.ts`) + +Uses `react-use-websocket` library. + +URL resolution: +- **Development**: `ws://localhost:9033/ws` +- **Production**: Derives from `window.location` (http→ws, https→wss) + +Reconnection: max 10 attempts, 3000ms interval. + +### Socket Actions (client → server) + +```typescript +SocketActions = { + CLEAR_DASHBOARD: "clear_dashboard", + GET_AVAILABLE_DASHBOARDS: "get_available_dashboards", + GET_SERVER_METADATA: "get_server_metadata", + SELECT_DASHBOARD: "select_dashboard", + INPUT_CHANGED: "input_changed", +} +``` + +### Server Events (server → client) + +- `available_dashboards` - List of runnable dashboards +- `execution_started` - Dashboard execution began; includes panel metadata and layout +- `leaf_node_updated` - Panel result ready; includes data/status +- `leaf_node_complete` - Panel execution finished +- `execution_complete` - All panels complete; includes full snapshot +- `execution_error` - Runtime error +- `control_complete` / `control_error` - Individual control results +- `workspace_error` - Mod parse/load error + +## Routes + +``` +/ Live dashboard view (WebSocket streaming) +/:dashboard_name Select specific dashboard +/snapshot/:dashboard_name View saved snapshot (read-only, no re-execution) +``` + +Query params on snapshot route encode: inputs, datetime range, search_path_prefix. + +## Theming + +Two CSS variable themes defined in `styles/index.css`: +- `.theme-steampipe-default` (light) +- `.theme-steampipe-dark` (dark) + +Custom color variables: +- Control colors: `--color-alert`, `--color-ok`, `--color-info`, `--color-skip`, `--color-severity` +- Layout: `--color-dashboard`, `--color-dashboard-panel` +- Text: `--color-foreground`, `--color-foreground-light`, `-lighter`, `-lightest` +- Tables: `--color-table-border`, `--color-table-divide`, `--color-table-head` +- Scale: `--color-black-scale-1` through `--color-black-scale-8` + +Tailwind plugins: `@tailwindcss/forms`, `@tailwindcss/typography`. + +## Component Registry + +Components registered dynamically in `utils/registerComponents.ts` into a map in `components/dashboards/index.ts`: + +```typescript +const componentsMap = {}; +const getComponent = (key: string) => componentsMap[key]; +const registerComponent = (key: string, component) => { componentsMap[key] = component; }; +``` + +The layout renderer looks up components by panel type string (e.g., `"card"`, `"chart"`, `"table"`). This allows extensibility without hardcoded imports. + +Registered types: Panel, Container, Dashboard, all chart types (Area, Bar, Column, Donut, Heatmap, Line, Pie), Flow, Sankey, Graph, ForceDirectedGraph, Tree, Hierarchy, all input types, Benchmark, DetectionBenchmark, Table, Text, Image, Card, Error. + +## Build & Dev Workflow + +```bash +cd ui/dashboard +yarn install +yarn start # Dev server on http://localhost:3000 (proxies to Go backend on :9033) +yarn test # Jest + React Testing Library +yarn storybook # Component playground on http://localhost:6006 +yarn build # Production build → build/ +``` + +### Craco Configuration (`craco.config.js`) + +- **WebAssembly**: `experiments.asyncWebAssembly` enabled +- **Path alias**: `@powerpipe` → `src/` +- **Node polyfills**: buffer, crypto, path, stream, vm (via `ProvidePlugin`) +- **Circular dependency detection**: `CircularDependencyPlugin` fails build on circular imports in `/src` + +### Schema Versions + +Event schema versions tracked in `utils/dashboardEventHandlers.ts`: +``` +EXECUTION_SCHEMA_VERSION_20220614 +EXECUTION_SCHEMA_VERSION_20220929 +EXECUTION_SCHEMA_VERSION_20221222 +EXECUTION_SCHEMA_VERSION_20240130 +EXECUTION_SCHEMA_VERSION_20240607 +EXECUTION_SCHEMA_VERSION_20241125 +``` + +Schema migration functions handle backwards compatibility between versions. + +## Key Type Definitions (`types/index.ts`) + +- `DashboardDataMode`: `"live"` | `"cli_snapshot"` | `"cloud_snapshot"` +- `DashboardRunState`: `"running"` | `"complete"` | `"error"` +- `DashboardPanelType`: `"dashboard"` | `"card"` | `"table"` | `"chart"` | `"input"` | `"graph"` | `"hierarchy"` | `"flow"` | `"benchmark"` | `"control"` | `"detection"` | `"image"` | `"text"` | `"error"` | `"with"` | `"edge"` +- `PanelLog`: `{ error, executionTime, isDependency, prefix, status, timestamp, title }` +- `ReceivedSocketMessagePayload`: `{ action: string, [key: string]: any }` + +## Data Flow + +``` +User Action (click dashboard, change input) + ↓ +React Component / Event Handler + ↓ +WebSocket send (react-use-websocket) + ↓ +Go backend receives, executes query/dashboard + ↓ +Go backend sends event via WebSocket + ↓ +useDashboardWebSocket receives message + ↓ +useDashboardWebSocketEventHandler buffers (500ms) + ↓ +Dispatch action to useDashboardState reducer + ↓ +State updated, Context re-renders subscribed components + ↓ +Component renders with new data (ECharts, ReactFlow, etc.) +``` diff --git a/.ai/environment-reference.md b/.ai/environment-reference.md new file mode 100644 index 00000000..216b5cb5 --- /dev/null +++ b/.ai/environment-reference.md @@ -0,0 +1,134 @@ +# Environment Variables & Configuration Reference + +## Powerpipe Environment Variables + +| Variable | Purpose | Default | +|----------|---------|---------| +| `POWERPIPE_LISTEN` | Server listen: `"local"` or `"network"` | `local` | +| `POWERPIPE_PORT` | Server port | `9033` | +| `POWERPIPE_BENCHMARK_TIMEOUT` | Benchmark timeout (seconds) | `300` | +| `POWERPIPE_DASHBOARD_TIMEOUT` | Dashboard query timeout (seconds) | `120` | +| `POWERPIPE_DISPLAY_WIDTH` | CLI output width | Auto-detect | +| `POWERPIPE_INSTALL_DIR` | Installation directory | `~/.powerpipe` | +| `POWERPIPE_MOD_LOCATION` | Mod directory override | Current dir | +| `POWERPIPE_DATABASE` | Default database connection string | - | +| `POWERPIPE_MAX_PARALLEL` | Max parallel DB connections | `10` | +| `POWERPIPE_QUERY_TIMEOUT` | Per-query timeout (seconds) | - | +| `POWERPIPE_SNAPSHOT_LOCATION` | Snapshot upload target | - | +| `POWERPIPE_UPDATE_CHECK` | Enable version check on startup | `true` | +| `POWERPIPE_TELEMETRY` | Telemetry level | `info` | +| `POWERPIPE_CACHE_ENABLED` | Enable query caching | `true` | +| `POWERPIPE_CACHE_TTL` | Cache TTL (seconds) | - | +| `POWERPIPE_CACHE_MAX_TTL` | Cache max TTL (seconds) | - | +| `POWERPIPE_MEMORY_MAX_MB` | Go memory limit (MB) | `1024` | +| `POWERPIPE_MEMORY_MAX_MB_PLUGIN` | Plugin memory limit (MB) | - | +| `POWERPIPE_LOG_LEVEL` | Log level (see below) | `off` | +| `POWERPIPE_CONFIG_PATH` | Colon-separated config search paths | - | +| `POWERPIPE_CONFIG_DUMP` | Debug: dump config as JSON (undocumented) | - | + +### Pipes Cloud Variables + +| Variable | Purpose | +|----------|---------| +| `PIPES_HOST` | Pipes cloud host | +| `PIPES_TOKEN` | Pipes authentication token | +| `PIPES_INSTALL_DIR` | Pipes installation directory | + +### Input Variables + +Set HCL variables via `PP_VAR_` prefix: +```bash +PP_VAR_region=us-east-1 +PP_VAR_max_age=30 +``` + +### Deprecated Variables + +| Variable | Replacement | +|----------|-------------| +| `STEAMPIPE_DIAGNOSTICS_LEVEL` | `PIPES_DIAGNOSTICS_LEVEL` | + +## Configuration Precedence (highest to lowest) + +1. CLI flags (`--flag`) +2. Environment variables (`POWERPIPE_*`) +3. Explicit workspace profile (`--workspace-profile`) +4. Default workspace profile +5. Config files (`.ppc`) +6. Viper defaults (set in `internal/cmdconfig/mappings.go`) + +## Log Levels + +Set via `POWERPIPE_LOG_LEVEL` (actual env var name from `app_specific.EnvLogLevel`). + +| Value | slog Level | Notes | +|-------|------------|-------| +| `trace` | Custom trace | Most verbose | +| `debug` | `slog.LevelDebug` | | +| `info` | `slog.LevelInfo` | | +| `warn` | `slog.LevelWarn` | | +| `error` | `slog.LevelError` | | +| `off` | Discard | **Default** - no logging | + +Logger implementation: Go `log/slog` with JSON handler to stderr. Sensitive values automatically redacted via `sanitize.Instance.SanitizeKeyValue()`. + +Performance tracing: `utils.LogTime("label")` logs timestamped markers. + +## File Extensions + +| Extension | Purpose | +|-----------|---------| +| `.pp` | Mod and resource files (primary) | +| `.sp` | Legacy Steampipe format (still supported) | +| `.ppvars` | Variable files | +| `.spvars` | Legacy variable files | +| `.auto.ppvars` | Auto-loaded variable files | +| `.ppc` | Config files | +| `.powerpipeignore` | Workspace ignore patterns | +| `.mod.cache.json` | Dependency lock file | + +## Database Connection String Formats + +| Format | Backend | +|--------|---------| +| `steampipe://profile/schema` | Steampipe (PostgreSQL) | +| `postgres://user:pass@host/db` | PostgreSQL | +| `mysql://user:pass@host/db` | MySQL | +| `duckdb:///path/to/db.duckdb` | DuckDB (file) | +| `duckdb://` | DuckDB (in-memory) | +| `sqlite:///path/to/db.sqlite` | SQLite | + +## Exit Codes + +| Code | Constant | Meaning | +|------|----------|---------| +| 0 | `ExitCodeSuccessful` | Success | +| 1 | `ExitCodeControlsAlarm` | Check/benchmark: alarms found, no errors | +| 2 | `ExitCodeControlsError` | Check/benchmark: control errors found | +| 21 | `ExitCodeSnapshotCreationFailed` | Snapshot creation failed | +| 22 | `ExitCodeSnapshotUploadFailed` | Snapshot upload failed | +| 41 | `ExitCodeQueryExecutionFailed` | Query execution failed | +| 62 | `ExitCodeModInstallFailed` | Mod installation failed | +| 250 | `ExitCodeInitializationFailed` | Workspace/DB initialization failed | +| 251 | `ExitCodeBindPortUnavailable` | Server port binding failed | +| 252 | `ExitCodeNoModFile` | No mod.pp found | +| 254 | `ExitCodeInsufficientOrWrongInputs` | Invalid user input | +| 255 | `ExitCodeUnknownErrorPanic` | Panic recovery (unhandled crash) | + +## Error Handling Patterns + +- **Panic recovery**: `main.go` has a deferred `recover()` that catches panics, logs error via `error_helpers.ShowError()`, and exits with code 255 +- **InitData errors**: Commands call `NewInitData[T]()`, then check `initData.Result.HasError()`. Errors from workspace loading, dependency install, and DB client creation are collected in `Result.ErrorAndWarnings` +- **Error display**: `error_helpers.ShowError(ctx, err)` and `error_helpers.FailOnError()` from pipe-fittings +- **Goroutine errors**: In `dashboardexecute`, child errors propagate via channels to parent nodes. No panic/recover in execution goroutines + +## Build Variables (injected via ldflags) + +| Variable | Dev Value | Release Value | +|----------|-----------|---------------| +| `main.version` | `0.0.0-dev-{branch}.{timestamp}` | Semver from git tag | +| `main.commit` | `none` | Git commit hash | +| `main.date` | `unknown` | Build timestamp | +| `main.builtBy` | `local` | `goreleaser` | + +Dev mode detection: `cmdconfig.IsLocal()` returns `true` when `builtBy == "local"`. diff --git a/.ai/pipe-fittings-detail.md b/.ai/pipe-fittings-detail.md new file mode 100644 index 00000000..bdb73f41 --- /dev/null +++ b/.ai/pipe-fittings-detail.md @@ -0,0 +1,173 @@ +# Pipe-Fittings Detailed Reference + +Pipe-fittings (`github.com/turbot/pipe-fittings/v2`) is the shared foundation library for Powerpipe, Flowpipe, Steampipe, and Tailpipe. + +## Package Map + +``` +pipe-fittings/ +├── modconfig/ HCL resource model (Mod, Variable, HclResource, ModTreeItem) +├── parse/ HCL parsing engine (Decoder, DecoderImpl, ModParseContext) +├── load_mod/ High-level mod loading orchestration +├── workspace/ Workspace abstraction (load mods, file watcher, variables) +├── backend/ Database backend interface (Postgres, MySQL, DuckDB, SQLite) +├── connection/ 40+ connection types (AWS, Azure, GCP, Slack, GitHub, ...) +├── credential/ 30+ credential types with lazy resolution +├── modinstaller/ Transactional mod dependency installation (git-based) +├── schema/ HCL block type constants and schema definitions +├── queryresult/ Query result streaming (Result, ColumnDef, RowResult) +├── export/ Export framework (JSON, CSV, snapshot) +├── printers/ CLI output formatting (table, JSON, YAML) +├── cmdconfig/ Cobra/Viper CLI flag binding (CmdBuilder) +├── steampipeconfig/ Snapshot types (SteampipeSnapshot, SnapshotPanel) +├── statushooks/ Progress reporting callbacks +├── constants/ Application-wide constants and env vars +├── utils/ General utilities (file, hash, JSON, collections) +├── error_helpers/ Error wrapping and formatting +├── hclhelpers/ HCL/CTY type conversions +├── cty_helpers/ CTY value helpers +├── filter/ PEG-based filter → SQL WHERE clause +├── filepaths/ Cross-platform path utilities +├── pipes/ Turbot Pipes cloud integration +├── plugin/ Steampipe plugin management +├── versionmap/ Semantic version resolution and lock files +├── ociinstaller/ OCI image downloading for plugins +├── secrets/ Secret detection and authentication +├── inputvars/ Variable validation and collection +├── options/ Execution options (query, dashboard, check) +├── perr/ Structured error types +├── cache/ TTL-based connection caching +└── sanitize/ Input sanitization +``` + +## Key Interfaces + +``` +modconfig.ModTreeItem Base interface for all executable resources +modconfig.HclResource Base interface for all HCL-defined resources +modconfig.Mod Root module container +modconfig.Variable Input variable with type validation +modconfig.ParamDef Parameter definition for queries +modconfig.ModResources Interface for resource collections + +backend.Backend Database backend (Connect, RowReader, Name) +backend.SearchPathProvider Search path for Steampipe/PostgreSQL +backend.SearchPathConfig Search path + prefix configuration +backend.BackendOption Configuration option for backends + +connection.ConnectionStringProvider Get connection string for a resource +connection.SearchPathProvider Search path from connection config + +parse.Decoder HCL block decoder interface +parse.DecoderImpl Base decoder with pluggable decode funcs +parse.ModParseContext Parsing state for a single mod + +queryresult.SyncQueryResult Complete query result (cols + rows) +queryresult.ColumnDef Column metadata (name, type) +queryresult.ResultStreamer Streaming result handler + +steampipeconfig.SteampipeSnapshot Dashboard execution snapshot +steampipeconfig.SnapshotPanel Individual panel data +steampipeconfig.SnapshotTreeNode Execution tree structure + +workspace.Workspace Base workspace (mod loading, file watcher) + +export.Manager Export format registry +export.Exporter Export implementation (JSON, CSV, snapshot) + +statushooks.* Progress reporting callbacks + +printers.Showable Objects supporting show command +printers.Listable Objects supporting list command +``` + +## How Powerpipe Extends Pipe-Fittings + +``` +pipe-fittings powerpipe +───────────── ───────── +workspace.Workspace ────▶ PowerpipeWorkspace + (mod loading, file watcher) + dashboard event handlers + + dashboard event channel + + PublishDashboardEvent() + + RegisterDashboardEventHandler() + + ResolveQueryFromQueryProvider() + +modconfig.ModResources ────▶ PowerpipeModResources + (interface for resource + Dashboards, DashboardCards, Charts, + collections) Tables, Texts, Graphs, Flows, ... + + Controls, Benchmarks + + Detections, DetectionBenchmarks + + Queries + + WalkResources(), AddResource() + +parse.DecoderImpl ────▶ PowerpipeModDecoder + (base HCL decoder) + custom decode for Dashboards + + custom decode for QueryProviders + + custom decode for NodeAndEdgeProviders + + custom decode for Benchmarks + + dynamic schema per resource type +``` + +## Usage by Powerpipe Component + +| Powerpipe Component | Top Pipe-Fittings Packages Used | Purpose | +|---------------------|-------------------------------|---------| +| `internal/resources/` (42 files) | modconfig, utils, cty_helpers, printers, schema | Resource type definitions | +| `internal/cmd/` (11 files) | constants, cmdconfig, error_helpers, modconfig | CLI command handlers | +| `internal/dashboardexecute/` (15 files) | steampipeconfig, modconfig, backend, connection | Dashboard execution engine | +| `internal/controlexecute/` (8 files) | steampipeconfig, modconfig, queryresult, schema | Control/benchmark execution | +| `internal/db_client/` (10 files) | backend, connection, constants, queryresult | Database client layer | +| `internal/cmdconfig/` (8 files) | cmdconfig, error_helpers, connection, parse | CLI config and flag handling | +| `internal/controldisplay/` (20 files) | constants, export, modconfig, filepaths | CLI output rendering | +| `internal/workspace/` (8 files) | workspace, modconfig, error_helpers, utils | Workspace wrapper | +| `internal/parse/` (5 files) | schema, modconfig, hclhelpers, parse | HCL parsing extensions | +| `internal/dashboardserver/` (6 files) | backend, connection, modconfig, steampipeconfig | WebSocket server | +| `internal/initialisation/` (2 files) | modconfig, backend, error_helpers, statushooks | Init orchestration | + +## Import Frequency (top 10) + +| Sub-Package | Imports | Importance | +|-------------|---------|------------| +| `modconfig` | 74 | CRITICAL - resource data model | +| `utils` | 62 | HIGH - utility functions | +| `constants` | 58 | HIGH - app constants | +| `error_helpers` | 34 | HIGH - error handling | +| `steampipeconfig` | 24 | HIGH - snapshot types | +| `schema` | 24 | HIGH - HCL schema | +| `cty_helpers` | 21 | MEDIUM - HCL type conversion | +| `printers` | 18 | MEDIUM - CLI output | +| `connection` | 17 | MEDIUM - DB connections | +| `statushooks` | 15 | MEDIUM - progress reporting | + +## Design Patterns + +- **Factory**: `backend.FromConnectionString()`, `modinstaller.NewModInstaller()` +- **Strategy**: Multiple backend implementations, exporters +- **Plugin Architecture**: Pluggable decoders, exporters, secret matchers +- **Visitor**: `WalkResources()` for mod traversal +- **Builder**: `CmdBuilder` for CLI setup, `ModParseContext` for parsing + +## Internal Dependency Graph + +``` +modconfig (resource definitions) + ↑ +parse (HCL parsing) + ↑ +load_mod (orchestration) + ↑ +workspace (runtime container) + ↑ +powerpipe/flowpipe (applications) + +connection/credential (data source config) + ↑ +backend (database abstraction) + ↑ +queryresult (execution results) + +modinstaller (dependency management) + ↑ +versionmap/ociinstaller (version/artifact handling) +``` diff --git a/.ai/testing-guide.md b/.ai/testing-guide.md new file mode 100644 index 00000000..f9854a87 --- /dev/null +++ b/.ai/testing-guide.md @@ -0,0 +1,222 @@ +# Testing Guide + +## Unit Tests (Go) + +### Running + +```bash +go test ./... # All unit tests +go test ./internal/controldisplay # Specific package +go test ./internal/resources -run TestName # Specific test +go test -v -cover ./... # Verbose with coverage +``` + +### Test Files (17 total) + +``` +internal/snapshot/snapshot_tag_test.go +internal/controldisplay/group_counter_graph_test.go +internal/controldisplay/formatter_template_test.go +internal/controldisplay/template_functions_test.go +internal/controldisplay/spacer_test.go +internal/controldisplay/result_status_test.go +internal/controldisplay/group_title_test.go +internal/controldisplay/group_counter_test.go +internal/controldisplay/result_reason_test.go +internal/controldisplay/formatter_test.go +internal/controlexecute/dimension_color_map_test.go +internal/resources/query_provider_impl_test.go +internal/resources/query_args_test.go +internal/workspace/lazy_fallback_test.go +internal/workspace/tag_filter_test.go +internal/workspace/resources_of_type_test.go +internal/parse/query_invocation_test.go +``` + +### Patterns + +Standard Go `testing` package only (no testify or other assertion libraries). + +**Table-driven tests** (most common): +```go +tests := map[string]struct { + input string + expected string +}{ + "case name": {input: "foo", expected: "bar"}, +} +for name, tt := range tests { + t.Run(name, func(t *testing.T) { + result := functionUnderTest(tt.input) + if result != tt.expected { + t.Fatalf("expected %s, got %s", tt.expected, result) + } + }) +} +``` + +**Assertions**: `reflect.DeepEqual()` for complex types, `t.Fatalf()` / `t.Errorf()` for failures. + +**Mocks**: Minimal test implementations of interfaces, created inline: +- `makeTaggedControl()` in `tag_filter_test.go` creates controls with specific tags +- `testFormatter` in `formatter_test.go` implements `Formatter` interface + +**Cleanup**: `defer os.RemoveAll()` for temp directories. + +### Key Test Files + +| File | What it tests | Scenarios | +|------|--------------|-----------| +| `resources/query_args_test.go` | `ResolveArgs()` | 30+ scenarios: named/positional args, defaults, runtime overrides, error cases | +| `workspace/tag_filter_test.go` | `ResourceFilterFromTagArgs()` | Tag-based resource filtering with mock controls | +| `controldisplay/formatter_test.go` | `NewFormatResolver()` | Export format resolution (snapshot, csv, json, asff, nunit3) | +| `parse/query_invocation_test.go` | Query parsing | SQL string vs named query resolution | + +--- + +## Acceptance Tests (BATS) + +### Running + +```bash +tests/acceptance/run-local.sh # All tests (starts/stops steampipe) +tests/acceptance/run-local.sh check.bats # Single test file +``` + +### Framework + +**BATS** (Bash Automated Testing System) with three libraries in `tests/acceptance/lib/`: +- `bats-core` - Core framework (test runner) +- `bats-assert` - 19 assertion functions +- `bats-support` - Support utilities + +Output format: TAP (Test Anything Protocol). + +### Prerequisites + +- **Steampipe service** must be running (`run-local.sh` handles this automatically) +- Required CLI tools: `jq`, `jd` (JSON diff), `sed`, `openssl`, `cksum`, and standard Unix tools +- Optional (CI): `SPIPETOOLS_PG_CONN_STRING`, `SPIPETOOLS_TOKEN` environment variables + +### Test Configuration + +| Setting | Value | +|---------|-------| +| `BATS_TEST_TIMEOUT` | 180 seconds | +| `BATS_NO_PARALLELIZE_WITHIN_FILE` | true (serial execution) | +| `STEAMPIPE_CONNECTION_WATCHER` | false | +| `STEAMPIPE_INTROSPECTION` | info | +| `POWERPIPE_DISPLAY_WIDTH` | 100 (for rendering tests) | + +### Test Files (15 files, 233 tests) + +| File | Purpose | +|------|---------| +| `check.bats` | Control/benchmark execution, exit codes, output formats | +| `dashboard.bats` | Dashboard execution and output | +| `dashboard_parsing_validation.bats` | HCL parsing validation | +| `database_precedence.bats` | Database config priority resolution | +| `config_precedence.bats` | Configuration priority | +| `config_path.bats` | Config path resolution | +| `backend.bats` | DuckDB and other backends | +| `mod.bats` | Mod install/dependency (**auto-generated, do NOT edit**) | +| `mod_install.bats` | Mod installation specific | +| `params_and_args.bats` | Parameter and argument resolution | +| `var_resolution.bats` | Variable resolution | +| `snapshot.bats` | Snapshot/export output | +| `resource_show_outputs.bats` | Resource display | +| `sp_files.bats` | Legacy .sp file support | +| `tag_filtering.bats` | Tag-based filtering | + +### Test Pattern + +```bash +load "$LIB_BATS_ASSERT/load.bash" +load "$LIB_BATS_SUPPORT/load.bash" + +@test "control run produces correct JSON output" { + cd $FUNCTIONALITY_TEST_MOD + run powerpipe control run my_control --output json + assert_equal $status 0 + assert_output --partial '"status": "ok"' +} + +@test "benchmark with alarms exits with code 1" { + cd $CHECK_ALL_MOD + run powerpipe benchmark run all_alarms + assert_equal $status 1 +} +``` + +### Common Assertions + +| Function | Purpose | +|----------|---------| +| `assert_equal $status ` | Check exit code | +| `assert_success` | Exit code 0 | +| `assert_failure` | Non-zero exit code | +| `assert_output ""` | Full stdout match | +| `assert_output --partial ""` | Partial stdout match | +| `assert_line` | Check specific output line | +| `assert_regex` | Regex match | + +### Test Data + +**53 test mods** in `tests/acceptance/test_data/mods/`: +- Core: `functionality_test_mod`, `check_all_mod` +- Control rendering: `control_rendering_test_mod` +- Dashboard variants: `dashboard_cards`, `dashboard_graphs`, `dashboard_inputs`, `dashboard_withs` +- Parsing: `dashboard_parsing_*` (3 variants) +- Database: `duckdb_mod`, `mod_with_db*` (7 variants) +- Variables: `test_workspace_mod_var_*` (4 variants) +- Special: `failure_test_mod`, `mod_with_blank_dimension_value`, `mod_with_list_param` + +**Expected outputs** in `test_data/templates/`: +- `expected_check_*.{csv,json,html,md,xml}` - Control output formats +- `expected_sps_*.json` - Dashboard snapshots +- `expected_*_title.txt` - Formatted display output + +**Helper scripts** in `test_data/scripts/`: +- `update_top_level_mod_version.sh` - Simulates mod version update +- `update_top_level_mod_commit.sh` - Simulates mod retagging + +### Test Generation + +`mod.bats` is auto-generated. Do NOT edit directly. + +```bash +make build-tests # Regenerate from JSON test cases +``` + +**Source**: `test_data/source_files/mod_test_cases.json` +**Template**: `test_data/templates/mod_test_template.bats.tmpl` +**Generator**: `tests/acceptance/test_generator/generate.go` + +### Environment Variables (set by `run.sh`) + +``` +BATS_PATH → lib/bats-core/bin/bats +LIB_BATS_ASSERT → lib/bats-assert +LIB_BATS_SUPPORT → lib/bats-support +TEST_DATA_DIR → test_data/templates +MODS_DIR → test_data/mods +SNAPSHOTS_DIR → test_data/snapshots +WORKSPACE_DIR → test_data/mods/sample_workspace +FUNCTIONALITY_TEST_MOD → test_data/mods/functionality_test_mod +CHECK_ALL_MOD → test_data/mods/check_all_mod +CONTROL_RENDERING_TEST_MOD → test_data/mods/control_rendering_test_mod +CONFIG_PARSING_TEST_MOD → test_data/mods/config_parsing_test_mod +``` + +--- + +## Frontend Tests + +```bash +cd ui/dashboard +yarn test # Jest + React Testing Library +yarn storybook # Component stories on http://localhost:6006 +``` + +Test files follow `*.test.ts` / `*.test.tsx` pattern. +Storybook stories follow `*.stories.@(js|jsx|ts|tsx)` pattern. diff --git a/CHANGELOG.md b/CHANGELOG.md index b46342f1..a91b699b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## v1.4.4 [2026-02-20] +_Dependencies_ +- Upgrade go and npm dependencies to remediate security vulnerabilities. + ## v1.4.3 [2026-02-12] _Dependencies_ - Upgrade go and npm dependencies to remediate vulnerabilities. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..4700ff0a --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,387 @@ +# Powerpipe + +Powerpipe is a CLI and dashboard server for DevOps. It runs dashboards, controls/benchmarks/detections, and queries, and serves a browser UI that renders dashboards and streams live execution via WebSocket. It targets local mods (HCL-defined resources) and Turbot Pipes cloud workspaces. + +**Detailed reference docs** (read on demand, not loaded by default): +- `.ai/dashboard-ui.md` - React/TypeScript frontend architecture, hooks, state, WebSocket protocol +- `.ai/testing-guide.md` - Unit tests, BATS acceptance tests, test data, test generation +- `.ai/environment-reference.md` - All env vars, exit codes, config precedence, file extensions, log levels +- `.ai/pipe-fittings-detail.md` - Full pipe-fittings package map, interfaces, import frequency +- `.ai/codebase-notes.md` - Detailed codebase walkthrough and key workflows + +## Architecture Overview + +``` +┌──────────────────────────────────────────────────────────────────────────┐ +│ User: powerpipe server / powerpipe benchmark run aws_compliance.cis │ +└──────────────┬───────────────────────────────────────────────────────────┘ + │ + ┌───────▼──────────┐ + │ Powerpipe CLI │ ← This repo (turbot/powerpipe) + │ (Cobra + Go) │ + └───────┬───────────┘ + │ Loads HCL mod + ┌───────▼──────────────┐ + │ Workspace / Mod │ ← pipe-fittings + internal/workspace + │ (dashboards, controls│ + │ benchmarks, queries)│ + └───────┬──────────────┘ + │ SQL queries + ┌───────▼──────────────┐ + │ Database Backend │ (Steampipe/PostgreSQL/MySQL/SQLite/DuckDB) + └──────────────────────┘ + │ + ┌───────▼──────────────┐ + │ Dashboard UI │ React 18 / TypeScript (Gin + WebSocket) + └──────────────────────┘ +``` + +### Initialization and Command Flow + +Every CLI command follows the same initialization pattern: + +``` +┌──────────────┐ ┌────────────────────────────────────────────────┐ +│ Cobra Command │────▶│ NewInitData[T]() │ +│ (cmd/*.go) │ │ T = Dashboard | Control | Query | Detection │ +└──────────────┘ └──────────────┬─────────────────────────────────┘ + │ + ┌──────────────▼──────────────────┐ + │ 1. LoadWorkspace() │ + │ pipe-fittings Workspace │ + │ + PowerpipeModDecoder (parse) │ + │ → PowerpipeModResources │ + ├─────────────────────────────────────┤ + │ 2. ResolveTargets[T]() │ + │ CLI args → actual resources │ + ├─────────────────────────────────────┤ + │ 3. Init() │ + │ ├─ Install mod dependencies │ + │ ├─ GetDefaultDatabaseConfig() │ + │ │ resolve: CLI > mod > default │ + │ ├─ NewDbClient() │ + │ │ → backend.FromConnectionString│ + │ ├─ ValidateModRequirements() │ + │ └─ Create DashboardExecutor │ + └─────────────────────────────────────┘ +``` + +### Dashboard Execution Flow + +``` +ExecuteDashboard(sessionId, rootResource, inputs) + │ + ▼ +┌─────────────────────────────────────────────────────────────┐ +│ DashboardExecutionTree │ +│ ├─ Root: DashboardRun (container) │ +│ │ ├─ LeafRun (card) ──── SQL ───▶ DbClient ──▶ Backend │ +│ │ ├─ LeafRun (chart) ──── SQL ───▶ DbClient ──▶ Backend │ +│ │ ├─ LeafRun (table) ──── SQL ───▶ DbClient ──▶ Backend │ +│ │ └─ LeafRun (graph) │ +│ │ ├─ with run (data provider) ── SQL ──▶ Backend │ +│ │ ├─ node run ── SQL(with args) ──────▶ Backend │ +│ │ └─ edge run ── SQL(with args) ──────▶ Backend │ +│ │ │ +│ ├─ Events published: │ +│ │ ExecutionStarted ──▶ WebSocket ──▶ UI │ +│ │ LeafNodeUpdated ──▶ WebSocket ──▶ UI (per panel) │ +│ │ ExecutionComplete ──▶ WebSocket ──▶ UI (snapshot) │ +│ │ │ +│ └─ ClientMap: connection pool keyed by connString+searchPath│ +└─────────────────────────────────────────────────────────────┘ +``` + +### Runtime Dependency Resolution + +Dashboard panels can depend on `with` blocks and `input` values via a publish-subscribe pattern: + +``` +DashboardRun (publisher) + │ + ├── publishes input values ────────────────────────┐ + │ │ + ├── LeafRun: "with.vpc_ids" (publisher) │ + │ └─ executes SQL, publishes result rows │ + │ │ │ + │ ▼ ▼ + ├── LeafRun: "chart.instances" (subscriber) │ + │ ├─ subscribes to "with.vpc_ids" channel │ + │ ├─ subscribes to "input.region" channel ◄──────┘ + │ ├─ waits for all dependency values + │ ├─ resolveSQLAndArgs() substitutes into SQL + │ └─ executeQuery() runs final SQL +``` + +### Dashboard Server Event Flow + +``` +┌──────────┐ WebSocket ┌──────────────┐ Event Bus ┌──────────────┐ +│ React UI │◄────────────▶│ Melody Server │◄───────────▶│ Executor │ +│ (browser) │ │ (Gin + WS) │ │ │ +└──────────┘ └──────────────┘ └──────────────┘ + +Client → Server: + {action: "request_dashboard", payload: {dashboard: "aws.dashboard.vpc"}} + {action: "update_input", payload: {inputs: {region: "us-east-1"}}} + +Server → Client: + {action: "execution_started", panels: {...}, layout: {...}} + {action: "leaf_node_updated", dashboard_node: {...}} + {action: "execution_complete", snapshot: {...}} + {action: "workspace_error", error: {...}} +``` + +## Pipe-Fittings Integration + +Pipe-fittings (`github.com/turbot/pipe-fittings/v2`) is the shared foundation library. Powerpipe imports 30+ sub-packages across 185+ Go files. The dependency is unidirectional. + +> Full package map, interface list, and import frequency: `.ai/pipe-fittings-detail.md` + +Powerpipe wraps and extends three key abstractions: + +``` +pipe-fittings powerpipe +───────────── ───────── +workspace.Workspace ────▶ PowerpipeWorkspace + (mod loading, file watcher) + dashboard event handlers/channel + + PublishDashboardEvent() + +modconfig.ModResources ────▶ PowerpipeModResources + (interface for resource + Dashboards, Cards, Charts, Tables, ... + collections) + Controls, Benchmarks, Detections, Queries + +parse.DecoderImpl ────▶ PowerpipeModDecoder + (base HCL decoder) + custom decode per resource type + + dynamic schema generation +``` + +## Resource Type Hierarchy + +``` +modconfig.HclResource (pipe-fittings) + │ + ├── modconfig.Mod, Variable, Local + │ + └── powerpipe resources (internal/resources/) + │ + ├── QueryProvider (interface: has SQL/Query/Args/Params) + │ ├── Query, Control, Detection + │ ├── DashboardCard, Chart, Table, Image, Text + │ └── NodeAndEdgeProvider (extends QueryProvider) + │ ├── DashboardGraph, DashboardFlow, DashboardHierarchy + │ + ├── WithProvider (has 'with' blocks) + ├── DashboardLeafNode (renderable panel) + ├── Benchmark (tree of Controls) + ├── DetectionBenchmark (tree of Detections) + ├── Dashboard, DashboardContainer, DashboardInput + └── DashboardCategory, DashboardEdge, DashboardNode +``` + +## Database Layer + +``` + backend.Backend (pipe-fittings) + │ + ┌────────────────┼────────────────┐ + │ │ │ + ┌───────▼──────┐ ┌──────▼───────┐ ┌──────▼──────┐ + │ Steampipe/ │ │ DuckDB │ │ MySQL │ + │ PostgreSQL │ │ │ │ │ + └──────────────┘ └──────────────┘ └─────────────┘ + ┌──────▼──────┐ + │ SQLite │ + └─────────────┘ + +DbClient (powerpipe wrapper around sql.DB + Backend) + ├── ExecuteSync(sql, args) → SyncQueryResult (blocks until complete) + └── Execute(sql, args) → Result with RowChan (streams rows) + +ClientMap (connection pool, keyed by connString + searchPathConfig) + ├── Default clients: shared, long-lived + └── Session clients: per-execution, closed after + +Database resolution priority (highest → lowest): + 1. Resource-level database/search_path + 2. Mod-level database/search_path + 3. Dependency mod database + 4. CLI --database flag + 5. Default connection +``` + +## Repository Map + +``` +powerpipe/ +├── main.go # Entry point +├── internal/ +│ ├── cmd/ # Cobra commands (server, mod, query, check, login, etc.) +│ ├── initialisation/ # Workspace loading, dependency install, DB client wiring +│ ├── controlinit/ # Formatter/executor wiring for control-like resources +│ ├── workspace/ # Powerpipe workspace wrapper around pipe-fittings +│ ├── resources/ # Powerpipe resource types (dashboards, controls, etc.) +│ ├── dashboardexecute/ # Dashboard/control/detection execution engine +│ ├── dashboardserver/ # Gin HTTP + Melody WebSocket server +│ ├── service/api/ # Gin setup, middleware, static asset serving +│ ├── db_client/ # Database/backend abstraction +│ ├── controlexecute/ # Control/benchmark/detection execution +│ ├── controlstatus/ # Control status formatting +│ ├── controldisplay/ # CLI output rendering +│ ├── dashboardassets/ # Embedded dashboard UI assets +│ ├── dashboardtypes/ # Execution state types +│ ├── dashboardevents/ # Event payloads for UI updates +│ ├── powerpipeconfig/ # Global config, pipeling connections +│ ├── parse/ # HCL schema/decoder for Powerpipe resources +│ ├── cmdconfig/ # CLI flag helpers +│ ├── constants/ # App constants, env vars +│ └── ... +├── ui/dashboard/ # React/TypeScript dashboard UI +├── tests/acceptance/ # BATS acceptance test suite +├── scripts/ # Build/test helper scripts +└── .ai/ # Detailed reference docs +``` + +## Development Guide + +### Building + +```bash +make build # Dev build with version ldflags → /usr/local/bin/powerpipe +go build -o powerpipe # Simple build without version injection +``` + +Dashboard assets (required for `powerpipe server` in dev): +```bash +cd ui/dashboard && yarn install && yarn build && make zip +``` + +### Testing + +```bash +go test ./... # Unit tests (17 files, Go testing package) +tests/acceptance/run-local.sh # Acceptance tests (15 BATS files, 233 tests) +tests/acceptance/run-local.sh check.bats # Single test file +``` + +> Full testing guide with patterns, test data, and BATS details: `.ai/testing-guide.md` + +### Local Development with Related Repos + +``` +pipe-fittings (shared library) + ↑ +powerpipe (depends on pipe-fittings) +``` + +Powerpipe's `go.mod` has a **commented-out replace directive**: + +```go +//replace github.com/turbot/pipe-fittings/v2 => ../pipe-fittings +``` + +Uncomment for local development against `../pipe-fittings`. **Re-comment before committing.** + +#### Cross-Repo Change Workflow + +1. Make the change in `pipe-fittings` first +2. Uncomment the replace directive in `powerpipe` +3. Build and test locally +4. Publish dependency (merge + tag) +5. `go get github.com/turbot/pipe-fittings/v2@v2.x.x` +6. Re-comment the replace directive +7. Commit and PR + +### Key Directories for Common Tasks + +| Task | Where to Look | +|------|--------------| +| Fix a CLI command | `internal/cmd/` + relevant `internal/` package | +| Fix dashboard execution | `internal/dashboardexecute/` | +| Fix control/benchmark run | `internal/controlexecute/`, `internal/controlinit/` | +| Fix query execution | `internal/cmd/query.go`, `internal/initialisation/` | +| Fix dashboard server | `internal/dashboardserver/`, `internal/service/api/` | +| Fix workspace loading | `internal/workspace/`, `internal/initialisation/` | +| Fix resource definitions | `internal/resources/` | +| Fix HCL parsing | `internal/parse/` | +| Fix DB client | `internal/db_client/` | +| Fix dashboard UI | `ui/dashboard/` (see `.ai/dashboard-ui.md`) | +| Fix display/export | `internal/controldisplay/`, `internal/display/` | +| Fix config | `internal/powerpipeconfig/`, `internal/cmdconfig/` | +| Add new resource type | `internal/resources/`, `internal/parse/mod_decoder.go`, `internal/parse/schema.go` | +| Change mod operations | pipe-fittings `modinstaller/` | +| Change event system | `internal/workspace/workspace_events.go`, `internal/dashboardevents/` | +| Change database config | `internal/db_client/database_config.go` | + +### Branching and Workflow + +- **Base branch**: `develop` for all work +- **Main branch**: `main` (releases merge here) +- **Release branch**: `v1.4.x` (or similar version branch) +- **PR titles**: End with `closes #XXXX` for bug fixes +- **Merge-to-develop PRs**: Title must be `Merge branch '' into develop` +- **Small PRs**: One logical change per PR + +## Gotchas + +- **Initialization order**: In `dashboardexecute/dashboard_run.go`, runs must be added to execution tree map **before** creating child runs (children look up parent by name) +- **Dashboard assets in dev**: `dashboardassets.Ensure()` checks at server startup. Missing `ui/dashboard/build/` fails the server. Fix: `cd ui/dashboard && yarn build` +- **`mod.bats` is auto-generated**: Do not edit `tests/acceptance/test_files/mod.bats` directly. Run `make build-tests` to regenerate +- **Steampipe service**: Required for acceptance tests. `run-local.sh` handles this, but manual test runs need `steampipe service start` first +- **Replace directive**: `go.mod` replace for pipe-fittings must remain commented in commits +- **Batch mode variables**: With `--input=false`, missing required variables cause immediate failure with no recovery +- **Runtime dependency deadlocks**: Circular `with` dependencies cause execution to hang. Validation should catch this, but be careful +- **Concurrent Viper access**: Background tasks receive config values as params, not via direct Viper reads, to avoid map access panics +- **Memory limit**: `POWERPIPE_MEMORY_MAX_MB` (default 1024) sets Go's `debug.SetMemoryLimit()` - affects GC, not a hard limit +- **Search path**: Non-existent schemas in search path cause runtime query failures, not parse-time errors + +## Release Process + +Follow these steps in order to perform a release: + +### 1. Changelog +- Draft a changelog entry in `CHANGELOG.md` matching the style of existing entries. +- Use today's date and the next patch version. + +### 2. Commit +- Commit message for release changelog changes should be the version number, e.g. `v1.4.3`. + +### 3. Release Issue +- Use the `.github/ISSUE_TEMPLATE/release_issue.md` template. +- Title: `Powerpipe v`, label: `release`. + +### 4. PRs +1. **Against `develop`**: Title should be `Merge branch '' into develop`. +2. **Against `main`**: Title should be `Release Powerpipe v`. + - Body format: + ``` + ## Release Issue + [Powerpipe v](link-to-release-issue) + + ## Checklist + - [ ] Confirmed that version has been correctly upgraded. + ``` + - Tag the release issue to the PR (add `release` label). + +### 5. powerpipe.io Changelog +- Create a changelog PR in the `turbot/powerpipe.io` repo. +- Branch off `main`, branch name: `pp-` (e.g. `pp-143`). +- Add a file at `content/changelog/-powerpipe-cli-v.md`. +- Frontmatter format: + ``` + --- + title: Powerpipe CLI v - + publishedAt: "T10:00:00" + permalink: powerpipe-cli-v + tags: cli + --- + ``` +- Body should match the changelog content from `CHANGELOG.md`. +- PR title: `Powerpipe CLI v`, base: `main`. + +### 6. Deploy powerpipe.io +- After the powerpipe.io changelog PR is merged, trigger the `Deploy powerpipe.io` workflow in `turbot/powerpipe.io` from `main`. + +### 7. Close Release Issue +- Check off all items in the release issue checklist as steps are completed. +- Close the release issue once all steps are done. diff --git a/go.mod b/go.mod index a7d5a82d..0ee006ce 100644 --- a/go.mod +++ b/go.mod @@ -63,7 +63,7 @@ require ( cloud.google.com/go/monitoring v1.24.0 // indirect cloud.google.com/go/storage v1.52.0 // indirect dario.cat/mergo v1.0.0 // indirect - filippo.io/edwards25519 v1.1.0 // indirect + filippo.io/edwards25519 v1.1.1 // indirect github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.29.0 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.51.0 // indirect diff --git a/go.sum b/go.sum index 2b7575b0..92a3853d 100644 --- a/go.sum +++ b/go.sum @@ -617,8 +617,8 @@ cloud.google.com/go/workflows v1.10.0/go.mod h1:fZ8LmRmZQWacon9UCX1r/g/DfAXx5VcP dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= -filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +filippo.io/edwards25519 v1.1.1 h1:YpjwWWlNmGIDyXOn8zLzqiD+9TyIlPhGFG96P39uBpw= +filippo.io/edwards25519 v1.1.1/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8= git.sr.ht/~sbinet/gg v0.3.1/go.mod h1:KGYtlADtqsqANL9ueOFkWymvzUvLMQllU5Ixo+8v3pc= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= diff --git a/ui/dashboard/package.json b/ui/dashboard/package.json index e2a0f119..e3c19750 100644 --- a/ui/dashboard/package.json +++ b/ui/dashboard/package.json @@ -140,14 +140,14 @@ "webpack-dev-server": "5.2.1", "js-yaml": "4.1.1", "glob": "10.5.0", - "qs": "6.14.1", + "qs": "6.14.2", "mdast-util-to-hast": "13.2.1", "on-headers": "1.1.0", - "tar": "7.5.7", + "tar": "7.5.8", "lodash-es": "4.17.23", "lodash": "4.17.23", "@remix-run/router": "1.23.2", - "jsonpath": "1.2.0" + "jsonpath": "1.2.1" }, "engines": { "node": ">=20", diff --git a/ui/dashboard/yarn.lock b/ui/dashboard/yarn.lock index 9a3a4de4..e3835427 100644 --- a/ui/dashboard/yarn.lock +++ b/ui/dashboard/yarn.lock @@ -11900,14 +11900,14 @@ __metadata: languageName: node linkType: hard -"jsonpath@npm:1.2.0": - version: 1.2.0 - resolution: "jsonpath@npm:1.2.0" +"jsonpath@npm:1.2.1": + version: 1.2.1 + resolution: "jsonpath@npm:1.2.1" dependencies: esprima: "npm:1.2.5" static-eval: "npm:2.1.1" underscore: "npm:1.13.6" - checksum: 10c0/730efd4b9b78d72b5fb03f53bd8246f19882aa5009895bd5c95fda5d9df19a21132ed3cc805f2c5ca25764718eac5a1a871b43e07804e993791c2f7f8f823d33 + checksum: 10c0/673d4e33c586c11eba16f19c212929fcf397d08f67341c7e2b70730b0c80f137ab18383f7a2e04622090fec065d979e19a714fc51e1b67412c989c855a1f2fc6 languageName: node linkType: hard @@ -15308,12 +15308,12 @@ __metadata: languageName: node linkType: hard -"qs@npm:6.14.1": - version: 6.14.1 - resolution: "qs@npm:6.14.1" +"qs@npm:6.14.2": + version: 6.14.2 + resolution: "qs@npm:6.14.2" dependencies: side-channel: "npm:^1.1.0" - checksum: 10c0/0e3b22dc451f48ce5940cbbc7c7d9068d895074f8c969c0801ac15c1313d1859c4d738e46dc4da2f498f41a9ffd8c201bd9fb12df67799b827db94cc373d2613 + checksum: 10c0/646110124476fc9acf3c80994c8c3a0600cbad06a4ede1c9e93341006e8426d64e85e048baf8f0c4995f0f1bf0f37d1f3acc5ec1455850b81978792969a60ef6 languageName: node linkType: hard @@ -17746,16 +17746,16 @@ __metadata: languageName: node linkType: hard -"tar@npm:7.5.7": - version: 7.5.7 - resolution: "tar@npm:7.5.7" +"tar@npm:7.5.8": + version: 7.5.8 + resolution: "tar@npm:7.5.8" dependencies: "@isaacs/fs-minipass": "npm:^4.0.0" chownr: "npm:^3.0.0" minipass: "npm:^7.1.2" minizlib: "npm:^3.1.0" yallist: "npm:^5.0.0" - checksum: 10c0/51f261afc437e1112c3e7919478d6176ea83f7f7727864d8c2cce10f0b03a631d1911644a567348c3063c45abdae39718ba97abb073d22aa3538b9a53ae1e31c + checksum: 10c0/8569db1b49f5d72084cbdcad9d2b39fcc115993186455aa052c1da0a2739b20e2d94af6a23609fc25d3ae63c9fed8b159f3b1d16b699e9ef25e3b8464603d153 languageName: node linkType: hard