Add a command to modify node hw_info data

If users need to move, e.g., a network card from one system to another, they
need to tell Razor that that is happening. To facilitate this, we need a
command that lets users selectively remove, add, or modify entries in the
nodes hw_info table.

This implements that, as a single atomic "set hw_info to" operation.  In cases
where partial change is desired, this can be implemented by modifying the data
read from the server -- since there is, in essence, only administrative change
performed to this data, we have no significant edit conflict risk.

https://tickets.puppetlabs.com/browse/RAZOR-69
Signed-off-by: Daniel Pittman <daniel@rimspace.net>
Documentation: Updating API.md and `create-task`
Documentation: Matcher has `upper` and `lower`
Fix create-policy validation

Repo and broker were required in the database but not in the command's validation. This rectifies that by fixing the command's validation.
Add alias `tag` for `tags` in `create-policy`

To allow more flexibility for the client, `tag` is being added as an alias for `tags`.

Fixes https://tickets.puppetlabs.com/browse/RAZOR-198
Add Razor::Conflict error for reporting command logical conflicts

This introduces the Razor::Conflict error, internally, which is then used to
report logical conflicts in commands.  This, alone, does nothing, but enables
us to correctly handle the `create-repo` case where logical conflicts
are possible.

https://tickets.puppetlabs.com/browse/RAZOR-185
Signed-off-by: Daniel Pittman <daniel@rimspace.net>
Migrate all object creation to a new API

The semantics offered by the Sequel ORM are fairly traditional: object
creation or searching is possible, but it will simply raise an error when
items that violate unique constraints are found.

We want to move beyond that, to a world where creation is idempotent: if the
object logically exists in the database, but is identical to what you
requested, then we should treat this as a success rather than an error.

This moves all the object creation to a new API, "import", on our data
objects.  This allows us to add the semantics without overriding the core
behaviour of the Sequel ORM.

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

Signed-off-by: Daniel Pittman <daniel@rimspace.net>
create-* commands should return different status if already exists

This updates the create-* commands to handle duplicates more nicely: if the
requested object is identical to the current object, it will simply return
success to the caller, since their desired state was achieved.

If any fields conflict between the two, however, this will raise the new
conflict error code, and report a 409 error along with detail of which fields
are mismatched between the two.

Identical is defined as "any publicly visible fields have equal values", which
includes "the value of being absent" on both sides -- that is, you can't add
an optional field to an existing object and have a match.

https://tickets.puppetlabs.com/browse/RAZOR-185
Signed-off-by: Daniel Pittman <daniel@rimspace.net>
Add shared example specs for required attributes

It is a common case when testing commands that there is a list of minimum required attributes in the database validation which can differ from the command validation. This adds shared examples which can programmatically test that the minimum case works, then that removing any one attribute fails.

Note that this will not catch cases where the command validation is stronger than the database validation.
Fix inconsistencies in commands for required attributes

This fixes the standardization of commands. This includes using 'hw-info' instead of 'hw_info' in several commands, although the old style will be conformed for backwards compatibility. The relevant spec tests are also updated to use the standard for checking required attributes.
Update specs to check required attributes

This updates the rest of the spec tests to use the standard way of checking required attributes.

Fixes https://tickets.puppetlabs.com/browse/RAZOR-221
Include server version number in API

Fixes https://tickets.puppetlabs.com/browse/RAZOR-217
Use short form for references

Since documentation is now derived from the validation framework, it makes sense that our internal representation should match the user's ideal representation. When a command needs an attribute to reference an existing object, the code previously used a long form (`{"name": "value"}`) rather than the shortcut form (`"value"`). This corrects the internal representation without affecting the external.

One side effect of this change is that `create-policy` will no longer create tags as a side effect.

Fixes https://tickets.puppetlabs.com/browse/RAZOR-246
Check references when verifying duplicate creation

When issuing the same `create-policy` command twice in a row, the code currently reports that several fields — including all fields that reference other objects — do not match. This fixes that by generating a new object that will be used in the comparison.

Fixes https://tickets.puppetlabs.com/browse/RAZOR-248
(maint) Remove unused files and dirs under ext during packaging

Currently, razor debian builds are failing because rmdir is called
on ext during the dh_install in the debian/rules, but ext still has
contents. This commit adds a line to remove the files that are still in
ext and the directories that are still in ext to allow the rmdir to
succeed cleanly.

The failures look like this:

```
rmdir ext		# should be emptied by now
rmdir: failed to remove 'ext': Directory not empty
make[1]: *** [override_dh_auto_install] Error 1
```
Fake Queue matcher: do not raise an exception when checking an empty queue

When the queue is empty and a test calls have_published, the test would
fail (as it should) but with a confusing error message about nil not having
a map method.

This change makes sure that we properly complain about the missing publish
in the test failure
Make sure update-tag-rule retags all affected nodes

This issue was cause by two cooperating bugs:

  1. In Razor::Data::Tag#around_save we used 'or' instead of '||' in
  setting need_eval_nodes which would be false if the rule for a
  preexisting tag was changed, and therefore eval_nodes would never be
  called. Ultimately, this is because 'a = false or true' sets a to
  false. Go Ruby.

  2. The spec test always caused an 'eval_nodes' message to be published
  when it created the tag it was testing with. We now clean out the queue
  after the tag is created to make sure we only succeed if the operations
  in the test cause a message to be published

Issue: https://tickets.puppetlabs.com/browse/RAZOR-250
* Rakefile: use razor-admin instead of duplicating code

Make rake tasks a shim around razor-admin commands for the things that
razor-admin can do. The code duplication between the two led to endless
problems where only one place was being updated.
Provide expected argument datatype for commands

In order for the client to know how to format data for arbitrary commands, the server needs to provide this information. This includes the expected JSON datatype as interpreted from the validation framework.

Included in this commit is the change to only support one datatype per attribute. If other datatypes are desired, they can be supported via the `conform!` method. `update-node-metadata` and `modify-node-metadata` have been updated to accept both `_` and `-` in their arguments that previously only accepted the non-standard `_`.

Fixes https://tickets.puppetlabs.com/browse/RAZOR-216
Make sure that nodes with nil facts/metadata/state do not case an internal error

When a node had nil facts/metadata/state, the matcher could fail by trying
to call nil.[] in value_lookup; this change makes sure that doesn't happen,
and that evaluating ("fact" "foo") against a node with nil facts actually
raises a RuleEvaluationError

This change also adds some light testing for Tag#match? as that is the main
user of matchers

Issue: https://tickets.puppetlabs.com/browse/RAZOR-254 (partial fix)