Skip to main content

API Architecture

The Thermostat API is a pretty standard Node.js server application. It serves its HTTP API using Koa, which is a HTTP server library similar to the popular Express library. It serves its SSH API using the SSH2 library which contains utilities for creating custom SSH clients and servers. It uses PostgreSQL as its underlying database for data storage and stores backup files on the filesystem.

API Architecture

Data Model

The core data model of the Thermostat API is depicted below:

Database Model

Clients

The Clients table contains the list of Clients that have applications currently associated with them, it currently just stores data about the client's name and unique identifier.

Applications

The Applications table contains the list of Applications that can be deployed with the Thermostat CLI. It stores data about the application's name, unique identifier, Git repository location, and client.

Servers

The Servers table contains the list of Servers that have the Thermostat CLI installed. It currently just stores data about the server's name and unique identifier.

Server Users

The ServerUsers table contains the list of each of the users on each of the servers that can access the Thermostat CLI. It stores data about the user's username, the server the user is associated with, the public key identifier used for authenticating the user, and contains a private key that can be used to access that user account via SSH.

Deployments

The Deployments table contains the list of all of the Deployments that servers are allowed to make. Each row links one server user and one application stage. This is the primary authorization mechanism that determines which servers are allowed to deploy which applications to prevent any random client server from deploying any random application. This confines the blast radius of a particular server being compromised to just the applications deployed on that server.

Employees

The Employees table contains the list of all of the developers that currently have access to Thermostat. It stores data about the employee's name, unique identifier, IP addresses, and public keys that can be used to authenticate the user. All employees are allowed to deploy any application, unlike server users that require a deployment record to deploy something.

Backups

The primary purpose of the Thermostat API server is to serve as a secure and convenient repository for backups for applications. This is useful not only for disaster recovery purposes, it also ensures full reproducibility of deployments and which allows users to easily transfer projects between different servers. This is somewhat useful for backing up or migrating staging and production environments, but it really shines in the context of local development environments. New developers frequently need to set up new local development environments for existing projects on their computers, and without a robust data transfer system this can be a long and arduous process of manually constructing the necessary data files for the project or finding and transferring them manually from an existing deployment on another server. Thermostat automates this entire process so one developer just needs to run thermostat upload to upload their development data to the Thermostat API and any other developer can easily deploy their own copy of the environment just by running thermostat deploy.

GitLab Integration

The Thermostat API also integrates with GitLab in order to automatically set up GitLab Deploy Keys for new application deployments on servers. Basically whenever a server requests information from the Thermostat API about an application in order to perform a deployment, the Thermostat API server checks that a deploy key exists in that application's GitLab repository settings that allows the requesting server to clone the Git repository. If such a deploy key doesn't already exist, the Thermostat API server creates it. This allows for easy deployments to new servers without having to mess with deploy keys directly. Note however that Thermostat has no way of creating deploy keys for transitive dependencies that may be needed to build the application, for example if the application also pulls WordPress plugins from GitLab during its build process, those deploy keys need to be manually added to those GitLab repositories in order to allow the new server to build the project.