Constructor(pid = None)
Arguments
pid
A device list in the Portable Inventory Data format as an argument, or a list of OtDevice objects for initialization. Most of the time, an OtDeviceSet object is initialized using the methods loadFile() or loadREST().
Return value
An object of class OtDeviceSet.
loadFile(filename)
Initialize an OtDeviceSet object with a Portable Inventory Data file as exported by OT-BASE Asset Center, or created with the Python SDK using the toFile() method.
Arguments
filename
Name of the JSON file to be loaded.
Example
set1 = OtDeviceSet()
set1.loadFile('OT-BASE Devices.json')
loadREST(host, auth, prot = 'https', cert = None, **kwargs)
Initialize an OtDeviceSet object with asset data loaded from OT-BASE Asset Center via the REST API.
Loading data online from OT-BASE Asset Center may take a while for large data sets, as full vulnerability and software data is pulled for each device.
Arguments
host = host name of a computer system where OT-BASE Asset Center is running
Note that only the host name or IP address of the server needs to be specified, not a URL or path.
auth = (userid, password)
Authentification data for connecting to OT-BASE Asset Center.
prot = 'http' | 'https'
The protocol that shall be used for connecting to OT-BASE Asset Center. By default, https is used.
cert = client certificate
Filename(s) of client certificate(s) that are required to open a connection via HTTPS to a secure OT-BASE Asset Center, such as in OT-BASE Cloud. The client certificate is passed as a file name (path name). Note that the client certificate must be in the .pem format. If the certificate file contains both public and private key, one file name is sufficient. If you have split public and private key in separate files, pass the two file names as a tuple; public key first, private key second. -- You can generate a .pem file from a .p12 file using openssl, like "openssl pkcs12 -in mycert.p12 -out mycert.pem -nodes".
modified = timestamp in ISO 8601 format, based on UTC
Return only asset data for devices that have been changed since the specified timestamp, or have been added to the inventory since the timestamp.
locationid = location identifier
Return only asset data for devices at a particular location, identified by location ID.
otsystem = OT system name
Return only asset data for devices that are part of a particular OT system.
otsystemid = OT system identifier
Return only asset data for devices that are part of a particular OT system.
ipaddress = IP address
Return only asset data for devices that have a specific IP address
name = Device name
Return only asset data for devices with a particular device name.
type = 'PLC' | 'RTU' | 'Actuator' | 'Sensor' | 'L2-Switch' | 'L3-Switch' | 'Desktop' | 'Laptop' | 'Server'
Return only asset data for devices of a particular type.
Example
set1 = OtDeviceSet()
set1.loadREST('192.168.0.15', (userid, password))
loadExel(filename, mapColumns, prefix = None)
Initialize an OtDeviceSet object with data loaded from an Excel spreadsheet.
Arguments
filename
The filename of the spreadsheet that you want to load (.xlsx format)
mapColumns
A dictionary that specifies which columns to use, and how these columns map to supported field names. Supported field names are:
deviceId, name, description, installationDate, stage, serialNumber, zone, safety, security, criticality
hardware_vendor, hardware_model, hardware_type, hardware_version, hardware_orderNumber, hardware_description, hardware_endOfLife, hardware_safety, hardware_lifecycle
context_location, context_locationId, context_referenceLocation, context_otSystem, context_deviceGroup
extended_fieldName
prefix
A prefix for creating device IDs. If the Excel data doesn't contain device IDs, a prefix must be provided, allowing the method to automatically generate device IDs.
Example
set1 = OtDeviceSet()
set1 = loadExcel('myfile.xslx', {'name': 'name', 'location': 'context_locationId', 'vendor': 'hardware_vendor'}, prefix = 'HBL5')
select(attrDict, match = 'SEARCH', op = 'AND')
Returns a subset of a device set as an OtDeviceSet object where devices in the subset match the criteria specified in the arguments.
Match criteria (attrDict argument)
Match criteria are specified using a dictionary with one or more of the keywords listed below. Note that you cannot use a keyword twice in a dictionary. If you want to select subsets that match different values for one and the same attribute, the solution is to select each subset independently and then create a result set using set arithmetic (result = set1 + set2).
General keywords
deviceId = device identifer
The device identifier of a device. When a full device identifier is specified, the resulting set will have either one or no entries, as device identifiers are unique.
Example:
result = set1.select({'deviceId': 'B55.PLC'})
The select statement will return all devices in set1 where the device ID contains the string "B55.PLC".
name = device name
The name of a device, such as its DNS name or host name. Note that device names don't need to be unique in OT-BASE.
description = description of a device
The description for a device, such as its function.
Example:
result = set1.select({'description': 'water treatment'})
Selects all devices which have the string "water treatment" in their description.
installationDate = installation date
The installation date of a device in the format YYYY-MM-DD.
stage = 'Planned' | 'Installed' | 'Testing' | 'Operational' | 'Decommissioned'
The lifecycle stage of a device.
serialNumber = serial number
The serial number of a device.
zone = network zone
The network zone of a device, such as 'Level 1'.
Example:
result = set1.select({'zone': 'Level 1'})
safety = safety classification
The safety classification of a device, such as 'SIL2'.
security = security classification
The security classification of a device.
criticality = criticality rating
The criticality rating of a device, following the schematic in OT-BASE, where multiple criticality dimensions can be assigned, separated by comma, and optionally be amended by a numeric parameter that is separated using a colon (as in 'SAFETY:2').
Hardware keywords
hardware_vendor = vendor name
Name of the hardware vendor of a device.
Example:
result = set1.select({'hardware_vendor': 'Rockwell'})
hardware_model = model name
Name of the hardware model of a device
Example:
result = set1.select({'hardware_model': '1756'})
hardware_type = 'PLC' | 'RTU' | 'Actuator' | 'Sensor' | 'L2-Switch' | 'L3-Switch' | 'Desktop' | 'Laptop' | 'Server'
The hardware type of a device.
Example:
result = set1.select({'hardware_type': 'PLC', 'hardware_vendor': 'Siemens'}, operator = 'AND')
hardware_version = version number
The hardware version of a device.
hardware_orderNumber = order number
The order number of a device's hardware.
hardware_description = Product description
The product description for a device's hardware.
hardware_endOfLife = end-of-life date
The end-of-life date for a device's hardware model, expressed as YYYY-MM-DD.
hardware_safety = safety certification
The safety certification of a device's hardware.
hardware_lifecycle = 'Active' | 'Phaseout' | 'Discontinued' | 'End of Life'
The lifecycle stage of a device's hardware model.
In the following example, we want to select devices where the hardware lifecycle is NOT active. Since we cannot specify a keyword more than once, we first select active devices from the device set and then create our result set using set arithmetic:
set2 = set1.select({'hardware_lifecycle': 'Active'})
result = set1 - set2
Context keywords
context_location = location tree
The location name of a device's location, expressed as a tree, using '/' as a separator.
context_locationId = location identifier
The location identifier of a device's location, as set in OT-BASE Asset Discovery.
context_referenceLocation = location tree
The location name of a device's reference location, expressed as a tree, using '/' as a separator.
context_otSystem = system name
The name of an OT system that a device is associated with.
Example:
result = set1.select({'context_otSystem': 'line 3'})
context_deviceGroup = device group name
The name of a device group that a device is a member of.
Software keywords
software_os_vendor = vendor name
The vendor of the operating system that is installed on a device.
software_os_name = product name
Name of the operating system that is installed on a device.
software_os_version = version string
The version of the operating system that is installed on a device.
software_os_installDate = installation date
The installation date of the operating system, if known.
software_os_lifecycle = 'Active' | 'Phaseout' | 'Discontinued' | 'End of Support'
Operating system lifecycle stage, if known.
software_os_licenseKey = license key
The license key of the operating system.
software_os_installDate = installation date in the format YYYY-MM-DD
The installation date of the operating system.
software_firmware_version = version string
The version of the firmware that is installed on a device.
software_category = 'OS' | 'Firmware' | 'Application' | 'Patch' | 'Component' | 'Antivirus' | 'Middleware' | 'Service' | 'Control Logic'
Category of software that is installed on a device. Since usually multiple software products are installed on OT devices, the condition is met if one of these software products falls within the specified category.
software_type = 'Engineering' | 'HMI / SCADA' | 'Office' | 'Security' | 'Infrastructure' | 'Business' | 'Other'
Type of software that is installed on a device. Since usually multiple software products are installed on OT devices, the condition is met if one of these software products is of the specified type.
software_vendor = vendor name
Name of a software vendor who's software is installed on a device. Since usually multiple software products are installed on OT devices, the condition is met if one of these software products are from the specified vendor.
Example:
result = set1.select({'software_vendor': 'OSIsoft'})
software_name = software product name
Name of a software product that is installed on a device. Since usually multiple software products are installed on OT devices, the condition is met if one of these software products have the specified name.
software_version = software product version
The product version of a software product that is installed on a device. Since usually multiple software products are installed on OT devices, the condition is met if one of these software products have the specified version.
software_licenseKey = license key
The license key of a software product that is installed on a device. Since usually multiple software products are installed on OT devices, the condition is met if one of these software products have the specified license key.
software_installDate = installation date in the format YYYY-MM-DD
The installation date of a software product that is installed on a device. Since usually multiple software products are installed on OT devices, the condition is met if one of these software products have the specified installation date.
software_lifecycle = 'Active' | 'Phaseout' | 'Discontinued' | 'End of Support'
The lifecycle stage of a software product that is installed on a device. Since usually multiple software products are installed on OT devices, the condition is met if one of these software products have the specified lifecycle stage.
Connections keywords
connections_network = network name
The name of a network that a device is connected to.
connections_networkAddress = network address
The network address of a network that a device is connected to, using CIDR notation.
connections_networkGroup = network group name
The name of a network group to which a network belongs that a device is connected to.
In the following example, we select all devices that are connected to networks belonging to the group "Safety":
result = set1.select({'connections_networkGroup': 'Safety'})
connections_medium = 'Copper' | 'Fiber'
The physical network medium used by a device's network adapters. Note that in many cases, this information is unknown.
connections_L2Address = network layer 2 address
The layer 2 address of a device's network adapter, usually the MAC address.
connections_L3Address = network layer 3 address
The layer 3 address of a device's network adapter, usually the IP address.
Example for selecting devices that use a specific IP address:
result = set1.select({'connections_L3Address': '192.168.0.9'}, match = 'EXACT')
In this statement, exact matching is requested because otherwise the query would also return devices with IP addresses such as 192.168.0.90, 192.168.0.91, 192.168.0.92 etc.
connections_counterpart = device ID
The device ID of the device (e.g. switch) that a device is directly connected to
Vulnerabilities keywords
connections_vlan = VLAN identifier
Identifier of a VLAN that a device is connected to.
vulnerabilities_cveId = CVE identifier in the format CVE-YYYY-number
The Common Vulnerability Enumerator of a vulnerability that applies to a device. If a device has multiple vulnerabilities, the condition is met if one of the vulnerabilities matches the CVE.
Example for selecting all devices that are vulnerable to CVE-2019-0708:
result = set1.select({'vulnerabilities_cveId': 'CVE-2019-0708'})
vulnerabilities_baseScore = CVSS base score
The CVSS base score of a vulnerability for a device. If a device has multiple vulnerabilities, the condition is met if one of the vulnerabilities matches the base score.
vulnerabilities_severity = 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL'
The CVSS severity of a vulnerability for a device. If a device has multiple vulnerabilities, the condition is met if one of the vulnerabilities matches the severity.
In the following example, we select devices that have one or more vulnerabilities with critical severity:
result = set1.select({'vulnerabilities_severity': 'CRITICAL'})
vulnerabilities_priority = 'Low' | 'Medium' | 'High' | 'Critical'
The priority of a vulnerability for a device. Priority is different from CVSS severity as it can be changed by the user. If a device has multiple vulnerabilities, the condition is met if one of the vulnerabilities matches the priority.
In the following example, we select devices that have one or more vulnerabilities with critical severity:
result = set1.select({'vulnerabilities_priority': 'CRITICAL'})
vulnerabilities_datePublished = Publication date of a vulnerability in the format YYYY-MM-DD
The publication date of a vulnerability for a device. If a device has multiple vulnerabilities, the condition is met if one of the vulnerabilities matches the publication date.
Extended keywords
extended_fieldName = value of a custom field
A property that is defined in a custom (user defined) field.
Match modifiers
op = 'AND' | 'OR'
Specifies if multiple arguments must all be matched for a device to make it into the result set ('AND'), or if it is enough for one argument to be matched ('OR'). The default setting is 'OR'.
Example for selecting devices that are manufactured by Dell and run the Windows 7 operating system:
result = set1.select({'hardware_vendor': 'Dell', 'software_os_name': 'Windows 7' }, operator = 'AND')
match = 'EXACT' | 'SEARCH'
Specifies if keyword arguments must be matched exactly (match == 'EXACT'). When match is set to 'SEARCH', or omitted, the matching condition is met if the keyword argument appears somewhere in the target string, without necessarily matching case. For example,
result = set1.select({'software_os_name' : 'xp'})
will return devices with the operating system name "Microsoft Windows XP Professional". As in OT-BASE Asset Center, the wildcards "?" and "%" can be used. "?" matches any character, and "%" matches any string.
get(attr, returnType = 'dict')
Returns the values of a specific attribute that is specified with the attr parameter.
Arguments
attr = attribute name
A string identifying the attribute for which values shall be returned. The following attribute names can be used:
deviceId, name, description, installationDate, stage, serialNumber, zone, safety, security, criticality
hardware, hardware_vendor, hardware_model, hardware_type, hardware_version, hardware_orderNumber, hardware_description, hardware_endOfLife, hardware_safety, hardware_lifecycle
context, context_location, context_locationId, context_referenceLocation, context_otSystem, context_deviceGroup
software, software_os_vendor, software_os_name, software_os_version, software_os_installDate, software_os_lifecycle, software_os_endOfSupport, software_firmware_version, software_category, software_type, software_vendor, software_name, software_version, software_licenseKey, software_installDate, software_lifecycle, software_endOfSupport
connections, connections_network, connections_networkAddress, connections_networkGroup, connections_medium, connections_L2Address, connections_L3Address, connections_vlan, connections_counterpart
vulnerabilities, vulnerabilities_cveId, vulnerabilities_baseScore, vulnerabilities_severity, vulnerabilities_priority, vulnerabilities_datePublished
extended
The list above contains two type of attributes: Attributes that return atomic values (such as single terms), and attributes that return complex values that are expressed as dictionaries. The latter are highlighted in italics. The meaning of the atomic arguments corresponds with the keywords in the select method.
The extended argument can also have atomic sub-arguments that can be referenced by using an underline suffix. Since extended fields are user defined, their names cannot be listed in this reference. As an example, if a custom field "MTTR" is defined for devices, it can be referenced as "extended_MTTR". In order to find out which extended fields are used by a data set, simply query for "extended" with no field name.
returnType = 'dict' | 'list' | 'set' | None
The requested return type. See below.
Examples
os_names = set1.get('software_os_name')
extended_fields = set1.get('extended')
Return value
The return value can be a list, set, or dictionary, depending on which type is requested by the second argument (if present).
- A result dictionary (default) contains unique attributes along with their frequency.
- A result list contains one element per device in the device set if the value for the requested attribute for a device is not empty. Such a list could, for example, be passed to matplotlib in order to plot a histogram.
- A result set contains only unique attributes.
set(attrDict)
Modifies the values of device attributes.
Arguments
attrDict = attribute dictionary
A dictionary with device attributes as keys. The values for each key will be set as the new value for the device attribute. Supported attribute names are:
name, description, installationDate, stage, serialNumber, zone, safety, security, criticality
hardware_vendor, hardware_model, hardware_type, hardware_version, hardware_orderNumber
context_location, context_locationId, context_referenceLocation, context_otSystem, context_deviceGroup
software_os_vendor, software_os_name, software_os_version, software_os_installDate, software_os_licenseKey, software_firmware_version
extended_{fieldName}
Example
set1.set({'criticality': 'SAFETY', 'context_locationId': '+GU7'})
set1.set({'extended_myCustomField': 'myNewValue'})
addTags(*tags)
Adds one or more tags to all devices in the device set.
Arguments
tags
One or more tags, passed as strings.
Example
set1.addTags('Tag 1', 'Tag 2')
removeTags(*tags)
Removes one or more tags from all devices in the device set. Other tags will remain intact.
Arguments
tags
One or more tags, passed as strings.
Example
set1.removeTags('Tag 1', 'Tag 2')
clone(prefix = None, mul = 1)
Produces a clone of the device set, using device IDs that are assigned based on the prefix that is passed as an argument, and on device type.
The following fields are cleared: serialNumber, connectivity, exposure, installDate. Device lifecycle stage is set to "Planned".
Arguments
prefix = prefix for the creation of device IDs
The clone method will automatically create device IDs based on the prefix, the device type, and an iterator.
mul = multiplication factor
Specifies how many copies of the device set shall be produced. Every device will still have a unique device ID. Applying a multiplication factor allows you to easily specify systems with multiple instances of a model device, such as a standard HMI station.
Example
set1clone = set1.clone(prefix = 'XYZ')
Example with multiplying devices of a model device to produce 20 instances of the model device(s):
my_new_system += hmi_model.clone(prefix = 'XZY', mul = 20)
show(columns = None, num = None)
Displays attributes of the device set in a tabular style. Note that this method is intended for a quick check of the device set and its attributes, not for algorithmic post-processing (for which you would use methods such as devices() or toExcel()).
Arguments
columns = list of columns to be included in the output
One or more columns that shall appear in the output can be passed as a list, using the following keywords:
deviceId, name, description, installationDate, stage, serialNumber, zone, safety, criticality
hardware_vendor, hardware_model, hardware_type, hardware_version, hardware_orderNumber, hardware_description, hardware_endOfLife, hardware_safety, hardware_lifecycle
context_location, context_locationId, context_referenceLocation, context_otSystem, context_deviceGroup
software_os_vendor, software_os_name, software_os_version, software_os_installDate, software_os_lifecycle, software_os_endOfSupport, software_firmware_version
extended_{fieldName}
If no columns argument is given, a representative subset will be output automatically.
num = maximum number of table rows
The optional num argument specifies the maximum number of table rows. If num is omitted, the full device set will be displayed.
Example
set1.show(['deviceId', 'name', 'description', 'software_os_name', 'extended_my custom field'], 20)
PID
Returns the asset data for all devices in a device set as a list in the Portable Inventory Data format.
__add__()
Adds devices to a device set. As with any set, the result set will not contain duplicate entries.
You can add
- another device set (type OtDeviceSet)
- a single device object (type OtDevice)
- a list of device objects (type OtDevice).
Example:
automation_gear = plcs + rtus + actuators
__sub__()
Substracts devices from a device set.
You can substract
- another device set (type OtDeviceSet)
- a single device object (type OtDevice)
- a list of device objects (type OtDevice).
Example:
automation_gear_without_plcs = automation_gear - plcs
createdWhen
Creation date of the device set if the set was loaded from a file in the Portable Inventory Data format.
createdBy
Name of the account that created the device set if the set was loaded from a file in the Portable Inventory Data format.
origin
Origin of the device set if the set was loaded from a file in the Portable Inventory Data format.
toExcel(filename, columns)
Stores asset data of the devices in the set as an Excel spreadsheet.
Arguments
filename
Specifies the file name that will be used to save the data.
columns = list of columns
One or more columns that shall appear in the output are passed as a list, using the following keywords:
deviceId, name, description, installationDate, stage, serialNumber, zone, safety, criticality
hardware_vendor, hardware_model, hardware_type, hardware_version, hardware_orderNumber, hardware_description, hardware_endOfLife, hardware_safety, hardware_lifecycle
context_location, context_locationId, context_referenceLocation, context_otSystem, context_deviceGroup
software_os_vendor, software_os_name, software_os_version, software_os_installDate, software_os_lifecycle, software_os_endOfSupport, software_firmware_version
extended_{fieldName}
Example
set1.toExcel('my OT devices.xlsx', ['deviceId', 'name', 'hardware_vendor', 'hardware_model', 'software_os_version']))
toFile(filename, user = 'unknown', organization = 'unknown')
Stores asset data of the devices in the set as a Portable Inventory Data file (JSON format).
Arguments
filename
specifies the file name that will be used to save the data.
user
Information on the user that created the file. If present, this information will be shown in OT-BASE Asset Center, OT-BASE Vantage, and OT-BASE Report Writer.
organization
Additional information on the user that created the file. If present, this information will be shown in OT-BASE Asset Center, OT-BASE Vantage, and OT-BASE Report Writer.
Example
set1.toFile('my OT devices.json', user = 'myself', organization = 'my org')
toAssetCenter(host, auth, prot = 'https', cert = None, overwrite = True)
Exports asset data of the device set to OT-BASE Asset Center using the REST API. You need to have an online connection to Asset Center and an active user account.
Arguments
host = IP address or hostname
Identifies the endpoint where OT-BASE Asset Center is hosted, either as an IP address or symbolic hostname.
prot = 'http' | 'https'
The protocol to be used. Default is https.
auth = (user ID, password)
Access credentials, expressed as a tuple
cert = client certificate
Filename(s) of client certificate(s) that are required to open a connection via HTTPS to a secure OT-BASE Asset Center, such as in OT-BASE Cloud. The client certificate is passed as a file name (path name). Note that the client certificate must be in the .pem format. If the certificate file contains both public and private key, one file name is sufficient. If you have split public and private key in separate files, pass the two file names as a tuple; public key first, private key second. -- You can generate a .pem file from a .p12 file using openssl, like "openssl pkcs12 -in mycert.p12 -out mycert.pem -nodes".
overwrite = True | False
Specifies if existing devices in OT-BASE Asset Center shall be updated. If set to False, the method will not overwrite existing device entries. It will, however, create a new device entry in Asset Center if the device ID doesn't exist yet. The overwrite = False setting is particularly useful when specifying new devices, for example using the clone() method. In this case, overwrite = False makes sure that no existing data is accidentally overwritten because newly assigned device IDs already exist in Asset Center.
Example
set1.toAssetCenter('192.168.178.5', (user, password), prot = 'http')
Return value
The status code of the HTTP request (200 = OK).
Comments
0 comments
Please sign in to leave a comment.