[openstack-hypervisor] Add list-nics action
Add action to list-nics on the hypervisor. This is used to gather candidate for the external network nic. Change-Id: Ife70804d035a900d5fe95059b26d3006860506da Signed-off-by: Guillaume Boutry <guillaume.boutry@canonical.com>
This commit is contained in:
parent
ef7c688448
commit
de0e8bd10e
@ -58,6 +58,10 @@ actions:
|
||||
type: string
|
||||
description: IP address to use for service configuration
|
||||
additionalProperties: false
|
||||
list-nics:
|
||||
description: |
|
||||
List host NICS, and which one are candidates for use as external NIC.
|
||||
additionalProperties: false
|
||||
|
||||
requires:
|
||||
amqp:
|
||||
|
@ -27,6 +27,7 @@ import os
|
||||
import secrets
|
||||
import socket
|
||||
import string
|
||||
import subprocess
|
||||
from typing import (
|
||||
List,
|
||||
Optional,
|
||||
@ -173,6 +174,10 @@ class HypervisorOperatorCharm(sunbeam_charm.OSBaseOperatorCharm):
|
||||
self.on.set_hypervisor_local_settings_action,
|
||||
self._set_hypervisor_local_settings_action,
|
||||
)
|
||||
self.framework.observe(
|
||||
self.on.list_nics_action,
|
||||
self._list_nics_action,
|
||||
)
|
||||
self.framework.observe(
|
||||
self.on.install,
|
||||
self._on_install,
|
||||
@ -320,6 +325,39 @@ class HypervisorOperatorCharm(sunbeam_charm.OSBaseOperatorCharm):
|
||||
if new_snap_settings:
|
||||
self.set_snap_data(new_snap_settings)
|
||||
|
||||
def _list_nics_action(self, event: ActionEvent):
|
||||
"""Run list_nics action."""
|
||||
cache = self.get_snap_cache()
|
||||
hypervisor = cache["openstack-hypervisor"]
|
||||
|
||||
if not hypervisor.present:
|
||||
event.fail("Hypervisor is not installed")
|
||||
return
|
||||
|
||||
process = subprocess.run(
|
||||
[
|
||||
"snap",
|
||||
"run",
|
||||
"openstack-hypervisor",
|
||||
"--verbose",
|
||||
"list-nics",
|
||||
"--format",
|
||||
"json",
|
||||
],
|
||||
capture_output=True,
|
||||
)
|
||||
|
||||
stderr = process.stderr.decode("utf-8")
|
||||
logger.debug("logs: %s", stderr)
|
||||
stdout = process.stdout.decode("utf-8")
|
||||
logger.debug("stdout: %s", stdout)
|
||||
if process.returncode != 0:
|
||||
event.fail(stderr)
|
||||
return
|
||||
|
||||
# cli returns a json dict with keys "nics" and "candidate"
|
||||
event.set_results({"result": stdout})
|
||||
|
||||
def ensure_services_running(self):
|
||||
"""Ensure systemd services running."""
|
||||
# This should taken care of by the snap
|
||||
|
@ -15,11 +15,14 @@
|
||||
"""Tests for Openstack hypervisor charm."""
|
||||
|
||||
import base64
|
||||
import json
|
||||
from unittest.mock import (
|
||||
MagicMock,
|
||||
)
|
||||
|
||||
import charm
|
||||
import ops
|
||||
import ops.testing
|
||||
import ops_sunbeam.test_utils as test_utils
|
||||
|
||||
|
||||
@ -35,7 +38,13 @@ class _HypervisorOperatorCharm(charm.HypervisorOperatorCharm):
|
||||
class TestCharm(test_utils.CharmTestCase):
|
||||
"""Test charm to test relations."""
|
||||
|
||||
PATCHES = ["socket", "snap", "get_local_ip_by_default_route", "os"]
|
||||
PATCHES = [
|
||||
"socket",
|
||||
"snap",
|
||||
"get_local_ip_by_default_route",
|
||||
"os",
|
||||
"subprocess",
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
"""Setup OpenStack Hypervisor tests."""
|
||||
@ -277,3 +286,53 @@ class TestCharm(test_utils.CharmTestCase):
|
||||
"masakari.enable": True,
|
||||
}
|
||||
hypervisor_snap_mock.set.assert_any_call(expect_settings, typed=True)
|
||||
|
||||
def test_list_nics_snap_not_installed(self):
|
||||
"""Check action raises ActionFailed if snap is not installed."""
|
||||
self.harness.begin()
|
||||
hypervisor_snap_mock = MagicMock()
|
||||
hypervisor_snap_mock.present = False
|
||||
self.snap.SnapCache.return_value = {
|
||||
"openstack-hypervisor": hypervisor_snap_mock
|
||||
}
|
||||
with self.assertRaises(ops.testing.ActionFailed):
|
||||
self.harness.run_action("list-nics")
|
||||
|
||||
def test_list_nics(self):
|
||||
"""Check action returns nics."""
|
||||
self.harness.begin()
|
||||
hypervisor_snap_mock = MagicMock()
|
||||
hypervisor_snap_mock.present = True
|
||||
self.snap.SnapCache.return_value = {
|
||||
"openstack-hypervisor": hypervisor_snap_mock
|
||||
}
|
||||
subprocess_run_mock = MagicMock()
|
||||
subprocess_run_mock.return_value = MagicMock(
|
||||
stdout=bytes(
|
||||
json.dumps({"nics": ["eth0", "eth1"], "candidates": ["eth2"]}),
|
||||
"utf-8",
|
||||
),
|
||||
stderr=b"yes things went well",
|
||||
returncode=0,
|
||||
)
|
||||
self.subprocess.run = subprocess_run_mock
|
||||
action_output = self.harness.run_action("list-nics")
|
||||
assert "candidates" in action_output.results["result"]
|
||||
|
||||
def test_list_nics_error(self):
|
||||
"""Check action raises ActionFailed if subprocess returns non-zero."""
|
||||
self.harness.begin()
|
||||
hypervisor_snap_mock = MagicMock()
|
||||
hypervisor_snap_mock.present = True
|
||||
self.snap.SnapCache.return_value = {
|
||||
"openstack-hypervisor": hypervisor_snap_mock
|
||||
}
|
||||
subprocess_run_mock = MagicMock()
|
||||
subprocess_run_mock.return_value = MagicMock(
|
||||
stdout=b"",
|
||||
stderr=b"things did not go well",
|
||||
returncode=1,
|
||||
)
|
||||
self.subprocess.run = subprocess_run_mock
|
||||
with self.assertRaises(ops.testing.ActionFailed):
|
||||
self.harness.run_action("list-nics")
|
||||
|
Loading…
x
Reference in New Issue
Block a user