How to parse a XML response in ansible? - xml-parsing

I'm running the panos_op ansible module and struggling to parse the output.
ok: [localhost] => {
"result": {
"changed": true,
"failed": false,
"msg": "Done",
"stdout": "{\"response\": {\"#status\": \"success\", \"result\": \"no\"}}",
"stdout_lines": [
"{\"response\": {\"#status\": \"success\", \"result\": \"no\"}}"
],
"stdout_xml": "<response status=\"success\"><result>no</result></response>"
}
}
This is as close as I can get to assigning the value for "result".
ok: [localhost] => {
"result.stdout": {
"response": {
"#status": "success",
"result": "no"
}
}
}
My goal is to set a conditional loop for the ansible task.
tasks:
- name: Checking for pending changes
panos_op:
ip_address: '{{ host }}'
password: '{{ operator_pw }}'
username: '{{ operator_user}}'
cmd: 'check pending-changes'
register: result
until: result.stdout.result = no
retries: 10
delay: 5
tags: check
How can I make this work?

Related

Ansible - check if item in a list of dictionaries is present in other list of dictionaries

How to check if an object of a list of dictionaries is present in another list of dictionaries (with Ansible?)
You could try jinja filters selectattr - I had an issue with using it, so I did revert to a simplified but ugly solution - build a filtered list and compare filtered attributes only (list-to-list).
I do not like it, but it works.
Let me know if you know other way.
playbook:
- name: find existing system_crontabs #would generate a list of dict
find:
path: /var/spool/cron/crontabs/
register: system_side_crontabs
become: True
- name: create lists of system_cron_names and repo_cron_names
set_fact:
system_cron_names: "[]"
repo_cron_names: "[]"
- name: build list of system_cron_names
set_fact:
system_cron_names: "{{ system_cron_names }} + [ '{{ item.path |basename }}' ]"
with_items: "{{ system_side_crontabs.files }}"
- name: build lists of repo_cron_names
set_fact:
repo_cron_names: "{{ repo_cron_names }} + [ '{{ item.user }}' ]"
with_items: "{{ crontabs }}"
- name: assert check if an object of system_crontab is defined in repo_crontab
assert:
that: "{{ [item] |intersect(repo_cron_names) | length }} == 1"
with_items: "{{ system_cron_names }}"
hosts_vars/prd-inner-mgmt202 #a list of dictionaries
crontabs:
- user: root
crontab_rules: |
11 1 * * * find /home/ansible/.ansible/tmp/ -atime +10 -delete
a result of find
ok: [prd-inner-mgmt202] => {
"changed": false,
"examined": 1,
"files": [ ### List of dictionary
{
"path": "/var/spool/cron/crontabs/root",
},
{
"path": "/var/spool/cron/crontabs/another_file",
}
],
"invocation": {
"module_args": {
"age": null,
"age_stamp": "mtime",
"contains": null,
"file_type": "file",
"follow": false,
"get_checksum": false,
"hidden": false,
"path": "/var/spool/cron/crontabs/",
"paths": [
"/var/spool/cron/crontabs/"
],
"patterns": [
"*"
],
"recurse": false,
"size": null,
"use_regex": false
},
"module_name": "find"
},
"matched": 1,
"msg": ""
}
generate a list of strings that are easy to compare
TASK [mid_crontab : build list of system_cron_names] **************************
"ansible_facts": {
"system_cron_names": [
"root",
]
},
"changed": false,
"invocation": {
"module_args": {
"system_cron_names": [
"root"
]
},
"module_name": "set_fact"
},
generate another list of strings
TASK [mid_crontab : build list of repo_cron_names] *****************************
ok: [prd-inner-mgmt202] => (item={u'crontab_rules': u'11 1 * * * find /home/ansible/.ansible/tmp/ -atime +10 -delete\n', u'user': u'root'}) => {
"ansible_facts": {
"repo_cron_names": [
"root"
]
},
"changed": false,
"invocation": {
"module_args": {
"repo_cron_names": [
"root",
"other"
]
},
"module_name": "set_fact"
},
"item": {
"crontab_rules": "11 1 * * * find /home/ansible/.ansible/tmp/ -atime +10 -delete\n",
"user": "root"
}
}
Assert the required check, use intersect jinja filter. In my case a system defined object (cron record) should exist in my repository - so the list should have 1 element.
TASK [mid_crontab : assert check if system_crontab is defined in repo_crontab] *
ok: [prd-inner-mgmt202] => (item=root) => {
"changed": false,
"invocation": {
"module_args": {
"that": "1 == 1"
},
"module_name": "assert"
},
"item": "root",
"msg": "All assertions passed"
}
Seems you want to reduce original dict to list of strings (names) and compare the difference:
---
- hosts: localhost
gather_facts: no
vars:
crontabs:
- user: root
crontab_rules: xxx
tasks:
- find:
path: /tmp/test
register: myfiles
- assert:
that: sys_crons_violation | count == 0
msg: "This crons are not defined in repo : {{ sys_crons_violation | join(', ') }}"
vars:
sys_crons: "{{ myfiles.files | map(attribute='path') | map('basename') | list }}"
repo_crons: "{{ crontabs | map(attribute='user') | list }}"
sys_crons_violation: "{{ sys_crons | difference(repo_crons) }}"
result:
TASK [find] ************************
TASK [assert] **********************
fatal: [localhost]: FAILED! => {
"assertion": "sys_crons_violation | count == 0",
"changed": false,
"evaluated_to": false,
"msg": "This crons are not defined in repo : another_file"
}

