-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
new: Support IP module to allocate a new IP (#628)
* ip module * simplify test * address comments * fix lint&doc * handle absent
- Loading branch information
1 parent
9974870
commit 4da84f0
Showing
5 changed files
with
254 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# ip | ||
|
||
Allocates a new IPv4 Address on your Account. The Linode must be configured to support additional addresses - please Open a support ticket requesting additional addresses before attempting allocation. | ||
|
||
- [Minimum Required Fields](#minimum-required-fields) | ||
- [Examples](#examples) | ||
- [Parameters](#parameters) | ||
- [Return Values](#return-values) | ||
|
||
## Minimum Required Fields | ||
| Field | Type | Required | Description | | ||
|-------------|-------|--------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | ||
| `api_token` | `str` | **Required** | The Linode account personal access token. It is necessary to run the module. <br/>It can be exposed by the environment variable `LINODE_API_TOKEN` instead. <br/>See details in [Usage](https://github.com/linode/ansible_linode?tab=readme-ov-file#usage). | | ||
|
||
## Examples | ||
|
||
```yaml | ||
- name: Allocate IP to Linode | ||
linode.cloud.ip: | ||
linode_id: 123 | ||
public: true | ||
type: ipv4 | ||
state: present | ||
``` | ||
## Parameters | ||
| Field | Type | Required | Description | | ||
|-----------|------|----------|------------------------------------------------------------------------------| | ||
| `state` | <center>`str`</center> | <center>**Required**</center> | The state of this IP. **(Choices: `present`, `absent`)** | | ||
| `linode_id` | <center>`int`</center> | <center>Optional</center> | The ID of a Linode you have access to that this address will be allocated to. | | ||
| `public` | <center>`bool`</center> | <center>Optional</center> | Whether to create a public or private IPv4 address. | | ||
| `type` | <center>`str`</center> | <center>Optional</center> | The type of address you are requesting. Only IPv4 addresses may be allocated through this operation. **(Choices: `ipv4`)** | | ||
| `address` | <center>`str`</center> | <center>Optional</center> | The IP address to delete. **(Conflicts With: `linode_id`,`public`,`type`)** | | ||
|
||
## Return Values | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
"""Documentation fragments for the ip module""" | ||
specdoc_examples = [''' | ||
- name: Allocate IP to Linode | ||
linode.cloud.ip: | ||
linode_id: 123 | ||
public: true | ||
type: ipv4 | ||
state: present'''] | ||
|
||
result_ip_samples = ['''{ | ||
"address": "97.107.143.141", | ||
"gateway": "97.107.143.1", | ||
"linode_id": 123, | ||
"prefix": 24, | ||
"public": true, | ||
"rdns": "test.example.org", | ||
"region": "us-east", | ||
"subnet_mask": "255.255.255.0", | ||
"type": "ipv4", | ||
"vpc_nat_1_1": { | ||
"vpc_id": 242, | ||
"subnet_id": 194, | ||
"address": "139.144.244.36" | ||
} | ||
}'''] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
#!/usr/bin/python | ||
# -*- coding: utf-8 -*- | ||
"""This module allows users to allocate a new IPv4 Address on their accounts.""" | ||
|
||
from __future__ import absolute_import, division, print_function | ||
|
||
from typing import Any, Optional | ||
|
||
import ansible_collections.linode.cloud.plugins.module_utils.doc_fragments.ip as docs | ||
from ansible_collections.linode.cloud.plugins.module_utils.linode_common import ( | ||
LinodeModuleBase, | ||
) | ||
from ansible_collections.linode.cloud.plugins.module_utils.linode_docs import ( | ||
global_authors, | ||
global_requirements, | ||
) | ||
from ansible_collections.linode.cloud.plugins.module_utils.linode_helper import ( | ||
filter_null_values, | ||
) | ||
from ansible_specdoc.objects import FieldType, SpecDocMeta, SpecField | ||
|
||
spec: dict = { | ||
"linode_id": SpecField( | ||
type=FieldType.integer, | ||
description=[ | ||
"The ID of a Linode you have access to " | ||
"that this address will be allocated to." | ||
], | ||
), | ||
"public": SpecField( | ||
type=FieldType.bool, | ||
description=["Whether to create a public or private IPv4 address."], | ||
), | ||
"type": SpecField( | ||
type=FieldType.string, | ||
choices=["ipv4"], | ||
description=[ | ||
"The type of address you are requesting. " | ||
"Only IPv4 addresses may be allocated through this operation." | ||
], | ||
), | ||
"address": SpecField( | ||
type=FieldType.string, | ||
description=["The IP address to delete."], | ||
conflicts_with=["linode_id", "public", "type"], | ||
), | ||
"state": SpecField( | ||
type=FieldType.string, | ||
choices=["present", "absent"], | ||
required=True, | ||
description=["The state of this IP."], | ||
), | ||
} | ||
|
||
SPECDOC_META = SpecDocMeta( | ||
description=[ | ||
"Allocates a new IPv4 Address on your Account. " | ||
"The Linode must be configured to support " | ||
"additional addresses - " | ||
"please Open a support ticket " | ||
"requesting additional addresses before attempting allocation.", | ||
], | ||
requirements=global_requirements, | ||
author=global_authors, | ||
options=spec, | ||
examples=docs.specdoc_examples, | ||
return_values={}, | ||
) | ||
|
||
DOCUMENTATION = r""" | ||
""" | ||
EXAMPLES = r""" | ||
""" | ||
RETURN = r""" | ||
""" | ||
|
||
|
||
class Module(LinodeModuleBase): | ||
"""Module for allocating a new IP""" | ||
|
||
def __init__(self) -> None: | ||
self.module_arg_spec = SPECDOC_META.ansible_spec | ||
self.results = { | ||
"changed": False, | ||
"actions": [], | ||
"ip": None, | ||
} | ||
super().__init__( | ||
module_arg_spec=self.module_arg_spec, | ||
required_together=[ | ||
("linode_id", "public", "type"), | ||
], | ||
) | ||
|
||
def _handle_present(self) -> None: | ||
params = filter_null_values(self.module.params) | ||
linode_id = params.get("linode_id") | ||
public = params.get("public") | ||
|
||
try: | ||
ip = self.client.networking.ip_allocate(linode_id, public) | ||
self.register_action( | ||
f"IP allocation to Linode {linode_id} completed." | ||
) | ||
except Exception as exc: | ||
self.fail(msg=f"failed to allocate IP to Linode {linode_id}: {exc}") | ||
|
||
self.results["ip"] = ip._raw_json | ||
|
||
def _handle_absent(self) -> None: | ||
# TODO: Implement deleting IP once it's available in python-sdk. | ||
# Raise an error for now when user reaches deleting IP. | ||
self.fail( | ||
msg="failed to delete IP: IP deleting is currently not supported." | ||
) | ||
|
||
def exec_module(self, **kwargs: Any) -> Optional[dict]: | ||
"""Entrypoint for IP module""" | ||
|
||
state = kwargs.get("state") | ||
|
||
if state == "absent": | ||
self._handle_absent() | ||
return self.results | ||
|
||
self._handle_present() | ||
|
||
return self.results | ||
|
||
|
||
def main() -> None: | ||
"""Constructs and calls the module""" | ||
Module() | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
- name: ip | ||
block: | ||
- set_fact: | ||
r: "{{ 1000000000 | random }}" | ||
|
||
- name: Create a Linode Instance | ||
linode.cloud.instance: | ||
label: 'ansible-test-{{ r }}' | ||
region: us-southeast | ||
type: g6-standard-1 | ||
image: linode/alpine3.19 | ||
state: present | ||
firewall_id: '{{ firewall_id }}' | ||
register: create_instance | ||
|
||
- name: Allocate a new IP to the Linode | ||
linode.cloud.ip: | ||
linode_id: '{{ create_instance.instance.id }}' | ||
public: true | ||
type: ipv4 | ||
state: present | ||
register: allocate_ip | ||
|
||
- name: Assert changes | ||
assert: | ||
that: | ||
- allocate_ip.ip.linode_id == create_instance.instance.id | ||
- allocate_ip.ip.type == 'ipv4' | ||
- allocate_ip.ip.region == create_instance.instance.region | ||
|
||
# - name: Delete an IP | ||
# linode.cloud.ip: | ||
# address: allocate_ip.ip.address | ||
# state: absent | ||
# register: delete_ip | ||
|
||
always: | ||
- ignore_errors: true | ||
block: | ||
- name: Delete instance | ||
linode.cloud.instance: | ||
label: '{{ create_instance.instance.label }}' | ||
state: absent | ||
|
||
|
||
environment: | ||
LINODE_UA_PREFIX: '{{ ua_prefix }}' | ||
LINODE_API_TOKEN: '{{ api_token }}' | ||
LINODE_API_URL: '{{ api_url }}' | ||
LINODE_API_VERSION: '{{ api_version }}' | ||
LINODE_CA: '{{ ca_file or "" }}' | ||
|
||
|