Kapitel 12: Rest

This commit is contained in:
Sven Velt 2024-09-20 15:57:42 +02:00
parent 4ff845d56a
commit 7005b82e6c
20 changed files with 677 additions and 0 deletions

1
12/Prepare_Workshop Submodule

@ -0,0 +1 @@
Subproject commit cc05cf60933293fb3e939a0981a6b804a2689d72

0
12/Win/Unix-Datei.txt Normal file
View file

3
12/Win/ansible.cfg Normal file
View file

@ -0,0 +1,3 @@
[defaults]
inventory = ./hosts

9
12/Win/hosts Normal file
View file

@ -0,0 +1,9 @@
[windows]
win2k12r2 ansible_host=172.22.240.164
[windows:vars]
ansible_user=Administrator
ansible_password=XXXXX
ansible_connection=winrm
ansible_winrm_server_cert_validation=ignore

141
12/Win/setup.txt Normal file
View file

@ -0,0 +1,141 @@
win2k12r2 | SUCCESS => {
"ansible_facts": {
"ansible_architecture": "64-Bit",
"ansible_architecture2": "x86_64",
"ansible_bios_date": null,
"ansible_bios_version": null,
"ansible_date_time": {
"date": "2022-03-18",
"day": "18",
"epoch": "1647607291,11022",
"epoch_int": 1647607291,
"epoch_local": "1647610891,11022",
"hour": "13",
"iso8601": "2022-03-18T12:41:31Z",
"iso8601_basic": "20220318T134131110217",
"iso8601_basic_short": "20220318T134131",
"iso8601_micro": "2022-03-18T12:41:31.110217Z",
"minute": "41",
"month": "03",
"second": "31",
"time": "13:41:31",
"tz": "W. Europe Standard Time",
"tz_offset": "+01:00",
"weekday": "Friday",
"weekday_number": "5",
"weeknumber": "11",
"year": "2022"
},
"ansible_distribution": "Microsoft Windows Server 2012 R2 Standard - Testversion",
"ansible_distribution_major_version": "6",
"ansible_distribution_version": "6.3.9600.0",
"ansible_domain": "",
"ansible_env": {
"ALLUSERSPROFILE": "C:\\ProgramData",
"APPDATA": "C:\\Users\\Administrator\\AppData\\Roaming",
"COMPUTERNAME": "WIN-A6UVOR2N33N",
"ChocolateyInstall": "C:\\ProgramData\\chocolatey",
"ChocolateyLastPathUpdate": "132835990150633065",
"ChocolateyToolsLocation": "C:\\tools",
"ComSpec": "C:\\Windows\\system32\\cmd.exe",
"CommonProgramFiles": "C:\\Program Files\\Common Files",
"CommonProgramFiles(x86)": "C:\\Program Files (x86)\\Common Files",
"CommonProgramW6432": "C:\\Program Files\\Common Files",
"FP_NO_HOST_CHECK": "NO",
"HOMEDRIVE": "C:",
"HOMEPATH": "\\Users\\Administrator",
"LOCALAPPDATA": "C:\\Users\\Administrator\\AppData\\Local",
"LOGONSERVER": "\\\\WIN-A6UVOR2N33N",
"NUMBER_OF_PROCESSORS": "2",
"OS": "Windows_NT",
"PATHEXT": ".COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.CPL",
"PROCESSOR_ARCHITECTURE": "AMD64",
"PROCESSOR_IDENTIFIER": "Intel64 Family 6 Model 61 Stepping 2, GenuineIntel",
"PROCESSOR_LEVEL": "6",
"PROCESSOR_REVISION": "3d02",
"PROMPT": "$P$G",
"PSExecutionPolicyPreference": "Unrestricted",
"PSModulePath": "C:\\Users\\Administrator\\Documents\\WindowsPowerShell\\Modules;C:\\Program Files\\WindowsPowerShell\\Modules;C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\Modules",
"PUBLIC": "C:\\Users\\Public",
"Path": "C:\\Windows\\system32;C:\\Windows;C:\\Windows\\System32\\Wbem;C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\;C:\\ProgramData\\chocolatey\\bin;",
"ProgramData": "C:\\ProgramData",
"ProgramFiles": "C:\\Program Files",
"ProgramFiles(x86)": "C:\\Program Files (x86)",
"ProgramW6432": "C:\\Program Files",
"SystemDrive": "C:",
"SystemRoot": "C:\\Windows",
"TEMP": "C:\\Users\\ADMINI~1\\AppData\\Local\\Temp",
"TMP": "C:\\Users\\ADMINI~1\\AppData\\Local\\Temp",
"USERDOMAIN": "WIN-A6UVOR2N33N",
"USERDOMAIN_ROAMINGPROFILE": "WIN-A6UVOR2N33N",
"USERNAME": "Administrator",
"USERPROFILE": "C:\\Users\\Administrator",
"windir": "C:\\Windows"
},
"ansible_fqdn": "WIN-A6UVOR2N33N",
"ansible_hostname": "WIN-A6UVOR2N33N",
"ansible_interfaces": [
{
"connection_name": "Ethernet",
"default_gateway": "172.22.240.1",
"dns_domain": "br240.void",
"interface_index": 21,
"interface_name": "Gigabit-Netzwerkverbindung Intel(R) 82574L #2",
"macaddress": "52:54:00:80:68:04"
}
],
"ansible_ip_addresses": [
"fe80::4d9b:297e:ee2f:4df2%21",
"172.22.240.164"
],
"ansible_kernel": "6.3.9600.0",
"ansible_lastboot": "2022-03-18 13:14:08Z",
"ansible_machine_id": "S-1-5-21-4249200181-1233407984-53629394",
"ansible_memfree_mb": 3435,
"ansible_memtotal_mb": 4096,
"ansible_netbios_name": "WIN-A6UVOR2N33N",
"ansible_nodename": "WIN-A6UVOR2N33N",
"ansible_os_family": "Windows",
"ansible_os_installation_type": "Server",
"ansible_os_name": "Microsoft Windows Server 2012 R2 Standard - Testversion",
"ansible_os_product_type": "server",
"ansible_owner_contact": "",
"ansible_owner_name": "Windows-Benutzer",
"ansible_pagefilefree_mb": 1408,
"ansible_pagefiletotal_mb": 1408,
"ansible_powershell_version": 4,
"ansible_processor": [
"0",
"GenuineIntel",
"Intel Core Processor (Broadwell, IBRS)",
"1",
"GenuineIntel",
"Intel Core Processor (Broadwell, IBRS)"
],
"ansible_processor_count": 0,
"ansible_processor_vcpus": 2,
"ansible_product_name": null,
"ansible_product_serial": null,
"ansible_reboot_pending": false,
"ansible_swaptotal_mb": 0,
"ansible_system": "Win32NT",
"ansible_system_description": "",
"ansible_system_vendor": null,
"ansible_uptime_seconds": 1646,
"ansible_user_dir": "C:\\Users\\Administrator",
"ansible_user_gecos": "",
"ansible_user_id": "Administrator",
"ansible_user_sid": "S-1-5-21-4249200181-1233407984-53629394-500",
"ansible_virtualization_role": "NA",
"ansible_virtualization_type": "NA",
"ansible_win_rm_certificate_expires": "2024-10-26 23:04:12",
"ansible_windows_domain": "WORKGROUP",
"ansible_windows_domain_member": false,
"ansible_windows_domain_role": "Stand-alone server",
"gather_subset": [
"all"
],
"module_setup": true
},
"changed": false
}

