mirror of
https://github.com/ansible-collections/community.general.git
synced 2026-02-03 23:41:51 +00:00
* Adding 'project' parameter support for the Scaleway SG module. * Adding changelog fragment. * Fixing documentation, organization is deprecated (although still available). * Updating docs to show both org and project ID options. * Incrementing version. Co-authored-by: Felix Fontein <felix@fontein.de> * Moving deprecated example to the end. --------- Co-authored-by: Felix Fontein <felix@fontein.de>
285 lines
8.2 KiB
Python
285 lines
8.2 KiB
Python
#!/usr/bin/python
|
|
#
|
|
# Scaleway Security Group management module
|
|
#
|
|
# Copyright (C) 2018 Antoine Barbare (antoinebarbare@gmail.com).
|
|
#
|
|
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
from __future__ import annotations
|
|
|
|
DOCUMENTATION = r"""
|
|
module: scaleway_security_group
|
|
short_description: Scaleway Security Group management module
|
|
author: Antoine Barbare (@abarbare)
|
|
description:
|
|
- This module manages Security Group on Scaleway account U(https://developer.scaleway.com).
|
|
extends_documentation_fragment:
|
|
- community.general.scaleway
|
|
- community.general.attributes
|
|
- community.general.scaleway.actiongroup_scaleway
|
|
|
|
attributes:
|
|
check_mode:
|
|
support: full
|
|
diff_mode:
|
|
support: none
|
|
action_group:
|
|
version_added: 11.3.0
|
|
|
|
options:
|
|
state:
|
|
description:
|
|
- Indicate desired state of the Security Group.
|
|
type: str
|
|
choices: [absent, present]
|
|
default: present
|
|
|
|
organization:
|
|
type: str
|
|
description:
|
|
- Organization identifier.
|
|
- Exactly one of O(project) and O(organization) must be specified.
|
|
|
|
region:
|
|
description:
|
|
- Scaleway region to use (for example V(par1)).
|
|
type: str
|
|
required: true
|
|
choices:
|
|
- ams1
|
|
- EMEA-NL-EVS
|
|
- ams2
|
|
- ams3
|
|
- par1
|
|
- EMEA-FR-PAR1
|
|
- par2
|
|
- EMEA-FR-PAR2
|
|
- par3
|
|
- waw1
|
|
- EMEA-PL-WAW1
|
|
- waw2
|
|
- waw3
|
|
|
|
name:
|
|
description:
|
|
- Name of the Security Group.
|
|
type: str
|
|
required: true
|
|
|
|
description:
|
|
description:
|
|
- Description of the Security Group.
|
|
type: str
|
|
|
|
stateful:
|
|
description:
|
|
- Create a stateful security group which allows established connections in and out.
|
|
type: bool
|
|
required: true
|
|
|
|
inbound_default_policy:
|
|
description:
|
|
- Default policy for incoming traffic.
|
|
type: str
|
|
choices: [accept, drop]
|
|
|
|
outbound_default_policy:
|
|
description:
|
|
- Default policy for outcoming traffic.
|
|
type: str
|
|
choices: [accept, drop]
|
|
|
|
organization_default:
|
|
description:
|
|
- Create security group to be the default one.
|
|
type: bool
|
|
|
|
project:
|
|
type: str
|
|
description:
|
|
- Project identifier.
|
|
- Exactly one of O(project) and O(organization) must be specified.
|
|
version_added: 12.3.0
|
|
"""
|
|
|
|
EXAMPLES = r"""
|
|
- name: Create a Security Group using a project ID
|
|
community.general.scaleway_security_group:
|
|
state: present
|
|
region: par1
|
|
name: security_group
|
|
description: "my security group description"
|
|
stateful: false
|
|
inbound_default_policy: accept
|
|
outbound_default_policy: accept
|
|
organization_default: false
|
|
project: 951df375-e094-4d26-97c1-ba548eeb9c42
|
|
register: security_group_creation_task
|
|
|
|
- name: Create a Security Group in the default project using an organization ID (deprecated)
|
|
community.general.scaleway_security_group:
|
|
state: present
|
|
region: par1
|
|
name: security_group
|
|
description: "my security group description"
|
|
organization: 43a3b6c8-916f-477b-b7ec-ff1898f5fdd9
|
|
stateful: false
|
|
inbound_default_policy: accept
|
|
outbound_default_policy: accept
|
|
organization_default: false
|
|
register: security_group_creation_task
|
|
"""
|
|
|
|
RETURN = r"""
|
|
data:
|
|
description: This is only present when O(state=present).
|
|
returned: when O(state=present)
|
|
type: dict
|
|
sample:
|
|
{
|
|
"scaleway_security_group": {
|
|
"description": "my security group description",
|
|
"enable_default_security": true,
|
|
"id": "0168fb1f-cc46-4f69-b4be-c95d2a19bcae",
|
|
"inbound_default_policy": "accept",
|
|
"name": "security_group",
|
|
"organization": "43a3b6c8-916f-477b-b7ec-ff1898f5fdd9",
|
|
"organization_default": false,
|
|
"outbound_default_policy": "accept",
|
|
"servers": [],
|
|
"stateful": false
|
|
}
|
|
}
|
|
"""
|
|
|
|
from uuid import uuid4
|
|
|
|
from ansible.module_utils.basic import AnsibleModule
|
|
|
|
from ansible_collections.community.general.plugins.module_utils.scaleway import (
|
|
SCALEWAY_LOCATION,
|
|
Scaleway,
|
|
scaleway_argument_spec,
|
|
)
|
|
|
|
|
|
def payload_from_security_group(security_group):
|
|
return {k: v for k, v in security_group.items() if k != "id" and v is not None}
|
|
|
|
|
|
def present_strategy(api, security_group):
|
|
ret = {"changed": False}
|
|
|
|
response = api.get("security_groups")
|
|
if not response.ok:
|
|
api.module.fail_json(
|
|
msg=f'Error getting security groups "{response.info["msg"]}": "{response.json["message"]}" ({response.json})'
|
|
)
|
|
|
|
security_group_lookup = {sg["name"]: sg for sg in response.json["security_groups"]}
|
|
|
|
if security_group["name"] not in security_group_lookup.keys():
|
|
ret["changed"] = True
|
|
if api.module.check_mode:
|
|
# Help user when check mode is enabled by defining id key
|
|
ret["scaleway_security_group"] = {"id": str(uuid4())}
|
|
return ret
|
|
|
|
# Create Security Group
|
|
response = api.post("/security_groups", data=payload_from_security_group(security_group))
|
|
|
|
if not response.ok:
|
|
msg = f'Error during security group creation: "{response.info["msg"]}": "{response.json["message"]}" ({response.json})'
|
|
api.module.fail_json(msg=msg)
|
|
ret["scaleway_security_group"] = response.json["security_group"]
|
|
|
|
else:
|
|
ret["scaleway_security_group"] = security_group_lookup[security_group["name"]]
|
|
|
|
return ret
|
|
|
|
|
|
def absent_strategy(api, security_group):
|
|
response = api.get("security_groups")
|
|
ret = {"changed": False}
|
|
|
|
if not response.ok:
|
|
api.module.fail_json(
|
|
msg=f'Error getting security groups "{response.info["msg"]}": "{response.json["message"]}" ({response.json})'
|
|
)
|
|
|
|
security_group_lookup = {sg["name"]: sg for sg in response.json["security_groups"]}
|
|
if security_group["name"] not in security_group_lookup.keys():
|
|
return ret
|
|
|
|
ret["changed"] = True
|
|
if api.module.check_mode:
|
|
return ret
|
|
|
|
response = api.delete(f"/security_groups/{security_group_lookup[security_group['name']]['id']}")
|
|
if not response.ok:
|
|
api.module.fail_json(
|
|
msg=f'Error deleting security group "{response.info["msg"]}": "{response.json["message"]}" ({response.json})'
|
|
)
|
|
|
|
return ret
|
|
|
|
|
|
def core(module):
|
|
security_group = {
|
|
"organization": module.params["organization"],
|
|
"name": module.params["name"],
|
|
"description": module.params["description"],
|
|
"stateful": module.params["stateful"],
|
|
"inbound_default_policy": module.params["inbound_default_policy"],
|
|
"outbound_default_policy": module.params["outbound_default_policy"],
|
|
"organization_default": module.params["organization_default"],
|
|
"project": module.params["project"],
|
|
}
|
|
|
|
region = module.params["region"]
|
|
module.params["api_url"] = SCALEWAY_LOCATION[region]["api_endpoint"]
|
|
|
|
api = Scaleway(module=module)
|
|
if module.params["state"] == "present":
|
|
summary = present_strategy(api=api, security_group=security_group)
|
|
else:
|
|
summary = absent_strategy(api=api, security_group=security_group)
|
|
module.exit_json(**summary)
|
|
|
|
|
|
def main():
|
|
argument_spec = scaleway_argument_spec()
|
|
argument_spec.update(
|
|
dict(
|
|
state=dict(type="str", default="present", choices=["absent", "present"]),
|
|
organization=dict(type="str"),
|
|
name=dict(type="str", required=True),
|
|
description=dict(type="str"),
|
|
region=dict(type="str", required=True, choices=list(SCALEWAY_LOCATION.keys())),
|
|
stateful=dict(type="bool", required=True),
|
|
inbound_default_policy=dict(type="str", choices=["accept", "drop"]),
|
|
outbound_default_policy=dict(type="str", choices=["accept", "drop"]),
|
|
organization_default=dict(type="bool"),
|
|
project=dict(type="str"),
|
|
)
|
|
)
|
|
module = AnsibleModule(
|
|
argument_spec=argument_spec,
|
|
supports_check_mode=True,
|
|
required_if=[["stateful", True, ["inbound_default_policy", "outbound_default_policy"]]],
|
|
mutually_exclusive=[
|
|
("organization", "project"),
|
|
],
|
|
required_one_of=[
|
|
("organization", "project"),
|
|
],
|
|
)
|
|
|
|
core(module)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|