SwiftStack Custom Middleware Example: FooAppender
This repo is intended to present an as-simple-as-usefully-possible example of writing, and using, custom middleware in SwiftStack using an on-premise Controller.
What does it do?
This middleware ensures, usefully, that a user metadata value of foo:$bar (where $bar can be configured) exists on objects you upload or modify in your SwiftStack cluster.
To restrict this behaviour to certain accounts, containers, or objects, you can configure an
enforce_pattern - only objects whose full name (
Object) matches this pattern will be modified by this middleware.
How do I deploy it?
We expect you to already have a SwiftStack environment setup for middleware development. If you do not have one, you can set one up by following the steps here.
The easiest way to deploy this is to copy
/opt/ss/lib/python2.7/site-packages/fooappender_middleware/__init__.py on every Swift node running proxy services in your cluster. The
fooappender_middleware, and its content, should be owned by root.
To do this quickly, log in as root, and clone this repo:
# cd /opt/ss/lib/python2.7/site-packages && git clone https://github.com/swiftstack/fooappender_middleware.git
Enable custom middleware on your SwiftStack Controller
As root, login to the controller over ssh, become root, and execute the below if you have not already to enable the Custom Middleware feature:
# . /opt/ss/etc/profile.d/01-swiftstack-controller.sh # m feature add custom_middleware localadmin
Then, on your "Middleware" page, hit "Add Custom Middleware", and set
- name to "fooappender_middleware"
- config to the below:
paste.filter_factory = fooappender_middleware:my_filter_factory enforce_pattern = ^[^/]+/[^/]+_fooenforce/ bar = Bar
- The 'bar' variable alters the value set for your
enforce_patternvariable controls which object paths will modified by this middleware. The regex is tested against the full name of your object -
- With the example above, objects in any container whose name ends in
_fooenforcewill have the
foometadata keyval appended to them.
Save your changes. Then, add the middleware to the Swift middleware pipeline:
- Hit View Pipeline Placement.
- Drag the
fooappender_middlewaremiddleare to the end of the proxy pipeline;
- Click Save and Validate Pipeline;
- Hit Click here to deploy;
- Hit Deploy Config to Swift Nodes.
Once the config deploy has finished, restart the proxy processes:
- Clusters >
Your Cluster> Manage > Restart Proxy Services on Swift Nodes.
How do I use it once it's deployed?
First, create a container within your account such that "
Container" matches the
enforce_pattern config setting above.
If you've followed the above instuctions, this means you could create a container named
container_fooenforce within your account, for example.
Then, either PUT or POST an object within it.
All being well, you should find it has a user metadata value of
Bar appended to it without interaction on your part.
Iterating and fixing problems
The most common symptom of a problem is that you become unable to connect to the Swift API. This would occur, for example, if your middleware throws an exception on load.
To find the exception (and to fix it), log into your proxy as root and find the exception the proxy has (probably) thrown.
- On EL 7, do this with
- On Ubuntu (14), use instead
grep -ri '/opt/ss/bin/swift-init proxy-server reload' /var/log/ssnoded.log(as the ssnoded process will constantly attempt to restart the proxy for you here).
If the proxy service can load but you still want to inspect logging output, you can - on both the above platform - find output in
...which should hopefully be enough to help you find the problem and fix it.
Fix the exception in your
__init__.py, then restart the proxy service to try again.