omnata-plugin-devkit 0.13.2a185__tar.gz → 0.13.2a187__tar.gz

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.
Files changed (88) hide show
  1. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/PKG-INFO +1 -1
  2. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/pyproject.toml +1 -1
  3. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/CONFIGURE_APIS.sql.jinja +2 -1
  4. omnata_plugin_devkit-0.13.2a187/src/omnata_plugin_devkit/jinja_templates/CREATE_GENERIC_SECRET_OBJECT.sql.jinja +50 -0
  5. omnata_plugin_devkit-0.13.2a187/src/omnata_plugin_devkit/jinja_templates/CREATE_GENERIC_SECRET_OBJECT_FROM_EXISTING.sql.jinja +82 -0
  6. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/RETRIEVE_SECRETS_UDF.sql.jinja +0 -2
  7. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/SET_CONNECTION_OBJECTS.sql.jinja +12 -26
  8. omnata_plugin_devkit-0.13.2a185/src/omnata_plugin_devkit/jinja_templates/CREATE_GENERIC_SECRET_OBJECT.sql.jinja +0 -35
  9. omnata_plugin_devkit-0.13.2a185/src/omnata_plugin_devkit/jinja_templates/CREATE_GENERIC_SECRET_OBJECT_FROM_EXISTING.sql.jinja +0 -55
  10. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/LICENSE +0 -0
  11. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/README.md +0 -0
  12. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/__init__.py +0 -0
  13. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/airbyte_wrapper.py +0 -0
  14. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/cli/__init__.py +0 -0
  15. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/development.ipynb +0 -0
  16. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/development_session.py +0 -0
  17. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/initialiser.py +0 -0
  18. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/API_LIMITS.sql.jinja +0 -0
  19. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/ASSIGN_OUTBOUND_TARGET_TYPE.sql.jinja +0 -0
  20. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/CHECK_CONNECTION_PROGRESS.sql.jinja +0 -0
  21. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/CONFIGURATION_FORM.sql.jinja +0 -0
  22. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/CONNECTION_FORM.sql.jinja +0 -0
  23. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/CONNECTION_TEST.sql.jinja +0 -0
  24. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/CONSTRUCT_FORM_OPTION.sql.jinja +0 -0
  25. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/CREATE_BILLING_EVENTS.sql.jinja +0 -0
  26. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/CREATE_NETWORK_RULE_OBJECT.sql.jinja +0 -0
  27. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/CREATE_NETWORK_RULE_OBJECT_FROM_EXISTING.sql.jinja +0 -0
  28. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/CREATE_OAUTH_SECRET_OBJECT.sql.jinja +0 -0
  29. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/DROP_NETWORK_RULES.sql.jinja +0 -0
  30. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/DROP_SECRETS.sql.jinja +0 -0
  31. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/FETCH_CONNECTIONS.sql.jinja +0 -0
  32. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/FETCH_SYNCS.sql.jinja +0 -0
  33. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/FETCH_SYNC_BRANCHES.sql.jinja +0 -0
  34. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/GET_MISSING_APP_PRIVILEGES.sql.jinja +0 -0
  35. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/INBOUND_LIST_STREAMS.sql.jinja +0 -0
  36. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/LIST_APP_SPECIFICATIONS.sql.jinja +0 -0
  37. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/LIST_STAGES.sql.jinja +0 -0
  38. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/NETWORK_ADDRESSES.sql.jinja +0 -0
  39. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/NGROK_POST_TUNNEL_FIELDS.sql.jinja +0 -0
  40. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/OUTBOUND_RECORD_VALIDATOR.sql.jinja +0 -0
  41. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/PENDING_API_CONFIGURATION.sql.jinja +0 -0
  42. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/POST_INSTALL_ACTIONS.sql.jinja +0 -0
  43. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/RENAME_CONNECTION_METHODS.sql.jinja +0 -0
  44. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/RETRIEVE_NETWORK_RULE_OBJECT.sql.jinja +0 -0
  45. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/RETRIEVE_SECRETS.sql.jinja +0 -0
  46. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/SET_EAI_ENABLED.sql.jinja +0 -0
  47. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/SET_EAI_SPECIFICATION.sql.jinja +0 -0
  48. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/SET_SI_SPECIFICATION.sql.jinja +0 -0
  49. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/SYNC.sql.jinja +0 -0
  50. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/TEST_CALLBACK.sql.jinja +0 -0
  51. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/TEST_OAUTH_TOKEN_EXISTS.sql.jinja +0 -0
  52. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/TUNNEL_TEST.sql.jinja +0 -0
  53. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/UPDATE_API_CONFIGURATION.sql.jinja +0 -0
  54. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/UPDATE_GENERIC_SECRET_OBJECT.sql.jinja +0 -0
  55. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/UPDATE_GENERIC_SECRET_OBJECT_OLD.sql.jinja +0 -0
  56. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/UPDATE_NETWORK_RULE_OBJECT.sql.jinja +0 -0
  57. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/jinja_templates/manifest.yml.jinja +0 -0
  58. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/native_app_packaging.py +0 -0
  59. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/plugin_registration.py +0 -0
  60. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/plugin_template/icon.svg +0 -0
  61. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/plugin_template/plugin.py +0 -0
  62. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/plugin_template/plugin_development.ipynb +0 -0
  63. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/plugin_template/requirements.txt +0 -0
  64. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/plugin_uploader.py +0 -0
  65. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/snowcli/__init__.py +0 -0
  66. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/snowcli/cli/__init__.py +0 -0
  67. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/snowcli/cli/api/__init__.py +0 -0
  68. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/snowcli/cli/api/config.py +0 -0
  69. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/snowcli/cli/api/constants.py +0 -0
  70. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/snowcli/cli/api/exceptions.py +0 -0
  71. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/snowcli/cli/api/secure_path.py +0 -0
  72. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/snowcli/cli/api/secure_utils.py +0 -0
  73. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/snowcli/cli/api/utils/__init__.py +0 -0
  74. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/snowcli/cli/api/utils/types.py +0 -0
  75. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/snowcli/cli/app/__init__.py +0 -0
  76. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/snowcli/cli/app/snow_connector.py +0 -0
  77. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/snowcli/cli/plugins/__init__.py +0 -0
  78. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/snowcli/cli/plugins/snowpark/__init__.py +0 -0
  79. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/snowcli/cli/plugins/snowpark/models.py +0 -0
  80. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/snowcli/cli/plugins/snowpark/package/__init__.py +0 -0
  81. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/snowcli/cli/plugins/snowpark/package_utils.py +0 -0
  82. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/snowcli/cli/plugins/snowpark/snowpark_shared.py +0 -0
  83. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/snowcli/cli/plugins/snowpark/venv.py +0 -0
  84. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/snowcli/cli/plugins/snowpark/zipper.py +0 -0
  85. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/snowcli/cli/templates/environment.yml.jinja +0 -0
  86. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/streamlit/plugin_configuration.py +0 -0
  87. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/test_step_definitions.py +0 -0
  88. {omnata_plugin_devkit-0.13.2a185 → omnata_plugin_devkit-0.13.2a187}/src/omnata_plugin_devkit/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: omnata-plugin-devkit
