Skip to content

Commit

Permalink
✨ add bto baremetals api (#86)
Browse files Browse the repository at this point in the history
* ✨ IF-5903 add bto baremetals api

* ✨ IF-5903 add bto baremetals api

* ✨ IF-5903 add bto baremetals api

Co-authored-by: oizaki.atsushi <atsushi.oizaki@ntt.com>
  • Loading branch information
a-oi-xon and a-oi-xon authored Nov 9, 2021
1 parent 05e8832 commit ed4b903
Show file tree
Hide file tree
Showing 6 changed files with 325 additions and 6 deletions.
65 changes: 59 additions & 6 deletions ecl/baremetal/v2/_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from ecl.baremetal.v2 import stock as _stock
from ecl.baremetal.v2 import nic_physical_port as _port
from ecl.baremetal.v2 import server as _server
from ecl.baremetal.v2 import chassis as _chassis
from ecl.baremetal import version as _version
from ecl import proxy2
from ecl import session
Expand Down Expand Up @@ -286,9 +287,9 @@ def find_server(self, name_or_id, ignore_missing=False):
"""
return self._find(_server.Server, name_or_id, ignore_missing=ignore_missing)

def create_server(self, name, networks, flavor, admin_pass=None,
image=None, key_name=None, availability_zone=None,
user_data=None, raid_arrays=None,
def create_server(self, name, networks, admin_pass=None, image=None,
flavor=None, chassis_id=None, key_name=None,
availability_zone=None, user_data=None, raid_arrays=None,
lvm_volume_groups=None, filesystems=None,
metadata=None, personality=None):
"""This API create additional Baremetal server.
Expand All @@ -297,11 +298,13 @@ def create_server(self, name, networks, flavor, admin_pass=None,
:param array networks: Network Array.
If it is specified greater than two, default gateway is
first network.
:param string flavor: The flavor reference for the desired flavor for your
Baremetal server.
:param string admin_pass: Password for the administrator.
:param string image: The image reference for the desired image for your
Baremetal server.
:param string flavor: The flavor reference for the desired flavor for your
Baremetal server. You can specify either flavor or chassis_id.
:param string chassis_id: The ID of chassis which you use to deploy
Baremetal server. You can specify either flavor or chassis_id.
:param string key_name: SSH Keypair name you created on KeyPairs API.
:param string availability_zone: The availability zone name in which to launch
the server.
Expand All @@ -318,11 +321,15 @@ def create_server(self, name, networks, flavor, admin_pass=None,
esxi.
:return: :class:`~ecl.baremetal.v2.server.Server`
"""
attrs = {"name": name, "networks": networks, "flavorRef": flavor}
attrs = {"name": name, "networks": networks}
if admin_pass:
attrs["adminPass"] = admin_pass
if image:
attrs["imageRef"] = image
if flavor:
attrs["flavorRef"] = flavor
if chassis_id:
attrs["chassis_id"] = chassis_id
if key_name:
attrs["key_name"] = key_name
if availability_zone:
Expand Down Expand Up @@ -350,6 +357,17 @@ def delete_server(self, server_id):
"""
return self._delete(_server.Server, server_id)

def update_server(self, server_id, name):
""" This API updates the editable attributes of the specified baremetal server.
:param string server_id: ID for the specified server.
:param string name: Name of your baremetal server as a string.
:return: :class:`~ecl.baremetal.v2.server.Server`
"""
attrs = {"name": name}
server = _server.Server()
return server.update(self.session, server_id, **attrs)

def start_server(self, server_id):
"""Power on the Baremetal Server associated with server_id.
This request will be accepted only when the task_state is None.
Expand Down Expand Up @@ -509,3 +527,38 @@ def update_metadata(self, server_id, key, **attr):
"""
metadata = _metadata.Metadata()
return metadata.update(self.session, server_id, key, **attr)

def chassis(self, details=True):
"""Lists all Chassis or ChassisDetail.
A chassis represents base object of baremetal server.
Each chassis is assigned an unique id and has dedicated disk spaces,
memory capacities and cpu resources. You can create baremetal server
upon this object.
:param bool details: When set to ``False``
:class:`~ecl.baremetal.v2.chassis.Chassis` instance
will be returned. The default, ``True``, will cause
:class:`~ecl.baremetal.v2.chassis.ChassisDetail`
instances to be returned.
:return: A List of :class:`~ecl.baremetal.v2.chassis.Chassis` or
:class:`~ecl.baremetal.v2.chassis.ChassisDetail`
"""
chassis = _chassis.ChassisDetail if details else _chassis.Chassis
return list(self._list(chassis))

def get_chassis(self, chassis_id):
"""Gets details for a ChassisDetail associated with chassis_id.
A chassis represents base object of baremetal server.
Each chassis is assigned an unique id and has dedicated disk spaces,
memory capacities and cpu resources. You can create baremetal server
upon this object.
:param string chassis_id: ID for the chassis.
:return: :class:`~ecl.baremetal.v2.chassis.Chassis`
"""
# Use "Chassis" instead of "ChassisDetail".
# Because "detail" is not included to the request path.
return self._get(_chassis.Chassis, chassis_id)
64 changes: 64 additions & 0 deletions ecl/baremetal/v2/chassis.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# 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 ecl.baremetal import baremetal_service
from ecl import resource2


class Chassis(resource2.Resource):
"""Chassis Resource"""

resource_key = 'chassis'
resources_key = 'chassis'
base_path = '/chassis'
service = baremetal_service.BaremetalService()

# Capabilities
allow_get = True
allow_list = True

# Properties
#: The ID for the chassis, which is a unique integer value.
id = resource2.Body('id')
#: The name of availability zone where chassis exists.
availability_zone = resource2.Body('availability_zone')
#: The name of flavor of chassis.
flavor_name = resource2.Body('flavor_name')
#: The object of summarized hardware spec. That has cpus, disks and rams.
hardware_summary = resource2.Body('hardware_summary', type=dict)
#: The status of chassis.
status = resource2.Body('status')
#: The ID of server attached to chassis. If no server is attached to chassis, the value is null.
server_id = resource2.Body('server_id')
#: The name of server attached to chassis. If no server is attached to chassis, the value is null.
server_name = resource2.Body('server_name')
#: The minimum contract period of your chassis.
contract_year = resource2.Body('contract_year', type=int)
#: The date that you start to use the chassis.
start_time = resource2.Body('start_time')

# Properties (for Detail)
#: The spec of all cpus installed in chassis.
cpus = resource2.Body('cpus', type=list)
#: The spec of all disks installed in chassis.
disks = resource2.Body('disks', type=list)
#: The spec of all rams installed in chassis.
rams = resource2.Body('rams', type=list)


class ChassisDetail(Chassis):
"""ChassisDetail Resource"""

base_path = '/chassis/detail'

# Capabilities
allow_get = False
11 changes: 11 additions & 0 deletions ecl/baremetal/v2/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class Server(resource2.Resource):
allow_list = True
allow_create = True
allow_delete = True
allow_update = True

# Properties
#: UUID of the Baremetal server.
Expand Down Expand Up @@ -115,6 +116,16 @@ def create(self, session, **attrs):
self._translate_response(resp, has_body=True)
return self

def update(self, session, server_id, **attrs):
url = "%s/%s" % (self.base_path, server_id)
body = {"server": attrs}
resp = session.put(url,
endpoint_filter=self.service,
json=body,
headers={"Accept": "application/json"})
self._translate_response(resp, has_body=True)
return self


class ServerDetail(Server):
base_path = '/servers/detail'
Expand Down
83 changes: 83 additions & 0 deletions ecl/tests/functional/baremetal/test_chassis.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# 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 six

from ecl.tests.functional import base


class TestChassis(base.BaseFunctionalTest):

def test_chassis(self):
chassis_list = list(self.conn.baremetal.chassis(details=False))
self.assertGreater(len(chassis_list), 0)

for chassis in chassis_list:
print(chassis)
self.assertIsInstance(chassis.id, six.string_types)
self.assertIsInstance(chassis.availability_zone, six.string_types)
self.assertIsInstance(chassis.flavor_name, six.string_types)
self.assertIsInstance(chassis.hardware_summary, dict)
self.assertIsInstance(chassis.status, six.string_types)
self.assertIsInstance(chassis.server_id,
(six.string_types, type(None)))
self.assertIsInstance(chassis.server_name,
(six.string_types, type(None)))
self.assertIsInstance(chassis.contract_year, int)
self.assertIsInstance(chassis.start_time, six.string_types)

def test_chassis_detail(self):
chassis_list = list(self.conn.baremetal.chassis(details=True))
self.assertGreater(len(chassis_list), 0)

for chassis in chassis_list:
print(chassis)
self.assertIsInstance(chassis.id, six.string_types)
self.assertIsInstance(chassis.availability_zone, six.string_types)
self.assertIsInstance(chassis.flavor_name, six.string_types)
self.assertIsInstance(chassis.hardware_summary, dict)
self.assertIsInstance(chassis.status, six.string_types)
self.assertIsInstance(chassis.server_id,
(six.string_types, type(None)))
self.assertIsInstance(chassis.server_name,
(six.string_types, type(None)))
self.assertIsInstance(chassis.contract_year, int)
self.assertIsInstance(chassis.start_time, six.string_types)

self.assertIsInstance(chassis.cpus, list)
self.assertIsInstance(chassis.disks, list)
self.assertIsInstance(chassis.rams, list)

def test_get_chassis(self):
# ChassisIDはMock Serverに合わせて変更する
chassis_id = '31e7a0c4-f49e-19e6-2192-c9f9cc6f5a74'

chassis = self.conn.baremetal.get_chassis(chassis_id)
print(chassis)
# Mock Serverを使用するとランダムなUUIDが返却されるのでパスパラメータを一致しない
# self.assertEqual(chassis.id, chassis_id)

self.assertIsInstance(chassis.availability_zone, six.string_types)
self.assertIsInstance(chassis.flavor_name, six.string_types)
self.assertIsInstance(chassis.hardware_summary, dict)
self.assertIsInstance(chassis.status, six.string_types)
self.assertIsInstance(chassis.server_id,
(six.string_types, type(None)))
self.assertIsInstance(chassis.server_name,
(six.string_types, type(None)))
self.assertIsInstance(chassis.contract_year, int)
self.assertIsInstance(chassis.start_time, six.string_types)

self.assertIsInstance(chassis.cpus, list)
self.assertIsInstance(chassis.disks, list)
self.assertIsInstance(chassis.rams, list)

9 changes: 9 additions & 0 deletions ecl/tests/functional/baremetal/test_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,12 @@ def test_04_show_server(self):
def test_05_delete_server(self):
server = self.conn.baremetal.delete_server("752aac2e-4b82-4d47-a7c7-xx")
assert False

def test_06_update_server(self):
# ServerIDはMock Serverに合わせて変更する
server_id = "3072a550-2ff4-a9d6-438b-0ce8b650eaa5"
name = "hoge"

server = self.conn.baremetal.update_server(server_id, name)
print(server)
self.assertIsInstance(server.id, six.string_types)
99 changes: 99 additions & 0 deletions ecl/tests/unit/baremetal/v2/test_charssis.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# 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 testtools

from ecl.baremetal.v2 import chassis

IDENTIFIER = 'IDENTIFIER'
CHASSIS_EXAMPLE = {
'id': IDENTIFIER,
'availability_zone': '2',
'flavor_name': '3',
'hardware_summary': {'4': 4},
'status': '5',
'server_id': '6',
'server_name': '7',
'contract_year': 8,
'start_time': '9',
}

CHASSIS_DETAIL_EXAMPLE = {
'id': IDENTIFIER,
'availability_zone': '2',
'flavor_name': '3',
'hardware_summary': {'4': 4},
'status': '5',
'server_id': '6',
'server_name': '7',
'contract_year': 8,
'start_time': '9',
'cpus': [{'10': 10},],
'disks': [{'11': 11},],
'rams': [{'12': 12},],
}
from unittest.mock import patch

class TestChassis(testtools.TestCase):

def test_basic(self):
sot = chassis.Chassis()
self.assertEqual('chassis', sot.resource_key)
self.assertEqual('chassis', sot.resources_key)
self.assertEqual('/chassis', sot.base_path)
self.assertEqual('baremetal-server', sot.service.service_type)
self.assertTrue(sot.allow_get)
self.assertTrue(sot.allow_list)
self.assertFalse(sot.allow_create)
self.assertFalse(sot.allow_delete)
self.assertFalse(sot.allow_update)
self.assertFalse(sot.allow_head)

def test_make_basic(self):
sot = chassis.Chassis(**CHASSIS_EXAMPLE)
self.assertEqual(CHASSIS_EXAMPLE['id'], sot.id)
self.assertEqual(CHASSIS_EXAMPLE['availability_zone'], sot.availability_zone)
self.assertEqual(CHASSIS_EXAMPLE['flavor_name'], sot.flavor_name)
self.assertEqual(CHASSIS_EXAMPLE['hardware_summary'], sot.hardware_summary)
self.assertEqual(CHASSIS_EXAMPLE['status'], sot.status)
self.assertEqual(CHASSIS_EXAMPLE['server_id'], sot.server_id)
self.assertEqual(CHASSIS_EXAMPLE['server_name'], sot.server_name)
self.assertEqual(CHASSIS_EXAMPLE['contract_year'], sot.contract_year)
self.assertEqual(CHASSIS_EXAMPLE['start_time'], sot.start_time)

def test_detail(self):
sot = chassis.ChassisDetail()
self.assertEqual('chassis', sot.resource_key)
self.assertEqual('chassis', sot.resources_key)
self.assertEqual('/chassis/detail', sot.base_path)
self.assertEqual('baremetal-server', sot.service.service_type)
self.assertFalse(sot.allow_get)
self.assertTrue(sot.allow_list)
self.assertFalse(sot.allow_create)
self.assertFalse(sot.allow_delete)
self.assertFalse(sot.allow_update)
self.assertFalse(sot.allow_head)

def test_make_detail(self):
sot = chassis.ChassisDetail(**CHASSIS_DETAIL_EXAMPLE)
self.assertEqual(CHASSIS_DETAIL_EXAMPLE['id'], sot.id)
self.assertEqual(CHASSIS_DETAIL_EXAMPLE['availability_zone'], sot.availability_zone)
self.assertEqual(CHASSIS_DETAIL_EXAMPLE['flavor_name'], sot.flavor_name)
self.assertEqual(CHASSIS_DETAIL_EXAMPLE['hardware_summary'], sot.hardware_summary)
self.assertEqual(CHASSIS_DETAIL_EXAMPLE['status'], sot.status)
self.assertEqual(CHASSIS_DETAIL_EXAMPLE['server_id'], sot.server_id)
self.assertEqual(CHASSIS_DETAIL_EXAMPLE['server_name'], sot.server_name)
self.assertEqual(CHASSIS_DETAIL_EXAMPLE['contract_year'], sot.contract_year)
self.assertEqual(CHASSIS_DETAIL_EXAMPLE['start_time'], sot.start_time)
self.assertEqual(CHASSIS_DETAIL_EXAMPLE['cpus'], sot.cpus)
self.assertEqual(CHASSIS_DETAIL_EXAMPLE['disks'], sot.disks)
self.assertEqual(CHASSIS_DETAIL_EXAMPLE['rams'], sot.rams)

0 comments on commit ed4b903

Please sign in to comment.