Commit Graph

22 Commits

Author SHA1 Message Date
Sergiy Markin ac4edb0c64 [focal] Deckhand project updates
- adjusted .gitignore to keep fresh egg-info and omit build artifacts
- fresh egg-info data is needed for promenade that depends on Deckhand
- restored deckhand-functional-uwsgi-py38 gate
- restored deckhand-integration-uwsgi-py38 gate
- made deckhand-airskiff-deployment gate voting ( treasuremap project
  has been updated)
- removed bionic gates
- updated focal dockerfile
- added more binary deps into bindep.txt
- updated deckhand chart values to latest images - focal and wallaby
- fixed python code to compy with CVE's found by fresh version of bandit
- implemented pip freeze approach
- added tox -e freeze profile to manage it
- requirements-frozen.txt is now main file with requirements
- requirements-direct.txt is the file to control deps
- updated setup.cfg to adjust to newer version of setuptools
- fixed airskiff-deploy gate
- fixed docker-image-build playbook to restore Quay repo image publish
- updated other playbooks to include roles from zuul/base-jobs in order
  to setup build hosts properly
- removed workaround with hardcoded dns resolver ip 10.96.0.10 as it
  became obsolette due to recent fix in openstack-helm-infra
- adjusted tools/whitespace-linter.sh script
- tox.ini has been brought to compliance with tox4 requirements
- replaced str() calls with six.text_type() according to D325 Deckhand specific
  commandment from Hacking.rst
- locked python-barbicanclient version with 5.2.0 because of breaking
  changes in the upper versions

Change-Id: I1cd3c97e83569c4db7e958b3400bdd4b7ea5e668
2023-04-20 19:39:43 +00:00
Wahlstedt, Walter (ww229g) 70aa35a396 update to focal and python 3.8
update dockerfile for python deckhand install
add deckhand version to chart 1.0
add chart version 0.2.0
update all packages to latest in requirements.txt
update zuul jobs for focal and python 3.8
remove zuul job functional-uwsgi-py38 in favor of functional-docker-py38
update tox config
typecast to string in re.sub() function
add stestr to test-requirements.txt
add SQLAlchemy jsonpickle sphinx-rtd-theme stestr to requirements.txt
deprecated function: BarbicanException -> BarbicanClientException
fix mock import using unittest
fix import collections to collections.abc
fix for collections modules for older than python 3.10 versions.
deprecated function: json -> to_json
deprecated function:  werkzeug.contrib.profiler ->
    werkzeug.middleware.profiler
deprecated function: falcon.AIP -> falcon.App
deprecation warning: switch from resp.body to resp.text
rename fixtures to dh_fixtures because there is an imported module
    fixtures
switch from stream.read to bounded_stream.read
deprecated function: falcon process_response needed additional parameter
deprecated function: falcon default_exception_handler changed parameter
    order
move from MagicMock object to falcon test generated object to fix
    incompatability with upgraded Falcon module.
Adjust gabbi tests to fix incompatability with upgraded DeepDiff module
update Makefile to execute ubuntu_focal
update HTK (helmtoolkit)
unpin barbican to pass integration tests
Use helm 3 in chart build.
    `helm serve` is removed in helm 3 so this moves
    to using local `file://` dependencies [0] instead.

Change-Id: I180416f480edea1b8968d80c993b3e1fcc95c08d
2023-02-24 10:51:57 -05:00
Phil Sphicas 5cd799cc5d Allow source substring extraction
When performing substitutions, there are occasions when the source value
does not exactly match the format required by the destination document
(e.g. the values.yaml structure of an Armada chart).

This change provides the ability extract a substring of the source
value, and substitute that into the destination document.

Two optional fields are added to `src` under `metadata.substitutions`:

  * `pattern`: a regular expression, with optional capture groups
  * `match_group`: the number of the desired capture group

The canonical use case is a chart that requires an image with the repo
name and tag in separate fields, while the substitution source has the
full image path as a single value.

For example, assuming that the source document "software-versions" has:

    data:
      images:
        hello: docker.io/library/hello-world:latest

