/// <summary> /// Computes a URN from the combination of a resource name, resource type, optional parent, /// optional project and optional stack. /// </summary> /// <returns></returns> internal static Output <string> Create( Input <string> name, Input <string> type, Resource?parent, Input <string>?parentUrn, Input <string>?project, Input <string>?stack) { if (parent != null && parentUrn != null) { throw new ArgumentException("Only one of 'parent' and 'parentUrn' can be non-null."); } Output <string> parentPrefix; if (parent != null || parentUrn != null) { var parentUrnOutput = parent != null ? parent.Urn : parentUrn !.ToOutput(); parentPrefix = parentUrnOutput.Apply( parentUrnString => parentUrnString.Substring( 0, parentUrnString.LastIndexOf("::", StringComparison.Ordinal)) + "$"); } else { parentPrefix = Output.Create($"urn:pulumi:{stack ?? Deployment.Instance.StackName}::{project ?? Deployment.Instance.ProjectName}::"); } return(Output.Format($"{parentPrefix}{type}::{name}")); }
/// <summary> /// <see cref="InheritedChildAlias"/> computes the alias that should be applied to a child /// based on an alias applied to it's parent. This may involve changing the name of the /// resource in cases where the resource has a named derived from the name of the parent, /// and the parent name changed. /// </summary> internal static Output <Alias> InheritedChildAlias(string childName, string parentName, Input <string> parentAlias, string childType) { // If the child name has the parent name as a prefix, then we make the assumption that // it was constructed from the convention of using '{name}-details' as the name of the // child resource. To ensure this is aliased correctly, we must then also replace the // parent aliases name in the prefix of the child resource name. // // For example: // * name: "newapp-function" // * options.parent.__name: "newapp" // * parentAlias: "urn:pulumi:stackname::projectname::awsx:ec2:Vpc::app" // * parentAliasName: "app" // * aliasName: "app-function" // * childAlias: "urn:pulumi:stackname::projectname::aws:s3/bucket:Bucket::app-function" var aliasName = Output.Create(childName); if (childName !.StartsWith(parentName, StringComparison.Ordinal)) { aliasName = parentAlias.ToOutput().Apply <string>(parentAliasUrn => { return(parentAliasUrn.Substring(parentAliasUrn.LastIndexOf("::", StringComparison.Ordinal) + 2) + childName.Substring(parentName.Length)); }); } var urn = Create( aliasName, childType, parent: null, parentUrn: parentAlias, project: null, stack: null); return(urn.Apply(u => new Alias { Urn = u })); }
public static Output <object?> ToObjectOutput(this object?obj) { var output = obj is IInput input?input.ToOutput() : obj as IOutput; return(output != null ? new Output <object?>(output.Resources, output.GetDataAsync()) : Output.Create(obj)); }
private static Output <string> CollapseAliasToUrn( Input <Alias> alias, string defaultName, string defaultType, Resource?defaultParent) { return(alias.ToOutput().Apply(a => { if (a.Urn != null) { CheckNull(a.Name, nameof(a.Name)); CheckNull(a.Type, nameof(a.Type)); CheckNull(a.Project, nameof(a.Project)); CheckNull(a.Stack, nameof(a.Stack)); CheckNull(a.Parent, nameof(a.Parent)); CheckNull(a.ParentUrn, nameof(a.ParentUrn)); if (a.NoParent) { ThrowAliasPropertyConflict(nameof(a.NoParent)); } return Output.Create(a.Urn); } var name = a.Name ?? defaultName; var type = a.Type ?? defaultType; var project = a.Project ?? Deployment.Instance.ProjectName; var stack = a.Stack ?? Deployment.Instance.StackName; var parentCount = (a.Parent != null ? 1 : 0) + (a.ParentUrn != null ? 1 : 0) + (a.NoParent ? 1 : 0); if (parentCount >= 2) { throw new ArgumentException( $"Only specify one of '{nameof(Alias.Parent)}', '{nameof(Alias.ParentUrn)}' or '{nameof(Alias.NoParent)}' in an {nameof(Alias)}"); } var(parent, parentUrn) = GetParentInfo(defaultParent, a); if (name == null) { throw new Exception("No valid 'Name' passed in for alias."); } if (type == null) { throw new Exception("No valid 'type' passed in for alias."); } return Pulumi.Urn.Create(name, type, parent, parentUrn, project, stack); })); }
/// <summary> /// Create a Stack with stack resources created by the <c>init</c> callback. /// An instance of this will be automatically created when any <see /// cref="Deployment.RunAsync(Action)"/> overload is called. /// </summary> internal Stack(Func <Task <IDictionary <string, object?> > > init) : this() { try { this.Outputs = Output.Create(RunInitAsync(init)); } finally { this.RegisterOutputs(this.Outputs); } }
internal Stack(Func <Task <IDictionary <string, object?> > > init) : base(_rootPulumiStackTypeName, $"{Deployment.Instance.ProjectName}-{Deployment.Instance.StackName}") { Deployment.InternalInstance.Stack = this; try { this.Outputs = Output.Create(RunInitAsync(init)); } finally { this.RegisterOutputs(this.Outputs); } }
/// <summary> /// Inspect all public properties of the stack to find outputs. Validate the values and register them as stack outputs. /// </summary> internal void RegisterPropertyOutputs() { var outputs = (from property in this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly) let attr1 = property.GetCustomAttribute <Pulumi.OutputAttribute>() #pragma warning disable 618 let attr2 = property.GetCustomAttribute <Pulumi.Serialization.OutputAttribute>() #pragma warning restore 618 where attr1 != null || attr2 != null let name = attr1?.Name ?? attr2?.Name ?? property.Name select new KeyValuePair <string, object?>(name, property.GetValue(this))).ToList(); // Check that none of the values are null: catch unassigned outputs var nulls = (from kv in outputs where kv.Value == null select kv.Key).ToList(); if (nulls.Any()) { var message = $"Output(s) '{string.Join(", ", nulls)}' have no value assigned. [Output] attributed properties must be assigned inside Stack constructor."; throw new RunException(message); } // Check that all the values are Output<T> var wrongTypes = (from kv in outputs let type = kv.Value.GetType() let isOutput = type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Output <>) where !isOutput select kv.Key).ToList(); if (wrongTypes.Any()) { var message = $"Output(s) '{string.Join(", ", wrongTypes)}' have incorrect type. [Output] attributed properties must be instances of Output<T>."; throw new RunException(message); } IDictionary <string, object?> dict = new Dictionary <string, object?>(outputs); this.Outputs = Output.Create(dict); this.RegisterOutputs(this.Outputs); }
public InputUnion() : this(Output.Create(default(Union <T0, T1>))) { }
public static Output <T> Create <T>(Task <T> value) => Output <T> .Create(value);
public InputMap() : this(Output.Create(ImmutableDictionary <string, V> .Empty)) { }
public InputList() : this(Output.Create(ImmutableArray <T> .Empty)) { }
public InputJson() : this(Output.Create(default(JsonElement))) { }
/// <summary> /// <see cref="SerializeResourcePropertiesAsync"/> walks the props object passed in, /// awaiting all interior promises besides those for <see cref="Resource.Urn"/> and <see /// cref="CustomResource.Id"/>, creating a reasonable POCO object that can be remoted over /// to registerResource. /// </summary> private static Task <SerializationResult> SerializeResourcePropertiesAsync( string label, IDictionary <string, IInput?> args) { return(SerializeFilteredPropertiesAsync( label, Output.Create(args), key => key != Constants.IdPropertyName && key != Constants.UrnPropertyName)); }