Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[minor_change] Add pagination support for aci_rest module (DCNE-101) #711

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions plugins/modules/aci_rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,17 @@
- Preserve the response for the provided path.
type: bool
default: false
page_size:
edudppaz marked this conversation as resolved.
Show resolved Hide resolved
description:
- The number of items to return in a single page.
type: int
required: false
edudppaz marked this conversation as resolved.
Show resolved Hide resolved
page:
description:
- The page number to return.
type: int
required: false
edudppaz marked this conversation as resolved.
Show resolved Hide resolved
default: 0
edudppaz marked this conversation as resolved.
Show resolved Hide resolved
extends_documentation_fragment:
- cisco.aci.aci
- cisco.aci.annotation
Expand Down Expand Up @@ -377,6 +388,8 @@
src=dict(type="path", aliases=["config_file"]),
content=dict(type="raw"),
rsp_subtree_preserve=dict(type="bool", default=False),
page_size=dict(type="int", required=False),
page=dict(type="int", required=False, default=0),
edudppaz marked this conversation as resolved.
Show resolved Hide resolved
)

module = AnsibleModule(
Expand All @@ -390,6 +403,10 @@
src = module.params.get("src")
rsp_subtree_preserve = module.params.get("rsp_subtree_preserve")
annotation = module.params.get("annotation")
page_size = module.params.get("page_size")
page = module.params.get("page")
if module.params.get("method") != "get" and page_size:
module.fail_json(msg="Pagination parameters (page and page_size) are only valid for GET method")

Check warning on line 409 in plugins/modules/aci_rest.py

View check run for this annotation

Codecov / codecov/patch

plugins/modules/aci_rest.py#L409

Added line #L409 was not covered by tests

# Report missing file
file_exists = False
Expand Down Expand Up @@ -453,6 +470,10 @@
# NOTE By setting aci.path we ensure that Ansible displays accurate URL info when the plugin and the aci_rest module are used.
aci.path = path.lstrip("/")
aci.url = "{0}/{1}".format(aci.base_url, aci.path)

if aci.params.get("method") == "get" and page_size:
aci.path = "{0}?page={1}&page-size={2}".format(aci.path, page, page_size)
aci.url = update_qsl(aci.url, {"page": page, "page-size": page_size})
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There seems to be a issue when doing setting url and path in this way when path contains other filters. As an example if path is "/api/class/fvSubnet.json?order-by=fvSubnet.descr" and you would add page information as above it would display the url as "https://173.36.219.82/api/class/fvSubnet.json?order-by=fvSubnet.descr?page=0&page-size=3" but would sent correctly to https://173.36.219.82:443/api/class/fvSubnet.json?order-by=fvSubnet.descr&page=0&page-size=3

as temp workaround tested that leveraging the update_qsl() function will display it correctly

Suggested change
aci.path = "{0}?page={1}&page-size={2}".format(aci.path, page, page_size)
aci.url = update_qsl(aci.url, {"page": page, "page-size": page_size})
aci.path = update_qsl(aci.path, {"page": page, "page-size": page_size})
aci.url = update_qsl(aci.url, {"page": page, "page-size": page_size})

I do think however we should rootcause this, because it is likely that similar behaviour is present for rsp-subtree

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I´ll look into this. thanks.

if aci.params.get("method") != "get" and not rsp_subtree_preserve:
aci.path = "{0}?rsp-subtree=modified".format(aci.path)
aci.url = update_qsl(aci.url, {"rsp-subtree": "modified"})
Expand Down
80 changes: 80 additions & 0 deletions tests/integration/targets/aci_rest/tasks/json_inline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@
path: /api/mo/uni/tn-[ansible_test].json
method: delete

- name: Remove tenant 2
cisco.aci.aci_rest:
<<: *tenant_absent
path: /api/mo/uni/tn-[ansible_test_2].json

# ADD TENANT
- name: Add tenant (check mode)
cisco.aci.aci_rest: &tenant_present
Expand Down Expand Up @@ -138,6 +143,75 @@
that:
- nm_query_all_tenants is not changed

# ADD TENANT 2
- name: Add tenant 2 (normal mode)
cisco.aci.aci_rest:
<<: *tenant_present
content:
{
"fvTenant": {
"attributes": {
"descr": "Ansible test tenant",
"name": "ansible_test_2"
}
}
}

# QUERY ALL TENANTS WITH PAGINATION
- name: Query all tenants with pagination (normal mode)
cisco.aci.aci_rest: &tenant_query_all_paginated
host: '{{ aci_hostname }}'
username: '{{ aci_username }}'
password: '{{ aci_password }}'
validate_certs: '{{ aci_validate_certs | default(false) }}'
use_ssl: '{{ aci_use_ssl | default(true) }}'
use_proxy: '{{ aci_use_proxy | default(true) }}'
output_level: '{{ aci_output_level | default("info") }}'
path: /api/class/uni/fvTenant.json
page_size: 10
page: 0
edudppaz marked this conversation as resolved.
Show resolved Hide resolved
method: get
register: nm_query_all_tenants_paginated

- name: Query all tenant with pagination - Size 1 / Page 0 (normal mode)
cisco.aci.aci_rest:
<<: *tenant_query_all_paginated
page_size: 1
page: 0
register: nm_query_all_tenants_paginated_1_0

- name: Query all tenant with pagination - Size 1 / Page 1 (normal mode)
cisco.aci.aci_rest:
<<: *tenant_query_all_paginated
page_size: 1
page: 1
register: nm_query_all_tenants_paginated_1_1

- name: Query all tenant with pagination - Size 2 / Page 0 (normal mode)
cisco.aci.aci_rest:
<<: *tenant_query_all_paginated
page_size: 2
page: 0
register: nm_query_all_tenants_paginated_2_0

- name: Verify query_all_tenants_paginated
ansible.builtin.assert:
that:
- nm_query_all_tenants_paginated is not changed
- nm_query_all_tenants_paginated_1_0 is not changed
- nm_query_all_tenants_paginated_1_1 is not changed
- nm_query_all_tenants_paginated_2_0 is not changed

- name: Verify pagination works as expected
ansible.builtin.assert:
that:
- nm_query_all_tenants_paginated is not changed
- nm_query_all_tenants_paginated_1_0.imdata | length == 1
- nm_query_all_tenants_paginated_1_1.imdata | length == 1
- nm_query_all_tenants_paginated_2_0.imdata | length == 2
- nm_query_all_tenants_paginated_1_0.imdata.0.fvTenant.attributes.name == nm_query_all_tenants_paginated_2_0.imdata.0.fvTenant.attributes.name
- nm_query_all_tenants_paginated_1_1.imdata.0.fvTenant.attributes.name == nm_query_all_tenants_paginated_2_0.imdata.1.fvTenant.attributes.name

# QUERY A TENANT
- name: Query our tenant
cisco.aci.aci_rest: &tenant_query
Expand All @@ -162,6 +236,12 @@
cisco.aci.aci_rest: *tenant_absent
register: nm_remove_tenant

- name: Remove tenant_2 (normal mode)
cisco.aci.aci_rest:
<<: *tenant_absent
path: /api/mo/uni/tn-[ansible_test_2].json
register: nm_remove_tenant_2

- name: Remove tenant again (normal mode)
cisco.aci.aci_rest: *tenant_absent
register: nm_remove_tenant_again
Expand Down
75 changes: 75 additions & 0 deletions tests/integration/targets/aci_rest/tasks/json_string.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@
path: /api/mo/uni/tn-[ansible_test].json
method: delete

- name: Remove tenant 2
cisco.aci.aci_rest:
<<: *tenant_absent
path: /api/mo/uni/tn-[ansible_test_2].json

# ADD TENANT
- name: Add tenant (check mode)
cisco.aci.aci_rest: &tenant_present
Expand Down Expand Up @@ -139,6 +144,76 @@
that:
- nm_query_all_tenants is not changed


# ADD TENANT 2
- name: Add tenant 2 (normal mode)
cisco.aci.aci_rest:
<<: *tenant_present
content: |
{
"fvTenant": {
"attributes": {
"descr": "Ansible test tenant",
"name": "ansible_test_2"
}
}
}

# QUERY ALL TENANTS WITH PAGINATION
- name: Query all tenants with pagination (normal mode)
cisco.aci.aci_rest: &tenant_query_all_paginated
host: '{{ aci_hostname }}'
username: '{{ aci_username }}'
password: '{{ aci_password }}'
validate_certs: '{{ aci_validate_certs | default(false) }}'
use_ssl: '{{ aci_use_ssl | default(true) }}'
use_proxy: '{{ aci_use_proxy | default(true) }}'
output_level: '{{ aci_output_level | default("info") }}'
path: /api/class/uni/fvTenant.json
page_size: 10
page: 0
method: get
register: nm_query_all_tenants_paginated

- name: Query all tenant with pagination - Size 1 / Page 0 (normal mode)
cisco.aci.aci_rest:
<<: *tenant_query_all_paginated
page_size: 1
page: 0
register: nm_query_all_tenants_paginated_1_0

- name: Query all tenant with pagination - Size 1 / Page 1 (normal mode)
cisco.aci.aci_rest:
<<: *tenant_query_all_paginated
page_size: 1
page: 1
register: nm_query_all_tenants_paginated_1_1

- name: Query all tenant with pagination - Size 2 / Page 0 (normal mode)
cisco.aci.aci_rest:
<<: *tenant_query_all_paginated
page_size: 2
page: 0
register: nm_query_all_tenants_paginated_2_0

- name: Verify query_all_tenants_paginated
ansible.builtin.assert:
that:
- nm_query_all_tenants_paginated is not changed
- nm_query_all_tenants_paginated_1_0 is not changed
- nm_query_all_tenants_paginated_1_1 is not changed
- nm_query_all_tenants_paginated_2_0 is not changed

- name: Verify pagination works as expected
ansible.builtin.assert:
that:
- nm_query_all_tenants_paginated is not changed
- nm_query_all_tenants_paginated_1_0.imdata | length == 1
- nm_query_all_tenants_paginated_1_1.imdata | length == 1
- nm_query_all_tenants_paginated_2_0.imdata | length == 2
- nm_query_all_tenants_paginated_1_0.imdata.0.fvTenant.attributes.name == nm_query_all_tenants_paginated_2_0.imdata.0.fvTenant.attributes.name
- nm_query_all_tenants_paginated_1_1.imdata.0.fvTenant.attributes.name == nm_query_all_tenants_paginated_2_0.imdata.1.fvTenant.attributes.name

# QUERY A TENANT
- name: Query our tenant
cisco.aci.aci_rest: &tenant_query
Expand Down
77 changes: 77 additions & 0 deletions tests/integration/targets/aci_rest/tasks/xml_string.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,18 @@
path: /api/mo/uni/tn-[ansible_test].xml
method: delete

- name: Remove tenant2
cisco.aci.aci_rest: &tenant_absent_2
host: '{{ aci_hostname }}'
username: '{{ aci_username }}'
password: '{{ aci_password }}'
validate_certs: '{{ aci_validate_certs | default(false) }}'
use_ssl: '{{ aci_use_ssl | default(true) }}'
use_proxy: '{{ aci_use_proxy | default(true) }}'
output_level: '{{ aci_output_level | default("info") }}'
path: /api/mo/uni/tn-[ansible_test_2].xml
method: delete

# ADD TENANT
- name: Add tenant (check mode)
cisco.aci.aci_rest:
Expand Down Expand Up @@ -184,6 +196,71 @@
that:
- nm_query_all_tenants is not changed

# ADD TENANT 2
- name: Add tenant 2 (normal mode)
cisco.aci.aci_rest:
<<: *tenant_present
path: /api/mo/uni.xml
content:
<fvTenant name="ansible_test_2"/>
register: nm_add_tenant_2

# QUERY ALL TENANTS WITH PAGINATION
- name: Query all tenants with pagination (normal mode)
cisco.aci.aci_rest: &tenant_query_all_paginated
host: '{{ aci_hostname }}'
username: '{{ aci_username }}'
password: '{{ aci_password }}'
validate_certs: '{{ aci_validate_certs | default(false) }}'
use_ssl: '{{ aci_use_ssl | default(true) }}'
use_proxy: '{{ aci_use_proxy | default(true) }}'
output_level: '{{ aci_output_level | default("info") }}'
path: /api/mo/uni.xml
page_size: 10
page: 0
method: get
register: nm_query_all_tenants_paginated


- name: Query all tenant with pagination - Size 1 / Page 0 (normal mode)
cisco.aci.aci_rest:
<<: *tenant_query_all_paginated
page_size: 1
page: 0
register: nm_query_all_tenants_paginated_1_0

- name: Query all tenant with pagination - Size 1 / Page 1 (normal mode)
cisco.aci.aci_rest:
<<: *tenant_query_all_paginated
page_size: 1
page: 1
register: nm_query_all_tenants_paginated_1_1

- name: Query all tenant with pagination - Size 2 / Page 0 (normal mode)
cisco.aci.aci_rest:
<<: *tenant_query_all_paginated
page_size: 2
page: 0
register: nm_query_all_tenants_paginated_2_0

- name: Verify query_all_tenants_paginated
ansible.builtin.assert:
that:
- nm_query_all_tenants_paginated is not changed
- nm_query_all_tenants_paginated_1_0 is not changed
- nm_query_all_tenants_paginated_1_1 is not changed
- nm_query_all_tenants_paginated_2_0 is not changed

- name: Verify pagination works as expected
ansible.builtin.assert:
that:
- nm_query_all_tenants_paginated is not changed
- nm_query_all_tenants_paginated_1_0.imdata | length == 1
- nm_query_all_tenants_paginated_1_1.imdata | length == 1
- nm_query_all_tenants_paginated_2_0.imdata | length == 2
- nm_query_all_tenants_paginated_1_0.imdata.0.fvTenant.attributes.name == nm_query_all_tenants_paginated_2_0.imdata.0.fvTenant.attributes.name
- nm_query_all_tenants_paginated_1_1.imdata.0.fvTenant.attributes.name == nm_query_all_tenants_paginated_2_0.imdata.1.fvTenant.attributes.name

# QUERY A TENANT
- name: Query our tenant
cisco.aci.aci_rest: &tenant_query
Expand Down
Loading