����JFIF��������� Mr.X
  
  __  __    __   __  _____      _            _          _____ _          _ _ 
 |  \/  |   \ \ / / |  __ \    (_)          | |        / ____| |        | | |
 | \  / |_ __\ V /  | |__) | __ ___   ____ _| |_ ___  | (___ | |__   ___| | |
 | |\/| | '__|> <   |  ___/ '__| \ \ / / _` | __/ _ \  \___ \| '_ \ / _ \ | |
 | |  | | |_ / . \  | |   | |  | |\ V / (_| | ||  __/  ____) | | | |  __/ | |
 |_|  |_|_(_)_/ \_\ |_|   |_|  |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1
 if you need WebShell for Seo everyday contact me on Telegram
 Telegram Address : @jackleet
        
        
For_More_Tools: Telegram: @jackleet | Bulk Smtp support mail sender | Business Mail Collector | Mail Bouncer All Mail | Bulk Office Mail Validator | Html Letter private



Upload:

Command:

deexcl@216.73.217.71: ~ $
# -*- coding: utf-8 -*-
# Copyright (c) 2017, Milan Ilic <milani@nordeus.com>
# Copyright (c) 2019, Jan Meerkamp <meerkamp@dvv.de>
# 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

# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type

DOCUMENTATION = '''
---
module: one_vm
short_description: Creates or terminates OpenNebula instances
description:
  - Manages OpenNebula instances
requirements:
  - pyone
extends_documentation_fragment:
  - community.general.attributes
attributes:
  check_mode:
    support: full
  diff_mode:
    support: none
options:
  api_url:
    description:
      - URL of the OpenNebula RPC server.
      - It is recommended to use HTTPS so that the username/password are not
      - transferred over the network unencrypted.
      - If not set then the value of the C(ONE_URL) environment variable is used.
    type: str
  api_username:
    description:
      - Name of the user to login into the OpenNebula RPC server. If not set
      - then the value of the C(ONE_USERNAME) environment variable is used.
    type: str
  api_password:
    description:
      - Password of the user to login into OpenNebula RPC server. If not set
      - then the value of the C(ONE_PASSWORD) environment variable is used.
      - if both I(api_username) or I(api_password) are not set, then it will try
      - authenticate with ONE auth file. Default path is "~/.one/one_auth".
      - Set environment variable C(ONE_AUTH) to override this path.
    type: str
  template_name:
    description:
      - Name of VM template to use to create a new instace
    type: str
  template_id:
    description:
      - ID of a VM template to use to create a new instance
    type: int
  vm_start_on_hold:
    description:
      - Set to true to put vm on hold while creating
    default: false
    type: bool
  instance_ids:
    description:
      - A list of instance ids used for states':' C(absent), C(running), C(rebooted), C(poweredoff)
    aliases: ['ids']
    type: list
    elements: int
  state:
    description:
      - C(present) - create instances from a template specified with C(template_id)/C(template_name).
      - C(running) - run instances
      - C(poweredoff) - power-off instances
      - C(rebooted) - reboot instances
      - C(absent) - terminate instances
    choices: ["present", "absent", "running", "rebooted", "poweredoff"]
    default: present
    type: str
  hard:
    description:
      - Reboot, power-off or terminate instances C(hard)
    default: false
    type: bool
  wait:
    description:
      - Wait for the instance to reach its desired state before returning. Keep
      - in mind if you are waiting for instance to be in running state it
      - doesn't mean that you will be able to SSH on that machine only that
      - boot process have started on that instance, see 'wait_for' example for
      - details.
    default: true
    type: bool
  wait_timeout:
    description:
      - How long before wait gives up, in seconds
    default: 300
    type: int
  attributes:
    description:
      - A dictionary of key/value attributes to add to new instances, or for
      - setting C(state) of instances with these attributes.
      - Keys are case insensitive and OpenNebula automatically converts them to upper case.
      - Be aware C(NAME) is a special attribute which sets the name of the VM when it's deployed.
      - C(#) character(s) can be appended to the C(NAME) and the module will automatically add
      - indexes to the names of VMs.
      - For example':' C(NAME':' foo-###) would create VMs with names C(foo-000), C(foo-001),...
      - When used with C(count_attributes) and C(exact_count) the module will
      - match the base name without the index part.
    default: {}
    type: dict
  labels:
    description:
      - A list of labels to associate with new instances, or for setting
      - C(state) of instances with these labels.
    default: []
    type: list
    elements: str
  count_attributes:
    description:
      - A dictionary of key/value attributes that can only be used with
      - C(exact_count) to determine how many nodes based on a specific
      - attributes criteria should be deployed. This can be expressed in
      - multiple ways and is shown in the EXAMPLES section.
    type: dict
  count_labels:
    description:
      - A list of labels that can only be used with C(exact_count) to determine
      - how many nodes based on a specific labels criteria should be deployed.
      - This can be expressed in multiple ways and is shown in the EXAMPLES
      - section.
    type: list
    elements: str
  count:
    description:
      - Number of instances to launch
    default: 1
    type: int
  exact_count:
    description:
      - Indicates how many instances that match C(count_attributes) and
      - C(count_labels) parameters should be deployed. Instances are either
      - created or terminated based on this value.
      - NOTE':' Instances with the least IDs will be terminated first.
    type: int
  mode:
    description:
      - Set permission mode of the instance in octet format, e.g. C(600) to give owner C(use) and C(manage) and nothing to group and others.
    type: str
  owner_id:
    description:
      - ID of the user which will be set as the owner of the instance
    type: int
  group_id:
    description:
      - ID of the group which will be set as the group of the instance
    type: int
  memory:
    description:
      - The size of the memory for new instances (in MB, GB, ...)
    type: str
  disk_size:
    description:
      - The size of the disk created for new instances (in MB, GB, TB,...).
      - NOTE':' If The Template hats Multiple Disks the Order of the Sizes is
      - matched against the order specified in C(template_id)/C(template_name).
    type: list
    elements: str
  cpu:
    description:
      - Percentage of CPU divided by 100 required for the new instance. Half a
      - processor is written 0.5.
    type: float
  vcpu:
    description:
      - Number of CPUs (cores) new VM will have.
    type: int
  networks:
    description:
      - A list of dictionaries with network parameters. See examples for more details.
    default: []
    type: list
    elements: dict
  disk_saveas:
    description:
      - Creates an image from a VM disk.
      - It is a dictionary where you have to specify C(name) of the new image.
      - Optionally you can specify C(disk_id) of the disk you want to save. By default C(disk_id) is 0.
      - I(NOTE)':' This operation will only be performed on the first VM (if more than one VM ID is passed)
      - and the VM has to be in the C(poweredoff) state.
      - Also this operation will fail if an image with specified C(name) already exists.
    type: dict
  persistent:
    description:
      - Create a private persistent copy of the template plus any image defined in DISK, and instantiate that copy.
    default: false
    type: bool
    version_added: '0.2.0'
  datastore_id:
    description:
      - Name of Datastore to use to create a new instace
    version_added: '0.2.0'
    type: int
  datastore_name:
    description:
      - Name of Datastore to use to create a new instace
    version_added: '0.2.0'
    type: str
  updateconf:
    description:
      - When I(instance_ids) is provided, updates running VMs with the C(updateconf) API call.
      - When new VMs are being created, emulates the C(updateconf) API call via direct template merge.
      - Allows for complete modifications of the C(CONTEXT) attribute.
    type: dict
    version_added: 6.3.0
author:
    - "Milan Ilic (@ilicmilan)"
    - "Jan Meerkamp (@meerkampdvv)"
'''


EXAMPLES = '''
- name: Create a new instance
  community.general.one_vm:
    template_id: 90
  register: result

- name: Print VM properties
  ansible.builtin.debug:
    msg: result

- name: Deploy a new VM on hold
  community.general.one_vm:
    template_name: 'app1_template'
    vm_start_on_hold: 'True'

- name: Deploy a new VM and set its name to 'foo'
  community.general.one_vm:
    template_name: 'app1_template'
    attributes:
      name: foo

- name: Deploy a new VM and set its group_id and mode
  community.general.one_vm:
    template_id: 90
    group_id: 16
    mode: 660

- name: Deploy a new VM  as persistent
  community.general.one_vm:
    template_id: 90
    persistent: true

- name: Change VM's permissions to 640
  community.general.one_vm:
    instance_ids: 5
    mode: 640

- name: Deploy 2 new instances and set memory, vcpu, disk_size and 3 networks
  community.general.one_vm:
    template_id: 15
    disk_size: 35.2 GB
    memory: 4 GB
    vcpu: 4
    count: 2
    networks:
      - NETWORK_ID: 27
      - NETWORK: "default-network"
        NETWORK_UNAME: "app-user"
        SECURITY_GROUPS: "120,124"
      - NETWORK_ID: 27
        SECURITY_GROUPS: "10"

- name: Deploy a new instance which uses a Template with two Disks
  community.general.one_vm:
    template_id: 42
    disk_size:
      - 35.2 GB
      - 50 GB
    memory: 4 GB
    vcpu: 4
    count: 1
    networks:
      - NETWORK_ID: 27

- name: "Deploy an new instance with attribute 'bar: bar1' and set its name to 'foo'"
  community.general.one_vm:
    template_id: 53
    attributes:
      name: foo
      bar: bar1

- name: "Enforce that 2 instances with attributes 'foo1: app1' and 'foo2: app2' are deployed"
  community.general.one_vm:
    template_id: 53
    attributes:
      foo1: app1
      foo2: app2
    exact_count: 2
    count_attributes:
      foo1: app1
      foo2: app2

- name: Enforce that 4 instances with an attribute 'bar' are deployed
  community.general.one_vm:
    template_id: 53
    attributes:
      name: app
      bar: bar2
    exact_count: 4
    count_attributes:
      bar:

# Deploy 2 new instances with attribute 'foo: bar' and labels 'app1' and 'app2' and names in format 'fooapp-##'
# Names will be: fooapp-00 and fooapp-01
- name: Deploy 2 new instances
  community.general.one_vm:
    template_id: 53
    attributes:
      name: fooapp-##
      foo: bar
    labels:
      - app1
      - app2
    count: 2

# Deploy 2 new instances with attribute 'app: app1' and names in format 'fooapp-###'
# Names will be: fooapp-002 and fooapp-003
- name: Deploy 2 new instances
  community.general.one_vm:
    template_id: 53
    attributes:
      name: fooapp-###
      app: app1
    count: 2

# Reboot all instances with name in format 'fooapp-#'
# Instances 'fooapp-00', 'fooapp-01', 'fooapp-002' and 'fooapp-003' will be rebooted
- name: Reboot all instances with names in a certain format
  community.general.one_vm:
    attributes:
      name: fooapp-#
    state: rebooted

# Enforce that only 1 instance with name in format 'fooapp-#' is deployed
# The task will delete oldest instances, so only the 'fooapp-003' will remain
- name: Enforce that only 1 instance with name in a certain format is deployed
  community.general.one_vm:
    template_id: 53
    exact_count: 1
    count_attributes:
      name: fooapp-#

- name: Deploy an new instance with a network
  community.general.one_vm:
    template_id: 53
    networks:
      - NETWORK_ID: 27
  register: vm

- name: Wait for SSH to come up
  ansible.builtin.wait_for_connection:
  delegate_to: '{{ vm.instances[0].networks[0].ip }}'

- name: Terminate VMs by ids
  community.general.one_vm:
    instance_ids:
      - 153
      - 160
    state: absent

- name: Reboot all VMs that have labels 'foo' and 'app1'
  community.general.one_vm:
    labels:
      - foo
      - app1
    state: rebooted

- name: "Fetch all VMs that have name 'foo' and attribute 'app: bar'"
  community.general.one_vm:
    attributes:
      name: foo
      app: bar
  register: results

- name: Deploy 2 new instances with labels 'foo1' and 'foo2'
  community.general.one_vm:
    template_name: app_template
    labels:
      - foo1
      - foo2
    count: 2

- name: Enforce that only 1 instance with label 'foo1' will be running
  community.general.one_vm:
    template_name: app_template
    labels:
      - foo1
    exact_count: 1
    count_labels:
      - foo1

- name: Terminate all instances that have attribute foo
  community.general.one_vm:
    template_id: 53
    exact_count: 0
    count_attributes:
      foo:

- name: "Power-off the VM and save VM's disk with id=0 to the image with name 'foo-image'"
  community.general.one_vm:
    instance_ids: 351
    state: poweredoff
    disk_saveas:
      name: foo-image

- name: "Save VM's disk with id=1 to the image with name 'bar-image'"
  community.general.one_vm:
    instance_ids: 351
    disk_saveas:
      name: bar-image
      disk_id: 1

- name: "Deploy 2 new instances with a custom 'start script'"
  community.general.one_vm:
    template_name: app_template
    count: 2
    updateconf:
      CONTEXT:
        START_SCRIPT: ip r r 169.254.16.86/32 dev eth0

- name: "Add a custom 'start script' to a running VM"
  community.general.one_vm:
    instance_ids: 351
    updateconf:
      CONTEXT:
        START_SCRIPT: ip r r 169.254.16.86/32 dev eth0

- name: "Update SSH public keys inside the VM's context"
  community.general.one_vm:
    instance_ids: 351
    updateconf:
      CONTEXT:
        SSH_PUBLIC_KEY: |-
          ssh-rsa ...
          ssh-ed25519 ...
'''

RETURN = '''
instances_ids:
    description: a list of instances ids whose state is changed or which are fetched with C(instance_ids) option.
    type: list
    returned: success
    sample: [ 1234, 1235 ]
instances:
    description: a list of instances info whose state is changed or which are fetched with C(instance_ids) option.
    type: complex
    returned: success
    contains:
        vm_id:
            description: vm id
            type: int
            sample: 153
        vm_name:
            description: vm name
            type: str
            sample: foo
        template_id:
            description: vm's template id
            type: int
            sample: 153
        group_id:
            description: vm's group id
            type: int
            sample: 1
        group_name:
            description: vm's group name
            type: str
            sample: one-users
        owner_id:
            description: vm's owner id
            type: int
            sample: 143
        owner_name:
            description: vm's owner name
            type: str
            sample: app-user
        mode:
            description: vm's mode
            type: str
            returned: success
            sample: 660
        state:
            description: state of an instance
            type: str
            sample: ACTIVE
        lcm_state:
            description: lcm state of an instance that is only relevant when the state is ACTIVE
            type: str
            sample: RUNNING
        cpu:
            description: Percentage of CPU divided by 100
            type: float
            sample: 0.2
        vcpu:
            description: Number of CPUs (cores)
            type: int
            sample: 2
        memory:
            description: The size of the memory in MB
            type: str
            sample: 4096 MB
        disk_size:
            description: The size of the disk in MB
            type: str
            sample: 20480 MB
        networks:
            description: a list of dictionaries with info about IP, NAME, MAC, SECURITY_GROUPS for each NIC
            type: list
            sample: [
                        {
                            "ip": "10.120.5.33",
                            "mac": "02:00:0a:78:05:21",
                            "name": "default-test-private",
                            "security_groups": "0,10"
                        },
                        {
                            "ip": "10.120.5.34",
                            "mac": "02:00:0a:78:05:22",
                            "name": "default-test-private",
                            "security_groups": "0"
                        }
                    ]
        uptime_h:
            description: Uptime of the instance in hours
            type: int
            sample: 35
        labels:
            description: A list of string labels that are associated with the instance
            type: list
            sample: [
                        "foo",
                        "spec-label"
                    ]
        attributes:
            description: A dictionary of key/values attributes that are associated with the instance
            type: dict
            sample: {
                        "HYPERVISOR": "kvm",
                        "LOGO": "images/logos/centos.png",
                        "TE_GALAXY": "bar",
                        "USER_INPUTS": null
                    }
        updateconf:
            description: A dictionary of key/values attributes that are set with the updateconf API call.
            type: dict
            version_added: 6.3.0
            sample: {
                        "OS": { "ARCH": "x86_64" },
                        "CONTEXT": {
                            "START_SCRIPT": "ip r r 169.254.16.86/32 dev eth0",
                            "SSH_PUBLIC_KEY": "ssh-rsa ...\\nssh-ed25519 ..."
                        }
                    }
tagged_instances:
    description:
        - A list of instances info based on a specific attributes and/or
        - labels that are specified with C(count_attributes) and C(count_labels)
        - options.
    type: complex
    returned: success
    contains:
        vm_id:
            description: vm id
            type: int
            sample: 153
        vm_name:
            description: vm name
            type: str
            sample: foo
        template_id:
            description: vm's template id
            type: int
            sample: 153
        group_id:
            description: vm's group id
            type: int
            sample: 1
        group_name:
            description: vm's group name
            type: str
            sample: one-users
        owner_id:
            description: vm's user id
            type: int
            sample: 143
        owner_name:
            description: vm's user name
            type: str
            sample: app-user
        mode:
            description: vm's mode
            type: str
            returned: success
            sample: 660
        state:
            description: state of an instance
            type: str
            sample: ACTIVE
        lcm_state:
            description: lcm state of an instance that is only relevant when the state is ACTIVE
            type: str
            sample: RUNNING
        cpu:
            description: Percentage of CPU divided by 100
            type: float
            sample: 0.2
        vcpu:
            description: Number of CPUs (cores)
            type: int
            sample: 2
        memory:
            description: The size of the memory in MB
            type: str
            sample: 4096 MB
        disk_size:
            description: The size of the disk in MB
            type: list
            sample: [
                        "20480 MB",
                        "10240 MB"
                    ]
        networks:
            description: a list of dictionaries with info about IP, NAME, MAC, SECURITY_GROUPS for each NIC
            type: list
            sample: [
                        {
                            "ip": "10.120.5.33",
                            "mac": "02:00:0a:78:05:21",
                            "name": "default-test-private",
                            "security_groups": "0,10"
                        },
                        {
                            "ip": "10.120.5.34",
                            "mac": "02:00:0a:78:05:22",
                            "name": "default-test-private",
                            "security_groups": "0"
                        }
                    ]
        uptime_h:
            description: Uptime of the instance in hours
            type: int
            sample: 35
        labels:
            description: A list of string labels that are associated with the instance
            type: list
            sample: [
                        "foo",
                        "spec-label"
                    ]
        attributes:
            description: A dictionary of key/values attributes that are associated with the instance
            type: dict
            sample: {
                        "HYPERVISOR": "kvm",
                        "LOGO": "images/logos/centos.png",
                        "TE_GALAXY": "bar",
                        "USER_INPUTS": null
                    }
        updateconf:
            description: A dictionary of key/values attributes that are set with the updateconf API call
            type: dict
            version_added: 6.3.0
            sample: {
                        "OS": { "ARCH": "x86_64" },
                        "CONTEXT": {
                            "START_SCRIPT": "ip r r 169.254.16.86/32 dev eth0",
                            "SSH_PUBLIC_KEY": "ssh-rsa ...\\nssh-ed25519 ..."
                        }
                    }
'''

try:
    import pyone
    HAS_PYONE = True
except ImportError:
    HAS_PYONE = False


import os

from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.common.dict_transformations import dict_merge

from ansible_collections.community.general.plugins.module_utils.opennebula import flatten, render


UPDATECONF_ATTRIBUTES = {
    "OS": ["ARCH", "MACHINE", "KERNEL", "INITRD", "BOOTLOADER", "BOOT", "SD_DISK_BUS", "UUID"],
    "FEATURES": ["ACPI", "PAE", "APIC", "LOCALTIME", "HYPERV", "GUEST_AGENT"],
    "INPUT": ["TYPE", "BUS"],
    "GRAPHICS": ["TYPE", "LISTEN", "PASSWD", "KEYMAP"],
    "RAW": ["DATA", "DATA_VMX", "TYPE"],
    "CONTEXT": [],
}


def check_updateconf(module, to_check):
    '''Checks if attributes are compatible with one.vm.updateconf API call.'''
    for attr, subattributes in to_check.items():
        if attr not in UPDATECONF_ATTRIBUTES:
            module.fail_json(msg="'{0:}' is not a valid VM attribute.".format(attr))
        if not UPDATECONF_ATTRIBUTES[attr]:
            continue
        for subattr in subattributes:
            if subattr not in UPDATECONF_ATTRIBUTES[attr]:
                module.fail_json(msg="'{0:}' is not a valid VM subattribute of '{1:}'".format(subattr, attr))


def parse_updateconf(vm_template):
    '''Extracts 'updateconf' attributes from a VM template.'''
    updateconf = {}
    for attr, subattributes in vm_template.items():
        if attr not in UPDATECONF_ATTRIBUTES:
            continue
        tmp = {}
        for subattr, value in subattributes.items():
            if UPDATECONF_ATTRIBUTES[attr] and subattr not in UPDATECONF_ATTRIBUTES[attr]:
                continue
            tmp[subattr] = value
        if tmp:
            updateconf[attr] = tmp
    return updateconf


def get_template(module, client, predicate):

    pool = client.templatepool.info(-2, -1, -1, -1)
    # Filter -2 means fetch all templates user can Use
    found = 0
    found_template = None
    template_name = ''

    for template in pool.VMTEMPLATE:
        if predicate(template):
            found = found + 1
            found_template = template
            template_name = template.NAME

    if found == 0:
        return None
    elif found > 1:
        module.fail_json(msg='There are more templates with name: ' + template_name)
    return found_template


def get_template_by_name(module, client, template_name):
    return get_template(module, client, lambda template: (template.NAME == template_name))


def get_template_by_id(module, client, template_id):
    return get_template(module, client, lambda template: (template.ID == template_id))


def get_template_id(module, client, requested_id, requested_name):
    template = get_template_by_id(module, client, requested_id) if requested_id is not None else get_template_by_name(module, client, requested_name)
    if template:
        return template.ID
    else:
        return None


def get_datastore(module, client, predicate):
    pool = client.datastorepool.info()
    found = 0
    found_datastore = None
    datastore_name = ''

    for datastore in pool.DATASTORE:
        if predicate(datastore):
            found = found + 1
            found_datastore = datastore
            datastore_name = datastore.NAME

    if found == 0:
        return None
    elif found > 1:
        module.fail_json(msg='There are more datastores with name: ' + datastore_name)
    return found_datastore


def get_datastore_by_name(module, client, datastore_name):
    return get_datastore(module, client, lambda datastore: (datastore.NAME == datastore_name))


def get_datastore_by_id(module, client, datastore_id):
    return get_datastore(module, client, lambda datastore: (datastore.ID == datastore_id))


def get_datastore_id(module, client, requested_id, requested_name):
    datastore = get_datastore_by_id(module, client, requested_id) if requested_id else get_datastore_by_name(module, client, requested_name)
    if datastore:
        return datastore.ID
    else:
        return None


def get_vm_by_id(client, vm_id):
    try:
        vm = client.vm.info(int(vm_id))
    except BaseException:
        return None
    return vm


def get_vms_by_ids(module, client, state, ids):
    vms = []

    for vm_id in ids:
        vm = get_vm_by_id(client, vm_id)
        if vm is None and state != 'absent':
            module.fail_json(msg='There is no VM with id=' + str(vm_id))
        vms.append(vm)

    return vms


def get_vm_info(client, vm):

    vm = client.vm.info(vm.ID)

    networks_info = []

    disk_size = []
    if 'DISK' in vm.TEMPLATE:
        if isinstance(vm.TEMPLATE['DISK'], list):
            for disk in vm.TEMPLATE['DISK']:
                disk_size.append(disk['SIZE'] + ' MB')
        else:
            disk_size.append(vm.TEMPLATE['DISK']['SIZE'] + ' MB')

    if 'NIC' in vm.TEMPLATE:
        if isinstance(vm.TEMPLATE['NIC'], list):
            for nic in vm.TEMPLATE['NIC']:
                networks_info.append({
                    'ip': nic.get('IP', ''),
                    'mac': nic.get('MAC', ''),
                    'name': nic.get('NETWORK', ''),
                    'security_groups': nic.get('SECURITY_GROUPS', '')
                })
        else:
            networks_info.append({
                'ip': vm.TEMPLATE['NIC'].get('IP', ''),
                'mac': vm.TEMPLATE['NIC'].get('MAC', ''),
                'name': vm.TEMPLATE['NIC'].get('NETWORK', ''),
                'security_groups':
                    vm.TEMPLATE['NIC'].get('SECURITY_GROUPS', '')
            })
    import time

    current_time = time.localtime()
    vm_start_time = time.localtime(vm.STIME)

    vm_uptime = time.mktime(current_time) - time.mktime(vm_start_time)
    vm_uptime /= (60 * 60)

    permissions_str = parse_vm_permissions(client, vm)

    # LCM_STATE is VM's sub-state that is relevant only when STATE is ACTIVE
    vm_lcm_state = None
    if vm.STATE == VM_STATES.index('ACTIVE'):
        vm_lcm_state = LCM_STATES[vm.LCM_STATE]

    vm_labels, vm_attributes = get_vm_labels_and_attributes_dict(client, vm.ID)

    updateconf = parse_updateconf(vm.TEMPLATE)

    info = {
        'template_id': int(vm.TEMPLATE['TEMPLATE_ID']),
        'vm_id': vm.ID,
        'vm_name': vm.NAME,
        'state': VM_STATES[vm.STATE],
        'lcm_state': vm_lcm_state,
        'owner_name': vm.UNAME,
        'owner_id': vm.UID,
        'networks': networks_info,
        'disk_size': disk_size,
        'memory': vm.TEMPLATE['MEMORY'] + ' MB',
        'vcpu': vm.TEMPLATE['VCPU'],
        'cpu': vm.TEMPLATE['CPU'],
        'group_name': vm.GNAME,
        'group_id': vm.GID,
        'uptime_h': int(vm_uptime),
        'attributes': vm_attributes,
        'mode': permissions_str,
        'labels': vm_labels,
        'updateconf': updateconf,
    }

    return info


def parse_vm_permissions(client, vm):
    vm_PERMISSIONS = client.vm.info(vm.ID).PERMISSIONS

    owner_octal = int(vm_PERMISSIONS.OWNER_U) * 4 + int(vm_PERMISSIONS.OWNER_M) * 2 + int(vm_PERMISSIONS.OWNER_A)
    group_octal = int(vm_PERMISSIONS.GROUP_U) * 4 + int(vm_PERMISSIONS.GROUP_M) * 2 + int(vm_PERMISSIONS.GROUP_A)
    other_octal = int(vm_PERMISSIONS.OTHER_U) * 4 + int(vm_PERMISSIONS.OTHER_M) * 2 + int(vm_PERMISSIONS.OTHER_A)

    permissions = str(owner_octal) + str(group_octal) + str(other_octal)

    return permissions


def set_vm_permissions(module, client, vms, permissions):
    changed = False

    for vm in vms:
        vm = client.vm.info(vm.ID)
        old_permissions = parse_vm_permissions(client, vm)
        changed = changed or old_permissions != permissions

        if not module.check_mode and old_permissions != permissions:
            permissions_str = bin(int(permissions, base=8))[2:]  # 600 -> 110000000
            mode_bits = [int(d) for d in permissions_str]
            try:
                client.vm.chmod(
                    vm.ID, mode_bits[0], mode_bits[1], mode_bits[2], mode_bits[3], mode_bits[4], mode_bits[5], mode_bits[6], mode_bits[7], mode_bits[8])
            except pyone.OneAuthorizationException:
                module.fail_json(msg="Permissions changing is unsuccessful, but instances are present if you deployed them.")

    return changed


def set_vm_ownership(module, client, vms, owner_id, group_id):
    changed = False

    for vm in vms:
        vm = client.vm.info(vm.ID)
        if owner_id is None:
            owner_id = vm.UID
        if group_id is None:
            group_id = vm.GID

        changed = changed or owner_id != vm.UID or group_id != vm.GID

        if not module.check_mode and (owner_id != vm.UID or group_id != vm.GID):
            try:
                client.vm.chown(vm.ID, owner_id, group_id)
            except pyone.OneAuthorizationException:
                module.fail_json(msg="Ownership changing is unsuccessful, but instances are present if you deployed them.")

    return changed


def update_vm(module, client, vm, updateconf_dict):
    changed = False
    if not updateconf_dict:
        return changed

    before = client.vm.info(vm.ID).TEMPLATE

    client.vm.updateconf(vm.ID, render(updateconf_dict), 1)  # 1: Merge new template with the existing one.

    after = client.vm.info(vm.ID).TEMPLATE

    changed = before != after
    return changed


def update_vms(module, client, vms, *args):
    changed = False
    for vm in vms:
        changed = update_vm(module, client, vm, *args) or changed
    return changed


def get_size_in_MB(module, size_str):

    SYMBOLS = ['B', 'KB', 'MB', 'GB', 'TB']

    s = size_str
    init = size_str
    num = ""
    while s and s[0:1].isdigit() or s[0:1] == '.':
        num += s[0]
        s = s[1:]
    num = float(num)
    symbol = s.strip()

    if symbol not in SYMBOLS:
        module.fail_json(msg="Cannot interpret %r %r %d" % (init, symbol, num))

    prefix = {'B': 1}

    for i, s in enumerate(SYMBOLS[1:]):
        prefix[s] = 1 << (i + 1) * 10

    size_in_bytes = int(num * prefix[symbol])
    size_in_MB = size_in_bytes / (1024 * 1024)

    return size_in_MB


def create_vm(module, client, template_id, attributes_dict, labels_list, disk_size, network_attrs_list, vm_start_on_hold, vm_persistent, updateconf_dict):
    if attributes_dict:
        vm_name = attributes_dict.get('NAME', '')

    template = client.template.info(template_id).TEMPLATE

    disk_count = len(flatten(template.get('DISK', [])))
    if disk_size:
        size_count = len(flatten(disk_size))
        # check if the number of disks is correct
        if disk_count != size_count:
            module.fail_json(msg='This template has ' + str(disk_count) + ' disks but you defined ' + str(size_count))

    vm_extra_template = dict_merge(template or {}, attributes_dict or {})
    vm_extra_template = dict_merge(vm_extra_template, {
        'LABELS': ','.join(labels_list),
        'NIC': flatten(network_attrs_list, extract=True),
        'DISK': flatten([
            disk if not size else dict_merge(disk, {
                'SIZE': str(int(get_size_in_MB(module, size))),
            })
            for disk, size in zip(
                flatten(template.get('DISK', [])),
                flatten(disk_size or [None] * disk_count),
            )
            if disk is not None
        ], extract=True)
    })
    vm_extra_template = dict_merge(vm_extra_template, updateconf_dict or {})

    try:
        vm_id = client.template.instantiate(template_id,
                                            vm_name,
                                            vm_start_on_hold,
                                            render(vm_extra_template),
                                            vm_persistent)
    except pyone.OneException as e:
        module.fail_json(msg=str(e))

    vm = get_vm_by_id(client, vm_id)
    return get_vm_info(client, vm)


def generate_next_index(vm_filled_indexes_list, num_sign_cnt):
    counter = 0
    cnt_str = str(counter).zfill(num_sign_cnt)

    while cnt_str in vm_filled_indexes_list:
        counter = counter + 1
        cnt_str = str(counter).zfill(num_sign_cnt)

    return cnt_str


def get_vm_labels_and_attributes_dict(client, vm_id):
    vm_USER_TEMPLATE = client.vm.info(vm_id).USER_TEMPLATE

    attrs_dict = {}
    labels_list = []

    for key, value in vm_USER_TEMPLATE.items():
        if key != 'LABELS':
            attrs_dict[key] = value
        else:
            if key is not None and value is not None:
                labels_list = value.split(',')

    return labels_list, attrs_dict


def get_all_vms_by_attributes(client, attributes_dict, labels_list):
    pool = client.vmpool.info(-2, -1, -1, -1).VM
    vm_list = []
    name = ''
    if attributes_dict:
        name = attributes_dict.pop('NAME', '')

    if name != '':
        base_name = name[:len(name) - name.count('#')]
        # Check does the name have indexed format
        with_hash = name.endswith('#')

        for vm in pool:
            if vm.NAME.startswith(base_name):
                if with_hash and vm.NAME[len(base_name):].isdigit():
                    # If the name has indexed format and after base_name it has only digits it'll be matched
                    vm_list.append(vm)
                elif not with_hash and vm.NAME == name:
                    # If the name is not indexed it has to be same
                    vm_list.append(vm)
        pool = vm_list

    import copy

    vm_list = copy.copy(pool)

    for vm in pool:
        remove_list = []
        vm_labels_list, vm_attributes_dict = get_vm_labels_and_attributes_dict(client, vm.ID)

        if attributes_dict and len(attributes_dict) > 0:
            for key, val in attributes_dict.items():
                if key in vm_attributes_dict:
                    if val and vm_attributes_dict[key] != val:
                        remove_list.append(vm)
                        break
                else:
                    remove_list.append(vm)
                    break
        vm_list = list(set(vm_list).difference(set(remove_list)))

        remove_list = []
        if labels_list and len(labels_list) > 0:
            for label in labels_list:
                if label not in vm_labels_list:
                    remove_list.append(vm)
                    break
        vm_list = list(set(vm_list).difference(set(remove_list)))

    return vm_list


def create_count_of_vms(module, client,
                        template_id, count,
                        attributes_dict, labels_list, disk_size, network_attrs_list,
                        wait, wait_timeout, vm_start_on_hold, vm_persistent, updateconf_dict):
    new_vms_list = []

    vm_name = ''
    if attributes_dict:
        vm_name = attributes_dict.get('NAME', '')

    if module.check_mode:
        return True, [], []

    # Create list of used indexes
    vm_filled_indexes_list = None
    num_sign_cnt = vm_name.count('#')
    if vm_name != '' and num_sign_cnt > 0:
        vm_list = get_all_vms_by_attributes(client, {'NAME': vm_name}, None)
        base_name = vm_name[:len(vm_name) - num_sign_cnt]
        vm_name = base_name
        # Make list which contains used indexes in format ['000', '001',...]
        vm_filled_indexes_list = list((vm.NAME[len(base_name):].zfill(num_sign_cnt)) for vm in vm_list)

    while count > 0:
        new_vm_name = vm_name
        # Create indexed name
        if vm_filled_indexes_list is not None:
            next_index = generate_next_index(vm_filled_indexes_list, num_sign_cnt)
            vm_filled_indexes_list.append(next_index)
            new_vm_name += next_index
        # Update NAME value in the attributes in case there is index
        attributes_dict['NAME'] = new_vm_name
        new_vm_dict = create_vm(module, client,
                                template_id, attributes_dict, labels_list, disk_size, network_attrs_list,
                                vm_start_on_hold, vm_persistent, updateconf_dict)
        new_vm_id = new_vm_dict.get('vm_id')
        new_vm = get_vm_by_id(client, new_vm_id)
        new_vms_list.append(new_vm)
        count -= 1

    if vm_start_on_hold:
        if wait:
            for vm in new_vms_list:
                wait_for_hold(module, client, vm, wait_timeout)
    else:
        if wait:
            for vm in new_vms_list:
                wait_for_running(module, client, vm, wait_timeout)

    return True, new_vms_list, []


def create_exact_count_of_vms(module, client,
                              template_id, exact_count, attributes_dict, count_attributes_dict,
                              labels_list, count_labels_list, disk_size, network_attrs_list,
                              hard, wait, wait_timeout, vm_start_on_hold, vm_persistent, updateconf_dict):
    vm_list = get_all_vms_by_attributes(client, count_attributes_dict, count_labels_list)

    vm_count_diff = exact_count - len(vm_list)
    changed = vm_count_diff != 0

    new_vms_list = []
    instances_list = []
    tagged_instances_list = vm_list

    if module.check_mode:
        return changed, instances_list, tagged_instances_list

    if vm_count_diff > 0:
        # Add more VMs
        changed, instances_list, tagged_instances = create_count_of_vms(module, client, template_id, vm_count_diff, attributes_dict,
                                                                        labels_list, disk_size, network_attrs_list, wait, wait_timeout,
                                                                        vm_start_on_hold, vm_persistent, updateconf_dict)

        tagged_instances_list += instances_list
    elif vm_count_diff < 0:
        # Delete surplus VMs
        old_vms_list = []

        while vm_count_diff < 0:
            old_vm = vm_list.pop(0)
            old_vms_list.append(old_vm)
            terminate_vm(module, client, old_vm, hard)
            vm_count_diff += 1

        if wait:
            for vm in old_vms_list:
                wait_for_done(module, client, vm, wait_timeout)

        instances_list = old_vms_list
        # store only the remaining instances
        old_vms_set = set(old_vms_list)
        tagged_instances_list = [vm for vm in vm_list if vm not in old_vms_set]

    return changed, instances_list, tagged_instances_list


VM_STATES = ['INIT', 'PENDING', 'HOLD', 'ACTIVE', 'STOPPED', 'SUSPENDED', 'DONE', '', 'POWEROFF', 'UNDEPLOYED', 'CLONING', 'CLONING_FAILURE']
LCM_STATES = ['LCM_INIT', 'PROLOG', 'BOOT', 'RUNNING', 'MIGRATE', 'SAVE_STOP',
              'SAVE_SUSPEND', 'SAVE_MIGRATE', 'PROLOG_MIGRATE', 'PROLOG_RESUME',
              'EPILOG_STOP', 'EPILOG', 'SHUTDOWN', 'STATE13', 'STATE14', 'CLEANUP_RESUBMIT', 'UNKNOWN', 'HOTPLUG', 'SHUTDOWN_POWEROFF',
              'BOOT_UNKNOWN', 'BOOT_POWEROFF', 'BOOT_SUSPENDED', 'BOOT_STOPPED', 'CLEANUP_DELETE', 'HOTPLUG_SNAPSHOT', 'HOTPLUG_NIC',
              'HOTPLUG_SAVEAS', 'HOTPLUG_SAVEAS_POWEROFF', 'HOTPULG_SAVEAS_SUSPENDED', 'SHUTDOWN_UNDEPLOY']


def wait_for_state(module, client, vm, wait_timeout, state_predicate):
    import time
    start_time = time.time()

    while (time.time() - start_time) < wait_timeout:
        vm = client.vm.info(vm.ID)
        state = vm.STATE
        lcm_state = vm.LCM_STATE

        if state_predicate(state, lcm_state):
            return vm
        elif state not in [VM_STATES.index('INIT'), VM_STATES.index('PENDING'), VM_STATES.index('HOLD'),
                           VM_STATES.index('ACTIVE'), VM_STATES.index('CLONING'), VM_STATES.index('POWEROFF')]:
            module.fail_json(msg='Action is unsuccessful. VM state: ' + VM_STATES[state])

        time.sleep(1)

    module.fail_json(msg="Wait timeout has expired!")


def wait_for_running(module, client, vm, wait_timeout):
    return wait_for_state(module, client, vm, wait_timeout, lambda state,
                          lcm_state: (state in [VM_STATES.index('ACTIVE')] and lcm_state in [LCM_STATES.index('RUNNING')]))


def wait_for_done(module, client, vm, wait_timeout):
    return wait_for_state(module, client, vm, wait_timeout, lambda state, lcm_state: (state in [VM_STATES.index('DONE')]))


def wait_for_hold(module, client, vm, wait_timeout):
    return wait_for_state(module, client, vm, wait_timeout, lambda state, lcm_state: (state in [VM_STATES.index('HOLD')]))


def wait_for_poweroff(module, client, vm, wait_timeout):
    return wait_for_state(module, client, vm, wait_timeout, lambda state, lcm_state: (state in [VM_STATES.index('POWEROFF')]))


def terminate_vm(module, client, vm, hard=False):
    changed = False

    if not vm:
        return changed

    changed = True

    if not module.check_mode:
        if hard:
            client.vm.action('terminate-hard', vm.ID)
        else:
            client.vm.action('terminate', vm.ID)

    return changed


def terminate_vms(module, client, vms, hard):
    changed = False

    for vm in vms:
        changed = terminate_vm(module, client, vm, hard) or changed

    return changed


def poweroff_vm(module, client, vm, hard):
    vm = client.vm.info(vm.ID)
    changed = False

    lcm_state = vm.LCM_STATE
    state = vm.STATE

    if lcm_state not in [LCM_STATES.index('SHUTDOWN'), LCM_STATES.index('SHUTDOWN_POWEROFF')] and state not in [VM_STATES.index('POWEROFF')]:
        changed = True

    if changed and not module.check_mode:
        if not hard:
            client.vm.action('poweroff', vm.ID)
        else:
            client.vm.action('poweroff-hard', vm.ID)

    return changed


def poweroff_vms(module, client, vms, hard):
    changed = False

    for vm in vms:
        changed = poweroff_vm(module, client, vm, hard) or changed

    return changed


def reboot_vms(module, client, vms, wait_timeout, hard):

    if not module.check_mode:
        # Firstly, power-off all instances
        for vm in vms:
            vm = client.vm.info(vm.ID)
            lcm_state = vm.LCM_STATE
            state = vm.STATE
            if lcm_state not in [LCM_STATES.index('SHUTDOWN_POWEROFF')] and state not in [VM_STATES.index('POWEROFF')]:
                poweroff_vm(module, client, vm, hard)

        # Wait for all to be power-off
        for vm in vms:
            wait_for_poweroff(module, client, vm, wait_timeout)

        for vm in vms:
            resume_vm(module, client, vm)

    return True


def resume_vm(module, client, vm):
    vm = client.vm.info(vm.ID)
    changed = False

    state = vm.STATE
    if state in [VM_STATES.index('HOLD')]:
        changed = release_vm(module, client, vm)
        return changed

    lcm_state = vm.LCM_STATE
    if lcm_state == LCM_STATES.index('SHUTDOWN_POWEROFF'):
        module.fail_json(msg="Cannot perform action 'resume' because this action is not available " +
                         "for LCM_STATE: 'SHUTDOWN_POWEROFF'. Wait for the VM to shutdown properly")
    if lcm_state not in [LCM_STATES.index('RUNNING')]:
        changed = True

    if changed and not module.check_mode:
        client.vm.action('resume', vm.ID)

    return changed


def resume_vms(module, client, vms):
    changed = False

    for vm in vms:
        changed = resume_vm(module, client, vm) or changed

    return changed


def release_vm(module, client, vm):
    vm = client.vm.info(vm.ID)
    changed = False

    state = vm.STATE
    if state != VM_STATES.index('HOLD'):
        module.fail_json(msg="Cannot perform action 'release' because this action is not available " +
                         "because VM is not in state 'HOLD'.")
    else:
        changed = True

    if changed and not module.check_mode:
        client.vm.action('release', vm.ID)

    return changed


def check_name_attribute(module, attributes):
    if attributes.get("NAME"):
        import re
        if re.match(r'^[^#]+#*$', attributes.get("NAME")) is None:
            module.fail_json(msg="Ilegal 'NAME' attribute: '" + attributes.get("NAME") +
                             "' .Signs '#' are allowed only at the end of the name and the name cannot contain only '#'.")


TEMPLATE_RESTRICTED_ATTRIBUTES = ["CPU", "VCPU", "OS", "FEATURES", "MEMORY", "DISK", "NIC", "INPUT", "GRAPHICS",
                                  "CONTEXT", "CREATED_BY", "CPU_COST", "DISK_COST", "MEMORY_COST",
                                  "TEMPLATE_ID", "VMID", "AUTOMATIC_DS_REQUIREMENTS", "DEPLOY_FOLDER", "LABELS"]


def check_attributes(module, attributes):
    for key in attributes.keys():
        if key in TEMPLATE_RESTRICTED_ATTRIBUTES:
            module.fail_json(msg='Restricted attribute `' + key + '` cannot be used when filtering VMs.')
    # Check the format of the name attribute
    check_name_attribute(module, attributes)


def disk_save_as(module, client, vm, disk_saveas, wait_timeout):
    if not disk_saveas.get('name'):
        module.fail_json(msg="Key 'name' is required for 'disk_saveas' option")

    image_name = disk_saveas.get('name')
    disk_id = disk_saveas.get('disk_id', 0)

    if not module.check_mode:
        if vm.STATE != VM_STATES.index('POWEROFF'):
            module.fail_json(msg="'disksaveas' option can be used only when the VM is in 'POWEROFF' state")
        try:
            client.vm.disksaveas(vm.ID, disk_id, image_name, 'OS', -1)
        except pyone.OneException as e:
            module.fail_json(msg=str(e))
        wait_for_poweroff(module, client, vm, wait_timeout)  # wait for VM to leave the hotplug_saveas_poweroff state


def get_connection_info(module):

    url = module.params.get('api_url')
    username = module.params.get('api_username')
    password = module.params.get('api_password')

    if not url:
        url = os.environ.get('ONE_URL')

    if not username:
        username = os.environ.get('ONE_USERNAME')

    if not password:
        password = os.environ.get('ONE_PASSWORD')

    if not username:
        if not password:
            authfile = os.environ.get('ONE_AUTH')
            if authfile is None:
                authfile = os.path.join(os.environ.get("HOME"), ".one", "one_auth")
            try:
                with open(authfile, "r") as fp:
                    authstring = fp.read().rstrip()
                username = authstring.split(":")[0]
                password = authstring.split(":")[1]
            except (OSError, IOError):
                module.fail_json(msg=("Could not find or read ONE_AUTH file at '%s'" % authfile))
            except Exception:
                module.fail_json(msg=("Error occurs when read ONE_AUTH file at '%s'" % authfile))
    if not url:
        module.fail_json(msg="Opennebula API url (api_url) is not specified")
    from collections import namedtuple

    auth_params = namedtuple('auth', ('url', 'username', 'password'))

    return auth_params(url=url, username=username, password=password)


def main():
    fields = {
        "api_url": {"required": False, "type": "str"},
        "api_username": {"required": False, "type": "str"},
        "api_password": {"required": False, "type": "str", "no_log": True},
        "instance_ids": {"required": False, "aliases": ['ids'], "type": "list", "elements": "int"},
        "template_name": {"required": False, "type": "str"},
        "template_id": {"required": False, "type": "int"},
        "vm_start_on_hold": {"default": False, "type": "bool"},
        "state": {
            "default": "present",
            "choices": ['present', 'absent', 'rebooted', 'poweredoff', 'running'],
            "type": "str"
        },
        "mode": {"required": False, "type": "str"},
        "owner_id": {"required": False, "type": "int"},
        "group_id": {"required": False, "type": "int"},
        "wait": {"default": True, "type": "bool"},
        "wait_timeout": {"default": 300, "type": "int"},
        "hard": {"default": False, "type": "bool"},
        "memory": {"required": False, "type": "str"},
        "cpu": {"required": False, "type": "float"},
        "vcpu": {"required": False, "type": "int"},
        "disk_size": {"required": False, "type": "list", "elements": "str"},
        "datastore_name": {"required": False, "type": "str"},
        "datastore_id": {"required": False, "type": "int"},
        "networks": {"default": [], "type": "list", "elements": "dict"},
        "count": {"default": 1, "type": "int"},
        "exact_count": {"required": False, "type": "int"},
        "attributes": {"default": {}, "type": "dict"},
        "count_attributes": {"required": False, "type": "dict"},
        "labels": {"default": [], "type": "list", "elements": "str"},
        "count_labels": {"required": False, "type": "list", "elements": "str"},
        "disk_saveas": {"type": "dict"},
        "persistent": {"default": False, "type": "bool"},
        "updateconf": {"type": "dict"},
    }

    module = AnsibleModule(argument_spec=fields,
                           mutually_exclusive=[
                               ['template_id', 'template_name', 'instance_ids'],
                               ['template_id', 'template_name', 'disk_saveas'],
                               ['instance_ids', 'count_attributes', 'count'],
                               ['instance_ids', 'count_labels', 'count'],
                               ['instance_ids', 'exact_count'],
                               ['instance_ids', 'attributes'],
                               ['instance_ids', 'labels'],
                               ['disk_saveas', 'attributes'],
                               ['disk_saveas', 'labels'],
                               ['exact_count', 'count'],
                               ['count', 'hard'],
                               ['instance_ids', 'cpu'], ['instance_ids', 'vcpu'],
                               ['instance_ids', 'memory'], ['instance_ids', 'disk_size'],
                               ['instance_ids', 'networks'],
                               ['persistent', 'disk_size']
                           ],
                           supports_check_mode=True)

    if not HAS_PYONE:
        module.fail_json(msg='This module requires pyone to work!')

    auth = get_connection_info(module)
    params = module.params
    instance_ids = params.get('instance_ids')
    requested_template_name = params.get('template_name')
    requested_template_id = params.get('template_id')
    put_vm_on_hold = params.get('vm_start_on_hold')
    state = params.get('state')
    permissions = params.get('mode')
    owner_id = params.get('owner_id')
    group_id = params.get('group_id')
    wait = params.get('wait')
    wait_timeout = params.get('wait_timeout')
    hard = params.get('hard')
    memory = params.get('memory')
    cpu = params.get('cpu')
    vcpu = params.get('vcpu')
    disk_size = params.get('disk_size')
    requested_datastore_id = params.get('datastore_id')
    requested_datastore_name = params.get('datastore_name')
    networks = params.get('networks')
    count = params.get('count')
    exact_count = params.get('exact_count')
    attributes = params.get('attributes')
    count_attributes = params.get('count_attributes')
    labels = params.get('labels')
    count_labels = params.get('count_labels')
    disk_saveas = params.get('disk_saveas')
    persistent = params.get('persistent')
    updateconf = params.get('updateconf')

    if not (auth.username and auth.password):
        module.warn("Credentials missing")
    else:
        one_client = pyone.OneServer(auth.url, session=auth.username + ':' + auth.password)

    if attributes:
        attributes = dict((key.upper(), value) for key, value in attributes.items())
        check_attributes(module, attributes)

    if count_attributes:
        count_attributes = dict((key.upper(), value) for key, value in count_attributes.items())
        if not attributes:
            import copy
            module.warn('When you pass `count_attributes` without `attributes` option when deploying, `attributes` option will have same values implicitly.')
            attributes = copy.copy(count_attributes)
        check_attributes(module, count_attributes)

    if updateconf:
        check_updateconf(module, updateconf)

    if count_labels and not labels:
        module.warn('When you pass `count_labels` without `labels` option when deploying, `labels` option will have same values implicitly.')
        labels = count_labels

    # Fetch template
    template_id = None
    if requested_template_id is not None or requested_template_name:
        template_id = get_template_id(module, one_client, requested_template_id, requested_template_name)
        if template_id is None:
            if requested_template_id is not None:
                module.fail_json(msg='There is no template with template_id: ' + str(requested_template_id))
            elif requested_template_name:
                module.fail_json(msg="There is no template with name: " + requested_template_name)

    # Fetch datastore
    datastore_id = None
    if requested_datastore_id or requested_datastore_name:
        datastore_id = get_datastore_id(module, one_client, requested_datastore_id, requested_datastore_name)
        if datastore_id is None:
            if requested_datastore_id:
                module.fail_json(msg='There is no datastore with datastore_id: ' + str(requested_datastore_id))
            elif requested_datastore_name:
                module.fail_json(msg="There is no datastore with name: " + requested_datastore_name)
        else:
            attributes['SCHED_DS_REQUIREMENTS'] = 'ID=' + str(datastore_id)

    if exact_count and template_id is None:
        module.fail_json(msg='Option `exact_count` needs template_id or template_name')

    if exact_count is not None and not (count_attributes or count_labels):
        module.fail_json(msg='Either `count_attributes` or `count_labels` has to be specified with option `exact_count`.')
    if (count_attributes or count_labels) and exact_count is None:
        module.fail_json(msg='Option `exact_count` has to be specified when either `count_attributes` or `count_labels` is used.')
    if template_id is not None and state != 'present':
        module.fail_json(msg="Only state 'present' is valid for the template")

    if memory:
        attributes['MEMORY'] = str(int(get_size_in_MB(module, memory)))
    if cpu:
        attributes['CPU'] = str(cpu)
    if vcpu:
        attributes['VCPU'] = str(vcpu)

    if exact_count is not None and state != 'present':
        module.fail_json(msg='The `exact_count` option is valid only for the `present` state')
    if exact_count is not None and exact_count < 0:
        module.fail_json(msg='`exact_count` cannot be less than 0')
    if count <= 0:
        module.fail_json(msg='`count` has to be greater than 0')

    if permissions is not None:
        import re
        if re.match("^[0-7]{3}$", permissions) is None:
            module.fail_json(msg="Option `mode` has to have exactly 3 digits and be in the octet format e.g. 600")

    if exact_count is not None:
        # Deploy an exact count of VMs
        changed, instances_list, tagged_instances_list = create_exact_count_of_vms(module, one_client, template_id, exact_count, attributes,
                                                                                   count_attributes, labels, count_labels, disk_size,
                                                                                   networks, hard, wait, wait_timeout, put_vm_on_hold, persistent, updateconf)
        vms = tagged_instances_list
    elif template_id is not None and state == 'present':
        # Deploy count VMs
        changed, instances_list, tagged_instances_list = create_count_of_vms(module, one_client, template_id, count,
                                                                             attributes, labels, disk_size, networks, wait, wait_timeout,
                                                                             put_vm_on_hold, persistent, updateconf)
        # instances_list - new instances
        # tagged_instances_list - all instances with specified `count_attributes` and `count_labels`
        vms = instances_list
    else:
        # Fetch data of instances, or change their state
        if not (instance_ids or attributes or labels):
            module.fail_json(msg="At least one of `instance_ids`,`attributes`,`labels` must be passed!")

        if memory or cpu or vcpu or disk_size or networks:
            module.fail_json(msg="Parameters as `memory`, `cpu`, `vcpu`, `disk_size` and `networks` you can only set when deploying a VM!")

        if hard and state not in ['rebooted', 'poweredoff', 'absent', 'present']:
            module.fail_json(msg="The 'hard' option can be used only for one of these states: 'rebooted', 'poweredoff', 'absent' and 'present'")

        vms = []
        tagged = False
        changed = False

        if instance_ids:
            vms = get_vms_by_ids(module, one_client, state, instance_ids)
        else:
            tagged = True
            vms = get_all_vms_by_attributes(one_client, attributes, labels)

        if len(vms) == 0 and state != 'absent' and state != 'present':
            module.fail_json(msg='There are no instances with specified `instance_ids`, `attributes` and/or `labels`')

        if len(vms) == 0 and state == 'present' and not tagged:
            module.fail_json(msg='There are no instances with specified `instance_ids`.')

        if tagged and state == 'absent':
            module.fail_json(msg='Option `instance_ids` is required when state is `absent`.')

        if state == 'absent':
            changed = terminate_vms(module, one_client, vms, hard)
        elif state == 'rebooted':
            changed = reboot_vms(module, one_client, vms, wait_timeout, hard)
        elif state == 'poweredoff':
            changed = poweroff_vms(module, one_client, vms, hard)
        elif state == 'running':
            changed = resume_vms(module, one_client, vms)

        instances_list = vms
        tagged_instances_list = []

    if permissions is not None:
        changed = set_vm_permissions(module, one_client, vms, permissions) or changed

    if owner_id is not None or group_id is not None:
        changed = set_vm_ownership(module, one_client, vms, owner_id, group_id) or changed

    if template_id is None and updateconf is not None:
        changed = update_vms(module, one_client, vms, updateconf) or changed

    if wait and not module.check_mode and state != 'present':
        wait_for = {
            'absent': wait_for_done,
            'rebooted': wait_for_running,
            'poweredoff': wait_for_poweroff,
            'running': wait_for_running
        }
        for vm in vms:
            if vm is not None:
                wait_for[state](module, one_client, vm, wait_timeout)

    if disk_saveas is not None:
        if len(vms) == 0:
            module.fail_json(msg="There is no VM whose disk will be saved.")
        disk_save_as(module, one_client, vms[0], disk_saveas, wait_timeout)
        changed = True

    # instances - a list of instances info whose state is changed or which are fetched with C(instance_ids) option
    instances = list(get_vm_info(one_client, vm) for vm in instances_list if vm is not None)
    instances_ids = list(vm.ID for vm in instances_list if vm is not None)
    # tagged_instances - A list of instances info based on a specific attributes and/or labels that are specified with C(count_attributes) and C(count_labels)
    tagged_instances = list(get_vm_info(one_client, vm) for vm in tagged_instances_list if vm is not None)

    result = {'changed': changed, 'instances': instances, 'instances_ids': instances_ids, 'tagged_instances': tagged_instances}

    module.exit_json(**result)


if __name__ == '__main__':
    main()

Filemanager

Name Type Size Permission Actions
__pycache__ Folder 0755
aerospike_migrations.py File 18.75 KB 0644
airbrake_deployment.py File 4.8 KB 0644
aix_devices.py File 9.89 KB 0644
aix_filesystem.py File 17.48 KB 0644
aix_inittab.py File 7.33 KB 0644
aix_lvg.py File 11 KB 0644
aix_lvol.py File 10.54 KB 0644
alerta_customer.py File 6.61 KB 0644
ali_instance.py File 39.51 KB 0644
ali_instance_info.py File 13.79 KB 0644
alternatives.py File 14.23 KB 0644
ansible_galaxy_install.py File 15.21 KB 0644
apache2_mod_proxy.py File 16.85 KB 0644
apache2_module.py File 8.95 KB 0644
apk.py File 12.07 KB 0644
apt_repo.py File 3.71 KB 0644
apt_rpm.py File 7.75 KB 0644
archive.py File 22.65 KB 0644
atomic_container.py File 6.69 KB 0644
atomic_host.py File 2.8 KB 0644
atomic_image.py File 5.3 KB 0644
awall.py File 4.61 KB 0644
beadm.py File 11.87 KB 0644
bearychat.py File 5.36 KB 0644
bigpanda.py File 6.32 KB 0644
bitbucket_access_key.py File 8.75 KB 0644
bitbucket_pipeline_key_pair.py File 5.95 KB 0644
bitbucket_pipeline_known_host.py File 8.8 KB 0644
bitbucket_pipeline_variable.py File 8.6 KB 0644
bower.py File 6.78 KB 0644
btrfs_info.py File 3.08 KB 0644
btrfs_subvolume.py File 28.14 KB 0644
bundler.py File 6.98 KB 0644
bzr.py File 6.02 KB 0644
campfire.py File 5.15 KB 0644
capabilities.py File 6.8 KB 0644
cargo.py File 5.9 KB 0644
catapult.py File 4.35 KB 0644
circonus_annotation.py File 7.46 KB 0644
cisco_webex.py File 5.58 KB 0644
clc_aa_policy.py File 10.52 KB 0644
clc_alert_policy.py File 17.39 KB 0644
clc_blueprint_package.py File 10.25 KB 0644
clc_firewall_policy.py File 21.16 KB 0644
clc_group.py File 16.72 KB 0644
clc_loadbalancer.py File 34.43 KB 0644
clc_modify_server.py File 34.27 KB 0644
clc_publicip.py File 12.15 KB 0644
clc_server.py File 55.34 KB 0644
clc_server_snapshot.py File 14.16 KB 0644
cloud_init_data_facts.py File 3.45 KB 0644
cloudflare_dns.py File 34.21 KB 0644
cobbler_sync.py File 4.38 KB 0644
cobbler_system.py File 10.74 KB 0644
composer.py File 9.25 KB 0644
consul.py File 21.73 KB 0644
consul_acl.py File 21.9 KB 0644
consul_kv.py File 11.4 KB 0644
consul_session.py File 9.69 KB 0644
copr.py File 16.71 KB 0644
cpanm.py File 8.59 KB 0644
cronvar.py File 13.65 KB 0644
crypttab.py File 10.98 KB 0644
datadog_downtime.py File 10.48 KB 0644
datadog_event.py File 5.77 KB 0644
datadog_monitor.py File 15.77 KB 0644
dconf.py File 18.53 KB 0644
deploy_helper.py File 19.5 KB 0644
dimensiondata_network.py File 9.03 KB 0644
dimensiondata_vlan.py File 18.51 KB 0644
discord.py File 6.7 KB 0644
django_manage.py File 15.82 KB 0644
dnf_versionlock.py File 12.25 KB 0644
dnsimple.py File 16.26 KB 0644
dnsimple_info.py File 9.35 KB 0644
dnsmadeeasy.py File 23.71 KB 0644
dpkg_divert.py File 13.43 KB 0644
easy_install.py File 6.63 KB 0644
ejabberd_user.py File 5.88 KB 0644
elasticsearch_plugin.py File 9.72 KB 0644
emc_vnx_sg_member.py File 5.12 KB 0644
etcd3.py File 8.56 KB 0644
facter.py File 1.88 KB 0644
filesize.py File 16.85 KB 0644
filesystem.py File 21 KB 0644
flatpak.py File 12.16 KB 0644
flatpak_remote.py File 9.08 KB 0644
flowdock.py File 5.84 KB 0644
gandi_livedns.py File 5.05 KB 0644
gconftool2.py File 5.41 KB 0644
gconftool2_info.py File 2.2 KB 0644
gem.py File 10.22 KB 0644
git_config.py File 8.63 KB 0644
github_deploy_key.py File 11.91 KB 0644
github_issue.py File 3.1 KB 0644
github_key.py File 7.49 KB 0644
github_release.py File 6.16 KB 0644
github_repo.py File 8.57 KB 0644
github_webhook.py File 8.75 KB 0644
github_webhook_info.py File 5.27 KB 0644
gitlab_branch.py File 5.46 KB 0644
gitlab_deploy_key.py File 9.41 KB 0644
gitlab_group.py File 13.13 KB 0644
gitlab_group_members.py File 18.54 KB 0644
gitlab_group_variable.py File 15.39 KB 0644
gitlab_hook.py File 12.31 KB 0644
gitlab_project.py File 26.07 KB 0644
gitlab_project_badge.py File 5.99 KB 0644
gitlab_project_members.py File 18.81 KB 0644
gitlab_project_variable.py File 16.48 KB 0644
gitlab_protected_branch.py File 6.92 KB 0644
gitlab_runner.py File 16.47 KB 0644
gitlab_user.py File 22.36 KB 0644
grove.py File 3.37 KB 0644
gunicorn.py File 6.73 KB 0644
hana_query.py File 7 KB 0644
haproxy.py File 17.2 KB 0644
heroku_collaborator.py File 4.21 KB 0644
hg.py File 9.77 KB 0644
hipchat.py File 6.28 KB 0644
homebrew.py File 30.28 KB 0644
homebrew_cask.py File 27.09 KB 0644
homebrew_tap.py File 7.59 KB 0644
homectl.py File 25.17 KB 0644
honeybadger_deployment.py File 3.76 KB 0644
hpilo_boot.py File 6.77 KB 0644
hpilo_info.py File 8.43 KB 0644
hponcfg.py File 3.1 KB 0644
htpasswd.py File 9.23 KB 0644
hwc_ecs_instance.py File 58.07 KB 0644
hwc_evs_disk.py File 34.9 KB 0644
hwc_network_vpc.py File 13.83 KB 0644
hwc_smn_topic.py File 9.79 KB 0644
hwc_vpc_eip.py File 26.16 KB 0644
hwc_vpc_peering_connect.py File 17.58 KB 0644
hwc_vpc_port.py File 30.1 KB 0644
hwc_vpc_private_ip.py File 9.57 KB 0644
hwc_vpc_route.py File 11.57 KB 0644
hwc_vpc_security_group.py File 18.89 KB 0644
hwc_vpc_security_group_rule.py File 17.45 KB 0644
hwc_vpc_subnet.py File 20.28 KB 0644
ibm_sa_domain.py File 4.35 KB 0644
ibm_sa_host.py File 3.38 KB 0644
ibm_sa_host_ports.py File 3.64 KB 0644
ibm_sa_pool.py File 3.06 KB 0644
ibm_sa_vol.py File 2.79 KB 0644
ibm_sa_vol_map.py File 3.71 KB 0644
icinga2_feature.py File 4.32 KB 0644
icinga2_host.py File 10.07 KB 0644
idrac_redfish_command.py File 7.79 KB 0644
idrac_redfish_config.py File 10.92 KB 0644
idrac_redfish_info.py File 7.95 KB 0644
ilo_redfish_command.py File 5.17 KB 0644
ilo_redfish_config.py File 5.46 KB 0644
ilo_redfish_info.py File 5.85 KB 0644
imc_rest.py File 15.01 KB 0644
imgadm.py File 9.8 KB 0644
infinity.py File 21.86 KB 0644
influxdb_database.py File 3.84 KB 0644
influxdb_query.py File 2.73 KB 0644
influxdb_retention_policy.py File 11.77 KB 0644
influxdb_user.py File 9.03 KB 0644
influxdb_write.py File 2.55 KB 0644
ini_file.py File 18.01 KB 0644
installp.py File 9.18 KB 0644
interfaces_file.py File 14.75 KB 0644
ip_netns.py File 3.49 KB 0644
ipa_config.py File 12.92 KB 0644
ipa_dnsrecord.py File 12.58 KB 0644
ipa_dnszone.py File 5.83 KB 0644
ipa_group.py File 11.41 KB 0644
ipa_hbacrule.py File 13.54 KB 0644
ipa_host.py File 10.51 KB 0644
ipa_hostgroup.py File 7.69 KB 0644
ipa_otpconfig.py File 5.69 KB 0644
ipa_otptoken.py File 22.64 KB 0644
ipa_pwpolicy.py File 8.83 KB 0644
ipa_role.py File 10.72 KB 0644
ipa_service.py File 7.15 KB 0644
ipa_subca.py File 7.54 KB 0644
ipa_sudocmd.py File 4.65 KB 0644
ipa_sudocmdgroup.py File 6.13 KB 0644
ipa_sudorule.py File 18.58 KB 0644
ipa_user.py File 13.82 KB 0644
ipa_vault.py File 7.93 KB 0644
ipify_facts.py File 2.91 KB 0644
ipinfoio_facts.py File 3.61 KB 0644
ipmi_boot.py File 6.45 KB 0644
ipmi_power.py File 8.27 KB 0644
iptables_state.py File 21.49 KB 0644
ipwcli_dns.py File 10.97 KB 0644
irc.py File 9.31 KB 0644
iso_create.py File 10.63 KB 0644
iso_customize.py File 11.19 KB 0644
iso_extract.py File 6.48 KB 0644
jabber.py File 4.56 KB 0644
java_cert.py File 19.97 KB 0644
java_keystore.py File 21.66 KB 0644
jboss.py File 5.84 KB 0644
jenkins_build.py File 9.01 KB 0644
jenkins_job.py File 11.73 KB 0644
jenkins_job_info.py File 7.49 KB 0644
jenkins_plugin.py File 27.48 KB 0644
jenkins_script.py File 6.6 KB 0644
jira.py File 26.18 KB 0644
kdeconfig.py File 8.16 KB 0644
kernel_blacklist.py File 4.04 KB 0644
keycloak_authentication.py File 19.1 KB 0644
keycloak_authz_authorization_scope.py File 9.72 KB 0644
keycloak_client.py File 36.33 KB 0644
keycloak_client_rolemapping.py File 12.5 KB 0644
keycloak_clientscope.py File 18.03 KB 0644
keycloak_clientscope_type.py File 8.93 KB 0644
keycloak_clientsecret_info.py File 4.47 KB 0644
keycloak_clientsecret_regenerate.py File 4.78 KB 0644
keycloak_clienttemplate.py File 16.01 KB 0644
keycloak_group.py File 16.42 KB 0644
keycloak_identity_provider.py File 22.37 KB 0644
keycloak_realm.py File 27.68 KB 0644
keycloak_realm_info.py File 3.82 KB 0644
keycloak_role.py File 11.54 KB 0644
keycloak_user_federation.py File 38.33 KB 0644
keycloak_user_rolemapping.py File 14.9 KB 0644
keyring.py File 8.28 KB 0644
keyring_info.py File 4.1 KB 0644
kibana_plugin.py File 7.94 KB 0644
launchd.py File 17.04 KB 0644
layman.py File 7.67 KB 0644
lbu.py File 2.88 KB 0644
ldap_attrs.py File 10.93 KB 0644
ldap_entry.py File 8.73 KB 0644
ldap_passwd.py File 3.95 KB 0644
ldap_search.py File 5.42 KB 0644
librato_annotation.py File 5.65 KB 0644
linode.py File 24.74 KB 0644
linode_v4.py File 9.45 KB 0644
listen_ports_facts.py File 14.46 KB 0644
lldp.py File 2.54 KB 0644
locale_gen.py File 7.23 KB 0644
logentries.py File 4.44 KB 0644
logentries_msg.py File 2.34 KB 0644
logstash_plugin.py File 4.82 KB 0644
lvg.py File 12.66 KB 0644
lvol.py File 21.61 KB 0644
lxc_container.py File 54.26 KB 0644
lxca_cmms.py File 4.56 KB 0644
lxca_nodes.py File 5.57 KB 0644
lxd_container.py File 30.1 KB 0644
lxd_profile.py File 17.68 KB 0644
lxd_project.py File 14.49 KB 0644
macports.py File 9.77 KB 0644
mail.py File 14.63 KB 0644
make.py File 6.44 KB 0644
manageiq_alert_profiles.py File 11.22 KB 0644
manageiq_alerts.py File 12.87 KB 0644
manageiq_group.py File 22.44 KB 0644
manageiq_policies.py File 6.58 KB 0644
manageiq_policies_info.py File 3.87 KB 0644
manageiq_provider.py File 35.9 KB 0644
manageiq_tags.py File 5.49 KB 0644
manageiq_tags_info.py File 3.41 KB 0644
manageiq_tenant.py File 17.7 KB 0644
manageiq_user.py File 9.6 KB 0644
mas.py File 8.77 KB 0644
matrix.py File 4 KB 0644
mattermost.py File 5.77 KB 0644
maven_artifact.py File 31.46 KB 0644
memset_dns_reload.py File 5.95 KB 0644
memset_memstore_info.py File 5.01 KB 0644
memset_server_info.py File 8.51 KB 0644
memset_zone.py File 10.9 KB 0644
memset_zone_domain.py File 9.23 KB 0644
memset_zone_record.py File 13.82 KB 0644
mksysb.py File 4.93 KB 0644
modprobe.py File 10.7 KB 0644
monit.py File 11.61 KB 0644
mqtt.py File 7.82 KB 0644
mssql_db.py File 7.14 KB 0644
mssql_script.py File 10.34 KB 0644
nagios.py File 41.18 KB 0644
netcup_dns.py File 8.16 KB 0644
newrelic_deployment.py File 5.7 KB 0644
nexmo.py File 3.65 KB 0644
nginx_status_info.py File 4.6 KB 0644
nictagadm.py File 5.97 KB 0644
nmcli.py File 103.39 KB 0644
nomad_job.py File 8.35 KB 0644
nomad_job_info.py File 12.15 KB 0644
nosh.py File 17.21 KB 0644
npm.py File 10.47 KB 0644
nsupdate.py File 19.44 KB 0644
ocapi_command.py File 8.68 KB 0644
ocapi_info.py File 6.5 KB 0644
oci_vcn.py File 7.99 KB 0644
odbc.py File 5.2 KB 0644
office_365_connector_card.py File 9.69 KB 0644
ohai.py File 1.38 KB 0644
omapi_host.py File 11.68 KB 0644
one_host.py File 9.92 KB 0644
one_image.py File 11.22 KB 0644
one_image_info.py File 7.71 KB 0644
one_service.py File 25.03 KB 0644
one_template.py File 7.79 KB 0644
one_vm.py File 59.44 KB 0644
oneandone_firewall_policy.py File 18.35 KB 0644
oneandone_load_balancer.py File 22.49 KB 0644
oneandone_monitoring_policy.py File 33.48 KB 0644
oneandone_private_network.py File 14.33 KB 0644
oneandone_public_ip.py File 9.74 KB 0644
oneandone_server.py File 22.31 KB 0644
onepassword_info.py File 16.47 KB 0644
oneview_datacenter_info.py File 4.82 KB 0644
oneview_enclosure_info.py File 7.85 KB 0644
oneview_ethernet_network.py File 8.95 KB 0644
oneview_ethernet_network_info.py File 5.95 KB 0644
oneview_fc_network.py File 4.03 KB 0644
oneview_fc_network_info.py File 3.55 KB 0644
oneview_fcoe_network.py File 3.83 KB 0644
oneview_fcoe_network_info.py File 3.47 KB 0644
oneview_logical_interconnect_group.py File 5.99 KB 0644
oneview_logical_interconnect_group_info.py File 4.01 KB 0644
oneview_network_set.py File 5.25 KB 0644
oneview_network_set_info.py File 5.14 KB 0644
oneview_san_manager.py File 7.77 KB 0644
oneview_san_manager_info.py File 4.17 KB 0644
online_server_info.py File 5.08 KB 0644
online_user_info.py File 1.88 KB 0644
open_iscsi.py File 14.72 KB 0644
openbsd_pkg.py File 26.47 KB 0644
opendj_backendprop.py File 6.99 KB 0644
openwrt_init.py File 5.92 KB 0644
opkg.py File 6.9 KB 0644
osx_defaults.py File 14.2 KB 0644
ovh_ip_failover.py File 8.7 KB 0644
ovh_ip_loadbalancing_backend.py File 11.29 KB 0644
ovh_monthly_billing.py File 5.03 KB 0644
pacemaker_cluster.py File 6.99 KB 0644
packet_device.py File 21.72 KB 0644
packet_ip_subnet.py File 10.73 KB 0644
packet_project.py File 7.07 KB 0644
packet_sshkey.py File 8.76 KB 0644
packet_volume.py File 9.13 KB 0644
packet_volume_attachment.py File 9.01 KB 0644
pacman.py File 31.36 KB 0644
pacman_key.py File 10.91 KB 0644
pagerduty.py File 8.89 KB 0644
pagerduty_alert.py File 8.91 KB 0644
pagerduty_change.py File 6.14 KB 0644
pagerduty_user.py File 9.15 KB 0644
pam_limits.py File 10.85 KB 0644
pamd.py File 30.43 KB 0644
parted.py File 25.85 KB 0644
pear.py File 11.32 KB 0644
pids.py File 6.7 KB 0644
pingdom.py File 3.88 KB 0644
pip_package_info.py File 4.3 KB 0644
pipx.py File 12.34 KB 0644
pipx_info.py File 6.58 KB 0644
pkg5.py File 5.2 KB 0644
pkg5_publisher.py File 5.47 KB 0644
pkgin.py File 11.7 KB 0644
pkgng.py File 18.61 KB 0644
pkgutil.py File 8.98 KB 0644
pmem.py File 21.09 KB 0644
portage.py File 16.14 KB 0644
portinstall.py File 6.74 KB 0644
pritunl_org.py File 5.52 KB 0644
pritunl_org_info.py File 3.6 KB 0644
pritunl_user.py File 10.08 KB 0644
pritunl_user_info.py File 4.65 KB 0644
profitbricks.py File 21.55 KB 0644
profitbricks_datacenter.py File 7.57 KB 0644
profitbricks_nic.py File 8.26 KB 0644
profitbricks_volume.py File 13.07 KB 0644
profitbricks_volume_attachments.py File 7.76 KB 0644
proxmox.py File 32.89 KB 0644
proxmox_disk.py File 27.7 KB 0644
proxmox_domain_info.py File 3.56 KB 0644
proxmox_group_info.py File 3.94 KB 0644
proxmox_kvm.py File 58.01 KB 0644
proxmox_nic.py File 10.28 KB 0644
proxmox_snap.py File 13.66 KB 0644
proxmox_storage_info.py File 5.61 KB 0644
proxmox_tasks_info.py File 5.1 KB 0644
proxmox_template.py File 8.66 KB 0644
proxmox_user_info.py File 7.99 KB 0644
pubnub_blocks.py File 23.72 KB 0644
pulp_repo.py File 25.61 KB 0644
puppet.py File 8.55 KB 0644
pushbullet.py File 5.82 KB 0644
pushover.py File 4.57 KB 0644
python_requirements_info.py File 6.21 KB 0644
rax.py File 32.63 KB 0644
rax_cbs.py File 7.03 KB 0644
rax_cbs_attachments.py File 7.05 KB 0644
rax_cdb.py File 7.99 KB 0644
rax_cdb_database.py File 4.8 KB 0644
rax_cdb_user.py File 6.31 KB 0644
rax_clb.py File 9.61 KB 0644
rax_clb_nodes.py File 8.63 KB 0644
rax_clb_ssl.py File 9.9 KB 0644
rax_dns.py File 5.25 KB 0644
rax_dns_record.py File 11.75 KB 0644
rax_facts.py File 4.52 KB 0644
rax_files.py File 12.19 KB 0644
rax_files_objects.py File 17.24 KB 0644
rax_identity.py File 3 KB 0644
rax_keypair.py File 5.14 KB 0644
rax_meta.py File 5.06 KB 0644
rax_mon_alarm.py File 7.66 KB 0644
rax_mon_check.py File 11.26 KB 0644
rax_mon_entity.py File 6.12 KB 0644
rax_mon_notification.py File 5.21 KB 0644
rax_mon_notification_plan.py File 6.09 KB 0644
rax_network.py File 3.74 KB 0644
rax_queue.py File 3.49 KB 0644
rax_scaling_group.py File 14.15 KB 0644
rax_scaling_policy.py File 8.91 KB 0644
read_csv.py File 6.36 KB 0644
redfish_command.py File 30.56 KB 0644
redfish_config.py File 13.2 KB 0644
redfish_info.py File 19.79 KB 0644
redhat_subscription.py File 47.28 KB 0644
redis.py File 10.67 KB 0644
redis_data.py File 7.41 KB 0644
redis_data_incr.py File 5.98 KB 0644
redis_data_info.py File 2.87 KB 0644
redis_info.py File 7.3 KB 0644
rhevm.py File 49.79 KB 0644
rhn_channel.py File 6.45 KB 0644
rhn_register.py File 15.37 KB 0644
rhsm_release.py File 4.1 KB 0644
rhsm_repository.py File 9.19 KB 0644
riak.py File 7.26 KB 0644
rocketchat.py File 7.85 KB 0644
rollbar_deployment.py File 4.1 KB 0644
rpm_ostree_pkg.py File 4.48 KB 0644
rundeck_acl_policy.py File 7.45 KB 0644
rundeck_job_executions_info.py File 5.52 KB 0644
rundeck_job_run.py File 10.55 KB 0644
rundeck_project.py File 5.46 KB 0644
runit.py File 7.88 KB 0644
sap_task_list_execute.py File 11.85 KB 0644
sapcar_extract.py File 7.38 KB 0644
say.py File 2.48 KB 0644
scaleway_compute.py File 23.75 KB 0644
scaleway_compute_private_network.py File 5.95 KB 0644
scaleway_container.py File 12.53 KB 0644
scaleway_container_info.py File 4.25 KB 0644
scaleway_container_namespace.py File 9.25 KB 0644
scaleway_container_namespace_info.py File 4.14 KB 0644
scaleway_container_registry.py File 8.03 KB 0644
scaleway_container_registry_info.py File 4.03 KB 0644
scaleway_database_backup.py File 11.92 KB 0644
scaleway_function.py File 11.85 KB 0644
scaleway_function_info.py File 4.16 KB 0644
scaleway_function_namespace.py File 9.21 KB 0644
scaleway_function_namespace_info.py File 4.11 KB 0644
scaleway_image_info.py File 3.79 KB 0644
scaleway_ip.py File 7.17 KB 0644
scaleway_ip_info.py File 2.8 KB 0644
scaleway_lb.py File 10.42 KB 0644
scaleway_organization_info.py File 3.02 KB 0644
scaleway_private_network.py File 6.74 KB 0644
scaleway_security_group.py File 7.27 KB 0644
scaleway_security_group_info.py File 3.08 KB 0644
scaleway_security_group_rule.py File 7.77 KB 0644
scaleway_server_info.py File 6.75 KB 0644
scaleway_snapshot_info.py File 3.16 KB 0644
scaleway_sshkey.py File 4.86 KB 0644
scaleway_user_data.py File 5.17 KB 0644
scaleway_volume.py File 5.14 KB 0644
scaleway_volume_info.py File 2.96 KB 0644
sefcontext.py File 13.65 KB 0644
selinux_permissive.py File 4.13 KB 0644
selogin.py File 7.24 KB 0644
sendgrid.py File 9.14 KB 0644
sensu_check.py File 12.81 KB 0644
sensu_client.py File 8.96 KB 0644
sensu_handler.py File 9.12 KB 0644
sensu_silence.py File 8.55 KB 0644
sensu_subscription.py File 4.92 KB 0644
seport.py File 8.93 KB 0644
serverless.py File 6.85 KB 0644
shutdown.py File 2.25 KB 0644
sl_vm.py File 12.47 KB 0644
slack.py File 19.4 KB 0644
slackpkg.py File 6.36 KB 0644
smartos_image_info.py File 3.45 KB 0644
snap.py File 13.94 KB 0644
snap_alias.py File 5.61 KB 0644
snmp_facts.py File 15.6 KB 0644
solaris_zone.py File 16.76 KB 0644
sorcery.py File 20.13 KB 0644
spectrum_device.py File 10.58 KB 0644
spectrum_model_attrs.py File 20.53 KB 0644
spotinst_aws_elastigroup.py File 49.74 KB 0644
ss_3par_cpg.py File 9.22 KB 0644
ssh_config.py File 11.22 KB 0644
stackdriver.py File 6.68 KB 0644
stacki_host.py File 10.32 KB 0644
statsd.py File 4.89 KB 0644
statusio_maintenance.py File 16.93 KB 0644
sudoers.py File 8.21 KB 0644
supervisorctl.py File 9.26 KB 0644
svc.py File 9.21 KB 0644
svr4pkg.py File 7.71 KB 0644
swdepot.py File 6.04 KB 0644
swupd.py File 8.82 KB 0644
syslogger.py File 5.62 KB 0644
syspatch.py File 4.1 KB 0644
sysrc.py File 7.22 KB 0644
sysupgrade.py File 4.25 KB 0644
taiga_issue.py File 11.1 KB 0644
telegram.py File 4.17 KB 0644
terraform.py File 25.6 KB 0644
timezone.py File 36.39 KB 0644
twilio.py File 5.86 KB 0644
typetalk.py File 3.41 KB 0644
udm_dns_record.py File 7.01 KB 0644
udm_dns_zone.py File 7.03 KB 0644
udm_group.py File 5.04 KB 0644
udm_share.py File 18.8 KB 0644
udm_user.py File 18.57 KB 0644
ufw.py File 22.58 KB 0644
uptimerobot.py File 3.85 KB 0644
urpmi.py File 6.32 KB 0644
utm_aaa_group.py File 7.3 KB 0644
utm_aaa_group_info.py File 3.58 KB 0644
utm_ca_host_key_cert.py File 4.62 KB 0644
utm_ca_host_key_cert_info.py File 2.99 KB 0644
utm_dns_host.py File 4.86 KB 0644
utm_network_interface_address.py File 3.9 KB 0644
utm_network_interface_address_info.py File 2.81 KB 0644
utm_proxy_auth_profile.py File 12.12 KB 0644
utm_proxy_exception.py File 7.56 KB 0644
utm_proxy_frontend.py File 9.02 KB 0644
utm_proxy_frontend_info.py File 4.33 KB 0644
utm_proxy_location.py File 6.69 KB 0644
utm_proxy_location_info.py File 3.66 KB 0644
vdo.py File 31.63 KB 0644
vertica_configuration.py File 6.42 KB 0644
vertica_info.py File 9.15 KB 0644
vertica_role.py File 8.03 KB 0644
vertica_schema.py File 11.41 KB 0644
vertica_user.py File 14.03 KB 0644
vexata_eg.py File 5.77 KB 0644
vexata_volume.py File 5.06 KB 0644
vmadm.py File 24.5 KB 0644
wakeonlan.py File 3.72 KB 0644
wdc_redfish_command.py File 10.37 KB 0644
wdc_redfish_info.py File 6.29 KB 0644
webfaction_app.py File 5.92 KB 0644
webfaction_db.py File 5.88 KB 0644
webfaction_domain.py File 5.06 KB 0644
webfaction_mailbox.py File 4.08 KB 0644
webfaction_site.py File 6.59 KB 0644
xattr.py File 6.81 KB 0644
xbps.py File 11.18 KB 0644
xcc_redfish_command.py File 30.16 KB 0644
xenserver_facts.py File 5.27 KB 0644
xenserver_guest.py File 97.16 KB 0644
xenserver_guest_info.py File 7.63 KB 0644
xenserver_guest_powerstate.py File 9.96 KB 0644
xfconf.py File 9.96 KB 0644
xfconf_info.py File 5.29 KB 0644
xfs_quota.py File 14.61 KB 0644
xml.py File 35.6 KB 0644
yarn.py File 12.68 KB 0644
yum_versionlock.py File 5.37 KB 0644
zfs.py File 9.46 KB 0644
zfs_delegate_admin.py File 9.46 KB 0644
zfs_facts.py File 7.84 KB 0644
znode.py File 9.07 KB 0644
zpool_facts.py File 6.11 KB 0644
zypper.py File 20.8 KB 0644
zypper_repository.py File 16.99 KB 0644