Then the following set of substitutions would put the repo and tag in
the applicable values in the destination document:

    metadata:
      substitutions:
        - src:
            schema: pegleg/SoftwareVersions/v1
            name: software-versions
            path: .images.hello
            pattern: '^(.*):(.*)'
            match_group: 1
          dest:
            path: .values.images.hello.repo
        - src:
            schema: pegleg/SoftwareVersions/v1
            name: software-versions
            path: .images.hello
            pattern: '^(.*):(.*)'
            match_group: 2
          dest:
            path: .values.images.hello.tag
    data:
      values:
        images:
          hello:
            repo:  # docker.io/library/hello-world
            tag:   # latest

Change-Id: I2fcb0d2b8e2fe3d85479ac2bad0b7b90f434eb77
2022-01-18 13:04:25 -08:00
Doug Aaser 2786769de5 Fix encrypted doc rendering
This patchset fixes a bug where Deckhand was failing to perform
substitution and layering on document sets where all the documents had a
storagePolicy of encrypted. Deckhand would attempt to substitute from an
encrypted source document, but when that document marked as encrypted,
it fails because the source doc had been redacted. The behavior now goes
as follows:

- Resolve Barbican references before layering and substitution have been
  performed so that the prior two operations don't attempt to operate on a
  Barbican reference
- After substitution, redact the destination document if it is marked as
  encrypted
- Now, after substition, we can redact the rest of the documents and
  substitutions

Change-Id: I725775d554c9eed2692fc6203c416a7119646680
2019-10-04 16:33:46 +00:00
Zuul 56e606bf4b Merge "fix: Redact secondhand substitutions of sensitive data" 2018-10-29 17:13:25 +00:00
Felipe Monteiro 9d91a072cd docs: Use sphinx-apidoc library for autodoc compatibility
This package is used for generation autodoc documentation
automatically which can be linked to by Deckhand
documentation from other places. This is to make autodoc
generation work in RTD.

More info: https://pypi.org/project/sphinxcontrib-apidoc/

Change-Id: I43aac82728e5935a5a2626f2fd29d7a7188d19f9
2018-10-27 22:52:39 +01:00
Felipe Monteiro 47ade1f0da fix: Redact secondhand substitutions of sensitive data
This patch set ensures that documents that substitute data from
encrypted document sources are themselves redacted, assuming that
cleartext-secrets=true. Note that this redaction fix only applies
to the substitution dest/src paths. The data section is already
being correctly redacted for secondhand sources.

Change-Id: I6ce16a109628259b2cc8132cd9db63261b5dbace
2018-10-25 09:39:50 -04:00
anthony.bellino 7defe473d2 Redact rendered Documents
- Uses the rendered-documents endpoint
- Adds a query parameter ?cleartext-secrets
- Adds unit tests, updates integration tests

Change-Id: I02423b9bf7456008d707b3cd91edc4fc281fa5fc
2018-10-24 22:42:25 -04:00
Aaron Sheffield 349e5600df Redacts Raw Documents
- If a document has a storage policy of encrypted
 - Redacts (sha256) the data section.
 - Redacts (sha256) the substition paths.
- Uses the same /documents endpoint, adds a new query parameter
  ?cleartext-secrets=true to show the non-redacted values.

Change-Id: I42808901b97c667a1148c00fbb7717a0847c9981
2018-10-19 23:56:12 -05:00
Felipe Monteiro c9d71a6509 substitution: Recursive pattern replacement
Patterns may now be replaced recursively. This can be
achieved by using specifying a ``pattern`` value and
``recurse`` (with a required ``depth`` argument).

Example:

    substitutions:
      - dest:
          path: .
          pattern: REGEX
          recurse:
            depth: -1
        src:
          schema: deckhand/Passphrase/v1
          name: example-password
          path: .

NOTE:

  Recursive selection of patterns will only consider
  matching patterns. Non-matching patterns will be ignored.
  Thus, even if recursion can "pass over" non-matching patterns,
  they will be silently ignored.