12
12/Win/useradd.yml Normal file
View file

@ -0,0 +1,12 @@
---
- hosts: windows
tasks:
- name: Ensure user bob is present
ansible.windows.win_user:
name: bob
password: B0bP4ssw0rd
state: present
groups:
- Benutzer

View file

@ -2,6 +2,7 @@
# Inventory
inventory = ./hosts.ini
inventory_plugins = ./plugins/inventory
# Roles paths
roles_path = ./roles:./roles.extern:./roles.webcluster:/etc/ansible/roles
@ -9,6 +10,9 @@ roles_path = ./roles:./roles.extern:./roles.webcluster:/etc/ansible/roles
# Interpreter Discovery - Ohne Warnings
interpreter_python = auto_silent
# Zusätzliche Module
library = ./plugins/modules
# SSH
remote_user = root
#host_key_checking = False

9
12/availenabled.yml Normal file
View file

@ -0,0 +1,9 @@
---
- hosts: localhost
gather_facts: no
tasks:
- availenabled:
path: /tmp/apache2/mods-
name: foo

View file

@ -0,0 +1,5 @@
{"ANSIBLE_MODULE_ARGS": {
"path": "/tmp/apache2/mods-",
"name": "foo"
}
}

View file

@ -0,0 +1,6 @@
#!/bin/sh
cat <<EOF
{ "gruppe1": { "hosts": ["host1", "host2"] }, "gruppe2": { "hosts": ["host3", "host4"] }, "_meta": {} }
EOF

