Add Openstack Undercloud backup
This new option allows to call the Mistral workflow to run an Undercloud full backup. Usage: openstack undercloud backup [--add-path ADD_FILES_TO_BACKUP] The --add-path allows to add additional files or folders to the Undercloud backup, for example: openstack undercloud backup --add-path /etc/hosts \ --add-path /var/log/ Depends-on: Iebd67568d5e72967e694b88fc8c73361543929a1 Change-Id: Ief10f5313244d2848b6de604e0493a51db1ed30f Related bp undercloud-backup-restore
This commit is contained in:
parent
11b659aea0
commit
eaaf2e8bc5
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
features:
|
||||
- Add a new option to the TripleO client in order to create an Undercloud
|
||||
backup.
|
||||
Usage, openstack undercloud backup [--add-path ADD_FILES_TO_BACKUP]
|
|
@ -93,6 +93,6 @@ openstack.tripleoclient.v1 =
|
|||
undercloud_deploy = tripleoclient.v1.undercloud_deploy:DeployUndercloud
|
||||
undercloud_install = tripleoclient.v1.undercloud:InstallUndercloud
|
||||
undercloud_upgrade = tripleoclient.v1.undercloud:UpgradeUndercloud
|
||||
|
||||
undercloud_backup = tripleoclient.v1.undercloud_backup:BackupUndercloud
|
||||
oslo.config.opts =
|
||||
undercloud_config = tripleoclient.v1.undercloud_config:list_opts
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
# Copyright 2018 Red Hat, Inc.
|
||||
#
|
||||
# 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 mock
|
||||
|
||||
from osc_lib.tests import utils
|
||||
from tripleoclient.v1 import undercloud_backup
|
||||
|
||||
|
||||
class TestUndercloudBackup(utils.TestCommand):
|
||||
|
||||
def setUp(self):
|
||||
super(TestUndercloudBackup, self).setUp()
|
||||
|
||||
# Get the command object to test
|
||||
self.cmd = undercloud_backup.BackupUndercloud(self.app, None)
|
||||
self.app.client_manager.workflow_engine = mock.Mock()
|
||||
self.workflow = self.app.client_manager.workflow_engine
|
||||
|
||||
@mock.patch('tripleoclient.workflows.undercloud_backup.backup',
|
||||
autospec=True)
|
||||
def test_undercloud_backup_noargs(self, plan_mock):
|
||||
arglist = []
|
||||
verifylist = []
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
self.cmd.take_action(parsed_args)
|
||||
plan_mock.assert_called_once_with(
|
||||
mock.ANY, {'sources_path': '/home/stack/'})
|
||||
|
||||
@mock.patch('tripleoclient.workflows.undercloud_backup.backup',
|
||||
autospec=True)
|
||||
def test_undercloud_backup_withargs(self, plan_mock):
|
||||
arglist = [
|
||||
'--add-path',
|
||||
'/tmp/foo.yaml',
|
||||
'--add-path',
|
||||
'/tmp/bar.yaml'
|
||||
]
|
||||
verifylist = []
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
self.cmd.take_action(parsed_args)
|
||||
plan_mock.assert_called_once_with(
|
||||
mock.ANY,
|
||||
{'sources_path': '/home/stack/,/tmp/bar.yaml,/tmp/foo.yaml'})
|
|
@ -0,0 +1,59 @@
|
|||
# Copyright 2017 Red Hat, Inc.
|
||||
#
|
||||
# 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 mock
|
||||
|
||||
from osc_lib.tests import utils
|
||||
from tripleoclient.workflows import undercloud_backup
|
||||
|
||||
|
||||
class TestUndercloudBackup(utils.TestCommand):
|
||||
|
||||
def setUp(self):
|
||||
super(TestUndercloudBackup, self).setUp()
|
||||
self.app.client_manager = mock.Mock()
|
||||
self.app.client_manager.workflow_engine = self.workflow = mock.Mock()
|
||||
self.tripleoclient = mock.Mock()
|
||||
self.websocket = mock.Mock()
|
||||
self.websocket.__enter__ = lambda s: self.websocket
|
||||
self.websocket.__exit__ = lambda s, *exc: None
|
||||
self.tripleoclient.messaging_websocket.return_value = self.websocket
|
||||
self.app.client_manager.tripleoclient = self.tripleoclient
|
||||
|
||||
@mock.patch('tripleoclient.workflows.base.wait_for_messages')
|
||||
@mock.patch('tripleoclient.workflows.base.start_workflow')
|
||||
def test_run_backup(self, start_wf_mock, messages_mock):
|
||||
messages_mock.return_value = []
|
||||
fetch_name = 'tripleo.undercloud_backup.v1.backup'
|
||||
fetch_input = {
|
||||
'sources_path': '/home/stack/'
|
||||
}
|
||||
undercloud_backup.backup(self.app.client_manager, fetch_input)
|
||||
start_wf_mock.assert_called_once_with(self.workflow,
|
||||
fetch_name,
|
||||
workflow_input=fetch_input)
|
||||
|
||||
@mock.patch('tripleoclient.workflows.base.wait_for_messages')
|
||||
@mock.patch('tripleoclient.workflows.base.start_workflow')
|
||||
def test_run_backup_with_args(self, start_wf_mock, messages_mock):
|
||||
messages_mock.return_value = []
|
||||
fetch_name = 'tripleo.undercloud_backup.v1.backup'
|
||||
fetch_input = {
|
||||
'sources_path': '/tmp/file1.txt,/home/stack/'
|
||||
}
|
||||
undercloud_backup.backup(self.app.client_manager, fetch_input)
|
||||
start_wf_mock.assert_called_once_with(self.workflow,
|
||||
fetch_name,
|
||||
workflow_input=fetch_input)
|
|
@ -0,0 +1,84 @@
|
|||
# Copyright 2018 Red Hat, Inc.
|
||||
#
|
||||
# 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 argparse
|
||||
import logging
|
||||
|
||||
from openstackclient.i18n import _
|
||||
from osc_lib.command import command
|
||||
from tripleoclient.workflows import undercloud_backup
|
||||
|
||||
LOG = logging.getLogger(__name__ + ".BackupUndercloud")
|
||||
|
||||
|
||||
class BackupUndercloud(command.Command):
|
||||
"""Backup the undercloud"""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = argparse.ArgumentParser(
|
||||
description=self.get_description(),
|
||||
prog=prog_name,
|
||||
add_help=False
|
||||
)
|
||||
|
||||
# Parameter to choose the files to backup
|
||||
parser.add_argument(
|
||||
'--add-path',
|
||||
action='append',
|
||||
default=['/home/stack/'],
|
||||
help=_("Add additional files to backup. "
|
||||
"Defaults to: /home/stack/ "
|
||||
"i.e. --add-path /this/is/a/folder/ "
|
||||
" --add-path /this/is/a/texfile.txt")
|
||||
)
|
||||
return parser
|
||||
|
||||
def _run_backup_undercloud(self, parsed_args):
|
||||
|
||||
clients = self.app.client_manager
|
||||
|
||||
files_to_backup = ','.join(sorted(list(set(parsed_args.add_path))))
|
||||
|
||||
# Define the backup sources_path (files to backup).
|
||||
# This is a comma separated string.
|
||||
# I.e. "/this/is/a/folder/,/this/is/a/texfile.txt"
|
||||
workflow_input = {
|
||||
"sources_path": files_to_backup
|
||||
}
|
||||
|
||||
LOG.debug('Launch the Undercloud Backup')
|
||||
try:
|
||||
output = undercloud_backup.backup(clients, workflow_input)
|
||||
LOG.info(output)
|
||||
except Exception as e:
|
||||
print ("Undercloud backup finished with errors")
|
||||
print ('Output: {}'.format(e))
|
||||
LOG.info(e)
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
|
||||
LOG.info(
|
||||
'\n'
|
||||
' #############################################################\n'
|
||||
' # Disclaimer #\n'
|
||||
' # Backup verification is the End Users responsibility #\n'
|
||||
' # Please verify backup integrity before any possible #\n'
|
||||
' # disruptive actions against the Undercloud. The resulting #\n'
|
||||
' # backup file path will be shown on a successful execution. #\n'
|
||||
' # #\n'
|
||||
' # .-Stay safe and avoid future issues-. #\n'
|
||||
' #############################################################\n')
|
||||
|
||||
self._run_backup_undercloud(parsed_args)
|
|
@ -0,0 +1,35 @@
|
|||
# Copyright 2018 Red Hat, Inc.
|
||||
#
|
||||
# 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 pprint
|
||||
|
||||
from tripleoclient.workflows import base
|
||||
|
||||
|
||||
def backup(clients, workflow_input):
|
||||
|
||||
workflow_client = clients.workflow_engine
|
||||
tripleoclients = clients.tripleoclient
|
||||
|
||||
with tripleoclients.messaging_websocket() as ws:
|
||||
execution = base.start_workflow(
|
||||
workflow_client,
|
||||
'tripleo.undercloud_backup.v1.backup',
|
||||
workflow_input=workflow_input
|
||||
)
|
||||
|
||||
for payload in base.wait_for_messages(workflow_client, ws, execution):
|
||||
if 'message' in payload:
|
||||
assert payload['status'] == "SUCCESS", pprint.pformat(payload)
|
||||
print('Undercloud Backup succeed')
|
Loading…
Reference in New Issue