Hey All, Is there an easy way to Append a pulumi.S...
# golang
r
Hey All, Is there an easy way to Append a pulumi.String(“Hello”) object to a Pulumi.StringArray object. I am trying implement something like this…
Copy code
var denyPorts pulumi.StringArray
for _, denyPort := range local.DenyPorts {
	append(denyPorts, pulumi.String(denyPort))
}
I basically receive the following error:
Copy code
append(denyPorts, pulumi.String(denyPort)) (value of type pulumi.StringArray) is not used
I assume there must be a way to combine pulumi.String and pulumi.StringArray If not what would be the suggested approach? Is there a different way to convert a []string object in go to pulumi.StringArray? Thanks in advance.
s
Disclaimer: I’m not a Golang expert. Maybe try defining
denyPorts
as a standard string array (
[]string
),
append
your items to it, and then reference it in the resource declaration as
pulumi.StringArray(denyPorts)
(or similar, might need to tweak the syntax there with braces instead).
r
I will have a crack at this tomorrow for sure and report back.
Hey @salmon-account-74572 I think this approach may have worked. However I get stuck with the concepts of how to handle appending to a Specific Pulumi Array Type … For Example. A Golang Object of Type: compute.FirewallAllowArray{} and it takes a type of compute.FirewallAllowArgs{} as it’s nested object. So ideally Go Slice Native Declaration: [FirewallAllowArgs]FirewallAllowArray… I don’t know how to append a “FirewallAllowArgs” object to a “FirewallAllowArray” object. Specifically I am trying to do this:
Copy code
// Create Pulumi Firewall Array Object
fwAllowArray := compute.FirewallAllowArray{}
// Create Multiple Pului Array Argument Object (Dynamic Allow Rules)
for _, rule := range MyRules {
   fwAllowArgs := compute.FirewallAllowArgs{
       Protocol: pulumi.String(rule.Protocol),
       Ports: pulumi.ToStringArray(rule.Ports) 
   }
   append(fwAllowArray, fwAllowArgs) <---- ERROR HERE *
}


* This bit Doesn't Work, I understand why cause its not a Native Slice and Append isn't understanding the underlying struct, BUT HOW does one dynamically add ArgsStrcuts to ArrayStructs with Go in Pulumi....? understanding this would really unlock me as it is a pattern is see time and time again with Array & ArrayArgs objects in Pulumi.
s
Let me ping some folks internally and see if someone more well-versed in the Go SDK can weigh in on this.
r
Thanks so much would appreciate this;
s
One of the engineers gave me this code:
Copy code
func Append(ctx context.Context, arr StringArrayInput, str StringInput) StringArrayOutput {
	return AllWithContext(ctx, arr, str).ApplyTWithContext(ctx, func(ctx context.Context, vars []interface{}) []string {
		arr := vars[0].([]string)
		str := vars[1].(string)
		return append(arr, str)
	}).(StringArrayOutput)
}
That doesn’t directly address the
FirewallAllowArray
portion of your question, I don’t think, but it might unlock a pattern that would work there. Personally, I need to study it a bit more to fully grok it. 🙂
e
I've just raised https://github.com/pulumi/pulumi/issues/11756 to track that we should support this better
s
Thanks @echoing-dinner-19531! (Both for creating the issue and for supplying the code snippet above!)
r
Thanks @echoing-dinner-19531 appreciate this; I myself and @adventurous-apartment-93389 been looking to build out some serious GCP patterns and (with Bias) we chose Go as the first stop and this has been a big sticking point for us the last few days. I think i would be awesome to get this one patched across any ArrayBased Object.
Am I right in thinking though the the explicit use of
Copy code
AppendWithContext
is the current way forward?
e
We normally have X and XWithContext methods in the Go SDK for anything that internally is an Apply. The fun with this will be Go doesn't actually have method overloads, so these will probably have to be on the type itself somehow. So not totally sure what we would do here, but the method implementation itself is sound you can copy paste that for now.
w
FWIW - I think the answer to the original question is simpler. In Go, append is used like
arr = append(arr, item)
, and doing so in your example above should work like you expect:
Copy code
fwAllowArray := compute.FirewallAllowArray{}
        for _, rule := range MyRules {
			fwAllowArgs := compute.FirewallAllowArgs{
				Protocol: pulumi.String(rule.Protocol),
				Ports:    pulumi.ToStringArray(rule.Ports),
			}
			fwAllowArray = append(fwAllowArray, fwAllowArgs)
		}
Here's a complete example:
Copy code
package main

import (
	"<http://github.com/pulumi/pulumi-gcp/sdk/v6/go/gcp/compute|github.com/pulumi/pulumi-gcp/sdk/v6/go/gcp/compute>"
	"<http://github.com/pulumi/pulumi/sdk/v3/go/pulumi|github.com/pulumi/pulumi/sdk/v3/go/pulumi>"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		MyRules := []struct {
			Protocol string
			Ports    []string
		}{
			{"tcp", []string{"80", "443"}},
			{"udp", []string{"53"}},
		}
		network, err := compute.NewNetwork(ctx, "my-network", &compute.NetworkArgs{})
		if err != nil {
			return err
		}

		// Firewall
		var fwAllowArray compute.FirewallAllowArray
		for _, rule := range MyRules {
			fwAllowArray = append(fwAllowArray, compute.FirewallAllowArgs{
				Protocol: pulumi.String(rule.Protocol),
				Ports:    pulumi.ToStringArray(rule.Ports),
			})
		}

		firewall, err := compute.NewFirewall(ctx, "fw-allow-http-https-udp53", &compute.FirewallArgs{
			Network:      network.ID(),
			Allows:       fwAllowArray,
			SourceRanges: pulumi.StringArray{},
		})
		if err != nil {
			return err
		}

		ctx.Export("id", firewall.ID())
		return nil
	})

}
r
Hey Gents (@salmon-account-74572, @echoing-dinner-19531 & @white-balloon-205). Firstly I want to say thanks for the collaboration. Really found it helpful on both closing my knowledge gap and building out some of our content. Been diving into the example and details. I have reworked the example into my overall solution and yep, it does work. 100% So thanks very much; I think where I got tied up is trying to find the balance between using Pulumi specific functions and types vs go native programming structures and functions. Thanks again for your help. If I find more elements like this I will certainly be asking about them cause I am trying to build out some very detailed Google Architectures which might be mutually beneficial going forward.
s
Happy to help, Tim! (Not that I was much help, except in bringing in the right folks!) Let us know how we can help further, happy to continue to collaborate.