Skip to content

Commit

Permalink
v9.0.9-SNAPSHOT -> v9.0.9
Browse files Browse the repository at this point in the history
  • Loading branch information
mershad-manesh committed Sep 13, 2023
2 parents 2c9dc55 + 0567dc4 commit eb16c00
Show file tree
Hide file tree
Showing 17 changed files with 522 additions and 280 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
### v9.0.9

Grafana Plugin for OpenNMS version 9.0.9 release contains a number of bug fixes and enhancements.

* [OPG-448](https://opennms.atlassian.net/browse/OPG-448) Converter outputs extra characters in resource name
* [OPG-454](https://opennms.atlassian.net/browse/OPG-454) Flow query with multi-value withHost does not return data
* [OPG-460](https://opennms.atlassian.net/browse/OPG-460) Entities DS - Nodes Table - Category Values showing under Primary SNMP ifIndex
* [OPG-461](https://opennms.atlassian.net/browse/OPG-461) Entity datasource no longer includes node ID / node label in IP interface query results
* [OPG-463](https://opennms.atlassian.net/browse/OPG-463) Entitles DS Tables Limit does not allow a value of zero

### v9.0.8

Grafana Plugin for OpenNMS version 9.0.8 is a re-release of version 9.0.7 which contains a number of bug fixes and enhancements.
Expand Down
2 changes: 1 addition & 1 deletion docs/antora.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ version: '9'
title: Plugin for Grafana
asciidoc:
attributes:
full-display-version: '9.0.8'
full-display-version: '9.0.9'
grafana-version-required: '9.x'
grafana-version-tested: '9.0'
node-js-build-version: '16.x'
Expand Down
459 changes: 275 additions & 184 deletions package-lock.json

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "opennms-grafana-plugin",
"version": "9.0.8",
"version": "9.0.9",
"description": "An OpenNMS Integration for Grafana",
"repository": {
"type": "git",
Expand All @@ -24,7 +24,7 @@
"@swc/core": "^1.2.144",
"@swc/helpers": "^0.5.1",
"@swc/jest": "^0.2.23",
"@testing-library/jest-dom": "^5.16.2",
"@testing-library/jest-dom": "^6.1.2",
"@testing-library/react": "^12.1.4",
"@types/flot": "0.0.32",
"@types/glob": "^8.0.0",
Expand All @@ -48,7 +48,7 @@
"recursive-copy": "^2.0.13",
"replace-in-file-webpack-plugin": "^1.0.6",
"rimraf": "^5.0.0",
"sass": "1.64.1",
"sass": "1.66.1",
"sass-loader": "13.3.2",
"specit": "^1.4.4",
"style-loader": "3.3.3",
Expand All @@ -61,7 +61,7 @@
"webpack": "^5.69.1",
"webpack-cli": "^5.0.2",
"webpack-livereload-plugin": "^3.0.2",
"which": "^3.0.0"
"which": "^4.0.0"
},
"engines": {
"node": ">=14"
Expand Down
2 changes: 1 addition & 1 deletion site.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ asciidoc:
attributes:
experimental: true
stem: latexmath
full-display-version: '9.0.8'
full-display-version: '9.0.9'
grafana-version-required: '9.x'
grafana-version-tested: '9.0'
node-js-build-version: '16.x'
Expand Down
7 changes: 4 additions & 3 deletions src/datasources/entity-ds/EntityClause.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ export const EntityClause = ({
if (attribute?.value?.type?.i === 'TIMESTAMP') {
type = 'datetime-local'
} else if (attribute?.value?.type?.i === 'INTEGER') {
type = 'number'
// leaving this as 'text' for now, otherwise user cannot input template variable
// type = 'number'
}
return type;
}
Expand Down Expand Up @@ -128,8 +129,8 @@ export const EntityClause = ({
<Segment
allowEmptyValue={false}
value={clause.comparator}
onChange={(text) => {
setComparator(index, text);
onChange={val => {
setComparator(index, val)
}}
options={comparatorOptions}
/>
Expand Down
22 changes: 17 additions & 5 deletions src/datasources/entity-ds/EntityClauseEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,38 @@ export const EntityClauseEditor = ({ setFilter, loading, propertiesAsArray, clau

// Build the filter. This could be extracted to a helper function.
clauses.forEach((d, i) => {
if ((d.type === OnmsEntityType.AND || d.type === OnmsEntityType.FIRST) && clauses[i].comparator?.value) {
// comparator could be: '{ id, label }' or else '{ value: { i, l } }'
let comparatorValue = clauses[i].comparator?.value

if (!comparatorValue && clauses[i].comparator?.id) {
comparatorValue = {
id: clauses[i].comparator.id,
label: clauses[i].comparator.label,
l: clauses[i].comparator.label,
i: clauses[i].comparator.id
}
}

if ((d.type === OnmsEntityType.AND || d.type === OnmsEntityType.FIRST) && comparatorValue) {
updatedFilter.withAndRestriction(
new API.Restriction(
clauses[i].attribute?.value?.id,
clauses[i].comparator?.value,
comparatorValue,
clauses[i].comparedString || clauses[i].comparedValue.value
)
)
} else if (d.type === OnmsEntityType.OR && clauses[i].comparator?.value) {
} else if (d.type === OnmsEntityType.OR && comparatorValue) {
updatedFilter.withOrRestriction(
new API.Restriction(
clauses[i].attribute?.value?.id,
clauses[i].comparator?.value,
comparatorValue,
clauses[i].comparedString || clauses[i].comparedValue.value
)
)
}
})

setFilter(updatedFilter);
setFilter(updatedFilter)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [clauses])

Expand Down
4 changes: 3 additions & 1 deletion src/datasources/entity-ds/EntityQueryEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
} from '@grafana/ui'
import { SelectableValue } from '@grafana/data';
import { useEntityProperties } from '../../hooks/useEntityProperties';
import { isInteger } from '../../lib/utils'
import { EntityClauseEditor } from './EntityClauseEditor';
import { EntityOrderByEditor } from './EntityOrderByEditor';
import { defaultClause } from './constants';
Expand Down Expand Up @@ -63,6 +64,7 @@ const clausesReducer = (clauses: OnmsEntityClause[], action: Action): OnmsEntity
default:
throw new Error("shouldn't get here")
}

return newClauses
}

Expand All @@ -78,7 +80,7 @@ export const EntityQueryEditor: React.FC<EntityQueryEditorProps> = ({ onChange,
const [clauses, dispatchClauses] = useReducer(clausesReducer, query.clauses || [{ ...defaultClause }])
const [loading, setLoading] = useState(false)
const [filter, setFilter] = useState(query?.filter || getSmallerAPIFilter())
const [limit, setLimit] = useState(query?.filter?.limit || 99)
const [limit, setLimit] = useState(isInteger(query?.filter?.limit) ? query.filter.limit : 99)
const [featuredAttributes, setFeaturedAttributes] = useState(true)
const { propertiesLoading, propertiesAsArray } = useEntityProperties(value.label || '', featuredAttributes, client)

Expand Down
9 changes: 3 additions & 6 deletions src/datasources/entity-ds/queries/queryBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { TemplateSrv } from '@grafana/runtime'
import { API } from 'opennms'
import { EntityQuery, EntityQueryRequest, FilterEditorData } from './../types'
import { getAttributeMapping } from './attributeMappings'
import { ALL_SELECTION_VALUE, EntityTypes } from '../../../constants/constants'
import { isInteger } from '../../../lib/utils'
import { getAttributeMapping } from './attributeMappings'
import { getFilterId } from '../EntityHelper'

const isAllVariable = (templateVar, templateSrv) => {
Expand All @@ -14,10 +15,6 @@ const isMultiVariable = (templateVar) => {
return !!(templateVar?.multi || templateVar?.isMulti)
}

const isNumber = (num: any) => {
return ((parseInt(num, 10) + '') === (num + ''))
}

const isEmptyNodeRestriction = (clause: API.Clause) => {
const restriction = clause.restriction
return restriction.attribute === 'node' && restriction.value === '{}'
Expand Down Expand Up @@ -86,7 +83,7 @@ const subtituteNodeRestriction = (clause: API.Clause) => {
new API.Clause(new API.Restriction('node.foreignId', restriction.comparator, nodeCriteria[1]), API.Operators.AND),
)
clause.restriction = replacement
} else if (isNumber(restriction.value)) {
} else if (isInteger(restriction.value)) {
clause.restriction = new API.Restriction('node.id', restriction.comparator, restriction.value)
} else {
console.warn('Found a "node" criteria but it does not appear to be a node ID nor a foreignSource:foreignId tuple.', restriction)
Expand Down
2 changes: 2 additions & 0 deletions src/datasources/entity-ds/queries/queryIPInterfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const columns = Object.freeze([
{ text: 'SNMP ifDescr', resource: 'snmpInterface.ifDescr' },
{ text: 'SNMP ifIndex', resource: 'snmpInterface.ifIndex' },
{ text: 'SNMP PhysAddr', resource: 'snmpInterface.physAddr' },
{ text: 'Node ID', resource: 'node.id' }
] as OnmsColumn[]);

export const getIPInterfaceColumns = () => columns
Expand Down Expand Up @@ -47,6 +48,7 @@ export const queryIPInterfaces = async (client: ClientDelegate, filter: API.Filt
iface.snmpInterface?.ifDescr,
iface.snmpInterface?.ifIndex,
iface.snmpInterface?.physAddr?.toString(),
iface.node?.id
];
});

Expand Down
36 changes: 27 additions & 9 deletions src/datasources/entity-ds/queries/queryNodes.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ClientDelegate } from "lib/client_delegate";
import { OnmsNode } from "opennms/src/model/OnmsNode";
import { ClientDelegate } from 'lib/client_delegate'
import { OnmsNode } from 'opennms/src/model/OnmsNode'
import { API } from 'opennms'
import { OnmsColumn, OnmsTableData } from '../types'

Expand Down Expand Up @@ -34,15 +34,31 @@ const columns = Object.freeze([

export const getNodeColumns = () => columns

const getSnmpPrimaryInterface = (node: OnmsNode) => {
if (node.ipInterfaces) {
const primary = node.ipInterfaces.filter(iface => {
return !!iface.snmpPrimary?.isPrimary()
})?.[0]

return primary
}

return undefined
}

export const queryNodes = async (client: ClientDelegate, filter: API.Filter): Promise<OnmsTableData> => {
let nodes: OnmsNode[] = [];
let nodes: OnmsNode[] = []

try {
nodes = await client.findNodes(filter, true)
} catch (e) {
console.error(e);
console.error(e)
}
const rows = nodes?.map((node) => {
const primaryIpInterface = getSnmpPrimaryInterface(node)
const ifIndex = primaryIpInterface?.snmpInterfaceId
const ipAddress = primaryIpInterface?.ipAddress?.correctForm() || ''

return [
node.id,
node.label,
Expand All @@ -51,10 +67,10 @@ export const queryNodes = async (client: ClientDelegate, filter: API.Filter): Pr
node.foreignId,
node.location,
node.createTime,
node.parent ? node.parent.id : undefined,
node.parent ? node.parent.foreignSource : undefined,
node.parent ? node.parent.foreignId : undefined,
node.type ? node.type.toDisplayString() : undefined,
node.parent ? node.parent.id : '',
node.parent ? node.parent.foreignSource : '',
node.parent ? node.parent.foreignId : '',
node.type ? node.type.toDisplayString() : '',
node.sysObjectId,
node.sysName,
node.sysDescription,
Expand All @@ -64,7 +80,9 @@ export const queryNodes = async (client: ClientDelegate, filter: API.Filter): Pr
node.netBiosDomain,
node.operatingSystem,
node.lastCapsdPoll,
node.categories ? node.categories.map(cat => cat.name) : undefined,
ifIndex || '',
ipAddress,
node.categories ? node.categories.map(cat => cat.name) : ''
]
})

Expand Down
42 changes: 31 additions & 11 deletions src/datasources/flow-ds/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ import { Model } from 'opennms'
import { ClientDelegate } from 'lib/client_delegate'
import { dscpLabel, dscpSelectOptions } from '../../lib/tos_helper'
import {
swapColumns,
getMultiValues,
getNodeFilterMap,
getNumberOrDefault,
getNodeAsResourceQuery,
isMultiValueString,
isString,
swapColumns,
valueOrDefault
} from 'lib/utils'
import { SimpleOpenNMSRequest } from 'lib/simpleRequest'
Expand Down Expand Up @@ -600,17 +602,20 @@ const getTimeRange = (options: FlowQueryRequest<FlowQuery>) => {
*/
const parseActiveFunctionsAndValues = (func: SelectableValue<string>, queryData: FlowQueryData, oldData: FlowParsedQueryRow, index: number) => {
const data = { ...oldData }
let inputParams: string | undefined = ''
let inputParams: string | string[] | undefined = ''

if (func.label) {
const fullFunction = FlowFunctions.get(func.label)

if ((fullFunction?.parameter || fullFunction?.parameter === '') && queryData.functionParameters) { //If there's a parameter, get it.
if ((fullFunction?.parameter || fullFunction?.parameter === '') && queryData.functionParameters) { // if there's a parameter, get it
inputParams = queryData.functionParameters[index]
} else if (fullFunction?.parameterOptions && queryData?.parameterOptions) { //If there's an option set, get it.
} else if (fullFunction?.parameterOptions && queryData?.parameterOptions) { // if there's an option set, get it
inputParams = queryData.parameterOptions?.[index]?.label
}

// Note, at this point, the parameter or option could be a multi-valued value like '{0.0.0.0,0.0.0.1}'
// In some (all?) cases the parameter needs to be changed to a string[] before passing on to opennms-js dao

data.queryFunctions.push({ [func.label]: inputParams })
}

Expand Down Expand Up @@ -799,6 +804,16 @@ const buildSeriesFlowQueryParams = (functionName: string, functionParams: FlowFu

for (let key of funcNames) {
if (item[key]) {
// opennms-js dao expects 'withHost' value to be a string[].
// If the value was a multi-valued template variable like '{0.0.0.0,0.0.0.1}',
// it needs to be turned into a string[].
// Could be the case with others as well
if (key === 'withHost') {
if (isMultiValueString(item[key])) {
return getMultiValues(item[key])
}
}

return item[key]
}
}
Expand Down Expand Up @@ -1037,13 +1052,18 @@ const metricFindExporterNodes = async ({ client, simpleRequest }, service: FlowT
}

const metricFindInterfacesOnExporterNode = async ({ client, simpleRequest }, service: FlowTemplateVariableQueryService) => {
const node = await simpleRequest.getNodeByIdOrFsFsId(service.nodeId);
const exporter = await client.getExporter(node.id);
let results = [] as any[];
exporter.interfaces.forEach(iff => {
results.push({ text: iff.name + "(" + iff.index + ")", value: iff.index, expandable: true });
});
return results;
let results = [] as any[]
const nodeIds = isMultiValueString(service.nodeId) ? getMultiValues(service.nodeId) : [service.nodeId]

for (let nodeId of nodeIds) {
const node = await simpleRequest.getNodeByIdOrFsFsId(nodeId)
const exporter = await client.getExporter(node.id)
exporter.interfaces.forEach(iff => {
results.push({ text: `${iff.name}(${iff.index})`, value: iff.index, expandable: true })
})
}

return results
}

const metricFindDscpOnExporterNodeAndInterface = async ({ client, simpleRequest }, service: FlowTemplateVariableQueryService) => {
Expand Down
2 changes: 1 addition & 1 deletion src/lib/dashboard-convert/performanceDs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ const convertStringPropertyQuery = (source: any) => {

// 'label' and 'name' will be filled in at runtime
const resourceState = {
id: `node[${legacyNodeId}].${legacyResourceId}]`,
id: `node[${legacyNodeId}].${legacyResourceId}`,
label: legacyResourceId,
parentId: `node[${legacyNodeId}]`
}
Expand Down
Loading

0 comments on commit eb16c00

Please sign in to comment.