Skip to content

Commit

Permalink
Merge pull request #408 from joseph-v/port-res
Browse files Browse the repository at this point in the history
Add Port resource to Delfin
  • Loading branch information
kumarashit authored Dec 18, 2020
2 parents 0f0661a + bac29da commit 9099b30
Show file tree
Hide file tree
Showing 18 changed files with 620 additions and 1 deletion.
54 changes: 54 additions & 0 deletions delfin/api/v1/ports.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Copyright 2020 The SODA Authors.
#
# 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 delfin import db
from delfin.api import api_utils
from delfin.api.common import wsgi
from delfin.api.views import ports as port_view


class PortController(wsgi.Controller):

def __init__(self):
super(PortController, self).__init__()
self.search_options = ['name', 'status', 'id', 'storage_id', 'wwn',
'native_controller_id', 'native_port_id']

def _get_ports_search_options(self):
"""Return ports search options allowed ."""
return self.search_options

def index(self, req):
ctxt = req.environ['delfin.context']
query_params = {}
query_params.update(req.GET)
# update options other than filters
sort_keys, sort_dirs = api_utils.get_sort_params(query_params)
marker, limit, offset = api_utils.get_pagination_params(query_params)
# strip out options except supported search options
api_utils.remove_invalid_options(ctxt, query_params,
self._get_ports_search_options())

ports = db.port_get_all(ctxt, marker, limit, sort_keys,
sort_dirs, query_params, offset)
return port_view.build_ports(ports)

def show(self, req, id):
ctxt = req.environ['delfin.context']
port = db.port_get(ctxt, id)
return port_view.build_port(port)


def create_resource():
return wsgi.Resource(PortController())
5 changes: 5 additions & 0 deletions delfin/api/v1/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from delfin.api.v1 import alert_source
from delfin.api.v1 import alerts
from delfin.api.v1 import controllers
from delfin.api.v1 import ports
from delfin.api.v1 import storage_pools
from delfin.api.v1 import storages
from delfin.api.v1 import volumes
Expand Down Expand Up @@ -99,3 +100,7 @@ def _setup_routes(self, mapper):
self.resources['controllers'] = controllers.create_resource()
mapper.resource("controller", "controllers",
controller=self.resources['controllers'])

self.resources['ports'] = ports.create_resource()
mapper.resource("port", "ports",
controller=self.resources['ports'])
26 changes: 26 additions & 0 deletions delfin/api/views/ports.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Copyright 2020 The SODA Authors.
#
# 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 copy


def build_ports(ports):
# Build list of ports
views = [build_port(port)
for port in ports]
return dict(ports=views)


def build_port(port):
view = copy.deepcopy(port)
return dict(view)
43 changes: 43 additions & 0 deletions delfin/common/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,49 @@ class VolumeType(object):
ALL = (THICK, THIN)


class PortConnectionStatus(object):
CONNECTED = 'connected'
DISCONNECTED = 'disconnected'
UNKNOWN = 'unknown'

ALL = (CONNECTED, DISCONNECTED, UNKNOWN)


class PortHealthStatus(object):
NORMAL = 'normal'
ABNORMAL = 'abnormal'
UNKNOWN = 'unknown'

ALL = (NORMAL, ABNORMAL, UNKNOWN)


class PortType(object):
FC = 'fc'
ISCSI = 'iscsi'
FICON = 'ficon'
FCOE = 'fcoe'
ETH = 'eth'
SAS = 'sas'
IB = 'ib'
OTHER = 'other'

ALL = (FC, ISCSI, FICON, FCOE, ETH, SAS, IB, OTHER)


class PortLogicalType(object):
FRONTEND = 'frontend'
BACKEND = 'backend'
SERVICE = 'service'
MANAGEMENT = 'management'
INTERNAL = 'internal'
MAINTENANCE = 'maintenance'
INTERCONNECT = 'interconnect'
OTHER = 'other'

ALL = (FRONTEND, BACKEND, SERVICE, MANAGEMENT,
INTERNAL, MAINTENANCE, INTERCONNECT, OTHER)


# Enumerations for alert severity
class Severity(object):
FATAL = 'Fatal'
Expand Down
58 changes: 58 additions & 0 deletions delfin/db/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,64 @@ def controller_get_all(context, marker=None, limit=None, sort_keys=None,
sort_dirs, filters, offset)


def ports_create(context, values):
"""Create multiple ports."""
return IMPL.ports_create(context, values)


def ports_update(context, values):
"""Update multiple ports."""
return IMPL.ports_update(context, values)


def ports_delete(context, values):
"""Delete multiple ports."""
return IMPL.ports_delete(context, values)


def port_create(context, values):
"""Create a port from the values dictionary."""
return IMPL.port_create(context, values)


def port_update(context, port_id, values):
"""Update a port with the values dictionary."""
return IMPL.port_update(context, port_id, values)


def port_get(context, port_id):
"""Get a port or raise an exception if it does not exist."""
return IMPL.port_get(context, port_id)


