1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00

Add scw_compute_private_network (#4727)

* Add scw_compute_private_network

* fix argument required and BOTMETA

* little fix in commentary/doc

* test with link for ansible-doc check

* remove unwanted file

* fix entry missing in  meta/runtime.yml

* scaleway_compute_private_network add some check in test and  some fic in doc

* a=add missing  del os.environ

* fix whitespace

* test_scaleway_compute_private_network : fix test

* test_scaleway_compute_private_network : fix pep8

* scaleway_compute_private_network

add . in description

* scaleway_compute_private_network: fix var name

* [scaleway_compute_private_network] add name for the example's task

* Update plugins/modules/cloud/scaleway/scaleway_compute_private_network.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update plugins/modules/cloud/scaleway/scaleway_compute_private_network.py

Co-authored-by: Felix Fontein <felix@fontein.de>

Co-authored-by: Felix Fontein <felix@fontein.de>
This commit is contained in:
pastral 2022-06-15 08:07:02 +02:00 committed by GitHub
parent 739ca737f1
commit 7f4c11cd64
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 392 additions and 0 deletions

2
.github/BOTMETA.yml vendored
View file

@ -440,6 +440,8 @@ files:
maintainers: claco maintainers: claco
$modules/cloud/scaleway/: $modules/cloud/scaleway/:
maintainers: $team_scaleway maintainers: $team_scaleway
$modules/cloud/scaleway/scaleway_compute_private_network.py:
maintainers: pastral
$modules/cloud/scaleway/scaleway_database_backup.py: $modules/cloud/scaleway/scaleway_database_backup.py:
maintainers: guillaume_ro_fr maintainers: guillaume_ro_fr
$modules/cloud/scaleway/scaleway_image_info.py: $modules/cloud/scaleway/scaleway_image_info.py:

View file

@ -1357,6 +1357,8 @@ plugin_routing:
redirect: community.general.notification.say redirect: community.general.notification.say
scaleway_compute: scaleway_compute:
redirect: community.general.cloud.scaleway.scaleway_compute redirect: community.general.cloud.scaleway.scaleway_compute
scaleway_compute_private_network:
redirect: community.general.cloud.scaleway.scaleway_compute_private_network
scaleway_database_backup: scaleway_database_backup:
redirect: community.general.cloud.scaleway.scaleway_database_backup redirect: community.general.cloud.scaleway.scaleway_database_backup
scaleway_image_facts: scaleway_image_facts:

View file

@ -0,0 +1,209 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Scaleway VPC management module
#
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = '''
---
module: scaleway_compute_private_network
short_description: Scaleway compute - private network management
version_added: 5.2.0
author: Pascal MANGIN (@pastral)
description:
- This module add or remove a private network to a compute instance
(U(https://developer.scaleway.com)).
extends_documentation_fragment:
- community.general.scaleway
options:
state:
type: str
description:
- Indicate desired state of the VPC.
default: present
choices:
- present
- absent
project:
type: str
description:
- Project identifier.
required: true
region:
type: str
description:
- Scaleway region to use (for example C(par1)).
required: true
choices:
- ams1
- EMEA-NL-EVS
- par1
- EMEA-FR-PAR1
- par2
- EMEA-FR-PAR2
- waw1
- EMEA-PL-WAW1
compute_id:
type: str
description:
- ID of the compute instance (see M(community.general.scaleway_compute)).
required: true
private_network_id:
type: str
description:
- ID of the private network (see M(community.general.scaleway_private_network)).
required: true
'''
EXAMPLES = '''
- name: Plug a VM to a private network
community.general.scaleway_compute_private_network:
project: '{{ scw_project }}'
state: present
region: par1
compute_id: "12345678-f1e6-40ec-83e5-12345d67ed89"
private_network_id: "22345678-f1e6-40ec-83e5-12345d67ed89"
register: nicsvpc_creation_task
- name: Unplug a VM from a private network
community.general.scaleway_compute_private_network:
project: '{{ scw_project }}'
state: absent
region: par1
compute_id: "12345678-f1e6-40ec-83e5-12345d67ed89"
private_network_id: "22345678-f1e6-40ec-83e5-12345d67ed89"
'''
RETURN = '''
scaleway_compute_private_network:
description: Information on the VPC.
returned: success when C(state=present)
type: dict
sample:
{
"created_at": "2022-01-15T11:11:12.676445Z",
"id": "12345678-f1e6-40ec-83e5-12345d67ed89",
"name": "network",
"organization_id": "a123b4cd-ef5g-678h-90i1-jk2345678l90",
"project_id": "a123b4cd-ef5g-678h-90i1-jk2345678l90",
"tags": [
"tag1",
"tag2",
"tag3",
"tag4",
"tag5"
],
"updated_at": "2022-01-15T11:12:04.624837Z",
"zone": "fr-par-2"
}
'''
from ansible_collections.community.general.plugins.module_utils.scaleway import SCALEWAY_LOCATION, scaleway_argument_spec, Scaleway
from ansible.module_utils.basic import AnsibleModule
def get_nics_info(api, compute_id, private_network_id):
response = api.get('servers/' + compute_id + '/private_nics')
if not response.ok:
msg = "Error during get servers information: %s: '%s' (%s)" % (response.info['msg'], response.json['message'], response.json)
api.module.fail_json(msg=msg)
i = 0
list_nics = response.json['private_nics']
while i < len(list_nics):
if list_nics[i]['private_network_id'] == private_network_id:
return list_nics[i]
i += 1
return None
def present_strategy(api, compute_id, private_network_id):
changed = False
nic = get_nics_info(api, compute_id, private_network_id)
if nic is not None:
return changed, nic
data = {"private_network_id": private_network_id}
changed = True
if api.module.check_mode:
return changed, {"status": "a private network would be add to a server"}
response = api.post(path='servers/' + compute_id + '/private_nics', data=data)
if not response.ok:
api.module.fail_json(msg='Error when adding a private network to a server [{0}: {1}]'.format(response.status_code, response.json))
return changed, response.json
def absent_strategy(api, compute_id, private_network_id):
changed = False
nic = get_nics_info(api, compute_id, private_network_id)
if nic is None:
return changed, {}
changed = True
if api.module.check_mode:
return changed, {"status": "private network would be destroyed"}
response = api.delete('servers/' + compute_id + '/private_nics/' + nic['id'])
if not response.ok:
api.module.fail_json(msg='Error deleting private network from server [{0}: {1}]'.format(
response.status_code, response.json))
return changed, response.json
def core(module):
compute_id = module.params['compute_id']
pn_id = module.params['private_network_id']
region = module.params["region"]
module.params['api_url'] = SCALEWAY_LOCATION[region]["api_endpoint"]
api = Scaleway(module=module)
if module.params["state"] == "absent":
changed, summary = absent_strategy(api=api, compute_id=compute_id, private_network_id=pn_id)
else:
changed, summary = present_strategy(api=api, compute_id=compute_id, private_network_id=pn_id)
module.exit_json(changed=changed, scaleway_compute_private_network=summary)
def main():
argument_spec = scaleway_argument_spec()
argument_spec.update(dict(
state=dict(default='present', choices=['absent', 'present']),
project=dict(required=True),
region=dict(required=True, choices=list(SCALEWAY_LOCATION.keys())),
compute_id=dict(required=True),
private_network_id=dict(required=True)
))
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
)
core(module)
if __name__ == '__main__':
main()

