/// <summary> /// End processing an intrinsic. /// </summary> public void ExitIntrinsic() { var lastIntrinsicInfo = this.currentIntrinsicInfo; this.currentIntrinsicInfo = this.intrinsicInfos.Pop(); if (this.currentIntrinsicInfo != null) { return; } // Recursion has returned to the "top level" intrinsic, so store it. if (this.lastWarning == null) { this.ReferenceLocations.Add(lastIntrinsicInfo); } else { // Process the warning this.warnings.Add(this.lastWarning.Message); this.lastWarning = null; } this.parentIntrinsicPath = null; }
/// <summary> /// Creates a modification record. /// </summary> /// <param name="jsonValue">The JSON value that will be replaced.</param> /// <param name="context">The context.</param> /// <param name="intrinsicInfo">The intrinsic information.</param> private static void CreateModification( JValue jsonValue, TerraformAttributeSetterContext context, IntrinsicInfo intrinsicInfo) { var intrinsic = intrinsicInfo.Intrinsic; // ReSharper disable once SwitchStatementMissingSomeEnumCasesNoDefault switch (intrinsic.Type) { case IntrinsicType.Base64: case IntrinsicType.Cidr: case IntrinsicType.Split: case IntrinsicType.Ref: case IntrinsicType.Select: case IntrinsicType.FindInMap: case IntrinsicType.GetAtt: case IntrinsicType.Join: case IntrinsicType.Sub: case IntrinsicType.ImportValue: context.Modifications.Add( new StateModification( jsonValue, context.Index, context.ContainingProperty, intrinsic.Render(context.Template, intrinsicInfo.TargetResource, context.Inputs))); break; } }
/// <summary> /// Begin processing an intrinsic. /// </summary> /// <param name="intrinsic">The intrinsic.</param> /// <param name="currentPath">The current path.</param> public void EnterIntrinsic(IIntrinsic intrinsic, PropertyPath currentPath) { if (this.lastWarning != null) { // Something that can't be resolved has been found, // so don't process any more here. return; } var clonedPath = currentPath.Clone(); try { if (this.parentIntrinsicPath == null) { // This is a "top level" intrinsic associated directly with a resource attribute. if (this.currentCloudFormationResource.Type == "AWS::Lambda::Permission" && currentPath.Path == "FunctionName" && intrinsic is RefIntrinsic) { // !! NASTY KLUDGE ALERT !! // AWS treats this property as a !Ref which is lambda function's name, but terraform actually wants the ARN here. // If I find more cases like this, then I'll put something into resource traits intrinsic = new GetAttIntrinsic( intrinsic.GetReferencedObjects(this.template).First(), "Arn"); } this.intrinsicInfos.Push(this.currentIntrinsicInfo); this.parentIntrinsicPath = clonedPath; this.currentIntrinsicInfo = this.GetIntrinsicInfo(intrinsic, currentPath); } else { // We have descended the graph to member intrinsic this.intrinsicInfos.Push(this.currentIntrinsicInfo); var intrinsicInfo = this.GetIntrinsicInfo(intrinsic, currentPath); this.currentIntrinsicInfo.NestedIntrinsics.Add(intrinsicInfo); this.currentIntrinsicInfo = intrinsicInfo; } } catch (DependencyResolutionWarning w) { this.lastWarning = w; } }
/// <summary> /// Hooks up a module input to a <see cref="Reference"/> that gets its value. /// </summary> /// <param name="referencedModule">The referenced module.</param> /// <param name="intrinsicInfo">The intrinsic information.</param> /// <param name="reference">The reference.</param> private static void ApplyModuleInputReference( ModuleInfo referencedModule, IntrinsicInfo intrinsicInfo, Reference reference) { // Find input with value matching the intrinsic evaluation var index = GetModuleInputIndex( referencedModule.Inputs, tuple => tuple.Item1.ScalarIdentity == intrinsicInfo.Evaluation.ToString()); if (index != -1) { // Overwrite the original scalar input with a new reference. referencedModule.Inputs[index] = new ModuleInputVariable( referencedModule.Inputs[index].Name, reference); } }