Skip to content

Commit d69678b

Browse files
authored
[Feature] AWS Client (#1755)
1 parent 4a87f8a commit d69678b

File tree

10 files changed

+529
-0
lines changed

10 files changed

+529
-0
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
- (Maintenance) Inspector Generics
1212
- (Bugfix) Fix Gateway Options
1313
- (Feature) StorageV2 Integration Service Definition
14+
- (Feature) AWS Client
1415

1516
## [1.2.43](https://github.com/arangodb/kube-arangodb/tree/1.2.43) (2024-10-14)
1617
- (Feature) ArangoRoute CRD

go.mod

+2
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ require (
8888
github.com/Microsoft/hcsshim v0.11.4 // indirect
8989
github.com/arangodb/go-velocypack v0.0.0-20200318135517-5af53c29c67e // indirect
9090
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
91+
github.com/aws/aws-sdk-go v1.55.5 // indirect
9192
github.com/beorn7/perks v1.0.1 // indirect
9293
github.com/blang/semver/v4 v4.0.0 // indirect
9394
github.com/bytedance/sonic v1.9.1 // indirect
@@ -146,6 +147,7 @@ require (
146147
github.com/huandu/xstrings v1.5.0 // indirect
147148
github.com/imdario/mergo v0.3.16 // indirect
148149
github.com/inconshreveable/mousetrap v1.1.0 // indirect
150+
github.com/jmespath/go-jmespath v0.4.0 // indirect
149151
github.com/jmoiron/sqlx v1.4.0 // indirect
150152
github.com/josharian/intern v1.0.0 // indirect
151153
github.com/json-iterator/go v1.1.12 // indirect

go.sum

+7
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPd
5050
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
5151
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
5252
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
53+
github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU=
54+
github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU=
5355
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
5456
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
5557
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
@@ -104,6 +106,7 @@ github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
104106
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
105107
github.com/cyphar/filepath-securejoin v0.3.1 h1:1V7cHiaW+C+39wEfpH6XlLBQo3j/PciWFrgfCLS8XrE=
106108
github.com/cyphar/filepath-securejoin v0.3.1/go.mod h1:F7i41x/9cBF7lzCrVsYs9fuzwRZm4NQsGTBdpp6mETc=
109+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
107110
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
108111
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
109112
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -268,6 +271,9 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2
268271
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
269272
github.com/jessevdk/go-assets v0.0.0-20160921144138-4f4301a06e15 h1:cW/amwGEJK5MSKntPXRjX4dxs/nGxGT8gXKIsKFmHGc=
270273
github.com/jessevdk/go-assets v0.0.0-20160921144138-4f4301a06e15/go.mod h1:Fdm/oWRW+CH8PRbLntksCNtmcCBximKPkVQYvmMl80k=
274+
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
275+
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
276+
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
271277
github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o=
272278
github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY=
273279
github.com/josephburnett/jd v1.6.1 h1:Uzqhcje4WqvVyp85F3Oj0ezISPTlnhnr/KaLZIy8qh0=
@@ -432,6 +438,7 @@ github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
432438
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
433439
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
434440
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
441+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
435442
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
436443
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
437444
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=

pkg/util/aws/config.go

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
21+
package aws
22+
23+
import (
24+
"net/http"
25+
26+
"github.com/aws/aws-sdk-go/aws"
27+
"github.com/aws/aws-sdk-go/aws/client"
28+
"github.com/aws/aws-sdk-go/aws/credentials"
29+
"github.com/aws/aws-sdk-go/aws/session"
30+
31+
"github.com/arangodb/kube-arangodb/pkg/util"
32+
"github.com/arangodb/kube-arangodb/pkg/util/errors"
33+
)
34+
35+
type Config struct {
36+
Endpoint string
37+
Region string
38+
39+
DisableSSL bool
40+
41+
HTTP HTTP
42+
Provider Provider
43+
TLS TLS
44+
}
45+
46+
func (c Config) GetRegion() string {
47+
if c.Region == "" {
48+
return "us-east-1"
49+
}
50+
51+
return c.Region
52+
}
53+
54+
func (c Config) GetProvider() (credentials.Provider, error) {
55+
return c.Provider.Provider()
56+
}
57+
58+
func (c Config) GetHttpClient() (*http.Client, error) {
59+
tls, err := c.TLS.configuration()
60+
if err != nil {
61+
return nil, errors.Wrapf(err, "Unable to create TLS")
62+
}
63+
64+
return &http.Client{
65+
Transport: c.HTTP.configuration(tls),
66+
}, nil
67+
}
68+
69+
func (c Config) GetAWSSession() (client.ConfigProvider, error) {
70+
prov, err := c.GetProvider()
71+
if err != nil {
72+
return nil, errors.Wrapf(err, "Unable to create Provider")
73+
}
74+
75+
cl, err := c.GetHttpClient()
76+
if err != nil {
77+
return nil, errors.Wrapf(err, "Unable to create HTTP Client")
78+
}
79+
80+
return session.NewSessionWithOptions(session.Options{
81+
Config: aws.Config{
82+
Credentials: credentials.NewCredentials(prov),
83+
Endpoint: util.NewType(c.Endpoint),
84+
S3ForcePathStyle: util.NewType(true),
85+
DisableSSL: util.NewType(c.DisableSSL),
86+
HTTPClient: cl,
87+
},
88+
})
89+
}

pkg/util/aws/file.go

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
21+
package aws
22+
23+
import (
24+
"os"
25+
"sync"
26+
"time"
27+
28+
"github.com/aws/aws-sdk-go/aws/credentials"
29+
30+
"github.com/arangodb/kube-arangodb/pkg/util"
31+
"github.com/arangodb/kube-arangodb/pkg/util/errors"
32+
)
33+
34+
type fileProvider struct {
35+
lock sync.Mutex
36+
37+
accessKeyIDFile string
38+
secretAccessKeyFile string
39+
sessionTokenFile string
40+
41+
recent time.Time
42+
}
43+
44+
func (f *fileProvider) Retrieve() (credentials.Value, error) {
45+
if f == nil {
46+
return credentials.Value{}, errors.Errorf("Object is nil")
47+
}
48+
49+
f.lock.Lock()
50+
defer f.lock.Unlock()
51+
52+
var v credentials.Value
53+
54+
v.ProviderName = "dynamic-file-provider"
55+
56+
if data, err := os.ReadFile(f.accessKeyIDFile); err != nil {
57+
return credentials.Value{}, errors.Wrapf(err, "Unable to open AccessKeyID File")
58+
} else {
59+
v.AccessKeyID = string(data)
60+
}
61+
62+
if data, err := os.ReadFile(f.secretAccessKeyFile); err != nil {
63+
return credentials.Value{}, errors.Wrapf(err, "Unable to open SecretAccessKey File")
64+
} else {
65+
v.SecretAccessKey = string(data)
66+
}
67+
68+
if f.sessionTokenFile != "" {
69+
if data, err := os.ReadFile(f.sessionTokenFile); err != nil {
70+
return credentials.Value{}, errors.Wrapf(err, "Unable to open SessionToken File")
71+
} else {
72+
v.SessionToken = string(data)
73+
}
74+
}
75+
76+
f.recent = util.RecentFileModTime(f.accessKeyIDFile, f.secretAccessKeyFile, f.sessionTokenFile)
77+
78+
return credentials.Value{}, nil
79+
}
80+
81+
func (f *fileProvider) IsExpired() bool {
82+
f.lock.Lock()
83+
defer f.lock.Unlock()
84+
85+
return util.RecentFileModTime(f.accessKeyIDFile, f.secretAccessKeyFile, f.sessionTokenFile).After(f.recent)
86+
}

pkg/util/aws/http.go

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
21+
package aws
22+
23+
import (
24+
"crypto/tls"
25+
"net/http"
26+
"time"
27+
)
28+
29+
type HTTP struct {
30+
}
31+
32+
func (s HTTP) configuration(t *tls.Config) http.RoundTripper {
33+
var c = http.Transport{
34+
Proxy: http.ProxyFromEnvironment,
35+
ForceAttemptHTTP2: true,
36+
MaxIdleConns: 100,
37+
IdleConnTimeout: 90 * time.Second,
38+
TLSHandshakeTimeout: 10 * time.Second,
39+
ExpectContinueTimeout: 1 * time.Second,
40+
TLSClientConfig: t,
41+
}
42+
43+
return &c
44+
}

pkg/util/aws/impersonate.go

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
21+
package aws
22+
23+
import (
24+
"context"
25+
"sync"
26+
"time"
27+
28+
"github.com/aws/aws-sdk-go/aws"
29+
"github.com/aws/aws-sdk-go/aws/credentials"
30+
"github.com/aws/aws-sdk-go/aws/session"
31+
"github.com/aws/aws-sdk-go/service/sts"
32+
33+
"github.com/arangodb/kube-arangodb/pkg/util"
34+
)
35+
36+
type impersonate struct {
37+
lock sync.Mutex
38+
39+
credentials credentials.Value
40+
expires time.Time
41+
42+
config ProviderImpersonate
43+
44+
creds credentials.Provider
45+
}
46+
47+
func (i *impersonate) Retrieve() (credentials.Value, error) {
48+
i.lock.Lock()
49+
defer i.lock.Unlock()
50+
51+
awsSession, err := session.NewSessionWithOptions(session.Options{
52+
Config: aws.Config{
53+
Credentials: credentials.NewCredentials(i.creds),
54+
S3ForcePathStyle: util.NewType(true),
55+
},
56+
})
57+
if err != nil {
58+
return credentials.Value{}, err
59+
}
60+
61+
s := sts.New(awsSession)
62+
63+
resp, err := s.AssumeRoleWithContext(context.Background(), &sts.AssumeRoleInput{
64+
RoleArn: util.NewType(i.config.Role),
65+
RoleSessionName: util.NewType(i.config.Name),
66+
})
67+
if err != nil {
68+
return credentials.Value{}, err
69+
}
70+
71+
if e := resp.Credentials.Expiration; e != nil {
72+
i.expires = *e
73+
}
74+
75+
i.credentials = credentials.Value{
76+
AccessKeyID: util.WithDefault(resp.Credentials.AccessKeyId),
77+
SecretAccessKey: util.WithDefault(resp.Credentials.SecretAccessKey),
78+
SessionToken: util.WithDefault(resp.Credentials.SessionToken),
79+
}
80+
81+
return i.credentials, nil
82+
}
83+
84+
func (i *impersonate) IsExpired() bool {
85+
i.lock.Lock()
86+
defer i.lock.Unlock()
87+
88+
return time.Now().After(i.expires)
89+
}

0 commit comments

Comments
 (0)