/
swis.py
140 lines (119 loc) · 5.27 KB
/
swis.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# (c) 2015, Brian Coca <bcoca@ansible.com>
# (c) 2012-17 Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
#
# Use SolarWinds SWIS client api to access(r/w) Orion DB from within a playbook
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = """
lookup: swis
author: anon
version_added: yes
short_description: return contents from OrionSDK
description:
- Returns the value of a column from the nodes view.
options:
_terms:
description: list of hostnames to query for column
npm_server:
IP of Orion server
column:
description: value from nodes view to be returned
type: string
default: nodes.customproperties.serialNumber
user_id:
description: userID to connect to OrionSDK with
type: string
default: **
passwd:
description: password to connect to OrionSDK with
type: string
default: **
update_flag:
description: update the value in Orion
type: boolean
default: False
new_value:
description: update the value in Orion
type: string
default: ''
"""
EXAMPLES = """
- name: Get Values From Orion -swis plugin default column value is SerialNumber
set_fact:
serialno: "{{ q('swis', inventory_hostname) }}"
- name: Update serial number on Orion via SDK
debug:
msg: "{{inventory_hostname}} was: {{item[0]}}, Changed to: {{ansible_net_serialnum}}"
loop: "{{ q('swis', inventory_hostname, update_flag=true, new_value= ansible_net_serialnum, user_id=orion_user, passwd=orion_pass) }}"
changed_when: "item[0] != ansible_net_serialnum"
"""
RETURN = """
_list:
the column from orion API
"""
import requests
from ansible.errors import AnsibleError
from ansible.plugins.lookup import LookupBase
from orionsdk import SwisClient
from ansible.module_utils.six.moves.urllib.error import HTTPError, URLError
from ansible.module_utils._text import to_text
from ansible.module_utils.urls import open_url, ConnectionError, SSLValidationError
try:
from __main__ import display
except ImportError:
from ansible.utils.display import Display
display = Display()
class LookupModule(LookupBase):
def run(self, terms, variables=None, **kwargs):
npm_server = kwargs.get('npm_server', '172.19.128.111')
column = kwargs.get('column', 'nodes.customproperties.serialNumber')
user_id = kwargs.get('user_id', '**')
passwd = kwargs.get('passwd', '**')
update_flag = kwargs.get('update_flag', False)
new_value = kwargs.get('new_value', '')
# lookups in general are expected to both take a list as input terms[], and output a list, ret[]
# this is done so they work with the looping construct 'with_'.
ret = []
for hostname in terms:
display.v("value to return %s" % column)
query = "SELECT {} FROM Orion.Nodes WHERE Caption = '{}'".format(column, hostname)
display.v("query: {}".format(query))
try:
orion = self.orion_connect(npm_server, user_id, passwd)
rsp = self.orion_query(orion, query)
display.v("result: {}".format(rsp['results'][0][rsp['results'][0].keys()[0]]))
if update_flag:
display.v("update {} with {}".format(column, new_value))
uri_query = "SELECT URI from Orion.Nodes WHERE Caption = '{}'".format(hostname)
uri = self.orion_query(orion, uri_query)
url = "{}/{}".format(uri['results'][0]['URI'], column.split('.')[-2])
display.v("url: {}".format(url))
orion.update(url, **{ column.split('.')[-1] : new_value } )
except HTTPError as e:
raise AnsibleError("Received HTTP error for %s : %s" % (hostname, str(e)))
except URLError as e:
raise AnsibleError("Failed lookup url for %s : %s" % (hostname, str(e)))
except SSLValidationError as e:
raise AnsibleError("Error validating the server's certificate for %s: %s" % (hostname, str(e)))
except ConnectionError as e:
raise AnsibleError("Error connecting to %s: %s" % (hostname, str(e)))
except Exception as e:
raise AnsibleError("Error: %s: %s" % (hostname, str(e)))
else:
display.v("response {}".format(rsp['results'][0].keys()[0]))
ret.append(to_text(rsp['results'][0][rsp['results'][0].keys()[0]]))
return ret
def orion_connect(self, npm_server, username, password):
""" Open connection to Orion server """
requests.packages.urllib3.disable_warnings()
swis = SwisClient(npm_server, username, password)
return swis
def orion_query(self, swis, query):
""" Connect to Orion server and send query """
rsp = swis.query("{}".format(query))
if rsp['results'] == []:
print("No results for: {}".format(query))
exit(-1)
display.v("Query Orion Existing SerialNumber: {}\n".format(rsp['results'][0][rsp['results'][0].keys()[0]]))
return rsp