diff --git a/beps/0005-split-backend-discovery/README.md b/beps/0005-split-backend-discovery/README.md new file mode 100644 index 0000000000..420a804160 --- /dev/null +++ b/beps/0005-split-backend-discovery/README.md @@ -0,0 +1,157 @@ +--- +title: Discovery API - Split Backends +status: provisional +authors: + - '@aramissennyeydd' +owners: +project-areas: + - core +creation-date: 2024-02-16 +--- + + + +# BEP: Discovery API - Split Backends + + + +[**Discussion Issue**](https://github.com/backstage/backstage/issues/NNNNN) + +- [Summary](#summary) +- [Motivation](#motivation) + - [Goals](#goals) + - [Non-Goals](#non-goals) +- [Proposal](#proposal) +- [Design Details](#design-details) +- [Release Plan](#release-plan) +- [Dependencies](#dependencies) +- [Alternatives](#alternatives) + +## Glossary + +### Gateway Node + +A node that serves as the primary discovery point. A gateway node will have all of the information necessary to route traffic through your system. + +### Non-gateway Node + +A node that needs to call a Gateway node for routing. + +## Summary + + + +The goal of this BEP is to define the architecture that we will be using for an automatic discovery API that handles split backends. While users can use the current target-based config, it is not runtime driven and adding plugins requires a config update. This new system allows existing backends to register with gateway nodes at start time and based on reachability, can be deregistered. + +## Motivation + + + +Split backends are a consistently difficult space to operate in and design for. There has been a growing desire for the framework to provide a way to get a list of the installed plugins. This was nearly impossible in the old backend, where plugins were hosted on unnormalized routes and had non-standard startup sequences. In the new backend, this has become significantly more doable. Moving this forward would unblock a number of cases that require knowledge of your entire Backstage installation, namely a single OpenAPI spec for your instance, checking installed permissions, and DevTools information. + +Ideally, this work will also make it easier for adopters to go down the path of split backends. + +### Goals + + + +1. As an integrator, I can now get a list of currently installed plugins across my deployment. +1. As an administrator, I can add/remove plugins without having to do a full redeployment of all of my Backstage nodes. + +### Non-Goals + + + +1. I can't install plugins using the new discovery API. +1. I can't control my deployments using the new discovery API. +1. If I fork the BackendInitialization logic, I may not be able to use this API. + +## Proposal + + + +## Design Details + + + +![](./discovery.png) + +![](./registrations.png) + +![](./frontend.png) + +### Gateway Scaling + +The primary concern with having multiple gateway nodes is alignment on what plugins are installed across the instance. For this, we propose a new database that will store, + +```ts +export interface PluginRegistrations { + plugin_id: string; + internal_url: string; + external_url: string; + last_check_in: timestamp; +} +``` + +As any gateway node _could_ be hit by any given plugin, the implementation should not rely on in-memory values per node. Gateway nodes should read and write from/to the database directly. + +The triplet `plugin_id`, `internal_url`, `external_url` should be unique. We may have multiple plugins on multiple URLs either internal or external. Routing in those cases is not covered in this BEP. Horizontally scaled plugins should use external technologies to route requests and handle load balancing. This should be reflected in their `backend.baseUrl` properties. Instance IP addresses should _not_ be sent or stored in this database. + +### Check ins + +To prevent stale data, we propose implementing "check ins". Each check in will write to the database's `last_check_in` row, these will be infrequent enough that this isn't a crazy load on the database. These check ins serve 2 purposes, + +1. to verify that the gateway node is reachable by the non-gateway node. +1. to verify that the gateway node has the most up to date data from the non-gateway node. + +The first is necessary to prevent a case where the non-gateway node loses network access or crashes. In this case, we will use the `last_check_in` timestamp. If an instance hasn't contacted the gateway plugin in x checkins (or seconds), we remove that instance's plugins. This will most likely be an optimistic update and will happen at read time for other operations. So the database may still have entries with expired `last_check_in` rows if the discovery API is not actively used. + +The second is necessary to prevent a case where an instance may restart with more/less plugins. The gateway needs a way of knowing that the instance data changed. This is why we propose a "check in" approach over just a heartbeat. The non-gateway plugin should send its list of plugins to the gateway plugin to check if anything has changed since it last checked in. This allows us to be much more specific about when the instance will re-register. + +In the case of horizontally scaled plugins, we should be able to keep the current check-ins, but we may revisit if the volume is too high. + +## Release Plan + + + +## Dependencies + + + +## Alternatives + + diff --git a/beps/0005-split-backend-discovery/discovery.png b/beps/0005-split-backend-discovery/discovery.png new file mode 100644 index 0000000000..111ba2f1e4 Binary files /dev/null and b/beps/0005-split-backend-discovery/discovery.png differ diff --git a/beps/0005-split-backend-discovery/frontend.png b/beps/0005-split-backend-discovery/frontend.png new file mode 100644 index 0000000000..b009e0a21d Binary files /dev/null and b/beps/0005-split-backend-discovery/frontend.png differ diff --git a/beps/0005-split-backend-discovery/registrations.png b/beps/0005-split-backend-discovery/registrations.png new file mode 100644 index 0000000000..77aeabd025 Binary files /dev/null and b/beps/0005-split-backend-discovery/registrations.png differ