Skip to content

Commit 714e2e8

Browse files
Srinivas ThatipamulaCopilot
andcommitted
Address PR review feedback: GUID-only refactor, pagination, record simplifications, description fixes
- Refactor 12 OneLake security/shortcut/settings commands to GUID-only (workspace-id, item-id) - Add pagination support (continuationToken) for list_data_access_roles and list_shortcuts - Simplify result classes to sealed records - Use new(...) shorthand for ResponseResult.Create calls - Remove cross-tool name references from descriptions - Remove CLI formatting from shortcut conflict policy description Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 8909037 commit 714e2e8

34 files changed

Lines changed: 179 additions & 474 deletions

tools/Fabric.Mcp.Tools.OneLake/README.md

Lines changed: 51 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,10 @@ You can verify which environment you're targeting by checking the endpoints in t
9898

9999
### Workspace and Item Identifiers
100100

101-
All commands accept either GUID identifiers or friendly names via the `--workspace` and `--item` options. The existing `--workspace-id` and `--item-id` switches remain available for scripts that already depend on them. Friendly-name inputs are sent directly to the OneLake APIs without local GUID resolution; when using names, specify the item as `<itemName>.<itemType>` (for example, `SalesLakehouse.lakehouse`). Table-based commands additionally accept schema identifiers through `--namespace` or its alias `--schema`.
101+
The Fabric Core REST APIs used by the Security, Shortcuts, and Settings commands require GUID identifiers. Use `--workspace-id` for workspace scope and `--item-id` for item scope. Table-based commands additionally accept schema identifiers through `--namespace` or its alias `--schema`.
102102

103103
```bash
104-
dotnet run -- onelake file list --workspace "Analytics Workspace" --item "SalesLakehouse.lakehouse" --path "Files"
104+
dotnet run -- onelake shortcut list --workspace-id "47242da5-ff3b-46fb-a94f-977909b773d5" --item-id "0e67ed13-2bb6-49be-9c87-a1105a4ea342"
105105
```
106106

