/
awsClientSigner.go
95 lines (85 loc) · 3.25 KB
/
awsClientSigner.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
// Copyright 2017 MSolution.IO
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package es
import (
"errors"
"net/http"
"strings"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/signer/v4"
"github.com/sha1sum/aws_signing_client"
"gopkg.in/olivere/elastic.v5"
)
const (
// The URI contains 5 mendatory parts split by '.'
// domainname.region.service.amazonaws.com
endpointMetaDataLengthRequirement = 5
)
var (
errWrongEndPoint = errors.New("Wrong endpoint parameter")
)
// checkParametersError checks errors from NewSignedElasticClient's parameters.
func checkParametersError(endpointMetaData []string, creds *credentials.Credentials) error {
if _, err := creds.Get(); err != nil {
return err
} else if len(endpointMetaData) < endpointMetaDataLengthRequirement {
return errWrongEndPoint
}
return nil
}
// NewSignedElasticClient creates a signed *elastic.Client ready for using with AWS ElasticSearch.
// It takes as parameter:
// - endpoint: The endpoint URI gettable from AWS.
// - creds: Credentials from AWS/Credentials.
func NewSignedElasticClient(endpoint string, creds *credentials.Credentials) (*elastic.Client, error) {
if cofs, err := NewSignedElasticClientOptions(endpoint, creds); err == nil {
cof := configEach(cofs...)
if ec, err := elastic.NewClient(elastic.SetURL(endpoint), cof); err == nil {
return ec, nil
} else {
return nil, err
}
} else {
return nil, err
}
}
// NewSignedElasticClientOptions builds elastic client option funcs which
// configure an ElasticSearch client to use AWSv4 signature.
func NewSignedElasticClientOptions(endpoint string, creds *credentials.Credentials) ([]elastic.ClientOptionFunc, error) {
if httpClient, err := NewSignedHttpClientForElasticSearch(endpoint, creds); err != nil {
return nil, err
} else {
return []elastic.ClientOptionFunc{
elastic.SetScheme("https"),
elastic.SetHttpClient(httpClient),
elastic.SetSniff(false),
}, nil
}
}
// NewSignedHttpClientForElasticSearch returns an http.Client which signs its
// requests with AWS v4 signatures, for ElasticSearch only.
func NewSignedHttpClientForElasticSearch(endpoint string, creds *credentials.Credentials) (*http.Client, error) {
endpointParts := strings.Split(endpoint, ".")
if err := checkParametersError(endpointParts, creds); err != nil {
return nil, err
}
region := endpointParts[len(endpointParts)-4]
return NewSignedHttpClient(creds, region, "es")
}
// NewSignedHttpCilent returns an http.Client which signs its requests with AWS
// v4 signatures for the provided service name and region.
func NewSignedHttpClient(creds *credentials.Credentials, region, service string) (*http.Client, error) {
signer := v4.NewSigner(creds)
return aws_signing_client.New(signer, nil, service, region)
}