View file

@ -0,0 +1,179 @@
# Copyright: (c) 2019, Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from ansible_collections.community.general.plugins.modules.cloud.scaleway import scaleway_compute_private_network
from ansible_collections.community.general.plugins.module_utils.scaleway import Scaleway, Response
from ansible_collections.community.general.tests.unit.plugins.modules.utils import set_module_args
from ansible_collections.community.general.tests.unit.compat.mock import patch
def response_without_nics():
info = {"status": 200,
"body": '{ "private_nics": []}'
}
return Response(None, info)
def response_with_nics():
info = {"status": 200,
"body": ('{ "private_nics": [{'
'"id": "c123b4cd-ef5g-678h-90i1-jk2345678l90",'
'"private_network_id": "b589b4cd-ef5g-678h-90i1-jk2345678l90",'
'"server_id": "c004b4cd-ef5g-678h-90i1-jk2345678l90",'
'"mac_address": "02:00:00:00:12:23",'
'"state": "available",'
'"creation_date": "2022-03-30T06:25:28.155973+00:00",'
'"modification_date": "2022-03-30T06:25:28.155973+00:00",'
'"zone": "fr-par-1"'
'}]}'
)
}
return Response(None, info)
def response_when_add_nics():
info = {"status": 200,
"body": ('{ "private_nics": {'
'"id": "c123b4cd-ef5g-678h-90i1-jk2345678l90",'
'"private_network_id": "b589b4cd-ef5g-678h-90i1-jk2345678l90",'
'"server_id": "c004b4cd-ef5g-678h-90i1-jk2345678l90",'
'"mac_address": "02:00:00:00:12:23",'
'"state": "available",'
'"creation_date": "2022-03-30T06:25:28.155973+00:00",'
'"modification_date": "2022-03-30T06:25:28.155973+00:00",'
'"zone": "fr-par-1"'
'}}'
)
}
return Response(None, info)
def response_remove_nics():
info = {"status": 200}
return Response(None, info)
def test_scaleway_private_network_without_arguments(capfd):
set_module_args({})
with pytest.raises(SystemExit) as results:
scaleway_compute_private_network.main()
out, err = capfd.readouterr()
assert not err
assert json.loads(out)['failed']
def test_scaleway_add_nic(capfd):
os.environ['SCW_API_TOKEN'] = 'notrealtoken'
pnid = 'b589b4cd-ef5g-678h-90i1-jk2345678l90'
cid = 'c004b4cd-ef5g-678h-90i1-jk2345678l90'
url = 'servers/' + cid + '/private_nics'
set_module_args({"project": "a123b4cd-ef5g-678h-90i1-jk2345678l90",
"state": "present",
"region": "par1",
"compute_id": cid,
"private_network_id": pnid
})
with patch.object(Scaleway, 'get') as mock_scw_get:
mock_scw_get.return_value = response_without_nics()
with patch.object(Scaleway, 'post') as mock_scw_post:
mock_scw_post.return_value = response_when_add_nics()
with pytest.raises(SystemExit) as results:
scaleway_compute_private_network.main()
mock_scw_post.assert_any_call(path=url, data={"private_network_id": pnid})
mock_scw_get.assert_any_call(url)
out, err = capfd.readouterr()
del os.environ['SCW_API_TOKEN']
assert not err
assert json.loads(out)['changed']
def test_scaleway_add_existing_nic(capfd):
os.environ['SCW_API_TOKEN'] = 'notrealtoken'
pnid = 'b589b4cd-ef5g-678h-90i1-jk2345678l90'
cid = 'c004b4cd-ef5g-678h-90i1-jk2345678l90'
url = 'servers/' + cid + '/private_nics'
set_module_args({"project": "a123b4cd-ef5g-678h-90i1-jk2345678l90",
"state": "present",
"region": "par1",
"compute_id": cid,
"private_network_id": pnid
})
with patch.object(Scaleway, 'get') as mock_scw_get:
mock_scw_get.return_value = response_with_nics()
with pytest.raises(SystemExit) as results:
scaleway_compute_private_network.main()
mock_scw_get.assert_any_call(url)
out, err = capfd.readouterr()
del os.environ['SCW_API_TOKEN']
assert not err
assert not json.loads(out)['changed']
def test_scaleway_remove_existing_nic(capfd):
os.environ['SCW_API_TOKEN'] = 'notrealtoken'
pnid = 'b589b4cd-ef5g-678h-90i1-jk2345678l90'
cid = 'c004b4cd-ef5g-678h-90i1-jk2345678l90'
nicid = 'c123b4cd-ef5g-678h-90i1-jk2345678l90'
url = 'servers/' + cid + '/private_nics'
urlremove = 'servers/' + cid + '/private_nics/' + nicid
set_module_args({"project": "a123b4cd-ef5g-678h-90i1-jk2345678l90",
"state": "absent",
"region": "par1",
"compute_id": cid,
"private_network_id": pnid
})
with patch.object(Scaleway, 'get') as mock_scw_get:
mock_scw_get.return_value = response_with_nics()
with patch.object(Scaleway, 'delete') as mock_scw_delete:
mock_scw_delete.return_value = response_remove_nics()
with pytest.raises(SystemExit) as results:
scaleway_compute_private_network.main()
mock_scw_delete.assert_any_call(urlremove)
mock_scw_get.assert_any_call(url)
out, err = capfd.readouterr()
del os.environ['SCW_API_TOKEN']
assert not err
assert json.loads(out)['changed']
def test_scaleway_remove_absent_nic(capfd):
os.environ['SCW_API_TOKEN'] = 'notrealtoken'
pnid = 'b589b4cd-ef5g-678h-90i1-jk2345678l90'
cid = 'c004b4cd-ef5g-678h-90i1-jk2345678l90'
url = 'servers/' + cid + '/private_nics'
set_module_args({"project": "a123b4cd-ef5g-678h-90i1-jk2345678l90",
"state": "absent",
"region": "par1",
"compute_id": cid,
"private_network_id": pnid
})
with patch.object(Scaleway, 'get') as mock_scw_get:
mock_scw_get.return_value = response_without_nics()
with pytest.raises(SystemExit) as results:
scaleway_compute_private_network.main()
mock_scw_get.assert_any_call(url)
out, err = capfd.readouterr()
del os.environ['SCW_API_TOKEN']
assert not err
assert not json.loads(out)['changed']