Merge "Add overcloud_parameters.GenerateFencingParameters."
This commit is contained in:
commit
45e8fa9721
@ -0,0 +1,6 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Adds `overcloud generate fencing` command, which outputs an environment
|
||||
file which can be used to configure node fencing in HA deployments.
|
||||
Currently IPMI and virtual (non-production) deployments are supported.
|
@ -83,5 +83,6 @@ openstack.tripleoclient.v1 =
|
||||
overcloud_update_clear_breakpoints = tripleoclient.v1.overcloud_update:ClearBreakpointsOvercloud
|
||||
overcloud_update_stack = tripleoclient.v1.overcloud_update:UpdateOvercloud
|
||||
overcloud_execute = tripleoclient.v1.overcloud_execute:RemoteExecute
|
||||
overcloud_generate_fencing = tripleoclient.v1.overcloud_parameters:GenerateFencingParameters
|
||||
undercloud_install = tripleoclient.v1.undercloud:InstallUndercloud
|
||||
undercloud_upgrade = tripleoclient.v1.undercloud:UpgradeUndercloud
|
||||
|
@ -83,3 +83,91 @@ class TestSetParameters(utils.TestCommand):
|
||||
self.assertRaises(
|
||||
exceptions.InvalidConfiguration,
|
||||
self._test_set_parameters, ".invalid", yaml.dump, {})
|
||||
|
||||
|
||||
class TestGenerateFencingParameters(utils.TestCommand):
|
||||
|
||||
def setUp(self):
|
||||
super(TestGenerateFencingParameters, self).setUp()
|
||||
|
||||
self.cmd = overcloud_parameters.GenerateFencingParameters(self.app,
|
||||
None)
|
||||
self.app.client_manager.workflow_engine = mock.Mock()
|
||||
|
||||
self.workflow = self.app.client_manager.workflow_engine
|
||||
|
||||
def test_generate_parameters(self):
|
||||
nodes_file = tempfile.NamedTemporaryFile(suffix='.json', delete=False,
|
||||
mode="wt")
|
||||
self.addCleanup(os.unlink, nodes_file.name)
|
||||
nodes_file.write("""
|
||||
{
|
||||
"nodes": [
|
||||
{
|
||||
"name": "control-0",
|
||||
"pm_password": "control-0-password",
|
||||
"pm_type": "pxe_ipmitool",
|
||||
"pm_user": "control-0-admin",
|
||||
"pm_addr": "0.1.2.3",
|
||||
"pm_port": "0123",
|
||||
"mac": [
|
||||
"00:11:22:33:44:55"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "control-1",
|
||||
"pm_password": "control-1-password",
|
||||
"pm_type": "pxe_ssh",
|
||||
"pm_user": "control-1-admin",
|
||||
"pm_addr": "1.2.3.4",
|
||||
"mac": [
|
||||
"11:22:33:44:55:66"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
""")
|
||||
nodes_file.close()
|
||||
|
||||
os.environ["OS_USERNAME"] = "test_os_username"
|
||||
os.environ["OS_PASSWORD"] = "test_os_password"
|
||||
os.environ["OS_AUTH_URL"] = "test://auth.url"
|
||||
os.environ["OS_TENANT_NAME"] = "test_os_tenant_name"
|
||||
|
||||
arglist = [nodes_file.name]
|
||||
verifylist = []
|
||||
|
||||
self.workflow.action_executions.create.return_value = mock.MagicMock(
|
||||
output='{"result":[]}')
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
self.cmd.take_action(parsed_args)
|
||||
|
||||
self.workflow.action_executions.create.assert_called_once_with(
|
||||
'tripleo.parameters.generate_fencing',
|
||||
{
|
||||
'fence_action': 'reboot',
|
||||
'nodes_json': [
|
||||
{
|
||||
u'mac': [u'00:11:22:33:44:55'],
|
||||
u'name': u'control-0',
|
||||
u'pm_port': u'0123',
|
||||
u'pm_addr': u'0.1.2.3',
|
||||
u'pm_type': u'pxe_ipmitool',
|
||||
u'pm_password': u'control-0-password',
|
||||
u'pm_user': u'control-0-admin'
|
||||
},
|
||||
{
|
||||
u'name': u'control-1',
|
||||
u'pm_addr': u'1.2.3.4',
|
||||
u'pm_type': u'pxe_ssh',
|
||||
u'pm_user': u'control-1-admin',
|
||||
u'pm_password': u'control-1-password',
|
||||
u'mac': [u'11:22:33:44:55:66']
|
||||
}],
|
||||
'delay': None,
|
||||
'os_auth': {},
|
||||
'ipmi_cipher': None,
|
||||
'ipmi_lanplus': False,
|
||||
'ipmi_privlvl': None
|
||||
},
|
||||
run_sync=True, save_result=True)
|
||||
|
@ -13,12 +13,15 @@
|
||||
import argparse
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import yaml
|
||||
|
||||
from osc_lib.command import command
|
||||
from osc_lib.i18n import _
|
||||
|
||||
from tripleoclient import exceptions
|
||||
from tripleoclient import utils
|
||||
from tripleoclient.workflows import base
|
||||
from tripleoclient.workflows import parameters
|
||||
|
||||
|
||||
@ -62,3 +65,77 @@ class SetParameters(command.Command):
|
||||
container=name,
|
||||
parameters=params
|
||||
)
|
||||
|
||||
|
||||
class GenerateFencingParameters(command.Command):
|
||||
"""Generate fencing parameters"""
|
||||
|
||||
log = logging.getLogger(__name__ + ".GenerateFencing")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(GenerateFencingParameters, self).get_parser(prog_name)
|
||||
parser.add_argument('-a', '--action', dest='fence_action',
|
||||
default='reboot',
|
||||
help=_('Operation to perform. Valid operations: '
|
||||
'on, off, reboot, status, list, diag, '
|
||||
'monitor or metadata. Defaults to: reboot'))
|
||||
parser.add_argument('--delay', type=int,
|
||||
help=_('Wait DELAY seconds before fencing is '
|
||||
'started'))
|
||||
parser.add_argument('--ipmi-lanplus',
|
||||
action='store_true',
|
||||
help=_('Use Lanplus. Defaults to: false'))
|
||||
parser.add_argument('--ipmi-cipher', type=int,
|
||||
help=_('Ciphersuite to use (same as ipmitool -C '
|
||||
'parameter.'))
|
||||
parser.add_argument('--ipmi-level',
|
||||
help=_('Privilegel level on IPMI device. Valid '
|
||||
'levels: callback, user, operator, '
|
||||
'administrator.'))
|
||||
parser.add_argument('--output', type=argparse.FileType('w'),
|
||||
help=_('Write parameters to a file'))
|
||||
parser.add_argument('instackenv', type=argparse.FileType('r'))
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
nodes_config = utils.parse_env_file(parsed_args.instackenv)
|
||||
|
||||
# We only need to collect OpenStack client authentication data
|
||||
# if we have nodes using Ironic's pxe_ssh driver. If there are
|
||||
# any, we'll use the fence_ironic fencing agent, which requires
|
||||
# the auth data.
|
||||
os_auth = None
|
||||
for node in nodes_config:
|
||||
if node["pm_type"] == "pxe_ssh":
|
||||
os_auth = {}
|
||||
if os_auth:
|
||||
try:
|
||||
os_auth["auth_url"] = os.environ["OS_AUTH_URL"]
|
||||
os_auth["login"] = os.environ["OS_USERNAME"]
|
||||
os_auth["passwd"] = os.environ["OS_PASSWORD"]
|
||||
os_auth["tenant_name"] = os.environ["OS_TENANT_NAME"]
|
||||
except KeyError:
|
||||
# This really shouldn't happen since we're running in
|
||||
# tripleoclient
|
||||
raise ValueError(
|
||||
_("Unable to find one or more of OS_AUTH_URL, "
|
||||
"OS_USERNAME, OS_PASSWORD or OS_TENANT_NAME in the "
|
||||
"environment."))
|
||||
workflow_input = {
|
||||
'nodes_json': nodes_config,
|
||||
'os_auth': os_auth,
|
||||
'fence_action': parsed_args.fence_action,
|
||||
'delay': parsed_args.delay,
|
||||
'ipmi_privlvl': parsed_args.ipmi_level,
|
||||
'ipmi_cipher': parsed_args.ipmi_cipher,
|
||||
'ipmi_lanplus': parsed_args.ipmi_lanplus,
|
||||
}
|
||||
result = base.call_action(
|
||||
self.app.client_manager.workflow_engine,
|
||||
'tripleo.parameters.generate_fencing',
|
||||
**workflow_input)
|
||||
fencing_parameters = yaml.safe_dump(result, default_flow_style=False)
|
||||
if parsed_args.output:
|
||||
parsed_args.output.write(fencing_parameters)
|
||||
else:
|
||||
print(fencing_parameters)
|
||||
|
Loading…
x
Reference in New Issue
Block a user