Skip to content

Commit

Permalink
feat(0.0.2): support create windows & restart cvm
Browse files Browse the repository at this point in the history
support create windows & restart cvm

Signed-off-by: ysbot <i@ysicing.me>
  • Loading branch information
ysicing committed Sep 9, 2022
1 parent 1592fec commit c857131
Show file tree
Hide file tree
Showing 8 changed files with 130 additions and 26 deletions.
50 changes: 43 additions & 7 deletions cloud/qcloud/qcloud.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func NewClient() *Client {
return &Client{client}
}

func (c *Client) Create(count int64, netaccess bool) error {
func (c *Client) Create(count int64, netaccess, windows bool) error {

// 实例化一个请求对象,每个接口都会对应一个request对象
request := cvm.NewRunInstancesRequest()
Expand All @@ -61,9 +61,16 @@ func (c *Client) Create(count int64, netaccess bool) error {
}
request.InstanceType = common.StringPtr(viper.GetString("qcloud.instance.type"))
request.ImageId = common.StringPtr(viper.GetString("qcloud.instance.image"))
disk := viper.GetInt64("qcloud.instance.disk")
if disk == 0 {
disk = 50
}
if windows && disk < 100 {
disk = 100
}
request.SystemDisk = &cvm.SystemDisk{
DiskType: common.StringPtr("CLOUD_PREMIUM"),
DiskSize: common.Int64Ptr(50),
DiskSize: common.Int64Ptr(disk),
}
request.VirtualPrivateCloud = &cvm.VirtualPrivateCloud{
VpcId: common.StringPtr(viper.GetString("qcloud.instance.network.vpc.id")),
Expand All @@ -84,10 +91,18 @@ func (c *Client) Create(count int64, netaccess bool) error {
}
}
request.InstanceCount = common.Int64Ptr(int64(count))
request.InstanceName = common.StringPtr(fmt.Sprintf("spot-%s", time.Now().Format("20060102150405")))
request.LoginSettings = &cvm.LoginSettings{
KeyIds: common.StringPtrs(viper.GetStringSlice("qcloud.instance.auth.sshkey.ids")),
namePrefix := "spot"
if windows {
request.LoginSettings = &cvm.LoginSettings{
KeepImageLogin: common.StringPtr("true"),
}
namePrefix = "spot-windows"
} else {
request.LoginSettings = &cvm.LoginSettings{
KeyIds: common.StringPtrs(viper.GetStringSlice("qcloud.instance.auth.sshkey.ids")),
}
}
request.InstanceName = common.StringPtr(fmt.Sprintf("%s-%s", namePrefix, time.Now().Format("20060102150405")))
request.SecurityGroupIds = common.StringPtrs(viper.GetStringSlice("qcloud.instance.securitygroup.ids"))
request.EnhancedService = &cvm.EnhancedService{
SecurityService: &cvm.RunSecurityServiceEnabled{
Expand Down Expand Up @@ -141,11 +156,11 @@ func (c *Client) List() ([]Instance, error) {
var ins []Instance
for _, i := range response.Response.InstanceSet {
if strings.HasPrefix(*i.InstanceName, "spot") {
ip := ""
ip := "-"
if len(i.PrivateIpAddresses) != 0 {
ip = *i.PrivateIpAddresses[0]
}
eip := ""
eip := "-"
if len(i.PublicIpAddresses) != 0 {
eip = *i.PublicIpAddresses[0]
}
Expand Down Expand Up @@ -193,3 +208,24 @@ func (c *Client) Drop(ids []string) error {
}
return nil
}

func (c *Client) Restart(id string) error {
// 实例化一个请求对象,每个接口都会对应一个request对象
request := cvm.NewRebootInstancesRequest()

request.InstanceIds = common.StringPtrs([]string{id})
// SOFT 表示软关机
// HARD 表示硬关机
// SOFT_FIRST 表示优先软关机,失败再执行硬关机
request.StopType = common.StringPtr("SOFT_FIRST")

// 返回的resp是一个RebootInstancesResponse的实例,与请求对象对应
_, err := c.RebootInstances(request)
if _, ok := err.(*errors.TencentCloudSDKError); ok {
return fmt.Errorf("tencent api error has returned: %v", err)
}
if err != nil {
return err
}
return nil
}
29 changes: 17 additions & 12 deletions cmd/destroy.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,30 +22,35 @@ func cmdDestroy() *cobra.Command {
if err != nil {
return err
}
if len(vms) == 0 {

okvms := []qcloud.Instance{}
var ids []string
for _, vm := range vms {
if vm.InstanceState == "RUNNING" {
ids = append(ids, vm.InstanceID)
okvms = append(okvms, vm)
}
}
if len(okvms) == 0 {
logrus.Info("没有可销毁的虚拟机")
return nil
}
if all {
logrus.Info("销毁所有虚拟机")
var ids []string
for _, vm := range vms {
ids = append(ids, vm.InstanceID)
}
logrus.Infof("销毁所有虚拟机, 数目: %d", len(ids))
return client.Drop(ids)
}
prompt := promptui.Select{
Label: "选择虚拟机",
Items: vms,
Items: okvms,
Templates: &promptui.SelectTemplates{
Label: "{{ . }}?",
Active: "\U0001F449 {{ .PrivateIpAddresses | cyan }} ({{ .InstanceName | red }})",
Inactive: " {{ .PrivateIpAddresses | cyan }} ({{ .InstanceName | red }})",
Selected: "\U0001F389 {{ .PrivateIpAddresses | green }}",
Active: "\U0001F449 {{ .PrivateIPAddresses | cyan }} ({{ .InstanceName | red }})",
Inactive: " {{ .PrivateIPAddresses | cyan }} ({{ .InstanceName | red }})",
Selected: "\U0001F389 {{ .PrivateIPAddresses | green }}",
},
Size: 4,
Searcher: func(input string, index int) bool {
vm := vms[index]
vm := okvms[index]
name := vm.PrivateIPAddresses
return strings.Contains(name, input)
},
Expand All @@ -56,7 +61,7 @@ func cmdDestroy() *cobra.Command {
return err
}

return client.Drop([]string{vms[i].InstanceID})
return client.Drop([]string{okvms[i].InstanceID})
},
}
c.Flags().BoolVarP(&all, "all", "a", false, "销毁所有虚拟机")
Expand Down
4 changes: 3 additions & 1 deletion cmd/new.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,18 @@ import (
func cmdNew() *cobra.Command {
var count int64
var netaccess bool
var windows bool
c := &cobra.Command{
Use: "new",
Aliases: []string{"up", "create"},
Short: "新建腾讯云虚拟机",
RunE: func(c *cobra.Command, args []string) error {
client := qcloud.NewClient()
return client.Create(count, netaccess)
return client.Create(count, netaccess, windows)
},
}
c.Flags().Int64VarP(&count, "count", "c", 1, "虚拟机数量")
c.Flags().BoolVar(&netaccess, "net", true, "是否开启公网访问, 单节点生效")
c.Flags().BoolVar(&windows, "windows", false, "windows节点")
return c
}
58 changes: 58 additions & 0 deletions cmd/restart.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package cmd

import (
"github.com/manifoldco/promptui"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/ysicing/spot/cloud/qcloud"
)

func cmdRestart() *cobra.Command {
c := &cobra.Command{
Use: "restart",
Aliases: []string{"rs"},
Short: "重启腾讯云竞价虚拟机",
RunE: func(c *cobra.Command, args []string) error {
client := qcloud.NewClient()
vms, err := client.List()
if err != nil {
return err
}

okvms := []qcloud.Instance{}
for _, vm := range vms {
if vm.InstanceState == "RUNNING" {
okvms = append(okvms, vm)
}
}
okvms = append(okvms, qcloud.Instance{
InstanceID: "ins-4yw9saqt",
InstanceName: "name",
PrivateIPAddresses: "pip",
InstanceState: "RUNNING",
})
if len(okvms) == 0 {
logrus.Info("没有可重启的虚拟机")
return nil
}
templates := &promptui.SelectTemplates{
Label: "{{ . }}",
Active: "\U0001F449 {{ .PrivateIPAddresses | cyan }} ({{ .InstanceName | red }})",
Inactive: " {{ .PrivateIPAddresses | cyan }} ({{ .InstanceName | red }})",
Selected: "\U0001F389 {{ .PrivateIPAddresses | green }}",
}
prompt := promptui.Select{
Label: "选择虚拟机",
Items: okvms,
Templates: templates,
}

i, _, err := prompt.Run()
if err != nil {
return err
}
return client.Restart(okvms[i].InstanceID)
},
}
return c
}
3 changes: 2 additions & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ func BuildRoot() *cobra.Command {
rootCmd.AddCommand(cmdNew())
rootCmd.AddCommand(cmdList())
rootCmd.AddCommand(cmdDestroy())
rootCmd.AddCommand(cmdRestart())
return rootCmd
}

Expand All @@ -44,7 +45,7 @@ func NewRootCmd() *cobra.Command {
SilenceUsage: true,
SilenceErrors: true,
Short: "腾讯云虚拟机管理工具",
Version: "0.0.1",
Version: "0.0.2",
PersistentPreRunE: func(cobraCmd *cobra.Command, args []string) error {
if globalFlags.Debug {
logrus.SetLevel(logrus.DebugLevel)
Expand Down
5 changes: 3 additions & 2 deletions config.example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ qcloud:
instance:
image: img-id
type: SA2.MEDIUM4
disk: 50
network:
vpc:
id: vpc-id
subnet:
id: subnet-id
auth:
sshkey:
ids:
- sshkey-id
ids:
- sshkey-id
securitygroup:
id: sg-id
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/ysicing/spot
go 1.19

require (
github.com/davecgh/go-spew v1.1.1
github.com/ergoapi/util v0.2.21
github.com/gosuri/uitable v0.0.4
github.com/manifoldco/promptui v0.9.0
Expand Down Expand Up @@ -44,7 +45,7 @@ require (
github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/subosito/gotenv v1.4.1 // indirect
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect
golang.org/x/sys v0.0.0-20220908164124-27713097b956 // indirect
golang.org/x/text v0.3.7 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -569,8 +569,8 @@ golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956 h1:XeJjHH1KiLpKGb6lvMiksZ9l0fVUh+AmGcm0nOMEBOY=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
Expand Down

0 comments on commit c857131

Please sign in to comment.