Add node attributes commannds to CLI v1

Add commands that allow to download and upload node attributes
for specified nodes:
    fuel node --node-id 1 --attributes --upload [--dir DIR]
    fuel node --node-id 1 --attributes --download [--dir DIR]

Change-Id: Ic368f393ed59e88631080ec8c3b3a7c0e29f6913
Implements: blueprint support-numa-cpu-pinning
This commit is contained in:
Alexander Saprykin
2016-02-15 16:21:32 +02:00
parent c45bd4ebb9
commit 36ab43141c
4 changed files with 104 additions and 2 deletions

View File

@@ -42,6 +42,7 @@ class NodeAction(Action):
Args.get_list_arg("List all nodes."),
Args.get_set_arg("Set role for specific node."),
Args.get_delete_arg("Delete specific node from environment."),
Args.get_attributes_arg("Node attributes."),
Args.get_network_arg("Node network configuration."),
Args.get_disk_arg("Node disk configuration."),
Args.get_deploy_arg("Deploy specific nodes."),
@@ -88,6 +89,7 @@ class NodeAction(Action):
("skip", self.execute_tasks),
("end", self.execute_tasks),
("start", self.execute_tasks),
("attributes", self.node_attributes),
(None, self.list)
)
@@ -375,3 +377,36 @@ class NodeAction(Action):
"Hostname for node with id {0} has been changed to {1}."
.format(node.id, params.hostname)
)
@check_all("node")
@check_any("upload", "download")
def node_attributes(self, params):
"""Download node attributes for specified node:
fuel node --node-id 1 --attributes --download [--dir download-dir]
Upload node attributes for specified node
fuel node --node-id 1 --attributes --upload [--dir upload-dir]
"""
node = self._get_one_node(params)
if params.upload:
data = node.read_attribute(
'attributes', params.dir, serializer=self.serializer)
node.update_node_attributes(data)
self.serializer.print_to_output(
{},
"Attributes for node {0} were uploaded."
.format(node.id))
elif params.download:
attributes = node.get_node_attributes()
file_path = node.write_attribute(
'attributes', attributes,
params.dir, serializer=self.serializer)
self.serializer.print_to_output(
{},
"Attributes for node {0} were written to {1}"
.format(node.id, file_path))
else:
raise error.ArgumentException(
"--upload or --download action should be specified.")

View File

@@ -24,6 +24,7 @@ class Node(BaseObject):
class_api_path = "nodes/"
instance_api_path = "nodes/{0}/"
attributes_api_path = "nodes/{0}/attributes/"
attributes_urls = {
"interfaces": ("interfaces", "default_assignment"),
@@ -74,6 +75,17 @@ class Node(BaseObject):
self.get_attribute_default_url(attributes_type)
)
def get_node_attributes(self):
return self.connection.get_request(
self.attributes_api_path.format(self.id)
)
def update_node_attributes(self, data):
return self.connection.put_request(
self.attributes_api_path.format(self.id),
data
)
def get_attribute(self, attributes_type):
return self.connection.get_request(
self.get_attribute_url(attributes_type)

View File

@@ -55,8 +55,9 @@ class TestHandlers(base.BaseTestCase):
def test_node_action(self):
help_msg = ["fuel node [-h] [--env ENV]",
"[--list | --set | --delete | --network | --disk |"
" --deploy | --hostname HOSTNAME | --name NAME |"
"[--list | --set | --delete | --attributes |"
" --network | --disk | --deploy |"
" --hostname HOSTNAME | --name NAME |"
" --delete-from-db | --provision]", "-h", "--help", " -s",
"--default", " -d", "--download", " -u",
"--upload", "--dir", "--node", "--node-id", " -r",

View File

@@ -15,11 +15,17 @@
# under the License.
import mock
import yaml
from fuelclient.cli.actions import node
from fuelclient.cli import error
from fuelclient.cli import serializers
from fuelclient.tests.unit.v1 import base
NODE_ATTRIBUTES_DATA = {
'test_attribute': 'value'
}
class TestNodeSetAction(base.UnitTestCase):
@@ -83,3 +89,51 @@ class TestNodeSetAction(base.UnitTestCase):
"Hostname for node with id {0} has been changed to {1}.".format(
self.node_id, new_hostname)
)
class TestNodeActions(base.UnitTestCase):
def setUp(self):
super(TestNodeActions, self).setUp()
self.node_id = 1
@mock.patch('fuelclient.objects.node.os.mkdir', mock.Mock())
def test_attributes_download(self):
mget = self.m_request.get(
'/api/v1/nodes/{0}/attributes/'.format(self.node_id),
json=NODE_ATTRIBUTES_DATA)
cmd = ['fuel', 'node', '--node', '1', '--attributes',
'--dir', '/fake/dir/', '--download']
m_open = mock.mock_open()
with mock.patch('fuelclient.cli.serializers.open', m_open,
create=True):
self.execute(cmd)
self.assertTrue(mget.called)
m_open.assert_called_once_with(
'/fake/dir/node_{0}/attributes.yaml'.format(self.node_id),
mock.ANY)
serializer = serializers.Serializer()
m_open().write.assert_called_once_with(
serializer.serialize(NODE_ATTRIBUTES_DATA))
@mock.patch('fuelclient.objects.node.os.path.exists',
mock.Mock(return_value=True))
def test_attributes_upload(self):
mput = self.m_request.put(
'/api/v1/nodes/{0}/attributes/'.format(self.node_id),
json=NODE_ATTRIBUTES_DATA)
cmd = ['fuel', 'node', '--node', '1', '--attributes',
'--dir', '/fake/dir', '--upload']
m_open = mock.mock_open(read_data=yaml.safe_dump(NODE_ATTRIBUTES_DATA))
with mock.patch('fuelclient.cli.serializers.open', m_open,
create=True):
self.execute(cmd)
self.assertTrue(mput.called)
m_open.assert_called_once_with(
'/fake/dir/node_{0}/attributes.yaml'.format(self.node_id),
mock.ANY)
self.assertEqual(mput.last_request.json(), NODE_ATTRIBUTES_DATA)
m_open().read.assert_called_once_with()