3. Objects Management#
This section is about managing the objects that can be targetted using the following JSON RPC url:
/pm/config/adom/{adom}/obj/{path_to_object}
/pm/config/global/obj/{path_to_object}
3.1. How to reference objects when names have special characters?#
It is required to escape the special character using the \\
(double
back-slash) notation.
For instance to update the Net_10.0.0.0/18
(where /
is the special
character) located in the root
ADOM:
{
"id": 4,
"method": "update",
"params": [
{
"url": "pm/config/adom/root/obj/firewall/address/Net_10.0.0.0\\/18",
"data": {
"subnet": "10.0.0.0/255.255.255.0",
}
}
],
"session": "{{session}}",
}
3.2. Metadata#
Metadata object has been introduced in FortiManager 7.2.0 to replace the Meta fields.
3.2.1. How to add a metadata?#
We add metadata site_id
with default value 0
in ADOM root
:
REQUEST:
{
"id": 3,
"method": "add",
"params": [
{
"data": {
"name": "site_id",
"value": "0"
},
"url": "/pm/config/adom/root/obj/fmg/variable"
}
],
"session": "uY6pkBTKxePxylSULcalT0qJWJ2Wpot75EMoQurXIk1lInRrfOpUw2/Ry6L2H/AGeKyr75k6i5x4xSeg4qN/Gg=="
}
Warning
The
value
attribute has to be set with astring
.
RESPONSE:
{
"id": 3,
"result": [
{
"data": {
"name": "site_id"
},
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/root/obj/fmg/variable"
}
]
}
3.2.2. How to delete a metadata?#
We delete metadata site_id
from ADOM root
:
REQUEST:
{
"id": 3,
"method": "delete",
"params": [
{
"url": "/pm/config/adom/root/obj/fmg/variable/site_id"
}
],
"session": "VhmbOYvjWhsmSXtHHkp1298dkvfaAt7cUQbUBLKqpTfN4/oqntbOLxtQvYnIhvtTdm9Xa8mlv+U5NxVKDJvd9Q=="
}
RESPONSE:
{
"id": 3,
"result": [
{
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/root/obj/fmg/variable/site_id"
}
]
}
3.2.3. How to assign a metadata to devices?#
For a single device:
We add a per-device mapping to metadata
site_id
for devicesite_001
in ADOMroot
. The value will be1
.REQUEST:
{ "id": 3, "method": "add", "params": [ { "data": [ { "_scope": [ { "name": "site_001", "vdom": "global" } ], "value": "1" } ], "url": "/pm/config/adom/root/obj/fmg/variable/site_id/dynamic_mapping" } ], "session": "1UFghhT0KF8dDRHAhCfP87MqAVZOwfDpOFyo1wLKLhYWfrNaMZPnkvcAKtmZUw6a9CHYVTRblay/iQjddRTrNg==" }
Warning
The
value
attribute has to be set with astring
.
RESPONSE:
{ "id": 3, "result": [ { "data": { "_scope": null }, "status": { "code": 0, "message": "OK" }, "url": "/pm/config/adom/root/obj/fmg/variable/site_id/dynamic_mapping" } ] }
For multiple devices
We add per-device mapping to metadata
site_id
for devicessite_002
andsite_003
, and their respective VDOMroot
for both, in ADOMroot
. New values will be2
and3
respectively:REQUEST:
{ "id": 3, "method": "add", "params": [ { "data": [ { "_scope": [ { "name": "site_002", "vdom": "root" } ], "value": "2" }, { "_scope": [ { "name": "site_003", "vdom": "root" } ], "value": "3" } ], "url": "/pm/config/adom/root/obj/fmg/variable/site_id/dynamic_mapping" } ], "session": "3xU3/QYJvng9a91JN0Ivzi0XY6RPyvrYxtfa4xPjJTKwvVQQAs0VG9aTjf6ozgqEYcCMF7xvhRKe27J43btpEQ==" }
Warning
The
value
attribute has to be set with astring
.
RESPONSE:
{ "id": 3, "result": [ { "status": { "code": 0, "message": "OK" }, "url": "/pm/config/adom/root/obj/fmg/variable/site_id/dynamic_mapping" } ] }
3.2.4. How to assign metadatas at Model Device creation time?#
It can be exposed by using the following FortiManager CLI debug command:
diagnose debug service dvmcmd 255
diagnose debug
{
"client": "gui json:23235",
"id": "57337fc8-5029-4458-b100-18cddddb707b",
"keep_session_idle": 1,
"method": "exec",
"params": [
{
"data": {
"add-dev-list": [
{
"_platform": "FortiGate-VM64-KVM",
"adm_pass": "******",
"adm_usr": "admin",
"desc": "Model device",
"device action": "add_model",
"device blueprint": "BRANCHES",
"extra commands": [
{
"id": 1,
"method": "set",
"params": [
{
"data": {
"_scope": {
"name": "BRANCH_03",
"vdom": "global",
"vdom_oid": 1
},
"value": "10.200.1.3"
},
"url": "pm/config/adom/DEMO/obj/fmg/variable/BGP_LOOPBACK/dynamic_mapping"
}
]
},
{
"id": 1,
"method": "set",
"params": [
{
"data": {
"_scope": {
"name": "BRANCH_03",
"vdom": "global",
"vdom_oid": 1
},
"value": ""
},
"url": "pm/config/adom/DEMO/obj/fmg/variable/INET1_IP/dynamic_mapping"
}
]
},
{
"id": 1,
"method": "set",
"params": [
{
"data": {
"_scope": {
"name": "BRANCH_03",
"vdom": "global",
"vdom_oid": 1
},
"value": ""
},
"url": "pm/config/adom/DEMO/obj/fmg/variable/INET2_IP/dynamic_mapping"
}
]
},
{
"id": 1,
"method": "set",
"params": [
{
"data": {
"_scope": {
"name": "BRANCH_03",
"vdom": "global",
"vdom_oid": 1
},
"value": "10.71.144.1/24"
},
"url": "pm/config/adom/DEMO/obj/fmg/variable/MPLS_IP/dynamic_mapping"
}
]
},
{
"id": 1,
"method": "set",
"params": [
{
"data": {
"_scope": {
"name": "BRANCH_03",
"vdom": "global",
"vdom_oid": 1
},
"value": "10.0.3.1/24"
},
"url": "pm/config/adom/DEMO/obj/fmg/variable/LAN_IP/dynamic_mapping"
}
]
},
{
"id": 1,
"method": "set",
"params": [
{
"data": {
"_scope": {
"name": "BRANCH_03",
"vdom": "global",
"vdom_oid": 1
},
"value": "10.0.31.1/24"
},
"url": "pm/config/adom/DEMO/obj/fmg/variable/VLAN1_IP/dynamic_mapping"
}
]
},
{
"id": 1,
"method": "set",
"params": [
{
"data": {
"_scope": {
"name": "BRANCH_03",
"vdom": "global",
"vdom_oid": 1
},
"value": "10.0.32.1/24"
},
"url": "pm/config/adom/DEMO/obj/fmg/variable/VLAN2_IP/dynamic_mapping"
}
]
},
{
"id": 1,
"method": "set",
"params": [
{
"data": {
"_scope": {
"name": "BRANCH_03",
"vdom": "global",
"vdom_oid": 1
},
"value": "10.0.33.1/24"
},
"url": "pm/config/adom/DEMO/obj/fmg/variable/VLAN3_IP/dynamic_mapping"
}
]
},
{
"id": 1,
"method": "set",
"params": [
{
"data": {
"_scope": {
"name": "BRANCH_03",
"vdom": "global",
"vdom_oid": 1
},
"value": "172.16.31.42/24"
},
"url": "pm/config/adom/DEMO/obj/fmg/variable/OOB/dynamic_mapping"
}
]
},
{
"id": 1,
"method": "set",
"params": [
{
"data": {
"_scope": {
"name": "BRANCH_03",
"vdom": "global",
"vdom_oid": 1
},
"value": "140"
},
"url": "pm/config/adom/DEMO/obj/fmg/variable/VLAN_BASE/dynamic_mapping"
}
]
}
],
"faz.perm": 15,
"faz.quota": 0,
"groups": [
"BRANCHES"
],
"is_vm": true,
"mgmt_mode": 3,
"mr": 2,
"name": "BRANCH_03",
"os_type": 0,
"os_ver": 7,
"sn": "FGVM08TM23000464"
}
],
"adom": "DEMO",
"flags": [
"create_task",
"nonblocking",
"log_dev"
]
},
"target start": 2,
"url": "/dvm/cmd/add/dev-list"
}
],
"session": 52098
}
3.2.5. How to unassign a metadata?#
We delete per-device mapping for device
site_001
in ADOMroot
REQUEST:
{ "id": 3, "method": "delete", "params": [ { "url": "/pm/config/adom/root/obj/fmg/variable/site_id/dynamic_mapping/site_001/global" } ], "session": "DeDg35oRLquI5LoY6jegKxzO30MuvijlQofAK7GSsVE2aHhdemGk7qmscZp9FlvFPsadu3fO9nyfhYf9asv4sA==" }
RESPONSE:
{ "id": 3, "result": [ { "status": { "code": 0, "message": "OK" }, "url": "/pm/config/adom/root/obj/fmg/variable/site_id/dynamic_mapping/site_001/global" } ] }
3.2.6. How to replace assigned device with another one?#
In ADOM root
, we have a metadata site_id
assigned to device
site_003
scope global
with value 3
:
REQUEST:
{
"id": 3,
"method": "get",
"params": [
{
"url": "/pm/config/adom/root/obj/fmg/variable/site_id/dynamic_mapping/site_003/global"
}
],
"session": "lSwBO+josIsWGTLgfPunWDUhI1yhnYXmsOexJszAjOrZgrAwcgSHmaLUcz8kgcwa+DTFdiPmJPQd6p6uhbDBRA=="
}
RESPONSE:
{
"id": 3,
"result": [
{
"data": {
"_scope": [
{
"name": "site_003",
"vdom": "global"
}
],
"oid": 3989,
"value": "3"
},
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/root/obj/fmg/variable/site_id/dynamic_mapping/site_003/global"
}
]
}
We replace devicee site_003
scope global
with device site_002
vdom
root
. Both value
and oid
shouldn’t be modified:
REQUEST:
{
"id": 3,
"method": "set",
"params": [
{
"data": [
{
"name": "site_002",
"vdom": "root"
}
],
"url": "/pm/config/adom/root/obj/fmg/variable/site_id/dynamic_mapping/site_003/global/_scope"
}
],
"session": "Wx30e3o21dbA577ZQC4uEWr2FxdYJNycLfL2JGZ8oa9x7p7/0W+catuBCyXJB6Rq3Y0vDQSWr4UIOpig3Q6TUzawM01Jsanb"
}
RESPONSE:
{
"id": 3,
"result": [
{
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/root/obj/fmg/variable/site_id/dynamic_mapping/site_003/global/_scope"
}
]
}
We can double check: both value
and oid
are still with same value as
before the replace operation:
REQUEST:
{
"id": 3,
"method": "get",
"params": [
{
"url": "/pm/config/adom/root/obj/fmg/variable/site_id/dynamic_mapping/site_002/root"
}
],
"session": "GDbXiJQeLFHJn353tBpV8dTv0j/YBBHvjN/diKqSn6SNkY9H2HUy+5tResAiNQgLGOGX2HXMaUwLJJQ57t0Jwg=="
}
RESPONSE:
{
"id": 3,
"result": [
{
"data": {
"_scope": [
{
"name": "site_002",
"vdom": "root"
}
],
"oid": 3989,
"value": "3"
},
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/root/obj/fmg/variable/site_id/dynamic_mapping/site_002/root"
}
]
}
3.2.7. How to get the value of a metadata for a specific device/vdom?#
We get the value of metadata site_id
for device site_001
and its global
scope from ADOM root
:
REQUEST:
{
"id": 3,
"method": "get",
"params": [
{
"url": "/pm/config/adom/root/obj/fmg/variable/site_id/dynamic_mapping/site_001/global"
}
],
"session": "iQ+NZu8QXUBKYgM9xUrzqCoHKx3l5SpClqociYCkl/b8GQNN2x9YReV6BsmIMiqgJs3rLpyvNjcBzu021YPh7A==",
"verbose": 1
}
RESPONSE:
{
"id": 3,
"result": [
{
"data": {
"_scope": [
{
"name": "site_001",
"vdom": "global"
}
],
"oid": 3934,
"value": "1"
},
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/root/obj/fmg/variable/site_id/dynamic_mapping/site_001/global"
}
]
}
We get the value of metadata site_id
for device site_002
and its VDOM
root
from ADOM root
:
REQUEST:
{
"id": 3,
"method": "get",
"params": [
{
"url": "/pm/config/adom/root/obj/fmg/variable/site_id/dynamic_mapping/site_002/root"
}
],
"session": "iQ+NZu8QXUDbEN3utJr/yA3FEKeC10AoEByuOehZ/eQhLjBl0boh2U9MCh8eI78aNTOIV+3SbjGXg+D0MkSgXQ==",
"verbose": 1
}
RESPONSE:
{
"id": 3,
"result": [
{
"data": {
"_scope": [
{
"name": "site_002",
"vdom": "root"
}
],
"oid": 3745,
"value": "2"
},
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/root/obj/fmg/variable/site_id/dynamic_mapping/site_002/root"
}
]
}
3.2.8. How to set multiple metadatas for one device?#
It is possible to use a single FortiManager JSON RPC API request.
The following example set the var_01
and var_02
metadata variables from
the dc_amer
ADOM for the dev_02
managed device:
REQUEST:
{
"id": 3,
"method": "add",
"params": [
{
"data": {
"_scope": [
{
"name": "dev_02",
"vdom": "global"
}
],
"value": "var_01_dev_02"
},
"url": "/pm/config/adom/dc_amer/obj/fmg/variable/var_01/dynamic_mapping"
},
{
"data": {
"_scope": [
{
"name": "dev_02",
"vdom": "global"
}
],
"value": "var_02_dev_02"
},
"url": "/pm/config/adom/dc_amer/obj/fmg/variable/var_02/dynamic_mapping"
}
],
"session": "tVbqoJKblP/y6kd7B81wXl0qgg/40nzI5Rh4ggoUVaE8b0KT0+xw/gd3/MzcufezS749zd+L7MVIMQDxqNR/rg=="
}
RESPONSE:
{
"id": 3,
"result": [
{
"data": {
"_scope": [
{
"name": "dev_02",
"vdom": "global"
}
]
},
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/dc_amer/obj/fmg/variable/var_01/dynamic_mapping"
},
{
"data": {
"_scope": [
{
"name": "dev_02",
"vdom": "global"
}
]
},
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/dc_amer/obj/fmg/variable/var_02/dynamic_mapping"
}
]
}
Note
Of course, existing per-device mappings for the
var_01
andvar_02
metadata variables are preserved.
3.2.9. How to assign a global metadata?#
Global ADOM is having the global metadata g_hostname
.
To assign it to ADOM root
, adom_70_001
and adom_72_001
:
REQUEST:
{
"id": 3,
"method": "exec",
"params": [
{
"data": {
"adom": "global",
"category": 3200,
"flags": "none",
"objs": [
"g_hostname"
],
"scope": [
{
"adom": "root"
},
{
"adom": "adom_70_001"
},
{
"adom": "adom_72_001"
}
],
"target": [
{
"adom": "root"
},
{
"adom": "adom_70_001"
},
{
"adom": "adom_72_001"
}
]
},
"url": "/securityconsole/assign/objs"
}
],
"session": "tshDOEgzpF26vjcMeyDha3MSpwg570lSrbKirRk1wkdLIToAZOgkWOw6xlIhawjUoMKkOZNAS49AQqiRWMzdtyZHSQg1POJs"
}
where category
is the number of the table fmg variable
.
You can get this number by issuing following command:
execute fmpolicy print-adom-object Global ?
In the output, you will see this line:
[...]
3200 "fmg variable"
[...]
RESPONSE:
{
"id": 3,
"result": [
{
"data": {
"task": 54
},
"status": {
"code": 0,
"message": "OK"
},
"url": "/securityconsole/assign/objs"
}
]
}
3.3. Firewall Address#
3.3.1. How to add a FQDN firewall address?#
To add FQDN www.foobar.com
in ADOM adom_70_001
:
REQUEST:
{
"id": 3,
"method": "add",
"params": [
{
"data": {
"color": 2,
"fqdn": "www.foobar.com",
"name": "fqdn_001",
"type": "fqdn"
},
"url": "/pm/config/adom/adom_70_001/obj/firewall/address"
}
],
"session": "FhdDcem5V4cjJZeGggJ36dn5fME4nxr4rkA0zojtu+c31+wGhWl2zhhhE2hyP/MAXWQQzNE1yUgQOrJ3eTH7SQ=="
}
RESPONSE:
{
"id": 3,
"result": [
{
"data": {
"name": "fqdn_001"
},
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/adom_70_001/obj/firewall/address"
}
]
}
3.4. Firewall Address Groups#
3.4.1. How to add a single member#
We add firewall address host_004
in the existing address group foobar
from ADOM adom_dc2
:
REQUEST:
{
"id": 3,
"method": "add",
"params": [
{
"data": [
"host_004"
],
"url": "/pm/config/adom/adom_dc2/obj/firewall/addrgrp/foobar/member"
}
],
"session": "mZMkY72ZIYcs8QInB0h5CUILmCKWCesbvxXJ3P/t+JSrzBh32BV/HvCU7BNMp4GLe8/5vO1qNAoRlsSytXUlTw=="
}
RESPONSE:
{
"id": 3,
"result": [
{
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/adom_dc2/obj/firewall/addrgrp/foobar/member"
}
]
}
3.4.2. How to delete a single member#
We delete firewall address host_004
from the existing address group foobar
from ADOM adom_dc2
:
REQUEST:
{
"id": 3,
"method": "delete",
"params": [
{
"data": [
"host_004"
],
"url": "/pm/config/adom/adom_dc2/obj/firewall/addrgrp/foobar/member"
}
],
"session": "5uNGBXEMc+cNXjSlx6RuyxE623Nul3hGTCEgeA7pONsNhMMEL1lxCUG7q2TVfnhD0BZiwMg+CgKpWuVY2k0oew=="
}
RESPONSE:
{
"id": 3,
"result": [
{
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/adom_dc2/obj/firewall/addrgrp/foobar/member"
}
]
}
3.4.3. How to delete all members?#
Note
You can delete all members because since FortiOS 7.2.0 (Internal Reference #0769154), you can operate an empty
firewall addrgrp
object
3.4.3.1. Using the unset
method#
The following example shows how to delete all members from othe grp_001
firewall addrgrp in the demo
ADOM using the unset
method
:
{
"id": 3,
"method": "unset",
"params": [
{
"url": "/pm/config/adom/demo/obj/firewall/addrgrp/grp_001/member"
}
],
"session": "{{session}}"
}
{
"id": 3,
"result": [
{
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/demo/obj/firewall/addrgrp/grp_001/member"
}
]
}
3.4.3.2. Using the unset attrs
#
The following example shows how to delete all members from othe grp_001
firewall addrgrp in the demo
ADOM using the unset attrs
described in How to unset a specific attribute?:
{
"id": 3,
"method": "set",
"params": [
{
"data": {
"unset attrs": [
"member"
]
},
"url": "/pm/config/adom/demo/obj/firewall/addrgrp/grp_001"
}
],
"session": "{{session}}"
}
{
"id": 3,
"result": [
{
"data": {
"name": "grp_001"
},
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/demo/obj/firewall/addrgrp/grp_001"
}
]
}
3.5. Wildcard FQDN#
3.5.1. How to add a wildcard FQDN?#
To add wilcard FQDN *.foobar.*
to ADOM adom_70_001
:
REQUEST:
{
"id": 3,
"method": "add",
"params": [
{
"data": {
"color": 3,
"name": "w_fqdn_001",
"wildcard-fqdn": "*.foobar.*",
},
"url": "/pm/config/adom/adom_70_001/obj/firewall/wildcard-fqdn/custom"
}
],
"session": "/CPDFD77zdvbfmX5tI0OwZ6mEha6Zcfsn1qPaITMmr43uysUgPlNBK5TgUIXFYQcoQXwF0w2oh1XcKRUnB2BMg=="
}
RESPONSE:
{
"id": 3,
"result": [
{
"data": {
"name": "w_fqdn_001"
},
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/adom_70_001/obj/firewall/wildcard-fqdn/custom"
}
]
}
3.6. Objects default values#
3.6.1. How to get the default values for a firewall address?#
REQUEST:
{
"id": 1,
"jsonrpc": "1.0",
"method": "get",
"params": [
{
"object template": 1,
"url": "/pm/config/adom/DB/obj/firewall/address"
}
],
"session": "HKERCCqx6ximKXlkWN7lxWIgqagVqpj0xXiJtFtYrpiLIL7X3nCuIdlnZw83N+N3JO95oUOOCIwE+emXMuLvcPvKXNHsVYSN",
"verbose": 1
}
3.7. How to bulk add objects?#
You have two methods:
params
multi-plexingdata
multi-plexing
3.7.1. params
multi-plexing#
REQUEST:
{
"id": 1,
"jsonrpc": "1.0",
"method": "add",
"params": [
{
"data": {
"name": "test_004",
"subnet": [
"10.0.0.4",
"255.255.255.0"
]
},
"url": "/pm/config/adom/DEMO_008/obj/firewall/address"
},
{
"data": {
"name": "test_005",
"subnet": [
"10.0.0.5",
"255.255.255.0"
]
},
"url": "/pm/config/adom/DEMO_008/obj/firewall/address"
},
{
"data": {
"name": "test_006",
"subnet": [
"10.0.0.6",
"255.255.255.0"
]
},
"url": "/pm/config/adom/DEMO_008/obj/firewall/address"
}
],
"session": "H4bqANWVw4+9ChxkRYdNfdtu4kE+5emeSojgay0fOghSwAPaFuzoBSZHjcvWc6l3TanYih4q9QktzVvLNTdpzA==",
"verbose": 1
}
RESPONSE:
{
"id": 1,
"result": [
{
"data": {
"name": "test_004"
},
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/DEMO_008/obj/firewall/address"
},
{
"data": {
"name": "test_005"
},
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/DEMO_008/obj/firewall/address"
},
{
"data": {
"name": "test_006"
},
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/DEMO_008/obj/firewall/address"
}
]
}
3.7.2. data
multi-plexing#
REQUEST:
{
"id": 1,
"jsonrpc": "1.0",
"method": "add",
"params": [
{
"data": [
{
"name": "test_001",
"subnet": [
"10.0.0.1",
"255.255.255.0"
]
},
{
"name": "test_002",
"subnet": [
"10.0.0.2",
"255.255.255.0"
]
},
{
"name": "test_003",
"subnet": [
"10.0.0.3",
"255.255.255.0"
]
}
],
"url": "/pm/config/adom/DEMO_008/obj/firewall/address"
}
],
"session": "31rAPPvgsYtaqwXnlwKZJrJQHff1V5hbfwj9lB62868KC1n73fF739Z+wTP+J5CoTxjKSWE8TqY7mTHyFovW7w==",
"verbose": 1
}
RESPONSE:
{
"id": 1,
"result": [
{
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/DEMO_008/obj/firewall/address"
}
]
}
3.8. Normalized Interfaces#
3.8.1. How to create a normalized interface?#
REQUEST:
{
"id": 1,
"jsonrpc": "1.0",
"method": "add",
"params": [
{
"data": {
"color": 2,
"default-mapping": "enable",
"defmap-intf": "ul_isp1",
"description": "Underlay over ISP #1",
"dynamic_mapping": [
{
"_scope": [
{
"name": "dut_fgt_2",
"vdom": "root"
}
],
"local-intf": [
"port1"
]
}
],
"name": "ul_isp1",
"platform_mapping": [
{
"intf-zone": "ul_isp1",
"name": "FortiGate-100F"
}
]
},
"url": "/pm/config/adom/{{adom}}/obj/dynamic/interface/ul_isp1"
}
],
"session": "{{session_id}}",
"verbose": 1
}
RESPONSE:
{
"id": 1,
"result": [
{
"data": {
"name": "ul_isp1"
},
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/knock_06999/obj/dynamic/interface/ul_isp1"
}
]
}
3.8.2. How to add a new per-platform mapping to an existing Normalized Interface?#
REQUEST:
{
"id": 3,
"method": "add",
"params": [
{
"data": {
"intf-zone": "ol_isp2",
"name": "FortiGate-40F"
},
"url": "/pm/config/adom/root/obj/dynamic/interface/ol_isp2/platform_mapping"
}
],
"session": "6hngsu9e2X+JBkpzxVIdWYPqLeYactJjmyyXeGkpkB/BlzGI8R9ynUPSP2wKFH5rTcijjR4+XBXWfliD7ichEg=="
}
RESPONSE:
{
"id": 3,
"result": [
{
"data": {
"name": "FortiGate-40F"
},
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/root/obj/dynamic/interface/ol_isp2/platform_mapping"
}
]
}
3.8.3. How to get the normalized interfaces with a per-device mapping set for a specific device?#
The following example shows how to get the list of normalized interfaces with a
per-device mapping for the dut_fgt_03
device and its root
VDOM:
{
"id": "1",
"method": "get",
"params":[
{
"url": "pm/config/adom/{{adom}}/obj/dynamic/interface",
"fields": ["name"],
"subfetch filter": 1,
"sub fetch": {
"dynamic_mapping": {
"fields": ["_scope", "local_intf"],
"subfetch count": ["==", 1],
"scope member": [
{
"name": "dut_fgt_03",
"vdom": "root"
}
]
},
"platform_mapping": {
"subfetch hidden": 1
}
}
}
],
"session": "{{session}}"
}
{
"id": "1",
"result": [
{
"data": [
{
"dynamic_mapping": [
{
"_scope": [
{
"name": "dut_fgt_03",
"vdom": "root"
}
],
"oid": 4890
}
],
"oid": 4889,
"name": "foobar"
},
{
"dynamic_mapping": [
{
"_scope": [
{
"name": "dut_fgt_03",
"vdom": "root"
}
],
"oid": 4856
}
],
"oid": 112,
"name": "wan"
}
],
"status": {
"code": 0,
"message": "OK"
},
"url": "pm/config/adom/production/obj/dynamic/interface"
}
]
}
3.8.4. How to delete an existing per-platform mapping?#
REQUEST:
{
"id": 3,
"method": "delete",
"params": [
{
"url": "/pm/config/adom/root/obj/dynamic/interface/ol_isp2/platform_mapping/FortiGate-40F"
}
],
"session": "vfIpN+LiUYGkHWcdTYcEe5RtIhDuIlw/42o9EsZ1KwNCHmSnytwa+cmTHGSJwEyYtencb3kLmFdq6AX5PK2FxQ=="
}
RESPONSE:
{
"id": 3,
"result": [
{
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/root/obj/dynamic/interface/ol_isp2/platform_mapping/FortiGate-40F"
}
]
}
3.9. How to get firewall addgrp members along with their details?#
We can use the expand datasrc
attribute.
We’re getting the member elements of our grp_003
address group:
REQUEST:
{
"id": 1,
"jsonrpc": "1.0",
"method": "get",
"params": [
{
"expand datasrc": [
{
"datasrc": [
{
"fields": [
"name",
"subnet"
],
"obj type": "firewall address"
},
{
"fields": [
"name",
"member"
],
"obj type": "firewall addrgrp"
}
],
"name": "member"
}
],
"filter": [
"name",
"==",
"grp_003"
],
"url": "/pm/config/adom/DEMO/obj/firewall/addrgrp"
}
],
"session": "mnvLPffV1QUzdQkAPo9dv5ysdS0wzcvhZMX1w8Hv9Q07XYWtTqeClXEYhLN6e0aBvfuowZ7x/2FHORh7qFs5iw==",
"verbose": 1
}
RESPONSE:
{
"id": 1,
"result": [
{
"data": [
{
"allow-routing": "disable",
"color": 0,
"comment": "",
"dynamic_mapping": null,
"exclude": "disable",
"exclude-member": [],
"member": [
{
"name": "host_005",
"obj type": "firewall address",
"subnet": [
"10.0.0.5",
"255.255.255.255"
]
},
{
"name": "host_006",
"obj type": "firewall address",
"subnet": [
"10.0.0.6",
"255.255.255.255"
]
},
{
"member": [
"host_001",
"host_002"
],
"name": "grp_001",
"obj type": "firewall addrgrp"
},
{
"member": [
"host_003",
"host_004"
],
"name": "grp_002",
"obj type": "firewall addrgrp"
}
],
"name": "grp_003",
"tagging": null,
"uuid": "c5097fe2-cbf3-51ea-94c7-4543af3302a3",
"visibility": "enable"
}
],
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/DEMO/obj/firewall/addrgrp"
}
]
}
3.10. How to get the full ADOM database objects syntax?#
Caught in #0607071.
REQUEST:
{
"id": 1,
"method": "get",
"params": [
{
"url": "pm/config/adom/root/obj",
"option": "syntax"
}
]
}
Note
Option syntax
is described in section [TODO].
3.11. Internet Service Objects#
3.11.1. How to get the regions that can be used in a Geographic Based Internet Service object?#
To get the regions that could be used to define a geographic based internet service object:
REQUEST:
{
"id": 3,
"method": "get",
"params": [
{
"url": "/pm/config/adom/root/_fdsdb/internet-service/region"
}
],
"session": "cE/JiIBEdO4fWbjUPcrkyTCxuNnT6IGv3NKKHbgXRdSLwphqWRCYRu0M1ZZq4iwMhbQgft8evZlgokRV1bukNg==",
"verbose": 1
}
RESPONSE:
{
"id": 3,
"result": [
{
"data": [
{
"id": 2,
"name": "Aargau",
"subarea": "34,1495,2468,3282,13226,13956,15459,17315,19920"
},
{
"id": 3,
"name": "Abidjan",
"subarea": "73"
},
{
"id": 4,
"name": "Abitibi-OuestQuebec",
"subarea": "12575"
},
{
"...": "..."
},
{
"id": 2141,
"name": "Zonguldak",
"subarea": "4207,27249"
},
{
"id": 2142,
"name": "Zulia",
"subarea": "3575,4819,14422,21046"
},
{
"id": 2143,
"name": "Zurich",
"subarea": "1836,6324,6902,7317,14740,17510,17737,18456,19790,20490,20503,21627,24895,25812,26600,27285"
}
],
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/root/_fdsdb/internet-service/region",
"version": "7.2557"
}
]
}
3.11.2. How to get the countries that can be used in a Geographic Based Internet Service object?#
To get the countries that could be used to define a geographic based internet service object:
REQUEST:
{
"id": 3,
"method": "get",
"params": [
{
"url": "/pm/config/adom/root/_fdsdb/internet-service/country"
}
],
"session": "B3w+I+2XazWeTp7nDKnycudpE7slpKntuw0BgsXlxu7cWi7qQyCd4lDUoWHdrRh/lSMLhVTh1cWdYTtJBY8BQQ==",
"verbose": 1
}
RESPONSE:
{
"id": 3,
"result": [
{
"data": [
{
"id": 4,
"name": "Afghanistan",
"subarea": "826,65535"
},
{
"id": 248,
"name": "Aland Islands",
"subarea": "65535"
},
{
"id": 8,
"name": "Albania",
"subarea": "206,478,505,527,561,607,951,978,1048,1719,1892,2045"
},
{
"...": "...",
},
{
"id": 887,
"name": "Yemen",
"subarea": "309,65535"
},
{
"id": 894,
"name": "Zambia",
"subarea": "431,1097,65535"
},
{
"id": 716,
"name": "Zimbabwe",
"subarea": "264,671,1152,2193,65535"
}
],
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/root/_fdsdb/internet-service/country",
"version": "7.2557"
}
]
}
3.11.3. How to get the cities that can be used in a Geographic Based Internet Service object?#
To get the cities that could be used to define a geographic based internet service object:
REQUEST:
{
"id": 3,
"method": "get",
"params": [
{
"url": "/pm/config/adom/root/_fdsdb/internet-service/city"
}
],
"session": "bRq2VA27Gi9fNaR3QpUn0yOhSiAqYDJwCvoz2GE3Mdiml2cBOfV7C/b4kCfMz5ObnBiM52DeJwUhnvGuLrNRzg==",
"verbose": 1
}
RESPONSE:
{
"id": 3,
"result": [
{
"data": [
{
"id": 1,
"name": "'s Hertogenbosch",
"subarea": ""
},
{
"id": 7,
"name": "'s-Heer Hendrikskinderen",
"subarea": ""
},
{
"id": 13,
"name": "3 de Mayo",
"subarea": ""
},
{
"...": "...",
},
{
"id": 27318,
"name": "`Ayn al Fijah",
"subarea": ""
},
{
"id": 27319,
"name": "`Ayn ash Sharqiyah",
"subarea": ""
},
{
"id": 29175,
"name": "`Uqayribat",
"subarea": ""
}
],
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/root/_fdsdb/internet-service/city",
"version": "7.2557"
}
]
}
3.11.4. How to get the list of the Internet Service objects?#
Caught in #0622870.
REQUEST:
{
"id": "22a9fecf-7838-4795-a838-1633321197c2",
"method": "get",
"params": [
{
"url": "pm/config/adom/root/_fdsdb/internet-service",
"option": [
"get used",
"get flags",
"get devobj mapping",
"get meta",
"extra info",
"no loadsub",
"get reserved"
]
}
]
}
and
REQUEST:
{
"id": "99a913f3-0177-463c-b3ce-04eabf9c0100",
"method": "get",
"params": [
{
"url": "pm/config/adom/640/obj/firewall/internet-service-name",
"option": [
"get used",
"get flags",
"get devobj mapping",
"get meta",
"extra info",
"no loadsub"
]
}
]
}
But according to the #0622870, it is better to consider the method explained in section [TODO] (datasrc).
3.12. Operations on objects#
3.12.1. Cloning objects#
3.12.1.1. How to clone a firewall address?#
REQUEST:
{
"id": 1,
"jsonrpc": "1.0",
"method": "clone",
"params": [
{
"data": {
"name": "clone_host_001"
},
"url": "/pm/config/adom/DEMO_013/obj/firewall/address/host_001"
}
],
"session": "/FPLhY0rgXbpuZYz3TpcGtHQirT0ZHF09ILBV0ZrsWs2Knebq+5+CZ0fXejmyNWVqUm9Aftknb1biLL2JwiyXw==",
"verbose": 1
}
RESPONSE:
{
"id": 1,
"result": [
{
"data": {
"name": "clone_host_001"
},
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/DEMO_013/obj/firewall/address/host_001"
}
]
}
3.12.2. Filtering objects#
Getting an object table could generate a lot of output data.
Furthermore, most of the time, you’re only interested by a sub-part of that table if not by a single entry.
This is what you can achieve by filtering objects.
3.12.2.1. The contain
operator#
To get firewall address groups containing member host_001
:
{
"id": 3,
"method": "get",
"params": [
{
"fields": [
"name",
"member"
],
"filter": [
"member",
"contain",
"host_001"
],
"loadsub": 0,
"url": "/pm/config/adom/dc_amer/obj/firewall/addrgrp"
}
],
"session": "{{ session }}"
}
{
"id": 3,
"result": [
{
"data": [
{
"member": [
"host_001",
"host_002"
],
"name": "host_grp_001",
"oid": 5170
}
],
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/dc_amer/obj/firewall/addrgrp"
}
]
}
3.12.2.2. How to filter firewall address according to their IPs?#
Caught in #0363496.
To retrieve firewall address included in a specific IP address
We can use the <= comparison operator.
In the below example, we want all firewall addresses belonging to IP subnet 3.14.142.0/24:
REQUEST:
{ "id": 1, "jsonrpc": "1.0", "method": "get", "params": [ { "fields": [ "name", "subnet" ], "filter": [ [ "type", "==", "ipmask" ], "&&", [ "subnet", "<=", [ "3.14.142.0", "255.255.255.0" ] ] ], "loadsub": 0, "url": "/pm/config/adom/DEMO/obj/firewall/address" } ], "session": "BEzK9BQ9ZEMoDQVxCstqIxMWKmCA+Ewi6olABeRf+XbFm9kICX5nXGVwFyDvfg/4SKmT5DzuSS1hEmckePhYiYl5BsZ31EDm", "verbose": 1 }
RESPONSE:
{ "id": 1, "result": [ { "data": [ { "name": "host_010", "subnet": [ "3.14.142.63", "255.255.255.255" ] } ], "status": { "code": 0, "message": "OK" }, "url": "/pm/config/adom/DEMO/obj/firewall/address" } ] }
To retrieve firewall address strictly matching a specic IP address
We can use the == comparison operator.
In the below example, we want all firewall addresses with an exact match for IP address 3.14.142.63/32:
REQUEST:
{ "id": 1, "jsonrpc": "1.0", "method": "get", "params": [ { "fields": [ "name", "subnet" ], "filter": [ [ "type", "==", "ipmask" ], "&&", [ "subnet", "==", [ "3.14.142.63", "255.255.255.255" ] ] ], "loadsub": 0, "url": "/pm/config/adom/DEMO/obj/firewall/address" } ], "session": "7StdWXSR+aCBi96k+XIsX7QiYJllIiObsp6MouYr5T9Zov+R5sNnTHs8jbO3mgOO0O77Di4wsdKaPSk1SgKh1uTnLUf7ba8j", "verbose": 1 }
RESPONSE:
{ "id": 1, "result": [ { "data": [ { "name": "host_010", "subnet": [ "3.14.142.63", "255.255.255.255" ] } ], "status": { "code": 0, "message": "OK" }, "url": "/pm/config/adom/DEMO/obj/firewall/address" } ] }
To retrieve all firewall addresses containing a specific IP address
We can use the >= comparison operator.
In the below example, we want all firewall addresses containing IP 10.1.0.111/32.
REQUEST:
{ "id": 1, "jsonrpc": "1.0", "method": "get", "params": [ { "fields": [ "name", "subnet" ], "filter": [ [ "type", "==", "ipmask" ], "&&", [ "subnet", ">=", [ "10.1.0.111", "255.255.255.255" ] ] ], "loadsub": 0, "url": "/pm/config/adom/DEMO/obj/firewall/address" } ], "session": "HjL4TOtmT+DejM8SEeBYwGZGNM6LhetafH9cgsLyf7ikeODmr2YlyipIW6b0VuaxqxEhaox9oXha0huWjA4Y7HHYMFnwpSWV", "verbose": 1 }
RESPONSE:
{ "id": 1, "result": [ { "data": [ { "name": "FABRIC_DEVICE", "subnet": [ "0.0.0.0", "0.0.0.0" ] }, { "name": "FIREWALL_AUTH_PORTAL_ADDRESS", "subnet": [ "0.0.0.0", "0.0.0.0" ] }, { "name": "all", "subnet": [ "0.0.0.0", "0.0.0.0" ] } ], "status": { "code": 0, "message": "OK" }, "url": "/pm/config/adom/DEMO/obj/firewall/address" } ] }
3.12.2.3. How to get the Last Modified timestamp?#
The following example will get the Last Modified timestamp (i.e., _modified
timestamp
) for the firewall address groups declared in the dc_amer
ADOM:
{
"id": 3,
"method": "get",
"params": [
{
"fields": [
"name",
"_modified timestamp"
],
"option": [
"extra info",
"no loadsub"
],
"url": "/pm/config/adom/dc_amer/obj/firewall/addrgrp"
}
],
"session": "PT2or1RfAXowIdjpnhHiEx4W6p12Hx3AkWE5RK9noPTLN5gKy79kywOSYEL5P5vjAc2Ymvt7Zo9OoXV8TndYfQ=="
}
{
"id": 3,
"result": [
{
"data": [
{
"_created timestamp": 1681399819,
"_last-modified-by": "admin",
"_modified timestamp": 1681399819,
"name": "G Suite",
"obj ver": 1,
"oid": 3699
},
{
"_created timestamp": 1681399819,
"_last-modified-by": "admin",
"_modified timestamp": 1681399819,
"name": "Microsoft Office 365",
"obj ver": 1,
"oid": 3700
},
{
"_created timestamp": 1681408275,
"_last-modified-by": "admin",
"_modified timestamp": 1681813548,
"name": "host_grp_001",
"obj ver": 3,
"oid": 5170
},
{
"_created timestamp": 1681408290,
"_last-modified-by": "admin",
"_modified timestamp": 1681813548,
"name": "host_grp_002",
"obj ver": 4,
"oid": 5171
},
{
"_created timestamp": 1684190778,
"_last-modified-by": "admin",
"_modified timestamp": 1684190778,
"name": "grp_001",
"obj ver": 1,
"oid": 5235
}
],
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/dc_amer/obj/firewall/addrgrp"
}
]
}
3.12.2.4. How to filter on the Last Modified timestamp?#
Idea is to retrieve the list of objects more recent that a specific timestamp.
Caught in #0539624.
{
"id": 1,
"method": "get",
"params": [
{
"url": "pm/config/adom/FortiOS-54/obj/firewall/address",
"option": [
"get used",
"get flags",
"get devobj mapping",
"get meta",
"extra info",
"no loadsub"
],
"filter": [
"_modified timestamp",
">=",
1549412522
]
}
]
}
Note
The option of interest is extra info
.
3.12.2.5. The like
operator#
What if goal is to retrieve all firewall addresses whose name start with
host_
?
{
"id": 3,
"method": "get",
"params": [
{
"fields": [
"name",
"subnet"
],
"filter": [
"name",
"like",
"host_%"
],
"loadsub": 0,
"url": "/pm/config/adom/demo/obj/firewall/address"
}
],
"session": "Wvq6WltRC50vmipqJhAacFrS0RAr/sxQGdrr3NaT2SbAdcz8XzyPbZTd98ewBhiFtMmWLDLkUrSQWCVGhqzvZA==",
"verbose": 1
}
{
"id": 3,
"result": [
{
"data": [
{
"name": "host_001",
"subnet": [
"10.0.0.111",
"255.255.255.255"
]
},
{
"name": "host_002",
"subnet": [
"10.0.0.112",
"255.255.255.255"
]
}
],
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/demo/obj/firewall/address"
}
]
}
3.12.2.6. How to delete multiple objects?#
The filter
operator can also be very useful to delete multiple objects with
a single FortiManager JSON RPC API request.
For instance to delete all firewall addresses starting with host_
:
REQUEST:
{
"id": 1,
"create task": {
"adom": "dc_amer"
},
"method": "delete",
"params": [
{
"filter": [
"name",
"like",
"host_%"
],
"url": "/pm/config/adom/dc_amer/obj/firewall/address"
}
],
"session": "{{session}}"
}
Note
We’re using the
create task
to get a sucessful response!In this case, we will just receive a task ID and we will have to review the task output.
The
filter
operator is for allname
starting withhost_
.
RESPONSE:
{
"id": 1,
"result": [
{
"data": {
"task": 7
},
"status": {
"code": 0,
"message": "OK"
}
}
]
}
Task failed!
Message (captured from the FortiManager GUI) is:
The command is invalid for selected url
OK…
In fact, an yes message is really not meaningful, we need to confirm such
dangerous delete
form.
We could place the wrong filter and delete a lot of objects!
Let’s retry by confirming the operation:
REQUEST:
{
"id": 1,
"create task": {
"adom": "dc_amer"
},
"method": "delete",
"params": [
{
"confirm": 1,
"filter": [
"name",
"like",
"host_%"
],
"url": "/pm/config/adom/dc_amer/obj/firewall/address"
}
],
"session": "{{session}}"
}
Note
To confirm, you just need to use the
confirm
attribute.
But… Wait. The task failed again!
used
Of course, our objects are used in some firewall policies.
Let’s force the delete operation!
REQUEST:
{
"id": 1,
"create task": {
"adom": "dc_amer"
},
"method": "delete",
"params": [
{
"confirm": 1,
"option": "force",
"filter": [
"name",
"like",
"host_%"
],
"url": "/pm/config/adom/dc_amer/obj/firewall/address"
}
],
"session": "{{session}}"
}
Note
To force the requested operation, you have to use the
option
attribute set with theforce
keyword.
This time the task is succeeded.
Warning
The operation is succeeded even if you have the following FortiManager CLI setting disabled:
config system admin setting
set objects-force-deletion disable
end
As a last word, on this particular exemple, to delete just the list of objects
(and not more matching the previous used filter
value) you could have used
the following filter:
"filter": [
"name",
"in",
"host_001",
"host_002",
"host_003",
]
3.12.3. Used/Unused objects#
Note
This section will take the firewall address
table as example, but you can
apply it to all other tables.
3.12.3.1. How to know whether a specific object is used?#
We can use the option get used
and observe the returned obj flags
.
Our firewall address foo_host_001
is member of a firewall address group. It
is only used in this firewall address group.
If we get it with the option get used
, we can see a returned obj flags
:
REQUEST:
{
"id": 1,
"jsonrpc": "1.0",
"method": "get",
"params": [
{
"fields": [
"name",
"obj flags"
],
"loadsub": 0,
"option": [
"get used"
],
"url": "/pm/config/adom/production_001/obj/firewall/address/foo_host_001"
}
],
"session": "oc+DBEboJovBLDkoYqyFkB3dnhoazTP1fbVTRIi1XbVHmVTvuL2A+lUxuYnhjk3L9Sdd74g/SqaOGFQO1saVB2aouTDXWgQg",
"verbose": 1
}
RESPONSE:
{
"id": 1,
"result": [
{
"data": {
"name": "foo_host_001",
"obj flags": 1
},
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/production_001/obj/firewall/address/foo_host_001"
}
]
}
When obj flags
is equal to 1
it means the object is used.
If we remove firewall address foo_host_001
from the group it was belonging
to, the same request now gives:
RESPONSE:
{
"id": 1,
"result": [
{
"data": {
"name": "foo_host_001"
},
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/production_001/obj/firewall/address/foo_host_001"
}
]
}
The obj flags
is no longer returned meaning the object isn’t used.
3.12.3.2. How to get the list of used objects?#
You can get the list of used objects by getting the table only using the get
used
option as seen in section How to know whether a specific object is
used?
For instance:
REQUEST:
{
"id": 3,
"method": "get",
"params": [
{
"fields": [
"name"
],
"option": [
"no loadsub",
"get used"
],
"url": "/pm/config/adom/production_001/obj/firewall/address"
}
],
"session": "Shc2xxYYd6Q0apcJAYewlcFxv/pgyCg/ADzB0hC187N1i70lzP9v2808/D2F89JhRFKPbxVAv0XiiK8SUAjrPQ==",
"verbose": 1
}
RESPONSE:
{
"id": 3,
"result": [
{
"data": [
{
"name": "FABRIC_DEVICE",
"oid": 2644
},
{
"name": "FIREWALL_AUTH_PORTAL_ADDRESS",
"oid": 2643
},
{
"name": "RFC1918-10",
"obj flags": 1,
"oid": 2646
},
{
"name": "RFC1918-172",
"obj flags": 1,
"oid": 2647
},
"...": "...",
{
"name": "metadata-server",
"oid": 2645
},
{
"name": "none",
"oid": 2634
},
{
"name": "wildcard.dropbox.com",
"oid": 2640
},
{
"name": "wildcard.google.com",
"obj flags": 1,
"oid": 2639
}
],
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/knock_45329/obj/firewall/address"
}
]
}
However, as you can see, FortiManager is still returning all firewall addresses!
You have to filter by yourself and isolate the returned objects which are using the obj flags.
You can try to add a filter
block:
"filter": [
"obj flags",
"==",
1
]
but it won’t work.
Fortunately, we can ask FortiManager to only return used objects using the following request:
REQUEST:
{
"id": 3,
"method": "get",
"params": [
{
"fields": [
"name"
],
"filter": [
[
"object used",
"==",
1
],
"&&",
[
"name",
"like",
"host_%"
]
],
"option": [
"no loadsub",
"get used"
],
"url": "/pm/config/adom/knock_45329/obj/firewall/address"
}
],
"session": "tdGYyiDdeDNhiaGmXCJShCAnWS+N5AIeWcb1bMtccP3xNmG6bGONVWUZkU5j+fpTAR48BlvGDfrebJdAcZGQBg==",
"verbose": 1
}
RESPONSE:
{
"id": 3,
"result": [
{
"data": [
{
"name": "host_001",
"obj flags": 1,
"oid": 4156
},
{
"name": "host_002",
"obj flags": 1,
"oid": 4157
},
{
"name": "host_003",
"obj flags": 1,
"oid": 4158
},
"...": "...",
{
"name": "host_198",
"obj flags": 1,
"oid": 4353
},
{
"name": "host_199",
"obj flags": 1,
"oid": 4354
},
{
"name": "host_200",
"obj flags": 1,
"oid": 4355
}
],
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/knock_45329/obj/firewall/address"
}
]
}
Note
You can keep using the
get used
option just to confirm that all returned objects have the flagobj flags
set to1
.
3.12.3.3. How to get unused objects?#
To get all unused firewall addresses from ADOM demo
and matching a specific
name
:
REQUEST:
{
"id": 3,
"method": "get",
"params": [
{
"fields": [
"name"
],
"filter": [
[
"object used",
"==",
0
],
"&&",
[
"name",
"like",
"host_%"
]
],
"option": [
"search all adoms",
"no loadsub"
],
"url": "/pm/config/adom/knock_45329/obj/firewall/address"
}
],
"session": "Iu1Msbu+H9FQO/IjfnpRMI96BfCoASYDwzizRfmx6Th6xcMWmCuERL4KYmej7vTRfR58KTYKNqRMbxa25l0vMg==",
"verbose": 1
}
RESPONSE:
{
"id": 3,
"result": [
{
"data": [
{
"name": "host_201",
"oid": 4489
},
{
"name": "host_300",
"oid": 4481
}
],
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/knock_45329/obj/firewall/address"
}
]
}
3.12.4. Where Used#
3.12.4.1. How to where used from the global adom?#
First of all, you have to allow FortiManager to search in all ADOMs:
config system global set search-all-adoms enable end
Then it’s a three steps process:
Start a where used request
In this example, we have the global object
g_host_001
in the Global ADOM. We want to see where this object is used in all ADOMs.{ "id": 1, "method": "exec", "params": [ { "data": { "mkey": "g_host_001", "obj": "global/obj/firewall/address" }, "url": "/cache/search/where/used/start" } ], "session": "{{session}}" }
{ "id": 1, "result": [ { "data": { "token": "K11EnEPIkRUx23ws7sbm6A==" }, "status": { "code": 0, "message": "OK" }, "url": "/cache/search/where/used/start" } ] }
Note
FortiManager returns the
token
attribute.Its value will allow you to follow the progress of the task, then to get the final result
Wait for the where used task to complete
{ "id": 1, "method": "exec", "params": [ { "token": "K11EnEPIkRUx23ws7sbm6A==", "url": "cache/search/where/used/get/summary" } ], "session": "{{session}}" }
{ "id": 1, "result": [ { "data": { "percent": 100 }, "status": { "code": 0, "message": "OK" }, "url": "cache/search/where/used/get/summary" } ] }
Note
The
percent
attribute is100
meaning the task is 100% complete.Should your value different than
100
, just keep looping with same request till it returns100
We can now get the final result
{ "id": 1, "method": "exec", "params": [ { "token": "K11EnEPIkRUx23ws7sbm6A==", "url": "/cache/search/where/used/get/detail" } ], "session": "{{session}}" }
{ "id": 1, "result": [ { "data": { "percent": 100, "total_num": 1, "where_used": [ { "data": [ { "attr": "dstaddr", "category": 181, "mapping_name": "firewall policy", "mattr": "policyid", "mkey": "4", "pkg": { "name": "pp.device1", "oid": 4710 } } ], "root": { "name": "DEMO_014", "oid": 22039 } } ] }, "status": { "code": 0, "message": "OK" }, "url": "/cache/search/where/used/get/detail" } ] }
Note
This output shows that:
Object
g_host_001
is used as a destination in policy packagepp.device1
The firewall policy referencing object
g_host_001
is having thepolicyid
4
The policy package
pp.device1
is in ADOMDEMO_014
3.12.4.2. How to where used from within a normal ADOM?#
Follow the same three steps process as the one describe in How to where used from the global adom?
You just need to replace the obj
attribute’s value with something like:
adom/<adom>/obj/firewall/address
For instance, if you want to where used the host_001
firewall address from
within the dc_emea
ADOM, your step 1 request will be:
{
"id": 1,
"method": "exec",
"params": [
{
"data": {
"mkey": "host_001",
"obj": "adom/dc_emea/obj/firewall/address"
},
"url": "/cache/search/where/used/start"
}
],
"session": "{{session}}"
}
3.12.5. Find duplicates objects#
To get duplicates firewall addresses:
REQUEST:
{
"id": 1,
"jsonrpc": "1.0",
"method": "get",
"params": [
{
"fields": [
"name",
"type",
"subnet",
"duplicate enntries"
],
"load assigned": 0,
"loadsub": 0,
"option": [
"find duplicates"
],
"url": "/pm/config/adom/demo_002/obj/firewall/address"
}
],
"session": "V3pHwSOgmHZEQoqJ4pVHJFQSCIiaXm0cOjvXp40JN1ps2FQWNwqMNz0jATnrQxGr2K78L6+mY9Os8WRVBRCxKw==",
"verbose": 1
}
RESPONSE:
{
"id": 1,
"result": [
{
"data": [
{
"duplicate entries": [
"login.microsoft.com",
"login.microsoftonline.com",
"login.windows.net",
"wildcard.dropbox.com",
"wildcard.google.com"
],
"name": "gmail.com",
"subnet": [
"0.0.0.0",
"0.0.0.0"
],
"type": "fqdn"
},
{
"duplicate entries": [
"FIREWALL_AUTH_PORTAL_ADDRESS",
"all"
],
"name": "FABRIC_DEVICE",
"subnet": [
"0.0.0.0",
"0.0.0.0"
],
"type": "ipmask"
},
{
"duplicate entries": [
"host_001_002"
],
"name": "host_001_001",
"subnet": [
"10.0.0.1",
"255.255.255.255"
],
"type": "ipmask"
}
],
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/demo_002/obj/firewall/address"
}
]
}
FortiManager is using the fields
attribute to format the response logic.
For instance, if we remove the type
criteria we will obtain this output:
REQUEST:
{
"id": 1,
"jsonrpc": "1.0",
"method": "get",
"params": [
{
"fields": [
"name",
"subnet"
],
"load assigned": 0,
"loadsub": 0,
"option": [
"find duplicates"
],
"url": "/pm/config/adom/demo_002/obj/firewall/address"
}
],
"session": "qpzdhu+2yDsbeuGJQB/OUGjnmIa+/35YCJrXTudpteCy2XnTgHPEeFZaYHs4sHq1yFQohl7NkpfVjkW7H1dUxF5/i1JnAyE+",
"verbose": 1
}
RESPONSE:
{
"id": 1,
"result": [
{
"data": [
{
"duplicate entries": [
"FCTEMS_ALL_FORTICLOUD_SERVERS",
"FIREWALL_AUTH_PORTAL_ADDRESS",
"SSLVPN_TUNNEL_ADDR1",
"all",
"gmail.com",
"login.microsoft.com",
"login.microsoftonline.com",
"login.windows.net",
"wildcard.dropbox.com",
"wildcard.google.com"
],
"name": "FABRIC_DEVICE",
"subnet": [
"0.0.0.0",
"0.0.0.0"
]
},
{
"duplicate entries": [
"host_001_002"
],
"name": "host_001_001",
"subnet": [
"10.0.0.1",
"255.255.255.255"
]
}
],
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/demo_002/obj/firewall/address"
}
]
}
Observe where are now listed the firewall addresses
FIREWALL_AUTH_PORTAL_ADDRESS
and all
.
The find duplicates
option is working with other objects, like address
groups, IPv6 firewall addresses, VIP, etc. You just have to replace the url
parameter with the proper path.
3.12.6. Merge objects#
3.12.6.1. How to merge firewall addresses?#
We want to merge firewall address host_001_001
and host_001_002
.
Destination firewall address name has to be one of them; we cannot merge for
instance to firewall address name host_001_merged
.
In below example, we will merge both firewall address in host_001_001
:
REQUEST:
{
"id": 1,
"jsonrpc": "1.0",
"method": "set",
"params": [
{
"merge": [
"host_001_001",
"host_001_002"
],
"url": "/pm/config/adom/demo_002/obj/firewall/address/host_001_001"
}
],
"session": "1PIOQRlz0dKA/xk8nUY1dsmOuiI7rHcjaAyiTjbaSzJVnpa8smZ8VSUAsWn7NWW/ZZWusUbbrNfte0RgNHdInGwTCiQICw3Y",
"verbose": 1
}
RESPONSE:
{
"id": 1,
"result": [
{
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/demo_002/obj/firewall/address/host_001_001"
}
]
}
Note that the above merge operation is also:
Replacing firewall address
host_001_002
with firewall addresshost_001_001
everywhere it was used (in firewall policy, in firewall address group, etc.)Deleting firewall address
host_001_002
The merge
operation is working with other objects, like address groups,
IPv6 firewall addresses, VIP, etc. You just have to replace the url
parameter with the proper path.
3.12.7. Find and Replace#
In the below example, we want to replace the antivirus profile
av-profile-001
used by some of our firewall policies, with antivirus profile
av-profile-002
.
First you need to where used the antivirus profile av-profile-001
object:
As you know the where used is a three steps process:
Step #1: We Need To Start A New Where Used Task
REQUEST:
{ "id": 1, "method": "exec", "params": [ { "data": { "flags": [ "direct used" ], "mkey": "av-profile-001", "obj": "adom/DEMO/obj/antivirus/profile" }, "url": "cache/search/where/used/start" } ], "session": 20456 }
RESPONSE:
{ "id": 1, "result": [ { "data": { "token": "ng9jCDhg9qZVmUt4oaYPZw==" }, "status": { "code": 0, "message": "OK" }, "url": "cache/search/where/used/start" } ] }
Step #2: with the returned token, we need to wait for the task to be completed:
REQUEST:
{ "id": 1, "method": "exec", "params": [ { "token": "ng9jCDhg9qZVmUt4oaYPZw==", "url": "cache/search/where/used/get/summary" } ], "session": 20456 }
RESPONSE:
{ "id": 1, "result": [ { "data": { "percent": 100 }, "status": { "code": 0, "message": "OK" }, "url": "cache/search/where/used/get/summary" } ] }
If the percent value isn’t equal to 100, just retry till it is 100.
Step #3: we can collect the where used result:
REQUEST:
{ "id": 1, "method": "exec", "params": [ { "token": "ng9jCDhg9qZVmUt4oaYPZw==", "url": "cache/search/where/used/get/detail" } ], "session": 20456 }
RESPONSE:
{ "id": 1, "result": [ { "data": { "percent": 100, "total_num": 2, "where_used": [ { "data": [ { "attr": "av-profile", "category": 181, "mapping_name": "firewall policy", "mattr": "policyid", "mkey": "1", "pkg": { "name": "default", "oid": 4685 } }, { "attr": "av-profile", "category": 181, "mapping_name": "firewall policy", "mattr": "policyid", "mkey": "2", "pkg": { "name": "default", "oid": 4685 } } ], "root": { "name": "DEMO", "oid": 136 } } ] }, "status": { "code": 0, "message": "OK" }, "url": "cache/search/where/used/get/detail" } ] }
From the above output, we can see that our antivirus profile
av-profile-001
is used by two firewall policies (id 1 and 2 respectively) in policy packagedefault
from ADOMDEMO
.
We can now proceed with the replace operation
To replace
av-profile-001
withav-profile-002
for policy #1REQUEST:
{ "id": 1, "method": "update", "params": [ { "url": "pm/config/adom/DEMO/pkg/default/firewall/policy/1", "used objs": { "from": "obj/antivirus/profile/av-profile-001", "to": [ "av-profile-002" ] } } ], "session": 20456 }
RESPONSE:
TBD
3.12.7.1. How to find and replace objects in firewall policy?#
Caught in #0636807.
REQUEST:
{
"method": "update",
"params": [
{
"target start": 2,
"url": "pm/config/adom/BusySYSLabFG/pkg/BUSYSYSLABFG_Monitoring/firewall/policy/3",
"used objs": {
"from": "obj/firewall/address/192.168.215.157-VCenter",
"to": [
"10.1.0.0/16-IT_BUSY"
]
}
}
],
"session": 4131
}
3.12.8. Partial installation#
Caught in #0225600.
This is the template to install any objects:
{
"id": 1,
"method": "exec",
"params": [
{
"data": {
"adom": "{{adom}}>",
"scope": [
{
"name": "{{device}}",
"vdom": "{{vdom}}"
},
{"...", "..."}
],
"target": [
"{{target}}"
]
},
"url": "/securityconsole/install/objects"
}
],
"session": "{{session}}",
}
where:
scope
could be omitted, in that case FortiManager will manage to find the devices/vdoms which are using the target objecttarget
is the target object to be installYou declare a target using the usual format.
For instance:
# For any objects /pm/config/adom/<adom>/obj/<fortios cli> # For a firewall policyid /pm/config/adom/<adom>/pkg/<pkg>/firewall/policy/<policyid> etc.
More information about the partial install mechanism are given in section Partial Install
3.12.8.1. How to partial install an IPS profile?#
3.12.8.1.1. Using the Legacy Partial Install API#
See Legacy Partial Install API for more details about the Legacy Partial Install API.
The following example shows how to partial install the ips_sensor_001
IPS
profile from the demo
ADOM against the dev_001
and dev_002
managed device and their respective root
VDOM:
{
"id": 1,
"method": "exec",
"params": [
{
"data": {
"adom": "demo",
"scope": [
{
"name": "dev_001",
"vdom": "root"
},
{
"name": "dev_002",
"vdom": "root"
}
],
"target": [
"/pm/config/adom/demo/obj/ips/sensor/ips_sensor_001"
]
},
"url": "/securityconsole/install/objects"
}
],
"session": "{{session}}"
}
{
"id": 1,
"result": [
{
"data": {
"task": 441
},
"status": {
"code": 0,
"message": "OK"
},
"url": "/securityconsole/install/objects"
}
]
}
3.12.8.1.2. Using the New Partial Install API#
See New Partial Install API for more details about the New Partial Install API.
The following example shows how to partial install the ips_sensor_001
IPS
profile from the demo
ADOM against the dev_001
and dev_002
managed device and their respective root
VDOM:
{
"id": 3,
"method": "exec",
"params": [
{
"data": {
"adom": "demo",
"flags": 0,
"objects": [
[
"update",
"obj/ips/sensor/ips_sensor_001",
"",
""
]
],
"scope": [
{
"name": "dev_001",
"vdom": "root"
},
{
"name": "dev_002",
"vdom": "root"
}
]
},
"url": "/securityconsole/install/objects/v2"
}
],
"session": "{{session}}"
}
{
"id": 3,
"result": [
{
"data": {
"task": 948
},
"status": {
"code": 0,
"message": "OK"
},
"url": "/securityconsole/install/objects/v2"
}
]
}
Note
It is important to wait for the end of the returned task ID before closing the API session
If you close the API session before, the task will fail
3.12.9. How to check for a duplicate object name?#
Caught in #893698
To check whether an object name is already used, you can use the option
duplicate check
:
"option": [
"duplicate check"
]
For instance, to check whether a firewall address with name host_001
already
exists in ADOM dc_amiens
:
{
"method": "add",
"id": 1,
"session": "{{session}}",
"params": [
{
"data": {
},
"url": "/pm/config/adom/dc_amiens/obj/firewall/address/host_001",
"option": ["duplicate check"]
}
]
}
Note
The
method
attribute isadd
{
"result": [
{
"data": "firewall address",
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/dc_amiens/obj/firewall/address/host_001"
}
],
"id": 1
}
The data
attribute contains the object’s category, here firewall address
.
{
"result": [
{
"data": null,
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/dc_amiens/obj/firewall/address/host_001"
}
],
"id": 1
}
The data
attribute is null
.
3.13. Global ADOM#
3.14. Object Revision#
3.14.1. How to add an object with an object revision note?#
Following example applies to firewall address object type.
It is showing how to add a new firewall address with an object revision note:
{
"id": 3,
"method": "add",
"params": [
{
"data": {
"color": 4,
"name": "host_005",
"subnet": "10.0.0.5/32"
},
"revision note": "Initial Revision",
"url": "/pm/config/adom/dc_amer/obj/firewall/address"
}
],
"session": "{{ session }}"
}
{
"id": 3,
"result": [
{
"data": {
"name": "host_005"
},
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/dc_amer/obj/firewall/address"
}
]
}
3.14.2. How to update an object with an object revision note?#
Following example applies to firewall address object type.
It is showing how to update both an existing firewall address and its associated object revision note:
{
"id": 3,
"method": "update",
"params": [
{
"data": {
"color": 10
},
"revision note": "Color changed a second time",
"url": "/pm/config/adom/dc_amer/obj/firewall/address/host_005"
}
],
"session": "{{ session }}"
}
{
"id": 3,
"result": [
{
"data": {
"name": "host_005"
},
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/dc_amer/obj/firewall/address/host_005"
}
]
}
3.14.3. How to get the revision notes for a specific object?#
Following example applies to firewall address object type.
It is showing how to get the revision notes for an existing firewall address:
{
"id": 3,
"method": "get",
"params": [
{
"url": "/pm/config/adom/dc_amer/_objrev/obj/firewall/address/host_005"
}
],
"session": "{{ session }}",
"verbose": 1
}
{
"id": 3,
"result": [
{
"data": [
{
"act": 1,
"category": 140,
"config": "{ \"allow-routing\": 0, \"associated-interface\": [ \"any\" ], \"clearpass-spt\": 0, \"color\": 4, \"dirty\": 1, \"dynamic_mapping\": null, \"fabric-object\": 0, \"list\": null, \"macaddr\": [ ], \"name\": \"host_005\", \"node-ip-only\": 0, \"obj-type\": 9, \"oid\": 4649, \"subnet\": [ \"10.0.0.5\", \"255.255.255.255\" ], \"tagging\": null, \"type\": 0, \"uuid\": \"2ea6e52a-d835-51ed-84f2-23efc39096ad\" }",
"flags": 0,
"key": "host_005",
"note": "Initial Revision",
"oid": 4649,
"pkg_oid": 0,
"timestamp": 1681195844,
"user": "devops"
},
{
"act": 3,
"category": 140,
"config": "{ \"_image-base64\": null, \"allow-routing\": 0, \"associated-interface\": [ \"aplink1\" ], \"cache-ttl\": 0, \"clearpass-spt\": 0, \"color\": 4, \"comment\": null, \"country\": [ ], \"dirty\": 1, \"dynamic_mapping\": null, \"end-ip\": \"0.0.0.0\", \"epg-name\": null, \"fabric-object\": 0, \"filter\": null, \"fqdn\": null, \"fsso-group\": [ ], \"interface\": [ ], \"list\": null, \"macaddr\": [ ], \"name\": \"host_005\", \"node-ip-only\": 0, \"obj-id\": null, \"obj-tag\": null, \"obj-type\": 9, \"oid\": 4649, \"organization\": null, \"policy-group\": null, \"sdn\": [ ], \"sdn-addr-type\": 0, \"sdn-tag\": null, \"start-ip\": \"0.0.0.0\", \"sub-type\": 0, \"subnet\": [ \"10.0.0.5\", \"255.255.255.255\" ], \"subnet-name\": null, \"tag-detection-level\": null, \"tag-type\": null, \"tagging\": null, \"tenant\": null, \"type\": 0, \"uuid\": \"2ea6e52a-d835-51ed-84f2-23efc39096ad\", \"wildcard\": [ \"0.0.0.0\", \"0.0.0.0\" ], \"wildcard-fqdn\": null }",
"flags": 0,
"key": "host_005",
"note": "Set interface to aplink1",
"oid": 4649,
"pkg_oid": 0,
"timestamp": 1681195844,
"user": "admin"
},
{
"act": 3,
"category": 140,
"config": "{ \"_image-base64\": null, \"allow-routing\": 0, \"associated-interface\": [ \"aplink1\" ], \"cache-ttl\": 0, \"clearpass-spt\": 0, \"color\": 22, \"comment\": null, \"country\": [ ], \"dirty\": 1, \"dynamic_mapping\": null, \"end-ip\": \"0.0.0.0\", \"epg-name\": null, \"fabric-object\": 0, \"filter\": null, \"fqdn\": null, \"fsso-group\": [ ], \"interface\": [ ], \"list\": null, \"macaddr\": [ ], \"name\": \"host_005\", \"node-ip-only\": 0, \"obj-id\": null, \"obj-tag\": null, \"obj-type\": 9, \"oid\": 4649, \"organization\": null, \"policy-group\": null, \"sdn\": [ ], \"sdn-addr-type\": 0, \"sdn-tag\": null, \"start-ip\": \"0.0.0.0\", \"sub-type\": 0, \"subnet\": [ \"10.0.0.5\", \"255.255.255.255\" ], \"subnet-name\": null, \"tag-detection-level\": null, \"tag-type\": null, \"tagging\": null, \"tenant\": null, \"type\": 0, \"uuid\": \"2ea6e52a-d835-51ed-84f2-23efc39096ad\", \"wildcard\": [ \"0.0.0.0\", \"0.0.0.0\" ], \"wildcard-fqdn\": null }",
"flags": 0,
"key": "host_005",
"note": "Color changed",
"oid": 4649,
"pkg_oid": 0,
"timestamp": 1681196213,
"user": "admin"
},
{
"act": 3,
"category": 140,
"config": "{ \"_image-base64\": null, \"allow-routing\": 0, \"associated-interface\": [ \"aplink1\" ], \"clearpass-spt\": 0, \"color\": 10, \"comment\": null, \"dirty\": 1, \"dynamic_mapping\": null, \"fabric-object\": 0, \"list\": null, \"macaddr\": [ ], \"name\": \"host_005\", \"node-ip-only\": 0, \"obj-tag\": null, \"obj-type\": 9, \"oid\": 4649, \"organization\": null, \"policy-group\": null, \"subnet\": [ \"10.0.0.5\", \"255.255.255.255\" ], \"subnet-name\": null, \"tag-detection-level\": null, \"tag-type\": null, \"tagging\": null, \"type\": 0, \"uuid\": \"2ea6e52a-d835-51ed-84f2-23efc39096ad\" }",
"flags": 0,
"key": "host_005",
"note": "Color changed a second time",
"oid": 4649,
"pkg_oid": 0,
"timestamp": 1681196478,
"user": "devops"
}
],
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/dc_amer/_objrev/obj/firewall/address/host_005"
}
]
}
3.14.4. How to revert to a specific object revision?#
Following example applies to firewall address object type.
It is showing how to revert an existing firewall address to a specific object revision.
In fact, there’s no specific revert operation. FortiManager is using the
replace
FortiManager JSON RPC API method with datas obtained from the object revision to be
reverted with:
{
"id": 3,
"method": "replace",
"params": [
{
"data": {
"color": 4,
"name": "host_005",
"subnet": "10.0.0.5/32"
},
"revision note": "Reverted from revision 1",
"url": "/pm/config/adom/dc_amer/obj/firewall/address/host_005"
}
],
"session": "{{ session }}"
}
{
"id": 3,
"result": [
{
"data": {
"name": "host_005"
},
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/dc_amer/obj/firewall/address/host_005"
}
]
}
3.15. How to copy objects?#
Here the word copy refers to the action of copying an object from ADOM DB to Device DB.
The target object isn’t push down to the managed devices.
A proper install operation should be triggered.
The FortiManager JSON RPC API endpoint used to trigger this copy operation isn’t documented hence we used the output of the following FortiManager debug command compile the information shared in this section:
diagnose debug service main 255
When we issue the following FortiManager CLI command to trigger a copy operation, we’re getting the following output:
# execute fmpolicy copy-adom-object dc_helsinki "firewall address" foo_002 france
Do you want to continue? (y/n)y
Request [/bin/newcli:14057:3]:
{ "client": "\/bin\/newcli:14057", "id": 3, "method": "exec", "params": [{ "data": { "adom": 3273, "category": 140, "override_conflict": 1, "query_only": 0, "scope": [{ "oid": 3569}], "src_list": [{ "oid": 4827}]}, "url": "install\/global"}], "root": "securityconsole", "session": 12207}
Waiting for task 1347...
Task completed
In the following example, we copy the foo_002
firewall address from the
dc_helsinki
ADOM to the devices belonging to the france
device group:
{
"id": 3,
"method": "exec",
"params": [
{
"data": {
"adom": "dc_helsinki",
"category": 140,
"override_conflict": 1,
"query_only": 0,
"scope": [
{
"name": "france"
}
],
"src_list": [
{
"oid": 4827
}
]
},
"url": "/securityconsole/install/global"
}
],
"session": "{{session}}"
}
{
"id": 3,
"result": [
{
"data": {
"task": 1350
},
"status": {
"code": 0,
"message": "OK"
},
"url": "/securityconsole/install/global"
}
]
}
FortiManager will return a task ID (task
attribute) but won’t run it in the
background. We have to wait for the end of the request.
The request is having a lot of numerical information:
The
category
attribute140
is the category ID for thefirewall address
tableUnfortunately, we cannot use the string
"firewall address"
as shown below:{ "category": "firewall address" }
We have to use an id
How to get it?
To get the category ID of the
firewall address
table:{ "id": 3, "method": "get", "params": [ { "option": [ "syntax" ], "url": "/pm/config/adom/dc_helsinki/obj/firewall/address" } ], "session": "{{session}}" }
In the response, you have to get:
.result[0]["data"]["firewall address"]["category"]
src_list
attributeThis list contains the OID of the objects to copy
For the
140
category (firewall address
) thesrc_list
list contain OID of firewall address objectsHow to get the OID of a firewall address?
{ "id": 3, "method": "get", "params": [ { "fields": [ "name" ], "loadsub": 0, "url": "/pm/config/adom/dc_helsinki/obj/firewall/address/foo_002" } ], "session": "7bQB94D0zHu7I9EGtwIbQJEbrcH7qRBI/hwWbqrP/RVUWLd8h1PiFyTD+brojmELiV/rVHcSdYX2CqTAtEcmhg==" }
{ "id": 3, "result": [ { "data": { "name": "foo_002", "oid": 4827 }, "status": { "code": 0, "message": "OK" }, "url": "/pm/config/adom/dc_helsinki/obj/firewall/address/foo_002" } ] }
You can use the usual scope
:
{
"scope": [
{
"name": "device_group_001",
},
{
"name": "device_group_002",
},
{
"name": "device_001",
"vdom": "vd_001"
},
{
"name": "device_001",
"vdom": "vd_002"
},
{
"...": "..."
}
]
}
3.16. Per-device mapping#
This is a mechanism where FortiManager can push the same object to multiple devices, but with different values.
For instance, you could have the net_branch_lan firewall address to represent the internal network of your remote sites and you would like it to be with the
10.0.1.0/24
for site #1, 10.0.2.0/24
for site #2, etc.
The per-device mapping feature isn’t available for all objects.
Note
CLI Template could be use to overcome the lack of per-device mapping support.
3.16.1. Per-device mapping for firewall.address#
3.16.1.1. How to get per-device mapping info for a firewall address obejct?#
The following example shows how to get the per-device mapping info for the
net_branch_lan
firewall address from the demo
ADOM:
{
"id": 3,
"method": "get",
"params": [
{
"url": "/pm/config/adom/demo/obj/firewall/address/net_branch_lan/dynamic_mapping"
}
],
"session": "{{session}}",
"verbose": 1
}
Note
To get the per-device mapping info, you just need to append the
dynamic_mapping
subtable in theurl
{
"id": 3,
"result": [
{
"data": [
{
"_scope": [
{
"name": "dev_001",
"vdom": "root"
}
],
"allow-routing": "disable",
"clearpass-spt": "unknown",
"color": 0,
"dirty": "dirty",
"fabric-object": "disable",
"macaddr": [],
"node-ip-only": "disable",
"obj-type": "ip",
"oid": 5584,
"route-tag": 0,
"subnet": [
"10.0.1.0",
"255.255.255.0"
],
"type": "ipmask",
"unset attrs": [
"associated-interface"
],
"uuid": "6c108da4-d257-51ee-25be-c01339bbfdb8"
}
],
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/demo/obj/firewall/address/net_branch_lan/dynamic_mapping"
}
]
}
Note
The
net_branch_lan
is having a single per-device mapping for thedev_001
device and itsroot
VDOMWhen FortiManager will push the
net_branch_lan
against thedev_001.root
device, it will use the IP address from thesubnet
blockWhen FortiManager will push the
net_branch_lan
against thedev_002.root
device, it will use the IP address from thesubnet
block of thenet_branch_lan
object itself, because there’s no per-device mapping for this device.
3.16.1.2. How to add a per-device mapping to a firewall address object?#
The following example shows how to add a new per-device mapping entry for the
dev_002
device and its root
VDOM, for the net_branch_lan
firewall
address from the demo
ADOM:
{
"id": 3,
"method": "add",
"params": [
{
"data": {
"_scope": [
{
"name": "dev_002",
"vdom": "root"
}
],
"subnet": [
"10.0.2.0",
"255.255.255.0"
]
},
"url": "/pm/config/adom/demo/obj/firewall/address/net_branch_lan/dynamic_mapping"
}
],
"session": "{{session}}"
}
{
"id": 3,
"result": [
{
"data": {
"_scope": [
{
"name": "dev_002",
"vdom": "root"
}
]
},
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/demo/obj/firewall/address/net_branch_lan/dynamic_mapping"
}
]
}
Note
FortiManager confirms the creation of the new per-device mapping entry returning its
_scope
attribute
You can add multiple per-device mapping entries in a single request.
The following example add per-device mapping entries for the dev_003
and dev_004
devices and their root
VDOM:
{
"id": 3,
"method": "add",
"params": [
{
"data": [
{
"_scope": [
{
"name": "dev_003",
"vdom": "root"
}
],
"subnet": [
"10.0.3.0",
"255.255.255.0"
]
},
{
"_scope": [
{
"name": "dev_004",
"vdom": "root"
}
],
"subnet": [
"10.0.4.0",
"255.255.255.0"
]
}
],
"url": "/pm/config/adom/demo/obj/firewall/address/net_branch_lan/dynamic_mapping"
}
],
"session": "{{session}}",
}
{
"id": 3,
"result": [
{
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/demo/obj/firewall/address/net_branch_lan/dynamic_mapping"
}
]
}
Note
For multiple per-device mapping entries, FortiManager confirms their creation with a generic OK response
3.16.1.3. How to delete a per-device mapping from a firewall address object?#
The following example shows how to delete the per-device mapping entry for the
dev_004
device and its root
VDOM, for the net_branch_lan
firewall
address from the demo
ADOM:
{
"id": 3,
"method": "delete",
"params": [
{
"url": "/pm/config/adom/demo/obj/firewall/address/net_branch_lan/dynamic_mapping/dev_004/root"
}
],
"session": "{{session}}"
}
{
"id": 3,
"result": [
{
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/demo/obj/firewall/address/net_branch_lan/dynamic_mapping/dev_004/root"
}
]
}
You can delete multiple per-device mapping entries in a single request.
The following example delete per-device mapping entries for the dev_003
and
dev_002
devices and their root
VDOM:
{
"id": 3,
"method": "delete",
"params": [
{
"url": "/pm/config/adom/demo/obj/firewall/address/net_branch_lan/dynamic_mapping/dev_003/root"
},
{
"url": "/pm/config/adom/demo/obj/firewall/address/net_branch_lan/dynamic_mapping/dev_002/root"
}
],
"session": "{{session}}"
}
{
"id": 3,
"result": [
{
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/demo/obj/firewall/address/net_branch_lan/dynamic_mapping/dev_03/root"
},
{
"status": {
"code": 0,
"message": "OK"
},
"url": "/pm/config/adom/demo/obj/firewall/address/net_branch_lan/dynamic_mapping/dev_002/root"
}
]
}