Skip to content

Commit

Permalink
Merge pull request #986 from AlexMabry/f-aws-iot-policy
Browse files Browse the repository at this point in the history
Issue #143 - Add aws_iot_policy resource based on work from @jhedev
  • Loading branch information
radeksimko authored Jul 19, 2017
2 parents 08d3006 + f44424e commit 4cc7378
Show file tree
Hide file tree
Showing 10 changed files with 12,850 additions and 0 deletions.
3 changes: 3 additions & 0 deletions aws/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import (
"github.com/aws/aws-sdk-go/service/glacier"
"github.com/aws/aws-sdk-go/service/iam"
"github.com/aws/aws-sdk-go/service/inspector"
"github.com/aws/aws-sdk-go/service/iot"
"github.com/aws/aws-sdk-go/service/kinesis"
"github.com/aws/aws-sdk-go/service/kms"
"github.com/aws/aws-sdk-go/service/lambda"
Expand Down Expand Up @@ -174,6 +175,7 @@ type AWSClient struct {
ssmconn *ssm.SSM
wafconn *waf.WAF
wafregionalconn *wafregional.WAFRegional
iotconn *iot.IoT
}

func (c *AWSClient) S3() *s3.S3 {
Expand Down Expand Up @@ -364,6 +366,7 @@ func (c *Config) Client() (interface{}, error) {
client.firehoseconn = firehose.New(sess)
client.inspectorconn = inspector.New(sess)
client.glacierconn = glacier.New(sess)
client.iotconn = iot.New(sess)
client.kinesisconn = kinesis.New(awsKinesisSess)
client.kmsconn = kms.New(awsKmsSess)
client.lambdaconn = lambda.New(sess)
Expand Down
1 change: 1 addition & 0 deletions aws/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,7 @@ func Provider() terraform.ResourceProvider {
"aws_inspector_resource_group": resourceAWSInspectorResourceGroup(),
"aws_instance": resourceAwsInstance(),
"aws_internet_gateway": resourceAwsInternetGateway(),
"aws_iot_policy": resourceAwsIotPolicy(),
"aws_key_pair": resourceAwsKeyPair(),
"aws_kinesis_firehose_delivery_stream": resourceAwsKinesisFirehoseDeliveryStream(),
"aws_kinesis_stream": resourceAwsKinesisStream(),
Expand Down
131 changes: 131 additions & 0 deletions aws/resource_aws_iot_policy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package aws

import (
"log"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/iot"
"github.com/hashicorp/terraform/helper/schema"
)

func resourceAwsIotPolicy() *schema.Resource {
return &schema.Resource{
Create: resourceAwsIotPolicyCreate,
Read: resourceAwsIotPolicyRead,
Update: resourceAwsIotPolicyUpdate,
Delete: resourceAwsIotPolicyDelete,
Schema: map[string]*schema.Schema{
"name": &schema.Schema{
Type: schema.TypeString,
Required: true,
},
"policy": &schema.Schema{
Type: schema.TypeString,
Required: true,
},
"arn": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
"default_version_id": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
},
}
}

func resourceAwsIotPolicyCreate(d *schema.ResourceData, meta interface{}) error {

conn := meta.(*AWSClient).iotconn

out, err := conn.CreatePolicy(&iot.CreatePolicyInput{
PolicyName: aws.String(d.Get("name").(string)),
PolicyDocument: aws.String(d.Get("policy").(string)),
})

if err != nil {
log.Printf("[ERROR] %s", err)
return err
}

d.SetId(*out.PolicyName)

return resourceAwsIotPolicyRead(d, meta)
}

func resourceAwsIotPolicyRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).iotconn

out, err := conn.GetPolicy(&iot.GetPolicyInput{
PolicyName: aws.String(d.Id()),
})

if err != nil {
log.Printf("[ERROR] %s", err)
return err
}

d.Set("arn", out.PolicyArn)
d.Set("default_version_id", out.DefaultVersionId)

return nil
}

func resourceAwsIotPolicyUpdate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).iotconn

if d.HasChange("policy") {
_, err := conn.CreatePolicyVersion(&iot.CreatePolicyVersionInput{
PolicyName: aws.String(d.Id()),
PolicyDocument: aws.String(d.Get("policy").(string)),
SetAsDefault: aws.Bool(true),
})

if err != nil {
log.Printf("[ERROR] %s", err)
return err
}
}

return resourceAwsIotPolicyRead(d, meta)
}

