Introducing GEO location new fields for System
New fields was created for the system object. Changes was made to include GEO location attributes (latitude, longitude) to the system object and adding a way to retrieve and modify those attributes using the API and CLI. Updates on: DB system model; DB migration; System object fields; API fields; CLI fields; API documentation. Story: 2008570 Task: 41721 Signed-off-by: Daniel Pinto Barros <DanielPinto.Barros@windriver.com> Change-Id: I86f124c44d80896427e3ac1bc799fe34588ae942
This commit is contained in:
parent
e3a97fc267
commit
8f0312b518
|
@ -525,6 +525,8 @@ itemNotFound (404)
|
|||
"timezone (Optional)", "plain", "xsd:string", "The timezone of the cloud system."
|
||||
"description (Optional)", "plain", "xsd:string", "A user-specified description of the cloud system."
|
||||
"location (Optional)", "plain", "xsd:string", "The user-specified location of the cloud system."
|
||||
"latitude (Optional)", "plain", "xsd:string", "The user-specified latitude GPS coordinate of the cloud system."
|
||||
"longitude (Optional)", "plain", "xsd:string", "The user-specified longitude GPS coordinate of the cloud system."
|
||||
"capabilities (Optional)", "plain", "xsd:dictionary", "System capabilities. <ul><li>sdn_enabled : (Boolean) Software Defined Networking enabled. </li><li>region_config : (Boolean) region selection: <ul><li>true : Secondary region. </li><li>false : Primary region. </li></ul></li><li>shared_services : Services provided by Primary region. </li><li>bm_region : Board Management controller network selection: <ul><li>External : OAM network. </li><li>Internal : Management network. </li></ul></li><li>cinder_backend : backend selection for Cinder. </li><li>vswitch_type : vSwitch selection. </li><li>security_feature : Selection of Spectre and Meltdown mitigation options. </li><li>https_enabled : (Boolean) selection of https mode for public URLs. </li></ul>"
|
||||
"contact (Optional)", "plain", "xsd:string", "The user-specified contact for the cloud system."
|
||||
"software_version (Optional)", "plain", "xsd:string", "Contains the Cloud Server Software Version and the Software Version of the underlying Linux Kernel."
|
||||
|
@ -555,6 +557,8 @@ itemNotFound (404)
|
|||
"updated_at": "2014-09-24T14:35:38.091392+00:00",
|
||||
"contact": null,
|
||||
"location": null,
|
||||
"latitude": null,
|
||||
"longitude": null,
|
||||
"description": "The Ottawa Cloud Test Lab.",
|
||||
"system_type": "Standard",
|
||||
"system_mode": "duplex",
|
||||
|
@ -591,6 +595,10 @@ The attributes of the System object that are modifiable are:
|
|||
|
||||
- location,
|
||||
|
||||
- latitude,
|
||||
|
||||
- longitude,
|
||||
|
||||
- sdn_enabled,
|
||||
|
||||
- contact.
|
||||
|
@ -616,6 +624,8 @@ badMediaType (415)
|
|||
"timezone (Optional)", "plain", "xsd:string", "The timezone of the cloud system."
|
||||
"description (Optional)", "plain", "xsd:string", "A user-specified description of the cloud system."
|
||||
"location (Optional)", "plain", "xsd:string", "The user-specified location of the cloud system."
|
||||
"latitude (Optional)", "plain", "xsd:string", "The user-specified latitude GPS coordinate of the cloud system."
|
||||
"longitude (Optional)", "plain", "xsd:string", "The user-specified longitude GPS coordinate of the cloud system."
|
||||
"capabilities (Optional)", "plain", "xsd:dictionary", "System capabilities. <ul><li>sdn_enabled : (Boolean) Software Defined Networking enabled. </li><li>region_config : (Boolean) region selection: <ul><li>true : Secondary region. </li><li>false : Primary region. </li></ul></li><li>shared_services : Services provided by Primary region. </li><li>bm_region : Board Management controller network selection: <ul><li>External : OAM network. </li><li>Internal : Management network. </li></ul></li><li>cinder_backend : backend selection for Cinder. </li><li>vswitch_type : vSwitch selection. </li><li>security_feature : Selection of Spectre and Meltdown mitigation options. </li><li>https_enabled : (Boolean) selection of https mode for public URLs. </li></ul>"
|
||||
"contact (Optional)", "plain", "xsd:string", "The user-specified contact for the cloud system."
|
||||
"software_version (Optional)", "plain", "xsd:string", "Contains the Cloud Server Software Version and the Software Version of the underlying Linux Kernel."
|
||||
|
@ -642,6 +652,16 @@ badMediaType (415)
|
|||
"value": "350 Terry Fox Dr, Kanata, Ontario, Canada",
|
||||
"op": "replace"
|
||||
}
|
||||
{
|
||||
"path": "/latitude",
|
||||
"value": "45.35189954974955",
|
||||
"op": "replace"
|
||||
}
|
||||
{
|
||||
"path": "/longitude",
|
||||
"value": "-75.91866628453701",
|
||||
"op": "replace"
|
||||
}
|
||||
{
|
||||
"path": "/contact",
|
||||
"value": "support@windriver.com",
|
||||
|
@ -684,6 +704,8 @@ badMediaType (415)
|
|||
"updated_at": "2017-07-31T17:44:06.051441+00:00",
|
||||
"created_at": "2017-07-31T17:35:46.836024+00:00",
|
||||
"location": "350 Terry Fox Dr, Kanata, Ontario, Canada",
|
||||
"latitude": "45.35189954974955",
|
||||
"longitude": "-75.91866628453701",
|
||||
"capabilities": {
|
||||
"sdn_enabled": true,
|
||||
"shared_services": "[]",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2013-2017 Wind River Systems, Inc.
|
||||
# Copyright (c) 2013-2021 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -17,9 +17,9 @@ from six.moves import input
|
|||
|
||||
def _print_isystem_show(isystem):
|
||||
fields = ['name', 'system_type', 'system_mode', 'description', 'location',
|
||||
'contact', 'timezone', 'software_version', 'uuid',
|
||||
'created_at', 'updated_at', 'region_name', 'service_project_name',
|
||||
'security_feature']
|
||||
'latitude', 'longitude', 'contact', 'timezone', 'software_version',
|
||||
'uuid', 'created_at', 'updated_at', 'region_name',
|
||||
'service_project_name', 'security_feature']
|
||||
if isystem.capabilities.get('region_config'):
|
||||
fields.append('shared_services')
|
||||
setattr(isystem, 'shared_services',
|
||||
|
@ -76,6 +76,12 @@ def do_show(cc, args):
|
|||
@utils.arg('-l', '--location',
|
||||
metavar='<location>',
|
||||
help='The location of the system')
|
||||
@utils.arg('-la', '--latitude',
|
||||
metavar='<latitude>',
|
||||
help='The latitude GEO location coordinate of the system')
|
||||
@utils.arg('-lo', '--longitude',
|
||||
metavar='<longitude>',
|
||||
help='The longitude GEO location coordinate of the system')
|
||||
@utils.arg('-p', '--https_enabled',
|
||||
metavar='<https_enabled>',
|
||||
choices=['true', 'false', 'True', 'False'],
|
||||
|
@ -134,8 +140,9 @@ def do_modify(cc, args):
|
|||
return
|
||||
print('Please follow the admin guide to complete the reconfiguration.')
|
||||
|
||||
field_list = ['name', 'system_mode', 'description', 'location', 'contact',
|
||||
'timezone', 'sdn_enabled', 'https_enabled', 'vswitch_type', 'security_feature']
|
||||
field_list = ['name', 'system_mode', 'description', 'location', 'latitude',
|
||||
'longitude', 'contact', 'timezone', 'sdn_enabled',
|
||||
'https_enabled', 'vswitch_type', 'security_feature']
|
||||
|
||||
# use field list as filter
|
||||
user_fields = dict((k, v) for (k, v) in vars(args).items()
|
||||
|
|
|
@ -75,6 +75,12 @@ class System(base.APIBase):
|
|||
location = wtypes.text
|
||||
"The location of the isystem"
|
||||
|
||||
latitude = wtypes.text
|
||||
"The latitude GPS coordinate of the system"
|
||||
|
||||
longitude = wtypes.text
|
||||
"The longitude GPS coordinate of the system"
|
||||
|
||||
services = int
|
||||
"The services of the isystem"
|
||||
|
||||
|
@ -132,8 +138,8 @@ class System(base.APIBase):
|
|||
def convert_with_links(cls, rpc_isystem, expand=True):
|
||||
# isystem = isystem(**rpc_isystem.as_dict())
|
||||
minimum_fields = ['id', 'uuid', 'name', 'system_type', 'system_mode',
|
||||
'description', 'capabilities',
|
||||
'contact', 'location', 'software_version',
|
||||
'description', 'capabilities', 'contact',
|
||||
'location', 'latitude', 'longitude', 'software_version',
|
||||
'created_at', 'updated_at', 'timezone',
|
||||
'region_name', 'service_project_name',
|
||||
'distributed_cloud_role', 'security_feature']
|
||||
|
@ -409,6 +415,12 @@ class SystemController(rest.RestController):
|
|||
"does not exist." %
|
||||
timezone))
|
||||
|
||||
if (p['path'] == '/latitude' or p['path'] == '/longitude'):
|
||||
if p['value'] is not None:
|
||||
if len(p['value']) > 30:
|
||||
raise wsme.exc.ClientSideError("Geolocation coordinates can not be "
|
||||
"longer than 30 characters")
|
||||
|
||||
if p['path'] == '/sdn_enabled':
|
||||
sdn_enabled = p['value'].lower()
|
||||
patch.remove(p)
|
||||
|
@ -557,7 +569,6 @@ class SystemController(rest.RestController):
|
|||
if name or location or contact:
|
||||
LOG.info("update SNMP config")
|
||||
pecan.request.rpcapi.update_snmp_config(pecan.request.context)
|
||||
|
||||
if 'system_mode' in delta_handle:
|
||||
LOG.info("update system mode %s" % system_mode)
|
||||
pecan.request.rpcapi.update_system_mode_config(
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
#
|
||||
# Copyright (c) 2021 Intel Corporation, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
from sqlalchemy import Column
|
||||
from sqlalchemy import MetaData
|
||||
from sqlalchemy import String
|
||||
from sqlalchemy import Table
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
"""
|
||||
This database upgrade updates the i_system table by creating
|
||||
new columns to store GPS coordinates.
|
||||
Arguments:
|
||||
- Requires sqlalchemy migration engine
|
||||
"""
|
||||
|
||||
meta = MetaData()
|
||||
meta.bind = migrate_engine
|
||||
migrate_engine.connect()
|
||||
|
||||
i_system = Table('i_system', meta, autoload=True)
|
||||
i_system.create_column(Column('latitude', String(30)))
|
||||
i_system.create_column(Column('longitude', String(30)))
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
# Downgrade is unsupported in this release.
|
||||
raise NotImplementedError('SysInv database downgrade is unsupported.')
|
|
@ -99,6 +99,8 @@ class isystem(Base):
|
|||
capabilities = Column(JSONEncodedDict)
|
||||
contact = Column(String(255))
|
||||
location = Column(String(255))
|
||||
latitude = Column(String(30))
|
||||
longitude = Column(String(30))
|
||||
services = Column(Integer, default=72)
|
||||
software_version = Column(String(255))
|
||||
timezone = Column(String(255))
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2013-2016 Wind River Systems, Inc.
|
||||
# Copyright (c) 2013-2021 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -27,6 +27,8 @@ class System(base.SysinvObject):
|
|||
'capabilities': utils.dict_or_none,
|
||||
'contact': utils.str_or_none,
|
||||
'location': utils.str_or_none,
|
||||
'latitude': utils.str_or_none,
|
||||
'longitude': utils.str_or_none,
|
||||
'services': utils.int_or_none,
|
||||
'software_version': utils.str_or_none,
|
||||
'timezone': utils.str_or_none,
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
#
|
||||
# Copyright (c) 2021 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
"""
|
||||
Tests for the API /isystems/ methods.
|
||||
"""
|
||||
|
||||
from sysinv.tests.api import base
|
||||
from sysinv.tests.db import utils as dbutils
|
||||
from six.moves import http_client
|
||||
|
||||
|
||||
class TestSystem(base.FunctionalTest):
|
||||
def setUp(self):
|
||||
super(TestSystem, self).setUp()
|
||||
|
||||
def _get_path(self, system_id=None):
|
||||
return "/isystems/%s" % system_id if system_id else "/isystems"
|
||||
|
||||
def _patch_and_check(self, path, updates, expect_errors=False):
|
||||
patch = []
|
||||
for att, val in updates.items():
|
||||
patch.append({"path": "/%s" % att,
|
||||
"value": val,
|
||||
"op": "replace"})
|
||||
|
||||
# Updating system attributes
|
||||
response = self.patch_json(path, patch,
|
||||
expect_errors=expect_errors)
|
||||
|
||||
if expect_errors:
|
||||
self.assertEqual(http_client.BAD_REQUEST, response.status_int)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
self.assertTrue(response.json['error_message'])
|
||||
else:
|
||||
patched_system = response.json
|
||||
|
||||
# Verify if system attributes was changed
|
||||
for att, val in updates.items():
|
||||
self.assertEqual(val, patched_system[att])
|
||||
|
||||
|
||||
class TestSystemUpdate(TestSystem):
|
||||
|
||||
def setUp(self):
|
||||
super(TestSystemUpdate, self).setUp()
|
||||
self.system = dbutils.create_test_isystem()
|
||||
|
||||
def test_update_latitude_longer_than_30_chars(self):
|
||||
update = {"latitude": "00.0000000111111111122222222223"}
|
||||
self._patch_and_check(self._get_path(self.system.uuid),
|
||||
update, expect_errors=True)
|
||||
|
||||
def test_update_latitude_valid_length(self):
|
||||
update = {"latitude": "00.11223344556677"}
|
||||
self._patch_and_check(self._get_path(self.system.uuid),
|
||||
update)
|
||||
|
||||
def test_update_latitude_null_value(self):
|
||||
update = {"latitude": None}
|
||||
self._patch_and_check(self._get_path(self.system.uuid),
|
||||
update)
|
||||
|
||||
def test_update_longitude_longer_than_30_chars(self):
|
||||
update = {"longitude": "00.0000000111111111122222222223"}
|
||||
self._patch_and_check(self._get_path(self.system.uuid),
|
||||
update, expect_errors=True)
|
||||
|
||||
def test_update_longitude_valid_length(self):
|
||||
update = {"longitude": "-00.11223344556677"}
|
||||
self._patch_and_check(self._get_path(self.system.uuid),
|
||||
update)
|
||||
|
||||
def test_update_longitude_null_value(self):
|
||||
update = {"longitude": None}
|
||||
self._patch_and_check(self._get_path(self.system.uuid),
|
||||
update)
|
|
@ -15,7 +15,7 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
# Copyright (c) 2013-2020 Wind River Systems, Inc.
|
||||
# Copyright (c) 2013-2021 Wind River Systems, Inc.
|
||||
#
|
||||
|
||||
"""Sysinv test utilities."""
|
||||
|
@ -201,6 +201,8 @@ def get_test_isystem(**kw):
|
|||
'system_mode': kw.get('system_mode', constants.SYSTEM_MODE_DUPLEX),
|
||||
'region_name': kw.get('region_name', constants.REGION_ONE_NAME),
|
||||
'location': kw.get('location', 'isystemlocation'),
|
||||
'latitude': kw.get('latitude'),
|
||||
'longitude': kw.get('longitude'),
|
||||
'services': kw.get('services', 72),
|
||||
'software_version': kw.get('software_version', SW_VERSION)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue