Travis
Travis

Reputation: 3193

nested struct with golang from json

I am trying to take a cloudwatch_event and get it into a go struct. I have a CloudwatchEvent struct and inside of that is a blob of json that I need to get into another struct. The first level of the struct seems to work fine, but there is a parsing error when it tries to access the nested json.

This is my sample event. I am trying to get down to detail > EC2InstanceId I think I will also need the status code.

{
  "version": "0",
  "id": "3e3c153a-8339-4e30-8c35-687ebef853fe",
  "detail-type": "EC2 Instance Launch Successful",
  "source": "aws.autoscaling",
  "account": "123456789012",
  "time": "2015-11-11T21:31:47Z",
  "region": "us-east-1",
  "resources": [
    "arn:aws:autoscaling:us-east-1:123456789012:autoScalingGroup:eb56d16b-bbf0-401d-b893-d5978ed4a025:autoScalingGroupName/sampleLuanchSucASG",
    "arn:aws:ec2:us-east-1:123456789012:instance/i-b188560f"
  ],
  "detail": {
    "StatusCode": "InProgress",
    "AutoScalingGroupName": "sampleLuanchSucASG",
    "ActivityId": "9cabb81f-42de-417d-8aa7-ce16bf026590",
    "Details": {
      "Availability Zone": "us-east-1b",
      "Subnet ID": "subnet-95bfcebe"
    },
    "RequestId": "9cabb81f-42de-417d-8aa7-ce16bf026590",
    "EndTime": "2015-11-11T21:31:47.208Z",
    "EC2InstanceId": "i-b188560f",
    "StartTime": "2015-11-11T21:31:13.671Z",
    "Cause": "At 2015-11-11T21:31:10Z a user request created an AutoScalingGroup changing the desired capacity from 0 to 1.  At 2015-11-11T21:31:11Z an instance was started in response to a difference between desired and actual capacity, increasing the capacity from 0 to 1."
  }
}

Since the aws-go-lambda library does not seem to handle these events i created two structs.

type CloudWatchEvent struct {
    Version    string          `json:"version"`
    ID         string          `json:"id"`
    DetailType string          `json:"detail-type"`
    Source     string          `json:"source"`
    AccountID  string          `json:"account"`
    Time       time.Time       `json:"time"`
    Region     string          `json:"region"`
    Resources  []string        `json:"resources"`
    Detail     CloudWatchDetails `json:"detail"`
}

type CloudWatchDetails struct {
    Detail struct {
        StatusCode           string `json:"StatusCode"`
        AutoScalingGroupName string `json:"AutoScalingGroupName"`
        ActivityID           string `json:"ActivityId"`
        Details              struct {
            AvailabilityZone string `json:"Availability Zone"`
            SubnetID         string `json:"Subnet ID"`
        } `json:"Details"`
        RequestID     string    `json:"RequestId"`
        EndTime       time.Time `json:"EndTime"`
        EC2InstanceID string    `json:"EC2InstanceId"`
        StartTime     time.Time `json:"StartTime"`
        Cause         time.Time `json:"Cause"`
    } `json:"detail"`
}

I seem to be able to address event.Version or event.Id fine but when I try and address event.Detail.EC2InstanceId I get what looks like a byte object.

Upvotes: 3

Views: 8698

Answers (1)

H4xorPL
H4xorPL

Reputation: 320

You were double nesting Detail property. Also "Cause" property in the JSON is a string and not a time.Time, you might want to change it.

That should do the trick.

type CloudWatchEvent struct {
    Version    string          `json:"version"`
    ID         string          `json:"id"`
    DetailType string          `json:"detail-type"`
    Source     string          `json:"source"`
    AccountID  string          `json:"account"`
    Time       time.Time       `json:"time"`
    Region     string          `json:"region"`
    Resources  []string        `json:"resources"`
    Detail     CloudWatchDetails `json:"detail"`
}

type CloudWatchDetails struct {
        StatusCode           string `json:"StatusCode"`
        AutoScalingGroupName string `json:"AutoScalingGroupName"`
        ActivityID           string `json:"ActivityId"`
        Details              struct {
            AvailabilityZone string `json:"Availability Zone"`
            SubnetID         string `json:"Subnet ID"`
        } `json:"Details"`
        RequestID     string    `json:"RequestId"`
        EndTime       time.Time `json:"EndTime"`
        EC2InstanceID string    `json:"EC2InstanceId"`
        StartTime     time.Time `json:"StartTime"`
        Cause         string `json:"Cause"`
}

Code in the playground

Upvotes: 4

Related Questions