-
Notifications
You must be signed in to change notification settings - Fork 3.4k
[Resource] az bicep: Add snapshot and run subcommands
#33398
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -757,6 +757,21 @@ def load_arguments(self, _): | |
| c.argument('no_restore', arg_type=bicep_no_restore_type, help="When set, generates the parameters file without restoring external modules.") | ||
| c.argument('diagnostics_format', arg_type=get_enum_type(['default', 'sarif']), help="Set diagnostics format.") | ||
|
|
||
| with self.argument_context('bicep snapshot') as c: | ||
| c.argument('file', arg_type=bicep_file_type, help="The path to the .bicepparam file to capture a snapshot for.") | ||
| c.argument('mode', arg_type=get_enum_type(['Overwrite', 'Validate']), | ||
| help="The snapshot mode. 'Overwrite' (default) writes the snapshot file. 'Validate' compares the existing snapshot against the current template and fails if differences are detected.") | ||
| c.argument('tenant_id', options_list=['--tenant-id'], help="The Azure tenant ID to use when capturing the snapshot.") | ||
| c.argument('subscription_id', options_list=['--subscription-id'], help="The Azure subscription ID to use when capturing the snapshot.") | ||
| c.argument('management_group_id', options_list=['--management-group-id'], help="The Azure management group ID to use when capturing the snapshot.") | ||
| c.argument('location', options_list=['--location'], help="The Azure location to use when capturing the snapshot.") | ||
| c.argument('resource_group', options_list=['--resource-group'], help="The Azure resource group name to use when capturing the snapshot.") | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in d88079b — switched |
||
| c.argument('deployment_name', options_list=['--deployment-name'], help="The deployment name to use when capturing the snapshot.") | ||
|
|
||
| with self.argument_context('bicep run') as c: | ||
| c.argument('command_string', options_list=['--command', '-c'], | ||
| help="The Bicep CLI command to run, including its arguments, as a single quoted string (e.g. \"build main.bicep\").") | ||
|
|
||
| with self.argument_context('resourcemanagement private-link create') as c: | ||
| c.argument('resource_group', arg_type=resource_group_name_type, | ||
| help='The name of the resource group.') | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4580,6 +4580,58 @@ def lint_bicep_file(cmd, file, no_restore=None, diagnostics_format=None): | |
| logger.error("az bicep lint could not be executed with the current version of Bicep CLI. Please upgrade Bicep CLI to v%s or later.", minimum_supported_version) | ||
|
|
||
|
|
||
| def snapshot_bicep_file(cmd, file, mode=None, tenant_id=None, subscription_id=None, | ||
| management_group_id=None, location=None, resource_group=None, | ||
| deployment_name=None): | ||
| ensure_bicep_installation(cmd.cli_ctx, stdout=False) | ||
|
|
||
| minimum_supported_version = "0.41.2" | ||
| if bicep_version_greater_than_or_equal_to(cmd.cli_ctx, minimum_supported_version): | ||
| args = ["snapshot", file] | ||
| if mode: | ||
| args += ["--mode", mode] | ||
| if tenant_id: | ||
| args += ["--tenant-id", tenant_id] | ||
| if subscription_id: | ||
| args += ["--subscription-id", subscription_id] | ||
| if management_group_id: | ||
| args += ["--management-group-id", management_group_id] | ||
| if location: | ||
| args += ["--location", location] | ||
| if resource_group: | ||
| args += ["--resource-group", resource_group] | ||
| if deployment_name: | ||
| args += ["--deployment-name", deployment_name] | ||
|
|
||
| output = run_bicep_command(cmd.cli_ctx, args) | ||
|
|
||
| if output: | ||
| print(output) | ||
| else: | ||
| logger.error("az bicep snapshot could not be executed with the current version of Bicep CLI. Please upgrade Bicep CLI to v%s or later.", minimum_supported_version) | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in d88079b — |
||
|
|
||
|
|
||
| def run_bicep_cli_passthrough(cmd, command_string): | ||
| import shlex | ||
|
Comment on lines
+4617
to
+4618
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
||
| # Use non-POSIX mode so that backslashes in Windows paths are preserved. | ||
| # In non-POSIX mode, shlex retains the surrounding quotes on quoted tokens, | ||
| # so strip them so the values are passed through cleanly to the Bicep CLI. | ||
| args = [] | ||
| for token in shlex.split(command_string, posix=False): | ||
|
Comment on lines
+4617
to
+4626
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in d88079b — |
||
| if len(token) >= 2 and token[0] in ('"', "'") and token[0] == token[-1]: | ||
| token = token[1:-1] | ||
| args.append(token) | ||
|
|
||
| if not args: | ||
| raise InvalidArgumentValueError("--command must not be empty.") | ||
|
|
||
| output = run_bicep_command(cmd.cli_ctx, args) | ||
|
|
||
| if output: | ||
| print(output) | ||
|
|
||
|
|
||
| def create_resourcemanager_privatelink( | ||
| cmd, resource_group, name, location): | ||
| rcf = _resource_privatelinks_client_factory(cmd.cli_ctx) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5669,6 +5669,68 @@ def test_bicep_lint_diagnostics_format_sarif(self): | |
|
|
||
| self.cmd('az bicep lint -f {tf} --diagnostics-format sarif') | ||
|
|
||
|
|
||
| class BicepSnapshotTest(LiveScenarioTest): | ||
| def setup(self): | ||
| super().setup() | ||
| self.cmd('az bicep uninstall') | ||
|
Comment on lines
+5673
to
+5676
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in d88079b — renamed both the method and the super() call to setUp in BicepSnapshotTest. |
||
|
|
||
| def tearDown(self): | ||
| super().tearDown() | ||
| self.cmd('az bicep uninstall') | ||
|
|
||
| def test_bicep_snapshot(self): | ||
| curr_dir = os.path.dirname(os.path.realpath(__file__)) | ||
| params_file = os.path.join(curr_dir, 'sample_params.bicepparam').replace('\\', '\\\\') | ||
| snapshot_path = os.path.join(curr_dir, 'sample_params.snapshot.json') | ||
|
Comment on lines
+5683
to
+5685
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The fixtures already exist in this directory and are reused by other Bicep tests (e.g. |
||
| self.kwargs.update({ | ||
| 'pf': params_file, | ||
| }) | ||
|
|
||
| try: | ||
| # Capture (default mode). | ||
| self.cmd('az bicep snapshot --file {pf}') | ||
| self.assertTrue(os.path.exists(snapshot_path)) | ||
|
|
||
| # Validate against the just-captured snapshot. | ||
| self.cmd('az bicep snapshot --file {pf} --mode Validate') | ||
| finally: | ||
| if os.path.exists(snapshot_path): | ||
| os.remove(snapshot_path) | ||
|
|
||
|
|
||
| class BicepRunTest(LiveScenarioTest): | ||
| def setup(self): | ||
| super().setup() | ||
| self.cmd('az bicep uninstall') | ||
|
Comment on lines
+5702
to
+5705
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in d88079b — same correction applied to BicepRunTest. |
||
|
|
||
| def tearDown(self): | ||
| super().tearDown() | ||
| self.cmd('az bicep uninstall') | ||
|
|
||
| def test_bicep_run_version(self): | ||
| # Ensure Bicep CLI is installed so the passthrough has something to call. | ||
| self.cmd('az bicep install') | ||
| # Use the --option=value form because the value itself starts with --, | ||
| # which argparse otherwise treats as another option flag. | ||
| self.cmd('az bicep run --command=--version') | ||
|
|
||
| def test_bicep_run_build(self): | ||
| curr_dir = os.path.dirname(os.path.realpath(__file__)) | ||
| bf = os.path.join(curr_dir, 'sample_params.bicep').replace('\\', '\\\\') | ||
| self.kwargs.update({ | ||
| 'bf': bf, | ||
| }) | ||
|
|
||
| self.cmd('az bicep install') | ||
| self.cmd('az bicep run --command "build {bf} --stdout"') | ||
|
|
||
| def test_bicep_run_empty_command_fails(self): | ||
| from azure.cli.core.azclierror import InvalidArgumentValueError | ||
| with self.assertRaises(InvalidArgumentValueError): | ||
| self.cmd('az bicep run --command " "') | ||
|
|
||
|
|
||
| class BicepInstallationTest(LiveScenarioTest): | ||
| def setup(self): | ||
| super().setup() | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clarified in d88079b by expanding the
--helptext for--tenant-id,--subscription-id,--management-group-id,--location,--resource-group, and--deployment-nameto call out that they are forwarded to the Bicep CLI as the deployment context used to resolveexistingreferences in the snapshot, and are unrelated to Azure CLI authentication. The help for--subscription-idalso explicitly points users to the global--subscriptionargument for switching the active subscription.We intentionally kept the names aligned with
bicep snapshot's native flags so that users coming from the Bicep CLI don't have to learn a new vocabulary. Happy to revisit (e.g.--snapshot-subscription-id) if you'd prefer the rename.