Parcourir la source

Improved model docstring quality

Jeremy Stretch il y a 8 ans
Parent
commit
bc958a23b3
4 fichiers modifiés avec 93 ajouts et 36 suppressions
  1. 9 5
      netbox/circuits/models.py
  2. 49 20
      netbox/dcim/models.py
  3. 23 7
      netbox/ipam/models.py
  4. 12 4
      netbox/secrets/models.py

+ 9 - 5
netbox/circuits/models.py

@@ -6,15 +6,16 @@ from dcim.models import Site, Interface
 
 class Provider(models.Model):
     """
-    A transit provider, IX, or direct peer
+    Each Circuit belongs to a Provider. This is usually a telecommunications company or similar organization. This model
+    stores information pertinent to the user's relationship with the Provider.
     """
     name = models.CharField(max_length=50, unique=True)
     slug = models.SlugField(unique=True)
     asn = models.PositiveIntegerField(blank=True, null=True, verbose_name='ASN')
     account = models.CharField(max_length=30, blank=True, verbose_name='Account number')
     portal_url = models.URLField(blank=True, verbose_name='Portal')
-    noc_contact = models.TextField(blank=True, verbose_name='NOC Contact')
-    admin_contact = models.TextField(blank=True, verbose_name='Admin Contact')
+    noc_contact = models.TextField(blank=True, verbose_name='NOC contact')
+    admin_contact = models.TextField(blank=True, verbose_name='Admin contact')
     comments = models.TextField(blank=True)
 
     class Meta:
@@ -38,7 +39,8 @@ class Provider(models.Model):
 
 class CircuitType(models.Model):
     """
-    A type of circuit
+    Circuits can be orgnanized by their functional role. For example, a user might wish to define CircuitTypes named
+    "Long Haul," "Metro," or "Out-of-Band".
     """
     name = models.CharField(max_length=50, unique=True)
     slug = models.SlugField(unique=True)
@@ -55,7 +57,9 @@ class CircuitType(models.Model):
 
 class Circuit(models.Model):
     """
-    A data circuit from a site to a provider (includes IX connections)
+    A communications circuit connects two points. Each Circuit belongs to a Provider; Providers may have multiple
+    circuits. Each circuit is also assigned a CircuitType and a Site. A Circuit may be terminated to a specific device
+    interface, but this is not required. Circuit port speed and commit rate are measured in Kbps.
     """
     cid = models.CharField(max_length=50, verbose_name='Circuit ID')
     provider = models.ForeignKey('Provider', related_name='circuits', on_delete=models.PROTECT)

+ 49 - 20
netbox/dcim/models.py

