- Introduction and Ansible playbook download
- Script flow charts
- Introduction of REST API and Cisco FMC API Explorer
- Script prerequisites
- Request Access Token
- Get policy content, modify content and "PUT' in FMC - Part 1
- Get policy content, modify content and "PUT' in FMC - Part 2
- Get deployable devices and deploy policy
In the last post in this series, I introduced the way to obtain the Access Token. Now we are ready to do some "real work" with the FMC REST APIs. In this post, we will modify the value of the JSON key of a policy rule. There are a couple of key steps to achieve this task:
- name: Get_Access_Policy
The first task is to obtain the whole JSON file of the "Access Policies".
The "url" for this operation can be find in the FMC API Explorer. If you are not familiar with it, please go back to my previous post Introduction of REST API and Cisco FMC API Explorer. The {{FMC_IP}} & {{domain}} are vars in "/etc/ansible/roles/FMC-enable-policyrule/vars/main.yml".
Also, in this task, we put the obtained "acc_token" in the headers field for authentication purpose. The return code for this "GET" call is "200".
location: /etc/ansible/roles/FMC-enable-policyrule/tasks/main.yml
In this step, we will pull the "json" key value which includes the "items" array:
- name: get policy array
Here we build a new array variable to hold the "items" array:
In the above task, we use the "json_query" method. If you want to know more about this method, please refer to the detailed description of "json_query" in Ansible documentation.
- name: get policy_id
In the above step, we got the access policy array. In this array, we may have multiple access policy items. The following shows the data structure of this array:
This jinja2 code is very straight forward. Basically it use a "for loop" to go through all the items in this array. If the "item.name" is equal to the "policy_name" variable defined in the VAR file ("/etc/ansible/roles/FMC-enable-policyrule/vars/main.yml"), it will return all the "item.id" value.
- name: get policy rule array
a. Locate the policy ID which named "FTD-1-Access-Policy-SYD".
b. Locate the policy rule ID name "Application Filter" under the above policy.
c. Modify the value of the "enable" key in the above policy rule.
As we know, every operation in FMC API is based on the object ID which is a system generated string. We cannot make changes by reference the configured name directly. So in our Ansible playbook, we need to search for the ID for Policy Name "FTD-1-Access-Policy-SYD". In the following, I will describe each name task in details:b. Locate the policy rule ID name "Application Filter" under the above policy.
c. Modify the value of the "enable" key in the above policy rule.
- name: Get_Access_Policy
The first task is to obtain the whole JSON file of the "Access Policies".
The "url" for this operation can be find in the FMC API Explorer. If you are not familiar with it, please go back to my previous post Introduction of REST API and Cisco FMC API Explorer. The {{FMC_IP}} & {{domain}} are vars in "/etc/ansible/roles/FMC-enable-policyrule/vars/main.yml".
Also, in this task, we put the obtained "acc_token" in the headers field for authentication purpose. The return code for this "GET" call is "200".
location: /etc/ansible/roles/FMC-enable-policyrule/tasks/main.yml
- name: Get_Access_Policy
uri:
url: "https://{{FMC_IP}}/api/fmc_config/v1/domain/{{domain}}/policy/accesspolicies"
method: GET
headers:
"x-auth-access-token": "{{acc_token}}"
Connection: keep-alive
validate_certs: no
status_code: 200
body_format: json
register: accesspolicies
|
After having the whole JSON file, we need to check what's the structure of this file. Under the "json", there is a "items" array. And the "accessPolicy" details including the "id" are in this array.
"device_list": {
"accept_ranges":
"bytes",
"cache_control":
"no-cache, no-store, must-revalidate, max-age=0",
"changed": false,
"connection":
"close",
"content_type":
"application/json",
"cookies": {},
"date": "Sun, 24 Jun
2018 00:54:34 GMT",
"failed": false,
"json": {
"items": [
{
"accessPolicy": {
"id":
"000c2911-ed30-0ed3-0000-008589936316",
"name":
"FTD-1-Access-Policy-SYD",
"type":
"AccessPolicy"
},
...
- name: get policy_json
In this step, we will pull the "json" key value which includes the "items" array:
location: /etc/ansible/roles/FMC-enable-policyrule/tasks/main.yml
- name: get policy_json
set_fact: policy_json: "{{accesspolicies.json}}" |
- name: get policy array
Here we build a new array variable to hold the "items" array:
location: /etc/ansible/roles/FMC-enable-policyrule/tasks/main.yml
- name: get policy array
set_fact: policy_array: "{{policy_json | json_query('items[]')}}" |
In the above task, we use the "json_query" method. If you want to know more about this method, please refer to the detailed description of "json_query" in Ansible documentation.
- name: get policy_id
In the above step, we got the access policy array. In this array, we may have multiple access policy items. The following shows the data structure of this array:
Click to Expand |
So we need to search the ID which belongs to the policy named "FTD-1-Access-Policy-SYD". I achieve this searching operation by using the Jinja2 template.
location: /etc/ansible/roles/FMC-enable-policyrule/tasks/get_policy_id.j2
{%- for item in policy_array -%}
{%- if item.name == policy_name -%} {{ item.id }} {%- endif -%} {%- endfor -%} |
This jinja2 code is very straight forward. Basically it use a "for loop" to go through all the items in this array. If the "item.name" is equal to the "policy_name" variable defined in the VAR file ("/etc/ansible/roles/FMC-enable-policyrule/vars/main.yml"), it will return all the "item.id" value.
location: /etc/ansible/roles/FMC-enable-policyrule/tasks/main.yml
- name: get policy_id
set_fact: policy_id: "{{lookup('template','/etc/ansible/roles/FMC-disable-policyrule/tasks/get_policy_id.j2') | trim}}" #"trim" will remove the "\n" retrun from the j2 file |
Here we use the Ansible "lookup template" to call the Jinja2 file. The "trim" keyword is used to get rid of the "\n" returned from Jinja2's return.
The method mentioned above is very useful for fetching the useful information from the JSON configuration file of a network device. For example, a network device has multiple interfaces. Each interface has it's own configuration such as IP address, duplex/speed etc. All the network interface configurations will be put in the same array. By using the jinja2 template, we can go through all the config items in this array and get the interface config based on the particular interface name or description.
- name: Get_Access_Policy_rules
The method mentioned above is very useful for fetching the useful information from the JSON configuration file of a network device. For example, a network device has multiple interfaces. Each interface has it's own configuration such as IP address, duplex/speed etc. All the network interface configurations will be put in the same array. By using the jinja2 template, we can go through all the config items in this array and get the interface config based on the particular interface name or description.
- name: Get_Access_Policy_rules
Now we have the policy ID for "FTD-1-Access-Policy-SYD". We can pull the policy rules in this policy and find out the specific rule we want to modify.
location: /etc/ansible/roles/FMC-enable-policyrule/tasks/main.yml
- name: Get_Access_Policy_rules
uri: url: "https://{{FMC_IP}}/api/fmc_config/v1/domain/{{domain}}/policy/accesspolicies/{{policy_id}}/accessrules?expanded=true" method: GET headers: "x-auth-access-token": "{{acc_token}}" validate_certs: no status_code: 200 body_format: json register: accesspolicierules |
I won't talk much about this as it's very similar to "- name: Get_Access_Policy" above.
- name: get policy_rule_json
Similar to "- name: get policy_json"
- name: get policy_rule_json
Similar to "- name: get policy_json"
location: /etc/ansible/roles/FMC-enable-policyrule/tasks/main.yml
- name: get policy_rule_json
set_fact: policy__rule_json: "{{accesspolicierules.json}}" |
- name: get policy rule array
Similar to "- name: get policy array"
- name: get policy_rule_content
Similar to " - name: get policy_id". However, in the Jinja2 file, we return the whole content of the item instead of only the "id".
The "policy_rule_name" we are going to search is "URL Filter"
The return will be something like this:
"policy_rule_content": {
"action": "BLOCK_RESET",
"enabled": true,
"id": "000C2911-ED30-0ed3-0000-000268436480",
...
},
"name": "URL Filter",
"sendEventsToFMC": true,
...
location: /etc/ansible/roles/FMC-enable-policyrule/tasks/main.yml
- name: get policy rule array
set_fact: policy_rule_array: "{{policy__rule_json | json_query('items[]')}}" |
- name: get policy_rule_content
Similar to " - name: get policy_id". However, in the Jinja2 file, we return the whole content of the item instead of only the "id".
location: /etc/ansible/roles/FMC-enable-policyrule/tasks/get_policy_rule_id.j2
{%- for item in policy_rule_array -%}
{%- if item.name == policy_rule_name -%} {{ item }} {%- endif -%} {%- endfor -%} |
The "policy_rule_name" we are going to search is "URL Filter"
location: /etc/ansible/roles/FMC-enable-policyrule/tasks/main.yml
- name: get policy_rule_content
set_fact: policy_rule_content: "{{lookup('template','/etc/ansible/roles/FMC-disable-policyrule/tasks/get_policy_rule_id.j2')}}" #"trim" will remove the "\n" retrun from the j2 file |
The return will be something like this:
"policy_rule_content": {
"action": "BLOCK_RESET",
"enabled": true,
"id": "000C2911-ED30-0ed3-0000-000268436480",
...
},
"name": "URL Filter",
"sendEventsToFMC": true,
...
The "enabled": true above is the key value we want to modify.
We have the "URL Filter" policy rule content now. In next step, I will modify this policy content to be the right format for a "PUT" call to modify the policy rule and this will be described in "Get policy content, modify content and "PUT' in FMC - Part 2".
We have the "URL Filter" policy rule content now. In next step, I will modify this policy content to be the right format for a "PUT" call to modify the policy rule and this will be described in "Get policy content, modify content and "PUT' in FMC - Part 2".
No comments:
Post a Comment