View file

@ -0,0 +1,36 @@
#!/usr/bin/python3
import json
import sys
try:
import lxc
except ImportError:
print("Could not import lxc module!")
sys.exit(1)
########################################
inventory ={ '_meta':{'hostvars':{} } }
########################################
ctnames = lxc.list_containers()
for ctname in ctnames:
ct = lxc.Container(ctname)
if ct.running:
groups = ct.get_running_config_item('lxc.group')
if not groups:
groups = 'ungrouped'
for group in groups.rstrip().split('\n'):
if not group in inventory:
inventory[group] = {
'hosts': [],
'vars': {
'ansible_connection': 'lxc',
}
}
inventory[group]['hosts'].append(ctname)
print(json.dumps(inventory))

View file

@ -0,0 +1,33 @@
#!/usr/bin/python3
import json
import sys
try:
import lxc
except ImportError:
print("Could not import lxc module!")
sys.exit(1)
########################################
inventory ={ '_meta':{'hostvars':{} } }
########################################
ctnames = lxc.list_containers()
for ctname in ctnames:
ct = lxc.Container(ctname)
if ct.running:
for group in ct.get_running_config_item('lxc.group').rstrip().split('\n'):
if not group in inventory:
inventory[group] = {
'hosts': [],
'vars': {
'ansible_connection': 'lxc',
}
}
inventory[group]['hosts'].append(ctname)
print(json.dumps(inventory))

View file

@ -0,0 +1,40 @@
#!/usr/bin/python3
import json
import sys
try:
import lxc
except ImportError:
print("Could not import lxc module!")
sys.exit(1)
########################################
inventory ={ '_meta':{'hostvars':{} } }
########################################
ctnames = lxc.list_containers()
for ctname in ctnames:
ct = lxc.Container(ctname)
if ct.running:
groups = ct.get_running_config_item('lxc.group')
if not groups:
groups = 'ungrouped'
for group in groups.rstrip().split('\n'):
if not group in inventory:
inventory[group] = {
'hosts': [],
'vars': {
'ansible_user': 'root',
},
}
inventory[group]['hosts'].append(ctname)
inventory['_meta']['hostvars'][ctname] = {
'ansible_host': ct.get_ips()[0],
}
print(json.dumps(inventory))

View file

@ -0,0 +1,22 @@
---
plugin: community.general.nmap
#strict: False
#ports: False
#ipv4: True
#ipv6: False
address: 192.168.0.0/24
#address: 192.168.50.0/24
#address: 10.128.16.8/24
#address: 80.241.57.126/32
cache: true
cache_connection: ./.cache/inventory
cache_plugin: yaml
cache_prefix: inventory_yaml_
cache_timeout: 30
groups:
nmap_without_hostname: "name|ansible.utils.ipv4"
nmap_debian: "'debian' in name"
nmap_centos: "'centos' in name"

16
inventory/hosts.nmap.yml Normal file
View file

@ -0,0 +1,16 @@
---
plugin: community.general.nmap
#strict: False
#ports: False
#ipv4: True
#ipv6: False
address: 192.168.0.0/24
#address: 192.168.50.0/24
#address: 10.128.17.0/24
#address: 80.241.57.126/32
groups:
nmap_without_hostname: "name|ansible.utils.ipv4"
nmap_debian: "'debian' in name"
nmap_centos: "'centos' in name"

View file

@ -0,0 +1,4 @@
---
plugin: community.libvirt.libvirt
uri: lxc:/

3
inventory/lxc.yml Normal file
View file

@ -0,0 +1,3 @@
---
plugin: lxc

75
plugins/inventory/lxc.py Normal file
View file

