feat: migrate AWS panel components into plugin directories (IW-243)#34
Merged
mguptahub merged 2 commits intoMay 6, 2026
Merged
Conversation
Move all 7 AWS service frontend panels from the main app repo into their plugin directories in the submodule, matching the GCP plugin pattern. Each plugin directory now ships its own Panel JSX and manifest.js for build-time discovery via setup-plugins.sh + generate-plugin-registry.js. Panels migrated: - ec2/EC2Panel.jsx + manifest.js - rds/RDSPanel.jsx + manifest.js - docdb/DocumentDBPanel.jsx + manifest.js - elasticache/ElastiCachePanel.jsx + manifest.js - lb/LBPanel.jsx + manifest.js - ses/SESPanel.jsx + manifest.js - secrets/SecretsPanel.jsx + manifest.js Import paths adjusted from ../x to ../../x to match the frontend/src/plugins/<slug>/ location after setup-plugins.sh copies them. AlertBanner and ResourceAlerts resolved via ../../components/.
Merged
6 tasks
…W-243) DatabasesPanel renders RDS + DocumentDB together under the "databases" service tab. It imports sibling plugins (./RDSPanel, ../docdb/DocumentDBPanel) and AlertBanner from the core app (../../components/AlertBanner), avoiding circular dependencies. rds/manifest.js updated to export DatabasesPanel (the composite) instead of RDSPanel directly, so the "databases" service tab renders both panels.
mguptahub
added a commit
that referenced
this pull request
May 11, 2026
* feat(gcp): add gcp-monitoring plugin manifest with monitoring.read scope and viewer role
* feat(gcp-iam): GCP Cloud IAM plugin — service accounts, IAM bindings, custom roles (IW-223)
Add plugin.json (gcp_scopes + gcp_roles), collector (IAM API), FastAPI router
at /api/gcp/iam, GcpIamPanel.jsx with service-account/roles table and drawer,
manifest.js registration, and 15 unit tests (all passing).
* fix(gcp-iam): update to gcp_credentials v2 API (IW-216/IW-223 rebase)
- Replace are_gcp_credentials_configured → are_credentials_configured
- Replace get_active_gcp_collector_regions → get_gcp_projects()
(new API returns [{"project_id": str}] dicts; extract project_id field)
- Update test_router.py mocks to match new function names and return types
Aligns gcp-iam plugin with the credential provider refactor from PR #150.
Co-Authored-By: Arun <arun@eyriehq.com>
* fix(gcp-iam): fix MetaItem to use drawer-meta-item/key/val design system classes
Replace bare <span className="meta-label"> with the canonical MetaItem
pattern from DESIGN.md: drawer-meta-item wrapper div + drawer-meta-key
label + drawer-meta-val value span. Ensures the drawer meta grid renders
correctly with the shared CSS grid layout.
Co-Authored-By: Arun <arun@eyriehq.com>
* feat(gcp-compute): GCP Compute Engine plugin — VM instances and persistent disks (IW-219)
Squash merge of feat/iw-219-gcp-compute. Adds gcp-compute plugin: collector, router, GcpComputePanel.jsx, manifest, 19 unit tests. Valkey binary client fix for GCP credential cache.
* feat(ec2): add root_device_name + volumes to collector, Boot column to router (IW-235)
Rebased onto release/0.14.0 (includes gcp-compute). Adds root_device_name and full volumes array to collector DB upsert, delete_on_termination to router, and root_device to detail response.
* fix(gcp-compute): show zone instead of self_link URL in drawer and metrics modal headers (IW-219)
* feat(gcp-billing): GCP Billing & Cost Management plugin (IW-224)
Adds gcp-billing plugin: collector (Cloud Billing API + BigQuery export path), router (/summary, /by-service, /trend, /projects), GcpBillingPanel.jsx, 28 unit tests. SetupBanner shown until BigQuery billing export is configured.
* fix(gcp-billing): change group from 'cost' to 'system' so it appears in sidebar (IW-224)
* fix(gcp-billing): auto-discover billing account + BQ dataset — no env vars required (IW-224)
* feat(gcp-compute): add Cloud Monitoring metrics collection and API endpoint (IW-236)
- collector.py: add collect_metrics() — incremental pull from Cloud Monitoring API
for CPU, memory, network in/out, disk read/write per VM instance; stores into
CollectedMetric with service_type='gcp-compute', resource_id=selfLink, region=project_id.
Uses ALIGN_MEAN for CPU/memory, ALIGN_SUM for network/disk; 1-hour buckets; 72 h window.
- plugin.json: add metrics_collector='collector:collect_metrics' and
https://www.googleapis.com/auth/monitoring.read scope + roles/monitoring.viewer.
- router.py: add GET /instances/metrics?resource_id=<selfLink>&hours=N endpoint
returning EC2-compatible JSON shape {instance_id, hours, period_seconds, metrics{…}}.
Co-Authored-By: Arun Engineer <arun@eyriehq.com>
* feat(gcp-compute): replace MetricChartStub with real recharts charts (IW-236)
- GcpComputePanel.jsx: replace MetricChartStub stub components with real
MetricChart + ChartTooltip (recharts LineChart pattern, same as EC2Panel).
- GcpMetricsModal: wire api.getGcpComputeMetrics(inst.self_link, hours) on
mount and hours change; show loading/error states.
- Renders CPU, Memory (empty note if no guest agent), Network Traffic
(merged in/out), Disk I/O (merged read/write) — same 1h/6h/24h/72h tabs.
- Adds formatBytes helper for network/disk axes.
Co-Authored-By: Surya Engineer <surya@eyriehq.com>
* fix: use em dash for null bytes in formatBytes (design system compliance)
Replace 'N/A' with '—' in formatBytes per DESIGN.md rule: missing/unavailable
values must show em dash, never 'N/A' or empty string.
* feat(gcp-memorystore): add Memorystore (Valkey) plugin scaffold (IW-222)
- plugin.json: registered as gcp connector, order=35, group=data
- collector.py: uses memorystore.googleapis.com/v1 REST API via httpx + Bearer token;
collects instances across all locations; Cloud Monitoring metrics via googleapiclient
(memory_usage, connected_clients, ops_per_sec, keyspace_hits/misses, hit_ratio)
- router.py: GET /instances, GET /instances/{id}/metrics, POST /refresh, GET /refresh/stream
- GcpMemorystorePanel.jsx: sortable table (Name|IP:Port|Engine|Size|State|Zone|Shards/Replicas|Auth|TLS),
detail drawer with connection/config/overview sections, metrics modal (4 charts)
- manifest.js: exports panel + Database icon
* fix(gcp-memorystore): remove unconditional invalidate_cache() calls (IW-237)
collect_resources() and collect_metrics() were calling invalidate_cache()
before get_gcp_credentials() on every Celery task run, nuking the 55-min
Valkey token cache each cycle and forcing a fresh token mint every time.
get_gcp_credentials() already handles expiry internally via _is_expired();
remove the manual invalidations so the cache is used as intended.
Co-Authored-By: Arun <arun@eyriehq.com>
* fix(gcp-memorystore): design system polish — bg-card, order 36 (IW-222)
- Replace undefined var(--bg-app) with var(--bg-card) in Connection drawer
- Fix order conflict: was 35 (same as gcp-billing), now 36
* feat(widgets): add dashboard widget config to gcp-compute and gcp-memorystore (IW-222)
Adds widget sections to both plugin.json files so they appear in the
Add Widget dialog. Uses region_key: project_id since GCP plugins store
project_id in CollectedMetric.region.
* fix(gcp-compute): use metric.labels.instance_name instead of invalid resource label
gce_instance resource labels are project_id, zone, and instance_id (numeric).
instance_name is NOT a valid resource label — using it caused all Cloud Monitoring
queries to return 0 results silently.
Fix: scope per-instance queries via metric.labels.instance_name (a metric label
on compute.googleapis.com metrics) and drop the invalid resource.labels.instance_name
from resource_filter.
Co-Authored-By: Arun <arun@eyriehq.com>
* fix(gcp-memorystore): use memorystore.googleapis.com/* metric namespace for Valkey
- Replace redis.googleapis.com/* metrics with memorystore.googleapis.com/instance/* equivalents
- Fix resource filter: use memorystore.googleapis.com/Instance (not redis_instance)
- Drop hit_ratio computation — separate hits/misses metrics unavailable in Valkey namespace
- Add cpu_utilization metric instead
Fixes IW-222
* feat(gcp-cloudsql): add Cloud SQL plugin — collector, router, frontend panel (IW-240)
- sqladmin.googleapis.com/v1 REST API via httpx + Bearer token
- Collects instance name, DB version, region/zone, tier, state, private/public IPs,
storage config, backup config, maintenance window, replica info
- Cloud Monitoring metrics: cpu_utilization, memory_usage, disk_bytes_used,
active_connections, queries_per_sec (cloudsql_database resource type)
- Router: GET /api/gcp/cloudsql/instances, metrics, refresh, SSE stream
- Frontend panel: sortable table, detail drawer with collapsible sections,
metrics modal with 5 charts and time range selector
- plugin.json: gcp connector, roles/cloudsql.viewer, widget config with all 5 metrics
* fix: Cloud SQL metric type + GCP refresh button consistency (IW-240) (#31)
* fix(gcp-cloudsql): use postgresql/transaction_count instead of non-existent /database/queries metric (IW-240)
* fix(gcp): remove text label from refresh buttons — icon-only to match EC2 style
GcpComputePanel and GcpBillingPanel had "Refresh"/"Refreshing…" text
alongside the icon. Remove the text so all GCP list panels are consistent
with the icon-only refresh button used on the EC2 panel.
Co-Authored-By: Surya <surya@eyriehq.com>
* fix(gcp): add showRefreshed 3-state to Compute and Billing refresh buttons
GcpComputePanel and GcpBillingPanel were missing the third refresh state
(Check icon + "Refreshed" text shown for 1500ms after refresh_done SSE).
Also switches both from es.onmessage+string-compare to the correct
es.addEventListener("refresh_done", ...) pattern used by all other panels.
---------
Co-authored-by: Arun Engineer <arun@eyriehq.com>
Co-authored-by: Surya <surya@eyriehq.com>
* feat: plugin registry-driven api block + GCP detail endpoints (IW-243) (#32)
* feat: add api blocks to all plugin.json manifests + GCP detail endpoints (IW-243)
- Add api block to every service plugin's plugin.json (ec2, rds, docdb, elasticache,
lb, secrets, ses, iam, eks, cost, mq, opensearch, gcp-compute, gcp-cloudsql,
gcp-memorystore, gcp-billing, gcp-iam) — declares endpoint templates for the
generic api.plugin(slug) client
- Add GET /instances/{id} detail endpoints to gcp-compute, gcp-cloudsql, gcp-memorystore
routers (previously only list and metrics existed)
- Update GCP panel DrawerDetail components to fetch fresh detail via the new detail
endpoint on open instead of using list-state data
- Update all GCP panel components to use api.plugin() instead of local fetchPlugin
helpers and removed api.getGcp* method calls
- Add PLUGIN_DEVELOPMENT.md at plugins root — the canonical guide for building new plugins
Co-Authored-By: Arun Engineer <arun@eyriehq.com>
* fix: prefix all AWS routes with /api/aws/ and make CloudSQL metrics flavor-aware (IW-243)
- Rename api_prefix in all 12 AWS plugin.json from /api/{svc} to /api/aws/{svc}
- Update widget.list_path and api block paths accordingly (ec2, rds, docdb,
elasticache, lb, cost, eks, mq, opensearch, secrets, ses, iam)
- Add api blocks to submodule plugin.json files for cost, eks, mq, opensearch, iam
- Update all hardcoded panel paths in EKSPanel, IAMPanel, MQPanel,
OpenSearchPanel, CostPanel to use /api/aws/ prefix
- Fix gcp-cloudsql collector.py: replace single postgresql transaction_count
metric with flavor-aware dispatch (POSTGRES_, MYSQL_, SQLSERVER_ prefixes);
unknown flavors fall back to common metrics only without erroring
* fix: update api block paths to /api/aws/ prefix in all AWS plugin.json files (IW-243)
Cherry-pick from wrong branch included api blocks with old /api/{svc}/ paths.
Update all plugin.json api block values to use /api/aws/{svc}/ prefix, consistent
with the api_prefix field and MGupta's review feedback.
---------
Co-authored-by: Arun Engineer <arun@eyriehq.com>
* feat(gcp-billing): fix SSE stream channel alignment and wire refresh/stream endpoint (IW-238) (#33)
- POST /refresh: use apply_async(countdown=0) and resolve billing account from DB
so the Valkey channel key matches what GET /refresh/stream subscribes to
- GET /refresh/stream: use same DB-resolved billing account fallback ('default')
to guarantee publish/subscribe pair alignment
- Add tests for POST /refresh (503 guard, task dispatch, channel key fallback)
and GET /refresh/stream (content-type check)
Co-authored-by: Arun Engineer <arun@eyriehq.com>
* feat: migrate AWS panel components into plugin directories (IW-243) (#34)
* feat: migrate AWS panel components into plugin directories (IW-243)
Move all 7 AWS service frontend panels from the main app repo into
their plugin directories in the submodule, matching the GCP plugin
pattern. Each plugin directory now ships its own Panel JSX and
manifest.js for build-time discovery via setup-plugins.sh +
generate-plugin-registry.js.
Panels migrated:
- ec2/EC2Panel.jsx + manifest.js
- rds/RDSPanel.jsx + manifest.js
- docdb/DocumentDBPanel.jsx + manifest.js
- elasticache/ElastiCachePanel.jsx + manifest.js
- lb/LBPanel.jsx + manifest.js
- ses/SESPanel.jsx + manifest.js
- secrets/SecretsPanel.jsx + manifest.js
Import paths adjusted from ../x to ../../x to match the
frontend/src/plugins/<slug>/ location after setup-plugins.sh copies
them. AlertBanner and ResourceAlerts resolved via ../../components/.
* feat: add DatabasesPanel composite + fix rds manifest to export it (IW-243)
DatabasesPanel renders RDS + DocumentDB together under the "databases" service tab.
It imports sibling plugins (./RDSPanel, ../docdb/DocumentDBPanel) and AlertBanner
from the core app (../../components/AlertBanner), avoiding circular dependencies.
rds/manifest.js updated to export DatabasesPanel (the composite) instead of
RDSPanel directly, so the "databases" service tab renders both panels.
---------
Co-authored-by: Arun Engineer <arun@eyriehq.com>
* feat(iam): use ShieldCheck icon to differentiate AWS IAM from GCP Cloud IAM (IW-244) (#35)
Co-authored-by: Arun Engineer <arun@eyriehq.com>
Co-authored-by: Surya <surya@eyriehq.com>
* fix(gcp-billing): thread actual currency from BQ through API and frontend (IW-246) (#36)
* fix(gcp-billing): thread actual currency from BQ through API and frontend (IW-246)
- BQ query selects ANY_VALUE(currency) per (month, service) row; stored in attrs
- _upsert_no_spend_data adds "currency": "USD" sentinel default
- summary/by-service endpoints read currency from attrs instead of hardcoding USD
- fmtUSD/fmtUSDShort accept currency param (default "USD")
- fmtUSDShort rewritten with Intl.NumberFormat compact notation (handles non-USD symbols)
- CostTooltip accepts currency prop; all YAxis tickFormatter and table call sites threaded
- Sync submodule JSX with latest frontend: Check icon, showRefreshed state, SSE addEventListener
* fix(gcp-billing): pass GCP project ID (not billing account ID) to refresh Celery task (IW-246)
---------
Co-authored-by: Surya <surya@eyriehq.com>
Co-authored-by: Arun <arun@eyriehq.com>
* feat(gcp-gke): GKE plugin — clusters, nodes, metrics (IW-218) (#38)
* feat(gcp-gke): add GKE plugin — collector, router, frontend panel (IW-218)
Collects GKE clusters and node pools via container.googleapis.com v1
(projects.locations.clusters.list with locations/-). Cloud Monitoring
metrics: cpu/memory allocatable utilization, container restart rate,
pod volume total. Tested against cluster-1 in asia-south1-a
(glass-effect-495104-d3): 1 cluster, 1 node pool (e2-medium/default-pool),
56 metric points collected — CPU ~22.7%, Memory ~17.9% utilization.
GcpGkePanel: sortable cluster table, detail drawer with node pool table,
metrics modal with 1h/6h/24h/72h tabs, 3-state refresh button.
* feat(gcp-gke): add per-node drawer and metrics modal (IW-218)
- GET /clusters/{id}/nodes/{name}/metrics — k8s_node Cloud Monitoring
metrics per node (cpu/memory allocatable utilization, network rx/tx)
- GkeNodesModal: clickable rows open GkeNodeDetailDrawer
- GkeNodeDetailDrawer: overview (pool, machine, zone, IP, version) + Metrics button
- GkeNodeMetricsModal: 4 charts with 1h/6h/24h/72h range tabs
- Escape key sequence: metrics → node drawer → nodes list
---------
Co-authored-by: Arun <arun@eyriehq.com>
* feat(gcp-lb): Cloud Load Balancing plugin + cross-plugin fixes (IW-221) (#39)
* feat(gcp-lb): add GCP Cloud Load Balancing plugin (IW-221)
Collects forwarding rules with backend health via GCP Compute API,
exposes REST endpoints for list/detail/metrics, and renders a sortable
panel with health-status badges and a Cloud Monitoring metrics modal.
Live test against test-lb (glass-effect-495104-d3 / asia-south1):
- 1 LB returned: test-lb, IP 35.207.193.109, TCP, EXTERNAL, port 80
- 1 backend: gke-cluster-1-default-pool-c4a4de25-grp (asia-south1-a), UNHEALTHY
- Overall health: UNHEALTHY (backend health check correctly propagated)
Co-Authored-By: Arun <arun@eyriehq.com>
* fix(gcp-lb): use name as resource_id (not selfLink), move to compute group (IW-221)
* fix(gcp-compute): include resource_id in instance list response (metrics endpoint fix)
* fix: route order (compute metrics), lb_id path greed, gcp-iam requires_mfa
* feat: require MFA for IAM and Billing plugins across all cloud providers
---------
Co-authored-by: Arun <arun@eyriehq.com>
* feat(gcp-secret-manager): GCP Secret Manager plugin (IW-247) (#41)
* feat(gcp-secret-manager): add GCP Secret Manager plugin — collector, router, frontend panel (IW-247)
Collects all secrets and their versions via secretmanager.googleapis.com v1.
Stores replication policy, version count, latest version state, labels, and
rotation config. Panel shows sortable table with detail drawer including
versions table and labels section. No metrics collector (sparse data, v1).
* feat(gcp-secret-manager): AWS parity — Load Value, RelativeTime, CopyButton, AgeBadge; fix(gcp-gke): widget resource_id_key → full path so dashboard metrics resolve correctly (IW-247)
---------
Co-authored-by: Arun <arun@eyriehq.com>
* feat(iw-248): reorganise plugins into aws/, gcp/, observability/ vendor groups (#43)
* feat(iw-248): reorganise plugins into aws/, gcp/, observability/ groups; update names to group/plugin format; add READMEs
- Move 12 AWS plugins into aws/ group
- Move 5 GCP plugins into gcp/ (dropping gcp- prefix in dir names)
- Move 3 observability plugins into observability/
- hello-world and gcp-monitoring remain at root (stubs, no group yet)
- Update plugin.json name fields to group/name format (e.g. aws/ec2, gcp/compute)
- Update services arrays to match new names
- Fix JSX relative imports: ../../ -> ../../../ for api/client, hooks/useData, constants, components/
- Add README.md to every plugin directory
- Add group-level README.md for aws/, gcp/, observability/
* fix(iw-248): move gcp-gke, gcp-lb, gcp-secret-manager into gcp/ group; update names and JSX imports
* fix(iw-248): revert JSX imports to ../../ — plugins copy flat to src/plugins/{name}/ in the build
* fix(iw-248): observability plugins — use parent.parent.parent for _shared path after moving one level deeper
* fix: GCP collectors always use configured project_id, not AWS region arg
collect_tasks.collect_metrics() iterates AWS regions (ap-south-1, us-east-1)
and passes them as the `region` parameter to every plugin metrics collector,
including GCP ones. All GCP collectors used `region if region else gcp.get(
"project_id")` — so the AWS region string silently became the GCP project ID,
causing all GCP metric and resource queries to fail silently (empty results).
Fix: use gcp.get("project_id", "") directly in all 13 GCP collector call-sites
across billing, cloud-sql, compute, gke, gke-metrics, iam, lb, lb-metrics,
memorystore, memorystore-metrics, secret-manager. The region param is still
accepted in the function signature for API compatibility but is no longer used
as project_id.
* fix: update services field in aws/lb and aws/rds plugin.json to namespaced names
aws/lb: services was ['elb'] (historic ELB name) — update to ['aws/lb']
aws/rds: services was ['databases'] (historic name) — update to ['aws/rds']
The IW-248 reorg correctly updated the 'name' field but missed updating the
'services' field in these two plugins, causing the plugin loader to register
them under old service_type keys, mismatching the rest of the namespaced system.
* fix(iw-248): update SERVICE_TYPE constants and inline service_type strings to namespaced format
IW-248 reorg updated plugin.json name/services fields but missed the Python
code entirely. Every collector.py and router.py had hardcoded old strings:
gcp-compute, gcp-gke, gcp-lb, gcp-iam, gcp-billing, gcp-memorystore,
gcp-cloudsql, gcp-secret-manager (GCP)
elb, databases, opensearch, secrets, iam, eks, mq, docdb, elasticache (AWS)
These are used when storing CollectedResource/CollectedMetric rows and when
queuing collect_gcp_resources tasks on refresh — causing 'no collector for
gcp-compute' warnings and all collected data stored under old service_type
keys that no frontend panel could resolve.
26 files updated. No logic changed, string constants only.
* fix: add api block to memorystore and cloud-sql plugin.json
Both plugins were missing the 'api' block so plugin-registry.js never
registered them in _pluginApiMap — causing 'api block not loaded' in
the panel. Added correct api.list/detail/metrics/refresh/stream paths
matching their router endpoints.
* fix(billing): SSE channel mismatch + 5-min timeout on empty-DB refresh
post_refresh was dispatching collect_gcp_resources with project_id while the
SSE stream subscribed on billing_account_id (or 'default' when DB empty).
The publish/subscribe channels never matched on first refresh — user waited
5 minutes for the fallback timeout before data appeared.
Fix: dispatch task with bid ('default' when DB empty) so publish and subscribe
keys always match. Also reduce billing refresh timeout from 5 min to 30s —
BQ queries complete in seconds, not minutes.
* fix: AWS router collect_resources.delay calls updated to namespaced service names
All 10 AWS plugin routers were queuing collect_resources.delay with old
flat names (ec2, elb, databases, eks, iam, mq, docdb, elasticache, opensearch,
secrets). These were missed in the IW-248 reorg — same pattern as the
collector/collector.py SERVICE_TYPE constants fixed earlier.
Refresh button in any AWS panel was queuing the task with the old name,
causing 'no plugin collector for ec2' warnings on every manual refresh.
* fix: AWS router/collector service_type DB query strings updated to namespaced names
38 occurrences of service_type == "ec2", "elb", "databases", "eks", "iam",
"mq", "docdb", "elasticache", "opensearch", "secrets", "ses", "cost"
in AWS router and collector files updated to "aws/ec2", "aws/lb", "aws/rds"
etc.
These were used in CollectedResource/CollectedMetric DB filter queries and
in SSE stream channel keys. Mismatch with the namespaced service_type now
stored by the collector caused:
- Panels returning empty data (query found 0 rows)
- Refresh not updating frontend (SSE channel mismatch → no refresh_done event)
* fix: EC2 collector service_type assignments missed in batch fix — now aws/ec2
* fix: AWS router SSE refresh channel strings updated to namespaced names
All 10 AWS routers had hardcoded old service names in their SSE channel keys:
refresh:ec2:{region}, refresh:elb:{region}, refresh:databases:{region}, ...
The Celery task (_publish_refresh_done) was publishing to refresh:aws/ec2:...
but the stream endpoint was subscribing to refresh:ec2:... → events never
delivered → panel waits for timeout then needs page reload to show new data.
GCP routers were already correct (they use f'refresh:{SERVICE_TYPE}:{pid}'
with the variable, not hardcoded strings).
* fix: aws/rds plugin registers RDSPanel directly, not composite DatabasesPanel
DatabasesPanel was a pre-IW-248 composite that rendered both RDS and
DocumentDB in one view. Now that DocumentDB has its own aws/docdb plugin,
the Databases sidebar entry should show only RDS data.
manifest.js now imports RDSPanel instead of DatabasesPanel.
---------
Co-authored-by: Arun <arun@eyriehq.com>
* fix: _metrics_start_end service_type args updated to namespaced names in all AWS collectors
All 8 AWS metric collectors called _metrics_start_end(db, 'ec2', ...) with
old flat names. _last_metric_timestamp queries collected_metrics by service_type,
but data is now stored with 'aws/ec2' etc. This caused the timestamp lookup to
always return None → always fetches full 72h window → re-upserts stale data
instead of incrementally fetching new CloudWatch datapoints.
Fixed: ec2, lb (elb), rds, eks, mq, docdb, elasticache, opensearch
* fix: EC2 metrics collection period 3600→300 (5-min granularity)
Using 1-hour period with a 1h widget range produces exactly 1 datapoint —
a dot, not a line. All other AWS collectors use 300s (5-min). EC2 now matches,
giving 12 datapoints/hour for proper chart rendering.
---------
Co-authored-by: Arun <arun@infrawatchlabs.com>
Co-authored-by: Arun <arun@eyriehq.com>
Co-authored-by: eyriehq-bot[bot] <269943525+eyriehq-bot[bot]@users.noreply.github.com>
Co-authored-by: Surya Engineer <surya@eyriehq.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
frontend/src/components/and into their respective plugin directories in this submodulemanifest.jsto each AWS plugin sosetup-plugins.sh+generate-plugin-registry.jsauto-discover them at build time../xto../../xto matchfrontend/src/plugins/<slug>/after setup-plugins.sh copies themPanels migrated
ec2/EC2Panel.jsxmanifest.js(icon: Server)rds/RDSPanel.jsxmanifest.js(icon: Database)docdb/DocumentDBPanel.jsxmanifest.js(icon: Database)elasticache/ElastiCachePanel.jsxmanifest.js(icon: HardDrive)lb/LBPanel.jsxmanifest.js(icon: Network)ses/SESPanel.jsxmanifest.js(icon: Mail)secrets/SecretsPanel.jsxmanifest.js(icon: KeyRound)Import changes
../api/client→../../api/client../hooks/useData→../../hooks/useData../hooks/useSubTab→../../hooks/useSubTab../constants→../../constants../plugin-registry→../../plugin-registry./AlertBanner→../../components/AlertBanner./ResourceAlerts→../../components/ResourceAlertsAll API calls already use
api.plugin(slug).*— no hardcoded paths to migrate.Test plan
npm run buildin frontend — all 7 AWS plugins should appear in generated registrydocker compose build frontendpasses clean