Skip to content

Commit

Permalink
Release v1.1
Browse files Browse the repository at this point in the history
- A Circuit has one-to-one relationship with each of A and Z side
  endpoint Interfaces.
- Circuits are resource objects and therefore may have attributes and
  support set query lookups.
- A circuit must have at least an A-side endpoint defined. For circuits
  for which you do not own the remote end, you may leave the Z-side
  empty and specify the remote endpoint by customizing the circuit name.
- The Interface object unicode representation changed to
  `device_hostname:name` so that it can more easily be used as a slug
  for computing Circuit slug.
- Circuits have the following detail routes available in the API:
  - `circuits/:id/devices/` - List peer devices on either end of
    circuit
  - `circuits/:id/interfaces/` - List interfaces bound to the circuit
  - `circuits/:id/addresses/` - List addresses bound to circuit
    interfaces
- Interface's have a new ``interfaces/:id/circuit/`` detail route that
  will display the circuit to which an interface is bound.
- Devices have a new ``devices/:id/circuits/`` detail route that will
  display all circuits bound to interfaces on the device.
- The API endpoint for `Network.descendents` will now emit a "Warning"
  header to clients calling that endpoint telling them that it is
  pending deprecation.
- Implemented 3-feature-release deprecation policy in the documentation.
- Updated and improved some docstrings in the code
- Fixed a couple of pep8 style inconsistencies
  • Loading branch information
jathanism committed Jan 23, 2017
1 parent b3c3e2c commit bbb7286
Show file tree
Hide file tree
Showing 22 changed files with 1,356 additions and 36 deletions.
34 changes: 34 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,40 @@ Changelog
Version History
===============

.. _v1.1:

1.1 (2017-01-23)
----------------

* A formal :ref:`deprecation-policy` has been implemented which dictates a
three-feature release cycle for removing deprecated API endpoints. Please see
the documentation on this topic for more details.
* Fix #203 - Implementation of Circuits as a resource object.

+ A Circuit has one-to-one relationship with each of A and Z side
endpoint Interfaces.
+ Circuits are resource objects and therefore may have attributes and
support set query lookups.
+ A circuit must have at least an A-side endpoint defined. For circuits for
which you do not own the remote end, you may leave the Z-side empty and
specify the remote endpoint by customizing the circuit name.

* Circuits have the following detail routes available in the API:

+ ``circuits/:id/devices/`` - List peer devices on either end of circuit
+ ``circuits/:id/interfaces/`` - List interfaces bound to the circuit
+ ``circuits/:id/addresses/`` - List addresses bound to circuit interfaces

* Interfaces have a new ``interfaces/:id/circuit/`` detail route that will
display the circuit to which an interface is bound.
* Devices have a new ``devices/:id/circuits/`` detail route that will
display all circuits bound to interfaces on the device.
* Fix #191 - The Interface object unicode representation changed to
``device_hostname:name`` so that it can more easily be used as a slug for
computing Circuit slug.
* Fix #230 - The misspelled ``networks/:id/descendents/`` API endpoint is
pending deprecation in exchange for ``networks/:id/descendants/``.

.. _v1.0.13:

1.0.13 (2017-01-12)
Expand Down
2 changes: 2 additions & 0 deletions demo/demo_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,6 @@

# Enable DEBUG logging to console
if os.getenv('NSOT_DEBUG'):
DEBUG = True
LOGGING['loggers']['nsot']['level'] = 'DEBUG'
LOGGING['loggers']['django.db.backends'] = {'handlers': ['console'], 'level': 'DEBUG'}
2 changes: 1 addition & 1 deletion docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ RUN pip install psycopg2

# Try to run this as late as possible for layer caching - this version will be
# updated every update so let the build not take longer than necessary
RUN pip install nsot==1.0.13
RUN pip install nsot==1.1
COPY conf /etc/nsot

ENTRYPOINT ["nsot-server", "--config=/etc/nsot/nsot.conf.py"]
Expand Down
53 changes: 53 additions & 0 deletions docs/development.rst
Original file line number Diff line number Diff line change
Expand Up @@ -161,3 +161,56 @@ We make use of bower's "main file" concept to distribute only "main" files.
Most packages don't consider consider the minified versions of their project to
be their main files so you'll likely also need to update the ``overrides``
section of ``bower.json`` with which files to distribute.

.. _versioning:

Versioning
----------

We use `semantic versioning <http://semver.org>`_. Version numbers will
follow this format::

Major version}.{Minor version}.{Revision number}.{Build number (optional)}

