/usr/sbin/fence_ironic is in fence-agents 4.0.25-2ubuntu1.
This file is owned by root:root, with mode 0o755.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | #!/usr/bin/python -tt
import atexit
import logging
import os
import re
import sys
from pipes import quote
sys.path.append("/usr/share/fence")
from fencing import *
from fencing import fail_usage, is_executable, run_command, run_delay
#BEGIN_VERSION_GENERATION
RELEASE_VERSION="4.0.25"
BUILD_DATE="(built Sat, 10 Feb 2018 00:55:27 -0800)"
REDHAT_COPYRIGHT="Copyright (C) Red Hat, Inc. 2004-2010 All rights reserved."
#END_VERSION_GENERATION
def get_name_or_uuid(options):
return options["--uuid"] if "--uuid" in options else options["--plug"]
def get_power_status(_, options):
output = ironic_run_command(options, "status")
stdout = output[1]
match = re.search('power[\\s]*([a-zA-Z]{2,3})', str(stdout))
status = match.group(1) if match else None
return status
def set_power_status(_, options):
ironic_run_command(options, options["--action"])
return
def get_devices_list(_, options):
nodes = {}
output = ironic_run_command(options, "list")
stdout = output[1]
for line in stdout.splitlines():
uuid = "UUID"
try:
(uuid, name, state) = line.split(',')
except ValueError:
pass
if "UUID" in uuid:
continue # skip line header
match = re.search('power[\\s]*([a-zA-Z]{2,3})', state)
status = match.group(1) if match else None
nodes[uuid] = (name, status)
return nodes
def ironic_run_command(options, action, timeout=None):
cmd = options["--openstack-path"] + " baremetal"
env = os.environ.copy()
# --username / -l
if "--username" in options and len(options["--username"]) != 0:
env["OS_USERNAME"] = options["--username"]
# --password / -p
if "--password" in options:
env["OS_PASSWORD"] = options["--password"]
# --tenant-name -t
if "--tenant-name" in options:
env["OS_TENANT_NAME"] = options["--tenant-name"]
# --auth-url
if "--auth-url" in options:
env["OS_AUTH_URL"] = options["--auth-url"]
# --action / -o
if action == "status":
cmd += " show %s -c power_state --format value" % (get_name_or_uuid(options))
elif action in ["on", "off"]:
cmd += " power %s %s" % (action, get_name_or_uuid(options))
elif action == "list":
cmd += " list -c 'Instance UUID' -c Name -c 'Power State' --format csv --quote minimal"
logging.debug("cmd -> %s" % cmd)
return run_command(options, cmd, timeout, env)
def define_new_opts():
all_opt["auth-url"] = {
"getopt" : ":",
"longopt" : "auth-url",
"help" : "--auth-url=[authurl] Auth URL",
"required" : "1",
"shortdesc" : "Keystone Admin Auth URL",
"order": 1
}
all_opt["tenant-name"] = {
"getopt" : "t:",
"longopt" : "tenant-name",
"help" : "-t, --tenant-name=[tenant] Tenantname",
"required" : "0",
"shortdesc" : "Keystone Admin Tenant",
"default": "admin",
"order": 1
}
all_opt["openstack-path"] = {
"getopt" : ":",
"longopt" : "openstack-path",
"help" : "--openstack-path=[path] Path to openstack binary",
"required" : "0",
"shortdesc" : "Path to the OpenStack binary",
"default" : "/usr/bin/openstack",
"order": 200
}
def main():
atexit.register(atexit_handler)
device_opt = ["login", "passwd", "port", "auth-url", "tenant-name", "openstack-path"]
define_new_opts()
options = check_input(device_opt, process_input(device_opt))
docs = {}
docs["shortdesc"] = "Fence agent for OpenStack's Ironic (Bare Metal as a service) service"
docs["longdesc"] = "fence_ironic is a Fencing agent \
which can be used with machines controlled by the Ironic service. \
This agent calls the openstack CLI. \
WARNING! This fence agent is not intended for production use. Relying on a functional ironic service for fencing is not a good design choice."
docs["vendorurl"] = "https://wiki.openstack.org/wiki/Ironic"
show_docs(options, docs)
run_delay(options)
if not is_executable(options["--openstack-path"]):
fail_usage("openstack tool not found or not accessible")
result = fence_action(None, options, set_power_status, get_power_status, get_devices_list)
sys.exit(result)
if __name__ == "__main__":
main()
|