Elasticsearch js query with must and must_not

I am trying to get a query to run with both must and must_not, but have not had any luck with the syntax I am attempting. I see a lot of people on StackOverflow using quotes on both sides like they would be in a Curl call, but this is straight out of a node application.
I will show the query that does work, and I am simply trying to add what I do not want to be included in the outcome. In either case, because this is just trash data that is on a local dev environment, the outcome should match.
First the working query:
client.search({
index: config.ES_INDEX,
type: "issue",
body: {
query: {
match: {
issue_state: 'Closed'
}
},
size: 1000
}
}).then(function(resp){
console.log(util.inspect(resp, {showHidden: false, depth: null}));
}).catch(function(err){
console.log('Failed to search. ' + err.message);
});
Output:
{ took: 5,
timed_out: false,
_shards: { total: 5, successful: 5, failed: 0 },
hits:
{ total: 1,
max_score: 1,
hits:
[ { _index: 'noc_tool',
_type: 'issue',
_id: 'Sy2IQFMLe',
_score: 1,
_source:
{ job_name: 'Job Name 1',
is_maintenance: 'no',
servicenow_id: 'lkjjklh',
type: 'Chase',
start_time: '1970-01-01T23:15:00.000Z',
maint_reminder: null,
update_duration: '4 Hours',
location: 'Test Group',
issue_state: 'Closed',
notes: [ { created_on: 1484063571941, body: 'lkjlkjhlkj' } ],
emailService: { lastEmailAt: 1484237594114 },
created_on: 1484063571941,
updated_on: 1484240538801,
reason: 'because I want to' } } ] } }
Now, the failed query:
client.search({
index: config.ES_INDEX,
type: "issue",
body: {
query: {
bool: {
must: [
{
term: {
issue_state: 'Closed'
}
}
],
must_not: [
{
term: {
is_maintenance: 'yes'
}
}
]
}
},
size: 1000
}
}).then(function(resp){
console.log(util.inspect(resp, {showHidden: false, depth: null}));
}).catch(function(err){
console.log('Failed to search. ' + err.message);
});
Output:
{ took: 6,
timed_out: false,
_shards: { total: 5, successful: 5, failed: 0 },
hits: { total: 0, max_score: null, hits: [] } }
Any help here would be much appreciated.
I ended up using a little "reverse logic" but here is what is working..
return new Promise(function(resolve, reject) {
client.search({
index: config.ES_INDEX,
type: "issue",
body: {
query: {
bool: {
must:[
{
match: {
issue_state: 'Closed'
}
},
{
match: {
is_maintenance: 'no'
}
}
]
}
},
size: 1000
}
}).then(function (resp) {
resolve (resp.hits.hits);
}).catch(function (err) {
reject('Failed to search. ' + err.message);
});

How can i conditionally use an ajax call to retrieve Jquery Datatables data?

We are using jQuery Datatables in our page. The table data is loaded with ajax calls. However, I only want to load the data if a certain condition is met. When the condition is not met, an empty datatable will be shown.
Below is the table as it is now. It works fine and loads the data correctly, but I haven't added the condition yet. The condition will be if (#Model.SelectedOrganizationId != null, load the data'Else, display an empty table`.
I could have two table initializations--one with data population and one without, but that seems repetitive. Also I could possibly just return null to the ajax call, but that seems unnecessary.(As in, why make the call if I don't have to?)
****************Edit***************************************************
Basically, I'd like to initialize an empty table and load the data after, if the condition is met.
function GetUnassignedActiveRolesGrid(showOnlyDistrictRoles)
{
/* Unassigned Active Roles */
unassignedActiveRolesGrid = $("#gridUnassignedActiveRoles").DataTable({
fixedHeader: true,
createdRow: function ( table ) {
setTabIndex(table);
},
processing: true,
info: true,
stateSave: false,
ajax: {
url: '#Url.Action("GetUnassignedActiveRoles", "UserAccount")',
data: {accountId: #Model.UserNameDetails.AccountId, organizationId: '#Model.SelectedOrganizationId', showOnlyDistrictRoles: showOnlyDistrictRoles},
dataSrc: "",
type: "GET",
dataType: "JSON"
},
paging: false,
searching: true,
autoWidth: false, // Disable the auto width calculation,
language: {
emptyTable: "Sorry, no role data available"
},
columns: [
{data: "ModuleName", title: "Module"},
{data: "Label", title: "Role"},
{data: "Description", title: "Description" },
{title: "Navigation", className: "center"},
{data: "ModuleSortOrder", title: "ModuleSortOrder" },
{data: "RoleSortOrder", title: "RoleSortOrder" }
],
order: [[4, "asc"], [5, "asc"], [0, "asc"], [1, "asc"]],
columnDefs: [
{ width: "20%", targets: [0,1] },
{ width: "50%", targets: 2 },
{ width: "10%", targets: 3 },
{ orderable: false, targets: [2] },
{ orderable: false, targets: [3] },
{ targets: 3, data:
function(role) {
return role.OrganizationId == '#Model.SelectedOrganizationId' ? "<a class='link_UnassignedActive_Add' href='#anchorUnassignedActiveRoles'>Add</a>" : "";
}},
{ visible: false, searchable: false, targets: [4,5] }
]
});
}

hapijs joi email validation option tldWhitelist usage

I'm trying to use Joi and Hapijs to validate POST submission requests.
Here is my swagger code:
server.route([
{
method: "POST",
path: '/cardsignup',
config: {
handler: card_signup,
description: 'Insert card signup record',
notes: 'save card signup to database',
tags: ['card', 'signup', 'api'],
plugins: {
'hapi-swagger': {
responseMessages: [
{code: 200, message: 'Success'},
{code: 400, message: 'Bad Request'},
{code: 401, message: 'Not Authorized'},
{code: 500, message: 'Internal Server Error'}
]
}
},
validate: {
payload: {
name: Joi.string()
.required()
.description('full name'),
email: Joi.string().email({
tldWhitelist:['example.com']
})
.required()
.description('email'),
signature_svg: Joi.string()
.optional()
.description('string encoded svg'),
signature_png: Joi.binary()
.optional()
.description('base64 encoded png'),
card_choice: Joi.string()
.required()
.description('card choice string'),
last4: Joi.number()
.required()
.description('last 4 digits of cc')
}
}
}
}
]);
When I do a POST to the server, I get this back, no matter what email I put in:
{
"statusCode": 400,
"error": "Bad Request",
"message": "child \"email\" fails because [\"email\" must be a valid email]",
"validation": {
"source": "payload",
"keys": [
"email"
]
}
}
Anybody have an example of how to use tldWhitelist?
Specifically, I want to verify that emails are from example.com
The value of tldWhitelist can be either an object lookup table or an array of valid top-level domains. For example:
tldWhitelist: ['com']

Cant configure timed out user confirmation url page in LoopbackJS

I try to configure, new registerede user's timed ot confirmation url.
When user clicks on timed out link from mail, screen looks like :
{"error":{"name":"Error","status":404,"message":"User not found: 19","statusCode":404,"code":"USER_NOT_FOUND","stack":"Error: User not found: 19\n at c:\\NodeJS\\UyguncaAdmin\\node_modules\\loopback\\common\\models\\user.js:477:19\n at c:\\NodeJS\\UyguncaAdmin\\node_modules\\loopback-datasource-juggler\\lib\\dao.js:1524:62\n at c:\\NodeJS\\UyguncaAdmin\\node_modules\\loopback-datasource-juggler\\lib\\dao.js:1456:9\n at Object.async.each (c:\\NodeJS\\UyguncaAdmin\\node_modules\\loopback-datasource-juggler\\node_modules\\async\\lib\\async.js:153:20)\n at allCb (c:\\NodeJS\\UyguncaAdmin\\node_modules\\loopback-datasource-juggler\\lib\\dao.js:1394:13)\n at c:\\NodeJS\\UyguncaAdmin\\node_modules\\loopback-connector-mysql\\node_modules\\loopback-connector\\lib\\sql.js:1071:7\n at c:\\NodeJS\\UyguncaAdmin\\node_modules\\loopback-datasource-juggler\\lib\\observer.js:166:22\n at doNotify (c:\\NodeJS\\UyguncaAdmin\\node_modules\\loopback-datasource-juggler\\lib\\observer.js:93:49)\n at MySQL.ObserverMixin._notifyBaseObservers (c:\\NodeJS\\UyguncaAdmin\\node_modules\\loopback-datasource-juggler\\lib\\observer.js:116:5)\n at MySQL.ObserverMixin.notifyObserversOf (c:\\NodeJS\\UyguncaAdmin\\node_modules\\loopback-datasource-juggler\\lib\\observer.js:91:8)"}}
I want to send more user-friendly page includes message like "Confirmation mail timed out ...".
I try to use "afterRemote" method, but it does not work. I cant get "in confirm afterRemote" message.
MyUser.afterRemote('confirm', function(ctx, inst, next) {
console.log('in confirm afterRemote...');
next(); });
Is there any way to do this? What is wrong with this afterRemote method?
Edit your server/config.json
and set "disableStackTrace": true and "disableStatusCode": true
under errorHandler section look below example
Don't forget to vote ;-)
Cheers
{
"restApiRoot": "/api",
"host": "0.0.0.0",
"port": 4000,
"remoting": {
"context": {
"enableHttpContext": false
},
"rest": {
"normalizeHttpPath": false,
"xml": false
},
"json": {
"strict": false,
"limit": "100kb"
},
"urlencoded": {
"extended": true,
"limit": "100kb"
},
"cors": {
"origin": true,
"credentials": true
},
"errorHandler": {
"disableStackTrace": true,
"disableStatusCode": true
}
}
}

Resources