@@ -84,7 +84,8 @@ RPC_CLIENT_CHOICES = [
 
 class Site(models.Model):
     """
-    A physical site
+    A Site represents a geographic location within a network; typically a building or campus. The optional facility
+    field can be used to include an external designation, such as a data center name (e.g. Equinix SV6).
     """
     name = models.CharField(max_length=50, unique=True)
     slug = models.SlugField(unique=True)
@@ -134,7 +135,9 @@ class Site(models.Model):
 
 class RackGroup(models.Model):
     """
-    An arbitrary grouping of Racks; e.g. a building or room.
+    Racks can be grouped as subsets within a Site. The scope of a group will depend on how Sites are defined. For
+    example, if a Site spans a corporate campus, a RackGroup might be defined to represent each building within that
+    campus. If a Site instead represents a single building, a RackGroup might represent a single room or floor.
     """
     name = models.CharField(max_length=50)
     slug = models.SlugField()
@@ -156,7 +159,8 @@ class RackGroup(models.Model):
 
 class Rack(models.Model):
     """
-    An equipment rack within a site (e.g. a 48U rack)
+    Devices are housed within Racks. Each rack has a defined height measured in rack units, and a front and rear face.
+    Each Rack is assigned to a Site and (optionally) a RackGroup.
     """
     name = models.CharField(max_length=50)
     facility_id = NullableCharField(max_length=30, blank=True, null=True, verbose_name='Facility ID')
@@ -271,7 +275,7 @@ class Rack(models.Model):
 
 class Manufacturer(models.Model):
     """
-    A hardware manufacturer
+    A Manufacturer represents a company which produces hardware devices; for example, Juniper or Dell.
     """
     name = models.CharField(max_length=50, unique=True)
     slug = models.SlugField(unique=True)
@@ -288,7 +292,18 @@ class Manufacturer(models.Model):
 
 class DeviceType(models.Model):
     """
-    A unique hardware type; manufacturer and model number (e.g. Juniper EX4300-48T)
+    A DeviceType represents a particular make (Manufacturer) and model of device. It specifies rack height and depth, as
+    well as high-level functional role(s).
+
+    Each DeviceType can have an arbitrary number of component templates assigned to it, which define console, power, and
+    interface objects. For example, a Juniper EX4300-48T DeviceType would have:
+
+      * 1 ConsolePortTemplate
+      * 2 PowerPortTemplates
+      * 48 InterfaceTemplates
+
+    When a new Device of this type is created, the appropriate console, power, and interface objects (as defined by the
+    DeviceType) are automatically created as well.
     """
     manufacturer = models.ForeignKey('Manufacturer', related_name='device_types', on_delete=models.PROTECT)
     model = models.CharField(max_length=50)
@@ -319,7 +334,7 @@ class DeviceType(models.Model):
 
 class ConsolePortTemplate(models.Model):
     """
-    A template for a ConsolePort to be created for a new device
+    A template for a ConsolePort to be created for a new Device.
     """
     device_type = models.ForeignKey('DeviceType', related_name='console_port_templates', on_delete=models.CASCADE)
     name = models.CharField(max_length=30)
@@ -334,7 +349,7 @@ class ConsolePortTemplate(models.Model):
 
 class ConsoleServerPortTemplate(models.Model):
     """
-    A template for a ConsoleServerPort to be created for a new device
+    A template for a ConsoleServerPort to be created for a new Device.
     """
     device_type = models.ForeignKey('DeviceType', related_name='cs_port_templates', on_delete=models.CASCADE)
     name = models.CharField(max_length=30)
@@ -349,7 +364,7 @@ class ConsoleServerPortTemplate(models.Model):
 
 class PowerPortTemplate(models.Model):
     """
-    A template for a PowerPort to be created for a new device
+    A template for a PowerPort to be created for a new Device.
     """
     device_type = models.ForeignKey('DeviceType', related_name='power_port_templates', on_delete=models.CASCADE)
     name = models.CharField(max_length=30)
@@ -364,7 +379,7 @@ class PowerPortTemplate(models.Model):
 
 class PowerOutletTemplate(models.Model):
     """
-    A template for a PowerOutlet to be created for a new device
+    A template for a PowerOutlet to be created for a new Device.
     """
     device_type = models.ForeignKey('DeviceType', related_name='power_outlet_templates', on_delete=models.CASCADE)
     name = models.CharField(max_length=30)
@@ -379,7 +394,7 @@ class PowerOutletTemplate(models.Model):
 
 class InterfaceTemplate(models.Model):
     """
-    A template for a physical data interface on a new device
+    A template for a physical data interface on a new Device.
     """
     device_type = models.ForeignKey('DeviceType', related_name='interface_templates', on_delete=models.CASCADE)
     name = models.CharField(max_length=30)
@@ -400,7 +415,8 @@ class InterfaceTemplate(models.Model):
 
 class DeviceRole(models.Model):
     """
-    The functional role of a device (e.g. router, switch, console server, etc.)
+    Devices are organized by functional role; for example, "Core Switch" or "File Server". Each DeviceRole is assigned a
+    color to be used when displaying rack elevations.
     """
     name = models.CharField(max_length=50, unique=True)
     slug = models.SlugField(unique=True)
@@ -418,7 +434,9 @@ class DeviceRole(models.Model):
 
 class Platform(models.Model):
     """
-    A class of software running on a hardware device (e.g. Juniper Junos or Cisco IOS)
+    Platform refers to the software or firmware running on a Device; for example, "Cisco IOS-XR" or "Juniper Junos".
+    NetBox uses Platforms to determine how to interact with devices when pulling inventory data or other information by
+    specifying an remote procedure call (RPC) client.
     """
     name = models.CharField(max_length=50, unique=True)
     slug = models.SlugField(unique=True)
@@ -436,7 +454,15 @@ class Platform(models.Model):
 
 class Device(models.Model):
     """
-    A physical piece of equipment mounted within a rack
+    A Device represents a piece of physical hardware mounted within a Rack. Each Device is assigned a DeviceType,
+    DeviceRole, and (optionally) a Platform. Device names are not required, however if one is set it must be unique.
+
+    Each Device must be assigned to a Rack, although associating it with a particular rack face or unit is optional (for
+    example, vertically mounted PDUs do not consume rack units).
+
+    When a new Device is created, console/power/interface components are created along with it as dictated by the
+    component templates assigned to its DeviceType. Components can also be added, modified, or deleted after the
+    creation of a Device.
     """
     device_type = models.ForeignKey('DeviceType', related_name='instances', on_delete=models.PROTECT)
     device_role = models.ForeignKey('DeviceRole', related_name='devices', on_delete=models.PROTECT)
@@ -553,7 +579,7 @@ class Device(models.Model):
 
 class ConsolePort(models.Model):
     """
-    A physical console port on a device
+    A physical console port within a Device. ConsolePorts connect to ConsoleServerPorts.
     """
     device = models.ForeignKey('Device', related_name='console_ports', on_delete=models.CASCADE)
     name = models.CharField(max_length=30)
@@ -596,7 +622,7 @@ class ConsoleServerPortManager(models.Manager):
 
 class ConsoleServerPort(models.Model):
     """
-    A physical port on a console server
+    A physical port within a Device (typically a designated console server) which provides access to ConsolePorts.
     """
     device = models.ForeignKey('Device', related_name='cs_ports', on_delete=models.CASCADE)
     name = models.CharField(max_length=30)
@@ -612,7 +638,7 @@ class ConsoleServerPort(models.Model):
 
 class PowerPort(models.Model):
     """
-    A physical power supply (intake) port on a device
+    A physical power supply (intake) port within a Device. PowerPorts connect to PowerOutlets.
     """
     device = models.ForeignKey('Device', related_name='power_ports', on_delete=models.CASCADE)
     name = models.CharField(max_length=30)
@@ -649,7 +675,7 @@ class PowerOutletManager(models.Manager):
 
 class PowerOutlet(models.Model):
     """
-    A physical power outlet (output) port on a device
+    A physical power outlet (output) within a Device which provides power to a PowerPort.
     """
     device = models.ForeignKey('Device', related_name='power_outlets', on_delete=models.CASCADE)
     name = models.CharField(max_length=30)
@@ -688,7 +714,8 @@ class InterfaceManager(models.Manager):
 
 class Interface(models.Model):
     """
-    A physical data interface on a device
+    A physical data interface within a Device. An Interface can connect to exactly one other Interface via the creation
+    of an InterfaceConnection.
     """
     device = models.ForeignKey('Device', related_name='interfaces', on_delete=models.CASCADE)
     name = models.CharField(max_length=30)
@@ -744,7 +771,8 @@ class Interface(models.Model):
 
 class InterfaceConnection(models.Model):
     """
-    A symmetrical, one-to-one connection between two device interfaces
+    An InterfaceConnection represents a symmetrical, one-to-one connection between two Interfaces. There is no
+    significant difference between the interface_a and interface_b fields.
     """
     interface_a = models.OneToOneField('Interface', related_name='connected_as_a', on_delete=models.CASCADE)
     interface_b = models.OneToOneField('Interface', related_name='connected_as_b', on_delete=models.CASCADE)
@@ -768,7 +796,8 @@ class InterfaceConnection(models.Model):
 
 class Module(models.Model):
     """
-    A hardware module belonging to a device. Used for inventory purposes only.
+    A Module represents a piece of hardware within a Device, such as a line card or power supply. Modules are used only
+    for inventory purposes.
     """
     device = models.ForeignKey('Device', related_name='modules', on_delete=models.CASCADE)
     parent = models.ForeignKey('self', related_name='submodules', blank=True, null=True, on_delete=models.CASCADE)

+ 23 - 7
netbox/ipam/models.py

@@ -38,7 +38,9 @@ STATUS_CHOICE_CLASSES = {
 
 class VRF(models.Model):
     """
-    A discrete layer three forwarding domain (e.g. a routing table)
+    A virtual routing and forwarding (VRF) table represents a discrete layer three forwarding domain (e.g. a routing
+    table). Prefixes and IPAddresses can optionally be assigned to VRFs. (Prefixes and IPAddresses not assigned to a VRF
+    are said to exist in the "global" table.)
     """
     name = models.CharField(max_length=50)
     rd = models.CharField(max_length=21, unique=True, verbose_name='Route distinguisher')
@@ -65,7 +67,8 @@ class VRF(models.Model):
 
 class RIR(models.Model):
     """
-    A regional Internet registry (e.g. ARIN) or governing standard (e.g. RFC 1918)
+    A Regional Internet Registry (RIR) is responsible for the allocation of a large portion of the global IP address
+    space. This can be an organization like ARIN or RIPE, or a governing standard such as RFC 1918.
     """
     name = models.CharField(max_length=50, unique=True)
     slug = models.SlugField(unique=True)
@@ -84,7 +87,8 @@ class RIR(models.Model):
 
 class Aggregate(models.Model):
     """
-    A top-level IPv4 or IPv6 prefix
+    An aggregate exists at the root level of the IP address space hierarchy in NetBox. Aggregates are used to organize
+    the hierarchy and track the overall utilization of available address space. Each Aggregate is assigned to a RIR.
     """
     family = models.PositiveSmallIntegerField(choices=AF_CHOICES)
     prefix = IPNetworkField()
@@ -145,7 +149,8 @@ class Aggregate(models.Model):
 
 class Role(models.Model):
     """
-    The role of an address resource (e.g. customer, infrastructure, mgmt, etc.)
+    A Role represents the functional role of a Prefix or VLAN; for example, "Customer," "Infrastructure," or
+    "Management."
     """
     name = models.CharField(max_length=50, unique=True)
     slug = models.SlugField(unique=True)
@@ -203,7 +208,9 @@ class PrefixQuerySet(models.QuerySet):
 
 class Prefix(models.Model):
     """
-    An IPv4 or IPv6 prefix, including mask length
+    A Prefix represents an IPv4 or IPv6 network, including mask length. Prefixes can optionally be assigned to Sites and
+    VRFs. A Prefix must be assigned a status and may optionally be assigned a used-define Role. A Prefix can also be
+    assigned to a VLAN where appropriate.
     """
     family = models.PositiveSmallIntegerField(choices=AF_CHOICES, editable=False)
     prefix = IPNetworkField()
@@ -263,7 +270,14 @@ class Prefix(models.Model):
 
 class IPAddress(models.Model):
     """
-    An IPv4 or IPv6 address
+    An IPAddress represents an individual IPV4 or IPv6 address and its mask. The mask length should match what is
+    configured in the real world. (Typically, only loopback interfaces are configured with /32 or /128 masks.) Like
+    Prefixes, IPAddresses can optionally be assigned to a VRF. An IPAddress can optionally be assigned to an Interface.
+    Interfaces can have zero or more IPAddresses assigned to them.
+
+    An IPAddress can also optionally point to a NAT inside IP, designating itself as a NAT outside IP. This is useful,
+    for example, when mapping public addresses to private addresses. When an Interface has been assigned an IPAddress
+    which has a NAT outside IP, that Interface's Device can use either the inside or outside IP as its primary IP.
     """
     family = models.PositiveSmallIntegerField(choices=AF_CHOICES, editable=False)
     address = IPAddressField()
@@ -311,7 +325,9 @@ class IPAddress(models.Model):
 
 class VLAN(models.Model):
     """
-    A VLAN within a site
+    A VLAN is a distinct layer two forwarding domain identified by a 12-bit integer (1-4094). Each VLAN must be assigned
+    to a Site, however VLAN IDs need not be unique within a Site. Like Prefixes, each VLAN is assigned an operational
+    status and optionally a user-defined Role. A VLAN can have zero or more Prefixes assigned to it.
     """
     site = models.ForeignKey('dcim.Site', related_name='vlans', on_delete=models.PROTECT)
     vid = models.PositiveSmallIntegerField(verbose_name='ID', validators=[

+ 12 - 4
netbox/secrets/models.py

@@ -52,7 +52,9 @@ class UserKeyQuerySet(models.QuerySet):
 
 class UserKey(models.Model):
     """
-    A user's personal public RSA key.
+    A UserKey stores a user's personal RSA (public) encryption key, which is used to generate their unique encrypted
+    copy of the master encryption key. The encrypted instance of the master key can be decrypted only with the user's
+    matching (private) decryption key.
     """
     user = models.OneToOneField(User, related_name='user_key', verbose_name='User')
     public_key = models.TextField(verbose_name='RSA public key')
@@ -161,7 +163,8 @@ class UserKey(models.Model):
 
 class SecretRole(models.Model):
     """
-    A functional classification of secret type. For example: login credentials, SNMP communities, etc.
+    A SecretRole represents an arbitrary functional classification of Secrets. For example, a user might define roles
+    such as "Login Credentials" or "SNMP Communities."
     """
     name = models.CharField(max_length=50, unique=True)
     slug = models.SlugField(unique=True)
@@ -180,8 +183,13 @@ class SecretRole(models.Model):
 
 class Secret(models.Model):
     """
-    A secret string of up to 255 bytes in length, stored as both an AES256-encrypted ciphertext and an irreversible
-    salted SHA256 hash (for plaintext validation).
+    A Secret stores an AES256-encrypted copy of sensitive data, such as passwords or secret keys. An irreversible
+    SHA-256 hash is stored along with the ciphertext for validation upon decryption. Each Secret is assigned to a
+    Device; Devices may have multiple Secrets associated with them. A name can optionally be defined along with the
+    ciphertext; this string is stored as plain text in the database.
+
+    A Secret can be up to 65,536 bytes (64KB) in length. Each secret string will be padded with random data to a minimum
+    of 64 bytes during encryption in order to protect short strings from ciphertext analysis.
     """
     device = models.ForeignKey(Device, related_name='secrets')
     role = models.ForeignKey('SecretRole', related_name='secrets', on_delete=models.PROTECT)