Skip to content

Commit 6e4e92d

Browse files
JanaHochThulium-DrakeIamLunchbox
authored
Feature: Proxmox vnet info (#173)
* proxmox_vnet_info: New module - Get Vnets, subnet and firewall rules for that vnet * proxmox_vnet_info: Add Documentation and example * proxmox_vnet_info: fix typos in docs * proxmox_vnet_info: fix sanity issues - fix PEP8 issues - add proxmox_vnet_info to runtime.yml - Add workaround for author string * proxmox_vnet_info: Added unit tests - Also fixed few minor issues in module * proxmox_vnet_info: Apply suggestions from code review Added all suggestions by @IamLunchbox Co-authored-by: IamLunchbox <[email protected]> * proxmox_vnet_info: fix minor sanity issue and failing test --------- Co-authored-by: Jeffrey van Pelt <[email protected]> Co-authored-by: IamLunchbox <[email protected]>
1 parent bed224f commit 6e4e92d

File tree

3 files changed

+440
-0
lines changed

3 files changed

+440
-0
lines changed

meta/runtime.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,6 @@ action_groups:
3737
- proxmox_user
3838
- proxmox_user_info
3939
- proxmox_vm_info
40+
- proxmox_vnet_info
4041
- proxmox_zone
4142
- proxmox_zone_info
Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
#!/usr/bin/python
2+
# -*- coding: utf-8 -*-
3+
4+
# Copyright (c) 2025, Jana Hoch <[email protected]>
5+
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
6+
# SPDX-License-Identifier: GPL-3.0-or-later
7+
8+
from __future__ import absolute_import, division, print_function
9+
10+
__metaclass__ = type
11+
12+
DOCUMENTATION = r"""
13+
module: proxmox_vnet_info
14+
short_description: Retrieve information about one or more Proxmox VE SDN vnets.
15+
version_added: "1.4.0"
16+
description:
17+
- Retrieve information about one or more Proxmox VE SDN vnets.
18+
author: 'Jana Hoch <[email protected]> (!UNKNOWN)'
19+
options:
20+
vnet:
21+
description:
22+
- Restrict results to a specific vnet.
23+
type: str
24+
25+
extends_documentation_fragment:
26+
- community.proxmox.proxmox.actiongroup_proxmox
27+
- community.proxmox.proxmox.documentation
28+
- community.proxmox.attributes
29+
- community.proxmox.attributes.info_module
30+
"""
31+
32+
EXAMPLES = r"""
33+
- name: Get all vnet details
34+
community.proxmox.proxmox_vnet_info:
35+
api_user: "{{ proxmox.api_user }}"
36+
api_token_id: "{{ proxmox.api_token_id }}"
37+
api_token_secret: "{{ vault.proxmox.api_token_secret }}"
38+
api_host: "{{ proxmox.api_host }}"
39+
validate_certs: false
40+
41+
- name: Get details for vnet - test
42+
community.proxmox.proxmox_vnet_info:
43+
api_user: "{{ proxmox.api_user }}"
44+
api_token_id: "{{ proxmox.api_token_id }}"
45+
api_token_secret: "{{ vault.proxmox.api_token_secret }}"
46+
api_host: "{{ proxmox.api_host }}"
47+
vnet: test
48+
validate_certs: false
49+
"""
50+
51+
RETURN = r"""
52+
vnets:
53+
description: List of vnets.
54+
returned: on success
55+
type: list
56+
elements: dict
57+
sample:
58+
[
59+
{
60+
"digest": "01505201eb33919888fb0cacba27d3aae803f6d2",
61+
"firewall_rules": [],
62+
"subnets": [
63+
{
64+
"cidr": "10.10.100.0/24",
65+
"dhcp-range": [],
66+
"digest": "47684c511d9b67e8eb41b93bc5c0b078786b0ee3",
67+
"id": "lab-10.10.100.0-24",
68+
"mask": "24",
69+
"network": "10.10.100.0",
70+
"snat": 1,
71+
"subnet": "lab-10.10.100.0-24",
72+
"type": "subnet",
73+
"vnet": "lab",
74+
"zone": "lab"
75+
}
76+
],
77+
"tag": 100,
78+
"type": "vnet",
79+
"vnet": "lab",
80+
"zone": "lab"
81+
},
82+
{
83+
"digest": "01505201eb33919888fb0cacba27d3aae803f6d2",
84+
"firewall_rules": [
85+
{
86+
"action": "ACCEPT",
87+
"dest": "+sdn/test2-gateway",
88+
"digest": "36016a02a5387d4c1171d29be966d550216bc500",
89+
"enable": 1,
90+
"log": "nolog",
91+
"macro": "DNS",
92+
"pos": 0,
93+
"type": "forward"
94+
},
95+
{
96+
"action": "ACCEPT",
97+
"digest": "36016a02a5387d4c1171d29be966d550216bc500",
98+
"enable": 1,
99+
"log": "nolog",
100+
"macro": "DHCPfwd",
101+
"pos": 1,
102+
"type": "forward"
103+
}
104+
],
105+
"subnets": [
106+
{
107+
"cidr": "10.10.0.0/24",
108+
"dhcp-range": [
109+
{
110+
"end-address": "10.10.0.50",
111+
"start-address": "10.10.0.5"
112+
}
113+
],
114+
"digest": "47684c511d9b67e8eb41b93bc5c0b078786b0ee3",
115+
"gateway": "10.10.0.1",
116+
"id": "test1-10.10.0.0-24",
117+
"mask": "24",
118+
"network": "10.10.0.0",
119+
"subnet": "test1-10.10.0.0-24",
120+
"type": "subnet",
121+
"vnet": "test2",
122+
"zone": "test1"
123+
},
124+
{
125+
"cidr": "10.10.1.0/24",
126+
"dhcp-range": [
127+
{
128+
"end-address": "10.10.1.50",
129+
"start-address": "10.10.1.5"
130+
}
131+
],
132+
"digest": "47684c511d9b67e8eb41b93bc5c0b078786b0ee3",
133+
"gateway": "10.10.1.0",
134+
"id": "test1-10.10.1.0-24",
135+
"mask": "24",
136+
"network": "10.10.1.0",
137+
"subnet": "test1-10.10.1.0-24",
138+
"type": "subnet",
139+
"vnet": "test2",
140+
"zone": "test1"
141+
}
142+
],
143+
"type": "vnet",
144+
"vnet": "test2",
145+
"zone": "test1"
146+
}
147+
]
148+
"""
149+
150+
from ansible.module_utils.basic import AnsibleModule
151+
from ansible_collections.community.proxmox.plugins.module_utils.proxmox import (
152+
proxmox_auth_argument_spec,
153+
ProxmoxAnsible
154+
)
155+
156+
157+
class ProxmoxVnetInfoAnsible(ProxmoxAnsible):
158+
def get_subnets(self, vnet):
159+
try:
160+
return self.proxmox_api.cluster().sdn().vnets(vnet).subnets().get()
161+
except Exception as e:
162+
self.module.fail_json(
163+
msg=f'Failed to retrieve subnet information from vnet {vnet}: {e}'
164+
)
165+
166+
def get_firewall(self, vnet_name):
167+
try:
168+
return self.proxmox_api.cluster().sdn().vnets(vnet_name).firewall().rules().get()
169+
except Exception as e:
170+
self.module.fail_json(
171+
msg=f'Failed to retrieve subnet information from vnet {vnet_name}: {e}'
172+
)
173+
174+
def get_vnet_detail(self):
175+
try:
176+
vnets = self.proxmox_api.cluster().sdn().vnets().get()
177+
for vnet in vnets:
178+
vnet['subnets'] = self.get_subnets(vnet['vnet'])
179+
vnet['firewall_rules'] = self.get_firewall(vnet['vnet'])
180+
return vnets
181+
except Exception as e:
182+
self.module.fail_json(
183+
msg=f'Failed to retrieve vnet information from cluster: {e}'
184+
)
185+
186+
187+
def main():
188+
module_args = proxmox_auth_argument_spec()
189+
vnet_info_args = dict(
190+
vnet=dict(type="str", required=False)
191+
)
192+
module_args.update(vnet_info_args)
193+
194+
module = AnsibleModule(
195+
argument_spec=module_args,
196+
required_together=[("api_token_id", "api_token_secret")],
197+
required_one_of=[("api_password", "api_token_id")],
198+
supports_check_mode=True,
199+
)
200+
201+
proxmox = ProxmoxVnetInfoAnsible(module)
202+
vnet = module.params['vnet']
203+
vnets = proxmox.get_vnet_detail()
204+
205+
if vnet:
206+
vnets = [vnet_details for vnet_details in vnets if vnet_details['vnet'] == vnet]
207+
208+
module.exit_json(
209+
changed=False,
210+
vnets=vnets,
211+
msg='Successfully retrieved vnet info'
212+
)
213+
214+
215+
if __name__ == "__main__":
216+
main()

0 commit comments

Comments
 (0)