diff --git a/deckhand/engine/document_validation.py b/deckhand/engine/document_validation.py index 2247d0db..fb0f876b 100644 --- a/deckhand/engine/document_validation.py +++ b/deckhand/engine/document_validation.py @@ -81,7 +81,7 @@ class BaseValidator(object): __slots__ = ('_schema_map') - _supported_versions = ('v1',) + _supported_versions = _SUPPORTED_SCHEMA_VERSIONS _schema_re = re.compile(r'^[a-zA-Z]+\/[a-zA-Z]+\/v\d+$') def __init__(self): diff --git a/deckhand/tests/functional/gabbits/resources/sample-schema-v2.yaml b/deckhand/tests/functional/gabbits/resources/sample-schema-v2.yaml new file mode 100644 index 00000000..4a092035 --- /dev/null +++ b/deckhand/tests/functional/gabbits/resources/sample-schema-v2.yaml @@ -0,0 +1,20 @@ +--- +schema: deckhand/DataSchema/v1 +metadata: + schema: metadata/Control/v1 + name: example/Doc/v2 +data: + $schema: http://json-schema.org/schema# + type: object + properties: + a: + type: string + b: + type: integer + minimum: 0 + maximum: 100 + required: + - a + - b + additionalProperties: false +... diff --git a/deckhand/tests/functional/gabbits/schema-validation/schema-validation-success-v2.yaml b/deckhand/tests/functional/gabbits/schema-validation/schema-validation-success-v2.yaml new file mode 100644 index 00000000..cc7d6f2a --- /dev/null +++ b/deckhand/tests/functional/gabbits/schema-validation/schema-validation-success-v2.yaml @@ -0,0 +1,214 @@ +# Test success path for rollback with a single bucket. +# +# 1. Purges existing data to ensure test isolation +# 2. Creates a v2 DataSchema +# 3. Checks that schema validation for the DataSchema passes +# 4. Puts a valid document (and LayeringPolicy) +# 5. Checks that the document passes schema pre-validation +# 6. Checks that the document passes schema post-validation +# 7. Puts an invalid document +# 8. Checks that the document fails schema pre-validation +# 9. Checks that the document fails schema post-validation by raising expected +# exception +# 10. Checks that the document entry details adhere to expected validation +# format +# 11. Re-puts the same invalid document with substitutions +# 12. Verify that the substitutions were sanitized in the validation output + +defaults: + request_headers: + content-type: application/x-yaml + response_headers: + content-type: application/x-yaml + verbose: true + +tests: + - name: purge + desc: Begin testing from known state. + DELETE: /api/v1.0/revisions + status: 204 + response_headers: null + + - name: create_schema + desc: Add example schema + PUT: /api/v1.0/buckets/mop/documents + status: 200 + data: <@resources/sample-schema-v2.yaml + + - name: verify_schema_is_valid + desc: Check schema validation of the added schema + GET: /api/v1.0/revisions/$HISTORY['create_schema'].$RESPONSE['$.[0].status.revision']/validations/deckhand-schema-validation + status: 200 + response_multidoc_jsonpaths: + $.`len`: 1 + $.[0].count: 1 + $.[0].results[0].id: 0 + $.[0].results[0].status: success + + - name: verify_schema_validation_in_list_view + desc: Check schema validation success shows in list view + GET: /api/v1.0/revisions/$HISTORY['create_schema'].$RESPONSE['$.[0].status.revision']/validations + status: 200 + response_multidoc_jsonpaths: + $.`len`: 1 + $.[0].count: 1 + $.[0].results[0].name: deckhand-schema-validation + $.[0].results[0].status: success + + - name: add_valid_document + desc: Add a document that follows the schema + PUT: /api/v1.0/buckets/good/documents + status: 200 + data: |- + --- + schema: deckhand/LayeringPolicy/v1 + metadata: + schema: metadata/Control/v1 + name: layering-policy + data: + layerOrder: + - site + --- + schema: example/Doc/v2 + metadata: + schema: metadata/Document/v1 + name: good + storagePolicy: cleartext + layeringDefinition: + abstract: false + layer: site + data: + a: this-one-is-required + b: 77 + + - name: verify_document_is_valid_pre_validation + desc: Check schema pre-validation of the added document + GET: /api/v1.0/revisions/$HISTORY['add_valid_document'].$RESPONSE['$.[0].status.revision']/validations/deckhand-schema-validation + status: 200 + response_multidoc_jsonpaths: + $.`len`: 1 + $.[0].count: 2 + $.[0].results[0].id: 0 + $.[0].results[0].status: success + + - name: verify_document_pre_validation_success_in_list_view + desc: Check document pre-validation success shows in list view + GET: /api/v1.0/revisions/$HISTORY['add_valid_document'].$RESPONSE['$.[0].status.revision']/validations + status: 200 + response_multidoc_jsonpaths: + $.`len`: 1 + $.[0].count: 1 + $.[0].results[*].name: deckhand-schema-validation + $.[0].results[*].status: success + + - name: verify_document_is_valid_post_validation + desc: Check that the document passes post-validation + GET: /api/v1.0/revisions/$HISTORY['add_valid_document'].$RESPONSE['$.[0].status.revision']/rendered-documents + status: 200 + + - name: add_invalid_document + desc: Add a document that does not follow the schema + PUT: /api/v1.0/buckets/bad/documents + status: 200 + data: |- + schema: example/Doc/v2 + metadata: + schema: metadata/Document/v1 + name: bad + storagePolicy: cleartext + layeringDefinition: + abstract: false + layer: site + data: + a: this-one-is-required-and-can-be-different + b: 177 + + - name: verify_invalid_document_is_valid_pre_validation + desc: Check success of schema pre-validation of the added document + GET: /api/v1.0/revisions/$HISTORY['add_invalid_document'].$RESPONSE['$.[0].status.revision']/validations/deckhand-schema-validation + status: 200 + response_multidoc_jsonpaths: + $.`len`: 1 + $.[0].count: 1 + $.[0].results[*].status: success + + - name: verify_document_pre_validation_failure_in_list_view + desc: Check document pre-validation success shows in list view + GET: /api/v1.0/revisions/$HISTORY['add_invalid_document'].$RESPONSE['$.[0].status.revision']/validations + status: 200 + response_multidoc_jsonpaths: + $.`len`: 1 + $.[0].count: 1 + $.[0].results[0].name: deckhand-schema-validation + $.[0].results[0].status: success + + - name: verify_document_is_invalid_post_validation + desc: Check that the document fails post-validation + GET: /api/v1.0/revisions/$HISTORY['add_invalid_document'].$RESPONSE['$.[0].status.revision']/rendered-documents + status: 400 + response_multidoc_jsonpaths: + $.`len`: 1 + $.[0].apiVersion: v1.0 + $.[0].code: 400 Bad Request + $.[0].details.errorCount: 1 + $.[0].details.errorType: InvalidDocumentFormat + $.[0].details.messageList[0].documents: + - layer: site + name: bad + schema: example/Doc/v2 + $.[0].details.messageList[0].error: true + $.[0].details.messageList[0].kind: ValidationMessage + $.[0].details.messageList[0].level: Error + $.[0].details.messageList[0].name: D002 + $.[0].kind: Status + $.[0].message: The provided documents failed schema validation + $.[0].reason: Validation + $.[0].status: Failure + + - name: add_invalid_document_with_substitutions + desc: Add a document that does not follow the schema + PUT: /api/v1.0/buckets/bad/documents + status: 200 + data: |- + --- + schema: example/Doc/v2 + metadata: + schema: metadata/Document/v1 + name: bad + storagePolicy: cleartext + layeringDefinition: + abstract: false + layer: site + substitutions: + - src: + schema: deckhand/Certificate/v1 + name: test-certificate + path: . + dest: + path: .a + data: + a: this-one-is-required-and-can-be-different + b: 177 + --- + schema: deckhand/Certificate/v1 + metadata: + name: test-certificate + schema: metadata/Document/v1 + storagePolicy: cleartext + layeringDefinition: + layer: site + storagePolicy: cleartext + data: this-should-definitely-be-sanitized + + - name: verify_document_post_validation_failure_entry_details_hides_secrets + desc: Check document validation failure hides secrets + GET: /api/v1.0/revisions/$HISTORY['add_invalid_document_with_substitutions'].$RESPONSE['$.[0].status.revision']/rendered-documents + status: 400 + response_multidoc_jsonpaths: + $.`len`: 1 + $.[0].code: 400 Bad Request + $.[0].details.errorCount: 1 + $.[0].details.errorType: InvalidDocumentFormat + $.[0].details.messageList[0].diagnostic.error_section: + a: 'Sanitized to avoid exposing secret.' + b: 177