Add helper functions for client API

The Razor::View module provides Sinatra helper functions to render database
objects as hashes, which can then be returned to the client as JSON.

Each returned hash can be thought of as an extension of a basic 'object' class,
which has the following three fields:

    - 'id': a URL that uniquely identifies the object
    - 'spec': a URL that identifies the type of the object
    - 'name': a human-readable name for the object

Different types of objects may specify other properties by defining additional
key-value pairs.

This extended-map format allows clients to consume the API without knowing a
priori either the types of objects to be listed, or how to build URLs for the
listed objects.
Create CLI client

This is a command-line client for Razor that uses the public API to retrieve
(and eventually control) a Razor server.

Because the client interacts only through the public API, it requires only a
basic Ruby environment and the rest-client gem. This allows the client to be
used remotely as well as locally, and avoids the performance penalty
associated with loading the entire Razor codebase.

The client takes a RESTful navigation approach to object retrieval, where each
command-line argument is interpreted as a further reference to retrieve. For
example, invoking `./bin/razor tags 27` will first load the /api endpoint, then
find the object with an 'id' value 'tags'. For each further argument, it will
attempt to find an object with a matching 'id' (or 'obj_id' in the case of
reference objects) field. When the last document is retrieved, it is formatted
and printed to the terminal.
Move `rule` from Tag to nested matcher object

Moving the `rule` field from Razor::Data::Tag to a nested Razor::Matcher object
will allow matchers to be validated independent of their host tags.
Add static rule validation to Razor::Matcher

This adds a #valid? method to matcher instances which ensures that their rule
matches the expected [operator, arg0, ..., argN] format. It ensures that each
operator is recognized, that the types of arg0-N can be handled by the operator
(after substitution), and that the top-level expression returns a boolean.

Though Ruby will happily evaluate `1 or 'fish'` and `'seven' and 4`, these make
no sense in terms of the boolean values that matchers are supposed to emit.
By defining explicitly the types of values returned by each operator, and what
values the operator is capable of processing, such travesties of logic can be
avoided. `and` and `or` are labeled as accepting and emitting only boolean
values, and so `["and", 1, "fish"]` and `["or", 'seven', 4] are correctly
recognized as invalid rules.

One side effect is that it is not possible to directly treat the output of the
"fact" operator as a boolean even if it is known to be so. Take, for example,
the rule `["fact", "is_virtual"]`. The logically equivalent and valid
expression would be `["eq", ["fact", "is_virtual"], true]`.
This is, admittedly, a little more verbose, but necessary for this sort of
static type evaluation.
Add error messages with Razor::Matcher#validate

This is mostly so people don't start pulling their hair out upon finding that
something like '["=" ["fatc" "f1"] 5]' is invalid. Instead of simply finding
that validation has failed, one can now call Matcher#errors to get a list of
error messages; in this case, the message would be something like

    "uses unrecognized operator 'fatc';
    recognized operators are [...]"

The messages are meant to follow the Sequel::Model::Validations format for
the field :matcher, though it makes some of the wording awkward.
No functional change - whitespace cleanup
* Gemfile.lock: update various gems to latest version
Razor::View#view_object_url: use object name in URL, compute collection name
Images: return correct reference from create_new_image; list/show images
Installers: return correct reference from create_installer; show installer query
Razor::Data::Tag::find_or_create_with_rule: idempotent find/create

This method will be used by create_tag and create_policy
create_tag command and very light testing
Rename Policy.sort_order to line_number and constrain it more

Calling it line_number will hopefully make it more intuitive that policies
are evaluated in ascending order (and it's what the old Razor called it,
too)

Also, insist that line_number is non-NULL and unique
Validate that named installer exists when saving policy

This is much weaker than a fk constraint, but better than no check at all
Revamp how hostname etc. in nodes gets set

The hostname_pattern for a policy is now assumed to produce fully-qualified
names (including domain)

The node now stores its own hostname, which is populated at the time when
the node is first bound to a policy; calling 'hostname' on a node that is
not bound is now legal, and will return nil.

The data model ensures that bound nodes always have a non-null hostname and
root_assword
Change interpolation of id into hostnames

The policy's hostname_pattern can now contain a '${id}' (rather than '%n')
to put the node's id into the hostname. This change is mostly there to
leave us some room to make other data available for use in
hostname_patterns - the '${expr}' syntax will just be more amenable to that
than the '%special' would be.
Command to create a new policy
Implement `broker_paths` in the config object

This roughly mirrors the `installer_paths` feature, but has better testing and
edge case behaviour implemented.  Also includes extra bonus testing.

Signed-off-by: Daniel Pittman <daniel@rimspace.net>
Lift common behaviour around path handling in config object

The installer and broker paths share similar behaviours; this lifts the
commonality into a single function and invokes it from both.

Signed-off-by: Daniel Pittman <daniel@rimspace.net>
Implement the "broker" abstraction for filesystem broker content

This adds a Razor::Broker class that wraps the filesystem based broker
content: configuration data, installation scripts and templates, and other
parts of the on-disk component are managed from this class.

This is not the "broker" referenced from a policy; that is an "instantiation"
of these brokers into the database -- still to be written -- that turns the
configuration data into a record of the chosen configuration, and otherwise
ties in with the rest of the running configuration.

Signed-off-by: Daniel Pittman <daniel@rimspace.net>