diff --git a/.gitignore b/.gitignore
index 72364f9..72f474c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -87,3 +87,4 @@ ENV/
# Rope project settings
.ropeproject
+/.idea/.gitignore
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
new file mode 100644
index 0000000..a55e7a1
--- /dev/null
+++ b/.idea/codeStyles/codeStyleConfig.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..8e3905d
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 0000000..105ce2d
--- /dev/null
+++ b/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..7e73c7f
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/stackstorm-orion.iml b/.idea/stackstorm-orion.iml
new file mode 100644
index 0000000..d0876a7
--- /dev/null
+++ b/.idea/stackstorm-orion.iml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CHANGES.md b/CHANGES.md
index 289e60d..400bc89 100755
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,5 +1,13 @@
# Changelog
+## 1.0.3
+
+- Added Action
+
+ - add_custom_poller_to_node
+
+- Updated node_create_snmpv3 action to include the option to specify which default pollers to enable when adding the Node
+
## 1.0.2
- Fixed small linting error and pushing a new version.
diff --git a/README.md b/README.md
index 89c20ef..f1b5085 100755
--- a/README.md
+++ b/README.md
@@ -34,28 +34,29 @@ snmp_internal: "SNMP community to use if internal specified"
## Actions
+* `add_custom_pollers_to_node` - Add a list of custom (Universal Device) pollers to a Node
* `add_node_to_ncm` - Add an Orion Node to NCM
* `drain_poller` - Drain nodes from one Orion poller to another.
* `get_discovery_progress` - Get the progress of an SolarWinds Orion Discovery.
* `list_node_custom_properties` - List the custom properties for a SolarWinds Orion nodes
* `list_nodes_by_poller` - List the nodes on a SolarWinds Orion poller
* `list_nodes_by_status` - List the nodes by status
-* `list_sdk_verb_args` - List all the arguments for a entity and verb that can be invoked via SolarWinds Orion.
+* `list_sdk_verb_args` - List all the arguments for an entity and verb that can be invoked via SolarWinds Orion.
* `list_sdk_verbs` - List all the verbs that can be invoked via SolarWinds Orion
* `ncm_config_download` - Download config(s) from SolarWinds NCM Orion module.
* `ncm_execute_script` - Execute an script on an Orion NCM Node.
-* `node_create` - Create an node in SolarWinds Orion.
-* `node_create_snmpv3` - Create an node in SolarWinds Orion with SNMPv3.
+* `node_create` - Create a node in SolarWinds Orion.
+* `node_create_snmpv3` - Create a node in SolarWinds Orion with SNMPv3.
* `node_discover_and_add_interfaces` - Discover and add Interfaces for a SolarWinds Orion node.
* `node_discover_and_add_interfaces_by_name_and_type` - Discover and add Interfaces for a SolarWinds Orion node based upon the ifName, ifType, and (optional) ifAdminStatus
* `node_remanage` - Re-manage a SolarWinds Orion nodes
* `node_status` - Query SolarWinds Orion for a node's status (i.e. Up/Down)
-* `node_unmanage` - Unmanage an SolarWinds Orion node
+* `node_unmanage` - Unmanage a SolarWinds Orion node
* `nodes_pollnow` - Force multiple polls of a list of SolarWinds Orion nodes.
* `query` - Execute generic SWQL queries.
* `start_discovery` - Create a discovery profile in SolarWinds Orion.
-* `update_interface_custom_properties` - Update an the custom properties of an interface on an Orion Node
-* `update_interface_properties` - Update an the "standard" properties (e.g. Unpluggable) on an interface of an Orion Nodes
+* `update_interface_custom_properties` - Update the custom properties of an interface on an Orion Node
+* `update_interface_properties` - Update the "standard" properties (e.g. Unpluggable) on an interface of an Orion Nodes
* `update_node_custom_properties` - Update an Orion Nodes custom properties
* `update_node_poller` - Update an Orion Nodes poller
diff --git a/actions/add_custom_pollers_to_node.py b/actions/add_custom_pollers_to_node.py
new file mode 100644
index 0000000..4ccf2f5
--- /dev/null
+++ b/actions/add_custom_pollers_to_node.py
@@ -0,0 +1,110 @@
+# Licensed to the StackStorm, Inc ('StackStorm') under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from lib.actions import OrionBaseAction
+from lib.utils import send_user_error
+
+
+class AddCustomPollersToNode(OrionBaseAction):
+ def run(self, node, custompollers):
+ """
+ Add list of SNMP Pollers to Node
+
+ Args:
+ - node: The caption in Orion of the node to poll.
+ - custompollers: The list of Orion Custom SNMP pollers to add to the Node
+
+ Returns
+ - List of custom pollers that were added to the Node, a list of Custom pollers that were
+ already assigned to the Node, and a list of Custom pollers that were not found in the system
+
+ Raises:
+ - ValueError: When a node is not found.
+
+ """
+ # Create empty results dict to hold action output data
+ results = {'added': [], 'existing': [], 'not_found': []}
+
+ # Establish a connection to the Orion Server
+ self.connect()
+
+ # Find the Node in the system
+ orion_node = self.get_node(node)
+
+ if not orion_node.npm:
+ error_msg = "Node not found"
+ send_user_error(error_msg)
+ raise ValueError(error_msg)
+
+ # Create a query string needed to pull the custom poller data assigned to the Node
+ # from the Orion DB
+
+ self.logger.info('Querying list of custom pollers already configured on Node...')
+
+ nodequery = 'SELECT NodeID, CustomPollerID FROM Orion.NPM.CustomPollerAssignmentOnNode ' \
+ 'WHERE NodeID=' + str(orion_node.npm_id)
+
+ # Execute the query for the custom Node pollers
+ nodeassignedpollers = self.query(nodequery)
+
+ # Create an empty list of CustomPollerIDs used to hold the ID for each of the pollers
+ # passed as input to the action
+
+ custompollerids = []
+
+ # Loop through all the pollers provided as input to the action and query the Orion DB
+ # for the CustomPollerID.
+
+ for entry in custompollers:
+ pollerquery = 'SELECT CustomPollerID, UniqueName FROM Orion.NPM.CustomPollers where ' \
+ 'UniqueName=\'' + str(entry) + '\''
+ entrypollerid = self.query(pollerquery)
+
+ # Check if the Custom Poller query returned exactly 1 result as expected
+ if len(entrypollerid['results']) == 1:
+ # Check if Custom Poller ID is included in the list returned from the existing
+ # poller query
+ if any(element for element in nodeassignedpollers['results'] if
+ element['CustomPollerID'] == entrypollerid['results'][0]['CustomPollerID']):
+ self.logger.info('Custom Poller {} already assigned to Node. Skipping...'
+ ''.format(entry))
+ # Update results data with matching poller name
+ results['existing'].append(entry)
+ else:
+ # Add Custom Poller ID to list if not found to have already been assigned to the
+ # Node
+ custompollerids.append(entrypollerid['results'][0])
+
+ # Check if the Custom poller query returned either 0 or more than the expected 1
+ if len(entrypollerid['results']) > 1 or len(entrypollerid['results']) == 0:
+ self.logger.info('Custom poller {} not found in Orion DB or the text query returned'
+ ' multiple entries and will be ignored...'.format(entry))
+ results['not_found'].append(entry)
+
+ # After validating all the pollers have not already been assigned to the Node, loop
+ # through all the entries and assign them to the Node
+
+ for entry in custompollerids:
+ entrydata = {
+ "NodeID": str(orion_node.npm_id),
+ "CustomPollerID": entry['CustomPollerID']
+ }
+ response = self.create('Orion.NPM.CustomPollerAssignmentOnNode', **entrydata)
+ self.logger.info('Custom poller {} successfully assigned to Node: {}'.format(
+ entry['UniqueName'], response))
+ # Update results data with matching poller name
+ results['added'].append(entry['UniqueName'])
+ return results
+
diff --git a/actions/add_custom_pollers_to_node.yaml b/actions/add_custom_pollers_to_node.yaml
new file mode 100644
index 0000000..893f59f
--- /dev/null
+++ b/actions/add_custom_pollers_to_node.yaml
@@ -0,0 +1,17 @@
+---
+description: "Add custom NPM Universal Device Pollers to a Node in SolarWinds"
+enabled: true
+entry_point: 'add_custom_pollers_to_node.py'
+name: "add_custom_pollers_to_node"
+pack: "orion"
+runner_type: "python-script"
+
+parameters:
+ node:
+ type: "string"
+ description: The Node which will have the custom pollers assigned to it
+ required: true
+ custompollers:
+ type: "array"
+ description: List of custom (Universal Device) pollers to be added to Node
+ required: true
diff --git a/actions/node_create_snmpv3.py b/actions/node_create_snmpv3.py
index 976b0ae..bae5a32 100644
--- a/actions/node_create_snmpv3.py
+++ b/actions/node_create_snmpv3.py
@@ -29,7 +29,8 @@ def run(self,
privacy_password,
auth_protocol,
auth_password,
- status):
+ status,
+ additional_pollers):
"""
Create an node in Orion.
"""
@@ -117,6 +118,12 @@ def run(self,
pollers_to_add['N.ResponseTime.ICMP.Native'] = False
pollers_to_add['N.ResponseTime.SNMP.Native'] = True
+ # Check to see if any additional pollers were passed as input
+ if additional_pollers:
+ # Enable all the pollers passed as input
+ for entry in additional_pollers:
+ pollers_to_add[entry] = True
+
pollers = []
for p in pollers_to_add:
pollers.append({
diff --git a/actions/node_create_snmpv3.yaml b/actions/node_create_snmpv3.yaml
index debd144..f78b5e6 100644
--- a/actions/node_create_snmpv3.yaml
+++ b/actions/node_create_snmpv3.yaml
@@ -1,5 +1,5 @@
---
-description: "Create an node using SNMPv3 in Solarwinds Orion."
+description: "Create an node using SNMPv3 in SolarWinds Orion."
enabled: true
entry_point: 'node_create_snmpv3.py'
name: "node_create_snmpv3"
@@ -35,6 +35,7 @@ parameters:
privacy_password:
type: "string"
required: true
+ secret: true
description: "The SNMPv3 Privacy password used to poll SNMP from remote device."
auth_protocol:
type: "string"
@@ -42,10 +43,13 @@ parameters:
enum:
- "MD5"
- "SHA1"
+ - "SHA256"
+ - "SHA512"
default: "SHA1"
auth_password:
type: "string"
required: true
+ secret: true
description: "The SNMPv3 Authentication password used to poll SNMP from remote device."
status:
type: "string"
@@ -54,3 +58,7 @@ parameters:
- "icmp"
description: "Protocol to use for Status and Response Time checks."
default: "snmp"
+ additional_pollers:
+ type: "array"
+ required: false
+ description: "List of Orion pollers to enable when creating Node. ** Must be specified using the correct Orion DB naming syntax."
diff --git a/pack.yaml b/pack.yaml
index cef5d3c..cb11015 100755
--- a/pack.yaml
+++ b/pack.yaml
@@ -8,7 +8,7 @@ keywords:
- ncm
- npm
- monitoring
-version: 1.0.2
+version: 1.0.3
python_versions:
- "3"
author: Encore Technologies