Show OAM Floating IP for Subcloud
Extends the dcmanager subcloud show command to display the floating OAM IP of the subcloud from the system controller. Change-Id: Ib421ea65660ed77a241798831c83cbaf1710f9e8 Story: 2007267 Task: 38896 Signed-off-by: Jessica Castelino <jessica.castelino@windriver.com>
This commit is contained in:
parent
845d9b9af4
commit
fe3ef48558
@ -261,7 +261,7 @@ serviceUnavailable (503)
|
||||
}
|
||||
|
||||
******************************************************
|
||||
Shows detailed information about a specific subcloud
|
||||
Shows information about a specific subcloud
|
||||
******************************************************
|
||||
|
||||
.. rest_method:: GET /v1.0/subclouds/{subcloud}
|
||||
@ -350,6 +350,98 @@ internalServerError (500), serviceUnavailable (503)
|
||||
|
||||
This operation does not accept a request body.
|
||||
|
||||
******************************************************
|
||||
Shows additional information about a specific subcloud
|
||||
******************************************************
|
||||
|
||||
.. rest_method:: GET /v1.0/subclouds/<200b>{subcloud}<200b>/detail
|
||||
|
||||
**Normal response codes**
|
||||
|
||||
200
|
||||
|
||||
**Error response codes**
|
||||
|
||||
itemNotFound (404), badRequest (400), unauthorized (401), forbidden
|
||||
(403), badMethod (405), HTTPUnprocessableEntity (422),
|
||||
internalServerError (500), serviceUnavailable (503)
|
||||
|
||||
**Request parameters**
|
||||
|
||||
.. csv-table::
|
||||
:header: "Parameter", "Style", "Type", "Description"
|
||||
:widths: 20, 20, 20, 60
|
||||
|
||||
"subcloud", "URI", "xsd:string", "The subcloud reference, name or id."
|
||||
|
||||
**Response parameters**
|
||||
|
||||
.. csv-table::
|
||||
:header: "Parameter", "Style", "Type", "Description"
|
||||
:widths: 20, 20, 20, 60
|
||||
|
||||
"id (Optional)", "plain", "xsd:int", "The unique identifier for this object."
|
||||
"created_at (Optional)", "plain", "xsd:dateTime", "The time when the object was created."
|
||||
"updated_at (Optional)", "plain", "xsd:dateTime", "The time when the object was last updated."
|
||||
"name (Optional)", "plain", "xsd:string", "The name provisioned for the subcloud."
|
||||
"management (Optional)", "plain", "xsd:string", "Management state of the subcloud."
|
||||
"availability (Optional)", "plain", "xsd:string", "Availability status of the subcloud."
|
||||
"management-subnet (Optional)", "plain", "xsd:string", "Management subnet for subcloud in CIDR format."
|
||||
"management-start-ip (Optional)", "plain", "xsd:string", "Start of management IP address range for subcloud."
|
||||
"management-end-ip (Optional)", "plain", "xsd:string", "End of management IP address range for subcloud."
|
||||
"systemcontroller-gateway-ip (Optional)", "plain", "xsd:string", "Systemcontroller gateway IP Address."
|
||||
"endpoint_sync_status (Optional)", "plain", "xsd:list", "The list of endpoint sync statuses."
|
||||
"platform_sync_status (Optional)", "plain", "xsd:string", "The platform sync status of the subcloud."
|
||||
"volume_sync_status (Optional)", "plain", "xsd:string", "The volume sync status of the subcloud."
|
||||
"compute_sync_status (Optional)", "plain", "xsd:string", "The compute sync status of the subcloud."
|
||||
"network_sync_status (Optional)", "plain", "xsd:string", "The network sync status of the subcloud."
|
||||
"patching_sync_status (Optional)", "plain", "xsd:string", "The patching sync status of the subcloud."
|
||||
"oam_floating_ip (Optional)", "plain", "xsd:string", "OAM Floating IP of the subcloud."
|
||||
|
||||
::
|
||||
|
||||
{
|
||||
"description": "test subcloud",
|
||||
"management-start-ip": "192.168.204.50",
|
||||
"created-at": "2018-02-25 19:06:35.208505",
|
||||
"updated-at": "2018-02-25 21:35:59.771779",
|
||||
"software-version": "18.01",
|
||||
"management-state": "unmanaged",
|
||||
"availability-status": "offline",
|
||||
"management-subnet": "192.168.204.0/24",
|
||||
"systemcontroller-gateway-ip": "192.168.204.101",
|
||||
"location": "ottawa",
|
||||
"endpoint_sync_status": [
|
||||
{
|
||||
"sync_status": "in-sync",
|
||||
"endpoint_type": "compute"
|
||||
},
|
||||
{
|
||||
"sync_status": "in-sync",
|
||||
"endpoint_type": "network"
|
||||
},
|
||||
{
|
||||
"sync_status": "in-sync",
|
||||
"endpoint_type": "patching"
|
||||
},
|
||||
{
|
||||
"sync_status": "in-sync",
|
||||
"endpoint_type": "platform"
|
||||
},
|
||||
{
|
||||
"sync_status": "in-sync",
|
||||
"endpoint_type": "volume"
|
||||
}
|
||||
],
|
||||
"management-gateway-ip": "192.168.204.1",
|
||||
"management-end-ip": "192.168.204.100",
|
||||
"id": 1,
|
||||
"name": "subcloud6",
|
||||
"oam_floating_ip" "10.10.10.12"
|
||||
}
|
||||
|
||||
This operation does not accept a request body.
|
||||
|
||||
******************************
|
||||
Modifies a specific subcloud
|
||||
******************************
|
||||
@ -449,65 +541,6 @@ Deletes a specific subcloud
|
||||
|
||||
This operation does not accept a request body.
|
||||
|
||||
****************************************************
|
||||
Generates the configuration of a specific subcloud
|
||||
****************************************************
|
||||
|
||||
.. rest_method:: POST /v1.0/subclouds/{subcloud}/config
|
||||
|
||||
**Normal response codes**
|
||||
|
||||
200
|
||||
|
||||
**Error response codes**
|
||||
|
||||
badRequest (400), unauthorized (401), forbidden (403), badMethod (405),
|
||||
HTTPUnprocessableEntity (422), internalServerError (500),
|
||||
serviceUnavailable (503)
|
||||
|
||||
**Request parameters**
|
||||
|
||||
.. csv-table::
|
||||
:header: "Parameter", "Style", "Type", "Description"
|
||||
:widths: 20, 20, 20, 60
|
||||
|
||||
"subcloud", "URI", "xsd:string", "The subcloud reference, name or id."
|
||||
"pxe-subnet (Optional)", "plain", "xsd:string", "PXE boot boot subnet for subcloud in CIDR format."
|
||||
"management-vlan (Optional)", "plain", "xsd:string", "VLAN for subcloud management network."
|
||||
"management-interface-port (Optional)", "plain", "xsd:string", "Subcloud management interface port."
|
||||
"management-interface-mtu (Optional)", "plain", "xsd:string", "Subcloud management interface mtu."
|
||||
"oam-subnet (Optional)", "plain", "xsd:string", "OAM subnet for subcloud in CIDR format."
|
||||
"oam-gateway-ip (Optional)", "plain", "xsd:string", "OAM gateway IP for subcloud."
|
||||
"oam-floating-ip (Optional)", "plain", "xsd:string", "OAM floating IP address for subcloud."
|
||||
"oam-unit-0-ip (Optional)", "plain", "xsd:string", "OAM unit 0 IP address for subcloud."
|
||||
"oam-unit-1-ip (Optional)", "plain", "xsd:string", "OAM unit 1 IP address for subcloud."
|
||||
"oam-interface-port (Optional)", "plain", "xsd:string", "Subcloud OAM interface port."
|
||||
"oam-interface-mtu (Optional)", "plain", "xsd:string", "Subcloud OAM interface mtu."
|
||||
"system-mode (Optional)", "plain", "xsd:string", "System mode, ``simplex, duplex, or duplex-direct``."
|
||||
|
||||
::
|
||||
|
||||
{
|
||||
"oam-gateway-ip": "10.10.20.1",
|
||||
"oam-interface-mtu": "1500",
|
||||
"oam-subnet": "10.10.20.0/24",
|
||||
"management-interface-port": "enp0s3",
|
||||
"system-mode": "duplex",
|
||||
"management-interface-mtu": "1500",
|
||||
"oam-unit-1-ip": "10.10.20.4",
|
||||
"oam-interface-port": "enp0s8",
|
||||
"management-vlan": "10",
|
||||
"pxe-subnet": "192.168.205.0/24",
|
||||
"oam-unit-0-ip": "10.10.20.3",
|
||||
"oam-floating-ip": "10.10.20.2"
|
||||
}
|
||||
|
||||
::
|
||||
|
||||
{
|
||||
"config": "[SYSTEM]\nSYSTEM_MODE=duplex\n[REGION2_PXEBOOT_NETWORK]\nPXEBOOT_CIDR = 192.168.205.0/24\n[MGMT_NETWORK]\nVLAN = 10\nCIDR = 192.168.204.0/24\nGATEWAY = 192.168.204.1\nIP_START_ADDRESS = 192.168.204.50\nIP_END_ADDRESS = 192.168.204.100\nDYNAMIC_ALLOCATION = Y\nLOGICAL_INTERFACE = LOGICAL_INTERFACE_1\n[LOGICAL_INTERFACE_1]\nLAG_INTERFACE = N\nINTERFACE_MTU = 1500\nINTERFACE_PORTS = enp0s3\n[OAM_NETWORK]\nCIDR = 10.10.20.0/24\nGATEWAY = 10.10.20.1\nIP_FLOATING_ADDRESS = 10.10.20.2\nIP_UNIT_0_ADDRESS = 10.10.20.3\nIP_UNIT_1_ADDRESS = 10.10.20.4\nLOGICAL_INTERFACE = LOGICAL_INTERFACE_2\n[LOGICAL_INTERFACE_2]\nLAG_INTERFACE = N\nINTERFACE_MTU = 1500\nINTERFACE_PORTS = enp0s8\n[SHARED_SERVICES]\nSYSTEM_CONTROLLER_SUBNET = 192.168.204.0/24\nSYSTEM_CONTROLLER_FLOATING_ADDRESS = 192.168.204.2\nREGION_NAME = RegionOne\nADMIN_PROJECT_NAME = admin\nADMIN_USER_NAME = admin\nADMIN_PASSWORD = Li69nux*\nKEYSTONE_ADMINURL = http://192.168.204.2:5000/v3\nKEYSTONE_SERVICE_NAME = keystone\nKEYSTONE_SERVICE_TYPE = identity\nGLANCE_SERVICE_NAME = glance\nGLANCE_SERVICE_TYPE = image\nGLANCE_CACHED = True\n[REGION_2_SERVICES]\nREGION_NAME = subcloud6\n[VERSION]\nRELEASE = 18.01\n"
|
||||
}
|
||||
|
||||
----------------
|
||||
Subcloud Alarms
|
||||
----------------
|
||||
|
@ -37,6 +37,7 @@ from controllerconfig.utils import validate_address_str
|
||||
from controllerconfig.utils import validate_network_str
|
||||
|
||||
from dcorch.drivers.openstack.keystone_v3 import KeystoneClient
|
||||
from keystoneauth1 import exceptions as keystone_exceptions
|
||||
|
||||
from dcmanager.api.controllers import restcomm
|
||||
from dcmanager.common import consts
|
||||
@ -48,7 +49,6 @@ from dcmanager.db import api as db_api
|
||||
from dcmanager.drivers.openstack.sysinv_v1 import SysinvClient
|
||||
from dcmanager.rpc import client as rpc_client
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
LOG = logging.getLogger(__name__)
|
||||
# System mode
|
||||
@ -333,8 +333,37 @@ class SubcloudsController(object):
|
||||
sysinv_client = SysinvClient(consts.DEFAULT_REGION_NAME, session)
|
||||
return sysinv_client.get_management_address_pool()
|
||||
|
||||
@staticmethod
|
||||
def get_ks_client(region_name=None):
|
||||
"""This will get a new keystone client (and new token)"""
|
||||
try:
|
||||
return KeystoneClient(region_name)
|
||||
except Exception:
|
||||
LOG.warn('Failure initializing KeystoneClient '
|
||||
'for region %s' % region_name)
|
||||
raise
|
||||
|
||||
def _get_oam_addresses(self, context, subcloud_name):
|
||||
"""Get the subclouds oam addresses"""
|
||||
|
||||
# First need to retrieve the Subcloud's Keystone session
|
||||
try:
|
||||
sc_ks_client = self.get_ks_client(subcloud_name)
|
||||
sysinv_client = SysinvClient(subcloud_name,
|
||||
sc_ks_client.session)
|
||||
return sysinv_client.get_oam_addresses()
|
||||
except (keystone_exceptions.EndpointNotFound, IndexError) as e:
|
||||
message = ("Identity endpoint for subcloud: %s not found. %s" %
|
||||
(subcloud_name, e))
|
||||
LOG.error(message)
|
||||
except exceptions.OAMAddressesNotFound:
|
||||
message = ("OAM addresses for subcloud: %s not found." %
|
||||
(subcloud_name))
|
||||
LOG.error(message)
|
||||
return None
|
||||
|
||||
@index.when(method='GET', template='json')
|
||||
def get(self, subcloud_ref=None):
|
||||
def get(self, subcloud_ref=None, detail=None):
|
||||
"""Get details about subcloud.
|
||||
|
||||
:param subcloud_ref: ID or name of subcloud
|
||||
@ -437,6 +466,17 @@ class SubcloudsController(object):
|
||||
subcloud_status_list}
|
||||
subcloud_dict.update(endpoint_sync_dict)
|
||||
|
||||
if detail is not None:
|
||||
oam_addresses = self._get_oam_addresses(context,
|
||||
subcloud_ref)
|
||||
if oam_addresses is not None:
|
||||
oam_floating_ip = oam_addresses.oam_floating_ip
|
||||
else:
|
||||
oam_floating_ip = "unavailable"
|
||||
floating_ip_dict = {"oam_floating_ip":
|
||||
oam_floating_ip}
|
||||
subcloud_dict.update(floating_ip_dict)
|
||||
|
||||
return subcloud_dict
|
||||
|
||||
@utils.synchronized(LOCK_NAME)
|
||||
|
@ -136,6 +136,10 @@ class InternalError(DCManagerException):
|
||||
message = _("Error when performing operation")
|
||||
|
||||
|
||||
class OAMAddressesNotFound(NotFound):
|
||||
message = _("OAM Addresses Not Found")
|
||||
|
||||
|
||||
class InvalidInputError(DCManagerException):
|
||||
message = _("An invalid value was provided")
|
||||
|
||||
|
@ -87,18 +87,14 @@ class SysinvClient(base.DriverBase):
|
||||
|
||||
return self.sysinv_client.address_pool.get(address_pool_uuid)
|
||||
|
||||
def get_oam_address_pool(self):
|
||||
def get_oam_addresses(self):
|
||||
"""Get the oam address pool for a host."""
|
||||
networks = self.sysinv_client.network.list()
|
||||
for network in networks:
|
||||
if network.type == sysinv_constants.NETWORK_TYPE_OAM:
|
||||
address_pool_uuid = network.pool_uuid
|
||||
break
|
||||
iextoam_object = self.sysinv_client.iextoam.list()
|
||||
if iextoam_object is not None and len(iextoam_object) != 0:
|
||||
return iextoam_object[0]
|
||||
else:
|
||||
LOG.error("OAM address pool not found")
|
||||
raise exceptions.InternalError()
|
||||
|
||||
return self.sysinv_client.address_pool.get(address_pool_uuid)
|
||||
LOG.error("OAM address not found")
|
||||
raise exceptions.OAMAddressesNotFound()
|
||||
|
||||
def create_route(self, interface_uuid, network, prefix, gateway, metric):
|
||||
"""Create a static route on an interface."""
|
||||
|
@ -153,8 +153,8 @@ class SubcloudInstall(object):
|
||||
raise e
|
||||
|
||||
def get_oam_address(self):
|
||||
oam_pool = self.sysinv_client.get_oam_address_pool()
|
||||
return self.format_address(oam_pool.floating_address)
|
||||
oam_addresses = self.sysinv_client.get_oam_addresses()
|
||||
return self.format_address(oam_addresses.oam_floating_ip)
|
||||
|
||||
def get_https_enabled(self):
|
||||
if self.https_enabled is None:
|
||||
|
@ -487,9 +487,9 @@ class SubcloudManager(manager.Manager):
|
||||
mgmt_floating_ip = mgmt_pool.floating_address
|
||||
mgmt_subnet = "%s/%d" % (mgmt_pool.network, mgmt_pool.prefix)
|
||||
|
||||
oam_pool = sysinv_client.get_oam_address_pool()
|
||||
oam_floating_ip = oam_pool.floating_address
|
||||
oam_subnet = "%s/%d" % (oam_pool.network, oam_pool.prefix)
|
||||
oam_addresses = sysinv_client.get_oam_addresses()
|
||||
oam_floating_ip = oam_addresses.oam_floating_ip
|
||||
oam_subnet = oam_addresses.oam_subnet
|
||||
|
||||
with open(overrides_file, 'w') as f_out_overrides_file:
|
||||
f_out_overrides_file.write(
|
||||
|
@ -23,6 +23,7 @@
|
||||
import copy
|
||||
import mock
|
||||
import six
|
||||
from six.moves import http_client
|
||||
import webtest
|
||||
|
||||
from dcmanager.api.controllers.v1 import subclouds
|
||||
@ -31,7 +32,6 @@ from dcmanager.rpc import client as rpc_client
|
||||
from dcmanager.tests.unit.api import test_root_controller as testroot
|
||||
from dcmanager.tests import utils
|
||||
|
||||
|
||||
FAKE_TENANT = utils.UUID1
|
||||
FAKE_ID = '1'
|
||||
FAKE_URL = '/v1.0/subclouds'
|
||||
@ -84,6 +84,20 @@ class FakeAddressPool(object):
|
||||
self.ranges.append(range)
|
||||
|
||||
|
||||
class FakeOAMAddressPool(object):
|
||||
def __init__(self, oam_subnet, oam_start_ip,
|
||||
oam_end_ip, oam_c1_ip,
|
||||
oam_c0_ip, oam_gateway_ip,
|
||||
oam_floating_ip):
|
||||
self.oam_start_ip = oam_start_ip
|
||||
self.oam_end_ip = oam_end_ip
|
||||
self.oam_c1_ip = oam_c1_ip
|
||||
self.oam_c0_ip = oam_c0_ip
|
||||
self.oam_subnet = oam_subnet
|
||||
self.oam_gateway_ip = oam_gateway_ip
|
||||
self.oam_floating_ip = oam_floating_ip
|
||||
|
||||
|
||||
class TestSubclouds(testroot.DCManagerApiTest):
|
||||
def setUp(self):
|
||||
super(TestSubclouds, self).setUp()
|
||||
@ -404,13 +418,58 @@ class TestSubclouds(testroot.DCManagerApiTest):
|
||||
self.app.delete_json, delete_url,
|
||||
headers=FAKE_HEADERS)
|
||||
|
||||
@mock.patch.object(subclouds.SubcloudsController,
|
||||
'_get_oam_addresses')
|
||||
@mock.patch.object(rpc_client, 'ManagerClient')
|
||||
@mock.patch.object(subclouds, 'db_api')
|
||||
def test_get_subcloud(self, mock_db_api, mock_rpc_client):
|
||||
def test_get_subcloud(self,
|
||||
mock_db_api,
|
||||
mock_rpc_client,
|
||||
mock_get_oam_addresses):
|
||||
get_url = FAKE_URL + '/' + FAKE_ID
|
||||
self.app.get(get_url, headers=FAKE_HEADERS)
|
||||
response = self.app.get(get_url, headers=FAKE_HEADERS)
|
||||
self.assertEqual(response.content_type, 'application/json')
|
||||
self.assertEqual(response.status_code, http_client.OK)
|
||||
self.assertEqual(response.json.get('oam_floating_ip', None), None)
|
||||
self.assertEqual(1, mock_db_api.subcloud_get_with_status.call_count)
|
||||
|
||||
@mock.patch.object(subclouds.SubcloudsController,
|
||||
'_get_oam_addresses')
|
||||
@mock.patch.object(rpc_client, 'ManagerClient')
|
||||
@mock.patch.object(subclouds, 'db_api')
|
||||
def test_get_subcloud_with_additional_detail(self,
|
||||
mock_db_api,
|
||||
mock_rpc_client,
|
||||
mock_get_oam_addresses):
|
||||
get_url = FAKE_URL + '/' + FAKE_ID + '/detail'
|
||||
oam_addresses = FakeOAMAddressPool('10.10.10.254',
|
||||
'10.10.10.1',
|
||||
'10.10.10.254',
|
||||
'10.10.10.4',
|
||||
'10.10.10.3',
|
||||
'10.10.10.1',
|
||||
'10.10.10.2')
|
||||
mock_get_oam_addresses.return_value = oam_addresses
|
||||
response = self.app.get(get_url, headers=FAKE_HEADERS)
|
||||
self.assertEqual(response.content_type, 'application/json')
|
||||
self.assertEqual(response.status_code, http_client.OK)
|
||||
self.assertEqual('10.10.10.2', response.json['oam_floating_ip'])
|
||||
|
||||
@mock.patch.object(subclouds.SubcloudsController,
|
||||
'_get_oam_addresses')
|
||||
@mock.patch.object(rpc_client, 'ManagerClient')
|
||||
@mock.patch.object(subclouds, 'db_api')
|
||||
def test_subcloud_oam_ip_unavailable(self,
|
||||
mock_db_api,
|
||||
mock_rpc_client,
|
||||
mock_get_oam_addresses):
|
||||
get_url = FAKE_URL + '/' + FAKE_ID + '/detail'
|
||||
mock_get_oam_addresses.return_value = None
|
||||
response = self.app.get(get_url, headers=FAKE_HEADERS)
|
||||
self.assertEqual(response.content_type, 'application/json')
|
||||
self.assertEqual(response.status_code, http_client.OK)
|
||||
self.assertEqual('unavailable', response.json['oam_floating_ip'])
|
||||
|
||||
@mock.patch.object(rpc_client, 'ManagerClient')
|
||||
@mock.patch.object(subclouds, 'db_api')
|
||||
def test_get_wrong_request(self, mock_db_api, mock_rpc_client):
|
||||
|
Loading…
Reference in New Issue
Block a user