Skip to content

Commit 2a9f7fe

Browse files
Jenkinsopenstack-gerrit
authored andcommitted
Merge "Node resource for bare-metal service"
2 parents d8b2295 + 183051a commit 2a9f7fe

File tree

2 files changed

+333
-0
lines changed

2 files changed

+333
-0
lines changed

openstack/bare_metal/v1/node.py

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
2+
# not use this file except in compliance with the License. You may obtain
3+
# a copy of the License at
4+
#
5+
# http://www.apache.org/licenses/LICENSE-2.0
6+
#
7+
# Unless required by applicable law or agreed to in writing, software
8+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10+
# License for the specific language governing permissions and limitations
11+
# under the License.
12+
13+
from openstack.bare_metal import bare_metal_service
14+
from openstack import resource2 as resource
15+
16+
17+
class Node(resource.Resource):
18+
19+
resources_key = 'nodes'
20+
base_path = '/nodes'
21+
service = bare_metal_service.BareMetalService()
22+
23+
# capabilities
24+
allow_create = True
25+
allow_get = True
26+
allow_update = True
27+
allow_delete = True
28+
allow_list = True
29+
patch_update = True
30+
31+
_query_mapping = resource.QueryParameters(
32+
'associated', 'driver', 'fields', 'provision_state', 'resource_class',
33+
instance_id='instance_uuid',
34+
is_maintenance='maintenance',
35+
)
36+
37+
# Properties
38+
#: The UUID of the chassis associated wit this node. Can be empty or None.
39+
chassis_id = resource.Body("chassis_uuid")
40+
#: The current clean step.
41+
clean_step = resource.Body("clean_step")
42+
#: Timestamp at which the node was last updated.
43+
created_at = resource.Body("created_at")
44+
#: The name of the driver.
45+
driver = resource.Body("driver")
46+
#: All the metadata required by the driver to manage this node. List of
47+
#: fields varies between drivers, and can be retrieved from the
48+
#: :class:`openstack.bare_metal.v1.driver.Driver` resource.
49+
driver_info = resource.Body("driver_info", type=dict)
50+
#: Internal metadata set and stored by node's driver. This is read-only.
51+
driver_internal_info = resource.Body("driver_internal_info", type=dict)
52+
#: A set of one or more arbitrary metadata key and value pairs.
53+
extra = resource.Body("extra")
54+
#: The UUID of the node resource.
55+
id = resource.Body("uuid", alternate_id=True)
56+
#: Information used to customize the deployed image, e.g. size of root
57+
#: partition, config drive in the form of base64 encoded string and other
58+
#: metadata.
59+
instance_info = resource.Body("instance_info")
60+
#: UUID of the nova instance associated with this node.
61+
instance_id = resource.Body("instance_uuid")
62+
#: Whether console access is enabled on this node.
63+
is_console_enabled = resource.Body("console_enabled", type=bool)
64+
#: Whether node is currently in "maintenance mode". Nodes put into
65+
#: maintenance mode are removed from the available resource pool.
66+
is_maintenance = resource.Body("maintenance", type=bool)
67+
#: Any error from the most recent transaction that started but failed to
68+
#: finish.
69+
last_error = resource.Body("last_error")
70+
#: A list of relative links, including self and bookmark links.
71+
links = resource.Body("links", type=list)
72+
#: user settable description of the reason why the node was placed into
73+
#: maintenance mode.
74+
maintenance_reason = resource.Body("maintenance_reason")
75+
#: Human readable identifier for the node. May be undefined. Certain words
76+
#: are reserved. Added in API microversion 1.5
77+
name = resource.Body("name")
78+
#: Network interface provider to use when plumbing the network connections
79+
#: for this node. Introduced in API microversion 1.20.
80+
network_interface = resource.Body("network_interface")
81+
#: Links to the collection of ports on this node.
82+
ports = resource.Body("ports", type=list)
83+
#: Links to the collection of portgroups on this node. Available since
84+
#: API microversion 1.24.
85+
port_groups = resource.Body("portgroups", type=list)
86+
#: The current power state. Usually "power on" or "power off", but may be
87+
#: "None" if service is unable to determine the power state.
88+
power_state = resource.Body("power_state")
89+
#: Physical characteristics of the node. Content populated by the service
90+
#: during inspection.
91+
properties = resource.Body("properties", type=dict)
92+
#: The current provisioning state of the node.
93+
provision_state = resource.Body("provision_state")
94+
#: The current RAID configuration of the node.
95+
raid_config = resource.Body("raid_config")
96+
#: The name of an service conductor host which is holding a lock on this
97+
#: node, if a lock is held.
98+
reservation = resource.Body("reservation")
99+
#: A string to be used by external schedulers to identify this node as a
100+
#: unit of a specific type of resource. Added in API microversion 1.21.
101+
resource_class = resource.Body("resource_class")
102+
#: Links to the collection of states.
103+
states = resource.Body("states", type=list)
104+
#: The requested state if a provisioning action has been requested. For
105+
#: example, ``AVAILABLE``, ``DEPLOYING``, ``DEPLOYWAIT``, ``DEPLOYING``,
106+
#: ``ACTIVE`` etc.
107+
target_provision_state = resource.Body("target_provision_state")
108+
#: The requested state during a state transition.
109+
target_power_state = resource.Body("target_power_state")
110+
#: The requested RAID configration of the node which will be applied when
111+
#: the node next transitions through the CLEANING state.
112+
target_raid_config = resource.Body("target_raid_config")
113+
#: Timestamp at which the node was last updated.
114+
updated_at = resource.Body("updated_at")
115+
116+
117+
class NodeDetail(Node):
118+
119+
base_path = '/nodes/detail'
120+
121+
# capabilities
122+
allow_create = False
123+
allow_get = False
124+
allow_update = False
125+
allow_delete = False
126+
allow_list = True
127+
128+
_query_mapping = resource.QueryParameters(
129+
'associated', 'driver', 'fields', 'provision_state', 'resource_class',
130+
instance_id='instance_uuid',
131+
is_maintenance='maintenance',
132+
)
133+
134+
#: The UUID of the node resource.
135+
id = resource.Body("uuid", alternate_id=True)
Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
2+
# not use this file except in compliance with the License. You may obtain
3+
# a copy of the License at
4+
#
5+
# http://www.apache.org/licenses/LICENSE-2.0
6+
#
7+
# Unless required by applicable law or agreed to in writing, software
8+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10+
# License for the specific language governing permissions and limitations
11+
# under the License.
12+
13+
import testtools
14+
15+
from openstack.bare_metal.v1 import node
16+
17+
# NOTE: Sample data from api-ref doc
18+
FAKE = {
19+
"chassis_uuid": "1", # NOTE: missed in api-ref sample
20+
"clean_step": {},
21+
"console_enabled": False,
22+
"created_at": "2016-08-18T22:28:48.643434+00:00",
23+
"driver": "agent_ipmitool",
24+
"driver_info": {
25+
"ipmi_password": "******",
26+
"ipmi_username": "ADMIN"
27+
},
28+
"driver_internal_info": {},
29+
"extra": {},
30+
"inspection_finished_at": None,
31+
"inspection_started_at": None,
32+
"instance_info": {},
33+
"instance_uuid": None,
34+
"last_error": None,
35+
"links": [
36+
{
37+
"href": "http://127.0.0.1:6385/v1/nodes/<NODE_ID>",
38+
"rel": "self"
39+
},
40+
{
41+
"href": "http://127.0.0.1:6385/nodes/<NODE_ID>",
42+
"rel": "bookmark"
43+
}
44+
],
45+
"maintenance": False,
46+
"maintenance_reason": None,
47+
"name": "test_node",
48+
"network_interface": "flat",
49+
"portgroups": [
50+
{
51+
"href": "http://127.0.0.1:6385/v1/nodes/<NODE_ID>/portgroups",
52+
"rel": "self"
53+
},
54+
{
55+
"href": "http://127.0.0.1:6385/nodes/<NODE_ID>/portgroups",
56+
"rel": "bookmark"
57+
}
58+
],
59+
"ports": [
60+
{
61+
"href": "http://127.0.0.1:6385/v1/nodes/<NODE_ID>/ports",
62+
"rel": "self"
63+
},
64+
{
65+
"href": "http://127.0.0.1:6385/nodes/<NODE_ID>/ports",
66+
"rel": "bookmark"
67+
}
68+
],
69+
"power_state": None,
70+
"properties": {},
71+
"provision_state": "enroll",
72+
"provision_updated_at": None,
73+
"raid_config": {},
74+
"reservation": None,
75+
"resource_class": None,
76+
"states": [
77+
{
78+
"href": "http://127.0.0.1:6385/v1/nodes/<NODE_ID>/states",
79+
"rel": "self"
80+
},
81+
{
82+
"href": "http://127.0.0.1:6385/nodes/<NODE_ID>/states",
83+
"rel": "bookmark"
84+
}
85+
],
86+
"target_power_state": None,
87+
"target_provision_state": None,
88+
"target_raid_config": {},
89+
"updated_at": None,
90+
"uuid": "6d85703a-565d-469a-96ce-30b6de53079d"
91+
}
92+
93+
94+
class TestNode(testtools.TestCase):
95+
96+
def test_basic(self):
97+
sot = node.Node()
98+
self.assertIsNone(sot.resource_key)
99+
self.assertEqual('nodes', sot.resources_key)
100+
self.assertEqual('/nodes', sot.base_path)
101+
self.assertEqual('baremetal', sot.service.service_type)
102+
self.assertTrue(sot.allow_create)
103+
self.assertTrue(sot.allow_get)
104+
self.assertTrue(sot.allow_update)
105+
self.assertTrue(sot.allow_delete)
106+
self.assertTrue(sot.allow_list)
107+
self.assertTrue(sot.patch_update)
108+
109+
def test_instantiate(self):
110+
sot = node.Node(**FAKE)
111+
112+
self.assertEqual(FAKE['uuid'], sot.id)
113+
self.assertEqual(FAKE['name'], sot.name)
114+
115+
self.assertEqual(FAKE['chassis_uuid'], sot.chassis_id)
116+
self.assertEqual(FAKE['clean_step'], sot.clean_step)
117+
self.assertEqual(FAKE['created_at'], sot.created_at)
118+
self.assertEqual(FAKE['driver'], sot.driver)
119+
self.assertEqual(FAKE['driver_info'], sot.driver_info)
120+
self.assertEqual(FAKE['driver_internal_info'],
121+
sot.driver_internal_info)
122+
self.assertEqual(FAKE['extra'], sot.extra)
123+
self.assertEqual(FAKE['instance_info'], sot.instance_info)
124+
self.assertEqual(FAKE['instance_uuid'], sot.instance_id)
125+
self.assertEqual(FAKE['console_enabled'], sot.is_console_enabled)
126+
self.assertEqual(FAKE['maintenance'], sot.is_maintenance)
127+
self.assertEqual(FAKE['last_error'], sot.last_error)
128+
self.assertEqual(FAKE['links'], sot.links)
129+
self.assertEqual(FAKE['maintenance_reason'], sot.maintenance_reason)
130+
self.assertEqual(FAKE['name'], sot.name)
131+
self.assertEqual(FAKE['network_interface'], sot.network_interface)
132+
self.assertEqual(FAKE['ports'], sot.ports)
133+
self.assertEqual(FAKE['portgroups'], sot.port_groups)
134+
self.assertEqual(FAKE['power_state'], sot.power_state)
135+
self.assertEqual(FAKE['properties'], sot.properties)
136+
self.assertEqual(FAKE['provision_state'], sot.provision_state)
137+
self.assertEqual(FAKE['raid_config'], sot.raid_config)
138+
self.assertEqual(FAKE['reservation'], sot.reservation)
139+
self.assertEqual(FAKE['resource_class'], sot.resource_class)
140+
self.assertEqual(FAKE['states'], sot.states)
141+
self.assertEqual(FAKE['target_provision_state'],
142+
sot.target_provision_state)
143+
self.assertEqual(FAKE['target_power_state'], sot.target_power_state)
144+
self.assertEqual(FAKE['target_raid_config'], sot.target_raid_config)
145+
self.assertEqual(FAKE['updated_at'], sot.updated_at)
146+
147+
148+
class TestNodeDetail(testtools.TestCase):
149+
150+
def test_basic(self):
151+
sot = node.NodeDetail()
152+
self.assertIsNone(sot.resource_key)
153+
self.assertEqual('nodes', sot.resources_key)
154+
self.assertEqual('/nodes/detail', sot.base_path)
155+
self.assertEqual('baremetal', sot.service.service_type)
156+
self.assertFalse(sot.allow_create)
157+
self.assertFalse(sot.allow_get)
158+
self.assertFalse(sot.allow_update)
159+
self.assertFalse(sot.allow_delete)
160+
self.assertTrue(sot.allow_list)
161+
162+
def test_instantiate(self):
163+
sot = node.NodeDetail(**FAKE)
164+
165+
self.assertEqual(FAKE['uuid'], sot.id)
166+
self.assertEqual(FAKE['name'], sot.name)
167+
168+
self.assertEqual(FAKE['chassis_uuid'], sot.chassis_id)
169+
self.assertEqual(FAKE['clean_step'], sot.clean_step)
170+
self.assertEqual(FAKE['created_at'], sot.created_at)
171+
self.assertEqual(FAKE['driver'], sot.driver)
172+
self.assertEqual(FAKE['driver_info'], sot.driver_info)
173+
self.assertEqual(FAKE['driver_internal_info'],
174+
sot.driver_internal_info)
175+
self.assertEqual(FAKE['extra'], sot.extra)
176+
self.assertEqual(FAKE['instance_info'], sot.instance_info)
177+
self.assertEqual(FAKE['instance_uuid'], sot.instance_id)
178+
self.assertEqual(FAKE['console_enabled'], sot.is_console_enabled)
179+
self.assertEqual(FAKE['maintenance'], sot.is_maintenance)
180+
self.assertEqual(FAKE['last_error'], sot.last_error)
181+
self.assertEqual(FAKE['links'], sot.links)
182+
self.assertEqual(FAKE['maintenance_reason'], sot.maintenance_reason)
183+
self.assertEqual(FAKE['name'], sot.name)
184+
self.assertEqual(FAKE['network_interface'], sot.network_interface)
185+
self.assertEqual(FAKE['ports'], sot.ports)
186+
self.assertEqual(FAKE['portgroups'], sot.port_groups)
187+
self.assertEqual(FAKE['power_state'], sot.power_state)
188+
self.assertEqual(FAKE['properties'], sot.properties)
189+
self.assertEqual(FAKE['provision_state'], sot.provision_state)
190+
self.assertEqual(FAKE['raid_config'], sot.raid_config)
191+
self.assertEqual(FAKE['reservation'], sot.reservation)
192+
self.assertEqual(FAKE['resource_class'], sot.resource_class)
193+
self.assertEqual(FAKE['states'], sot.states)
194+
self.assertEqual(FAKE['target_provision_state'],
195+
sot.target_provision_state)
196+
self.assertEqual(FAKE['target_power_state'], sot.target_power_state)
197+
self.assertEqual(FAKE['target_raid_config'], sot.target_raid_config)
198+
self.assertEqual(FAKE['updated_at'], sot.updated_at)

0 commit comments

Comments
 (0)