Dre4m Shell
Server IP : 85.214.239.14  /  Your IP : 18.220.133.1
Web Server : Apache/2.4.62 (Debian)
System : Linux h2886529.stratoserver.net 4.9.0 #1 SMP Tue Jan 9 19:45:01 MSK 2024 x86_64
User : www-data ( 33)
PHP Version : 7.4.18
Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
MySQL : OFF  |  cURL : OFF  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : ON  |  Pkexec : OFF
Directory :  /usr/lib/python3/dist-packages/ansible_collections/vultr/cloud/plugins/inventory/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ HOME SHELL ]     

Current File : /usr/lib/python3/dist-packages/ansible_collections/vultr/cloud/plugins/inventory/vultr.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright (c) jasites <jsites@vultr.com>
# Copyright: Contributors to the Ansible project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later

# flake8: noqa: E402

from __future__ import absolute_import, division, print_function

__metaclass__ = type


DOCUMENTATION = """
---
name: vultr
short_description: Retrieves list of instances via Vultr v2 API
description:
  - Vultr inventory plugin.
  - Retrieves list of instances via Vultr v2 API.
  - Configuration of this plugin is done with files ending with '(vultr|vultr_hosts|vultr_instances).(yaml|yml)'
version_added: '1.4.0'
author:
  - jasites (@jasites)
extends_documentation_fragment:
  - constructed
  - inventory_cache
options:
  api_endpoint:
    description:
      - URL to API endpint (without trailing slash).
      - Fallback environment variable C(VULTR_API_ENDPOINT).
    type: str
    env:
      - name: VULTR_API_ENDPOINT
    default: https://api.vultr.com/v2
  api_key:
    description:
      - API key of the Vultr API.
      - Fallback environment variable C(VULTR_API_KEY).
    type: str
    env:
      - name: VULTR_API_KEY
    required: true
  api_results_per_page:
    description:
      - When receiving large numbers of instances, specify how many instances should be returned per call to API.
      - This does not determine how many results are returned; all instances are returned according to other filters.
      - Vultr API maximum is 500.
      - Fallback environment variable C(VULTR_API_RESULTS_PER_PAGE).
    type: int
    env:
      - name: VULTR_API_RESULTS_PER_PAGE
    default: 100
  api_timeout:
    description:
      - HTTP timeout to Vultr API.
      - Fallback environment variable C(VULTR_API_TIMEOUT).
    type: int
    env:
      - name: VULTR_API_TIMEOUT
    default: 60
  attributes:
    description:
      - Instance attributes to add as host variables to each host added to inventory.
      - See U(https://www.vultr.com/api/#operation/list-instances) for valid values.
    type: list
    elements: str
    default:
      - id
      - region
      - label
      - plan
      - hostname
      - main_ip
      - v6_main_ip
      - tags
  filters:
    description:
      - Filter hosts with Jinja2 templates.
      - If not provided, all hosts are added to inventory.
    type: list
    elements: str
    default: []
  instance_type:
    description:
      - Type of instance.
    type: str
    default: cloud
    choices:
      - cloud
      - bare_metal
    version_added: '1.8.0'
  plugin:
    description:
      - Name of Vultr inventory plugin.
      - This should always be C(vultr.cloud.vultr).
    type: str
    choices: ['vultr.cloud.vultr']
    required: true
  variable_prefix:
    description:
      - Prefix of generated variables (e.g. C(id) becomes C(vultr_id)).
    type: str
    default: 'vultr_'
  validate_certs:
    description:
      - Validate SSL certs of the Vultr API.
    type: bool
    default: true
notes:
  - Also see the API documentation on U(https://www.vultr.com/api/).
"""

EXAMPLES = """
---
# File endings vultr{,-{hosts,instances}}.y{,a}ml
# All configuration done via environment variables:
plugin: vultr.cloud.vultr

# Grouping and filtering configuration in inventory file
plugin: vultr.cloud.vultr
api_key: '{{ lookup("pipe"), "./get_vultr_api_key.sh" }}'
keyed_groups:
  - key: vultr_tags | lower
    prefix: ''
    separator: ''
filters:
  - '"vpc" in vultr_tags'
  - 'vultr_plan == "vc2-2c-4gb"'

# Unless you can connect to your servers via it's vultr label,
# we suggest setting ansible_host with compose:
plugin: vultr.cloud.vultr
compose:
  ansible_host: vultr_main_ip

# Respectively for IPv6:
plugin: vultr.cloud.vultr
compose:
  ansible_host: vultr_v6_main_ip

# Prioritize IPv6 over IPv4 if available.
plugin: vultr.cloud.vultr
compose:
  ansible_host: vultr_v6_main_ip or vultr_main_ip

# Querying the bare metal instances
plugin: vultr.cloud.vultr
instance_type: bare_metal
"""

RETURN = r""" # """

import json

from ansible.errors import AnsibleError, AnsibleParserError
from ansible.module_utils._text import to_native
from ansible.module_utils.six.moves.urllib.error import HTTPError, URLError
from ansible.module_utils.urls import Request
from ansible.plugins.inventory import BaseInventoryPlugin, Cacheable, Constructable

