
Set flake8-import-order version to 0.17.1 Full py3 compatible version. Add all Python3 modules to stdlib list. Also includes fix to an enum34 dependency bug. Change-Id: I58dd80fc33942656c69ce67ee523a1d57f693e93
162 lines
5.3 KiB
Python
162 lines
5.3 KiB
Python
#!/usr/bin/env python3
|
|
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
import json
|
|
import os.path
|
|
import time
|
|
|
|
from ansible.module_utils.basic import AnsibleModule # noqa
|
|
|
|
|
|
DOCUMENTATION = '''
|
|
---
|
|
module: virtualbmc_domain
|
|
short_description: Manages domains in VirtualBMC.
|
|
'''
|
|
|
|
|
|
RETRIES = 60
|
|
INTERVAL = 0.5
|
|
|
|
|
|
def _vbmc_command(module, args):
|
|
cmd = [module.params["vbmc_path"], "--no-daemon"]
|
|
if module.params["log_directory"]:
|
|
log_file = os.path.join(module.params["log_directory"],
|
|
"vbmc-%s.log" % module.params["domain"])
|
|
cmd += ["--log-file", log_file]
|
|
cmd += args
|
|
result = module.run_command(cmd, check_rc=True)
|
|
rc, out, err = result
|
|
return out
|
|
|
|
|
|
def _get_domain(module, allow_missing=False):
|
|
domain_name = module.params["domain"]
|
|
if allow_missing:
|
|
# Use a list to avoid failing if the domain does not exist.
|
|
domains = _vbmc_command(module, ["list", "-f", "json"])
|
|
domains = json.loads(domains)
|
|
# vbmc list returns a list of dicts. Transform into a dict of dicts
|
|
# keyed by domain name.
|
|
domains = {d["Domain name"]: d for d in domains}
|
|
try:
|
|
return domains[domain_name]
|
|
except KeyError:
|
|
return None
|
|
else:
|
|
domain = _vbmc_command(module, ["show", domain_name, "-f", "json"])
|
|
domain = json.loads(domain)
|
|
domain = {field["Property"]: field["Value"] for field in domain}
|
|
return domain
|
|
|
|
|
|
def _add_domain(module):
|
|
domain_name = module.params["domain"]
|
|
args = [
|
|
"add", domain_name,
|
|
"--address", module.params["ipmi_address"],
|
|
"--port", str(module.params["ipmi_port"]),
|
|
"--username", module.params["ipmi_username"],
|
|
"--password", module.params["ipmi_password"],
|
|
]
|
|
if module.params["libvirt_uri"]:
|
|
args += ["--libvirt-uri", module.params["libvirt_uri"]]
|
|
_vbmc_command(module, args)
|
|
|
|
|
|
def _wait_for_existence(module, exists):
|
|
"""Wait for the domain to exist or cease existing."""
|
|
for _ in range(RETRIES):
|
|
domain = _get_domain(module, allow_missing=True)
|
|
if (exists and domain) or (not exists and not domain):
|
|
return
|
|
time.sleep(INTERVAL)
|
|
action = "added" if exists else "deleted"
|
|
module.fail_json(msg="Timed out waiting for domain %s to be %s" %
|
|
(module.params['domain'], action))
|
|
|
|
|
|
def _wait_for_status(module, status):
|
|
"""Wait for the domain to reach a particular status."""
|
|
for _ in range(RETRIES):
|
|
domain = _get_domain(module)
|
|
if domain["status"] == status:
|
|
return
|
|
time.sleep(INTERVAL)
|
|
module.fail_json(msg="Timed out waiting for domain %s to reach status "
|
|
"%s" % (module.params['domain'], status))
|
|
|
|
|
|
def _virtualbmc_domain(module):
|
|
"""Configure a VirtualBMC domain."""
|
|
changed = False
|
|
domain_name = module.params["domain"]
|
|
|
|
# Even if the domain is present in VBMC, we can't guarantee that it's
|
|
# configured correctly. It's easiest to delete and re-add it; this should
|
|
# involve minimal downtime.
|
|
domain = _get_domain(module, allow_missing=True)
|
|
if domain and domain["Status"] == "running":
|
|
if not module.check_mode:
|
|
module.debug("Stopping domain %s" % domain_name)
|
|
_vbmc_command(module, ["stop", domain_name])
|
|
_wait_for_status(module, "down")
|
|
changed = True
|
|
|
|
if domain:
|
|
if not module.check_mode:
|
|
module.debug("Deleting domain %s" % domain_name)
|
|
_vbmc_command(module, ["delete", domain_name])
|
|
_wait_for_existence(module, False)
|
|
changed = True
|
|
|
|
if module.params['state'] == 'present':
|
|
if not module.check_mode:
|
|
module.debug("Adding domain %s" % domain_name)
|
|
_add_domain(module)
|
|
_wait_for_existence(module, True)
|
|
|
|
module.debug("Starting domain %s" % domain_name)
|
|
_vbmc_command(module, ["start", domain_name])
|
|
_wait_for_status(module, "running")
|
|
changed = True
|
|
|
|
return {"changed": changed}
|
|
|
|
|
|
def main():
|
|
module = AnsibleModule(
|
|
argument_spec=dict(
|
|
domain=dict(type='str', required=True),
|
|
ipmi_address=dict(type='str', required=True),
|
|
ipmi_port=dict(type='int', required=True),
|
|
ipmi_username=dict(type='str', required=True),
|
|
ipmi_password=dict(type='str', required=True, no_log=True),
|
|
libvirt_uri=dict(type='str'),
|
|
log_directory=dict(type='str'),
|
|
state=dict(type=str, default='present',
|
|
choices=['present', 'absent']),
|
|
vbmc_path=dict(type='str'),
|
|
),
|
|
supports_check_mode=True,
|
|
)
|
|
|
|
result = _virtualbmc_domain(module)
|
|
module.exit_json(**result)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|