/// <summary> /// Gets the stack dynamic parameters. /// </summary> /// <param name="fileParameters">Parameters read from parameter file, if any.</param> /// <returns>A <see cref="RuntimeDefinedParameterDictionary"/> containing all non-SSM template parameters</returns> public RuntimeDefinedParameterDictionary GetStackDynamicParameters(IDictionary <string, string> fileParameters) { var dynamicParams = new RuntimeDefinedParameterDictionaryHelper(); try { foreach (var param in this.TemplateParameters) { var builder = new RuntimeDefinedParameterBuilder(param.Name, GetClrTypeFromAwsType(param.Type)); if ((param.Default == null && this.stackOperation == StackOperation.Create && !fileParameters.ContainsKey(param.Name)) || (this.stackOperation == StackOperation.Export && this.templateResolver.NoEchoParameters.Contains(param.Name))) { // Only make parameter mandatory when creating, and the parameter isn't defined in a parameter file // or if exporting a stack and parameter is NoEcho builder.WithMandatory(); } if (!string.IsNullOrEmpty(param.Description)) { builder.WithHelpMessage(param.Description); } if (param.IsSsmParameter) { // For all AWS::SSM::Parameter types, the value is a string which is the referenced parameter key. // Validation of the actual SSM parameter _value_ is done by CF when the parameter is fetched. builder.WithValidatePattern(new Regex(@"[\w\.\-/]+")); builder.WithValidateLength(1, 2048); } else if (param.Type.Contains("AWS::")) { // Set a ValidatePattern for the given AWS type var baseType = param.Type; if (param.Type.StartsWith("List<")) { baseType = Regex.Match(param.Type, @"List<(?<baseType>.*)>").Groups["baseType"].Value; } builder.WithValidatePattern(AwsParameterTypeRegexes[baseType]); } else { if (param.AllowedValues != null && param.AllowedValues.Any()) { builder.WithValidateSet(param.AllowedValues.ToArray()); } if (param.Type == "String") { if (param.AllowedPattern != null) { builder.WithValidatePattern(param.AllowedPattern); } if (param.HasMaxLength || param.HasMinLength) { builder.WithValidateLength(param.MinLength ?? 0, param.MaxLength ?? int.MaxValue); } } if ((param.Type == "Number" || param.Type == "List<Number>") && (param.HasMaxValue || param.HasMinValue)) { builder.WithValidateRange(param.MinValue, param.MaxValue); } } var dynamicParameter = builder.Build(); dynamicParams.Add(dynamicParameter); } } catch (Exception e) { this.logger?.LogError($"Error creating dynamic parameters: {e.Message}"); this.logger?.LogError(e.StackTrace); throw; } return((RuntimeDefinedParameterDictionary)dynamicParams); }
/// <summary> /// Gets the dynamic parameters. /// The parameter is created based on the value of <see cref="Constants.DynamicParameterName"/> /// </summary> /// <returns>A <see cref="RuntimeDefinedParameterDictionary"/></returns> public object GetDynamicParameters() { var dynamicParams = new RuntimeDefinedParameterDictionaryHelper(); switch ((TestCases)this.TestNumber) { case TestCases.UndecoratedArgument: // All input values will be treated as object dynamicParams.Add(new RuntimeDefinedParameterBuilder(Constants.DynamicParameterName)); break; case TestCases.NumericArgumentDouble: // Input values will be cast to double dynamicParams.Add(new RuntimeDefinedParameterBuilder(Constants.DynamicParameterName, typeof(double))); break; case TestCases.PocoArgument: // The input value is explicitly an instance of TestPoco dynamicParams.Add(new RuntimeDefinedParameterBuilder(Constants.DynamicParameterName, typeof(TestPoco))); break; case TestCases.MandatoryArgument: // All input values will be treated as object - param is mandatory dynamicParams.Add(new RuntimeDefinedParameterBuilder(Constants.DynamicParameterName).WithMandatory()); break; case TestCases.MandatoryWithAllowNull: dynamicParams.Add( new RuntimeDefinedParameterBuilder(Constants.DynamicParameterName).WithMandatory().WithAllowNull()); break; case TestCases.ValueFromPipeline: // All input values will be treated as object dynamicParams.Add(new RuntimeDefinedParameterBuilder(Constants.DynamicParameterName).WithValueFromPipeline()); break; case TestCases.ValueFromPipelineByPropertyName: // All input values will be treated as object dynamicParams.Add( new RuntimeDefinedParameterBuilder(Constants.DynamicParameterName) .WithValueFromPipelineByPropertyName()); break; case TestCases.ValidateSetViaArguments: dynamicParams.Add(new RuntimeDefinedParameterBuilder(Constants.DynamicParameterName).WithValidateSet(Constants.ValidStrings)); break; case TestCases.ValidateSetFromPipeline: dynamicParams.Add( new RuntimeDefinedParameterBuilder(Constants.DynamicParameterName) .WithValidateSet(Constants.ValidStrings).WithValueFromPipeline()); break; case TestCases.ValidateSetFromPipelineByPropertyName: dynamicParams.Add( new RuntimeDefinedParameterBuilder(Constants.DynamicParameterName) .WithValidateSet(Constants.ValidStrings).WithValueFromPipelineByPropertyName()); break; case TestCases.PositionalArgument: dynamicParams.Add(new RuntimeDefinedParameterBuilder(Constants.DynamicParameterName).WithPosition(0)); break; case TestCases.AliasArgument: dynamicParams.Add(new RuntimeDefinedParameterBuilder(Constants.DynamicParameterName).WithAliases( Constants.ParameterAliasOne, Constants.ParameterAliasTwo)); break; case TestCases.ValidatePatternViaArguments: dynamicParams.Add(new RuntimeDefinedParameterBuilder(Constants.DynamicParameterName).WithValidatePattern(Constants.IpAddressRegex)); break; case TestCases.ValidatePatternWithRegexObject: dynamicParams.Add(new RuntimeDefinedParameterBuilder(Constants.DynamicParameterName).WithValidatePattern(new Regex(Constants.IpAddressRegex))); break; case TestCases.ValidatePatterWithOptionsCaseSensitive: // Uses default RegexOptions.None - which is case sensitive dynamicParams.Add(new RuntimeDefinedParameterBuilder(Constants.DynamicParameterName).WithValidatePattern(Constants.CaseSensitivityRegex)); break; case TestCases.ValidatePatterWithRegexObjectOptionsCaseSensitive: // Uses default RegexOptions.None - which is case sensitive dynamicParams.Add(new RuntimeDefinedParameterBuilder(Constants.DynamicParameterName).WithValidatePattern(new Regex(Constants.CaseSensitivityRegex))); break; case TestCases.ValidatePatterWithOptionsCaseInsensitive: dynamicParams.Add(new RuntimeDefinedParameterBuilder(Constants.DynamicParameterName).WithValidatePattern(Constants.CaseSensitivityRegex, RegexOptions.IgnoreCase)); break; case TestCases.ValidatePatternWithRegexObjectOptionsCaseInsensitive: dynamicParams.Add(new RuntimeDefinedParameterBuilder(Constants.DynamicParameterName).WithValidatePattern(new Regex(Constants.CaseSensitivityRegex, RegexOptions.IgnoreCase))); break; case TestCases.ValidateRangeWithMinMax: dynamicParams.Add(new RuntimeDefinedParameterBuilder(Constants.DynamicParameterName, typeof(int)).WithValidateRange(Constants.ValidRange[0], Constants.ValidRange[1])); break; case TestCases.ValidateScript: dynamicParams.Add(new RuntimeDefinedParameterBuilder(Constants.DynamicParameterName, typeof(int)).WithValidateScript(Constants.ValidateScript)); break; case TestCases.ValidateNotNull: dynamicParams.Add(new RuntimeDefinedParameterBuilder(Constants.DynamicParameterName).WithValidateNotNull()); break; case TestCases.ValidateNotNullOrEmpty: dynamicParams.Add(new RuntimeDefinedParameterBuilder(Constants.DynamicParameterName).WithValidateNotNullOrEmpty()); break; case TestCases.ValidateCount: dynamicParams.Add(new RuntimeDefinedParameterBuilder(Constants.DynamicParameterName).WithValidateCount(Constants.ValidCounts[0], Constants.ValidCounts[1])); break; case TestCases.ValidateLength: dynamicParams.Add(new RuntimeDefinedParameterBuilder(Constants.DynamicParameterName).WithValidateLength(Constants.ValidLengths[0], Constants.ValidLengths[1])); break; case TestCases.ParameterSetsFirstParameterInSetASecondParameterNotInSet: dynamicParams.Add(new RuntimeDefinedParameterBuilder(Constants.DynamicParameterSetFirstParameter).WithParameterSets(Constants.DynamicParameterSetsSetA)); dynamicParams.Add(new RuntimeDefinedParameterBuilder(Constants.DynamicParameterSetSecondParameter)); break; case TestCases.ParameterSetInvalidCombination: dynamicParams.Add(new RuntimeDefinedParameterBuilder(Constants.DynamicParameterSetFirstParameter).WithParameterSets(Constants.DynamicParameterSetsSetA)); dynamicParams.Add(new RuntimeDefinedParameterBuilder(Constants.DynamicParameterSetSecondParameter).WithParameterSets(Constants.DynamicParameterSetsSetB)); break; case TestCases.ValueFromRemainingArguments: dynamicParams.Add(new RuntimeDefinedParameterBuilder(Constants.DynamicParameterName).WithValueFromRemainingArguments()); break; #if NETCOREAPP // PowerShell Core only case TestCases.ValidateRangeWithRangeKindNonNegative: dynamicParams.Add(new RuntimeDefinedParameterBuilder(Constants.DynamicParameterName, typeof(int)).WithValidateRange(Constants.ValidRangeKindNonNegative)); break; #endif #if NETCOREAPP3_1 // PowerShell 7 only case TestCases.ValidatePatternWithCustomMessage: dynamicParams.Add( new RuntimeDefinedParameterBuilder(Constants.DynamicParameterName) .WithValidatePattern(Constants.IpAddressRegex) .WithValidationErrorMessage(Constants.InvalidIpAddressCustomMessage)); break; case TestCases.ValidateSetWithCustomMessage: dynamicParams.Add( new RuntimeDefinedParameterBuilder(Constants.DynamicParameterName) .WithValidateSet(Constants.ValidStrings) .WithValidationErrorMessage(Constants.InvalidParameterValueCustomMessage)); break; #endif } // Return the RuntimeDefinedParameterDictionaryHelper. return((RuntimeDefinedParameterDictionary)dynamicParams); }