diff --git a/src/Storage/Storage.Management.Test/ScenarioTests/StorageDataPlaneTests.ps1 b/src/Storage/Storage.Management.Test/ScenarioTests/StorageDataPlaneTests.ps1 index 0ba0aec2c245..8ee3d115becb 100644 --- a/src/Storage/Storage.Management.Test/ScenarioTests/StorageDataPlaneTests.ps1 +++ b/src/Storage/Storage.Management.Test/ScenarioTests/StorageDataPlaneTests.ps1 @@ -854,7 +854,9 @@ function Test-DatalakeGen2 $dir1 = New-AzDataLakeGen2Item -Context $storageContext -FileSystem $filesystemName -Path $directoryPath1 -Directory -Permission rwxrwxrwx -Umask ---rwx--- -Property @{"ContentEncoding" = "UDF8"; "CacheControl" = "READ"} -Metadata @{"tag1" = "value1"; "tag2" = "value2" } Assert-AreEqual $dir1.Path $directoryPath1 Assert-AreEqual $dir1.Permissions.ToSymbolicPermissions() "rwx---rwx" - $dir2 = New-AzDataLakeGen2Item -Context $storageContext -FileSystem $filesystemName -Path $directoryPath2 -Directory + $dir2 = New-AzDataLakeGen2Item -Context $storageContext -FileSystem $filesystemName -Path $directoryPath2 -Directory -Permission r---wx-wT -Umask --x-wx--x + Assert-AreEqual $dir2.Path $directoryPath2 + Assert-AreEqual $dir2.Permissions.ToSymbolicPermissions() "r------wT" # Create (upload) File $t = New-AzDataLakeGen2Item -Context $storageContext -FileSystem $filesystemName -Path $filePath1 -Source $localSrcFile -Force -AsJob @@ -874,20 +876,20 @@ function Test-DatalakeGen2 ## create ACL with 3 ACEs $acl = New-AzDataLakeGen2ItemAclObject -AccessControlType user -Permission rw- $acl = New-AzDataLakeGen2ItemAclObject -AccessControlType group -Permission rw- -InputObject $acl - $acl = New-AzDataLakeGen2ItemAclObject -AccessControlType other -Permission "-wx" -InputObject $acl + $acl = New-AzDataLakeGen2ItemAclObject -AccessControlType other -Permission "-wt" -InputObject $acl ##Update File with pipeline $file1 = Get-AzDataLakeGen2Item -Context $storageContext -FileSystem $filesystemName -Path $filePath1 | Update-AzDataLakeGen2Item ` -Acl $acl ` -Property @{"ContentType" = $ContentType; "ContentMD5" = $ContentMD5} ` -Metadata @{"tag1" = "value1"; "tag2" = "value2" } ` - -Permission rw-rw--wx ` + -Permission rw-rw--wt ` -Owner '$superuser' ` -Group '$superuser' $sas = New-AzDataLakeGen2SasToken -FileSystem $filesystemName -Path $filePath1 -Permission rw -Context $storageContext $ctxsas = New-AzStorageContext -StorageAccountName $StorageAccountName -SasToken $sas $file1 = Get-AzDataLakeGen2Item -Context $ctxsas -FileSystem $filesystemName -Path $filePath1 Assert-AreEqual $file1.Path $filePath1 - Assert-AreEqual $file1.Permissions.ToSymbolicPermissions() "rw-rw--wx" + Assert-AreEqual $file1.Permissions.ToSymbolicPermissions() "rw-rw--wt" Assert-AreEqual $file1.Properties.ContentType $ContentType Assert-AreEqual $file1.Properties.Metadata.Count 2 Assert-AreEqual $file1.Owner '$superuser' diff --git a/src/Storage/Storage.Management.Test/Storage.Management.Test.csproj b/src/Storage/Storage.Management.Test/Storage.Management.Test.csproj index 0dfbecdf7239..1718f6949a14 100644 --- a/src/Storage/Storage.Management.Test/Storage.Management.Test.csproj +++ b/src/Storage/Storage.Management.Test/Storage.Management.Test.csproj @@ -11,10 +11,10 @@ - - - - + + + + diff --git a/src/Storage/Storage.Management/ChangeLog.md b/src/Storage/Storage.Management/ChangeLog.md index 7b0f41da69de..486e3e5581c8 100644 --- a/src/Storage/Storage.Management/ChangeLog.md +++ b/src/Storage/Storage.Management/ChangeLog.md @@ -18,6 +18,10 @@ - Additional information about change #1 --> ## Upcoming Release +* Added support for sticky bit + - `New-AzDataLakeGen2Item` + - `New-AzDataLakeGen2ACLObject` + - `Update-AzDataLakeGen2Item` * Added warning messages for an upcoming cmdlet breaking change - `New-AzStorageAccount` - `Set-AzStorageAccount` diff --git a/src/Storage/Storage.Management/help/New-AzDataLakeGen2Item.md b/src/Storage/Storage.Management/help/New-AzDataLakeGen2Item.md index 4eb552167673..00ee9e2b733b 100644 --- a/src/Storage/Storage.Management/help/New-AzDataLakeGen2Item.md +++ b/src/Storage/Storage.Management/help/New-AzDataLakeGen2Item.md @@ -36,15 +36,15 @@ This cmdlet only works if Hierarchical Namespace is enabled for the Storage acco ### Example 1: Create a directory with specified permission, Umask, properties, and metadata ```powershell -New-AzDataLakeGen2Item -FileSystem "testfilesystem" -Path "dir1/dir2/" -Directory -Permission rwxrwxrwx -Umask ---rw---- -Property @{"CacheControl" = "READ"; "ContentDisposition" = "True"} -Metadata @{"tag1" = "value1"; "tag2" = "value2" } +New-AzDataLakeGen2Item -FileSystem "testfilesystem" -Path "dir1/dir2/" -Directory -Permission rwxrwxrwT -Umask ---rw---- -Property @{"CacheControl" = "READ"; "ContentDisposition" = "True"} -Metadata @{"tag1" = "value1"; "tag2" = "value2" } ``` ```output - FileSystem Name: filesystem1 +FileSystem Name: filesystem1 Path IsDirectory Length LastModified Permissions Owner Group ---- ----------- ------ ------------ ----------- ----- ----- -dir1/dir2 True 2020-03-23 09:15:56Z rwx---rwx $superuser $superuser +dir1/dir2 True 2020-03-23 09:15:56Z rwx---rwT $superuser $superuser ``` This command creates a directory with specified Permission, Umask, properties, and metadata @@ -55,8 +55,9 @@ $task = New-AzDataLakeGen2Item -FileSystem "testfilesystem" -Path "dir1/dir2/fi $task | Wait-Job $task.Output ``` + ```output - FileSystem Name: filesystem1 +FileSystem Name: filesystem1 Path IsDirectory Length LastModified Permissions Owner Group ---- ----------- ------ ------------ ----------- ----- ----- @@ -204,9 +205,9 @@ Accept wildcard characters: False ``` ### -Permission -Sets POSIX access permissions for the file owner, the file owning group, and others. -Each class may be granted read, write, or execute permission. -Symbolic (rwxrw-rw-) is supported. +Sets POSIX access permissions for the file owner, the file owning group, and others. Each class may be granted read, write, or execute permission. Symbolic (rwxrw-rw-) is supported. +The sticky bit is also supported and its represented either by the letter t or T in the final character-place depending on whether the execution bit for the others category is set or unset respectively, +absence of t or T indicates sticky bit not set. ```yaml Type: System.String @@ -301,7 +302,7 @@ Accept wildcard characters: False ``` ### CommonParameters -This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216). +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS diff --git a/src/Storage/Storage.Management/help/Set-AzDataLakeGen2ItemAclObject.md b/src/Storage/Storage.Management/help/Set-AzDataLakeGen2ItemAclObject.md index 8e8aab9f06d2..caad92672759 100644 --- a/src/Storage/Storage.Management/help/Set-AzDataLakeGen2ItemAclObject.md +++ b/src/Storage/Storage.Management/help/Set-AzDataLakeGen2ItemAclObject.md @@ -32,7 +32,7 @@ Update-AzDataLakeGen2Item -FileSystem "filesystem1" -Path "dir1/dir3" -ACL $acl ``` ```output - FileSystem Name: filesystem1 +FileSystem Name: filesystem1 Path IsDirectory Length LastModified Permissions Owner Group ---- ----------- ------ ------------ ----------- ----- ----- @@ -43,10 +43,12 @@ This command creates an ACL object with 3 ACL entries (use -InputObject paramete ### Example 2: Create an ACL object with 4 ACL entries, and update permission of an existing ACL entry + + ``` PS C:\>$acl = Set-AzDataLakeGen2ItemAclObject -AccessControlType user -Permission rwx -DefaultScope PS C:\>$acl = Set-AzDataLakeGen2ItemAclObject -AccessControlType group -Permission rw- -InputObject $acl -PS C:\>$acl = Set-AzDataLakeGen2ItemAclObject -AccessControlType other -Permission "rw-" -InputObject $acl +PS C:\>$acl = Set-AzDataLakeGen2ItemAclObject -AccessControlType other -Permission "rwt" -InputObject $acl PS C:\>$acl = Set-AzDataLakeGen2ItemAclObject -AccessControlType user -EntityId $id -Permission rwx -InputObject $acl PS C:\>$acl @@ -54,7 +56,7 @@ DefaultScope AccessControlType EntityId Permissions ------------ ----------------- -------- ----------- True User rwx False Group rw- -False Other rw- +False Other rwt False User ********-****-****-****-************ rwx PS C:\>$acl = Set-AzDataLakeGen2ItemAclObject -AccessControlType user -EntityId $id -Permission r-x -InputObject $acl @@ -137,8 +139,10 @@ Accept wildcard characters: False ``` ### -Permission -The permission field is a 3-character sequence where the first character is 'r' to grant read access, the second character is 'w' to grant write access, and the third character is 'x' to grant execute permission. -If access is not granted, the '-' character is used to denote that the permission is denied. +The permission field is a 3-character sequence where the first character is 'r' to grant read access, the second character is 'w' to grant write access, and the third character is 'x' to grant execute permission. +If access is not granted, the '-' character is used to denote that the permission is denied. +The sticky bit is also supported and its represented either by the letter t or T in the final character-place depending on whether the execution bit for the others category is set or unset respectively, +absence of t or T indicates sticky bit not set. ```yaml Type: System.String @@ -153,7 +157,7 @@ Accept wildcard characters: False ``` ### CommonParameters -This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216). +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS diff --git a/src/Storage/Storage.Management/help/Update-AzDataLakeGen2Item.md b/src/Storage/Storage.Management/help/Update-AzDataLakeGen2Item.md index db6eb4157b34..1ada880ca5f2 100644 --- a/src/Storage/Storage.Management/help/Update-AzDataLakeGen2Item.md +++ b/src/Storage/Storage.Management/help/Update-AzDataLakeGen2Item.md @@ -38,24 +38,26 @@ This cmdlet only works if Hierarchical Namespace is enabled for the Storage acco ```powershell $acl = Set-AzDataLakeGen2ItemAclObject -AccessControlType user -Permission rwx $acl = Set-AzDataLakeGen2ItemAclObject -AccessControlType group -Permission rw- -InputObject $acl -$acl = Set-AzDataLakeGen2ItemAclObject -AccessControlType other -Permission "rw-" -InputObject $acl +$acl = Set-AzDataLakeGen2ItemAclObject -AccessControlType other -Permission "rwt" -InputObject $acl Get-AzDataLakeGen2ChildItem -FileSystem "filesystem1" -Recurse | Update-AzDataLakeGen2Item -ACL $acl ``` ```output - FileSystem Name: filesystem1 +FileSystem Name: filesystem1 Path IsDirectory Length LastModified Permissions Owner Group ---- ----------- ------ ------------ ----------- ----- ----- -dir1 True 2020-03-13 13:07:34Z rwxrw-rw- $superuser $superuser -dir1/file1 False 1024 2020-03-23 09:29:18Z rwxrw-rw- $superuser $superuser -dir2 True 2020-03-23 09:28:36Z rwxrw-rw- $superuser $superuser +dir1 True 2020-03-13 13:07:34Z rwxrw-rwt $superuser $superuser +dir1/file1 False 1024 2020-03-23 09:29:18Z rwxrw-rwt $superuser $superuser +dir2 True 2020-03-23 09:28:36Z rwxrw-rwt $superuser $superuser ``` This command first creates an ACL object with 3 acl entry (use -InputObject parameter to add acl entry to existing acl object), then get all items in a filesystem and update acl on the items. ### Example 2: Update all properties on a file, and show them + + ``` PS C:\> $file = Update-AzDataLakeGen2Item -FileSystem "filesystem1" -Path "dir1/file1" ` -Acl $acl ` @@ -143,7 +145,7 @@ Update-AzDataLakeGen2Item -FileSystem "filesystem1" -Path 'dir1/dir3/' -ACL $acl ``` ```output - FileSystem Name: filesystem1 +FileSystem Name: filesystem1 Path IsDirectory Length LastModified Permissions Owner Group ---- ----------- ------ ------------ ----------- ----- ----- @@ -294,10 +296,9 @@ Accept wildcard characters: False ``` ### -Permission -Sets POSIX access permissions for the file owner, the file owning group, and others. -Each class may be granted read, write, or execute permission. -Symbolic (rwxrw-rw-) is supported. -Invalid in conjunction with Acl. +Sets POSIX access permissions for the file owner, the file owning group, and others. Each class may be granted read, write, or execute permission. Symbolic (rwxrw-rw-) is supported. +The sticky bit is also supported and its represented either by the letter t or T in the final character-place depending on whether the execution bit for the others category is set or unset respectively, +absence of t or T indicates sticky bit not set.Invalid in conjunction with ACL. ```yaml Type: System.String @@ -360,7 +361,7 @@ Accept wildcard characters: False ``` ### CommonParameters -This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216). +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS diff --git a/src/Storage/Storage/DatalakeGen2/Cmdlet/NewAzDataLakeGen2ACLObject.cs b/src/Storage/Storage/DatalakeGen2/Cmdlet/NewAzDataLakeGen2ACLObject.cs index 43853a3d449f..a139b1be281c 100644 --- a/src/Storage/Storage/DatalakeGen2/Cmdlet/NewAzDataLakeGen2ACLObject.cs +++ b/src/Storage/Storage/DatalakeGen2/Cmdlet/NewAzDataLakeGen2ACLObject.cs @@ -46,8 +46,9 @@ public class SetAzDataLakeGen2ItemAclObjectCommand : AzureDataCmdlet IgnoreCase = true)] public AccessControlType AccessControlType; - [Parameter(Mandatory = true, HelpMessage = "The permission field is a 3-character sequence where the first character is 'r' to grant read access, the second character is 'w' to grant write access, and the third character is 'x' to grant execute permission. If access is not granted, the '-' character is used to denote that the permission is denied.")] - [ValidatePattern("[r-][w-][x-]")] + [Parameter(Mandatory = true, HelpMessage = "The permission field is a 3-character sequence where the first character is 'r' to grant read access, the second character is 'w' to grant write access, and the third character is 'x' to grant execute permission. If access is not granted, the '-' character is used to denote that the permission is denied. " + + "The sticky bit is also supported and its represented either by the letter t or T in the final character-place depending on whether the execution bit for the others category is set or unset respectively, absence of t or T indicates sticky bit not set.")] + [ValidatePattern("[r-][w-][xtT-]")] public string Permission { get; set; } [Parameter(Mandatory = false, HelpMessage = "If input the PSPathAccessControlEntry[] object, will add the new ACL entry as a new element of the input PSPathAccessControlEntry[] object. If an ACL entry when same AccessControlType, EntityId, DefaultScope exist, will update permission of it.")] @@ -80,7 +81,7 @@ public override void ExecuteCmdlet() psacls.Remove(entryToRemove); } - PSPathAccessControlEntry psacl = new PSPathAccessControlEntry(this.AccessControlType, PathAccessControlExtensions.ParseSymbolicRolePermissions(this.Permission), this.DefaultScope, this.EntityId); + PSPathAccessControlEntry psacl = new PSPathAccessControlEntry(this.AccessControlType, PathAccessControlExtensions.ParseSymbolicRolePermissions(this.Permission, true), this.DefaultScope, this.EntityId); psacls.Add(psacl); WriteObject(psacls.ToArray(), true); diff --git a/src/Storage/Storage/DatalakeGen2/Cmdlet/NewAzDataLakeGen2Item.cs b/src/Storage/Storage/DatalakeGen2/Cmdlet/NewAzDataLakeGen2Item.cs index 433694f14e64..92fa745b2f49 100644 --- a/src/Storage/Storage/DatalakeGen2/Cmdlet/NewAzDataLakeGen2Item.cs +++ b/src/Storage/Storage/DatalakeGen2/Cmdlet/NewAzDataLakeGen2Item.cs @@ -83,9 +83,10 @@ public string Source [ValidatePattern("([r-][w-][x-]){3}")] public string Umask { get; set; } - [Parameter(Mandatory = false, HelpMessage = "Sets POSIX access permissions for the file owner, the file owning group, and others. Each class may be granted read, write, or execute permission. Symbolic (rwxrw-rw-) is supported. ")] + [Parameter(Mandatory = false, HelpMessage = "Sets POSIX access permissions for the file owner, the file owning group, and others. Each class may be granted read, write, or execute permission. Symbolic (rwxrw-rw-) is supported. " + + "The sticky bit is also supported and its represented either by the letter t or T in the final character-place depending on whether the execution bit for the others category is set or unset respectively, absence of t or T indicates sticky bit not set.")] [ValidateNotNullOrEmpty] - [ValidatePattern("([r-][w-][x-]){3}")] + [ValidatePattern("([r-][w-][x-]){2}([r-][w-][xtT-])")] public string Permission { get; set; } @@ -384,13 +385,34 @@ protected void SetBlobPermissionWithUMask(CloudBlockBlob blob, string permission string blobPermission = string.Empty; for (int i = 0; i < permission.Length; i++) { - if (umask[i] != '-') + if (Char.ToLower(permission[i]) == 't') { - blobPermission += '-'; + if (permission[i] == 'T') + { + blobPermission += permission[i]; + } + else + { + if (umask[i] == '-') + { + blobPermission += 't'; + } + else + { + blobPermission += 'T'; + } + } } else { - blobPermission += permission[i]; + if (umask[i] != '-') + { + blobPermission += '-'; + } + else + { + blobPermission += permission[i]; + } } } diff --git a/src/Storage/Storage/DatalakeGen2/Cmdlet/UpdateAzDataLakeGen2Item.cs b/src/Storage/Storage/DatalakeGen2/Cmdlet/UpdateAzDataLakeGen2Item.cs index c7b5f2dfd296..d0dd204779a9 100644 --- a/src/Storage/Storage/DatalakeGen2/Cmdlet/UpdateAzDataLakeGen2Item.cs +++ b/src/Storage/Storage/DatalakeGen2/Cmdlet/UpdateAzDataLakeGen2Item.cs @@ -53,9 +53,11 @@ public class SetAzDataLakeGen2ItemCommand : StorageCloudBlobCmdletBase [ValidateNotNull] public AzureDataLakeGen2Item InputObject { get; set; } - [Parameter(Mandatory = false, HelpMessage = "Sets POSIX access permissions for the file owner, the file owning group, and others. Each class may be granted read, write, or execute permission. Symbolic (rwxrw-rw-) is supported. Invalid in conjunction with ACL.")] + [Parameter(Mandatory = false, HelpMessage = "Sets POSIX access permissions for the file owner, the file owning group, and others. Each class may be granted read, write, or execute permission. Symbolic (rwxrw-rw-) is supported." + + "The sticky bit is also supported and its represented either by the letter t or T in the final character-place depending on whether the execution bit for the others category is set or unset respectively, absence of t or T indicates sticky bit not set." + + "Invalid in conjunction with ACL.")] [ValidateNotNullOrEmpty] - [ValidatePattern("([r-][w-][x-]){3}")] + [ValidatePattern("([r-][w-][x-]){2}[r-][w-][xtT-]")] public string Permission { get; set; } [Parameter(Mandatory = false, HelpMessage = "Sets the owner of the item.")] diff --git a/src/Storage/Storage/Storage.csproj b/src/Storage/Storage/Storage.csproj index 2c1e7b7dbc3f..787b156aca8a 100644 --- a/src/Storage/Storage/Storage.csproj +++ b/src/Storage/Storage/Storage.csproj @@ -13,10 +13,10 @@ - - - - + + + + diff --git a/tools/StaticAnalysis/Exceptions/Az.Storage/AssemblyVersionConflict.csv b/tools/StaticAnalysis/Exceptions/Az.Storage/AssemblyVersionConflict.csv index ce6888d46b5b..9b85fea64761 100644 --- a/tools/StaticAnalysis/Exceptions/Az.Storage/AssemblyVersionConflict.csv +++ b/tools/StaticAnalysis/Exceptions/Az.Storage/AssemblyVersionConflict.csv @@ -12,3 +12,5 @@ "Az.Storage","Newtonsoft.Json","6.0.0.0","10.0.0.0","Microsoft.Rest.ClientRuntime","1","1010","Assembly Newtonsoft.Json version 6.0.0.0 referenced from Microsoft.Rest.ClientRuntime.dll does not match assembly version on disk: 10.0.0.0","Update any references to version 6.0.0.0 of assembly Newtonsoft.Json" "Az.Storage","Newtonsoft.Json","6.0.0.0","10.0.0.0","Microsoft.WindowsAzure.Commands.Common","1","1010","Assembly Newtonsoft.Json version 6.0.0.0 referenced from Microsoft.WindowsAzure.Commands.Common.dll does not match assembly version on disk: 10.0.0.0","Update any references to version 6.0.0.0 of assembly Newtonsoft.Json" "Az.Storage","Newtonsoft.Json","6.0.0.0","10.0.0.0","Microsoft.Azure.Commands.ResourceManager.Common","1","1010","Assembly Newtonsoft.Json version 6.0.0.0 referenced from Microsoft.Azure.Commands.ResourceManager.Common.dll does not match assembly version on disk: 10.0.0.0","Update any references to version 6.0.0.0 of assembly Newtonsoft.Json" +"Az.Storage","Newtonsoft.Json","13.0.0.0","10.0.0.0","Microsoft.Azure.PowerShell.Storage.Management.Sdk","1","1010","Assembly Newtonsoft.Json version 13.0.0.0 referenced from Microsoft.Azure.PowerShell.Storage.Management.Sdk.dll does not match assembly version on disk: 10.0.0.0","Update any references to version 10.0.0.0 of assembly Newtonsoft.Json" +