curl -X POST with JSON how can I filtered Integer with less then or greater then (API is from Zabbix)" - json

i try to make a "maintenance.get" on Zabbix and what I need is the current active maintenance. which just working is:
curl --noproxy '*' -H "Content-Type: application/json" -X POST http://local.zabbix.lan/api_jsonrpc.php -d'
{
"jsonrpc": "2.0",
"method": "maintenance.get",
"params": {
"output": "extend",
"search": {
"name": ["Auto_"]
},
"filter": {
"active_till": "1657562960"
}
}
},
"auth": "07fxxx574444444444a65034c6xxxxx0",
"id": 1
}
' | sed 's/","/\n/g'
{"jsonrpc":"2.0
result":[{"maintenanceid":"199
name":"Auto_Maintenance_2022-07-11_16:56:53\u00b4
maintenance_type":"0
description":"
active_since":"1657551360
active_till":"1657572960
tags_evaltype":"0
timeperiods":[{"timeperiodid":"199
timeperiod_type":"3
every":"1
month":"0
dayofweek":"64
day":"0
start_time":"64800
period":"3600
start_date":"0"}]},{"maintenanceid":"200
name":"Auto_Maintenance_2022-07-11_17:51:06
maintenance_type":"0
description":"
active_since":"1657554660
active_till":"1657558260
tags_evaltype":"0
timeperiods":[{"timeperiodid":"200
timeperiod_type":"3
every":"1
month":"0
dayofweek":"64
day":"0
start_time":"64800
period":"3600
start_date":"0"}]}],"id":1}
but I get the whole list. I would need set a greater than operator to get only the number greater from today (so date in the future). what I tried with my knowledge is that but unfortunately it does not work:
{
"jsonrpc": "2.0",
"method": "maintenance.get",
"params": {
"output": "extend",
"search": {
"name": ["Auto_"]
},
"filter": {
"active_till": {
">=": [1657562960]
}
}
},
"auth": "07f186572af264203ba65034c6cc83a0",
"id": 1
}

Related

jq map object fields from TeemIP IPAM databese to fields for Kea DHCP server

How to transform data about PCs from TeemIP IPAM database, to feed it to Kea DHCP server as reservations with jq.
This is the data I would like to transform
{
"objects": {
"PC::8": {
"code": 0,
"message": "",
"class": "PC",
"key": "8",
"fields": {
"name": "ntb",
"macaddress": "50:74:9d:b5:5f:5d",
"ipaddress_id_friendlyname": "10.1.1.6"
}
},
"PC::7": {
"code": 0,
"message": "",
"class": "PC",
"key": "7",
"fields": {
"name": "pc",
"macaddress": "00:11:c0:92:ab:0e",
"ipaddress_id_friendlyname": "10.1.70.70"
}
}
},
"code": 0,
"message": "Found: 2"
}
to this output
{
"hostname": "ntb",
"hw-address": "50:74:9d:b5:5f:5d",
"ip-address": "10.1.1.6"
},
{
"hostname": "pc",
"hw-address": "00:11:c0:92:ab:0e",
"ip-address": "10.1.70.70"
}
I've tried something like
cat pcs.json |jq '[.[]]|.[]|.[]|.[]|.[]|map(.)|{hostname: .name, hw-address: .macaddress, ip-address: .ipaddress_id_friendlyname}'
But I was not successful by any means. I'm total noob with json. Please help.
Navigate to and iterate over the target items using .objects[].fields, and construct your objects:
jq '
.objects[].fields | {
hostname: .name,
"hw-address": .macaddress,
"ip-address": .ipaddress_id_friendlyname
}
'
{
"hostname": "ntb",
"hw-address": "50:74:9d:b5:5f:5d",
"ip-address": "10.1.1.6"
}
{
"hostname": "pc",
"hw-address": "00:11:c0:92:ab:0e",
"ip-address": "10.1.70.70"
}
Demo
This produces a so-called stream of objects (no commas in between). If you rather wanted an array of objects (enclosed in square brackets, and its items delimited by commas), just surround the whole filter with a pair of brackets.

Error when invoke a PATCH command to Orion Context Broker

We're trying to invoke commands from Orion to IoT Device using PATCH and POST requests, but we're always having the following error:
Error [MANDATORY_PARAMS_NOT_FOUND] handing request:
Some of the mandatory params weren't found in the request: ["API Key","Device Id","Payload"]
Steps:
Create a "Device Entity" in Orion Context Broker
Provisioning a new Device
Create a Service in IoT JSON Agent
{
"services": [
{
"apikey": "my_api_key",
"protocol": [
"IoTA-JSON"
],
"cbroker": "orion:1026",
"entity_type": "Device",
"resource": "/iot/json"
}
]
}
Send a POST request to http://iot-agent-host:4041/v2/op/update to execute a command, via gateway, into the IoT Device (Works OK):
{
"actionType": "update",
"entities": [
{
"id": "shelly-1pm-test",
"type": "Device",
"cmd": {
"type": "command",
"value": {
"turn": "off",
"idDevice": "device001"
}
}
}
]
}
Send a PATCH request to http://context-broker-host:1026/v2/entities/entity-name/attrs to execute a command, via Orion CB, into the IoT Device, getting 204 in the response:
{
"cmd": {
"type": "command",
"value": {
"turn": "off",
"idDevice": "98cdac2e6101"
}
}
}
The command is not executed. Viewing the IoT JSON Agent logfile we can see:
[MANDATORY_PARAMS_NOT_FOUND] handing request: Some of the mandatory params weren't found in the request: ["API Key","Device Id","Payload"]
Any ideas?
Thanks in advance
MANDATORY_PARAMS_NOT_FOUND is an error message specific to the IoT Agent for JSON. It is usually invoked by an incoming measure which has failed to supply the necessary anti-spoofing information. It should not occur when a command is sent. You have not supplied the actuator provisioning call, but I assume it is something like this:
curl -L -X POST 'http://localhost:4041/iot/devices' \
-H 'fiware-service: openiot' \
-H 'fiware-servicepath: /' \
-H 'Content-Type: application/json' \
--data-raw '{
"devices": [
{
"device_id": "bell001",
"entity_name": "urn:ngsi-ld:Bell:001",
"entity_type": "Bell",
"protocol": "PDI-IoTA-JSON",
"transport": "HTTP",
"endpoint": "http://my-device/iot/bell001",
"commands": [
{
"name": "ring",
"type": "command"
}
]
}
]
}'
Where http://my-device/iot/bell001 is the listening endpoint of the actuator. At a guess your device is responding to this by sending a response to http://iot-agent/iot/json - probably a GET - specifically a response without i or k or d parameters.
i: is the device ID.
k: the API Key for the device's service.
d: the data payload
If you set the IOTA_LOG_LEVEL=DEBUG, the following transactions should occur:
Incoming Request:
op=IoTAgentNGSI.ContextServer-v2 | from=n/a | srv=openiot | subsrv=/ | msg=Handling v2 update from [iot-agent:4041] | comp=IoTAgent
op=IoTAgentNGSI.ContextServer-v2 | from=n/a | srv=openiot | subsrv=/ | msg={
"entities": [
{
"id": "Bell:001",
"type": "Bell",
"ring": {
"type": "command",
"value": "",
"metadata": {}
}
}
],
"actionType": "update"
} | comp=IoTAgent
Actuation Request:
op=IoTAgentNGSI.Request | from=n/a | srv=n/a | subsrv=n/a | msg=Options: {
"url": "http://iot-sensors:3001/iot/bell001",
"method": "POST",
"body": "{ring:''}",
"headers": {
"fiware-service": "openiot",
"fiware-servicepath": "/",
"content-type": "application/json"
},
"responseType": "text"
} | comp=IoTAgent
Set status to pending
op=IoTAgentNGSI.Entities-v2 | from=n/a | srv=n/a | subsrv=n/a | msg=Using the following NGSI v2 request:
{
"url": "http://orion:1026/v2/entities/Bell:001/attrs?type=Bell",
"method": "PATCH",
"headers": {
"fiware-service": "openiot",
"fiware-servicepath": "/"
},
"json": {
"ring_status": {
"type": "commandStatus",
"value": "PENDING",
"metadata": {
"TimeInstant": {
"type": "DateTime",
"value": "2022-07-12T06:47:59.795Z"
}
}
}
}
If the device responds with 200, set status to OK
op=IoTAgentNGSI.Entities-v2 | from=n/a | srv=openiot | subsrv=/ | msg=Updating device value in the Context Broker at [http://orion:1026/v2/op/update] | comp=IoTAgent
op=IoTAgentNGSI.Entities-v2 | from=n/a | srv=openiot | subsrv=/ | msg=Using the following NGSI v2 request:
2022-07-12T06:47:59.944482296Z
{
"url": "http://orion:1026/v2/op/update",
"method": "POST",
"headers": {
"fiware-service": "openiot",
"fiware-servicepath": "/"
},
"json": {
"actionType": "update",
"entities": [
{
"ring_status": {
"type": "commandStatus",
"value": "OK",
"metadata": {
"TimeInstant": {
"type": "DateTime",
"value": "2022-07-12T06:47:59.942Z"
}
}
},
"ring_info": {
"type": "commandResult",
"value": " ring OK",
"metadata": {
"TimeInstant": {
"type": "DateTime",
"value": "2022-07-12T06:47:59.942Z"
}
}
}
]
}
}
I'm guessing that your device is responding incorrectly to the actuation request (number 2 in the list)

jq command to add onto a map

Is there a command to use jq to add onto this type of map?
append an array of maps using keys (ie, vm1, vm2, vm3)
Note: I have an existing vm_map {} in a json file and i want to add to the vm_map
this is my new_json.json file
{
"gcs_config": [
{
"bucket_name": "somebucket",
"bucket_readers": [],
"bucket_writers": []
}
],
"label_application": "someapp",
"label_environment": "dev",
"lits_vm_zone": "somezone",
"project_id": "someproject",
"region": "someregion",
"storage_bucket_required": true,
"vm_map" : {}
}
expected: using jq to add onto vm_maps map. I will have an empty vm_map and each time it runs, i will add a x amount of new entries.
{
"gcs_config": [
{
"bucket_name": "somebucket",
"bucket_readers": [],
"bucket_writers": []
}
],
"label_application": "someapp",
"label_environment": "dev",
"lits_vm_zone": "zone-a",
"project_id": "someproject",
"region": "someregion",
"storage_bucket_required": true,
"vm_map": {
"vm1": {
"host": "vm1",
"network": "10.1.1.1",
"name": "vm1"
},
"vm2": {
"host": "123",
"network": "10.1.12",
"name": "vm2"
}
}
}
The file you describe is not valid JSON. I'm assuming you mean
{
"vm_map": {
"vm1": {
"host": "vm1",
"network": "xxxxx",
"name": "xxxxxxx"
},
"vm2": {
"host": "vm2",
"network": "xxxxx",
"name": "xxxxxxx"
}
}
}
You can use this:
jq \
--arg VMHOST "$VMHOST" \
--arg NETWORK_IP "$NETWORK_IP" \
--arg VM_NAME "$VM_NAME" \
'
.vm_map[ $VMHOST ] = {
host: $VMHOST,
network: $NETWORK_IP,
name: $VM_NAME
}
'

Convert timestamps in JSON string with Bash commands

I have the following string as below:
{
"name": {
"value": "Demo"
},
"activity": {
"value": "CLOSED",
"timestamp": "2020-11-19T10:58:17.534+0000"
},
"state": {
"value": "OK",
"timestamp": "2020-11-19T10:58:17.570+0000"
},
"lastErrorCode": {
"value": "NO_MESSAGE",
"timestamp": "2020-11-19T10:58:17.570+0000"
}
}
How can I convert all timestamps in that string to another format (Timezone)? Example like (on cmd line):
echo '2020-11-19T10:58:17.534+0000' | xargs date +'%Y-%m-%d %H:%M:%S' -d
results in:
2020-11-19 11:58:17
That string of yours is actually a JSON(-string). Please use a tool that supports JSON and can do dateTime-conversions, like xidel.
First of all, the value of the timestamp-keys is not a valid dateTime. You'd have to change the timezone property 0000 to 00:00 to make it a valid one:
$ xidel -s input.json -e '
for $x in $json//timestamp return
dateTime(replace($x,"0000","00:00"))
'
2020-11-19T10:58:17.534Z
2020-11-19T10:58:17.57Z
2020-11-19T10:58:17.57Z
Then to change the timezone to +01:00 use adjust-dateTime-to-timezone():
$ xidel -s input.json -e '
for $x in $json//timestamp return
adjust-dateTime-to-timezone(
dateTime(replace($x,"0000","00:00")),
duration("PT1H")
)
'
2020-11-19T11:58:17.534+01:00
2020-11-19T11:58:17.57+01:00
2020-11-19T11:58:17.57+01:00
(You can remove duration("PT1H") if your timezone already is +01:00)
Finally to customize your output use format-dateTime():
$ xidel -s input.json -e '
for $x in $json//timestamp return
format-dateTime(
adjust-dateTime-to-timezone(
dateTime(replace($x,"0000","00:00")),
duration("PT1H")
),
"[Y]-[M01]-[D01] [H01]:[m01]:[s01]"
)
'
2020-11-19 11:58:17
2020-11-19 11:58:17
2020-11-19 11:58:17
If instead you want to update the JSON with these customized dateTimes... that can be done, but requires a more advanced recursive function:
$ xidel -s input.json --xquery '
declare function local:change-timestamp($a){
if (exists($a)) then
if ($a instance of map(*)) then
map:merge(
map:keys($a) ! map{
.:if (.="timestamp") then
format-dateTime(
adjust-dateTime-to-timezone(
dateTime(replace($a(.),"0000","00:00")),
duration("PT1H")
),
"[Y]-[M01]-[D01] [H01]:[m01]:[s01]"
)
else
local:change-timestamp($a(.))
}
)
else
$a
else
()
};
local:change-timestamp($json)
'
{
"name": {
"value": "Demo"
},
"activity": {
"value": "CLOSED",
"timestamp": "2020-11-19 11:58:17"
},
"state": {
"value": "OK",
"timestamp": "2020-11-19 11:58:17"
},
"lastErrorCode": {
"value": "NO_MESSAGE",
"timestamp": "2020-11-19 11:58:17"
}
}
Also check the xidel playground.
Should be possible using regex. Something like this:
str='{
"name": {
"value": "Demo"
},
"activity": {
"value": "CLOSED",
"timestamp": "2020-11-19T10:58:17.534+0000"
},
"state": {
"value": "OK",
"timestamp": "2020-11-19T10:58:17.570+0000"
},
"lastErrorCode": {
"value": "NO_MESSAGE",
"timestamp": "2020-11-19T10:58:17.570+0000"
}
}'
re='(.*?-[0-9]+-[0-9]+)T([0-9:]+)(\.[0-9+]+)(.*)'
while [[ $str =~ $re ]]; do
str="${BASH_REMATCH[1]} ${BASH_REMATCH[2]}${BASH_REMATCH[4]}"
done
echo "$str"
Returns:
{
"name": {
"value": "Demo"
},
"activity": {
"value": "CLOSED",
"timestamp": "2020-11-19 10:58:17"
},
"state": {
"value": "OK",
"timestamp": "2020-11-19 10:58:17"
},
"lastErrorCode": {
"value": "NO_MESSAGE",
"timestamp": "2020-11-19 10:58:17"
}
}

Add or Update a field in one JSON file from another JSON file based on matching field

I have two JSON files a.json and b.json. The contents in a.json file is a JSON object and inside b.json its an array.I want to add/update status field in each mappings in a.json by retrieving the value from b.json file.
a.json:
{
"title": 25886,
"data": {
"request": {
"c": 46369,
"t1": 1562050127.376641
},
},
"rs": {
"mappings": {
"12345": {
"id": "12345",
"name": "test",
"customer_id": "11228",
},
"45678": {
"id": "45678",
"name": "abc",
"customer_id": "11206",
}
}
}}
b.json:
[
{
"status": "pending",
"extra": {
"name": "test"
},
"enabled": true,
"id": "12345"
},
{
"status": "not_started",
"extra": {
"name": "abc"
},
"enabled": true,
"id": "45678"
}
]
Below is my expected output:
{
"title": 25886,
"data": {
"request": {
"c": 46369,
"t1": 1562050127.376641
},
},
"rs": {
"mappings": {
"12345": {
"id": "12345",
"name": "test",
"customer_id": "11228",
"status":"pending"
},
"45678": {
"id": "45678",
"name": "abc",
"customer_id": "11206",
"status":"not_started"
}
}
}}
In this expected JSON file we have status field whose value is retrieved from b.json file based on a matching id value. How to do this using jq ?
For the purposes of this problem, b.json essentially defines a dictionary, so for simplicity, efficiency and perhaps elegance,
it make sense to start by using the builtin function INDEX to create the relevant dictionary:
INDEX( $b[] | {id, status}; .id )
This assumes an invocation of jq along the lines of:
jq --argfile b b.json -f update.jq a.json
(Yes, I know --argfile has been deprecated. Feel free to choose another way to set $b to the contents of b.json.)
Now, to perform the update, it will be simplest to use the "update" operator, |=, in conjunction with map_values. (Feel free to check the jq manual :-)
Putting everything together:
INDEX( $b[] | {id, status}; .id ) as $dict
| .rs.mappings |= map_values( .status = $dict[.id].status )