Add fuel2 commands for node interfaces and disks
This patch adds commands that allow to download and upload configuration of interfaces and disks for a node: - fuel2 node interfaces download - fuel2 node interfaces upload - fuel2 node interfaces get-default - fuel2 node disk upload - fuel2 node disk download - fuel2 node disk get-default DocImpact Change-Id: I8f84761c0f114d78d2c67d40e8c4b24bfd3fc273
This commit is contained in:
@@ -12,11 +12,13 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import abc
|
||||
import collections
|
||||
import json
|
||||
import operator
|
||||
import os
|
||||
|
||||
from oslo_utils import fileutils
|
||||
import six
|
||||
|
||||
from fuelclient.cli import error
|
||||
@@ -45,6 +47,124 @@ class NodeMixIn(object):
|
||||
return numa_topology_info
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class BaseUploadCommand(NodeMixIn, base.BaseCommand):
|
||||
"""Base class for uploading attributes of a node."""
|
||||
|
||||
@abc.abstractproperty
|
||||
def attribute(self):
|
||||
"""String with the name of the attribute."""
|
||||
pass
|
||||
|
||||
@abc.abstractproperty
|
||||
def uploader(self):
|
||||
"""Callable for uploading data."""
|
||||
pass
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(BaseUploadCommand, self).get_parser(prog_name)
|
||||
parser.add_argument('id',
|
||||
type=int,
|
||||
help='Id of a node.')
|
||||
parser.add_argument('-f',
|
||||
'--format',
|
||||
required=True,
|
||||
choices=self.supported_file_formats,
|
||||
help='Format of serialized '
|
||||
'{} data.'.format(self.attribute))
|
||||
parser.add_argument('-d',
|
||||
'--directory',
|
||||
required=False,
|
||||
default=os.curdir,
|
||||
help='Source directory. Defaults to '
|
||||
'the current directory.')
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
directory = parsed_args.directory
|
||||
|
||||
file_path = self.get_attributes_path(self.attribute,
|
||||
parsed_args.format,
|
||||
parsed_args.id,
|
||||
directory)
|
||||
|
||||
try:
|
||||
with open(file_path, 'r') as stream:
|
||||
attributes = data_utils.safe_load(parsed_args.format,
|
||||
stream)
|
||||
self.uploader(parsed_args.id, attributes)
|
||||
except (OSError, IOError):
|
||||
msg = 'Could not read configuration of {} at {}.'
|
||||
raise error.InvalidFileException(msg.format(self.attribute,
|
||||
file_path))
|
||||
|
||||
msg = ('Configuration of {t} for node with id '
|
||||
'{node} was loaded from {path}\n')
|
||||
self.app.stdout.write(msg.format(t=self.attribute,
|
||||
node=parsed_args.id,
|
||||
path=file_path))
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class BaseDownloadCommand(NodeMixIn, base.BaseCommand):
|
||||
"""Base class for downloading attributes of a node."""
|
||||
|
||||
@abc.abstractproperty
|
||||
def attribute(self):
|
||||
"""String with the name of the attribute."""
|
||||
pass
|
||||
|
||||
@abc.abstractproperty
|
||||
def downloader(self):
|
||||
"""Callable for downloading data."""
|
||||
pass
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(BaseDownloadCommand, self).get_parser(prog_name)
|
||||
parser.add_argument('id',
|
||||
type=int,
|
||||
help='Id of a node.')
|
||||
parser.add_argument('-f',
|
||||
'--format',
|
||||
required=True,
|
||||
choices=self.supported_file_formats,
|
||||
help='Format of serialized '
|
||||
'{} data.'.format(self.attribute))
|
||||
parser.add_argument('-d',
|
||||
'--directory',
|
||||
required=False,
|
||||
default=os.curdir,
|
||||
help='Destination directory. Defaults to '
|
||||
'the current directory.')
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
directory = parsed_args.directory
|
||||
attributes = self.downloader(parsed_args.id)
|
||||
file_path = self.get_attributes_path(self.attribute,
|
||||
parsed_args.format,
|
||||
parsed_args.id,
|
||||
directory)
|
||||
|
||||
try:
|
||||
fileutils.ensure_tree(os.path.dirname(file_path))
|
||||
fileutils.delete_if_exists(file_path)
|
||||
|
||||
with open(file_path, 'w') as stream:
|
||||
data_utils.safe_dump(parsed_args.format, stream, attributes)
|
||||
except (OSError, IOError):
|
||||
msg = 'Could not store configuration of {} at {}.'
|
||||
raise error.InvalidFileException(msg.format(self.attribute,
|
||||
file_path))
|
||||
|
||||
msg = ('Configuration of {t} for node with id '
|
||||
'{node} was stored in {path}\n')
|
||||
self.app.stdout.write(msg.format(t=self.attribute,
|
||||
node=parsed_args.id,
|
||||
path=file_path))
|
||||
|
||||
|
||||
class NodeList(NodeMixIn, base.BaseListCommand):
|
||||
"""Show list of all available nodes."""
|
||||
|
||||
@@ -393,3 +513,63 @@ class NodeAnsibleInventory(NodeMixIn, base.BaseCommand):
|
||||
)
|
||||
)
|
||||
self.app.stdout.write(u'\n\n')
|
||||
|
||||
|
||||
class NodeInterfacesDownload(BaseDownloadCommand):
|
||||
"""Download and store configuration of interfaces for a node to a file."""
|
||||
|
||||
attribute = 'interfaces'
|
||||
|
||||
@property
|
||||
def downloader(self):
|
||||
return self.client.get_interfaces
|
||||
|
||||
|
||||
class NodeInterfacesGetDefault(BaseDownloadCommand):
|
||||
"""Download default configuration of interfaces for a node to a file."""
|
||||
|
||||
attribute = 'interfaces'
|
||||
|
||||
@property
|
||||
def downloader(self):
|
||||
return self.client.get_default_interfaces
|
||||
|
||||
|
||||
class NodeInterfacesUpload(BaseUploadCommand):
|
||||
"""Upload stored configuration of interfaces for a node from a file."""
|
||||
|
||||
attribute = 'interfaces'
|
||||
|
||||
@property
|
||||
def uploader(self):
|
||||
return self.client.set_interfaces
|
||||
|
||||
|
||||
class NodeDisksDownload(BaseDownloadCommand):
|
||||
"""Download and store configuration of disks for a node to a file."""
|
||||
|
||||
attribute = 'disks'
|
||||
|
||||
@property
|
||||
def downloader(self):
|
||||
return self.client.get_disks
|
||||
|
||||
|
||||
class NodeDisksGetDefault(BaseDownloadCommand):
|
||||
"""Download default configuration of disks for a node to a file."""
|
||||
|
||||
attribute = 'disks'
|
||||
|
||||
@property
|
||||
def downloader(self):
|
||||
return self.client.get_default_disks
|
||||
|
||||
|
||||
class NodeDisksUpload(BaseUploadCommand):
|
||||
"""Upload stored configuration of disks for a node from a file."""
|
||||
|
||||
attribute = 'disks'
|
||||
|
||||
@property
|
||||
def uploader(self):
|
||||
return self.client.set_disks
|
||||
|
||||
@@ -15,9 +15,11 @@
|
||||
# under the License.
|
||||
|
||||
import io
|
||||
import json
|
||||
|
||||
import mock
|
||||
import six
|
||||
import yaml
|
||||
|
||||
from fuelclient import main as main_mod
|
||||
from fuelclient.tests.unit.v2.cli import test_engine
|
||||
@@ -290,6 +292,104 @@ node-4 ansible_host=10.20.0.5
|
||||
self.m_client.delete_labels_for_nodes.assert_called_once_with(
|
||||
labels=labels, node_ids=None)
|
||||
|
||||
@mock.patch('json.dump')
|
||||
def test_node_disks_download_json(self, m_dump):
|
||||
args = 'node disks download --format json -d /tmp 42'
|
||||
test_data = {'foo': 'bar'}
|
||||
expected_path = '/tmp/node_42/disks.json'
|
||||
|
||||
self.m_client.get_disks.return_value = test_data
|
||||
|
||||
m_open = mock.mock_open()
|
||||
with mock.patch('fuelclient.commands.node.open', m_open, create=True):
|
||||
self.exec_command(args)
|
||||
|
||||
m_open.assert_called_once_with(expected_path, 'w')
|
||||
m_dump.assert_called_once_with(test_data, mock.ANY, indent=4)
|
||||
self.m_get_client.assert_called_once_with('node', mock.ANY)
|
||||
self.m_client.get_disks.assert_called_once_with(42)
|
||||
|
||||
def test_node_disks_upload_json(self):
|
||||
args = 'node disks upload --format json -d /tmp 42'
|
||||
test_data = {'foo': 'bar'}
|
||||
expected_path = '/tmp/node_42/disks.json'
|
||||
|
||||
m_open = mock.mock_open(read_data=json.dumps(test_data))
|
||||
with mock.patch('fuelclient.commands.node.open', m_open, create=True):
|
||||
self.exec_command(args)
|
||||
|
||||
m_open.assert_called_once_with(expected_path, 'r')
|
||||
self.m_get_client.assert_called_once_with('node', mock.ANY)
|
||||
self.m_client.set_disks.assert_called_once_with(42, test_data)
|
||||
|
||||
@mock.patch('json.dump')
|
||||
def test_node_disks_getdefault_json(self, m_dump):
|
||||
args = 'node disks get-default --format json -d /tmp 42'
|
||||
test_data = {'foo': 'bar'}
|
||||
expected_path = '/tmp/node_42/disks.json'
|
||||
|
||||
self.m_client.get_default_disks.return_value = test_data
|
||||
|
||||
m_open = mock.mock_open()
|
||||
with mock.patch('fuelclient.commands.node.open', m_open, create=True):
|
||||
self.exec_command(args)
|
||||
|
||||
m_open.assert_called_once_with(expected_path, 'w')
|
||||
m_dump.assert_called_once_with(test_data, mock.ANY, indent=4)
|
||||
self.m_get_client.assert_called_once_with('node', mock.ANY)
|
||||
self.m_client.get_default_disks.assert_called_once_with(42)
|
||||
|
||||
@mock.patch('yaml.safe_dump')
|
||||
def test_node_disks_download_yaml(self, m_safe_dump):
|
||||
args = 'node disks download --format yaml -d /tmp 42'
|
||||
test_data = {'foo': 'bar'}
|
||||
expected_path = '/tmp/node_42/disks.yaml'
|
||||
|
||||
self.m_client.get_disks.return_value = test_data
|
||||
|
||||
m_open = mock.mock_open()
|
||||
with mock.patch('fuelclient.commands.node.open', m_open, create=True):
|
||||
self.exec_command(args)
|
||||
|
||||
m_open.assert_called_once_with(expected_path, 'w')
|
||||
m_safe_dump.assert_called_once_with(test_data, mock.ANY,
|
||||
default_flow_style=False)
|
||||
|
||||
self.m_get_client.assert_called_once_with('node', mock.ANY)
|
||||
self.m_client.get_disks.assert_called_once_with(42)
|
||||
|
||||
def test_node_disks_upload_yaml(self):
|
||||
args = 'node disks upload --format yaml -d /tmp 42'
|
||||
test_data = {'foo': 'bar'}
|
||||
expected_path = '/tmp/node_42/disks.yaml'
|
||||
|
||||
m_open = mock.mock_open(read_data=yaml.dump(test_data))
|
||||
with mock.patch('fuelclient.commands.node.open', m_open, create=True):
|
||||
self.exec_command(args)
|
||||
|
||||
m_open.assert_called_once_with(expected_path, 'r')
|
||||
self.m_get_client.assert_called_once_with('node', mock.ANY)
|
||||
self.m_client.set_disks.assert_called_once_with(42, test_data)
|
||||
|
||||
@mock.patch('yaml.safe_dump')
|
||||
def test_node_disks_getdefault_yaml(self, m_safe_dump):
|
||||
args = 'node disks get-default --format yaml -d /tmp 42'
|
||||
test_data = {'foo': 'bar'}
|
||||
expected_path = '/tmp/node_42/disks.yaml'
|
||||
|
||||
self.m_client.get_default_disks.return_value = test_data
|
||||
|
||||
m_open = mock.mock_open()
|
||||
with mock.patch('fuelclient.commands.node.open', m_open, create=True):
|
||||
self.exec_command(args)
|
||||
|
||||
m_open.assert_called_once_with(expected_path, 'w')
|
||||
m_safe_dump.assert_called_once_with(test_data, mock.ANY,
|
||||
default_flow_style=False)
|
||||
|
||||
self.m_get_client.assert_called_once_with('node', mock.ANY)
|
||||
self.m_client.get_default_disks.assert_called_once_with(42)
|
||||
|
||||
def test_node_delete_specific_labels_for_specific_nodes(self):
|
||||
labels_keys = ['key_1', 'key_2']
|
||||
node_ids = ['42', '43']
|
||||
@@ -362,3 +462,101 @@ node-4 ansible_host=10.20.0.5
|
||||
|
||||
self.m_get_client.assert_called_once_with('node', mock.ANY)
|
||||
self.m_client.upload_attributes.assert_called_once_with(42, None)
|
||||
|
||||
@mock.patch('json.dump')
|
||||
def test_node_interfaces_download_json(self, m_dump):
|
||||
args = 'node interfaces download --format json -d /tmp 42'
|
||||
test_data = {'foo': 'bar'}
|
||||
expected_path = '/tmp/node_42/interfaces.json'
|
||||
|
||||
self.m_client.get_interfaces.return_value = test_data
|
||||
|
||||
m_open = mock.mock_open()
|
||||
with mock.patch('fuelclient.commands.node.open', m_open, create=True):
|
||||
self.exec_command(args)
|
||||
|
||||
m_open.assert_called_once_with(expected_path, 'w')
|
||||
m_dump.assert_called_once_with(test_data, mock.ANY, indent=4)
|
||||
self.m_get_client.assert_called_once_with('node', mock.ANY)
|
||||
self.m_client.get_interfaces.assert_called_once_with(42)
|
||||
|
||||
def test_node_interfaces_upload_json(self):
|
||||
args = 'node interfaces upload --format json -d /tmp 42'
|
||||
test_data = {'foo': 'bar'}
|
||||
expected_path = '/tmp/node_42/interfaces.json'
|
||||
|
||||
m_open = mock.mock_open(read_data=json.dumps(test_data))
|
||||
with mock.patch('fuelclient.commands.node.open', m_open, create=True):
|
||||
self.exec_command(args)
|
||||
|
||||
m_open.assert_called_once_with(expected_path, 'r')
|
||||
self.m_get_client.assert_called_once_with('node', mock.ANY)
|
||||
self.m_client.set_interfaces.assert_called_once_with(42, test_data)
|
||||
|
||||
@mock.patch('json.dump')
|
||||
def test_node_interfaces_getdefault_json(self, m_dump):
|
||||
args = 'node interfaces get-default --format json -d /tmp 42'
|
||||
test_data = {'foo': 'bar'}
|
||||
expected_path = '/tmp/node_42/interfaces.json'
|
||||
|
||||
self.m_client.get_default_interfaces.return_value = test_data
|
||||
|
||||
m_open = mock.mock_open()
|
||||
with mock.patch('fuelclient.commands.node.open', m_open, create=True):
|
||||
self.exec_command(args)
|
||||
|
||||
m_open.assert_called_once_with(expected_path, 'w')
|
||||
m_dump.assert_called_once_with(test_data, mock.ANY, indent=4)
|
||||
self.m_get_client.assert_called_once_with('node', mock.ANY)
|
||||
self.m_client.get_default_interfaces.assert_called_once_with(42)
|
||||
|
||||
@mock.patch('yaml.safe_dump')
|
||||
def test_node_interfaces_download_yaml(self, m_safe_dump):
|
||||
args = 'node interfaces download --format yaml -d /tmp 42'
|
||||
test_data = {'foo': 'bar'}
|
||||
expected_path = '/tmp/node_42/interfaces.yaml'
|
||||
|
||||
self.m_client.get_interfaces.return_value = test_data
|
||||
|
||||
m_open = mock.mock_open()
|
||||
with mock.patch('fuelclient.commands.node.open', m_open, create=True):
|
||||
self.exec_command(args)
|
||||
|
||||
m_open.assert_called_once_with(expected_path, 'w')
|
||||
m_safe_dump.assert_called_once_with(test_data, mock.ANY,
|
||||
default_flow_style=False)
|
||||
|
||||
self.m_get_client.assert_called_once_with('node', mock.ANY)
|
||||
self.m_client.get_interfaces.assert_called_once_with(42)
|
||||
|
||||
def test_node_interfaces_upload_yaml(self):
|
||||
args = 'node interfaces upload --format yaml -d /tmp 42'
|
||||
test_data = {'foo': 'bar'}
|
||||
expected_path = '/tmp/node_42/interfaces.yaml'
|
||||
|
||||
m_open = mock.mock_open(read_data=yaml.dump(test_data))
|
||||
with mock.patch('fuelclient.commands.node.open', m_open, create=True):
|
||||
self.exec_command(args)
|
||||
|
||||
m_open.assert_called_once_with(expected_path, 'r')
|
||||
self.m_get_client.assert_called_once_with('node', mock.ANY)
|
||||
self.m_client.set_interfaces.assert_called_once_with(42, test_data)
|
||||
|
||||
@mock.patch('yaml.safe_dump')
|
||||
def test_node_interfaces_getdefault_yaml(self, m_safe_dump):
|
||||
args = 'node interfaces get-default --format yaml -d /tmp 42'
|
||||
test_data = {'foo': 'bar'}
|
||||
expected_path = '/tmp/node_42/interfaces.yaml'
|
||||
|
||||
self.m_client.get_default_interfaces.return_value = test_data
|
||||
|
||||
m_open = mock.mock_open()
|
||||
with mock.patch('fuelclient.commands.node.open', m_open, create=True):
|
||||
self.exec_command(args)
|
||||
|
||||
m_open.assert_called_once_with(expected_path, 'w')
|
||||
m_safe_dump.assert_called_once_with(test_data, mock.ANY,
|
||||
default_flow_style=False)
|
||||
|
||||
self.m_get_client.assert_called_once_with('node', mock.ANY)
|
||||
self.m_client.get_default_interfaces.assert_called_once_with(42)
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
# under the License.
|
||||
|
||||
import mock
|
||||
import os
|
||||
import yaml
|
||||
|
||||
import fuelclient
|
||||
@@ -360,6 +361,58 @@ class TestNodeFacade(test_api.BaseLibTest):
|
||||
m_open().write.assert_called_once_with(
|
||||
serializer.serialize(fake_attributes))
|
||||
|
||||
def test_node_disks_upload(self):
|
||||
node_id = 42
|
||||
new_disks = {'test_key': u'test ☃ value'}
|
||||
|
||||
node_uri = self.get_object_uri(self.res_uri, node_id)
|
||||
disks_uri = os.path.join(node_uri, 'disks/')
|
||||
|
||||
get_matcher = self.m_request.get(node_uri, json=self.fake_node)
|
||||
upd_matcher = self.m_request.put(disks_uri, json={})
|
||||
|
||||
self.client.set_disks(node_id, new_disks)
|
||||
|
||||
self.assertTrue(node_uri, get_matcher.called)
|
||||
self.assertTrue(disks_uri, upd_matcher.called)
|
||||
|
||||
req_data = upd_matcher.last_request.json()
|
||||
self.assertEqual(new_disks, req_data)
|
||||
|
||||
def test_node_disks_download(self):
|
||||
node_id = 42
|
||||
fake_resp = {'test_key': u'test ☃ value'}
|
||||
|
||||
node_uri = self.get_object_uri(self.res_uri, node_id)
|
||||
disks_uri = os.path.join(node_uri, 'disks/')
|
||||
|
||||
node_matcher = self.m_request.get(node_uri, json=self.fake_node)
|
||||
disks_matcher = self.m_request.get(disks_uri, json=fake_resp)
|
||||
|
||||
disks = self.client.get_disks(node_id)
|
||||
|
||||
self.assertTrue(node_uri, node_matcher.called)
|
||||
self.assertTrue(disks_uri, disks_matcher.called)
|
||||
|
||||
self.assertEqual(disks, fake_resp)
|
||||
|
||||
def test_node_disks_defaults(self):
|
||||
node_id = 42
|
||||
fake_resp = {'test_key': u'test ☃ value'}
|
||||
|
||||
node_uri = self.get_object_uri(self.res_uri, node_id)
|
||||
disks_uri = os.path.join(node_uri, 'disks/defaults')
|
||||
|
||||
node_matcher = self.m_request.get(node_uri, json=self.fake_node)
|
||||
disks_matcher = self.m_request.get(disks_uri, json=fake_resp)
|
||||
|
||||
disks = self.client.get_default_disks(node_id)
|
||||
|
||||
self.assertTrue(node_uri, node_matcher.called)
|
||||
self.assertTrue(disks_uri, disks_matcher.called)
|
||||
|
||||
self.assertEqual(disks, fake_resp)
|
||||
|
||||
@mock.patch('fuelclient.objects.node.os.path.exists',
|
||||
mock.Mock(return_value=True))
|
||||
def test_node_attribute_upload(self):
|
||||
@@ -382,3 +435,56 @@ class TestNodeFacade(test_api.BaseLibTest):
|
||||
'/fake/dir/node_{0}/attributes.yaml'.format(node_id), mock.ANY)
|
||||
self.assertEqual(m_put.last_request.json(), fake_attributes)
|
||||
m_open().read.assert_called_once_with()
|
||||
|
||||
def test_node_interfaces_upload(self):
|
||||
node_id = 42
|
||||
new_interfaces = {'test_key': u'test ☃ value'}
|
||||
|
||||
node_uri = self.get_object_uri(self.res_uri, node_id)
|
||||
interfaces_uri = os.path.join(node_uri, 'interfaces/')
|
||||
|
||||
get_matcher = self.m_request.get(node_uri, json=self.fake_node)
|
||||
upd_matcher = self.m_request.put(interfaces_uri, json={})
|
||||
|
||||
self.client.set_interfaces(node_id, new_interfaces)
|
||||
|
||||
self.assertTrue(node_uri, get_matcher.called)
|
||||
self.assertTrue(interfaces_uri, upd_matcher.called)
|
||||
|
||||
req_data = upd_matcher.last_request.json()
|
||||
self.assertEqual(new_interfaces, req_data)
|
||||
|
||||
def test_node_interfaces_download(self):
|
||||
node_id = 42
|
||||
fake_resp = {'test_key': u'test ☃ value'}
|
||||
|
||||
node_uri = self.get_object_uri(self.res_uri, node_id)
|
||||
interfaces_uri = os.path.join(node_uri, 'interfaces/')
|
||||
|
||||
node_matcher = self.m_request.get(node_uri, json=self.fake_node)
|
||||
interfaces_matcher = self.m_request.get(interfaces_uri, json=fake_resp)
|
||||
|
||||
interfaces = self.client.get_interfaces(node_id)
|
||||
|
||||
self.assertTrue(node_uri, node_matcher.called)
|
||||
self.assertTrue(interfaces_uri, interfaces_matcher.called)
|
||||
|
||||
self.assertEqual(interfaces, fake_resp)
|
||||
|
||||
def test_node_interfaces_default(self):
|
||||
node_id = 42
|
||||
fake_resp = {'test_key': u'test ☃ value'}
|
||||
|
||||
node_uri = self.get_object_uri(self.res_uri, node_id)
|
||||
interfaces_uri = os.path.join(node_uri,
|
||||
'interfaces/default_assignment')
|
||||
|
||||
node_matcher = self.m_request.get(node_uri, json=self.fake_node)
|
||||
interfaces_matcher = self.m_request.get(interfaces_uri, json=fake_resp)
|
||||
|
||||
interfaces = self.client.get_default_interfaces(node_id)
|
||||
|
||||
self.assertTrue(node_uri, node_matcher.called)
|
||||
self.assertTrue(interfaces_uri, interfaces_matcher.called)
|
||||
|
||||
self.assertEqual(interfaces, fake_resp)
|
||||
|
||||
@@ -168,11 +168,74 @@ class NodeClient(base_v1.BaseV1Client):
|
||||
return node.write_attribute(
|
||||
'attributes', attributes, directory=directory)
|
||||
|
||||
def get_disks(self, node_id):
|
||||
"""Download configuration of disks for a node
|
||||
|
||||
:param node_id: Id of a node.
|
||||
:return: dict with the configuration of disks for the node.
|
||||
|
||||
"""
|
||||
node = self._entity_wrapper(node_id)
|
||||
return node.get_attribute('disks')
|
||||
|
||||
def get_default_disks(self, node_id):
|
||||
"""Download default configuration of disks for a node
|
||||
|
||||
:param node_id: Id of a node.
|
||||
:return: dict with the default configuration of disks
|
||||
for the node.
|
||||
|
||||
"""
|
||||
node = self._entity_wrapper(node_id)
|
||||
return node.get_default_attribute('disks')
|
||||
|
||||
def set_disks(self, node_id, disks):
|
||||
"""Upload and set configuration of disks for a node
|
||||
|
||||
:param node_id: Id of a node.
|
||||
:param interfaces: dict that contains valid configuration
|
||||
for disks
|
||||
|
||||
"""
|
||||
node = self._entity_wrapper(node_id)
|
||||
return node.upload_node_attribute('disks', disks)
|
||||
|
||||
def upload_attributes(self, node_id, directory=None):
|
||||
node = self._entity_wrapper(node_id)
|
||||
attributes = node.read_attribute('attributes', directory=directory)
|
||||
node.update_node_attributes(attributes)
|
||||
|
||||
def get_interfaces(self, node_id):
|
||||
"""Download configuration of interfaces for a node
|
||||
|
||||
:param node_id: Id of a node.
|
||||
:return: dict with the configuration of interfaces for the node.
|
||||
|
||||
"""
|
||||
node = self._entity_wrapper(node_id)
|
||||
return node.get_attribute('interfaces')
|
||||
|
||||
def get_default_interfaces(self, node_id):
|
||||
"""Download default configuration of interfaces for a node
|
||||
|
||||
:param node_id: Id of a node.
|
||||
:return: dict with the configuration of interfaces for the node.
|
||||
|
||||
"""
|
||||
node = self._entity_wrapper(node_id)
|
||||
return node.get_default_attribute('interfaces')
|
||||
|
||||
def set_interfaces(self, node_id, interfaces):
|
||||
"""Upload and set configuration of interfaces for a node
|
||||
|
||||
:param node_id: Id of a node.
|
||||
:param interfaces: dict that contains valid configuration
|
||||
for interfaces
|
||||
|
||||
"""
|
||||
node = self._entity_wrapper(node_id)
|
||||
return node.upload_node_attribute('interfaces', interfaces)
|
||||
|
||||
def _check_label(self, labels, item):
|
||||
checking_list = []
|
||||
|
||||
|
||||
@@ -63,6 +63,12 @@ fuelclient =
|
||||
node_attributes-download=fuelclient.commands.node:NodeAttributesDownload
|
||||
node_attributes-upload=fuelclient.commands.node:NodeAttributesUpload
|
||||
node_create-vms-conf=fuelclient.commands.node:NodeCreateVMsConf
|
||||
node_interfaces_download=fuelclient.commands.node:NodeInterfacesDownload
|
||||
node_interfaces_get-default=fuelclient.commands.node:NodeInterfacesGetDefault
|
||||
node_interfaces_upload=fuelclient.commands.node:NodeInterfacesUpload
|
||||
node_disks_download=fuelclient.commands.node:NodeDisksDownload
|
||||
node_disks_get-default=fuelclient.commands.node:NodeDisksGetDefault
|
||||
node_disks_upload=fuelclient.commands.node:NodeDisksUpload
|
||||
node_label_delete=fuelclient.commands.node:NodeLabelDelete
|
||||
node_label_list=fuelclient.commands.node:NodeLabelList
|
||||
node_label_set=fuelclient.commands.node:NodeLabelSet
|
||||
|
||||
Reference in New Issue
Block a user