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
2930type 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
3539func 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
125148func (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
147170func (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
169192func (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
214237func (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+ }
0 commit comments