Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/quantum/azext_quantum/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@
- name: Get the list of Azure Quantum workspaces available
text: |-
az quantum workspace list
- name: Create a new Azure Quantum workspace
text: |-
az quantum workspace create -g MyResourceGroup -w MyWorkspace -l MyLocation -sa MyStorageAccountName
- name: Delete an Azure Quantum workspace that is no longer being used
text: |-
az quantum workspace delete -g MyResourceGroup -w MyWorkspace
Expand Down
2 changes: 2 additions & 0 deletions src/quantum/azext_quantum/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

def load_arguments(self, _):
workspace_name_type = CLIArgumentType(options_list=['--workspace-name', '-w'], help='Name of the Quantum Workspace. You can configure the default workspace using `az quantum workspace set`.', id_part=None, required=False)
storage_account_name_type = CLIArgumentType(options_list=['--storage_account', '-sa'], help='Name of the storage account to be used by a quantum workspace.')
program_args_type = CLIArgumentType(nargs='*', help='List of arguments expected by the Q# operation specified as --name=value after `--`.')
target_id_type = CLIArgumentType(options_list=['--target-id', '-t'], help='Target id.')
project_type = CLIArgumentType(help='The location of the Q# project to submit. Defaults to current folder.')
Expand All @@ -19,6 +20,7 @@ def load_arguments(self, _):

with self.argument_context('quantum workspace') as c:
c.argument('workspace_name', workspace_name_type)
c.argument('storage_account', storage_account_name_type)

with self.argument_context('quantum target') as c:
c.argument('workspace_name', workspace_name_type)
Expand Down
1 change: 1 addition & 0 deletions src/quantum/azext_quantum/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ def load_command_table(self, _):
target_ops = CliCommandType(operations_tmpl='azext_quantum.operations.target#{}')

with self.command_group('quantum workspace', workspace_ops) as w:
w.command('create', 'create')
w.command('delete', 'delete', validator=validate_workspace_info)
w.command('list', 'list')
w.command('show', 'show', validator=validate_workspace_info)
Expand Down
36 changes: 36 additions & 0 deletions src/quantum/azext_quantum/operations/workspace.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
from knack.util import CLIError

from .._client_factory import cf_workspaces
from ..vendored_sdks.azure_mgmt_quantum.models import QuantumWorkspace
from ..vendored_sdks.azure_mgmt_quantum.models import QuantumWorkspaceIdentity
from ..vendored_sdks.azure_mgmt_quantum.models import Provider


class WorkspaceInfo(object):
Expand Down Expand Up @@ -43,6 +46,39 @@ def save(self, cmd):
cmd.cli_ctx.config.set_value('quantum', 'group', self.resource_group)
cmd.cli_ctx.config.set_value('quantum', 'workspace', self.name)

def get_basic_quantum_workspace(location, info, storage_account):
qw = QuantumWorkspace()
# Use a default provider
# Replace this with user specified providers as part of task:
# https://ms-quantum.visualstudio.com/Quantum%20Program/_workitems/edit/16184
prov = Provider()
prov.provider_id = "Microsoft"
prov.provider_sku = "Basic"
qw.providers = [prov]
# Allow the system to assign the workspace identity
qw.identity = QuantumWorkspaceIdentity()
qw.identity.type = "SystemAssigned"
qw.location = location
qw.storage_account = f"/subscriptions/{info.subscription}/resourceGroups/{info.resource_group}/providers/Microsoft.Storage/storageAccounts/{storage_account}"
return qw


def create(cmd, resource_group_name=None, workspace_name=None, location=None, storage_account=None):
"""
Creates a new Azure Quantum workspace.
"""
client = cf_workspaces(cmd.cli_ctx)
if (not workspace_name):
raise CLIError("An explicit workspace name is required for this command.")
if (not storage_account):
raise CLIError("A quantum workspace requires a valid storage account.")
info = WorkspaceInfo(cmd, resource_group_name, workspace_name)
if (not info.resource_group):
raise CLIError("Please run 'az quantum workspace set' first to select a default Quantum Workspace.")
quantum_workspace = get_basic_quantum_workspace(location, info, storage_account)
return client.create_and_update(info.resource_group, info.name, quantum_workspace, polling=False)


def delete(cmd, resource_group_name=None, workspace_name=None):
"""
Deletes the given (or current) Azure Quantum workspace.
Expand Down
15 changes: 10 additions & 5 deletions src/quantum/azext_quantum/tests/latest/test_quantum_workspace.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,14 @@ def test_workspace(self):
# clear
self.cmd(f'az quantum workspace clear')

# create
self.cmd(f'az quantum workspace create -g {TEST_RG} -w {TEST_WORKSPACE_CREATE_DELETE} -l {TEST_WORKSPACE_LOCATION} -sa {TEST_WORKSPACE_SA} -o json'), checks=[
self.check("name", TEST_WORKSPACE_CREATE_DELETE),
self.check("provisioningState", "Succeeded")
])

# delete
## TODO: This test is disabled until the 'create' command is added.
# self.cmd(f'az quantum workspace delete -g {TEST_RG} -w {TEST_WORKSPACE_CREATE_DELETE} -o json'), checks=[
# self.check("name", TEST_WORKSPACE_CREATE_DELETE),
# self.check("provisioningState", )
#])
self.cmd(f'az quantum workspace delete -g {TEST_RG} -w {TEST_WORKSPACE_CREATE_DELETE} -o json'), checks=[
self.check("name", TEST_WORKSPACE_CREATE_DELETE),
self.check("provisioningState", "Deleting")
])
2 changes: 2 additions & 0 deletions src/quantum/azext_quantum/tests/latest/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
TEST_RG = 'aqua-provider-validator'
TEST_WORKSPACE = 'validator-workspace-westus'
TEST_WORKSPACE_CREATE_DELETE = 'validator-workspace-crdl-westus'
TEST_WORKSPACE_SA = 'aqvalidatorstorage'
TEST_WORKSPACE_LOCATION = 'westus'


def is_private_preview_subscription(scenario):
Expand Down