����JFIF���������
__ __ __ __ _____ _ _ _____ _ _ _ | \/ | \ \ / / | __ \ (_) | | / ____| | | | | | \ / |_ __\ V / | |__) | __ ___ ____ _| |_ ___ | (___ | |__ ___| | | | |\/| | '__|> < | ___/ '__| \ \ / / _` | __/ _ \ \___ \| '_ \ / _ \ | | | | | | |_ / . \ | | | | | |\ V / (_| | || __/ ____) | | | | __/ | | |_| |_|_(_)_/ \_\ |_| |_| |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1 if you need WebShell for Seo everyday contact me on Telegram Telegram Address : @jackleetFor_More_Tools:
# -*- coding: utf-8 -*-
# Copyright (c) 2016, Shinichi TAMURA (@tmshn)
# 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
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = r'''
---
module: timezone
short_description: Configure timezone setting
description:
- This module configures the timezone setting, both of the system clock and of the hardware clock.
If you want to set up the NTP, use M(ansible.builtin.service) module.
- It is recommended to restart C(crond) after changing the timezone, otherwise the jobs may run at the wrong time.
- Several different tools are used depending on the OS/Distribution involved.
For Linux it can use C(timedatectl) or edit C(/etc/sysconfig/clock) or C(/etc/timezone) and C(hwclock).
On SmartOS, C(sm-set-timezone), for macOS, C(systemsetup), for BSD, C(/etc/localtime) is modified.
On AIX, C(chtz) is used.
- Make sure that the zoneinfo files are installed with the appropriate OS package, like C(tzdata) (usually always installed,
when not using a minimal installation like Alpine Linux).
- As of Ansible 2.3 support was added for SmartOS and BSDs.
- As of Ansible 2.4 support was added for macOS.
- As of Ansible 2.9 support was added for AIX 6.1+
- Windows and HPUX are not supported, please let us know if you find any other OS/distro in which this fails.
extends_documentation_fragment:
- community.general.attributes
attributes:
check_mode:
support: full
diff_mode:
support: full
options:
name:
description:
- Name of the timezone for the system clock.
- Default is to keep current setting.
- B(At least one of name and hwclock are required.)
type: str
hwclock:
description:
- Whether the hardware clock is in UTC or in local timezone.
- Default is to keep current setting.
- Note that this option is recommended not to change and may fail
to configure, especially on virtual environments such as AWS.
- B(At least one of name and hwclock are required.)
- I(Only used on Linux.)
type: str
aliases: [ rtc ]
choices: [ local, UTC ]
notes:
- On SmartOS the C(sm-set-timezone) utility (part of the smtools package) is required to set the zone timezone
- On AIX only Olson/tz database timezones are useable (POSIX is not supported).
- An OS reboot is also required on AIX for the new timezone setting to take effect.
author:
- Shinichi TAMURA (@tmshn)
- Jasper Lievisse Adriaanse (@jasperla)
- Indrajit Raychaudhuri (@indrajitr)
'''
RETURN = r'''
diff:
description: The differences about the given arguments.
returned: success
type: complex
contains:
before:
description: The values before change
type: dict
after:
description: The values after change
type: dict
'''
EXAMPLES = r'''
- name: Set timezone to Asia/Tokyo
community.general.timezone:
name: Asia/Tokyo
'''
import errno
import os
import platform
import random
import re
import string
import filecmp
from ansible.module_utils.basic import AnsibleModule, get_distribution
from ansible.module_utils.six import iteritems
class Timezone(object):
"""This is a generic Timezone manipulation class that is subclassed based on platform.
A subclass may wish to override the following action methods:
- get(key, phase) ... get the value from the system at `phase`
- set(key, value) ... set the value to the current system
"""
def __new__(cls, module):
"""Return the platform-specific subclass.
It does not use load_platform_subclass() because it needs to judge based
on whether the `timedatectl` command exists and is available.
Args:
module: The AnsibleModule.
"""
if platform.system() == 'Linux':
timedatectl = module.get_bin_path('timedatectl')
if timedatectl is not None:
rc, stdout, stderr = module.run_command(timedatectl)
if rc == 0:
return super(Timezone, SystemdTimezone).__new__(SystemdTimezone)
else:
module.debug('timedatectl command was found but not usable: %s. using other method.' % stderr)
return super(Timezone, NosystemdTimezone).__new__(NosystemdTimezone)
else:
return super(Timezone, NosystemdTimezone).__new__(NosystemdTimezone)
elif re.match('^joyent_.*Z', platform.version()):
# platform.system() returns SunOS, which is too broad. So look at the
# platform version instead. However we have to ensure that we're not
# running in the global zone where changing the timezone has no effect.
zonename_cmd = module.get_bin_path('zonename')
if zonename_cmd is not None:
(rc, stdout, dummy) = module.run_command(zonename_cmd)
if rc == 0 and stdout.strip() == 'global':
module.fail_json(msg='Adjusting timezone is not supported in Global Zone')
return super(Timezone, SmartOSTimezone).__new__(SmartOSTimezone)
elif platform.system() == 'Darwin':
return super(Timezone, DarwinTimezone).__new__(DarwinTimezone)
elif re.match('^(Free|Net|Open)BSD', platform.platform()):
return super(Timezone, BSDTimezone).__new__(BSDTimezone)
elif platform.system() == 'AIX':
AIXoslevel = int(platform.version() + platform.release())
if AIXoslevel >= 61:
return super(Timezone, AIXTimezone).__new__(AIXTimezone)
else:
module.fail_json(msg='AIX os level must be >= 61 for timezone module (Target: %s).' % AIXoslevel)
else:
# Not supported yet
return super(Timezone, Timezone).__new__(Timezone)
def __init__(self, module):
"""Initialize of the class.
Args:
module: The AnsibleModule.
"""
super(Timezone, self).__init__()
self.msg = []
# `self.value` holds the values for each params on each phases.
# Initially there's only info of "planned" phase, but the
# `self.check()` function will fill out it.
self.value = dict()
for key in module.argument_spec:
value = module.params[key]
if value is not None:
self.value[key] = dict(planned=value)
self.module = module
def abort(self, msg):
"""Abort the process with error message.
This is just the wrapper of module.fail_json().
Args:
msg: The error message.
"""
error_msg = ['Error message:', msg]
if len(self.msg) > 0:
error_msg.append('Other message(s):')
error_msg.extend(self.msg)
self.module.fail_json(msg='\n'.join(error_msg))
def execute(self, *commands, **kwargs):
"""Execute the shell command.
This is just the wrapper of module.run_command().
Args:
*commands: The command to execute.
It will be concatenated with single space.
**kwargs: Only 'log' key is checked.
If kwargs['log'] is true, record the command to self.msg.
Returns:
stdout: Standard output of the command.
"""
command = ' '.join(commands)
(rc, stdout, stderr) = self.module.run_command(command, check_rc=True)
if kwargs.get('log', False):
self.msg.append('executed `%s`' % command)
return stdout
def diff(self, phase1='before', phase2='after'):
"""Calculate the difference between given 2 phases.
Args:
phase1, phase2: The names of phase to compare.
Returns:
diff: The difference of value between phase1 and phase2.
This is in the format which can be used with the
`--diff` option of ansible-playbook.
"""
diff = {phase1: {}, phase2: {}}
for key, value in iteritems(self.value):
diff[phase1][key] = value[phase1]
diff[phase2][key] = value[phase2]
return diff
def check(self, phase):
"""Check the state in given phase and set it to `self.value`.
Args:
phase: The name of the phase to check.
Returns:
NO RETURN VALUE
"""
if phase == 'planned':
return
for key, value in iteritems(self.value):
value[phase] = self.get(key, phase)
def change(self):
"""Make the changes effect based on `self.value`."""
for key, value in iteritems(self.value):
if value['before'] != value['planned']:
self.set(key, value['planned'])
# ===========================================
# Platform specific methods (must be replaced by subclass).
def get(self, key, phase):
"""Get the value for the key at the given phase.
Called from self.check().
Args:
key: The key to get the value
phase: The phase to get the value
Return:
value: The value for the key at the given phase.
"""
self.abort('get(key, phase) is not implemented on target platform')
def set(self, key, value):
"""Set the value for the key (of course, for the phase 'after').
Called from self.change().
Args:
key: Key to set the value
value: Value to set
"""
self.abort('set(key, value) is not implemented on target platform')
def _verify_timezone(self):
tz = self.value['name']['planned']
tzfile = '/usr/share/zoneinfo/%s' % tz
if not os.path.isfile(tzfile):
self.abort('given timezone "%s" is not available' % tz)
return tzfile
class SystemdTimezone(Timezone):
"""This is a Timezone manipulation class for systemd-powered Linux.
It uses the `timedatectl` command to check/set all arguments.
"""
regexps = dict(
hwclock=re.compile(r'^\s*RTC in local TZ\s*:\s*([^\s]+)', re.MULTILINE),
name=re.compile(r'^\s*Time ?zone\s*:\s*([^\s]+)', re.MULTILINE)
)
subcmds = dict(
hwclock='set-local-rtc',
name='set-timezone'
)
def __init__(self, module):
super(SystemdTimezone, self).__init__(module)
self.timedatectl = module.get_bin_path('timedatectl', required=True)
self.status = dict()
# Validate given timezone
if 'name' in self.value:
self._verify_timezone()
def _get_status(self, phase):
if phase not in self.status:
self.status[phase] = self.execute(self.timedatectl, 'status')
return self.status[phase]
def get(self, key, phase):
status = self._get_status(phase)
value = self.regexps[key].search(status).group(1)
if key == 'hwclock':
# For key='hwclock'; convert yes/no -> local/UTC
if self.module.boolean(value):
value = 'local'
else:
value = 'UTC'
return value
def set(self, key, value):
# For key='hwclock'; convert UTC/local -> yes/no
if key == 'hwclock':
if value == 'local':
value = 'yes'
else:
value = 'no'
self.execute(self.timedatectl, self.subcmds[key], value, log=True)
class NosystemdTimezone(Timezone):
"""This is a Timezone manipulation class for non systemd-powered Linux.
For timezone setting, it edits the following file and reflect changes:
- /etc/sysconfig/clock ... RHEL/CentOS
- /etc/timezone ... Debian/Ubuntu
For hwclock setting, it executes `hwclock --systohc` command with the
'--utc' or '--localtime' option.
"""
conf_files = dict(
name=None, # To be set in __init__
hwclock=None, # To be set in __init__
adjtime='/etc/adjtime'
)
# It's fine if all tree config files don't exist
allow_no_file = dict(
name=True,
hwclock=True,
adjtime=True
)
regexps = dict(
name=None, # To be set in __init__
hwclock=re.compile(r'^UTC\s*=\s*([^\s]+)', re.MULTILINE),
adjtime=re.compile(r'^(UTC|LOCAL)$', re.MULTILINE)
)
dist_regexps = dict(
SuSE=re.compile(r'^TIMEZONE\s*=\s*"?([^"\s]+)"?', re.MULTILINE),
redhat=re.compile(r'^ZONE\s*=\s*"?([^"\s]+)"?', re.MULTILINE)
)
dist_tzline_format = dict(
SuSE='TIMEZONE="%s"\n',
redhat='ZONE="%s"\n'
)
def __init__(self, module):
super(NosystemdTimezone, self).__init__(module)
# Validate given timezone
planned_tz = ''
if 'name' in self.value:
tzfile = self._verify_timezone()
planned_tz = self.value['name']['planned']
# `--remove-destination` is needed if /etc/localtime is a symlink so
# that it overwrites it instead of following it.
self.update_timezone = ['%s --remove-destination %s /etc/localtime' % (self.module.get_bin_path('cp', required=True), tzfile)]
self.update_hwclock = self.module.get_bin_path('hwclock', required=True)
distribution = get_distribution()
self.conf_files['name'] = '/etc/timezone'
self.regexps['name'] = re.compile(r'^([^\s]+)', re.MULTILINE)
self.tzline_format = '%s\n'
# Distribution-specific configurations
if self.module.get_bin_path('dpkg-reconfigure') is not None:
# Debian/Ubuntu
if 'name' in self.value:
self.update_timezone = ['%s -sf %s /etc/localtime' % (self.module.get_bin_path('ln', required=True), tzfile),
'%s --frontend noninteractive tzdata' % self.module.get_bin_path('dpkg-reconfigure', required=True)]
self.conf_files['hwclock'] = '/etc/default/rcS'
elif distribution == 'Alpine' or distribution == 'Gentoo':
self.conf_files['hwclock'] = '/etc/conf.d/hwclock'
if distribution == 'Alpine':
self.update_timezone = ['%s -z %s' % (self.module.get_bin_path('setup-timezone', required=True), planned_tz)]
else:
# RHEL/CentOS/SUSE
if self.module.get_bin_path('tzdata-update') is not None:
# tzdata-update cannot update the timezone if /etc/localtime is
# a symlink so we have to use cp to update the time zone which
# was set above.
if not os.path.islink('/etc/localtime'):
self.update_timezone = [self.module.get_bin_path('tzdata-update', required=True)]
# else:
# self.update_timezone = 'cp --remove-destination ...' <- configured above
self.conf_files['name'] = '/etc/sysconfig/clock'
self.conf_files['hwclock'] = '/etc/sysconfig/clock'
try:
f = open(self.conf_files['name'], 'r')
except IOError as err:
if self._allow_ioerror(err, 'name'):
# If the config file doesn't exist detect the distribution and set regexps.
if distribution == 'SuSE':
# For SUSE
self.regexps['name'] = self.dist_regexps['SuSE']
self.tzline_format = self.dist_tzline_format['SuSE']
else:
# For RHEL/CentOS
self.regexps['name'] = self.dist_regexps['redhat']
self.tzline_format = self.dist_tzline_format['redhat']
else:
self.abort('could not read configuration file "%s"' % self.conf_files['name'])
else:
# The key for timezone might be `ZONE` or `TIMEZONE`
# (the former is used in RHEL/CentOS and the latter is used in SUSE linux).
# So check the content of /etc/sysconfig/clock and decide which key to use.
sysconfig_clock = f.read()
f.close()
if re.search(r'^TIMEZONE\s*=', sysconfig_clock, re.MULTILINE):
# For SUSE
self.regexps['name'] = self.dist_regexps['SuSE']
self.tzline_format = self.dist_tzline_format['SuSE']
else:
# For RHEL/CentOS
self.regexps['name'] = self.dist_regexps['redhat']
self.tzline_format = self.dist_tzline_format['redhat']
def _allow_ioerror(self, err, key):
# In some cases, even if the target file does not exist,
# simply creating it may solve the problem.
# In such cases, we should continue the configuration rather than aborting.
if err.errno != errno.ENOENT:
# If the error is not ENOENT ("No such file or directory"),
# (e.g., permission error, etc), we should abort.
return False
return self.allow_no_file.get(key, False)
def _edit_file(self, filename, regexp, value, key):
"""Replace the first matched line with given `value`.
If `regexp` matched more than once, other than the first line will be deleted.
Args:
filename: The name of the file to edit.
regexp: The regular expression to search with.
value: The line which will be inserted.
key: For what key the file is being editted.
"""
# Read the file
try:
file = open(filename, 'r')
except IOError as err:
if self._allow_ioerror(err, key):
lines = []
else:
self.abort('tried to configure %s using a file "%s", but could not read it' % (key, filename))
else:
lines = file.readlines()
file.close()
# Find the all matched lines
matched_indices = []
for i, line in enumerate(lines):
if regexp.search(line):
matched_indices.append(i)
if len(matched_indices) > 0:
insert_line = matched_indices[0]
else:
insert_line = 0
# Remove all matched lines
for i in matched_indices[::-1]:
del lines[i]
# ...and insert the value
lines.insert(insert_line, value)
# Write the changes
try:
file = open(filename, 'w')
except IOError:
self.abort('tried to configure %s using a file "%s", but could not write to it' % (key, filename))
else:
file.writelines(lines)
file.close()
self.msg.append('Added 1 line and deleted %s line(s) on %s' % (len(matched_indices), filename))
def _get_value_from_config(self, key, phase):
filename = self.conf_files[key]
try:
file = open(filename, mode='r')
except IOError as err:
if self._allow_ioerror(err, key):
if key == 'hwclock':
return 'n/a'
elif key == 'adjtime':
return 'UTC'
elif key == 'name':
return 'n/a'
else:
self.abort('tried to configure %s using a file "%s", but could not read it' % (key, filename))
else:
status = file.read()
file.close()
try:
value = self.regexps[key].search(status).group(1)
except AttributeError:
if key == 'hwclock':
# If we cannot find UTC in the config that's fine.
return 'n/a'
elif key == 'adjtime':
# If we cannot find UTC/LOCAL in /etc/cannot that means UTC
# will be used by default.
return 'UTC'
elif key == 'name':
if phase == 'before':
# In 'before' phase UTC/LOCAL doesn't need to be set in
# the timezone config file, so we ignore this error.
return 'n/a'
else:
self.abort('tried to configure %s using a file "%s", but could not find a valid value in it' % (key, filename))
else:
if key == 'hwclock':
# convert yes/no -> UTC/local
if self.module.boolean(value):
value = 'UTC'
else:
value = 'local'
elif key == 'adjtime':
# convert LOCAL -> local
if value != 'UTC':
value = value.lower()
return value
def get(self, key, phase):
planned = self.value[key]['planned']
if key == 'hwclock':
value = self._get_value_from_config(key, phase)
if value == planned:
# If the value in the config file is the same as the 'planned'
# value, we need to check /etc/adjtime.
value = self._get_value_from_config('adjtime', phase)
elif key == 'name':
value = self._get_value_from_config(key, phase)
if value == planned:
# If the planned values is the same as the one in the config file
# we need to check if /etc/localtime is also set to the 'planned' zone.
if os.path.islink('/etc/localtime'):
# If /etc/localtime is a symlink and is not set to the TZ we 'planned'
# to set, we need to return the TZ which the symlink points to.
if os.path.exists('/etc/localtime'):
# We use readlink() because on some distros zone files are symlinks
# to other zone files, so it's hard to get which TZ is actually set
# if we follow the symlink.
path = os.readlink('/etc/localtime')
# most linuxes has it in /usr/share/zoneinfo
# alpine linux links under /etc/zoneinfo
linktz = re.search(r'(?:/(?:usr/share|etc)/zoneinfo/)(.*)', path, re.MULTILINE)
if linktz:
valuelink = linktz.group(1)
if valuelink != planned:
value = valuelink
else:
# Set current TZ to 'n/a' if the symlink points to a path
# which isn't a zone file.
value = 'n/a'
else:
# Set current TZ to 'n/a' if the symlink to the zone file is broken.
value = 'n/a'
else:
# If /etc/localtime is not a symlink best we can do is compare it with
# the 'planned' zone info file and return 'n/a' if they are different.
try:
if not filecmp.cmp('/etc/localtime', '/usr/share/zoneinfo/' + planned):
return 'n/a'
except Exception:
return 'n/a'
else:
self.abort('unknown parameter "%s"' % key)
return value
def set_timezone(self, value):
self._edit_file(filename=self.conf_files['name'],
regexp=self.regexps['name'],
value=self.tzline_format % value,
key='name')
for cmd in self.update_timezone:
self.execute(cmd)
def set_hwclock(self, value):
if value == 'local':
option = '--localtime'
utc = 'no'
else:
option = '--utc'
utc = 'yes'
if self.conf_files['hwclock'] is not None:
self._edit_file(filename=self.conf_files['hwclock'],
regexp=self.regexps['hwclock'],
value='UTC=%s\n' % utc,
key='hwclock')
self.execute(self.update_hwclock, '--systohc', option, log=True)
def set(self, key, value):
if key == 'name':
self.set_timezone(value)
elif key == 'hwclock':
self.set_hwclock(value)
else:
self.abort('unknown parameter "%s"' % key)
class SmartOSTimezone(Timezone):
"""This is a Timezone manipulation class for SmartOS instances.
It uses the C(sm-set-timezone) utility to set the timezone, and
inspects C(/etc/default/init) to determine the current timezone.
NB: A zone needs to be rebooted in order for the change to be
activated.
"""
def __init__(self, module):
super(SmartOSTimezone, self).__init__(module)
self.settimezone = self.module.get_bin_path('sm-set-timezone', required=False)
if not self.settimezone:
module.fail_json(msg='sm-set-timezone not found. Make sure the smtools package is installed.')
def get(self, key, phase):
"""Lookup the current timezone name in `/etc/default/init`. If anything else
is requested, or if the TZ field is not set we fail.
"""
if key == 'name':
try:
f = open('/etc/default/init', 'r')
for line in f:
m = re.match('^TZ=(.*)$', line.strip())
if m:
return m.groups()[0]
except Exception:
self.module.fail_json(msg='Failed to read /etc/default/init')
else:
self.module.fail_json(msg='%s is not a supported option on target platform' % key)
def set(self, key, value):
"""Set the requested timezone through sm-set-timezone, an invalid timezone name
will be rejected and we have no further input validation to perform.
"""
if key == 'name':
cmd = 'sm-set-timezone %s' % value
(rc, stdout, stderr) = self.module.run_command(cmd)
if rc != 0:
self.module.fail_json(msg=stderr)
# sm-set-timezone knows no state and will always set the timezone.
# XXX: https://github.com/joyent/smtools/pull/2
m = re.match(r'^\* Changed (to)? timezone (to)? (%s).*' % value, stdout.splitlines()[1])
if not (m and m.groups()[-1] == value):
self.module.fail_json(msg='Failed to set timezone')
else:
self.module.fail_json(msg='%s is not a supported option on target platform' % key)
class DarwinTimezone(Timezone):
"""This is the timezone implementation for Darwin which, unlike other *BSD
implementations, uses the `systemsetup` command on Darwin to check/set
the timezone.
"""
regexps = dict(
name=re.compile(r'^\s*Time ?Zone\s*:\s*([^\s]+)', re.MULTILINE)
)
def __init__(self, module):
super(DarwinTimezone, self).__init__(module)
self.systemsetup = module.get_bin_path('systemsetup', required=True)
self.status = dict()
# Validate given timezone
if 'name' in self.value:
self._verify_timezone()
def _get_current_timezone(self, phase):
"""Lookup the current timezone via `systemsetup -gettimezone`."""
if phase not in self.status:
self.status[phase] = self.execute(self.systemsetup, '-gettimezone')
return self.status[phase]
def _verify_timezone(self):
tz = self.value['name']['planned']
# Lookup the list of supported timezones via `systemsetup -listtimezones`.
# Note: Skip the first line that contains the label 'Time Zones:'
out = self.execute(self.systemsetup, '-listtimezones').splitlines()[1:]
tz_list = list(map(lambda x: x.strip(), out))
if tz not in tz_list:
self.abort('given timezone "%s" is not available' % tz)
return tz
def get(self, key, phase):
if key == 'name':
status = self._get_current_timezone(phase)
value = self.regexps[key].search(status).group(1)
return value
else:
self.module.fail_json(msg='%s is not a supported option on target platform' % key)
def set(self, key, value):
if key == 'name':
self.execute(self.systemsetup, '-settimezone', value, log=True)
else:
self.module.fail_json(msg='%s is not a supported option on target platform' % key)
class BSDTimezone(Timezone):
"""This is the timezone implementation for *BSD which works simply through
updating the `/etc/localtime` symlink to point to a valid timezone name under
`/usr/share/zoneinfo`.
"""
def __init__(self, module):
super(BSDTimezone, self).__init__(module)
def __get_timezone(self):
zoneinfo_dir = '/usr/share/zoneinfo/'
localtime_file = '/etc/localtime'
# Strategy 1:
# If /etc/localtime does not exist, assum the timezone is UTC.
if not os.path.exists(localtime_file):
self.module.warn('Could not read /etc/localtime. Assuming UTC.')
return 'UTC'
# Strategy 2:
# Follow symlink of /etc/localtime
zoneinfo_file = localtime_file
while not zoneinfo_file.startswith(zoneinfo_dir):
try:
zoneinfo_file = os.readlink(localtime_file)
except OSError:
# OSError means "end of symlink chain" or broken link.
break
else:
return zoneinfo_file.replace(zoneinfo_dir, '')
# Strategy 3:
# (If /etc/localtime is not symlinked)
# Check all files in /usr/share/zoneinfo and return first non-link match.
for dname, dummy, fnames in sorted(os.walk(zoneinfo_dir)):
for fname in sorted(fnames):
zoneinfo_file = os.path.join(dname, fname)
if not os.path.islink(zoneinfo_file) and filecmp.cmp(zoneinfo_file, localtime_file):
return zoneinfo_file.replace(zoneinfo_dir, '')
# Strategy 4:
# As a fall-back, return 'UTC' as default assumption.
self.module.warn('Could not identify timezone name from /etc/localtime. Assuming UTC.')
return 'UTC'
def get(self, key, phase):
"""Lookup the current timezone by resolving `/etc/localtime`."""
if key == 'name':
return self.__get_timezone()
else:
self.module.fail_json(msg='%s is not a supported option on target platform' % key)
def set(self, key, value):
if key == 'name':
# First determine if the requested timezone is valid by looking in
# the zoneinfo directory.
zonefile = '/usr/share/zoneinfo/' + value
try:
if not os.path.isfile(zonefile):
self.module.fail_json(msg='%s is not a recognized timezone' % value)
except Exception:
self.module.fail_json(msg='Failed to stat %s' % zonefile)
# Now (somewhat) atomically update the symlink by creating a new
# symlink and move it into place. Otherwise we have to remove the
# original symlink and create the new symlink, however that would
# create a race condition in case another process tries to read
# /etc/localtime between removal and creation.
suffix = "".join([random.choice(string.ascii_letters + string.digits) for x in range(0, 10)])
new_localtime = '/etc/localtime.' + suffix
try:
os.symlink(zonefile, new_localtime)
os.rename(new_localtime, '/etc/localtime')
except Exception:
os.remove(new_localtime)
self.module.fail_json(msg='Could not update /etc/localtime')
else:
self.module.fail_json(msg='%s is not a supported option on target platform' % key)
class AIXTimezone(Timezone):
"""This is a Timezone manipulation class for AIX instances.
It uses the C(chtz) utility to set the timezone, and
inspects C(/etc/environment) to determine the current timezone.
While AIX time zones can be set using two formats (POSIX and
Olson) the preferred method is Olson.
See the following article for more information:
https://developer.ibm.com/articles/au-aix-posix/
NB: AIX needs to be rebooted in order for the change to be
activated.
"""
def __init__(self, module):
super(AIXTimezone, self).__init__(module)
self.settimezone = self.module.get_bin_path('chtz', required=True)
def __get_timezone(self):
""" Return the current value of TZ= in /etc/environment """
try:
f = open('/etc/environment', 'r')
etcenvironment = f.read()
f.close()
except Exception:
self.module.fail_json(msg='Issue reading contents of /etc/environment')
match = re.search(r'^TZ=(.*)$', etcenvironment, re.MULTILINE)
if match:
return match.group(1)
else:
return None
def get(self, key, phase):
"""Lookup the current timezone name in `/etc/environment`. If anything else
is requested, or if the TZ field is not set we fail.
"""
if key == 'name':
return self.__get_timezone()
else:
self.module.fail_json(msg='%s is not a supported option on target platform' % key)
def set(self, key, value):
"""Set the requested timezone through chtz, an invalid timezone name
will be rejected and we have no further input validation to perform.
"""
if key == 'name':
# chtz seems to always return 0 on AIX 7.2, even for invalid timezone values.
# It will only return non-zero if the chtz command itself fails, it does not check for
# valid timezones. We need to perform a basic check to confirm that the timezone
# definition exists in /usr/share/lib/zoneinfo
# This does mean that we can only support Olson for now. The below commented out regex
# detects Olson date formats, so in the future we could detect Posix or Olson and
# act accordingly.
# regex_olson = re.compile('^([a-z0-9_\-\+]+\/?)+$', re.IGNORECASE)
# if not regex_olson.match(value):
# msg = 'Supplied timezone (%s) does not appear to a be valid Olson string' % value
# self.module.fail_json(msg=msg)
# First determine if the requested timezone is valid by looking in the zoneinfo
# directory.
zonefile = '/usr/share/lib/zoneinfo/' + value
try:
if not os.path.isfile(zonefile):
self.module.fail_json(msg='%s is not a recognized timezone.' % value)
except Exception:
self.module.fail_json(msg='Failed to check %s.' % zonefile)
# Now set the TZ using chtz
cmd = 'chtz %s' % value
(rc, stdout, stderr) = self.module.run_command(cmd)
if rc != 0:
self.module.fail_json(msg=stderr)
# The best condition check we can do is to check the value of TZ after making the
# change.
TZ = self.__get_timezone()
if TZ != value:
msg = 'TZ value does not match post-change (Actual: %s, Expected: %s).' % (TZ, value)
self.module.fail_json(msg=msg)
else:
self.module.fail_json(msg='%s is not a supported option on target platform' % key)
def main():
# Construct 'module' and 'tz'
module = AnsibleModule(
argument_spec=dict(
hwclock=dict(type='str', choices=['local', 'UTC'], aliases=['rtc']),
name=dict(type='str'),
),
required_one_of=[
['hwclock', 'name']
],
supports_check_mode=True,
)
tz = Timezone(module)
# Check the current state
tz.check(phase='before')
if module.check_mode:
diff = tz.diff('before', 'planned')
# In check mode, 'planned' state is treated as 'after' state
diff['after'] = diff.pop('planned')
else:
# Make change
tz.change()
# Check the current state
tz.check(phase='after')
# Examine if the current state matches planned state
(after, planned) = tz.diff('after', 'planned').values()
if after != planned:
tz.abort('still not desired state, though changes have made - '
'planned: %s, after: %s' % (str(planned), str(after)))
diff = tz.diff('before', 'after')
changed = (diff['before'] != diff['after'])
if len(tz.msg) > 0:
module.exit_json(changed=changed, diff=diff, msg='\n'.join(tz.msg))
else:
module.exit_json(changed=changed, diff=diff)
if __name__ == '__main__':
main()
| 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 |
|