107107
## Available Commands
@@ -632,53 +632,54 @@ These tools manage role-based data access policies on OneLake items (Lakehouse /
632632

633633
#### List Data Access Roles
634634

635-
Lists all data access roles defined on a single item.
635+
Lists all data access roles defined on a single item. Supports pagination via `--continuation-token`.
636636

637637
```bash
638-
dotnet run -- onelake security list --workspace "Analytics Workspace" --item "SalesLakehouse.lakehouse"
638+
dotnet run -- onelake security list --workspace-id "47242da5-ff3b-46fb-a94f-977909b773d5" --item-id "0e67ed13-2bb6-49be-9c87-a1105a4ea342"
639639
```
640640

641641
**Parameters:**
642-
- `--workspace`/`--workspace-id`: Workspace identifier
643-
- `--item`/`--item-id`: Item identifier
642+
- `--workspace-id`: Workspace ID (GUID)
643+
- `--item-id`: Item ID (GUID)
644+
- `--continuation-token`: (Optional) Token for retrieving the next page of results
644645

645646
#### Get Data Access Role
646647

647648
Gets the full definition of a single data access role — members, permissions, decision rules.
648649

649650
```bash
650-
dotnet run -- onelake security get --workspace "Analytics Workspace" --item "SalesLakehouse.lakehouse" --role-name "DataAnalysts"
651+
dotnet run -- onelake security get --workspace-id "47242da5-ff3b-46fb-a94f-977909b773d5" --item-id "0e67ed13-2bb6-49be-9c87-a1105a4ea342" --role-name "DataAnalysts"
651652
```
652653

653654
**Parameters:**
654-
- `--workspace`/`--workspace-id`: Workspace identifier
655-
- `--item`/`--item-id`: Item identifier
655+
- `--workspace-id`: Workspace ID (GUID)
656+
- `--item-id`: Item ID (GUID)
656657
- `--role-name`: Name of the data access role to retrieve
657658

658659
#### Create or Update Data Access Role
659660

660661
Upserts a single data access role on a single item. Scoped to one role per call — does not affect other roles. The role name is derived from the `name` field in the JSON definition.
661662

662663
```bash
663-
dotnet run -- onelake security create-or-update --workspace "Analytics Workspace" --item "SalesLakehouse.lakehouse" --role-definition '{"name":"DataAnalysts","members":{"fabricItemMembers":[{"itemAccessType":"ReadAll"}]},"decisionRules":[{"effect":"Permit","permission":[{"attributeName":"Path","attributeValueIncludedIn":["Tables/*"]}]}]}'
664+
dotnet run -- onelake security create-or-update --workspace-id "47242da5-ff3b-46fb-a94f-977909b773d5" --item-id "0e67ed13-2bb6-49be-9c87-a1105a4ea342" --role-definition '{"name":"DataAnalysts","members":{"fabricItemMembers":[{"itemAccessType":"ReadAll"}]},"decisionRules":[{"effect":"Permit","permission":[{"attributeName":"Path","attributeValueIncludedIn":["Tables/*"]}]}]}'
664665
```
665666

666667
**Parameters:**
667-
- `--workspace`/`--workspace-id`: Workspace identifier
668-
- `--item`/`--item-id`: Item identifier
668+
- `--workspace-id`: Workspace ID (GUID)
669+
- `--item-id`: Item ID (GUID)
669670
- `--role-definition`: JSON definition of the role (must include `name`, `members`, and `decisionRules`)
670671

671672
#### Delete Data Access Role
672673

673674
Deletes a single data access role from a single item. Destructive — principals that gained access only via this role lose it.
674675

675676
```bash
676-
dotnet run -- onelake security delete --workspace "Analytics Workspace" --item "SalesLakehouse.lakehouse" --role-name "TempRole"
677+
dotnet run -- onelake security delete --workspace-id "47242da5-ff3b-46fb-a94f-977909b773d5" --item-id "0e67ed13-2bb6-49be-9c87-a1105a4ea342" --role-name "TempRole"
677678
```
678679

679680
**Parameters:**
680-
- `--workspace`/`--workspace-id`: Workspace identifier
681-
- `--item`/`--item-id`: Item identifier
681+
- `--workspace-id`: Workspace ID (GUID)
682+
- `--item-id`: Item ID (GUID)
682683
- `--role-name`: Name of the data access role to delete
683684

684685
### Shortcut Operations
@@ -687,28 +688,29 @@ Shortcuts are references to data stored in external or internal locations (ADLS
687688

688689
#### List Shortcuts
689690

690-
Lists shortcuts defined within an item, recursing through subfolders.
691+
Lists shortcuts defined within an item, recursing through subfolders. Supports pagination via `--continuation-token`.
691692

692693
```bash
693-
dotnet run -- onelake shortcut list --workspace "Analytics Workspace" --item "SalesLakehouse.lakehouse"
694+
dotnet run -- onelake shortcut list --workspace-id "47242da5-ff3b-46fb-a94f-977909b773d5" --item-id "0e67ed13-2bb6-49be-9c87-a1105a4ea342"
694695
```
695696

696697
**Parameters:**
697-
- `--workspace`/`--workspace-id`: Workspace identifier
698-
- `--item`/`--item-id`: Item identifier
698+
- `--workspace-id`: Workspace ID (GUID)
699+
- `--item-id`: Item ID (GUID)
699700
- `--parent-path`: (Optional) Parent path to scope the listing
701+
- `--continuation-token`: (Optional) Token for retrieving the next page of results
700702

701703
#### Get Shortcut
702704

703705
Gets the properties of a single shortcut (name, path, target, configuration).
704706

705707
```bash
706-
dotnet run -- onelake shortcut get --workspace "Analytics Workspace" --item "SalesLakehouse.lakehouse" --shortcut-name "ExternalData" --shortcut-path "Tables/ExternalData"
708+
dotnet run -- onelake shortcut get --workspace-id "47242da5-ff3b-46fb-a94f-977909b773d5" --item-id "0e67ed13-2bb6-49be-9c87-a1105a4ea342" --shortcut-name "ExternalData" --shortcut-path "Tables/ExternalData"
707709
```
708710

709711
**Parameters:**
710-
- `--workspace`/`--workspace-id`: Workspace identifier
711-
- `--item`/`--item-id`: Item identifier
712+
- `--workspace-id`: Workspace ID (GUID)
713+
- `--item-id`: Item ID (GUID)
712714
- `--shortcut-name`: Name of the shortcut
713715
- `--shortcut-path`: Path of the shortcut within the item
714716

@@ -717,12 +719,12 @@ dotnet run -- onelake shortcut get --workspace "Analytics Workspace" --item "Sal
717719
Creates one or more shortcuts in a single call. Pass `--create-or-overwrite` to upsert (default fails on conflict).
718720

719721
```bash
720-
dotnet run -- onelake shortcut create-or-update --workspace "Analytics Workspace" --item "SalesLakehouse.lakehouse" --shortcuts '[{"name":"ExternalData","path":"Tables/ExternalData","target":{"adlsGen2":{"location":"https://storageaccount.dfs.core.windows.net","subpath":"/container/path"}}}]'
722+
dotnet run -- onelake shortcut create-or-update --workspace-id "47242da5-ff3b-46fb-a94f-977909b773d5" --item-id "0e67ed13-2bb6-49be-9c87-a1105a4ea342" --shortcuts '[{"name":"ExternalData","path":"Tables/ExternalData","target":{"adlsGen2":{"location":"https://storageaccount.dfs.core.windows.net","subpath":"/container/path"}}}]'
721723
```
722724

723725
**Parameters:**
724-
- `--workspace`/`--workspace-id`: Workspace identifier
725-
- `--item`/`--item-id`: Item identifier
726+
- `--workspace-id`: Workspace ID (GUID)
727+
- `--item-id`: Item ID (GUID)
726728
- `--shortcuts`: JSON array of shortcut definitions
727729
- `--create-or-overwrite`: (Optional) If set, overwrites existing shortcuts
728730

@@ -731,26 +733,25 @@ dotnet run -- onelake shortcut create-or-update --workspace "Analytics Workspace
731733
Deletes a single shortcut from an item. The destination data is preserved — only the shortcut reference is removed.
732734

733735
```bash
734-
dotnet run -- onelake shortcut delete --workspace "Analytics Workspace" --item "SalesLakehouse.lakehouse" --shortcut-name "ExternalData" --shortcut-path "Tables/ExternalData"
736+
dotnet run -- onelake shortcut delete --workspace-id "47242da5-ff3b-46fb-a94f-977909b773d5" --item-id "0e67ed13-2bb6-49be-9c87-a1105a4ea342" --shortcut-name "ExternalData" --shortcut-path "Tables/ExternalData"
735737
```
736738

737739
**Parameters:**
738-
- `--workspace`/`--workspace-id`: Workspace identifier
739-
- `--item`/`--item-id`: Item identifier
740+
- `--workspace-id`: Workspace ID (GUID)
741+
- `--item-id`: Item ID (GUID)
740742
- `--shortcut-name`: Name of the shortcut to delete
741743
- `--shortcut-path`: Path of the shortcut
742744

743745
#### Reset Shortcut Cache
744746

745-
Drops cached shortcut reads for an item, forcing the next read to re-resolve from the destination. Use sparingly — primarily for debugging stale-cache issues.
747+
Drops cached shortcut reads for a workspace, forcing the next read to re-resolve from the destination. Use sparingly — primarily for debugging stale-cache issues.
746748

747749
```bash
748-
dotnet run -- onelake shortcut reset-cache --workspace "Analytics Workspace" --item "SalesLakehouse.lakehouse"
750+
dotnet run -- onelake shortcut reset-cache --workspace-id "47242da5-ff3b-46fb-a94f-977909b773d5"
749751
```
750752

751753
**Parameters:**
752-
- `--workspace`/`--workspace-id`: Workspace identifier
753-
- `--item`/`--item-id`: Item identifier
754+
- `--workspace-id`: Workspace ID (GUID)
754755

755756
### Settings Operations
756757

@@ -761,34 +762,34 @@ Workspace-level OneLake settings for diagnostics and immutability policies. Thes
761762
Gets the OneLake settings for a workspace — diagnostics configuration and immutability policy.
762763

763764
```bash
764-
dotnet run -- onelake settings get --workspace "Analytics Workspace"
765+
dotnet run -- onelake settings get --workspace-id "47242da5-ff3b-46fb-a94f-977909b773d5"
765766
```
766767

767768
**Parameters:**
768-
- `--workspace`/`--workspace-id`: Workspace identifier
769+
- `--workspace-id`: Workspace ID (GUID)
769770

770771
#### Modify Diagnostics
771772

772773
Modifies the diagnostic logging configuration for OneLake at the workspace scope. Replaces the existing diagnostics block; fetch with `get settings` first if you want to merge.
773774

774775
```bash
775-
dotnet run -- onelake settings modify-diagnostics --workspace "Analytics Workspace" --diagnostics-config '{"logAnalyticsWorkspaceId":"<workspace-id>","level":"Verbose"}'
776+
dotnet run -- onelake settings modify-diagnostics --workspace-id "47242da5-ff3b-46fb-a94f-977909b773d5" --diagnostics-config '{"logAnalyticsWorkspaceId":"<workspace-id>","level":"Verbose"}'
776777
```
777778

778779
**Parameters:**
779-
- `--workspace`/`--workspace-id`: Workspace identifier
780+
- `--workspace-id`: Workspace ID (GUID)
780781
- `--diagnostics-config`: JSON configuration for diagnostic settings
781782

782783
#### Modify Immutability Policy
783784

784785
Modifies the workspace-level OneLake immutability policy. **Warning:** Once enabled, immutability cannot be disabled — confirm with the user before applying.
785786

786787
```bash
787-
dotnet run -- onelake settings modify-immutability --workspace "Analytics Workspace" --immutability-policy '{"state":"Enabled"}'
788+
dotnet run -- onelake settings modify-immutability --workspace-id "47242da5-ff3b-46fb-a94f-977909b773d5" --immutability-policy '{"state":"Enabled"}'
788789
```
789790

790791
**Parameters:**
791-
- `--workspace`/`--workspace-id`: Workspace identifier
792+
- `--workspace-id`: Workspace ID (GUID)
792793
- `--immutability-policy`: JSON immutability policy configuration
793794

794795
## Quick Reference - fabmcp.exe Commands
@@ -864,43 +865,43 @@ fabmcp.exe onelake table get --workspace "Analytics Workspace" --item "SalesLake
864865
### Security Operations
865866
```cmd
866867
# List data access roles on an item
867-
fabmcp.exe onelake security list --workspace "47242da5-ff3b-46fb-a94f-977909b773d5" --item "0e67ed13-2bb6-49be-9c87-a1105a4ea342"
868+
fabmcp.exe onelake security list --workspace-id "47242da5-ff3b-46fb-a94f-977909b773d5" --item-id "0e67ed13-2bb6-49be-9c87-a1105a4ea342"
868869
869870
# Get a specific role definition
870-
fabmcp.exe onelake security get --workspace "47242da5-ff3b-46fb-a94f-977909b773d5" --item "0e67ed13-2bb6-49be-9c87-a1105a4ea342" --role-name "DataAnalysts"
871+
fabmcp.exe onelake security get --workspace-id "47242da5-ff3b-46fb-a94f-977909b773d5" --item-id "0e67ed13-2bb6-49be-9c87-a1105a4ea342" --role-name "DataAnalysts"
871872
872873
# Delete a data access role
873-
fabmcp.exe onelake security delete --workspace "47242da5-ff3b-46fb-a94f-977909b773d5" --item "0e67ed13-2bb6-49be-9c87-a1105a4ea342" --role-name "TempRole"
874+
fabmcp.exe onelake security delete --workspace-id "47242da5-ff3b-46fb-a94f-977909b773d5" --item-id "0e67ed13-2bb6-49be-9c87-a1105a4ea342" --role-name "TempRole"
874875
```
875876

876877
### Shortcut Operations
877878
```cmd
878879
# List shortcuts on an item
879-
fabmcp.exe onelake shortcut list --workspace "47242da5-ff3b-46fb-a94f-977909b773d5" --item "0e67ed13-2bb6-49be-9c87-a1105a4ea342"
880+
fabmcp.exe onelake shortcut list --workspace-id "47242da5-ff3b-46fb-a94f-977909b773d5" --item-id "0e67ed13-2bb6-49be-9c87-a1105a4ea342"
880881
881882
# Get a specific shortcut
882-
fabmcp.exe onelake shortcut get --workspace "47242da5-ff3b-46fb-a94f-977909b773d5" --item "0e67ed13-2bb6-49be-9c87-a1105a4ea342" --shortcut-name "ExternalData" --shortcut-path "Tables/ExternalData"
883+
fabmcp.exe onelake shortcut get --workspace-id "47242da5-ff3b-46fb-a94f-977909b773d5" --item-id "0e67ed13-2bb6-49be-9c87-a1105a4ea342" --shortcut-name "ExternalData" --shortcut-path "Tables/ExternalData"
883884
884885
# Delete a shortcut
885-
fabmcp.exe onelake shortcut delete --workspace "47242da5-ff3b-46fb-a94f-977909b773d5" --item "0e67ed13-2bb6-49be-9c87-a1105a4ea342" --shortcut-name "ExternalData" --shortcut-path "Tables/ExternalData"
886+
fabmcp.exe onelake shortcut delete --workspace-id "47242da5-ff3b-46fb-a94f-977909b773d5" --item-id "0e67ed13-2bb6-49be-9c87-a1105a4ea342" --shortcut-name "ExternalData" --shortcut-path "Tables/ExternalData"
886887
887888
# Reset shortcut cache
888-
fabmcp.exe onelake shortcut reset-cache --workspace "47242da5-ff3b-46fb-a94f-977909b773d5" --item "0e67ed13-2bb6-49be-9c87-a1105a4ea342"
889+
fabmcp.exe onelake shortcut reset-cache --workspace-id "47242da5-ff3b-46fb-a94f-977909b773d5"
889890
```
890891

891892
### Settings Operations
892893
```cmd
893894
# Get workspace OneLake settings
894-
fabmcp.exe onelake settings get --workspace "47242da5-ff3b-46fb-a94f-977909b773d5"
895+
fabmcp.exe onelake settings get --workspace-id "47242da5-ff3b-46fb-a94f-977909b773d5"
895896
896897
# Modify diagnostics configuration
897-
fabmcp.exe onelake settings modify-diagnostics --workspace "47242da5-ff3b-46fb-a94f-977909b773d5" --diagnostics-config '{"logAnalyticsWorkspaceId":"<id>","level":"Verbose"}'
898+
fabmcp.exe onelake settings modify-diagnostics --workspace-id "47242da5-ff3b-46fb-a94f-977909b773d5" --diagnostics-config '{"logAnalyticsWorkspaceId":"<id>","level":"Verbose"}'
898899
899900
# Modify immutability policy
900-
fabmcp.exe onelake settings modify-immutability --workspace "47242da5-ff3b-46fb-a94f-977909b773d5" --immutability-policy '{"state":"Enabled"}'
901+
fabmcp.exe onelake settings modify-immutability --workspace-id "47242da5-ff3b-46fb-a94f-977909b773d5" --immutability-policy '{"state":"Enabled"}'
901902
```
902903

903-
**Note:** Replace the workspace identifier (`47242da5-ff3b-46fb-a94f-977909b773d5`) and item identifier (`0e67ed13-2bb6-49be-9c87-a1105a4ea342`) with your actual Fabric workspace and item values (names or IDs).
904+
**Note:** Replace the workspace ID (`47242da5-ff3b-46fb-a94f-977909b773d5`) and item ID (`0e67ed13-2bb6-49be-9c87-a1105a4ea342`) with your actual Fabric GUIDs.
904905

905906
## Common Usage Patterns
906907

@@ -1064,4 +1065,4 @@ The test suite includes examples of testable service architecture patterns follo
10641065
- Follow the established command patterns (see existing commands as examples)
10651066
- Use proper error handling with meaningful HTTP status codes
10661067
- Include comprehensive parameter validation
1067-
- Write tests that verify both success and error scenarios
1068+
- Write tests that verify both success and error scenarios

tools/Fabric.Mcp.Tools.OneLake/src/Commands/Security/DataAccessRoleCreateOrUpdateCommand.cs

Lines changed: 5 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -40,37 +40,16 @@ public sealed class DataAccessRoleCreateOrUpdateCommand(
4040
protected override void RegisterOptions(Command command)
4141
{
4242
base.RegisterOptions(command);
43-
command.Options.Add(FabricOptionDefinitions.WorkspaceId.AsOptional());
44-
command.Options.Add(FabricOptionDefinitions.Workspace.AsOptional());
45-
command.Options.Add(FabricOptionDefinitions.ItemId.AsOptional());
46-
command.Options.Add(FabricOptionDefinitions.Item.AsOptional());
43+
command.Options.Add(FabricOptionDefinitions.WorkspaceId.AsRequired());
44+
command.Options.Add(FabricOptionDefinitions.ItemId.AsRequired());
4745
command.Options.Add(FabricOptionDefinitions.RoleDefinition.AsRequired());
48-
command.Validators.Add(result =>
49-
{
50-
var workspaceId = result.GetValueOrDefault<string>(FabricOptionDefinitions.WorkspaceId.Name);
51-
var workspace = result.GetValueOrDefault<string>(FabricOptionDefinitions.Workspace.Name);
52-
var itemId = result.GetValueOrDefault<string>(FabricOptionDefinitions.ItemId.Name);
53-
var item = result.GetValueOrDefault<string>(FabricOptionDefinitions.Item.Name);
54-
55-
if (string.IsNullOrWhiteSpace(workspaceId) && string.IsNullOrWhiteSpace(workspace))
56-
{
57-
result.AddError("Workspace identifier is required. Provide --workspace or --workspace-id.");
58-
}
59-
60-
if (string.IsNullOrWhiteSpace(item) && string.IsNullOrWhiteSpace(itemId))
61-
{
62-
result.AddError("Item identifier is required. Provide --item or --item-id.");
63-
}
64-
});
6546
}
6647

6748
protected override DataAccessRoleCreateOrUpdateOptions BindOptions(ParseResult parseResult)
6849
{
6950
var options = base.BindOptions(parseResult);
7051
options.WorkspaceId = parseResult.GetValueOrDefault<string>(FabricOptionDefinitions.WorkspaceId.Name);
71-
options.Workspace = parseResult.GetValueOrDefault<string>(FabricOptionDefinitions.Workspace.Name);
7252
options.ItemId = parseResult.GetValueOrDefault<string>(FabricOptionDefinitions.ItemId.Name);
73-
options.Item = parseResult.GetValueOrDefault<string>(FabricOptionDefinitions.Item.Name);
7453
options.RoleDefinition = parseResult.GetValueOrDefault<string>(FabricOptionDefinitions.RoleDefinition.Name);
7554
return options;
7655
}
@@ -85,24 +64,19 @@ public override async Task<CommandResponse> ExecuteAsync(CommandContext context,
8564
var options = BindOptions(parseResult);
8665
try
8766
{
88-
var workspaceIdentifier = !string.IsNullOrWhiteSpace(options.WorkspaceId)
89-
? options.WorkspaceId
90-
: options.Workspace;
9167

92-
var itemIdentifier = !string.IsNullOrWhiteSpace(options.ItemId)
93-
? options.ItemId
94-
: options.Item;
9568

96-
var result = await _oneLakeService.CreateOrUpdateDataAccessRoleAsync(workspaceIdentifier!, itemIdentifier!, options.RoleDefinition!, cancellationToken);
69+
var result = await _oneLakeService.CreateOrUpdateDataAccessRoleAsync(options.WorkspaceId!, options.ItemId!, options.RoleDefinition!, cancellationToken);
9770
context.Response.Results = ResponseResult.Create(result, OneLakeJsonContext.Default.DataAccessRole);
9871
}
9972
catch (Exception ex)
10073
{
10174
_logger.LogError(ex, "Error creating/updating data access role. Workspace: {Workspace}, Item: {Item}.",
102-
options.WorkspaceId ?? options.Workspace, options.ItemId ?? options.Item);
75+
options.WorkspaceId, options.ItemId);
10376
HandleException(context, ex);
10477
}
10578

10679
return context.Response;
10780
}
10881
}
82+

0 commit comments

Comments
 (0)