/// <summary> /// Deletes a Google Cloud Storage object or bucket. Used by Remove-Item. /// </summary> /// <param name="path">The path to the object or bucket to remove.</param> /// <param name="recurse">If true, will remove the desendants of the item as well. Required for a /// non-empty bucket.</param> protected override void RemoveItem(string path, bool recurse) { if (!ShouldProcess(path, "Remove-Item")) { return; } var gcsPath = GcsPath.Parse(path); switch (gcsPath.Type) { case GcsPath.GcsPathType.Drive: throw new InvalidOperationException("Use Remove-PSDrive to remove a drive."); case GcsPath.GcsPathType.Bucket: RemoveBucket(gcsPath, recurse); BucketCache.ForceRefresh(); break; case GcsPath.GcsPathType.Object: if (IsItemContainer(path)) { RemoveFolder(GcsPath.Parse(path + "/"), recurse); } else { Service.Objects.Delete(gcsPath.Bucket, gcsPath.ObjectPath).Execute(); } BucketModels.Clear(); break; default: throw new InvalidOperationException($"Unknown Path Type {gcsPath.Type}"); } TelemetryReporter.ReportSuccess(nameof(GoogleCloudStorageProvider), nameof(RemoveItem)); }
/// <summary> /// Copies a Google Cloud Storage object or folder to another object or folder. Used by Copy-Item. /// </summary> /// <param name="path">The path to copy from.</param> /// <param name="copyPath">The path to copy to.</param> /// <param name="recurse">If true, will copy all decendent objects as well.</param> protected override void CopyItem(string path, string copyPath, bool recurse) { if (!ShouldProcess($"Copy-Item from {path} to {copyPath}")) { return; } var dyanmicParameters = (GcsCopyItemDynamicParameters)DynamicParameters; if (recurse) { path = path.TrimEnd('\\') + "\\"; copyPath = copyPath.TrimEnd('\\') + "\\"; } var gcsPath = GcsPath.Parse(path); var gcsCopyPath = GcsPath.Parse(copyPath); if (recurse) { IEnumerable <Object> children = ListChildren(gcsPath, true); foreach (Object child in children) { string objectSubPath = gcsPath.RelativePathToChild(child.Name); string destinationObject = GcsPath.Parse(MakePath(copyPath, objectSubPath)).ObjectPath; ObjectsResource.CopyRequest childRequest = Service.Objects.Copy(null, child.Bucket, child.Name, gcsCopyPath.Bucket, destinationObject); childRequest.SourceGeneration = dyanmicParameters.SourceGeneration; childRequest.DestinationPredefinedAcl = dyanmicParameters.DestinationAcl; childRequest.Projection = ObjectsResource.CopyRequest.ProjectionEnum.Full; Object childObject = childRequest.Execute(); bool isContainer = (new GcsPath(childObject).Type != GcsPath.GcsPathType.Object); WriteItemObject(childObject, copyPath, isContainer); } } if (!recurse || GetBucketModel(gcsPath.Bucket).IsReal(gcsPath.ObjectPath)) { ObjectsResource.CopyRequest request = Service.Objects.Copy(null, gcsPath.Bucket, gcsPath.ObjectPath, gcsCopyPath.Bucket, gcsCopyPath.ObjectPath); request.SourceGeneration = dyanmicParameters.SourceGeneration; request.DestinationPredefinedAcl = dyanmicParameters.DestinationAcl; request.Projection = ObjectsResource.CopyRequest.ProjectionEnum.Full; Object response = request.Execute(); WriteItemObject(response, copyPath, gcsCopyPath.Type != GcsPath.GcsPathType.Object); } BucketModels.Clear(); TelemetryReporter.ReportSuccess(nameof(GoogleCloudStorageProvider), nameof(CopyItem)); }
/// <summary> /// Deletes a Google Cloud Storage object or bucket. Used by Remove-Item. /// </summary> /// <param name="path">The path to the object or bucket to remove.</param> /// <param name="recurse">If true, will remove the desendants of the item as well. Required for a /// non-empty bucket.</param> protected override void RemoveItem(string path, bool recurse) { if (!ShouldProcess(path, "Remove-Item")) { return; } var gcsPath = GcsPath.Parse(path); switch (gcsPath.Type) { case GcsPath.GcsPathType.Drive: throw new InvalidOperationException("Use Remove-PSDrive to remove a drive."); case GcsPath.GcsPathType.Bucket: RemoveBucket(gcsPath, recurse); // If the bucket cache is not initialized, then don't bother initializing it // because that will cause a long wait time and we may not even know whether // the user needs to use all the other buckets right away. Also, we should not // refresh the whole cache right at this instance (which is why we call // GetValueWithoutUpdate) for the same reason. Dictionary <string, Bucket> bucketDict = BucketCache.GetLastValueWithoutUpdate(); if (bucketDict != null) { bucketDict.Remove(gcsPath.Bucket); } break; case GcsPath.GcsPathType.Object: if (IsItemContainer(path)) { RemoveFolder(GcsPath.Parse(path + "/"), recurse); } else { Service.Objects.Delete(gcsPath.Bucket, gcsPath.ObjectPath).Execute(); } BucketModels.Clear(); break; default: throw new InvalidOperationException($"Unknown Path Type {gcsPath.Type}"); } TelemetryReporter.ReportSuccess(nameof(GoogleCloudStorageProvider), nameof(RemoveItem)); }
/// <summary> /// Gets a writer used to upload data to a Google Cloud Storage object. Used by Set-Content. /// </summary> /// <param name="path">The path of the object to upload to.</param> /// <returns>The writer.</returns> public IContentWriter GetContentWriter(string path) { var gcsPath = GcsPath.Parse(path); Object body = new Object { Name = gcsPath.ObjectPath, Bucket = gcsPath.Bucket }; var inputStream = new AnonymousPipeServerStream(PipeDirection.Out); var outputStream = new AnonymousPipeClientStream(PipeDirection.In, inputStream.ClientSafePipeHandle); var contentType = ((GcsGetContentWriterDynamicParameters)DynamicParameters).ContentType ?? GcsCmdlet.UTF8TextMimeType; ObjectsResource.InsertMediaUpload request = Service.Objects.Insert(body, gcsPath.Bucket, outputStream, contentType); request.UploadAsync(); IContentWriter contentWriter = new GcsContentWriter(inputStream); // Force the bucket models to refresh with the potentially new object. BucketModels.Clear(); TelemetryReporter.ReportSuccess(nameof(GoogleCloudStorageProvider), nameof(GetContentWriter)); return(contentWriter); }
/// <summary> /// Creates a new item at the given path. /// </summary> /// <param name="path">The path of the item ot create.</param> /// <param name="itemTypeName">The type of item to create. "Directory" is the only special one. /// That will create an object with a name ending in "/".</param> /// <param name="newItemValue">The value of the item to create. We assume it is a string.</param> protected override void NewItem(string path, string itemTypeName, object newItemValue) { if (!ShouldProcess(path, "New-Item")) { return; } bool newFolder = itemTypeName == "Directory"; if (newFolder && !path.EndsWith("/")) { path += "/"; } var gcsPath = GcsPath.Parse(path); switch (gcsPath.Type) { case GcsPath.GcsPathType.Drive: throw new InvalidOperationException("Use New-PSDrive to create a new drive."); case GcsPath.GcsPathType.Bucket: Bucket newBucket = NewBucket(gcsPath, (NewGcsBucketDynamicParameters)DynamicParameters); WriteItemObject(newBucket, path, true); break; case GcsPath.GcsPathType.Object: var dynamicParameters = (NewGcsObjectDynamicParameters)DynamicParameters; Stream contentStream = GetContentStream(newItemValue, dynamicParameters); Object newObject = NewObject(gcsPath, dynamicParameters, contentStream); WriteItemObject(newObject, path, newFolder); break; default: throw new InvalidOperationException($"Unknown Path Type {gcsPath.Type}"); } BucketModels.Clear(); TelemetryReporter.ReportSuccess(nameof(GoogleCloudStorageProvider), nameof(NewItem)); }