edit: I have solved my issue, look inside thread f...
# golang
d
edit: I have solved my issue, look inside thread for solution. Hi folks, I'm seriously struggling with using Pulumi stack references containing complex objects. I'm exporting this:
Copy code
type SubnetServiceEndpoint struct {
	ServiceEndpoint          string             `pulumi:"ServiceEndpoints"`
	ServiceEndpointLocations pulumi.StringArray `pulumi:"ServiceEndpointsLocation"`
}

type Subnet struct {
	AddressPrefix                     string                  `pulumi:"AddressPrefix"`
	Name                              string                  `pulumi:"Name"`
	ServiceEndpoints                  []SubnetServiceEndpoint `pulumi:"ServiceEndpoints"`
	PrivateEndpointNetworkPolicies    string                  `pulumi:"PrivateEndpointNetworkPolicies"`
	PrivateLinkServiceNetworkPolicies string                  `pulumi:"PrivateLinkServiceNetworkPolicies"`
}

type AddressSpace struct {
	AddressPrefix string `pulumi:"AddressPrefix"`
}

type VNETPeering struct {
	NetworkPeerName                  string         `pulumi:"NetworkPeerName"`
	RemoteAddressSpace               []AddressSpace `pulumi:"RemoteAddressSpace"`
	RemoteVirtualNetworkAddressSpace []AddressSpace `pulumi:"RemoteVirtualNetworkAddressSpace"`
	RemoteVirtualNetwork             string         `pulumi:"RemoteVirtualNetwork"`
}

type VNET struct {
	Name         string        `pulumi:"VNETName"`
	VNETPeering  []VNETPeering `pulumi:"VNETPeering"`
	AddressSpace string        `pulumi:"AddressSpace"`
	Subnets      []Subnet      `pulumi:"Subnets"`
}

.... elsewhere in the code, I export OutputVNET which is a VNET{} struct, using
ctx.Export("VNET", OutputVNET)
.. running pulumi up shows the output in all it's nested data filled glory!! Then in my other stack, were I'd like to use this output, I have a stack reference
stagingBase *pulumi.StackReference
(that works, because I can read all the other simple stack references).. How does one use ApplyT to unmarshal the
map[string]interface{}
to my set of struct types? I tried using type assertions but it was unsightly and arcane.. please help!
c
I have a small question. How do you marshal this object? As I never had any problem with unmarshal, but I have a problem how to marshal it. It always says me:
Copy code
error: an unhandled error occurred: program failed:
waiting for RPCs: json: error calling MarshalJSON for type pulumi.StringOutput: Outputs can not be marshaled to JSON
d
I refactored my structs to be this fashion:
Copy code
type Subnet struct {
	AddressPrefix                     pulumi.String          `json:"addressPrefix"`
	Etag                              pulumi.String          `json:"etag"`
	ID                                pulumi.String          `json:"id"`
	Name                              pulumi.String          `json:"name"`
	PrivateEndpointNetworkPolicies    pulumi.String          `json:"privateEndpointNetworkPolicies"`
	PrivateLinkServiceNetworkPolicies pulumi.String          `json:"privateLinkServiceNetworkPolicies"`
	ProvisioningState                 pulumi.String          `json:"provisioningState"`
	ServiceEndpoints                  []ServiceEndpoint `json:"serviceEndpoints"`
	Type                              pulumi.String          `json:"type"`
	IPConfigurations                  []IPConfiguration `json:"ipConfigurations"`
}

type ServiceEndpoint struct {
	Locations         []string      `json:"locations"`
	ProvisioningState pulumi.String `json:"provisioningState"`
	Service           pulumi.String  `json:"service"`
}

type IPConfiguration struct {
	Etag              string `json:"etag"`
	ID                string `json:"id"`
	ProvisioningState string `json:"provisioningState"`
}
.. it turns out I was hitting a race condition because ApplyT is async.. the amount of data took a while and my function would exit returning a nil struct 🤦‍♂️ .. this is how I populated my struct from the stack reference:
Copy code
func convertOutputToSubnet(i pulumi.AnyOutput) ([]Subnet, error) {
	var subnets []Subnet
	done := make(chan bool)
	var finalErr error

	i.ApplyT(func(v interface{}) (interface{}, error) {
		interfaceSlice, ok := v.([]interface{})
		if !ok {
			finalErr = fmt.Errorf("unexpected type")
			done <- true
			return nil, finalErr
		}

		for _, v := range interfaceSlice {
			var s Subnet
			bytes, err := json.Marshal(v)
			if err != nil {
				finalErr = err
				done <- true
				return nil, err
			}
			err = json.Unmarshal(bytes, &s)
			if err != nil {
				finalErr = err
				done <- true
				return nil, err
			}

			if s.Name != "" {
				subnets = append(subnets, s)
			}
		}

		done <- true
		return subnets, nil
	})

	<-done

	if finalErr != nil {
		return nil, finalErr
	}

	return subnets, nil
}
credit where credit is due.. thanks ChatGPT.. I for one welcome our AI overlords
c
Thanks, I also thought the same as pulumi can't marshal unknown objects.