Skip to content

Commit

Permalink
[Function] Fix ensure_function_has_auth_set to enrich function even…
Browse files Browse the repository at this point in the history
… if no access key was set but passed in auth info (#3140)
  • Loading branch information
Tankilevitch committed Feb 22, 2023
1 parent 06aed77 commit 748d377
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 13 deletions.
27 changes: 26 additions & 1 deletion mlrun/api/api/utils.py
Expand Up @@ -229,6 +229,15 @@ def apply_enrichment_and_validation_on_function(
ensure_function_security_context(function, auth_info)


def ensure_function_auth_and_sensitive_data_is_masked(
function,
auth_info: mlrun.api.schemas.AuthInfo,
allow_empty_access_key: bool = False,
):
ensure_function_has_auth_set(function, auth_info, allow_empty_access_key)
mask_function_sensitive_data(function, auth_info)


def mask_function_sensitive_data(function, auth_info: mlrun.api.schemas.AuthInfo):
if not mlrun.runtimes.RuntimeKinds.is_local_runtime(function.kind):
_mask_v3io_access_key_env_var(function, auth_info)
Expand Down Expand Up @@ -417,7 +426,16 @@ def _mask_v3io_access_key_env_var(
)


def ensure_function_has_auth_set(function, auth_info: mlrun.api.schemas.AuthInfo):
def ensure_function_has_auth_set(
function: mlrun.runtimes.BaseRuntime,
auth_info: mlrun.api.schemas.AuthInfo,
allow_empty_access_key: bool = False,
):
"""
:param function: Function object.
:param auth_info: The auth info of the request.
:param allow_empty_access_key: Whether to raise an error if access key wasn't set or requested to get generated
"""
if (
not mlrun.runtimes.RuntimeKinds.is_local_runtime(function.kind)
and mlrun.api.utils.auth.verifier.AuthVerifier().is_jobs_auth_required()
Expand All @@ -438,10 +456,17 @@ def ensure_function_has_auth_set(function, auth_info: mlrun.api.schemas.AuthInfo
]

function.metadata.credentials.access_key = auth_info.access_key

if not function.metadata.credentials.access_key:
if allow_empty_access_key:
# skip further enrichment as we allow empty access key
return

raise mlrun.errors.MLRunInvalidArgumentError(
"Function access key must be set (function.metadata.credentials.access_key)"
)

# after access key was passed or enriched with the condition above, we mask it with creating auth secret
if not function.metadata.credentials.access_key.startswith(
mlrun.model.Credentials.secret_reference_prefix
):
Expand Down
16 changes: 6 additions & 10 deletions mlrun/api/crud/functions.py
Expand Up @@ -44,16 +44,12 @@ def store_function(
function_obj = mlrun.new_function(
name=name, project=project, runtime=function, tag=tag
)
# only need to ensure auth and sensitive data is masked
mlrun.api.api.utils.apply_enrichment_and_validation_on_function(
function_obj,
auth_info,
ensure_auth=True,
mask_sensitive_data=True,
# below is not needed as part of storing the function but rather validated when running the function
perform_auto_mount=False,
validate_service_account=False,
ensure_security_context=False,
# not raising exception if no access key was provided as the store of the function can be part of
# intermediate steps or temporary objects which might not be executed at any phase and therefore we don't
# want to enrich if user didn't requested.
# (The way user will request to generate is by passing $generate in the metadata.credentials.access_key)
mlrun.api.api.utils.ensure_function_auth_and_sensitive_data_is_masked(
function_obj, auth_info, allow_empty_access_key=True
)
function = function_obj.to_dict()

Expand Down
2 changes: 2 additions & 0 deletions mlrun/model.py
Expand Up @@ -789,6 +789,7 @@ def __init__(
last_update=None,
iterations=None,
ui_url=None,
reason: str = None,
):
self.state = state or "created"
self.status_text = status_text
Expand All @@ -801,6 +802,7 @@ def __init__(
self.last_update = last_update
self.iterations = iterations
self.ui_url = ui_url
self.reason = reason


class RunTemplate(ModelObj):
Expand Down
4 changes: 2 additions & 2 deletions mlrun/runtimes/base.py
Expand Up @@ -1670,8 +1670,8 @@ def _ensure_run_not_stuck_on_non_terminal_state(
)
run.setdefault("status", {})["state"] = RunStates.error
run.setdefault("status", {})[
"status_text"
] = "A runtime resource related to this tun could not be found"
"reason"
] = "A runtime resource related to this run could not be found"
run.setdefault("status", {})["last_update"] = now.isoformat()
db.store_run(db_session, run, run_uid, project)

Expand Down
15 changes: 15 additions & 0 deletions tests/system/runtimes/test_kubejob.py
Expand Up @@ -68,6 +68,21 @@ def test_deploy_function_without_image_with_requirements(self):
assert function.spec.image == expected_spec_image
function.run()

def test_store_function_is_not_failing_if_generate_access_key_not_requested(self):
code_path = str(self.assets_path / "kubejob_function.py")
function_name = "simple-function"
function = mlrun.code_to_function(
name=function_name,
kind="job",
project=self.project_name,
filename=code_path,
)
hash_key = function.save(versioned=True)
function = mlrun.get_run_db().get_function(
function_name, project=self.project_name, tag="latest", hash_key=hash_key
)
assert not function["metadata"]["credentials"]["access_key"]

def test_store_function_after_run_local_verify_credentials_are_masked(self):
code_path = str(self.assets_path / "kubejob_function.py")
function_name = "simple-function"
Expand Down

0 comments on commit 748d377

Please sign in to comment.