SimpleDB domain resource (#7600)

This commit is contained in:
Martin Häger 2016-07-12 13:55:58 +02:00 committed by Paul Stack
parent 8b80d05103
commit 32abd937f1
12 changed files with 2096 additions and 0 deletions

View File

@ -51,6 +51,7 @@ import (
"github.com/aws/aws-sdk-go/service/route53"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/aws/aws-sdk-go/service/ses"
"github.com/aws/aws-sdk-go/service/simpledb"
"github.com/aws/aws-sdk-go/service/sns"
"github.com/aws/aws-sdk-go/service/sqs"
"github.com/aws/aws-sdk-go/service/sts"
@ -96,6 +97,7 @@ type AWSClient struct {
autoscalingconn *autoscaling.AutoScaling
s3conn *s3.S3
sesConn *ses.SES
simpledbconn *simpledb.SimpleDB
sqsconn *sqs.SQS
snsconn *sns.SNS
stsconn *sts.STS
@ -219,6 +221,9 @@ func (c *Config) Client() (interface{}, error) {
log.Println("[INFO] Initializing SES connection")
client.sesConn = ses.New(sess)
log.Println("[INFO] Initializing SimpleDB connection")
client.simpledbconn = simpledb.New(sess)
log.Println("[INFO] Initializing SQS connection")
client.sqsconn = sqs.New(sess)

View File

@ -260,6 +260,7 @@ func Provider() terraform.ResourceProvider {
"aws_s3_bucket_notification": resourceAwsS3BucketNotification(),
"aws_security_group": resourceAwsSecurityGroup(),
"aws_security_group_rule": resourceAwsSecurityGroupRule(),
"aws_simpledb_domain": resourceAwsSimpleDBDomain(),
"aws_spot_instance_request": resourceAwsSpotInstanceRequest(),
"aws_spot_fleet_request": resourceAwsSpotFleetRequest(),
"aws_sqs_queue": resourceAwsSqsQueue(),

View File

@ -0,0 +1,81 @@
package aws
import (
"fmt"
"log"
"github.com/hashicorp/terraform/helper/schema"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/service/simpledb"
)
func resourceAwsSimpleDBDomain() *schema.Resource {
return &schema.Resource{
Create: resourceAwsSimpleDBDomainCreate,
Read: resourceAwsSimpleDBDomainRead,
Delete: resourceAwsSimpleDBDomainDelete,
Schema: map[string]*schema.Schema{
"name": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
},
}
}
func resourceAwsSimpleDBDomainCreate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).simpledbconn
name := d.Get("name").(string)
input := &simpledb.CreateDomainInput{
DomainName: aws.String(name),
}
_, err := conn.CreateDomain(input)
if err != nil {
return fmt.Errorf("Create SimpleDB Domain failed: %s", err)
}
d.SetId(name)
return nil
}
func resourceAwsSimpleDBDomainRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).simpledbconn
input := &simpledb.DomainMetadataInput{
DomainName: aws.String(d.Id()),
}
_, err := conn.DomainMetadata(input)
if awsErr, ok := err.(awserr.Error); ok {
if awsErr.Code() == "NoSuchDomain" {
log.Printf("[WARN] Removing SimpleDB domain %q because it's gone.", d.Id())
d.SetId("")
return nil
}
}
if err != nil {
return err
}
d.Set("name", d.Id())
return nil
}
func resourceAwsSimpleDBDomainDelete(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).simpledbconn
input := &simpledb.DeleteDomainInput{
DomainName: aws.String(d.Id()),
}
_, err := conn.DeleteDomain(input)
if err != nil {
return fmt.Errorf("Delete SimpleDB Domain failed: %s", err)
}
d.SetId("")
return nil
}

View File

@ -0,0 +1,80 @@
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/simpledb"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)
func TestAccAWSSimpleDBDomain_basic(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSSimpleDBDomainDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccAWSSimpleDBDomainConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSSimpleDBDomainExists("aws_simpledb_domain.test_domain"),
),
},
},
})
}
func testAccCheckAWSSimpleDBDomainDestroy(s *terraform.State) error {
conn := testAccProvider.Meta().(*AWSClient).simpledbconn
for _, rs := range s.RootModule().Resources {
if rs.Type != "aws_simpledb_domain" {
continue
}
input := &simpledb.DomainMetadataInput{
DomainName: aws.String(rs.Primary.ID),
}
_, err := conn.DomainMetadata(input)
if err == nil {
return fmt.Errorf("Domain exists when it should be destroyed!")
}
// Verify the error is an API error, not something else
_, ok := err.(awserr.Error)
if !ok {
return err
}
}
return nil
}
func testAccCheckAWSSimpleDBDomainExists(n string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Not found: %s", n)
}
if rs.Primary.ID == "" {
return fmt.Errorf("No SimpleDB domain with that name exists")
}
conn := testAccProvider.Meta().(*AWSClient).simpledbconn
input := &simpledb.DomainMetadataInput{
DomainName: aws.String(rs.Primary.ID),
}
_, err := conn.DomainMetadata(input)
return err
}
}
var testAccAWSSimpleDBDomainConfig = `
resource "aws_simpledb_domain" "test_domain" {
name = "terraform-test-domain"
}
`

