omnata-plugin-devkit 0.13.2a184__tar.gz → 0.13.2a186__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.
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/PKG-INFO +1 -1
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/pyproject.toml +1 -1
- omnata_plugin_devkit-0.13.2a186/src/omnata_plugin_devkit/jinja_templates/CREATE_GENERIC_SECRET_OBJECT.sql.jinja +50 -0
- omnata_plugin_devkit-0.13.2a186/src/omnata_plugin_devkit/jinja_templates/CREATE_GENERIC_SECRET_OBJECT_FROM_EXISTING.sql.jinja +82 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/RETRIEVE_SECRETS_UDF.sql.jinja +0 -2
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/SET_CONNECTION_OBJECTS.sql.jinja +18 -29
- omnata_plugin_devkit-0.13.2a184/src/omnata_plugin_devkit/jinja_templates/CREATE_GENERIC_SECRET_OBJECT.sql.jinja +0 -35
- omnata_plugin_devkit-0.13.2a184/src/omnata_plugin_devkit/jinja_templates/CREATE_GENERIC_SECRET_OBJECT_FROM_EXISTING.sql.jinja +0 -55
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/LICENSE +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/README.md +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/__init__.py +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/airbyte_wrapper.py +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/cli/__init__.py +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/development.ipynb +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/development_session.py +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/initialiser.py +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/API_LIMITS.sql.jinja +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/ASSIGN_OUTBOUND_TARGET_TYPE.sql.jinja +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/CHECK_CONNECTION_PROGRESS.sql.jinja +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/CONFIGURATION_FORM.sql.jinja +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/CONFIGURE_APIS.sql.jinja +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/CONNECTION_FORM.sql.jinja +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/CONNECTION_TEST.sql.jinja +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/CONSTRUCT_FORM_OPTION.sql.jinja +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/CREATE_BILLING_EVENTS.sql.jinja +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/CREATE_NETWORK_RULE_OBJECT.sql.jinja +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/CREATE_NETWORK_RULE_OBJECT_FROM_EXISTING.sql.jinja +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/CREATE_OAUTH_SECRET_OBJECT.sql.jinja +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/DROP_NETWORK_RULES.sql.jinja +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/DROP_SECRETS.sql.jinja +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/FETCH_CONNECTIONS.sql.jinja +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/FETCH_SYNCS.sql.jinja +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/FETCH_SYNC_BRANCHES.sql.jinja +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/GET_MISSING_APP_PRIVILEGES.sql.jinja +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/INBOUND_LIST_STREAMS.sql.jinja +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/LIST_APP_SPECIFICATIONS.sql.jinja +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/LIST_STAGES.sql.jinja +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/NETWORK_ADDRESSES.sql.jinja +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/NGROK_POST_TUNNEL_FIELDS.sql.jinja +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/OUTBOUND_RECORD_VALIDATOR.sql.jinja +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/PENDING_API_CONFIGURATION.sql.jinja +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/POST_INSTALL_ACTIONS.sql.jinja +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/RENAME_CONNECTION_METHODS.sql.jinja +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/RETRIEVE_NETWORK_RULE_OBJECT.sql.jinja +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/RETRIEVE_SECRETS.sql.jinja +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/SET_EAI_ENABLED.sql.jinja +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/SET_EAI_SPECIFICATION.sql.jinja +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/SET_SI_SPECIFICATION.sql.jinja +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/SYNC.sql.jinja +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/TEST_CALLBACK.sql.jinja +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/TEST_OAUTH_TOKEN_EXISTS.sql.jinja +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/TUNNEL_TEST.sql.jinja +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/UPDATE_API_CONFIGURATION.sql.jinja +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/UPDATE_GENERIC_SECRET_OBJECT.sql.jinja +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/UPDATE_GENERIC_SECRET_OBJECT_OLD.sql.jinja +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/UPDATE_NETWORK_RULE_OBJECT.sql.jinja +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/jinja_templates/manifest.yml.jinja +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/native_app_packaging.py +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/plugin_registration.py +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/plugin_template/icon.svg +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/plugin_template/plugin.py +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/plugin_template/plugin_development.ipynb +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/plugin_template/requirements.txt +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/plugin_uploader.py +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/snowcli/__init__.py +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/snowcli/cli/__init__.py +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/snowcli/cli/api/__init__.py +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/snowcli/cli/api/config.py +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/snowcli/cli/api/constants.py +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/snowcli/cli/api/exceptions.py +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/snowcli/cli/api/secure_path.py +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/snowcli/cli/api/secure_utils.py +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/snowcli/cli/api/utils/__init__.py +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/snowcli/cli/api/utils/types.py +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/snowcli/cli/app/__init__.py +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/snowcli/cli/app/snow_connector.py +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/snowcli/cli/plugins/__init__.py +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/snowcli/cli/plugins/snowpark/__init__.py +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/snowcli/cli/plugins/snowpark/models.py +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/snowcli/cli/plugins/snowpark/package/__init__.py +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/snowcli/cli/plugins/snowpark/package_utils.py +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/snowcli/cli/plugins/snowpark/snowpark_shared.py +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/snowcli/cli/plugins/snowpark/venv.py +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/snowcli/cli/plugins/snowpark/zipper.py +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/snowcli/cli/templates/environment.yml.jinja +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/streamlit/plugin_configuration.py +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/test_step_definitions.py +0 -0
- {omnata_plugin_devkit-0.13.2a184 → omnata_plugin_devkit-0.13.2a186}/src/omnata_plugin_devkit/utils.py +0 -0
|
@@ -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
|
|
@@ -244,36 +244,25 @@ def run(session, parameters):
|
|
|
244
244
|
logger.info(f"Executing SQL: {cfg_sql}")
|
|
245
245
|
session.sql(cfg_sql).collect()
|
|
246
246
|
|
|
247
|
-
# (6) Other secrets —
|
|
248
|
-
|
|
247
|
+
# (6) Other secrets — delegate to CREATE_GENERIC_SECRET_OBJECT[_FROM_EXISTING].
|
|
248
|
+
# Both procs write SECRET_STRING via a dollar-quoted literal; binding via
|
|
249
|
+
# SECRET_STRING = ? is byte-faithful for the value's bytes BUT interprets
|
|
250
|
+
# backslash escapes inside that VARCHAR (turning `\n` into a raw LF), which
|
|
251
|
+
# corrupts PEM-bearing JSON. Keep the read+merge logic centralised in
|
|
252
|
+
# CREATE_GENERIC_SECRET_OBJECT_FROM_EXISTING rather than duplicating it here.
|
|
253
|
+
new_contents_json = json.dumps(connection_secrets or {})
|
|
249
254
|
if merge_with_secret_name:
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
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
|
-
if connection_secrets:
|
|
267
|
-
for k, v in connection_secrets.items():
|
|
268
|
-
seed_secrets[k] = v
|
|
269
|
-
# json.dumps emits strict JSON: every U+0000–U+001F byte is escaped, so PEM line breaks
|
|
270
|
-
# in caller-supplied values land in SECRET_STRING as `\n` (two bytes) rather than as a
|
|
271
|
-
# raw LF that would later trip strict json.loads on the read paths.
|
|
272
|
-
_call_proc(
|
|
273
|
-
session,
|
|
274
|
-
"call PLUGIN.CREATE_GENERIC_SECRET_OBJECT(?, ?)",
|
|
275
|
-
[other_secrets_fqn, json.dumps(seed_secrets)],
|
|
276
|
-
)
|
|
255
|
+
_call_proc(
|
|
256
|
+
session,
|
|
257
|
+
"call PLUGIN.CREATE_GENERIC_SECRET_OBJECT_FROM_EXISTING(?, ?, NULL, ?)",
|
|
258
|
+
[other_secrets_fqn, merge_with_secret_name, new_contents_json],
|
|
259
|
+
)
|
|
260
|
+
else:
|
|
261
|
+
_call_proc(
|
|
262
|
+
session,
|
|
263
|
+
"call PLUGIN.CREATE_GENERIC_SECRET_OBJECT(?, ?)",
|
|
264
|
+
[other_secrets_fqn, new_contents_json],
|
|
265
|
+
)
|
|
277
266
|
|
|
278
267
|
# (7) External Access Integration.
|
|
279
268
|
eai_rules = [network_rule_fqn]
|
|
@@ -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
|
-
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|