diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 88adf46f..4ec8e692 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -12,6 +12,7 @@ /plugins/CodeRabbit/ @TimWheeler-SQUP /plugins/DattoRMM/ @TimWheeler-SQUP /plugins/DigiCert/ @shaswot77 +/plugins/DigitalOcean/ @clarkd /plugins/FantasyPremierLeague/ @TimWheeler-SQUP /plugins/GoogleSheets/ @kieranlangton /plugins/Huntress/ @Deenk diff --git a/plugins/DigitalOcean/v1/configValidation.json b/plugins/DigitalOcean/v1/configValidation.json new file mode 100644 index 00000000..8aaea53b --- /dev/null +++ b/plugins/DigitalOcean/v1/configValidation.json @@ -0,0 +1,11 @@ +{ + "steps": [ + { + "displayName": "Authenticate", + "dataStream": { "name": "account" }, + "required": true, + "error": "Could not authenticate with DigitalOcean. Check that the personal access token is valid, has not expired, and has the account:read scope.", + "success": "Connected to DigitalOcean successfully." + } + ] +} diff --git a/plugins/DigitalOcean/v1/correlationRules/relate-agent-session-to-environment.json b/plugins/DigitalOcean/v1/correlationRules/relate-agent-session-to-environment.json new file mode 100644 index 00000000..e7ccd852 --- /dev/null +++ b/plugins/DigitalOcean/v1/correlationRules/relate-agent-session-to-environment.json @@ -0,0 +1,20 @@ +{ + "displayName": "Environment runs Agent Session", + "source": { + "types": "Agent Session" + }, + "target": { + "types": "Environment" + }, + "conditions": [ + { + "sourceProperty": "configId", + "operator": "equals", + "targetProperty": "rawId" + } + ], + "labels": { + "forward": "started from", + "reverse": "runs" + } +} diff --git a/plugins/DigitalOcean/v1/correlationRules/relate-droplet-to-kubernetes-cluster.json b/plugins/DigitalOcean/v1/correlationRules/relate-droplet-to-kubernetes-cluster.json new file mode 100644 index 00000000..81a0e689 --- /dev/null +++ b/plugins/DigitalOcean/v1/correlationRules/relate-droplet-to-kubernetes-cluster.json @@ -0,0 +1,20 @@ +{ + "displayName": "Kubernetes Cluster has Droplet as node", + "source": { + "types": "Droplet" + }, + "target": { + "types": "Kubernetes Cluster" + }, + "conditions": [ + { + "sourceProperty": "kubernetesClusterId", + "operator": "equals", + "targetProperty": "rawId" + } + ], + "labels": { + "forward": "node of", + "reverse": "has node" + } +} diff --git a/plugins/DigitalOcean/v1/correlationRules/relate-load-balancer-to-droplet.json b/plugins/DigitalOcean/v1/correlationRules/relate-load-balancer-to-droplet.json new file mode 100644 index 00000000..0021caf4 --- /dev/null +++ b/plugins/DigitalOcean/v1/correlationRules/relate-load-balancer-to-droplet.json @@ -0,0 +1,20 @@ +{ + "displayName": "Load Balancer routes to Droplet", + "source": { + "types": "Load Balancer" + }, + "target": { + "types": "Droplet" + }, + "conditions": [ + { + "sourceProperty": "primaryBackendDropletId", + "operator": "equals", + "targetProperty": "rawId" + } + ], + "labels": { + "forward": "routes to", + "reverse": "receives traffic from" + } +} diff --git a/plugins/DigitalOcean/v1/correlationRules/relate-resources-to-project.json b/plugins/DigitalOcean/v1/correlationRules/relate-resources-to-project.json new file mode 100644 index 00000000..89eab037 --- /dev/null +++ b/plugins/DigitalOcean/v1/correlationRules/relate-resources-to-project.json @@ -0,0 +1,30 @@ +{ + "displayName": "Project contains resources", + "source": { + "types": ["Droplet", "App", "Kubernetes Cluster", "Database", "Load Balancer", "Agent"] + }, + "bridge": { + "types": "Project Resource" + }, + "target": { + "types": "Project" + }, + "sourceConditions": [ + { + "sourceProperty": "rawId", + "operator": "equals", + "targetProperty": "resourceId" + } + ], + "targetConditions": [ + { + "sourceProperty": "projectId", + "operator": "equals", + "targetProperty": "rawId" + } + ], + "labels": { + "forward": "in project", + "reverse": "contains" + } +} diff --git a/plugins/DigitalOcean/v1/correlationRules/relate-resources-to-vpc.json b/plugins/DigitalOcean/v1/correlationRules/relate-resources-to-vpc.json new file mode 100644 index 00000000..04e87eb8 --- /dev/null +++ b/plugins/DigitalOcean/v1/correlationRules/relate-resources-to-vpc.json @@ -0,0 +1,20 @@ +{ + "displayName": "VPC contains resources", + "source": { + "types": ["Droplet", "Kubernetes Cluster", "Load Balancer", "Database"] + }, + "target": { + "types": "VPC" + }, + "conditions": [ + { + "sourceProperty": "vpcUuid", + "operator": "equals", + "targetProperty": "rawId" + } + ], + "labels": { + "forward": "in", + "reverse": "contains" + } +} diff --git a/plugins/DigitalOcean/v1/correlationRules/relate-trigger-to-agent-session.json b/plugins/DigitalOcean/v1/correlationRules/relate-trigger-to-agent-session.json new file mode 100644 index 00000000..c35e9c71 --- /dev/null +++ b/plugins/DigitalOcean/v1/correlationRules/relate-trigger-to-agent-session.json @@ -0,0 +1,20 @@ +{ + "displayName": "Trigger is bound to Agent Session", + "source": { + "types": "Trigger" + }, + "target": { + "types": "Agent Session" + }, + "conditions": [ + { + "sourceProperty": "boundSessionId", + "operator": "equals", + "targetProperty": "rawId" + } + ], + "labels": { + "forward": "bound to", + "reverse": "driven by" + } +} diff --git a/plugins/DigitalOcean/v1/custom_types.json b/plugins/DigitalOcean/v1/custom_types.json new file mode 100644 index 00000000..4864ec38 --- /dev/null +++ b/plugins/DigitalOcean/v1/custom_types.json @@ -0,0 +1,93 @@ +[ + { + "name": "Account", + "sourceType": "Account", + "icon": "building", + "singular": "Account", + "plural": "Accounts" + }, + { + "name": "Droplet", + "sourceType": "Droplet", + "icon": "server", + "singular": "Droplet", + "plural": "Droplets" + }, + { + "name": "App", + "sourceType": "App", + "icon": "rocket", + "singular": "App", + "plural": "Apps" + }, + { + "name": "Kubernetes Cluster", + "sourceType": "Kubernetes Cluster", + "icon": "dharmachakra", + "singular": "Kubernetes Cluster", + "plural": "Kubernetes Clusters" + }, + { + "name": "Database", + "sourceType": "Database", + "icon": "database", + "singular": "Database", + "plural": "Databases" + }, + { + "name": "Load Balancer", + "sourceType": "Load Balancer", + "icon": "network-wired", + "singular": "Load Balancer", + "plural": "Load Balancers" + }, + { + "name": "Agent", + "sourceType": "Agent", + "icon": "robot", + "singular": "Agent", + "plural": "Agents" + }, + { + "name": "VPC", + "sourceType": "VPC", + "icon": "cloud", + "singular": "VPC", + "plural": "VPCs" + }, + { + "name": "Project", + "sourceType": "Project", + "icon": "folder-open", + "singular": "Project", + "plural": "Projects" + }, + { + "name": "Project Resource", + "sourceType": "Project Resource", + "icon": "link", + "singular": "Project Resource", + "plural": "Project Resources" + }, + { + "name": "Environment", + "sourceType": "Environment", + "icon": "cube", + "singular": "Environment", + "plural": "Environments" + }, + { + "name": "Agent Session", + "sourceType": "Agent Session", + "icon": "terminal", + "singular": "Agent Session", + "plural": "Agent Sessions" + }, + { + "name": "Trigger", + "sourceType": "Trigger", + "icon": "bolt", + "singular": "Trigger", + "plural": "Triggers" + } +] diff --git a/plugins/DigitalOcean/v1/dataStreams/account.json b/plugins/DigitalOcean/v1/dataStreams/account.json new file mode 100644 index 00000000..5857a335 --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/account.json @@ -0,0 +1,92 @@ +{ + "name": "account", + "displayName": "Account", + "description": "The DigitalOcean account and team the token belongs to, with its status and resource limits", + "tags": [ + "Account" + ], + "baseDataSourceName": "httpRequestUnscoped", + "visibility": { + "type": "hidden" + }, + "config": { + "httpMethod": "get", + "endpointPath": "v2/account", + "pathToData": "account", + "expandInnerObjects": true + }, + "matches": "none", + "metadata": [ + { + "name": "team.uuid", + "displayName": "Team ID", + "shape": "string", + "visible": false + }, + { + "name": "team.name", + "displayName": "Team", + "shape": "string", + "role": "label" + }, + { + "name": "email", + "displayName": "Email", + "shape": "string" + }, + { + "name": "status", + "displayName": "Status", + "shape": "string" + }, + { + "name": "health", + "displayName": "Health", + "computed": true, + "valueExpression": "{{ $['status'] }}", + "shape": [ + "state", + { + "map": { + "success": [ + "active" + ], + "warning": [ + "warning" + ], + "error": [ + "locked" + ] + } + } + ] + }, + { + "name": "status_message", + "displayName": "Status Message", + "shape": "string" + }, + { + "name": "droplet_limit", + "displayName": "Droplet Limit", + "shape": "number" + }, + { + "name": "floating_ip_limit", + "displayName": "Reserved IP Limit", + "shape": "number" + }, + { + "name": "email_verified", + "displayName": "Email Verified", + "shape": "boolean" + }, + { + "name": "uuid", + "displayName": "User ID", + "shape": "string", + "visible": false + } + ], + "timeframes": false +} diff --git a/plugins/DigitalOcean/v1/dataStreams/agentSessions.json b/plugins/DigitalOcean/v1/dataStreams/agentSessions.json new file mode 100644 index 00000000..bf874777 --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/agentSessions.json @@ -0,0 +1,143 @@ +{ + "name": "agentSessions", + "displayName": "Agent Sessions", + "description": "Harness Runtime sessions with their status, agent kind and last activity (destroyed sessions excluded)", + "tags": [ + "AI", + "Inventory" + ], + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "get", + "endpointPath": "v2/agents/sessions", + "postRequestScript": "agentSessions.js", + "getArgs": [ + { + "key": "page_size", + "value": "200" + } + ] + }, + "matches": "none", + "ui": [ + { + "type": "objects", + "name": "environment", + "label": "Environment (optional)", + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "Environment" + ] + } + } + } + ], + "metadata": [ + { + "name": "id", + "displayName": "ID", + "shape": "string", + "visible": false + }, + { + "name": "name", + "displayName": "Name", + "shape": "string", + "role": "label" + }, + { + "name": "status", + "displayName": "Status", + "shape": "string" + }, + { + "name": "health", + "displayName": "Health", + "computed": true, + "valueExpression": "{{ $['status'] }}", + "shape": [ + "state", + { + "map": { + "success": [ + "READY" + ], + "warning": [ + "PROVISIONING", + "DESTROYING" + ], + "error": [ + "FAILED", + "LOCKED" + ], + "unknown": [ + "PAUSED", + "DETACHED", + "UNSPECIFIED" + ] + } + } + ] + }, + { + "name": "agentKind", + "displayName": "Agent", + "shape": "string" + }, + { + "name": "pauseReason", + "displayName": "Pause Reason", + "shape": "string" + }, + { + "name": "warnings", + "displayName": "Warnings", + "shape": [ + "array", + { + "itemShape": "string" + } + ] + }, + { + "name": "keepWarm", + "displayName": "Keep Warm", + "shape": "boolean" + }, + { + "name": "idleTimeoutSeconds", + "displayName": "Idle Timeout", + "shape": "seconds" + }, + { + "name": "createdAt", + "displayName": "Created", + "shape": "date" + }, + { + "name": "lastEventAt", + "displayName": "Last Activity", + "shape": "date" + }, + { + "name": "configId", + "displayName": "Environment ID", + "shape": "string", + "visible": false + }, + { + "name": "parentSessionId", + "displayName": "Parent Session ID", + "shape": "string", + "visible": false + }, + { + "sourceId": "id", + "sourceType": "Agent Session", + "name": "name" + } + ], + "timeframes": false +} diff --git a/plugins/DigitalOcean/v1/dataStreams/agentUsage.json b/plugins/DigitalOcean/v1/dataStreams/agentUsage.json new file mode 100644 index 00000000..03afe30a --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/agentUsage.json @@ -0,0 +1,68 @@ +{ + "name": "agentUsage", + "displayName": "Agent Usage", + "description": "Token usage of a Gradient AI agent split by usage source and input or output", + "tags": [ + "AI", + "Usage" + ], + "baseDataSourceName": "httpRequestScopedSingle", + "config": { + "httpMethod": "get", + "endpointPath": "v2/gen-ai/agents/{{object.rawId}}/usage", + "getArgs": [ + { + "key": "start", + "value": "{{timeframe.start}}" + }, + { + "key": "stop", + "value": "{{timeframe.end}}" + } + ], + "postRequestScript": "agentUsage.js" + }, + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "Agent" + ] + } + }, + "metadata": [ + { + "name": "start", + "displayName": "Start", + "shape": "date", + "role": "timestamp" + }, + { + "name": "stop", + "displayName": "End", + "shape": "date" + }, + { + "name": "source", + "displayName": "Usage Source", + "shape": "string" + }, + { + "name": "usageType", + "displayName": "Usage Type", + "shape": "string" + }, + { + "name": "tokens", + "displayName": "Tokens", + "shape": [ + "number", + { + "decimalPlaces": 0, + "thousandsSeparator": true + } + ] + } + ], + "timeframes": true +} diff --git a/plugins/DigitalOcean/v1/dataStreams/agents.json b/plugins/DigitalOcean/v1/dataStreams/agents.json new file mode 100644 index 00000000..e0c69dc7 --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/agents.json @@ -0,0 +1,140 @@ +{ + "name": "agents", + "displayName": "Agents", + "description": "Gradient AI platform agents with their deployment status, model and region", + "tags": [ + "AI", + "Inventory" + ], + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "get", + "endpointPath": "v2/gen-ai/agents", + "postRequestScript": "agents.js", + "paging": { + "mode": "nextUrl", + "pageSize": { + "realm": "queryArg", + "path": "per_page", + "value": "200" + }, + "in": { + "realm": "payload", + "path": "links.pages.next" + } + } + }, + "matches": "none", + "metadata": [ + { + "name": "id", + "displayName": "ID", + "shape": "string", + "visible": false + }, + { + "name": "name", + "displayName": "Name", + "shape": "string", + "role": "label" + }, + { + "name": "deploymentStatus", + "displayName": "Deployment Status", + "shape": "string" + }, + { + "name": "health", + "displayName": "Health", + "computed": true, + "valueExpression": "{{ $['deploymentStatus'] || 'STATUS_UNKNOWN' }}", + "shape": [ + "state", + { + "map": { + "success": [ + "STATUS_RUNNING" + ], + "error": [ + "STATUS_FAILED" + ], + "warning": [ + "STATUS_WAITING_FOR_DEPLOYMENT", + "STATUS_BUILDING", + "STATUS_DEPLOYING", + "STATUS_WAITING_FOR_UNDEPLOYMENT", + "STATUS_UNDEPLOYING", + "STATUS_UNDEPLOYMENT_FAILED" + ], + "unknown": [ + "STATUS_UNKNOWN", + "STATUS_DELETED" + ] + } + } + ] + }, + { + "name": "model", + "displayName": "Model", + "shape": "string" + }, + { + "name": "region", + "displayName": "Region", + "shape": "string" + }, + { + "name": "visibility", + "displayName": "Visibility", + "shape": "string" + }, + { + "name": "url", + "displayName": "Endpoint", + "shape": "url" + }, + { + "name": "projectId", + "displayName": "Project ID", + "shape": "string", + "visible": false + }, + { + "name": "tagList", + "displayName": "Tags", + "shape": "string" + }, + { + "name": "createdAt", + "displayName": "Created", + "shape": "date" + }, + { + "name": "updatedAt", + "displayName": "Updated", + "shape": "date" + }, + { + "sourceId": "id", + "sourceType": "Agent", + "name": "name" + } + ], + "timeframes": false, + "ui": [ + { + "type": "objects", + "name": "project", + "label": "Project (optional)", + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "Project" + ] + } + } + } + ] +} diff --git a/plugins/DigitalOcean/v1/dataStreams/appDeployments.json b/plugins/DigitalOcean/v1/dataStreams/appDeployments.json new file mode 100644 index 00000000..64f702c1 --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/appDeployments.json @@ -0,0 +1,108 @@ +{ + "name": "appDeployments", + "displayName": "App Deployments", + "description": "Most recent deployments of an App Platform app with their phase and cause", + "tags": [ + "Applications", + "Deployments" + ], + "baseDataSourceName": "httpRequestScopedSingle", + "config": { + "httpMethod": "get", + "endpointPath": "v2/apps/{{object.rawId}}/deployments", + "getArgs": [ + { + "key": "page", + "value": "1" + }, + { + "key": "per_page", + "value": "50" + } + ], + "pathToData": "deployments" + }, + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "App" + ] + } + }, + "metadata": [ + { + "name": "id", + "displayName": "ID", + "shape": "string", + "visible": false + }, + { + "name": "phase", + "displayName": "Phase", + "shape": "string", + "role": "label" + }, + { + "name": "health", + "displayName": "Health", + "computed": true, + "valueExpression": "{{ $['phase'] || 'UNKNOWN' }}", + "shape": [ + "state", + { + "map": { + "success": [ + "ACTIVE" + ], + "error": [ + "ERROR", + "CANCELED" + ], + "warning": [ + "PENDING_BUILD", + "BUILDING", + "PENDING_DEPLOY", + "DEPLOYING" + ], + "unknown": [ + "UNKNOWN", + "SUPERSEDED" + ] + } + } + ] + }, + { + "name": "cause", + "displayName": "Cause", + "shape": "string" + }, + { + "name": "created_at", + "displayName": "Created", + "shape": "date" + }, + { + "name": "updated_at", + "displayName": "Updated", + "shape": "date" + }, + { + "name": "phase_last_updated_at", + "displayName": "Phase Last Updated", + "shape": "date" + } + ], + "timeframes": false, + "defaultShaping": { + "sort": { + "by": [ + [ + "created_at", + "desc" + ] + ] + } + } +} diff --git a/plugins/DigitalOcean/v1/dataStreams/appHealth.json b/plugins/DigitalOcean/v1/dataStreams/appHealth.json new file mode 100644 index 00000000..37d51c36 --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/appHealth.json @@ -0,0 +1,89 @@ +{ + "name": "appHealth", + "displayName": "App Health", + "description": "Per-component health of an App Platform app, with CPU and memory usage and replica counts", + "tags": [ + "Applications", + "Health" + ], + "baseDataSourceName": "httpRequestScopedSingle", + "config": { + "httpMethod": "get", + "endpointPath": "v2/apps/{{object.rawId}}/health", + "pathToData": "app_health.components" + }, + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "App" + ] + } + }, + "metadata": [ + { + "name": "name", + "displayName": "Component", + "shape": "string", + "role": "label" + }, + { + "name": "state", + "displayName": "State", + "shape": "string" + }, + { + "name": "health", + "displayName": "Health", + "computed": true, + "valueExpression": "{{ $['state'] || 'UNKNOWN' }}", + "shape": [ + "state", + { + "map": { + "success": [ + "HEALTHY" + ], + "error": [ + "UNHEALTHY" + ], + "unknown": [ + "UNKNOWN" + ] + } + } + ] + }, + { + "name": "cpu_usage_percent", + "displayName": "CPU Usage", + "shape": [ + "percent", + { + "decimalPlaces": 1 + } + ] + }, + { + "name": "memory_usage_percent", + "displayName": "Memory Usage", + "shape": [ + "percent", + { + "decimalPlaces": 1 + } + ] + }, + { + "name": "replicas_desired", + "displayName": "Replicas Desired", + "shape": "number" + }, + { + "name": "replicas_ready", + "displayName": "Replicas Ready", + "shape": "number" + } + ], + "timeframes": false +} diff --git a/plugins/DigitalOcean/v1/dataStreams/appMetrics.json b/plugins/DigitalOcean/v1/dataStreams/appMetrics.json new file mode 100644 index 00000000..6e2e362f --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/appMetrics.json @@ -0,0 +1,90 @@ +{ + "name": "appMetrics", + "displayName": "App Metrics", + "description": "CPU, memory or restart count time series for an App Platform app, one row per component instance and timestamp", + "tags": [ + "Applications", + "Monitoring" + ], + "baseDataSourceName": "httpRequestScopedSingle", + "config": { + "httpMethod": "get", + "endpointPath": "v2/monitoring/metrics/apps/{{metric}}", + "getArgs": [ + { + "key": "app_id", + "value": "{{object.rawId}}" + }, + { + "key": "start", + "value": "{{timeframe.unixStart}}" + }, + { + "key": "end", + "value": "{{timeframe.unixEnd}}" + } + ], + "postRequestScript": "appMetrics.js" + }, + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "App" + ] + } + }, + "ui": [ + { + "type": "radio", + "name": "metric", + "label": "Metric", + "defaultValue": "cpu_percentage", + "options": [ + { + "value": "cpu_percentage", + "label": "CPU (%)" + }, + { + "value": "memory_percentage", + "label": "Memory (%)" + }, + { + "value": "restart_count", + "label": "Restart count" + } + ] + } + ], + "metadata": [ + { + "name": "timestamp", + "displayName": "Time", + "shape": "date", + "role": "timestamp" + }, + { + "name": "value", + "displayName": "Value", + "shape": [ + "number", + { + "decimalPlaces": 2 + } + ], + "role": "value" + }, + { + "name": "component", + "displayName": "Component", + "shape": "string", + "role": "label" + }, + { + "name": "instance", + "displayName": "Instance", + "shape": "string" + } + ], + "timeframes": true +} diff --git a/plugins/DigitalOcean/v1/dataStreams/apps.json b/plugins/DigitalOcean/v1/dataStreams/apps.json new file mode 100644 index 00000000..4f655379 --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/apps.json @@ -0,0 +1,137 @@ +{ + "name": "apps", + "displayName": "Apps", + "description": "App Platform apps with their region, live URL and the phase of the active deployment", + "tags": [ + "Applications", + "Inventory" + ], + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "get", + "endpointPath": "v2/apps", + "postRequestScript": "apps.js", + "paging": { + "mode": "nextUrl", + "pageSize": { + "realm": "queryArg", + "path": "per_page", + "value": "200" + }, + "in": { + "realm": "payload", + "path": "links.pages.next" + } + } + }, + "matches": "none", + "metadata": [ + { + "name": "id", + "displayName": "ID", + "shape": "string", + "visible": false + }, + { + "name": "name", + "displayName": "Name", + "shape": "string", + "role": "label" + }, + { + "name": "activeDeploymentPhase", + "displayName": "Active Deployment Phase", + "shape": "string" + }, + { + "name": "health", + "displayName": "Health", + "computed": true, + "valueExpression": "{{ $['activeDeploymentPhase'] || 'NONE' }}", + "shape": [ + "state", + { + "map": { + "success": [ + "ACTIVE" + ], + "error": [ + "ERROR", + "CANCELED" + ], + "warning": [ + "PENDING_BUILD", + "BUILDING", + "PENDING_DEPLOY", + "DEPLOYING" + ], + "unknown": [ + "UNKNOWN", + "NONE", + "SUPERSEDED" + ] + } + } + ] + }, + { + "name": "inProgressDeploymentPhase", + "displayName": "In-progress Deployment", + "shape": "string" + }, + { + "name": "region", + "displayName": "Region", + "shape": "string" + }, + { + "name": "tier", + "displayName": "Tier", + "shape": "string" + }, + { + "name": "liveUrl", + "displayName": "Live URL", + "shape": "url" + }, + { + "name": "defaultIngress", + "displayName": "Default Ingress", + "shape": "url", + "visible": false + }, + { + "name": "activeDeploymentId", + "displayName": "Active Deployment ID", + "shape": "string", + "visible": false + }, + { + "name": "lastDeploymentAt", + "displayName": "Last Deployment", + "shape": "date" + }, + { + "name": "projectId", + "displayName": "Project ID", + "shape": "string", + "visible": false + }, + { + "name": "createdAt", + "displayName": "Created", + "shape": "date" + }, + { + "name": "updatedAt", + "displayName": "Updated", + "shape": "date" + }, + { + "sourceId": "id", + "sourceType": "App", + "name": "name" + } + ], + "timeframes": false +} diff --git a/plugins/DigitalOcean/v1/dataStreams/balance.json b/plugins/DigitalOcean/v1/dataStreams/balance.json new file mode 100644 index 00000000..896bc4c5 --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/balance.json @@ -0,0 +1,78 @@ +{ + "name": "balance", + "displayName": "Balance", + "description": "Account balance, month-to-date usage and the balance including usage as of the last time it was generated", + "tags": [ + "Cost", + "Billing" + ], + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "get", + "endpointPath": "v2/customers/my/balance" + }, + "matches": "none", + "metadata": [ + { + "name": "month_to_date_usage", + "displayName": "month_to_date_usage", + "shape": "string", + "visible": false + }, + { + "name": "month_to_date_balance", + "displayName": "month_to_date_balance", + "shape": "string", + "visible": false + }, + { + "name": "account_balance", + "displayName": "account_balance", + "shape": "string", + "visible": false + }, + { + "name": "usage", + "displayName": "Month-to-Date Usage", + "computed": true, + "valueExpression": "{{ Number($['month_to_date_usage']) }}", + "shape": [ + "number", + { + "decimalPlaces": 2 + } + ], + "role": "value" + }, + { + "name": "monthToDateBalance", + "displayName": "Month-to-Date Balance", + "computed": true, + "valueExpression": "{{ Number($['month_to_date_balance']) }}", + "shape": [ + "number", + { + "decimalPlaces": 2 + } + ] + }, + { + "name": "accountBalance", + "displayName": "Account Balance", + "computed": true, + "valueExpression": "{{ Number($['account_balance']) }}", + "shape": [ + "number", + { + "decimalPlaces": 2 + } + ] + }, + { + "name": "generated_at", + "displayName": "Generated", + "shape": "date" + } + ], + "timeframes": false +} diff --git a/plugins/DigitalOcean/v1/dataStreams/conversationSignals.json b/plugins/DigitalOcean/v1/dataStreams/conversationSignals.json new file mode 100644 index 00000000..7a710865 --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/conversationSignals.json @@ -0,0 +1,85 @@ +{ + "name": "conversationSignals", + "displayName": "Conversation Signals", + "description": "Conversations recorded by Signals for a Harness Runtime environment, with turns, duration and number of detected signals", + "tags": [ + "AI", + "Quality" + ], + "baseDataSourceName": "httpRequestScopedSingle", + "config": { + "httpMethod": "get", + "endpointPath": "v1/signals/agents/{{object.rawId}}/sessions", + "getArgs": [ + { + "key": "start_time", + "value": "{{timeframe.unixStart}}" + }, + { + "key": "end_time", + "value": "{{timeframe.unixEnd}}" + } + ], + "postRequestScript": "conversationSignals.js", + "paging": { + "mode": "token", + "pageSize": { + "realm": "queryArg", + "path": "limit", + "value": "100" + }, + "in": { + "realm": "payload", + "path": "edges.99.cursor" + }, + "out": { + "realm": "queryArg", + "path": "after" + } + } + }, + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "Environment" + ] + } + }, + "metadata": [ + { + "name": "startedAt", + "displayName": "Started", + "shape": "date", + "role": "timestamp" + }, + { + "name": "sessionId", + "displayName": "Session ID", + "shape": "string", + "role": "label" + }, + { + "name": "totalTurns", + "displayName": "Turns", + "shape": "number", + "role": "value" + }, + { + "name": "durationSeconds", + "displayName": "Duration", + "shape": "seconds" + }, + { + "name": "signalCount", + "displayName": "Signals", + "shape": "number" + }, + { + "sourceId": "sessionId", + "sourceType": "Agent Session", + "name": "sessionId" + } + ], + "timeframes": true +} diff --git a/plugins/DigitalOcean/v1/dataStreams/cost.json b/plugins/DigitalOcean/v1/dataStreams/cost.json new file mode 100644 index 00000000..19009b98 --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/cost.json @@ -0,0 +1,108 @@ +{ + "name": "cost", + "displayName": "Cost", + "description": "Daily usage cost by resource, SKU and region for the account over the selected timeframe", + "tags": [ + "Cost", + "Billing" + ], + "baseDataSourceName": "httpRequestScopedSingle", + "config": { + "httpMethod": "get", + "endpointPath": "v2/billing/do:team:{{object.rawId}}/insights/{{timeframe.start.slice(0, 10)}}/{{timeframe.end.slice(0, 10)}}", + "postRequestScript": "cost.js", + "paging": { + "mode": "offset", + "pageSize": { + "realm": "queryArg", + "path": "per_page", + "value": "200" + }, + "offset": { + "mode": "page", + "rowCountIn": { + "realm": "payloadArraySize", + "path": "data_points" + }, + "base": 1 + }, + "out": { + "realm": "queryArg", + "path": "page" + } + } + }, + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "Account" + ] + } + }, + "metadata": [ + { + "name": "start_date", + "displayName": "Date", + "shape": [ + "date", + { + "format": "dd/MM/yyyy" + } + ], + "role": "timestamp" + }, + { + "name": "description", + "displayName": "Description", + "shape": "string", + "role": "label" + }, + { + "name": "group_description", + "displayName": "Group", + "shape": "string" + }, + { + "name": "region", + "displayName": "Region", + "shape": "string" + }, + { + "name": "sku", + "displayName": "SKU", + "shape": "string" + }, + { + "name": "total_amount", + "displayName": "total_amount", + "shape": "string", + "visible": false + }, + { + "name": "cost", + "displayName": "Cost", + "computed": true, + "valueExpression": "{{ Number($['total_amount']) }}", + "shape": [ + "currency", + { + "code": "usd" + } + ], + "role": "value" + }, + { + "name": "usage_team_urn", + "displayName": "Team URN", + "shape": "string", + "visible": false + } + ], + "timeframes": [ + "last7days", + "last30days", + "thisMonth", + "lastMonth" + ] +} diff --git a/plugins/DigitalOcean/v1/dataStreams/databases.json b/plugins/DigitalOcean/v1/dataStreams/databases.json new file mode 100644 index 00000000..1c4df5a5 --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/databases.json @@ -0,0 +1,155 @@ +{ + "name": "databases", + "displayName": "Databases", + "description": "Managed database clusters with their engine, version, status, size and node count", + "tags": [ + "Database", + "Inventory" + ], + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "get", + "endpointPath": "v2/databases", + "postRequestScript": "databases.js", + "paging": { + "mode": "nextUrl", + "pageSize": { + "realm": "queryArg", + "path": "per_page", + "value": "200" + }, + "in": { + "realm": "payload", + "path": "links.pages.next" + } + } + }, + "matches": "none", + "metadata": [ + { + "name": "id", + "displayName": "ID", + "shape": "string", + "visible": false + }, + { + "name": "name", + "displayName": "Name", + "shape": "string", + "role": "label" + }, + { + "name": "engine", + "displayName": "Engine", + "shape": "string" + }, + { + "name": "version", + "displayName": "Version", + "shape": "string" + }, + { + "name": "status", + "displayName": "Status", + "shape": "string" + }, + { + "name": "health", + "displayName": "Health", + "computed": true, + "valueExpression": "{{ $['status'] }}", + "shape": [ + "state", + { + "map": { + "success": [ + "online" + ], + "warning": [ + "creating", + "resizing", + "migrating", + "forking" + ] + } + } + ] + }, + { + "name": "region", + "displayName": "Region", + "shape": "string" + }, + { + "name": "size", + "displayName": "Size", + "shape": "string" + }, + { + "name": "numNodes", + "displayName": "Nodes", + "shape": "number" + }, + { + "name": "versionEndOfLife", + "displayName": "Version End of Life", + "shape": "date" + }, + { + "name": "projectId", + "displayName": "Project ID", + "shape": "string", + "visible": false + }, + { + "name": "vpcUuid", + "displayName": "VPC ID", + "shape": "string", + "visible": false + }, + { + "name": "tagList", + "displayName": "Tags", + "shape": "string" + }, + { + "name": "createdAt", + "displayName": "Created", + "shape": "date" + }, + { + "sourceId": "id", + "sourceType": "Database", + "name": "name" + } + ], + "timeframes": false, + "ui": [ + { + "type": "objects", + "name": "project", + "label": "Project (optional)", + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "Project" + ] + } + } + }, + { + "type": "objects", + "name": "vpc", + "label": "VPC (optional)", + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "VPC" + ] + } + } + } + ] +} diff --git a/plugins/DigitalOcean/v1/dataStreams/dropletMetrics.json b/plugins/DigitalOcean/v1/dataStreams/dropletMetrics.json new file mode 100644 index 00000000..cdd05977 --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/dropletMetrics.json @@ -0,0 +1,156 @@ +{ + "name": "dropletMetrics", + "displayName": "Droplet Metrics", + "description": "Time series monitoring metrics for a Droplet, such as CPU, load, memory, disk and bandwidth", + "tags": [ + "Compute", + "Performance" + ], + "baseDataSourceName": "httpRequestScopedSingle", + "config": { + "httpMethod": "get", + "endpointPath": "v2/monitoring/metrics/droplet/{{metric.split(':')[0]}}", + "getArgs": [ + { + "key": "host_id", + "value": "{{object.rawId}}" + }, + { + "key": "start", + "value": "{{timeframe.unixStart}}" + }, + { + "key": "end", + "value": "{{timeframe.unixEnd}}" + }, + { + "key": "interface", + "value": "{{metric.split(':')[1] || null}}" + }, + { + "key": "direction", + "value": "{{metric.split(':')[2] || null}}" + } + ], + "postRequestScript": "dropletMetrics.js" + }, + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "Droplet" + ] + } + }, + "ui": [ + { + "type": "autocomplete", + "name": "metric", + "label": "Metric", + "allowCustomValues": false, + "isMulti": false, + "defaultValue": "cpu", + "data": { + "source": "fixed", + "values": [ + { + "value": "cpu", + "label": "CPU usage (%)" + }, + { + "value": "load_1", + "label": "Load average (1 min)" + }, + { + "value": "load_5", + "label": "Load average (5 min)" + }, + { + "value": "load_15", + "label": "Load average (15 min)" + }, + { + "value": "memory_available", + "label": "Memory available" + }, + { + "value": "memory_free", + "label": "Memory free" + }, + { + "value": "memory_cached", + "label": "Memory cached" + }, + { + "value": "memory_total", + "label": "Memory total" + }, + { + "value": "filesystem_free", + "label": "Filesystem free" + }, + { + "value": "filesystem_size", + "label": "Filesystem size" + }, + { + "value": "bandwidth:public:inbound", + "label": "Bandwidth (public inbound)" + }, + { + "value": "bandwidth:public:outbound", + "label": "Bandwidth (public outbound)" + }, + { + "value": "bandwidth:private:inbound", + "label": "Bandwidth (private inbound)" + }, + { + "value": "bandwidth:private:outbound", + "label": "Bandwidth (private outbound)" + } + ] + }, + "validation": { + "required": true + } + } + ], + "metadata": [ + { + "name": "timestamp", + "displayName": "Time", + "shape": "date", + "role": "timestamp" + }, + { + "name": "value", + "displayName": "Value", + "shape": [ + "number", + { + "decimalPlaces": 4, + "thousandsSeparator": true + } + ], + "role": "value" + }, + { + "name": "bytes", + "displayName": "Bytes", + "shape": "bytes" + }, + { + "name": "series", + "displayName": "Series", + "shape": "string", + "role": "label" + }, + { + "name": "unit", + "displayName": "Unit", + "shape": "string" + } + ], + "timeframes": true +} diff --git a/plugins/DigitalOcean/v1/dataStreams/droplets.json b/plugins/DigitalOcean/v1/dataStreams/droplets.json new file mode 100644 index 00000000..46ceba95 --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/droplets.json @@ -0,0 +1,158 @@ +{ + "name": "droplets", + "displayName": "Droplets", + "description": "Droplets with their status, size, region, image and IP addresses", + "tags": [ + "Compute", + "Inventory" + ], + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "get", + "endpointPath": "v2/droplets", + "postRequestScript": "droplets.js", + "paging": { + "mode": "nextUrl", + "pageSize": { + "realm": "queryArg", + "path": "per_page", + "value": "200" + }, + "in": { + "realm": "payload", + "path": "links.pages.next" + } + } + }, + "matches": "none", + "metadata": [ + { + "name": "id", + "displayName": "ID", + "shape": "string", + "visible": false + }, + { + "name": "name", + "displayName": "Name", + "shape": "string", + "role": "label" + }, + { + "name": "status", + "displayName": "Status", + "shape": "string" + }, + { + "name": "health", + "displayName": "Health", + "computed": true, + "valueExpression": "{{ $['status'] }}", + "shape": [ + "state", + { + "map": { + "success": [ + "active" + ], + "warning": [ + "new", + "off" + ], + "unknown": [ + "archive" + ] + } + } + ] + }, + { + "name": "region", + "displayName": "Region", + "shape": "string" + }, + { + "name": "sizeSlug", + "displayName": "Size", + "shape": "string" + }, + { + "name": "vcpus", + "displayName": "vCPUs", + "shape": "number" + }, + { + "name": "memory", + "displayName": "Memory", + "shape": "megabytes" + }, + { + "name": "disk", + "displayName": "Disk", + "shape": "gigabytes" + }, + { + "name": "image", + "displayName": "Image", + "shape": "string" + }, + { + "name": "publicIp", + "displayName": "Public IP", + "shape": "string" + }, + { + "name": "privateIp", + "displayName": "Private IP", + "shape": "string" + }, + { + "name": "vpcUuid", + "displayName": "VPC ID", + "shape": "string", + "visible": false + }, + { + "name": "kubernetesClusterId", + "displayName": "Kubernetes Cluster ID", + "shape": "string", + "visible": false + }, + { + "name": "locked", + "displayName": "Locked", + "shape": "boolean" + }, + { + "name": "tagList", + "displayName": "Tags", + "shape": "string" + }, + { + "name": "createdAt", + "displayName": "Created", + "shape": "date" + }, + { + "sourceId": "id", + "sourceType": "Droplet", + "name": "name" + } + ], + "timeframes": false, + "ui": [ + { + "type": "objects", + "name": "vpc", + "label": "VPC (optional)", + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "VPC" + ] + } + } + } + ] +} diff --git a/plugins/DigitalOcean/v1/dataStreams/environments.json b/plugins/DigitalOcean/v1/dataStreams/environments.json new file mode 100644 index 00000000..1dfc91f5 --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/environments.json @@ -0,0 +1,57 @@ +{ + "name": "environments", + "displayName": "Environments", + "description": "Harness Runtime environment configs with their spec schema version and creation date", + "tags": [ + "AI", + "Inventory" + ], + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "get", + "endpointPath": "v2/agents/configs", + "pathToData": "configs", + "getArgs": [ + { + "key": "page_size", + "value": "200" + } + ] + }, + "matches": "none", + "metadata": [ + { + "name": "id", + "displayName": "ID", + "shape": "string", + "visible": false + }, + { + "name": "name", + "displayName": "Name", + "shape": "string", + "role": "label" + }, + { + "name": "agentspec_schema_version", + "displayName": "Spec Version", + "shape": "string" + }, + { + "name": "created_at", + "displayName": "Created", + "shape": "date" + }, + { + "name": "updated_at", + "displayName": "Updated", + "shape": "date" + }, + { + "sourceId": "id", + "sourceType": "Environment", + "name": "name" + } + ], + "timeframes": false +} diff --git a/plugins/DigitalOcean/v1/dataStreams/evaluationTestCases.json b/plugins/DigitalOcean/v1/dataStreams/evaluationTestCases.json new file mode 100644 index 00000000..fb0e563c --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/evaluationTestCases.json @@ -0,0 +1,91 @@ +{ + "name": "evaluationTestCases", + "displayName": "Evaluation Test Cases", + "description": "Gradient AI evaluation test cases with their star metric, success threshold and dataset", + "tags": [ + "AI", + "Quality" + ], + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "get", + "endpointPath": "v2/gen-ai/evaluation_test_cases", + "postRequestScript": "evaluationTestCases.js" + }, + "matches": "none", + "metadata": [ + { + "name": "id", + "displayName": "ID", + "shape": "string", + "visible": false + }, + { + "name": "name", + "displayName": "Name", + "shape": "string", + "role": "label" + }, + { + "name": "description", + "displayName": "Description", + "shape": "string" + }, + { + "name": "totalRuns", + "displayName": "Total Runs", + "shape": "number" + }, + { + "name": "latestVersionRuns", + "displayName": "Latest Version Runs", + "shape": "number" + }, + { + "name": "version", + "displayName": "Version", + "shape": "number" + }, + { + "name": "starMetric", + "displayName": "Star Metric", + "shape": "string" + }, + { + "name": "successThreshold", + "displayName": "Success Threshold", + "shape": [ + "number", + { + "decimalPlaces": 2 + } + ] + }, + { + "name": "successThresholdPct", + "displayName": "Success Threshold (%)", + "shape": "number" + }, + { + "name": "datasetName", + "displayName": "Dataset", + "shape": "string" + }, + { + "name": "datasetRows", + "displayName": "Dataset Rows", + "shape": "number" + }, + { + "name": "createdAt", + "displayName": "Created", + "shape": "date" + }, + { + "name": "updatedAt", + "displayName": "Updated", + "shape": "date" + } + ], + "timeframes": false +} diff --git a/plugins/DigitalOcean/v1/dataStreams/invoices.json b/plugins/DigitalOcean/v1/dataStreams/invoices.json new file mode 100644 index 00000000..a4b7b6b8 --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/invoices.json @@ -0,0 +1,69 @@ +{ + "name": "invoices", + "displayName": "Invoices", + "description": "Issued invoices and the current month's invoice preview with their billing period and amount", + "tags": [ + "Cost", + "Billing" + ], + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "get", + "endpointPath": "v2/customers/my/invoices", + "postRequestScript": "invoices.js", + "paging": { + "mode": "nextUrl", + "pageSize": { + "realm": "queryArg", + "path": "per_page", + "value": "200" + }, + "in": { + "realm": "payload", + "path": "links.pages.next" + } + } + }, + "matches": "none", + "metadata": [ + { + "name": "invoice_uuid", + "displayName": "Invoice UUID", + "shape": "string", + "visible": false + }, + { + "name": "invoice_id", + "displayName": "Invoice Number", + "shape": "string", + "role": "label" + }, + { + "name": "invoice_period", + "displayName": "Period", + "shape": "string" + }, + { + "name": "amount", + "displayName": "Amount", + "shape": [ + "currency", + { + "code": "usd" + } + ], + "role": "value" + }, + { + "name": "preview", + "displayName": "Preview", + "shape": "boolean" + }, + { + "name": "updated_at", + "displayName": "Updated", + "shape": "date" + } + ], + "timeframes": false +} diff --git a/plugins/DigitalOcean/v1/dataStreams/kubernetesClusters.json b/plugins/DigitalOcean/v1/dataStreams/kubernetesClusters.json new file mode 100644 index 00000000..ee7328c2 --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/kubernetesClusters.json @@ -0,0 +1,158 @@ +{ + "name": "kubernetesClusters", + "displayName": "Kubernetes Clusters", + "description": "DOKS clusters with their state, version, region and node counts", + "tags": [ + "Kubernetes", + "Inventory" + ], + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "get", + "endpointPath": "v2/kubernetes/clusters", + "postRequestScript": "kubernetesClusters.js", + "paging": { + "mode": "nextUrl", + "pageSize": { + "realm": "queryArg", + "path": "per_page", + "value": "200" + }, + "in": { + "realm": "payload", + "path": "links.pages.next" + } + } + }, + "matches": "none", + "metadata": [ + { + "name": "id", + "displayName": "ID", + "shape": "string", + "visible": false + }, + { + "name": "name", + "displayName": "Name", + "shape": "string", + "role": "label" + }, + { + "name": "status", + "displayName": "Status", + "shape": "string" + }, + { + "name": "health", + "displayName": "Health", + "computed": true, + "valueExpression": "{{ $['status'] }}", + "shape": [ + "state", + { + "map": { + "success": [ + "running" + ], + "warning": [ + "provisioning", + "upgrading", + "degraded" + ], + "error": [ + "error" + ], + "unknown": [ + "deleting", + "deleted" + ] + } + } + ] + }, + { + "name": "statusMessage", + "displayName": "Status Message", + "shape": "string" + }, + { + "name": "region", + "displayName": "Region", + "shape": "string" + }, + { + "name": "version", + "displayName": "Version", + "shape": "string" + }, + { + "name": "nodePools", + "displayName": "Node Pools", + "shape": "number" + }, + { + "name": "nodes", + "displayName": "Nodes", + "shape": "number" + }, + { + "name": "ha", + "displayName": "HA Control Plane", + "shape": "boolean" + }, + { + "name": "autoUpgrade", + "displayName": "Auto Upgrade", + "shape": "boolean" + }, + { + "name": "endpoint", + "displayName": "API Endpoint", + "shape": "string", + "visible": false + }, + { + "name": "vpcUuid", + "displayName": "VPC ID", + "shape": "string", + "visible": false + }, + { + "name": "tagList", + "displayName": "Tags", + "shape": "string" + }, + { + "name": "createdAt", + "displayName": "Created", + "shape": "date" + }, + { + "name": "updatedAt", + "displayName": "Updated", + "shape": "date" + }, + { + "sourceId": "id", + "sourceType": "Kubernetes Cluster", + "name": "name" + } + ], + "timeframes": false, + "ui": [ + { + "type": "objects", + "name": "vpc", + "label": "VPC (optional)", + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "VPC" + ] + } + } + } + ] +} diff --git a/plugins/DigitalOcean/v1/dataStreams/kubernetesNodes.json b/plugins/DigitalOcean/v1/dataStreams/kubernetesNodes.json new file mode 100644 index 00000000..495fe812 --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/kubernetesNodes.json @@ -0,0 +1,117 @@ +{ + "name": "kubernetesNodes", + "displayName": "Kubernetes Nodes", + "description": "Worker nodes of a DOKS cluster with their node pool, size and state", + "tags": [ + "Kubernetes", + "Inventory" + ], + "baseDataSourceName": "httpRequestScopedSingle", + "config": { + "httpMethod": "get", + "endpointPath": "v2/kubernetes/clusters/{{object.rawId}}/node_pools", + "postRequestScript": "kubernetesNodes.js" + }, + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "Kubernetes Cluster" + ] + } + }, + "metadata": [ + { + "name": "id", + "displayName": "ID", + "shape": "string", + "visible": false + }, + { + "name": "name", + "displayName": "Name", + "shape": "string", + "role": "label" + }, + { + "name": "poolName", + "displayName": "Node Pool", + "shape": "string" + }, + { + "name": "poolSize", + "displayName": "Size", + "shape": "string" + }, + { + "name": "status", + "displayName": "Status", + "shape": "string" + }, + { + "name": "health", + "displayName": "Health", + "computed": true, + "valueExpression": "{{ $['status'] }}", + "shape": [ + "state", + { + "map": { + "success": [ + "running" + ], + "warning": [ + "provisioning", + "draining" + ], + "unknown": [ + "deleting" + ] + } + } + ] + }, + { + "name": "dropletId", + "displayName": "Droplet ID", + "shape": "string", + "visible": false + }, + { + "name": "autoScale", + "displayName": "Auto Scale", + "shape": "boolean" + }, + { + "name": "poolCount", + "displayName": "Pool Node Count", + "shape": "number" + }, + { + "name": "minNodes", + "displayName": "Pool Min Nodes", + "shape": "number" + }, + { + "name": "maxNodes", + "displayName": "Pool Max Nodes", + "shape": "number" + }, + { + "name": "createdAt", + "displayName": "Created", + "shape": "date" + }, + { + "name": "updatedAt", + "displayName": "Updated", + "shape": "date" + }, + { + "sourceId": "dropletId", + "sourceType": "Droplet", + "name": "name" + } + ], + "timeframes": false +} diff --git a/plugins/DigitalOcean/v1/dataStreams/loadBalancerMetrics.json b/plugins/DigitalOcean/v1/dataStreams/loadBalancerMetrics.json new file mode 100644 index 00000000..2b8a4de3 --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/loadBalancerMetrics.json @@ -0,0 +1,187 @@ +{ + "name": "loadBalancerMetrics", + "displayName": "Load Balancer Metrics", + "description": "Time series of a load balancer metric such as request rate, connections, response time or health (the unit depends on the selected metric)", + "tags": [ + "Monitoring", + "Performance" + ], + "baseDataSourceName": "httpRequestScopedSingle", + "config": { + "httpMethod": "get", + "endpointPath": "v2/monitoring/metrics/load_balancer/{{metric}}", + "getArgs": [ + { + "key": "lb_id", + "value": "{{object.rawId}}" + }, + { + "key": "start", + "value": "{{timeframe.unixStart}}" + }, + { + "key": "end", + "value": "{{timeframe.unixEnd}}" + } + ], + "postRequestScript": "loadBalancerMetrics.js" + }, + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "Load Balancer" + ] + } + }, + "ui": [ + { + "type": "autocomplete", + "name": "metric", + "label": "Metric", + "allowCustomValues": false, + "isMulti": false, + "defaultValue": "frontend_http_requests_per_second", + "data": { + "source": "fixed", + "values": [ + { + "value": "frontend_http_requests_per_second", + "label": "HTTP requests (per second)" + }, + { + "value": "frontend_connections_current", + "label": "Current connections (count)" + }, + { + "value": "frontend_http_responses", + "label": "HTTP responses by status class (per second)" + }, + { + "value": "droplets_http_response_time_avg", + "label": "Droplet HTTP response time, average (seconds)" + }, + { + "value": "droplets_http_response_time_50p", + "label": "Droplet HTTP response time, 50th percentile (seconds)" + }, + { + "value": "droplets_http_response_time_95p", + "label": "Droplet HTTP response time, 95th percentile (seconds)" + }, + { + "value": "droplets_http_response_time_99p", + "label": "Droplet HTTP response time, 99th percentile (seconds)" + }, + { + "value": "frontend_network_throughput_http", + "label": "HTTP throughput (bytes per second)" + }, + { + "value": "frontend_network_throughput_tcp", + "label": "TCP throughput (bytes per second)" + }, + { + "value": "frontend_network_throughput_udp", + "label": "UDP throughput (bytes per second)" + }, + { + "value": "frontend_cpu_utilization", + "label": "CPU utilization (percent)" + }, + { + "value": "droplets_health_checks", + "label": "Droplet health check status" + }, + { + "value": "droplets_downtime", + "label": "Droplet downtime status" + }, + { + "value": "droplets_connections", + "label": "Droplet active connections (count)" + }, + { + "value": "droplets_http_responses", + "label": "Droplet HTTP responses by status class (per second)" + }, + { + "value": "droplets_queue_size", + "label": "Droplet queue size (count)" + }, + { + "value": "frontend_connections_limit", + "label": "Max connections limit (count)" + }, + { + "value": "frontend_tls_connections_current", + "label": "Current TLS connections rate (per second)" + }, + { + "value": "frontend_tls_connections_limit", + "label": "Max TLS connections limit (count)" + }, + { + "value": "frontend_tls_connections_exceeding_rate_limit", + "label": "TLS connections closed for exceeding rate limit (count)" + }, + { + "value": "droplets_http_session_duration_avg", + "label": "Droplet HTTP session duration, average (seconds)" + }, + { + "value": "droplets_http_session_duration_50p", + "label": "Droplet HTTP session duration, 50th percentile (seconds)" + }, + { + "value": "droplets_http_session_duration_95p", + "label": "Droplet HTTP session duration, 95th percentile (seconds)" + }, + { + "value": "frontend_nlb_tcp_network_throughput", + "label": "Network LB TCP throughput (bytes per second)" + }, + { + "value": "frontend_nlb_udp_network_throughput", + "label": "Network LB UDP throughput (bytes per second)" + }, + { + "value": "frontend_firewall_dropped_bytes", + "label": "Network LB firewall dropped bytes" + }, + { + "value": "frontend_firewall_dropped_packets", + "label": "Network LB firewall dropped packets (per second)" + } + ] + }, + "validation": { + "required": true + } + } + ], + "metadata": [ + { + "name": "timestamp", + "displayName": "Time", + "shape": "date", + "role": "timestamp" + }, + { + "name": "series", + "displayName": "Series", + "shape": "string" + }, + { + "name": "value", + "displayName": "Value", + "shape": [ + "number", + { + "decimalPlaces": 2 + } + ] + } + ], + "timeframes": true +} diff --git a/plugins/DigitalOcean/v1/dataStreams/loadBalancers.json b/plugins/DigitalOcean/v1/dataStreams/loadBalancers.json new file mode 100644 index 00000000..a3f1dc97 --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/loadBalancers.json @@ -0,0 +1,147 @@ +{ + "name": "loadBalancers", + "displayName": "Load Balancers", + "description": "Load balancers with their status, IP address, region, size and number of backend Droplets", + "tags": [ + "Network", + "Inventory" + ], + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "get", + "endpointPath": "v2/load_balancers", + "postRequestScript": "loadBalancers.js", + "paging": { + "mode": "nextUrl", + "pageSize": { + "realm": "queryArg", + "path": "per_page", + "value": "200" + }, + "in": { + "realm": "payload", + "path": "links.pages.next" + } + } + }, + "matches": "none", + "metadata": [ + { + "name": "id", + "displayName": "ID", + "shape": "string", + "visible": false + }, + { + "name": "name", + "displayName": "Name", + "shape": "string", + "role": "label" + }, + { + "name": "status", + "displayName": "Status", + "shape": "string" + }, + { + "name": "health", + "displayName": "Health", + "computed": true, + "valueExpression": "{{ $['status'] }}", + "shape": [ + "state", + { + "map": { + "success": [ + "active" + ], + "warning": [ + "new" + ], + "error": [ + "errored" + ] + } + } + ] + }, + { + "name": "ip", + "displayName": "IP Address", + "shape": "string" + }, + { + "name": "region", + "displayName": "Region", + "shape": "string" + }, + { + "name": "type", + "displayName": "Type", + "shape": "string" + }, + { + "name": "network", + "displayName": "Network", + "shape": "string" + }, + { + "name": "size", + "displayName": "Size", + "shape": "string" + }, + { + "name": "sizeUnit", + "displayName": "Nodes", + "shape": "number" + }, + { + "name": "backendDroplets", + "displayName": "Backend Droplets", + "shape": "number" + }, + { + "name": "primaryBackendDropletId", + "displayName": "Primary Backend Droplet ID", + "shape": "string", + "visible": false + }, + { + "name": "targetTag", + "displayName": "Target Tag", + "shape": "string" + }, + { + "name": "vpcUuid", + "displayName": "VPC ID", + "shape": "string", + "visible": false + }, + { + "name": "createdAt", + "displayName": "Created", + "shape": "date" + }, + { + "sourceId": "id", + "sourceType": "Load Balancer", + "name": "name" + } + ], + "timeframes": false, + "ui": [ + { + "type": "objects", + "name": "vpc", + "label": "VPC (optional)", + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "VPC" + ] + } + } + } + ] +} diff --git a/plugins/DigitalOcean/v1/dataStreams/projectResources.json b/plugins/DigitalOcean/v1/dataStreams/projectResources.json new file mode 100644 index 00000000..e56c307b --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/projectResources.json @@ -0,0 +1,75 @@ +{ + "name": "projectResources", + "displayName": "Project Resources", + "description": "Resources assigned to a project with their type, ID and when they were assigned", + "tags": [ + "Inventory" + ], + "baseDataSourceName": "httpRequestScopedSingle", + "config": { + "httpMethod": "get", + "endpointPath": "v2/projects/{{object.rawId}}/resources", + "postRequestScript": "projectResources.js", + "paging": { + "mode": "nextUrl", + "pageSize": { + "realm": "queryArg", + "path": "per_page", + "value": "200" + }, + "in": { + "realm": "payload", + "path": "links.pages.next" + } + } + }, + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "Project" + ] + } + }, + "metadata": [ + { + "name": "id", + "displayName": "URN", + "shape": "string", + "visible": false + }, + { + "name": "name", + "displayName": "Resource", + "shape": "string", + "role": "label" + }, + { + "name": "resourceType", + "displayName": "Type", + "shape": "string" + }, + { + "name": "resourceId", + "displayName": "Resource ID", + "shape": "string" + }, + { + "name": "status", + "displayName": "Status", + "shape": "string" + }, + { + "name": "assignedAt", + "displayName": "Assigned", + "shape": "date" + }, + { + "name": "projectId", + "displayName": "Project ID", + "shape": "string", + "visible": false + } + ], + "timeframes": false +} diff --git a/plugins/DigitalOcean/v1/dataStreams/projects.json b/plugins/DigitalOcean/v1/dataStreams/projects.json new file mode 100644 index 00000000..df2bdf75 --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/projects.json @@ -0,0 +1,77 @@ +{ + "name": "projects", + "displayName": "Projects", + "description": "Projects with their purpose, environment and whether they are the default project", + "tags": [ + "Inventory" + ], + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "get", + "endpointPath": "v2/projects", + "pathToData": "projects", + "paging": { + "mode": "nextUrl", + "pageSize": { + "realm": "queryArg", + "path": "per_page", + "value": "200" + }, + "in": { + "realm": "payload", + "path": "links.pages.next" + } + } + }, + "matches": "none", + "metadata": [ + { + "name": "id", + "displayName": "ID", + "shape": "string", + "visible": false + }, + { + "name": "name", + "displayName": "Name", + "shape": "string", + "role": "label" + }, + { + "name": "purpose", + "displayName": "Purpose", + "shape": "string" + }, + { + "name": "environment", + "displayName": "Environment", + "shape": "string" + }, + { + "name": "is_default", + "displayName": "Default", + "shape": "boolean" + }, + { + "name": "description", + "displayName": "Description", + "shape": "string" + }, + { + "name": "created_at", + "displayName": "Created", + "shape": "date" + }, + { + "name": "updated_at", + "displayName": "Updated", + "shape": "date" + }, + { + "sourceId": "id", + "sourceType": "Project", + "name": "name" + } + ], + "timeframes": false +} diff --git a/plugins/DigitalOcean/v1/dataStreams/scripts/agentSessions.js b/plugins/DigitalOcean/v1/dataStreams/scripts/agentSessions.js new file mode 100644 index 00000000..128d114e --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/scripts/agentSessions.js @@ -0,0 +1,25 @@ +// Destroyed sessions are skipped so they don't pile up as dead objects +const KINDS = { CLAUDE_CODE: "Claude Code", OPENCODE: "OpenCode", CODEX_CLI: "Codex CLI", CURSOR_CLI: "Cursor CLI", HERMES: "Hermes", OPENAI_CODEX: "OpenAI Codex", LANGGRAPH: "LangGraph", CUSTOM: "Custom", NONE: "None" }; +const kind = (k) => { const key = (k || "").replace(/^AGENT_KIND_/, ""); return KINDS[key] || key || null; }; + +result = (data.sessions || []) + .filter((s) => s.status !== "SESSION_STATUS_DESTROYED") + .map((s) => ({ + id: s.session_id, + name: s.name || s.session_id, + status: (s.status || "").replace(/^SESSION_STATUS_/, ""), + agentKind: kind(s.agent_kind), + configId: s.config_id || null, + parentSessionId: s.parent_session_id || null, + pauseReason: s.pause_reason || null, + keepWarm: s.keep_warm ?? null, + idleTimeoutSeconds: s.idle_timeout_seconds ?? null, + warnings: s.warnings || [], + createdAt: s.created_at, + lastEventAt: s.last_event_at || null + })); + +// Optional Environment picker arrives at context.config.environment as an array whose rawId is a single-element array; empty means no filter +const unwrap = (v) => (Array.isArray(v) ? v[0] : v); +const ids = new Set((context.config?.environment || []).map((o) => unwrap(o.rawId)).filter(Boolean)); +if (ids.size) result = result.filter((row) => ids.has(row.configId)); diff --git a/plugins/DigitalOcean/v1/dataStreams/scripts/agentUsage.js b/plugins/DigitalOcean/v1/dataStreams/scripts/agentUsage.js new file mode 100644 index 00000000..6d3aa248 --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/scripts/agentUsage.js @@ -0,0 +1,14 @@ +// Flattens agent and log insights usage measurements into one row per usage type +const sources = [ + ["Agent", data.usage], + ["Log insights", data.log_insights_usage] +]; +result = sources.flatMap(([source, u]) => + (u?.measurements || []).map((m) => ({ + start: u.start, + stop: u.stop, + source, + usageType: m.usage_type, + tokens: Number(m.tokens || 0) + })) +); diff --git a/plugins/DigitalOcean/v1/dataStreams/scripts/agents.js b/plugins/DigitalOcean/v1/dataStreams/scripts/agents.js new file mode 100644 index 00000000..1786e198 --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/scripts/agents.js @@ -0,0 +1,21 @@ +// Flattens model and deployment details and joins tags, which would otherwise arrive as an array +result = (data.agents || []).map((a) => ({ + id: a.uuid, + name: a.name, + deploymentStatus: a.deployment?.status || null, + visibility: a.deployment?.visibility || null, + model: a.model?.name || null, + region: a.region || null, + url: a.deployment?.url || a.url || null, + projectId: a.project_id || null, + tagList: (a.tags || []).join(", "), + createdAt: a.created_at, + updatedAt: a.updated_at +})); + +// Optional Project/VPC object pickers arrive at context.config. as arrays whose rawId is a single-element array; empty means no filter +const unwrap = (v) => (Array.isArray(v) ? v[0] : v); +for (const [param, column] of Object.entries({ project: "projectId" })) { + const ids = new Set((context.config?.[param] || []).map((o) => unwrap(o.rawId)).filter(Boolean)); + if (ids.size) result = result.filter((row) => ids.has(row[column])); +} diff --git a/plugins/DigitalOcean/v1/dataStreams/scripts/appMetrics.js b/plugins/DigitalOcean/v1/dataStreams/scripts/appMetrics.js new file mode 100644 index 00000000..044fbffd --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/scripts/appMetrics.js @@ -0,0 +1,15 @@ +// Prometheus-style matrix: one series per component instance, values are [unixSeconds, "string"] pairs +const rows = []; +for (const series of data?.data?.result || []) { + const m = series.metric || {}; + for (const [ts, v] of series.values || []) { + const n = Number(v); + rows.push({ + timestamp: new Date(Number(ts) * 1000).toISOString(), + value: Number.isFinite(n) ? n : null, + component: m.app_component || null, + instance: m.app_component_instance || null + }); + } +} +result = rows; diff --git a/plugins/DigitalOcean/v1/dataStreams/scripts/apps.js b/plugins/DigitalOcean/v1/dataStreams/scripts/apps.js new file mode 100644 index 00000000..cfca6ffd --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/scripts/apps.js @@ -0,0 +1,17 @@ +// Apps keep their name under spec.name and their live deployment phase under active_deployment +result = (data.apps || []).map((a) => ({ + id: a.id, + name: a.spec?.name || a.id, + region: a.region?.slug || null, + tier: a.tier_slug || null, + liveUrl: a.live_url || null, + defaultIngress: a.default_ingress || null, + activeDeploymentId: a.active_deployment?.id || null, + activeDeploymentPhase: a.active_deployment?.phase || null, + inProgressDeploymentPhase: a.in_progress_deployment?.phase || null, + lastDeploymentAt: a.last_deployment_created_at || null, + projectId: a.project_id || null, + createdAt: a.created_at, + updatedAt: a.updated_at +})); + diff --git a/plugins/DigitalOcean/v1/dataStreams/scripts/conversationSignals.js b/plugins/DigitalOcean/v1/dataStreams/scripts/conversationSignals.js new file mode 100644 index 00000000..d37b29d0 --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/scripts/conversationSignals.js @@ -0,0 +1,8 @@ +// Signals pages are GraphQL-style edges; each node is one recorded conversation +result = (data.edges || []).map((e) => e.node).filter(Boolean).map((n) => ({ + sessionId: n.session_id, + startedAt: n.started_at, + totalTurns: n.total_turns ?? null, + durationSeconds: n.duration_seconds ?? null, + signalCount: n.signal_count ?? 0 +})); diff --git a/plugins/DigitalOcean/v1/dataStreams/scripts/cost.js b/plugins/DigitalOcean/v1/dataStreams/scripts/cost.js new file mode 100644 index 00000000..cdca36c1 --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/scripts/cost.js @@ -0,0 +1,2 @@ +// The API omits data_points entirely when there is no usage, which would otherwise surface as one empty row +result = data.data_points || []; diff --git a/plugins/DigitalOcean/v1/dataStreams/scripts/databases.js b/plugins/DigitalOcean/v1/dataStreams/scripts/databases.js new file mode 100644 index 00000000..f2377c0f --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/scripts/databases.js @@ -0,0 +1,23 @@ +// Joins tags, which would otherwise arrive as an array +result = (data.databases || []).map((d) => ({ + id: d.id, + name: d.name, + engine: d.engine, + version: d.version, + status: d.status, + region: d.region, + size: d.size, + numNodes: d.num_nodes, + versionEndOfLife: d.version_end_of_life || null, + projectId: d.project_id || null, + vpcUuid: d.private_network_uuid || null, + tagList: (d.tags || []).join(", "), + createdAt: d.created_at +})); + +// Optional Project/VPC object pickers arrive at context.config. as arrays whose rawId is a single-element array; empty means no filter +const unwrap = (v) => (Array.isArray(v) ? v[0] : v); +for (const [param, column] of Object.entries({ project: "projectId", vpc: "vpcUuid" })) { + const ids = new Set((context.config?.[param] || []).map((o) => unwrap(o.rawId)).filter(Boolean)); + if (ids.size) result = result.filter((row) => ids.has(row[column])); +} diff --git a/plugins/DigitalOcean/v1/dataStreams/scripts/dropletMetrics.js b/plugins/DigitalOcean/v1/dataStreams/scripts/dropletMetrics.js new file mode 100644 index 00000000..a17946dc --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/scripts/dropletMetrics.js @@ -0,0 +1,37 @@ +// CPU arrives as cumulative per-mode counters, so it needs converting to a busy percentage; every other metric is a plain gauge +const metric = String(context.config.metric || "cpu").split(":")[0]; +const series = data?.data?.result || []; +const iso = (t) => new Date(Number(t) * 1000).toISOString(); + +if (metric === "cpu") { + // Sum the counters across modes per timestamp, tracking idle separately + const byTime = {}; + for (const s of series) { + for (const [t, v] of s.values || []) { + const e = (byTime[t] = byTime[t] || { total: 0, idle: 0, modes: {} }); + e.total += Number(v); + e.modes[s.metric.mode] = Number(v); + if (s.metric.mode === "idle") e.idle = Number(v); + } + } + const times = Object.keys(byTime).map(Number).sort((a, b) => a - b); + const rows = []; + for (let i = 1; i < times.length; i++) { + const prev = byTime[times[i - 1]]; + const cur = byTime[times[i]]; + const dTotal = cur.total - prev.total; + const dIdle = cur.idle - prev.idle; + // A counter reset (reboot) makes a delta negative, so skip that interval + const reset = Object.keys(cur.modes).some((m) => cur.modes[m] - (prev.modes[m] ?? 0) < 0); + if (reset || dTotal <= 0) continue; + rows.push({ timestamp: iso(times[i]), value: 100 * (1 - dIdle / dTotal), bytes: null, series: "CPU", unit: "%" }); + } + result = rows; +} else { + const unit = metric.startsWith("memory") || metric.startsWith("filesystem") ? "bytes" : metric.startsWith("load") ? "load" : ""; + result = series.flatMap((s) => { + const m = s.metric || {}; + const label = m.mountpoint || [m.interface, m.direction].filter(Boolean).join(" ") || metric; + return (s.values || []).map(([t, v]) => ({ timestamp: iso(t), value: Number(v), bytes: unit === "bytes" ? Number(v) : null, series: label, unit })); + }); +} diff --git a/plugins/DigitalOcean/v1/dataStreams/scripts/droplets.js b/plugins/DigitalOcean/v1/dataStreams/scripts/droplets.js new file mode 100644 index 00000000..5dae294b --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/scripts/droplets.js @@ -0,0 +1,30 @@ +// Flattens nested region/size/image/networks and joins tags, which would otherwise arrive as an array +// DOKS tags each worker node "k8s:"; other k8s:* tags (e.g. k8s:worker) are not ids +const clusterId = (d) => (d.tags || []).map((t) => /^k8s:([0-9a-f-]{36})$/.exec(t)).find(Boolean)?.[1] || null; +const ip = (d, type) => ((d.networks && d.networks.v4) || []).find((n) => n.type === type)?.ip_address || null; + +result = (data.droplets || []).map((d) => ({ + id: String(d.id), + name: d.name, + status: d.status, + region: d.region?.slug || null, + sizeSlug: d.size_slug, + vcpus: d.vcpus, + memory: d.memory, + disk: d.disk, + image: [d.image?.distribution, d.image?.name].filter(Boolean).join(" "), + publicIp: ip(d, "public"), + privateIp: ip(d, "private"), + vpcUuid: d.vpc_uuid || null, + kubernetesClusterId: clusterId(d), + locked: d.locked, + tagList: (d.tags || []).join(", "), + createdAt: d.created_at +})); + +// Optional Project/VPC object pickers arrive at context.config. as arrays whose rawId is a single-element array; empty means no filter +const unwrap = (v) => (Array.isArray(v) ? v[0] : v); +for (const [param, column] of Object.entries({ vpc: "vpcUuid" })) { + const ids = new Set((context.config?.[param] || []).map((o) => unwrap(o.rawId)).filter(Boolean)); + if (ids.size) result = result.filter((row) => ids.has(row[column])); +} diff --git a/plugins/DigitalOcean/v1/dataStreams/scripts/evaluationTestCases.js b/plugins/DigitalOcean/v1/dataStreams/scripts/evaluationTestCases.js new file mode 100644 index 00000000..4e60dbc5 --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/scripts/evaluationTestCases.js @@ -0,0 +1,16 @@ +// Flattens the star metric and dataset objects into plain columns +result = (data.evaluation_test_cases || []).map((t) => ({ + id: t.test_case_uuid, + name: t.name, + description: t.description || null, + totalRuns: t.total_runs, + latestVersionRuns: t.latest_version_number_of_runs, + version: t.version, + starMetric: t.star_metric?.name || null, + successThreshold: t.star_metric?.success_threshold ?? null, + successThresholdPct: t.star_metric?.success_threshold_pct ?? null, + datasetName: t.dataset_name || t.dataset?.dataset_name || null, + datasetRows: t.dataset?.row_count ?? null, + createdAt: t.created_at, + updatedAt: t.updated_at +})); diff --git a/plugins/DigitalOcean/v1/dataStreams/scripts/invoices.js b/plugins/DigitalOcean/v1/dataStreams/scripts/invoices.js new file mode 100644 index 00000000..6d22885b --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/scripts/invoices.js @@ -0,0 +1,15 @@ +// Combines the issued invoices with the separate invoice_preview object (current month) into one row set +const toRow = (i, preview) => ({ + invoice_uuid: i.invoice_uuid || null, + invoice_id: i.invoice_id || null, + invoice_period: i.invoice_period || null, + amount: i.amount === undefined || i.amount === null || i.amount === "" ? null : Number(i.amount), + preview, + updated_at: i.updated_at || null +}); + +result = (data.invoices || []).map((i) => toRow(i, false)); +if (data.invoice_preview && !data.links?.pages?.prev) { + // Only emit the preview once (first page), as it is repeated on every page + result.unshift(toRow(data.invoice_preview, true)); +} diff --git a/plugins/DigitalOcean/v1/dataStreams/scripts/kubernetesClusters.js b/plugins/DigitalOcean/v1/dataStreams/scripts/kubernetesClusters.js new file mode 100644 index 00000000..03f7d2db --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/scripts/kubernetesClusters.js @@ -0,0 +1,28 @@ +// Flattens cluster status and summarises the embedded node pools +result = (data.kubernetes_clusters || []).map((c) => { + const pools = c.node_pools || []; + return { + id: c.id, + name: c.name, + status: c.status?.state || null, + statusMessage: c.status?.message || null, + region: c.region, + version: c.version, + nodePools: pools.length, + nodes: pools.reduce((sum, p) => sum + (p.count || 0), 0), + ha: c.ha, + autoUpgrade: c.auto_upgrade, + endpoint: c.endpoint || null, + vpcUuid: c.vpc_uuid || null, + tagList: (c.tags || []).join(", "), + createdAt: c.created_at, + updatedAt: c.updated_at + }; +}); + +// Optional Project/VPC object pickers arrive at context.config. as arrays whose rawId is a single-element array; empty means no filter +const unwrap = (v) => (Array.isArray(v) ? v[0] : v); +for (const [param, column] of Object.entries({ vpc: "vpcUuid" })) { + const ids = new Set((context.config?.[param] || []).map((o) => unwrap(o.rawId)).filter(Boolean)); + if (ids.size) result = result.filter((row) => ids.has(row[column])); +} diff --git a/plugins/DigitalOcean/v1/dataStreams/scripts/kubernetesNodes.js b/plugins/DigitalOcean/v1/dataStreams/scripts/kubernetesNodes.js new file mode 100644 index 00000000..7e544fdf --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/scripts/kubernetesNodes.js @@ -0,0 +1,17 @@ +// Flattens node pools into one row per worker node, carrying the pool settings +result = (data.node_pools || []).flatMap((p) => + (p.nodes || []).map((n) => ({ + id: n.id, + name: n.name, + poolName: p.name, + poolSize: p.size, + status: n.status?.state || null, + dropletId: n.droplet_id != null ? String(n.droplet_id) : null, + autoScale: p.auto_scale, + poolCount: p.count, + minNodes: p.min_nodes, + maxNodes: p.max_nodes, + createdAt: n.created_at, + updatedAt: n.updated_at + })) +); diff --git a/plugins/DigitalOcean/v1/dataStreams/scripts/loadBalancerMetrics.js b/plugins/DigitalOcean/v1/dataStreams/scripts/loadBalancerMetrics.js new file mode 100644 index 00000000..55dba043 --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/scripts/loadBalancerMetrics.js @@ -0,0 +1,12 @@ +// Flattens Prometheus-style matrix results into one row per sample, labelled by the labels other than lb_id and region (constant per LB, so noise) +result = (data.data?.result || []).flatMap((r) => { + const labels = Object.entries(r.metric || {}) + .filter(([k]) => k !== "lb_id" && k !== "region") + .map(([, v]) => v); + const series = labels.length ? labels.join(" / ") : "Total"; + return (r.values || []).map(([ts, v]) => ({ + timestamp: new Date(Number(ts) * 1000).toISOString(), + series, + value: Number(v) + })); +}); diff --git a/plugins/DigitalOcean/v1/dataStreams/scripts/loadBalancers.js b/plugins/DigitalOcean/v1/dataStreams/scripts/loadBalancers.js new file mode 100644 index 00000000..bad63460 --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/scripts/loadBalancers.js @@ -0,0 +1,25 @@ +// Flattens region and counts backend Droplets +result = (data.load_balancers || []).map((l) => ({ + id: l.id, + name: l.name, + status: l.status, + ip: l.ip || null, + region: l.region?.slug || null, + type: l.type || null, + network: l.network || null, + size: l.size || null, + sizeUnit: l.size_unit ?? null, + backendDroplets: (l.droplet_ids || []).length, + // Correlation matches scalars only, so only the first backend can be related + primaryBackendDropletId: l.droplet_ids?.length ? String(l.droplet_ids[0]) : null, + targetTag: l.tag || null, + vpcUuid: l.vpc_uuid || null, + createdAt: l.created_at +})); + +// Optional Project/VPC object pickers arrive at context.config. as arrays whose rawId is a single-element array; empty means no filter +const unwrap = (v) => (Array.isArray(v) ? v[0] : v); +for (const [param, column] of Object.entries({ vpc: "vpcUuid" })) { + const ids = new Set((context.config?.[param] || []).map((o) => unwrap(o.rawId)).filter(Boolean)); + if (ids.size) result = result.filter((row) => ids.has(row[column])); +} diff --git a/plugins/DigitalOcean/v1/dataStreams/scripts/projectResources.js b/plugins/DigitalOcean/v1/dataStreams/scripts/projectResources.js new file mode 100644 index 00000000..0fa10e7b --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/scripts/projectResources.js @@ -0,0 +1,16 @@ +// Resources are only listed as URNs ("do::"), so split them into a type and an id that matches the resource's rawId +const projectId = context.objects?.[0]?.rawId; + +result = (data.resources || []).map((r) => { + const [, type, ...rest] = (r.urn || "").split(":"); + const resourceId = rest.join(":"); + return { + id: r.urn, + name: `${type} ${resourceId}`, + projectId, + resourceType: type, + resourceId, + status: r.status || null, + assignedAt: r.assigned_at || null + }; +}); diff --git a/plugins/DigitalOcean/v1/dataStreams/scripts/sessionDialogues.js b/plugins/DigitalOcean/v1/dataStreams/scripts/sessionDialogues.js new file mode 100644 index 00000000..27562be2 --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/scripts/sessionDialogues.js @@ -0,0 +1,29 @@ +// One row per dialogue turn, summarising its steps: tool calls and failures, tool time, token usage and detected signals +const num = (v) => (v === null || v === undefined || v === "" ? null : Number(v)); +result = (data.edges || []).map((e) => e.node).filter(Boolean).map((n) => { + const steps = n.steps || []; + const results = steps.filter((s) => s.type === "tool_result"); + const usage = steps.filter((s) => s.type === "usage").map((s) => s.usage || {}); + const sum = (k) => usage.reduce((t, u) => t + (num(u[k]) || 0), 0); + const signals = n.signals || []; + return { + id: n.id, + sequence: num(n.sequence), + createdAt: n.created_at || null, + runStatus: n.run_status || null, + failureCode: n.failure_code || null, + toolCalls: steps.filter((s) => s.type === "tool_call").length, + toolFailures: results.filter((s) => s.ok === false).length, + toolDurationMs: results.reduce((t, s) => t + (num(s.duration_ms) || 0), 0), + // Each usage step is one model call (the figures are not running totals), so the turn's tokens are the sum + inputTokens: sum("input_tokens"), + outputTokens: sum("output_tokens"), + cachedInputTokens: sum("cached_input_tokens"), + reasoningTokens: sum("reasoning_tokens"), + modelCalls: usage.length, + model: usage.map((u) => u.model_id).filter(Boolean)[0] || null, + signalCount: signals.length, + signalLabels: [...new Set(signals.map((s) => s.label).filter(Boolean))], + userMessage: n.user_message || null + }; +}); diff --git a/plugins/DigitalOcean/v1/dataStreams/scripts/sessionSignals.js b/plugins/DigitalOcean/v1/dataStreams/scripts/sessionSignals.js new file mode 100644 index 00000000..80d5113a --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/scripts/sessionSignals.js @@ -0,0 +1,15 @@ +// One row per signal detected in a session's turns; confidence can arrive as a string +result = (data.edges || []).map((e) => e.node).filter(Boolean).flatMap((n) => + (n.signals || []).map((s, i) => ({ + id: `${n.id}-${i}`, + turn: n.sequence === undefined ? null : Number(n.sequence), + createdAt: n.created_at || null, + category: s.category || null, + label: s.label || null, + signalType: s.signal_type || null, + layer: s.layer || null, + confidence: s.confidence === undefined || s.confidence === null ? null : Number(s.confidence), + snippet: s.snippet || null, + stepIndex: s.step_index ?? null + })) +); diff --git a/plugins/DigitalOcean/v1/dataStreams/scripts/triggerExecutions.js b/plugins/DigitalOcean/v1/dataStreams/scripts/triggerExecutions.js new file mode 100644 index 00000000..f3ff5970 --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/scripts/triggerExecutions.js @@ -0,0 +1,11 @@ +// Adds a run duration from the execution's created and updated times +result = (data.executions || []).map((e) => ({ + id: e.execution_id, + status: e.status, + failureReason: e.failure_reason || null, + sessionId: e.session_id || null, + outputTruncated: e.output_truncated ?? null, + createdAt: e.created_at, + updatedAt: e.updated_at, + durationSeconds: e.created_at && e.updated_at && ["succeeded", "failed"].includes(e.status) ? (Date.parse(e.updated_at) - Date.parse(e.created_at)) / 1000 : null +})); diff --git a/plugins/DigitalOcean/v1/dataStreams/scripts/triggers.js b/plugins/DigitalOcean/v1/dataStreams/scripts/triggers.js new file mode 100644 index 00000000..7c10f40a --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/scripts/triggers.js @@ -0,0 +1,14 @@ +// Flattens the trigger's cron settings into scalar columns +result = (data.triggers || []).map((t) => ({ + id: t.trigger_id, + name: t.name || t.trigger_id, + kind: t.kind || null, + status: t.status || null, + schedule: t.cron?.cron_expr || null, + timezone: t.cron?.timezone || null, + nextRunAt: t.cron?.next_run_at || null, + sessionMode: t.session_mode || null, + boundSessionId: t.bound_session_id || null, + createdAt: t.created_at, + updatedAt: t.updated_at +})); diff --git a/plugins/DigitalOcean/v1/dataStreams/sessionDialogues.json b/plugins/DigitalOcean/v1/dataStreams/sessionDialogues.json new file mode 100644 index 00000000..6c103819 --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/sessionDialogues.json @@ -0,0 +1,166 @@ +{ + "name": "sessionDialogues", + "displayName": "Session Dialogues", + "description": "Turns of a Harness Runtime session recorded by Signals, with each turn's run status, tool calls, token usage and detected signals", + "tags": [ + "AI", + "Quality" + ], + "baseDataSourceName": "httpRequestScopedSingle", + "config": { + "httpMethod": "get", + "endpointPath": "v1/signals/sessions/{{object.rawId}}/dialogues", + "postRequestScript": "sessionDialogues.js", + "paging": { + "mode": "token", + "pageSize": { + "realm": "queryArg", + "path": "limit", + "value": "100" + }, + "in": { + "realm": "payload", + "path": "edges.99.cursor" + }, + "out": { + "realm": "queryArg", + "path": "after" + } + } + }, + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "Agent Session" + ] + } + }, + "metadata": [ + { + "name": "id", + "displayName": "Dialogue ID", + "shape": "string", + "visible": false + }, + { + "name": "sequence", + "displayName": "Sequence", + "shape": [ + "number", + { + "thousandsSeparator": false, + "decimalPlaces": 0 + } + ] + }, + { + "name": "createdAt", + "displayName": "Time", + "shape": "date", + "role": "timestamp" + }, + { + "name": "runStatus", + "displayName": "Run Status", + "shape": "string" + }, + { + "name": "health", + "displayName": "Health", + "computed": true, + "valueExpression": "{{ $['runStatus'] }}", + "shape": [ + "state", + { + "map": { + "success": [ + "completed" + ], + "error": [ + "failed", + "error", + "cancelled" + ], + "warning": [ + "running", + "pending" + ] + } + } + ] + }, + { + "name": "failureCode", + "displayName": "Failure Code", + "shape": "string" + }, + { + "name": "toolCalls", + "displayName": "Tool Calls", + "shape": "number" + }, + { + "name": "toolFailures", + "displayName": "Tool Failures", + "shape": "number" + }, + { + "name": "toolDurationMs", + "displayName": "Tool Time", + "shape": "milliseconds" + }, + { + "name": "inputTokens", + "displayName": "Input Tokens", + "shape": "number", + "role": "value" + }, + { + "name": "outputTokens", + "displayName": "Output Tokens", + "shape": "number" + }, + { + "name": "cachedInputTokens", + "displayName": "Cached Input Tokens", + "shape": "number" + }, + { + "name": "reasoningTokens", + "displayName": "Reasoning Tokens", + "shape": "number" + }, + { + "name": "modelCalls", + "displayName": "Model Calls", + "shape": "number" + }, + { + "name": "model", + "displayName": "Model", + "shape": "string" + }, + { + "name": "signalCount", + "displayName": "Signals", + "shape": "number" + }, + { + "name": "signalLabels", + "displayName": "Signal Labels", + "shape": [ + "array", + { + "itemShape": "string" + } + ] + }, + { + "name": "userMessage", + "displayName": "User Message", + "shape": "string" + } + ], + "timeframes": false +} diff --git a/plugins/DigitalOcean/v1/dataStreams/sessionSignals.json b/plugins/DigitalOcean/v1/dataStreams/sessionSignals.json new file mode 100644 index 00000000..b0e6f8d8 --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/sessionSignals.json @@ -0,0 +1,108 @@ +{ + "name": "sessionSignals", + "displayName": "Session Signals", + "description": "Behavioral signals detected in a Harness Runtime session (from DigitalOcean Signals), such as execution failures and loops, with their confidence", + "tags": [ + "AI", + "Quality" + ], + "baseDataSourceName": "httpRequestScopedSingle", + "config": { + "httpMethod": "get", + "endpointPath": "v1/signals/sessions/{{object.rawId}}/dialogues", + "postRequestScript": "sessionSignals.js", + "paging": { + "mode": "token", + "pageSize": { + "realm": "queryArg", + "path": "limit", + "value": "100" + }, + "in": { + "realm": "payload", + "path": "edges.99.cursor" + }, + "out": { + "realm": "queryArg", + "path": "after" + } + } + }, + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "Agent Session" + ] + } + }, + "metadata": [ + { + "name": "id", + "displayName": "ID", + "shape": "string", + "visible": false + }, + { + "name": "createdAt", + "displayName": "Time", + "shape": "date", + "role": "timestamp" + }, + { + "name": "turn", + "displayName": "Sequence", + "shape": [ + "number", + { + "thousandsSeparator": false, + "decimalPlaces": 0 + } + ] + }, + { + "name": "category", + "displayName": "Category", + "shape": "string" + }, + { + "name": "label", + "displayName": "Signal", + "shape": "string", + "role": "label" + }, + { + "name": "signalType", + "displayName": "Signal Type", + "shape": "string" + }, + { + "name": "layer", + "displayName": "Layer", + "shape": "string" + }, + { + "name": "confidence", + "displayName": "Confidence", + "shape": [ + "percent", + { + "asZeroToOne": true, + "decimalPlaces": 0 + } + ], + "role": "value" + }, + { + "name": "snippet", + "displayName": "Detail", + "shape": "string" + }, + { + "name": "stepIndex", + "displayName": "Step", + "shape": "number" + } + ], + "timeframes": false +} diff --git a/plugins/DigitalOcean/v1/dataStreams/triggerExecutions.json b/plugins/DigitalOcean/v1/dataStreams/triggerExecutions.json new file mode 100644 index 00000000..4f1093f8 --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/triggerExecutions.json @@ -0,0 +1,98 @@ +{ + "name": "triggerExecutions", + "displayName": "Trigger Executions", + "description": "Execution history of a Harness Runtime trigger with each run's status, duration and failure reason", + "tags": [ + "AI", + "Automation" + ], + "baseDataSourceName": "httpRequestScopedSingle", + "config": { + "httpMethod": "get", + "endpointPath": "v2/agents/triggers/{{object.rawId}}/executions", + "postRequestScript": "triggerExecutions.js", + "getArgs": [ + { + "key": "page_size", + "value": "200" + } + ] + }, + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "Trigger" + ] + } + }, + "metadata": [ + { + "name": "id", + "displayName": "Execution ID", + "shape": "string", + "visible": false + }, + { + "name": "createdAt", + "displayName": "Started", + "shape": "date", + "role": "timestamp" + }, + { + "name": "status", + "displayName": "Status", + "shape": "string" + }, + { + "name": "health", + "displayName": "Health", + "computed": true, + "valueExpression": "{{ $['status'] }}", + "shape": [ + "state", + { + "map": { + "success": [ + "succeeded" + ], + "error": [ + "failed" + ], + "warning": [ + "pending", + "running" + ] + } + } + ] + }, + { + "name": "durationSeconds", + "displayName": "Duration", + "shape": "seconds" + }, + { + "name": "failureReason", + "displayName": "Failure Reason", + "shape": "string" + }, + { + "name": "outputTruncated", + "displayName": "Output Truncated", + "shape": "boolean" + }, + { + "name": "updatedAt", + "displayName": "Updated", + "shape": "date" + }, + { + "name": "sessionId", + "displayName": "Session ID", + "shape": "string", + "visible": false + } + ], + "timeframes": false +} diff --git a/plugins/DigitalOcean/v1/dataStreams/triggers.json b/plugins/DigitalOcean/v1/dataStreams/triggers.json new file mode 100644 index 00000000..871f6990 --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/triggers.json @@ -0,0 +1,107 @@ +{ + "name": "triggers", + "displayName": "Triggers", + "description": "Harness Runtime cron and webhook triggers with their status and schedule", + "tags": [ + "AI", + "Inventory" + ], + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "get", + "endpointPath": "v2/agents/triggers", + "postRequestScript": "triggers.js", + "getArgs": [ + { + "key": "page_size", + "value": "200" + } + ] + }, + "matches": "none", + "metadata": [ + { + "name": "id", + "displayName": "ID", + "shape": "string", + "visible": false + }, + { + "name": "name", + "displayName": "Name", + "shape": "string", + "role": "label" + }, + { + "name": "kind", + "displayName": "Kind", + "shape": "string" + }, + { + "name": "status", + "displayName": "Status", + "shape": "string" + }, + { + "name": "health", + "displayName": "Health", + "computed": true, + "valueExpression": "{{ $['status'] }}", + "shape": [ + "state", + { + "map": { + "success": [ + "active" + ], + "unknown": [ + "paused" + ] + } + } + ] + }, + { + "name": "schedule", + "displayName": "Schedule", + "shape": "string" + }, + { + "name": "timezone", + "displayName": "Timezone", + "shape": "string" + }, + { + "name": "nextRunAt", + "displayName": "Next Run", + "shape": "date" + }, + { + "name": "sessionMode", + "displayName": "Session Mode", + "shape": "string" + }, + { + "name": "boundSessionId", + "displayName": "Bound Session ID", + "shape": "string", + "visible": false + }, + { + "name": "createdAt", + "displayName": "Created", + "shape": "date" + }, + { + "name": "updatedAt", + "displayName": "Updated", + "shape": "date" + }, + { + "sourceId": "id", + "sourceType": "Trigger", + "name": "name" + } + ], + "timeframes": false +} diff --git a/plugins/DigitalOcean/v1/dataStreams/vpcs.json b/plugins/DigitalOcean/v1/dataStreams/vpcs.json new file mode 100644 index 00000000..e50eca71 --- /dev/null +++ b/plugins/DigitalOcean/v1/dataStreams/vpcs.json @@ -0,0 +1,79 @@ +{ + "name": "vpcs", + "displayName": "VPCs", + "description": "VPC networks with their region, IP range and whether they are the default for their region", + "tags": [ + "Network", + "Inventory" + ], + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "get", + "endpointPath": "v2/vpcs", + "pathToData": "vpcs", + "paging": { + "mode": "nextUrl", + "pageSize": { + "realm": "queryArg", + "path": "per_page", + "value": "200" + }, + "in": { + "realm": "payload", + "path": "links.pages.next" + } + } + }, + "matches": "none", + "metadata": [ + { + "name": "id", + "displayName": "ID", + "shape": "string", + "visible": false + }, + { + "name": "name", + "displayName": "Name", + "shape": "string", + "role": "label" + }, + { + "name": "region", + "displayName": "Region", + "shape": "string" + }, + { + "name": "ip_range", + "displayName": "IP Range", + "shape": "string" + }, + { + "name": "default", + "displayName": "Default", + "shape": "boolean" + }, + { + "name": "description", + "displayName": "Description", + "shape": "string" + }, + { + "name": "urn", + "displayName": "URN", + "shape": "string", + "visible": false + }, + { + "name": "created_at", + "displayName": "Created", + "shape": "date" + }, + { + "sourceId": "id", + "sourceType": "VPC", + "name": "name" + } + ], + "timeframes": false +} diff --git a/plugins/DigitalOcean/v1/defaultContent/Core Cloud/app.dash.json b/plugins/DigitalOcean/v1/defaultContent/Core Cloud/app.dash.json new file mode 100644 index 00000000..797d5ac4 --- /dev/null +++ b/plugins/DigitalOcean/v1/defaultContent/Core Cloud/app.dash.json @@ -0,0 +1,534 @@ +{ + "name": "App", + "schemaVersion": "1.5", + "timeframe": "last24hours", + "variables": [ + "{{variables.[App]}}" + ], + "dashboard": { + "_type": "layout/grid", + "columns": 4, + "version": 1, + "contents": [ + { + "i": "b80895a6-9a87-4ee8-9b05-f4a6fe79805f", + "x": 0, + "y": 0, + "w": 1, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Properties", + "description": "Imported properties of this app", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "datastream-properties", + "name": "properties" + }, + "timeframe": "none", + "scope": { + "scope": "{{scopes.[Apps]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[App]}}" + }, + "variables": [ + "{{variables.[App]}}" + ], + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": true + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "richTable", + "encoding": { + "columns": [ + { + "field": "name", + "title": "Name", + "renderer": { + "type": "text" + } + }, + { + "field": "activeDeploymentPhase", + "title": "Active Deployment", + "renderer": { + "type": "badge", + "colors": { + "ACTIVE": "#22C55E", + "ERROR": "#EF4444", + "CANCELED": "#EF4444", + "PENDING_BUILD": "#F59E0B", + "BUILDING": "#F59E0B", + "PENDING_DEPLOY": "#F59E0B", + "DEPLOYING": "#F59E0B", + "SUPERSEDED": "#94A3B8", + "UNKNOWN": "#94A3B8" + }, + "defaultColor": "#94A3B8" + } + }, + { + "field": "region", + "title": "Region", + "renderer": { + "type": "text" + } + }, + { + "field": "tier", + "title": "Tier", + "renderer": { + "type": "text" + } + }, + { + "field": "liveUrl", + "title": "Live URL", + "renderer": { + "type": "link" + } + }, + { + "field": "lastDeploymentAt", + "title": "Last Deployment", + "renderer": { + "type": "date", + "relative": true + } + }, + { + "field": "createdAt", + "title": "Created", + "renderer": { + "type": "date", + "relative": true + } + } + ] + }, + "style": { + "richTableTranspose": true, + "richTableCellPadding": 4, + "richTableFontSize": 13 + } + } + } + } + }, + { + "i": "cc195425-66de-4256-a44c-381be6ea79f1", + "x": 1, + "y": 0, + "w": 3, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Component Health", + "description": "Health of each component, with CPU and memory usage", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[appHealth]}}", + "name": "appHealth", + "pluginConfigId": "{{configId}}" + }, + "timeframe": "none", + "scope": { + "scope": "{{scopes.[Apps]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[App]}}" + }, + "variables": [ + "{{variables.[App]}}" + ], + "visualisation": { + "type": "data-stream-blocks", + "config": { + "data-stream-blocks": { + "labelColumn": "name", + "stateColumn": "health", + "linkColumn": "none", + "columns": 3, + "sublabel": "state" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "statusGrid", + "encoding": { + "label": { + "field": "name", + "type": "nominal" + }, + "status": { + "field": "health", + "type": "nominal" + } + }, + "style": { + "statusGridColumnsPerRow": 3, + "statusGridMaxBlockHeight": 140, + "statusGridLabelWrap": true, + "statusGridOrderByField": "name", + "statusGridOrderDirection": "asc" + } + } + } + } + }, + { + "i": "741fc7aa-3c23-46e9-866e-5f32c6bb6aa8", + "x": 0, + "y": 3, + "w": 2, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "CPU Usage", + "description": "CPU usage of each component instance", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[appMetrics]}}", + "name": "appMetrics", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "metric": "cpu_percentage" + }, + "sort": { + "by": [ + [ + "timestamp", + "asc" + ] + ] + } + }, + "scope": { + "scope": "{{scopes.[Apps]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[App]}}" + }, + "variables": [ + "{{variables.[App]}}" + ], + "visualisation": { + "type": "data-stream-line-graph", + "config": { + "data-stream-line-graph": { + "xAxisColumn": "timestamp", + "yAxisColumn": [ + "value" + ], + "seriesColumn": "instance", + "showLegend": true, + "legendPosition": "bottom", + "yAxisLabel": "CPU (%)", + "showYAxisLabel": true, + "showTrendLine": false + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "line", + "encoding": { + "x": { + "field": "timestamp", + "type": "temporal", + "title": "Time" + }, + "y": { + "field": "value", + "type": "quantitative", + "title": "CPU (%)" + }, + "series": { + "field": "instance", + "type": "nominal" + } + }, + "markLines": [ + { + "value": 80, + "label": "80%", + "color": "#EF4444" + } + ], + "style": { + "cartesianAreaGradient": true, + "cartesianSmooth": true, + "cartesianSymbol": "none", + "cartesianLineWidth": 2, + "cartesianYAxisRangeMode": "percentage", + "colors": [ + "#0069FF", + "#8B5CF6", + "#06B6D4", + "#EC4899", + "#F59E0B" + ], + "legendPosition": "bottom", + "cartesianShowVerticalGridLines": false + } + } + } + } + }, + { + "i": "4853bc76-d458-4736-b1b5-35faca6d9608", + "x": 2, + "y": 3, + "w": 2, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Memory Usage", + "description": "Memory usage of each component instance", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[appMetrics]}}", + "name": "appMetrics", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "metric": "memory_percentage" + }, + "sort": { + "by": [ + [ + "timestamp", + "asc" + ] + ] + } + }, + "scope": { + "scope": "{{scopes.[Apps]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[App]}}" + }, + "variables": [ + "{{variables.[App]}}" + ], + "visualisation": { + "type": "data-stream-line-graph", + "config": { + "data-stream-line-graph": { + "xAxisColumn": "timestamp", + "yAxisColumn": [ + "value" + ], + "seriesColumn": "instance", + "showLegend": true, + "legendPosition": "bottom", + "yAxisLabel": "Memory (%)", + "showYAxisLabel": true, + "showTrendLine": false + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "line", + "encoding": { + "x": { + "field": "timestamp", + "type": "temporal", + "title": "Time" + }, + "y": { + "field": "value", + "type": "quantitative", + "title": "Memory (%)" + }, + "series": { + "field": "instance", + "type": "nominal" + } + }, + "markLines": [ + { + "value": 80, + "label": "80%", + "color": "#EF4444" + } + ], + "style": { + "cartesianAreaGradient": true, + "cartesianSmooth": true, + "cartesianSymbol": "none", + "cartesianLineWidth": 2, + "cartesianYAxisRangeMode": "percentage", + "colors": [ + "#14B8A6", + "#6366F1", + "#10B981", + "#3B82F6", + "#EC4899" + ], + "legendPosition": "bottom", + "cartesianShowVerticalGridLines": false + } + } + } + } + }, + { + "i": "5c01dd34-6693-41f0-b59a-7a149c2c5ac2", + "x": 0, + "y": 5, + "w": 4, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Recent Deployments", + "description": "The 50 most recent deployments of this app", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[appDeployments]}}", + "name": "appDeployments", + "pluginConfigId": "{{configId}}", + "sort": { + "by": [ + [ + "created_at", + "desc" + ] + ] + } + }, + "timeframe": "none", + "scope": { + "scope": "{{scopes.[Apps]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[App]}}" + }, + "variables": [ + "{{variables.[App]}}" + ], + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": false, + "columnOrder": [ + "created_at", + "health", + "phase", + "cause", + "phase_last_updated_at", + "updated_at" + ], + "hiddenColumns": [ + "id" + ] + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "richTable", + "encoding": { + "columns": [ + { + "field": "created_at", + "title": "Created", + "renderer": { + "type": "date" + }, + "width": 170 + }, + { + "field": "phase", + "title": "Phase", + "renderer": { + "type": "badge", + "colors": { + "ACTIVE": "#22C55E", + "ERROR": "#EF4444", + "CANCELED": "#EF4444", + "PENDING_BUILD": "#F59E0B", + "BUILDING": "#F59E0B", + "PENDING_DEPLOY": "#F59E0B", + "DEPLOYING": "#F59E0B", + "SUPERSEDED": "#94A3B8", + "UNKNOWN": "#94A3B8" + }, + "defaultColor": "#94A3B8" + } + }, + { + "field": "cause", + "title": "Cause", + "renderer": { + "type": "text" + } + }, + { + "field": "phase_last_updated_at", + "title": "Phase Updated", + "renderer": { + "type": "date", + "relative": true + } + }, + { + "field": "updated_at", + "title": "Updated", + "renderer": { + "type": "date", + "relative": true + } + } + ] + }, + "style": { + "richTableSort": { + "field": "created_at", + "direction": "desc" + }, + "richTableCellPadding": 6, + "richTableWrapText": true + } + } + } + } + } + ] + } +} diff --git a/plugins/DigitalOcean/v1/defaultContent/Core Cloud/droplet.dash.json b/plugins/DigitalOcean/v1/defaultContent/Core Cloud/droplet.dash.json new file mode 100644 index 00000000..974ee41b --- /dev/null +++ b/plugins/DigitalOcean/v1/defaultContent/Core Cloud/droplet.dash.json @@ -0,0 +1,873 @@ +{ + "name": "Droplet", + "schemaVersion": "1.5", + "timeframe": "last24hours", + "variables": [ + "{{variables.[Droplet]}}" + ], + "dashboard": { + "_type": "layout/grid", + "columns": 4, + "version": 1, + "contents": [ + { + "i": "98a9f729-af6a-4b40-86e1-cac5b1a2809c", + "x": 0, + "y": 0, + "w": 1, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Properties", + "description": "Imported properties of this droplet", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "datastream-properties", + "name": "properties" + }, + "timeframe": "none", + "scope": { + "scope": "{{scopes.[Droplets]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Droplet]}}" + }, + "variables": [ + "{{variables.[Droplet]}}" + ], + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": true + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "richTable", + "encoding": { + "columns": [ + { + "field": "name", + "title": "Name", + "renderer": { + "type": "text" + } + }, + { + "field": "status", + "title": "Status", + "renderer": { + "type": "badge", + "colors": { + "active": "#22C55E", + "running": "#22C55E", + "online": "#22C55E", + "new": "#F59E0B", + "off": "#94A3B8", + "archive": "#94A3B8", + "errored": "#EF4444", + "error": "#EF4444" + } + } + }, + { + "field": "region", + "title": "Region", + "renderer": { + "type": "text" + } + }, + { + "field": "sizeSlug", + "title": "Size", + "renderer": { + "type": "text" + } + }, + { + "field": "vcpus", + "title": "vCPUs", + "renderer": { + "type": "number" + } + }, + { + "field": "memory", + "title": "Memory", + "renderer": { + "type": "number", + "suffix": " MB" + } + }, + { + "field": "disk", + "title": "Disk", + "renderer": { + "type": "number", + "suffix": " GB" + } + }, + { + "field": "image", + "title": "Image", + "renderer": { + "type": "text" + } + }, + { + "field": "publicIp", + "title": "Public IP", + "renderer": { + "type": "text" + } + }, + { + "field": "privateIp", + "title": "Private IP", + "renderer": { + "type": "text" + } + }, + { + "field": "tagList", + "title": "Tags", + "renderer": { + "type": "tag-list", + "color": "#334155" + } + }, + { + "field": "createdAt", + "title": "Created", + "renderer": { + "type": "date", + "relative": true + } + } + ] + }, + "style": { + "richTableTranspose": true, + "richTableCellPadding": 4, + "richTableFontSize": 13 + } + } + } + } + }, + { + "i": "8eaf9b95-1d58-4ec6-98c1-b32aeb1e34c8", + "x": 1, + "y": 0, + "w": 1, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "CPU Now", + "description": "Most recent CPU busy percentage", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[dropletMetrics]}}", + "name": "dropletMetrics", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "metric": "cpu" + }, + "sort": { + "by": [ + [ + "timestamp", + "desc" + ] + ] + }, + "metadata": [ + { + "name": "value", + "shape": [ + "percent", + { + "decimalPlaces": 1 + } + ] + }, + { + "pattern": ".*" + } + ] + }, + "scope": { + "scope": "{{scopes.[Droplets]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Droplet]}}" + }, + "variables": [ + "{{variables.[Droplet]}}" + ], + "visualisation": { + "type": "data-stream-gauge", + "config": { + "data-stream-gauge": { + "value": { + "type": "mean", + "columns": [ + "value" + ] + }, + "label": "CPU (%)", + "minimum": 0, + "maximum": 100 + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "gauge", + "encoding": { + "value": { + "field": "value", + "type": "quantitative", + "title": "CPU" + } + }, + "style": { + "gaugeMin": 0, + "gaugeMax": 100, + "gaugeLabelText": "Latest CPU", + "labelFontSize": 28, + "gaugeBands": [ + { + "to": 0.6, + "color": "#22C55E" + }, + { + "to": 0.8, + "color": "#F59E0B" + }, + { + "to": 1, + "color": "#EF4444" + } + ] + } + } + } + } + }, + { + "i": "f9045505-4a87-4acc-ab2b-4a3c6fab0f74", + "x": 2, + "y": 0, + "w": 2, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "CPU Usage", + "description": "Percentage of CPU time spent busy", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[dropletMetrics]}}", + "name": "dropletMetrics", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "metric": "cpu" + }, + "sort": { + "by": [ + [ + "timestamp", + "asc" + ] + ] + }, + "metadata": [ + { + "name": "value", + "shape": [ + "percent", + { + "decimalPlaces": 1 + } + ] + }, + { + "pattern": ".*" + } + ] + }, + "scope": { + "scope": "{{scopes.[Droplets]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Droplet]}}" + }, + "variables": [ + "{{variables.[Droplet]}}" + ], + "visualisation": { + "type": "data-stream-line-graph", + "config": { + "data-stream-line-graph": { + "xAxisColumn": "timestamp", + "yAxisColumn": [ + "value" + ], + "seriesColumn": "none", + "showLegend": false, + "legendPosition": "bottom", + "yAxisLabel": "CPU (%)", + "showYAxisLabel": true, + "showTrendLine": false + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "line", + "encoding": { + "x": { + "field": "timestamp", + "type": "temporal", + "title": "Time" + }, + "y": { + "field": "value", + "type": "quantitative", + "title": "CPU" + } + }, + "markLines": [ + { + "value": 80, + "label": "80%", + "color": "#EF4444" + } + ], + "style": { + "cartesianAreaGradient": true, + "cartesianSmooth": true, + "cartesianSymbol": "none", + "cartesianLineWidth": 2, + "cartesianYAxisRangeMode": "percentage", + "colors": [ + "#0069FF" + ], + "cartesianShowVerticalGridLines": false + } + } + } + } + }, + { + "i": "66622130-b460-4348-b9a9-37f0d732acbd", + "x": 0, + "y": 3, + "w": 2, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Load Average", + "description": "One-minute load average", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[dropletMetrics]}}", + "name": "dropletMetrics", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "metric": "load_1" + }, + "sort": { + "by": [ + [ + "timestamp", + "asc" + ] + ] + }, + "metadata": [ + { + "name": "value", + "shape": [ + "number", + { + "decimalPlaces": 2 + } + ] + }, + { + "pattern": ".*" + } + ] + }, + "scope": { + "scope": "{{scopes.[Droplets]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Droplet]}}" + }, + "variables": [ + "{{variables.[Droplet]}}" + ], + "visualisation": { + "type": "data-stream-line-graph", + "config": { + "data-stream-line-graph": { + "xAxisColumn": "timestamp", + "yAxisColumn": [ + "value" + ], + "seriesColumn": "none", + "showLegend": false, + "legendPosition": "bottom", + "yAxisLabel": "Load", + "showYAxisLabel": true, + "showTrendLine": false + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "line", + "encoding": { + "x": { + "field": "timestamp", + "type": "temporal", + "title": "Time" + }, + "y": { + "field": "value", + "type": "quantitative", + "title": "Load" + } + }, + "markLines": [ + { + "type": "average", + "label": "Average", + "color": "#94A3B8" + } + ], + "style": { + "cartesianSmooth": true, + "cartesianSymbol": "none", + "cartesianLineWidth": 2, + "colors": [ + "#8B5CF6" + ], + "cartesianShowVerticalGridLines": false + } + } + } + } + }, + { + "i": "878b06e8-ec14-40a3-b40f-396a37c85312", + "x": 2, + "y": 3, + "w": 2, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Memory Available", + "description": "Memory available to processes", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[dropletMetrics]}}", + "name": "dropletMetrics", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "metric": "memory_available" + }, + "sort": { + "by": [ + [ + "timestamp", + "asc" + ] + ] + } + }, + "scope": { + "scope": "{{scopes.[Droplets]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Droplet]}}" + }, + "variables": [ + "{{variables.[Droplet]}}" + ], + "visualisation": { + "type": "data-stream-line-graph", + "config": { + "data-stream-line-graph": { + "xAxisColumn": "timestamp", + "yAxisColumn": [ + "bytes" + ], + "seriesColumn": "none", + "showLegend": false, + "legendPosition": "bottom", + "yAxisLabel": "Available", + "showYAxisLabel": true, + "showTrendLine": false + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "line", + "encoding": { + "x": { + "field": "timestamp", + "type": "temporal", + "title": "Time" + }, + "y": { + "field": "bytes", + "type": "quantitative", + "title": "Available" + } + }, + "style": { + "cartesianAreaGradient": true, + "cartesianSmooth": true, + "cartesianSymbol": "none", + "cartesianLineWidth": 2, + "colors": [ + "#06B6D4" + ], + "cartesianShowVerticalGridLines": false + } + } + } + } + }, + { + "i": "77d46510-0b99-4651-a0ca-263b88cee79d", + "x": 0, + "y": 5, + "w": 2, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Disk Free", + "description": "Free space on each mounted filesystem", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[dropletMetrics]}}", + "name": "dropletMetrics", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "metric": "filesystem_free" + }, + "sort": { + "by": [ + [ + "timestamp", + "asc" + ] + ] + } + }, + "scope": { + "scope": "{{scopes.[Droplets]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Droplet]}}" + }, + "variables": [ + "{{variables.[Droplet]}}" + ], + "visualisation": { + "type": "data-stream-line-graph", + "config": { + "data-stream-line-graph": { + "xAxisColumn": "timestamp", + "yAxisColumn": [ + "bytes" + ], + "seriesColumn": "series", + "showLegend": true, + "legendPosition": "bottom", + "yAxisLabel": "Free", + "showYAxisLabel": true, + "showTrendLine": false + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "line", + "encoding": { + "x": { + "field": "timestamp", + "type": "temporal", + "title": "Time" + }, + "y": { + "field": "bytes", + "type": "quantitative", + "title": "Free" + }, + "series": { + "field": "series", + "type": "nominal" + } + }, + "style": { + "cartesianAreaGradient": true, + "cartesianSmooth": true, + "cartesianSymbol": "none", + "cartesianLineWidth": 2, + "colors": [ + "#14B8A6", + "#6366F1", + "#F59E0B", + "#EC4899", + "#3B82F6" + ], + "legendPosition": "bottom", + "cartesianShowVerticalGridLines": false + } + } + } + } + }, + { + "i": "b590dbf5-c65e-4ed5-aea1-6b2e96b2a5ff", + "x": 2, + "y": 5, + "w": 1, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Public Bandwidth In", + "description": "Inbound traffic on the public interface (unit not stated by the API)", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[dropletMetrics]}}", + "name": "dropletMetrics", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "metric": "bandwidth:public:inbound" + }, + "sort": { + "by": [ + [ + "timestamp", + "asc" + ] + ] + }, + "metadata": [ + { + "name": "value", + "shape": [ + "number", + { + "decimalPlaces": 2 + } + ] + }, + { + "pattern": ".*" + } + ] + }, + "scope": { + "scope": "{{scopes.[Droplets]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Droplet]}}" + }, + "variables": [ + "{{variables.[Droplet]}}" + ], + "visualisation": { + "type": "data-stream-line-graph", + "config": { + "data-stream-line-graph": { + "xAxisColumn": "timestamp", + "yAxisColumn": [ + "value" + ], + "seriesColumn": "none", + "showLegend": false, + "legendPosition": "bottom", + "yAxisLabel": "Inbound", + "showYAxisLabel": true, + "showTrendLine": false + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "line", + "encoding": { + "x": { + "field": "timestamp", + "type": "temporal", + "title": "Time" + }, + "y": { + "field": "value", + "type": "quantitative", + "title": "Inbound" + } + }, + "style": { + "cartesianAreaGradient": true, + "cartesianSmooth": true, + "cartesianSymbol": "none", + "cartesianLineWidth": 2, + "colors": [ + "#10B981" + ], + "cartesianShowVerticalGridLines": false + } + } + } + } + }, + { + "i": "4c7c6698-7208-45af-99e1-f5f6ea8601bd", + "x": 3, + "y": 5, + "w": 1, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Public Bandwidth Out", + "description": "Outbound traffic on the public interface (unit not stated by the API)", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[dropletMetrics]}}", + "name": "dropletMetrics", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "metric": "bandwidth:public:outbound" + }, + "sort": { + "by": [ + [ + "timestamp", + "asc" + ] + ] + }, + "metadata": [ + { + "name": "value", + "shape": [ + "number", + { + "decimalPlaces": 2 + } + ] + }, + { + "pattern": ".*" + } + ] + }, + "scope": { + "scope": "{{scopes.[Droplets]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Droplet]}}" + }, + "variables": [ + "{{variables.[Droplet]}}" + ], + "visualisation": { + "type": "data-stream-line-graph", + "config": { + "data-stream-line-graph": { + "xAxisColumn": "timestamp", + "yAxisColumn": [ + "value" + ], + "seriesColumn": "none", + "showLegend": false, + "legendPosition": "bottom", + "yAxisLabel": "Outbound", + "showYAxisLabel": true, + "showTrendLine": false + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "line", + "encoding": { + "x": { + "field": "timestamp", + "type": "temporal", + "title": "Time" + }, + "y": { + "field": "value", + "type": "quantitative", + "title": "Outbound" + } + }, + "style": { + "cartesianAreaGradient": true, + "cartesianSmooth": true, + "cartesianSymbol": "none", + "cartesianLineWidth": 2, + "colors": [ + "#EC4899" + ], + "cartesianShowVerticalGridLines": false + } + } + } + } + } + ] + } +} diff --git a/plugins/DigitalOcean/v1/defaultContent/Core Cloud/kubernetesCluster.dash.json b/plugins/DigitalOcean/v1/defaultContent/Core Cloud/kubernetesCluster.dash.json new file mode 100644 index 00000000..a8827c36 --- /dev/null +++ b/plugins/DigitalOcean/v1/defaultContent/Core Cloud/kubernetesCluster.dash.json @@ -0,0 +1,580 @@ +{ + "name": "Kubernetes Cluster", + "schemaVersion": "1.5", + "timeframe": "last24hours", + "variables": [ + "{{variables.[Kubernetes Cluster]}}" + ], + "dashboard": { + "_type": "layout/grid", + "columns": 4, + "version": 1, + "contents": [ + { + "i": "877c4568-cfbb-44bd-adc5-53402d738ea5", + "x": 0, + "y": 0, + "w": 1, + "h": 5, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Properties", + "description": "Imported properties of this Kubernetes cluster", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "datastream-properties", + "name": "properties" + }, + "timeframe": "none", + "scope": { + "scope": "{{scopes.[Kubernetes Clusters]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Kubernetes Cluster]}}" + }, + "variables": [ + "{{variables.[Kubernetes Cluster]}}" + ], + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": true + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "richTable", + "encoding": { + "columns": [ + { + "field": "name", + "title": "Name", + "renderer": { + "type": "text" + } + }, + { + "field": "status", + "title": "Status", + "renderer": { + "type": "badge", + "colors": { + "active": "#22C55E", + "running": "#22C55E", + "online": "#22C55E", + "new": "#F59E0B", + "off": "#94A3B8", + "archive": "#94A3B8", + "errored": "#EF4444", + "error": "#EF4444" + } + } + }, + { + "field": "region", + "title": "Region", + "renderer": { + "type": "text" + } + }, + { + "field": "version", + "title": "Version", + "renderer": { + "type": "text" + } + }, + { + "field": "nodePools", + "title": "Node Pools", + "renderer": { + "type": "number" + } + }, + { + "field": "nodes", + "title": "Nodes", + "renderer": { + "type": "number" + } + }, + { + "field": "ha", + "title": "High Availability", + "renderer": { + "type": "boolean" + } + }, + { + "field": "autoUpgrade", + "title": "Auto Upgrade", + "renderer": { + "type": "boolean" + } + }, + { + "field": "tagList", + "title": "Tags", + "renderer": { + "type": "tag-list", + "color": "#334155" + } + }, + { + "field": "createdAt", + "title": "Created", + "renderer": { + "type": "date", + "relative": true + } + } + ] + }, + "style": { + "richTableTranspose": true, + "richTableCellPadding": 4, + "richTableFontSize": 13 + } + } + } + } + }, + { + "i": "e45c4c14-1675-4e72-a62e-77a2d68e2cbd", + "x": 1, + "y": 0, + "w": 1, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Node Count", + "description": "Number of worker nodes in this cluster", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[kubernetesNodes]}}", + "name": "kubernetesNodes", + "pluginConfigId": "{{configId}}", + "group": { + "by": [], + "aggregate": [ + { + "type": "count" + } + ] + } + }, + "timeframe": "none", + "scope": { + "scope": "{{scopes.[Kubernetes Clusters]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Kubernetes Cluster]}}" + }, + "variables": [ + "{{variables.[Kubernetes Cluster]}}" + ], + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "count", + "comparisonColumn": "none" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "count", + "type": "quantitative", + "title": "Nodes" + } + ] + }, + "style": { + "scalarLabelPosition": "none", + "scalarValueColor": "#06B6D4" + } + } + } + } + }, + { + "i": "6e7640a0-ce83-4793-90cb-9a7d2b2bdcce", + "x": 2, + "y": 0, + "w": 1, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Node Pools", + "description": "Number of node pools in this cluster", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "datastream-properties", + "name": "properties" + }, + "timeframe": "none", + "scope": { + "scope": "{{scopes.[Kubernetes Clusters]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Kubernetes Cluster]}}" + }, + "variables": [ + "{{variables.[Kubernetes Cluster]}}" + ], + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "nodePools", + "comparisonColumn": "none" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "nodePools", + "type": "quantitative", + "title": "Node Pools" + } + ] + }, + "style": { + "scalarLabelPosition": "none", + "scalarValueColor": "#8B5CF6" + } + } + } + } + }, + { + "i": "cb53fad9-3182-4045-9f94-27a7dd08a200", + "x": 3, + "y": 0, + "w": 1, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Kubernetes Version", + "description": "DOKS version this cluster runs", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "datastream-properties", + "name": "properties" + }, + "timeframe": "none", + "scope": { + "scope": "{{scopes.[Kubernetes Clusters]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Kubernetes Cluster]}}" + }, + "variables": [ + "{{variables.[Kubernetes Cluster]}}" + ], + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "version", + "comparisonColumn": "none" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "version", + "type": "nominal", + "title": "Version" + } + ] + }, + "style": { + "scalarLabelPosition": "none", + "scalarValueColor": "#0069FF" + } + } + } + } + }, + { + "i": "d40ac1f9-bdee-4e2d-9d42-dd532288447b", + "x": 1, + "y": 2, + "w": 3, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Node Health", + "description": "Health of each worker node", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[kubernetesNodes]}}", + "name": "kubernetesNodes", + "pluginConfigId": "{{configId}}" + }, + "timeframe": "none", + "scope": { + "scope": "{{scopes.[Kubernetes Clusters]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Kubernetes Cluster]}}" + }, + "variables": [ + "{{variables.[Kubernetes Cluster]}}" + ], + "visualisation": { + "type": "data-stream-blocks", + "config": { + "data-stream-blocks": { + "labelColumn": "name", + "stateColumn": "health", + "linkColumn": "name", + "columns": 3, + "sublabel": "poolName" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "statusGrid", + "encoding": { + "label": { + "field": "name", + "type": "nominal" + }, + "status": { + "field": "health", + "type": "nominal" + }, + "group": { + "field": "poolName", + "type": "nominal" + } + }, + "style": { + "statusGridColumnsPerRow": 4, + "statusGridMaxBlockHeight": 110, + "statusGridLabelWrap": true, + "statusGridOrderByField": "name", + "statusGridOrderDirection": "asc" + } + } + } + } + }, + { + "i": "cd9b0b88-3162-4ba9-ae05-012fcabbfdd4", + "x": 0, + "y": 5, + "w": 4, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Nodes", + "description": "Worker nodes with their node pool, size and autoscaling limits", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[kubernetesNodes]}}", + "name": "kubernetesNodes", + "pluginConfigId": "{{configId}}", + "sort": { + "by": [ + [ + "poolName", + "asc" + ], + [ + "name", + "asc" + ] + ] + } + }, + "timeframe": "none", + "scope": { + "scope": "{{scopes.[Kubernetes Clusters]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Kubernetes Cluster]}}" + }, + "variables": [ + "{{variables.[Kubernetes Cluster]}}" + ], + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": false, + "columnOrder": [ + "name", + "health", + "status", + "poolName", + "poolSize", + "autoScale", + "poolCount", + "minNodes", + "maxNodes", + "createdAt", + "updatedAt" + ], + "hiddenColumns": [ + "id", + "dropletId" + ], + "rowLinkColumnName": { + "value": "name", + "label": "Name" + } + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "richTable", + "encoding": { + "columns": [ + { + "field": "name", + "title": "Node", + "renderer": { + "type": "text" + } + }, + { + "field": "status", + "title": "State", + "renderer": { + "type": "badge", + "colors": { + "running": "#22C55E", + "provisioning": "#F59E0B", + "draining": "#F59E0B", + "deleting": "#94A3B8" + }, + "defaultColor": "#94A3B8" + } + }, + { + "field": "poolName", + "title": "Pool", + "renderer": { + "type": "badge", + "defaultColor": "#1E3A8A" + } + }, + { + "field": "poolSize", + "title": "Size", + "renderer": { + "type": "text" + } + }, + { + "field": "autoScale", + "title": "Autoscale", + "renderer": { + "type": "boolean" + }, + "align": "center" + }, + { + "field": "poolCount", + "title": "Pool Nodes", + "renderer": { + "type": "number" + }, + "align": "right" + }, + { + "field": "minNodes", + "title": "Min", + "renderer": { + "type": "number" + }, + "align": "right", + "width": 60 + }, + { + "field": "maxNodes", + "title": "Max", + "renderer": { + "type": "number" + }, + "align": "right", + "width": 60 + }, + { + "field": "createdAt", + "title": "Created", + "renderer": { + "type": "date", + "relative": true + } + }, + { + "field": "updatedAt", + "title": "Updated", + "renderer": { + "type": "date", + "relative": true + } + } + ] + }, + "style": { + "richTableCellPadding": 6 + } + } + } + } + } + ] + } +} diff --git a/plugins/DigitalOcean/v1/defaultContent/Core Cloud/loadBalancer.dash.json b/plugins/DigitalOcean/v1/defaultContent/Core Cloud/loadBalancer.dash.json new file mode 100644 index 00000000..2ad75e48 --- /dev/null +++ b/plugins/DigitalOcean/v1/defaultContent/Core Cloud/loadBalancer.dash.json @@ -0,0 +1,683 @@ +{ + "name": "Load Balancer", + "schemaVersion": "1.5", + "timeframe": "last24hours", + "variables": [ + "{{variables.[Load Balancer]}}" + ], + "dashboard": { + "_type": "layout/grid", + "columns": 4, + "version": 1, + "contents": [ + { + "i": "2331b976-9f9d-4030-9d81-191c1a338805", + "x": 0, + "y": 0, + "w": 1, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Properties", + "description": "Imported properties of this load balancer", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "datastream-properties", + "name": "properties" + }, + "timeframe": "none", + "scope": { + "scope": "{{scopes.[Load Balancers]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Load Balancer]}}" + }, + "variables": [ + "{{variables.[Load Balancer]}}" + ], + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": true + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "richTable", + "encoding": { + "columns": [ + { + "field": "name", + "title": "Name", + "renderer": { + "type": "text" + } + }, + { + "field": "status", + "title": "Status", + "renderer": { + "type": "badge", + "colors": { + "active": "#22C55E", + "running": "#22C55E", + "online": "#22C55E", + "new": "#F59E0B", + "off": "#94A3B8", + "archive": "#94A3B8", + "errored": "#EF4444", + "error": "#EF4444" + } + } + }, + { + "field": "ip", + "title": "IP", + "renderer": { + "type": "text" + } + }, + { + "field": "region", + "title": "Region", + "renderer": { + "type": "text" + } + }, + { + "field": "type", + "title": "Type", + "renderer": { + "type": "text" + } + }, + { + "field": "network", + "title": "Network", + "renderer": { + "type": "text" + } + }, + { + "field": "size", + "title": "Size", + "renderer": { + "type": "text" + } + }, + { + "field": "backendDroplets", + "title": "Backend Droplets", + "renderer": { + "type": "number" + } + }, + { + "field": "createdAt", + "title": "Created", + "renderer": { + "type": "date", + "relative": true + } + } + ] + }, + "style": { + "richTableTranspose": true, + "richTableCellPadding": 4, + "richTableFontSize": 13 + } + } + } + } + }, + { + "i": "4f530f9b-448f-44c2-8551-6670ee59b15e", + "x": 1, + "y": 0, + "w": 1, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Health Checks", + "description": "Average Droplet health check status across the timeframe; 100 means every check passed", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[loadBalancerMetrics]}}", + "name": "loadBalancerMetrics", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "metric": "droplets_health_checks" + } + }, + "scope": { + "scope": "{{scopes.[Load Balancers]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Load Balancer]}}" + }, + "variables": [ + "{{variables.[Load Balancer]}}" + ], + "visualisation": { + "type": "data-stream-gauge", + "config": { + "data-stream-gauge": { + "value": { + "type": "mean", + "columns": [ + "value" + ] + }, + "label": "Health Checks", + "minimum": 0, + "maximum": 100 + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "gauge", + "encoding": { + "value": { + "field": "value", + "type": "quantitative", + "aggregate": "avg", + "title": "Health Checks" + } + }, + "style": { + "gaugeMin": 0, + "gaugeMax": 100, + "gaugeLabelText": "Health Checks", + "labelFontSize": 28, + "gaugeBands": [ + { + "to": 0.9, + "color": "#EF4444" + }, + { + "to": 0.99, + "color": "#F59E0B" + }, + { + "to": 1, + "color": "#22C55E" + } + ] + } + } + } + } + }, + { + "i": "d8595e31-904e-41a7-b6fb-9cfc02244988", + "x": 2, + "y": 0, + "w": 2, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "HTTP Requests per Second", + "description": "Rate of HTTP requests received by the load balancer", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[loadBalancerMetrics]}}", + "name": "loadBalancerMetrics", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "metric": "frontend_http_requests_per_second" + }, + "sort": { + "by": [ + [ + "timestamp", + "asc" + ] + ] + } + }, + "scope": { + "scope": "{{scopes.[Load Balancers]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Load Balancer]}}" + }, + "variables": [ + "{{variables.[Load Balancer]}}" + ], + "visualisation": { + "type": "data-stream-line-graph", + "config": { + "data-stream-line-graph": { + "xAxisColumn": "timestamp", + "yAxisColumn": [ + "value" + ], + "seriesColumn": "series", + "showLegend": false, + "legendPosition": "bottom", + "yAxisLabel": "Requests/s", + "showYAxisLabel": true, + "showTrendLine": false + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "line", + "encoding": { + "x": { + "field": "timestamp", + "type": "temporal", + "title": "Time" + }, + "y": { + "field": "value", + "type": "quantitative", + "title": "Requests/s" + } + }, + "style": { + "cartesianAreaGradient": true, + "cartesianSmooth": true, + "cartesianSymbol": "none", + "cartesianLineWidth": 2, + "colors": [ + "#0069FF" + ], + "cartesianShowVerticalGridLines": false + } + } + } + } + }, + { + "i": "42b53679-8096-4eb9-ae57-8a7a79e626c6", + "x": 0, + "y": 3, + "w": 2, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "HTTP Responses", + "description": "Rate of HTTP responses by status class", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[loadBalancerMetrics]}}", + "name": "loadBalancerMetrics", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "metric": "frontend_http_responses" + }, + "sort": { + "by": [ + [ + "timestamp", + "asc" + ] + ] + } + }, + "scope": { + "scope": "{{scopes.[Load Balancers]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Load Balancer]}}" + }, + "variables": [ + "{{variables.[Load Balancer]}}" + ], + "visualisation": { + "type": "data-stream-line-graph", + "config": { + "data-stream-line-graph": { + "xAxisColumn": "timestamp", + "yAxisColumn": [ + "value" + ], + "seriesColumn": "series", + "showLegend": true, + "legendPosition": "bottom", + "yAxisLabel": "Responses/s", + "showYAxisLabel": true, + "showTrendLine": false + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "line", + "encoding": { + "x": { + "field": "timestamp", + "type": "temporal", + "title": "Time" + }, + "y": { + "field": "value", + "type": "quantitative", + "title": "Responses/s" + }, + "series": { + "field": "series", + "type": "nominal" + } + }, + "style": { + "cartesianAreaGradient": true, + "cartesianSmooth": true, + "cartesianSymbol": "none", + "cartesianLineWidth": 2, + "cartesianStack": "on", + "mappedColors": { + "1xx": "#94A3B8", + "2xx": "#22C55E", + "3xx": "#3B82F6", + "4xx": "#F59E0B", + "5xx": "#EF4444" + }, + "legendPosition": "bottom", + "cartesianShowVerticalGridLines": false + } + } + } + } + }, + { + "i": "46747fa6-8c0e-42a8-981e-d25259f97f80", + "x": 2, + "y": 3, + "w": 2, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Current Connections", + "description": "Open connections to the load balancer", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[loadBalancerMetrics]}}", + "name": "loadBalancerMetrics", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "metric": "frontend_connections_current" + }, + "sort": { + "by": [ + [ + "timestamp", + "asc" + ] + ] + } + }, + "scope": { + "scope": "{{scopes.[Load Balancers]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Load Balancer]}}" + }, + "variables": [ + "{{variables.[Load Balancer]}}" + ], + "visualisation": { + "type": "data-stream-line-graph", + "config": { + "data-stream-line-graph": { + "xAxisColumn": "timestamp", + "yAxisColumn": [ + "value" + ], + "seriesColumn": "series", + "showLegend": false, + "legendPosition": "bottom", + "yAxisLabel": "Connections", + "showYAxisLabel": true, + "showTrendLine": false + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "line", + "encoding": { + "x": { + "field": "timestamp", + "type": "temporal", + "title": "Time" + }, + "y": { + "field": "value", + "type": "quantitative", + "title": "Connections" + } + }, + "style": { + "cartesianSmooth": true, + "cartesianSymbol": "none", + "cartesianLineWidth": 2, + "colors": [ + "#8B5CF6" + ], + "cartesianShowVerticalGridLines": false + } + } + } + } + }, + { + "i": "27f0c1e6-17e0-475e-93ee-9532f9e6f804", + "x": 0, + "y": 5, + "w": 2, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Response Time (Average)", + "description": "Average HTTP response time of the backend Droplets", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[loadBalancerMetrics]}}", + "name": "loadBalancerMetrics", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "metric": "droplets_http_response_time_avg" + }, + "sort": { + "by": [ + [ + "timestamp", + "asc" + ] + ] + } + }, + "scope": { + "scope": "{{scopes.[Load Balancers]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Load Balancer]}}" + }, + "variables": [ + "{{variables.[Load Balancer]}}" + ], + "visualisation": { + "type": "data-stream-line-graph", + "config": { + "data-stream-line-graph": { + "xAxisColumn": "timestamp", + "yAxisColumn": [ + "value" + ], + "seriesColumn": "series", + "showLegend": true, + "legendPosition": "bottom", + "yAxisLabel": "Seconds", + "showYAxisLabel": true, + "showTrendLine": false + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "line", + "encoding": { + "x": { + "field": "timestamp", + "type": "temporal", + "title": "Time" + }, + "y": { + "field": "value", + "type": "quantitative", + "title": "Seconds" + } + }, + "markLines": [ + { + "type": "average", + "label": "Average", + "color": "#94A3B8" + } + ], + "style": { + "cartesianSmooth": true, + "cartesianSymbol": "none", + "cartesianLineWidth": 2, + "colors": [ + "#06B6D4" + ], + "cartesianShowVerticalGridLines": false + } + } + } + } + }, + { + "i": "f5917a1e-9f46-4485-86ee-c412a054e903", + "x": 2, + "y": 5, + "w": 2, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Response Time (95th Percentile)", + "description": "95th percentile HTTP response time of the backend Droplets", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[loadBalancerMetrics]}}", + "name": "loadBalancerMetrics", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "metric": "droplets_http_response_time_95p" + }, + "sort": { + "by": [ + [ + "timestamp", + "asc" + ] + ] + } + }, + "scope": { + "scope": "{{scopes.[Load Balancers]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Load Balancer]}}" + }, + "variables": [ + "{{variables.[Load Balancer]}}" + ], + "visualisation": { + "type": "data-stream-line-graph", + "config": { + "data-stream-line-graph": { + "xAxisColumn": "timestamp", + "yAxisColumn": [ + "value" + ], + "seriesColumn": "series", + "showLegend": true, + "legendPosition": "bottom", + "yAxisLabel": "Seconds", + "showYAxisLabel": true, + "showTrendLine": false + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "line", + "encoding": { + "x": { + "field": "timestamp", + "type": "temporal", + "title": "Time" + }, + "y": { + "field": "value", + "type": "quantitative", + "title": "Seconds" + } + }, + "markLines": [ + { + "type": "max", + "label": "Peak", + "color": "#EF4444" + } + ], + "style": { + "cartesianSmooth": true, + "cartesianSymbol": "none", + "cartesianLineWidth": 2, + "colors": [ + "#EC4899" + ], + "cartesianShowVerticalGridLines": false + } + } + } + } + } + ] + } +} diff --git a/plugins/DigitalOcean/v1/defaultContent/Core Cloud/manifest.json b/plugins/DigitalOcean/v1/defaultContent/Core Cloud/manifest.json new file mode 100644 index 00000000..dea43f2c --- /dev/null +++ b/plugins/DigitalOcean/v1/defaultContent/Core Cloud/manifest.json @@ -0,0 +1,24 @@ +{ + "items": [ + { + "name": "droplet", + "type": "dashboard" + }, + { + "name": "app", + "type": "dashboard" + }, + { + "name": "kubernetesCluster", + "type": "dashboard" + }, + { + "name": "loadBalancer", + "type": "dashboard" + }, + { + "name": "vpc", + "type": "dashboard" + } + ] +} diff --git a/plugins/DigitalOcean/v1/defaultContent/Core Cloud/vpc.dash.json b/plugins/DigitalOcean/v1/defaultContent/Core Cloud/vpc.dash.json new file mode 100644 index 00000000..edefcc86 --- /dev/null +++ b/plugins/DigitalOcean/v1/defaultContent/Core Cloud/vpc.dash.json @@ -0,0 +1,670 @@ +{ + "name": "VPC", + "schemaVersion": "1.5", + "timeframe": "last24hours", + "variables": [ + "{{variables.[VPC]}}" + ], + "dashboard": { + "_type": "layout/grid", + "columns": 4, + "version": 1, + "contents": [ + { + "i": "10a180b3-06e1-4966-aaf6-0c499c06128d", + "x": 0, + "y": 0, + "w": 1, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Droplets", + "description": "Droplets in this VPC", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[droplets]}}", + "name": "droplets", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "vpc": { + "scope": "{{scopes.[VPCs]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[VPC]}}" + } + }, + "group": { + "by": [], + "aggregate": [ + { + "type": "count" + } + ] + } + }, + "timeframe": "none", + "variables": [ + "{{variables.[VPC]}}" + ], + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "count", + "comparisonColumn": "none" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "count", + "type": "quantitative", + "title": "Droplets" + } + ] + }, + "style": { + "scalarLabelPosition": "none", + "scalarValueColor": "#0069FF" + } + } + } + } + }, + { + "i": "db9fa204-e5c8-4c00-8b67-9912bacb19bd", + "x": 1, + "y": 0, + "w": 1, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Kubernetes Clusters", + "description": "Kubernetes clusters in this VPC", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[kubernetesClusters]}}", + "name": "kubernetesClusters", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "vpc": { + "scope": "{{scopes.[VPCs]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[VPC]}}" + } + }, + "group": { + "by": [], + "aggregate": [ + { + "type": "count" + } + ] + } + }, + "timeframe": "none", + "variables": [ + "{{variables.[VPC]}}" + ], + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "count", + "comparisonColumn": "none" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "count", + "type": "quantitative", + "title": "Kubernetes Clusters" + } + ] + }, + "style": { + "scalarLabelPosition": "none", + "scalarValueColor": "#06B6D4" + } + } + } + } + }, + { + "i": "42c343a2-b1dc-4de0-8d67-34e9b465b062", + "x": 2, + "y": 0, + "w": 1, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Load Balancers", + "description": "Load balancers in this VPC", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[loadBalancers]}}", + "name": "loadBalancers", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "vpc": { + "scope": "{{scopes.[VPCs]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[VPC]}}" + } + }, + "group": { + "by": [], + "aggregate": [ + { + "type": "count" + } + ] + } + }, + "timeframe": "none", + "variables": [ + "{{variables.[VPC]}}" + ], + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "count", + "comparisonColumn": "none" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "count", + "type": "quantitative", + "title": "Load Balancers" + } + ] + }, + "style": { + "scalarLabelPosition": "none", + "scalarValueColor": "#EC4899" + } + } + } + } + }, + { + "i": "4e968ff8-1f9c-47ec-acfb-da598461669c", + "x": 3, + "y": 0, + "w": 1, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Databases", + "description": "Managed database clusters in this VPC", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[databases]}}", + "name": "databases", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "vpc": { + "scope": "{{scopes.[VPCs]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[VPC]}}" + } + }, + "group": { + "by": [], + "aggregate": [ + { + "type": "count" + } + ] + } + }, + "timeframe": "none", + "variables": [ + "{{variables.[VPC]}}" + ], + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "count", + "comparisonColumn": "none" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "count", + "type": "quantitative", + "title": "Databases" + } + ] + }, + "style": { + "scalarLabelPosition": "none", + "scalarValueColor": "#F59E0B" + } + } + } + } + }, + { + "i": "420e0d5e-9cc8-43fa-83e4-fd26ecb074bd", + "x": 0, + "y": 2, + "w": 1, + "h": 6, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Properties", + "description": "Imported properties of this VPC", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "datastream-properties", + "name": "properties" + }, + "timeframe": "none", + "scope": { + "scope": "{{scopes.[VPCs]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[VPC]}}" + }, + "variables": [ + "{{variables.[VPC]}}" + ], + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": true + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "richTable", + "encoding": { + "columns": [ + { + "field": "name", + "title": "Name", + "renderer": { + "type": "text" + } + }, + { + "field": "region", + "title": "Region", + "renderer": { + "type": "text" + } + }, + { + "field": "ipRange", + "title": "IP Range", + "renderer": { + "type": "text" + } + }, + { + "field": "isDefault", + "title": "Default", + "renderer": { + "type": "boolean", + "trueLabel": "Yes", + "falseLabel": "No" + } + }, + { + "field": "description", + "title": "Description", + "renderer": { + "type": "text" + } + }, + { + "field": "createdAt", + "title": "Created", + "renderer": { + "type": "date", + "relative": true + } + } + ] + }, + "style": { + "richTableTranspose": true, + "richTableCellPadding": 4, + "richTableFontSize": 13 + } + } + } + } + }, + { + "i": "f382bc86-7e37-4dfa-924c-15d68e3e370e", + "x": 1, + "y": 2, + "w": 3, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Droplet Health", + "description": "Health of the Droplets in this VPC", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[droplets]}}", + "name": "droplets", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "vpc": { + "scope": "{{scopes.[VPCs]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[VPC]}}" + } + } + }, + "timeframe": "none", + "variables": [ + "{{variables.[VPC]}}" + ], + "visualisation": { + "type": "data-stream-blocks", + "config": { + "data-stream-blocks": { + "labelColumn": "name", + "stateColumn": "health", + "linkColumn": "name", + "columns": 3, + "sublabel": "status" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "statusGrid", + "encoding": { + "label": { + "field": "name", + "type": "nominal" + }, + "status": { + "field": "health", + "type": "nominal" + } + }, + "style": { + "statusGridColumnsPerRow": 3, + "statusGridOrderByField": "name", + "statusGridOrderDirection": "asc", + "statusGridMaxBlockHeight": 110, + "statusGridLabelWrap": true + } + } + } + } + }, + { + "i": "eb1fc05a-dd9b-4f8a-b04f-8e4c41c84da9", + "x": 1, + "y": 5, + "w": 1, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Cluster Health", + "description": "Health of the Kubernetes clusters in this VPC", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[kubernetesClusters]}}", + "name": "kubernetesClusters", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "vpc": { + "scope": "{{scopes.[VPCs]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[VPC]}}" + } + } + }, + "timeframe": "none", + "variables": [ + "{{variables.[VPC]}}" + ], + "visualisation": { + "type": "data-stream-blocks", + "config": { + "data-stream-blocks": { + "labelColumn": "name", + "stateColumn": "health", + "linkColumn": "name", + "columns": 1, + "sublabel": "status" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "statusGrid", + "encoding": { + "label": { + "field": "name", + "type": "nominal" + }, + "status": { + "field": "health", + "type": "nominal" + } + }, + "style": { + "statusGridColumnsPerRow": 1, + "statusGridOrderByField": "name", + "statusGridOrderDirection": "asc", + "statusGridMaxBlockHeight": 110, + "statusGridLabelWrap": true + } + } + } + } + }, + { + "i": "7b5e1b3d-0a34-46e7-a937-b4d09ec10132", + "x": 2, + "y": 5, + "w": 1, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Load Balancer Health", + "description": "Health of the load balancers in this VPC", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[loadBalancers]}}", + "name": "loadBalancers", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "vpc": { + "scope": "{{scopes.[VPCs]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[VPC]}}" + } + } + }, + "timeframe": "none", + "variables": [ + "{{variables.[VPC]}}" + ], + "visualisation": { + "type": "data-stream-blocks", + "config": { + "data-stream-blocks": { + "labelColumn": "name", + "stateColumn": "health", + "linkColumn": "name", + "columns": 1, + "sublabel": "status" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "statusGrid", + "encoding": { + "label": { + "field": "name", + "type": "nominal" + }, + "status": { + "field": "health", + "type": "nominal" + } + }, + "style": { + "statusGridColumnsPerRow": 1, + "statusGridOrderByField": "name", + "statusGridOrderDirection": "asc", + "statusGridMaxBlockHeight": 110, + "statusGridLabelWrap": true + } + } + } + } + }, + { + "i": "f264bf8a-7475-44bc-a1d5-1b33fa6f3daa", + "x": 3, + "y": 5, + "w": 1, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Database Health", + "description": "Health of the managed database clusters in this VPC", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[databases]}}", + "name": "databases", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "vpc": { + "scope": "{{scopes.[VPCs]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[VPC]}}" + } + } + }, + "timeframe": "none", + "variables": [ + "{{variables.[VPC]}}" + ], + "visualisation": { + "type": "data-stream-blocks", + "config": { + "data-stream-blocks": { + "labelColumn": "name", + "stateColumn": "health", + "linkColumn": "name", + "columns": 1, + "sublabel": "engine" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "statusGrid", + "encoding": { + "label": { + "field": "name", + "type": "nominal" + }, + "status": { + "field": "health", + "type": "nominal" + } + }, + "style": { + "statusGridColumnsPerRow": 1, + "statusGridOrderByField": "name", + "statusGridOrderDirection": "asc", + "statusGridMaxBlockHeight": 110, + "statusGridLabelWrap": true + } + } + } + } + } + ] + } +} diff --git a/plugins/DigitalOcean/v1/defaultContent/Data & Learning/database.dash.json b/plugins/DigitalOcean/v1/defaultContent/Data & Learning/database.dash.json new file mode 100644 index 00000000..72c6b510 --- /dev/null +++ b/plugins/DigitalOcean/v1/defaultContent/Data & Learning/database.dash.json @@ -0,0 +1,517 @@ +{ + "name": "Database", + "schemaVersion": "1.5", + "timeframe": "last24hours", + "variables": [ + "{{variables.[Database]}}" + ], + "dashboard": { + "_type": "layout/grid", + "columns": 4, + "version": 1, + "contents": [ + { + "i": "501e43ab-f2fe-49d6-a444-c048cc34fc1c", + "x": 0, + "y": 0, + "w": 1, + "h": 4, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Properties", + "description": "Imported properties of this database cluster", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "datastream-properties", + "name": "properties" + }, + "timeframe": "none", + "scope": { + "scope": "{{scopes.[Databases]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Database]}}" + }, + "variables": [ + "{{variables.[Database]}}" + ], + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": true + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "richTable", + "encoding": { + "columns": [ + { + "field": "name", + "title": "Name", + "renderer": { + "type": "text" + } + }, + { + "field": "status", + "title": "Status", + "renderer": { + "type": "badge", + "colors": { + "online": "#22C55E", + "creating": "#F59E0B", + "resizing": "#F59E0B", + "migrating": "#F59E0B", + "forking": "#F59E0B" + }, + "defaultColor": "#94A3B8" + } + }, + { + "field": "engine", + "title": "Engine", + "renderer": { + "type": "badge", + "colors": { + "pg": "#336791", + "mysql": "#00758F", + "redis": "#DC382D", + "valkey": "#6E2DD4", + "mongodb": "#47A248", + "kafka": "#231F20", + "opensearch": "#005EB8" + }, + "defaultColor": "#475569" + } + }, + { + "field": "version", + "title": "Version", + "renderer": { + "type": "text" + } + }, + { + "field": "region", + "title": "Region", + "renderer": { + "type": "text" + } + }, + { + "field": "size", + "title": "Size", + "renderer": { + "type": "text" + } + }, + { + "field": "numNodes", + "title": "Nodes", + "renderer": { + "type": "number" + } + }, + { + "field": "tagList", + "title": "Tags", + "renderer": { + "type": "tag-list", + "color": "#334155" + } + }, + { + "field": "createdAt", + "title": "Created", + "renderer": { + "type": "date", + "relative": true + } + } + ] + }, + "style": { + "richTableTranspose": true, + "richTableCellPadding": 4, + "richTableFontSize": 13 + } + } + } + } + }, + { + "i": "94aa487f-877e-4f72-88e3-0ebf79a80aaf", + "x": 1, + "y": 0, + "w": 1, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Status", + "description": "Current status of this database cluster", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "datastream-properties", + "name": "properties" + }, + "timeframe": "none", + "scope": { + "scope": "{{scopes.[Databases]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Database]}}" + }, + "variables": [ + "{{variables.[Database]}}" + ], + "visualisation": { + "type": "data-stream-blocks", + "config": { + "data-stream-blocks": { + "labelColumn": "name", + "stateColumn": "none", + "linkColumn": "none", + "columns": 1, + "sublabel": "status" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "statusGrid", + "encoding": { + "label": { + "field": "name", + "type": "nominal" + }, + "status": { + "field": "status", + "type": "nominal" + } + }, + "style": { + "statusGridColumnsPerRow": 1, + "statusGridLabelWrap": true, + "mappedColors": { + "online": "#22C55E", + "creating": "#F59E0B", + "resizing": "#F59E0B", + "migrating": "#F59E0B", + "forking": "#F59E0B" + } + } + } + } + } + }, + { + "i": "1a55cb51-a284-498d-93ab-4b8542040c6a", + "x": 2, + "y": 0, + "w": 1, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Engine", + "description": "Database engine of this cluster", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "datastream-properties", + "name": "properties" + }, + "timeframe": "none", + "scope": { + "scope": "{{scopes.[Databases]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Database]}}" + }, + "variables": [ + "{{variables.[Database]}}" + ], + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "engine", + "comparisonColumn": "none" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "engine", + "type": "nominal", + "title": "Engine" + } + ] + }, + "style": { + "scalarLabelPosition": "none", + "scalarValueColor": "#F59E0B" + } + } + } + } + }, + { + "i": "e541cbbd-e263-4d03-b55b-bb37f83c0e97", + "x": 3, + "y": 0, + "w": 1, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Version", + "description": "Engine version this cluster runs", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "datastream-properties", + "name": "properties" + }, + "timeframe": "none", + "scope": { + "scope": "{{scopes.[Databases]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Database]}}" + }, + "variables": [ + "{{variables.[Database]}}" + ], + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "version", + "comparisonColumn": "none" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "version", + "type": "nominal", + "title": "Version" + } + ] + }, + "style": { + "scalarLabelPosition": "none", + "scalarValueColor": "#0069FF" + } + } + } + } + }, + { + "i": "7a486338-85c6-4df6-a0de-4c10cb2b7e5d", + "x": 1, + "y": 2, + "w": 1, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Nodes", + "description": "Number of nodes in this cluster", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "datastream-properties", + "name": "properties" + }, + "timeframe": "none", + "scope": { + "scope": "{{scopes.[Databases]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Database]}}" + }, + "variables": [ + "{{variables.[Database]}}" + ], + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "numNodes", + "comparisonColumn": "none" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "numNodes", + "type": "quantitative", + "title": "Nodes" + } + ] + }, + "style": { + "scalarLabelPosition": "none", + "scalarValueColor": "#06B6D4" + } + } + } + } + }, + { + "i": "a47ed9fa-e746-4820-9bff-a4dbd50a785a", + "x": 2, + "y": 2, + "w": 1, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Size", + "description": "Node size slug of this cluster", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "datastream-properties", + "name": "properties" + }, + "timeframe": "none", + "scope": { + "scope": "{{scopes.[Databases]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Database]}}" + }, + "variables": [ + "{{variables.[Database]}}" + ], + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "size", + "comparisonColumn": "none" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "size", + "type": "nominal", + "title": "Size" + } + ] + }, + "style": { + "scalarLabelPosition": "none", + "scalarValueColor": "#8B5CF6" + } + } + } + } + }, + { + "i": "d0825d45-913e-4e4a-98e9-17797766744b", + "x": 3, + "y": 2, + "w": 1, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Region", + "description": "Region this cluster runs in", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "datastream-properties", + "name": "properties" + }, + "timeframe": "none", + "scope": { + "scope": "{{scopes.[Databases]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Database]}}" + }, + "variables": [ + "{{variables.[Database]}}" + ], + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "region", + "comparisonColumn": "none" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "region", + "type": "nominal", + "title": "Region" + } + ] + }, + "style": { + "scalarLabelPosition": "none", + "scalarValueColor": "#14B8A6" + } + } + } + } + } + ] + } +} diff --git a/plugins/DigitalOcean/v1/defaultContent/Data & Learning/manifest.json b/plugins/DigitalOcean/v1/defaultContent/Data & Learning/manifest.json new file mode 100644 index 00000000..d37d5e7d --- /dev/null +++ b/plugins/DigitalOcean/v1/defaultContent/Data & Learning/manifest.json @@ -0,0 +1,8 @@ +{ + "items": [ + { + "name": "database", + "type": "dashboard" + } + ] +} diff --git a/plugins/DigitalOcean/v1/defaultContent/Managed Agents/agent.dash.json b/plugins/DigitalOcean/v1/defaultContent/Managed Agents/agent.dash.json new file mode 100644 index 00000000..021a7136 --- /dev/null +++ b/plugins/DigitalOcean/v1/defaultContent/Managed Agents/agent.dash.json @@ -0,0 +1,568 @@ +{ + "name": "Agent", + "schemaVersion": "1.5", + "timeframe": "last7days", + "variables": [ + "{{variables.[Agent]}}" + ], + "dashboard": { + "_type": "layout/grid", + "columns": 4, + "version": 1, + "contents": [ + { + "i": "7e3de896-1ed6-4497-8c67-aca622a458e8", + "x": 0, + "y": 0, + "w": 1, + "h": 5, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Properties", + "description": "Imported properties of this agent", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "datastream-properties", + "name": "properties" + }, + "timeframe": "none", + "scope": { + "scope": "{{scopes.[Agents]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Agent]}}" + }, + "variables": [ + "{{variables.[Agent]}}" + ], + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": true + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "richTable", + "encoding": { + "columns": [ + { + "field": "name", + "title": "Name", + "renderer": { + "type": "text" + } + }, + { + "field": "deploymentStatus", + "title": "Deployment", + "renderer": { + "type": "badge", + "colors": { + "STATUS_RUNNING": "#22C55E", + "STATUS_FAILED": "#EF4444", + "STATUS_UNDEPLOYMENT_FAILED": "#EF4444", + "STATUS_UNKNOWN": "#94A3B8", + "STATUS_DELETED": "#94A3B8" + }, + "defaultColor": "#F59E0B" + } + }, + { + "field": "model", + "title": "Model", + "renderer": { + "type": "text" + } + }, + { + "field": "region", + "title": "Region", + "renderer": { + "type": "text" + } + }, + { + "field": "visibility", + "title": "Visibility", + "renderer": { + "type": "text" + } + }, + { + "field": "url", + "title": "URL", + "renderer": { + "type": "link" + } + }, + { + "field": "tagList", + "title": "Tags", + "renderer": { + "type": "tag-list", + "color": "#334155" + } + }, + { + "field": "createdAt", + "title": "Created", + "renderer": { + "type": "date", + "relative": true + } + } + ] + }, + "style": { + "richTableTranspose": true, + "richTableCellPadding": 4, + "richTableFontSize": 13 + } + } + } + } + }, + { + "i": "83d4c034-e8a4-4096-b12b-c61cad0c9adb", + "x": 1, + "y": 0, + "w": 1, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Input Tokens", + "description": "Input tokens used in the timeframe", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[agentUsage]}}", + "name": "agentUsage", + "pluginConfigId": "{{configId}}", + "filter": { + "multiOperation": "and", + "filters": [ + { + "column": "usageType", + "operation": "equals", + "value": "INPUT" + } + ] + }, + "group": { + "by": [], + "aggregate": [ + { + "type": "sum", + "names": [ + "tokens" + ] + } + ] + } + }, + "scope": { + "scope": "{{scopes.[Agents]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Agent]}}" + }, + "variables": [ + "{{variables.[Agent]}}" + ], + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "tokens_sum", + "comparisonColumn": "none" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "tokens_sum", + "type": "quantitative", + "title": "Input Tokens" + } + ] + }, + "style": { + "scalarLabelPosition": "none", + "scalarValueColor": "#0069FF" + } + } + } + } + }, + { + "i": "7eaa3964-1eb7-402d-9582-c4575150bc05", + "x": 2, + "y": 0, + "w": 1, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Output Tokens", + "description": "Output tokens generated in the timeframe", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[agentUsage]}}", + "name": "agentUsage", + "pluginConfigId": "{{configId}}", + "filter": { + "multiOperation": "and", + "filters": [ + { + "column": "usageType", + "operation": "equals", + "value": "OUTPUT" + } + ] + }, + "group": { + "by": [], + "aggregate": [ + { + "type": "sum", + "names": [ + "tokens" + ] + } + ] + } + }, + "scope": { + "scope": "{{scopes.[Agents]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Agent]}}" + }, + "variables": [ + "{{variables.[Agent]}}" + ], + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "tokens_sum", + "comparisonColumn": "none" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "tokens_sum", + "type": "quantitative", + "title": "Output Tokens" + } + ] + }, + "style": { + "scalarLabelPosition": "none", + "scalarValueColor": "#8B5CF6" + } + } + } + } + }, + { + "i": "1ee503e8-2fb3-43d6-9012-09c6263b5e24", + "x": 3, + "y": 0, + "w": 1, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Total Tokens", + "description": "All tokens used in the timeframe", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[agentUsage]}}", + "name": "agentUsage", + "pluginConfigId": "{{configId}}", + "group": { + "by": [], + "aggregate": [ + { + "type": "sum", + "names": [ + "tokens" + ] + } + ] + } + }, + "scope": { + "scope": "{{scopes.[Agents]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Agent]}}" + }, + "variables": [ + "{{variables.[Agent]}}" + ], + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "tokens_sum", + "comparisonColumn": "none" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "tokens_sum", + "type": "quantitative", + "title": "Total Tokens" + } + ] + }, + "style": { + "scalarLabelPosition": "none", + "scalarValueColor": "#14B8A6" + } + } + } + } + }, + { + "i": "2f0970ef-6cfa-4b18-9db5-543ad288f085", + "x": 1, + "y": 2, + "w": 1, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Input vs Output", + "description": "Share of tokens in the timeframe that were input or output", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[agentUsage]}}", + "name": "agentUsage", + "pluginConfigId": "{{configId}}", + "group": { + "by": [ + [ + "usageType", + "uniqueValues" + ] + ], + "aggregate": [ + { + "type": "sum", + "names": [ + "tokens" + ] + } + ] + } + }, + "scope": { + "scope": "{{scopes.[Agents]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Agent]}}" + }, + "variables": [ + "{{variables.[Agent]}}" + ], + "visualisation": { + "type": "data-stream-donut-chart", + "config": { + "data-stream-donut-chart": { + "valueColumn": "tokens_sum", + "labelColumn": "usageType_uniqueValues", + "hideCenterValue": false, + "showValuesAsPercentage": true, + "legendPosition": "auto", + "legendMode": "table" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "pie", + "encoding": { + "label": { + "field": "usageType_uniqueValues", + "type": "nominal", + "title": "Usage Type" + }, + "value": { + "field": "tokens_sum", + "type": "quantitative", + "title": "Tokens" + } + }, + "style": { + "pieInnerRadius": 62, + "pieDonutCenterValue": "total", + "labelFontSize": 16, + "pieLegendStyle": "table", + "pieLabels": "none", + "pieBorderRadius": 6, + "piePadAngle": 2, + "mappedColors": { + "INPUT": "#0069FF", + "OUTPUT": "#8B5CF6" + } + } + } + } + } + }, + { + "i": "60eb8d9d-7735-4e72-8f01-38734bdd430c", + "x": 2, + "y": 2, + "w": 2, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Token Usage", + "description": "Tokens used in the timeframe by usage source, split into input and output", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[agentUsage]}}", + "name": "agentUsage", + "pluginConfigId": "{{configId}}", + "group": { + "by": [ + [ + "source", + "uniqueValues" + ], + [ + "usageType", + "uniqueValues" + ] + ], + "aggregate": [ + { + "type": "sum", + "names": [ + "tokens" + ] + } + ] + } + }, + "scope": { + "scope": "{{scopes.[Agents]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Agent]}}" + }, + "variables": [ + "{{variables.[Agent]}}" + ], + "visualisation": { + "type": "data-stream-bar-chart", + "config": { + "data-stream-bar-chart": { + "xAxisData": "source_uniqueValues", + "yAxisData": [ + "tokens_sum" + ], + "xAxisGroup": "usageType_uniqueValues", + "xAxisLabel": "", + "yAxisLabel": "Tokens", + "showXAxisLabel": false, + "showYAxisLabel": true, + "showLegend": true, + "legendPosition": "bottom", + "showGrid": true, + "horizontalLayout": "vertical", + "displayMode": "actual", + "showTotals": true, + "showValue": false, + "grouping": false, + "range": { + "type": "auto" + } + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "bar", + "encoding": { + "x": { + "field": "source_uniqueValues", + "type": "nominal", + "title": "Usage Source" + }, + "y": { + "field": "tokens_sum", + "type": "quantitative", + "title": "Tokens" + }, + "series": { + "field": "usageType_uniqueValues", + "type": "nominal", + "title": "Usage Type" + } + }, + "style": { + "cartesianStack": "on", + "cartesianShowStackedTotals": true, + "legendPosition": "bottom", + "cartesianBarBorderRadius": 4, + "mappedColors": { + "INPUT": "#0069FF", + "OUTPUT": "#8B5CF6" + }, + "cartesianShowVerticalGridLines": false + } + } + } + } + } + ] + } +} diff --git a/plugins/DigitalOcean/v1/defaultContent/Managed Agents/agentSession.dash.json b/plugins/DigitalOcean/v1/defaultContent/Managed Agents/agentSession.dash.json new file mode 100644 index 00000000..29fa397a --- /dev/null +++ b/plugins/DigitalOcean/v1/defaultContent/Managed Agents/agentSession.dash.json @@ -0,0 +1,970 @@ +{ + "name": "Agent Session", + "schemaVersion": "1.5", + "timeframe": "last7days", + "variables": [ + "{{variables.[Agent Session]}}" + ], + "dashboard": { + "_type": "layout/grid", + "columns": 4, + "version": 1, + "contents": [ + { + "i": "af5645da-ccab-4344-84e1-7316de90910a", + "x": 0, + "y": 0, + "w": 1, + "h": 8, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Properties", + "description": "Imported properties of this session", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "datastream-properties", + "name": "properties" + }, + "timeframe": "none", + "scope": { + "scope": "{{scopes.[Agent Sessions]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Agent Session]}}" + }, + "variables": [ + "{{variables.[Agent Session]}}" + ], + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": true + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "richTable", + "encoding": { + "columns": [ + { + "field": "name", + "title": "Name", + "renderer": { + "type": "text" + } + }, + { + "field": "status", + "title": "Status", + "renderer": { + "type": "badge", + "colors": { + "READY": "#22C55E", + "PROVISIONING": "#F59E0B", + "DESTROYING": "#F59E0B", + "FAILED": "#EF4444", + "LOCKED": "#EF4444", + "PAUSED": "#94A3B8", + "DETACHED": "#94A3B8" + }, + "defaultColor": "#94A3B8" + } + }, + { + "field": "agentKind", + "title": "Agent", + "renderer": { + "type": "text" + } + }, + { + "field": "createdAt", + "title": "Created", + "renderer": { + "type": "date", + "relative": true + } + } + ] + }, + "style": { + "richTableTranspose": true, + "richTableCellPadding": 4, + "richTableFontSize": 13 + } + } + } + } + }, + { + "i": "c7fe331a-3f3f-493e-a3d9-6ffaf742e550", + "x": 1, + "y": 0, + "w": 1, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Turns", + "description": "Turns in this session recorded by Signals", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[sessionDialogues]}}", + "name": "sessionDialogues", + "pluginConfigId": "{{configId}}", + "group": { + "by": [], + "aggregate": [ + { + "type": "count" + } + ] + } + }, + "timeframe": "none", + "scope": { + "scope": "{{scopes.[Agent Sessions]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Agent Session]}}" + }, + "variables": [ + "{{variables.[Agent Session]}}" + ], + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "count", + "comparisonColumn": "none" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "count", + "type": "quantitative", + "title": "Turns" + } + ] + }, + "style": { + "scalarLabelPosition": "none", + "scalarValueColor": "#0069FF" + } + } + } + } + }, + { + "i": "63f27c23-e30d-416a-b9d0-c015ba2001f5", + "x": 2, + "y": 0, + "w": 1, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Tool Failures", + "description": "Tool calls that failed across this session", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[sessionDialogues]}}", + "name": "sessionDialogues", + "pluginConfigId": "{{configId}}", + "group": { + "by": [], + "aggregate": [ + { + "type": "sum", + "names": [ + "toolFailures" + ] + } + ] + } + }, + "timeframe": "none", + "scope": { + "scope": "{{scopes.[Agent Sessions]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Agent Session]}}" + }, + "variables": [ + "{{variables.[Agent Session]}}" + ], + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "toolFailures_sum", + "comparisonColumn": "none" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "toolFailures_sum", + "type": "quantitative", + "title": "Tool Failures" + } + ] + }, + "style": { + "scalarLabelPosition": "none", + "scalarValueColor": "#EF4444" + } + } + } + } + }, + { + "i": "7827c790-b0d7-4051-92c0-fb015d4b1de2", + "x": 3, + "y": 0, + "w": 1, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Signals", + "description": "Behavioral signals Signals detected in this session", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[sessionSignals]}}", + "name": "sessionSignals", + "pluginConfigId": "{{configId}}", + "group": { + "by": [], + "aggregate": [ + { + "type": "count" + } + ] + } + }, + "timeframe": "none", + "scope": { + "scope": "{{scopes.[Agent Sessions]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Agent Session]}}" + }, + "variables": [ + "{{variables.[Agent Session]}}" + ], + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "count", + "comparisonColumn": "none" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "count", + "type": "quantitative", + "title": "Signals" + } + ] + }, + "style": { + "scalarLabelPosition": "none", + "scalarValueColor": "#EC4899" + } + } + } + } + }, + { + "i": "8a0c75f3-93ae-41d2-9856-cd50d33aa723", + "x": 1, + "y": 2, + "w": 3, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Token Usage", + "description": "Input and output tokens used in each turn of this session", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[sessionDialogues]}}", + "name": "sessionDialogues", + "pluginConfigId": "{{configId}}", + "group": { + "by": [ + [ + "sequence", + "uniqueValues" + ] + ], + "aggregate": [ + { + "type": "sum", + "names": [ + "inputTokens" + ] + }, + { + "type": "sum", + "names": [ + "outputTokens" + ] + } + ] + }, + "sort": { + "by": [ + [ + "sequence_uniqueValues", + "asc" + ] + ] + } + }, + "timeframe": "none", + "scope": { + "scope": "{{scopes.[Agent Sessions]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Agent Session]}}" + }, + "variables": [ + "{{variables.[Agent Session]}}" + ], + "visualisation": { + "type": "data-stream-bar-chart", + "config": { + "data-stream-bar-chart": { + "xAxisData": "sequence_uniqueValues", + "yAxisData": [ + "inputTokens_sum", + "outputTokens_sum" + ], + "xAxisGroup": "none", + "xAxisLabel": "Turn", + "yAxisLabel": "", + "showXAxisLabel": false, + "showYAxisLabel": false, + "showLegend": true, + "legendPosition": "bottom", + "showGrid": true, + "horizontalLayout": "vertical", + "displayMode": "actual", + "showTotals": false, + "showValue": false, + "grouping": true, + "range": { + "type": "auto" + } + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "bar", + "encoding": { + "x": { + "field": "sequence_uniqueValues", + "type": "ordinal", + "title": "Turn" + } + }, + "style": { + "cartesianBarBorderRadius": 4, + "legendPosition": "bottom", + "colors": [ + "#0069FF", + "#8B5CF6" + ], + "cartesianShowVerticalGridLines": false + } + } + } + } + }, + { + "i": "06ea9e1f-8108-4f6b-9467-87ada62e5b01", + "x": 1, + "y": 5, + "w": 2, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Tool Calls vs Failures", + "description": "Tool calls made in each turn of this session, and how many failed", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[sessionDialogues]}}", + "name": "sessionDialogues", + "pluginConfigId": "{{configId}}", + "group": { + "by": [ + [ + "sequence", + "uniqueValues" + ] + ], + "aggregate": [ + { + "type": "sum", + "names": [ + "toolCalls" + ] + }, + { + "type": "sum", + "names": [ + "toolFailures" + ] + } + ] + }, + "sort": { + "by": [ + [ + "sequence_uniqueValues", + "asc" + ] + ] + } + }, + "timeframe": "none", + "scope": { + "scope": "{{scopes.[Agent Sessions]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Agent Session]}}" + }, + "variables": [ + "{{variables.[Agent Session]}}" + ], + "visualisation": { + "type": "data-stream-bar-chart", + "config": { + "data-stream-bar-chart": { + "xAxisData": "sequence_uniqueValues", + "yAxisData": [ + "toolCalls_sum", + "toolFailures_sum" + ], + "xAxisGroup": "none", + "xAxisLabel": "Turn", + "yAxisLabel": "", + "showXAxisLabel": false, + "showYAxisLabel": false, + "showLegend": true, + "legendPosition": "bottom", + "showGrid": true, + "horizontalLayout": "vertical", + "displayMode": "actual", + "showTotals": false, + "showValue": false, + "grouping": true, + "range": { + "type": "auto" + } + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "bar", + "encoding": { + "x": { + "field": "sequence_uniqueValues", + "type": "ordinal", + "title": "Turn" + } + }, + "style": { + "cartesianBarBorderRadius": 4, + "legendPosition": "bottom", + "colors": [ + "#14B8A6", + "#EF4444" + ], + "cartesianShowVerticalGridLines": false + } + } + } + } + }, + { + "i": "bbab232e-2fc4-40e8-9698-08bffef1c053", + "x": 3, + "y": 5, + "w": 1, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Signals by Category", + "description": "Signals detected in this session by category", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[sessionSignals]}}", + "name": "sessionSignals", + "pluginConfigId": "{{configId}}", + "group": { + "by": [ + [ + "category", + "uniqueValues" + ] + ], + "aggregate": [ + { + "type": "count" + } + ] + } + }, + "timeframe": "none", + "scope": { + "scope": "{{scopes.[Agent Sessions]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Agent Session]}}" + }, + "variables": [ + "{{variables.[Agent Session]}}" + ], + "visualisation": { + "type": "data-stream-donut-chart", + "config": { + "data-stream-donut-chart": { + "valueColumn": "count", + "labelColumn": "category_uniqueValues", + "hideCenterValue": false, + "showValuesAsPercentage": true, + "legendPosition": "auto", + "legendMode": "table" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "pie", + "encoding": { + "label": { + "field": "category_uniqueValues", + "type": "nominal", + "title": "Category" + }, + "value": { + "field": "count", + "type": "quantitative", + "title": "Signals" + } + }, + "style": { + "pieInnerRadius": 62, + "pieDonutCenterValue": "total", + "labelFontSize": 16, + "pieLegendStyle": "table", + "pieLabels": "none", + "pieBorderRadius": 6, + "piePadAngle": 2, + "mappedColors": { + "failure": "#EF4444", + "loops": "#F59E0B" + }, + "colors": [ + "#8B5CF6", + "#06B6D4", + "#EC4899", + "#14B8A6" + ] + } + } + } + } + }, + { + "i": "32c019c0-4aa6-4dba-9980-c746444e3d95", + "x": 0, + "y": 8, + "w": 4, + "h": 4, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Detected Signals", + "description": "Every signal Signals detected in this session, with its category and confidence", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[sessionSignals]}}", + "name": "sessionSignals", + "pluginConfigId": "{{configId}}", + "sort": { + "by": [ + [ + "createdAt", + "desc" + ] + ] + } + }, + "timeframe": "none", + "scope": { + "scope": "{{scopes.[Agent Sessions]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Agent Session]}}" + }, + "variables": [ + "{{variables.[Agent Session]}}" + ], + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": false, + "columnOrder": [ + "createdAt", + "turn", + "category", + "label", + "layer", + "confidence", + "snippet", + "stepIndex" + ], + "hiddenColumns": [ + "id", + "signalType" + ] + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "richTable", + "encoding": { + "columns": [ + { + "field": "createdAt", + "title": "Time", + "renderer": { + "type": "date", + "relative": true + } + }, + { + "field": "turn", + "title": "Sequence", + "renderer": { + "type": "number", + "decimals": 0 + }, + "align": "right", + "width": 90 + }, + { + "field": "category", + "title": "Category", + "renderer": { + "type": "badge", + "colors": { + "failure": "#EF4444", + "loops": "#F59E0B" + }, + "defaultColor": "#64748B" + } + }, + { + "field": "label", + "title": "Signal", + "renderer": { + "type": "text" + } + }, + { + "field": "layer", + "title": "Layer", + "renderer": { + "type": "badge", + "defaultColor": "#1E3A8A" + } + }, + { + "field": "confidence", + "title": "Confidence", + "renderer": { + "type": "progress", + "max": 1 + }, + "width": 130 + }, + { + "field": "stepIndex", + "title": "Step", + "renderer": { + "type": "number", + "decimals": 0 + }, + "align": "right", + "width": 60 + }, + { + "field": "snippet", + "title": "Detail", + "renderer": { + "type": "text" + } + } + ] + }, + "style": { + "richTableSort": { + "field": "createdAt", + "direction": "desc" + }, + "richTableCellPadding": 6, + "richTableWrapText": true + } + } + } + } + }, + { + "i": "3bf10050-7e83-4920-b4b9-842f2584a975", + "x": 0, + "y": 12, + "w": 4, + "h": 5, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Dialogue", + "description": "Each turn of this session with its run status, tool calls, tokens and detected signals", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[sessionDialogues]}}", + "name": "sessionDialogues", + "pluginConfigId": "{{configId}}", + "sort": { + "by": [ + [ + "createdAt", + "asc" + ] + ] + } + }, + "timeframe": "none", + "scope": { + "scope": "{{scopes.[Agent Sessions]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Agent Session]}}" + }, + "variables": [ + "{{variables.[Agent Session]}}" + ], + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": false, + "columnOrder": [ + "createdAt", + "health", + "toolCalls", + "toolFailures", + "inputTokens", + "outputTokens", + "signalLabels", + "userMessage" + ], + "hiddenColumns": [ + "id", + "sequence", + "runStatus", + "failureCode", + "toolDurationMs", + "cachedInputTokens", + "reasoningTokens", + "modelCalls", + "model", + "signalCount" + ] + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "richTable", + "encoding": { + "columns": [ + { + "field": "createdAt", + "title": "Time", + "renderer": { + "type": "date" + } + }, + { + "field": "runStatus", + "title": "Run Status", + "renderer": { + "type": "badge", + "colors": { + "completed": "#22C55E", + "failed": "#EF4444", + "error": "#EF4444", + "cancelled": "#EF4444", + "running": "#F59E0B", + "pending": "#F59E0B" + }, + "defaultColor": "#94A3B8" + } + }, + { + "field": "toolCalls", + "title": "Tool Calls", + "renderer": { + "type": "number", + "decimals": 0 + }, + "align": "right", + "width": 90 + }, + { + "field": "toolFailures", + "title": "Tool Failures", + "renderer": { + "type": "number", + "decimals": 0, + "thresholds": [ + { + "to": 0, + "color": "#64748B" + }, + { + "to": 1000000, + "color": "#EF4444" + } + ] + }, + "align": "right", + "width": 100 + }, + { + "field": "inputTokens", + "title": "Input Tokens", + "renderer": { + "type": "number", + "compact": true + }, + "align": "right", + "width": 100 + }, + { + "field": "outputTokens", + "title": "Output Tokens", + "renderer": { + "type": "number", + "compact": true + }, + "align": "right", + "width": 100 + }, + { + "field": "signalLabels", + "title": "Signals", + "renderer": { + "type": "tag-list", + "separator": ",", + "color": "#BE185D" + } + }, + { + "field": "userMessage", + "title": "User Message", + "renderer": { + "type": "text" + } + } + ] + }, + "style": { + "richTableSort": { + "field": "createdAt", + "direction": "asc" + }, + "richTableCellPadding": 6, + "richTableWrapText": true, + "richTableRowHighlight": { + "field": "runStatus", + "colors": { + "failed": "rgba(239,68,68,0.15)", + "error": "rgba(239,68,68,0.15)", + "cancelled": "rgba(239,68,68,0.15)" + } + } + } + } + } + } + } + ] + } +} diff --git a/plugins/DigitalOcean/v1/defaultContent/Managed Agents/environment.dash.json b/plugins/DigitalOcean/v1/defaultContent/Managed Agents/environment.dash.json new file mode 100644 index 00000000..a8d63ee0 --- /dev/null +++ b/plugins/DigitalOcean/v1/defaultContent/Managed Agents/environment.dash.json @@ -0,0 +1,840 @@ +{ + "name": "Environment", + "schemaVersion": "1.5", + "timeframe": "last7days", + "variables": [ + "{{variables.[Environment]}}" + ], + "dashboard": { + "_type": "layout/grid", + "columns": 4, + "version": 1, + "contents": [ + { + "i": "1040e37a-d578-4e44-9de6-546d6f3885c6", + "x": 0, + "y": 0, + "w": 1, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Sessions", + "description": "Harness Runtime sessions started from this environment", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[agentSessions]}}", + "name": "agentSessions", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "environment": { + "scope": "{{scopes.[Environments]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Environment]}}" + } + }, + "group": { + "by": [], + "aggregate": [ + { + "type": "count" + } + ] + } + }, + "timeframe": "none", + "variables": [ + "{{variables.[Environment]}}" + ], + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "count", + "comparisonColumn": "none" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "count", + "type": "quantitative", + "title": "Sessions" + } + ] + }, + "style": { + "scalarLabelPosition": "none", + "scalarValueColor": "#0069FF" + } + } + } + } + }, + { + "i": "0d09f2d6-19e6-49ce-94df-17d8bc4069c8", + "x": 1, + "y": 0, + "w": 1, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Conversations", + "description": "Conversations recorded by Signals in the timeframe", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[conversationSignals]}}", + "name": "conversationSignals", + "pluginConfigId": "{{configId}}", + "group": { + "by": [], + "aggregate": [ + { + "type": "count" + } + ] + } + }, + "scope": { + "scope": "{{scopes.[Environments]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Environment]}}" + }, + "variables": [ + "{{variables.[Environment]}}" + ], + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "count", + "comparisonColumn": "none" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "count", + "type": "quantitative", + "title": "Conversations" + } + ] + }, + "style": { + "scalarLabelPosition": "none", + "scalarValueColor": "#06B6D4" + } + } + } + } + }, + { + "i": "b3f9c861-9ff8-476d-bb08-edc2b4519f36", + "x": 2, + "y": 0, + "w": 1, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Average Turns", + "description": "Average number of turns per conversation in the timeframe", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[conversationSignals]}}", + "name": "conversationSignals", + "pluginConfigId": "{{configId}}", + "group": { + "by": [], + "aggregate": [ + { + "type": "mean", + "names": [ + "totalTurns" + ] + } + ] + } + }, + "scope": { + "scope": "{{scopes.[Environments]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Environment]}}" + }, + "variables": [ + "{{variables.[Environment]}}" + ], + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "totalTurns_mean", + "comparisonColumn": "none" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "totalTurns_mean", + "type": "quantitative", + "title": "Average Turns" + } + ] + }, + "style": { + "scalarLabelPosition": "none", + "scalarValueColor": "#8B5CF6" + } + } + } + } + }, + { + "i": "b59f3d05-37ab-44c6-b85d-a8dce2df1e80", + "x": 3, + "y": 0, + "w": 1, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Average Duration", + "description": "Average conversation duration in the timeframe", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[conversationSignals]}}", + "name": "conversationSignals", + "pluginConfigId": "{{configId}}", + "group": { + "by": [], + "aggregate": [ + { + "type": "mean", + "names": [ + "durationSeconds" + ] + } + ] + } + }, + "scope": { + "scope": "{{scopes.[Environments]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Environment]}}" + }, + "variables": [ + "{{variables.[Environment]}}" + ], + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "durationSeconds_mean", + "comparisonColumn": "none" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "durationSeconds_mean", + "type": "quantitative", + "title": "Average Duration" + } + ] + }, + "style": { + "scalarLabelPosition": "none", + "scalarValueColor": "#14B8A6" + } + } + } + } + }, + { + "i": "4b442638-42c1-4518-9e4b-b8c1cc4fb52e", + "x": 0, + "y": 2, + "w": 1, + "h": 5, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Properties", + "description": "Imported properties of this environment", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "datastream-properties", + "name": "properties" + }, + "timeframe": "none", + "scope": { + "scope": "{{scopes.[Environments]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Environment]}}" + }, + "variables": [ + "{{variables.[Environment]}}" + ], + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": true + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "richTable", + "encoding": { + "columns": [ + { + "field": "name", + "title": "Name", + "renderer": { + "type": "text" + } + }, + { + "field": "specVersion", + "title": "Spec Version", + "renderer": { + "type": "text" + } + }, + { + "field": "createdAt", + "title": "Created", + "renderer": { + "type": "date", + "relative": true + } + } + ] + }, + "style": { + "richTableTranspose": true, + "richTableCellPadding": 4, + "richTableFontSize": 13 + } + } + } + } + }, + { + "i": "f1370f4e-96cf-4dbc-ac14-4a6b8222d1f3", + "x": 1, + "y": 2, + "w": 2, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Session Health", + "description": "Health of the sessions started from this environment", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[agentSessions]}}", + "name": "agentSessions", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "environment": { + "scope": "{{scopes.[Environments]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Environment]}}" + } + } + }, + "timeframe": "none", + "variables": [ + "{{variables.[Environment]}}" + ], + "visualisation": { + "type": "data-stream-blocks", + "config": { + "data-stream-blocks": { + "labelColumn": "name", + "stateColumn": "health", + "linkColumn": "name", + "columns": 2, + "sublabel": "agentKind" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "statusGrid", + "encoding": { + "label": { + "field": "name", + "type": "nominal" + }, + "status": { + "field": "health", + "type": "nominal" + } + }, + "style": { + "statusGridColumnsPerRow": 2, + "statusGridOrderByField": "name", + "statusGridOrderDirection": "asc", + "statusGridMaxBlockHeight": 110, + "statusGridLabelWrap": true + } + } + } + } + }, + { + "i": "262145df-37ba-4568-ba55-6151a0c5fed9", + "x": 3, + "y": 2, + "w": 1, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Total Signals", + "description": "Signals detected across conversations in the timeframe", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[conversationSignals]}}", + "name": "conversationSignals", + "pluginConfigId": "{{configId}}", + "group": { + "by": [], + "aggregate": [ + { + "type": "sum", + "names": [ + "signalCount" + ] + } + ] + } + }, + "scope": { + "scope": "{{scopes.[Environments]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Environment]}}" + }, + "variables": [ + "{{variables.[Environment]}}" + ], + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "signalCount_sum", + "comparisonColumn": "none" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "signalCount_sum", + "type": "quantitative", + "title": "Total Signals" + } + ] + }, + "style": { + "scalarLabelPosition": "none", + "scalarValueColor": "#EC4899" + } + } + } + } + }, + { + "i": "97cee13c-7553-47f7-8761-fe4f3145fc98", + "x": 1, + "y": 5, + "w": 3, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Conversations Over Time", + "description": "Conversations recorded by Signals per day", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[conversationSignals]}}", + "name": "conversationSignals", + "pluginConfigId": "{{configId}}", + "group": { + "by": [ + [ + "startedAt", + "byDay" + ] + ], + "aggregate": [ + { + "type": "count" + } + ] + }, + "sort": { + "by": [ + [ + "startedAt_byDay", + "asc" + ] + ] + } + }, + "scope": { + "scope": "{{scopes.[Environments]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Environment]}}" + }, + "variables": [ + "{{variables.[Environment]}}" + ], + "visualisation": { + "type": "data-stream-bar-chart", + "config": { + "data-stream-bar-chart": { + "xAxisData": "startedAt_byDay", + "yAxisData": [ + "count" + ], + "xAxisGroup": "none", + "xAxisLabel": "", + "yAxisLabel": "Conversations", + "showXAxisLabel": false, + "showYAxisLabel": true, + "showLegend": false, + "legendPosition": "bottom", + "showGrid": true, + "horizontalLayout": "vertical", + "displayMode": "actual", + "showTotals": false, + "showValue": false, + "grouping": false, + "range": { + "type": "auto" + } + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "bar", + "encoding": { + "x": { + "field": "startedAt_byDay", + "type": "temporal", + "title": "Day" + }, + "y": { + "field": "count", + "type": "quantitative", + "title": "Conversations" + } + }, + "style": { + "cartesianBarBorderRadius": 4, + "colors": [ + "#06B6D4" + ], + "cartesianShowVerticalGridLines": false + } + } + } + } + }, + { + "i": "c116dc3e-04db-40bf-9d1b-c9160204eca7", + "x": 0, + "y": 7, + "w": 4, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Signals Over Time", + "description": "Signals detected per day across conversations", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[conversationSignals]}}", + "name": "conversationSignals", + "pluginConfigId": "{{configId}}", + "group": { + "by": [ + [ + "startedAt", + "byDay" + ] + ], + "aggregate": [ + { + "type": "sum", + "names": [ + "signalCount" + ] + } + ] + }, + "sort": { + "by": [ + [ + "startedAt_byDay", + "asc" + ] + ] + } + }, + "scope": { + "scope": "{{scopes.[Environments]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Environment]}}" + }, + "variables": [ + "{{variables.[Environment]}}" + ], + "visualisation": { + "type": "data-stream-line-graph", + "config": { + "data-stream-line-graph": { + "xAxisColumn": "startedAt_byDay", + "yAxisColumn": [ + "signalCount_sum" + ], + "seriesColumn": "none", + "showLegend": false, + "legendPosition": "bottom", + "yAxisLabel": "Signals", + "showYAxisLabel": true, + "showTrendLine": false + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "line", + "encoding": { + "x": { + "field": "startedAt_byDay", + "type": "temporal", + "title": "Day" + }, + "y": { + "field": "signalCount_sum", + "type": "quantitative", + "title": "Signals" + } + }, + "style": { + "cartesianAreaGradient": true, + "cartesianSmooth": true, + "cartesianSymbol": "circle", + "cartesianLineWidth": 2, + "colors": [ + "#EC4899" + ], + "cartesianShowVerticalGridLines": false, + "cartesianPointRadius": 5 + } + } + } + } + }, + { + "i": "ef86f9be-3562-4bff-ad25-4b5209feb872", + "x": 0, + "y": 10, + "w": 4, + "h": 4, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Conversations", + "description": "Every conversation recorded by Signals in the timeframe, with its turns, duration and signals", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[conversationSignals]}}", + "name": "conversationSignals", + "pluginConfigId": "{{configId}}", + "sort": { + "by": [ + [ + "startedAt", + "desc" + ] + ] + } + }, + "scope": { + "scope": "{{scopes.[Environments]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Environment]}}" + }, + "variables": [ + "{{variables.[Environment]}}" + ], + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": false, + "columnOrder": [ + "startedAt", + "sessionId", + "totalTurns", + "durationSeconds", + "signalCount" + ], + "hiddenColumns": [], + "rowLinkColumnName": { + "value": "sessionId", + "label": "Session ID" + } + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "richTable", + "encoding": { + "columns": [ + { + "field": "startedAt", + "title": "Started", + "renderer": { + "type": "date", + "relative": true + } + }, + { + "field": "sessionId", + "title": "Session", + "renderer": { + "type": "text" + } + }, + { + "field": "totalTurns", + "title": "Turns", + "renderer": { + "type": "bar", + "color": "#8B5CF6" + } + }, + { + "field": "durationSeconds", + "title": "Duration", + "renderer": { + "type": "number", + "decimals": 0, + "suffix": " s" + }, + "align": "right" + }, + { + "field": "signalCount", + "title": "Signals", + "renderer": { + "type": "number", + "thresholds": [ + { + "to": 0, + "color": "#22C55E" + }, + { + "to": 1000000, + "color": "#EC4899" + } + ] + }, + "align": "right", + "width": 90 + } + ] + }, + "style": { + "richTableSort": { + "field": "startedAt", + "direction": "desc" + }, + "richTableCellPadding": 6 + } + } + } + } + } + ] + } +} diff --git a/plugins/DigitalOcean/v1/defaultContent/Managed Agents/harnessOverview.dash.json b/plugins/DigitalOcean/v1/defaultContent/Managed Agents/harnessOverview.dash.json new file mode 100644 index 00000000..80caedb5 --- /dev/null +++ b/plugins/DigitalOcean/v1/defaultContent/Managed Agents/harnessOverview.dash.json @@ -0,0 +1,712 @@ +{ + "name": "Harness Overview", + "schemaVersion": "1.5", + "timeframe": "last24hours", + "dashboard": { + "_type": "layout/grid", + "columns": 10, + "version": 1, + "contents": [ + { + "i": "1eb71ed1-02c9-4a56-80e1-106860479c24", + "x": 0, + "y": 0, + "w": 2, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Environments", + "description": "Number of Harness Runtime environments", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[environments]}}", + "name": "environments", + "pluginConfigId": "{{configId}}", + "group": { + "by": [], + "aggregate": [ + { + "type": "count" + } + ] + } + }, + "timeframe": "none", + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "count", + "comparisonColumn": "none" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "count", + "type": "quantitative", + "title": "Environments" + } + ] + }, + "style": { + "scalarLabelPosition": "none", + "scalarValueColor": "#0069FF" + } + } + } + } + }, + { + "i": "42ac37e3-39b5-406e-a492-7b323a52b95e", + "x": 2, + "y": 0, + "w": 2, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Active Sessions", + "description": "Harness Runtime sessions that are ready", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[agentSessions]}}", + "name": "agentSessions", + "pluginConfigId": "{{configId}}", + "filter": { + "multiOperation": "and", + "filters": [ + { + "column": "status", + "operation": "equals", + "value": "READY" + } + ] + }, + "group": { + "by": [], + "aggregate": [ + { + "type": "count" + } + ] + } + }, + "timeframe": "none", + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "count", + "comparisonColumn": "none" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "count", + "type": "quantitative", + "title": "Active Sessions" + } + ] + }, + "style": { + "scalarLabelPosition": "none", + "scalarValueColor": "#22C55E" + } + } + } + } + }, + { + "i": "02b7ebc4-1b3a-4ac8-b4ac-6c09cce91c5b", + "x": 4, + "y": 0, + "w": 2, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Paused Sessions", + "description": "Harness Runtime sessions that are paused", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[agentSessions]}}", + "name": "agentSessions", + "pluginConfigId": "{{configId}}", + "filter": { + "multiOperation": "and", + "filters": [ + { + "column": "status", + "operation": "equals", + "value": "PAUSED" + } + ] + }, + "group": { + "by": [], + "aggregate": [ + { + "type": "count" + } + ] + } + }, + "timeframe": "none", + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "count", + "comparisonColumn": "none" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "count", + "type": "quantitative", + "title": "Paused Sessions" + } + ] + }, + "style": { + "scalarLabelPosition": "none", + "scalarValueColor": "#94A3B8" + } + } + } + } + }, + { + "i": "fe91e3f0-add7-4b26-988c-9146106a1fc1", + "x": 6, + "y": 0, + "w": 2, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Failed Sessions", + "description": "Harness Runtime sessions that have failed or are locked", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[agentSessions]}}", + "name": "agentSessions", + "pluginConfigId": "{{configId}}", + "filter": { + "multiOperation": "or", + "filters": [ + { + "column": "status", + "operation": "equals", + "value": "FAILED" + }, + { + "column": "status", + "operation": "equals", + "value": "LOCKED" + } + ] + }, + "group": { + "by": [], + "aggregate": [ + { + "type": "count" + } + ] + } + }, + "timeframe": "none", + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "count", + "comparisonColumn": "none" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "count", + "type": "quantitative", + "title": "Failed Sessions" + } + ] + }, + "style": { + "scalarLabelPosition": "none", + "scalarValueColor": "#EF4444" + } + } + } + } + }, + { + "i": "f195fe62-521c-4ee4-a617-db82fc2947f7", + "x": 8, + "y": 0, + "w": 2, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Triggers", + "description": "Number of Harness Runtime cron and webhook triggers", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[triggers]}}", + "name": "triggers", + "pluginConfigId": "{{configId}}", + "group": { + "by": [], + "aggregate": [ + { + "type": "count" + } + ] + } + }, + "timeframe": "none", + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "count", + "comparisonColumn": "none" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "count", + "type": "quantitative", + "title": "Triggers" + } + ] + }, + "style": { + "scalarLabelPosition": "none", + "scalarValueColor": "#8B5CF6" + } + } + } + } + }, + { + "i": "d9e4e091-02c0-4818-a9b2-ab4de26b1fae", + "x": 0, + "y": 2, + "w": 4, + "h": 4, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Session Health", + "description": "Health of every Harness Runtime session", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[agentSessions]}}", + "name": "agentSessions", + "pluginConfigId": "{{configId}}" + }, + "timeframe": "none", + "visualisation": { + "type": "data-stream-blocks", + "config": { + "data-stream-blocks": { + "labelColumn": "name", + "stateColumn": "health", + "linkColumn": "name", + "columns": 3, + "sublabel": "agentKind" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "statusGrid", + "encoding": { + "label": { + "field": "name", + "type": "nominal" + }, + "status": { + "field": "health", + "type": "nominal" + } + }, + "style": { + "statusGridColumnsPerRow": 3, + "statusGridOrderByField": "name", + "statusGridOrderDirection": "asc", + "statusGridMaxBlockHeight": 110, + "statusGridLabelWrap": true + } + } + } + } + }, + { + "i": "cb16ad3b-1332-4688-8ec5-1e8786b5a176", + "x": 4, + "y": 2, + "w": 3, + "h": 4, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Sessions by Agent", + "description": "Harness Runtime sessions by the coding agent they run", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[agentSessions]}}", + "name": "agentSessions", + "pluginConfigId": "{{configId}}", + "group": { + "by": [ + [ + "agentKind", + "uniqueValues" + ] + ], + "aggregate": [ + { + "type": "count" + } + ] + } + }, + "timeframe": "none", + "visualisation": { + "type": "data-stream-donut-chart", + "config": { + "data-stream-donut-chart": { + "valueColumn": "count", + "labelColumn": "agentKind_uniqueValues", + "hideCenterValue": false, + "showValuesAsPercentage": true, + "legendPosition": "auto", + "legendMode": "table" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "pie", + "encoding": { + "label": { + "field": "agentKind_uniqueValues", + "type": "nominal", + "title": "Agent" + }, + "value": { + "field": "count", + "type": "quantitative", + "title": "Sessions" + } + }, + "style": { + "pieInnerRadius": 62, + "pieDonutCenterValue": "total", + "labelFontSize": 16, + "pieLegendStyle": "table", + "pieLabels": "none", + "pieBorderRadius": 6, + "piePadAngle": 2, + "colors": [ + "#0069FF", + "#8B5CF6", + "#06B6D4", + "#F59E0B", + "#EC4899", + "#14B8A6" + ] + } + } + } + } + }, + { + "i": "df1f1339-d599-486d-a525-9107c232d141", + "x": 7, + "y": 2, + "w": 3, + "h": 4, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Trigger Health", + "description": "Health of every Harness Runtime trigger", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[triggers]}}", + "name": "triggers", + "pluginConfigId": "{{configId}}" + }, + "timeframe": "none", + "visualisation": { + "type": "data-stream-blocks", + "config": { + "data-stream-blocks": { + "labelColumn": "name", + "stateColumn": "health", + "linkColumn": "name", + "columns": 2, + "sublabel": "kind" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "statusGrid", + "encoding": { + "label": { + "field": "name", + "type": "nominal" + }, + "status": { + "field": "health", + "type": "nominal" + } + }, + "style": { + "statusGridColumnsPerRow": 2, + "statusGridOrderByField": "name", + "statusGridOrderDirection": "asc", + "statusGridMaxBlockHeight": 110, + "statusGridLabelWrap": true + } + } + } + } + }, + { + "i": "5163f0e8-a6f7-44fb-a5c2-6325a03cedc6", + "x": 0, + "y": 6, + "w": 10, + "h": 4, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Sessions", + "description": "Every Harness Runtime session with its status, agent and last activity", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[agentSessions]}}", + "name": "agentSessions", + "pluginConfigId": "{{configId}}", + "sort": { + "by": [ + [ + "lastEventAt", + "desc" + ] + ] + } + }, + "timeframe": "none", + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": false, + "columnOrder": [ + "name", + "health", + "status", + "agentKind", + "pauseReason", + "warnings", + "keepWarm", + "idleTimeoutSeconds", + "lastEventAt", + "createdAt" + ], + "hiddenColumns": [ + "id", + "configId", + "parentSessionId" + ], + "rowLinkColumnName": { + "value": "name", + "label": "Name" + } + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "richTable", + "encoding": { + "columns": [ + { + "field": "name", + "title": "Session", + "renderer": { + "type": "text" + } + }, + { + "field": "status", + "title": "Status", + "renderer": { + "type": "badge", + "colors": { + "READY": "#22C55E", + "PROVISIONING": "#F59E0B", + "DESTROYING": "#F59E0B", + "FAILED": "#EF4444", + "LOCKED": "#EF4444", + "PAUSED": "#94A3B8", + "DETACHED": "#94A3B8" + }, + "defaultColor": "#94A3B8" + } + }, + { + "field": "agentKind", + "title": "Agent", + "renderer": { + "type": "badge", + "defaultColor": "#1E3A8A" + } + }, + { + "field": "pauseReason", + "title": "Pause Reason", + "renderer": { + "type": "text" + } + }, + { + "field": "warnings", + "title": "Warnings", + "renderer": { + "type": "text", + "colors": { + "*": "#F59E0B" + } + } + }, + { + "field": "keepWarm", + "title": "Keep Warm", + "renderer": { + "type": "boolean", + "trueLabel": "Yes", + "falseLabel": "No" + }, + "align": "center", + "width": 90 + }, + { + "field": "lastEventAt", + "title": "Last Activity", + "renderer": { + "type": "date", + "relative": true + } + }, + { + "field": "createdAt", + "title": "Created", + "renderer": { + "type": "date", + "relative": true + } + } + ] + }, + "style": { + "richTableSort": { + "field": "lastEventAt", + "direction": "desc" + }, + "richTableCellPadding": 6, + "richTableRowHighlight": { + "field": "status", + "colors": { + "FAILED": "rgba(239,68,68,0.15)", + "LOCKED": "rgba(239,68,68,0.15)", + "PROVISIONING": "rgba(245,158,11,0.12)" + } + } + } + } + } + } + } + ] + } +} diff --git a/plugins/DigitalOcean/v1/defaultContent/Managed Agents/manifest.json b/plugins/DigitalOcean/v1/defaultContent/Managed Agents/manifest.json new file mode 100644 index 00000000..a7bc14ed --- /dev/null +++ b/plugins/DigitalOcean/v1/defaultContent/Managed Agents/manifest.json @@ -0,0 +1,24 @@ +{ + "items": [ + { + "name": "agent", + "type": "dashboard" + }, + { + "name": "harnessOverview", + "type": "dashboard" + }, + { + "name": "environment", + "type": "dashboard" + }, + { + "name": "agentSession", + "type": "dashboard" + }, + { + "name": "trigger", + "type": "dashboard" + } + ] +} diff --git a/plugins/DigitalOcean/v1/defaultContent/Managed Agents/trigger.dash.json b/plugins/DigitalOcean/v1/defaultContent/Managed Agents/trigger.dash.json new file mode 100644 index 00000000..3aa747b2 --- /dev/null +++ b/plugins/DigitalOcean/v1/defaultContent/Managed Agents/trigger.dash.json @@ -0,0 +1,442 @@ +{ + "name": "Trigger", + "schemaVersion": "1.5", + "timeframe": "last7days", + "variables": [ + "{{variables.[Trigger]}}" + ], + "dashboard": { + "_type": "layout/grid", + "columns": 4, + "version": 1, + "contents": [ + { + "i": "b7fda4fd-18d3-4cc7-8836-eb635daa514b", + "x": 0, + "y": 0, + "w": 1, + "h": 6, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Properties", + "description": "Imported properties of this trigger", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "datastream-properties", + "name": "properties" + }, + "timeframe": "none", + "scope": { + "scope": "{{scopes.[Triggers]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Trigger]}}" + }, + "variables": [ + "{{variables.[Trigger]}}" + ], + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": true + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "richTable", + "encoding": { + "columns": [ + { + "field": "name", + "title": "Name", + "renderer": { + "type": "text" + } + }, + { + "field": "kind", + "title": "Kind", + "renderer": { + "type": "badge", + "colors": { + "cron": "#0069FF", + "webhook": "#8B5CF6" + }, + "defaultColor": "#475569" + } + }, + { + "field": "status", + "title": "Status", + "renderer": { + "type": "badge", + "colors": { + "active": "#22C55E", + "paused": "#94A3B8" + }, + "defaultColor": "#94A3B8" + } + }, + { + "field": "schedule", + "title": "Schedule", + "renderer": { + "type": "text" + } + }, + { + "field": "timezone", + "title": "Timezone", + "renderer": { + "type": "text" + } + }, + { + "field": "sessionMode", + "title": "Session Mode", + "renderer": { + "type": "text" + } + }, + { + "field": "createdAt", + "title": "Created", + "renderer": { + "type": "date", + "relative": true + } + } + ] + }, + "style": { + "richTableTranspose": true, + "richTableCellPadding": 4, + "richTableFontSize": 13 + } + } + } + } + }, + { + "i": "6eed37d4-5dd8-49a1-9fe8-bf8cb4249f20", + "x": 1, + "y": 0, + "w": 3, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Execution History", + "description": "Health of each recent execution of this trigger", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[triggerExecutions]}}", + "name": "triggerExecutions", + "pluginConfigId": "{{configId}}", + "sort": { + "by": [ + [ + "createdAt", + "asc" + ] + ] + } + }, + "timeframe": "none", + "scope": { + "scope": "{{scopes.[Triggers]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Trigger]}}" + }, + "variables": [ + "{{variables.[Trigger]}}" + ], + "visualisation": { + "type": "data-stream-blocks", + "config": { + "data-stream-blocks": { + "labelColumn": "createdAt", + "stateColumn": "health", + "linkColumn": "none", + "columns": 10, + "sublabel": "status" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "healthHistory", + "encoding": { + "time": { + "field": "createdAt", + "type": "temporal", + "title": "Started" + }, + "status": { + "field": "health", + "type": "nominal", + "title": "Health" + } + }, + "style": { + "historyShowUptime": true, + "historyUptimeLabel": "success rate", + "historyShowTimeLabels": true + } + } + } + } + }, + { + "i": "2e742c84-132c-4e2d-9e50-60e411e6e615", + "x": 1, + "y": 2, + "w": 3, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Execution Duration", + "description": "How long each execution of this trigger took", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[triggerExecutions]}}", + "name": "triggerExecutions", + "pluginConfigId": "{{configId}}", + "sort": { + "by": [ + [ + "createdAt", + "asc" + ] + ] + } + }, + "timeframe": "none", + "scope": { + "scope": "{{scopes.[Triggers]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Trigger]}}" + }, + "variables": [ + "{{variables.[Trigger]}}" + ], + "visualisation": { + "type": "data-stream-line-graph", + "config": { + "data-stream-line-graph": { + "xAxisColumn": "createdAt", + "yAxisColumn": [ + "durationSeconds" + ], + "seriesColumn": "none", + "showLegend": false, + "legendPosition": "bottom", + "yAxisLabel": "Duration", + "showYAxisLabel": true, + "showTrendLine": false + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "line", + "encoding": { + "x": { + "field": "createdAt", + "type": "temporal", + "title": "Started" + }, + "y": { + "field": "durationSeconds", + "type": "quantitative", + "title": "Duration" + } + }, + "markLines": [ + { + "type": "average", + "label": "Average", + "color": "#94A3B8" + } + ], + "style": { + "cartesianAreaGradient": true, + "cartesianSmooth": true, + "cartesianLineWidth": 2, + "colors": [ + "#0069FF" + ], + "cartesianConnectNulls": false, + "cartesianShowVerticalGridLines": false + } + } + } + } + }, + { + "i": "f2e35209-4e88-4ee1-8cf7-00d88fdce9f0", + "x": 1, + "y": 4, + "w": 3, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Executions", + "description": "Every recent execution of this trigger with its status, duration and failure reason", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[triggerExecutions]}}", + "name": "triggerExecutions", + "pluginConfigId": "{{configId}}", + "sort": { + "by": [ + [ + "createdAt", + "desc" + ] + ] + } + }, + "timeframe": "none", + "scope": { + "scope": "{{scopes.[Triggers]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Trigger]}}" + }, + "variables": [ + "{{variables.[Trigger]}}" + ], + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": false, + "columnOrder": [ + "createdAt", + "health", + "status", + "durationSeconds", + "failureReason", + "outputTruncated", + "updatedAt" + ], + "hiddenColumns": [ + "id", + "sessionId" + ] + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "richTable", + "encoding": { + "columns": [ + { + "field": "createdAt", + "title": "Started", + "renderer": { + "type": "date", + "relative": true + } + }, + { + "field": "status", + "title": "Status", + "renderer": { + "type": "badge", + "colors": { + "succeeded": "#22C55E", + "failed": "#EF4444", + "running": "#F59E0B", + "pending": "#F59E0B" + }, + "defaultColor": "#94A3B8" + } + }, + { + "field": "durationSeconds", + "title": "Duration", + "renderer": { + "type": "number", + "decimals": 1, + "suffix": " s" + }, + "align": "right" + }, + { + "field": "failureReason", + "title": "Failure Reason", + "renderer": { + "type": "text", + "colors": { + "*": "#EF4444" + } + } + }, + { + "field": "outputTruncated", + "title": "Output Truncated", + "renderer": { + "type": "boolean", + "trueLabel": "Yes", + "falseLabel": "No" + }, + "align": "center", + "width": 120 + }, + { + "field": "updatedAt", + "title": "Updated", + "renderer": { + "type": "date", + "relative": true + } + } + ] + }, + "style": { + "richTableSort": { + "field": "createdAt", + "direction": "desc" + }, + "richTableCellPadding": 6, + "richTableWrapText": true, + "richTableRowHighlight": { + "field": "status", + "colors": { + "failed": "rgba(239,68,68,0.15)" + } + } + } + } + } + } + } + ] + } +} diff --git a/plugins/DigitalOcean/v1/defaultContent/Projects/manifest.json b/plugins/DigitalOcean/v1/defaultContent/Projects/manifest.json new file mode 100644 index 00000000..bf40c909 --- /dev/null +++ b/plugins/DigitalOcean/v1/defaultContent/Projects/manifest.json @@ -0,0 +1,8 @@ +{ + "items": [ + { + "name": "project", + "type": "dashboard" + } + ] +} diff --git a/plugins/DigitalOcean/v1/defaultContent/Projects/project.dash.json b/plugins/DigitalOcean/v1/defaultContent/Projects/project.dash.json new file mode 100644 index 00000000..f05e4c69 --- /dev/null +++ b/plugins/DigitalOcean/v1/defaultContent/Projects/project.dash.json @@ -0,0 +1,697 @@ +{ + "name": "Project", + "schemaVersion": "1.5", + "timeframe": "last24hours", + "variables": [ + "{{variables.[Project]}}" + ], + "dashboard": { + "_type": "layout/grid", + "columns": 4, + "version": 1, + "contents": [ + { + "i": "148aaee6-21bd-4429-94bd-d42b05c3a4f1", + "x": 0, + "y": 0, + "w": 1, + "h": 5, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Properties", + "description": "Imported properties of this project", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "datastream-properties", + "name": "properties" + }, + "timeframe": "none", + "scope": { + "scope": "{{scopes.[Projects]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Project]}}" + }, + "variables": [ + "{{variables.[Project]}}" + ], + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": true + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "richTable", + "encoding": { + "columns": [ + { + "field": "name", + "title": "Name", + "renderer": { + "type": "text" + } + }, + { + "field": "purpose", + "title": "Purpose", + "renderer": { + "type": "text" + } + }, + { + "field": "environment", + "title": "Environment", + "renderer": { + "type": "badge", + "colors": { + "Production": "#EF4444", + "Staging": "#F59E0B", + "Development": "#22C55E" + }, + "defaultColor": "#94A3B8" + } + }, + { + "field": "isDefault", + "title": "Default", + "renderer": { + "type": "boolean", + "trueLabel": "Yes", + "falseLabel": "No" + } + }, + { + "field": "description", + "title": "Description", + "renderer": { + "type": "text" + } + }, + { + "field": "createdAt", + "title": "Created", + "renderer": { + "type": "date", + "relative": true + } + } + ] + }, + "style": { + "richTableTranspose": true, + "richTableCellPadding": 4, + "richTableFontSize": 13 + } + } + } + } + }, + { + "i": "dda75319-74d6-4464-a8bf-1339f14856f8", + "x": 1, + "y": 0, + "w": 1, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Resources", + "description": "Number of resources assigned to this project", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[projectResources]}}", + "name": "projectResources", + "pluginConfigId": "{{configId}}", + "group": { + "by": [], + "aggregate": [ + { + "type": "count" + } + ] + } + }, + "timeframe": "none", + "scope": { + "scope": "{{scopes.[Projects]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Project]}}" + }, + "variables": [ + "{{variables.[Project]}}" + ], + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "count", + "comparisonColumn": "none" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "count", + "type": "quantitative", + "title": "Resources" + } + ] + }, + "style": { + "scalarLabelPosition": "none", + "scalarValueColor": "#0069FF" + } + } + } + } + }, + { + "i": "c31a7268-b898-448a-b452-496aba88fc58", + "x": 2, + "y": 0, + "w": 1, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Databases", + "description": "Managed database clusters in this project", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[databases]}}", + "name": "databases", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "project": { + "scope": "{{scopes.[Projects]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Project]}}" + } + }, + "group": { + "by": [], + "aggregate": [ + { + "type": "count" + } + ] + } + }, + "timeframe": "none", + "variables": [ + "{{variables.[Project]}}" + ], + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "count", + "comparisonColumn": "none" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "count", + "type": "quantitative", + "title": "Databases" + } + ] + }, + "style": { + "scalarLabelPosition": "none", + "scalarValueColor": "#F59E0B" + } + } + } + } + }, + { + "i": "491a6107-35f9-4abb-9c4b-b0b813892ced", + "x": 3, + "y": 0, + "w": 1, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Agents", + "description": "Gradient AI agents in this project", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[agents]}}", + "name": "agents", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "project": { + "scope": "{{scopes.[Projects]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Project]}}" + } + }, + "group": { + "by": [], + "aggregate": [ + { + "type": "count" + } + ] + } + }, + "timeframe": "none", + "variables": [ + "{{variables.[Project]}}" + ], + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "count", + "comparisonColumn": "none" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "count", + "type": "quantitative", + "title": "Agents" + } + ] + }, + "style": { + "scalarLabelPosition": "none", + "scalarValueColor": "#14B8A6" + } + } + } + } + }, + { + "i": "e767e95c-4bb7-422e-8239-1752a8d08834", + "x": 1, + "y": 2, + "w": 3, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Resources by Type", + "description": "Share of this project's resources by resource type", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[projectResources]}}", + "name": "projectResources", + "pluginConfigId": "{{configId}}", + "group": { + "by": [ + [ + "resourceType", + "uniqueValues" + ] + ], + "aggregate": [ + { + "type": "count" + } + ] + }, + "sort": { + "by": [ + [ + "count", + "desc" + ] + ] + } + }, + "timeframe": "none", + "scope": { + "scope": "{{scopes.[Projects]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Project]}}" + }, + "variables": [ + "{{variables.[Project]}}" + ], + "visualisation": { + "type": "data-stream-donut-chart", + "config": { + "data-stream-donut-chart": { + "valueColumn": "count", + "labelColumn": "resourceType_uniqueValues", + "hideCenterValue": false, + "showValuesAsPercentage": true, + "legendPosition": "auto", + "legendMode": "table" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "pie", + "encoding": { + "label": { + "field": "resourceType_uniqueValues", + "type": "nominal", + "title": "Type" + }, + "value": { + "field": "count", + "type": "quantitative", + "title": "Resources" + } + }, + "style": { + "pieInnerRadius": 62, + "pieDonutCenterValue": "total", + "labelFontSize": 16, + "pieLegendStyle": "table", + "pieLabels": "none", + "pieBorderRadius": 6, + "piePadAngle": 2, + "mappedColors": { + "droplet": "#0069FF", + "app": "#8B5CF6", + "kubernetes": "#06B6D4", + "dbaas": "#F59E0B", + "loadbalancer": "#EC4899", + "volume": "#14B8A6", + "space": "#6366F1", + "reservedip": "#10B981", + "volumesnapshot": "#94A3B8" + } + } + } + } + } + }, + { + "i": "bea84b0f-1f43-47b9-a4d4-fd2f568dbf7f", + "x": 0, + "y": 5, + "w": 2, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Database Health", + "description": "Health of the managed database clusters in this project", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[databases]}}", + "name": "databases", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "project": { + "scope": "{{scopes.[Projects]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Project]}}" + } + } + }, + "timeframe": "none", + "variables": [ + "{{variables.[Project]}}" + ], + "visualisation": { + "type": "data-stream-blocks", + "config": { + "data-stream-blocks": { + "labelColumn": "name", + "stateColumn": "health", + "linkColumn": "name", + "columns": 1, + "sublabel": "engine" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "statusGrid", + "encoding": { + "label": { + "field": "name", + "type": "nominal" + }, + "status": { + "field": "health", + "type": "nominal" + } + }, + "style": { + "statusGridColumnsPerRow": 2, + "statusGridOrderByField": "name", + "statusGridOrderDirection": "asc", + "statusGridMaxBlockHeight": 110, + "statusGridLabelWrap": true + } + } + } + } + }, + { + "i": "e6d069b1-9a87-481f-ad7e-289c40ecbffc", + "x": 2, + "y": 5, + "w": 2, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Agent Health", + "description": "Deployment health of the Gradient AI agents in this project", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[agents]}}", + "name": "agents", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "project": { + "scope": "{{scopes.[Projects]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Project]}}" + } + } + }, + "timeframe": "none", + "variables": [ + "{{variables.[Project]}}" + ], + "visualisation": { + "type": "data-stream-blocks", + "config": { + "data-stream-blocks": { + "labelColumn": "name", + "stateColumn": "health", + "linkColumn": "name", + "columns": 1, + "sublabel": "deploymentStatus" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "statusGrid", + "encoding": { + "label": { + "field": "name", + "type": "nominal" + }, + "status": { + "field": "health", + "type": "nominal" + } + }, + "style": { + "statusGridColumnsPerRow": 2, + "statusGridOrderByField": "name", + "statusGridOrderDirection": "asc", + "statusGridMaxBlockHeight": 110, + "statusGridLabelWrap": true + } + } + } + } + }, + { + "i": "30526437-8339-4de2-aea9-9ec8bb0de942", + "x": 0, + "y": 8, + "w": 4, + "h": 4, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Resources", + "description": "Every resource assigned to this project", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[projectResources]}}", + "name": "projectResources", + "pluginConfigId": "{{configId}}", + "sort": { + "by": [ + [ + "resourceType", + "asc" + ] + ] + } + }, + "timeframe": "none", + "scope": { + "scope": "{{scopes.[Projects]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Project]}}" + }, + "variables": [ + "{{variables.[Project]}}" + ], + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": false, + "columnOrder": [ + "resourceType", + "resourceId", + "status", + "assignedAt" + ], + "hiddenColumns": [ + "id", + "name", + "projectId" + ] + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "richTable", + "encoding": { + "columns": [ + { + "field": "resourceType", + "title": "Type", + "renderer": { + "type": "badge", + "colors": { + "droplet": "#0069FF", + "app": "#8B5CF6", + "kubernetes": "#06B6D4", + "dbaas": "#F59E0B", + "loadbalancer": "#EC4899", + "volume": "#14B8A6", + "space": "#6366F1", + "reservedip": "#10B981", + "volumesnapshot": "#94A3B8" + }, + "defaultColor": "#475569" + }, + "width": 140 + }, + { + "field": "resourceId", + "title": "Resource ID", + "renderer": { + "type": "text" + } + }, + { + "field": "status", + "title": "Status", + "renderer": { + "type": "badge", + "colors": { + "ok": "#22C55E", + "assigned": "#22C55E", + "already_assigned": "#22C55E", + "not_found": "#EF4444", + "service_down": "#F59E0B" + }, + "defaultColor": "#94A3B8" + }, + "width": 110 + }, + { + "field": "assignedAt", + "title": "Assigned", + "renderer": { + "type": "date", + "relative": true + } + } + ] + }, + "style": { + "richTableSort": { + "field": "resourceType", + "direction": "asc" + }, + "richTableCellPadding": 6 + } + } + } + } + } + ] + } +} diff --git a/plugins/DigitalOcean/v1/defaultContent/billing.dash.json b/plugins/DigitalOcean/v1/defaultContent/billing.dash.json new file mode 100644 index 00000000..a6a49d55 --- /dev/null +++ b/plugins/DigitalOcean/v1/defaultContent/billing.dash.json @@ -0,0 +1,772 @@ +{ + "name": "Billing", + "schemaVersion": "1.5", + "timeframe": "last30days", + "dashboard": { + "_type": "layout/grid", + "columns": 4, + "version": 1, + "contents": [ + { + "i": "3753cc95-a8d5-41ac-90ae-f13ffe0b3de7", + "x": 0, + "y": 0, + "w": 1, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Month-to-Date Usage", + "description": "Usage charges so far this month", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[balance]}}", + "name": "balance", + "pluginConfigId": "{{configId}}" + }, + "timeframe": "none", + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "usage", + "comparisonColumn": "none" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "usage", + "type": "quantitative", + "title": "Month-to-Date Usage" + } + ] + }, + "style": { + "scalarLabelPosition": "none", + "scalarValueColor": "#10B981" + } + } + } + } + }, + { + "i": "eb8a31fc-d829-49d5-b11a-39739c9d7a9a", + "x": 1, + "y": 0, + "w": 1, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Account Balance", + "description": "Account balance excluding this month's usage (negative means credit)", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[balance]}}", + "name": "balance", + "pluginConfigId": "{{configId}}" + }, + "timeframe": "none", + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "accountBalance", + "comparisonColumn": "none" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "accountBalance", + "type": "quantitative", + "title": "Account Balance" + } + ] + }, + "style": { + "scalarLabelPosition": "none", + "scalarValueColor": "#0069FF" + } + } + } + } + }, + { + "i": "96977df3-7f23-4d03-bf25-748fee6e55dd", + "x": 2, + "y": 0, + "w": 1, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Cost in Timeframe", + "description": "Total cost across the dashboard timeframe", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[cost]}}", + "name": "cost", + "pluginConfigId": "{{configId}}", + "group": { + "by": [], + "aggregate": [ + { + "type": "sum", + "names": [ + "cost" + ] + } + ] + } + }, + "scope": { + "scope": "{{scopes.[Accounts]}}", + "workspace": "{{workspaceId}}" + }, + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "cost_sum", + "comparisonColumn": "none" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "cost_sum", + "type": "quantitative", + "title": "Cost in Timeframe" + } + ] + }, + "style": { + "scalarLabelPosition": "none", + "scalarValueColor": "#8B5CF6" + } + } + } + } + }, + { + "i": "686956ec-d0d9-4e5c-8786-9ac530e81538", + "x": 3, + "y": 0, + "w": 1, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Current Invoice Preview", + "description": "Running total of the invoice for the current month", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[invoices]}}", + "name": "invoices", + "pluginConfigId": "{{configId}}", + "filter": { + "multiOperation": "and", + "filters": [ + { + "column": "preview", + "operation": "equals", + "value": "true" + } + ] + } + }, + "timeframe": "none", + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "amount", + "comparisonColumn": "none" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "amount", + "type": "quantitative", + "title": "Current Invoice Preview" + } + ] + }, + "style": { + "scalarLabelPosition": "none", + "scalarValueColor": "#F59E0B" + } + } + } + } + }, + { + "i": "408a4cfc-cc65-4621-a103-19b4a9a4679a", + "x": 0, + "y": 2, + "w": 4, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Daily Cost", + "description": "Cost per day split by resource group", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[cost]}}", + "name": "cost", + "pluginConfigId": "{{configId}}", + "group": { + "by": [ + [ + "start_date", + "byDay" + ], + [ + "group_description", + "uniqueValues" + ] + ], + "aggregate": [ + { + "type": "sum", + "names": [ + "cost" + ] + } + ] + }, + "sort": { + "by": [ + [ + "start_date_byDay", + "asc" + ] + ] + } + }, + "scope": { + "scope": "{{scopes.[Accounts]}}", + "workspace": "{{workspaceId}}" + }, + "visualisation": { + "type": "data-stream-bar-chart", + "config": { + "data-stream-bar-chart": { + "xAxisData": "start_date_byDay", + "yAxisData": [ + "cost_sum" + ], + "xAxisGroup": "group_description_uniqueValues", + "xAxisLabel": "", + "yAxisLabel": "Cost (USD)", + "showXAxisLabel": false, + "showYAxisLabel": true, + "showLegend": true, + "legendPosition": "bottom", + "showGrid": true, + "horizontalLayout": "vertical", + "displayMode": "actual", + "showTotals": true, + "showValue": false, + "grouping": false, + "range": { + "type": "auto" + } + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "bar", + "encoding": { + "x": { + "field": "start_date_byDay", + "type": "temporal", + "title": "Day" + }, + "y": { + "field": "cost_sum", + "type": "quantitative", + "title": "Cost (USD)" + }, + "series": { + "field": "group_description_uniqueValues", + "type": "nominal", + "title": "Group" + } + }, + "style": { + "cartesianStack": "on", + "legendPosition": "bottom", + "cartesianShowYAxisTitle": true, + "cartesianYAxisTitle": "Cost (USD)", + "colors": [ + "#0069FF", + "#8B5CF6", + "#06B6D4", + "#F59E0B", + "#EC4899", + "#14B8A6", + "#6366F1", + "#10B981", + "#3B82F6", + "#F97316" + ], + "cartesianShowVerticalGridLines": false + } + } + } + } + }, + { + "i": "18a7443c-6906-4e34-828c-e4653354c967", + "x": 0, + "y": 5, + "w": 2, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Cost by Region", + "description": "Share of cost in the timeframe by region", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[cost]}}", + "name": "cost", + "pluginConfigId": "{{configId}}", + "group": { + "by": [ + [ + "region", + "uniqueValues" + ] + ], + "aggregate": [ + { + "type": "sum", + "names": [ + "cost" + ] + } + ] + }, + "sort": { + "by": [ + [ + "cost_sum", + "desc" + ] + ] + } + }, + "scope": { + "scope": "{{scopes.[Accounts]}}", + "workspace": "{{workspaceId}}" + }, + "visualisation": { + "type": "data-stream-donut-chart", + "config": { + "data-stream-donut-chart": { + "valueColumn": "cost_sum", + "labelColumn": "region_uniqueValues", + "hideCenterValue": false, + "showValuesAsPercentage": true, + "legendPosition": "auto", + "legendMode": "table" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "pie", + "encoding": { + "label": { + "field": "region_uniqueValues", + "type": "nominal", + "title": "Region" + }, + "value": { + "field": "cost_sum", + "type": "quantitative", + "title": "Cost" + } + }, + "style": { + "pieInnerRadius": 62, + "pieDonutCenterValue": "total", + "labelFontSize": 16, + "pieLegendStyle": "table", + "pieLabels": "none", + "pieBorderRadius": 6, + "piePadAngle": 2, + "colors": [ + "#0069FF", + "#8B5CF6", + "#06B6D4", + "#F59E0B", + "#EC4899", + "#14B8A6", + "#6366F1", + "#10B981" + ] + } + } + } + } + }, + { + "i": "dfea239e-7fa3-49fb-9cab-183dbb858ac3", + "x": 2, + "y": 5, + "w": 2, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Top Resources by Cost", + "description": "The ten most expensive resources in the timeframe", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[cost]}}", + "name": "cost", + "pluginConfigId": "{{configId}}", + "group": { + "by": [ + [ + "description", + "uniqueValues" + ] + ], + "aggregate": [ + { + "type": "sum", + "names": [ + "cost" + ] + } + ] + }, + "sort": { + "by": [ + [ + "cost_sum", + "desc" + ] + ], + "top": 10 + } + }, + "scope": { + "scope": "{{scopes.[Accounts]}}", + "workspace": "{{workspaceId}}" + }, + "visualisation": { + "type": "data-stream-bar-chart", + "config": { + "data-stream-bar-chart": { + "xAxisData": "description_uniqueValues", + "yAxisData": [ + "cost_sum" + ], + "xAxisGroup": "none", + "xAxisLabel": "", + "yAxisLabel": "Cost (USD)", + "showXAxisLabel": false, + "showYAxisLabel": true, + "showLegend": false, + "legendPosition": "bottom", + "showGrid": true, + "horizontalLayout": "horizontal", + "displayMode": "actual", + "showTotals": false, + "showValue": false, + "grouping": false, + "range": { + "type": "auto" + } + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "bar", + "encoding": { + "x": { + "field": "description_uniqueValues", + "type": "nominal", + "title": "Resource" + }, + "y": { + "field": "cost_sum", + "type": "quantitative", + "title": "Cost (USD)" + } + }, + "style": { + "cartesianHorizontal": true, + "cartesianBarBorderRadius": 6, + "showLabels": true, + "colors": [ + "#6366F1" + ], + "cartesianShowVerticalGridLines": false, + "cartesianShowHorizontalGridLines": false + } + } + } + } + }, + { + "i": "920c8cc2-c36d-4417-8669-ca8013b1c6ed", + "x": 0, + "y": 8, + "w": 2, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Invoice History", + "description": "Amount of the last 12 issued invoices by billing period, oldest to newest", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[invoices]}}", + "name": "invoices", + "pluginConfigId": "{{configId}}", + "sql": "SELECT \"invoice_period\", \"amount\" FROM (SELECT \"invoice_period\", \"amount\" FROM \"dataset\" WHERE NOT \"preview\" ORDER BY \"invoice_period\" DESC LIMIT 12) ORDER BY \"invoice_period\" ASC" + }, + "timeframe": "none", + "visualisation": { + "type": "data-stream-bar-chart", + "config": { + "data-stream-bar-chart": { + "xAxisData": "invoice_period", + "yAxisData": [ + "amount" + ], + "xAxisGroup": "none", + "xAxisLabel": "", + "yAxisLabel": "Amount (USD)", + "showXAxisLabel": false, + "showYAxisLabel": true, + "showLegend": false, + "legendPosition": "bottom", + "showGrid": true, + "horizontalLayout": "vertical", + "displayMode": "actual", + "showTotals": false, + "showValue": false, + "grouping": false, + "range": { + "type": "auto" + } + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "bar", + "encoding": { + "x": { + "field": "invoice_period", + "type": "ordinal", + "title": "Billing Period" + }, + "y": { + "field": "amount", + "type": "quantitative", + "title": "Amount (USD)" + } + }, + "markLines": [ + { + "type": "average", + "label": "Average", + "color": "#94A3B8" + } + ], + "style": { + "cartesianBarBorderRadius": 6, + "colors": [ + "#8B5CF6" + ], + "cartesianXAxisLabelRotation": -45, + "cartesianShowVerticalGridLines": false + } + } + } + } + }, + { + "i": "5739c63a-5962-45d2-96ec-3bbe6bc86033", + "x": 2, + "y": 8, + "w": 2, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Invoices", + "description": "Issued invoices and the current month's preview", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[invoices]}}", + "name": "invoices", + "pluginConfigId": "{{configId}}", + "sort": { + "by": [ + [ + "invoice_period", + "desc" + ] + ] + } + }, + "timeframe": "none", + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": false, + "columnOrder": [ + "invoice_period", + "invoice_id", + "amount", + "preview", + "updated_at" + ], + "hiddenColumns": [ + "invoice_uuid" + ] + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "richTable", + "encoding": { + "columns": [ + { + "field": "invoice_period", + "title": "Period", + "renderer": { + "type": "text" + }, + "width": 90 + }, + { + "field": "invoice_id", + "title": "Invoice", + "renderer": { + "type": "text" + } + }, + { + "field": "amount", + "title": "Amount", + "renderer": { + "type": "number", + "prefix": "$", + "decimals": 2 + }, + "align": "right" + }, + { + "field": "preview", + "title": "Status", + "renderer": { + "type": "boolean", + "trueLabel": "Preview", + "falseLabel": "Issued", + "trueColor": "#F59E0B", + "falseColor": "#22C55E" + } + }, + { + "field": "updated_at", + "title": "Updated", + "renderer": { + "type": "date", + "relative": true + } + } + ] + }, + "style": { + "richTableSort": { + "field": "invoice_period", + "direction": "desc" + }, + "richTableCellPadding": 5 + } + } + } + } + } + ] + } +} diff --git a/plugins/DigitalOcean/v1/defaultContent/manifest.json b/plugins/DigitalOcean/v1/defaultContent/manifest.json new file mode 100644 index 00000000..ddbbd3db --- /dev/null +++ b/plugins/DigitalOcean/v1/defaultContent/manifest.json @@ -0,0 +1,28 @@ +{ + "items": [ + { + "name": "overview", + "type": "dashboard" + }, + { + "name": "billing", + "type": "dashboard" + }, + { + "name": "Projects", + "type": "folder" + }, + { + "name": "Managed Agents", + "type": "folder" + }, + { + "name": "Data & Learning", + "type": "folder" + }, + { + "name": "Core Cloud", + "type": "folder" + } + ] +} diff --git a/plugins/DigitalOcean/v1/defaultContent/overview.dash.json b/plugins/DigitalOcean/v1/defaultContent/overview.dash.json new file mode 100644 index 00000000..7f3c3a0f --- /dev/null +++ b/plugins/DigitalOcean/v1/defaultContent/overview.dash.json @@ -0,0 +1,1149 @@ +{ + "name": "Overview", + "schemaVersion": "1.5", + "timeframe": "last24hours", + "dashboard": { + "_type": "layout/grid", + "columns": 14, + "version": 1, + "contents": [ + { + "i": "92874ea0-a8b4-4ca7-86bd-d7260ea44083", + "x": 0, + "y": 0, + "w": 2, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Month-to-Date Usage", + "description": "Usage charges so far this month, in the account's billing currency", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[balance]}}", + "name": "balance", + "pluginConfigId": "{{configId}}" + }, + "timeframe": "none", + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "usage", + "comparisonColumn": "none" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "usage", + "type": "quantitative", + "title": "Month-to-Date Usage" + } + ] + }, + "style": { + "scalarLabelPosition": "none", + "scalarValueColor": "#10B981" + } + } + } + } + }, + { + "i": "ddeca161-9429-43df-a4be-3f0d3e0acd22", + "x": 2, + "y": 0, + "w": 2, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Droplets", + "description": "Number of Droplets", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[droplets]}}", + "name": "droplets", + "pluginConfigId": "{{configId}}", + "group": { + "by": [], + "aggregate": [ + { + "type": "count" + } + ] + } + }, + "timeframe": "none", + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "count", + "comparisonColumn": "none" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "count", + "type": "quantitative", + "title": "Droplets" + } + ] + }, + "style": { + "scalarLabelPosition": "none", + "scalarValueColor": "#0069FF" + } + } + } + } + }, + { + "i": "c83ec79e-2611-4dd7-969c-2a9ff4db63e3", + "x": 4, + "y": 0, + "w": 2, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Apps", + "description": "Number of App Platform apps", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[apps]}}", + "name": "apps", + "pluginConfigId": "{{configId}}", + "group": { + "by": [], + "aggregate": [ + { + "type": "count" + } + ] + } + }, + "timeframe": "none", + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "count", + "comparisonColumn": "none" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "count", + "type": "quantitative", + "title": "Apps" + } + ] + }, + "style": { + "scalarLabelPosition": "none", + "scalarValueColor": "#8B5CF6" + } + } + } + } + }, + { + "i": "bcd446bf-6484-4ad4-8280-43595ea0475a", + "x": 6, + "y": 0, + "w": 2, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Kubernetes Clusters", + "description": "Number of DOKS clusters", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[kubernetesClusters]}}", + "name": "kubernetesClusters", + "pluginConfigId": "{{configId}}", + "group": { + "by": [], + "aggregate": [ + { + "type": "count" + } + ] + } + }, + "timeframe": "none", + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "count", + "comparisonColumn": "none" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "count", + "type": "quantitative", + "title": "Kubernetes Clusters" + } + ] + }, + "style": { + "scalarLabelPosition": "none", + "scalarValueColor": "#06B6D4" + } + } + } + } + }, + { + "i": "60c24852-e1d0-4b36-9da8-f6e97db9b937", + "x": 8, + "y": 0, + "w": 2, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Databases", + "description": "Number of managed database clusters", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[databases]}}", + "name": "databases", + "pluginConfigId": "{{configId}}", + "group": { + "by": [], + "aggregate": [ + { + "type": "count" + } + ] + } + }, + "timeframe": "none", + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "count", + "comparisonColumn": "none" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "count", + "type": "quantitative", + "title": "Databases" + } + ] + }, + "style": { + "scalarLabelPosition": "none", + "scalarValueColor": "#F59E0B" + } + } + } + } + }, + { + "i": "4033d349-68d5-42cc-9a9c-6eb672f75f6c", + "x": 10, + "y": 0, + "w": 2, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Load Balancers", + "description": "Number of load balancers", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[loadBalancers]}}", + "name": "loadBalancers", + "pluginConfigId": "{{configId}}", + "group": { + "by": [], + "aggregate": [ + { + "type": "count" + } + ] + } + }, + "timeframe": "none", + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "count", + "comparisonColumn": "none" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "count", + "type": "quantitative", + "title": "Load Balancers" + } + ] + }, + "style": { + "scalarLabelPosition": "none", + "scalarValueColor": "#EC4899" + } + } + } + } + }, + { + "i": "22deca19-5843-49ed-93ae-5bfb0193c9fb", + "x": 12, + "y": 0, + "w": 2, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Agent Sessions", + "description": "Number of Harness Runtime agent sessions", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[agentSessions]}}", + "name": "agentSessions", + "pluginConfigId": "{{configId}}", + "group": { + "by": [], + "aggregate": [ + { + "type": "count" + } + ] + } + }, + "timeframe": "none", + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "count", + "comparisonColumn": "none" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "count", + "type": "quantitative", + "title": "Agent Sessions" + } + ] + }, + "style": { + "scalarLabelPosition": "none", + "scalarValueColor": "#14B8A6" + } + } + } + } + }, + { + "i": "615dc95a-da83-4310-be84-47ed426a361d", + "x": 0, + "y": 2, + "w": 6, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Droplet Health", + "description": "Health of every Droplet", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[droplets]}}", + "name": "droplets", + "pluginConfigId": "{{configId}}" + }, + "timeframe": "none", + "visualisation": { + "type": "data-stream-blocks", + "config": { + "data-stream-blocks": { + "labelColumn": "name", + "stateColumn": "health", + "linkColumn": "name", + "columns": 3, + "sublabel": "status" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "statusGrid", + "encoding": { + "label": { + "field": "name", + "type": "nominal" + }, + "status": { + "field": "health", + "type": "nominal" + } + }, + "style": { + "statusGridColumnsPerRow": 3, + "statusGridOrderByField": "name", + "statusGridOrderDirection": "asc", + "statusGridMaxBlockHeight": 110, + "statusGridLabelWrap": true + } + } + } + } + }, + { + "i": "04bf1eda-243a-4c23-b111-4527309291b1", + "x": 6, + "y": 2, + "w": 4, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "App Health", + "description": "Health of every App Platform app, from its active deployment", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[apps]}}", + "name": "apps", + "pluginConfigId": "{{configId}}" + }, + "timeframe": "none", + "visualisation": { + "type": "data-stream-blocks", + "config": { + "data-stream-blocks": { + "labelColumn": "name", + "stateColumn": "health", + "linkColumn": "name", + "columns": 3, + "sublabel": "activeDeploymentPhase" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "statusGrid", + "encoding": { + "label": { + "field": "name", + "type": "nominal" + }, + "status": { + "field": "health", + "type": "nominal" + } + }, + "style": { + "statusGridColumnsPerRow": 2, + "statusGridOrderByField": "name", + "statusGridOrderDirection": "asc", + "statusGridMaxBlockHeight": 110, + "statusGridLabelWrap": true + } + } + } + } + }, + { + "i": "7d86e7f0-1abe-482c-b943-421c6f2fecf0", + "x": 10, + "y": 2, + "w": 4, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Cluster Health", + "description": "Health of every DOKS cluster", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[kubernetesClusters]}}", + "name": "kubernetesClusters", + "pluginConfigId": "{{configId}}" + }, + "timeframe": "none", + "visualisation": { + "type": "data-stream-blocks", + "config": { + "data-stream-blocks": { + "labelColumn": "name", + "stateColumn": "health", + "linkColumn": "name", + "columns": 3, + "sublabel": "status" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "statusGrid", + "encoding": { + "label": { + "field": "name", + "type": "nominal" + }, + "status": { + "field": "health", + "type": "nominal" + } + }, + "style": { + "statusGridColumnsPerRow": 2, + "statusGridOrderByField": "name", + "statusGridOrderDirection": "asc", + "statusGridMaxBlockHeight": 110, + "statusGridLabelWrap": true + } + } + } + } + }, + { + "i": "09f117ad-537b-46ce-8cf0-5b53d6d6bb66", + "x": 0, + "y": 5, + "w": 6, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Database Health", + "description": "Health of every managed database cluster", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[databases]}}", + "name": "databases", + "pluginConfigId": "{{configId}}" + }, + "timeframe": "none", + "visualisation": { + "type": "data-stream-blocks", + "config": { + "data-stream-blocks": { + "labelColumn": "name", + "stateColumn": "health", + "linkColumn": "none", + "columns": 3, + "sublabel": "engine" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "statusGrid", + "encoding": { + "label": { + "field": "name", + "type": "nominal" + }, + "status": { + "field": "health", + "type": "nominal" + } + }, + "style": { + "statusGridColumnsPerRow": 3, + "statusGridOrderByField": "name", + "statusGridOrderDirection": "asc", + "statusGridMaxBlockHeight": 110, + "statusGridLabelWrap": true + } + } + } + } + }, + { + "i": "b33cb3e0-9a50-4e0b-a97f-d868b6bb0dd9", + "x": 6, + "y": 5, + "w": 4, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Load Balancer Health", + "description": "Health of every load balancer", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[loadBalancers]}}", + "name": "loadBalancers", + "pluginConfigId": "{{configId}}" + }, + "timeframe": "none", + "visualisation": { + "type": "data-stream-blocks", + "config": { + "data-stream-blocks": { + "labelColumn": "name", + "stateColumn": "health", + "linkColumn": "name", + "columns": 1, + "sublabel": "status" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "statusGrid", + "encoding": { + "label": { + "field": "name", + "type": "nominal" + }, + "status": { + "field": "health", + "type": "nominal" + } + }, + "style": { + "statusGridColumnsPerRow": 2, + "statusGridOrderByField": "name", + "statusGridOrderDirection": "asc", + "statusGridMaxBlockHeight": 110, + "statusGridLabelWrap": true + } + } + } + } + }, + { + "i": "48444bb4-e0aa-4247-abf5-7555c49f0c24", + "x": 10, + "y": 5, + "w": 4, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Session Health", + "description": "Health of every Harness Runtime agent session", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[agentSessions]}}", + "name": "agentSessions", + "pluginConfigId": "{{configId}}" + }, + "timeframe": "none", + "visualisation": { + "type": "data-stream-blocks", + "config": { + "data-stream-blocks": { + "labelColumn": "name", + "stateColumn": "health", + "linkColumn": "name", + "columns": 1, + "sublabel": "agentKind" + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "statusGrid", + "encoding": { + "label": { + "field": "name", + "type": "nominal" + }, + "status": { + "field": "health", + "type": "nominal" + } + }, + "style": { + "statusGridColumnsPerRow": 2, + "statusGridOrderByField": "name", + "statusGridOrderDirection": "asc", + "statusGridMaxBlockHeight": 110, + "statusGridLabelWrap": true + } + } + } + } + }, + { + "i": "46a07523-5232-47be-b7ad-21f625502715", + "x": 0, + "y": 8, + "w": 14, + "h": 4, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Droplet Inventory", + "description": "Every Droplet with its size, region, image and addresses", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[droplets]}}", + "name": "droplets", + "pluginConfigId": "{{configId}}", + "sort": { + "by": [ + [ + "name", + "asc" + ] + ] + } + }, + "timeframe": "none", + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": false, + "columnOrder": [ + "name", + "health", + "status", + "region", + "sizeSlug", + "vcpus", + "memory", + "disk", + "image", + "publicIp", + "privateIp", + "tagList", + "createdAt" + ], + "hiddenColumns": [ + "id", + "vpcUuid", + "locked" + ], + "rowLinkColumnName": { + "value": "name", + "label": "Name" + } + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "richTable", + "encoding": { + "columns": [ + { + "field": "name", + "title": "Droplet", + "renderer": { + "type": "text" + } + }, + { + "field": "status", + "title": "Status", + "renderer": { + "type": "badge", + "colors": { + "active": "#22C55E", + "running": "#22C55E", + "online": "#22C55E", + "new": "#F59E0B", + "off": "#94A3B8", + "archive": "#94A3B8", + "errored": "#EF4444", + "error": "#EF4444" + }, + "defaultColor": "#94A3B8" + } + }, + { + "field": "region", + "title": "Region", + "renderer": { + "type": "badge", + "defaultColor": "#1E3A8A" + } + }, + { + "field": "sizeSlug", + "title": "Size", + "renderer": { + "type": "text" + } + }, + { + "field": "vcpus", + "title": "vCPUs", + "renderer": { + "type": "number" + }, + "align": "right", + "width": 70 + }, + { + "field": "memory", + "title": "Memory", + "renderer": { + "type": "number", + "suffix": " MB" + }, + "align": "right" + }, + { + "field": "disk", + "title": "Disk", + "renderer": { + "type": "number", + "suffix": " GB" + }, + "align": "right" + }, + { + "field": "image", + "title": "Image", + "renderer": { + "type": "text" + } + }, + { + "field": "publicIp", + "title": "Public IP", + "renderer": { + "type": "text" + } + }, + { + "field": "privateIp", + "title": "Private IP", + "renderer": { + "type": "text" + } + }, + { + "field": "tagList", + "title": "Tags", + "renderer": { + "type": "tag-list", + "color": "#334155" + } + }, + { + "field": "createdAt", + "title": "Created", + "renderer": { + "type": "date", + "relative": true + } + } + ] + }, + "style": { + "richTableSort": { + "field": "name", + "direction": "asc" + }, + "richTableCellPadding": 6, + "richTableRowHighlight": { + "field": "status", + "colors": { + "off": "rgba(245,158,11,0.12)", + "new": "rgba(245,158,11,0.12)", + "archive": "rgba(148,163,184,0.12)" + } + } + } + } + } + } + }, + { + "i": "1ac22974-b059-4b3b-8c17-7728182d99ea", + "x": 0, + "y": 12, + "w": 14, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Database Inventory", + "description": "Every managed database cluster with its engine, version and end-of-life date", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[databases]}}", + "name": "databases", + "pluginConfigId": "{{configId}}", + "sort": { + "by": [ + [ + "name", + "asc" + ] + ] + } + }, + "timeframe": "none", + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": false, + "columnOrder": [ + "name", + "health", + "engine", + "version", + "versionEndOfLife", + "region", + "size", + "numNodes", + "tagList", + "createdAt" + ], + "hiddenColumns": [ + "id", + "projectId", + "status" + ] + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "richTable", + "encoding": { + "columns": [ + { + "field": "name", + "title": "Database", + "renderer": { + "type": "text" + } + }, + { + "field": "status", + "title": "Status", + "renderer": { + "type": "badge", + "colors": { + "online": "#22C55E", + "creating": "#F59E0B", + "resizing": "#F59E0B", + "migrating": "#F59E0B", + "forking": "#F59E0B" + }, + "defaultColor": "#94A3B8" + } + }, + { + "field": "engine", + "title": "Engine", + "renderer": { + "type": "badge", + "colors": { + "pg": "#336791", + "mysql": "#00758F", + "redis": "#DC382D", + "valkey": "#6E2DD4", + "mongodb": "#47A248", + "kafka": "#231F20", + "opensearch": "#005EB8" + }, + "defaultColor": "#475569" + } + }, + { + "field": "version", + "title": "Version", + "renderer": { + "type": "text" + }, + "align": "center", + "width": 80 + }, + { + "field": "versionEndOfLife", + "title": "End of Life", + "renderer": { + "type": "date" + } + }, + { + "field": "region", + "title": "Region", + "renderer": { + "type": "badge", + "defaultColor": "#1E3A8A" + } + }, + { + "field": "size", + "title": "Size", + "renderer": { + "type": "text" + } + }, + { + "field": "numNodes", + "title": "Nodes", + "renderer": { + "type": "number" + }, + "align": "right", + "width": 70 + }, + { + "field": "tagList", + "title": "Tags", + "renderer": { + "type": "tag-list", + "color": "#334155" + } + }, + { + "field": "createdAt", + "title": "Created", + "renderer": { + "type": "date", + "relative": true + } + } + ] + }, + "style": { + "richTableSort": { + "field": "name", + "direction": "asc" + }, + "richTableCellPadding": 6, + "richTableRowHighlight": { + "field": "versionEndOfLife", + "thresholds": [ + { + "to": "now", + "color": "rgba(239,68,68,0.15)" + } + ] + } + } + } + } + } + } + ] + } +} diff --git a/plugins/DigitalOcean/v1/defaultContent/scopes.json b/plugins/DigitalOcean/v1/defaultContent/scopes.json new file mode 100644 index 00000000..2f730dc2 --- /dev/null +++ b/plugins/DigitalOcean/v1/defaultContent/scopes.json @@ -0,0 +1,206 @@ +[ + { + "name": "Accounts", + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "Account" + ] + } + }, + "variable": { + "name": "Account", + "allowMultipleSelection": false, + "default": "none", + "type": "object" + } + }, + { + "name": "Droplets", + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "Droplet" + ] + } + }, + "variable": { + "name": "Droplet", + "allowMultipleSelection": false, + "default": "none", + "type": "object" + } + }, + { + "name": "Apps", + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "App" + ] + } + }, + "variable": { + "name": "App", + "allowMultipleSelection": false, + "default": "none", + "type": "object" + } + }, + { + "name": "Kubernetes Clusters", + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "Kubernetes Cluster" + ] + } + }, + "variable": { + "name": "Kubernetes Cluster", + "allowMultipleSelection": false, + "default": "none", + "type": "object" + } + }, + { + "name": "Load Balancers", + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "Load Balancer" + ] + } + }, + "variable": { + "name": "Load Balancer", + "allowMultipleSelection": false, + "default": "none", + "type": "object" + } + }, + { + "name": "Agents", + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "Agent" + ] + } + }, + "variable": { + "name": "Agent", + "allowMultipleSelection": false, + "default": "none", + "type": "object" + } + }, + { + "name": "Projects", + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "Project" + ] + } + }, + "variable": { + "name": "Project", + "allowMultipleSelection": false, + "default": "none", + "type": "object" + } + }, + { + "name": "Databases", + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "Database" + ] + } + }, + "variable": { + "name": "Database", + "allowMultipleSelection": false, + "default": "none", + "type": "object" + } + }, + { + "name": "VPCs", + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "VPC" + ] + } + }, + "variable": { + "name": "VPC", + "allowMultipleSelection": false, + "default": "none", + "type": "object" + } + }, + { + "name": "Environments", + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "Environment" + ] + } + }, + "variable": { + "name": "Environment", + "allowMultipleSelection": false, + "default": "none", + "type": "object" + } + }, + { + "name": "Agent Sessions", + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "Agent Session" + ] + } + }, + "variable": { + "name": "Agent Session", + "allowMultipleSelection": false, + "default": "none", + "type": "object" + } + }, + { + "name": "Triggers", + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "Trigger" + ] + } + }, + "variable": { + "name": "Trigger", + "allowMultipleSelection": false, + "default": "none", + "type": "object" + } + } +] diff --git a/plugins/DigitalOcean/v1/docs/README.md b/plugins/DigitalOcean/v1/docs/README.md new file mode 100644 index 00000000..48d12c67 --- /dev/null +++ b/plugins/DigitalOcean/v1/docs/README.md @@ -0,0 +1,101 @@ +Monitor your [DigitalOcean](https://www.digitalocean.com) estate in SquaredUp — Droplets, App Platform apps, Kubernetes clusters, managed databases, load balancers, Gradient AI agents, and billing — via the [DigitalOcean API](https://docs.digitalocean.com/reference/api/). + +## Setup + +You will need a DigitalOcean **personal access token**. The plugin only reads data, so a token with read scopes is enough. + +1. Sign in to the [DigitalOcean Control Panel](https://cloud.digitalocean.com). +2. Go to **API → Tokens** ([cloud.digitalocean.com/account/api/tokens](https://cloud.digitalocean.com/account/api/tokens)) and click **Generate New Token**. +3. Give the token a name (e.g. `SquaredUp`) and choose an **Expiration**. When the token expires, the plugin stops returning data until you supply a new one. +4. Under **Scopes**, choose **Custom Scopes** and grant **read** on: `account`, `droplet`, `app`, `kubernetes`, `database`, `load_balancer`, `monitoring`, `billing`, `genai`, `vpc`, `project` and `agent_harness_session`, plus **query** on `signals`. A **Read Only** token also works. See [token scopes](https://docs.digitalocean.com/reference/api/scopes/) for details. +5. Click **Generate Token**, copy the token (it starts `dop_v1_`) and paste it into the **Personal access token** field. + +The token belongs to one team. To monitor several teams, add the plugin once per team. + +## Configuration fields + +| Field | What it is | Where to find it | Required | +| ------------------------- | ------------------------------------------------------------------ | ----------------------------------------------------- | -------- | +| **Personal access token** | Authenticates every request as a bearer token. | Control Panel → **API → Tokens** (see above). | Yes | + +On save, the plugin validates the token by fetching your account details, so an invalid or expired token, or one without the `account:read` scope, fails setup. Other scopes are not checked on save — a token missing one shows errors on the tiles that need it. Agents and Harness Runtime objects are optional in the import: without the `genai` or `agent_harness_session` scope, or on an account that doesn't use them, the import skips them with a warning and imports everything else. + +## What this plugin monitors + +- **Compute**: Droplet status, size, region and image, plus CPU, load, memory, disk and bandwidth history from DigitalOcean Monitoring. +- **App Platform**: app status from the active deployment, per-component health with CPU, memory and replicas, recent deployments, and CPU, memory and restart history. +- **Kubernetes**: DOKS cluster state, version and node counts, plus a per-node view of each cluster's node pools. +- **Databases and load balancers**: managed database cluster status, engine and version. Load balancer status, plus request rate, connections, response time and health-check history. +- **AI agents**: Gradient AI platform agent deployment status, model and region, token usage per agent, and evaluation test cases. +- **Harness Runtime**: environments, agent sessions (status, agent, last activity), and cron and webhook triggers with their execution history. Where Signals collection is switched on, each environment's conversations (turns, duration, detected signals), and each session's turns (tool calls, token usage) and the signals detected in them. +- **Projects and networking**: projects and the resources assigned to them, and VPCs with the Droplets, clusters, load balancers and databases inside each. +- **Billing**: month-to-date usage and balance, invoice history, and daily cost by resource, SKU and region. + +The out-of-the-box dashboards include an account-wide **Overview** and a **Billing** dashboard. Perspectives follow DigitalOcean's own navigation: **Projects**, **Managed Agents** (Agent), **Data & Learning** (Database) and **Core Cloud** (Droplet, App, Kubernetes Cluster, Load Balancer, VPC). + +## Data streams + +- **Projects**: all projects with their purpose and environment (account-wide). +- **Project Resources**: the resources assigned to a project, with their type and when they were assigned (per project). +- **VPCs**: all VPC networks with their region and IP range (account-wide). +- **Droplets**: all Droplets with their status, size, region, image and IP addresses (account-wide). +- **Droplet Metrics**: a time series for one Droplet. Choose CPU, load average, memory, filesystem or bandwidth (per Droplet). +- **Apps**: all App Platform apps with the phase of their active deployment (account-wide). +- **App Health**: health, CPU, memory and replicas for each component of an app (per app). +- **App Deployments**: the 50 most recent deployments of an app, with phase and cause (per app). +- **App Metrics**: CPU, memory or restart count time series for each component instance (per app). +- **Kubernetes Clusters**: all DOKS clusters with their state, version and node counts (account-wide). +- **Kubernetes Nodes**: worker nodes of a cluster, with their node pool, size and state (per cluster). +- **Databases**: all managed database clusters with their engine, version, status and size (account-wide). +- **Load Balancers**: all load balancers with their status, IP address, region and backend Droplet count (account-wide). +- **Load Balancer Metrics**: a time series for one load balancer metric, such as requests per second, connections, response time or health checks (per load balancer). +- **Environments**: all Harness Runtime environment configs (account-wide). +- **Agent Sessions**: Harness Runtime sessions with their status, agent kind and last activity, optionally filtered to an environment (account-wide). +- **Triggers**: Harness Runtime cron and webhook triggers with their status and schedule (account-wide). +- **Trigger Executions**: each run of a trigger, with status, duration and failure reason (per trigger). +- **Conversation Signals**: conversations Signals recorded for an environment, with turns, duration and number of detected signals (per environment). +- **Session Dialogues**: each turn of a session with its run status, tool calls and failures, tool time, token usage and detected signals (per agent session). +- **Session Signals**: each behavioral signal detected in a session, such as an execution failure or a tool loop, with its category, confidence and detail (per agent session). +- **Agents**: all Gradient AI agents with their deployment status, model and region (account-wide). +- **Agent Usage**: input and output tokens used by an agent over the timeframe (per agent). +- **Evaluation Test Cases**: Gradient AI evaluation test cases with their star metric and success threshold (account-wide). +- **Balance**: month-to-date usage, month-to-date balance and account balance (account-wide). +- **Invoices**: issued invoices and the current month's preview, in USD (account-wide). +- **Cost**: daily usage cost in USD by resource, SKU and region (per account). + +## What gets indexed + +| Object type | API source | Represents | +| ---------------------- | ----------------------------- | -------------------------------------------------------------- | +| **Account** | `GET /v2/account` | The DigitalOcean team the token belongs to. | +| **Droplet** | `GET /v2/droplets` | A Droplet (virtual machine). | +| **App** | `GET /v2/apps` | An App Platform app. | +| **Kubernetes Cluster** | `GET /v2/kubernetes/clusters` | A DigitalOcean Kubernetes (DOKS) cluster. | +| **Database** | `GET /v2/databases` | A managed database cluster (any engine). | +| **Load Balancer** | `GET /v2/load_balancers` | A load balancer. | +| **Agent** | `GET /v2/gen-ai/agents` | A Gradient AI platform agent. | +| **Environment** | `GET /v2/agents/configs` | A Harness Runtime environment config. | +| **Agent Session** | `GET /v2/agents/sessions` | A Harness Runtime session (destroyed sessions are skipped). | +| **Trigger** | `GET /v2/agents/triggers` | A Harness Runtime cron or webhook trigger. | +| **VPC** | `GET /v2/vpcs` | A VPC network. | +| **Project** | `GET /v2/projects` | A project that groups resources. | +| **Project Resource** | `GET /v2/projects/{id}/resources` | One resource's membership of a project; links resources to their project. | + +**Relationships:** Droplets that are Kubernetes worker nodes link to their **Kubernetes Cluster**. Droplets, clusters, load balancers and databases link to their **VPC**. Each load balancer links to its first backend Droplet. Droplets, apps, clusters, databases, load balancers and agents link to the **Project** they belong to. Agent sessions link to the **Environment** they were started from, and triggers to the session they are bound to. + +## Known limitations + +- **Agent observability is partly console-only.** DigitalOcean's public API exposes agent token usage and evaluations. Agent latency, time to first token, request counts, runtime logs and traces are only available in the Control Panel. +- **Database metrics aren't included.** DigitalOcean Monitoring only offers database metrics for MySQL. The plugin reports status, engine, version and size for all engines. +- **Droplet memory, disk and load need the metrics agent.** These metrics only appear for Droplets with the [DigitalOcean metrics agent](https://docs.digitalocean.com/products/monitoring/how-to/install-metrics-agent/) installed. CPU and bandwidth work without it. +- **Bandwidth has no stated unit.** The API doesn't state a unit for Droplet bandwidth, so it's shown as a plain number. +- **Metric resolution coarsens over longer timeframes.** DigitalOcean chooses the sample interval: about 2 minutes over the last hour, falling to very few points over 7 days or more. +- **Cost covers at most 31 days.** The billing insights API caps each request at 31 days, so the **Cost** stream offers timeframes up to last 30 days or one calendar month. +- **No currency is stated for balance.** Invoices and cost are in USD; balance values are shown as plain numbers because the API names no currency. +- **Load balancers link to one backend Droplet.** Relationships match single values, so a load balancer with several backend Droplets is linked to the first one only. The **Backend Droplets** count shows the full number. +- **Relationships appear after an import.** They are worked out after each import finishes. On a newly added data source, project memberships are imported from the second import onwards (by default 12 hours later). +- **Some project resources aren't imported.** Spaces, volumes, snapshots and reserved IPs appear in a project's resource list but aren't imported as objects, so they don't link to anything. +- **Harness Runtime lists stop at 200.** Environments, agent sessions, triggers and each trigger's executions return the first 200 items, because the API's paging can't be followed to the end. +- **Signals needs collection switched on.** Conversation Signals and Session Dialogues only return data for environments where Signals collection is enabled in DigitalOcean. +- **Rate limits.** DigitalOcean allows 5,000 requests per hour and 250 per minute per token. Very large estates with many busy dashboards may be throttled. +- **Read-only.** The plugin never creates, modifies or deletes anything in DigitalOcean. diff --git a/plugins/DigitalOcean/v1/icon.svg b/plugins/DigitalOcean/v1/icon.svg new file mode 100644 index 00000000..50febf8a --- /dev/null +++ b/plugins/DigitalOcean/v1/icon.svg @@ -0,0 +1 @@ + diff --git a/plugins/DigitalOcean/v1/indexDefinitions/default.json b/plugins/DigitalOcean/v1/indexDefinitions/default.json new file mode 100644 index 00000000..4b473c97 --- /dev/null +++ b/plugins/DigitalOcean/v1/indexDefinitions/default.json @@ -0,0 +1,332 @@ +{ + "steps": [ + { + "name": "account", + "dataStream": { + "name": "account" + }, + "timeframe": "none", + "objectMapping": { + "id": "team.uuid", + "name": "team.name", + "type": { + "value": "Account" + }, + "properties": [ + { + "accountStatus": "status" + }, + { + "dropletLimit": "droplet_limit" + } + ] + } + }, + { + "name": "droplets", + "dataStream": { + "name": "droplets" + }, + "timeframe": "none", + "objectMapping": { + "id": "id", + "name": "name", + "type": { + "value": "Droplet" + }, + "properties": [ + "status", + "region", + "sizeSlug", + "vcpus", + "memory", + "disk", + "image", + "publicIp", + "privateIp", + "vpcUuid", + "tagList", + "createdAt", + "kubernetesClusterId" + ] + } + }, + { + "name": "apps", + "dataStream": { + "name": "apps" + }, + "timeframe": "none", + "objectMapping": { + "id": "id", + "name": "name", + "type": { + "value": "App" + }, + "properties": [ + "region", + "tier", + "liveUrl", + "defaultIngress", + "activeDeploymentPhase", + "lastDeploymentAt", + "projectId", + "createdAt" + ] + } + }, + { + "name": "kubernetesClusters", + "dataStream": { + "name": "kubernetesClusters" + }, + "timeframe": "none", + "objectMapping": { + "id": "id", + "name": "name", + "type": { + "value": "Kubernetes Cluster" + }, + "properties": [ + "status", + "region", + "version", + "nodePools", + "nodes", + "ha", + "autoUpgrade", + "vpcUuid", + "tagList", + "createdAt" + ] + } + }, + { + "name": "databases", + "dataStream": { + "name": "databases" + }, + "timeframe": "none", + "objectMapping": { + "id": "id", + "name": "name", + "type": { + "value": "Database" + }, + "properties": [ + "engine", + "version", + "status", + "region", + "size", + "numNodes", + "projectId", + "tagList", + "createdAt", + "vpcUuid" + ] + } + }, + { + "name": "loadBalancers", + "dataStream": { + "name": "loadBalancers" + }, + "timeframe": "none", + "objectMapping": { + "id": "id", + "name": "name", + "type": { + "value": "Load Balancer" + }, + "properties": [ + "status", + "ip", + "region", + "type", + "network", + "size", + "backendDroplets", + "vpcUuid", + "createdAt", + "primaryBackendDropletId" + ] + } + }, + { + "name": "agents", + "dataStream": { + "name": "agents" + }, + "timeframe": "none", + "objectMapping": { + "id": "id", + "name": "name", + "type": { + "value": "Agent" + }, + "properties": [ + "deploymentStatus", + "model", + "region", + "visibility", + "url", + "projectId", + "tagList", + "createdAt" + ] + }, + "optional": true + }, + { + "name": "vpcs", + "dataStream": { + "name": "vpcs" + }, + "timeframe": "none", + "objectMapping": { + "id": "id", + "name": "name", + "type": { + "value": "VPC" + }, + "properties": [ + "region", + { + "ipRange": "ip_range" + }, + { + "isDefault": "default" + }, + "description", + { + "createdAt": "created_at" + } + ] + } + }, + { + "name": "projects", + "dataStream": { + "name": "projects" + }, + "timeframe": "none", + "objectMapping": { + "id": "id", + "name": "name", + "type": { + "value": "Project" + }, + "properties": [ + "purpose", + "environment", + { + "isDefault": "is_default" + }, + "description", + { + "createdAt": "created_at" + } + ] + } + }, + { + "name": "projectResources", + "dataStream": { + "name": "projectResources" + }, + "scope": { + "query": "g.V().has(\"sourceType\", \"Project\")" + }, + "timeframe": "none", + "objectMapping": { + "id": "id", + "name": "name", + "type": { + "value": "Project Resource" + }, + "properties": [ + "projectId", + "resourceType", + "resourceId", + { + "assignedAt": "assignedAt" + } + ] + }, + "optional": true, + "dependsOn": [ + "projects" + ] + }, + { + "name": "environments", + "dataStream": { + "name": "environments" + }, + "timeframe": "none", + "objectMapping": { + "id": "id", + "name": "name", + "type": { + "value": "Environment" + }, + "properties": [ + { + "specVersion": "agentspec_schema_version" + }, + { + "createdAt": "created_at" + } + ] + }, + "optional": true + }, + { + "name": "agentSessions", + "dataStream": { + "name": "agentSessions" + }, + "timeframe": "none", + "objectMapping": { + "id": "id", + "name": "name", + "type": { + "value": "Agent Session" + }, + "properties": [ + "status", + "agentKind", + "configId", + "parentSessionId", + "createdAt" + ] + }, + "optional": true + }, + { + "name": "triggers", + "dataStream": { + "name": "triggers" + }, + "timeframe": "none", + "objectMapping": { + "id": "id", + "name": "name", + "type": { + "value": "Trigger" + }, + "properties": [ + "kind", + "status", + "schedule", + "timezone", + "sessionMode", + "boundSessionId", + "createdAt" + ] + }, + "optional": true + } + ] +} diff --git a/plugins/DigitalOcean/v1/metadata.json b/plugins/DigitalOcean/v1/metadata.json new file mode 100644 index 00000000..174fd72a --- /dev/null +++ b/plugins/DigitalOcean/v1/metadata.json @@ -0,0 +1,86 @@ +{ + "name": "digitalocean", + "displayName": "DigitalOcean", + "version": "1.0.0", + "author": { + "name": "@clarkd", + "type": "community" + }, + "description": "Monitor your DigitalOcean Droplets, apps, Kubernetes clusters, databases, load balancers, AI agents and spend.", + "category": "Cloud Platforms", + "type": "hybrid", + "schemaVersion": "2.1", + "importNotSupported": false, + "restrictedToPlatforms": [], + "keywords": [ + "digitalocean", + "droplets", + "kubernetes", + "app platform", + "databases", + "load balancers", + "gradient ai", + "agents", + "billing", + "cloud", + "vpc", + "projects", + "harness runtime", + "signals" + ], + "objectTypes": [ + "Account", + "Droplet", + "App", + "Kubernetes Cluster", + "Database", + "Load Balancer", + "Agent", + "VPC", + "Project", + "Project Resource", + "Environment", + "Agent Session", + "Trigger" + ], + "links": [ + { + "category": "documentation", + "url": "https://github.com/squaredup/plugins/blob/main/plugins/DigitalOcean/v1/docs/README.md", + "label": "Help adding this plugin" + }, + { + "category": "source", + "url": "https://github.com/squaredup/plugins/tree/main/plugins/DigitalOcean", + "label": "Repository" + } + ], + "base": { + "plugin": "WebAPI", + "majorVersion": "1", + "config": { + "baseUrl": "https://api.digitalocean.com", + "authMode": "none", + "headers": [ + { + "key": "Authorization", + "value": "Bearer {{accessToken}}" + } + ] + } + }, + "screenshots": [ + "https://github.com/squaredup/plugins/blob/main/plugins/DigitalOcean/v1/screenshots/overview.png", + "https://github.com/squaredup/plugins/blob/main/plugins/DigitalOcean/v1/screenshots/billing.png", + "https://github.com/squaredup/plugins/blob/main/plugins/DigitalOcean/v1/screenshots/project.png", + "https://github.com/squaredup/plugins/blob/main/plugins/DigitalOcean/v1/screenshots/droplet.png", + "https://github.com/squaredup/plugins/blob/main/plugins/DigitalOcean/v1/screenshots/app.png", + "https://github.com/squaredup/plugins/blob/main/plugins/DigitalOcean/v1/screenshots/kubernetes-cluster.png", + "https://github.com/squaredup/plugins/blob/main/plugins/DigitalOcean/v1/screenshots/load-balancer.png", + "https://github.com/squaredup/plugins/blob/main/plugins/DigitalOcean/v1/screenshots/vpc.png", + "https://github.com/squaredup/plugins/blob/main/plugins/DigitalOcean/v1/screenshots/database.png", + "https://github.com/squaredup/plugins/blob/main/plugins/DigitalOcean/v1/screenshots/harness-overview.png", + "https://github.com/squaredup/plugins/blob/main/plugins/DigitalOcean/v1/screenshots/environment.png", + "https://github.com/squaredup/plugins/blob/main/plugins/DigitalOcean/v1/screenshots/agent-session.png" + ] +} diff --git a/plugins/DigitalOcean/v1/screenshots/agent-session.png b/plugins/DigitalOcean/v1/screenshots/agent-session.png new file mode 100644 index 00000000..a5f10118 Binary files /dev/null and b/plugins/DigitalOcean/v1/screenshots/agent-session.png differ diff --git a/plugins/DigitalOcean/v1/screenshots/app.png b/plugins/DigitalOcean/v1/screenshots/app.png new file mode 100644 index 00000000..e2349885 Binary files /dev/null and b/plugins/DigitalOcean/v1/screenshots/app.png differ diff --git a/plugins/DigitalOcean/v1/screenshots/billing.png b/plugins/DigitalOcean/v1/screenshots/billing.png new file mode 100644 index 00000000..4e31b073 Binary files /dev/null and b/plugins/DigitalOcean/v1/screenshots/billing.png differ diff --git a/plugins/DigitalOcean/v1/screenshots/database.png b/plugins/DigitalOcean/v1/screenshots/database.png new file mode 100644 index 00000000..7fa5804a Binary files /dev/null and b/plugins/DigitalOcean/v1/screenshots/database.png differ diff --git a/plugins/DigitalOcean/v1/screenshots/droplet.png b/plugins/DigitalOcean/v1/screenshots/droplet.png new file mode 100644 index 00000000..192ca0ef Binary files /dev/null and b/plugins/DigitalOcean/v1/screenshots/droplet.png differ diff --git a/plugins/DigitalOcean/v1/screenshots/environment.png b/plugins/DigitalOcean/v1/screenshots/environment.png new file mode 100644 index 00000000..5d188419 Binary files /dev/null and b/plugins/DigitalOcean/v1/screenshots/environment.png differ diff --git a/plugins/DigitalOcean/v1/screenshots/harness-overview.png b/plugins/DigitalOcean/v1/screenshots/harness-overview.png new file mode 100644 index 00000000..1b59ea53 Binary files /dev/null and b/plugins/DigitalOcean/v1/screenshots/harness-overview.png differ diff --git a/plugins/DigitalOcean/v1/screenshots/kubernetes-cluster.png b/plugins/DigitalOcean/v1/screenshots/kubernetes-cluster.png new file mode 100644 index 00000000..8ba44da9 Binary files /dev/null and b/plugins/DigitalOcean/v1/screenshots/kubernetes-cluster.png differ diff --git a/plugins/DigitalOcean/v1/screenshots/load-balancer.png b/plugins/DigitalOcean/v1/screenshots/load-balancer.png new file mode 100644 index 00000000..ff16678b Binary files /dev/null and b/plugins/DigitalOcean/v1/screenshots/load-balancer.png differ diff --git a/plugins/DigitalOcean/v1/screenshots/overview.png b/plugins/DigitalOcean/v1/screenshots/overview.png new file mode 100644 index 00000000..fe3ef25b Binary files /dev/null and b/plugins/DigitalOcean/v1/screenshots/overview.png differ diff --git a/plugins/DigitalOcean/v1/screenshots/project.png b/plugins/DigitalOcean/v1/screenshots/project.png new file mode 100644 index 00000000..def782f1 Binary files /dev/null and b/plugins/DigitalOcean/v1/screenshots/project.png differ diff --git a/plugins/DigitalOcean/v1/screenshots/vpc.png b/plugins/DigitalOcean/v1/screenshots/vpc.png new file mode 100644 index 00000000..5c59ffea Binary files /dev/null and b/plugins/DigitalOcean/v1/screenshots/vpc.png differ diff --git a/plugins/DigitalOcean/v1/ui.json b/plugins/DigitalOcean/v1/ui.json new file mode 100644 index 00000000..73900b39 --- /dev/null +++ b/plugins/DigitalOcean/v1/ui.json @@ -0,0 +1,10 @@ +[ + { + "type": "password", + "name": "accessToken", + "label": "Personal access token", + "placeholder": "dop_v1_xxxxxxxxxxxxxxxx", + "help": "Generate a read-scoped token in the [DigitalOcean Control Panel](https://cloud.digitalocean.com/account/api/tokens)", + "validation": { "required": true } + } +]