feat(submit): require explicit confirmation for all prepare_submit_job params
Remove defaults from queue, executor_memory, executor_cores, num_executors, and app_name in prepare_submit_job. All must now be explicitly confirmed by the caller. Also add extra_args to the PendingSubmission snapshot so users can confirm non-conf spark-submit flags (e.g. --jars, --py-files) at prepare time; confirm_submit_job passes them through to build_spark_submit_command. This is an intentional breaking change to the MCP tool contract: callers can no longer rely on implicit defaults.
This commit is contained in:
@@ -86,7 +86,15 @@ def test_prepare_submit_job_works_via_body(tmp_path):
|
||||
script.write_text("print('hi')\n")
|
||||
r = c.post(
|
||||
"/prepare_submit_job",
|
||||
json={"connection": "prod", "script_path": str(script), "queue": "research"},
|
||||
json={
|
||||
"connection": "prod",
|
||||
"script_path": str(script),
|
||||
"queue": "research",
|
||||
"executor_memory": "4G",
|
||||
"executor_cores": 2,
|
||||
"num_executors": 2,
|
||||
"app_name": "test-app",
|
||||
},
|
||||
)
|
||||
assert r.status_code == 200, r.text
|
||||
body = r.json()
|
||||
@@ -102,7 +110,15 @@ def test_prepare_rejects_nonexistent_script_path_with_400():
|
||||
c.post("/save_connection", json={"name": "prod", "master": "yarn"})
|
||||
r = c.post(
|
||||
"/prepare_submit_job",
|
||||
json={"connection": "prod", "script_path": "/nope/does_not_exist.py"},
|
||||
json={
|
||||
"connection": "prod",
|
||||
"script_path": "/nope/does_not_exist.py",
|
||||
"queue": "default",
|
||||
"executor_memory": "4G",
|
||||
"executor_cores": 2,
|
||||
"num_executors": 2,
|
||||
"app_name": "test-app",
|
||||
},
|
||||
)
|
||||
assert r.status_code == 400
|
||||
detail = r.json()["detail"]
|
||||
@@ -121,7 +137,15 @@ def test_prepare_rejects_sql_policy_violation_with_400(tmp_path):
|
||||
bad_script.write_text('spark.sql("DROP TABLE users")\n')
|
||||
r = c.post(
|
||||
"/prepare_submit_job",
|
||||
json={"connection": "prod", "script_path": str(bad_script)},
|
||||
json={
|
||||
"connection": "prod",
|
||||
"script_path": str(bad_script),
|
||||
"queue": "default",
|
||||
"executor_memory": "4G",
|
||||
"executor_cores": 2,
|
||||
"num_executors": 2,
|
||||
"app_name": "test-app",
|
||||
},
|
||||
)
|
||||
assert r.status_code == 400
|
||||
detail = r.json()["detail"]
|
||||
@@ -199,7 +223,15 @@ def test_list_and_get_pending_job_roundtrip_via_body(tmp_path):
|
||||
script.write_text("print('hi')\n")
|
||||
prep = c.post(
|
||||
"/prepare_submit_job",
|
||||
json={"connection": "prod", "script_path": str(script)},
|
||||
json={
|
||||
"connection": "prod",
|
||||
"script_path": str(script),
|
||||
"queue": "default",
|
||||
"executor_memory": "4G",
|
||||
"executor_cores": 2,
|
||||
"num_executors": 2,
|
||||
"app_name": "test-app",
|
||||
},
|
||||
).json()
|
||||
pid = prep["pending_id"]
|
||||
|
||||
@@ -261,7 +293,15 @@ def test_unknown_connection_in_prepare_returns_404():
|
||||
c = TestClient(app)
|
||||
r = c.post(
|
||||
"/prepare_submit_job",
|
||||
json={"connection": "nope", "script_path": "/tmp/x.py"},
|
||||
json={
|
||||
"connection": "nope",
|
||||
"script_path": "/tmp/x.py",
|
||||
"queue": "default",
|
||||
"executor_memory": "4G",
|
||||
"executor_cores": 2,
|
||||
"num_executors": 2,
|
||||
"app_name": "test-app",
|
||||
},
|
||||
)
|
||||
assert r.status_code == 404
|
||||
assert "nope" in r.json()["detail"]
|
||||
@@ -275,7 +315,15 @@ def test_confirm_non_pending_returns_400(tmp_path):
|
||||
script.write_text("print('hi')\n")
|
||||
prep = c.post(
|
||||
"/prepare_submit_job",
|
||||
json={"connection": "prod", "script_path": str(script)},
|
||||
json={
|
||||
"connection": "prod",
|
||||
"script_path": str(script),
|
||||
"queue": "default",
|
||||
"executor_memory": "4G",
|
||||
"executor_cores": 2,
|
||||
"num_executors": 2,
|
||||
"app_name": "test-app",
|
||||
},
|
||||
).json()
|
||||
pid = prep["pending_id"]
|
||||
c.post("/cancel_pending_job", json={"pending_id": pid})
|
||||
@@ -292,7 +340,15 @@ def test_cancel_already_submitted_returns_400(tmp_path):
|
||||
script.write_text("print('hi')\n")
|
||||
prep = c.post(
|
||||
"/prepare_submit_job",
|
||||
json={"connection": "prod", "script_path": str(script)},
|
||||
json={
|
||||
"connection": "prod",
|
||||
"script_path": str(script),
|
||||
"queue": "default",
|
||||
"executor_memory": "4G",
|
||||
"executor_cores": 2,
|
||||
"num_executors": 2,
|
||||
"app_name": "test-app",
|
||||
},
|
||||
).json()
|
||||
pid = prep["pending_id"]
|
||||
# Simulate a SUBMITTED state by mutating the pending directly
|
||||
|
||||
Reference in New Issue
Block a user