mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-04-27 04:41:26 -07:00
ACI: Add missing examples to module docs (#36417)
This PR includes: - A cleanup of documentation examples for ACI modules - A small fix in aci_rest integration test
This commit is contained in:
parent
fb9af72b48
commit
6534e6a450
21 changed files with 566 additions and 135 deletions
|
@ -54,7 +54,44 @@ options:
|
||||||
extends_documentation_fragment: aci
|
extends_documentation_fragment: aci
|
||||||
'''
|
'''
|
||||||
|
|
||||||
EXAMPLES = r''' # '''
|
EXAMPLES = r'''
|
||||||
|
- name: Add AEP to domain binding
|
||||||
|
aci_aep_to_domain: &binding_present
|
||||||
|
host: apic
|
||||||
|
username: admin
|
||||||
|
password: SomeSecretPassword
|
||||||
|
aep: test_aep
|
||||||
|
domain: phys_dom
|
||||||
|
domain_type: phys
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Remove AEP to domain binding
|
||||||
|
aci_aep_to_domain: &binding_absent
|
||||||
|
host: apic
|
||||||
|
username: admin
|
||||||
|
password: SomeSecretPassword
|
||||||
|
aep: test_aep
|
||||||
|
domain: phys_dom
|
||||||
|
domain_type: phys
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: Query our AEP to domain binding
|
||||||
|
aci_aep_to_domain:
|
||||||
|
host: apic
|
||||||
|
username: admin
|
||||||
|
password: SomeSecretPassword
|
||||||
|
aep: test_aep
|
||||||
|
domain: phys_dom
|
||||||
|
domain_type: phys
|
||||||
|
state: query
|
||||||
|
|
||||||
|
- name: Query all AEP to domain bindings
|
||||||
|
aci_aep_to_domain: &binding_query
|
||||||
|
host: apic
|
||||||
|
username: admin
|
||||||
|
password: SomeSecretPassword
|
||||||
|
state: query
|
||||||
|
'''
|
||||||
|
|
||||||
RETURN = r'''
|
RETURN = r'''
|
||||||
current:
|
current:
|
||||||
|
|
|
@ -97,9 +97,9 @@ EXAMPLES = r'''
|
||||||
password: SomeSecretPassword
|
password: SomeSecretPassword
|
||||||
state: preview
|
state: preview
|
||||||
export_policy: config_backup
|
export_policy: config_backup
|
||||||
snapshot: 'run-2017-08-28T06-24-01'
|
snapshot: run-2017-08-28T06-24-01
|
||||||
compare_export_policy: config_backup
|
compare_export_policy: config_backup
|
||||||
compare_snapshot: 'run-2017-08-27T23-43-56'
|
compare_snapshot: run-2017-08-27T23-43-56
|
||||||
|
|
||||||
- name: Rollback Configuration
|
- name: Rollback Configuration
|
||||||
aci_config_rollback:
|
aci_config_rollback:
|
||||||
|
@ -109,7 +109,7 @@ EXAMPLES = r'''
|
||||||
state: rollback
|
state: rollback
|
||||||
import_policy: rollback_config
|
import_policy: rollback_config
|
||||||
export_policy: config_backup
|
export_policy: config_backup
|
||||||
snapshot: 'run-2017-08-28T06-24-01'
|
snapshot: run-2017-08-28T06-24-01
|
||||||
|
|
||||||
- name: Rollback Configuration
|
- name: Rollback Configuration
|
||||||
aci_config_rollback:
|
aci_config_rollback:
|
||||||
|
@ -119,8 +119,8 @@ EXAMPLES = r'''
|
||||||
state: rollback
|
state: rollback
|
||||||
import_policy: rollback_config
|
import_policy: rollback_config
|
||||||
export_policy: config_backup
|
export_policy: config_backup
|
||||||
snapshot: 'run-2017-08-28T06-24-01'
|
snapshot: run-2017-08-28T06-24-01
|
||||||
description: 'Rollback 8-27 changes'
|
description: Rollback 8-27 changes
|
||||||
import_mode: atomic
|
import_mode: atomic
|
||||||
import_type: replace
|
import_type: replace
|
||||||
fail_on_decrypt: yes
|
fail_on_decrypt: yes
|
||||||
|
|
|
@ -66,18 +66,42 @@ options:
|
||||||
extends_documentation_fragment: aci
|
extends_documentation_fragment: aci
|
||||||
'''
|
'''
|
||||||
|
|
||||||
# FIXME: Add more, better examples
|
|
||||||
EXAMPLES = r'''
|
EXAMPLES = r'''
|
||||||
- aci_contract:
|
- name: Add a new contract
|
||||||
host: '{{ inventory_hostname }}'
|
aci_contract:
|
||||||
username: '{{ username }}'
|
host: apic
|
||||||
password: '{{ password }}'
|
username: admin
|
||||||
contract: '{{ contract }}'
|
password: SomeSecretPassword
|
||||||
description: '{{ descr }}'
|
tenant: production
|
||||||
tenant: '{{ tenant }}'
|
contract: web_to_db
|
||||||
scope: '{{ scope }}'
|
description: Communication between web-servers and database
|
||||||
priority: '{{ priority }}'
|
scope: application-profile
|
||||||
target: '{{ target }}'
|
state: present
|
||||||
|
|
||||||
|
- name: Remove an existing contract
|
||||||
|
aci_contract:
|
||||||
|
host: apic
|
||||||
|
username: admin
|
||||||
|
password: SomeSecretPassword
|
||||||
|
tenant: production
|
||||||
|
contract: web_to_db
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: Query a specific contract
|
||||||
|
aci_contract:
|
||||||
|
host: apic
|
||||||
|
username: admin
|
||||||
|
password: SomeSecretPassword
|
||||||
|
tenant: production
|
||||||
|
contract: web_to_db
|
||||||
|
state: query
|
||||||
|
|
||||||
|
- name: Query all contracts
|
||||||
|
aci_contract:
|
||||||
|
host: apic
|
||||||
|
username: admin
|
||||||
|
password: SomeSecretPassword
|
||||||
|
state: query
|
||||||
'''
|
'''
|
||||||
|
|
||||||
RETURN = r'''
|
RETURN = r'''
|
||||||
|
|
|
@ -62,15 +62,50 @@ extends_documentation_fragment: aci
|
||||||
|
|
||||||
# FIXME: Add more, better examples
|
# FIXME: Add more, better examples
|
||||||
EXAMPLES = r'''
|
EXAMPLES = r'''
|
||||||
- aci_subject_filter_binding:
|
- name: Add a new contract subject to filer binding
|
||||||
host: '{{ inventory_hostname }}'
|
aci_subject_filter_binding:
|
||||||
username: '{{ username }}'
|
host: apic
|
||||||
password: '{{ password }}'
|
username: admin
|
||||||
tenant: '{{ tenant }}'
|
password: SomeSecretPassword
|
||||||
contract: '{{ contract }}'
|
tenant: production
|
||||||
subject: '{{ subject }}'
|
contract: web_to_db
|
||||||
|
subject: test
|
||||||
filter: '{{ filter }}'
|
filter: '{{ filter }}'
|
||||||
log: '{{ log }}'
|
log: '{{ log }}'
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Remove an existing contract subject to filter binding
|
||||||
|
aci_subject_filter_binding:
|
||||||
|
host: apic
|
||||||
|
username: admin
|
||||||
|
password: SomeSecretPassword
|
||||||
|
tenant: production
|
||||||
|
contract: web_to_db
|
||||||
|
subject: test
|
||||||
|
filter: '{{ filter }}'
|
||||||
|
log: '{{ log }}'
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Query a specific contract subject to filter binding
|
||||||
|
aci_subject_filter_binding:
|
||||||
|
host: apic
|
||||||
|
username: admin
|
||||||
|
password: SomeSecretPassword
|
||||||
|
tenant: production
|
||||||
|
contract: web_to_db
|
||||||
|
subject: test
|
||||||
|
filter: '{{ filter }}'
|
||||||
|
state: query
|
||||||
|
|
||||||
|
- name: Query all contract subject to filter bindings
|
||||||
|
aci_subject_filter_binding:
|
||||||
|
host: apic
|
||||||
|
username: admin
|
||||||
|
password: SomeSecretPassword
|
||||||
|
tenant: production
|
||||||
|
contract: web_to_db
|
||||||
|
subject: test
|
||||||
|
state: query
|
||||||
'''
|
'''
|
||||||
|
|
||||||
RETURN = r'''
|
RETURN = r'''
|
||||||
|
|
|
@ -64,7 +64,52 @@ options:
|
||||||
extends_documentation_fragment: aci
|
extends_documentation_fragment: aci
|
||||||
'''
|
'''
|
||||||
|
|
||||||
EXAMPLES = r''' # '''
|
EXAMPLES = r'''
|
||||||
|
- name: Add domain to VLAN pool binding
|
||||||
|
aci_domain_to_encap_pool:
|
||||||
|
host: apic
|
||||||
|
username: admin
|
||||||
|
password: SomeSecretPassword
|
||||||
|
domain: phys_dom
|
||||||
|
domain_type: phys
|
||||||
|
pool: test_pool
|
||||||
|
pool_type: vlan
|
||||||
|
pool_allocation_mode: dynamic
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Remove domain to VLAN pool binding
|
||||||
|
aci_domain_to_encap_pool:
|
||||||
|
host: apic
|
||||||
|
username: admin
|
||||||
|
password: SomeSecretPassword
|
||||||
|
domain: phys_dom
|
||||||
|
domain_type: phys
|
||||||
|
pool: test_pool
|
||||||
|
pool_type: vlan
|
||||||
|
pool_allocation_mode: dynamic
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: Query our domain to VLAN pool binding
|
||||||
|
aci_domain_to_encap_pool:
|
||||||
|
host: apic
|
||||||
|
username: admin
|
||||||
|
password: SomeSecretPassword
|
||||||
|
domain: phys_dom
|
||||||
|
pool: test_pool
|
||||||
|
pool_type: vlan
|
||||||
|
pool_allocation_mode: dynamic
|
||||||
|
state: query
|
||||||
|
|
||||||
|
- name: Query all domain to VLAN pool bindings
|
||||||
|
aci_domain_to_encap_pool:
|
||||||
|
host: apic
|
||||||
|
username: admin
|
||||||
|
password: SomeSecretPassword
|
||||||
|
domain_type: phys
|
||||||
|
pool_type: vlan
|
||||||
|
pool_allocation_mode: dynamic
|
||||||
|
state: query
|
||||||
|
'''
|
||||||
|
|
||||||
RETURN = r'''
|
RETURN = r'''
|
||||||
current:
|
current:
|
||||||
|
|
|
@ -67,7 +67,51 @@ options:
|
||||||
extends_documentation_fragment: aci
|
extends_documentation_fragment: aci
|
||||||
'''
|
'''
|
||||||
|
|
||||||
EXAMPLES = r''' # '''
|
EXAMPLES = r'''
|
||||||
|
- name: Add a new contract to EPG binding
|
||||||
|
aci_epg_to_contract:
|
||||||
|
host: apic
|
||||||
|
username: admin
|
||||||
|
password: SomeSecretPassword
|
||||||
|
tenant: anstest
|
||||||
|
ap: anstest
|
||||||
|
epg: anstest
|
||||||
|
contract: anstest_http
|
||||||
|
contract_type: provider
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Remove an existing contract to EPG binding
|
||||||
|
aci_epg_to_contract:
|
||||||
|
host: apic
|
||||||
|
username: admin
|
||||||
|
password: SomeSecretPassword
|
||||||
|
tenant: anstest
|
||||||
|
ap: anstest
|
||||||
|
epg: anstest
|
||||||
|
contract: anstest_http
|
||||||
|
contract_type: provider
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: Query a specific contract to EPG binding
|
||||||
|
aci_epg_to_contract:
|
||||||
|
host: apic
|
||||||
|
username: admin
|
||||||
|
password: SomeSecretPassword
|
||||||
|
tenant: anstest
|
||||||
|
ap: anstest
|
||||||
|
epg: anstest
|
||||||
|
contract: anstest_http
|
||||||
|
contract_type: provider
|
||||||
|
state: query
|
||||||
|
|
||||||
|
- name: Query all provider contract to EPG bindings
|
||||||
|
aci_epg_to_contract:
|
||||||
|
host: apic
|
||||||
|
username: admin
|
||||||
|
password: SomeSecretPassword
|
||||||
|
contract_type: provider
|
||||||
|
state: query
|
||||||
|
'''
|
||||||
|
|
||||||
RETURN = r'''
|
RETURN = r'''
|
||||||
current:
|
current:
|
||||||
|
|
|
@ -103,7 +103,50 @@ options:
|
||||||
extends_documentation_fragment: aci
|
extends_documentation_fragment: aci
|
||||||
'''
|
'''
|
||||||
|
|
||||||
EXAMPLES = r''' # '''
|
EXAMPLES = r'''
|
||||||
|
- name: Add a new physical domain to EPG binding
|
||||||
|
aci_epg_to_domain:
|
||||||
|
host: apic
|
||||||
|
username: admin
|
||||||
|
password: SomeSecretPassword
|
||||||
|
tenant: anstest
|
||||||
|
ap: anstest
|
||||||
|
epg: anstest
|
||||||
|
domain: anstest
|
||||||
|
domain_type: phys
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Remove an existing physical domain to EPG binding
|
||||||
|
aci_epg_to_domain:
|
||||||
|
host: apic
|
||||||
|
username: admin
|
||||||
|
password: SomeSecretPassword
|
||||||
|
tenant: anstest
|
||||||
|
ap: anstest
|
||||||
|
epg: anstest
|
||||||
|
domain: anstest
|
||||||
|
domain_type: phys
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: Query a specific physical domain to EPG binding
|
||||||
|
aci_epg_to_domain:
|
||||||
|
host: apic
|
||||||
|
username: admin
|
||||||
|
password: SomeSecretPassword
|
||||||
|
tenant: anstest
|
||||||
|
ap: anstest
|
||||||
|
epg: anstest
|
||||||
|
domain: anstest
|
||||||
|
domain_type: phys
|
||||||
|
state: query
|
||||||
|
|
||||||
|
- name: Query all domain to EPG bindings
|
||||||
|
aci_epg_to_domain:
|
||||||
|
host: apic
|
||||||
|
username: admin
|
||||||
|
password: SomeSecretPassword
|
||||||
|
state: query
|
||||||
|
'''
|
||||||
|
|
||||||
RETURN = r'''
|
RETURN = r'''
|
||||||
current:
|
current:
|
||||||
|
|
|
@ -58,36 +58,36 @@ extends_documentation_fragment: aci
|
||||||
EXAMPLES = r'''
|
EXAMPLES = r'''
|
||||||
- name: Add firmware source
|
- name: Add firmware source
|
||||||
aci_firmware_source:
|
aci_firmware_source:
|
||||||
host: '{{ aci_hostname }}'
|
host: apic
|
||||||
username: '{{ aci_username }}'
|
username: admin
|
||||||
password: '{{ aci_password }}'
|
password: SomeSecretPassword
|
||||||
source: aci-msft-pkg-3.1.1i.zip
|
source: aci-msft-pkg-3.1.1i.zip
|
||||||
url: foobar.cisco.com/download/cisco/aci/aci-msft-pkg-3.1.1i.zip
|
url: foo.bar.cisco.com/download/cisco/aci/aci-msft-pkg-3.1.1i.zip
|
||||||
url_protocol: http
|
url_protocol: http
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
- name: Remove firmware source
|
- name: Remove firmware source
|
||||||
aci_firmware_source:
|
aci_firmware_source:
|
||||||
host: '{{ aci_hostname }}'
|
host: apic
|
||||||
username: '{{ aci_username }}'
|
username: admin
|
||||||
password: '{{ aci_password }}'
|
password: SomeSecretPassword
|
||||||
source: aci-msft-pkg-3.1.1i.zip
|
source: aci-msft-pkg-3.1.1i.zip
|
||||||
state: absent
|
state: absent
|
||||||
|
|
||||||
- name: Query all firmware sources
|
|
||||||
aci_firmware_source:
|
|
||||||
host: '{{ aci_hostname }}'
|
|
||||||
username: '{{ aci_username }}'
|
|
||||||
password: '{{ aci_password }}'
|
|
||||||
state: query
|
|
||||||
|
|
||||||
- name: Query a specific firmware source
|
- name: Query a specific firmware source
|
||||||
aci_firmware_source:
|
aci_firmware_source:
|
||||||
host: '{{ aci_hostname }}'
|
host: apic
|
||||||
username: '{{ aci_username }}'
|
username: admin
|
||||||
password: '{{ aci_password }}'
|
password: SomeSecretPassword
|
||||||
source: aci-msft-pkg-3.1.1i.zip
|
source: aci-msft-pkg-3.1.1i.zip
|
||||||
state: query
|
state: query
|
||||||
|
|
||||||
|
- name: Query all firmware sources
|
||||||
|
aci_firmware_source:
|
||||||
|
host: apic
|
||||||
|
username: admin
|
||||||
|
password: SomeSecretPassword
|
||||||
|
state: query
|
||||||
'''
|
'''
|
||||||
|
|
||||||
RETURN = r'''
|
RETURN = r'''
|
||||||
|
|
|
@ -111,12 +111,13 @@ options:
|
||||||
extends_documentation_fragment: aci
|
extends_documentation_fragment: aci
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
# TODO: Add query examples
|
||||||
EXAMPLES = r'''
|
EXAMPLES = r'''
|
||||||
- name: creating a Port Channel (PC) Interface Policy Group
|
- name: Create a Port Channel (PC) Interface Policy Group
|
||||||
aci_interface_policy_leaf_policy_group:
|
aci_interface_policy_leaf_policy_group:
|
||||||
host: apic
|
host: apic
|
||||||
username: yourusername
|
username: admin
|
||||||
password: yourpassword
|
password: SomeSecretPassword
|
||||||
policy_group: policygroupname
|
policy_group: policygroupname
|
||||||
description: policygroupname description
|
description: policygroupname description
|
||||||
lag_type: link
|
lag_type: link
|
||||||
|
@ -124,33 +125,33 @@ EXAMPLES = r'''
|
||||||
fibre_channel_interface_policy: whateverfcpolicy
|
fibre_channel_interface_policy: whateverfcpolicy
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
- name: creating a Virtual Port Channel (VPC) Interface Policy Group (no description)
|
- name: Create a Virtual Port Channel (VPC) Interface Policy Group (no description)
|
||||||
aci_interface_policy_leaf_policy_group:
|
aci_interface_policy_leaf_policy_group:
|
||||||
host: apic
|
host: apic
|
||||||
username: yourusername
|
username: admin
|
||||||
password: yourpassword
|
password: SomeSecretPassword
|
||||||
policy_group: policygroupname
|
policy_group: policygroupname
|
||||||
lag_type: node
|
lag_type: node
|
||||||
link_level_policy: whateverlinklevelpolicy
|
link_level_policy: whateverlinklevelpolicy
|
||||||
fibre_channel_interface_policy: whateverfcpolicy
|
fibre_channel_interface_policy: whateverfcpolicy
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
- name: creating a Leaf Access Port Policy Group (no description)
|
- name: Create a Leaf Access Port Policy Group (no description)
|
||||||
aci_interface_policy_leaf_policy_group:
|
aci_interface_policy_leaf_policy_group:
|
||||||
host: apic
|
host: apic
|
||||||
username: yourusername
|
username: admin
|
||||||
password: yourpassword
|
password: SomeSecretPassword
|
||||||
policy_group: policygroupname
|
policy_group: policygroupname
|
||||||
lag_type: leaf
|
lag_type: leaf
|
||||||
link_level_policy: whateverlinklevelpolicy
|
link_level_policy: whateverlinklevelpolicy
|
||||||
fibre_channel_interface_policy: whateverfcpolicy
|
fibre_channel_interface_policy: whateverfcpolicy
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
- name: deleting an Interface policy Leaf Policy Group
|
- name: Delete an Interface policy Leaf Policy Group
|
||||||
aci_interface_policy_leaf_policy_group:
|
aci_interface_policy_leaf_policy_group:
|
||||||
host: apic
|
host: apic
|
||||||
username: yourusername
|
username: admin
|
||||||
password: yourpassword
|
password: SomeSecretPassword
|
||||||
policy_group: policygroupname
|
policy_group: policygroupname
|
||||||
lag_type: type_name
|
lag_type: type_name
|
||||||
state: absent
|
state: absent
|
||||||
|
|
|
@ -48,8 +48,8 @@ EXAMPLES = r'''
|
||||||
- name: Associating an interface selector profile to a switch policy leaf profile
|
- name: Associating an interface selector profile to a switch policy leaf profile
|
||||||
aci_interface_selector_to_switch_policy_leaf_profile:
|
aci_interface_selector_to_switch_policy_leaf_profile:
|
||||||
host: apic
|
host: apic
|
||||||
username: someusername
|
username: admin
|
||||||
password: somepassword
|
password: SomeSecretPassword
|
||||||
leaf_profile: sw_name
|
leaf_profile: sw_name
|
||||||
interface_selector: interface_profile_name
|
interface_selector: interface_profile_name
|
||||||
state: present
|
state: present
|
||||||
|
@ -57,8 +57,8 @@ EXAMPLES = r'''
|
||||||
- name: Remove an interface selector profile associated with a switch policy leaf profile
|
- name: Remove an interface selector profile associated with a switch policy leaf profile
|
||||||
aci_interface_selector_to_switch_policy_leaf_profile:
|
aci_interface_selector_to_switch_policy_leaf_profile:
|
||||||
host: apic
|
host: apic
|
||||||
username: someusername
|
username: admin
|
||||||
password: somepassword
|
password: SomeSecretPassword
|
||||||
leaf_profile: sw_name
|
leaf_profile: sw_name
|
||||||
interface_selector: interface_profile_name
|
interface_selector: interface_profile_name
|
||||||
state: absent
|
state: absent
|
||||||
|
@ -66,8 +66,8 @@ EXAMPLES = r'''
|
||||||
- name: Query an interface selector profile associated with a switch policy leaf profile
|
- name: Query an interface selector profile associated with a switch policy leaf profile
|
||||||
aci_interface_selector_to_switch_policy_leaf_profile:
|
aci_interface_selector_to_switch_policy_leaf_profile:
|
||||||
host: apic
|
host: apic
|
||||||
username: someusername
|
username: admin
|
||||||
password: somepassword
|
password: SomeSecretPassword
|
||||||
leaf_profile: sw_name
|
leaf_profile: sw_name
|
||||||
interface_selector: interface_profile_name
|
interface_selector: interface_profile_name
|
||||||
state: query
|
state: query
|
||||||
|
|
|
@ -65,8 +65,8 @@ notes:
|
||||||
EXAMPLES = r'''
|
EXAMPLES = r'''
|
||||||
- name: Add a tenant using certifcate authentication
|
- name: Add a tenant using certifcate authentication
|
||||||
aci_rest:
|
aci_rest:
|
||||||
host: '{{ inventory_hostname }}'
|
host: apic
|
||||||
username: '{{ aci_username }}'
|
username: admin
|
||||||
private_key: pki/admin.key
|
private_key: pki/admin.key
|
||||||
method: post
|
method: post
|
||||||
path: /api/mo/uni.xml
|
path: /api/mo/uni.xml
|
||||||
|
@ -75,8 +75,8 @@ EXAMPLES = r'''
|
||||||
|
|
||||||
- name: Add a tenant using inline YAML
|
- name: Add a tenant using inline YAML
|
||||||
aci_rest:
|
aci_rest:
|
||||||
host: '{{ inventory_hostname }}'
|
host: apic
|
||||||
username: '{{ aci_username }}'
|
username: admin
|
||||||
private_key: pki/admin.key
|
private_key: pki/admin.key
|
||||||
validate_certs: no
|
validate_certs: no
|
||||||
path: /api/mo/uni.json
|
path: /api/mo/uni.json
|
||||||
|
@ -90,8 +90,8 @@ EXAMPLES = r'''
|
||||||
|
|
||||||
- name: Add a tenant using a JSON string
|
- name: Add a tenant using a JSON string
|
||||||
aci_rest:
|
aci_rest:
|
||||||
host: '{{ inventory_hostname }}'
|
host: apic
|
||||||
username: '{{ aci_username }}'
|
username: admin
|
||||||
private_key: pki/admin.key
|
private_key: pki/admin.key
|
||||||
validate_certs: no
|
validate_certs: no
|
||||||
path: /api/mo/uni.json
|
path: /api/mo/uni.json
|
||||||
|
@ -109,8 +109,8 @@ EXAMPLES = r'''
|
||||||
|
|
||||||
- name: Add a tenant using an XML string
|
- name: Add a tenant using an XML string
|
||||||
aci_rest:
|
aci_rest:
|
||||||
host: '{{ inventory_hostname }}'
|
host: apic
|
||||||
username: '{{ aci_username }}'
|
username: admin
|
||||||
private_key: pki/{{ aci_username}}.key
|
private_key: pki/{{ aci_username}}.key
|
||||||
validate_certs: no
|
validate_certs: no
|
||||||
path: /api/mo/uni.xml
|
path: /api/mo/uni.xml
|
||||||
|
@ -120,17 +120,17 @@ EXAMPLES = r'''
|
||||||
|
|
||||||
- name: Get tenants using password authentication
|
- name: Get tenants using password authentication
|
||||||
aci_rest:
|
aci_rest:
|
||||||
host: '{{ inventory_hostname }}'
|
host: apic
|
||||||
username: '{{ aci_username }}'
|
username: admin
|
||||||
password: '{{ aci_password }}'
|
password: SomeSecretPassword
|
||||||
method: get
|
method: get
|
||||||
path: /api/node/class/fvTenant.json
|
path: /api/node/class/fvTenant.json
|
||||||
delegate_to: localhost
|
delegate_to: localhost
|
||||||
|
|
||||||
- name: Configure contracts
|
- name: Configure contracts
|
||||||
aci_rest:
|
aci_rest:
|
||||||
host: '{{ inventory_hostname }}'
|
host: apic
|
||||||
username: '{{ aci_username }}'
|
username: admin
|
||||||
private_key: pki/admin.key
|
private_key: pki/admin.key
|
||||||
method: post
|
method: post
|
||||||
path: /api/mo/uni.xml
|
path: /api/mo/uni.xml
|
||||||
|
@ -139,8 +139,8 @@ EXAMPLES = r'''
|
||||||
|
|
||||||
- name: Register leaves and spines
|
- name: Register leaves and spines
|
||||||
aci_rest:
|
aci_rest:
|
||||||
host: '{{ inventory_hostname }}'
|
host: apic
|
||||||
username: '{{ aci_username }}'
|
username: admin
|
||||||
private_key: pki/admin.key
|
private_key: pki/admin.key
|
||||||
validate_certs: no
|
validate_certs: no
|
||||||
method: post
|
method: post
|
||||||
|
@ -155,8 +155,8 @@ EXAMPLES = r'''
|
||||||
|
|
||||||
- name: Wait for all controllers to become ready
|
- name: Wait for all controllers to become ready
|
||||||
aci_rest:
|
aci_rest:
|
||||||
host: '{{ inventory_hostname }}'
|
host: apic
|
||||||
username: '{{ aci_username }}'
|
username: admin
|
||||||
private_key: pki/admin.key
|
private_key: pki/admin.key
|
||||||
validate_certs: no
|
validate_certs: no
|
||||||
path: /api/node/class/topSystem.json?query-target-filter=eq(topSystem.role,"controller")
|
path: /api/node/class/topSystem.json?query-target-filter=eq(topSystem.role,"controller")
|
||||||
|
|
|
@ -118,7 +118,108 @@ EXAMPLES = r'''
|
||||||
'''
|
'''
|
||||||
|
|
||||||
RETURN = r'''
|
RETURN = r'''
|
||||||
#
|
current:
|
||||||
|
description: The existing configuration from the APIC after the module has finished
|
||||||
|
returned: success
|
||||||
|
type: list
|
||||||
|
sample:
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"fvTenant": {
|
||||||
|
"attributes": {
|
||||||
|
"descr": "Production environment",
|
||||||
|
"dn": "uni/tn-production",
|
||||||
|
"name": "production",
|
||||||
|
"nameAlias": "",
|
||||||
|
"ownerKey": "",
|
||||||
|
"ownerTag": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
error:
|
||||||
|
description: The error information as returned from the APIC
|
||||||
|
returned: failure
|
||||||
|
type: dict
|
||||||
|
sample:
|
||||||
|
{
|
||||||
|
"code": "122",
|
||||||
|
"text": "unknown managed object class foo"
|
||||||
|
}
|
||||||
|
raw:
|
||||||
|
description: The raw output returned by the APIC REST API (xml or json)
|
||||||
|
returned: parse error
|
||||||
|
type: string
|
||||||
|
sample: '<?xml version="1.0" encoding="UTF-8"?><imdata totalCount="1"><error code="122" text="unknown managed object class foo"/></imdata>'
|
||||||
|
sent:
|
||||||
|
description: The actual/minimal configuration pushed to the APIC
|
||||||
|
returned: info
|
||||||
|
type: list
|
||||||
|
sample:
|
||||||
|
{
|
||||||
|
"fvTenant": {
|
||||||
|
"attributes": {
|
||||||
|
"descr": "Production environment"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
previous:
|
||||||
|
description: The original configuration from the APIC before the module has started
|
||||||
|
returned: info
|
||||||
|
type: list
|
||||||
|
sample:
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"fvTenant": {
|
||||||
|
"attributes": {
|
||||||
|
"descr": "Production",
|
||||||
|
"dn": "uni/tn-production",
|
||||||
|
"name": "production",
|
||||||
|
"nameAlias": "",
|
||||||
|
"ownerKey": "",
|
||||||
|
"ownerTag": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
proposed:
|
||||||
|
description: The assembled configuration from the user-provided parameters
|
||||||
|
returned: info
|
||||||
|
type: dict
|
||||||
|
sample:
|
||||||
|
{
|
||||||
|
"fvTenant": {
|
||||||
|
"attributes": {
|
||||||
|
"descr": "Production environment",
|
||||||
|
"name": "production"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
filter_string:
|
||||||
|
description: The filter string used for the request
|
||||||
|
returned: failure or debug
|
||||||
|
type: string
|
||||||
|
sample: ?rsp-prop-include=config-only
|
||||||
|
method:
|
||||||
|
description: The HTTP method used for the request to the APIC
|
||||||
|
returned: failure or debug
|
||||||
|
type: string
|
||||||
|
sample: POST
|
||||||
|
response:
|
||||||
|
description: The HTTP response from the APIC
|
||||||
|
returned: failure or debug
|
||||||
|
type: string
|
||||||
|
sample: OK (30 bytes)
|
||||||
|
status:
|
||||||
|
description: The HTTP status from the APIC
|
||||||
|
returned: failure or debug
|
||||||
|
type: int
|
||||||
|
sample: 200
|
||||||
|
url:
|
||||||
|
description: The HTTP url used for the request to the APIC
|
||||||
|
returned: failure or debug
|
||||||
|
type: string
|
||||||
|
sample: https://10.11.12.13/api/mo/uni/tn-production.json
|
||||||
'''
|
'''
|
||||||
|
|
||||||
from ansible.module_utils.network.aci.aci import ACIModule, aci_argument_spec
|
from ansible.module_utils.network.aci.aci import ACIModule, aci_argument_spec
|
||||||
|
|
|
@ -69,8 +69,8 @@ EXAMPLES = r'''
|
||||||
- name: adding a switch policy leaf profile selector associated Node Block range (w/ policy group)
|
- name: adding a switch policy leaf profile selector associated Node Block range (w/ policy group)
|
||||||
aci_switch_leaf_selector:
|
aci_switch_leaf_selector:
|
||||||
host: apic
|
host: apic
|
||||||
username: someusername
|
username: admin
|
||||||
password: somepassword
|
password: SomeSecretPassword
|
||||||
leaf_profile: sw_name
|
leaf_profile: sw_name
|
||||||
leaf: leaf_selector_name
|
leaf: leaf_selector_name
|
||||||
leaf_node_blk: node_blk_name
|
leaf_node_blk: node_blk_name
|
||||||
|
@ -82,8 +82,8 @@ EXAMPLES = r'''
|
||||||
- name: adding a switch policy leaf profile selector associated Node Block range (w/o policy group)
|
- name: adding a switch policy leaf profile selector associated Node Block range (w/o policy group)
|
||||||
aci_switch_leaf_selector:
|
aci_switch_leaf_selector:
|
||||||
host: apic
|
host: apic
|
||||||
username: someusername
|
username: admin
|
||||||
password: somepassword
|
password: SomeSecretPassword
|
||||||
leaf_profile: sw_name
|
leaf_profile: sw_name
|
||||||
leaf: leaf_selector_name
|
leaf: leaf_selector_name
|
||||||
leaf_node_blk: node_blk_name
|
leaf_node_blk: node_blk_name
|
||||||
|
@ -94,8 +94,8 @@ EXAMPLES = r'''
|
||||||
- name: Removing a switch policy leaf profile selector
|
- name: Removing a switch policy leaf profile selector
|
||||||
aci_switch_leaf_selector:
|
aci_switch_leaf_selector:
|
||||||
host: apic
|
host: apic
|
||||||
username: someusername
|
username: admin
|
||||||
password: somepassword
|
password: SomeSecretPassword
|
||||||
leaf_profile: sw_name
|
leaf_profile: sw_name
|
||||||
leaf: leaf_selector_name
|
leaf: leaf_selector_name
|
||||||
state: absent
|
state: absent
|
||||||
|
@ -103,8 +103,8 @@ EXAMPLES = r'''
|
||||||
- name: Querying a switch policy leaf profile selector
|
- name: Querying a switch policy leaf profile selector
|
||||||
aci_switch_leaf_selector:
|
aci_switch_leaf_selector:
|
||||||
host: apic
|
host: apic
|
||||||
username: someusername
|
username: admin
|
||||||
password: somepassword
|
password: SomeSecretPassword
|
||||||
leaf_profile: sw_name
|
leaf_profile: sw_name
|
||||||
leaf: leaf_selector_name
|
leaf: leaf_selector_name
|
||||||
state: query
|
state: query
|
||||||
|
|
|
@ -44,8 +44,8 @@ EXAMPLES = r'''
|
||||||
- name: creating a Leaf Profile with description
|
- name: creating a Leaf Profile with description
|
||||||
aci_switch_policy_leaf_profile:
|
aci_switch_policy_leaf_profile:
|
||||||
host: apic
|
host: apic
|
||||||
username: someusername
|
username: admin
|
||||||
password: somepassword
|
password: SomeSecretPassword
|
||||||
leaf_profile: sw_name
|
leaf_profile: sw_name
|
||||||
description: sw_description
|
description: sw_description
|
||||||
state: present
|
state: present
|
||||||
|
@ -53,16 +53,16 @@ EXAMPLES = r'''
|
||||||
- name: Deleting a Leaf Profile
|
- name: Deleting a Leaf Profile
|
||||||
aci_switch_policy_leaf_profile:
|
aci_switch_policy_leaf_profile:
|
||||||
host: apic
|
host: apic
|
||||||
username: someusername
|
username: admin
|
||||||
password: somepassword
|
password: SomeSecretPassword
|
||||||
leaf_profile: sw_name
|
leaf_profile: sw_name
|
||||||
state: absent
|
state: absent
|
||||||
|
|
||||||
- name: Query a Leaf Profile
|
- name: Query a Leaf Profile
|
||||||
aci_switch_policy_leaf_profile:
|
aci_switch_policy_leaf_profile:
|
||||||
host: apic
|
host: apic
|
||||||
username: someusername
|
username: admin
|
||||||
password: somepassword
|
password: SomeSecretPassword
|
||||||
leaf_profile: sw_name
|
leaf_profile: sw_name
|
||||||
state: query
|
state: query
|
||||||
'''
|
'''
|
||||||
|
|
|
@ -58,9 +58,9 @@ extends_documentation_fragment: aci
|
||||||
EXAMPLES = r'''
|
EXAMPLES = r'''
|
||||||
- name: Add Explicit vPC Protection Group
|
- name: Add Explicit vPC Protection Group
|
||||||
aci_switch_policy_vpc_protection_group:
|
aci_switch_policy_vpc_protection_group:
|
||||||
host: "{{ aci_hostname }}"
|
host: apic
|
||||||
username: "{{ aci_username }}"
|
username: admin
|
||||||
password: "{{ aci_password }}"
|
password: SomeSecretPassword
|
||||||
protection_group: protectiongroupname
|
protection_group: protectiongroupname
|
||||||
protection_group_id: 6
|
protection_group_id: 6
|
||||||
vpc_domain_policy: vpcdomainpolicyname
|
vpc_domain_policy: vpcdomainpolicyname
|
||||||
|
@ -70,15 +70,116 @@ EXAMPLES = r'''
|
||||||
|
|
||||||
- name: Remove Explicit vPC Protection Group
|
- name: Remove Explicit vPC Protection Group
|
||||||
aci_switch_policy_vpc_protection_group:
|
aci_switch_policy_vpc_protection_group:
|
||||||
host: "{{ aci_hostname }}"
|
host: apic
|
||||||
username: "{{ aci_username }}"
|
username: admin
|
||||||
password: "{{ aci_password }}"
|
password: SomeSecretPassword
|
||||||
protection_group: protectiongroupname
|
protection_group: protectiongroupname
|
||||||
state: absent
|
state: absent
|
||||||
'''
|
'''
|
||||||
|
|
||||||
RETURN = r'''
|
RETURN = r'''
|
||||||
#
|
current:
|
||||||
|
description: The existing configuration from the APIC after the module has finished
|
||||||
|
returned: success
|
||||||
|
type: list
|
||||||
|
sample:
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"fvTenant": {
|
||||||
|
"attributes": {
|
||||||
|
"descr": "Production environment",
|
||||||
|
"dn": "uni/tn-production",
|
||||||
|
"name": "production",
|
||||||
|
"nameAlias": "",
|
||||||
|
"ownerKey": "",
|
||||||
|
"ownerTag": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
error:
|
||||||
|
description: The error information as returned from the APIC
|
||||||
|
returned: failure
|
||||||
|
type: dict
|
||||||
|
sample:
|
||||||
|
{
|
||||||
|
"code": "122",
|
||||||
|
"text": "unknown managed object class foo"
|
||||||
|
}
|
||||||
|
raw:
|
||||||
|
description: The raw output returned by the APIC REST API (xml or json)
|
||||||
|
returned: parse error
|
||||||
|
type: string
|
||||||
|
sample: '<?xml version="1.0" encoding="UTF-8"?><imdata totalCount="1"><error code="122" text="unknown managed object class foo"/></imdata>'
|
||||||
|
sent:
|
||||||
|
description: The actual/minimal configuration pushed to the APIC
|
||||||
|
returned: info
|
||||||
|
type: list
|
||||||
|
sample:
|
||||||
|
{
|
||||||
|
"fvTenant": {
|
||||||
|
"attributes": {
|
||||||
|
"descr": "Production environment"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
previous:
|
||||||
|
description: The original configuration from the APIC before the module has started
|
||||||
|
returned: info
|
||||||
|
type: list
|
||||||
|
sample:
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"fvTenant": {
|
||||||
|
"attributes": {
|
||||||
|
"descr": "Production",
|
||||||
|
"dn": "uni/tn-production",
|
||||||
|
"name": "production",
|
||||||
|
"nameAlias": "",
|
||||||
|
"ownerKey": "",
|
||||||
|
"ownerTag": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
proposed:
|
||||||
|
description: The assembled configuration from the user-provided parameters
|
||||||
|
returned: info
|
||||||
|
type: dict
|
||||||
|
sample:
|
||||||
|
{
|
||||||
|
"fvTenant": {
|
||||||
|
"attributes": {
|
||||||
|
"descr": "Production environment",
|
||||||
|
"name": "production"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
filter_string:
|
||||||
|
description: The filter string used for the request
|
||||||
|
returned: failure or debug
|
||||||
|
type: string
|
||||||
|
sample: ?rsp-prop-include=config-only
|
||||||
|
method:
|
||||||
|
description: The HTTP method used for the request to the APIC
|
||||||
|
returned: failure or debug
|
||||||
|
type: string
|
||||||
|
sample: POST
|
||||||
|
response:
|
||||||
|
description: The HTTP response from the APIC
|
||||||
|
returned: failure or debug
|
||||||
|
type: string
|
||||||
|
sample: OK (30 bytes)
|
||||||
|
status:
|
||||||
|
description: The HTTP status from the APIC
|
||||||
|
returned: failure or debug
|
||||||
|
type: int
|
||||||
|
sample: 200
|
||||||
|
url:
|
||||||
|
description: The HTTP url used for the request to the APIC
|
||||||
|
returned: failure or debug
|
||||||
|
type: string
|
||||||
|
sample: https://10.11.12.13/api/mo/uni/tn-production.json
|
||||||
'''
|
'''
|
||||||
|
|
||||||
from ansible.module_utils.network.aci.aci import ACIModule, aci_argument_spec
|
from ansible.module_utils.network.aci.aci import ACIModule, aci_argument_spec
|
||||||
|
|
|
@ -58,34 +58,34 @@ extends_documentation_fragment: aci
|
||||||
EXAMPLES = r'''
|
EXAMPLES = r'''
|
||||||
- name: Add taboo contract
|
- name: Add taboo contract
|
||||||
aci_taboo_contract:
|
aci_taboo_contract:
|
||||||
host: '{{ aci_hostname }}'
|
host: apic
|
||||||
username: '{{ aci_username }}'
|
username: admin
|
||||||
password: '{{ aci_password }}'
|
password: SomeSecretPassword
|
||||||
tenant: ansible_test
|
tenant: ansible_test
|
||||||
taboo_contract: taboo_contract_test
|
taboo_contract: taboo_contract_test
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
- name: Remove taboo contract
|
- name: Remove taboo contract
|
||||||
aci_taboo_contract:
|
aci_taboo_contract:
|
||||||
host: '{{ aci_hostname }}'
|
host: apic
|
||||||
username: '{{ aci_username }}'
|
username: admin
|
||||||
password: '{{ aci_password }}'
|
password: SomeSecretPassword
|
||||||
tenant: ansible_test
|
tenant: ansible_test
|
||||||
taboo_contract: taboo_contract_test
|
taboo_contract: taboo_contract_test
|
||||||
state: absent
|
state: absent
|
||||||
|
|
||||||
- name: Query all taboo contracts
|
- name: Query all taboo contracts
|
||||||
aci_taboo_contract:
|
aci_taboo_contract:
|
||||||
host: '{{ aci_hostname }}'
|
host: apic
|
||||||
username: '{{ aci_username }}'
|
username: admin
|
||||||
password: '{{ aci_password }}'
|
password: SomeSecretPassword
|
||||||
state: query
|
state: query
|
||||||
|
|
||||||
- name: Query a specific taboo contract
|
- name: Query a specific taboo contract
|
||||||
aci_taboo_contract:
|
aci_taboo_contract:
|
||||||
host: '{{ aci_hostname }}'
|
host: apic
|
||||||
username: '{{ aci_username }}'
|
username: admin
|
||||||
password: '{{ aci_password }}'
|
password: SomeSecretPassword
|
||||||
tenant: ansible_test
|
tenant: ansible_test
|
||||||
taboo_contract: taboo_contract_test
|
taboo_contract: taboo_contract_test
|
||||||
state: query
|
state: query
|
||||||
|
|
|
@ -49,9 +49,9 @@ extends_documentation_fragment: aci
|
||||||
# FIXME: Add more, better examples
|
# FIXME: Add more, better examples
|
||||||
EXAMPLES = r'''
|
EXAMPLES = r'''
|
||||||
- aci_tenant_action_rule_profile:
|
- aci_tenant_action_rule_profile:
|
||||||
host: '{{ inventory_hostname }}'
|
host: apic
|
||||||
username: '{{ username }}'
|
username: admin
|
||||||
password: '{{ password }}'
|
password: SomeSecretPassword
|
||||||
action_rule: '{{ action_rule }}'
|
action_rule: '{{ action_rule }}'
|
||||||
description: '{{ descr }}'
|
description: '{{ descr }}'
|
||||||
tenant: '{{ tenant }}'
|
tenant: '{{ tenant }}'
|
||||||
|
|
|
@ -51,9 +51,9 @@ extends_documentation_fragment: aci
|
||||||
# FIXME: Add more, better examples
|
# FIXME: Add more, better examples
|
||||||
EXAMPLES = r'''
|
EXAMPLES = r'''
|
||||||
- aci_tenant_span_dst_group:
|
- aci_tenant_span_dst_group:
|
||||||
host: '{{ inventory_hostname }}'
|
host: apic
|
||||||
username: '{{ username }}'
|
username: admin
|
||||||
password: '{{ password }}'
|
password: SomeSecretPassword
|
||||||
dst_group: '{{ dst_group }}'
|
dst_group: '{{ dst_group }}'
|
||||||
description: '{{ descr }}'
|
description: '{{ descr }}'
|
||||||
tenant: '{{ tenant }}'
|
tenant: '{{ tenant }}'
|
||||||
|
|
|
@ -56,10 +56,10 @@ extends_documentation_fragment: aci
|
||||||
|
|
||||||
EXAMPLES = r'''
|
EXAMPLES = r'''
|
||||||
- aci_tenant_span_src_group:
|
- aci_tenant_span_src_group:
|
||||||
host:"{{ inventory_hostname }}"
|
host: apic
|
||||||
username:"{{ username }}"
|
username: admin
|
||||||
password:"{{ password }}"
|
password: SomeSecretPassword
|
||||||
tenant:"{{ tenant }}"
|
tenant: production
|
||||||
src_group: "{{ src_group }}"
|
src_group: "{{ src_group }}"
|
||||||
dst_group: "{{ dst_group }}"
|
dst_group: "{{ dst_group }}"
|
||||||
admin_state: "{{ admin_state }}"
|
admin_state: "{{ admin_state }}"
|
||||||
|
|
|
@ -50,10 +50,10 @@ extends_documentation_fragment: aci
|
||||||
|
|
||||||
EXAMPLES = r'''
|
EXAMPLES = r'''
|
||||||
- aci_tenant_span_src_group_to_dst_group:
|
- aci_tenant_span_src_group_to_dst_group:
|
||||||
host:"{{ inventory_hostname }}"
|
host: apic
|
||||||
username:"{{ username }}"
|
username: admin
|
||||||
password:"{{ password }}"
|
password: SomeSecretPassword
|
||||||
tenant:"{{ tenant }}"
|
tenant: production
|
||||||
src_group: "{{ src_group }}"
|
src_group: "{{ src_group }}"
|
||||||
dst_group: "{{ dst_group }}"
|
dst_group: "{{ dst_group }}"
|
||||||
description: "{{ description }}"
|
description: "{{ description }}"
|
||||||
|
|
|
@ -176,7 +176,7 @@
|
||||||
state: absent
|
state: absent
|
||||||
register: provide_absent2
|
register: provide_absent2
|
||||||
|
|
||||||
- name: delte consume binding - idempotency works
|
- name: delete consume binding - idempotency works
|
||||||
aci_epg_to_contract:
|
aci_epg_to_contract:
|
||||||
<<: *aci_epg_consume_absent
|
<<: *aci_epg_consume_absent
|
||||||
register: consume_absent_idempotent
|
register: consume_absent_idempotent
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue