Skip to content

Commit

Permalink
feat(arm): update arm
Browse files Browse the repository at this point in the history
update arm

Signed-off-by: ysicing <i@ysicing.me>
  • Loading branch information
ysicing committed Nov 4, 2022
1 parent d587d33 commit fe7121d
Show file tree
Hide file tree
Showing 9 changed files with 159 additions and 61 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@
## 功能

- [x] 开通Linux/Windows机器
- [x] 开通Linux/Windows竞价机器
- [x] 重启机器
- [x] 销毁机器
- [x] 列出镜像列表
- [x] 选择镜像启动虚拟机
- [ ] <del>专业版漏洞扫描</del>
- [x] 开通LinuxArm架构按量机器(限定广州地域)

## 安装

Expand Down
146 changes: 114 additions & 32 deletions cloud/qcloud/qcloud.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,10 @@ import (
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312"
cwp "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cwp/v20180228"
)

type Client struct {
cvmCliet *cvm.Client
cwpClient *cwp.Client
cvmCliet *cvm.Client
}

type Instance struct {
Expand All @@ -44,23 +42,23 @@ type Image struct {
OsName string
}

func NewClient() *Client {
func NewClient(regions ...string) *Client {
// 实例化一个认证对象,入参需要传入腾讯云账户secretId,secretKey,此处还需注意密钥对的保密
// 密钥可前往https://console.cloud.tencent.com/cam/capi网站进行获取
credential := common.NewCredential(
viper.GetString("qcloud.account.id"),
viper.GetString("qcloud.account.secret"),
)
logrus.Debugf("credential: %s, %s", credential.SecretId, credential.SecretKey)
region := viper.GetString("qcloud.region")
if len(regions) > 0 {
region = regions[0]
}
// 实例化一个client选项,可选的,没有特殊需求可以跳过
cvmcpf := profile.NewClientProfile()
cvmcpf.HttpProfile.Endpoint = "cvm.tencentcloudapi.com"
// 实例化要请求产品的client对象,clientProfile是可选的
cvmClient, _ := cvm.NewClient(credential, viper.GetString("qcloud.region"), cvmcpf)
cwpcpf := profile.NewClientProfile()
cwpcpf.HttpProfile.Endpoint = "cwp.tencentcloudapi.com"
cwpClient, _ := cwp.NewClient(credential, viper.GetString("qcloud.region"), cwpcpf)
return &Client{cvmCliet: cvmClient, cwpClient: cwpClient}
cvmClient, _ := cvm.NewClient(credential, region, cvmcpf)
return &Client{cvmCliet: cvmClient}
}

func (c *Client) Create(count int64, netaccess, windows bool, image string) error {
Expand Down Expand Up @@ -154,6 +152,112 @@ func (c *Client) Create(count int64, netaccess, windows bool, image string) erro
return nil
}

func (c *Client) CreateArm(count, exp int64, netaccess bool, image string) error {

// 实例化一个请求对象,每个接口都会对应一个request对象
request := cvm.NewRunInstancesRequest()
// arm 只支持按量
request.InstanceChargeType = common.StringPtr("POSTPAID_BY_HOUR")
qzone := viper.GetString("qcloud.zone")
if !strings.HasPrefix(qzone, "ap-guangzhou-") {
qzone = "ap-guangzhou-6"
}
request.Placement = &cvm.Placement{
Zone: common.StringPtr(qzone),
}
if viper.GetInt64("qcloud.project.id") > 0 {
request.Placement.ProjectId = common.Int64Ptr(viper.GetInt64("qcloud.project.id"))
}
intype := viper.GetString("qcloud.instance.type")
if !strings.HasPrefix(intype, "SR") {
intype = "SR1.MEDIUM2"
}
request.InstanceType = common.StringPtr(intype)
disk := viper.GetInt64("qcloud.instance.disk")
if disk == 0 {
disk = 50
}
request.SystemDisk = &cvm.SystemDisk{
DiskType: common.StringPtr("CLOUD_PREMIUM"),
DiskSize: common.Int64Ptr(disk),
}
vpcid := viper.GetString("qcloud.instance.network.vpc.id")
vpcsub := viper.GetString("qcloud.instance.network.subnet.id")
if len(vpcid) > 4 && len(vpcsub) > 7 {
request.VirtualPrivateCloud = &cvm.VirtualPrivateCloud{
VpcId: common.StringPtr(vpcid),
SubnetId: common.StringPtr(vpcsub),
AsVpcGateway: common.BoolPtr(false),
Ipv6AddressCount: common.Uint64Ptr(0),
}
}
if count == 1 && netaccess {
request.InternetAccessible = &cvm.InternetAccessible{
InternetChargeType: common.StringPtr("TRAFFIC_POSTPAID_BY_HOUR"),
InternetMaxBandwidthOut: common.Int64Ptr(100),
PublicIpAssigned: common.BoolPtr(true),
}
} else {
request.InternetAccessible = &cvm.InternetAccessible{
InternetMaxBandwidthOut: common.Int64Ptr(0),
PublicIpAssigned: common.BoolPtr(false),
}
}
request.InstanceCount = common.Int64Ptr(int64(count))
defaultImage := viper.GetString("qcloud.instance.image")
if len(image) == 0 {
image = defaultImage
}
namePrefix := "spot-arm"
request.LoginSettings = &cvm.LoginSettings{
KeyIds: common.StringPtrs(viper.GetStringSlice("qcloud.instance.auth.sshkey.ids")),
}
request.ImageId = common.StringPtr(image)
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{
Enabled: common.BoolPtr(true),
},
MonitorService: &cvm.RunMonitorServiceEnabled{
Enabled: common.BoolPtr(true),
},
AutomationService: &cvm.RunAutomationServiceEnabled{
Enabled: common.BoolPtr(true),
},
}
request.InstanceMarketOptions = &cvm.InstanceMarketOptionsRequest{
SpotOptions: &cvm.SpotMarketOptions{
MaxPrice: common.StringPtr("1000"),
},
}
request.DisableApiTermination = common.BoolPtr(false)
if exp >= 12 {
exp = 12
}
if exp <= 1 {
exp = 1
}
request.ActionTimer = &cvm.ActionTimer{
TimerAction: common.StringPtr("TerminateInstances"),
ActionTime: common.StringPtr(time.Now().Add(time.Hour * time.Duration(exp)).Format("2006-01-02 15:04:05")),
Externals: &cvm.Externals{
ReleaseAddress: common.BoolPtr(true),
},
}

// 返回的resp是一个RunInstancesResponse的实例,与请求对象对应
response, err := c.cvmCliet.RunInstances(request)
if _, ok := err.(*errors.TencentCloudSDKError); ok {
return fmt.Errorf("tencent api error has returned: %v", err)
}
if err != nil {
return err
}
logrus.Debugf("%s", response.ToJsonString())
return nil
}

func (c *Client) List() ([]Instance, error) {
// 实例化一个请求对象,每个接口都会对应一个request对象
request := cvm.NewDescribeInstancesRequest()
Expand Down Expand Up @@ -251,28 +355,6 @@ func (c *Client) Restart(id string) error {
return nil
}

func (c *Client) Scan(id string) error {
request := cwp.NewScanVulRequest()
request.VulLevels = common.StringPtr("1;2;3;4")
request.HostType = common.Uint64Ptr(2)
request.VulCategories = common.StringPtr("1;2;4")
request.QuuidList = common.StringPtrs([]string{id})
request.TimeoutPeriod = common.Uint64Ptr(3600)
response, err := c.cwpClient.ScanVul(request)
if terr, ok := err.(*errors.TencentCloudSDKError); ok {
if terr.Code == "OperationDenied" {
logrus.Warnf("%s %s", id, terr.Message)
return nil
}
return fmt.Errorf("tencent api error has returned: %v", err)
}
if err != nil {
return err
}
logrus.Infof("Scan %s task create %d", id, response.Response.TaskId)
return nil
}

func (c *Client) ImageList(notPublic bool) ([]Image, error) {
request := cvm.NewDescribeImagesRequest()
request.Offset = common.Uint64Ptr(0)
Expand Down
27 changes: 27 additions & 0 deletions cmd/arm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package cmd

import (
"github.com/ysicing/spot/cloud/qcloud"

"github.com/spf13/cobra"
)

func cmdNewArm() *cobra.Command {
var count, exp int64
var netaccess bool
var image string
c := &cobra.Command{
Use: "arm",
Short: "新建腾讯云ARM虚拟机",
Version: "0.1.0",
RunE: func(c *cobra.Command, args []string) error {
client := qcloud.NewClient("ap-guangzhou")
return client.CreateArm(count, exp, netaccess, image)
},
}
c.Flags().Int64VarP(&count, "count", "c", 1, "虚拟机数量")
c.Flags().BoolVar(&netaccess, "net", true, "是否开启公网访问, 单节点生效")
c.Flags().StringVarP(&image, "image", "i", "", "指定linux arm镜像")
c.Flags().Int64VarP(&exp, "exp", "e", 2, "销毁时间(区间1-12小时)")
return c
}
4 changes: 2 additions & 2 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func BuildRoot() *cobra.Command {
rootCmd.AddCommand(cmdList())
rootCmd.AddCommand(cmdDestroy())
rootCmd.AddCommand(cmdRestart())
rootCmd.AddCommand(cmdScan())
rootCmd.AddCommand(cmdNewArm())
rootCmd.AddCommand(cmdImage())
return rootCmd
}
Expand All @@ -47,7 +47,7 @@ func NewRootCmd() *cobra.Command {
SilenceUsage: true,
SilenceErrors: true,
Short: "腾讯云虚拟机管理工具",
Version: "0.0.5",
Version: "0.1.0",
PersistentPreRunE: func(cobraCmd *cobra.Command, args []string) error {
if globalFlags.Debug {
logrus.SetLevel(logrus.DebugLevel)
Expand Down
20 changes: 0 additions & 20 deletions cmd/scan.go

This file was deleted.

13 changes: 13 additions & 0 deletions config.example.arm.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
qcloud:
account:
id: <qcloud-SecretId>
secret: <qcloud-SecretId>
instance:
image: img-kh0snalc
type: SR1.MEDIUM2
auth:
sshkey:
ids:
- sshkey-id
securitygroup:
id: sg-id
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ require (
github.com/spf13/viper v1.13.0
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.527
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm v1.0.527
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cwp v1.0.515
)

require (
Expand Down
3 changes: 0 additions & 3 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -376,13 +376,10 @@ github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PK
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs=
github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.515/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.527 h1:hpZMjoYnR+ma5HMWWNaNc5fshpFXXaUPrZMo4OXPxYQ=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.527/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm v1.0.527 h1:I+jCU9S0o6EMRZ4121/Rj7llkX2Fsy1ksmSCf3y6r1M=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm v1.0.527/go.mod h1:mqG8ES2o28GJam1eGuudqzj2cduhDFXeTEB4jO0H64I=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cwp v1.0.515 h1:42n+Eh5o2Rwf4VNqAyUvU89D6RHLVmMu/DdLGV6Rvro=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cwp v1.0.515/go.mod h1:sYPKkNBw8FpgP8+AnEbqh9K3bSDxZJhKqK8BxxXz4AM=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
Expand Down
2 changes: 1 addition & 1 deletion version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.0.5
0.1.0

0 comments on commit fe7121d

Please sign in to comment.