from ..module_utils.vultr_v2 import VULTR_USER_AGENT


class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):

    NAME = "vultr.cloud.vultr"

    RESOURCES_PER_TYPE = {
        "cloud": {
            "resource": "instances",
            "response": "instances",
        },
        "bare_metal": {
            "resource": "bare-metals",
            "response": "bare_metals",
        },
    }

    def _get_instances(self):
        instances = []
        api_key = self.get_option("api_key")
        if self.templar.is_template(api_key):
            api_key = self.templar.template(api_key)

        headers = {
            "Content-Type": "application/json",
            "User-Agent": VULTR_USER_AGENT,
            "Authorization": "Bearer {0}".format(api_key),
        }

        self.req = Request(
            headers=headers,
            timeout=int(self.get_option("api_timeout")),  # type: ignore
            validate_certs=self.get_option("validate_certs"),  # type: ignore
        )

        instance_type_config = self.get_option("instance_type") or "cloud"
        self.display.vvv("Type is: {0}".format(instance_type_config))

        instance_type = self.RESOURCES_PER_TYPE[instance_type_config]

        api_endpoint = "{0}/{1}?per_page={2}".format(
            self.get_option("api_endpoint"),
            instance_type["resource"],  # type: ignore
            self.get_option("api_results_per_page"),
        )

        cursor = ""
        req_url = api_endpoint
        try:
            while True:
                self.display.vvv("Querying API: {0}".format(req_url))

                page = json.load(self.req.get(req_url))
                instances.extend(page[instance_type["response"]])  # type: ignore
                cursor = page["meta"]["links"]["next"]

                if cursor == "":
                    return instances

                req_url = "{0}&cursor={1}".format(api_endpoint, cursor)

        except (KeyError, ValueError):
            raise AnsibleParserError("Unable to parse JSON response.")
        except (URLError, HTTPError) as err:
            raise AnsibleParserError(err)

    def _populate(self, instances):
        attributes = self.get_option("attributes")
        host_filters = self.get_option("filters")
        strict = self.get_option("strict")
        variable_prefix = self.get_option("variable_prefix")

        for instance in instances:
            instance_label = instance.get("label")

            if not instance_label:
                self.display.warning(msg="instance ID {0} has no label, skipping.".format(instance.get("id")))
                continue

            host_variables = {}
            for k, v in instance.items():
                if k in attributes:
                    host_variables["{0}{1}".format(variable_prefix, k)] = v

            if not self._passes_filters(
                host_filters,
                host_variables,
                instance_label,
                strict,  # type: ignore
            ):
                self.display.vvv("Host {0} excluded by filters".format(instance_label))
                continue

            self.inventory.add_host(instance_label)  # type: ignore

            for var_name, var_val in host_variables.items():
                self.inventory.set_variable(instance_label, var_name, var_val)  # type: ignore

            self._set_composite_vars(
                self.get_option("compose"),
                self.inventory.get_host(instance_label).get_vars(),  # type: ignore
                instance_label,
                strict,  # type: ignore
            )

            self._add_host_to_composed_groups(
                self.get_option("groups"),
                dict(),
                instance_label,
                strict,  # type: ignore
            )

            self._add_host_to_keyed_groups(
                self.get_option("keyed_groups"),
                dict(),
                instance_label,
                strict,  # type: ignore
            )

    def _passes_filters(self, filters, variables, host, strict=False):
        if filters and isinstance(filters, list):
            for template in filters:
                try:
                    if not self._compose(template, variables):
                        return False
                except Exception as e:
                    if strict:
                        raise AnsibleError(
                            "Could not evaluate host filter {0} for {1}: {2}".format(
                                template,
                                host,
                                to_native(e),
                            ),
                        )
                    return False
        return True

    def verify_file(self, path):
        valid = False
        if super(InventoryModule, self).verify_file(path):
            if path.endswith(
                (
                    "vultr.yaml",
                    "vultr.yml",
                    "vultr_hosts.yaml",
                    "vultr_hosts.yml",
                    "vultr_instances.yaml",
                    "vultr_instances.yml",
                )
            ):
                valid = True
            else:
                self.display.vvv(
                    "Skipping due to inventory configuration file name mismatch. "
                    "Valid filename endings: "
                    "vultr.yaml, vultr.yml, vultr_hosts.yaml, vultr_hosts.yml, "
                    "vultr_instances.yaml, vultr_instances.yml"
                )
        return valid

    def parse(self, inventory, loader, path, cache=True):
        super(InventoryModule, self).parse(inventory, loader, path)

        self._read_config_data(path)

        cache_key = self.get_cache_key(path)
        use_cache = self.get_option("cache") and cache
        update_cache = self.get_option("cache") and not cache

        instances = None
        if use_cache:
            try:
                instances = self._cache[cache_key]
            except KeyError:
                update_cache = True

        if instances is None:
            instances = self._get_instances()

        if update_cache:
            self._cache[cache_key] = instances

        self._populate(instances)

Anon7 - 2022
AnonSec Team