Move Instance to its own file
Change-Id: I607b804f719e2a660c2e52a672b68b9281af4569
This commit is contained in:
parent
8464fced77
commit
7b3561bb9a
@ -13,7 +13,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from metalsmith._provisioner import Instance
|
||||
from metalsmith._instance import Instance
|
||||
from metalsmith._provisioner import Provisioner
|
||||
|
||||
__all__ = ['Instance', 'Provisioner']
|
||||
|
127
metalsmith/_instance.py
Normal file
127
metalsmith/_instance.py
Normal file
@ -0,0 +1,127 @@
|
||||
# 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.
|
||||
|
||||
from metalsmith import _os_api
|
||||
|
||||
|
||||
# NOTE(dtantsur): include available since there is a period of time between
|
||||
# claiming the instance and starting the actual provisioning via ironic.
|
||||
_DEPLOYING_STATES = frozenset(['available', 'deploying', 'wait call-back',
|
||||
'deploy complete'])
|
||||
_ACTIVE_STATES = frozenset(['active'])
|
||||
_ERROR_STATE = frozenset(['error', 'deploy failed'])
|
||||
|
||||
_HEALTHY_STATES = frozenset(['deploying', 'active'])
|
||||
|
||||
|
||||
class Instance(object):
|
||||
"""Instance status in metalsmith."""
|
||||
|
||||
def __init__(self, api, node):
|
||||
self._api = api
|
||||
self._uuid = node.uuid
|
||||
self._node = node
|
||||
|
||||
@property
|
||||
def hostname(self):
|
||||
"""Node's hostname."""
|
||||
return self._node.instance_info.get(_os_api.HOSTNAME_FIELD)
|
||||
|
||||
def ip_addresses(self):
|
||||
"""Returns IP addresses for this instance.
|
||||
|
||||
:return: dict mapping network name or ID to a list of IP addresses.
|
||||
"""
|
||||
result = {}
|
||||
for nic in self.nics():
|
||||
net = getattr(nic.network, 'name', None) or nic.network.id
|
||||
result.setdefault(net, []).extend(
|
||||
ip['ip_address'] for ip in nic.fixed_ips
|
||||
if ip.get('ip_address')
|
||||
)
|
||||
return result
|
||||
|
||||
@property
|
||||
def is_deployed(self):
|
||||
"""Whether the node is deployed."""
|
||||
return self._node.provision_state in _ACTIVE_STATES
|
||||
|
||||
@property
|
||||
def is_healthy(self):
|
||||
"""Whether the node is not at fault or maintenance."""
|
||||
return self.state in _HEALTHY_STATES and not self._node.maintenance
|
||||
|
||||
def nics(self):
|
||||
"""List NICs for this instance.
|
||||
|
||||
:return: List of `Port` objects with additional ``network`` fields
|
||||
with full representations of their networks.
|
||||
"""
|
||||
result = []
|
||||
vifs = self._api.list_node_attached_ports(self.node)
|
||||
for vif in vifs:
|
||||
port = self._api.get_port(vif.id)
|
||||
port.network = self._api.get_network(port.network_id)
|
||||
result.append(port)
|
||||
return result
|
||||
|
||||
@property
|
||||
def node(self):
|
||||
"""Underlying `Node` object."""
|
||||
return self._node
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
"""Instance state.
|
||||
|
||||
``deploying``
|
||||
deployment is in progress
|
||||
``active``
|
||||
node is provisioned
|
||||
``maintenance``
|
||||
node is provisioned but is in maintenance mode
|
||||
``error``
|
||||
node has a failure
|
||||
``unknown``
|
||||
node in unexpected state (maybe unprovisioned or modified by
|
||||
a third party)
|
||||
"""
|
||||
prov_state = self._node.provision_state
|
||||
if prov_state in _DEPLOYING_STATES:
|
||||
return 'deploying'
|
||||
elif prov_state in _ERROR_STATE:
|
||||
return 'error'
|
||||
elif prov_state in _ACTIVE_STATES:
|
||||
if self._node.maintenance:
|
||||
return 'maintenance'
|
||||
else:
|
||||
return 'active'
|
||||
else:
|
||||
return 'unknown'
|
||||
|
||||
def to_dict(self):
|
||||
"""Convert instance to a dict."""
|
||||
return {
|
||||
'hostname': self.hostname,
|
||||
'ip_addresses': self.ip_addresses(),
|
||||
'node': self._node.to_dict(),
|
||||
'state': self.state,
|
||||
'uuid': self._uuid,
|
||||
}
|
||||
|
||||
@property
|
||||
def uuid(self):
|
||||
"""Instance UUID (the same as `Node` UUID for metalsmith)."""
|
||||
return self._uuid
|
@ -20,6 +20,7 @@ import sys
|
||||
|
||||
import six
|
||||
|
||||
from metalsmith import _instance
|
||||
from metalsmith import _os_api
|
||||
from metalsmith import _scheduler
|
||||
from metalsmith import _utils
|
||||
@ -30,115 +31,6 @@ LOG = logging.getLogger(__name__)
|
||||
|
||||
_CREATED_PORTS = 'metalsmith_created_ports'
|
||||
_ATTACHED_PORTS = 'metalsmith_attached_ports'
|
||||
# NOTE(dtantsur): include available since there is a period of time between
|
||||
# claiming the instance and starting the actual provisioning via ironic.
|
||||
_DEPLOYING_STATES = frozenset(['available', 'deploying', 'wait call-back',
|
||||
'deploy complete'])
|
||||
_ACTIVE_STATES = frozenset(['active'])
|
||||
_ERROR_STATE = frozenset(['error', 'deploy failed'])
|
||||
|
||||
_HEALTHY_STATES = frozenset(['deploying', 'active'])
|
||||
|
||||
|
||||
class Instance(object):
|
||||
"""Instance status in metalsmith."""
|
||||
|
||||
def __init__(self, api, node):
|
||||
self._api = api
|
||||
self._uuid = node.uuid
|
||||
self._node = node
|
||||
|
||||
@property
|
||||
def hostname(self):
|
||||
"""Node's hostname."""
|
||||
return self._node.instance_info.get(_os_api.HOSTNAME_FIELD)
|
||||
|
||||
def ip_addresses(self):
|
||||
"""Returns IP addresses for this instance.
|
||||
|
||||
:return: dict mapping network name or ID to a list of IP addresses.
|
||||
"""
|
||||
result = {}
|
||||
for nic in self.nics():
|
||||
net = getattr(nic.network, 'name', None) or nic.network.id
|
||||
result.setdefault(net, []).extend(
|
||||
ip['ip_address'] for ip in nic.fixed_ips
|
||||
if ip.get('ip_address')
|
||||
)
|
||||
return result
|
||||
|
||||
@property
|
||||
def is_deployed(self):
|
||||
"""Whether the node is deployed."""
|
||||
return self._node.provision_state in _ACTIVE_STATES
|
||||
|
||||
@property
|
||||
def is_healthy(self):
|
||||
"""Whether the node is not at fault or maintenance."""
|
||||
return self.state in _HEALTHY_STATES and not self._node.maintenance
|
||||
|
||||
def nics(self):
|
||||
"""List NICs for this instance.
|
||||
|
||||
:return: List of `Port` objects with additional ``network`` fields
|
||||
with full representations of their networks.
|
||||
"""
|
||||
result = []
|
||||
vifs = self._api.list_node_attached_ports(self.node)
|
||||
for vif in vifs:
|
||||
port = self._api.get_port(vif.id)
|
||||
port.network = self._api.get_network(port.network_id)
|
||||
result.append(port)
|
||||
return result
|
||||
|
||||
@property
|
||||
def node(self):
|
||||
"""Underlying `Node` object."""
|
||||
return self._node
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
"""Instance state.
|
||||
|
||||
``deploying``
|
||||
deployment is in progress
|
||||
``active``
|
||||
node is provisioned
|
||||
``maintenance``
|
||||
node is provisioned but is in maintenance mode
|
||||
``error``
|
||||
node has a failure
|
||||
``unknown``
|
||||
node in unexpected state (maybe unprovisioned or modified by
|
||||
a third party)
|
||||
"""
|
||||
prov_state = self._node.provision_state
|
||||
if prov_state in _DEPLOYING_STATES:
|
||||
return 'deploying'
|
||||
elif prov_state in _ERROR_STATE:
|
||||
return 'error'
|
||||
elif prov_state in _ACTIVE_STATES:
|
||||
if self._node.maintenance:
|
||||
return 'maintenance'
|
||||
else:
|
||||
return 'active'
|
||||
else:
|
||||
return 'unknown'
|
||||
|
||||
def to_dict(self):
|
||||
"""Convert instance to a dict."""
|
||||
return {
|
||||
'hostname': self.hostname,
|
||||
'ip_addresses': self.ip_addresses(),
|
||||
'node': self._node.to_dict(),
|
||||
'state': self.state,
|
||||
'uuid': self._uuid,
|
||||
}
|
||||
|
||||
@property
|
||||
def uuid(self):
|
||||
"""Instance UUID (the same as `Node` UUID for metalsmith)."""
|
||||
return self._uuid
|
||||
|
||||
|
||||
class Provisioner(object):
|
||||
@ -362,7 +254,7 @@ class Provisioner(object):
|
||||
|
||||
# Update the node to return it's latest state
|
||||
node = self._api.get_node(node, refresh=True)
|
||||
return Instance(self._api, node)
|
||||
return _instance.Instance(self._api, node)
|
||||
|
||||
def _get_nics(self, nics):
|
||||
"""Validate and get the NICs."""
|
||||
@ -506,6 +398,9 @@ class Provisioner(object):
|
||||
order as ``instances``.
|
||||
"""
|
||||
with self._api.cache_node_list_for_lookup():
|
||||
return [Instance(self._api,
|
||||
return [
|
||||
_instance.Instance(
|
||||
self._api,
|
||||
self._api.get_node(inst, accept_hostname=True))
|
||||
for inst in instances]
|
||||
for inst in instances
|
||||
]
|
||||
|
@ -22,6 +22,7 @@ import six
|
||||
import testtools
|
||||
|
||||
from metalsmith import _cmd
|
||||
from metalsmith import _instance
|
||||
from metalsmith import _provisioner
|
||||
|
||||
|
||||
@ -37,7 +38,7 @@ class TestDeploy(testtools.TestCase):
|
||||
@mock.patch.object(_cmd, 'logging', autospec=True)
|
||||
def test_args_ok(self, mock_log, mock_os_conf, mock_pr):
|
||||
instance = mock_pr.return_value.provision_node.return_value
|
||||
instance.create_autospec(_provisioner.Instance)
|
||||
instance.create_autospec(_instance.Instance)
|
||||
instance.node.name = None
|
||||
instance.node.uuid = '123'
|
||||
instance.state = 'active'
|
||||
@ -79,7 +80,7 @@ class TestDeploy(testtools.TestCase):
|
||||
@mock.patch.object(_cmd, 'logging', autospec=True)
|
||||
def test_args_json_format(self, mock_log, mock_os_conf, mock_pr):
|
||||
instance = mock_pr.return_value.provision_node.return_value
|
||||
instance.create_autospec(_provisioner.Instance)
|
||||
instance.create_autospec(_instance.Instance)
|
||||
instance.to_dict.return_value = {'node': 'dict'}
|
||||
|
||||
args = ['--format', 'json', 'deploy', '--network', 'mynet',
|
||||
@ -116,7 +117,7 @@ class TestDeploy(testtools.TestCase):
|
||||
|
||||
def test_no_ips(self, mock_os_conf, mock_pr):
|
||||
instance = mock_pr.return_value.provision_node.return_value
|
||||
instance.create_autospec(_provisioner.Instance)
|
||||
instance.create_autospec(_instance.Instance)
|
||||
instance.is_deployed = True
|
||||
instance.ip_addresses.return_value = {}
|
||||
instance.node.name = None
|
||||
@ -131,7 +132,7 @@ class TestDeploy(testtools.TestCase):
|
||||
|
||||
def test_not_deployed_no_ips(self, mock_os_conf, mock_pr):
|
||||
instance = mock_pr.return_value.provision_node.return_value
|
||||
instance.create_autospec(_provisioner.Instance)
|
||||
instance.create_autospec(_instance.Instance)
|
||||
instance.is_deployed = False
|
||||
instance.node.name = None
|
||||
instance.node.uuid = '123'
|
||||
@ -146,7 +147,7 @@ class TestDeploy(testtools.TestCase):
|
||||
@mock.patch.object(_cmd.LOG, 'info', autospec=True)
|
||||
def test_no_logs_not_deployed(self, mock_log, mock_os_conf, mock_pr):
|
||||
instance = mock_pr.return_value.provision_node.return_value
|
||||
instance.create_autospec(_provisioner.Instance)
|
||||
instance.create_autospec(_instance.Instance)
|
||||
instance.is_deployed = False
|
||||
|
||||
args = ['deploy', '--network', 'mynet', '--image', 'myimg', 'compute']
|
||||
@ -619,7 +620,7 @@ class TestShow(testtools.TestCase):
|
||||
'metalsmith._format._print', autospec=True))
|
||||
self.mock_print = self.print_fixture.mock
|
||||
self.instances = [
|
||||
mock.Mock(spec=_provisioner.Instance, hostname=hostname,
|
||||
mock.Mock(spec=_instance.Instance, hostname=hostname,
|
||||
uuid=hostname[-1], is_deployed=(hostname[-1] == '1'),
|
||||
state=('active' if hostname[-1] == '1' else 'deploying'),
|
||||
**{'ip_addresses.return_value': {'private':
|
||||
|
116
metalsmith/test/test_instance.py
Normal file
116
metalsmith/test/test_instance.py
Normal file
@ -0,0 +1,116 @@
|
||||
# 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 metalsmith import _instance
|
||||
from metalsmith.test import test_provisioner
|
||||
|
||||
|
||||
class TestInstanceIPAddresses(test_provisioner.Base):
|
||||
def setUp(self):
|
||||
super(TestInstanceIPAddresses, self).setUp()
|
||||
self.instance = _instance.Instance(self.api, self.node)
|
||||
self.api.list_node_attached_ports.return_value = [
|
||||
mock.Mock(spec=['id'], id=i) for i in ('111', '222')
|
||||
]
|
||||
self.ports = [
|
||||
mock.Mock(spec=['network_id', 'fixed_ips', 'network'],
|
||||
network_id=n, fixed_ips=[{'ip_address': ip}])
|
||||
for n, ip in [('0', '192.168.0.1'), ('1', '10.0.0.2')]
|
||||
]
|
||||
self.api.get_port.side_effect = self.ports
|
||||
self.nets = [
|
||||
mock.Mock(spec=['id', 'name'], id=str(i)) for i in range(2)
|
||||
]
|
||||
for n in self.nets:
|
||||
n.name = 'name-%s' % n.id
|
||||
self.api.get_network.side_effect = self.nets
|
||||
|
||||
def test_ip_addresses(self):
|
||||
ips = self.instance.ip_addresses()
|
||||
self.assertEqual({'name-0': ['192.168.0.1'],
|
||||
'name-1': ['10.0.0.2']},
|
||||
ips)
|
||||
|
||||
def test_missing_ip(self):
|
||||
self.ports[0].fixed_ips = {}
|
||||
ips = self.instance.ip_addresses()
|
||||
self.assertEqual({'name-0': [],
|
||||
'name-1': ['10.0.0.2']}, ips)
|
||||
|
||||
|
||||
class TestInstanceStates(test_provisioner.Base):
|
||||
def setUp(self):
|
||||
super(TestInstanceStates, self).setUp()
|
||||
self.instance = _instance.Instance(self.api, self.node)
|
||||
|
||||
def test_state_deploying(self):
|
||||
self.node.provision_state = 'wait call-back'
|
||||
self.assertEqual('deploying', self.instance.state)
|
||||
self.assertFalse(self.instance.is_deployed)
|
||||
self.assertTrue(self.instance.is_healthy)
|
||||
|
||||
def test_state_deploying_when_available(self):
|
||||
self.node.provision_state = 'available'
|
||||
self.assertEqual('deploying', self.instance.state)
|
||||
self.assertFalse(self.instance.is_deployed)
|
||||
self.assertTrue(self.instance.is_healthy)
|
||||
|
||||
def test_state_deploying_maintenance(self):
|
||||
self.node.maintenance = True
|
||||
self.node.provision_state = 'wait call-back'
|
||||
self.assertEqual('deploying', self.instance.state)
|
||||
self.assertFalse(self.instance.is_deployed)
|
||||
self.assertFalse(self.instance.is_healthy)
|
||||
|
||||
def test_state_active(self):
|
||||
self.node.provision_state = 'active'
|
||||
self.assertEqual('active', self.instance.state)
|
||||
self.assertTrue(self.instance.is_deployed)
|
||||
self.assertTrue(self.instance.is_healthy)
|
||||
|
||||
def test_state_maintenance(self):
|
||||
self.node.maintenance = True
|
||||
self.node.provision_state = 'active'
|
||||
self.assertEqual('maintenance', self.instance.state)
|
||||
self.assertTrue(self.instance.is_deployed)
|
||||
self.assertFalse(self.instance.is_healthy)
|
||||
|
||||
def test_state_error(self):
|
||||
self.node.provision_state = 'deploy failed'
|
||||
self.assertEqual('error', self.instance.state)
|
||||
self.assertFalse(self.instance.is_deployed)
|
||||
self.assertFalse(self.instance.is_healthy)
|
||||
|
||||
def test_state_unknown(self):
|
||||
self.node.provision_state = 'enroll'
|
||||
self.assertEqual('unknown', self.instance.state)
|
||||
self.assertFalse(self.instance.is_deployed)
|
||||
self.assertFalse(self.instance.is_healthy)
|
||||
|
||||
@mock.patch.object(_instance.Instance, 'ip_addresses', autospec=True)
|
||||
def test_to_dict(self, mock_ips):
|
||||
self.node.provision_state = 'wait call-back'
|
||||
self.node.to_dict.return_value = {'node': 'dict'}
|
||||
self.node.instance_info = {'metalsmith_hostname': 'host'}
|
||||
mock_ips.return_value = {'private': ['1.2.3.4']}
|
||||
|
||||
self.assertEqual({'hostname': 'host',
|
||||
'ip_addresses': {'private': ['1.2.3.4']},
|
||||
'node': {'node': 'dict'},
|
||||
'state': 'deploying',
|
||||
'uuid': self.node.uuid},
|
||||
self.instance.to_dict())
|
@ -17,8 +17,8 @@ import fixtures
|
||||
import mock
|
||||
import testtools
|
||||
|
||||
from metalsmith import _instance
|
||||
from metalsmith import _os_api
|
||||
from metalsmith import _provisioner
|
||||
|
||||
|
||||
class TestInit(testtools.TestCase):
|
||||
@ -95,13 +95,13 @@ class TestNodes(testtools.TestCase):
|
||||
self.assertIs(res, self.cli.node.get.return_value)
|
||||
|
||||
def test_get_node_by_instance(self):
|
||||
inst = _provisioner.Instance(mock.Mock(), mock.Mock())
|
||||
inst = _instance.Instance(mock.Mock(), mock.Mock())
|
||||
res = self.api.get_node(inst)
|
||||
self.assertIs(res, inst.node)
|
||||
self.assertFalse(self.cli.node.get.called)
|
||||
|
||||
def test_get_node_by_instance_with_refresh(self):
|
||||
inst = _provisioner.Instance(mock.Mock(),
|
||||
inst = _instance.Instance(mock.Mock(),
|
||||
mock.Mock(spec=['uuid'], uuid='uuid1'))
|
||||
res = self.api.get_node(inst, refresh=True)
|
||||
self.cli.node.get.assert_called_once_with('uuid1',
|
||||
|
@ -16,6 +16,7 @@
|
||||
import mock
|
||||
import testtools
|
||||
|
||||
from metalsmith import _instance
|
||||
from metalsmith import _os_api
|
||||
from metalsmith import _provisioner
|
||||
from metalsmith import exceptions
|
||||
@ -612,7 +613,7 @@ class TestShowInstance(Base):
|
||||
inst = self.pr.show_instance('uuid1')
|
||||
self.api.get_node.assert_called_once_with('uuid1',
|
||||
accept_hostname=True)
|
||||
self.assertIsInstance(inst, _provisioner.Instance)
|
||||
self.assertIsInstance(inst, _instance.Instance)
|
||||
self.assertIs(inst.node, self.node)
|
||||
self.assertIs(inst.uuid, self.node.uuid)
|
||||
self.api.cache_node_list_for_lookup.assert_called_once_with()
|
||||
@ -626,104 +627,7 @@ class TestShowInstance(Base):
|
||||
])
|
||||
self.assertIsInstance(result, list)
|
||||
for inst in result:
|
||||
self.assertIsInstance(inst, _provisioner.Instance)
|
||||
self.assertIsInstance(inst, _instance.Instance)
|
||||
self.assertIs(result[0].node, self.node)
|
||||
self.assertIs(result[0].uuid, self.node.uuid)
|
||||
self.api.cache_node_list_for_lookup.assert_called_once_with()
|
||||
|
||||
|
||||
class TestInstanceStates(Base):
|
||||
def setUp(self):
|
||||
super(TestInstanceStates, self).setUp()
|
||||
self.instance = _provisioner.Instance(self.api, self.node)
|
||||
|
||||
def test_state_deploying(self):
|
||||
self.node.provision_state = 'wait call-back'
|
||||
self.assertEqual('deploying', self.instance.state)
|
||||
self.assertFalse(self.instance.is_deployed)
|
||||
self.assertTrue(self.instance.is_healthy)
|
||||
|
||||
def test_state_deploying_when_available(self):
|
||||
self.node.provision_state = 'available'
|
||||
self.assertEqual('deploying', self.instance.state)
|
||||
self.assertFalse(self.instance.is_deployed)
|
||||
self.assertTrue(self.instance.is_healthy)
|
||||
|
||||
def test_state_deploying_maintenance(self):
|
||||
self.node.maintenance = True
|
||||
self.node.provision_state = 'wait call-back'
|
||||
self.assertEqual('deploying', self.instance.state)
|
||||
self.assertFalse(self.instance.is_deployed)
|
||||
self.assertFalse(self.instance.is_healthy)
|
||||
|
||||
def test_state_active(self):
|
||||
self.node.provision_state = 'active'
|
||||
self.assertEqual('active', self.instance.state)
|
||||
self.assertTrue(self.instance.is_deployed)
|
||||
self.assertTrue(self.instance.is_healthy)
|
||||
|
||||
def test_state_maintenance(self):
|
||||
self.node.maintenance = True
|
||||
self.node.provision_state = 'active'
|
||||
self.assertEqual('maintenance', self.instance.state)
|
||||
self.assertTrue(self.instance.is_deployed)
|
||||
self.assertFalse(self.instance.is_healthy)
|
||||
|
||||
def test_state_error(self):
|
||||
self.node.provision_state = 'deploy failed'
|
||||
self.assertEqual('error', self.instance.state)
|
||||
self.assertFalse(self.instance.is_deployed)
|
||||
self.assertFalse(self.instance.is_healthy)
|
||||
|
||||
def test_state_unknown(self):
|
||||
self.node.provision_state = 'enroll'
|
||||
self.assertEqual('unknown', self.instance.state)
|
||||
self.assertFalse(self.instance.is_deployed)
|
||||
self.assertFalse(self.instance.is_healthy)
|
||||
|
||||
@mock.patch.object(_provisioner.Instance, 'ip_addresses', autospec=True)
|
||||
def test_to_dict(self, mock_ips):
|
||||
self.node.provision_state = 'wait call-back'
|
||||
self.node.to_dict.return_value = {'node': 'dict'}
|
||||
self.node.instance_info = {'metalsmith_hostname': 'host'}
|
||||
mock_ips.return_value = {'private': ['1.2.3.4']}
|
||||
|
||||
self.assertEqual({'hostname': 'host',
|
||||
'ip_addresses': {'private': ['1.2.3.4']},
|
||||
'node': {'node': 'dict'},
|
||||
'state': 'deploying',
|
||||
'uuid': self.node.uuid},
|
||||
self.instance.to_dict())
|
||||
|
||||
|
||||
class TestInstanceIPAddresses(Base):
|
||||
def setUp(self):
|
||||
super(TestInstanceIPAddresses, self).setUp()
|
||||
self.instance = _provisioner.Instance(self.api, self.node)
|
||||
self.api.list_node_attached_ports.return_value = [
|
||||
mock.Mock(spec=['id'], id=i) for i in ('111', '222')
|
||||
]
|
||||
self.ports = [
|
||||
mock.Mock(spec=['network_id', 'fixed_ips', 'network'],
|
||||
network_id=n, fixed_ips=[{'ip_address': ip}])
|
||||
for n, ip in [('0', '192.168.0.1'), ('1', '10.0.0.2')]
|
||||
]
|
||||
self.api.get_port.side_effect = self.ports
|
||||
self.nets = [
|
||||
mock.Mock(spec=['id', 'name'], id=str(i)) for i in range(2)
|
||||
]
|
||||
for n in self.nets:
|
||||
n.name = 'name-%s' % n.id
|
||||
self.api.get_network.side_effect = self.nets
|
||||
|
||||
def test_ip_addresses(self):
|
||||
ips = self.instance.ip_addresses()
|
||||
self.assertEqual({'name-0': ['192.168.0.1'],
|
||||
'name-1': ['10.0.0.2']},
|
||||
ips)
|
||||
|
||||
def test_missing_ip(self):
|
||||
self.ports[0].fixed_ips = {}
|
||||
ips = self.instance.ip_addresses()
|
||||
self.assertEqual({'name-0': [],
|
||||
'name-1': ['10.0.0.2']}, ips)
|
||||
|
Loading…
Reference in New Issue
Block a user