Add support to reject changes from approvals

Formally "support for negative requirements"

This change adds support to reject a change from entering a pipeline
based off any existing approvals. This is useful to stop queuing any
changes with a negative vote.

Two new options are added:

reject:
  approval:
    - ...

To the pipelines, and:

reject-approval:
  - ...

To the triggers.

The approval format is the same for the "require approval" section.
Reject approvals could be considered a negative of the require section.

Change-Id: I3369920530e0b7439208b8fd43a9e75994860666
diff --git a/tests/fixtures/layout-requirement-reject-username.yaml b/tests/fixtures/layout-requirement-reject-username.yaml
new file mode 100644
index 0000000..9c71045
--- /dev/null
+++ b/tests/fixtures/layout-requirement-reject-username.yaml
@@ -0,0 +1,37 @@
+pipelines:
+  - name: pipeline
+    manager: IndependentPipelineManager
+    reject:
+      approval:
+        - username: 'jenkins'
+    trigger:
+      gerrit:
+        - event: comment-added
+    success:
+      gerrit:
+        verified: 1
+    failure:
+      gerrit:
+        verified: -1
+
+  - name: trigger
+    manager: IndependentPipelineManager
+    trigger:
+      gerrit:
+        - event: comment-added
+          reject-approval:
+            - username: 'jenkins'
+    success:
+      gerrit:
+        verified: 1
+    failure:
+      gerrit:
+        verified: -1
+
+projects:
+  - name: org/project1
+    pipeline:
+      - project1-pipeline
+  - name: org/project2
+    trigger:
+      - project2-trigger
\ No newline at end of file
diff --git a/tests/fixtures/layout-requirement-reject.yaml b/tests/fixtures/layout-requirement-reject.yaml
new file mode 100644
index 0000000..1f5d714
--- /dev/null
+++ b/tests/fixtures/layout-requirement-reject.yaml
@@ -0,0 +1,44 @@
+pipelines:
+  - name: pipeline
+    manager: IndependentPipelineManager
+    require:
+      approval:
+        - username: jenkins
+          verified: [1, 2]
+    reject:
+      approval:
+        - verified: [-1, -2]
+    trigger:
+      gerrit:
+        - event: comment-added
+    success:
+      gerrit:
+        verified: 1
+    failure:
+      gerrit:
+        verified: -1
+
+  - name: trigger
+    manager: IndependentPipelineManager
+    trigger:
+      gerrit:
+        - event: comment-added
+          require-approval:
+            - username: jenkins
+              verified: [1, 2]
+          reject-approval:
+            - verified: [-1, -2]
+    success:
+      gerrit:
+        verified: 1
+    failure:
+      gerrit:
+        verified: -1
+
+projects:
+  - name: org/project1
+    pipeline:
+      - project1-pipeline
+  - name: org/project2
+    trigger:
+      - project2-trigger
diff --git a/tests/fixtures/layouts/bad_reject.yaml b/tests/fixtures/layouts/bad_reject.yaml
new file mode 100644
index 0000000..b1e7f84
--- /dev/null
+++ b/tests/fixtures/layouts/bad_reject.yaml
@@ -0,0 +1,21 @@
+# Template is going to be called but missing a parameter
+
+pipelines:
+  - name: 'check'
+    manager: IndependentPipelineManager
+    require:
+      open: True
+      current-patchset: True
+      approval:
+        - verified: [1, 2]
+          username: jenkins
+        - workflow: 1
+    reject:
+      # Reject only takes 'approval', has no need for open etc..
+      open: True
+      approval:
+        - code-review: [-1, -2]
+          username: core-person
+    trigger:
+      gerrit:
+        - event: patchset-created
diff --git a/tests/fixtures/layouts/good_layout.yaml b/tests/fixtures/layouts/good_layout.yaml
index 9ba1806..3608d0c 100644
--- a/tests/fixtures/layouts/good_layout.yaml
+++ b/tests/fixtures/layouts/good_layout.yaml
@@ -4,9 +4,18 @@
 pipelines:
   - name: check
     manager: IndependentPipelineManager
+    require:
+      open: True
+      current-patchset: True
     trigger:
       gerrit:
         - event: patchset-created
+        - event: comment-added
+          require-approval:
+            - verified: [-1, -2]
+              username: jenkins
+          approval:
+            - workflow: 1
     success:
       gerrit:
         verified: 1
@@ -26,6 +35,16 @@
     manager: DependentPipelineManager
     success-message: Your change is awesome.
     failure-message: Build failed.  For information on how to proceed, see http://wiki.example.org/Test_Failures
+    require:
+      open: True
+      current-patchset: True
+      approval:
+        - verified: [1, 2]
+          username: jenkins
+        - workflow: 1
+    reject:
+      approval:
+        - code-review: [-1, -2]
     trigger:
       gerrit:
         - event: comment-added