/******************************************************************************* * Copyright 2012-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"). You may not use * this file except in compliance with the License. A copy of the License is located at * * http://aws.amazon.com/apache2.0 * * or in the "license" file accompanying this file. * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR * CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. * ***************************************************************************** * * AWS Tools for Windows (TM) PowerShell (TM) * */ using System; using System.Management.Automation; using Amazon.PowerShell.Common; using Amazon.Runtime; using Amazon.S3; using Amazon.S3.Model; namespace Amazon.PowerShell.Cmdlets.S3 { /// /// Creates a new bucket with the supplied name and permissions. /// [Cmdlet("New", "S3Bucket", SupportsShouldProcess = true, ConfirmImpact = ConfirmImpact.Low)] [OutputType("Amazon.S3.Model.S3Bucket")] [AWSCmdlet("Creates a new bucket in Amazon S3.", Operation = new [] {"PutBucket"}, SelectReturnType = typeof(Amazon.S3.Model.PutBucketResponse))] [AWSCmdletOutput("Amazon.S3.Model.S3Bucket or Amazon.S3.Model.PutBucketResponse", "Returns an Amazon.S3.Model.S3Bucket instance representing the new bucket.", "The service response (type Amazon.S3.Model.PutBucketResponse) is added to the cmdlet entry in the $AWSHistory stack." )] public class NewS3BucketCmdlet : AmazonS3ClientCmdlet, IExecutor { #region Parameter BucketName /// /// The name that will be given to the new bucket. This name needs to be /// unique across Amazon S3. /// [Parameter(Position = 0, ValueFromPipelineByPropertyName = true, ValueFromPipeline = true, Mandatory = true)] [Amazon.PowerShell.Common.AWSRequiredParameter] public System.String BucketName { get; set; } #endregion #region Parameter CannedACLName /// /// Specifies the name of the canned ACL (access control list) of permissions to be applied to the S3 bucket. /// Please refer to Amazon.S3.Model.S3CannedACL for information on S3 Canned ACLs. /// [Parameter(ValueFromPipelineByPropertyName = true)] [AWSConstantClassSource("Amazon.S3.S3CannedACL")] public Amazon.S3.S3CannedACL CannedACLName { get; set; } #endregion #region Parameter PublicReadOnly /// /// If set, applies an ACL making the bucket public with read-only permissions /// This parameter is obsolete. Use CannedACLName instead. /// [Parameter(ValueFromPipelineByPropertyName = true)] [Obsolete("This parameter is obsolete. Use CannedACLName instead.")] public SwitchParameter PublicReadOnly { get; set; } #endregion #region Parameter PublicReadWrite /// /// If set, applies an ACL making the bucket public with read-write permissions. /// This parameter is obsolete. Use CannedACLName instead. /// [Parameter(ValueFromPipelineByPropertyName = true)] [Obsolete("This parameter is obsolete. Use CannedACLName instead.")] public SwitchParameter PublicReadWrite { get; set; } #endregion #region Parameter Force /// /// This parameter overrides confirmation prompts to force /// the cmdlet to continue its operation. This parameter should always /// be used with caution. /// [Parameter(ValueFromPipelineByPropertyName = true)] public SwitchParameter Force { get; set; } #endregion #region Parameter ObjectLockEnabledForBucket /// /// Specifies whether you want S3 Object Lock to be enabled for the new bucket. /// [Parameter(ValueFromPipelineByPropertyName = true)] public bool? ObjectLockEnabledForBucket { get; set; } #endregion #region Parameter Select /// /// Use the -Select parameter to control the cmdlet output. /// Specifying -Select '*' will result in the cmdlet returning the whole service response (Amazon.S3.Model.PutBucketResponse). /// Specifying -Select '^ParameterName' will result in the cmdlet returning the selected cmdlet parameter value. /// [System.Management.Automation.Parameter] public string Select { get; set; } = "*"; #endregion protected override void ProcessRecord() { base.ProcessRecord(); if (!ConfirmShouldProceed(this.Force.IsPresent, this.BucketName, "New-S3Bucket (PutBucket)")) return; var context = new CmdletContext { BucketName = this.BucketName }; if (ParameterWasBound(nameof(this.Select))) { context.Select = CreateSelectDelegate(Select) ?? throw new System.ArgumentException("Invalid value for -Select parameter.", nameof(this.Select)); } if (!string.IsNullOrEmpty(this.CannedACLName)) context.CannedACL = this.CannedACLName; #pragma warning disable CS0618, CS0612 //A class member was marked with the Obsolete attribute else if (this.PublicReadOnly.IsPresent) context.CannedACL = S3CannedACL.PublicRead; else if (this.PublicReadWrite.IsPresent) context.CannedACL = S3CannedACL.PublicReadWrite; #pragma warning restore CS0618, CS0612 //A class member was marked with the Obsolete attribute context.ObjectLockEnabledForBucket = this.ObjectLockEnabledForBucket; var output = Execute(context) as CmdletOutput; ProcessOutput(output); } #region IExecutor Members public object Execute(ExecutorContext context) { var cmdletContext = context as CmdletContext; var request = new PutBucketRequest(); if (cmdletContext.BucketName != null) request.BucketName = cmdletContext.BucketName; if (cmdletContext.CannedACL != null) request.CannedACL = cmdletContext.CannedACL.Value; // Forcibly set a location constraint to match whatever Region argument was used // with the cmdlet; this will prevent S3 issuing the "unspecified location constraint // didn't match" message, potentially confusing new users. request.BucketRegionName = _RegionEndpoint.SystemName; if (cmdletContext.ObjectLockEnabledForBucket != null) { request.ObjectLockEnabledForBucket = cmdletContext.ObjectLockEnabledForBucket.Value; } ServiceCalls.PushServiceRequest(request, this.MyInvocation, IsSensitiveRequest); using (var client = Client ?? CreateClient(_CurrentCredentials, _RegionEndpoint)) { CmdletOutput output; try { var response = CallAWSServiceOperation(client, request); object pipelineOutput = null; pipelineOutput = cmdletContext.Select(response, this); output = new CmdletOutput { PipelineOutput = pipelineOutput, ServiceResponse = response }; } catch (Exception e) { output = new CmdletOutput { ErrorResponse = e }; this.WriteError(new ErrorRecord(e, $"Failed to create the specified bucket.\r\nAmazon S3 error: {e.Message}", ErrorCategory.InvalidOperation, this)); } return output; } } public ExecutorContext CreateContext() { return new CmdletContext(); } #endregion #region AWS Service Operation Call private Amazon.S3.Model.PutBucketResponse CallAWSServiceOperation(IAmazonS3 client, Amazon.S3.Model.PutBucketRequest request) { Utils.Common.WriteVerboseEndpointMessage(this, client.Config, "Amazon S3", "PutBucket"); try { #if DESKTOP return client.PutBucket(request); #elif CORECLR return client.PutBucketAsync(request).GetAwaiter().GetResult(); #else #error "Unknown build edition" #endif } catch (AmazonServiceException exc) { var webException = exc.InnerException as System.Net.WebException; if (webException != null) { throw new Exception(Utils.Common.FormatNameResolutionFailureMessage(client.Config, webException.Message), webException); } throw; } } #endregion internal class CmdletContext : ExecutorContext { public String BucketName { get; set; } public S3CannedACL CannedACL { get; set; } public bool? ObjectLockEnabledForBucket { get; set; } public System.Func Select { get; set; } = // since S3 bucket has only a name and a creation date, take a simple route to // emit the instance rather than a ListBuckets/search approach (response, cmdlet) => new S3Bucket { BucketName = cmdlet.BucketName, CreationDate = DateTime.UtcNow }; } } }