-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
new: Support IP module to allocate a new IP #628
base: dev
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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 | ||
|
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" | ||
} | ||
}'''] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
#!/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." | ||
], | ||
), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I find delete IP is not properly implemented in python sdk. We can't use the delete() function from Base because the endpoint is not correct. I'll create a python-sdk ticket to implement the right endpoint. |
||
"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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we raise an error here until the issue in the Python SDK has been resolved? |
||
return None | ||
|
||
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() |
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 "" }}' | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick