From 784897a68cd932cac6bb5afd8c65db7a77a1ed2f Mon Sep 17 00:00:00 2001 From: Jean de Kernier Date: Mon, 29 Jul 2019 17:03:55 +0200 Subject: [PATCH] resource/aws_iot_policy: Delete oldest policy version when max number is reached --- aws/resource_aws_iot_policy.go | 57 ++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/aws/resource_aws_iot_policy.go b/aws/resource_aws_iot_policy.go index 724540e7404..6a720e866c9 100644 --- a/aws/resource_aws_iot_policy.go +++ b/aws/resource_aws_iot_policy.go @@ -1,6 +1,7 @@ package aws import ( + "fmt" "log" "github.com/aws/aws-sdk-go/aws" @@ -75,6 +76,10 @@ func resourceAwsIotPolicyRead(d *schema.ResourceData, meta interface{}) error { func resourceAwsIotPolicyUpdate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).iotconn + if err := iotPolicyPruneVersions(d.Id(), conn); err != nil { + return err + } + if d.HasChange("policy") { _, err := conn.CreatePolicyVersion(&iot.CreatePolicyVersionInput{ PolicyName: aws.String(d.Id()), @@ -129,3 +134,55 @@ func resourceAwsIotPolicyDelete(d *schema.ResourceData, meta interface{}) error return nil } + +// iotPolicyPruneVersions deletes the oldest non-default version if the maximum +// number of versions (5) has been reached. +func iotPolicyPruneVersions(name string, iotconn *iot.IoT) error { + versions, err := iotPolicyListVersions(name, iotconn) + if err != nil { + return err + } + if len(versions) < 5 { + return nil + } + + var oldestVersion *iot.PolicyVersion + + for _, version := range versions { + if *version.IsDefaultVersion { + continue + } + if oldestVersion == nil || + version.CreateDate.Before(*oldestVersion.CreateDate) { + oldestVersion = version + } + } + + err = iotPolicyDeleteVersion(name, *oldestVersion.VersionId, iotconn) + return err +} + +func iotPolicyListVersions(name string, iotconn *iot.IoT) ([]*iot.PolicyVersion, error) { + request := &iot.ListPolicyVersionsInput{ + PolicyName: aws.String(name), + } + + response, err := iotconn.ListPolicyVersions(request) + if err != nil { + return nil, fmt.Errorf("Error listing versions for IoT policy %s: %s", name, err) + } + return response.PolicyVersions, nil +} + +func iotPolicyDeleteVersion(name, versionID string, iotconn *iot.IoT) error { + request := &iot.DeletePolicyVersionInput{ + PolicyName: aws.String(name), + PolicyVersionId: aws.String(versionID), + } + + _, err := iotconn.DeletePolicyVersion(request) + if err != nil { + return fmt.Errorf("Error deleting version %s from IoT policy %s: %s", versionID, name, err) + } + return nil +}