This is useful for reducing the number of substitution
stanzas that are required for the purposes of performing
all the string pattern replacements that are required.
Best practice is to limit the scope of the recursion
as much as possible: e.g. avoid passing in "$" as the
``jsonpath``, but rather a JSON path that lives closer
to the nested strings in question.

Included in this patch set:

* recursive implementation for pattern replacement
* unit tests for most scenarios and edge cases
* docstring updates
* documentation updates
* schema updates for validation

Change-Id: I85048349097ed696667fae80f1180808d264bbcf
2018-09-12 09:24:46 -06:00
Felipe Monteiro 59836a0e64 [fix] Substitution source documents accidentally modified
This resolves a regression introduced in [0] which was causing
substitution source documents to become modified while performing
substitution into destination documents. A unit test has been
included to prevent the regression.

[0] 1583b78902

Change-Id: I737b8688cfea54dc6b14d8ca243fb43f8363dcaf
2018-09-04 21:58:45 +01:00
Felipe Monteiro 2acbff8d57 refactor: Clean up jsonpath_replace method
This patch set cleans up jsonpath_replace method to increase
its readability. Currently, there is some weird legacy code in
there which doesn't make much sense and is most likely dead code.
In fact, before this change, there was no unit test for validating
that `MissingDocumentPattern` is raised correctly.

The `jsonpath_replace` is refactored to only call the inner
private function _do_replace once, after performing data
expansion (populating the data dictionary with nonexistent
nested keys).

Unit tests have been added to validate the exception above.

Change-Id: I1c18c4f8c79c1b9d3124747f8aa04743f27434eb
2018-08-18 00:30:45 +01:00
Felipe Monteiro cd2d3020ec refactor: Use yaml.add_representer to reduce complexity
This patchset uses yaml.add_representer for DocumentDict
which enables yaml.safe_load/safe_load_all to correctly
serialize the DocumentDict object without a recursive
routine.

This also completely removes the usage of jsonpath_parse
from DocumentDict as jsonpath-ng is a rather expensive
library to call continuously; and even though Deckhand
does some caching to alleviate this, it is simply better
to avoid it altogether in a wrapper that is used everywhere
across the engine module, which does all the heavy processing.

This also reduces the amount of wrapping using DocumentDict
because the better way to do this in the DB module is to
have a helper function retrieve the data from the DB and
immediately wrap it in a DocumentDict if applicable;
this is left as an exercise for later.

Change-Id: I715ff7e314cf0ec0d34c17f3378514d235dfb377
2018-07-10 19:23:52 +01:00
Felipe Monteiro d55ee9fb6e Add better caching to jsonpath-ng wrapper functions
This patchset uses beaker (used by Promenade and Drydock) to
achieve better caching around jsonpath-ng wrapper functions
(jsonpath_replace and jsonpath_parse).

Change-Id: Ifae24775b4741ade7673dc91776c35d2de5b9065
2018-07-03 02:07:27 +00:00
Felipe Monteiro 177675e96f [fix] Parent substitution/layering before replacement
Currently it doesn't seem document replacement works
exactly as expected: The parent-replacement document
can receive layering and substitution data prior to
being replaced. Currently, Deckhand does not account
for this scenario.

A child-replacement depends on its parent-replacement
the same way any child depends on its parent: so that the
child layers with its parent only after the parent has
received all layering and substitution data. But other
documents that depend on the parent-replacement actually
depend on the child-replacement instead as the
child-replacement replaces its parent. So the dependency
chain is: PR -> CR -> anything that layers with PR.

A unit and functional test have been added for regression.

Co-Authored-By: Felipe Monteiro <felipe.monteiro@att.com>
Change-Id: I353393f416aa6e441d84add9ebedcd152944d7e8
2018-05-14 19:31:57 -04:00
Felipe Monteiro 97578a933f [fix gate] Fix pep8 errors
Fix failing pep8 errors which were never being flagged but now are,
possibly due to changes in flake8 rules. This patchset corrects
the following errors:

