Add action that returns list of registered compute nodes.
List contains only nodes registered to the same nova-cloud-controller as the nova-compute service running on targeted unit. Closes-Bug: #1911013 Change-Id: I28d1a9bd18b3a87fc31ff4bca5bfe58449cdae57
This commit is contained in:
parent
1989ec7890
commit
3f00b8f509
|
@ -301,6 +301,7 @@ deployed then see file `actions.yaml`.
|
||||||
* `disable`
|
* `disable`
|
||||||
* `enable`
|
* `enable`
|
||||||
* `hugepagereport`
|
* `hugepagereport`
|
||||||
|
* `list-compute-nodes`
|
||||||
* `node-name`
|
* `node-name`
|
||||||
* `openstack-upgrade`
|
* `openstack-upgrade`
|
||||||
* `pause`
|
* `pause`
|
||||||
|
|
|
@ -12,6 +12,8 @@ register-to-cloud:
|
||||||
README.md, section 'Cloud downscaling'.
|
README.md, section 'Cloud downscaling'.
|
||||||
openstack-upgrade:
|
openstack-upgrade:
|
||||||
description: Perform openstack upgrades. Config option action-managed-upgrade must be set to True.
|
description: Perform openstack upgrades. Config option action-managed-upgrade must be set to True.
|
||||||
|
list-compute-nodes:
|
||||||
|
description: List all nova-compute nodes registered in the Openstack cloud.
|
||||||
node-name:
|
node-name:
|
||||||
description: Return nova-compute node name. This can be used to identify this unit in the list of nova-compute services.
|
description: Return nova-compute node name. This can be used to identify this unit in the list of nova-compute services.
|
||||||
pause:
|
pause:
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
import json
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
@ -136,7 +137,17 @@ def register_to_cloud():
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
def list_computes():
|
||||||
|
"""Implementation of `list-compute-nodes` action."""
|
||||||
|
nova = cloud_utils.nova_client()
|
||||||
|
function_set({'node-name': cloud_utils.service_hostname()})
|
||||||
|
computes = [service.to_dict()
|
||||||
|
for service in nova.services.list(binary='nova-compute')]
|
||||||
|
function_set({'compute-nodes': json.dumps(computes)})
|
||||||
|
|
||||||
|
|
||||||
def node_name():
|
def node_name():
|
||||||
|
"""Implementation of 'node-name' action."""
|
||||||
function_set({'node-name': cloud_utils.service_hostname()})
|
function_set({'node-name': cloud_utils.service_hostname()})
|
||||||
|
|
||||||
|
|
||||||
|
@ -145,6 +156,7 @@ ACTIONS = {
|
||||||
'enable': enable,
|
'enable': enable,
|
||||||
'remove-from-cloud': remove_from_cloud,
|
'remove-from-cloud': remove_from_cloud,
|
||||||
'register-to-cloud': register_to_cloud,
|
'register-to-cloud': register_to_cloud,
|
||||||
|
'list-compute-nodes': list_computes,
|
||||||
'node-name': node_name,
|
'node-name': node_name,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
cloud.py
|
|
@ -11,15 +11,29 @@
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
import json
|
||||||
import sys
|
import sys
|
||||||
from unittest import TestCase
|
from unittest import TestCase
|
||||||
from unittest.mock import MagicMock, patch
|
from unittest.mock import MagicMock, patch, call
|
||||||
|
|
||||||
sys.modules['nova_compute_hooks'] = MagicMock()
|
sys.modules['nova_compute_hooks'] = MagicMock()
|
||||||
import cloud
|
import cloud
|
||||||
del sys.modules['nova_compute_hooks']
|
del sys.modules['nova_compute_hooks']
|
||||||
|
|
||||||
|
|
||||||
|
class _MockComputeHost:
|
||||||
|
|
||||||
|
def __init__(self, node_name, state='enabled', binary='nova-compute'):
|
||||||
|
self.node_name = node_name
|
||||||
|
self.state = state
|
||||||
|
self.binary = binary
|
||||||
|
|
||||||
|
def to_dict(self):
|
||||||
|
return {'node_name': self.node_name,
|
||||||
|
'state': self.state,
|
||||||
|
'binary': self.binary}
|
||||||
|
|
||||||
|
|
||||||
class _ActionTestCase(TestCase):
|
class _ActionTestCase(TestCase):
|
||||||
|
|
||||||
NAME = ''
|
NAME = ''
|
||||||
|
@ -233,6 +247,37 @@ class TestRegisterToCloud(_ActionTestCase):
|
||||||
cloud.function_fail.assert_not_called()
|
cloud.function_fail.assert_not_called()
|
||||||
|
|
||||||
|
|
||||||
|
class TestListComputeNodes(_ActionTestCase):
|
||||||
|
NAME = 'list-compute-nodes'
|
||||||
|
|
||||||
|
MOCK_LIST = [_MockComputeHost('compute0'),
|
||||||
|
_MockComputeHost('compute1')]
|
||||||
|
|
||||||
|
def setUp(self, to_mock=None):
|
||||||
|
super(TestListComputeNodes, self).setUp()
|
||||||
|
self.nova_client = MagicMock()
|
||||||
|
services = MagicMock()
|
||||||
|
services.list.return_value = self.MOCK_LIST
|
||||||
|
self.nova_client.services = services
|
||||||
|
|
||||||
|
def test_list_compute_nodes(self):
|
||||||
|
"""Test listing nov-compute services."""
|
||||||
|
cloud.cloud_utils.nova_client.return_value = self.nova_client
|
||||||
|
expected_identity = 'compute-0'
|
||||||
|
cloud.cloud_utils.service_hostname.return_value = expected_identity
|
||||||
|
self.call_action()
|
||||||
|
|
||||||
|
expected_nodes = [host.to_dict() for host in self.MOCK_LIST
|
||||||
|
if host.binary == 'nova-compute']
|
||||||
|
|
||||||
|
expected_calls = [call({'node-name': expected_identity}),
|
||||||
|
call({'compute-nodes': json.dumps(expected_nodes)})]
|
||||||
|
|
||||||
|
self.nova_client.services.list.assert_called_with(
|
||||||
|
binary='nova-compute')
|
||||||
|
cloud.function_set.assert_has_calls(expected_calls)
|
||||||
|
|
||||||
|
|
||||||
class TestNodeName(_ActionTestCase):
|
class TestNodeName(_ActionTestCase):
|
||||||
NAME = 'node-name'
|
NAME = 'node-name'
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue