More HDFS Manage Access dialog updates (#7692)

* Add support for default permissions on directories

(cherry picked from commit 4e81cceba142c6763c3447b4d2965cd75764f8f9)

* Remove unneeded import

(cherry picked from commit ffe5f357357e75e9290966e89768c699df2e1311)

* Add recursive apply and clean up webhdfs

(cherry picked from commit ae76df14f99e599df1cdfcc74ee22d3822f11a59)

* Final set of changes

* Undo changes to azdata/sqlops and few minor fixes

* Remove cast to fix build error

* Hide defaults checkbox for files and switch checkbox order
This commit is contained in:
Charles Gagnon
2019-10-11 15:18:17 -07:00
committed by GitHub
parent 888327f5bc
commit d02c680dab
9 changed files with 466 additions and 162 deletions

View File

@@ -3,10 +3,14 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as azdata from 'azdata';
import * as vscode from 'vscode';
import { IFileSource } from '../objectExplorerNodeProvider/fileSources';
import { PermissionStatus, AclEntry, AclEntryScope, AclType, AclEntryPermission } from './aclEntry';
import { FileStatus } from './fileStatus';
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
/**
* Model for storing the state of a specified file/folder in HDFS
@@ -29,7 +33,7 @@ export class HdfsModel {
*/
public fileStatus: FileStatus;
constructor(private fileSource: IFileSource, private path: string) {
constructor(private readonly fileSource: IFileSource, private readonly path: string) {
this.refresh();
}
@@ -53,7 +57,8 @@ export class HdfsModel {
if (!this.permissionStatus) {
return;
}
const newEntry = new AclEntry(AclEntryScope.access, type, name, name, new AclEntryPermission(true, true, true));
const newEntry = new AclEntry(type, name, name);
newEntry.addPermission(AclEntryScope.access, new AclEntryPermission(true, true, true));
// Don't add duplicates. This also checks the owner, group and other items
if ([this.permissionStatus.owner, this.permissionStatus.group, this.permissionStatus.other].concat(this.permissionStatus.aclEntries).find(entry => entry.isEqual(newEntry))) {
return;
@@ -78,10 +83,62 @@ export class HdfsModel {
* permissions that shouldn't change need to still exist and have the same values.
* @param recursive Whether to apply the changes recursively (to all sub-folders and files)
*/
public apply(recursive: boolean = false): Promise<any> {
// TODO Apply recursive
public async apply(recursive: boolean = false): Promise<void> {
await this.applyAclChanges(this.path);
if (recursive) {
azdata.tasks.startBackgroundOperation(
{
connection: undefined,
displayName: localize('mssql.recursivePermissionOpStarted', "Applying permission changes recursively under '{0}'", this.path),
description: '',
isCancelable: false,
operation: async op => {
await this.applyToChildrenRecursive(op, this.path);
op.updateStatus(azdata.TaskStatus.Succeeded, localize('mssql.recursivePermissionOpSucceeded', "Permission changes applied successfully."));
}
}
);
}
}
/**
* Recursive call to apply the current set of changes to all children of this path (if any)
* @param op Background operation used to track status of the task
* @param path The path
*/
private async applyToChildrenRecursive(op: azdata.BackgroundOperation, path: string): Promise<void> {
try {
op.updateStatus(azdata.TaskStatus.InProgress, localize('mssql.recursivePermissionOpProgress', "Applying permission changes to '{0}'.", path));
const files = await this.fileSource.enumerateFiles(path, true);
// Apply changes to all children of this path and then recursively apply to children of any directories
await Promise.all(
[
files.map(file => this.applyAclChanges(file.path)),
files.filter(f => f.isDirectory).map(d => this.applyToChildrenRecursive(op, d.path))
]);
} catch (error) {
const errMsg = localize('mssql.recursivePermissionOpError', "Error applying permission changes: {0}", (error instanceof Error ? error.message : error));
vscode.window.showErrorMessage(errMsg);
op.updateStatus(azdata.TaskStatus.Failed, errMsg);
}
}
/**
* Applies the current set of Permissions/ACLs to the specified path
* @param path The path to apply the changes to
*/
private async applyAclChanges(path: string): Promise<any> {
// HDFS won't remove existing default ACLs even if you call setAcl with no default ACLs specified. You
// need to call removeDefaultAcl specifically to remove them.
if (!this.permissionStatus.owner.getPermission(AclEntryScope.default) &&
!this.permissionStatus.group.getPermission(AclEntryScope.default) &&
!this.permissionStatus.other.getPermission(AclEntryScope.default)) {
await this.fileSource.removeDefaultAcl(path);
}
return Promise.all([
this.fileSource.setAcl(this.path, this.permissionStatus.owner, this.permissionStatus.group, this.permissionStatus.other, this.permissionStatus.aclEntries),
this.fileSource.setPermission(this.path, this.permissionStatus)]);
this.fileSource.setAcl(path, this.permissionStatus.owner, this.permissionStatus.group, this.permissionStatus.other, this.permissionStatus.aclEntries),
this.fileSource.setPermission(path, this.permissionStatus)]);
}
}