Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure correct error message when have error decrypting parameter and also have keys that convert #5328

Merged
merged 12 commits into from
Sep 13, 2021
7 changes: 7 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ Changed

Contributed by @ericreeves.

Fixed
~~~~~

* Correct error reported when encrypted key value is reported, and another key value parameter that requires conversion is present. #5328
Contributed by @amanda11, Ammeon Solutions


3.5.0 - June 23, 2021
---------------------

Expand Down
1 change: 1 addition & 0 deletions st2api/st2api/controllers/v1/actionexecutions.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ def _schedule_execution(
liveaction=liveaction_db,
action_db=action_db,
runnertype_db=runnertype_db,
validate_params=False,
)

# By this point the execution is already in the DB therefore need to mark it failed.
Expand Down
49 changes: 49 additions & 0 deletions st2api/tests/unit/controllers/v1/test_executions.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,26 @@
"non_secret_param_2": {"type": "string", "required": True},
},
}
ACTION_DEFAULT_ENCRYPT_AND_BOOL = {
"name": "st2.dummy.default_encrypted_and_bool",
"description": "An action that uses a jinja template with decrypt_kv filter "
"in default parameter",
"enabled": True,
"pack": "starterpack",
"runner_type": "local-shell-cmd",
"parameters": {
"encrypted_param": {
"type": "string",
"default": "{{ st2kv.system.secret | decrypt_kv }}",
"secret": True,
},
"bool_param": {
"type": "boolean",
"default": "{{ st2kv.system.test_bool }}",
},
},
}


LIVE_ACTION_1 = {
"action": "sixpack.st2.dummy.action1",
Expand Down Expand Up @@ -298,6 +318,9 @@
LIVE_ACTION_DEFAULT_ENCRYPT = {
"action": "starterpack.st2.dummy.default_encrypted_value",
}
LIVE_ACTION_DEFAULT_ENCRYPT_AND_BOOL = {
"action": "starterpack.st2.dummy.default_encrypted_and_bool",
}
LIVE_ACTION_DEFAULT_ENCRYPT_SECRET_PARAM = {
"action": "starterpack.st2.dummy.default_encrypted_value_secret_param",
}
Expand Down Expand Up @@ -359,6 +382,10 @@ def setUpClass(cls):
post_resp = cls.app.post_json("/v1/actions", cls.action_decrypt)
cls.action_decrypt["id"] = post_resp.json["id"]

cls.action_decrypt_and_bool = copy.deepcopy(ACTION_DEFAULT_ENCRYPT_AND_BOOL)
post_resp = cls.app.post_json("/v1/actions", cls.action_decrypt_and_bool)
cls.action_decrypt_and_bool["id"] = post_resp.json["id"]

cls.action_decrypt_secret_param = copy.deepcopy(
ACTION_DEFAULT_ENCRYPT_SECRET_PARAMS
)
Expand Down Expand Up @@ -390,6 +417,8 @@ def tearDownClass(cls):
cls.app.delete("/v1/actions/%s" % cls.action_inquiry["id"])
cls.app.delete("/v1/actions/%s" % cls.action_template["id"])
cls.app.delete("/v1/actions/%s" % cls.action_decrypt["id"])
cls.app.delete("/v1/actions/%s" % cls.action_decrypt_secret_param["id"])
cls.app.delete("/v1/actions/%s" % cls.action_decrypt_and_bool["id"])
cls.app.delete(
"/v1/actions/%s" % cls.action_with_output_schema_secret_param["id"]
)
Expand Down Expand Up @@ -913,6 +942,26 @@ def test_template_param(self):
# was not rendered, and the provided parameter was used
self.assertEqual(post_resp.json["parameters"]["intparam"], live_int_param)

def test_template_encrypted_and_bool(self):
# register datastore values which are used in this test case
KeyValuePairAPI._setup_crypto()
register_items = [
{
"name": "test_bool",
"value": "true",
},
]
[KeyValuePair.add_or_update(KeyValuePairDB(**x)) for x in register_items]

post_resp = self._do_post(
LIVE_ACTION_DEFAULT_ENCRYPT_AND_BOOL, expect_errors=True
)
self.assertEqual(post_resp.status_int, 400)
self.assertEqual(
post_resp.json["faultstring"],
'Failed to render parameter "encrypted_param": Referenced datastore item "st2kv.system.secret" doesn\'t exist or it contains an empty string',
)

def test_template_encrypted_params(self):
# register datastore values which are used in this test case
KeyValuePairAPI._setup_crypto()
Expand Down
19 changes: 11 additions & 8 deletions st2common/st2common/services/action.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ def _get_immutable_params(parameters):
return [k for k, v in six.iteritems(parameters) if v.get("immutable", False)]


def create_request(liveaction, action_db=None, runnertype_db=None):
def create_request(
liveaction, action_db=None, runnertype_db=None, validate_params=True
):
"""
Create an action execution.

Expand Down Expand Up @@ -108,13 +110,14 @@ def create_request(liveaction, action_db=None, runnertype_db=None):
# Validate action parameters.
schema = util_schema.get_schema_for_action_parameters(action_db, runnertype_db)
validator = util_schema.get_validator()
util_schema.validate(
liveaction.parameters,
schema,
validator,
use_default=True,
allow_default_none=True,
)
if validate_params:
util_schema.validate(
liveaction.parameters,
schema,
validator,
use_default=True,
allow_default_none=True,
)

# validate that no immutable params are being overriden. Although possible to
# ignore the override it is safer to inform the user to avoid surprises.
Expand Down
21 changes: 21 additions & 0 deletions st2common/tests/unit/services/test_action.py
Original file line number Diff line number Diff line change
Expand Up @@ -624,3 +624,24 @@ def test_root_liveaction(self):
child, expected_root = self._create_nested_executions(depth=i)
actual_root = action_service.get_root_liveaction(child)
self.assertEqual(expected_root["id"], actual_root["id"])

def test_invalid_json_request_validate(self):
parameters = {"hosts": "127.0.0.1", "cmd": "uname -a", "arg_default_value": 123}
liveaction = LiveActionDB(action=ACTION_REF, parameters=parameters)

self.assertRaises(
jsonschema.ValidationError,
action_service.create_request,
liveaction,
)

def test_invalid_json_request_skipvalidate(self):
parameters = {"hosts": "127.0.0.1", "cmd": "uname -a", "arg_default_value": 123}
liveaction = LiveActionDB(action=ACTION_REF, parameters=parameters)

self.assertRaises(
jsonschema.ValidationError,
action_service.create_request,
liveaction,
False,
)