View File

@ -0,0 +1,180 @@
package v2
import (
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"errors"
"fmt"
"net/http"
"net/url"
"sort"
"strings"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/request"
)
var (
errInvalidMethod = errors.New("v2 signer only handles HTTP POST")
)
const (
signatureVersion = "2"
signatureMethod = "HmacSHA256"
timeFormat = "2006-01-02T15:04:05Z"
)
type signer struct {
// Values that must be populated from the request
Request *http.Request
Time time.Time
Credentials *credentials.Credentials
Debug aws.LogLevelType
Logger aws.Logger
Query url.Values
stringToSign string
signature string
}
// SignRequestHandler is a named request handler the SDK will use to sign
// service client request with using the V4 signature.
var SignRequestHandler = request.NamedHandler{
Name: "v2.SignRequestHandler", Fn: SignSDKRequest,
}
// SignSDKRequest requests with signature version 2.
//
// Will sign the requests with the service config's Credentials object
// Signing is skipped if the credentials is the credentials.AnonymousCredentials
// object.
func SignSDKRequest(req *request.Request) {
// If the request does not need to be signed ignore the signing of the
// request if the AnonymousCredentials object is used.
if req.Config.Credentials == credentials.AnonymousCredentials {
return
}
if req.HTTPRequest.Method != "POST" && req.HTTPRequest.Method != "GET" {
// The V2 signer only supports GET and POST
req.Error = errInvalidMethod
return
}
v2 := signer{
Request: req.HTTPRequest,
Time: req.Time,
Credentials: req.Config.Credentials,
Debug: req.Config.LogLevel.Value(),
Logger: req.Config.Logger,
}
req.Error = v2.Sign()
if req.Error != nil {
return
}
if req.HTTPRequest.Method == "POST" {
// Set the body of the request based on the modified query parameters
req.SetStringBody(v2.Query.Encode())
// Now that the body has changed, remove any Content-Length header,
// because it will be incorrect
req.HTTPRequest.ContentLength = 0
req.HTTPRequest.Header.Del("Content-Length")
} else {
req.HTTPRequest.URL.RawQuery = v2.Query.Encode()
}
}
func (v2 *signer) Sign() error {
credValue, err := v2.Credentials.Get()
if err != nil {
return err
}
if v2.Request.Method == "POST" {
// Parse the HTTP request to obtain the query parameters that will
// be used to build the string to sign. Note that because the HTTP
// request will need to be modified, the PostForm and Form properties
// are reset to nil after parsing.
v2.Request.ParseForm()
v2.Query = v2.Request.PostForm
v2.Request.PostForm = nil
v2.Request.Form = nil
} else {
v2.Query = v2.Request.URL.Query()
}
// Set new query parameters
v2.Query.Set("AWSAccessKeyId", credValue.AccessKeyID)
v2.Query.Set("SignatureVersion", signatureVersion)
v2.Query.Set("SignatureMethod", signatureMethod)
v2.Query.Set("Timestamp", v2.Time.UTC().Format(timeFormat))
if credValue.SessionToken != "" {
v2.Query.Set("SecurityToken", credValue.SessionToken)
}
// in case this is a retry, ensure no signature present
v2.Query.Del("Signature")
method := v2.Request.Method
host := v2.Request.URL.Host
path := v2.Request.URL.Path
if path == "" {
path = "/"
}
// obtain all of the query keys and sort them
queryKeys := make([]string, 0, len(v2.Query))
for key := range v2.Query {
queryKeys = append(queryKeys, key)
}
sort.Strings(queryKeys)
// build URL-encoded query keys and values
queryKeysAndValues := make([]string, len(queryKeys))
for i, key := range queryKeys {
k := strings.Replace(url.QueryEscape(key), "+", "%20", -1)
v := strings.Replace(url.QueryEscape(v2.Query.Get(key)), "+", "%20", -1)
queryKeysAndValues[i] = k + "=" + v
}
// join into one query string
query := strings.Join(queryKeysAndValues, "&")
// build the canonical string for the V2 signature
v2.stringToSign = strings.Join([]string{
method,
host,
path,
query,
}, "\n")
hash := hmac.New(sha256.New, []byte(credValue.SecretAccessKey))
hash.Write([]byte(v2.stringToSign))
v2.signature = base64.StdEncoding.EncodeToString(hash.Sum(nil))
v2.Query.Set("Signature", v2.signature)
if v2.Debug.Matches(aws.LogDebugWithSigning) {
v2.logSigningInfo()
}
return nil
}
const logSignInfoMsg = `DEBUG: Request Signature:
---[ STRING TO SIGN ]--------------------------------
%s
---[ SIGNATURE ]-------------------------------------
%s
-----------------------------------------------------`
func (v2 *signer) logSigningInfo() {
msg := fmt.Sprintf(logSignInfoMsg, v2.stringToSign, v2.Query.Get("Signature"))
v2.Logger.Log(msg)
}

