Repository URL to install this package:
|
Version:
6.0.0 ▾
|
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright: 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
DOCUMENTATION = r"""
---
module: digital_ocean_project
short_description: Manage a DigitalOcean project
description:
- Manage a project in DigitalOcean
author: "Tyler Auerbeck (@tylerauerbeck)"
version_added: 1.6.0
options:
state:
description:
- Indicate desired state of the target.
- C(present) will create the project
- C(absent) will delete the project, if it exists.
default: present
choices: ['present', 'absent']
type: str
oauth_token:
description:
- DigitalOcean OAuth token. Can be specified in C(DO_API_KEY), C(DO_API_TOKEN), or C(DO_OAUTH_TOKEN) environment variables
aliases: ['API_TOKEN']
type: str
required: true
environment:
description:
- The environment of the projects resources.
choices: ['Development', 'Staging', 'Production']
type: str
is_default:
description:
- If true, all resources will be added to this project if no project is specified.
default: False
type: bool
name:
description:
- The human-readable name for the project. The maximum length is 175 characters and the name must be unique.
type: str
id:
description:
- UUID of the project
type: str
purpose:
description:
- The purpose of the project. The maximum length is 255 characters
- Required if state is C(present)
- If not one of DO provided purposes, will be prefixed with C(Other)
- DO provided purposes can be found below
- C(Just trying out DigitalOcean)
- C(Class project/Educational Purposes)
- C(Website or blog)
- C(Web Application)
- C(Service or API)
- C(Mobile Application)
- C(Machine Learning/AI/Data Processing)
- C(IoT)
- C(Operational/Developer tooling)
type: str
description:
description:
- The description of the project. The maximum length is 255 characters.
type: str
"""
EXAMPLES = r"""
# Creates a new project
- community.digitalocean.digital_ocean_project:
name: "TestProj"
state: "present"
description: "This is a test project"
purpose: "IoT"
environment: "Development"
# Updates the existing project with the new environment
- community.digitalocean.digital_ocean_project:
name: "TestProj"
state: "present"
description: "This is a test project"
purpose: "IoT"
environment: "Production"
# This renames an existing project by utilizing the id of the project
- community.digitalocean.digital_ocean_project:
name: "TestProj2"
id: "12312312-abcd-efgh-ijkl-123123123123"
state: "present"
description: "This is a test project"
purpose: "IoT"
environment: "Development"
# This creates a project that results with a purpose of "Other: My Prod App"
- community.digitalocean.digital_ocean_project:
name: "ProdProj"
state: "present"
description: "This is a prod app"
purpose: "My Prod App"
environment: "Production"
# This removes a project
- community.digitalocean.digital_ocean_project:
name: "ProdProj"
state: "absent"
"""
RETURN = r"""
# Digital Ocean API info https://docs.digitalocean.com/reference/api/api-reference/#tag/Projects
data:
description: a DigitalOcean Project
returned: changed
type: dict
sample: {
"project": {
"created_at": "2021-05-28T00:00:00Z",
"description": "This is a test description",
"environment": "Development",
"id": "12312312-abcd-efgh-1234-abcdefgh123",
"is_default": false,
"name": "Test123",
"owner_id": 1234567,
"owner_uuid": "12312312-1234-5678-abcdefghijklm",
"purpose": "IoT",
"updated_at": "2021-05-29T00:00:00Z",
}
}
"""
import time
import json
from ansible.module_utils.basic import AnsibleModule, env_fallback
from ansible_collections.community.digitalocean.plugins.module_utils.digital_ocean import (
DigitalOceanHelper,
)
class DOProject(object):
def __init__(self, module):
self.rest = DigitalOceanHelper(module)
self.module = module
# pop the oauth token so we don't include it in the POST data
self.module.params.pop("oauth_token")
self.id = None
self.name = None
self.purpose = None
self.description = None
self.environment = None
self.is_default = None
def get_by_id(self, project_id):
if not project_id:
return None
response = self.rest.get("projects/{0}".format(project_id))
json_data = response.json
if response.status_code == 200:
project = json_data.get("project", None)
if project is not None:
self.id = project.get("id", None)
self.name = project.get("name", None)
self.purpose = project.get("purpose", None)
self.description = project.get("description", None)
self.environment = project.get("environment", None)
self.is_default = project.get("is_default", None)
return json_data
return None
def get_by_name(self, project_name):
if not project_name:
return None
page = 1
while page is not None:
response = self.rest.get("projects?page={0}".format(page))
json_data = response.json
if response.status_code == 200:
for project in json_data["projects"]:
if project.get("name", None) == project_name:
self.id = project.get("id", None)
self.name = project.get("name", None)
self.description = project.get("description", None)
self.purpose = project.get("purpose", None)
self.environment = project.get("environment", None)
self.is_default = project.get("is_default", None)
return {"project": project}
if (
"links" in json_data
and "pages" in json_data["links"]
and "next" in json_data["links"]["pages"]
):
page += 1
else:
page = None
return None
def get_project(self):
json_data = self.get_by_id(self.module.params["id"])
if not json_data:
json_data = self.get_by_name(self.module.params["name"])
return json_data
def create(self, state):
json_data = self.get_project()
request_params = dict(self.module.params)
if json_data is not None:
changed = False
valid_purpose = [
"Just trying out DigitalOcean",
"Class project/Educational Purposes",
"Website or blog",
"Web Application",
"Service or API",
"Mobile Application",
"Machine Learning/AI/Data Processing",
"IoT",
"Operational/Developer tooling",
]
for key in request_params.keys():
if (
key == "purpose"
and request_params[key] is not None
and request_params[key] not in valid_purpose
):
param = "Other: " + request_params[key]
else:
param = request_params[key]
if json_data["project"][key] != param and param is not None:
changed = True
if changed:
response = self.rest.put(
"projects/{0}".format(json_data["project"]["id"]),
data=request_params,
)
if response.status_code != 200:
self.module.fail_json(changed=False, msg="Unable to update project")
self.module.exit_json(changed=True, data=response.json)
else:
self.module.exit_json(changed=False, data=json_data)
else:
response = self.rest.post("projects", data=request_params)
if response.status_code != 201:
self.module.fail_json(changed=False, msg="Unable to create project")
self.module.exit_json(changed=True, data=response.json)
def delete(self):
json_data = self.get_project()
if json_data:
if self.module.check_mode:
self.module.exit_json(changed=True)
response = self.rest.delete(
"projects/{0}".format(json_data["project"]["id"])
)
json_data = response.json
if response.status_code == 204:
self.module.exit_json(changed=True, msg="Project deleted")
self.module.fail_json(changed=False, msg="Failed to delete project")
else:
self.module.exit_json(changed=False, msg="Project not found")
def core(module):
state = module.params.pop("state")
project = DOProject(module)
if state == "present":
project.create(state)
elif state == "absent":
project.delete()
def main():
module = AnsibleModule(
argument_spec=dict(
state=dict(choices=["present", "absent"], default="present", type="str"),
oauth_token=dict(
aliases=["API_TOKEN"],
no_log=True,
fallback=(
env_fallback,
["DO_API_TOKEN", "DO_API_KEY", "DO_OAUTH_TOKEN"],
),
required=True,
),
name=dict(type="str"),
id=dict(type="str"),
description=dict(type="str"),
purpose=dict(type="str"),
is_default=dict(type="bool", default=False),
environment=dict(
choices=["Development", "Staging", "Production"], type="str"
),
),
required_one_of=(["id", "name"],),
required_if=(
[
("state", "present", ["purpose"]),
]
),
)
core(module)
if __name__ == "__main__":
main()