Add commands to operate snapshot config
Added two commands to dump snapshot config and provide it for snapshot task Will download default config and dump it to stdout fuel snapshot --conf > conf.yaml Next command will accept config as input and bypass it to snapshot generation request fuel snapshot < conf.yaml This is required to overwrite certain parameters if needed, some of those are: - target directory of snapshot generation - timeout of snapshot generation procedure - exclusion/inclusion of certain directories Depends on I5e01a7459cefe49a128192d82dd827f02866f909 Related-Bug: 1382511 Related-Bug: 1420054 DocImpact Change-Id: I1ddab26fba1346dad30955289e7d28f4d3aa1562
This commit is contained in:
@@ -207,7 +207,7 @@ class EnvironmentAction(Action):
|
||||
full_path = '{0}/deployment_tasks'.format(dir_path)
|
||||
if params.download:
|
||||
tasks = cluster.get_deployment_tasks()
|
||||
self.serializer.write_to_file(full_path, tasks)
|
||||
self.serializer.write_to_path(full_path, tasks)
|
||||
print("Deployment tasks for cluster {0} "
|
||||
"downloaded into {1}.yaml.".format(cluster.id, full_path))
|
||||
elif params.upload:
|
||||
|
||||
@@ -95,7 +95,7 @@ class ReleaseAction(Action):
|
||||
full_path = '{0}/networks'.format(dir_path)
|
||||
if params.download:
|
||||
networks = release.get_networks()
|
||||
self.serializer.write_to_file(full_path, networks)
|
||||
self.serializer.write_to_path(full_path, networks)
|
||||
print("Networks for release {0} "
|
||||
"downloaded into {1}.yaml".format(release.id, full_path))
|
||||
elif params.upload:
|
||||
@@ -117,7 +117,7 @@ class ReleaseAction(Action):
|
||||
full_path = '{0}/deployment_tasks'.format(dir_path)
|
||||
if params.download:
|
||||
tasks = release.get_deployment_tasks()
|
||||
self.serializer.write_to_file(full_path, tasks)
|
||||
self.serializer.write_to_path(full_path, tasks)
|
||||
print("Deployment tasks for release {0} "
|
||||
"downloaded into {1}.yaml.".format(release.id, full_path))
|
||||
elif params.upload:
|
||||
|
||||
@@ -12,6 +12,10 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import sys
|
||||
|
||||
import yaml
|
||||
|
||||
from fuelclient.cli.actions.base import Action
|
||||
import fuelclient.cli.arguments as Args
|
||||
from fuelclient.cli.formatting import download_snapshot_with_progress_bar
|
||||
@@ -27,8 +31,11 @@ class SnapshotAction(Action):
|
||||
super(SnapshotAction, self).__init__()
|
||||
self.args = (
|
||||
Args.get_dir_arg("Directory to which download snapshot."),
|
||||
Args.get_boolean_arg("conf",
|
||||
help_="Provide this flag to generate conf")
|
||||
)
|
||||
self.flag_func_map = (
|
||||
('conf', self.get_snapshot_config),
|
||||
(None, self.get_snapshot),
|
||||
)
|
||||
|
||||
@@ -38,8 +45,17 @@ class SnapshotAction(Action):
|
||||
|
||||
To download diagnostic snapshot to specific directory:
|
||||
fuel snapshot --dir path/to/directory
|
||||
|
||||
To specify config for snapshoting
|
||||
fuel snapshot < conf.yaml
|
||||
|
||||
"""
|
||||
snapshot_task = SnapshotTask.start_snapshot_task()
|
||||
if sys.stdin.isatty():
|
||||
conf = {}
|
||||
else:
|
||||
conf = yaml.load(sys.stdin.read())
|
||||
|
||||
snapshot_task = SnapshotTask.start_snapshot_task(conf)
|
||||
self.serializer.print_to_output(
|
||||
snapshot_task.data,
|
||||
"Generating dump..."
|
||||
@@ -49,3 +65,14 @@ class SnapshotAction(Action):
|
||||
snapshot_task.connection.root + snapshot_task.data["message"],
|
||||
directory=params.dir
|
||||
)
|
||||
|
||||
def get_snapshot_config(self, params):
|
||||
"""Download default config for snapshot
|
||||
|
||||
fuel snapshot --conf > dump_conf.yaml
|
||||
|
||||
To use json formatter
|
||||
fuel snapshot --conf --json
|
||||
"""
|
||||
conf = SnapshotTask.get_default_config()
|
||||
self.serializer.write_to_file(sys.stdout, conf)
|
||||
|
||||
@@ -74,10 +74,10 @@ class Serializer(object):
|
||||
path, self.format
|
||||
)
|
||||
|
||||
def write_to_file(self, path, data):
|
||||
def write_to_path(self, path, data):
|
||||
full_path = self.prepare_path(path)
|
||||
with open(full_path, "w+") as file_to_write:
|
||||
file_to_write.write(self.serializer["w"](data))
|
||||
self.write_to_file(file_to_write, data)
|
||||
return full_path
|
||||
|
||||
def read_from_file(self, path):
|
||||
@@ -87,6 +87,14 @@ class Serializer(object):
|
||||
with open(full_path, "r") as file_to_read:
|
||||
return self.serializer["r"](file_to_read.read())
|
||||
|
||||
def write_to_file(self, file_obj, data):
|
||||
"""Writes to opened file or file like object
|
||||
:param file_obj: opened file
|
||||
:param data: any serializable object
|
||||
"""
|
||||
serialized = self.serializer["w"](data)
|
||||
file_obj.write(serialized)
|
||||
|
||||
|
||||
class FileFormatBasedSerializer(Serializer):
|
||||
|
||||
|
||||
@@ -134,14 +134,14 @@ class Environment(BaseObject):
|
||||
|
||||
def write_network_data(self, network_data, directory=os.curdir,
|
||||
serializer=None):
|
||||
return (serializer or self.serializer).write_to_file(
|
||||
return (serializer or self.serializer).write_to_path(
|
||||
self.get_network_data_path(directory),
|
||||
network_data
|
||||
)
|
||||
|
||||
def write_settings_data(self, settings_data, directory=os.curdir,
|
||||
serializer=None):
|
||||
return (serializer or self.serializer).write_to_file(
|
||||
return (serializer or self.serializer).write_to_path(
|
||||
self.get_settings_data_path(directory),
|
||||
settings_data
|
||||
)
|
||||
@@ -262,7 +262,7 @@ class Environment(BaseObject):
|
||||
os.makedirs(dir_name)
|
||||
if isinstance(facts, dict):
|
||||
engine_file_path = os.path.join(dir_name, "engine")
|
||||
(serializer or self.serializer).write_to_file(
|
||||
(serializer or self.serializer).write_to_path(
|
||||
engine_file_path, facts["engine"])
|
||||
facts = facts["nodes"]
|
||||
name_template = u"{name}"
|
||||
@@ -273,7 +273,7 @@ class Environment(BaseObject):
|
||||
dir_name,
|
||||
name_template.format(**_fact)
|
||||
)
|
||||
(serializer or self.serializer).write_to_file(fact_path, _fact)
|
||||
(serializer or self.serializer).write_to_path(fact_path, _fact)
|
||||
return dir_name
|
||||
|
||||
def read_deployment_info(self, fact_type,
|
||||
|
||||
@@ -93,7 +93,7 @@ class Node(BaseObject):
|
||||
)
|
||||
if os.path.exists(attribute_path):
|
||||
os.remove(attribute_path)
|
||||
return (serializer or self.serializer).write_to_file(
|
||||
return (serializer or self.serializer).write_to_path(
|
||||
attribute_path,
|
||||
attributes
|
||||
)
|
||||
|
||||
@@ -95,6 +95,10 @@ class DeployTask(Task):
|
||||
class SnapshotTask(Task):
|
||||
|
||||
@classmethod
|
||||
def start_snapshot_task(cls):
|
||||
dump_task = cls.connection.put_request("logs/package", {})
|
||||
def start_snapshot_task(cls, conf):
|
||||
dump_task = cls.connection.put_request("logs/package", conf)
|
||||
return cls(dump_task["id"])
|
||||
|
||||
@classmethod
|
||||
def get_default_config(cls):
|
||||
return cls.connection.get_request("logs/package/config/default/")
|
||||
|
||||
58
fuelclient/tests/test_snapshot.py
Normal file
58
fuelclient/tests/test_snapshot.py
Normal file
@@ -0,0 +1,58 @@
|
||||
# Copyright 2015 Mirantis, 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.
|
||||
|
||||
|
||||
from mock import call
|
||||
from mock import patch
|
||||
|
||||
from fuelclient.tests import base
|
||||
|
||||
|
||||
class TestSnapshot(base.UnitTestCase):
|
||||
|
||||
@patch('fuelclient.cli.actions.snapshot.SnapshotTask.get_default_config')
|
||||
@patch('sys.stdout.write')
|
||||
def test_get_default_config(self, mwrite, mconf):
|
||||
|
||||
mconf.return_value = {'key': 'value'}
|
||||
|
||||
self.execute(['fuel', 'snapshot', '--conf'])
|
||||
self.assertEqual(mwrite.call_args_list, [call('key: value\n')])
|
||||
|
||||
@patch('fuelclient.cli.actions.snapshot.SnapshotTask.start_snapshot_task')
|
||||
@patch('fuelclient.cli.actions.snapshot.'
|
||||
'download_snapshot_with_progress_bar')
|
||||
@patch('sys.stdin')
|
||||
def test_snapshot_with_provided_conf(self, mstdin, mbar, mstart):
|
||||
conf = 'key: value\n'
|
||||
|
||||
mstdin.isatty.return_value = False
|
||||
mstdin.read.return_value = conf
|
||||
|
||||
self.execute(['fuel', 'snapshot'])
|
||||
|
||||
mstart.assert_called_once_with({'key': 'value'})
|
||||
self.assertEqual(mstdin.read.call_count, 1)
|
||||
|
||||
@patch('fuelclient.cli.actions.snapshot.SnapshotTask.start_snapshot_task')
|
||||
@patch('fuelclient.cli.actions.snapshot.'
|
||||
'download_snapshot_with_progress_bar')
|
||||
@patch('sys.stdin')
|
||||
def test_snapshot_without_conf(self, mstdin, mbar, mstart):
|
||||
|
||||
mstdin.isatty.return_value = True
|
||||
|
||||
self.execute(['fuel', 'snapshot'])
|
||||
|
||||
mstart.assert_called_once_with({})
|
||||
Reference in New Issue
Block a user