Fix intermittent test failure due to content ordering

One of the IPMI tests would very occasionally fail because the order of data
was not what was expected.  This was a situation I considered theoretical,
rather than practical, when the test was first written -- and the order does
not matter, just the unordered set of values.

This updates the test to use an order-insensitive comparison, ensuring it will
always pass regardless of random chance altering the order.

https://tickets.puppetlabs.com/browse/RAZOR-177

Signed-off-by: Daniel Pittman <daniel@rimspace.net>
Make `json_name_from_ruby` available in Object

We regularly need to present the user with a name for something they
submitted, for type checking and so forth.  Since this is so common, and
happens in so many places, it seems reasonable to have a single central method
to expose this translation capability to the world.

By design this should take everything -- classes, and instances -- and return
the correct string for the user.  Returned strings are not translated, since
these are technical terms, not internal jargon.

https://tickets.puppetlabs.com/browse/RAZOR-118

Signed-off-by: Daniel Pittman <daniel@rimspace.net>
Initial command validation DSL and implementation

This adds a DSL for command validation, along with an implementation covering
the most basic validation needs.  This is obviously incomplete, but serves to
replace a number of current command validations.

https://tickets.puppetlabs.com/browse/RAZOR-118

Signed-off-by: Daniel Pittman <daniel@rimspace.net>
Realize node name in the database

We previously had a fairly universal concept of a node "name" through the
code, but it was only constructed in the application logic, not in
the database.

This means that various database level operations were simply impossible when
using the name, and that a complex set of deconstructions had to be used
through the codebase to deal with this.

Now, we simply have the column in the database, and use it.  This fixes that
non-uniform API, a win alone, but also paves the way for a future when users
can assign more meaningful names to nodes without violating the expectations
of the overall system.

https://tickets.puppetlabs.com/browse/RAZOR-118

Signed-off-by: Daniel Pittman <daniel@rimspace.net>
Use object reference validation for node reinstall commands

This moves to using the validation DSL to pre-check the node is a valid
reference when we issue a node-reinstall command.  That avoids the need to
handle it in the code specifically.

This also changes the return code from 202 to 404 if you issue the command
against a node that does not exist, which seems reasonable as that is
ultimately a user intent failure: we can't do what they wanted, and they
presumably expected *something* to be reinstalled when they issued
the command.

https://tickets.puppetlabs.com/browse/RAZOR-118

Signed-off-by: Daniel Pittman <daniel@rimspace.net>
Add validation for the IPMI credential command

This adds validation, along with the additional validation feature that some
attributes may cause others to be required, but only if they are present.

https://tickets.puppetlabs.com/browse/RAZOR-118

Signed-off-by: Daniel Pittman <daniel@rimspace.net>
Validate more commands, and add "value in set" operation

In order to validate the "set desired power state" value for a node, we need
to restrict the value to a small subset of legal values.  This implements that
check in the validator, and then applies that to the problem at hand.

https://tickets.puppetlabs.com/browse/RAZOR-118

Signed-off-by: Daniel Pittman <daniel@rimspace.net>
Validate `create-task`, adding nested object support

In order to handle the `create-task` command several features were added to
the validation language: nested object support, and the ability to define
additional attributes based on patterns when the set are not knowable ahead
of time.

https://tickets.puppetlabs.com/browse/RAZOR-118

Signed-off-by: Daniel Pittman <daniel@rimspace.net>
Validate `create-tag` command

This adds validation for the `create-tag` command.  This simply uses the
existing tooling, adding nothing, in a pleasant break.

https://tickets.puppetlabs.com/browse/RAZOR-118

Signed-off-by: Daniel Pittman <daniel@rimspace.net>
Validate `delete-tag`, adding boolean attribute support

In order to validate the `delete-tag` we need support for boolean attributes;
since Ruby splits into TrueClass and FalseClass, rather than a unified Boolean
class, we add the `type: :bool` tag to attribute checks, and restructure the
code to handle this additional special case a little better.

Then, implement `delete-tag` validation using this new capability.

https://tickets.puppetlabs.com/browse/RAZOR-118

Signed-off-by: Daniel Pittman <daniel@rimspace.net>
Validate `update_tag_rule` command.

https://tickets.puppetlabs.com/browse/RAZOR-118

Signed-off-by: Daniel Pittman <daniel@rimspace.net>
Validate `create-broker`, and make `references` mode liberal

This adds validation for the `create-broker` command.  Unlike previous
commands, this one has a field that references an object that is not stored in
the database, the BrokerType.

Supporting that made for two new features required in the validation code:
 * use a duck-type interface to check if the object exists
 * support different "search key" and "attribute name" in references

Finally, since we needed a unified interface for everything that we reference,
this updates the BrokerType `find` method to follow the same conventions as
the Sequel::Model classes.  That eliminates various special case code, and
lets us treat them polymorphicly.

https://tickets.puppetlabs.com/browse/RAZOR-118

Signed-off-by: Daniel Pittman <daniel@rimspace.net>
Validate `create-policy`, and add array attribute validation

This is a large change, because array attribute validation behaves somewhat
differently to hash attribute validation, resulting in the final split between
the two.

This was necessary to implement validation of the `create-policy` command,
which uses an array of nested objects.  Now that is done, we should have all
the major features required for validation in place.

https://tickets.puppetlabs.com/browse/RAZOR-118

Signed-off-by: Daniel Pittman <daniel@rimspace.net>
Report, and abort, spec tests if migrations are not current

Every time we ship a new migration, everyone gets the excitement of debugging
some random failure like "no such method name on BlahBlah".  While that is
fun, and brings some zest to the development process, it isn't really
that efficient.

Instead, we can detect the situation where migrations are behind (or ahead of)
the current state on disk, and report a nice, clear error message to the
person trying to run the tests.

This should reduce developer headaches without any particular problem for
anyone else.

Signed-off-by: Daniel Pittman <daniel@rimspace.net>
Schema and model class for the command log

The command log will allow us to both store an audit trail of commands
issues against the server and use those commands to report status and
errors of background jobs connected to specific commands.
Add logic for creating (starting) and finishing commands
No functional change - remove trailing whitespace
Have all commands add an entry to the command log

Any successfully submitted command will now create an entry in the command
log, and the command specs check for that. For now, all commands will
pretend to be synchronous, and report a status of 'finished' when the
corresponding request ends.
Update command status for background tasks

For ISO import, we thread a command object through to the message
processor, tkaing care to pass it along to each stage of the import
process. The import process then updates the status of the command, in
particular marks it as 'running' as soon as it starts working on it, and
marks it as 'finished' when the last step of the import saga is done.

Most of the error reporting is done by our message processor - that is
crude, and better ways to report errors from within the actual processing
is the main reason why we try to pass the command to each stage of the
saga.

We can't demand that all background tasks have a command associated with
it: changing node metadata and tag rules spawn background jobs in
Node.around_save and Tag.around_save, where they do not have access to a
command object, nor does it seem desirable from the user's POV to treat
them as async commands - or should we ? Might actually be nice for the user
to know that the system's state has settled after doing e.g. a change to a
tag. Though can we always assume that every background process is directly
connected to a command ?

The way the command is threaded through all over the place is a bit clumsy;
an alternative would be to have the messaging plugin define a 'command'
method that returns the command associated with the operation if there is
one, and methods that are called during async processing can access it that
way to e.g. report errors or update the status