Skip to content

Commit ff3a1d3

Browse files
committed
[compute] Add set host command
set host command is missing, add it as SetHost class. Change-Id: I7acb94150718b7150598632cbebc3d85018a0d59
1 parent 8787ad2 commit ff3a1d3

6 files changed

Lines changed: 228 additions & 0 deletions

File tree

doc/source/command-objects/host.rst

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,41 @@ List all hosts
2121

2222
Only return hosts in the availability zone
2323

24+
host set
25+
--------
26+
27+
Set host command
28+
29+
.. program:: host set
30+
.. code:: bash
31+
32+
os host set
33+
[--enable | --disable]
34+
[--enable-maintenance | --disable-maintenance]
35+
<host>
36+
37+
.. _host-set:
38+
.. option:: --enable
39+
40+
Enable the host
41+
42+
.. option:: --disable
43+
44+
Disable the host
45+
46+
.. _maintenance-set:
47+
.. option:: --enable-maintenance
48+
49+
Enable maintenance mode for the host
50+
51+
.. option:: --disable-maintenance
52+
53+
Disable maintenance mode for the host
54+
55+
.. describe:: <host>
56+
57+
The host (name or ID)
58+
2459
host show
2560
---------
2661

openstackclient/compute/v2/host.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,63 @@ def take_action(self, parsed_args):
4444
) for s in data))
4545

4646

47+
class SetHost(command.Command):
48+
"""Set host properties"""
49+
def get_parser(self, prog_name):
50+
parser = super(SetHost, self).get_parser(prog_name)
51+
parser.add_argument(
52+
"host",
53+
metavar="<host>",
54+
help="The host to modify (name or ID)"
55+
)
56+
status = parser.add_mutually_exclusive_group()
57+
status.add_argument(
58+
'--enable',
59+
action='store_true',
60+
help='Enable the host'
61+
)
62+
status.add_argument(
63+
'--disable',
64+
action='store_true',
65+
help='Disable the host'
66+
)
67+
maintenance = parser.add_mutually_exclusive_group()
68+
maintenance.add_argument(
69+
'--enable-maintenance',
70+
action='store_true',
71+
help='Enable maintenance mode for the host'
72+
)
73+
maintenance.add_argument(
74+
'--disable-maintenance',
75+
action='store_true',
76+
help='Disable maintenance mode for the host',
77+
)
78+
return parser
79+
80+
def take_action(self, parsed_args):
81+
kwargs = {}
82+
83+
if parsed_args.enable:
84+
kwargs['status'] = True
85+
if parsed_args.disable:
86+
kwargs['status'] = False
87+
if parsed_args.enable_maintenance:
88+
kwargs['maintenance_mode'] = True
89+
if parsed_args.disable_maintenance:
90+
kwargs['maintenance_mode'] = False
91+
92+
compute_client = self.app.client_manager.compute
93+
foundhost = utils.find_resource(
94+
compute_client.hosts,
95+
parsed_args.host
96+
)
97+
98+
compute_client.hosts.update(
99+
foundhost.id,
100+
kwargs
101+
)
102+
103+
47104
class ShowHost(command.Lister):
48105
"""Show host command"""
49106

openstackclient/tests/compute/v2/fakes.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,9 @@ def __init__(self, **kwargs):
140140
self.keypairs = mock.Mock()
141141
self.keypairs.resource_class = fakes.FakeResource(None, {})
142142

143+
self.hosts = mock.Mock()
144+
self.hosts.resource_class = fakes.FakeResource(None, {})
145+
143146
self.auth_token = kwargs['token']
144147

145148
self.management_url = kwargs['endpoint']
@@ -878,3 +881,56 @@ def create_networks(attrs={}, methods={}, count=2):
878881
networks.append(FakeNetwork.create_one_network(attrs, methods))
879882

