190 lines
4.3 KiB
Python
190 lines
4.3 KiB
Python
#!/usr/bin/python
|
|
|
|
# Copyright: (c) 2020-, Sven Velt <sven-ansiblerole@velt.biz>
|
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
from __future__ import (absolute_import, division, print_function)
|
|
__metaclass__ = type
|
|
|
|
DOCUMENTATION = r'''
|
|
---
|
|
module: lxc_container_info
|
|
short_description: Gather info about LXC Containers
|
|
version_added: "0.1.0"
|
|
description: Gather some information about (all) LXC Containers
|
|
options:
|
|
name:
|
|
description: Name of Container to gather informations
|
|
required: false
|
|
type: str
|
|
requirements:
|
|
- 'lxc-python3'
|
|
author:
|
|
- Sven Velt
|
|
'''
|
|
|
|
EXAMPLES = r'''
|
|
# Gather information of all containers:
|
|
- name: Gather LXC informations
|
|
lxc_container_info:
|
|
|
|
# Gather information of one container:
|
|
- name: Gather LXC informations
|
|
lxc_container_info:
|
|
name: containername
|
|
'''
|
|
|
|
|
|
RETURN = r'''
|
|
# These are examples of possible return values, and in general should use other names for return values.
|
|
containers:
|
|
description: dict of container information
|
|
returned: always
|
|
type: complex
|
|
contains:
|
|
containername:
|
|
description: name of container
|
|
type: complex
|
|
contains:
|
|
all_interfaces:
|
|
description: List of all interfaces
|
|
type: str
|
|
returned: always
|
|
sample: '["lo", "eth0"]'
|
|
defined:
|
|
description: if container is defined
|
|
type: bool
|
|
returned: always
|
|
sample: true
|
|
exists:
|
|
description: if container is defined
|
|
type: bool
|
|
returned: always
|
|
sample: true
|
|
init_pid:
|
|
description: PID of init of container (if running)
|
|
type: init
|
|
sample: 1234
|
|
original_message:
|
|
description: The original name param that was passed in.
|
|
type: str
|
|
returned: always
|
|
sample: 'hello world'
|
|
message:
|
|
description: The output message that the test module generates.
|
|
type: str
|
|
returned: always
|
|
sample: 'goodbye'
|
|
my_useful_info:
|
|
description: The dictionary containing information about your system.
|
|
type: dict
|
|
returned: always
|
|
sample: {
|
|
'foo': 'bar',
|
|
'answer': 42,
|
|
}
|
|
'''
|
|
|
|
import ipaddress
|
|
|
|
try:
|
|
import lxc
|
|
except ImportError:
|
|
HAS_LXC = False
|
|
else:
|
|
HAS_LXC = True
|
|
|
|
from ansible.module_utils.basic import AnsibleModule
|
|
|
|
|
|
def run_module():
|
|
module_args = dict(
|
|
name=dict(type='str', default=''),
|
|
)
|
|
|
|
result = dict(
|
|
changed=False,
|
|
containers={},
|
|
)
|
|
|
|
module = AnsibleModule(
|
|
argument_spec=module_args,
|
|
supports_check_mode=True
|
|
)
|
|
|
|
if not HAS_LXC:
|
|
module.fail_json(
|
|
msg='The `lxc` module is not importable. Check the requirements.'
|
|
)
|
|
|
|
if module.params['name']:
|
|
ctnames = [ module.params['name'], ]
|
|
else:
|
|
ctnames = lxc.list_containers()
|
|
|
|
for ctname in ctnames:
|
|
ct = lxc.Container(ctname)
|
|
|
|
res_ct = {}
|
|
res_ct['defined'] = ct.defined
|
|
res_ct['exists'] = ct.defined
|
|
res_ct['state'] = ct.state
|
|
res_ct['running'] = ct.running
|
|
res_ct['init_pid'] = ct.init_pid
|
|
res_ct['all_interfaces'] = ct.get_interfaces()
|
|
|
|
res_ifaces = {}
|
|
for iface in ct.get_interfaces():
|
|
res_if = {}
|
|
res_if['ipv4_addresses'] = []
|
|
res_if['ipv6_addresses'] = []
|
|
for addr in ct.get_ips(iface):
|
|
try:
|
|
res_if['ipv4_addresses'].append(str(ipaddress.IPv4Address(addr)))
|
|
except ipaddress.AddressValueError:
|
|
try:
|
|
res_if['ipv6_addresses'].append(str(ipaddress.IPv6Address(addr)))
|
|
except:
|
|
pass
|
|
res_ifaces[iface] = res_if
|
|
res_ct['interfaces'] = res_ifaces
|
|
|
|
res_stat = {}
|
|
if ct.running:
|
|
res_stat['mem'] = {}
|
|
for (k, v) in [ ('usage', 'memory.usage_in_bytes'), ('max_usage', 'memory.max_usage_in_bytes') ]:
|
|
try:
|
|
res_stat['mem'][k] = int(ct.get_cgroup_item(v))
|
|
except KeyError:
|
|
pass
|
|
for (k, v) in [ ('usage_mb', 'memory.usage_in_bytes'), ('max_usage_mb', 'memory.max_usage_in_bytes') ]:
|
|
try:
|
|
res_stat['mem'][k] = int(ct.get_cgroup_item(v)) // 1048576
|
|
except KeyError:
|
|
pass
|
|
|
|
res_stat['kmem'] = {}
|
|
for (k, v) in [ ('usage', 'memory.kmem.usage_in_bytes'), ('max_usage', 'memory.kmem.max_usage_in_bytes') ]:
|
|
try:
|
|
res_stat['kmem'][k] = int(ct.get_cgroup_item(v))
|
|
except KeyError:
|
|
pass
|
|
for (k, v) in [ ('usage_mb', 'memory.kmem.usage_in_bytes'), ('max_usage_mb', 'memory.kmem.max_usage_in_bytes') ]:
|
|
try:
|
|
res_stat['kmem'][k] = int(ct.get_cgroup_item(v)) // 1048576
|
|
except KeyError:
|
|
pass
|
|
|
|
res_ct['stats'] = res_stat
|
|
|
|
result['containers'][ctname] = res_ct
|
|
|
|
module.exit_json(**result)
|
|
|
|
|
|
def main():
|
|
run_module()
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|