aws-cloudformation / cloudformation-cli-go-plugin

The CloudFormation Provider Development Toolkit Go Plugin allows you to autogenerate Go code based on an input schema.
52 stars 31 forks source link

Expose previous and current resource properties #185

Closed parsnips closed 2 years ago

parsnips commented 3 years ago

Issue #, if available:

https://github.com/aws-cloudformation/cloudformation-cli-go-plugin/issues/184

Description of changes:

Allows users to use their own Unmarshal strategy by exposing the making the raw resource bytes through a get method.

e.g.


       // Populate the previous model
    prevModel := &resource.Model{}
    if err := json.Unmarshal(req.GetPreviousResourcePropertiesBody(), prevModel); err != nil {
        log.Printf("Error unmarshaling prev model: %v", err)
        return handler.NewFailedEvent(err)
    }

    // Populate the current model
    currentModel := &resource.Model{}
    if err := json.Unmarshal(req.GetResourcePropertiesBody(), currentModel); err != nil {
        log.Printf("Error unmarshaling model: %v", err)
        return handler.NewFailedEvent(err)
    }

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

kddejong commented 3 years ago

I like this idea. A lot of times when working with other packages they already have the models I need defined. They already have the logic for Marshaling and Unmarshaling as well.

The only thing that I got tripped up is when I have to send the response the stringify would fail a lot with non standard types

parsnips commented 3 years ago

The only thing that I got tripped up is when I have to send the response the stringify would fail a lot with non standard types

Yes I noticed that bool is sent in as a string in my case and now understand why the stringify and unstringify methods exist... In my case I just encapsulated that logic into a type... and used it in place of bools in my model.

eg:

type StringyBool bool

func (s *StringyBool) UnmarshalJSON(data []byte) error {
    asStr := string(data)
    if asStr == "true" {
        *s = true
    } else { // else if asStr == "false"
        *s = false
    }

    return nil
}

It's a matter of different approaches I guess.. but this one gives the end user a bit more flexibility.