880883
return networks
884+
885+
886+
class FakeHost(object):
887+
"""Fake one host."""
888+
889+
@staticmethod
890+
def create_one_host(attrs=None):
891+
"""Create a fake host.
892+
893+
:param Dictionary attrs:
894+
A dictionary with all attributes
895+
:return:
896+
A FakeResource object, with id and other attributes
897+
"""
898+
if attrs is None:
899+
attrs = {}
900+
901+
# Set default attributes.
902+
host_info = {
903+
"id": 1,
904+
"service_id": 1,
905+
"host": "host1",
906+
"uuid": 'host-id-' + uuid.uuid4().hex,
907+
"vcpus": 10,
908+
"memory_mb": 100,
909+
"local_gb": 100,
910+
"vcpus_used": 5,
911+
"memory_mb_used": 50,
912+
"local_gb_used": 10,
913+
"hypervisor_type": "xen",
914+
"hypervisor_version": 1,
915+
"hypervisor_hostname": "devstack1",
916+
"free_ram_mb": 50,
917+
"free_disk_gb": 50,
918+
"current_workload": 10,
919+
"running_vms": 1,
920+
"cpu_info": "",
921+
"disk_available_least": 1,
922+
"host_ip": "10.10.10.10",
923+
"supported_instances": "",
924+
"metrics": "",
925+
"pci_stats": "",
926+
"extra_resources": "",
927+
"stats": "",
928+
"numa_topology": "",
929+
"ram_allocation_ratio": 1.0,
930+
"cpu_allocation_ratio": 1.0
931+
}
932+
host_info.update(attrs)
933+
host = fakes.FakeResource(
934+
info=copy.deepcopy(host_info),
935+
loaded=True)
936+
return host
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# Copyright 2016 IBM Corporation
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
4+
# not use this file except in compliance with the License. You may obtain
5+
# a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12+
# License for the specific language governing permissions and limitations
13+
# under the License.
14+
#
15+
16+
from openstackclient.compute.v2 import host
17+
from openstackclient.tests.compute.v2 import fakes as compute_fakes
18+
19+
20+
class TestHost(compute_fakes.TestComputev2):
21+
22+
def setUp(self):
23+
super(TestHost, self).setUp()
24+
25+
# Get a shortcut to the FlavorManager Mock
26+
self.host_mock = self.app.client_manager.compute.hosts
27+
self.host_mock.reset_mock()
28+
29+
30+
class TestHostSet(TestHost):
31+
32+
def setUp(self):
33+
super(TestHostSet, self).setUp()
34+
35+
self.host = compute_fakes.FakeHost.create_one_host()
36+
self.host_mock.get.return_value = self.host
37+
self.host_mock.update.return_value = None
38+
39+
self.cmd = host.SetHost(self.app, None)
40+
41+
def test_host_set_no_option(self):
42+
arglist = [
43+
str(self.host.id)
44+
]
45+
verifylist = [
46+
('host', str(self.host.id))
47+
]
48+
49+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
50+
51+
result = self.cmd.take_action(parsed_args)
52+
self.assertIsNone(result)
53+
54+
body = {}
55+
self.host_mock.update.assert_called_with(self.host.id, body)
56+
57+
def test_host_set(self):
58+
arglist = [
59+
'--enable',
60+
'--disable-maintenance',
61+
str(self.host.id)
62+
]
63+
verifylist = [
64+
('enable', True),
65+
('enable_maintenance', False),
66+
('host', str(self.host.id))
67+
]
68+
69+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
70+
71+
result = self.cmd.take_action(parsed_args)
72+
self.assertIsNone(result)
73+
74+
body = {'status': True, 'maintenance_mode': False}
75+
self.host_mock.update.assert_called_with(self.host.id, body)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
features:
3+
- Command ``host set`` is now available for compute
4+
[Bug `1556929 <https://bugs.launchpad.net/python-openstackclient/+bug/1556929>`_]

setup.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ openstack.compute.v2 =
7979
flavor_unset = openstackclient.compute.v2.flavor:UnsetFlavor
8080

8181
host_list = openstackclient.compute.v2.host:ListHost
82+
host_set = openstackclient.compute.v2.host:SetHost
8283
host_show = openstackclient.compute.v2.host:ShowHost
8384

8485
hypervisor_list = openstackclient.compute.v2.hypervisor:ListHypervisor

0 commit comments

Comments
 (0)