From 0c41d3f48206ca8dfd9b1fffd9dabd7207698218 Mon Sep 17 00:00:00 2001 From: Nicholas Hairs Date: Fri, 22 Nov 2024 19:35:11 +1100 Subject: [PATCH] More docs, contributing, security --- CODE_OF_CONDUCT.md | 1 + docs/changelog.md | 42 +++++++++++++- docs/contributing.md | 107 ++++++++++++++++++++++++++++++++++++ docs/error-handling.md | 4 +- docs/index.md | 6 -- docs/middleware.md | 9 +-- docs/security.md | 14 +++++ docs/subserver-blueprint.md | 9 +-- mkdocs.yml | 12 ++-- src/nserver/server.py | 8 ++- 10 files changed, 182 insertions(+), 30 deletions(-) create mode 120000 CODE_OF_CONDUCT.md create mode 100644 docs/contributing.md create mode 100644 docs/security.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 120000 index 0000000..d0fcfe9 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1 @@ +docs/contributing.md \ No newline at end of file diff --git a/docs/changelog.md b/docs/changelog.md index 9f9f034..7947d46 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,6 +1,44 @@ # Change Log +All notable changes to this project will be documented in this file. -## 2.0.0 +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + + +## [3.0.0](https://github.com/nhairs/nserver/compare/v2.0.0...dev) - UNRELEASED + +!!! tip + Version `3.0.0` represents a large incompatible refactor of `nserver` with version `2.0.0` considered a ["misfire"](https://github.com/nhairs/nserver/pull/4#issuecomment-2254354192). If you have been using functionality from `2.0.0` or the development branch you should expect a large number of breaking changes. + +### Added +- Add Python 3.13 support +- Generalised CLI interface for running applications; see `nserver --help`. + - Implemented in `nserver.cli`. +- `nserver.application` classes that focus on running a given server instance. + - This lays the ground work for different ways of running servers in the future; e.g. using threads. +- `nserver.server.RawNameServer` that handles `RawMiddleware` including exception handling. + +### Removed +- Drop Python 3.7 support +- `nserver.server.SubServer` has been removed. + - `NameServer` instances can now be registered to other `NameServer` instances. + +### Changed +- Refactored `nserver.server.NameServer` + - "Raw" functionality has been removed. This has been moved to the `nserver.server.RawNameServer`. + - "Transport" and other related "Application" functionality has been removed from `NameServer` instances. This has moved to the `nserver.application` classes. + - `NameServer` instances can now be registered to other instances. This replaces `SubServer` functionality that was in development. +- Refactoring of `nserver.server` and `nserver.middleware` classes. +- `NameServer` `name` argument / attribute is no longer used when creating the logger. + +### Development Changes +- Development tooling has moved to `uv`. + - The tooling remains wrapped in `dev.sh`. + - This remove the requirement for `docker` in local development. +- Test suite added to GitHub Actions. +- Added contributing guidelies. + +## [2.0.0](https://github.com/nhairs/nserver/compare/v1.0.0...v2.0.0) - 2023-12-20 - Implement [Middleware][middleware] - This includes adding error handling middleware that facilitates [error handling][error-handling]. @@ -10,6 +48,6 @@ - Add [Blueprints][blueprints] - Include refactoring `NameServer` into a new shared based `Scaffold` class. -## 1.0.0 +## [1.0.0](https://github.com/nhairs/nserver/commit/628db055848c6543641d514b4186f8d953b6af7d) - 2023-11-03 - Beta release diff --git a/docs/contributing.md b/docs/contributing.md new file mode 100644 index 0000000..22c8de4 --- /dev/null +++ b/docs/contributing.md @@ -0,0 +1,107 @@ +# Contributing + +Contributions are welcome! + +## Code of Conduct + +In general we follow the [Python Software Foundation Code of Conduct](https://policies.python.org/python.org/code-of-conduct/). Please note that we are not affiliated with the PSF. + +## Pull Request Process + +**0. Before you begin** + +If you're not familiar with contributing to open source software, [start by reading this guide](https://opensource.guide/how-to-contribute/). + +Be aware that anything you contribute will be licenced under [the project's licence](https://github.com/nhairs/nserver/blob/main/LICENSE). If you are making a change as a part of your job, be aware that your employer might own your work and you'll need their permission in order to licence the code. + +### 1. Find something to work on + +Where possible it's best to stick to established issues where discussion has already taken place. Contributions that haven't come from a discussed issue are less likely to be accepted. + +The following are things that can be worked on without an existing issue: + +- Updating documentation. This includes fixing in-code documentation / comments, and the overall docs. +- Small changes that don't change functionality such as refactoring or adding / updating tests. + +### 2. Fork the repository and make your changes + +We don't have styling documentation, so where possible try to match existing code. This includes the use of "headings" and "dividers" (this will make sense when you look at the code). + +Common devleopment tooling has been wrapped in `dev.sh` (which uses `uv` under the hood). + +Before creating your pull request you'll want to format your code and run the linters and tests: + +```shell +# Format +./dev.sh format + +# Lint +./dev.sh lint + +# Tests +./dev.sh test +``` + +If making changes to the documentation you can preview the changes locally using `./dev.sh docs`. Changes to the README can be previewed using [`grip`](https://github.com/joeyespo/grip) (not included in `dev` dependencies). + +!!! note + In general we will always squash merge pull requests so you do not need to worry about a "clean" commit history. + +### 3. Checklist + +Before pushing and creating your pull request, you should make sure you've done the following: + +- Updated any relevant tests. +- Formatted your code and run the linters and tests. +- Updated the version number in `pyproject.toml`. In general using a `.devN` suffix is acceptable. + This is not required for changes that do no affect the code such as documentation. +- Add details of the changes to the change log (`docs/changelog.md`), creating a new section if needed. +- Add notes for new / changed features in the relevant docstring. + +**4. Create your pull request** + +When creating your pull request be aware that the title and description will be used for the final commit so pay attention to them. + +Your pull request description should include the following: + +- Why the pull request is being made +- Summary of changes +- How the pull request was tested - especially if not covered by unit testing. + +Once you've submitted your pull request make sure that all CI jobs are passing. Pull requests with failing jobs will not be reviewed. + +### 5. Code review + +Your code will be reviewed by a maintainer. + +If you're not familiar with code review start by reading [this guide](https://google.github.io/eng-practices/review/). + +!!! tip "Remember you are not your work" + + You might be asked to explain or justify your choices. This is not a criticism of your value as a person! + + Often this is because there are multiple ways to solve the same problem and the reviewer would like to understand more about the way you solved. + +## Common Topics + +### Versioning and breaking compatability + +This project uses semantic versioning. + +In general backwards compatability is always preferred. + +Feature changes MUST be compatible with all [security supported versions of Python](https://endoflife.date/python) and SHOULD be compatible with all unsupported versions of Python where [recent downloads over the last 90 days exceeds 10% of all downloads](https://pypistats.org/packages/nserver). + +In general, only the latest `major.minor` version of NServer is supported. Bug fixes and feature backports requiring a version branch may be considered but must be discussed with the maintainers first. + +See also [Security Policy](security.md). + +### Spelling + +The original implementation of this project used Australian spelling so it will continue to use Australian spelling for all code. + +Documentation is more flexible and may use a variety of English spellings. + +### Contacting the Maintainers + +In general it is preferred to keep communication to GitHub, e.g. through comments on issues and pull requests. If you do need to contact the maintainers privately, please do so using the email addresses in the maintainers section of the `pyproject.toml`. diff --git a/docs/error-handling.md b/docs/error-handling.md index 2299e4c..a4c1d37 100644 --- a/docs/error-handling.md +++ b/docs/error-handling.md @@ -1,8 +1,8 @@ # Error Handling -Custom exception handling is handled through the [`ExceptionHandlerMiddleware`][nserver.middleware.ExceptionHandlerMiddleware] and [`RawExceptionHandlerMiddleware`][nserver.middleware.RawExceptionHandlerMiddleware] [Middleware][middleware]. These middleware will catch any `Exception`s raised by their respective middleware stacks. +Custom exception handling is handled through the [`QueryExceptionHandlerMiddleware`][nserver.middleware.QueryExceptionHandlerMiddleware] and [`RawExceptionHandlerMiddleware`][nserver.middleware.RawExceptionHandlerMiddleware] [Middleware][middleware]. These middleware will catch any `Exception`s raised by their respective middleware stacks. -In general you are probably able to use the `ExceptionHandlerMiddleware` as the `RawExceptionHandlerMiddleware` is only needed to catch exceptions resulting from `RawMiddleware` or broken exception handlers in the `ExceptionHandlerMiddleware`. If you only write `QueryMiddleware` and your `ExceptionHandlerMiddleware` handlers never raise exceptions then you'll be good to go with just the `ExceptionHandlerMiddleware`. +In general you are probably able to use the `QueryExceptionHandlerMiddleware` as the `RawExceptionHandlerMiddleware` is only needed to catch exceptions resulting from `RawMiddleware` or broken exception handlers in the `QueryExceptionHandlerMiddleware`. If you only write `QueryMiddleware` and your `QueryExceptionHandlerMiddleware` handlers never raise exceptions then you'll be good to go with just the `QueryExceptionHandlerMiddleware`. Both of these middleware have a default exception handler that will be used for anything not matching a registered handler. The default handler can be overwritten by registering a handler for the `Exception` class. diff --git a/docs/index.md b/docs/index.md index bc00750..ad02296 100644 --- a/docs/index.md +++ b/docs/index.md @@ -14,9 +14,6 @@ NServer has been built upon [dnslib](https://github.com/paulc/dnslib) however us NServer has been inspired by easy to use high level frameworks such as [Flask](https://github.com/pallets/flask) or [Requests](https://github.com/psf/requests). -!!! warning - NServer is currently Beta software and does not have complete documentation, testing, or implementation of certain features. - ## Features @@ -54,9 +51,6 @@ In the case of bug reports, please help us help you by following best practices In the case of feature requests, please provide background to the problem you are trying to solve so to help find a solution that makes the most sense for the library as well as your usecase. Before making a feature request consider looking at my (roughly written) [design notes](https://github.com/nhairs/nserver/blob/main/DESIGN_NOTES.md). -## Contributing -I am still working through open source licencing and contributing, so not taking PRs at this point in time. Instead raise and issue and I'll try get to it as soon a feasible. - ## Licence This project is licenced under the MIT Licence - see [`LICENCE`](https://github.com/nhairs/nserver/blob/main/LICENCE). diff --git a/docs/middleware.md b/docs/middleware.md index 9e924da..d5fb819 100644 --- a/docs/middleware.md +++ b/docs/middleware.md @@ -2,9 +2,6 @@ Middleware can be used to modify the behaviour of a server seperate to the individual rules that are registered to the server. Middleware is run on all requests and can modify both the input and response of a request. -!!! note - Middleware requires `nserver>=3.0` - ## Middleware Stacks Middleware operates in a stack with each middleware calling the middleware below it until one returns and the result is propagated back up the chain. NServer uses two stacks, the outmost stack deals with raw DNS records (`RawMiddleware`), which will eventually convert the record to a `Query` which will then be passed to the main `QueryMiddleware` stack. @@ -19,7 +16,7 @@ For most use cases you likely want to use [`QueryMiddleware`][nserver.middleware ### Registering `QueryMiddleware` -`QueryMiddleware` can be registered to `NameServer` and `SubServer` instances using their `register_middleware` methods. +`QueryMiddleware` can be registered to `NameServer` instances using their `register_middleware` methods. ```python from nserver import NameServer @@ -41,7 +38,7 @@ from nserver import Query, Response class MyLoggingMiddleware(QueryMiddleware): def __init__(self, logging_name: str): super().__init__() - self.logger = logging.getLogger(f"my-awesome-app.{name}") + self.logger = logging.getLogger(f"my-awesome-app.{logging_name}") return def process_query( @@ -60,7 +57,7 @@ server.register_middleware(MyLoggingMiddleware("bar")) Once processed the `QueryMiddleware` stack will look as follows: -- [`ExceptionHandlerMiddleware`][nserver.middleware.ExceptionHandlerMiddleware] +- [`QueryExceptionHandlerMiddleware`][nserver.middleware.QueryExceptionHandlerMiddleware] - Customisable error handler for `Exception`s originating from within the stack. - `` - [`HookMiddleware`][nserver.middleware.HookMiddleware] diff --git a/docs/security.md b/docs/security.md new file mode 100644 index 0000000..d2974bb --- /dev/null +++ b/docs/security.md @@ -0,0 +1,14 @@ +# Security Policy + +## Supported Versions + +Security support for Python JSON Logger is provided for all [security supported versions of Python](https://endoflife.date/python) and for unsupported versions of Python where [recent downloads over the last 90 days exceeds 10% of all downloads](https://pypistats.org/packages/nserver). + + +As of 2024-11-22 security support is provided for Python versions `3.8+`. + + +## Reporting a Vulnerability + +Please report vulnerabilties [using GitHub](https://github.com/nhairs/nserver/security/advisories/new). + diff --git a/docs/subserver-blueprint.md b/docs/subserver-blueprint.md index 774fc45..2323222 100644 --- a/docs/subserver-blueprint.md +++ b/docs/subserver-blueprint.md @@ -1,6 +1,5 @@ # Sub-Servers and Blueprints - ## Sub-Servers To allow for composing an application into different parts, a [`NameServer`][nserver.server.NameServer] can be included in another `NameServer`. @@ -11,9 +10,6 @@ Use cases: - Reuse a server registered under different rules. - Allow custom packages to define their own rules that you can add to your own server. -!!! note - Adding a `NameServer` to another requires `nserver>=3.0` - ### Using Sub-Servers ```python @@ -57,9 +53,6 @@ In particular errors will not propagate up from a child server to it's parent as [`Blueprint`][nserver.server.Blueprint]s act as a container for rules. They are an efficient way to compose your application if you do not want or need to use functionality provided by a `QueryMiddleware` stack. -!!! note - Blueprints require `nserver>=3.0` - ### Using Blueprints ```python @@ -91,4 +84,4 @@ mysite.rules.insert(0, no_email_blueprint) - Is used directly in `register_rule` (e.g. `some_server.register_rule(my_blueprint)`). - If rule does not match an internal rule will continue to the next rule in the parent server. - In comparison the server classes will return `NXDOMAIN` if a rule doesn't match their internal rules. + In comparison `NameServer` instances will return `NXDOMAIN` if a rule doesn't match their internal rules. diff --git a/mkdocs.yml b/mkdocs.yml index 2524ccf..be01854 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -15,8 +15,10 @@ nav: - error-handling.md - subserver-blueprint.md - production-deployment.md - - changelog.md - external-resources.md + - changelog.md + - security.md + - contributing.md - API Reference: - ... | reference/nserver/* @@ -84,10 +86,10 @@ plugins: python: paths: - src - #import: - # - https://docs.python.org/3/objects.inv - # - https://mkdocstrings.github.io/objects.inv - # - https://mkdocstrings.github.io/griffe/objects.inv + import: + - https://docs.python.org/3/objects.inv + - https://mkdocstrings.github.io/objects.inv + - https://mkdocstrings.github.io/griffe/objects.inv options: filters: - "!^_" diff --git a/src/nserver/server.py b/src/nserver/server.py index 6f88616..480d896 100644 --- a/src/nserver/server.py +++ b/src/nserver/server.py @@ -258,7 +258,13 @@ def prepare_middleware(self) -> None: class NameServer( MiddlewareMixin[m.QueryMiddleware, m.QueryExceptionHandlerMiddleware], RulesMixin, LoggingMixin ): - """High level DNS Name Server for responding to DNS queries.""" + """High level DNS Name Server for responding to DNS queries. + + *Changed in `3.0`*: + + - "Raw" functionality removed and moved to `RawNameServer`. + - "Transport" and "Application" functionality removed. + """ def __init__(self, name: str) -> None: """