Skip to content

Commit e29ac17

Browse files
authored
added auto-iteration mode cmdlets
1 parent 5747dc7 commit e29ac17

File tree

5 files changed

+169
-27
lines changed

5 files changed

+169
-27
lines changed

generator/AWSPSGeneratorLib/Writers/SourceCode/CmdletSourceWriter.cs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,15 @@ public void Write(IndentedTextWriter writer)
6464
var methodDocumentation = DocumentationUtils.GetMethodDocumentation(methodInfo.DeclaringType, Operation.MethodName, MethodAnalysis.AssemblyDocumentation);
6565

6666
if (autoIteration != null)
67-
methodDocumentation += $"<br/><br/>{(Operation.LegacyPagination == ServiceOperation.LegacyPaginationType.DisablePagination ? $"In the AWS.Tools.{ServiceConfig.AssemblyName} module, t" : "T")}his cmdlet automatically pages all available results to the pipeline - parameters related to iteration are only needed if you want to manually control the paginated output. To disable autopagination, use -NoAutoIteration.";
67+
{
68+
methodDocumentation +=
69+
$"<br/><br/>{(Operation.LegacyPagination == ServiceOperation.LegacyPaginationType.DisablePagination ? $"In the AWS.Tools.{ServiceConfig.AssemblyName} module, t" : "T")}his cmdlet automatically pages all available results to the pipeline - parameters related to iteration are only needed if you want to manually control the paginated output. To disable autopagination, use -NoAutoIteration.";
70+
71+
if (autoIteration.SupportLegacyAutoIterationMode)
72+
{
73+
methodDocumentation += " This cmdlet didn't autopaginate in V4, auto-pagination support was added in V5.";
74+
}
75+
}
6876

6977
if (GetOperationObsoleteMessage(methodInfo) != null)
7078
methodDocumentation += "<br/><br/>This operation is deprecated.";
@@ -523,6 +531,11 @@ public void WriteNoAutoIterationSwitchParam(IndentedTextWriter writer)
523531
writer.WriteLine("/// By default the cmdlet will auto-iterate and retrieve all results to the pipeline by performing multiple");
524532
writer.WriteLine($"/// service calls. If set, the cmdlet will retrieve only the next 'page' of results using the value of {startProperty.CmdletParameterName}");
525533
writer.WriteLine("/// as the start point.");
534+
if (autoIteration.SupportLegacyAutoIterationMode)
535+
{
536+
writer.WriteLine("/// This cmdlet didn't autopaginate in V4. To preserve the V4 autopagination behavior for all cmdlets, run Set-AWSAutoIterationMode -IterationMode v4.");
537+
}
538+
526539
writer.WriteLine("/// </summary>");
527540
writer.WriteLine("[System.Management.Automation.Parameter(ValueFromPipelineByPropertyName = true)]");
528541
writer.WriteLine("public SwitchParameter NoAutoIteration { get; set; }");
@@ -1366,7 +1379,7 @@ private void WriteIExecutorIterPattern1(IndentedTextWriter writer)
13661379
// disable auto-iteration for cmdlets that didn't have auto-iteration in v4 in legacy mode.
13671380
if (autoIteration.SupportLegacyAutoIterationMode)
13681381
{
1369-
writer.WriteLine(@$"var _shouldAutoIterate = !(SessionState.PSVariable.GetValue(""AWS_POWERSHELL_AUTOITERATION_MODE"")?.ToString() == ""legacy"");");
1382+
writer.WriteLine(@$"var _shouldAutoIterate = !(SessionState.PSVariable.GetValue(""AWSPowerShell_AutoIteration_Mode"")?.ToString() == ""v4"");");
13701383
}
13711384

13721385
writer.WriteLine();

modules/AWSPowerShell/Cmdlets/Account/Basic/Get-ACCTRegionList-Cmdlet.cs

