Skip to content

Commit c8a1c3e

Browse files
committed
feat(volcengine):add provider
1 parent d7307b6 commit c8a1c3e

File tree

8 files changed

+344
-2
lines changed

8 files changed

+344
-2
lines changed

go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ require (
2828
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tat v1.0.759
2929
github.com/tencentyun/cos-go-sdk-v5 v0.7.43
3030
github.com/tidwall/gjson v1.17.0
31+
github.com/volcengine/volcengine-go-sdk v1.0.168
3132
golang.org/x/oauth2 v0.12.0
3233
)
3334

@@ -48,6 +49,7 @@ require (
4849
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
4950
github.com/golang/protobuf v1.5.3 // indirect
5051
github.com/google/go-querystring v1.0.0 // indirect
52+
github.com/google/uuid v1.3.0 // indirect
5153
github.com/hashicorp/hcl v1.0.0 // indirect
5254
github.com/jmespath/go-jmespath v0.4.0 // indirect
5355
github.com/json-iterator/go v1.1.12 // indirect
@@ -72,6 +74,7 @@ require (
7274
github.com/subosito/gotenv v1.4.2 // indirect
7375
github.com/tidwall/match v1.1.1 // indirect
7476
github.com/tidwall/pretty v1.2.0 // indirect
77+
github.com/volcengine/volc-sdk-golang v1.0.23 // indirect
7578
golang.org/x/crypto v0.13.0 // indirect
7679
golang.org/x/net v0.15.0 // indirect
7780
golang.org/x/sys v0.12.0 // indirect

pkg/plugins/volcengine.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//go:build !no_volcengine
2+
3+
package plugins
4+
5+
import (
6+
"github.com/404tk/cloudtoolkit/pkg/providers/volcengine"
7+
"github.com/404tk/cloudtoolkit/pkg/schema"
8+
)
9+
10+
type Volcengine struct{}
11+
12+
func (p Volcengine) Check(block schema.Options) (schema.Provider, error) {
13+
return volcengine.New(block)
14+
}
15+
16+
func (p Volcengine) Desc() string {
17+
return "Volcengine"
18+
}
19+
20+
func init() {
21+
registerProvider("volcengine", Volcengine{})
22+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package billing
2+
3+
import (
4+
"github.com/404tk/cloudtoolkit/utils/logger"
5+
"github.com/volcengine/volcengine-go-sdk/service/billing"
6+
"github.com/volcengine/volcengine-go-sdk/volcengine"
7+
"github.com/volcengine/volcengine-go-sdk/volcengine/session"
8+
)
9+
10+
func QueryAccountBalance(conf *volcengine.Config) {
11+
sess, _ := session.NewSession(conf.WithRegion("cn-beijing"))
12+
svc := billing.New(sess)
13+
queryBalanceAcctInput := &billing.QueryBalanceAcctInput{}
14+
resp, err := svc.QueryBalanceAcct(queryBalanceAcctInput)
15+
if err == nil {
16+
logger.Warning("Available cash amount:", *resp.AvailableBalance)
17+
}
18+
}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
package ecs
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/404tk/cloudtoolkit/pkg/schema"
8+
"github.com/404tk/cloudtoolkit/utils/logger"
9+
"github.com/404tk/cloudtoolkit/utils/processbar"
10+
"github.com/volcengine/volcengine-go-sdk/service/ecs"
11+
"github.com/volcengine/volcengine-go-sdk/volcengine"
12+
"github.com/volcengine/volcengine-go-sdk/volcengine/session"
13+
)
14+
15+
type Driver struct {
16+
Conf *volcengine.Config
17+
Region string
18+
}
19+
20+
func (d *Driver) NewClient(region string) *ecs.ECS {
21+
if region == "all" || region == "" {
22+
region = "cn-beijing"
23+
}
24+
sess, _ := session.NewSession(d.Conf.WithRegion(region))
25+
return ecs.New(sess)
26+
}
27+
28+
func (d *Driver) GetResource(ctx context.Context) ([]schema.Host, error) {
29+
list := []schema.Host{}
30+
logger.Info("Start enumerating ECS ...")
31+
svc := d.NewClient(d.Region)
32+
33+
var regions []string
34+
if d.Region == "all" {
35+
input := &ecs.DescribeRegionsInput{MaxResults: volcengine.Int32(100)}
36+
resp, err := svc.DescribeRegions(input)
37+
if err != nil {
38+
logger.Error("Describe regions failed.")
39+
return list, err
40+
}
41+
for _, r := range resp.Regions {
42+
regions = append(regions, *r.RegionId)
43+
}
44+
} else {
45+
regions = append(regions, d.Region)
46+
}
47+
flag := false
48+
prevLength := 0
49+
count := 0
50+
for _, r := range regions {
51+
svc = d.NewClient(r)
52+
token := volcengine.String("")
53+
for {
54+
request := &ecs.DescribeInstancesInput{
55+
MaxResults: volcengine.Int32(100),
56+
NextToken: token,
57+
}
58+
resp, err := svc.DescribeInstances(request)
59+
if err != nil {
60+
return list, err
61+
}
62+
for _, i := range resp.Instances {
63+
// Getting Host Information
64+
ipv4 := volcengine.StringValue(i.EipAddress.IpAddress)
65+
var privateIPv4 string
66+
if len(i.NetworkInterfaces) > 0 {
67+
privateIPv4 = volcengine.StringValue(i.NetworkInterfaces[0].PrimaryIpAddress)
68+
}
69+
70+
_host := schema.Host{
71+
HostName: volcengine.StringValue(i.Hostname),
72+
ID: volcengine.StringValue(i.InstanceId),
73+
State: volcengine.StringValue(i.Status),
74+
PublicIPv4: ipv4,
75+
PrivateIpv4: privateIPv4,
76+
OSType: volcengine.StringValue(i.OsType), // Windows or Linux
77+
Public: ipv4 != "",
78+
Region: r,
79+
}
80+
list = append(list, _host)
81+
}
82+
if len(resp.Instances) < 100 ||
83+
volcengine.StringValue(resp.NextToken) == "" {
84+
break
85+
}
86+
token = resp.NextToken
87+
}
88+
select {
89+
case <-ctx.Done():
90+
goto done
91+
default:
92+
prevLength, flag = processbar.RegionPrint(r, len(list)-count, prevLength, flag)
93+
count = len(list)
94+
}
95+
}
96+
done:
97+
if !flag {
98+
fmt.Printf("\n\033[F\033[K")
99+
}
100+
101+
return list, nil
102+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package iam
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"time"
7+
8+
"github.com/404tk/cloudtoolkit/pkg/schema"
9+
"github.com/404tk/cloudtoolkit/utils"
10+
"github.com/404tk/cloudtoolkit/utils/logger"
11+
"github.com/volcengine/volcengine-go-sdk/service/iam"
12+
"github.com/volcengine/volcengine-go-sdk/volcengine"
13+
"github.com/volcengine/volcengine-go-sdk/volcengine/session"
14+
)
15+
16+
type Driver struct {
17+
Conf *volcengine.Config
18+
}
19+
20+
func (d *Driver) NewClient() *iam.IAM {
21+
sess, _ := session.NewSession(d.Conf.WithRegion("cn-beijing"))
22+
return iam.New(sess)
23+
}
24+
25+
func (d *Driver) ListUsers(ctx context.Context) ([]schema.User, error) {
26+
list := []schema.User{}
27+
select {
28+
case <-ctx.Done():
29+
return list, nil
30+
default:
31+
logger.Info("Start enumerating IAM ...")
32+
}
33+
svc := d.NewClient()
34+
var offset int32 = 0
35+
//policy_infos = make(map[string]string)
36+
for {
37+
listUsersInput := &iam.ListUsersInput{
38+
Limit: volcengine.Int32(100),
39+
Offset: volcengine.Int32(offset),
40+
}
41+
resp, err := svc.ListUsers(listUsersInput)
42+
if err != nil {
43+
logger.Error("List users failed.")
44+
return list, err
45+
}
46+
47+
for _, user := range resp.UserMetadata {
48+
_user := schema.User{
49+
UserName: volcengine.StringValue(user.UserName),
50+
UserId: fmt.Sprint(*user.AccountId),
51+
}
52+
date, _ := time.Parse("20060102T150405Z", volcengine.StringValue(user.CreateDate))
53+
_user.CreateTime = date.String()
54+
55+
input := &iam.GetLoginProfileInput{UserName: user.UserName}
56+
lresp, err := svc.GetLoginProfile(input)
57+
if err == nil {
58+
_user.EnableLogin = true
59+
ldate := volcengine.StringValue(lresp.LoginProfile.LastLoginDate)
60+
if ldate != "" && ldate != "19700101T000000Z" {
61+
lastLoginDate, _ := time.Parse("20060102T150405Z", ldate)
62+
_user.LastLogin = lastLoginDate.String()
63+
}
64+
65+
}
66+
67+
if utils.ListPolicies {
68+
// _user.Policies = listPoliciesForUser(client, _user.UserName)
69+
}
70+
71+
list = append(list, _user)
72+
select {
73+
case <-ctx.Done():
74+
return list, nil
75+
default:
76+
continue
77+
}
78+
}
79+
if len(resp.UserMetadata) < 100 || *resp.Total == offset {
80+
break
81+
}
82+
offset += 100
83+
}
84+
return list, nil
85+
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
package volcengine
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/404tk/cloudtoolkit/pkg/providers/volcengine/billing"
8+
"github.com/404tk/cloudtoolkit/pkg/providers/volcengine/ecs"
9+
"github.com/404tk/cloudtoolkit/pkg/providers/volcengine/iam"
10+
"github.com/404tk/cloudtoolkit/pkg/schema"
11+
"github.com/404tk/cloudtoolkit/utils"
12+
"github.com/404tk/cloudtoolkit/utils/cache"
13+
"github.com/404tk/cloudtoolkit/utils/logger"
14+
"github.com/volcengine/volcengine-go-sdk/service/iam20210801"
15+
"github.com/volcengine/volcengine-go-sdk/volcengine"
16+
"github.com/volcengine/volcengine-go-sdk/volcengine/credentials"
17+
"github.com/volcengine/volcengine-go-sdk/volcengine/session"
18+
)
19+
20+
type Provider struct {
21+
conf *volcengine.Config
22+
region string
23+
}
24+
25+
// New creates a new provider client for alibaba API
26+
func New(options schema.Options) (*Provider, error) {
27+
accessKey, ok := options.GetMetadata(utils.AccessKey)
28+
if !ok {
29+
return nil, &schema.ErrNoSuchKey{Name: utils.AccessKey}
30+
}
31+
secretKey, ok := options.GetMetadata(utils.SecretKey)
32+
if !ok {
33+
return nil, &schema.ErrNoSuchKey{Name: utils.SecretKey}
34+
}
35+
region, _ := options.GetMetadata(utils.Region)
36+
token, _ := options.GetMetadata(utils.SecurityToken)
37+
cred := credentials.NewStaticCredentials(accessKey, secretKey, token)
38+
config := volcengine.NewConfig().WithCredentials(cred)
39+
40+
payload, _ := options.GetMetadata(utils.Payload)
41+
if payload == "cloudlist" {
42+
name, err := getProject(region, config)
43+
if err != nil {
44+
return nil, err
45+
}
46+
cache.Cfg.CredInsert(name, options)
47+
}
48+
49+
return &Provider{
50+
conf: config,
51+
region: region,
52+
}, nil
53+
}
54+
55+
func getProject(r string, conf *volcengine.Config) (string, error) {
56+
if r == "all" {
57+
conf = conf.WithRegion("cn-beijing")
58+
} else {
59+
conf = conf.WithRegion(r)
60+
}
61+
sess, _ := session.NewSession(conf)
62+
svc := iam20210801.New(sess)
63+
out, err := svc.ListProjects(&iam20210801.ListProjectsInput{})
64+
if err != nil {
65+
return "", err
66+
}
67+
name := fmt.Sprintf("%s(%d)", *out.Projects[0].ProjectName, *out.Projects[0].AccountID)
68+
logger.Warning("Current project:", name)
69+
return name, nil
70+
}
71+
72+
// Name returns the name of the provider
73+
func (p *Provider) Name() string {
74+
return "volcengine"
75+
}
76+
77+
// Resources returns the provider for a resource deployment source.
78+
func (p *Provider) Resources(ctx context.Context) (schema.Resources, error) {
79+
list := schema.NewResources()
80+
list.Provider = p.Name()
81+
var err error
82+
for _, product := range utils.Cloudlist {
83+
switch product {
84+
case "balance":
85+
billing.QueryAccountBalance(p.conf)
86+
case "host":
87+
d := &ecs.Driver{Conf: p.conf, Region: p.region}
88+
list.Hosts, err = d.GetResource(ctx)
89+
case "domain":
90+
case "account":
91+
d := &iam.Driver{Conf: p.conf}
92+
list.Users, err = d.ListUsers(ctx)
93+
case "database":
94+
case "bucket":
95+
case "sms":
96+
case "log":
97+
default:
98+
}
99+
}
100+
101+
return list, err
102+
}
103+
104+
func (p *Provider) UserManagement(action, args_1, args_2 string) {}
105+
106+
func (p *Provider) BucketDump(ctx context.Context, action, bucketname string) {}
107+
108+
func (p *Provider) EventDump(action, args string) {}
109+
110+
func (p *Provider) ExecuteCloudVMCommand(instanceId, cmd string) {}
111+
112+
func (p *Provider) DBManagement(action, args string) {}

runner/banner.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const banner = `
1212
`
1313

1414
// Version is the current version of cloudtoolkit
15-
const Version = `0.1.3`
15+
const Version = `0.1.5`
1616

1717
// showBanner is used to show the banner to the user
1818
func ShowBanner() {

runner/console/use.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ func use(args []string) {
2323

2424
func loadModule(m string) error {
2525
switch m {
26-
case "alibaba", "tencent", "huawei", "aws":
26+
case "alibaba", "tencent", "huawei", "aws", "volcengine":
2727
config = loadConfig1()
2828
case "azure":
2929
config = loadConfig2()

0 commit comments

Comments
 (0)