@ -0,0 +1,75 @@
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = r'''
'''
EXAMPLES = r'''
'''
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable
from ansible.errors import AnsibleError
try:
import lxc
except ImportError:
raise AnsibleError('the lxc inventory plugin requires lxc-python.')
class InventoryModule(BaseInventoryPlugin, Constructable):
NAME = 'lxc'
def parse(self, inventory, loader, path, cache=True):
super(InventoryModule, self).parse(
inventory,
loader,
path,
cache=cache
)
config_data = self._read_config_data(path)
self._consume_options(config_data)
ctnames = lxc.list_containers()
for ctname in ctnames:
ct = lxc.Container(ctname)
if ct.running:
self.inventory.add_host(ctname)
for group in ct.get_running_config_item('lxc.group').rstrip().split('\n'):
self.inventory.add_group(group)
self.inventory.add_child(group, ctname)
self.inventory.set_variable(ctname, 'ansible_connection', 'lxc')
# Get variables for compose
# variables = self.inventory.hosts[ctname].get_vars()
# print(variables)
# print(ctname)
# print( self.get_option('compose') )
# print( self.get_option('strict') )
# # Set composed variables
# self._set_composite_vars(
# self.get_option('compose'),
# variables,
# ctname,
# self.get_option('strict'),
# )
# print('XXX')
#
# # Add host to composed groups
# self._add_host_to_composed_groups(
# self.get_option('groups'),
# variables,
# inventory_hostname,
# self.get_option('strict'),
# )
#
# # Add host to keyed groups
# self._add_host_to_keyed_groups(
# self.get_option('keyed_groups'),
# variables,
# inventory_hostname,
# self.get_option('strict'),
# )

View file

@ -0,0 +1,81 @@
#!/usr/bin/python
import os
from operator import xor
def main():
module = AnsibleModule(
argument_spec = dict(
path = dict(required=True),
base = dict(default=""),
p_enabled = dict(default='enabled'),
p_available = dict(default='available'),
name = dict(required=True),
suffix= dict(default='.conf'),
state = dict(default='present', choices=['present', 'absent']),
)
)
# path: /etc/apache2 or /etc/apache2/conf-
# base: conf- or ""
# name: FILENAME or FILENAME.conf
path = module.params.get('path')
base = module.params.get('base')
p_enabled = module.params.get('p_enabled')
p_available = module.params.get('p_available')
name = module.params.get('name')
suffix = module.params.get('suffix')
state = module.params.get('state') == 'present'
# pre-checks
if os.path.isdir(path):
p_available = os.path.join(path, base + p_available)
p_enabled = os.path.join(path, base + p_enabled)
else:
p_available = path + p_available
p_enabled = path + p_enabled
for p in [p_available, p_enabled]:
if not os.path.isdir(p):
module.fail_json(msg="Directory %s not found" % p)
# define internal variables
src = os.path.join(p_available, name + suffix)
dest = os.path.join(p_enabled, name + suffix)
if not (os.path.isfile(src) or os.path.islink(src)):
module.fail_json(msg="Source not found")
dest_exists=True
if not (os.path.isfile(dest) or os.path.islink(dest)):
dest_exists=False
# if there's no difference, no change, exit "ok"
if not xor(state, dest_exists):
module.exit_json()
if state:
# try to create symlink
try:
os.symlink(os.path.relpath(src, p_enabled), dest)
except:
module.fail_json(msg="Could not create symlink")
else:
# test, if symlink
if not os.path.islink(dest):
module.fail_json(msg="Destination is not a symlink")
# try to remove symlink
try:
os.unlink(dest)
except:
module.fail_json(msg="Could not remove symlink")
module.exit_json(changed=True)
from ansible.module_utils.basic import *
if __name__ == '__main__':
main()

View file

@ -0,0 +1,177 @@
#!/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'] = {
'usage': int(ct.get_cgroup_item("memory.usage_in_bytes")),
'max_usage': int(ct.get_cgroup_item("memory.max_usage_in_bytes")),
'usage_mb': int(ct.get_cgroup_item("memory.usage_in_bytes")) // 1048576,
'max_usage_mb': int(ct.get_cgroup_item("memory.max_usage_in_bytes")) // 1048576,
}
res_stat['kmem'] = {
'usage': int(ct.get_cgroup_item("memory.kmem.usage_in_bytes")),
'max_usage': int(ct.get_cgroup_item("memory.kmem.max_usage_in_bytes")),
'usage_mb': int(ct.get_cgroup_item("memory.kmem.usage_in_bytes")) // 1048576,
'max_usage_mb': int(ct.get_cgroup_item("memory.kmem.max_usage_in_bytes")) // 1048576,
}
res_ct['stats'] = res_stat
result['containers'][ctname] = res_ct
module.exit_json(**result)
def main():
run_module()
if __name__ == '__main__':
main()