Docstrings formatted according to pep257

Bug #1020184

quantum/common/*
quantum/db/*
quantum/debug/*
quantum/extensions/*

Change-Id: I8fdf72ae1702ef2a2652a1db683d8b31e09e6f84
This commit is contained in:
Sergey Skripnick 2013-04-26 12:03:12 +03:00
parent 85ffc01eee
commit b28dc107a9
19 changed files with 113 additions and 104 deletions

View File

@ -108,8 +108,7 @@ def parse(args):
def setup_logging(conf):
"""
Sets up the logging options for a log with supplied name
"""Sets up the logging options for a log with supplied name.
:param conf: a cfg.ConfOpts object
"""
@ -119,8 +118,7 @@ def setup_logging(conf):
def load_paste_app(app_name):
"""
Builds and returns a WSGI app from a paste config file.
"""Builds and returns a WSGI app from a paste config file.
:param app_name: Name of the application to load
:raises RuntimeError when config file cannot be located or application

View File

@ -25,12 +25,11 @@ from quantum.openstack.common.exception import OpenstackException
class QuantumException(OpenstackException):
"""Base Quantum Exception
"""Base Quantum Exception.
To correctly use this class, inherit from it and define
a 'message' property. That message will get printf'd
with the keyword arguments provided to the constructor.
"""
message = _("An unknown exception occurred.")

View File

@ -47,7 +47,8 @@ from quantum.common import constants
class _AnsiColorizer(object):
"""
"""ANSI colored texts.
A colorizer is an object that loosely wraps around a stream, allowing
callers to write text to the stream in a particular color.
@ -60,7 +61,8 @@ class _AnsiColorizer(object):
self.stream = stream
def supported(cls, stream=sys.stdout):
"""
"""Checks for coloring terminal support.
A class method that returns True if the current platform supports
coloring terminal output using this method. Returns False otherwise.
"""
@ -84,8 +86,7 @@ class _AnsiColorizer(object):
supported = classmethod(supported)
def write(self, text, color):
"""
Write the given text to the stream in the given color.
"""Write the given text to the stream in the given color.
@param text: Text to be written to the stream.
@ -96,9 +97,7 @@ class _AnsiColorizer(object):
class _Win32Colorizer(object):
"""
See _AnsiColorizer docstring.
"""
"""See _AnsiColorizer docstring."""
def __init__(self, stream):
from win32console import GetStdHandle, STD_OUT_HANDLE
from win32console import FOREGROUND_RED, FOREGROUND_BLUE
@ -144,9 +143,7 @@ class _Win32Colorizer(object):
class _NullColorizer(object):
"""
See _AnsiColorizer docstring.
"""
"""See _AnsiColorizer docstring."""
def __init__(self, stream):
self.stream = stream
@ -198,6 +195,7 @@ class QuantumTestResult(result.TextTestResult):
# NOTE(vish, tfukushima): copied from unittest with edit to add color
def addError(self, test, err):
"""Overrides normal addError to add support for errorClasses.
If the exception is a registered class, the error will be added
to the list for that class, not errors.
"""

View File

@ -58,8 +58,7 @@ def read_cached_file(filename, cache_info, reload_func=None):
def find_config_file(options, config_file):
"""
Return the first config file found.
"""Return the first config file found.
We search for the paste config file in the following order:
* If --config-file option is used, use that

View File

@ -158,6 +158,7 @@ class AgentDbMixin(ext_agent.AgentPluginBase):
class AgentExtRpcCallback(object):
"""Processes the rpc report in plugin implementations."""
RPC_API_VERSION = '1.0'
START_TIME = timeutils.utcnow()

View File

@ -33,6 +33,7 @@ LOG = logging.getLogger(__name__)
class NetworkDhcpAgentBinding(model_base.BASEV2):
"""Represents binding between quantum networks and DHCP agents."""
network_id = sa.Column(sa.String(36),
sa.ForeignKey("networks.id", ondelete='CASCADE'),
primary_key=True)
@ -45,6 +46,7 @@ class NetworkDhcpAgentBinding(model_base.BASEV2):
class RouterL3AgentBinding(model_base.BASEV2, models_v2.HasId):
"""Represents binding between quantum routers and L3 agents."""
router_id = sa.Column(sa.String(36),
sa.ForeignKey("routers.id", ondelete='CASCADE'))
l3_agent = orm.relation(agents_db.Agent)
@ -159,8 +161,7 @@ class AgentSchedulerDbMixin(agentscheduler.AgentSchedulerPluginBase,
return {'agents': []}
def add_router_to_l3_agent(self, context, id, router_id):
"""Add a l3 agent to host a router.
"""
"""Add a l3 agent to host a router."""
router = self.get_router(context, router_id)
with context.session.begin(subtransactions=True):
agent_db = self._get_agent(context, id)
@ -192,8 +193,9 @@ class AgentSchedulerDbMixin(agentscheduler.AgentSchedulerPluginBase,
context, routers, agent_db.host)
def remove_router_from_l3_agent(self, context, id, router_id):
"""Remove the router from l3 agent. After it, the router
will be non-hosted until there is update which
"""Remove the router from l3 agent.
After it, the router will be non-hosted until there is update which
lead to re schedule or be added to another agent manually.
"""
agent = self._get_agent(context, id)
@ -356,8 +358,7 @@ class AgentSchedulerDbMixin(agentscheduler.AgentSchedulerPluginBase,
self, context, router)
def schedule_routers(self, context, routers):
"""Schedule the routers to l3 agents.
"""
"""Schedule the routers to l3 agents."""
for router in routers:
self.schedule_router(context, router)

View File

@ -77,10 +77,7 @@ BASE = model_base.BASEV2
class MySQLPingListener(object):
"""
Ensures that MySQL connections checked out of the
pool are alive.
"""Ensures that MySQL connections checked out of the pool are alive.
Borrowed from:
http://groups.google.com/group/sqlalchemy/msg/a4ce563d802c929f
@ -98,8 +95,7 @@ class MySQLPingListener(object):
class SqliteForeignKeysListener(PoolListener):
"""
Ensures that the foreign key constraints are enforced in SQLite.
"""Ensures that the foreign key constraints are enforced in SQLite.
The foreign key constraints are disabled by default in SQLite,
so the foreign key constraints will be enabled here for every
@ -110,9 +106,10 @@ class SqliteForeignKeysListener(PoolListener):
def configure_db():
"""
Establish the database, create an engine if needed, and
register the models.
"""Configure database.
Establish the database, create an engine if needed, and register
the models.
"""
global _ENGINE
if not _ENGINE:
@ -233,10 +230,11 @@ def unregister_models(base=BASE):
def greenthread_yield(dbapi_con, con_record):
"""
Ensure other greenthreads get a chance to execute by forcing a context
switch. With common database backends (eg MySQLdb and sqlite), there is
no implicit yield caused by network I/O since they are implemented by
C libraries that eventlet cannot monkey patch.
"""Ensure other greenthreads get a chance to execute.
This is done by forcing a context switch. With common database
backends (eg MySQLdb and sqlite), there is no implicit yield caused
by network I/O since they are implemented by C libraries that
eventlet cannot monkey patch.
"""
greenthread.sleep(0)

View File

@ -50,12 +50,12 @@ AUTO_DELETE_PORT_OWNERS = ['network:dhcp']
class QuantumDbPluginV2(quantum_plugin_base_v2.QuantumPluginBaseV2):
"""A class that implements the v2 Quantum plugin interface
using SQLAlchemy models. Whenever a non-read call happens
the plugin will call an event handler class method (e.g.,
network_created()). The result is that this class can be
sub-classed by other classes that add custom behaviors on
certain events.
"""V2 Quantum plugin interface implementation using SQLAlchemy models.
Whenever a non-read call happens the plugin will call an event handler
class method (e.g., network_created()). The result is that this class
can be sub-classed by other classes that add custom behaviors on certain
events.
"""
# This attribute specifies whether the plugin supports or not
@ -730,7 +730,6 @@ class QuantumDbPluginV2(quantum_plugin_base_v2.QuantumPluginBaseV2):
Verifies the specified CIDR does not overlap with the ones defined
for the other subnets specified for this network, or with any other
CIDR if overlapping IPs are disabled.
"""
new_subnet_ipset = netaddr.IPSet([new_subnet_cidr])
if cfg.CONF.allow_overlapping_ips:
@ -760,9 +759,7 @@ class QuantumDbPluginV2(quantum_plugin_base_v2.QuantumPluginBaseV2):
ie: constituted by valid and appropriately ordered IP addresses.
Also, verify pools do not overlap among themselves.
Finally, verify that each range fall within the subnet's CIDR.
"""
subnet = netaddr.IPNetwork(subnet_cidr)
subnet_first_ip = netaddr.IPAddress(subnet.first + 1)
subnet_last_ip = netaddr.IPAddress(subnet.last - 1)
@ -843,9 +840,7 @@ class QuantumDbPluginV2(quantum_plugin_base_v2.QuantumPluginBaseV2):
Pools are defined by the 'allocation_pools' attribute,
a list of dict objects with 'start' and 'end' keys for
defining the pool range.
"""
pools = []
# Auto allocate the pool around gateway_ip
net = netaddr.IPNetwork(subnet['cidr'])
@ -1167,11 +1162,11 @@ class QuantumDbPluginV2(quantum_plugin_base_v2.QuantumPluginBaseV2):
return self._make_subnet_dict(subnet)
def update_subnet(self, context, id, subnet):
"""Update the subnet with new info. The change however will not be
realized until the client renew the dns lease or we support
gratuitous DHCP offers
"""
"""Update the subnet with new info.
The change however will not be realized until the client renew the
dns lease or we support gratuitous DHCP offers
"""
s = subnet['subnet']
db_subnet = self._get_subnet(context, id)
# Fill 'ip_version' and 'allocation_pools' fields with the current

View File

@ -47,6 +47,7 @@ DEVICE_OWNER_FLOATINGIP = l3_constants.DEVICE_OWNER_FLOATINGIP
class Router(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant):
"""Represents a v2 quantum router."""
name = sa.Column(sa.String(255))
status = sa.Column(sa.String(16))
admin_state_up = sa.Column(sa.Boolean)
@ -61,10 +62,12 @@ class ExternalNetwork(model_base.BASEV2):
class FloatingIP(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant):
"""Represents a floating IP, which may or many not be
allocated to a tenant, and may or may not be associated with
an internal port/ip address/router.
"""Represents a floating IP address.
This IP address may or many not be allocated to a tenant, and may or
may not be associated with an internal port/ip address/router.
"""
floating_ip_address = sa.Column(sa.String(64), nullable=False)
floating_network_id = sa.Column(sa.String(36), nullable=False)
floating_port_id = sa.Column(sa.String(36), sa.ForeignKey('ports.id'),
@ -509,7 +512,9 @@ class L3_NAT_db_mixin(l3.RouterPluginBase):
port_id=internal_port['id'])
def get_assoc_data(self, context, fip, floating_network_id):
"""When a floating IP is associated with an internal port,
"""Determine/extract data associated with the internal port.
When a floating IP is associated with an internal port,
we need to extract/determine some data associated with the
internal port, including the internal_ip_address, and router_id.
We also need to confirm that this internal port is owned by the
@ -723,12 +728,13 @@ class L3_NAT_db_mixin(l3.RouterPluginBase):
filters=filters)
def prevent_l3_port_deletion(self, context, port_id):
"""Checks to make sure a port is allowed to be deleted, raising
an exception if this is not the case. This should be called by
any plugin when the API requests the deletion of a port, since
some ports for L3 are not intended to be deleted directly via a
DELETE to /ports, but rather via other API calls that perform the
proper deletion checks.
"""Checks to make sure a port is allowed to be deleted.
Raises an exception if this is not the case. This should be called by
any plugin when the API requests the deletion of a port, since some
ports for L3 are not intended to be deleted directly via a DELETE
to /ports, but rather via other API calls that perform the proper
deletion checks.
"""
port_db = self._get_port(context, port_id)
if port_db['device_owner'] in [DEVICE_OWNER_ROUTER_INTF,

View File

@ -36,6 +36,7 @@ LOG = logging.getLogger(__name__)
class SessionPersistence(model_base.BASEV2):
vip_id = sa.Column(sa.String(36),
sa.ForeignKey("vips.id"),
primary_key=True)
@ -49,6 +50,7 @@ class SessionPersistence(model_base.BASEV2):
class PoolStatistics(model_base.BASEV2):
"""Represents pool statistics."""
pool_id = sa.Column(sa.String(36), sa.ForeignKey("pools.id"),
primary_key=True)
bytes_in = sa.Column(sa.Integer, nullable=False)
@ -59,6 +61,7 @@ class PoolStatistics(model_base.BASEV2):
class Vip(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant):
"""Represents a v2 quantum loadbalancer vip."""
name = sa.Column(sa.String(255))
description = sa.Column(sa.String(255))
port_id = sa.Column(sa.String(36), sa.ForeignKey('ports.id'))
@ -78,6 +81,7 @@ class Vip(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant):
class Member(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant):
"""Represents a v2 quantum loadbalancer member."""
pool_id = sa.Column(sa.String(36), sa.ForeignKey("pools.id"),
nullable=False)
address = sa.Column(sa.String(64), nullable=False)
@ -89,6 +93,7 @@ class Member(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant):
class Pool(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant):
"""Represents a v2 quantum loadbalancer pool."""
vip_id = sa.Column(sa.String(36), sa.ForeignKey("vips.id"))
name = sa.Column(sa.String(255))
description = sa.Column(sa.String(255))
@ -115,6 +120,7 @@ class Pool(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant):
class HealthMonitor(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant):
"""Represents a v2 quantum loadbalancer healthmonitor."""
type = sa.Column(sa.Enum("PING", "TCP", "HTTP", "HTTPS",
name="healthmontiors_type"),
nullable=False)
@ -135,10 +141,8 @@ class HealthMonitor(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant):
class PoolMonitorAssociation(model_base.BASEV2):
"""
Represents the many-to-many association between pool and
healthMonitor classes
"""
"""Many-to-many association between pool and healthMonitor classes."""
pool_id = sa.Column(sa.String(36),
sa.ForeignKey("pools.id"),
primary_key=True)
@ -148,9 +152,10 @@ class PoolMonitorAssociation(model_base.BASEV2):
class LoadBalancerPluginDb(LoadBalancerPluginBase):
"""
A class that wraps the implementation of the Quantum
loadbalancer plugin database access interface using SQLAlchemy models.
"""Wraps loadbalancer with SQLAlchemy models.
A class that wraps the implementation of the Quantum loadbalancer
plugin database access interface using SQLAlchemy models.
"""
@property
@ -279,6 +284,7 @@ class LoadBalancerPluginDb(LoadBalancerPluginBase):
def _check_session_persistence_info(self, info):
"""Performs sanity check on session persistence info.
:param info: Session persistence info
"""
if info['type'] == 'APP_COOKIE':

View File

@ -19,6 +19,7 @@ from sqlalchemy import orm
class QuantumBase(object):
"""Base class for Quantum Models."""
__table_args__ = {'mysql_engine': 'InnoDB'}
def __setitem__(self, key, value):
@ -45,6 +46,7 @@ class QuantumBase(object):
def iteritems(self):
"""Make the model object behave like a dict.
Includes attributes from joins.
"""
local = dict(self)

View File

@ -24,12 +24,14 @@ from quantum.openstack.common import uuidutils
class HasTenant(object):
"""Tenant mixin, add to subclasses that have a tenant."""
# NOTE(jkoelker) tenant_id is just a free form string ;(
tenant_id = sa.Column(sa.String(255))
class HasId(object):
"""id mixin, add to subclasses that have an id."""
id = sa.Column(sa.String(36),
primary_key=True,
default=uuidutils.generate_uuid)
@ -45,8 +47,8 @@ class IPAvailabilityRange(model_base.BASEV2):
only done if the range is contiguous. If not, the first_ip will be
the same as the last_ip. When adjacent ips are recycled the ranges
will be merged.
"""
allocation_pool_id = sa.Column(sa.String(36),
sa.ForeignKey('ipallocationpools.id',
ondelete="CASCADE"),
@ -79,6 +81,7 @@ class IPAllocationPool(model_base.BASEV2, HasId):
class IPAllocation(model_base.BASEV2):
"""Internal representation of allocated IP addresses in a Quantum subnet.
"""
port_id = sa.Column(sa.String(36), sa.ForeignKey('ports.id',
ondelete="CASCADE"),
nullable=True)
@ -94,11 +97,13 @@ class IPAllocation(model_base.BASEV2):
class Route(object):
"""mixin of a route."""
destination = sa.Column(sa.String(64), nullable=False, primary_key=True)
nexthop = sa.Column(sa.String(64), nullable=False, primary_key=True)
class SubnetRoute(model_base.BASEV2, Route):
subnet_id = sa.Column(sa.String(36),
sa.ForeignKey('subnets.id',
ondelete="CASCADE"),
@ -107,6 +112,7 @@ class SubnetRoute(model_base.BASEV2, Route):
class Port(model_base.BASEV2, HasId, HasTenant):
"""Represents a port on a quantum v2 network."""
name = sa.Column(sa.String(255))
network_id = sa.Column(sa.String(36), sa.ForeignKey("networks.id"),
nullable=False)
@ -120,6 +126,7 @@ class Port(model_base.BASEV2, HasId, HasTenant):
class DNSNameServer(model_base.BASEV2):
"""Internal representation of a DNS nameserver."""
address = sa.Column(sa.String(128), nullable=False, primary_key=True)
subnet_id = sa.Column(sa.String(36),
sa.ForeignKey('subnets.id',
@ -133,6 +140,7 @@ class Subnet(model_base.BASEV2, HasId, HasTenant):
When a subnet is created the first and last entries will be created. These
are used for the IP allocation.
"""
name = sa.Column(sa.String(255))
network_id = sa.Column(sa.String(36), sa.ForeignKey('networks.id'))
ip_version = sa.Column(sa.Integer, nullable=False)
@ -154,6 +162,7 @@ class Subnet(model_base.BASEV2, HasId, HasTenant):
class Network(model_base.BASEV2, HasId, HasTenant):
"""Represents a v2 quantum network."""
name = sa.Column(sa.String(255))
ports = orm.relationship(Port, backref='networks')
subnets = orm.relationship(Subnet, backref='networks')

View File

@ -105,11 +105,11 @@ class PortSecurityDbMixin(object):
return self._fields(res, fields)
def _determine_port_security_and_has_ip(self, context, port):
"""Returns a tuple of (port_security_enabled, has_ip) where
port_security_enabled and has_ip are bools. Port_security is the
value assocated with the port if one is present otherwise the value
associated with the network is returned. has_ip is if the port is
associated with an ip or not.
"""Returns a tuple of booleans (port_security_enabled, has_ip).
Port_security is the value assocated with the port if one is present
otherwise the value associated with the network is returned. has_ip is
if the port is associated with an ip or not.
"""
has_ip = self._ip_on_port(port)
# we don't apply security groups for dhcp, router

View File

@ -34,16 +34,15 @@ class Quota(model_base.BASEV2, models_v2.HasId):
class DbQuotaDriver(object):
"""
Driver to perform necessary checks to enforce quotas and obtain
quota information. The default driver utilizes the local
database.
"""Driver to perform necessary checks to enforce quotas and obtain quota
information.
The default driver utilizes the local database.
"""
@staticmethod
def get_tenant_quotas(context, resources, tenant_id):
"""
Given a list of resources, retrieve the quotas for the given
"""Given a list of resources, retrieve the quotas for the given
tenant.
:param context: The request context, for access checks.
@ -76,16 +75,13 @@ class DbQuotaDriver(object):
@staticmethod
def get_all_quotas(context, resources):
"""
Given a list of resources, retrieve the quotas for the all
tenants.
"""Given a list of resources, retrieve the quotas for the all tenants.
:param context: The request context, for access checks.
:param resources: A dictionary of the registered resource keys.
:return quotas: list of dict of tenant_id:, resourcekey1:
resourcekey2: ...
"""
tenant_default = dict((key, resource.default)
for key, resource in resources.items())
@ -120,7 +116,8 @@ class DbQuotaDriver(object):
context.session.add(tenant_quota)
def _get_quotas(self, context, tenant_id, resources, keys):
"""
"""Retrieves the quotas for specific resources.
A helper method which retrieves the quotas for the specific
resources identified by keys, and which apply to the current
context.
@ -131,7 +128,6 @@ class DbQuotaDriver(object):
:param keys: A list of the desired quotas to retrieve.
"""
desired = set(keys)
sub_resources = dict((k, v) for k, v in resources.items()
if k in desired)

View File

@ -30,12 +30,14 @@ from quantum.openstack.common import uuidutils
class SecurityGroup(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant):
"""Represents a v2 quantum security group."""
name = sa.Column(sa.String(255))
description = sa.Column(sa.String(255))
class SecurityGroupPortBinding(model_base.BASEV2):
"""Represents binding between quantum ports and security profiles."""
port_id = sa.Column(sa.String(36),
sa.ForeignKey("ports.id",
ondelete='CASCADE'),
@ -48,6 +50,7 @@ class SecurityGroupPortBinding(model_base.BASEV2):
class SecurityGroupRule(model_base.BASEV2, models_v2.HasId,
models_v2.HasTenant):
"""Represents a v2 quantum security group rule."""
security_group_id = sa.Column(sa.String(36),
sa.ForeignKey("securitygroups.id",
ondelete="CASCADE"),
@ -86,6 +89,7 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase):
def create_security_group(self, context, security_group, default_sg=False):
"""Create security group.
If default_sg is true that means we are a default security group for
a given tenant if it does not exist.
"""
@ -140,8 +144,8 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase):
filters=filters)
def get_security_group(self, context, id, fields=None, tenant_id=None):
"""Tenant id is given to handle the case when we
are creating a security group rule on behalf of another use.
"""Tenant id is given to handle the case when creating a security
group rule on behalf of another use.
"""
if tenant_id:
@ -257,7 +261,9 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase):
bulk_rule)[0]
def _validate_security_group_rules(self, context, security_group_rule):
"""Check that rules being installed all belong to the same security
"""Check that rules being installed.
Check that all rules belong to the same security
group, remote_group_id/security_group_id belong to the same tenant,
and rules are valid.
"""

View File

@ -120,9 +120,8 @@ class SecurityGroupServerRpcMixin(sg_db.SecurityGroupDbMixin):
class SecurityGroupServerRpcCallbackMixin(object):
"""A mix-in that enable SecurityGroup agent
support in plugin implementations.
"""A mix-in that enable SecurityGroup agent support in plugin
implementations.
"""
def security_group_rules_for_devices(self, context, **kwargs):

View File

@ -109,8 +109,7 @@ class ClearProbe(ProbeCommand):
class ExecProbe(ProbeCommand):
"""Exec commands on the namespace of the probe
"""
"""Exec commands on the namespace of the probe."""
log = logging.getLogger(__name__ + '.ExecProbe')
@ -134,8 +133,7 @@ class ExecProbe(ProbeCommand):
class PingAll(ProbeCommand):
"""Ping all fixed_ip
"""
"""Ping all fixed_ip."""
log = logging.getLogger(__name__ + '.ExecProbe')

View File

@ -132,6 +132,7 @@ class AgentPluginBase(object):
@abstractmethod
def delete_agent(self, context, id):
"""Delete agent.
Agents register themselves on reporting state.
But if a agent does not report its status
for a long time (for example, it is dead for ever. ),
@ -143,11 +144,9 @@ class AgentPluginBase(object):
@abstractmethod
def update_agent(self, context, agent):
"""Disable or Enable the agent.
Discription also can be updated.
Some agents cannot be disabled,
such as plugins, services.
An error code should be reported in this case.
Discription also can be updated. Some agents cannot be disabled, such
as plugins, services. An error code should be reported in this case.
@raise exceptions.BadRequest:
"""
pass

View File

@ -52,8 +52,7 @@ EXTENDED_ATTRIBUTES_2_0 = {
class Portsecurity(object):
"""Extension class supporting port security
"""
"""Extension class supporting port security."""
@classmethod
def get_name(cls):