Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
699e383
Add Redstor plugin (v1)
TimWheeler-SQUP Sep 1, 2026
3c1fba5
Fix Redstor review findings: dashboards, naming, security, and API ve…
TimWheeler-SQUP Sep 2, 2026
13e1e9d
Fix Redstor auth to use JWK signing and Bearer token
TimWheeler-SQUP Sep 7, 2026
e12936e
Fix Redstor data model issues found in live tenant testing
TimWheeler-SQUP Sep 8, 2026
1788c8f
Fix Redstor Edition indexing to use edition ID, not a composite key
TimWheeler-SQUP Sep 10, 2026
04eaba5
Restore Account-to-Company link and tidy up Redstor data streams
TimWheeler-SQUP Sep 11, 2026
fa973ea
Restructure Redstor backup/restore streams and fix RedAPI param usage
TimWheeler-SQUP Sep 11, 2026
98d491f
Revert Company Backups to its original form and drop redundant scripts
TimWheeler-SQUP Sep 11, 2026
372ea06
Surface error detail on account error streams and clear API detail fr…
TimWheeler-SQUP Sep 11, 2026
b0bebb0
Add companyBackupRollupSummary stream for /backups/status/summary
TimWheeler-SQUP Sep 12, 2026
961983d
Remove companyBackupRollupSummary data stream
TimWheeler-SQUP Sep 12, 2026
0e78a07
Pre-PR polish: tags, un-hide Company Subscriptions, README/ui.json wo…
TimWheeler-SQUP Sep 14, 2026
438cc73
Rebuild Redstor OOB dashboards into Overview and Account view
TimWheeler-SQUP Sep 14, 2026
e1dc7da
Merge remote-tracking branch 'origin/main' into work/tw/PLUG-2655
TimWheeler-SQUP Oct 1, 2026
3837f5a
Use title case for Redstor Account View dashboard name
TimWheeler-SQUP Oct 1, 2026
19e6aaf
Add Redstor correlation rules and update README wording
TimWheeler-SQUP Oct 6, 2026
174cb23
Update Redstor README
TimWheeler-SQUP Oct 6, 2026
d8963e0
Merge remote-tracking branch 'origin/work/tw/PLUG-2655' into work/tw/…
TimWheeler-SQUP Oct 7, 2026
029c717
Sequence Redstor product index steps with dependsOn
TimWheeler-SQUP Oct 7, 2026
f0b4937
Convert Redstor dashboards to SmartViz and add Company View
TimWheeler-SQUP Oct 7, 2026
7f03fc0
Update Redstor Company View and Overview dashboards
TimWheeler-SQUP Oct 7, 2026
38dff32
Address CodeRabbit review on Redstor plugin
TimWheeler-SQUP Oct 8, 2026
4efb924
Update plugins/Redstor/v1/dataStreams/estateConsumption.json
TimWheeler-SQUP Oct 8, 2026
66b2901
Reword Company ID description in Redstor README
TimWheeler-SQUP Oct 8, 2026
8124dc4
Fix README conflict markers left in Company ID table
TimWheeler-SQUP Oct 8, 2026
8a86123
Keep parent product on indexed Redstor Editions
TimWheeler-SQUP Oct 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ plugins/MetOffice/* @blackgrouse
plugins/Phare/* @vinbab
plugins/Postcoder/* @richbenwell
plugins/RDAP/* @richbenwell
plugins/Redstor/ @TimWheeler-SQUP
plugins/RSS/* @clarkd
plugins/Rootly/* @noorulkhan-n
plugins/SendGrid/* @richbenwell
Expand Down
18 changes: 18 additions & 0 deletions plugins/Redstor/v1/configValidation.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"steps": [
{
"displayName": "Authenticate",
"dataStream": { "name": "companyProfile" },
"required": true,
"error": "Could not authenticate with Redstor RedAPI. Check the Company ID, Client ID and Private Key.",
"success": "Connected to Redstor successfully."
},
{
"displayName": "Check customer access",
"dataStream": { "name": "companyCustomers" },
"required": false,
"error": "Authenticated, but could not list customer companies for this Partner account.",
"success": "Customer companies accessible."
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"displayName": "Company has Account",
"source": {
"types": "Account"
},
"target": {
"types": "Company"
},
"conditions": [
{
"sourceProperty": "companyId",
"operator": "equals",
"targetProperty": "companyId"
}
],
"labels": {
"forward": "belongs to",
"reverse": "has"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"displayName": "Company has customer Company",
"source": {
"types": "Company"
},
"target": {
"types": "Company"
},
"conditions": [
{
"sourceProperty": "parentCompanyId",
"operator": "equals",
"targetProperty": "companyId"
}
],
"labels": {
"forward": "is a customer of",
"reverse": "has customer"
}
}
37 changes: 37 additions & 0 deletions plugins/Redstor/v1/custom_types.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
[
{
"name": "Redstor Company",
"sourceType": "Company",
"icon": "building",
"singular": "Company",
"plural": "Companies"
},
{
"name": "Redstor Account",
"sourceType": "Account",
"icon": "cloud-arrow-up",
"singular": "Account",
"plural": "Accounts"
},
{
"name": "Redstor Product",
"sourceType": "Product",
"icon": "cube",
"singular": "Product",
"plural": "Products"
},
{
"name": "Redstor Service",
"sourceType": "Service",
"icon": "sitemap",
"singular": "Service",
"plural": "Services"
},
{
"name": "Redstor Edition",
"sourceType": "Edition",
"icon": "layer-group",
"singular": "Edition",
"plural": "Editions"
}
]
38 changes: 38 additions & 0 deletions plugins/Redstor/v1/dataStreams/accountBackupErrors.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"name": "accountBackupErrors",
"displayName": "Account Backup Errors",
"description": "Backup error and warning messages for an account",
"tags": ["Backup"],
"baseDataSourceName": "httpRequestScopedSingle",
"config": {
"httpMethod": "get",
"endpointPath": "/backups/status/accounts/errors",
"getArgs": [{ "key": "accountId", "value": "{{object.rawId}}" }],
"paging": {
"mode": "token",
"pageSize": { "realm": "queryArg", "path": "maxResults", "value": "100" },
"in": { "realm": "payload", "path": "nextPageToken" },
"out": { "realm": "queryArg", "path": "pageToken" }
},
"pathToData": "results",
"errorHandling": { "type": "script", "script": "errorHandling/accountBackupErrors.js" }
},
"matches": { "sourceType": { "type": "oneOf", "values": ["Account"] } },
"metadata": [
{ "name": "timestamp", "displayName": "Time", "shape": "date", "role": "timestamp" },
{ "name": "message", "displayName": "Message", "shape": "string", "role": "label" },
{ "name": "category", "displayName": "Category", "shape": "string" },
{ "name": "type", "displayName": "Type", "shape": "string" },
{ "name": "count", "displayName": "Count", "shape": "number" },
{ "name": "extraInfo", "displayName": "Error Message", "shape": "string" },
{ "name": "productId", "displayName": "Service ID", "shape": "number", "visible": false },
{
"name": "serviceName",
"displayName": "Service",
"sourceId": "productId",
"sourceType": "Service",
"objectPropertyPath": "name"
}
],
"timeframes": false
}
37 changes: 37 additions & 0 deletions plugins/Redstor/v1/dataStreams/accountBackups.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"name": "accountBackups",
"displayName": "Account Backups",
"description": "Backup run history for an account, over Redstor's rolling seven day window",
"tags": ["Backup"],
"baseDataSourceName": "httpRequestScopedSingle",
"config": {
"httpMethod": "get",
"endpointPath": "/backups/status/accounts",
"getArgs": [
{ "key": "companyId", "value": "{{object.companyId}}" },
{ "key": "accountId", "value": "{{object.rawId}}" }
],
"paging": {
"mode": "token",
"pageSize": { "realm": "queryArg", "path": "maxResults", "value": "100" },
"in": { "realm": "payload", "path": "nextPageToken" },
"out": { "realm": "queryArg", "path": "pageToken" }
},
"postRequestScript": "accountBackups.js"
},
"matches": { "sourceType": { "type": "oneOf", "values": ["Account"] } },
"metadata": [
{ "name": "timestamp", "displayName": "Time", "shape": "date", "role": "timestamp" },
{
"name": "overallStatus",
"displayName": "Status",
"computed": true,
"valueExpression": "{{ $['status'] === 1 ? 'success' : ($['status'] === 2 ? 'warning' : 'error') }}",
"shape": "state"
},
{ "name": "status", "displayName": "Status Code", "shape": "number", "visible": false },
{ "name": "message", "displayName": "Message", "shape": "string", "role": "label" },
{ "name": "errorCount", "displayName": "Error Count", "shape": "number" }
],
"timeframes": false
}
38 changes: 38 additions & 0 deletions plugins/Redstor/v1/dataStreams/accountRestoreErrors.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"name": "accountRestoreErrors",
"displayName": "Account Restore Errors",
"description": "Restore error and warning messages for an account",
"tags": ["Restore"],
"baseDataSourceName": "httpRequestScopedSingle",
"config": {
"httpMethod": "get",
"endpointPath": "/restores/status/accounts/errors",
"getArgs": [{ "key": "accountId", "value": "{{object.rawId}}" }],
"paging": {
"mode": "token",
"pageSize": { "realm": "queryArg", "path": "maxResults", "value": "100" },
"in": { "realm": "payload", "path": "nextPageToken" },
"out": { "realm": "queryArg", "path": "pageToken" }
},
"pathToData": "results",
"errorHandling": { "type": "script", "script": "errorHandling/accountRestoreErrors.js" }
},
"matches": { "sourceType": { "type": "oneOf", "values": ["Account"] } },
"metadata": [
{ "name": "timestamp", "displayName": "Time", "shape": "date", "role": "timestamp" },
{ "name": "message", "displayName": "Message", "shape": "string", "role": "label" },
{ "name": "category", "displayName": "Category", "shape": "string" },
{ "name": "type", "displayName": "Type", "shape": "string" },
{ "name": "count", "displayName": "Count", "shape": "number" },
{ "name": "extraInfo", "displayName": "Error Message", "shape": "string" },
{ "name": "productId", "displayName": "Service ID", "shape": "number", "visible": false },
{
"name": "serviceName",
"displayName": "Service",
"sourceId": "productId",
"sourceType": "Service",
"objectPropertyPath": "name"
}
],
"timeframes": false
}
45 changes: 45 additions & 0 deletions plugins/Redstor/v1/dataStreams/accountRestores.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"name": "accountRestores",
"displayName": "Account Restores",
"description": "Current restore operation status for an account",
"tags": ["Restore"],
"baseDataSourceName": "httpRequestScopedSingle",
"config": {
"httpMethod": "get",
"endpointPath": "/restores/status/accounts",
"getArgs": [
{ "key": "companyId", "value": "{{object.companyId}}" },
{ "key": "accountId", "value": "{{object.rawId}}" }
],
"paging": {
"mode": "token",
"pageSize": { "realm": "queryArg", "path": "maxResults", "value": "100" },
"in": { "realm": "payload", "path": "nextPageToken" },
"out": { "realm": "queryArg", "path": "pageToken" }
},
"pathToData": "results"
},
"matches": { "sourceType": { "type": "oneOf", "values": ["Account"] } },
"metadata": [
{ "name": "timestamp", "displayName": "Time", "shape": "date", "role": "timestamp" },
{
"name": "status",
"displayName": "Status",
"valueExpression": "{{ ({ 0: 'Failed', 1: 'Completed successfully', 2: 'Completed with warnings', 3: 'Completed with errors' })[$['status']] ?? $['status'] }}",
Comment thread
TimWheeler-SQUP marked this conversation as resolved.
"shape": [
"state",
{
"map": {
"success": ["Completed successfully"],
"warning": ["Completed with warnings"],
"error": ["Completed with errors", "Failed"]
}
}
]
},
{ "name": "accountName", "displayName": "Account", "shape": "string", "visible": false },
{ "name": "accountId", "displayName": "Account ID", "shape": "guid", "visible": false },
{ "name": "productId", "displayName": "Service ID", "shape": "number", "visible": false }
],
"timeframes": false
}
33 changes: 33 additions & 0 deletions plugins/Redstor/v1/dataStreams/backupAccounts.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"name": "backupAccounts",
"displayName": "Company Accounts",
"description": "Backup accounts for a company (one row per account, and a single seat can hold more than one)",
"tags": ["Accounts"],
"baseDataSourceName": "httpRequestScopedSingle",
"config": {
"httpMethod": "get",
"endpointPath": "/storage/accounts",
"getArgs": [{ "key": "companyId", "value": "{{object.rawId}}" }],
"paging": {
"mode": "token",
"pageSize": { "realm": "queryArg", "path": "maxResults", "value": "100" },
"in": { "realm": "payload", "path": "nextPageToken" },
"out": { "realm": "queryArg", "path": "pageToken" }
},
"postRequestScript": "backupAccounts.js"
},
"matches": { "sourceType": { "type": "oneOf", "values": ["Company"] } },
"metadata": [
{ "name": "accountId", "displayName": "Account ID", "shape": "guid", "visible": false },
{ "name": "accountName", "displayName": "Account Name", "shape": "string", "role": "label" },
{ "name": "displayName", "displayName": "Display Name", "shape": "string" },
{ "name": "serviceId", "displayName": "Service ID", "shape": "number", "visible": false },
{ "name": "serviceName", "displayName": "Service", "shape": "string" },
{ "name": "productId", "displayName": "Product ID", "shape": "number", "visible": false },
{ "name": "productName", "displayName": "Product", "shape": "string" },
{ "name": "storageRegion", "displayName": "Storage Region", "shape": "string" },
{ "name": "createOn", "displayName": "Created On", "shape": "date" },
{ "name": "companyId", "displayName": "Company ID", "shape": "guid", "visible": false }
],
"timeframes": false
}
37 changes: 37 additions & 0 deletions plugins/Redstor/v1/dataStreams/companyBackupSummary.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"name": "companyBackupSummary",
"displayName": "Company Backup Summary",
"description": "Current backup operation status by product for a company",
"tags": ["Backup"],
"baseDataSourceName": "httpRequestScopedSingle",
"config": {
"httpMethod": "get",
"endpointPath": "/backups/status",
"getArgs": [{ "key": "companyId", "value": "{{object.rawId}}" }],
"paging": {
"mode": "token",
"pageSize": { "realm": "queryArg", "path": "maxResults", "value": "100" },
"in": { "realm": "payload", "path": "nextPageToken" },
"out": { "realm": "queryArg", "path": "pageToken" }
},
"pathToData": "results"
},
"matches": { "sourceType": { "type": "oneOf", "values": ["Company"] } },
"metadata": [
{ "name": "productName", "displayName": "Product", "shape": "string", "role": "label" },
{ "name": "succeeded", "displayName": "Succeeded", "shape": "number" },
{ "name": "completedWithWarnings", "displayName": "Completed with Warnings", "shape": "number" },
{ "name": "completedWithErrors", "displayName": "Completed with Errors", "shape": "number" },
{ "name": "failed", "displayName": "Failed", "shape": "number" },
{ "name": "missed", "displayName": "Missed", "shape": "number" },
{
"name": "overallStatus",
"displayName": "Status",
"computed": true,
"valueExpression": "{{ $['failed'] > 0 ? 'error' : (($['completedWithErrors'] > 0 || $['missed'] > 0) ? 'warning' : 'success') }}",
"shape": "state"
},
{ "name": "productId", "displayName": "Product ID", "shape": "number", "visible": false }
],
"timeframes": false
}
35 changes: 35 additions & 0 deletions plugins/Redstor/v1/dataStreams/companyBackups.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"name": "companyBackups",
"displayName": "Company Backups",
"description": "Recent backup operation status history per account for a company",
"tags": ["Backup"],
"baseDataSourceName": "httpRequestScopedSingle",
"config": {
"httpMethod": "get",
"endpointPath": "/backups/status/accounts",
"getArgs": [{ "key": "companyId", "value": "{{object.rawId}}" }],
"paging": {
"mode": "token",
"pageSize": { "realm": "queryArg", "path": "maxResults", "value": "100" },
"in": { "realm": "payload", "path": "nextPageToken" },
"out": { "realm": "queryArg", "path": "pageToken" }
},
"postRequestScript": "companyBackups.js"
},
"matches": { "sourceType": { "type": "oneOf", "values": ["Company"] } },
"metadata": [
{ "name": "accountName", "displayName": "Account", "shape": "string", "role": "label" },
{ "name": "timestamp", "displayName": "Time", "shape": "date", "role": "timestamp" },
{
"name": "status",
"displayName": "Status Code",
"shape": "number",
"help": "0 = Failed, 1 = Completed successfully, 2 = Completed with warnings, 3 = Completed with errors"
},
{ "name": "message", "displayName": "Message", "shape": "string" },
{ "name": "errorCount", "displayName": "Error Count", "shape": "number" },
{ "name": "productId", "displayName": "Product ID", "shape": "number", "visible": false },
{ "name": "accountId", "displayName": "Account ID", "shape": "guid", "visible": false }
],
"timeframes": false
}
Loading
Loading