airbyte-internal-ops 0.4.2__py3-none-any.whl → 0.5.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {airbyte_internal_ops-0.4.2.dist-info → airbyte_internal_ops-0.5.0.dist-info}/METADATA +1 -1
- {airbyte_internal_ops-0.4.2.dist-info → airbyte_internal_ops-0.5.0.dist-info}/RECORD +13 -52
- airbyte_ops_mcp/cli/cloud.py +27 -0
- airbyte_ops_mcp/cloud_admin/api_client.py +473 -0
- airbyte_ops_mcp/cloud_admin/models.py +56 -0
- airbyte_ops_mcp/mcp/cloud_connector_versions.py +460 -0
- airbyte_ops_mcp/mcp/prerelease.py +5 -44
- airbyte_ops_mcp/regression_tests/ci_output.py +8 -4
- airbyte_ops_mcp/regression_tests/http_metrics.py +21 -2
- airbyte_ops_mcp/regression_tests/models.py +6 -0
- airbyte_ops_mcp/telemetry.py +162 -0
- airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/.gitignore +0 -1
- airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/README.md +0 -420
- airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/__init__.py +0 -2
- airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/commons/__init__.py +0 -1
- airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/commons/backends/__init__.py +0 -8
- airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/commons/backends/base_backend.py +0 -16
- airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/commons/backends/duckdb_backend.py +0 -87
- airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/commons/backends/file_backend.py +0 -165
- airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/commons/connection_objects_retrieval.py +0 -377
- airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/commons/connector_runner.py +0 -247
- airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/commons/errors.py +0 -7
- airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/commons/evaluation_modes.py +0 -25
- airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/commons/hacks.py +0 -23
- airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/commons/json_schema_helper.py +0 -384
- airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/commons/mitm_addons.py +0 -37
- airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/commons/models.py +0 -595
- airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/commons/proxy.py +0 -207
- airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/commons/secret_access.py +0 -47
- airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/commons/segment_tracking.py +0 -45
- airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/commons/utils.py +0 -214
- airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/conftest.py.disabled +0 -751
- airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/consts.py +0 -4
- airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/poetry.lock +0 -4480
- airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/pytest.ini +0 -9
- airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/regression_tests/__init__.py +0 -1
- airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/regression_tests/test_check.py +0 -61
- airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/regression_tests/test_discover.py +0 -117
- airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/regression_tests/test_read.py +0 -627
- airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/regression_tests/test_spec.py +0 -43
- airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/report.py +0 -542
- airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/stash_keys.py +0 -38
- airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/templates/__init__.py +0 -0
- airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/templates/private_details.html.j2 +0 -305
- airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/templates/report.html.j2 +0 -515
- airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/utils.py +0 -187
- airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/validation_tests/__init__.py +0 -0
- airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/validation_tests/test_check.py +0 -61
- airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/validation_tests/test_discover.py +0 -217
- airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/validation_tests/test_read.py +0 -177
- airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/validation_tests/test_spec.py +0 -631
- {airbyte_internal_ops-0.4.2.dist-info → airbyte_internal_ops-0.5.0.dist-info}/WHEEL +0 -0
- {airbyte_internal_ops-0.4.2.dist-info → airbyte_internal_ops-0.5.0.dist-info}/entry_points.txt +0 -0
|
@@ -5,6 +5,7 @@ airbyte_ops_mcp/gcp_auth.py,sha256=i0cm1_xX4fj_31iKlfARpNvTaSr85iGTSw9KMf4f4MU,7
|
|
|
5
5
|
airbyte_ops_mcp/github_actions.py,sha256=FSi_tjS9TbwRVp8dwlDZhFOi7lJXEZQLhPm2KpcjNlY,7022
|
|
6
6
|
airbyte_ops_mcp/github_api.py,sha256=ezpMR1vjqQ-1f5yOLBVbxW70OPtUferl1uA0u_gUVo8,12733
|
|
7
7
|
airbyte_ops_mcp/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
+
airbyte_ops_mcp/telemetry.py,sha256=GUQX-oD6besFl-kAyycci1HCk1jov_JFwUAqKVN0yKE,5230
|
|
8
9
|
airbyte_ops_mcp/_legacy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
10
|
airbyte_ops_mcp/_legacy/airbyte_ci/README.md,sha256=qEYx4geDR8AEDjrcA303h7Nol-CMDLojxUyiGzQprM8,236
|
|
10
11
|
airbyte_ops_mcp/_legacy/airbyte_ci/connector_erd_generator/README.md,sha256=wRQ9tSkf__riq8wTht2IKt_jPK1bW0v10dDo5tSsbZM,842
|
|
@@ -22,46 +23,6 @@ airbyte_ops_mcp/_legacy/airbyte_ci/connector_insights/pylint.py,sha256=jnQJTA-cq
|
|
|
22
23
|
airbyte_ops_mcp/_legacy/airbyte_ci/connector_insights/result_backends.py,sha256=Y02Q0d4_dQPzmFs_hk12MlqAhPHWEG5kyKbQjC-Ry28,4058
|
|
23
24
|
airbyte_ops_mcp/_legacy/airbyte_ci/connector_insights/utils.py,sha256=gYnmJMJM5LlFjNvKyU8FCxQd8LbTgDhs3IYsARohQlE,3189
|
|
24
25
|
airbyte_ops_mcp/_legacy/airbyte_ci/connector_insights/pylint_plugins/cdk_deprecation_checkers.py,sha256=M31bV-BRnkNuUOD80S9sJs9Q3NnrwVRBNlVQwvGdyKY,2677
|
|
25
|
-
airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/.gitignore,sha256=hezODgoJG1gosD6k_mLf3vy3dGxbM5LrsgCS7c5ZUn4,27
|
|
26
|
-
airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/README.md,sha256=RbzoUEUCkrF50pAOJ-COqOWCjpGyApdJbctfh7UoIsM,15299
|
|
27
|
-
airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/__init__.py,sha256=STIY57jAIPRSp9m2aYFzaQD4MsNFPphaVilP1tQ6y60,58
|
|
28
|
-
airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/conftest.py.disabled,sha256=fbHkaY_lRalFD5VW9EgeTinNYtLarAKRZOIQ_qVneqg,28169
|
|
29
|
-
airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/consts.py,sha256=wZaZSAcLl3eSASrpqR_45n9n1ss4aqk5FL1MOxeIYQI,120
|
|
30
|
-
airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/poetry.lock,sha256=7ePhtVKe_fi3W3VUUe5NyOCALuKYalSQy0hq4qX99ls,362992
|
|
31
|
-
airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/pytest.ini,sha256=bIqTl-q7al042Y_3CbKa2feUgsPrxdvAOH6aQTK95s4,314
|
|
32
|
-
airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/report.py,sha256=UE_uLvRD-NXa0hO_QpaIaTXwgLdyXjkOW4P-Ys8iXAE,21908
|
|
33
|
-
airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/stash_keys.py,sha256=VdBX4c9T7VcWGrKolm-UsxLck0gaaKt9vI63cg9sh7k,1667
|
|
34
|
-
airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/utils.py,sha256=8j6V4WE6NRdjxNr9EJFW_e-2I8byn2pVywmbxhYaFgM,6433
|
|
35
|
-
airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/commons/__init__.py,sha256=G8L2E8OSuhpnMnK0HMO9iDiZF6Hb8iubfV6FJ-40Dm8,57
|
|
36
|
-
airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/commons/connection_objects_retrieval.py,sha256=Oo3sCc6gdfwDwaKHZAc_HkXxrviFre144gPzkkQuANg,15776
|
|
37
|
-
airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/commons/connector_runner.py,sha256=TlQlmCP3P_svxkTmEZqaYW438EvFh4CWvP7JnHLcPPw,9896
|
|
38
|
-
airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/commons/errors.py,sha256=i0G3BKwTstHWL5rTWsUepKqjPWYTwbIk3sR56EJSKGw,196
|
|
39
|
-
airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/commons/evaluation_modes.py,sha256=VE_9VBL9oyCHe98E3PrMriSkAFGyWbJ9dAuWTGFbd2o,870
|
|
40
|
-
airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/commons/hacks.py,sha256=oIwDL_wGNjp5ZDby5RAb0CPLCObB6kqZ0hFVzvG5Wc4,1009
|
|
41
|
-
airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/commons/json_schema_helper.py,sha256=9ecYGiryX4M759Y-BAQ73oGiVYb7migBPEgGlSCeAeE,13325
|
|
42
|
-
airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/commons/mitm_addons.py,sha256=9IlIJ7886bsi0_nvyoRDS8OQ9Ob3y9tBEstfhtdlBT4,1302
|
|
43
|
-
airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/commons/models.py,sha256=IxRPkBnk0Aqn1EatH68OdV9HHbdYMUAG48_0Dd2CBf8,21604
|
|
44
|
-
airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/commons/proxy.py,sha256=qDl0Xv3kt-RRSTDI5747905qkSZXW4WnWOgY1jI_2Z4,9035
|
|
45
|
-
airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/commons/secret_access.py,sha256=e-Ypy721XLosqBh6BBw3i9kHVnZ1SzhUvwRJz7R1wtc,1647
|
|
46
|
-
airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/commons/segment_tracking.py,sha256=SS-ZLkNlJpJMjCZo7KBBMnUqW88zz4uXxBqlzGKA7sw,1274
|
|
47
|
-
airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/commons/utils.py,sha256=x35pbCfAlsfSQfZ78zwtXQhNCba-YZCzoCVtQ3TDCz8,7801
|
|
48
|
-
airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/commons/backends/__init__.py,sha256=igpz_JxLRYJTXWuM5G2yr8mCkoWXjJir2ywxbeaCHgc,270
|
|
49
|
-
airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/commons/backends/base_backend.py,sha256=vnrWioE7UY2WI7zyBJ5hNvgI3SlxIAtk6JPP3HxPUX4,454
|
|
50
|
-
airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/commons/backends/duckdb_backend.py,sha256=hWvzauicoI3JgtOGVbfeai4GhJZ_exW0JQyeVqf7C3M,3420
|
|
51
|
-
airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/commons/backends/file_backend.py,sha256=yWoedpDnLgI8b9lNU8Ei4bdfkNfGXH0qULxYo4W7Ijo,6551
|
|
52
|
-
airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/regression_tests/__init__.py,sha256=G8L2E8OSuhpnMnK0HMO9iDiZF6Hb8iubfV6FJ-40Dm8,57
|
|
53
|
-
airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/regression_tests/test_check.py,sha256=Dg8VKP6GIxoA2LWWS6qfCN9J4JxmnnagqxUuvZt1Urw,2129
|
|
54
|
-
airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/regression_tests/test_discover.py,sha256=pHAlNOOt9dkbNFFzeuJDPQOfGu-YnRj0BkC5_LzCGRc,4063
|
|
55
|
-
airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/regression_tests/test_read.py,sha256=iyMPkLIEJ9PiqlJqxHegzXbwirgUMFqnPMLIN_8L9Qw,26750
|
|
56
|
-
airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/regression_tests/test_spec.py,sha256=6pkDPTUNE14YZKJoGzuYERzfRFk42jLuxoNIDVcJM04,1485
|
|
57
|
-
airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
58
|
-
airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/templates/private_details.html.j2,sha256=vwU1Y_mEF7AHqZOdnAZOKpDLOguNST4JJ9FG8WTPBHo,9078
|
|
59
|
-
airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/templates/report.html.j2,sha256=ZdMJ7YDoDa9sbpIBCI6HfrD6KHsXJX7SotLfj_DmqMY,20131
|
|
60
|
-
airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/validation_tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
61
|
-
airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/validation_tests/test_check.py,sha256=1opKdmFiB-tDyelXTwFtef0ByhKN2FSCS2NXBrdsxHk,1733
|
|
62
|
-
airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/validation_tests/test_discover.py,sha256=SpiA9DU1pAQAKsNs7ccyUo2nLyZLAT02S0OatnvlmwE,8024
|
|
63
|
-
airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/validation_tests/test_read.py,sha256=U3XSVB8uwYzirrDk4r3VIA1vN96E05JGtrTA0moe8gI,6773
|
|
64
|
-
airbyte_ops_mcp/_legacy/airbyte_ci/connector_live_tests/validation_tests/test_spec.py,sha256=_PuwluCueXxDzE95tUWa1PyjQ_60Oo2KtDWMT3S8rpQ,26397
|
|
65
26
|
airbyte_ops_mcp/_legacy/airbyte_ci/connector_ops/README.md,sha256=bkrbgjGvnbuUBgDWaQ6f-WF7p3h3Ft3lZAMR1LLTMm4,1317
|
|
66
27
|
airbyte_ops_mcp/_legacy/airbyte_ci/connector_ops/__init__.py,sha256=4Hw-PX1-VgESLF16cDdvuYCzGJtHntThLF4qIiULWeo,61
|
|
67
28
|
airbyte_ops_mcp/_legacy/airbyte_ci/connector_ops/utils.py,sha256=yZsrdj2Jv-6rb97recNncZCkmY79EqpPiZOMUOf8ke4,28573
|
|
@@ -353,15 +314,15 @@ airbyte_ops_mcp/cli/__init__.py,sha256=XpL7FyVfgabfBF2JR7u7NwJ2krlYqjd_OwLcWf-Xc
|
|
|
353
314
|
airbyte_ops_mcp/cli/_base.py,sha256=I8tWnyQf0ks4r3J8N8h-5GZxyn37T-55KsbuHnxYlcg,415
|
|
354
315
|
airbyte_ops_mcp/cli/_shared.py,sha256=jg-xMyGzTCGPqKd8VTfE_3kGPIyO_3Kx5sQbG4rPc0Y,1311
|
|
355
316
|
airbyte_ops_mcp/cli/app.py,sha256=SEdBpqFUG2O8zGV5ifwptxrLGFph_dLr66-MX9d69gQ,789
|
|
356
|
-
airbyte_ops_mcp/cli/cloud.py,sha256=
|
|
317
|
+
airbyte_ops_mcp/cli/cloud.py,sha256=b5oiu2oNXJXA3AcjpBcOKf1t84Tc5seSNsSwYhK0oI8,45587
|
|
357
318
|
airbyte_ops_mcp/cli/gh.py,sha256=koJPu0MDB6AW7mJq2z4dZV65ofvsZTkqoeitGF8KJR8,5364
|
|
358
319
|
airbyte_ops_mcp/cli/registry.py,sha256=L4nDKhlegr31gSE-GUvDFSq10KgDz5kJuZXgLIxYIyg,9785
|
|
359
320
|
airbyte_ops_mcp/cli/repo.py,sha256=G1hoQpH0XYhUH3FFOsia9xabGB0LP9o3XcwBuqvFVo0,16331
|
|
360
321
|
airbyte_ops_mcp/cloud_admin/__init__.py,sha256=cqE96Q10Kp6elhH9DAi6TVsIwSUy3sooDLLrxTaktGk,816
|
|
361
|
-
airbyte_ops_mcp/cloud_admin/api_client.py,sha256=
|
|
322
|
+
airbyte_ops_mcp/cloud_admin/api_client.py,sha256=vFklWFQECau0oLor-ngW6pgkhH5np9x9yaPCUxgix_Q,56701
|
|
362
323
|
airbyte_ops_mcp/cloud_admin/auth.py,sha256=qE2Aqe0qbZB755KscL65s54Jz78-F-X5a8fXKsrYEOQ,3749
|
|
363
324
|
airbyte_ops_mcp/cloud_admin/connection_config.py,sha256=9opGQer-cGMJANmm-LFLMwvMCNu3nzxa2n2XHkZj9Fw,4899
|
|
364
|
-
airbyte_ops_mcp/cloud_admin/models.py,sha256=
|
|
325
|
+
airbyte_ops_mcp/cloud_admin/models.py,sha256=yldPAL9Lce83U3JN-f6qPc2X5LPnLCYqgnXrM1DRq98,4799
|
|
365
326
|
airbyte_ops_mcp/connection_config_retriever/__init__.py,sha256=Xoi-YvARrNPhECdpwEDDkdwEpnvj8zuUlwULpf4iRrU,800
|
|
366
327
|
airbyte_ops_mcp/connection_config_retriever/audit_logging.py,sha256=QdOG9984NXeMaKeJnFUZ4oCOmqi37PBRG2NRBBjrZQQ,2753
|
|
367
328
|
airbyte_ops_mcp/connection_config_retriever/retrieval.py,sha256=s6yeCyrboWkUd6KdaheEo87x-rLtQNTL8XeR8O9z2HI,12160
|
|
@@ -372,14 +333,14 @@ airbyte_ops_mcp/mcp/__init__.py,sha256=QqkNkxzdXlg-W03urBAQ3zmtOKFPf35rXgO9ceUjp
|
|
|
372
333
|
airbyte_ops_mcp/mcp/_guidance.py,sha256=48tQSnDnxqXtyGJxxgjz0ZiI814o_7Fj7f6R8jpQ7so,2375
|
|
373
334
|
airbyte_ops_mcp/mcp/_http_headers.py,sha256=9TAH2RYhFR3z2JugW4Q3WrrqJIdaCzAbyA1GhtQ_EMM,7278
|
|
374
335
|
airbyte_ops_mcp/mcp/_mcp_utils.py,sha256=WNwcGzF7XGKZNAYRt0Uhj5BkRfmwqnFABCrk77OZjRw,11512
|
|
375
|
-
airbyte_ops_mcp/mcp/cloud_connector_versions.py,sha256=
|
|
336
|
+
airbyte_ops_mcp/mcp/cloud_connector_versions.py,sha256=M_dA1YuZkEw-K8xiE1NSqKAP_CvXGo0_Ewv-Y2oc_wQ,33105
|
|
376
337
|
airbyte_ops_mcp/mcp/connector_analysis.py,sha256=OC4KrOSkMkKPkOisWnSv96BDDE5TQYHq-Jxa2vtjJpo,298
|
|
377
338
|
airbyte_ops_mcp/mcp/connector_qa.py,sha256=aImpqdnqBPDrz10BS0owsV4kuIU2XdalzgbaGZsbOL0,258
|
|
378
339
|
airbyte_ops_mcp/mcp/gcp_logs.py,sha256=IPtq4098_LN1Cgeba4jATO1iYFFFpL2-aRO0pGcOdzs,2689
|
|
379
340
|
airbyte_ops_mcp/mcp/github_actions.py,sha256=_mAVTl6UX3F7S_HeV1-M5R4jMNzNQGI3ADs3sBzden8,11760
|
|
380
341
|
airbyte_ops_mcp/mcp/github_repo_ops.py,sha256=PiERpt8abo20Gz4CfXhrDNlVM4o4FOt5sweZJND2a0s,5314
|
|
381
342
|
airbyte_ops_mcp/mcp/metadata.py,sha256=fwGW97WknR5lfKcQnFtK6dU87aA6TmLj1NkKyqDAV9g,270
|
|
382
|
-
airbyte_ops_mcp/mcp/prerelease.py,sha256=
|
|
343
|
+
airbyte_ops_mcp/mcp/prerelease.py,sha256=KxBNRxwkIzfD981xphi07cvlgR-QEDmSe88aBfqNAyQ,9561
|
|
383
344
|
airbyte_ops_mcp/mcp/prod_db_queries.py,sha256=VsiBBnVbOjc8lBb2Xr1lmcH3wu7QHQfjd4lORarEE1s,42700
|
|
384
345
|
airbyte_ops_mcp/mcp/prompts.py,sha256=mJld9mdPECXYZffWXGSvNs4Xevx3rxqUGNlzGKVC2_s,1599
|
|
385
346
|
airbyte_ops_mcp/mcp/registry.py,sha256=PW-VYUj42qx2pQ_apUkVaoUFq7VgB9zEU7-aGrkSCCw,290
|
|
@@ -396,14 +357,14 @@ airbyte_ops_mcp/registry/models.py,sha256=B4L4TKr52wo0xs0CqvCBrpowqjShzVnZ5eTr2-
|
|
|
396
357
|
airbyte_ops_mcp/registry/publish.py,sha256=VoPxsM2_0zJ829orzCRN-kjgcJtuBNyXgW4I9J680ro,12717
|
|
397
358
|
airbyte_ops_mcp/regression_tests/__init__.py,sha256=8pwJIdz1Lb9oFV6UQ3DSjYKd8HCSqU8RpH5SDgEcEBA,1038
|
|
398
359
|
airbyte_ops_mcp/regression_tests/cdk_secrets.py,sha256=iRjqqBS96KZoswfgT7ju-pE_pfbYoDy4PfrK-K8uyYs,3204
|
|
399
|
-
airbyte_ops_mcp/regression_tests/ci_output.py,sha256=
|
|
360
|
+
airbyte_ops_mcp/regression_tests/ci_output.py,sha256=os69gcEhbomrGRAfnwPYAXhsAiJSWOuyW1gWZPx9-hw,15498
|
|
400
361
|
airbyte_ops_mcp/regression_tests/config.py,sha256=dwWeY0tatdbwl9BqbhZ7EljoZDCtKmGO5fvOAIxeXmA,5873
|
|
401
362
|
airbyte_ops_mcp/regression_tests/connection_fetcher.py,sha256=5wIiA0VvCFNEc-fr6Po18gZMX3E5fyPOGf2SuVOqv5U,12799
|
|
402
363
|
airbyte_ops_mcp/regression_tests/connection_secret_retriever.py,sha256=FhWNVWq7sON4nwUmVJv8BgXBOqg1YV4b5WuWyCzZ0LU,4695
|
|
403
364
|
airbyte_ops_mcp/regression_tests/connector_runner.py,sha256=OZzUa2aLh0sHaEARsDePOA-e3qEX4cvh3Jhnvi8S1rY,10130
|
|
404
365
|
airbyte_ops_mcp/regression_tests/evaluation_modes.py,sha256=lAL6pEDmy_XCC7_m4_NXjt_f6Z8CXeAhMkc0FU8bm_M,1364
|
|
405
|
-
airbyte_ops_mcp/regression_tests/http_metrics.py,sha256=
|
|
406
|
-
airbyte_ops_mcp/regression_tests/models.py,sha256=
|
|
366
|
+
airbyte_ops_mcp/regression_tests/http_metrics.py,sha256=busCYLb7qID0vv7yAtzARf__-HukpE3mAoc-pYI_gCQ,13256
|
|
367
|
+
airbyte_ops_mcp/regression_tests/models.py,sha256=jfe__WV8j2_fK9Cp256x5OhS9STRC63iPLG-36iPUgc,9104
|
|
407
368
|
airbyte_ops_mcp/regression_tests/obfuscation.py,sha256=JanpCLj6M9-_Zto6PABzNaY3OA93Frq3YpJ1411QNtQ,4395
|
|
408
369
|
airbyte_ops_mcp/regression_tests/schema_generation.py,sha256=cUYztcSOejsgkUREUWvfi6QBYK6fC4Dbxtztxxt8bdc,5323
|
|
409
370
|
airbyte_ops_mcp/regression_tests/commons/__init__.py,sha256=lNew_sAL4c8dPy3gMFbGC5_FuUX1P6QzGULbqS2H4M0,104
|
|
@@ -414,7 +375,7 @@ airbyte_ops_mcp/regression_tests/regression/comparators.py,sha256=MJkLZEKHivgrG0
|
|
|
414
375
|
airbyte_ops_mcp/regression_tests/validation/__init__.py,sha256=MBEwGOoNuqT4_oCahtoK62OKWIjUCfWa7vZTxNj_0Ek,1532
|
|
415
376
|
airbyte_ops_mcp/regression_tests/validation/catalog_validators.py,sha256=jqqVAMOk0mtdPgwu4d0hA0ZEjtsNh5gapvGydRv3_qk,12553
|
|
416
377
|
airbyte_ops_mcp/regression_tests/validation/record_validators.py,sha256=RjauAhKWNwxMBTu0eNS2hMFNQVs5CLbQU51kp6FOVDk,7432
|
|
417
|
-
airbyte_internal_ops-0.
|
|
418
|
-
airbyte_internal_ops-0.
|
|
419
|
-
airbyte_internal_ops-0.
|
|
420
|
-
airbyte_internal_ops-0.
|
|
378
|
+
airbyte_internal_ops-0.5.0.dist-info/METADATA,sha256=vCU17MQXGD6FZ9PfnzKV_gBSgNkTx_W4klz3aOFEulM,5679
|
|
379
|
+
airbyte_internal_ops-0.5.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
380
|
+
airbyte_internal_ops-0.5.0.dist-info/entry_points.txt,sha256=WxP0l7bRFss4Cr5uQqVj9mTEKwnRKouNuphXQF0lotA,171
|
|
381
|
+
airbyte_internal_ops-0.5.0.dist-info/RECORD,,
|
airbyte_ops_mcp/cli/cloud.py
CHANGED
|
@@ -82,6 +82,7 @@ from airbyte_ops_mcp.regression_tests.models import (
|
|
|
82
82
|
ExecutionInputs,
|
|
83
83
|
TargetOrControl,
|
|
84
84
|
)
|
|
85
|
+
from airbyte_ops_mcp.telemetry import track_regression_test
|
|
85
86
|
|
|
86
87
|
# Path to connectors directory within the airbyte repo
|
|
87
88
|
CONNECTORS_SUBDIR = Path("airbyte-integrations") / "connectors"
|
|
@@ -953,6 +954,32 @@ def regression_test(
|
|
|
953
954
|
f"Failed to pull control connector image: {resolved_control_image}"
|
|
954
955
|
)
|
|
955
956
|
|
|
957
|
+
# Track telemetry for the regression test
|
|
958
|
+
# Extract version from image tag (e.g., "airbyte/source-github:1.0.0" -> "1.0.0")
|
|
959
|
+
target_version = (
|
|
960
|
+
resolved_test_image.rsplit(":", 1)[-1]
|
|
961
|
+
if ":" in resolved_test_image
|
|
962
|
+
else "unknown"
|
|
963
|
+
)
|
|
964
|
+
control_version = None
|
|
965
|
+
if resolved_control_image and ":" in resolved_control_image:
|
|
966
|
+
control_version = resolved_control_image.rsplit(":", 1)[-1]
|
|
967
|
+
|
|
968
|
+
# Get tester identity from environment (GitHub Actions sets GITHUB_ACTOR)
|
|
969
|
+
tester = os.getenv("GITHUB_ACTOR") or os.getenv("USER")
|
|
970
|
+
|
|
971
|
+
track_regression_test(
|
|
972
|
+
user_id=tester,
|
|
973
|
+
connector_image=resolved_test_image,
|
|
974
|
+
command=command,
|
|
975
|
+
target_version=target_version,
|
|
976
|
+
control_version=control_version,
|
|
977
|
+
additional_properties={
|
|
978
|
+
"connection_id": connection_id,
|
|
979
|
+
"skip_compare": skip_compare,
|
|
980
|
+
},
|
|
981
|
+
)
|
|
982
|
+
|
|
956
983
|
# Execute the appropriate mode
|
|
957
984
|
if skip_compare:
|
|
958
985
|
# Single-version mode: run only the connector image
|
|
@@ -15,6 +15,9 @@ from airbyte import constants
|
|
|
15
15
|
from airbyte.exceptions import PyAirbyteInputError
|
|
16
16
|
|
|
17
17
|
from airbyte_ops_mcp import constants as ops_constants
|
|
18
|
+
from airbyte_ops_mcp.mcp.prod_db_queries import (
|
|
19
|
+
_resolve_canonical_name_to_definition_id,
|
|
20
|
+
)
|
|
18
21
|
|
|
19
22
|
# Internal enums for scoped configuration API "magic strings"
|
|
20
23
|
# These values caused issues during development and are now centralized here
|
|
@@ -959,3 +962,473 @@ def set_connector_version_override(
|
|
|
959
962
|
)
|
|
960
963
|
|
|
961
964
|
return True
|
|
965
|
+
|
|
966
|
+
|
|
967
|
+
def set_workspace_connector_version_override(
|
|
968
|
+
workspace_id: str,
|
|
969
|
+
connector_name: str,
|
|
970
|
+
connector_type: Literal["source", "destination"],
|
|
971
|
+
api_root: str,
|
|
972
|
+
client_id: str | None = None,
|
|
973
|
+
client_secret: str | None = None,
|
|
974
|
+
version: str | None = None,
|
|
975
|
+
unset: bool = False,
|
|
976
|
+
override_reason: str | None = None,
|
|
977
|
+
override_reason_reference_url: str | None = None,
|
|
978
|
+
user_email: str | None = None,
|
|
979
|
+
bearer_token: str | None = None,
|
|
980
|
+
) -> bool:
|
|
981
|
+
"""Set or clear a workspace-level version override for a connector type.
|
|
982
|
+
|
|
983
|
+
This pins ALL instances of a connector type within a workspace to a specific version.
|
|
984
|
+
For example, pinning 'source-github' at workspace level means all GitHub sources
|
|
985
|
+
in that workspace will use the pinned version.
|
|
986
|
+
|
|
987
|
+
Args:
|
|
988
|
+
workspace_id: The workspace ID
|
|
989
|
+
connector_name: The connector name (e.g., 'source-github')
|
|
990
|
+
connector_type: Either "source" or "destination"
|
|
991
|
+
api_root: The API root URL
|
|
992
|
+
client_id: The Airbyte Cloud client ID (required if no bearer_token)
|
|
993
|
+
client_secret: The Airbyte Cloud client secret (required if no bearer_token)
|
|
994
|
+
version: The version to pin to (e.g., "0.1.0"), or None to unset
|
|
995
|
+
unset: If True, removes any existing override
|
|
996
|
+
override_reason: Required when setting. Explanation for the override
|
|
997
|
+
override_reason_reference_url: Optional URL with more context
|
|
998
|
+
user_email: Email of user creating the override
|
|
999
|
+
bearer_token: Pre-existing bearer token (takes precedence over client credentials)
|
|
1000
|
+
|
|
1001
|
+
Returns:
|
|
1002
|
+
True if operation succeeded, False if no override existed (unset only)
|
|
1003
|
+
|
|
1004
|
+
Raises:
|
|
1005
|
+
PyAirbyteInputError: If the API request fails or parameters are invalid
|
|
1006
|
+
"""
|
|
1007
|
+
# Input validation
|
|
1008
|
+
if (version is None) == (not unset):
|
|
1009
|
+
raise PyAirbyteInputError(
|
|
1010
|
+
message="Must specify EXACTLY ONE of version (to set) OR unset=True (to clear), but not both",
|
|
1011
|
+
)
|
|
1012
|
+
|
|
1013
|
+
if not unset and (not override_reason or len(override_reason.strip()) < 10):
|
|
1014
|
+
raise PyAirbyteInputError(
|
|
1015
|
+
message="override_reason is required when setting a version and must be at least 10 characters",
|
|
1016
|
+
)
|
|
1017
|
+
|
|
1018
|
+
access_token = _get_access_token(client_id, client_secret, bearer_token)
|
|
1019
|
+
|
|
1020
|
+
# Resolve connector name to actor_definition_id using the shared registry lookup
|
|
1021
|
+
actor_definition_id = _resolve_canonical_name_to_definition_id(connector_name)
|
|
1022
|
+
|
|
1023
|
+
if unset:
|
|
1024
|
+
# Get the existing workspace-level configuration
|
|
1025
|
+
active_config = _get_scoped_configuration_context(
|
|
1026
|
+
actor_definition_id=actor_definition_id,
|
|
1027
|
+
scope_type=_ScopeType.WORKSPACE,
|
|
1028
|
+
scope_id=workspace_id,
|
|
1029
|
+
api_root=api_root,
|
|
1030
|
+
access_token=access_token,
|
|
1031
|
+
)
|
|
1032
|
+
|
|
1033
|
+
if not active_config:
|
|
1034
|
+
return False
|
|
1035
|
+
|
|
1036
|
+
# Verify this is actually a workspace-scoped config (not inherited from org)
|
|
1037
|
+
api_scope_type = active_config.get("scope_type", "").lower()
|
|
1038
|
+
api_scope_id = active_config.get("scope_id", "")
|
|
1039
|
+
if api_scope_type != _ScopeType.WORKSPACE.value or api_scope_id != workspace_id:
|
|
1040
|
+
raise PyAirbyteInputError(
|
|
1041
|
+
message=f"Cannot delete: the active config is not workspace-scoped. "
|
|
1042
|
+
f"Expected scope_type='{_ScopeType.WORKSPACE.value}' and scope_id='{workspace_id}', "
|
|
1043
|
+
f"but got scope_type='{api_scope_type}' and scope_id='{api_scope_id}'. "
|
|
1044
|
+
f"This may be an inherited config from organization level.",
|
|
1045
|
+
context={
|
|
1046
|
+
"workspace_id": workspace_id,
|
|
1047
|
+
"expected_scope_type": _ScopeType.WORKSPACE.value,
|
|
1048
|
+
"actual_scope_type": api_scope_type,
|
|
1049
|
+
"actual_scope_id": api_scope_id,
|
|
1050
|
+
"full_config": active_config,
|
|
1051
|
+
},
|
|
1052
|
+
)
|
|
1053
|
+
|
|
1054
|
+
# Delete the configuration
|
|
1055
|
+
delete_endpoint = f"{api_root}/scoped_configuration/delete"
|
|
1056
|
+
delete_payload = {"scopedConfigurationId": active_config["id"]}
|
|
1057
|
+
|
|
1058
|
+
response = requests.post(
|
|
1059
|
+
delete_endpoint,
|
|
1060
|
+
json=delete_payload,
|
|
1061
|
+
headers={
|
|
1062
|
+
"Authorization": f"Bearer {access_token}",
|
|
1063
|
+
"User-Agent": ops_constants.USER_AGENT,
|
|
1064
|
+
"Content-Type": "application/json",
|
|
1065
|
+
},
|
|
1066
|
+
timeout=30,
|
|
1067
|
+
)
|
|
1068
|
+
|
|
1069
|
+
if response.status_code not in (200, 204):
|
|
1070
|
+
raise PyAirbyteInputError(
|
|
1071
|
+
message=f"Failed to delete workspace version override: {response.status_code} {response.text}",
|
|
1072
|
+
context={
|
|
1073
|
+
"delete_endpoint": delete_endpoint,
|
|
1074
|
+
"config_id": active_config["id"],
|
|
1075
|
+
"status_code": response.status_code,
|
|
1076
|
+
"response": response.text,
|
|
1077
|
+
},
|
|
1078
|
+
)
|
|
1079
|
+
|
|
1080
|
+
return True
|
|
1081
|
+
|
|
1082
|
+
# Set a new workspace-level override
|
|
1083
|
+
# Resolve version string to version ID
|
|
1084
|
+
version_id = resolve_connector_version_id(
|
|
1085
|
+
actor_definition_id=actor_definition_id,
|
|
1086
|
+
connector_type=connector_type,
|
|
1087
|
+
version=version,
|
|
1088
|
+
api_root=api_root,
|
|
1089
|
+
bearer_token=access_token,
|
|
1090
|
+
)
|
|
1091
|
+
|
|
1092
|
+
# Check for existing workspace-level configuration
|
|
1093
|
+
existing_config = _get_scoped_configuration_context(
|
|
1094
|
+
actor_definition_id=actor_definition_id,
|
|
1095
|
+
scope_type=_ScopeType.WORKSPACE,
|
|
1096
|
+
scope_id=workspace_id,
|
|
1097
|
+
api_root=api_root,
|
|
1098
|
+
access_token=access_token,
|
|
1099
|
+
)
|
|
1100
|
+
|
|
1101
|
+
if existing_config:
|
|
1102
|
+
existing_version_id = existing_config.get("value")
|
|
1103
|
+
existing_version_name = existing_config.get("value_name", "unknown")
|
|
1104
|
+
|
|
1105
|
+
# If already pinned to the same version, no action needed
|
|
1106
|
+
if existing_version_id == version_id:
|
|
1107
|
+
raise PyAirbyteInputError(
|
|
1108
|
+
message=f"Workspace is already pinned to version {existing_version_name} for {connector_name}. "
|
|
1109
|
+
f"Use unset=True first if you want to re-pin to a different version.",
|
|
1110
|
+
context={
|
|
1111
|
+
"workspace_id": workspace_id,
|
|
1112
|
+
"connector_name": connector_name,
|
|
1113
|
+
"existing_version": existing_version_name,
|
|
1114
|
+
"requested_version": version,
|
|
1115
|
+
},
|
|
1116
|
+
)
|
|
1117
|
+
|
|
1118
|
+
# Verify this is a workspace-scoped config before deleting
|
|
1119
|
+
api_scope_type = existing_config.get("scope_type", "").lower()
|
|
1120
|
+
api_scope_id = existing_config.get("scope_id", "")
|
|
1121
|
+
if (
|
|
1122
|
+
api_scope_type == _ScopeType.WORKSPACE.value
|
|
1123
|
+
and api_scope_id == workspace_id
|
|
1124
|
+
):
|
|
1125
|
+
# Delete existing workspace-level config before creating new one
|
|
1126
|
+
delete_endpoint = f"{api_root}/scoped_configuration/delete"
|
|
1127
|
+
delete_payload = {"scopedConfigurationId": existing_config["id"]}
|
|
1128
|
+
|
|
1129
|
+
delete_response = requests.post(
|
|
1130
|
+
delete_endpoint,
|
|
1131
|
+
json=delete_payload,
|
|
1132
|
+
headers={
|
|
1133
|
+
"Authorization": f"Bearer {access_token}",
|
|
1134
|
+
"User-Agent": ops_constants.USER_AGENT,
|
|
1135
|
+
"Content-Type": "application/json",
|
|
1136
|
+
},
|
|
1137
|
+
timeout=30,
|
|
1138
|
+
)
|
|
1139
|
+
|
|
1140
|
+
if delete_response.status_code not in (200, 204):
|
|
1141
|
+
raise PyAirbyteInputError(
|
|
1142
|
+
message=f"Failed to delete existing workspace version override: "
|
|
1143
|
+
f"{delete_response.status_code} {delete_response.text}",
|
|
1144
|
+
)
|
|
1145
|
+
|
|
1146
|
+
# Get user ID from email
|
|
1147
|
+
if not user_email:
|
|
1148
|
+
raise PyAirbyteInputError(
|
|
1149
|
+
message="user_email is required to set a version override",
|
|
1150
|
+
)
|
|
1151
|
+
origin = get_user_id_by_email(
|
|
1152
|
+
email=user_email,
|
|
1153
|
+
api_root=api_root,
|
|
1154
|
+
bearer_token=access_token,
|
|
1155
|
+
)
|
|
1156
|
+
|
|
1157
|
+
# Create the override
|
|
1158
|
+
endpoint = f"{api_root}/scoped_configuration/create"
|
|
1159
|
+
payload: dict[str, Any] = {
|
|
1160
|
+
"config_key": _ScopedConfigKey.CONNECTOR_VERSION.value,
|
|
1161
|
+
"resource_type": _ResourceType.ACTOR_DEFINITION.value,
|
|
1162
|
+
"resource_id": actor_definition_id,
|
|
1163
|
+
"scope_type": _ScopeType.WORKSPACE.value,
|
|
1164
|
+
"scope_id": workspace_id,
|
|
1165
|
+
"value": version_id,
|
|
1166
|
+
"description": override_reason,
|
|
1167
|
+
"origin_type": _OriginType.USER.value,
|
|
1168
|
+
"origin": origin,
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1171
|
+
if override_reason_reference_url:
|
|
1172
|
+
payload["reference_url"] = override_reason_reference_url
|
|
1173
|
+
|
|
1174
|
+
response = requests.post(
|
|
1175
|
+
endpoint,
|
|
1176
|
+
json=payload,
|
|
1177
|
+
headers={
|
|
1178
|
+
"Authorization": f"Bearer {access_token}",
|
|
1179
|
+
"User-Agent": ops_constants.USER_AGENT,
|
|
1180
|
+
"Content-Type": "application/json",
|
|
1181
|
+
},
|
|
1182
|
+
timeout=30,
|
|
1183
|
+
)
|
|
1184
|
+
|
|
1185
|
+
if response.status_code not in (200, 201):
|
|
1186
|
+
raise PyAirbyteInputError(
|
|
1187
|
+
message=f"Failed to set workspace version override: {response.status_code} {response.text}",
|
|
1188
|
+
context={
|
|
1189
|
+
"workspace_id": workspace_id,
|
|
1190
|
+
"connector_name": connector_name,
|
|
1191
|
+
"version": version,
|
|
1192
|
+
"endpoint": endpoint,
|
|
1193
|
+
"status_code": response.status_code,
|
|
1194
|
+
"response": response.text,
|
|
1195
|
+
},
|
|
1196
|
+
)
|
|
1197
|
+
|
|
1198
|
+
return True
|
|
1199
|
+
|
|
1200
|
+
|
|
1201
|
+
def set_organization_connector_version_override(
|
|
1202
|
+
organization_id: str,
|
|
1203
|
+
connector_name: str,
|
|
1204
|
+
connector_type: Literal["source", "destination"],
|
|
1205
|
+
api_root: str,
|
|
1206
|
+
client_id: str | None = None,
|
|
1207
|
+
client_secret: str | None = None,
|
|
1208
|
+
version: str | None = None,
|
|
1209
|
+
unset: bool = False,
|
|
1210
|
+
override_reason: str | None = None,
|
|
1211
|
+
override_reason_reference_url: str | None = None,
|
|
1212
|
+
user_email: str | None = None,
|
|
1213
|
+
bearer_token: str | None = None,
|
|
1214
|
+
) -> bool:
|
|
1215
|
+
"""Set or clear an organization-level version override for a connector type.
|
|
1216
|
+
|
|
1217
|
+
This pins ALL instances of a connector type across an entire organization to a
|
|
1218
|
+
specific version. For example, pinning 'source-github' at organization level means
|
|
1219
|
+
all GitHub sources in all workspaces within that organization will use the pinned version.
|
|
1220
|
+
|
|
1221
|
+
Args:
|
|
1222
|
+
organization_id: The organization ID
|
|
1223
|
+
connector_name: The connector name (e.g., 'source-github')
|
|
1224
|
+
connector_type: Either "source" or "destination"
|
|
1225
|
+
api_root: The API root URL
|
|
1226
|
+
client_id: The Airbyte Cloud client ID (required if no bearer_token)
|
|
1227
|
+
client_secret: The Airbyte Cloud client secret (required if no bearer_token)
|
|
1228
|
+
version: The version to pin to (e.g., "0.1.0"), or None to unset
|
|
1229
|
+
unset: If True, removes any existing override
|
|
1230
|
+
override_reason: Required when setting. Explanation for the override
|
|
1231
|
+
override_reason_reference_url: Optional URL with more context
|
|
1232
|
+
user_email: Email of user creating the override
|
|
1233
|
+
bearer_token: Pre-existing bearer token (takes precedence over client credentials)
|
|
1234
|
+
|
|
1235
|
+
Returns:
|
|
1236
|
+
True if operation succeeded, False if no override existed (unset only)
|
|
1237
|
+
|
|
1238
|
+
Raises:
|
|
1239
|
+
PyAirbyteInputError: If the API request fails or parameters are invalid
|
|
1240
|
+
"""
|
|
1241
|
+
# Input validation
|
|
1242
|
+
if (version is None) == (not unset):
|
|
1243
|
+
raise PyAirbyteInputError(
|
|
1244
|
+
message="Must specify EXACTLY ONE of version (to set) OR unset=True (to clear), but not both",
|
|
1245
|
+
)
|
|
1246
|
+
|
|
1247
|
+
if not unset and (not override_reason or len(override_reason.strip()) < 10):
|
|
1248
|
+
raise PyAirbyteInputError(
|
|
1249
|
+
message="override_reason is required when setting a version and must be at least 10 characters",
|
|
1250
|
+
)
|
|
1251
|
+
|
|
1252
|
+
access_token = _get_access_token(client_id, client_secret, bearer_token)
|
|
1253
|
+
|
|
1254
|
+
# Resolve connector name to actor_definition_id using the shared registry lookup
|
|
1255
|
+
actor_definition_id = _resolve_canonical_name_to_definition_id(connector_name)
|
|
1256
|
+
|
|
1257
|
+
if unset:
|
|
1258
|
+
# Get the existing organization-level configuration
|
|
1259
|
+
active_config = _get_scoped_configuration_context(
|
|
1260
|
+
actor_definition_id=actor_definition_id,
|
|
1261
|
+
scope_type=_ScopeType.ORGANIZATION,
|
|
1262
|
+
scope_id=organization_id,
|
|
1263
|
+
api_root=api_root,
|
|
1264
|
+
access_token=access_token,
|
|
1265
|
+
)
|
|
1266
|
+
|
|
1267
|
+
if not active_config:
|
|
1268
|
+
return False
|
|
1269
|
+
|
|
1270
|
+
# Verify this is actually an organization-scoped config
|
|
1271
|
+
api_scope_type = active_config.get("scope_type", "").lower()
|
|
1272
|
+
api_scope_id = active_config.get("scope_id", "")
|
|
1273
|
+
if (
|
|
1274
|
+
api_scope_type != _ScopeType.ORGANIZATION.value
|
|
1275
|
+
or api_scope_id != organization_id
|
|
1276
|
+
):
|
|
1277
|
+
raise PyAirbyteInputError(
|
|
1278
|
+
message=f"Cannot delete: the active config is not organization-scoped. "
|
|
1279
|
+
f"Expected scope_type='{_ScopeType.ORGANIZATION.value}' and scope_id='{organization_id}', "
|
|
1280
|
+
f"but got scope_type='{api_scope_type}' and scope_id='{api_scope_id}'.",
|
|
1281
|
+
context={
|
|
1282
|
+
"organization_id": organization_id,
|
|
1283
|
+
"expected_scope_type": _ScopeType.ORGANIZATION.value,
|
|
1284
|
+
"actual_scope_type": api_scope_type,
|
|
1285
|
+
"actual_scope_id": api_scope_id,
|
|
1286
|
+
"full_config": active_config,
|
|
1287
|
+
},
|
|
1288
|
+
)
|
|
1289
|
+
|
|
1290
|
+
# Delete the configuration
|
|
1291
|
+
delete_endpoint = f"{api_root}/scoped_configuration/delete"
|
|
1292
|
+
delete_payload = {"scopedConfigurationId": active_config["id"]}
|
|
1293
|
+
|
|
1294
|
+
response = requests.post(
|
|
1295
|
+
delete_endpoint,
|
|
1296
|
+
json=delete_payload,
|
|
1297
|
+
headers={
|
|
1298
|
+
"Authorization": f"Bearer {access_token}",
|
|
1299
|
+
"User-Agent": ops_constants.USER_AGENT,
|
|
1300
|
+
"Content-Type": "application/json",
|
|
1301
|
+
},
|
|
1302
|
+
timeout=30,
|
|
1303
|
+
)
|
|
1304
|
+
|
|
1305
|
+
if response.status_code not in (200, 204):
|
|
1306
|
+
raise PyAirbyteInputError(
|
|
1307
|
+
message=f"Failed to delete organization version override: {response.status_code} {response.text}",
|
|
1308
|
+
context={
|
|
1309
|
+
"delete_endpoint": delete_endpoint,
|
|
1310
|
+
"config_id": active_config["id"],
|
|
1311
|
+
"status_code": response.status_code,
|
|
1312
|
+
"response": response.text,
|
|
1313
|
+
},
|
|
1314
|
+
)
|
|
1315
|
+
|
|
1316
|
+
return True
|
|
1317
|
+
|
|
1318
|
+
# Set a new organization-level override
|
|
1319
|
+
# Resolve version string to version ID
|
|
1320
|
+
version_id = resolve_connector_version_id(
|
|
1321
|
+
actor_definition_id=actor_definition_id,
|
|
1322
|
+
connector_type=connector_type,
|
|
1323
|
+
version=version,
|
|
1324
|
+
api_root=api_root,
|
|
1325
|
+
bearer_token=access_token,
|
|
1326
|
+
)
|
|
1327
|
+
|
|
1328
|
+
# Check for existing organization-level configuration
|
|
1329
|
+
existing_config = _get_scoped_configuration_context(
|
|
1330
|
+
actor_definition_id=actor_definition_id,
|
|
1331
|
+
scope_type=_ScopeType.ORGANIZATION,
|
|
1332
|
+
scope_id=organization_id,
|
|
1333
|
+
api_root=api_root,
|
|
1334
|
+
access_token=access_token,
|
|
1335
|
+
)
|
|
1336
|
+
|
|
1337
|
+
if existing_config:
|
|
1338
|
+
existing_version_id = existing_config.get("value")
|
|
1339
|
+
existing_version_name = existing_config.get("value_name", "unknown")
|
|
1340
|
+
|
|
1341
|
+
# If already pinned to the same version, no action needed
|
|
1342
|
+
if existing_version_id == version_id:
|
|
1343
|
+
raise PyAirbyteInputError(
|
|
1344
|
+
message=f"Organization is already pinned to version {existing_version_name} for {connector_name}. "
|
|
1345
|
+
f"Use unset=True first if you want to re-pin to a different version.",
|
|
1346
|
+
context={
|
|
1347
|
+
"organization_id": organization_id,
|
|
1348
|
+
"connector_name": connector_name,
|
|
1349
|
+
"existing_version": existing_version_name,
|
|
1350
|
+
"requested_version": version,
|
|
1351
|
+
},
|
|
1352
|
+
)
|
|
1353
|
+
|
|
1354
|
+
# Verify this is an organization-scoped config before deleting
|
|
1355
|
+
api_scope_type = existing_config.get("scope_type", "").lower()
|
|
1356
|
+
api_scope_id = existing_config.get("scope_id", "")
|
|
1357
|
+
if (
|
|
1358
|
+
api_scope_type == _ScopeType.ORGANIZATION.value
|
|
1359
|
+
and api_scope_id == organization_id
|
|
1360
|
+
):
|
|
1361
|
+
# Delete existing organization-level config before creating new one
|
|
1362
|
+
delete_endpoint = f"{api_root}/scoped_configuration/delete"
|
|
1363
|
+
delete_payload = {"scopedConfigurationId": existing_config["id"]}
|
|
1364
|
+
|
|
1365
|
+
delete_response = requests.post(
|
|
1366
|
+
delete_endpoint,
|
|
1367
|
+
json=delete_payload,
|
|
1368
|
+
headers={
|
|
1369
|
+
"Authorization": f"Bearer {access_token}",
|
|
1370
|
+
"User-Agent": ops_constants.USER_AGENT,
|
|
1371
|
+
"Content-Type": "application/json",
|
|
1372
|
+
},
|
|
1373
|
+
timeout=30,
|
|
1374
|
+
)
|
|
1375
|
+
|
|
1376
|
+
if delete_response.status_code not in (200, 204):
|
|
1377
|
+
raise PyAirbyteInputError(
|
|
1378
|
+
message=f"Failed to delete existing organization version override: "
|
|
1379
|
+
f"{delete_response.status_code} {delete_response.text}",
|
|
1380
|
+
)
|
|
1381
|
+
|
|
1382
|
+
# Get user ID from email
|
|
1383
|
+
if not user_email:
|
|
1384
|
+
raise PyAirbyteInputError(
|
|
1385
|
+
message="user_email is required to set a version override",
|
|
1386
|
+
)
|
|
1387
|
+
origin = get_user_id_by_email(
|
|
1388
|
+
email=user_email,
|
|
1389
|
+
api_root=api_root,
|
|
1390
|
+
bearer_token=access_token,
|
|
1391
|
+
)
|
|
1392
|
+
|
|
1393
|
+
# Create the override
|
|
1394
|
+
endpoint = f"{api_root}/scoped_configuration/create"
|
|
1395
|
+
payload: dict[str, Any] = {
|
|
1396
|
+
"config_key": _ScopedConfigKey.CONNECTOR_VERSION.value,
|
|
1397
|
+
"resource_type": _ResourceType.ACTOR_DEFINITION.value,
|
|
1398
|
+
"resource_id": actor_definition_id,
|
|
1399
|
+
"scope_type": _ScopeType.ORGANIZATION.value,
|
|
1400
|
+
"scope_id": organization_id,
|
|
1401
|
+
"value": version_id,
|
|
1402
|
+
"description": override_reason,
|
|
1403
|
+
"origin_type": _OriginType.USER.value,
|
|
1404
|
+
"origin": origin,
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1407
|
+
if override_reason_reference_url:
|
|
1408
|
+
payload["reference_url"] = override_reason_reference_url
|
|
1409
|
+
|
|
1410
|
+
response = requests.post(
|
|
1411
|
+
endpoint,
|
|
1412
|
+
json=payload,
|
|
1413
|
+
headers={
|
|
1414
|
+
"Authorization": f"Bearer {access_token}",
|
|
1415
|
+
"User-Agent": ops_constants.USER_AGENT,
|
|
1416
|
+
"Content-Type": "application/json",
|
|
1417
|
+
},
|
|
1418
|
+
timeout=30,
|
|
1419
|
+
)
|
|
1420
|
+
|
|
1421
|
+
if response.status_code not in (200, 201):
|
|
1422
|
+
raise PyAirbyteInputError(
|
|
1423
|
+
message=f"Failed to set organization version override: {response.status_code} {response.text}",
|
|
1424
|
+
context={
|
|
1425
|
+
"organization_id": organization_id,
|
|
1426
|
+
"connector_name": connector_name,
|
|
1427
|
+
"version": version,
|
|
1428
|
+
"endpoint": endpoint,
|
|
1429
|
+
"status_code": response.status_code,
|
|
1430
|
+
"response": response.text,
|
|
1431
|
+
},
|
|
1432
|
+
)
|
|
1433
|
+
|
|
1434
|
+
return True
|