Skip to content

Commit 7c43df8

Browse files
committed
uhost clone&reset-password&create-image and udisk snapshost manage
1 parent d862e75 commit 7c43df8

136 files changed

Lines changed: 2527 additions & 1819 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
## Change Log
2+
v0.1.5
3+
* support batch operation.
4+
5+
v0.1.4
6+
* add udisk.
7+
* polling udisk and uhost long time operation
8+
* async complete resource-id
29

310
v0.1.3
411
* integrate auto completion.

base/client.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,33 @@
11
package base
22

33
import (
4+
pudisk "github.com/ucloud/ucloud-sdk-go/private/services/udisk"
5+
puhost "github.com/ucloud/ucloud-sdk-go/private/services/uhost"
46
"github.com/ucloud/ucloud-sdk-go/services/pathx"
57
"github.com/ucloud/ucloud-sdk-go/services/uaccount"
68
"github.com/ucloud/ucloud-sdk-go/services/udisk"
79
"github.com/ucloud/ucloud-sdk-go/services/uhost"
8-
"github.com/ucloud/ucloud-sdk-go/services/ulb"
910
"github.com/ucloud/ucloud-sdk-go/services/unet"
1011
"github.com/ucloud/ucloud-sdk-go/services/vpc"
1112
"github.com/ucloud/ucloud-sdk-go/ucloud"
1213
"github.com/ucloud/ucloud-sdk-go/ucloud/auth"
1314
)
1415

16+
//PrivateUDiskClient 私有模块的udisk client 即未在官网开放的接口
17+
type PrivateUDiskClient = pudisk.UDiskClient
18+
19+
//PrivateUHostClient 私有模块的udisk client 即未在官网开放的接口
20+
type PrivateUHostClient = puhost.UHostClient
21+
1522
//Client aggregate client for business
1623
type Client struct {
1724
uaccount.UAccountClient
1825
uhost.UHostClient
1926
unet.UNetClient
20-
ulb.ULBClient
2127
vpc.VPCClient
2228
pathx.PathXClient
2329
udisk.UDiskClient
30+
PrivateUHostClient
2431
}
2532

2633
// NewClient will return a aggregate client
@@ -29,9 +36,9 @@ func NewClient(config *ucloud.Config, credential *auth.Credential) *Client {
2936
*uaccount.NewClient(config, credential),
3037
*uhost.NewClient(config, credential),
3138
*unet.NewClient(config, credential),
32-
*ulb.NewClient(config, credential),
3339
*vpc.NewClient(config, credential),
3440
*pathx.NewClient(config, credential),
3541
*udisk.NewClient(config, credential),
42+
*puhost.NewClient(config, credential),
3643
}
3744
}

