The Basics
So I’ve seen a few implementations of ‘config services’ being built in all sorts of {ruby,python,php,java} applications. It really gets on my nerves to see people implementing things that could be much simpler. As Engineers we should really strive to get the most simple product built in a flexible way. So here is my go at implementing a ‘config service’ (basically a key value store optimised for reads). This was originally tweeted in a set of four tweets (1, 2, 3, 4).
Tweet 1
A 'Config Service' that fits in a tweet: <Location /config> DAV svn SVNPath /var/svn/config SVNAutoversioning on </Location>
Simply place this in your apache server configuration. You’ll need to create the SVN repo, which can be done with ‘svnadmin create /var/svn/config’ then chmod it to be writiable and readable by apache. What we are doing here is turning on WebDAV (which lets us upload and make directories on the apache server) and turning on SVN backed autoversioning which means that every change we make will be recorded in the SVN repo.
Tweet 2
To get a variable: curl -s http://config/config/namespace/key
This simply performs a GET request for a key. You can’t do this until you add some keys to the server.
Tweet 3
To change a variable: echo "value" | curl -T- http://config/config/namespace/key
This creates/modifies a key. You will need to have the namespace created first, which is in the next tweet.
Tweet 4
Make a new namespace: curl -XMKCOL http://config/config/namespace
This creates a namespace to put keys in.
Extensions
Users
The service above doesn’t support users, so anyone can modify the keys, and the svn logs look like this:
------------------------------------------------------------------------ r5 | (no author) | 2012-10-15 12:36:33 +1100 (Mon, 15 Oct 2012) | 2 lines Autoversioning commit:Â a non-deltaV client made a change to /namespace/key ------------------------------------------------------------------------
All we need to do is require the user to authenticate when doing PUT requests to the server. You can use this method to restrict certain namespaces too. Generate a htpasswd file for the users and place it in /var/svn/users and change the code to read as follows.
<Location /config>
DAV svn
SVNPath /var/svn/config
SVNAutoversioning on
AuthName "Config Service"
AuthType Basic
AuthUserFile /var/svn/users
<LimitExcept GET>
require valid-user
</Limit>
</Location>
Viewing the logs
Simply do this:
svn checkout http://config/config cd config svn log
You can also use this to make bulk/atomic changes in the same way you would make changes to a subversion repository.