1528
vendor/github.com/aws/aws-sdk-go/service/simpledb/api.go generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
package simpledb
import "github.com/aws/aws-sdk-go/aws/client"
func init() {
initClient = func(c *client.Client) {
// SimpleDB uses custom error unmarshaling logic
c.Handlers.UnmarshalError.Clear()
c.Handlers.UnmarshalError.PushBack(unmarshalError)
}
}

View File

@ -0,0 +1,102 @@
// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.
package simpledb
import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/client"
"github.com/aws/aws-sdk-go/aws/client/metadata"
"github.com/aws/aws-sdk-go/aws/corehandlers"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/private/protocol/query"
"github.com/aws/aws-sdk-go/private/signer/v2"
)
// Amazon SimpleDB is a web service providing the core database functions of
// data indexing and querying in the cloud. By offloading the time and effort
// associated with building and operating a web-scale database, SimpleDB provides
// developers the freedom to focus on application development. A traditional,
// clustered relational database requires a sizable upfront capital outlay,
// is complex to design, and often requires extensive and repetitive database
// administration. Amazon SimpleDB is dramatically simpler, requiring no schema,
// automatically indexing your data and providing a simple API for storage and
// access. This approach eliminates the administrative burden of data modeling,
// index maintenance, and performance tuning. Developers gain access to this
// functionality within Amazon's proven computing environment, are able to scale
// instantly, and pay only for what they use.
//
// Visit http://aws.amazon.com/simpledb/ (http://aws.amazon.com/simpledb/)
// for more information.
//The service client's operations are safe to be used concurrently.
// It is not safe to mutate any of the client's properties though.
type SimpleDB struct {
*client.Client
}
// Used for custom client initialization logic
var initClient func(*client.Client)
// Used for custom request initialization logic
var initRequest func(*request.Request)
// A ServiceName is the name of the service the client will make API calls to.
const ServiceName = "sdb"
// New creates a new instance of the SimpleDB client with a session.
// If additional configuration is needed for the client instance use the optional
// aws.Config parameter to add your extra config.
//
// Example:
// // Create a SimpleDB client from just a session.
// svc := simpledb.New(mySession)
//
// // Create a SimpleDB client with additional configuration
// svc := simpledb.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
func New(p client.ConfigProvider, cfgs ...*aws.Config) *SimpleDB {
c := p.ClientConfig(ServiceName, cfgs...)
return newClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion)
}
// newClient creates, initializes and returns a new service client instance.
func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion string) *SimpleDB {
svc := &SimpleDB{
Client: client.New(
cfg,
metadata.ClientInfo{
ServiceName: ServiceName,
SigningRegion: signingRegion,
Endpoint: endpoint,
APIVersion: "2009-04-15",
},
handlers,
),
}
// Handlers
svc.Handlers.Sign.PushBackNamed(v2.SignRequestHandler)
svc.Handlers.Sign.PushBackNamed(corehandlers.BuildContentLengthHandler)
svc.Handlers.Build.PushBackNamed(query.BuildHandler)
svc.Handlers.Unmarshal.PushBackNamed(query.UnmarshalHandler)
svc.Handlers.UnmarshalMeta.PushBackNamed(query.UnmarshalMetaHandler)
svc.Handlers.UnmarshalError.PushBackNamed(query.UnmarshalErrorHandler)
// Run custom client initialization if present
if initClient != nil {
initClient(svc.Client)
}
return svc
}
// newRequest creates a new request for a SimpleDB operation and runs any
// custom request initialization.
func (c *SimpleDB) newRequest(op *request.Operation, params, data interface{}) *request.Request {
req := c.NewRequest(op, params, data)
// Run custom request initialization if present
if initRequest != nil {
initRequest(req)
}
return req
}

