71 lines
2.6 KiB
Python
71 lines
2.6 KiB
Python
"""Generate a network device's asset number from its type prefix and name.
|
|
|
|
Every network device on this fleet already follows one convention, applied by
|
|
hand: AP-<name>, SW-<name>, SVR-<name>, IDF-<name>. This turns that into
|
|
something the create path does, so the same value is not typed twice.
|
|
|
|
Generation only fills a BLANK asset number. A device that carries a real
|
|
identifier of its own - a vendor tag, a controller name, a serial - keeps it.
|
|
That is the platform rule: adopt an external identifier where one exists, derive
|
|
one only where none does.
|
|
"""
|
|
|
|
import re
|
|
|
|
|
|
# Characters that must not reach a unique business key. assetnumber ends up in
|
|
# URLs and in joins other subsystems make, and the existing data already shows
|
|
# why this matters: IDF-Telco-Demarc-#1 came from the name 'Telco Demarc #1',
|
|
# carrying a '#' into an identifier.
|
|
_SEPARATORS = re.compile(r'[\s_/\\]+')
|
|
_ILLEGAL = re.compile(r'[^A-Za-z0-9.-]')
|
|
_RUNS = re.compile(r'-{2,}')
|
|
|
|
|
|
def sanitize(value):
|
|
"""A name reduced to something safe to use as an identifier.
|
|
|
|
Whitespace and slashes become single dashes; anything outside
|
|
letters/digits/dot/dash is dropped rather than transliterated, because a
|
|
guessed transliteration in a business key is worse than a shorter one.
|
|
"""
|
|
text = (value or '').strip()
|
|
if not text:
|
|
return ''
|
|
text = _SEPARATORS.sub('-', text)
|
|
text = _ILLEGAL.sub('', text)
|
|
text = _RUNS.sub('-', text)
|
|
return text.strip('-')
|
|
|
|
|
|
def generate(prefix, name):
|
|
"""'<PREFIX>-<name>', or the bare name when the type has no prefix.
|
|
|
|
Returns '' when there is nothing to build from, so the caller can fall back
|
|
to demanding an explicit value rather than inventing one.
|
|
|
|
Does NOT stack an existing prefix: a name already starting with the prefix
|
|
(IDF-03 under type IDF) is returned as-is, because IDF-IDF-03 is nobody's
|
|
intent. Matched case-insensitively on the prefix plus its dash.
|
|
"""
|
|
cleanname = sanitize(name)
|
|
if not cleanname:
|
|
return ''
|
|
cleanprefix = sanitize(prefix).upper()
|
|
if not cleanprefix:
|
|
return cleanname
|
|
if cleanname.upper().startswith(cleanprefix + '-'):
|
|
return cleanname
|
|
return '{}-{}'.format(cleanprefix, cleanname)
|
|
|
|
|
|
def generate_for_type(networkdevicetypeid, name):
|
|
"""Same, looking the prefix up from the device type. '' if no type given."""
|
|
if not networkdevicetypeid:
|
|
return sanitize(name)
|
|
from shopdb.api import db
|
|
from ..models import NetworkDeviceType
|
|
|
|
devicetype = db.session.get(NetworkDeviceType, networkdevicetypeid)
|
|
return generate(devicetype.prefix if devicetype else None, name)
|