-
Notifications
You must be signed in to change notification settings - Fork 7
Add N-Central plugin #115
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Add N-Central plugin #115
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| { | ||
| "steps": [ | ||
| { | ||
| "displayName": "Authenticate", | ||
| "dataStream": { "name": "serverInfoAuthenticated" }, | ||
| "required": true, | ||
| "error": "Could not authenticate with N-central. Check the Base URL and User-API Token are correct and that the token hasn't expired.", | ||
| "success": "Connected successfully." | ||
| } | ||
| ] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| [ | ||
| { | ||
| "name": "N-central Service Organization", | ||
| "sourceType": "N-central Service Organization", | ||
| "icon": "building", | ||
| "singular": "Service Organization", | ||
| "plural": "Service Organizations" | ||
| }, | ||
| { | ||
| "name": "N-central Customer", | ||
| "sourceType": "N-central Customer", | ||
| "icon": "briefcase", | ||
| "singular": "Customer", | ||
| "plural": "Customers" | ||
| }, | ||
| { | ||
| "name": "N-central Site", | ||
| "sourceType": "N-central Site", | ||
| "icon": "location-dot", | ||
| "singular": "Site", | ||
| "plural": "Sites" | ||
| }, | ||
| { | ||
| "name": "N-central Device", | ||
| "sourceType": "N-central Device", | ||
| "icon": "microchip", | ||
| "singular": "Device", | ||
| "plural": "Devices" | ||
| } | ||
| ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| { | ||
| "name": "customerActiveIssues", | ||
| "displayName": "Customer Active Issues", | ||
| "description": "Currently active issues and alerts for a customer", | ||
| "tags": ["Customer", "Alerts"], | ||
| "baseDataSourceName": "httpRequestScopedSingle", | ||
| "config": { | ||
| "httpMethod": "get", | ||
| "endpointPath": "api/org-units/{{object.rawId}}/active-issues", | ||
| "pathToData": "data", | ||
| "expandInnerObjects": true, | ||
| "paging": { | ||
| "mode": "offset", | ||
| "pageSize": { "realm": "queryArg", "path": "pageSize", "value": "200" }, | ||
| "offset": { | ||
| "mode": "page", | ||
| "rowCountIn": { "realm": "payloadArraySize", "path": "data" }, | ||
| "base": 1 | ||
| }, | ||
| "out": { "realm": "queryArg", "path": "pageNumber" } | ||
| } | ||
| }, | ||
| "matches": { "sourceType": { "type": "oneOf", "values": ["N-central Customer"] } }, | ||
| "metadata": [ | ||
| { "name": "orgUnitId", "shape": "number", "visible": false }, | ||
| { "name": "deviceId", "shape": "number", "visible": false }, | ||
| { | ||
| "name": "_extra.deviceName", | ||
| "displayName": "Device", | ||
| "shape": "string", | ||
| "role": "label", | ||
| "sourceId": "deviceId", | ||
| "sourceType": "N-central Device" | ||
| }, | ||
| { "name": "serviceName", "displayName": "Service", "shape": "string" }, | ||
| { "name": "serviceType", "displayName": "Service Type", "shape": "string" }, | ||
| { "name": "notificationState", "displayName": "Notification State", "shape": "number" }, | ||
| { | ||
| "name": "_extra.transitionTime", | ||
| "displayName": "Since", | ||
| "shape": "date", | ||
| "role": "timestamp" | ||
| }, | ||
| { "name": "_extra.licenseMode", "displayName": "License Mode", "shape": "string" }, | ||
| { | ||
| "name": "_extra.remoteControllable", | ||
| "displayName": "Remote Controllable", | ||
| "shape": "boolean" | ||
| }, | ||
| { "name": "serviceId", "shape": "number", "visible": false }, | ||
| { "name": "taskId", "shape": "number", "visible": false }, | ||
| { "name": "serviceItemId", "shape": "number", "visible": false }, | ||
| { "name": "_extra.customerTree.0", "shape": "string", "visible": false }, | ||
| { "name": "_extra.customerTree.1", "shape": "string", "visible": false }, | ||
| { "name": "_extra.customerTree.2", "shape": "string", "visible": false } | ||
|
Comment on lines
+53
to
+55
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Description: Check how other plugins declare pattern-based hidden metadata entries.
rg -n --glob 'plugins/**/dataStreams/*.json' '"pattern"' -B2 -A2 | head -60Repository: squaredup/plugins Length of output: 155 🏁 Script executed: #!/bin/bash
set -e
printf '%s\n' '--- target stream ---'
cat -n plugins/N-Central/v1/dataStreams/customerActiveIssues.json
printf '%s\n' '--- customerTree references ---'
rg -n '"customerTree"|customerActiveIssues|"_extra\\.' plugins/N-Central plugins --glob '*.json' | head -120
printf '%s\n' '--- pattern support and schema references ---'
rg -n '"pattern"|pattern.*shape|shape.*pattern|visible.*false' . --glob '*.json' --glob '*.md' --glob '*.ts' --glob '*.js' | head -160Repository: squaredup/plugins Length of output: 23600 🏁 Script executed: #!/bin/bash
set -e
printf '%s\n' '--- comparable metadata patterns ---'
for f in \
plugins/NinjaOne/v1/dataStreams/organizationLocations.json \
plugins/NinjaOne/v1/dataStreams/organizations.json \
plugins/N-Central/v1/dataStreams/*.json \
plugins/UniFi/v1/dataStreams/deviceInfo.json \
plugins/NASA/v1/dataStreams/neoCloseApproaches.json
do
[ -f "$f" ] || continue
echo "### $f"
rg -n -B8 -A8 '"pattern"' "$f"
done
printf '%s\n' '--- metadata schema/documentation ---'
rg -n -i 'metadata.*pattern|pattern.*metadata|data stream.*metadata|unmapped column|expandInnerObjects' . \
--glob '*.md' --glob '*.json' --glob '*.yaml' --glob '*.yml' --glob '*.ts' --glob '*.js' | head -200
printf '%s\n' '--- all N-Central data stream metadata tails ---'
for f in plugins/N-Central/v1/dataStreams/*.json; do
echo "### $f"
tail -40 "$f"
doneRepository: squaredup/plugins Length of output: 955 🏁 Script executed: #!/bin/bash
printf '%s\n' '--- comparable metadata patterns ---'
for f in \
plugins/NinjaOne/v1/dataStreams/organizationLocations.json \
plugins/NinjaOne/v1/dataStreams/organizations.json \
plugins/UniFi/v1/dataStreams/deviceInfo.json \
plugins/NASA/v1/dataStreams/neoCloseApproaches.json
do
[ -f "$f" ] || continue
echo "### $f"
rg -n -B10 -A5 '"pattern"' "$f" || true
done
printf '%s\n' '--- metadata-related repository files and text ---'
git ls-files | rg -i 'schema|metadata|datasource|datastream|readme|contribut|valid'
rg -n -i 'metadata.*pattern|pattern.*metadata|unmapped column|expandInnerObjects' . \
--glob '*.md' --glob '*.json' --glob '*.yaml' --glob '*.yml' --glob '*.ts' --glob '*.js' \
| head -200 || true
printf '%s\n' '--- pattern metadata entries with surrounding declarations ---'
python3 - <<'PY'
import json
import subprocess
files = subprocess.check_output(
["git", "ls-files", "plugins"], text=True
).splitlines()
for path in files:
if "/dataStreams/" not in path or not path.endswith(".json"):
continue
try:
obj = json.load(open(path))
except Exception:
continue
metadata = obj.get("metadata")
if not isinstance(metadata, list):
continue
for i, entry in enumerate(metadata):
if isinstance(entry, dict) and "pattern" in entry:
print(f"{path}:{i + 1}: {json.dumps(entry, separators=(',', ':'))}")
for neighbor in metadata[max(0, i-2):i]:
print(" before", json.dumps(neighbor, separators=(',', ':')))
break
PYRepository: squaredup/plugins Length of output: 50373 🏁 Script executed: #!/bin/bash
set -e
printf '%s\n' '--- metadata reference ---'
cat -n .claude/skills/build-plugin/references/metadata.md
printf '%s\n' '--- N-Central pattern-based streams ---'
for f in \
plugins/N-Central/v1/dataStreams/customers.json \
plugins/N-Central/v1/dataStreams/devices.json \
plugins/N-Central/v1/dataStreams/serverInfoAuthenticated.json \
plugins/N-Central/v1/dataStreams/serviceOrgs.json \
plugins/N-Central/v1/dataStreams/sites.json
do
echo "### $f"
cat -n "$f"
doneRepository: squaredup/plugins Length of output: 19193 🌐 Web query:
💡 Result: In SquaredUp, the metadata configuration for a Web API data stream does not use a regex pattern to define column field names [1][2][3]. Instead, column field names are specified explicitly using the name parameter within the metadata array [2][3][4]. The metadata configuration serves to map raw data from an API response to columns that SquaredUp can interpret [2][5]. You define this by providing an array of objects, where each object corresponds to a column and includes the following key properties [2][3]: name: The exact path or key of the field in the API response (e.g., fields.summary or nested.object.value) [2][4]. To identify the correct name, it is recommended to first fetch the data without metadata to inspect the raw structure [2][3]. displayName: An optional, human-readable label for the column [2][3]. shape: A recommended property that defines the data type (e.g., string, number, date, url) [2][4]. role: An optional, recommended property that identifies the purpose of the column (e.g., value, label, timestamp, id) [2][3][4]. If your data stream returns nested objects, you must use the dot notation (e.g., fields.summary) as the name to reference the specific field [2][4]. SquaredUp does not support using regex patterns for mapping or selecting these field names dynamically within the standard metadata configuration [2][3]. If complex manipulation or dynamic field selection is required, this is typically handled via Tile Data Scripts using JavaScript, where you can process the data object before converting it to the required stream format using the api.toStreamData function [5]. Citations:
🌐 Web query:
💡 Result: In the context of data streaming and architecture, a metadata pattern refers to the practice of embedding descriptive information—such as schema definitions, data types, roles, and configuration parameters—alongside the raw data payload to allow consuming systems to correctly interpret, transform, and visualize that data [1][2]. In platforms like SquaredUp, for example, this pattern is implemented by requiring or allowing users to define a metadata object that explicitly describes the structure of incoming data streams [1][3]. This ensures that downstream components know how to handle specific columns, apply correct formatting, or assign roles (e.g., identifying a field as a 'timestamp' or 'id') without needing hard-coded assumptions [1][4][2]. Key aspects of the metadata pattern in data streams include: 1. Data Interpretation: By providing metadata (often called "shapes" or "schema hints"), the system can distinguish between data types (string, number, date, URL) and roles, enabling automated UI generation or consistent processing across diverse data sources [1][4]. 2. Decoupling: This pattern decouples the raw data from its presentation layer. By centralizing metadata configuration, administrators can override or refine how data is displayed or processed without altering the underlying data source [5]. 3. Programmatic Transformation: Development environments often provide utilities to merge raw data with metadata at runtime, such as functions that convert raw API responses into standardized 'stream data' format [2][6]. 4. Contextual Information: In API integrations, metadata is also frequently used to manage streaming concerns like pagination (e.g., using response headers or body fields to identify continuation tokens) and authentication [7]. By adopting a metadata-driven approach, streaming architectures become more resilient to changes in data format and easier to integrate with dynamic visualization or monitoring tools [3][5]. Citations:
🏁 Script executed: #!/bin/bash
set -e
for url in \
'https://docs.squaredup.com/data-sources/web-api-plugin/data-stream-parameters' \
'https://docs.squaredup.com/data-sources/web-api-plugin' \
'https://docs.squaredup.com/reference/shapes'
do
echo "### $url"
curl -L --max-time 15 -sS "$url" \
| tr '<>' '\n\n' \
| rg -i -C2 'metadata|pattern|regular expression|regex' \
| head -80 || true
done
node - <<'JS'
const pattern = /^_extra\.customerTree\..*$/;
const names = [
"_extra.customerTree.0",
"_extra.customerTree.1",
"_extra.customerTree.2",
"_extra.customerTree.3",
"_extra.customerTree.10",
"_extra.customerTree",
"_extra.otherField",
];
for (const name of names) console.log(name, pattern.test(name));
JSRepository: squaredup/plugins Length of output: 50374 🏁 Script executed: #!/bin/bash
set -e
python3 - <<'PY'
import html
import re
import urllib.request
urls = [
"https://docs.squaredup.com/data-sources/web-api-plugin/data-stream-parameters",
"https://docs.squaredup.com/data-sources/web-api-plugin",
"https://docs.squaredup.com/reference/shapes",
]
for url in urls:
print(f"### {url}")
text = html.unescape(urllib.request.urlopen(url, timeout=15).read().decode("utf-8", "ignore"))
matches = list(re.finditer(r"(?i)pattern|regular expression|regex|metadata", text))
for match in matches[:20]:
start = max(0, match.start() - 180)
end = min(len(text), match.end() + 300)
snippet = re.sub(r"\s+", " ", text[start:end])
print(snippet)
PY
node - <<'JS'
const pattern = /^_extra\.customerTree\..*$/;
const names = [
"_extra.customerTree.0",
"_extra.customerTree.1",
"_extra.customerTree.2",
"_extra.customerTree.3",
"_extra.customerTree.10",
"_extra.customerTree",
"_extra.otherField",
];
for (const name of names) console.log(`${name}: ${pattern.test(name)}`);
JSRepository: squaredup/plugins Length of output: 2524 🌐 Web query:
💡 Result: To retrieve active issues in N-able N-central, you use the Active Issues Management API, which allows you to query active issues based on a specific organization unit (OU) [1]. The primary endpoint for this is: GET /api/org-units/{orgUnitId}/active-issues [1] Key Details: - Requirement: You must provide a valid orgUnitId as a path parameter [1]. The API supports customer and site organization unit types [1]. - Response Structure: The response returns a data object containing a list of active issues [1]. Each issue object includes standard fields such as deviceId, serviceId, serviceName, and notificationState [1][2]. - Customer Tree: Within the response, each active issue object includes an _extra field which contains a customerTree property [1][3]. This property is an array providing the hierarchical path of the organization, for example: ["System", "Service_Organization", "Customer Name"] [1][3]. Known Limitations: - The API requires a specific orgUnitId and cannot query across all customers or the entire organizational hierarchy in a single request [1][2]. - There is a documented known issue where specific fields in the _extra object (deviceClassValue and deviceClassLabel) return as null [4]. For implementation, ensure your request includes an Authorization header with a valid Bearer token obtained via the authentication API [1][5]. Optional query parameters include pageNumber, pageSize, sortBy, and sortOrder to manage the retrieved results [1]. Citations:
🏁 Script executed: #!/bin/bash
python3 - <<'PY'
import json
import subprocess
paths = subprocess.check_output(["git", "ls-files", "plugins"], text=True).splitlines()
for path in paths:
if "/dataStreams/" not in path or not path.endswith(".json"):
continue
try:
data = json.load(open(path))
except Exception:
continue
for entry in data.get("metadata", []):
if isinstance(entry, dict) and "pattern" in entry:
print(path, sorted(entry))
PYRepository: squaredup/plugins Length of output: 10100 🏁 Script executed: #!/bin/bash
set -e
for f in \
plugins/AutoTask/v1/dataStreams/tickets.json \
plugins/DattoRMM/v1/dataStreams/dattoAllDevices.json
do
echo "### $f"
cat -n "$f" | tail -45
doneRepository: squaredup/plugins Length of output: 4470 Replace the fixed Set the pattern to 🤖 Prompt for AI Agents |
||
| ], | ||
| "timeframes": false | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| { | ||
| "name": "customers", | ||
| "displayName": "Customers", | ||
| "description": "Customers, one row per customer", | ||
| "tags": ["Organization"], | ||
| "baseDataSourceName": "httpRequestUnscoped", | ||
| "config": { | ||
| "httpMethod": "get", | ||
| "endpointPath": "api/customers", | ||
| "pathToData": "data", | ||
| "paging": { | ||
| "mode": "offset", | ||
| "pageSize": { "realm": "queryArg", "path": "pageSize", "value": "200" }, | ||
| "offset": { | ||
| "mode": "page", | ||
| "rowCountIn": { "realm": "payloadArraySize", "path": "data" }, | ||
| "base": 1 | ||
| }, | ||
| "out": { "realm": "queryArg", "path": "pageNumber" } | ||
| } | ||
| }, | ||
| "matches": "none", | ||
| "metadata": [{ "pattern": ".*" }], | ||
| "timeframes": false, | ||
| "visibility": { "type": "hidden" } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| { | ||
| "name": "deviceAssets", | ||
| "displayName": "Device Assets", | ||
| "description": "Hardware and software inventory for a device", | ||
| "tags": ["Device", "Inventory"], | ||
| "baseDataSourceName": "httpRequestScopedSingle", | ||
| "config": { | ||
| "httpMethod": "get", | ||
| "endpointPath": "api/devices/{{object.rawId}}/assets", | ||
| "postRequestScript": "deviceAssets.js" | ||
| }, | ||
| "matches": { "sourceType": { "type": "oneOf", "values": ["N-central Device"] } }, | ||
| "metadata": [ | ||
| { "name": "category", "displayName": "Category", "shape": "string" }, | ||
| { "name": "name", "displayName": "Name", "shape": "string", "role": "label" }, | ||
| { "name": "id", "displayName": "ID", "shape": "string", "role": "id", "visible": false }, | ||
| { "pattern": ".*" } | ||
| ], | ||
| "timeframes": false | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| { | ||
| "name": "deviceLifecycleInfo", | ||
| "displayName": "Device Lifecycle Info", | ||
| "description": "Warranty, lease, and hardware replacement details for a device", | ||
| "tags": ["Device", "Inventory"], | ||
| "baseDataSourceName": "httpRequestScopedSingle", | ||
| "config": { | ||
| "httpMethod": "get", | ||
| "endpointPath": "api/devices/{{object.rawId}}/assets/lifecycle-info" | ||
| }, | ||
| "matches": { "sourceType": { "type": "oneOf", "values": ["N-central Device"] } }, | ||
| "metadata": [ | ||
| { "name": "warrantyExpiryDate", "displayName": "Warranty Expiry Date", "shape": "date" }, | ||
| { "name": "leaseExpiryDate", "displayName": "Lease Expiry Date", "shape": "date" }, | ||
| { "name": "expectedReplacementDate", "displayName": "Expected Replacement Date", "shape": "date" }, | ||
| { "name": "purchaseDate", "displayName": "Purchase Date", "shape": "date" }, | ||
| { "name": "cost", "displayName": "Cost", "shape": ["number", { "decimalPlaces": 2 }] }, | ||
| { "name": "location", "displayName": "Location", "shape": "string" }, | ||
| { "name": "assetTag", "displayName": "Asset Tag", "shape": "string" }, | ||
| { "name": "description", "displayName": "Description", "shape": "string" }, | ||
| { "name": "updateWarrantyError", "displayName": "Update Warranty Error", "shape": "string" }, | ||
| { "pattern": ".*" } | ||
| ], | ||
| "timeframes": false | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| { | ||
| "name": "deviceList", | ||
| "displayName": "Devices", | ||
| "description": "Managed devices, optionally filtered to a customer or site, one row per device", | ||
| "tags": ["Customer", "Site", "Device"], | ||
| "baseDataSourceName": "httpRequestUnscoped", | ||
| "config": { | ||
| "httpMethod": "get", | ||
| "endpointPath": "{{ (typeof orgUnit !== 'undefined' && orgUnit && orgUnit.length) ? 'api/org-units/' + (Array.isArray(orgUnit[0].rawId) ? orgUnit[0].rawId[0] : orgUnit[0].rawId) + '/devices' : 'api/devices' }}", | ||
| "pathToData": "data", | ||
| "paging": { | ||
| "mode": "offset", | ||
| "pageSize": { "realm": "queryArg", "path": "pageSize", "value": "100" }, | ||
| "offset": { | ||
| "mode": "page", | ||
| "rowCountIn": { "realm": "payloadArraySize", "path": "data" }, | ||
| "base": 1 | ||
| }, | ||
| "out": { "realm": "queryArg", "path": "pageNumber" } | ||
| } | ||
| }, | ||
| "matches": "none", | ||
| "ui": [ | ||
| { | ||
| "type": "objects", | ||
| "name": "orgUnit", | ||
| "label": "Customer or Site (optional)", | ||
| "objectLimit": 1, | ||
| "matches": { | ||
| "sourceType": { "type": "oneOf", "values": ["N-central Customer", "N-central Site"] } | ||
| } | ||
| } | ||
| ], | ||
| "metadata": [ | ||
| { | ||
| "name": "longName", | ||
| "displayName": "Device", | ||
| "shape": "string", | ||
| "role": "label", | ||
| "sourceId": "deviceId", | ||
| "sourceType": "N-central Device" | ||
| }, | ||
| { "name": "deviceId", "shape": "number", "visible": false }, | ||
| { "name": "deviceClass", "displayName": "Device Class", "shape": "string" }, | ||
| { "name": "supportedOs", "displayName": "OS", "shape": "string" }, | ||
| { "name": "isProbe", "displayName": "Probe", "shape": "boolean" }, | ||
| { "name": "licenseMode", "displayName": "License Mode", "shape": "string" }, | ||
| { "name": "customerId", "shape": "number", "visible": false }, | ||
| { "name": "siteId", "shape": "number", "visible": false }, | ||
| { "pattern": ".*" } | ||
| ], | ||
| "timeframes": false | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| { | ||
| "name": "deviceServiceMonitorStatus", | ||
| "displayName": "Device Service Monitor Status", | ||
| "description": "Current service monitor health status for a device", | ||
| "tags": ["Device", "Monitoring"], | ||
| "baseDataSourceName": "httpRequestScopedSingle", | ||
| "config": { | ||
| "httpMethod": "get", | ||
| "endpointPath": "api/devices/{{object.rawId}}/service-monitor-status", | ||
| "pathToData": "data" | ||
| }, | ||
| "matches": { "sourceType": { "type": "oneOf", "values": ["N-central Device"] } }, | ||
| "metadata": [ | ||
| { "name": "moduleName", "displayName": "Service", "shape": "string", "role": "label" }, | ||
| { "name": "taskIdent", "displayName": "Instance", "shape": "string" }, | ||
| { | ||
| "name": "stateStatus", | ||
| "displayName": "Status", | ||
| "shape": [ | ||
| "state", | ||
| { | ||
| "map": { | ||
| "success": ["Normal"], | ||
| "warning": ["Misconfigured", "Stale", "Warning"], | ||
| "error": ["Failed"], | ||
| "unmonitored": ["Disabled", "Unmanaged"] | ||
| } | ||
| } | ||
| ] | ||
| }, | ||
| { "name": "taskNote", "displayName": "Template", "shape": "string" }, | ||
| { | ||
| "name": "lastScanTime", | ||
| "displayName": "Last Scan", | ||
| "shape": ["date", { "inputPattern": "yyyy-MM-dd HH:mm:ss.SSS xx" }] | ||
| }, | ||
| { | ||
| "name": "transitionTime", | ||
| "displayName": "Status Changed", | ||
| "shape": ["date", { "inputPattern": "yyyy-MM-dd HH:mm:ss.SSS xx" }] | ||
| }, | ||
| { "name": "timeToStale", "displayName": "Time to Stale (s)", "shape": "seconds" }, | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| { "name": "applianceName", "displayName": "Probe", "shape": "string" }, | ||
| { "name": "isManagedTask", "displayName": "Managed", "shape": "boolean" }, | ||
| { "name": "taskId", "displayName": "Task ID", "shape": "number", "role": "id", "visible": false }, | ||
| { "name": "serviceId", "displayName": "Service ID", "shape": "number", "visible": false }, | ||
| { "name": "serviceItemId", "displayName": "Service Item ID", "shape": "number", "visible": false }, | ||
| { "name": "applianceId", "displayName": "Appliance ID", "shape": "string", "visible": false } | ||
| ], | ||
| "timeframes": false | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| { | ||
| "name": "devices", | ||
| "displayName": "Devices", | ||
| "description": "Managed devices, one row per device", | ||
| "tags": ["Device"], | ||
| "baseDataSourceName": "httpRequestUnscoped", | ||
| "config": { | ||
| "httpMethod": "get", | ||
| "endpointPath": "api/devices", | ||
| "pathToData": "data", | ||
| "paging": { | ||
| "mode": "offset", | ||
| "pageSize": { "realm": "queryArg", "path": "pageSize", "value": "100" }, | ||
| "offset": { | ||
| "mode": "page", | ||
| "rowCountIn": { "realm": "payloadArraySize", "path": "data" }, | ||
| "base": 1 | ||
| }, | ||
| "out": { "realm": "queryArg", "path": "pageNumber" } | ||
| } | ||
| }, | ||
| "matches": "none", | ||
| "metadata": [{ "pattern": ".*" }], | ||
| "timeframes": false, | ||
| "visibility": { "type": "hidden" } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🌐 Web query:
N-able N-central REST API org-units active-issues notificationState values💡 Result:
In the N-able N-central REST API, the notificationState field returned by the GET /api/org-units/{orgUnitId}/active-issues endpoint is represented by an integer value [1][2]. While official API documentation for N-central often displays these as integer codes (e.g., 5 in examples) [1][2], community-provided technical documentation and integration scripts identify these values as corresponding to specific issue or monitoring states [3]. Specifically, observed mappings include [3]: 2: Stale 4: Warning 5: Failed 6: Misconfigured 7: Disconnected 8: Disabled These values indicate the current status of the active issue being reported for a device or service within the specified organization unit [1]. Always refer to the latest N-able developer documentation for the specific N-central version in use, as these integer mappings may be subject to change or updates in future releases [4].
Citations:
🏁 Script executed:
Repository: squaredup/plugins
Length of output: 12590
🏁 Script executed:
Repository: squaredup/plugins
Length of output: 19865
🌐 Web query:
site:developer.n-able.com/n-central "notificationState" "active issues" numeric code severity mapping💡 Result:
In the N-able N-central Active Issues API, the notificationState field is represented by a numeric code that corresponds to the status of an issue [1][2]. According to official technical documentation and developer resources, these numeric codes map to the following states: 2: Stale [2] 4: Warning [2] 5: Failed [2] 6: Misconfigured [2] 7: Disconnected [2] 8: Disabled [2] These codes categorize the severity and current functional status of the monitored service or device within the N-central environment [1][2].
Citations:
🌐 Web query:
site:developer.n-able.com/n-central/recipes/nc-rest-api-get-active-issues notificationState💡 Result:
NotificationState is not a standard or universal term in software development but rather a specific property or data field used within particular applications or systems to track the status of alerts or issues [1]. In the context of N-central, for example, Notification State is a field used to categorize the status of active issues [1]. This status is often represented by integer constants that correspond to different conditions, such as: 2: Stale 4: Warning 5: Failed 6: Misconfigured 7: Disconnected 8: Disabled When encountered in other software environments, notificationState typically serves a similar purpose: acting as an enumeration or property that defines whether a notification is active, suppressed, pending, or cleared, depending on the specific implementation requirements of that system [1].
Citations:
🏁 Script executed:
Repository: squaredup/plugins
Length of output: 50373
Map
notificationStateto status categories.The API uses numeric codes for statuses such as
Stale,Warning,Failed,Misconfigured,Disconnected, andDisabled. The dashboards display this field directly, so raw integers are opaque. Use astateshape with amapfor the documented codes and preserve unknown codes as unknown.🤖 Prompt for AI Agents
Source: Learnings