Patch version numbers (0.0.x) are used for changes that are API compatible. You
should be able to upgrade between minor point releases without any other code
changes.

Minor version numbers (0.x.0) may include API changes, in line with the
:ref:`deprecation-policy`. You should read the release notes carefully before
upgrading between minor point releases.

Major version numbers (x.0.0) are reserved for substantial project milestones.

.. _deprecation-policy:

Deprecation policy
------------------

NSoT releases follow a formal deprecation policy, which is in line with
`Django's deprecation policy <https://docs.djangoproject.com/en/stable/internals/release-process/#internal-release-deprecation-policy>`_.

The timeline for deprecation of a feature present in version 1.0 would work as follows:

* Version 1.1 would remain **fully backwards compatible** with 1.0, but would raise
Python ``PendingDeprecationWarning`` warnings if you use the feature that are
due to be deprecated. These warnings are **silent by default**, but can be
explicitly enabled when you're ready to start migrating any required changes.

Additionally, a ``WARN`` message will be logged to standard out from the
``nsot-server`` process.

Finally, a ``Warning`` header will be sent back in any response from the API.
For example::

Warning: 299 - "The `descendents` API endpoint is pending deprecation. Use
the `descendants` API endpoint instead."

* Version 1.2 would escalate the Python warnings to ``DeprecationWarning``,
which is **loud by default**.
* Version 1.3 would remove the deprecated bits of API entirely and accessing
any deprecated API endoints will result in a ``404`` error.

Note that in line with Django's policy, any parts of the framework not
mentioned in the documentation should generally be considered private API, and
may be subject to change.
5 changes: 5 additions & 0 deletions docs/models.rst
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,11 @@ children
The child networks of this network

descendents
.. deprecated:: 1.1
Use *descendants* instead, which is the correctly spelled version of the
same method.

descendants
All children of the children of this network

closest_parent
Expand Down
7 changes: 7 additions & 0 deletions nsot/api/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,3 +148,10 @@ def filter_mac_address(self, queryset, value):
built-in field type.
"""
return queryset.filter(mac_address=value)


class CircuitFilter(ResourceFilter):
"""Filter for Circuit objects."""
class Meta:
model = models.Circuit
fields = ['endpoint_a', 'endpoint_z', 'name', 'attributes']
41 changes: 41 additions & 0 deletions nsot/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,47 @@ class Meta:
'parent_id', 'addresses', 'attributes')


#########
# Circuit
#########
class CircuitSerializer(ResourceSerializer):
"""Used for GET, DELETE on Circuits"""

class Meta:
model = models.Circuit
fields = '__all__'


class CircuitCreateSerializer(CircuitSerializer):
"""Used for POST on Circuits."""

class Meta:
model = models.Circuit
# Display name and site are auto-generated, don't include them here
fields = ('endpoint_a', 'endpoint_z', 'name', 'attributes')


class CircuitUpdateSerializer(BulkSerializerMixin, CircuitCreateSerializer):
"""Used for PUT on Circuits."""
attributes = JSONDictField(
required=True, help_text='Dictionary of attributes to set.'
)

class Meta:
model = models.Circuit
list_serializer_class = BulkListSerializer
fields = ('id', 'endpoint_a', 'endpoint_z', 'name', 'attributes')


class CircuitPartialUpdateSerializer(BulkSerializerMixin,
CircuitCreateSerializer):
"""Used for PATCH on Circuits."""
class Meta:
model = models.Circuit
list_serializer_class = BulkListSerializer
fields = ('id', 'endpoint_a', 'endpoint_z', 'name', 'attributes')


###########
# AuthToken
###########
Expand Down
2 changes: 2 additions & 0 deletions nsot/api/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
router.register(r'sites', views.SiteViewSet)
router.register(r'attributes', views.AttributeViewSet)
router.register(r'changes', views.ChangeViewSet)
router.register(r'circuits', views.CircuitViewSet)
router.register(r'devices', views.DeviceViewSet)
router.register(r'interfaces', views.InterfaceViewSet)
router.register(r'networks', views.NetworkViewSet)
Expand All @@ -28,6 +29,7 @@
# Resources that are nested under /sites
sites_router.register(r'attributes', views.AttributeViewSet)
sites_router.register(r'changes', views.ChangeViewSet)
sites_router.register(r'circuits', views.CircuitViewSet)
sites_router.register(r'devices', views.DeviceViewSet)
sites_router.register(r'interfaces', views.InterfaceViewSet)
sites_router.register(r'networks', views.NetworkViewSet)
Expand Down
Loading

0 comments on commit bbb7286

Please sign in to comment.