Lines changed: 76 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ namespace Amazon.PowerShell.Cmdlets.ACCT
3131
{
3232
/// <summary>
3333
/// Lists all the Regions for a given account and their respective opt-in statuses. Optionally,
34-
/// this list can be filtered by the <c>region-opt-status-contains</c> parameter.
34+
/// this list can be filtered by the <c>region-opt-status-contains</c> parameter.<br/><br/>This cmdlet automatically pages all available results to the pipeline - parameters related to iteration are only needed if you want to manually control the paginated output. To disable autopagination, use -NoAutoIteration. This cmdlet didn't autopaginate in V4, auto-pagination support was added in V5.
3535
/// </summary>
3636
[Cmdlet("Get", "ACCTRegionList")]
3737
[OutputType("Amazon.Account.Model.Region")]
@@ -91,10 +91,15 @@ public partial class GetACCTRegionListCmdlet : AmazonAccountClientCmdlet, IExecu
9191
/// see <a href="http://docs.aws.amazon.com/cli/latest/userguide/pagination.html">Pagination</a>
9292
/// in the <i>Amazon Web Services Command Line Interface User Guide</i>. </para>
9393
/// </para>
94+
/// <para>
95+
/// <br/><b>Note:</b> In AWSPowerShell and AWSPowerShell.NetCore this parameter is used to limit the total number of items returned by the cmdlet.
96+
/// <br/>In AWS.Tools this parameter is simply passed to the service to specify how many items should be returned by each service call.
97+
/// <br/>Pipe the output of this cmdlet into Select-Object -First to terminate retrieving data pages early and control the number of items returned.
98+
/// </para>
9499
/// </summary>
95100
[System.Management.Automation.Parameter(ValueFromPipelineByPropertyName = true)]
96-
[Alias("MaxResults")]
97-
public System.Int32? MaxResult { get; set; }
101+
[Alias("MaxItems","MaxResults")]
102+
public int? MaxResult { get; set; }
98103
#endregion
99104

100105
#region Parameter NextToken
@@ -104,6 +109,10 @@ public partial class GetACCTRegionListCmdlet : AmazonAccountClientCmdlet, IExecu
104109
/// a previously truncated response. For usage examples, see <a href="http://docs.aws.amazon.com/cli/latest/userguide/pagination.html">Pagination</a>
105110
/// in the <i>Amazon Web Services Command Line Interface User Guide</i>.</para>
106111
/// </para>
112+
/// <para>
113+
/// <br/><b>Note:</b> This parameter is only used if you are manually controlling output pagination of the service API call.
114+
/// <br/>'NextToken' is only returned by the cmdlet when '-Select *' is specified. In order to manually control output pagination, set '-NextToken' to null for the first call then set the 'NextToken' using the same property output from the previous call for subsequent calls.
115+
/// </para>
107116
/// </summary>
108117
[System.Management.Automation.Parameter(ValueFromPipelineByPropertyName = true)]
109118
public System.String NextToken { get; set; }
@@ -120,6 +129,17 @@ public partial class GetACCTRegionListCmdlet : AmazonAccountClientCmdlet, IExecu
120129
public string Select { get; set; } = "Regions";
121130
#endregion
122131

132+
#region Parameter NoAutoIteration
133+
/// <summary>
134+
/// By default the cmdlet will auto-iterate and retrieve all results to the pipeline by performing multiple
135+
/// service calls. If set, the cmdlet will retrieve only the next 'page' of results using the value of NextToken
136+
/// as the start point.
137+
/// This cmdlet didn't autopaginate in V4. To preserve the V4 autopagination behavior for all cmdlets, run Set-AWSAutoIterationMode -IterationMode v4.
138+
/// </summary>
139+
[System.Management.Automation.Parameter(ValueFromPipelineByPropertyName = true)]
140+
public SwitchParameter NoAutoIteration { get; set; }
141+
#endregion
142+
123143
protected override void StopProcessing()
124144
{
125145
base.StopProcessing();
@@ -141,6 +161,15 @@ protected override void ProcessRecord()
141161
}
142162
context.AccountId = this.AccountId;
143163
context.MaxResult = this.MaxResult;
164+
#if !MODULAR
165+
if (ParameterWasBound(nameof(this.MaxResult)) && this.MaxResult.HasValue)
166+
{
167+
WriteWarning("AWSPowerShell and AWSPowerShell.NetCore use the MaxResult parameter to limit the total number of items returned by the cmdlet." +
168+
" This behavior is obsolete and will be removed in a future version of these modules. Pipe the output of this cmdlet into Select-Object -First to terminate" +
169+
" retrieving data pages early and control the number of items returned. AWS.Tools already implements the new behavior of simply passing MaxResult" +
170+
" to the service to specify how many items should be returned by each service call.");
171+
}
172+
#endif
144173
context.NextToken = this.NextToken;
145174
if (this.RegionOptStatusContain != null)
146175
{
@@ -159,7 +188,9 @@ protected override void ProcessRecord()
159188
public object Execute(ExecutorContext context)
160189
{
161190
var cmdletContext = context as CmdletContext;
162-
// create request
191+
var useParameterSelect = this.Select.StartsWith("^");
192+
193+
// create request and set iteration invariants
163194
var request = new Amazon.Account.Model.ListRegionsRequest();
164195

165196
if (cmdletContext.AccountId != null)
@@ -168,38 +199,59 @@ public object Execute(ExecutorContext context)
168199
}
169200
if (cmdletContext.MaxResult != null)
170201
{
171-
request.MaxResults = cmdletContext.MaxResult.Value;
172-
}
173-
if (cmdletContext.NextToken != null)
174-
{
175-
request.NextToken = cmdletContext.NextToken;
202+
request.MaxResults = AutoIterationHelpers.ConvertEmitLimitToServiceTypeInt32(cmdletContext.MaxResult.Value);
176203
}
177204
if (cmdletContext.RegionOptStatusContain != null)
178205
{
179206
request.RegionOptStatusContains = cmdletContext.RegionOptStatusContain;
180207
}
181208

182-
CmdletOutput output;
209+
// Initialize loop variant and commence piping
210+
var _nextToken = cmdletContext.NextToken;
211+
var _userControllingPaging = this.NoAutoIteration.IsPresent || ParameterWasBound(nameof(this.NextToken));
212+
var _shouldAutoIterate = !(SessionState.PSVariable.GetValue("AWSPowerShell_AutoIteration_Mode")?.ToString() == "v4");
183213

184-
// issue call
185214
var client = Client ?? CreateClient(_CurrentCredentials, _RegionEndpoint);
186-
try
215+
do
187216
{
188-
var response = CallAWSServiceOperation(client, request);
189-
object pipelineOutput = null;
190-
pipelineOutput = cmdletContext.Select(response, this);
191-
output = new CmdletOutput
217+
request.NextToken = _nextToken;
218+
219+
CmdletOutput output;
220+
221+
try
192222
{
193-
PipelineOutput = pipelineOutput,
194-
ServiceResponse = response
195-
};
196-
}
197-
catch (Exception e)
223+
224+
var response = CallAWSServiceOperation(client, request);
225+
226+
object pipelineOutput = null;
227+
if (!useParameterSelect)
228+
{
229+
pipelineOutput = cmdletContext.Select(response, this);
230+
}
231+
output = new CmdletOutput
232+
{
233+
PipelineOutput = pipelineOutput,
234+
ServiceResponse = response
235+
};
236+
237+
_nextToken = response.NextToken;
238+
}
239+
catch (Exception e)
240+
{
241+
output = new CmdletOutput { ErrorResponse = e };
242+
}
243+
244+
ProcessOutput(output);
245+
246+
} while (!_userControllingPaging && _shouldAutoIterate && AutoIterationHelpers.HasValue(_nextToken));
247+
248+
if (useParameterSelect)
198249
{
199-
output = new CmdletOutput { ErrorResponse = e };
250+
WriteObject(cmdletContext.Select(null, this));
200251
}
201252