base/config.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,6 @@ func init() {
187187
ConfigInstance.LoadConfig()
188188
timeout, _ := time.ParseDuration("15s")
189189
ClientConfig = &sdk.Config{
190-
ProjectId: ConfigInstance.ProjectID,
191190
BaseUrl: "https://api.ucloud.cn/",
192191
Timeout: timeout,
193192
UserAgent: fmt.Sprintf("UCloud CLI v%s", Version),

base/util.go

Lines changed: 147 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"github.com/ucloud/ucloud-sdk-go/ucloud/response"
2121

2222
"github.com/ucloud/ucloud-cli/model"
23+
"github.com/ucloud/ucloud-cli/ux"
2324
)
2425

2526
//ConfigPath 配置文件路径
@@ -263,59 +264,162 @@ var RegionLabel = map[string]string{
263264
"afr-nigeria": "Lagos",
264265
}
265266

266-
//Poll 轮询
267-
func Poll(describeFunc func(string, string, string, string) (interface{}, error)) func(string, string, string, string, []string) chan bool {
268-
stateFields := []string{"State", "Status"}
269-
return func(resourceID, projectID, region, zone string, targetState []string) chan bool {
270-
w := waiter.StateWaiter{
271-
Pending: []string{"pending"},
272-
Target: []string{"avaliable"},
273-
Refresh: func() (interface{}, string, error) {
274-
inst, err := describeFunc(resourceID, projectID, region, zone)
275-
if err != nil {
276-
return nil, "", err
277-
}
267+
//Poller 轮询器
268+
type Poller struct {
269+
stateFields []string
270+
DescribeFunc func(string, string, string, string) (interface{}, error)
271+
Out io.Writer
272+
Timeout time.Duration
273+
SdescribeFunc func(string) (interface{}, error)
274+
}
275+
276+
//Spoll 简化版
277+
func (p *Poller) Spoll(resourceID, pollText string, targetStates []string) {
278+
w := waiter.StateWaiter{
279+
Pending: []string{"pending"},
280+
Target: []string{"avaliable"},
281+
Refresh: func() (interface{}, string, error) {
282+
inst, err := p.SdescribeFunc(resourceID)
283+
if err != nil {
284+
return nil, "", err
285+
}
278286

279-
if inst == nil {
280-
return nil, "pending", nil
287+
if inst == nil {
288+
return nil, "pending", nil
289+
}
290+
instValue := reflect.ValueOf(inst)
291+
instValue = reflect.Indirect(instValue)
292+
instType := instValue.Type()
293+
if instValue.Kind() != reflect.Struct {
294+
return nil, "", fmt.Errorf("Instance is not struct")
295+
}
296+
state := ""
297+
for i := 0; i < instValue.NumField(); i++ {
298+
for _, sf := range p.stateFields {
299+
if instType.Field(i).Name == sf {
300+
state = instValue.Field(i).String()
301+
}
281302
}
282-
instValue := reflect.ValueOf(inst)
283-
instValue = reflect.Indirect(instValue)
284-
instType := instValue.Type()
285-
if instValue.Kind() != reflect.Struct {
286-
return nil, "", fmt.Errorf("Instance is not struct")
303+
}
304+
if state != "" {
305+
for _, t := range targetStates {
306+
if t == state {
307+
return inst, "avaliable", nil
308+
}
287309
}
288-
state := ""
289-
for i := 0; i < instValue.NumField(); i++ {
290-
for _, sf := range stateFields {
291-
if instType.Field(i).Name == sf {
292-
state = instValue.Field(i).String()
293-
}
310+
}
311+
return nil, "pending", nil
312+
313+
},
314+
Timeout: p.Timeout,
315+
}
316+
317+
done := make(chan bool)
318+
go func() {
319+
if resp, err := w.Wait(); err != nil {
320+
log.Error(err)
321+
if _, ok := err.(*waiter.TimeoutError); ok {
322+
done <- false
323+
return
324+
}
325+
} else {
326+
log.Infof("%#v", resp)
327+
}
328+
done <- true
329+
}()
330+
331+
spinner := ux.NewDotSpinner(p.Out)
332+
spinner.Start(pollText)
333+
ret := <-done
334+
if ret {
335+
spinner.Stop()
336+
} else {
337+
spinner.Timeout()
338+
}
339+
}
340+
341+
//Poll function
342+
func (p *Poller) Poll(resourceID, projectID, region, zone, pollText string, targetState []string) {
343+
w := waiter.StateWaiter{
344+
Pending: []string{"pending"},
345+
Target: []string{"avaliable"},
346+
Refresh: func() (interface{}, string, error) {
347+
inst, err := p.DescribeFunc(resourceID, projectID, region, zone)
348+
if err != nil {
349+
return nil, "", err
350+
}
351+
352+
if inst == nil {
353+
return nil, "pending", nil
354+
}
355+
instValue := reflect.ValueOf(inst)
356+
instValue = reflect.Indirect(instValue)
357+
instType := instValue.Type()
358+
if instValue.Kind() != reflect.Struct {
359+
return nil, "", fmt.Errorf("Instance is not struct")
360+
}
361+
state := ""
362+
for i := 0; i < instValue.NumField(); i++ {
363+
for _, sf := range p.stateFields {
364+
if instType.Field(i).Name == sf {
365+
state = instValue.Field(i).String()
294366
}
295367
}
296-
if state != "" {
297-
for _, t := range targetState {
298-
if t == state {
299-
return inst, "avaliable", nil
300-
}
368+
}
369+
if state != "" {
370+
for _, t := range targetState {
371+
if t == state {
372+
return inst, "avaliable", nil
301373
}
302374
}
303-
return nil, "pending", nil
375+
}
376+
return nil, "pending", nil
304377

305-
},
306-
Timeout: 5 * time.Minute,
307-
}
378+
},
379+
Timeout: p.Timeout,
380+
}
308381

309-
done := make(chan bool)
310-
go func() {
311-
if resp, err := w.Wait(); err != nil {
312-
log.Error(err)
313-
} else {
314-
log.Infof("%#v", resp)
382+
done := make(chan bool)
383+
go func() {
384+
if resp, err := w.Wait(); err != nil {
385+
log.Error(err)
386+
if _, ok := err.(*waiter.TimeoutError); ok {
387+
done <- false
388+
return
315389
}
316-
done <- true
317-
}()
318-
return done
390+
} else {
391+
log.Infof("%#v", resp)
392+
}
393+
done <- true
394+
}()
395+
396+
spinner := ux.NewDotSpinner(p.Out)
397+
spinner.Start(pollText)
398+
ret := <-done
399+
if ret {
400+
spinner.Stop()
401+
} else {
402+
spinner.Timeout()
403+
}
404+
}
405+
406+
//NewSpoller simple
407+
func NewSpoller(describeFunc func(string) (interface{}, error), out io.Writer) *Poller {
408+
return &Poller{
409+
SdescribeFunc: describeFunc,
410+
Out: out,
411+
stateFields: []string{"State", "Status"},
412+
Timeout: 10 * time.Minute,
413+
}
414+
}
415+
416+
//NewPoller 轮询
417+
func NewPoller(describeFunc func(string, string, string, string) (interface{}, error), out io.Writer) *Poller {
418+
return &Poller{
419+
DescribeFunc: describeFunc,
420+
Out: out,
421+
stateFields: []string{"State", "Status"},
422+
Timeout: 10 * time.Minute,
319423
}
320424
}
321425

0 commit comments

Comments
 (0)