Ejemplo n.º 1
0
        /// <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}"));
        }
Ejemplo n.º 2
0
        /// <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
            }));
        }
Ejemplo n.º 3
0
        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));
        }
Ejemplo n.º 4
0
        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);
            }));
        }
Ejemplo n.º 5
0
 /// <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);
     }
 }
Ejemplo n.º 6
0
        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);
            }
        }
Ejemplo n.º 7
0
        /// <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);
        }
Ejemplo n.º 8
0
 public InputUnion() : this(Output.Create(default(Union <T0, T1>)))
 {
 }
Ejemplo n.º 9
0
 public static Output <T> Create <T>(Task <T> value)
 => Output <T> .Create(value);
Ejemplo n.º 10
0
 public InputMap() : this(Output.Create(ImmutableDictionary <string, V> .Empty))
 {
 }
Ejemplo n.º 11
0
 public InputList() : this(Output.Create(ImmutableArray <T> .Empty))
 {
 }
Ejemplo n.º 12
0
 public InputJson() : this(Output.Create(default(JsonElement)))
 {
 }
Ejemplo n.º 13
0
 /// <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));
 }