202-
return output;
253+
254+
return null;
203255
}
204256

205257
public ExecutorContext CreateContext()
@@ -234,7 +286,7 @@ private Amazon.Account.Model.ListRegionsResponse CallAWSServiceOperation(IAmazon
234286
internal partial class CmdletContext : ExecutorContext
235287
{
236288
public System.String AccountId { get; set; }
237-
public System.Int32? MaxResult { get; set; }
289+
public int? MaxResult { get; set; }
238290
public System.String NextToken { get; set; }
239291
public List<System.String> RegionOptStatusContain { get; set; }
240292
public System.Func<Amazon.Account.Model.ListRegionsResponse, GetACCTRegionListCmdlet, object> Select { get; set; } =

modules/AWSPowerShell/Common/CommonCmdlets.cs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,80 @@ protected override void ProcessRecord()
597597
noteProperty.Value = (bool)showSensitiveData.Value;
598598
}
599599

600+
result.Properties.Add(noteProperty);
601+
WriteObject(result);
602+
}
603+
}
604+
605+
/// <summary>
606+
/// Controls the auto-iteration behavior for AWS PowerShell cmdlets.
607+
/// Sets a shell variable that determines whether cmdlets use standard or v4 auto-iteration mode.
608+
/// In standard mode, all operations with pagination support will auto-iterate by default.
609+
/// In v4 mode, only operations that had auto-iteration in v4 will auto-iterate, maintaining backward compatibility.
610+
/// </summary>
611+
[Cmdlet("Set", "AWSAutoIterationMode")]
612+
[AWSCmdlet("Controls the auto-iteration behavior for AWS PowerShell cmdlets. Sets whether to use standard mode (all operations with pagination support auto-iterate) or v4 mode (only operations that had auto-iteration in v4 will auto-iterate).")]
613+
[OutputType("None")]
614+
public class SetAWSAutoIterationModeCmdlet : PSCmdlet
615+
{
616+
#region Parameter IterationMode
617+
618+
/// <summary>
619+
/// Controls the auto-iteration behavior for AWS PowerShell cmdlets.
620+
/// When set to 'standard' (default), all operations with pagination support will auto-iterate.
621+
/// When set to 'v4', only operations that had auto-iteration in v4 will auto-iterate, maintaining backward compatibility.
622+
/// </summary>
623+
[Parameter(ValueFromPipelineByPropertyName = true, Mandatory = true)]
624+
[ValidateSet("standard", "v4")]
625+
public string IterationMode { get; set; }
626+
627+
#endregion
628+
629+
#region Parameter Scope
630+
/// <summary>
631+
/// <para>
632+
/// Sets the scope of the shell variable AWSPowerShell_AutoIteration_Mode.
633+
/// For details about variables scopes, see https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_scopes.
634+
/// </para>
635+
/// </summary>
636+
[Parameter(ValueFromPipelineByPropertyName = true)]
637+
public VariableScope Scope { get; set; }
638+
#endregion
639+
640+
protected override void ProcessRecord()
641+
{
642+
base.ProcessRecord();
643+
WriteVerbose($"Setting IterationMode to {IterationMode}");
644+
string scope = MyInvocation.BoundParameters.ContainsKey("Scope") ? Scope.ToString() + ":" : "";
645+
646+
this.SessionState.PSVariable.Set(scope + SessionKeys.AWSAutoIterationMode, IterationMode);
647+
}
648+
}
649+
650+
/// <summary>
651+
/// Returns the current auto-iteration mode setting that controls how cmdlets handle pagination.
652+
/// This cmdlet returns the current value ('standard' or 'v4') indicating which auto-iteration mode is active.
653+
/// </summary>
654+
[Cmdlet("Get", "AWSAutoIterationMode")]
655+
[AWSCmdlet("Gets the current auto-iteration mode setting that controls how cmdlets handle pagination.")]
656+
[OutputType("PSObject")]
657+
public class GetAWSAutoIterationModeCmdlet : PSCmdlet
658+
{
659+
protected override void ProcessRecord()
660+
{
661+
base.ProcessRecord();
662+
var autoIterationMode= this.SessionState.PSVariable.Get(SessionKeys.AWSAutoIterationMode);
663+
var result = new PSObject();
664+
665+
const string defaultAutoIterationMode = "standard";
666+
667+
var noteProperty = new PSNoteProperty("AutoIterationMode", defaultAutoIterationMode);
668+
669+
if (autoIterationMode != null)
670+
{
671+
noteProperty.Value = autoIterationMode.Value.ToString();
672+
}
673+
600674
result.Properties.Add(noteProperty);
601675
WriteObject(result);
602676
}

modules/AWSPowerShell/Common/CredentialsArguments.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -725,6 +725,7 @@ internal static class SessionKeys
725725
public const string AWSRegionVariableName = "StoredAWSRegion";
726726
public const string AWSShowSensitiveData = "AWSPowerShell_Show_Sensitive_Data";
727727
public const string AWSProxyVariableName = "AWSProxy";
728+
public const string AWSAutoIterationMode = "AWSPowerShell_AutoIteration_Mode";
728729
}
729730

730731
internal static class CredentialProfileOptionsExtractor

modules/ModularAWSPowerShell/AWS.Tools.Common.psd1

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,9 @@ Alternative modules, AWSPowerShell.NetCore and AWSPowerShell, provide support fo
9595
'Clear-AWSDefaultConfiguration',
9696
'Get-AWSPowerShellVersion',
9797
'Set-AWSSensitiveDataConfiguration',
98-
'Get-AWSSensitiveDataConfiguration',
98+
'Get-AWSSensitiveDataConfiguration',
99+
'Set-AWSAutoIterationMode',
100+
'Get-AWSAutoIterationMode',
99101
'New-AWSCredential',
100102
'Set-AWSCredential',
101103
'Clear-AWSCredential',

0 commit comments

Comments
 (0)