snowflake-cli 3.2.2__py3-none-any.whl → 3.4.1__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.
- snowflake/cli/__about__.py +1 -1
- snowflake/cli/_app/__main__.py +2 -2
- snowflake/cli/_app/cli_app.py +224 -192
- snowflake/cli/_app/commands_registration/commands_registration_with_callbacks.py +1 -27
- snowflake/cli/_app/constants.py +4 -0
- snowflake/cli/_app/snow_connector.py +12 -0
- snowflake/cli/_app/telemetry.py +10 -3
- snowflake/cli/_plugins/connection/util.py +12 -19
- snowflake/cli/_plugins/cortex/commands.py +2 -4
- snowflake/cli/_plugins/git/manager.py +1 -1
- snowflake/cli/_plugins/helpers/commands.py +207 -1
- snowflake/cli/_plugins/nativeapp/artifacts.py +16 -628
- snowflake/cli/_plugins/nativeapp/bundle_context.py +1 -1
- snowflake/cli/_plugins/nativeapp/codegen/artifact_processor.py +1 -1
- snowflake/cli/_plugins/nativeapp/codegen/compiler.py +42 -20
- snowflake/cli/_plugins/nativeapp/codegen/setup/native_app_setup_processor.py +9 -2
- snowflake/cli/_plugins/nativeapp/codegen/snowpark/python_processor.py +6 -3
- snowflake/cli/_plugins/nativeapp/codegen/templates/templates_processor.py +44 -34
- snowflake/cli/_plugins/nativeapp/commands.py +113 -21
- snowflake/cli/_plugins/nativeapp/constants.py +5 -0
- snowflake/cli/_plugins/nativeapp/entities/application.py +226 -296
- snowflake/cli/_plugins/nativeapp/entities/application_package.py +911 -141
- snowflake/cli/_plugins/nativeapp/entities/application_package_child_interface.py +43 -0
- snowflake/cli/_plugins/nativeapp/feature_flags.py +5 -1
- snowflake/cli/_plugins/nativeapp/release_channel/__init__.py +13 -0
- snowflake/cli/_plugins/nativeapp/release_channel/commands.py +246 -0
- snowflake/cli/_plugins/nativeapp/release_directive/__init__.py +13 -0
- snowflake/cli/_plugins/nativeapp/release_directive/commands.py +243 -0
- snowflake/cli/_plugins/nativeapp/same_account_install_method.py +9 -17
- snowflake/cli/_plugins/nativeapp/sf_facade_exceptions.py +80 -0
- snowflake/cli/_plugins/nativeapp/sf_sql_facade.py +1184 -80
- snowflake/cli/_plugins/nativeapp/utils.py +11 -0
- snowflake/cli/_plugins/nativeapp/v2_conversions/compat.py +7 -3
- snowflake/cli/_plugins/nativeapp/version/commands.py +32 -5
- snowflake/cli/_plugins/notebook/commands.py +55 -2
- snowflake/cli/_plugins/notebook/exceptions.py +1 -1
- snowflake/cli/_plugins/notebook/manager.py +7 -5
- snowflake/cli/_plugins/notebook/notebook_entity.py +120 -0
- snowflake/cli/_plugins/notebook/notebook_entity_model.py +42 -0
- snowflake/cli/_plugins/notebook/notebook_project_paths.py +15 -0
- snowflake/cli/_plugins/notebook/types.py +3 -0
- snowflake/cli/_plugins/snowpark/commands.py +48 -30
- snowflake/cli/_plugins/snowpark/common.py +47 -2
- snowflake/cli/_plugins/snowpark/snowpark_entity.py +247 -4
- snowflake/cli/_plugins/snowpark/snowpark_entity_model.py +18 -30
- snowflake/cli/_plugins/snowpark/snowpark_project_paths.py +156 -23
- snowflake/cli/_plugins/snowpark/zipper.py +33 -1
- snowflake/cli/_plugins/spcs/common.py +129 -0
- snowflake/cli/_plugins/spcs/services/commands.py +131 -14
- snowflake/cli/_plugins/spcs/services/manager.py +169 -1
- snowflake/cli/_plugins/stage/commands.py +2 -1
- snowflake/cli/_plugins/stage/diff.py +60 -39
- snowflake/cli/_plugins/stage/manager.py +34 -13
- snowflake/cli/_plugins/stage/utils.py +1 -1
- snowflake/cli/_plugins/streamlit/commands.py +10 -1
- snowflake/cli/_plugins/streamlit/manager.py +70 -22
- snowflake/cli/_plugins/streamlit/streamlit_entity.py +131 -1
- snowflake/cli/_plugins/streamlit/streamlit_entity_model.py +14 -24
- snowflake/cli/_plugins/streamlit/streamlit_project_paths.py +30 -0
- snowflake/cli/_plugins/workspace/commands.py +6 -5
- snowflake/cli/_plugins/workspace/manager.py +9 -5
- snowflake/cli/api/artifacts/__init__.py +13 -0
- snowflake/cli/api/artifacts/bundle_map.py +500 -0
- snowflake/cli/api/artifacts/common.py +78 -0
- snowflake/cli/api/artifacts/utils.py +82 -0
- snowflake/cli/api/cli_global_context.py +36 -2
- snowflake/cli/api/commands/flags.py +10 -4
- snowflake/cli/api/commands/utils.py +28 -2
- snowflake/cli/api/config.py +6 -2
- snowflake/cli/api/connections.py +12 -1
- snowflake/cli/api/constants.py +10 -1
- snowflake/cli/api/entities/common.py +81 -14
- snowflake/cli/api/entities/resolver.py +160 -0
- snowflake/cli/api/entities/utils.py +65 -23
- snowflake/cli/api/errno.py +63 -3
- snowflake/cli/api/feature_flags.py +19 -4
- snowflake/cli/api/metrics.py +21 -27
- snowflake/cli/api/project/definition_conversion.py +4 -4
- snowflake/cli/api/project/project_paths.py +28 -0
- snowflake/cli/api/project/schemas/entities/common.py +130 -1
- snowflake/cli/api/project/schemas/entities/entities.py +4 -0
- snowflake/cli/api/project/schemas/project_definition.py +54 -6
- snowflake/cli/api/project/schemas/updatable_model.py +2 -2
- snowflake/cli/api/project/schemas/v1/native_app/native_app.py +5 -7
- snowflake/cli/api/project/schemas/v1/streamlit/streamlit.py +1 -1
- snowflake/cli/api/project/util.py +45 -0
- snowflake/cli/api/secure_path.py +6 -0
- snowflake/cli/api/sql_execution.py +5 -1
- snowflake/cli/api/stage_path.py +7 -2
- snowflake/cli/api/utils/graph.py +3 -0
- snowflake/cli/api/utils/path_utils.py +24 -0
- {snowflake_cli-3.2.2.dist-info → snowflake_cli-3.4.1.dist-info}/METADATA +14 -15
- {snowflake_cli-3.2.2.dist-info → snowflake_cli-3.4.1.dist-info}/RECORD +96 -82
- {snowflake_cli-3.2.2.dist-info → snowflake_cli-3.4.1.dist-info}/WHEEL +1 -1
- snowflake/cli/api/project/schemas/v1/native_app/path_mapping.py +0 -65
- {snowflake_cli-3.2.2.dist-info → snowflake_cli-3.4.1.dist-info}/entry_points.txt +0 -0
- {snowflake_cli-3.2.2.dist-info → snowflake_cli-3.4.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from typing import Optional
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ApplicationPackageChildInterface(ABC):
|
|
7
|
+
@abstractmethod
|
|
8
|
+
def bundle(self, bundle_root=Path, *args, **kwargs) -> None:
|
|
9
|
+
"""
|
|
10
|
+
Bundles the entity artifacts into the provided root directory. Must not have any side-effects, such as deploying the artifacts into a stage, etc.
|
|
11
|
+
@param bundle_root: The directory where the bundle contents should be put.
|
|
12
|
+
"""
|
|
13
|
+
pass
|
|
14
|
+
|
|
15
|
+
@abstractmethod
|
|
16
|
+
def get_deploy_sql(
|
|
17
|
+
self,
|
|
18
|
+
artifacts_dir: Path,
|
|
19
|
+
schema: Optional[str],
|
|
20
|
+
*args,
|
|
21
|
+
**kwargs,
|
|
22
|
+
) -> str:
|
|
23
|
+
"""
|
|
24
|
+
Returns the SQL that would create the entity object. Must not execute the SQL or have any other side-effects.
|
|
25
|
+
@param artifacts_dir: Path to the child entity artifacts directory relative to the deploy root.
|
|
26
|
+
@param [Optional] schema: Schema to use when creating the object.
|
|
27
|
+
"""
|
|
28
|
+
pass
|
|
29
|
+
|
|
30
|
+
@abstractmethod
|
|
31
|
+
def get_usage_grant_sql(
|
|
32
|
+
self,
|
|
33
|
+
app_role: str,
|
|
34
|
+
schema: Optional[str],
|
|
35
|
+
*args,
|
|
36
|
+
**kwargs,
|
|
37
|
+
) -> str:
|
|
38
|
+
"""
|
|
39
|
+
Returns the SQL that would grant the required USAGE privilege to the provided application role on the entity object. Must not execute the SQL or have any other side-effects.
|
|
40
|
+
@param app_role: The application role to grant the privileges to.
|
|
41
|
+
@param [Optional] schema: The schema where the object was created.
|
|
42
|
+
"""
|
|
43
|
+
pass
|
|
@@ -18,7 +18,11 @@ from snowflake.cli.api.feature_flags import BooleanFlag, FeatureFlagMixin
|
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
@unique
|
|
21
|
-
class FeatureFlag(
|
|
21
|
+
class FeatureFlag(
|
|
22
|
+
FeatureFlagMixin
|
|
23
|
+
): # TODO move this to snowflake.cli.api.feature_flags
|
|
22
24
|
ENABLE_NATIVE_APP_PYTHON_SETUP = BooleanFlag(
|
|
23
25
|
"ENABLE_NATIVE_APP_PYTHON_SETUP", False
|
|
24
26
|
)
|
|
27
|
+
ENABLE_NATIVE_APP_CHILDREN = BooleanFlag("ENABLE_NATIVE_APP_CHILDREN", False)
|
|
28
|
+
ENABLE_RELEASE_CHANNELS = BooleanFlag("ENABLE_RELEASE_CHANNELS", None)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Copyright (c) 2024 Snowflake Inc.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
# Copyright (c) 2024 Snowflake Inc.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import logging
|
|
18
|
+
from typing import Optional
|
|
19
|
+
|
|
20
|
+
import typer
|
|
21
|
+
from snowflake.cli._plugins.nativeapp.v2_conversions.compat import (
|
|
22
|
+
force_project_definition_v2,
|
|
23
|
+
)
|
|
24
|
+
from snowflake.cli._plugins.workspace.manager import WorkspaceManager
|
|
25
|
+
from snowflake.cli.api.cli_global_context import get_cli_context
|
|
26
|
+
from snowflake.cli.api.commands.decorators import with_project_definition
|
|
27
|
+
from snowflake.cli.api.commands.snow_typer import SnowTyperFactory
|
|
28
|
+
from snowflake.cli.api.entities.utils import EntityActions
|
|
29
|
+
from snowflake.cli.api.output.formats import OutputFormat
|
|
30
|
+
from snowflake.cli.api.output.types import (
|
|
31
|
+
CollectionResult,
|
|
32
|
+
CommandResult,
|
|
33
|
+
MessageResult,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
app = SnowTyperFactory(
|
|
37
|
+
name="release-channel",
|
|
38
|
+
help="Manages release channels of an application package",
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
log = logging.getLogger(__name__)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@app.command("list", requires_connection=True)
|
|
45
|
+
@with_project_definition()
|
|
46
|
+
@force_project_definition_v2()
|
|
47
|
+
def release_channel_list(
|
|
48
|
+
channel: Optional[str] = typer.Argument(
|
|
49
|
+
default=None,
|
|
50
|
+
show_default=False,
|
|
51
|
+
help="The release channel to list. If not provided, all release channels are listed.",
|
|
52
|
+
),
|
|
53
|
+
**options,
|
|
54
|
+
) -> CommandResult:
|
|
55
|
+
"""
|
|
56
|
+
Lists the release channels available for an application package.
|
|
57
|
+
"""
|
|
58
|
+
|
|
59
|
+
cli_context = get_cli_context()
|
|
60
|
+
ws = WorkspaceManager(
|
|
61
|
+
project_definition=cli_context.project_definition,
|
|
62
|
+
project_root=cli_context.project_root,
|
|
63
|
+
)
|
|
64
|
+
package_id = options["package_entity_id"]
|
|
65
|
+
channels = ws.perform_action(
|
|
66
|
+
package_id,
|
|
67
|
+
EntityActions.RELEASE_CHANNEL_LIST,
|
|
68
|
+
release_channel=channel,
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
if cli_context.output_format == OutputFormat.JSON:
|
|
72
|
+
return CollectionResult(channels)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
@app.command("add-accounts", requires_connection=True)
|
|
76
|
+
@with_project_definition()
|
|
77
|
+
@force_project_definition_v2()
|
|
78
|
+
def release_channel_add_accounts(
|
|
79
|
+
channel: str = typer.Argument(
|
|
80
|
+
show_default=False,
|
|
81
|
+
help="The release channel to add accounts to.",
|
|
82
|
+
),
|
|
83
|
+
target_accounts: str = typer.Option(
|
|
84
|
+
show_default=False,
|
|
85
|
+
help="The accounts to add to the release channel. Format must be `org1.account1,org2.account2`.",
|
|
86
|
+
),
|
|
87
|
+
**options,
|
|
88
|
+
) -> CommandResult:
|
|
89
|
+
"""
|
|
90
|
+
Adds accounts to a release channel.
|
|
91
|
+
"""
|
|
92
|
+
|
|
93
|
+
cli_context = get_cli_context()
|
|
94
|
+
ws = WorkspaceManager(
|
|
95
|
+
project_definition=cli_context.project_definition,
|
|
96
|
+
project_root=cli_context.project_root,
|
|
97
|
+
)
|
|
98
|
+
package_id = options["package_entity_id"]
|
|
99
|
+
ws.perform_action(
|
|
100
|
+
package_id,
|
|
101
|
+
EntityActions.RELEASE_CHANNEL_ADD_ACCOUNTS,
|
|
102
|
+
release_channel=channel,
|
|
103
|
+
target_accounts=target_accounts.split(","),
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
return MessageResult("Successfully added accounts to the release channel.")
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
@app.command("remove-accounts", requires_connection=True)
|
|
110
|
+
@with_project_definition()
|
|
111
|
+
@force_project_definition_v2()
|
|
112
|
+
def release_channel_remove_accounts(
|
|
113
|
+
channel: str = typer.Argument(
|
|
114
|
+
show_default=False,
|
|
115
|
+
help="The release channel to remove accounts from.",
|
|
116
|
+
),
|
|
117
|
+
target_accounts: str = typer.Option(
|
|
118
|
+
show_default=False,
|
|
119
|
+
help="The accounts to remove from the release channel. Format must be `org1.account1,org2.account2`.",
|
|
120
|
+
),
|
|
121
|
+
**options,
|
|
122
|
+
) -> CommandResult:
|
|
123
|
+
"""
|
|
124
|
+
Removes accounts from a release channel.
|
|
125
|
+
"""
|
|
126
|
+
|
|
127
|
+
cli_context = get_cli_context()
|
|
128
|
+
ws = WorkspaceManager(
|
|
129
|
+
project_definition=cli_context.project_definition,
|
|
130
|
+
project_root=cli_context.project_root,
|
|
131
|
+
)
|
|
132
|
+
package_id = options["package_entity_id"]
|
|
133
|
+
ws.perform_action(
|
|
134
|
+
package_id,
|
|
135
|
+
EntityActions.RELEASE_CHANNEL_REMOVE_ACCOUNTS,
|
|
136
|
+
release_channel=channel,
|
|
137
|
+
target_accounts=target_accounts.split(","),
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
return MessageResult("Successfully removed accounts from the release channel.")
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
@with_project_definition()
|
|
144
|
+
@app.command("set-accounts", requires_connection=True)
|
|
145
|
+
@force_project_definition_v2()
|
|
146
|
+
def release_channel_set_accounts(
|
|
147
|
+
channel: str = typer.Argument(
|
|
148
|
+
show_default=False,
|
|
149
|
+
help="The release channel to set accounts for.",
|
|
150
|
+
),
|
|
151
|
+
target_accounts: str = typer.Option(
|
|
152
|
+
show_default=False,
|
|
153
|
+
help="The accounts to set for the release channel. Format must be `org1.account1,org2.account2`.",
|
|
154
|
+
),
|
|
155
|
+
**options,
|
|
156
|
+
) -> CommandResult:
|
|
157
|
+
"""
|
|
158
|
+
Sets accounts for a release channel.
|
|
159
|
+
"""
|
|
160
|
+
|
|
161
|
+
cli_context = get_cli_context()
|
|
162
|
+
ws = WorkspaceManager(
|
|
163
|
+
project_definition=cli_context.project_definition,
|
|
164
|
+
project_root=cli_context.project_root,
|
|
165
|
+
)
|
|
166
|
+
package_id = options["package_entity_id"]
|
|
167
|
+
ws.perform_action(
|
|
168
|
+
package_id,
|
|
169
|
+
EntityActions.RELEASE_CHANNEL_SET_ACCOUNTS,
|
|
170
|
+
release_channel=channel,
|
|
171
|
+
target_accounts=target_accounts.split(","),
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
return MessageResult("Successfully set accounts for the release channel.")
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
@app.command("add-version", requires_connection=True)
|
|
178
|
+
@with_project_definition()
|
|
179
|
+
@force_project_definition_v2()
|
|
180
|
+
def release_channel_add_version(
|
|
181
|
+
channel: str = typer.Argument(
|
|
182
|
+
show_default=False,
|
|
183
|
+
help="The release channel to add a version to.",
|
|
184
|
+
),
|
|
185
|
+
version: str = typer.Option(
|
|
186
|
+
show_default=False,
|
|
187
|
+
help="The version to add to the release channel.",
|
|
188
|
+
),
|
|
189
|
+
**options,
|
|
190
|
+
) -> CommandResult:
|
|
191
|
+
"""
|
|
192
|
+
Adds a version to a release channel.
|
|
193
|
+
"""
|
|
194
|
+
|
|
195
|
+
cli_context = get_cli_context()
|
|
196
|
+
ws = WorkspaceManager(
|
|
197
|
+
project_definition=cli_context.project_definition,
|
|
198
|
+
project_root=cli_context.project_root,
|
|
199
|
+
)
|
|
200
|
+
package_id = options["package_entity_id"]
|
|
201
|
+
ws.perform_action(
|
|
202
|
+
package_id,
|
|
203
|
+
EntityActions.RELEASE_CHANNEL_ADD_VERSION,
|
|
204
|
+
release_channel=channel,
|
|
205
|
+
version=version,
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
return MessageResult(
|
|
209
|
+
f"Successfully added version {version} to the release channel."
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
@app.command("remove-version", requires_connection=True)
|
|
214
|
+
@with_project_definition()
|
|
215
|
+
@force_project_definition_v2()
|
|
216
|
+
def release_channel_remove_version(
|
|
217
|
+
channel: str = typer.Argument(
|
|
218
|
+
show_default=False,
|
|
219
|
+
help="The release channel to remove a version from.",
|
|
220
|
+
),
|
|
221
|
+
version: str = typer.Option(
|
|
222
|
+
show_default=False,
|
|
223
|
+
help="The version to remove from the release channel.",
|
|
224
|
+
),
|
|
225
|
+
**options,
|
|
226
|
+
) -> CommandResult:
|
|
227
|
+
"""
|
|
228
|
+
Removes a version from a release channel.
|
|
229
|
+
"""
|
|
230
|
+
|
|
231
|
+
cli_context = get_cli_context()
|
|
232
|
+
ws = WorkspaceManager(
|
|
233
|
+
project_definition=cli_context.project_definition,
|
|
234
|
+
project_root=cli_context.project_root,
|
|
235
|
+
)
|
|
236
|
+
package_id = options["package_entity_id"]
|
|
237
|
+
ws.perform_action(
|
|
238
|
+
package_id,
|
|
239
|
+
EntityActions.RELEASE_CHANNEL_REMOVE_VERSION,
|
|
240
|
+
release_channel=channel,
|
|
241
|
+
version=version,
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
return MessageResult(
|
|
245
|
+
f"Successfully removed version {version} from the release channel."
|
|
246
|
+
)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Copyright (c) 2024 Snowflake Inc.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
# Copyright (c) 2024 Snowflake Inc.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import logging
|
|
18
|
+
from typing import Optional
|
|
19
|
+
|
|
20
|
+
import typer
|
|
21
|
+
from snowflake.cli._plugins.nativeapp.constants import DEFAULT_CHANNEL
|
|
22
|
+
from snowflake.cli._plugins.nativeapp.v2_conversions.compat import (
|
|
23
|
+
force_project_definition_v2,
|
|
24
|
+
)
|
|
25
|
+
from snowflake.cli._plugins.workspace.manager import WorkspaceManager
|
|
26
|
+
from snowflake.cli.api.cli_global_context import get_cli_context
|
|
27
|
+
from snowflake.cli.api.commands.decorators import with_project_definition
|
|
28
|
+
from snowflake.cli.api.commands.flags import like_option
|
|
29
|
+
from snowflake.cli.api.commands.snow_typer import SnowTyperFactory
|
|
30
|
+
from snowflake.cli.api.entities.utils import EntityActions
|
|
31
|
+
from snowflake.cli.api.output.types import (
|
|
32
|
+
CollectionResult,
|
|
33
|
+
CommandResult,
|
|
34
|
+
MessageResult,
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
app = SnowTyperFactory(
|
|
38
|
+
name="release-directive",
|
|
39
|
+
help="Manages release directives of an application package",
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
log = logging.getLogger(__name__)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@app.command("list", requires_connection=True)
|
|
46
|
+
@with_project_definition()
|
|
47
|
+
@force_project_definition_v2()
|
|
48
|
+
def release_directive_list(
|
|
49
|
+
like: str = like_option(
|
|
50
|
+
help_example="`snow app release-directive list --like='my%'` lists all release directives starting with 'my'",
|
|
51
|
+
),
|
|
52
|
+
channel: Optional[str] = typer.Option(
|
|
53
|
+
default=None,
|
|
54
|
+
show_default=False,
|
|
55
|
+
help="The release channel to use when listing release directives. If not provided, release directives from all release channels are listed.",
|
|
56
|
+
),
|
|
57
|
+
**options,
|
|
58
|
+
) -> CommandResult:
|
|
59
|
+
"""
|
|
60
|
+
Lists release directives in an application package.
|
|
61
|
+
If no release channel is specified, release directives for all channels are listed.
|
|
62
|
+
If a release channel is specified, only release directives for that channel are listed.
|
|
63
|
+
|
|
64
|
+
If `--like` is provided, only release directives matching the SQL pattern are listed.
|
|
65
|
+
"""
|
|
66
|
+
|
|
67
|
+
cli_context = get_cli_context()
|
|
68
|
+
ws = WorkspaceManager(
|
|
69
|
+
project_definition=cli_context.project_definition,
|
|
70
|
+
project_root=cli_context.project_root,
|
|
71
|
+
)
|
|
72
|
+
package_id = options["package_entity_id"]
|
|
73
|
+
result = ws.perform_action(
|
|
74
|
+
package_id,
|
|
75
|
+
EntityActions.RELEASE_DIRECTIVE_LIST,
|
|
76
|
+
release_channel=channel,
|
|
77
|
+
like=like,
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
return CollectionResult(result)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
@app.command("set", requires_connection=True)
|
|
84
|
+
@with_project_definition()
|
|
85
|
+
@force_project_definition_v2()
|
|
86
|
+
def release_directive_set(
|
|
87
|
+
directive: str = typer.Argument(
|
|
88
|
+
show_default=False,
|
|
89
|
+
help="Name of the release directive to set",
|
|
90
|
+
),
|
|
91
|
+
channel: str = typer.Option(
|
|
92
|
+
DEFAULT_CHANNEL,
|
|
93
|
+
help="Name of the release channel to use",
|
|
94
|
+
),
|
|
95
|
+
target_accounts: Optional[str] = typer.Option(
|
|
96
|
+
None,
|
|
97
|
+
show_default=False,
|
|
98
|
+
help="List of the accounts to apply the release directive to. Format must be `org1.account1,org2.account2`",
|
|
99
|
+
),
|
|
100
|
+
version: str = typer.Option(
|
|
101
|
+
show_default=False,
|
|
102
|
+
help="Version of the application package to use",
|
|
103
|
+
),
|
|
104
|
+
patch: int = typer.Option(
|
|
105
|
+
show_default=False,
|
|
106
|
+
help="Patch number to use for the selected version",
|
|
107
|
+
),
|
|
108
|
+
**options,
|
|
109
|
+
) -> CommandResult:
|
|
110
|
+
"""
|
|
111
|
+
Sets a release directive.
|
|
112
|
+
|
|
113
|
+
target_accounts cannot be specified for default release directives.
|
|
114
|
+
target_accounts field is required when creating a new non-default release directive.
|
|
115
|
+
"""
|
|
116
|
+
|
|
117
|
+
cli_context = get_cli_context()
|
|
118
|
+
ws = WorkspaceManager(
|
|
119
|
+
project_definition=cli_context.project_definition,
|
|
120
|
+
project_root=cli_context.project_root,
|
|
121
|
+
)
|
|
122
|
+
package_id = options["package_entity_id"]
|
|
123
|
+
ws.perform_action(
|
|
124
|
+
package_id,
|
|
125
|
+
EntityActions.RELEASE_DIRECTIVE_SET,
|
|
126
|
+
release_directive=directive,
|
|
127
|
+
version=version,
|
|
128
|
+
patch=patch,
|
|
129
|
+
target_accounts=None if target_accounts is None else target_accounts.split(","),
|
|
130
|
+
release_channel=channel,
|
|
131
|
+
)
|
|
132
|
+
return MessageResult("Successfully set release directive.")
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
@app.command("unset", requires_connection=True)
|
|
136
|
+
@with_project_definition()
|
|
137
|
+
@force_project_definition_v2()
|
|
138
|
+
def release_directive_unset(
|
|
139
|
+
directive: str = typer.Argument(
|
|
140
|
+
show_default=False,
|
|
141
|
+
help="Name of the release directive",
|
|
142
|
+
),
|
|
143
|
+
channel: str = typer.Option(
|
|
144
|
+
DEFAULT_CHANNEL,
|
|
145
|
+
help="Name of the release channel to use",
|
|
146
|
+
),
|
|
147
|
+
**options,
|
|
148
|
+
) -> CommandResult:
|
|
149
|
+
"""
|
|
150
|
+
Unsets a release directive.
|
|
151
|
+
"""
|
|
152
|
+
|
|
153
|
+
cli_context = get_cli_context()
|
|
154
|
+
ws = WorkspaceManager(
|
|
155
|
+
project_definition=cli_context.project_definition,
|
|
156
|
+
project_root=cli_context.project_root,
|
|
157
|
+
)
|
|
158
|
+
package_id = options["package_entity_id"]
|
|
159
|
+
ws.perform_action(
|
|
160
|
+
package_id,
|
|
161
|
+
EntityActions.RELEASE_DIRECTIVE_UNSET,
|
|
162
|
+
release_directive=directive,
|
|
163
|
+
release_channel=channel,
|
|
164
|
+
)
|
|
165
|
+
return MessageResult(f"Successfully unset release directive {directive}.")
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
@app.command("add-accounts", requires_connection=True)
|
|
169
|
+
@with_project_definition()
|
|
170
|
+
@force_project_definition_v2()
|
|
171
|
+
def release_directive_add_accounts(
|
|
172
|
+
directive: str = typer.Argument(
|
|
173
|
+
show_default=False,
|
|
174
|
+
help="Name of the release directive",
|
|
175
|
+
),
|
|
176
|
+
channel: str = typer.Option(
|
|
177
|
+
DEFAULT_CHANNEL,
|
|
178
|
+
help="Name of the release channel to use",
|
|
179
|
+
),
|
|
180
|
+
target_accounts: str = typer.Option(
|
|
181
|
+
show_default=False,
|
|
182
|
+
help="List of the accounts to add to the release directive. Format must be `org1.account1,org2.account2`",
|
|
183
|
+
),
|
|
184
|
+
**options,
|
|
185
|
+
) -> CommandResult:
|
|
186
|
+
"""
|
|
187
|
+
Adds accounts to a release directive.
|
|
188
|
+
"""
|
|
189
|
+
|
|
190
|
+
cli_context = get_cli_context()
|
|
191
|
+
ws = WorkspaceManager(
|
|
192
|
+
project_definition=cli_context.project_definition,
|
|
193
|
+
project_root=cli_context.project_root,
|
|
194
|
+
)
|
|
195
|
+
package_id = options["package_entity_id"]
|
|
196
|
+
ws.perform_action(
|
|
197
|
+
package_id,
|
|
198
|
+
EntityActions.RELEASE_DIRECTIVE_ADD_ACCOUNTS,
|
|
199
|
+
release_directive=directive,
|
|
200
|
+
target_accounts=target_accounts.split(","),
|
|
201
|
+
release_channel=channel,
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
return MessageResult("Successfully added accounts to the release directive.")
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
@app.command("remove-accounts", requires_connection=True)
|
|
208
|
+
@with_project_definition()
|
|
209
|
+
@force_project_definition_v2()
|
|
210
|
+
def release_directive_remove_accounts(
|
|
211
|
+
directive: str = typer.Argument(
|
|
212
|
+
show_default=False,
|
|
213
|
+
help="Name of the release directive",
|
|
214
|
+
),
|
|
215
|
+
channel: str = typer.Option(
|
|
216
|
+
DEFAULT_CHANNEL,
|
|
217
|
+
help="Name of the release channel to use",
|
|
218
|
+
),
|
|
219
|
+
target_accounts: str = typer.Option(
|
|
220
|
+
show_default=False,
|
|
221
|
+
help="List of the accounts to remove from the release directive. Format must be `org1.account1,org2.account2`",
|
|
222
|
+
),
|
|
223
|
+
**options,
|
|
224
|
+
) -> CommandResult:
|
|
225
|
+
"""
|
|
226
|
+
Removes accounts from a release directive.
|
|
227
|
+
"""
|
|
228
|
+
|
|
229
|
+
cli_context = get_cli_context()
|
|
230
|
+
ws = WorkspaceManager(
|
|
231
|
+
project_definition=cli_context.project_definition,
|
|
232
|
+
project_root=cli_context.project_root,
|
|
233
|
+
)
|
|
234
|
+
package_id = options["package_entity_id"]
|
|
235
|
+
ws.perform_action(
|
|
236
|
+
package_id,
|
|
237
|
+
EntityActions.RELEASE_DIRECTIVE_REMOVE_ACCOUNTS,
|
|
238
|
+
release_directive=directive,
|
|
239
|
+
target_accounts=target_accounts.split(","),
|
|
240
|
+
release_channel=channel,
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
return MessageResult("Successfully removed accounts from the release directive.")
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
1
2
|
from typing import Optional
|
|
2
3
|
|
|
3
4
|
from snowflake.cli._plugins.nativeapp.constants import (
|
|
@@ -8,25 +9,15 @@ from snowflake.cli._plugins.nativeapp.exceptions import (
|
|
|
8
9
|
ApplicationCreatedExternallyError,
|
|
9
10
|
)
|
|
10
11
|
from snowflake.cli._plugins.stage.manager import StageManager
|
|
12
|
+
from snowflake.cli.api.project.util import to_identifier
|
|
11
13
|
|
|
12
14
|
|
|
15
|
+
@dataclass
|
|
13
16
|
class SameAccountInstallMethod:
|
|
14
17
|
_requires_created_by_cli: bool
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
def __init__(
|
|
20
|
-
self,
|
|
21
|
-
requires_created_by_cli: bool,
|
|
22
|
-
version: Optional[str] = None,
|
|
23
|
-
patch: Optional[int] = None,
|
|
24
|
-
from_release_directive: bool = False,
|
|
25
|
-
):
|
|
26
|
-
self._requires_created_by_cli = requires_created_by_cli
|
|
27
|
-
self.version = version
|
|
28
|
-
self.patch = patch
|
|
29
|
-
self._from_release_directive = from_release_directive
|
|
18
|
+
version: Optional[str] = None
|
|
19
|
+
patch: Optional[int] = None
|
|
20
|
+
_from_release_directive: bool = False
|
|
30
21
|
|
|
31
22
|
@classmethod
|
|
32
23
|
def unversioned_dev(cls):
|
|
@@ -39,7 +30,7 @@ class SameAccountInstallMethod:
|
|
|
39
30
|
|
|
40
31
|
@classmethod
|
|
41
32
|
def release_directive(cls):
|
|
42
|
-
return cls(False,
|
|
33
|
+
return cls(False, _from_release_directive=True)
|
|
43
34
|
|
|
44
35
|
@property
|
|
45
36
|
def is_dev_mode(self) -> bool:
|
|
@@ -53,8 +44,9 @@ class SameAccountInstallMethod:
|
|
|
53
44
|
return ""
|
|
54
45
|
|
|
55
46
|
if self.version:
|
|
47
|
+
version_clause = f"version {to_identifier(self.version)}"
|
|
56
48
|
patch_clause = f"patch {self.patch}" if self.patch else ""
|
|
57
|
-
return f"using
|
|
49
|
+
return f"using {version_clause} {patch_clause}"
|
|
58
50
|
|
|
59
51
|
stage_name = StageManager.quote_stage_name(stage_fqn)
|
|
60
52
|
return f"using {stage_name}"
|