func resourceAwsIotPolicyDelete(d *schema.ResourceData, meta interface{}) error {

conn := meta.(*AWSClient).iotconn

out, err := conn.ListPolicyVersions(&iot.ListPolicyVersionsInput{
PolicyName: aws.String(d.Id()),
})

if err != nil {
return err
}

// Delete all non-default versions of the policy
for _, ver := range out.PolicyVersions {
if !*ver.IsDefaultVersion {
_, err = conn.DeletePolicyVersion(&iot.DeletePolicyVersionInput{
PolicyName: aws.String(d.Id()),
PolicyVersionId: ver.VersionId,
})
if err != nil {
log.Printf("[ERROR] %s", err)
return err
}
}
}

//Delete default policy version
_, err = conn.DeletePolicy(&iot.DeletePolicyInput{
PolicyName: aws.String(d.Id()),
})

if err != nil {
log.Printf("[ERROR] %s", err)
return err
}

return nil
}
120 changes: 120 additions & 0 deletions aws/resource_aws_iot_policy_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package aws

import (
"fmt"
"testing"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/service/iot"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
"regexp"
)

func TestAccAWSIoTPolicy_basic(t *testing.T) {
rName := acctest.RandomWithPrefix("PubSubToAnyTopic-")

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSIoTPolicyDestroy_basic,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccAWSIoTPolicyConfigInitialState(rName),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("aws_iot_policy.pubsub", "name", rName),
resource.TestCheckResourceAttrSet("aws_iot_policy.pubsub", "arn"),
resource.TestCheckResourceAttrSet("aws_iot_policy.pubsub", "default_version_id"),
resource.TestCheckResourceAttrSet("aws_iot_policy.pubsub", "policy"),
),
},
},
})
}

func TestAccAWSIoTPolicy_invalidJson(t *testing.T) {
rName := acctest.RandomWithPrefix("PubSubToAnyTopic-")

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSIoTPolicyDestroy_basic,
Steps: []resource.TestStep{
{
Config: testAccAWSIoTPolicyInvalidJsonConfig(rName),
ExpectError: regexp.MustCompile("MalformedPolicyException.*"),
},
},
})
}

func testAccCheckAWSIoTPolicyDestroy_basic(s *terraform.State) error {
conn := testAccProvider.Meta().(*AWSClient).iotconn

for _, rs := range s.RootModule().Resources {
if rs.Type != "aws_iot_policy" {
continue
}

// Try to find the Policy
GetPolicyOpts := &iot.GetPolicyInput{
PolicyName: aws.String(rs.Primary.Attributes["name"]),
}

resp, err := conn.GetPolicy(GetPolicyOpts)

if err == nil {
if resp.PolicyName != nil {
return fmt.Errorf("IoT Policy still exists")
}
}

// Verify the error is what we want
if err != nil {
iotErr, ok := err.(awserr.Error)
if !ok || iotErr.Code() != "ResourceNotFoundException" {
return err
}
}
}

return nil
}

func testAccAWSIoTPolicyConfigInitialState(rName string) string {
return fmt.Sprintf(`
resource "aws_iot_policy" "pubsub" {
name = "%s"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": ["iot:*"],
"Resource": ["*"]
}]
}
EOF
}
`, rName)
}

func testAccAWSIoTPolicyInvalidJsonConfig(rName string) string {
return fmt.Sprintf(`
resource "aws_iot_policy" "pubsub" {
name = "%s"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": ["iot:*"],
"Resource": ["*"]
}]
}
EOF
}
`, rName)
}
Loading

0 comments on commit 4cc7378

Please sign in to comment.