Skip to content

Commit

Permalink
1.0.6 Release (#60)
Browse files Browse the repository at this point in the history
Bugfixes
======

- Resolves Issues #58, #57, #51 and makes auth backwards compatible by defaulting to OAuth if client_id is present without specifying auth.

- Order_by is implemented client-side to provide proper sorting as previously documented.
  • Loading branch information
amittell authored May 28, 2021
1 parent 6c0a3c6 commit 9fe7d9e
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 42 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,18 @@ Servicenow.Servicenow Release Notes
.. contents:: Topics



v1.0.6
======

Bugfixes
--------

- Resolves Issues #58, #57, #51 and makes auth backwards compatible by defaulting to OAuth if client_id is present without specifying auth.
- Order_by is implemented client-side to provide proper sorting as previously documented.

=======

v1.0.5
======

Expand Down
2 changes: 1 addition & 1 deletion changelogs/.plugin-cache.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ plugins:
shell: {}
strategy: {}
vars: {}
version: 1.0.5
version: 1.0.6
8 changes: 8 additions & 0 deletions changelogs/changelog.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,11 @@ releases:
fragments:
- 27_openid.yml
release_date: '2021-04-02'
1.0.6:
changes:
bugfixes:
- order_by again working by locally sorting return list of records
- makes auth backwards compatible by defaulting to OAuth if client_id is present without specifying auth
fragments:
- 58_order_by.yml
release_date: '2021-05-26'
10 changes: 10 additions & 0 deletions changelogs/fragments/58_order_by.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
major_changes:
- auth field now required for anything other than Basic authentication, but, if client_id specified without auth, defaults to OAuth
- refactored client to inherit from AnsibleModule
- supports OpenID Connect authentication protocol
- supports bearer tokens for authentication
minor_changes:
- standardized invocation output
bugfixes:
- order_by again working by locally sorting return list of records
5 changes: 4 additions & 1 deletion plugins/module_utils/service_now.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,10 @@ def _mod_debug(self, key, **kwargs):
def _login(self):
self.result['changed'] = False
if self.params['auth'] == 'basic':
self._auth_basic()
if self.client_id is not None:
self._auth_oauth()
else:
self._auth_basic()
elif self.params['auth'] == 'oauth':
self._auth_oauth()
elif self.params['auth'] == 'token':
Expand Down
109 changes: 69 additions & 40 deletions plugins/modules/snow_record_find.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,19 +218,45 @@
try:
# This is being managed by ServiceNowModule
import pysnow
import re
import requests
except ImportError:
pass


class BuildQuery(object):
class SnowRecordFind(object):
'''
This is a BuildQuery manipulation class that constructs
a pysnow.QueryBuilder object based on data input.
'''

def __init__(self, module):
self.module = module

# Define query parameters
self.data = module.params['query']
self.max_records = self.module.params['max_records']
self.order_by = self.module.params['order_by']
self.return_fields = self.module.params['return_fields']

# Define sort criteria
self.reverse = False
if self.order_by is not None:
if self.order_by[0] == '-':
self.reverse = True
if self.order_by[0] in ['-', '+']:
self.order_by = self.order_by[1:]

# Define table parameters
self.table = module.connection.resource(
api_path='/table/' + self.module.params['table'])
self.table.parameters.display_value = self.module.params['display_value']
self.table.parameters.exclude_reference_link = self.module.params[
'exclude_reference_link']
self.table.parameters.suppress_pagination_header = self.module.params[
'suppress_pagination_header']

# Define query expression operators
self.logic_operators = ["AND", "OR", "NQ"]
self.condition_operator = {
'equals': self._condition_closure,
Expand All @@ -245,17 +271,20 @@ def __init__(self, module):
self.accepted_cond_ops = self.condition_operator.keys()
self.append_operator = False
self.simple_query = True
self.data = module.params['query']

# Build the query
self.query = pysnow.QueryBuilder()
self._iterate_operators(self.data)

def _condition_closure(self, cond, query_field, query_value):
self.qb.field(query_field)
getattr(self.qb, cond)(query_value)
self.query.field(query_field)
getattr(self.query, cond)(query_value)

def _iterate_fields(self, data, logic_op, cond_op):
if isinstance(data, dict):
for query_field, query_value in data.items():
if self.append_operator:
getattr(self.qb, logic_op)()
getattr(self.query, logic_op)()
self.condition_operator[cond_op](
cond_op, query_field, query_value)
self.append_operator = True
Expand Down Expand Up @@ -296,10 +325,39 @@ def _iterate_operators(self, data):
)
)

def build_query(self):
self.qb = pysnow.QueryBuilder()
self._iterate_operators(self.data)
return (self.qb)
def _sort_key(self, e):
if self.order_by in e.keys():
return self.order_by
else:
prog = re.compile(r'.*' + self.order_by + r'.*')
for key in e.keys():
if prog.match(key):
return key
return None

def execute(self):
try:
response = self.table.get(
query=self.query,
limit=self.max_records,
fields=self.return_fields)
except Exception as detail:
self.module.fail(
msg='Failed to find record: {0}'.format(to_native(detail))
)

rlist = response.all()
if len(rlist) > 0:
self.order_by = self._sort_key(rlist[0])
if self.order_by is not None:
self.module.result['record'] = sorted(
rlist,
key=lambda x: x[self.order_by],
reverse=self.reverse)
else:
self.module.result['record'] = rlist

self.module.exit()


def main():
Expand Down Expand Up @@ -347,37 +405,8 @@ def main():
supports_check_mode=True,
)

params = module.params
table = params['table']
query = params['query']
max_records = params['max_records']
display_value = params['display_value']
exclude_reference_link = params['exclude_reference_link']
suppress_pagination_header = params['suppress_pagination_header']
return_fields = params['return_fields']

# Do the lookup
try:
bq = BuildQuery(module)
qb = bq.build_query()
table = module.connection.resource(api_path='/table/' + table)

table.parameters.display_value = display_value
table.parameters.exclude_reference_link = exclude_reference_link
table.parameters.suppress_pagination_header = suppress_pagination_header

response = table.get(
query=qb,
limit=max_records,
fields=return_fields)
except Exception as detail:
module.fail(
msg='Failed to find record: {0}'.format(to_native(detail))
)

module.result['record'] = response.all()

module.exit()
query = SnowRecordFind(module)
query.execute()


if __name__ == '__main__':
Expand Down

0 comments on commit 9fe7d9e

Please sign in to comment.