Skip to content

Commit 36301d2

Browse files
committed
feat(replay): add provider-scoped demo replay command
1 parent 8e14395 commit 36301d2

35 files changed

Lines changed: 2055 additions & 322 deletions

pkg/plugins/alibaba.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,16 @@ package plugins
44

55
import (
66
"github.com/404tk/cloudtoolkit/pkg/providers/alibaba"
7+
replay "github.com/404tk/cloudtoolkit/pkg/providers/alibaba/replay"
78
"github.com/404tk/cloudtoolkit/pkg/schema"
89
)
910

1011
type Alibaba struct{}
1112

1213
func (p Alibaba) Check(block schema.Options) (schema.Provider, error) {
14+
if replay.IsActiveForProvider("alibaba") {
15+
return alibaba.NewWithConfig(block, replay.ClientConfig())
16+
}
1317
return alibaba.New(block)
1418
}
1519

pkg/providers/alibaba/alibaba.go

Lines changed: 100 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"encoding/base64"
66
"fmt"
7+
"net/http"
78
"strings"
89
"time"
910

@@ -27,12 +28,29 @@ import (
2728

2829
// Provider is a data provider for alibaba API
2930
type Provider struct {
30-
apiCred _auth.Credential
31-
region string
31+
apiCred _auth.Credential
32+
region string
33+
apiClientOptions []_api.Option
34+
ossClientOptions []_oss.Option
35+
slsHTTPClient *http.Client
3236
}
3337

3438
// New creates a new provider client for alibaba API
3539
func New(options schema.Options) (*Provider, error) {
40+
return NewWithConfig(options, ClientConfig{})
41+
}
42+
43+
type ClientConfig struct {
44+
APIOptions []_api.Option
45+
OSSOptions []_oss.Option
46+
SLSHTTPClient *http.Client
47+
SkipCredentialCache bool
48+
}
49+
50+
// NewWithConfig creates a new provider client for alibaba API with injected
51+
// transport options. This keeps payload behavior intact while allowing
52+
// replay/test clients to flow through the real provider and driver stack.
53+
func NewWithConfig(options schema.Options, cfg ClientConfig) (*Provider, error) {
3654
apiCred, err := _auth.FromOptions(options)
3755
if err != nil {
3856
return nil, err
@@ -42,7 +60,7 @@ func New(options schema.Options) (*Provider, error) {
4260
payload, _ := options.GetMetadata(utils.Payload)
4361
if payload == "cloudlist" {
4462
// Get current username
45-
response, err := _api.NewClient(apiCred).GetCallerIdentity(context.Background(), region)
63+
response, err := _api.NewClient(apiCred, cfg.APIOptions...).GetCallerIdentity(context.Background(), region)
4664
if err != nil {
4765
return nil, err
4866
}
@@ -56,13 +74,18 @@ func New(options schema.Options) (*Provider, error) {
5674
}
5775
}
5876
msg := fmt.Sprintf("Current user: %s (%s)", userName, accountArn)
59-
cache.Cfg.CredInsert(userName, options)
77+
if !cfg.SkipCredentialCache {
78+
cache.Cfg.CredInsert(userName, options)
79+
}
6080
logger.Warning(msg)
6181
}
6282

6383
return &Provider{
64-
apiCred: apiCred,
65-
region: region,
84+
apiCred: apiCred,
85+
region: region,
86+
apiClientOptions: append([]_api.Option(nil), cfg.APIOptions...),
87+
ossClientOptions: append([]_oss.Option(nil), cfg.OSSOptions...),
88+
slsHTTPClient: cfg.SLSHTTPClient,
6689
}, nil
6790
}
6891

@@ -78,40 +101,40 @@ func (p *Provider) Resources(ctx context.Context) (schema.Resources, error) {
78101
for _, product := range utils.Cloudlist {
79102
switch product {
80103
case "balance":
81-
d := &_bss.Driver{Cred: p.apiCred, Region: p.region}
104+
d := p.newBSSDriver(p.region)
82105
d.QueryAccountBalance(ctx)
83106
case "host":
84-
ecsprovider := &_ecs.Driver{Cred: p.apiCred, Region: p.region}
107+
ecsprovider := p.newECSDriver(p.region)
85108
hosts, err := ecsprovider.GetResource(ctx)
86109
schema.AppendAssets(&list, hosts)
87110
list.AddError("host", err)
88111
case "domain":
89-
dnsprovider := &_dns.Driver{Cred: p.apiCred, Region: p.region}
112+
dnsprovider := p.newDNSDriver(p.region)
90113
domains, err := dnsprovider.GetDomains(ctx)
91114
schema.AppendAssets(&list, domains)
92115
list.AddError("domain", err)
93116
case "account":
94-
ramprovider := &_iam.Driver{Cred: p.apiCred, Region: p.region}
117+
ramprovider := p.newIAMDriver(p.region)
95118
users, err := ramprovider.ListUsers(ctx)
96119
schema.AppendAssets(&list, users)
97120
list.AddError("account", err)
98121
case "database":
99-
rdsprovider := &_rds.Driver{Cred: p.apiCred, Region: p.region}
122+
rdsprovider := p.newRDSDriver(p.region)
100123
databases, err := rdsprovider.GetDatabases(ctx)
101124
schema.AppendAssets(&list, databases)
102125
list.AddError("database", err)
103126
case "bucket":
104-
ossprovider := &_oss.Driver{Cred: p.apiCred, Region: p.region}
127+
ossprovider := p.newOSSDriver(p.region)
105128
storages, err := ossprovider.GetBuckets(ctx)
106129
schema.AppendAssets(&list, storages)
107130
list.AddError("bucket", err)
108131
case "sms":
109-
smsprovider := &_sms.Driver{Cred: p.apiCred, Region: p.region}
132+
smsprovider := p.newSMSDriver(p.region)
110133
sms, err := smsprovider.GetResource(ctx)
111134
list.Sms = sms
112135
list.AddError("sms", err)
113136
case "log":
114-
slsprovider := &sls.Driver{Cred: p.apiCred, Region: p.region}
137+
slsprovider := p.newSLSDriver(p.region)
115138
logs, err := slsprovider.ListProjects(ctx)
116139
schema.AppendAssets(&list, logs)
117140
list.AddError("log", err)
@@ -123,7 +146,7 @@ func (p *Provider) Resources(ctx context.Context) (schema.Resources, error) {
123146
}
124147

125148
func (p *Provider) UserManagement(action, username, password string) {
126-
r := &_iam.Driver{Cred: p.apiCred, Region: p.region}
149+
r := p.newIAMDriver(p.region)
127150
switch action {
128151
case "add":
129152
r.UserName = username
@@ -145,7 +168,7 @@ func (p *Provider) UserManagement(action, username, password string) {
145168
}
146169

147170
func (p *Provider) BucketDump(ctx context.Context, action, bucketName string) {
148-
ossdrvier := &_oss.Driver{Cred: p.apiCred, Region: p.region}
171+
ossdrvier := p.newOSSDriver(p.region)
149172
switch action {
150173
case "list":
151174
infos, err := p.bucketInfos(context.Background(), ossdrvier, bucketName)
@@ -167,7 +190,7 @@ func (p *Provider) BucketDump(ctx context.Context, action, bucketName string) {
167190
}
168191

169192
func (p *Provider) EventDump(action, args string) {
170-
d := _sas.Driver{Cred: p.apiCred}
193+
d := p.newSASDriver()
171194
switch action {
172195
case "dump":
173196
events, err := d.DumpEvents()
@@ -199,7 +222,7 @@ func (p *Provider) ExecuteCloudVMCommand(instanceID, cmd string) {
199222
logger.Error("Unable to resolve instance metadata.")
200223
return
201224
}
202-
d := _ecs.Driver{Cred: p.apiCred, Region: host.Region}
225+
d := p.newECSDriver(host.Region)
203226
command, err := base64.StdEncoding.DecodeString(cmd)
204227
if err != nil {
205228
logger.Error(err.Error())
@@ -212,12 +235,12 @@ func (p *Provider) ExecuteCloudVMCommand(instanceID, cmd string) {
212235
}
213236

214237
func (p *Provider) DBManagement(action, instanceID string) {
215-
r := &_rds.Driver{Cred: p.apiCred, Region: p.region}
238+
r := p.newRDSDriver(p.region)
216239
switch action {
217240
case "useradd":
218241
db, ok := p.lookupDatabase(instanceID)
219242
if !ok {
220-
logger.Error("Unable to resolve database metadata.")
243+
logger.Error("Unable to resolve database metadata, retry: shell <instance-id>")
221244
return
222245
}
223246
r.Region = db.Region
@@ -235,18 +258,6 @@ func (p *Provider) lookupHost(instanceID string) (schema.Host, bool) {
235258
return host, true
236259
}
237260
}
238-
logger.Info("Host metadata cache miss, refreshing instances ...")
239-
driver := &_ecs.Driver{Cred: p.apiCred, Region: p.region}
240-
hosts, err := driver.GetResource(context.Background())
241-
if err != nil {
242-
logger.Error(err)
243-
return schema.Host{}, false
244-
}
245-
for _, host := range hosts {
246-
if host.ID == instanceID {
247-
return host, true
248-
}
249-
}
250261
return schema.Host{}, false
251262
}
252263

@@ -257,7 +268,7 @@ func (p *Provider) lookupDatabase(instanceID string) (schema.Database, bool) {
257268
}
258269
}
259270
logger.Info("Database metadata cache miss, refreshing instances ...")
260-
driver := &_rds.Driver{Cred: p.apiCred, Region: p.region}
271+
driver := p.newRDSDriver(p.region)
261272
databases, err := driver.GetDatabases(context.Background())
262273
if err != nil {
263274
logger.Error(err)
@@ -307,3 +318,59 @@ func (p *Provider) bucketInfos(ctx context.Context, driver *_oss.Driver, bucketN
307318
return nil, fmt.Errorf("bucket %s region not found; set region explicitly or use `list all` first", bucketName)
308319
}
309320
}
321+
322+
func (p *Provider) newBSSDriver(region string) *_bss.Driver {
323+
driver := &_bss.Driver{Cred: p.apiCred, Region: region}
324+
driver.SetClientOptions(p.apiClientOptions...)
325+
return driver
326+
}
327+
328+
func (p *Provider) newDNSDriver(region string) *_dns.Driver {
329+
driver := &_dns.Driver{Cred: p.apiCred, Region: region}
330+
driver.SetClientOptions(p.apiClientOptions...)
331+
return driver
332+
}
333+
334+
func (p *Provider) newECSDriver(region string) *_ecs.Driver {
335+
driver := &_ecs.Driver{Cred: p.apiCred, Region: region}
336+
driver.SetClientOptions(p.apiClientOptions...)
337+
return driver
338+
}
339+
340+
func (p *Provider) newIAMDriver(region string) *_iam.Driver {
341+
driver := &_iam.Driver{Cred: p.apiCred, Region: region}
342+
driver.SetClientOptions(p.apiClientOptions...)
343+
return driver
344+
}
345+
346+
func (p *Provider) newOSSDriver(region string) *_oss.Driver {
347+
driver := &_oss.Driver{Cred: p.apiCred, Region: region}
348+
if len(p.ossClientOptions) != 0 {
349+
driver.Client = _oss.NewClient(p.apiCred, p.ossClientOptions...)
350+
}
351+
return driver
352+
}
353+
354+
func (p *Provider) newRDSDriver(region string) *_rds.Driver {
355+
driver := &_rds.Driver{Cred: p.apiCred, Region: region}
356+
driver.SetClientOptions(p.apiClientOptions...)
357+
return driver
358+
}
359+
360+
func (p *Provider) newSASDriver() _sas.Driver {
361+
driver := _sas.Driver{Cred: p.apiCred}
362+
driver.SetClientOptions(p.apiClientOptions...)
363+
return driver
364+
}
365+
366+
func (p *Provider) newSLSDriver(region string) *sls.Driver {
367+
driver := &sls.Driver{Cred: p.apiCred, Region: region}
368+
driver.SetHTTPClient(p.slsHTTPClient)
369+
return driver
370+
}
371+
372+
func (p *Provider) newSMSDriver(region string) *_sms.Driver {
373+
driver := &_sms.Driver{Cred: p.apiCred, Region: region}
374+
driver.SetClientOptions(p.apiClientOptions...)
375+
return driver
376+
}

pkg/providers/alibaba/alibaba_bucketdump_test.go

Lines changed: 0 additions & 59 deletions
This file was deleted.

pkg/providers/alibaba/bss/balance.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ func (d *Driver) newClient() *api.Client {
1818
return api.NewClient(d.Cred, d.clientOptions...)
1919
}
2020

21+
func (d *Driver) SetClientOptions(opts ...api.Option) {
22+
d.clientOptions = append([]api.Option(nil), opts...)
23+
}
24+
2125
func (d *Driver) QueryAccountBalance(ctx context.Context) {
2226
select {
2327
case <-ctx.Done():

pkg/providers/alibaba/dns/dns.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ func (d *Driver) newClient() *api.Client {
2020
return api.NewClient(d.Cred, d.clientOptions...)
2121
}
2222

23+
func (d *Driver) SetClientOptions(opts ...api.Option) {
24+
d.clientOptions = append([]api.Option(nil), opts...)
25+
}
26+
2327
func (d *Driver) GetDomains(ctx context.Context) ([]schema.Domain, error) {
2428
list := []schema.Domain{}
2529
select {

pkg/providers/alibaba/iam/users.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ func (d *Driver) newClient() *api.Client {
2828
return api.NewClient(d.Cred, d.clientOptions...)
2929
}
3030

31+
func (d *Driver) SetClientOptions(opts ...api.Option) {
32+
d.clientOptions = append([]api.Option(nil), opts...)
33+
}
34+
3135
func (d *Driver) ListUsers(ctx context.Context) ([]schema.User, error) {
3236
list := []schema.User{}
3337
select {

pkg/providers/alibaba/rds/databases.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ func (d *Driver) newClient() *api.Client {
4141
return api.NewClient(d.Cred, d.clientOptions...)
4242
}
4343

44+
func (d *Driver) SetClientOptions(opts ...api.Option) {
45+
d.clientOptions = append([]api.Option(nil), opts...)
46+
}
47+
4448
func (d *Driver) GetDatabases(ctx context.Context) ([]schema.Database, error) {
4549
list := []schema.Database{}
4650
select {

0 commit comments

Comments
 (0)