Coverage for /Users/jingyu.wy/git/ansible-module-apsarastack/src/ansible_collections/alibaba/apsarastack/plugins/modules/ali_vpc.py: 30%
101 statements
« prev ^ index » next coverage.py v7.8.0, created at 2025-05-22 16:05 +0800
« prev ^ index » next coverage.py v7.8.0, created at 2025-05-22 16:05 +0800
1#!/usr/bin/python
2# -*- coding: utf-8 -*-
4# Copyright (c) 2017-present Alibaba Group Holding Limited. He Guimin <heguimin36@163.com.com>
5# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
6#
7# This file is part of Ansible
8#
9# Ansible is free software: you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation, either version 3 of the License, or
12# (at your option) any later version.
13#
14# Ansible is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with Ansible. If not, see http://www.gnu.org/licenses/.
22from __future__ import (absolute_import, division, print_function)
24import time
26from ansible.module_utils.basic import AnsibleModule
28try:
29 from ansible_collections.alibaba.apsarastack.plugins.module_utils.apsarastack_common import common_argument_spec
30 from ansible_collections.alibaba.apsarastack.plugins.module_utils.apsarastack_connections import vpc_connect
31except ImportError:
32 from ..module_utils.apsarastack_common import common_argument_spec
33 from ..module_utils.apsarastack_connections import vpc_connect
35__metaclass__ = type
37ANSIBLE_METADATA = {'metadata_version': '1.1',
38 'status': ['preview'],
39 'supported_by': 'community'}
41DOCUMENTATION = """
42---
43module: ali_vpc
44short_description: Configure Alibaba Cloud virtual private cloud(VPC)
45description:
46 - Create, Delete Apsarastack virtual private cloud(VPC).
47 It supports updating VPC description.
48options:
49 state:
50 description:
51 - Whether or not to create, delete VPC.
52 choices: ['present', 'absent']
53 type: str
54 default: 'present'
55 name:
56 description:
57 - The name to give your VPC, which is a string of 2 to 128 Chinese or English characters. It must begin with an
58 uppercase/lowercase letter or a Chinese character and can contain numerals, "_" or "-".
59 It cannot begin with http:// or https://.
60 This is used in combination with C(cidr_block) to determine if a VPC already exists.
61 aliases: ['vpc_name']
62 type: str
63 vpc_id:
64 description:
65 - The id of VPC, required when operate existing vpc.
66 type: str
67 aliases: ['id']
68 description:
69 description:
70 - The description of VPC, which is a string of 2 to 256 characters. It cannot begin with http:// or https://.
71 type: str
72 cidr_block:
73 description:
74 - The primary CIDR of the VPC. This is used in conjunction with the C(name) to ensure idempotence.
75 aliases: ['cidr']
76 required: True
77 type: str
78 user_cidrs:
79 description:
80 - List of user custom cidr in the VPC. It no more than three.
81 type: list
82 elements: str
83 multi_ok:
84 description:
85 - By default the module will not create another VPC if there is another VPC with the same name and CIDR block.
86 Specify this as true if you want duplicate VPCs created.
87 default: False
88 type: bool
89 recent:
90 description:
91 - By default the module will not choose the recent one if there is another VPC with the same I(name) and
92 I(cidr_block). Specify this as true if you want to target the recent VPC.
93 There will be conflict when I(multi_ok=True) and I(recent=True).
94 default: False
95 type: bool
96 tags:
97 description:
98 - A hash/dictionaries of vpc tags. C({"key":"value"})
99 type: dict
100 purge_tags:
101 description:
102 - Delete existing tags on the vpc that are not specified in the task.
103 If True, it means you have to specify all the desired tags on each task affecting a vpc.
104 default: False
105 type: bool
106notes:
107 - There will be launch a virtual router along with creating a vpc successfully.
108 - There is only one virtual router in one vpc and one route table in one virtual router.
109requirements:
110 - "python >= 3.6"
111 - "footmark >= 1.14.1"
112extends_documentation_fragment:
113 - apsarastack
114author:
115 - "Wang Yu (@zshongyi)
116 - "He Guimin (@xiaozhu36)"
117"""
119EXAMPLES = """
120# Note: These examples do not set authentication details, see the Alibaba Cloud Guide for details.
121- name: Create a new vpc
122 ali_vpc:
123 cidr_block: '192.168.0.0/16'
124 name: 'Demo_VPC'
125 description: 'Demo VPC'
127- name: Choose the latest VPC as target when there are several vpcs with same name and cidr block
128 ali_vpc:
129 cidr_block: '192.168.0.0/16'
130 name: 'Demo_VPC'
131 recent: True
133- name: Delete a vpc
134 ali_vpc:
135 state: absent
136 cidr_block: '192.168.0.0/16'
137 name: 'Demo_VPC'
138"""
140RETURN = '''
141vpc:
142 description: info about the VPC that was created or deleted
143 returned: always
144 type: complex
145 contains:
146 cidr_block:
147 description: The CIDR of the VPC
148 returned: always
149 type: str
150 sample: 10.0.0.0/8
151 creation_time:
152 description: The time the VPC was created.
153 returned: always
154 type: str
155 sample: '2018-06-24T15:14:45Z'
156 description:
157 description: The VPC description.
158 returned: always
159 type: str
160 sample: "my ansible vpc"
161 id:
162 description: alias of 'vpc_id'.
163 returned: always
164 type: str
165 sample: vpc-c2e00da5
166 is_default:
167 description: indicates whether this is the default VPC
168 returned: always
169 type: bool
170 sample: false
171 state:
172 description: state of the VPC
173 returned: always
174 type: str
175 sample: available
176 tags:
177 description: tags attached to the VPC, includes name
178 returned: always
179 type: dict
180 sample:
181 user_cidrs:
182 description: The custom CIDR of the VPC
183 returned: always
184 type: list
185 sample: []
186 vpc_id:
187 description: VPC resource id
188 returned: always
189 type: str
190 sample: vpc-c2e00da5
191 vpc_name:
192 description: Name of the VPC
193 returned: always
194 type: str
195 sample: my-vpc
196 vrouter_id:
197 description: The ID of virtual router which in the VPC
198 returned: always
199 type: str
200 sample: available
201 vswitch_ids:
202 description: List IDs of virtual switch which in the VPC
203 returned: always
204 type: list
205 sample: [vsw-123cce3, vsw-34cet4v]
206'''
209HAS_FOOTMARK = False
211try:
212 from footmark.exception import VPCResponseError
213 HAS_FOOTMARK = True
214except ImportError:
215 HAS_FOOTMARK = False
218def vpc_exists(module, vpc, vpc_id, name, cidr_block, multi, recent):
219 """Returns None or a vpc object depending on the existence of a VPC. When supplied
220 with a CIDR and Name, it will check them to determine if it is a match
221 otherwise it will assume the VPC does not exist and thus return None.
222 """
223 if multi:
224 return None
225 matching_vpcs = []
226 try:
227 for v in vpc.describe_vpcs():
228 if cidr_block and v.cidr_block != cidr_block:
229 continue
230 if name and v.vpc_name != name:
231 continue
232 if vpc_id and v.vpc_id != vpc_id:
233 continue
234 matching_vpcs.append(v)
236 except Exception as e:
237 module.fail_json(msg="Failed to describe VPCs: {0}".format(e))
239 if len(matching_vpcs) == 1:
240 return matching_vpcs[0]
241 elif len(matching_vpcs) > 1:
242 if recent:
243 return matching_vpcs[-1]
244 module.fail_json(msg='Currently there are {0} VPCs that have the same name and '
245 'CIDR block you specified. If you would like to create '
246 'the VPC anyway please pass True to the multi_ok param. '
247 'Or, please pass True to the recent param to choose the recent one.'.format(len(matching_vpcs)))
248 return None
251def main():
252 argument_spec = common_argument_spec()
253 argument_spec.update(dict(
254 state=dict(default='present', choices=['present', 'absent']),
255 cidr_block=dict(type='str', required=True, aliases=['cidr']),
256 user_cidrs=dict(type='list', elements='str'),
257 name=dict(type='str', aliases=['vpc_name']),
258 vpc_id=dict(type='str', aliases=['id']),
259 multi_ok=dict(type='bool', default=False),
260 description=dict(type='str'),
261 recent=dict(type='bool', default=False),
262 tags=dict(type='dict'),
263 purge_tags=dict(type='bool', default=False)
264 ))
266 module = AnsibleModule(argument_spec=argument_spec)
268 if HAS_FOOTMARK is False:
269 module.fail_json(msg='footmark required for the module ali_vpc.')
271 vpc_conn = vpc_connect(module)
273 # Get values of variable
274 state = module.params['state']
275 vpc_name = module.params['name']
276 description = module.params['description']
277 vpc_id = module.params['vpc_id']
279 if str(description).startswith('http://') or str(description).startswith('https://'):
280 module.fail_json(msg='description can not start with http:// or https://')
281 if str(vpc_name).startswith('http://') or str(vpc_name).startswith('https://'):
282 module.fail_json(msg='vpc_name can not start with http:// or https://')
284 changed = False
286 # Check if VPC exists
287 vpc = vpc_exists(module, vpc_conn, vpc_id, vpc_name, module.params['cidr_block'], module.params['multi_ok'], module.params['recent'])
289 if state == 'absent':
290 if not vpc:
291 module.exit_json(changed=changed, vpc={})
293 try:
294 module.exit_json(changed=vpc.delete(), vpc={})
295 except VPCResponseError as ex:
296 module.fail_json(msg='Unable to delete vpc {0}, error: {1}'.format(vpc.id, ex))
298 if not vpc:
299 params = module.params
300 params['client_token'] = "Ansible-Apsarastack-%s-%s" % (hash(str(module.params)), str(time.time()))
301 params['vpc_name'] = vpc_name
302 try:
303 vpc = vpc_conn.create_vpc(**params)
304 module.exit_json(changed=True, vpc=vpc.get().read())
305 except VPCResponseError as e:
306 module.fail_json(msg='Unable to create vpc, error: {0}'.format(e))
308 if not description:
309 description = vpc.description
311 try:
312 if vpc.modify(vpc_name, description):
313 changed = True
314 except VPCResponseError as e:
315 module.fail_json(msg='Unable to modify vpc {0}, error: {1}'.format(vpc.id, e))
317 tags = module.params['tags']
318 if module.params['purge_tags']:
319 if not tags:
320 tags = vpc.tags
321 try:
322 if vpc.remove_tags(tags):
323 changed = True
324 module.exit_json(changed=changed, vpc=vpc.get().read())
325 except Exception as e:
326 module.fail_json(msg="{0}".format(e))
328 if tags:
329 try:
330 if vpc.add_tags(tags):
331 changed = True
332 except Exception as e:
333 module.fail_json(msg="{0}".format(e))
334 module.exit_json(changed=changed, vpc=vpc.get().read())
337if __name__ == '__main__':
338 main()