def port_delete_by_storage(context, storage_id):
"""Delete a port or raise an exception if it does not exist."""
return IMPL.port_delete_by_storage(context, storage_id)


def port_get_all(context, marker=None, limit=None, sort_keys=None,
sort_dirs=None, filters=None, offset=None):
"""Retrieves all ports.
If no sort parameters are specified then the returned volumes are sorted
first by the 'created_at' key and then by the 'id' key in descending
order.
:param context: context of this request, it's helpful to trace the request
:param marker: the last item of the previous page, used to determine the
next page of results to return
:param limit: maximum number of items to return
:param sort_keys: list of attributes by which results should be sorted,
paired with corresponding item in sort_dirs
:param sort_dirs: list of directions in which results should be sorted,
paired with corresponding item in sort_keys, for example
'desc' for descending order
:param filters: dictionary of filters
:param offset: number of items to skip
:returns: list of controllers
"""
return IMPL.port_get_all(context, marker, limit, sort_keys,
sort_dirs, filters, offset)


def disk_create(context, values):
"""Create a disk from the values dictionary."""
return IMPL.disk_create(context, values)
Expand Down
144 changes: 143 additions & 1 deletion delfin/db/sqlalchemy/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -701,7 +701,6 @@ def controller_delete_by_storage(context, storage_id):
def controller_get_all(context, marker=None, limit=None, sort_keys=None,
sort_dirs=None, filters=None, offset=None):
"""Retrieves all controllers."""

session = get_session()
with session.begin():
# Generate the query
Expand All @@ -726,6 +725,148 @@ def _process_controller_info_filters(query, filters):
return query


def ports_create(context, ports):
"""Create multiple ports."""
session = get_session()
ports_refs = []
with session.begin():

for port in ports:
LOG.debug('adding new port for native_port_id {0}:'
.format(port.get('native_port_id')))
if not port.get('id'):
port['id'] = uuidutils.generate_uuid()

port_ref = models.Port()
port_ref.update(port)
ports_refs.append(port_ref)

session.add_all(ports_refs)

return ports_refs


def ports_update(context, ports):
"""Update multiple ports."""
session = get_session()

with session.begin():
port_refs = []

for port in ports:
LOG.debug('updating port {0}:'.format(
port.get('id')))
query = _port_get_query(context, session)
result = query.filter_by(id=port.get('id')
).update(port)

if not result:
LOG.error(exception.PortNotFound(port.get(
'id')))
else:
port_refs.append(result)

return port_refs


def ports_delete(context, ports_id_list):
"""Delete multiple ports."""
session = get_session()
with session.begin():
for port_id in ports_id_list:
LOG.debug('deleting port {0}:'.format(port_id))
query = _port_get_query(context, session)
result = query.filter_by(id=port_id).delete()

if not result:
LOG.error(exception.PortNotFound(port_id))
return


def _port_get_query(context, session=None):
return model_query(context, models.Port, session=session)


def _port_get(context, port_id, session=None):
result = (_port_get_query(context, session=session)
.filter_by(id=port_id)
.first())

if not result:
raise exception.PortNotFound(port_id)

return result


def port_create(context, values):
"""Create a port from the values dictionary."""
if not values.get('id'):
values['id'] = uuidutils.generate_uuid()

port_ref = models.Port()
port_ref.update(values)

session = get_session()
with session.begin():
session.add(port_ref)

return _port_get(context,
port_ref['id'],
session=session)


def port_update(context, port_id, values):
"""Update a port with the values dictionary."""
session = get_session()

with session.begin():
query = _port_get_query(context, session)
result = query.filter_by(id=port_id).update(values)

if not result:
raise exception.PortNotFound(port_id)

return result


def port_get(context, port_id):
"""Get a port or raise an exception if it does not exist."""
return _port_get(context, port_id)


def port_delete_by_storage(context, storage_id):
"""Delete port or raise an exception if it does not exist."""
_port_get_query(context).filter_by(storage_id=storage_id).delete()


def port_get_all(context, marker=None, limit=None, sort_keys=None,
sort_dirs=None, filters=None, offset=None):
"""Retrieves all ports."""

session = get_session()
with session.begin():
# Generate the query
query = _generate_paginate_query(context, session, models.Port,
marker, limit, sort_keys, sort_dirs,
filters, offset,
)
# No Port would match, return empty list
if query is None:
return []
return query.all()


@apply_like_filters(model=models.Port)
def _process_port_info_filters(query, filters):
"""Common filter processing for ports queries."""
if filters:
if not is_valid_model_filters(models.Port, filters):
return
query = query.filter_by(**filters)

return query


def disk_create(context, values):
"""Create a disk from the values dictionary."""
return NotImplemented
Expand Down Expand Up @@ -860,6 +1001,7 @@ def alert_source_get_all(context, marker=None, limit=None, sort_keys=None,
models.Controller: (_controller_get_query,
_process_controller_info_filters,
_controller_get),
models.Port: (_port_get_query, _process_port_info_filters, _port_get),
}


Expand Down
Loading

0 comments on commit 9099b30

Please sign in to comment.