View File

@ -0,0 +1,53 @@
package simpledb
import (
"encoding/xml"
"io"
"io/ioutil"
"strings"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/request"
)
type xmlErrorDetail struct {
Code string `xml:"Code"`
Message string `xml:"Message"`
}
type xmlErrorResponse struct {
XMLName xml.Name `xml:"Response"`
Errors []xmlErrorDetail `xml:"Errors>Error"`
RequestID string `xml:"RequestID"`
}
func unmarshalError(r *request.Request) {
defer r.HTTPResponse.Body.Close()
defer io.Copy(ioutil.Discard, r.HTTPResponse.Body)
if r.HTTPResponse.ContentLength == int64(0) {
// No body, use status code to generate an awserr.Error
r.Error = awserr.NewRequestFailure(
awserr.New(strings.Replace(r.HTTPResponse.Status, " ", "", -1), r.HTTPResponse.Status, nil),
r.HTTPResponse.StatusCode,
"",
)
return
}
resp := &xmlErrorResponse{}
err := xml.NewDecoder(r.HTTPResponse.Body).Decode(resp)
if err != nil && err != io.EOF {
r.Error = awserr.New("SerializationError", "failed to decode SimpleDB XML error response", nil)
} else if len(resp.Errors) == 0 {
r.Error = awserr.New("MissingError", "missing error code in SimpleDB XML error response", nil)
} else {
// If there are multiple error codes, return only the first as the aws.Error interface only supports
// one error code.
r.Error = awserr.NewRequestFailure(
awserr.New(resp.Errors[0].Code, resp.Errors[0].Message, nil),
r.HTTPResponse.StatusCode,
resp.RequestID,
)
}
}

12
vendor/vendor.json vendored
View File

@ -389,6 +389,12 @@
"path": "github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil",
"revision": "2cc71659118a868dc7544a7ef0808eb42d487011"
},
{
"checksumSHA1": "F6mth+G7dXN1GI+nktaGo8Lx8aE=",
"path": "github.com/aws/aws-sdk-go/private/signer/v2",
"revision": "333fcdc9874ea63fbdb3176e12ffa04b5ec44f5a",
"revisionTime": "2016-07-05T22:03:21Z"
},
{
"comment": "v1.1.23",
"path": "github.com/aws/aws-sdk-go/private/signer/v4",
@ -565,6 +571,12 @@
"path": "github.com/aws/aws-sdk-go/service/s3",
"revision": "2cc71659118a868dc7544a7ef0808eb42d487011"
},
{
"checksumSHA1": "DW5kDRWLA2yAgYh9vsI+0uVqq/Q=",
"path": "github.com/aws/aws-sdk-go/service/simpledb",
"revision": "333fcdc9874ea63fbdb3176e12ffa04b5ec44f5a",
"revisionTime": "2016-07-05T22:03:21Z"
},
{
"comment": "v1.1.23",
"path": "github.com/aws/aws-sdk-go/service/sns",

View File

@ -0,0 +1,31 @@
---
layout: "aws"
page_title: "AWS: simpledb_domain"
sidebar_current: "docs-aws-resource-simpledb-domain"
description: |-
Provides a SimpleDB domain resource.
---
# aws\_simpledb\_domain
Provides a SimpleDB domain resource
## Example Usage
```
resource "aws_simpledb_domain" "users" {
name = "users"
}
```
## Argument Reference
The following arguments are supported:
* `name` - (Required) The name of the SimpleDB domain
## Attributes Reference
The following attributes are exported:
* `id` - The name of the SimpleDB domain

View File

@ -728,6 +728,18 @@
</li>
<li<%= sidebar_current(/^docs-aws-resource-simpledb/) %>>
<a href="#">SimpleDB Resources</a>
<ul class="nav nav-visible">
<li<%= sidebar_current("docs-aws-resource-simpledb-domain") %>>
<a href="/docs/providers/aws/r/simpledb_domain.html">aws_simpledb_domain</a>
</li>
</ul>
</li>
<li<%= sidebar_current(/^docs-aws-resource-sns/) %>>
<a href="#">SNS Resources</a>
<ul class="nav nav-visible">