./deckhand/engine/layering.py:567:21: W503 line break before binary operator
./deckhand/engine/secrets_manager.py:406:33: W503 line break before binary operator
./deckhand/engine/utils.py:33:17: W503 line break before binary operator
./deckhand/common/utils.py:292:17: W503 line break before binary operator

Change-Id: Ic26aecb6b8049e138a826af9953f45298e817795
2018-05-09 02:14:08 +01:00
Felipe Monteiro a5bb91bc76 [fix] Handles quotes in JSON path for substitution
This is to fix a use case where a subpath like 'filter:authtoken' in
a JSON path like ".values.conf.paste.'filter:authtoken'.password" fails
because the resulting Python object that is created in memory
for substitution constructs a dict key like "'filter:authtoken'" resulting
in Deckhand failing to index into the dict as the key needs to be
stripped of start and end quotes that are only necessary for achieving
valid YAML syntax.

A unit test is added for regression.

Change-Id: I19974efc977b0cdc5793e649fa068d1a3bd7339e
2018-04-27 01:38:56 +00:00
Felipe Monteiro 106038d3cd [fix] Pass secret URI instead of UUID to barbican get_secret
This is to change passing the secret URI instead of the secret
UUID to barbican's get secret endpoint from which the secret
itself can be extracted.

While the API [0] expects a UUID the CLI instead expects a URI
and the latter extracts the UUID from the URI automatically [1].

API ref:

GET /v1/secrets/{uuid}
Headers:
    Accept: application/json
    X-Auth-Token: {token}
    (or X-Project-Id: {project_id})

CLI ref:

$  barbican help secret get
usage: barbican secret get [-h] [-f {shell,table,value}] [-c COLUMN]
                           [--max-width <integer>] [--prefix PREFIX]
                           [--decrypt] [--payload]
                           [--payload_content_type PAYLOAD_CONTENT_TYPE]
                           URI

Retrieve a secret by providing its URI.

Finally, this adds logic for ensuring that all encrypted data is retrieved
and injected back into the raw documents with Barbican references, during
document rendering. Currently, this process is only performed for
documents with substitutions, but should also be carried out for encrypted
documents themselves.

[0] https://docs.openstack.org/barbican/latest/api/reference/secrets.html#get-v1-secrets-uuid
[1] https://docs.openstack.org/python-barbicanclient/latest/reference/index.html#barbicanclient.v1.secrets.SecretManager.get

Change-Id: I1717592b7acdedb66353c25fb5dcda2d5330196b
2018-04-11 17:33:58 -04:00
Scott Hussey 4d90257372 [Fix] Multidigit array index
- Allow array index in substitution destinations to have
  multiple digits

Change-Id: I8ef6241763dd7d841e25774fa041f7f4a3b11c7b
2018-04-05 16:56:30 -05:00
Bryan Strassner c50501cc89 [fix] Updates to use cached jsonpath
Layering code was not using a parse cache for jsonpath
This change adds use of the cache around all calls to jsonpath_ng.parse

Change-Id: I800eb397badf19ed2ea47b88fa7c91e4a09225ef
2018-04-02 16:30:06 -05:00
Felipe Monteiro a5f75722dc Log all document data following any layering action failure
This is to log out all document data following any layering action
failure. This consists of two stages:

1) Scrubbing all primitives contained in the data sections of both
   the child and parent being layered together.
2) Logging scrubbed-out data sections for both documents, in addition
   to their names, schemas, and the layering action itself.

This will hopefully provide DEs with enough information about why
a layering action may have failed to apply while at the same time
preventing any secret data from being logged out.

Change-Id: I3fedd259bba7b930c7969e9c30d1fffef5bf77bd
2018-03-29 10:10:03 -04:00
Felipe Monteiro 1264e5af6c Document replacement: Update Document unique constraint
This updates the unique constraint for Document model from
schema/metadata.name to schema/metadata.name/layer which is
a pre-requisite for document replacement implementation.

The remainder fo the changes are taken of in child PS
(particulary those related to the layering module):
https://review.gerrithub.io/#/c/403888/

Change-Id: Icc4f4960b3a3951f649c7886dbe0bce77341a9f7
2018-03-28 17:08:03 -04:00