Skip to content

Commit

Permalink
feat(aws): new resource: spotinst_data_integration (#301)
Browse files Browse the repository at this point in the history
  • Loading branch information
TalGevaSpot authored Apr 19, 2022
1 parent cb5e5bc commit 8f7d4c4
Show file tree
Hide file tree
Showing 12 changed files with 731 additions and 6 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
## Unreleased

FEATURES:
**New Resource:** `spotinst_data_integration`

## 1.72.0 (April 12, 2022)

BUG FIXES:
Expand Down
40 changes: 40 additions & 0 deletions docs/resources/data_integration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
layout: "spotinst"
page_title: "Spotinst: data_integration"
subcategory: "Data Integration"
description: |-
Manages an Data Integration resource.
---

# spotinst\_data\_integration

Provides a Spotinst Data Integration resource.

## Example Usage

```hcl
resource "spotinst_data_integration" "example" {
name = "foo"
status = "enabled"
s3 {
bucketName = "terraform-test-do-not-delete"
subdir = "terraform-test-data-integration"
}
}
```

## Argument Reference

The following arguments are supported:

* `name`- (Required) The name of the data integration.
* `status` - (Optional, only when update) Determines if this data integration is on or off. Valid values: `"enabled"`, `"disabled"`
* `s3` - (Required) When vendor value is s3, the following fields are included:
* `bucketName` - (Required) The name of the bucket to use. Your spot IAM Role policy needs to include s3:putObject permissions for this bucket. Can't be null.
* `subdir` - (Optional) The subdirectory in which your files will be stored within the bucket. Adds the prefix subdir/ to new objects' keys. Can't be null or contain '/'.


## Attributes Reference

In addition to all arguments above, the following attributes are exported:
* `id` - The Spotinst Data Integration ID.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ require (
github.com/hashicorp/go-version v1.4.0
github.com/hashicorp/terraform-plugin-docs v0.5.1
github.com/hashicorp/terraform-plugin-sdk v1.17.2
github.com/spotinst/spotinst-sdk-go v1.116.0
github.com/spotinst/spotinst-sdk-go v1.117.0
golang.org/x/lint v0.0.0-20200302205851-738671d3881b
)
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -361,8 +361,8 @@ github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spotinst/spotinst-sdk-go v1.116.0 h1:ph2ik0i2ryJn5l5RdI9NPAb172kfyBepTW7PQD6yDOQ=
github.com/spotinst/spotinst-sdk-go v1.116.0/go.mod h1:786KK8PDw7vdtLgni44bUS1JjxdA/Xa2XLhsqTHXQdg=
github.com/spotinst/spotinst-sdk-go v1.117.0 h1:EYNv/Ija63F5u2WSGEuFATyyseTkdTbJatsu8Z5ZMgM=
github.com/spotinst/spotinst-sdk-go v1.117.0/go.mod h1:786KK8PDw7vdtLgni44bUS1JjxdA/Xa2XLhsqTHXQdg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
Expand Down
132 changes: 132 additions & 0 deletions spotinst/commons/common_dataintegration.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
package commons

import (
"fmt"
"github.com/spotinst/spotinst-sdk-go/service/dataintegration/providers/aws"
"github.com/spotinst/spotinst-sdk-go/spotinst"
"log"

"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)

var vendorTypes = []string{"s3"}

const (
DataIntegrationResourceName ResourceName = "spotinst_data_integration"
)

var DataIntegrationResource *DataIntegrationResourceTerraformResource

type DataIntegrationResourceTerraformResource struct {
GenericResource
}

type DataIntegrationWrapper struct {
DataIntegration *aws.DataIntegration
}

// NewDataIntegrationResource creates a new DataIntegration resource
func NewDataIntegrationResource(fieldMap map[FieldName]*GenericField) *DataIntegrationResourceTerraformResource {
return &DataIntegrationResourceTerraformResource{
GenericResource: GenericResource{
resourceName: DataIntegrationResourceName,
fields: NewGenericFields(fieldMap),
},
}
}

// OnCreate is called when creating a new resource block and returns a new DataIntegration resource or an error.
func (res *DataIntegrationResourceTerraformResource) OnCreate(
resourceData *schema.ResourceData,
meta interface{}) (*aws.DataIntegration, error) {

if res.fields == nil || res.fields.fieldsMap == nil || len(res.fields.fieldsMap) == 0 {
return nil, fmt.Errorf("resource fields are nil or empty, cannot create")
}

diWrapper := NewDataIntegrationWrapper()
for _, field := range res.fields.fieldsMap {
if field.onCreate == nil {
continue
}
log.Printf(string(ResourceFieldOnCreate), field.resourceAffinity, field.fieldNameStr)
if err := field.onCreate(diWrapper, resourceData, meta); err != nil {
return nil, err
}
}
return diWrapper.GetDataIntegration(), nil
}

// OnRead is called when reading an existing resource and throws an error if it is unable to do so.
func (res *DataIntegrationResourceTerraformResource) OnRead(
extendedResourceDefinition *aws.DataIntegration,
resourceData *schema.ResourceData,
meta interface{}) error {

if res.fields == nil || res.fields.fieldsMap == nil || len(res.fields.fieldsMap) == 0 {
return fmt.Errorf("resource fields are nil or empty, cannot read")
}

diWrapper := NewDataIntegrationWrapper()
diWrapper.SetDataIntegration(extendedResourceDefinition)

for _, field := range res.fields.fieldsMap {
if field.onRead == nil {
continue
}
log.Printf(string(ResourceFieldOnRead), field.resourceAffinity, field.fieldNameStr)
if err := field.onRead(diWrapper, resourceData, meta); err != nil {
return err
}
}
return nil
}

// OnUpdate is called when updating an existing resource and returns
// an DataIntegration with a bool indicating if had been updated, or an error.
func (res *DataIntegrationResourceTerraformResource) OnUpdate(
resourceData *schema.ResourceData,
meta interface{}) (bool, *aws.DataIntegration, error) {
if res.fields == nil || res.fields.fieldsMap == nil || len(res.fields.fieldsMap) == 0 {
return false, nil, fmt.Errorf("resource fields are nil or empty, cannot update")
}

diWrapper := NewDataIntegrationWrapper()
hasChanged := false
var vendor = ""
for _, field := range res.fields.fieldsMap {
if contains(vendorTypes, field.fieldNameStr) {
vendor = field.fieldNameStr
}
if field.onUpdate == nil {
continue
}
if field.hasFieldChange(resourceData, meta) {
log.Printf(string(ResourceFieldOnUpdate), field.resourceAffinity, field.fieldNameStr)
if err := field.onUpdate(diWrapper, resourceData, meta); err != nil {
return false, nil, err
}
hasChanged = true
}
}
diWrapper.DataIntegration.SetVendor(spotinst.String(vendor))
return hasChanged, diWrapper.GetDataIntegration(), nil
}

// Spotinst DataIntegration must have a wrapper struct.
// the wrapper struct is intended to help reflect the field states into the DataIntegration object properly.
func NewDataIntegrationWrapper() *DataIntegrationWrapper {
return &DataIntegrationWrapper{
DataIntegration: &aws.DataIntegration{},
}
}

// GetDataIntegration returns a wrapped DataIntegration
func (diWrapper *DataIntegrationWrapper) GetDataIntegration() *aws.DataIntegration {
return diWrapper.DataIntegration
}

// SetDataIntegration applies DataIntegration fields to the DataIntegration wrapper.
func (diWrapper *DataIntegrationWrapper) SetDataIntegration(di *aws.DataIntegration) {
diWrapper.DataIntegration = di
}
2 changes: 2 additions & 0 deletions spotinst/commons/consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ const (
MultaiTarget ResourceAffinity = "Multai_Target"
MultaiTargetSet ResourceAffinity = "Multai_Target_Set"

DataIntegration ResourceAffinity = "Data_Integration"

HealthCheck ResourceAffinity = "Health_Check"

SuspendProcesses ResourceAffinity = "Suspend_Processes"
Expand Down
8 changes: 5 additions & 3 deletions spotinst/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@ package spotinst
import (
"errors"
"fmt"
stdlog "log"
"strings"

"github.com/hashicorp/go-cleanhttp"
"github.com/hashicorp/terraform-plugin-sdk/meta"
"github.com/spotinst/spotinst-sdk-go/service/dataintegration"
"github.com/spotinst/spotinst-sdk-go/service/elastigroup"
"github.com/spotinst/spotinst-sdk-go/service/healthcheck"
"github.com/spotinst/spotinst-sdk-go/service/managedinstance"
Expand All @@ -21,6 +19,8 @@ import (
"github.com/spotinst/spotinst-sdk-go/spotinst/log"
"github.com/spotinst/spotinst-sdk-go/spotinst/session"
"github.com/spotinst/terraform-provider-spotinst/version"
stdlog "log"
"strings"
)

var ErrNoValidCredentials = errors.New("\n\nNo valid credentials found " +
Expand All @@ -44,6 +44,7 @@ type Client struct {
mrscaler mrscaler.Service
ocean ocean.Service
managedInstance managedinstance.Service
dataIntegration dataintegration.Service
}

// Client configures and returns a fully initialized Spotinst client.
Expand All @@ -65,6 +66,7 @@ func (c *Config) Client() (*Client, error) {
mrscaler: mrscaler.New(sess),
ocean: ocean.New(sess),
managedInstance: managedinstance.New(sess),
dataIntegration: dataintegration.New(sess),
}

stdlog.Println("[INFO] Spotinst client configured")
Expand Down
12 changes: 12 additions & 0 deletions spotinst/dataintegration/consts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package dataintegration

import "github.com/spotinst/terraform-provider-spotinst/spotinst/commons"

const (
DataIntegrationName commons.FieldName = "name"
S3 commons.FieldName = "s3"
Status commons.FieldName = "status"

BucketName commons.FieldName = "bucket_name"
SubDir commons.FieldName = "subdir"
)
Loading

0 comments on commit 8f7d4c4

Please sign in to comment.