3
- Version: 0.13.2a185
3
+ Version: 0.13.2a187
4
4
  Summary:
5
5
  License-File: LICENSE
6
6
  Author: James Weakley
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "omnata-plugin-devkit"
3
- version = "0.13.2a185"
3
+ version = "0.13.2a187"
4
4
  description = ""
5
5
  authors = ["James Weakley <james.weakley@omnata.com>"]
6
6
  readme = "README.md"
@@ -323,7 +323,8 @@ try{
323
323
  OBJECT,
324
324
  VARCHAR,
325
325
  VARCHAR,
326
- VARCHAR)`
326
+ VARCHAR)`,
327
+ `SET_CONNECTION_OBJECTS(OBJECT)`
327
328
  ];
328
329
  procsToAlter.forEach(function(procToAlter) {
329
330
  var sqlText = `alter procedure ${procToAlter}
@@ -0,0 +1,50 @@
1
+ create or replace procedure PLUGIN.CREATE_GENERIC_SECRET_OBJECT(SECRET_NAME VARCHAR, SECRET_CONTENTS VARCHAR)
2
+ returns object
3
+ language python
4
+ RUNTIME_VERSION = '3.10'
5
+ PACKAGES = ({{packages}})
6
+ HANDLER = 'run'
7
+ COMMENT = $$
8
+ Creates a generic secret object. SECRET_STRING is written via a dollar-quoted
9
+ literal rather than a bind parameter: bind binding for SECRET_STRING = ? was
10
+ observed to interpret backslash escapes inside the value, turning a JSON `\n`
11
+ two-byte escape into a raw LF byte and corrupting the stored JSON. Dollar
12
+ quoting is byte-faithful.
13
+ $$
14
+ execute as owner
15
+ as
16
+ $$
17
+ from logging import getLogger
18
+ logger = getLogger(__name__)
19
+
20
+ # Avoid putting two literal dollar signs in this proc body (the body itself
21
+ # is dollar-quoted, so a stray `$$` would close it early).
22
+ _TWO_DOLLARS = "$" + "$"
23
+
24
+
25
+ def run(session, secret_name, secret_contents):
26
+ try:
27
+ if secret_contents is None:
28
+ secret_contents = ""
29
+ if _TWO_DOLLARS in secret_contents:
30
+ raise ValueError(
31
+ "secret_contents contains '" + _TWO_DOLLARS + "', which is "
32
+ "currently not supported due to Snowflake delimiter requirements."
33
+ )
34
+ sql = (
35
+ "CREATE OR REPLACE SECRET IDENTIFIER(?) TYPE = GENERIC_STRING "
36
+ "SECRET_STRING = " + _TWO_DOLLARS + secret_contents + _TWO_DOLLARS
37
+ )
38
+ session.sql(sql, params=[secret_name]).collect()
39
+ session.sql(
40
+ "grant usage on secret IDENTIFIER(?) to application role OMNATA_MANAGEMENT",
41
+ params=[secret_name],
42
+ ).collect()
43
+ return {"success": True, "data": None}
44
+ except Exception as e:
45
+ return {"success": False, "error": f"CREATE_GENERIC_SECRET_OBJECT: {str(e)}"}
46
+ $$
47
+ ;
48
+
49
+ grant usage on procedure PLUGIN.CREATE_GENERIC_SECRET_OBJECT(VARCHAR, VARCHAR)
50
+ to application role OMNATA_MANAGEMENT;
@@ -0,0 +1,82 @@
1
+ create or replace procedure PLUGIN.CREATE_GENERIC_SECRET_OBJECT_FROM_EXISTING(
2
+ SECRET_NAME VARCHAR,
3
+ SECRET_TO_CLONE VARCHAR,
4
+ KEYS_TO_INCLUDE ARRAY,
5
+ NEW_CONTENTS_TO_MERGE VARCHAR DEFAULT NULL
6
+ )
7
+ returns object
8
+ language python
9
+ RUNTIME_VERSION = '3.10'
10
+ PACKAGES = ({{packages}})
11
+ HANDLER = 'run'
12
+ COMMENT = $$
13
+ Creates a generic secret object using an existing secret as the seed.
14
+ - KEYS_TO_INCLUDE (optional): if provided, restrict the cloned content to
15
+ these keys before any merging.
16
+ - NEW_CONTENTS_TO_MERGE (optional): JSON object string whose entries are
17
+ merged on top of the cloned content (overwriting matching keys). Use
18
+ this to add or update fields in one shot without a second proc call.
19
+ The write itself is delegated to CREATE_GENERIC_SECRET_OBJECT, which uses a
20
+ dollar-quoted SECRET_STRING literal to avoid bind-parameter escape
21
+ interpretation that corrupts newlines in PEM values.
22
+ $$
23
+ execute as owner
24
+ as
25
+ $$
26
+ import json
27
+ from logging import getLogger
28
+ logger = getLogger(__name__)
29
+
30
+
31
+ def _call_proc(session, sql, params):
32
+ rows = session.sql(sql, params=params).collect()
33
+ if not rows:
34
+ raise RuntimeError(f"delegate proc returned no rows: {sql}")
35
+ val = rows[0][0]
36
+ if isinstance(val, str):
37
+ try:
38
+ val = json.loads(val)
39
+ except json.JSONDecodeError:
40
+ pass
41
+ if isinstance(val, dict) and val.get('success') is False:
42
+ raise RuntimeError(val.get('error') or f"delegate proc failed: {sql}")
43
+ return val.get('data') if isinstance(val, dict) else val
44
+
45
+
46
+ def run(session, secret_name, secret_to_clone, keys_to_include, new_contents_to_merge):
47
+ try:
48
+ existing = _call_proc(
49
+ session,
50
+ "call PLUGIN.RETRIEVE_SECRETS(NULL, ?)",
51
+ [secret_to_clone],
52
+ ) or {}
53
+ if not isinstance(existing, dict):
54
+ existing = {}
55
+ if keys_to_include is not None:
56
+ existing = {k: existing[k] for k in keys_to_include if k in existing}
57
+ if new_contents_to_merge is not None:
58
+ try:
59
+ new_dict = json.loads(new_contents_to_merge)
60
+ except (TypeError, json.JSONDecodeError) as parse_err:
61
+ raise ValueError(
62
+ f"NEW_CONTENTS_TO_MERGE must be a JSON object string: {parse_err}"
63
+ ) from parse_err
64
+ if not isinstance(new_dict, dict):
65
+ raise ValueError("NEW_CONTENTS_TO_MERGE must decode to a JSON object")
66
+ existing = {**existing, **new_dict}
67
+ _call_proc(
68
+ session,
69
+ "call PLUGIN.CREATE_GENERIC_SECRET_OBJECT(?, ?)",
70
+ [secret_name, json.dumps(existing)],
71
+ )
72
+ return {"success": True, "data": None}
73
+ except Exception as e:
74
+ return {
75
+ "success": False,
76
+ "error": f"CREATE_GENERIC_SECRET_OBJECT_FROM_EXISTING: {str(e)}",
77
+ }
78
+ $$
79
+ ;
80
+
81
+ grant usage on procedure PLUGIN.CREATE_GENERIC_SECRET_OBJECT_FROM_EXISTING(VARCHAR, VARCHAR, ARRAY, VARCHAR)
82
+ to application role OMNATA_MANAGEMENT;
@@ -25,13 +25,11 @@ def run(oauth_secret_name,other_secrets_name):
25
25
  other_secrets_name
26
26
  )
27
27
  if len(secret_string_content) > 2:
28
- logger.info(f"Raw secret string: {secret_string_content}")
29
28
  other_secrets = json.loads(secret_string_content)
30
29
  connection_secrets = {
31
30
  **connection_secrets,
32
31
  **other_secrets,
33
32
  }
34
- logger.info(f"Parsed secret string: {connection_secrets}")
35
33
  except Exception as exception:
36
34
  logger.error(f"Error parsing secrets content for secret {other_secrets_name}: {str(exception)}")
37
35
  raise ValueError(f"Error parsing secrets content: {str(exception)}") from exception
@@ -45,6 +45,7 @@ execute as owner
45
45
  as
46
46
  $$
47
47
  import json
48
+ import _snowflake
48
49
  from logging import getLogger
49
50
  from typing import Any, Dict, List, Literal, Optional
50
51
  from pydantic import BaseModel, ConfigDict, Field, model_validator
@@ -244,35 +245,20 @@ def run(session, parameters):
244
245
  logger.info(f"Executing SQL: {cfg_sql}")
245
246
  session.sql(cfg_sql).collect()
246
247
 
247
- # (6) Other secrets — seeded from an existing secret and/or caller-supplied values.
248
+ # (6) Other secrets — read the seed directly via _snowflake.get_generic_secret_string
249
+ # rather than going through RETRIEVE_SECRETS / CREATE_GENERIC_SECRET_OBJECT_FROM_EXISTING.
250
+ # The cross-proc VARCHAR bind path was observed to mangle backslash escapes in JSON
251
+ # payloads; reading the secret in-process avoids any extra hop. The secret must be
252
+ # bound to this proc by CONFIGURE_APIS — the alias is the unqualified name.
248
253
  seed_secrets = {}
249
254
  if merge_with_secret_name:
250
- # RETRIEVE_SECRETS_UDF reads the secret contents via _snowflake.get_generic_secret_string,
251
- # which takes the binding alias (the unqualified name) not the FQN. The source secret
252
- # must already be bound to RETRIEVE_SECRETS_UDF via a prior CONFIGURE_APIS run.
253
- # Passing NULL for the OAuth secret name keeps the access_token key out of the returned object.
254
- seed_rows = session.sql(
255
- "select PLUGIN.RETRIEVE_SECRETS_UDF(NULL, ?)",
256
- params=[merge_with_secret_name],
257
- ).collect()
258
- seed_value = seed_rows[0][0] if seed_rows else None
259
- if isinstance(seed_value, str):
260
- try:
261
- seed_value = json.loads(seed_value)
262
- except json.JSONDecodeError:
263
- seed_value = None
264
- if isinstance(seed_value, dict):
265
- seed_secrets = dict(seed_value)
266
- logger.info(f"Seeded secret value {seed_secrets}")
255
+ raw = _snowflake.get_generic_secret_string(merge_with_secret_name)
256
+ if raw and len(raw) > 2:
257
+ decoded = json.loads(raw)
258
+ if isinstance(decoded, dict):
259
+ seed_secrets = decoded
267
260
  if connection_secrets:
268
- for k, v in connection_secrets.items():
269
- seed_secrets[k] = v
270
- # json.dumps emits strict JSON: every U+0000–U+001F byte is escaped, so PEM line breaks
271
- # in caller-supplied values land in SECRET_STRING as `\n` (two bytes) rather than as a
272
- # raw LF that would later trip strict json.loads on the read paths.
273
- logger.info(f"Writing generic secrets, dict: {seed_secrets}")
274
- logger.info(f"Writing generic secrets, raw: {json.dumps(seed_secrets)}")
275
- json.loads(json.dumps(seed_secrets))
261
+ seed_secrets.update(connection_secrets)
276
262
  _call_proc(
277
263
  session,
278
264
  "call PLUGIN.CREATE_GENERIC_SECRET_OBJECT(?, ?)",
@@ -1,35 +0,0 @@
1
- create or replace procedure PLUGIN.CREATE_GENERIC_SECRET_OBJECT(SECRET_NAME VARCHAR,SECRET_CONTENTS VARCHAR)
2
- returns object
3
- language javascript
4
- COMMENT = $$
5
- Creates a generic secret object.
6
- $$
7
- execute as owner
8
- as
9
- $$
10
- try{
11
- snowflake.createStatement( {
12
- sqlText: `CREATE OR REPLACE SECRET IDENTIFIER(?) TYPE = GENERIC_STRING SECRET_STRING = ?`,
13
- binds:[SECRET_NAME,SECRET_CONTENTS]
14
- } ).execute();
15
- snowflake.createStatement( {
16
- sqlText: `grant usage on secret IDENTIFIER(?) to application role OMNATA_MANAGEMENT`,
17
- binds:[SECRET_NAME]
18
- } ).execute();
19
- return {
20
- "success": true,
21
- "data": null
22
- }
23
- }
24
- catch(e){
25
- return {
26
- "success": false,
27
- "error": `CREATE_GENERIC_SECRET_OBJECT: ${String(e)}`
28
- }
29
- }
30
- $$
31
- ;
32
-
33
- grant usage on procedure PLUGIN.CREATE_GENERIC_SECRET_OBJECT(VARCHAR,VARCHAR)
34
- to application role OMNATA_MANAGEMENT;
35
-
@@ -1,55 +0,0 @@
1
- create or replace procedure PLUGIN.CREATE_GENERIC_SECRET_OBJECT_FROM_EXISTING(SECRET_NAME VARCHAR,SECRET_TO_CLONE VARCHAR,KEYS_TO_INCLUDE ARRAY)
2
- returns object
3
- language javascript
4
- COMMENT = $$
5
- Creates a generic secret object, using an existing object as a starting point.
6
- $$
7
- execute as owner
8
- as
9
- $$
10
- try{
11
- // retrieve the existing secrets
12
- var results = snowflake.createStatement( {
13
- sqlText: `call RETRIEVE_SECRETS(null,?)`,
14
- binds:[SECRET_TO_CLONE]
15
- } ).execute();
16
- results.next();
17
- var procResult = results.getColumnValue(1);
18
- if (procResult.success===false){
19
- throw procResult.error;
20
- }
21
- var existingSecrets = procResult.data;
22
- if (KEYS_TO_INCLUDE != null){
23
- // pick out the specific keys from the KEYS_TO_INCLUDE array
24
- existingSecrets = KEYS_TO_INCLUDE.reduce((acc,key) => {
25
- acc[key] = existingSecrets[key];
26
- return acc;
27
- }, {})
28
- }
29
- // create the secret object by calling the regular proc
30
- var results = snowflake.createStatement( {
31
- sqlText: `call CREATE_GENERIC_SECRET_OBJECT(?,?)`,
32
- binds:[SECRET_NAME,JSON.stringify(existingSecrets)]
33
- } ).execute();
34
- results.next();
35
- var procResult = results.getColumnValue(1);
36
- if (procResult.success===false){
37
- throw procResult.error;
38
- }
39
- return {
40
- "success": true,
41
- "data": null
42
- }
43
- }
44
- catch(e){
45
- return {
46
- "success": false,
47
- "error": `CREATE_GENERIC_SECRET_OBJECT_FROM_EXISTING: ${String(e)}`
48
- }
49
- }
50
- $$
51
- ;
52
-
53
- grant usage on procedure PLUGIN.CREATE_GENERIC_SECRET_OBJECT_FROM_EXISTING(VARCHAR,VARCHAR,ARRAY)
54
- to application role OMNATA_MANAGEMENT;
55
-