feat: manually mirror opencoze's code from bytedance
Change-Id: I09a73aadda978ad9511264a756b2ce51f5761adf
This commit is contained in:
43
scripts/volcengine/.volcengine.example.env
Normal file
43
scripts/volcengine/.volcengine.example.env
Normal file
@@ -0,0 +1,43 @@
|
||||
export VE_AK=""
|
||||
export VE_SK=""
|
||||
export VE_REGION=""
|
||||
|
||||
export VE_PROJECT_NAME="default"
|
||||
export VE_VPC_NAME="opencoze-vpc"
|
||||
|
||||
# MySQL
|
||||
export VE_MYSQL_DB_NAME="opencoze"
|
||||
export VE_MYSQL_USER_NAME="coze"
|
||||
export VE_MYSQL_USER_PASSWORD="Opencoze123"
|
||||
export VE_MYSQL_PORT="3306"
|
||||
export VE_MYSQL_DB_ENGINE_VERSION="MySQL_8_0"
|
||||
export VE_MYSQL_INSTANCE_CLASS="vedb.mysql.g2.medium"
|
||||
|
||||
# The intermediate variable is empty by default; no input is required.
|
||||
|
||||
# ZoneID
|
||||
export VE_ZONE_ID=""
|
||||
|
||||
# network
|
||||
export VE_VPC_ID=""
|
||||
export VE_SUBNET_ID=""
|
||||
export VE_ACL_ID=""
|
||||
export VE_SAFE_GROUP_ID=""
|
||||
|
||||
# mysql
|
||||
export VE_MYSQL_INSTANCE_ID=""
|
||||
export VE_MYSQL_WHITELIST_ID=""
|
||||
|
||||
# redis
|
||||
export VE_REDIS_INSTANCE_ID=""
|
||||
export VE_REDIS_ALLOWLIST_ID=""
|
||||
|
||||
# rocketmq
|
||||
export VE_ROCKETMQ_ALLOWLIST_ID=""
|
||||
export VE_ROCKETMQ_INSTANCE_ID=""
|
||||
|
||||
# elasticsearch
|
||||
export VE_ES_INSTANCE_ID=""
|
||||
|
||||
# ECS
|
||||
export VE_ECS_INSTANCE_ID=""
|
||||
132
scripts/volcengine/elasticsearch.go
Normal file
132
scripts/volcengine/elasticsearch.go
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/volcengine/volcengine-go-sdk/service/escloud"
|
||||
"github.com/volcengine/volcengine-go-sdk/volcengine"
|
||||
)
|
||||
|
||||
func CreateESInstance(vpcID, subnetID, zoneID, ts string) (string, error) {
|
||||
if os.Getenv("VE_ES_INSTANCE_ID") != "" {
|
||||
return os.Getenv("VE_ES_INSTANCE_ID"), nil
|
||||
}
|
||||
svc := escloud.New(sess)
|
||||
reqNetworkSpecs := &escloud.NetworkSpecForCreateInstanceInOneStepInput{
|
||||
Bandwidth: volcengine.Int32(10),
|
||||
IsOpen: volcengine.Bool(true),
|
||||
SpecName: volcengine.String("es.eip.bgp_fixed_bandwidth"),
|
||||
Type: volcengine.String("Kibana"),
|
||||
}
|
||||
reqExtraPerformance := &escloud.ExtraPerformanceForCreateInstanceInOneStepInput{
|
||||
Throughput: volcengine.Int32(0),
|
||||
}
|
||||
reqNodeSpecsAssigns := &escloud.NodeSpecsAssignForCreateInstanceInOneStepInput{
|
||||
ExtraPerformance: reqExtraPerformance,
|
||||
Number: volcengine.Int32(1),
|
||||
ResourceSpecName: volcengine.String("kibana.x2.small"),
|
||||
StorageSize: volcengine.Int32(0),
|
||||
Type: volcengine.String("Kibana"),
|
||||
}
|
||||
|
||||
reqNodeSpecsAssigns1 := &escloud.NodeSpecsAssignForCreateInstanceInOneStepInput{
|
||||
ExtraPerformance: reqExtraPerformance,
|
||||
Number: volcengine.Int32(1),
|
||||
ResourceSpecName: volcengine.String("es.x2.medium"),
|
||||
StorageSize: volcengine.Int32(30),
|
||||
StorageSpecName: volcengine.String("es.volume.essd.pl0"),
|
||||
Type: volcengine.String("Hot"),
|
||||
}
|
||||
reqSubnet := &escloud.SubnetForCreateInstanceInOneStepInput{
|
||||
SubnetId: volcengine.String(subnetID),
|
||||
}
|
||||
reqVPC := &escloud.VPCForCreateInstanceInOneStepInput{
|
||||
VpcId: volcengine.String(vpcID),
|
||||
}
|
||||
name := "opencoze-es-" + ts
|
||||
reqInstanceConfiguration := &escloud.InstanceConfigurationForCreateInstanceInOneStepInput{
|
||||
AdminPassword: volcengine.String(password),
|
||||
ChargeType: volcengine.String("PostPaid"),
|
||||
EnableHttps: volcengine.Bool(false),
|
||||
EnablePureMaster: volcengine.Bool(false),
|
||||
InstanceName: volcengine.String(name),
|
||||
NetworkSpecs: []*escloud.NetworkSpecForCreateInstanceInOneStepInput{reqNetworkSpecs},
|
||||
NodeSpecsAssigns: []*escloud.NodeSpecsAssignForCreateInstanceInOneStepInput{reqNodeSpecsAssigns, reqNodeSpecsAssigns1},
|
||||
ProjectName: volcengine.String(projectName),
|
||||
RegionId: volcengine.String(region),
|
||||
Subnet: reqSubnet,
|
||||
VPC: reqVPC,
|
||||
Version: volcengine.String("V7_10"),
|
||||
ZoneId: volcengine.String(zoneID),
|
||||
DeletionProtection: volcengine.Bool(false),
|
||||
}
|
||||
reqTags := &escloud.TagForCreateInstanceInOneStepInput{
|
||||
Key: volcengine.String("opencoze"),
|
||||
Value: volcengine.String("1"),
|
||||
}
|
||||
createInstanceInOneStepInput := &escloud.CreateInstanceInOneStepInput{
|
||||
InstanceConfiguration: reqInstanceConfiguration,
|
||||
Tags: []*escloud.TagForCreateInstanceInOneStepInput{reqTags},
|
||||
}
|
||||
|
||||
resp, err := svc.CreateInstanceInOneStep(createInstanceInOneStepInput)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if resp.InstanceId == nil {
|
||||
return "", errors.New("InstanceId is empty")
|
||||
}
|
||||
|
||||
return *resp.InstanceId, nil
|
||||
}
|
||||
|
||||
func GetESConnectAddress(instanceID string) (string, error) {
|
||||
svc := escloud.New(sess)
|
||||
describeInstanceInput := &escloud.DescribeInstanceInput{
|
||||
InstanceId: volcengine.String(instanceID),
|
||||
}
|
||||
|
||||
for {
|
||||
resp, err := svc.DescribeInstance(describeInstanceInput)
|
||||
if resp.InstanceInfo != nil && resp.InstanceInfo.Status != nil && *resp.InstanceInfo.Status != "Running" {
|
||||
fmt.Printf("[Elasticsearch] instance(%s) is %s, waiting for it to become ready... \n", instanceID, *resp.InstanceInfo.Status)
|
||||
time.Sleep(retryTime)
|
||||
continue
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.Printf("[Elasticsearch] will retry get es instance = %s failed, err= %s\n", instanceID, err.Error())
|
||||
time.Sleep(retryTime)
|
||||
continue
|
||||
}
|
||||
|
||||
if resp.InstanceInfo.ESPrivateEndpoint == nil {
|
||||
log.Printf("[Elasticsearch] DescribeInstanceDetail resp.InstanceInfo.ESPrivateEndpoint is empty, will retry")
|
||||
time.Sleep(retryTime)
|
||||
continue
|
||||
}
|
||||
|
||||
return *resp.InstanceInfo.ESPrivateEndpoint, nil
|
||||
}
|
||||
}
|
||||
66
scripts/volcengine/env.go
Normal file
66
scripts/volcengine/env.go
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func updateEnvVarInFile(key, newValue string) {
|
||||
oldValue := os.Getenv(key)
|
||||
if len(oldValue) > 0 {
|
||||
return
|
||||
}
|
||||
|
||||
filePath := ".env"
|
||||
input, err := os.ReadFile(filePath)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("can not read file %s: %w", ".env", err))
|
||||
}
|
||||
|
||||
lines := strings.Split(string(input), "\n")
|
||||
found := false
|
||||
|
||||
for i, line := range lines {
|
||||
trimmedLine := strings.TrimSpace(line)
|
||||
|
||||
var prefix string
|
||||
if strings.HasPrefix(trimmedLine, "export ") {
|
||||
prefix = "export "
|
||||
trimmedLine = strings.TrimPrefix(trimmedLine, "export ")
|
||||
}
|
||||
|
||||
parts := strings.SplitN(trimmedLine, "=", 2)
|
||||
if len(parts) == 2 && parts[0] == key {
|
||||
lines[i] = fmt.Sprintf(`%s%s="%s"`, prefix, key, newValue)
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
panic(fmt.Errorf("can not find var %s in file %s", key, filePath))
|
||||
}
|
||||
|
||||
output := strings.Join(lines, "\n")
|
||||
err = os.WriteFile(filePath, []byte(output), 0o644)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("can not write file %s: %w", filePath, err))
|
||||
}
|
||||
}
|
||||
77
scripts/volcengine/esc.go
Normal file
77
scripts/volcengine/esc.go
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
|
||||
"github.com/volcengine/volcengine-go-sdk/service/ecs"
|
||||
"github.com/volcengine/volcengine-go-sdk/volcengine"
|
||||
)
|
||||
|
||||
func CreateECSInstance(zoneID, sgID, subnetID, ts string) (string, error) {
|
||||
if os.Getenv("VE_ECS_INSTANCE_ID") != "" {
|
||||
return os.Getenv("VE_ECS_INSTANCE_ID"), nil
|
||||
}
|
||||
svc := ecs.New(sess)
|
||||
reqEipAddress := &ecs.EipAddressForRunInstancesInput{
|
||||
BandwidthMbps: volcengine.Int32(10),
|
||||
ChargeType: volcengine.String("PayByBandwidth"),
|
||||
ISP: volcengine.String("BGP"),
|
||||
ReleaseWithInstance: volcengine.Bool(true),
|
||||
}
|
||||
reqNetworkInterfaces := &ecs.NetworkInterfaceForRunInstancesInput{
|
||||
SecurityGroupIds: volcengine.StringSlice([]string{sgID}),
|
||||
SubnetId: volcengine.String(subnetID),
|
||||
}
|
||||
reqTags := &ecs.TagForRunInstancesInput{
|
||||
Key: volcengine.String("opencoze"),
|
||||
Value: volcengine.String("1"),
|
||||
}
|
||||
reqVolumes := &ecs.VolumeForRunInstancesInput{
|
||||
Size: volcengine.Int32(100),
|
||||
}
|
||||
|
||||
name := "opencoze-ecs-" + ts
|
||||
runInstancesInput := &ecs.RunInstancesInput{
|
||||
DryRun: volcengine.Bool(false),
|
||||
EipAddress: reqEipAddress,
|
||||
Hostname: volcengine.String("opencoze-server"),
|
||||
ImageId: volcengine.String("image-yd6lmt386vgqef1r7xpu"),
|
||||
InstanceChargeType: volcengine.String("PostPaid"),
|
||||
InstanceName: volcengine.String(name),
|
||||
InstanceTypeId: volcengine.String("ecs.c4il.4xlarge"),
|
||||
NetworkInterfaces: []*ecs.NetworkInterfaceForRunInstancesInput{reqNetworkInterfaces},
|
||||
Password: volcengine.String(password),
|
||||
ProjectName: volcengine.String(projectName),
|
||||
Tags: []*ecs.TagForRunInstancesInput{reqTags},
|
||||
Volumes: []*ecs.VolumeForRunInstancesInput{reqVolumes},
|
||||
ZoneId: volcengine.String(zoneID),
|
||||
}
|
||||
|
||||
resp, err := svc.RunInstances(runInstancesInput)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if len(resp.InstanceIds) == 0 {
|
||||
return "", errors.New("[ECS] InstanceIds is empty")
|
||||
}
|
||||
|
||||
return *resp.InstanceIds[0], nil
|
||||
}
|
||||
15
scripts/volcengine/go.mod
Normal file
15
scripts/volcengine/go.mod
Normal file
@@ -0,0 +1,15 @@
|
||||
module github.com/coze-dev/coze-studio/scripts/volcengine
|
||||
|
||||
go 1.24.1
|
||||
|
||||
require (
|
||||
github.com/joho/godotenv v1.5.1
|
||||
github.com/volcengine/volcengine-go-sdk v1.1.18
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/volcengine/volc-sdk-golang v1.0.23 // indirect
|
||||
gopkg.in/yaml.v2 v2.2.8 // indirect
|
||||
)
|
||||
95
scripts/volcengine/go.sum
Normal file
95
scripts/volcengine/go.sum
Normal file
@@ -0,0 +1,95 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
|
||||
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/volcengine/volc-sdk-golang v1.0.23 h1:anOslb2Qp6ywnsbyq9jqR0ljuO63kg9PY+4OehIk5R8=
|
||||
github.com/volcengine/volc-sdk-golang v1.0.23/go.mod h1:AfG/PZRUkHJ9inETvbjNifTDgut25Wbkm2QoYBTbvyU=
|
||||
github.com/volcengine/volcengine-go-sdk v1.1.18 h1:tVcp1m6R8fgwZFb/MaltrpZY7b2+vYNbmO1MHlDSXIs=
|
||||
github.com/volcengine/volcengine-go-sdk v1.1.18/go.mod h1:EyKoi6t6eZxoPNGr2GdFCZti2Skd7MO3eUzx7TtSvNo=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
386
scripts/volcengine/main.go
Normal file
386
scripts/volcengine/main.go
Normal file
@@ -0,0 +1,386 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
"github.com/volcengine/volcengine-go-sdk/volcengine"
|
||||
"github.com/volcengine/volcengine-go-sdk/volcengine/credentials"
|
||||
"github.com/volcengine/volcengine-go-sdk/volcengine/session"
|
||||
)
|
||||
|
||||
var (
|
||||
ak string
|
||||
sk string
|
||||
region string
|
||||
sess *session.Session
|
||||
projectName string
|
||||
vpcName string
|
||||
)
|
||||
|
||||
const (
|
||||
password = "Opencoze123"
|
||||
)
|
||||
|
||||
// MySQL
|
||||
var (
|
||||
mysqlDBName string
|
||||
mysqlUserName string
|
||||
mysqlUserPassword string
|
||||
mysqlPort string
|
||||
mysqlDBEngineVersion string
|
||||
mysqlInstanceClass string
|
||||
)
|
||||
|
||||
const retryTime = 10 * time.Second
|
||||
|
||||
func main() {
|
||||
if err := loadEnv(); err != nil {
|
||||
panic("loadEnv failed, err=" + err.Error())
|
||||
}
|
||||
|
||||
if err := initServer(); err != nil {
|
||||
panic("initServer failed, err=" + err.Error())
|
||||
}
|
||||
ts := time.Now().Format("0102-150405")
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// ------------------------- Setup Network -------------------------
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
// 1. get zoneID
|
||||
zoneID, err := GetChosenZoneID()
|
||||
if err != nil {
|
||||
panic("[Zone] GetZoneID failed, err=" + err.Error())
|
||||
}
|
||||
fmt.Println("[Zone] Chosen ZoneID:", zoneID)
|
||||
updateEnvVarInFile("VE_ZONE_ID", zoneID)
|
||||
|
||||
// 2.1 create vpc
|
||||
vpcID, err := CreatePrivateNetwork(vpcName, ts, zoneID)
|
||||
if err != nil {
|
||||
panic("CreatePrivateNetwork failed, err=" + err.Error())
|
||||
}
|
||||
fmt.Println("[VPC] Created successfully vpcID:", vpcID)
|
||||
updateEnvVarInFile("VE_VPC_ID", vpcID)
|
||||
|
||||
CheckVpcStatus(vpcID)
|
||||
|
||||
// 2.2 create subnet
|
||||
subnetID, err := CreateSubnet(vpcName, ts, vpcID, zoneID)
|
||||
if err != nil {
|
||||
panic("CreateSubnet failed, err=" + err.Error())
|
||||
}
|
||||
fmt.Println("[Subnet] Created successfully subnetID:", subnetID)
|
||||
updateEnvVarInFile("VE_SUBNET_ID", subnetID)
|
||||
|
||||
CheckVpcStatus(vpcID)
|
||||
|
||||
// 2.3 create network acl
|
||||
aclID, err := CreateNetworkACL(vpcName, ts, vpcID)
|
||||
if err != nil {
|
||||
panic("CreateNetworkACL failed, err=" + err.Error())
|
||||
}
|
||||
fmt.Println("[ACL] Created successfully aclID:", aclID)
|
||||
updateEnvVarInFile("VE_ACL_ID", aclID)
|
||||
|
||||
CheckACLStatus(aclID)
|
||||
|
||||
// 2.4 attach subnet to acl
|
||||
if err = AttachSubnetToACL(aclID, subnetID); err != nil {
|
||||
panic("AttachSubnetToACL failed, err=" + err.Error())
|
||||
}
|
||||
fmt.Println("[ACL] Attached successfully subnetID:", subnetID)
|
||||
|
||||
// 2.5 create safe group
|
||||
sgID, err := CreateSafeGroup(ts, vpcID)
|
||||
if err != nil {
|
||||
panic("CreateSafeGroup failed, err=" + err.Error())
|
||||
}
|
||||
fmt.Println("[SafeGroup] Created successfully safe group ID:", sgID)
|
||||
updateEnvVarInFile("VE_SAFE_GROUP_ID", sgID)
|
||||
|
||||
CheckSafeGroupStatus(sgID)
|
||||
|
||||
// 2.6 create rule
|
||||
if err = CreateSafeGroupRule(sgID); err != nil {
|
||||
panic("CreateSafeGroupRule failed, err=" + err.Error())
|
||||
}
|
||||
fmt.Println("[SafeGroup] Created safe group rule successfully")
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// ----------------- Create All Instances First---------------------
|
||||
// -----------------------------------------------------------------
|
||||
// 3.1 create mysql instance
|
||||
mysqlInstanceID, err := CreateMySQLInstance(vpcID, subnetID, zoneID, ts)
|
||||
if err != nil {
|
||||
panic("CreateMySQLInstance failed, err=" + err.Error())
|
||||
}
|
||||
fmt.Println("[MySQL] Created mysqlInstanceID:", mysqlInstanceID)
|
||||
updateEnvVarInFile("VE_MYSQL_INSTANCE_ID", mysqlInstanceID)
|
||||
|
||||
// 4.1 create redis white list
|
||||
allowListID, err := CreateRedisAllowList(ts)
|
||||
if err != nil {
|
||||
panic("CreateRedisAllowList failed, err=" + err.Error())
|
||||
}
|
||||
fmt.Printf("[Redis] Created successfully AllowListID : %s\n", allowListID)
|
||||
updateEnvVarInFile("VE_REDIS_ALLOWLIST_ID", allowListID)
|
||||
|
||||
// 4.2 create redis instance with allow list id
|
||||
redisInstanceID, err := CreateRedisInstance(zoneID, allowListID, vpcID, subnetID, ts)
|
||||
if err != nil {
|
||||
panic("CreateRedisInstance failed, err=" + err.Error())
|
||||
}
|
||||
fmt.Printf("[Redis] Created successfully RedisInstanceID : %s\n", redisInstanceID)
|
||||
updateEnvVarInFile("VE_REDIS_INSTANCE_ID", redisInstanceID)
|
||||
|
||||
// 5.1 create rocketmq allow list
|
||||
rmqAllowListID, err := CreateRocketMQAllowList(ts)
|
||||
if err != nil {
|
||||
panic("CreateRocketMQAllowList failed, err=" + err.Error())
|
||||
}
|
||||
fmt.Printf("[RocketMQ] Created successfully AllowListID : %s\n", rmqAllowListID)
|
||||
updateEnvVarInFile("VE_ROCKETMQ_ALLOWLIST_ID", rmqAllowListID)
|
||||
|
||||
// 6.1 create elasticsearch instance
|
||||
esInstanceID, err := CreateESInstance(vpcID, subnetID, zoneID, ts)
|
||||
if err != nil {
|
||||
panic("CreateESInstance failed, err=" + err.Error())
|
||||
}
|
||||
fmt.Printf("[Elasticsearch] Created successfully instanceID : %s\n", esInstanceID)
|
||||
updateEnvVarInFile("VE_ES_INSTANCE_ID", esInstanceID)
|
||||
|
||||
// ecsInstanceID, err := CreateECSInstance(zoneID, sgID, subnetID, ts)
|
||||
// if err != nil {
|
||||
// panic("CreateECSInstance failed, err=" + err.Error())
|
||||
// }
|
||||
// fmt.Printf("[ECS] Created successfully instanceID : %s\n", ecsInstanceID)
|
||||
// updateEnvVarInFile("VE_ECS_INSTANCE_ID", ecsInstanceID)
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// -------- Waiting for the instance to become available -----------
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
fmt.Println("-----------------------------------------------------------------")
|
||||
fmt.Println("Waiting for the instance to become available")
|
||||
// ----------------- MySQL -------------------
|
||||
// 3.2 get mysql connect host and port
|
||||
mysqlHost, mysqlPort, err := GetMySQLConnectAddress(mysqlInstanceID)
|
||||
if err != nil {
|
||||
panic("GetMySQLConnectAddress failed, err=" + err.Error())
|
||||
}
|
||||
fmt.Printf("[MySQL] MySQL connect address: %s:%s\n", mysqlHost, mysqlPort)
|
||||
|
||||
// 3.3 Create DB
|
||||
if err = CreateDB(mysqlInstanceID); err != nil {
|
||||
panic("CreateDB failed, err=" + err.Error())
|
||||
}
|
||||
fmt.Printf("[MySQL] Created successfully db : %s\n", mysqlDBName)
|
||||
|
||||
// 3.4 Create mysql whitelist
|
||||
whitelistID, err := CreateMySQLWhiteList(mysqlInstanceID, ts)
|
||||
if err != nil {
|
||||
panic("CreateMySQLWhiteList failed, err=" + err.Error())
|
||||
}
|
||||
fmt.Printf("[MySQL] Created successfully AllowListID : %s \n", whitelistID)
|
||||
updateEnvVarInFile("VE_MYSQL_WHITELIST_ID", whitelistID)
|
||||
|
||||
// 3.5 Associate whitelist to instance
|
||||
if err = AssociateMySQLWhiteList(mysqlInstanceID, whitelistID); err != nil {
|
||||
panic("AssociateMySQLWhiteList failed, err=" + err.Error())
|
||||
}
|
||||
fmt.Printf("[MySQL] Associated AllowListID(%s) to MySQLInstanceID(%s)\n", whitelistID, mysqlInstanceID)
|
||||
|
||||
// ----------------- Redis -------------------
|
||||
// 4.3 get redis connection string
|
||||
redisConn, err := GetRedisConnectionString(redisInstanceID)
|
||||
if err != nil {
|
||||
panic("GetRedisConnectionString failed, err=" + err.Error())
|
||||
}
|
||||
fmt.Printf("[Redis] Redis connection: %s\n", redisConn)
|
||||
|
||||
// ----------------- RocketMQ -------------------
|
||||
|
||||
// 5.2 create rocketmq instance
|
||||
rmqInstanceID, err := CreateRocketMQInstance(vpcID, subnetID, zoneID, ts, rmqAllowListID)
|
||||
if err != nil {
|
||||
panic("CreateRocketMQInstance failed, err=" + err.Error())
|
||||
}
|
||||
fmt.Printf("[RocketMQ] Created successfully instanceID : %s\n", rmqInstanceID)
|
||||
updateEnvVarInFile("VE_ROCKETMQ_INSTANCE_ID", rmqInstanceID)
|
||||
|
||||
// 5.3 get rocketmq connect address
|
||||
rmqConnectAddress, err := GetRocketMQConnectAddress(rmqInstanceID)
|
||||
if err != nil {
|
||||
panic("GetRocketMQConnectAddress failed, err=" + err.Error())
|
||||
}
|
||||
fmt.Printf("[RocketMQ] connect address: %s\n", rmqConnectAddress)
|
||||
|
||||
rmqAK, rmqSK, err := CreateRocketMQAccessKey(rmqInstanceID)
|
||||
if err != nil {
|
||||
panic("CreateRocketMQAccessKey failed, err=" + err.Error())
|
||||
}
|
||||
fmt.Printf("[RocketMQ] access key: %s, secret key: %s\n", rmqAK, rmqSK)
|
||||
|
||||
if err = CreateRocketMQTopic(rmqAK, rmqInstanceID); err != nil {
|
||||
panic("CreateRocketMQTopic failed, err=" + err.Error())
|
||||
}
|
||||
fmt.Printf("[RocketMQ] topic created successfully\n")
|
||||
|
||||
if err = CreateRocketMQGroup(rmqInstanceID); err != nil {
|
||||
panic("CreateRocketMQGroup failed, err=" + err.Error())
|
||||
}
|
||||
fmt.Printf("[RocketMQ] group created successfully\n")
|
||||
|
||||
// ----------------- Elasticsearch -------------------
|
||||
|
||||
// 5.2 get elasticsearch connect address
|
||||
esConnectAddress, err := GetESConnectAddress(esInstanceID)
|
||||
if err != nil {
|
||||
panic("GetESConnectAddress failed, err=" + err.Error())
|
||||
}
|
||||
fmt.Printf("[Elasticsearch] connect address: %s\n", esConnectAddress)
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// ------------------------ Output Env -----------------------------
|
||||
// -----------------------------------------------------------------
|
||||
fmt.Println("-----------------------------------------------------------------")
|
||||
fmt.Println("Output Env :")
|
||||
|
||||
fmt.Printf("# MySQL\n")
|
||||
fmt.Printf("export MYSQL_DATABASE=%s\n", mysqlDBName)
|
||||
fmt.Printf("export MYSQL_USER=%s\n", mysqlUserName)
|
||||
fmt.Printf("export MYSQL_PASSWORD=%s\n", mysqlUserPassword)
|
||||
fmt.Printf("export MYSQL_HOST=%s\n", mysqlHost)
|
||||
fmt.Printf("export MYSQL_PORT=%s\n", mysqlPort)
|
||||
fmt.Println("")
|
||||
|
||||
fmt.Printf("# Redis\n")
|
||||
fmt.Printf("export REDIS_AOF_ENABLED=no\n")
|
||||
fmt.Printf("export REDIS_IO_THREADS=4\n")
|
||||
fmt.Printf("export ALLOW_EMPTY_PASSWORD=yes\n")
|
||||
fmt.Printf("export REDIS_ADDR=%s\n", redisConn)
|
||||
fmt.Println("")
|
||||
|
||||
fmt.Printf("# Elasticsearch\n")
|
||||
fmt.Printf("export ES_VERSION=v7\n")
|
||||
fmt.Printf("export ES_ADDR=%s\n", esConnectAddress)
|
||||
fmt.Printf("export ES_USERNAME=admin\n")
|
||||
fmt.Printf("export ES_PASSWORD=%s\n", password)
|
||||
fmt.Println("")
|
||||
|
||||
fmt.Printf("# RocketMQ\n")
|
||||
fmt.Printf("export RMQ_NAME_SERVER=%s\n", rmqConnectAddress)
|
||||
fmt.Printf("export RMQ_ACCESS_KEY=%s\n", rmqAK)
|
||||
fmt.Printf("export RMQ_SECRET_KEY=%s\n", rmqSK)
|
||||
fmt.Println("")
|
||||
}
|
||||
|
||||
func initServer() error {
|
||||
config := volcengine.NewConfig().WithRegion(region).
|
||||
WithCredentials(credentials.NewStaticCredentials(ak, sk, ""))
|
||||
|
||||
var err error
|
||||
sess, err = session.NewSession(config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func loadEnv() error {
|
||||
err := godotenv.Load()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ak = os.Getenv("VE_AK")
|
||||
sk = os.Getenv("VE_SK")
|
||||
region = os.Getenv("VE_REGION")
|
||||
projectName = os.Getenv("VE_PROJECT_NAME")
|
||||
vpcName = os.Getenv("VE_VPC_NAME")
|
||||
|
||||
// MySQL
|
||||
mysqlDBName = os.Getenv("VE_MYSQL_DB_NAME")
|
||||
mysqlUserName = os.Getenv("VE_MYSQL_USER_NAME")
|
||||
mysqlUserPassword = os.Getenv("VE_MYSQL_USER_PASSWORD")
|
||||
mysqlPort = os.Getenv("VE_MYSQL_PORT")
|
||||
mysqlDBEngineVersion = os.Getenv("VE_MYSQL_DB_ENGINE_VERSION")
|
||||
mysqlInstanceClass = os.Getenv("VE_MYSQL_INSTANCE_CLASS")
|
||||
|
||||
if ak == "" {
|
||||
return errors.New("VE_AK is empty")
|
||||
}
|
||||
|
||||
if sk == "" {
|
||||
return errors.New("VE_SK is empty")
|
||||
}
|
||||
|
||||
if region == "" {
|
||||
return errors.New("VE_REGION is empty")
|
||||
}
|
||||
|
||||
if projectName == "" {
|
||||
return errors.New("VE_PROJECT_NAME is empty")
|
||||
}
|
||||
|
||||
if vpcName == "" {
|
||||
return errors.New("VE_VPC_NAME is empty")
|
||||
}
|
||||
|
||||
// MySQL
|
||||
if mysqlDBName == "" {
|
||||
return errors.New("VE_MYSQL_INSTANCE_NAME is empty")
|
||||
}
|
||||
|
||||
if mysqlUserName == "" {
|
||||
return errors.New("VE_MYSQL_USER_NAME is empty")
|
||||
}
|
||||
|
||||
if mysqlUserPassword == "" {
|
||||
return errors.New("VE_MYSQL_USER_PASSWORD is empty")
|
||||
}
|
||||
|
||||
if mysqlPort == "" {
|
||||
return errors.New("VE_MYSQL_PORT is empty")
|
||||
}
|
||||
|
||||
if mysqlDBEngineVersion == "" {
|
||||
return errors.New("VE_MYSQL_DB_ENGINE_VERSION is empty")
|
||||
}
|
||||
|
||||
if mysqlInstanceClass == "" {
|
||||
return errors.New("VE_MYSQL_INSTANCE_CLASS is empty")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func s(p *string) string {
|
||||
if p == nil {
|
||||
return ""
|
||||
}
|
||||
return *p
|
||||
}
|
||||
174
scripts/volcengine/mysql.go
Normal file
174
scripts/volcengine/mysql.go
Normal file
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/volcengine/volcengine-go-sdk/service/vedbm"
|
||||
"github.com/volcengine/volcengine-go-sdk/volcengine"
|
||||
)
|
||||
|
||||
func CreateMySQLInstance(vpcID, subnetID, zoneID, ts string) (string, error) {
|
||||
if os.Getenv("VE_MYSQL_INSTANCE_ID") != "" {
|
||||
return os.Getenv("VE_MYSQL_INSTANCE_ID"), nil
|
||||
}
|
||||
svc := vedbm.New(sess)
|
||||
reqTags := &vedbm.TagForCreateDBInstanceInput{
|
||||
Key: volcengine.String("opencoze"),
|
||||
Value: volcengine.String("1"),
|
||||
}
|
||||
|
||||
createDBInstanceInput := &vedbm.CreateDBInstanceInput{
|
||||
ChargeType: volcengine.String("PostPaid"),
|
||||
DBEngineVersion: volcengine.String(mysqlDBEngineVersion),
|
||||
DBTimeZone: volcengine.String("UTC +08:00"),
|
||||
InstanceName: volcengine.String(mysqlDBName + "-" + ts),
|
||||
LowerCaseTableNames: volcengine.String("1"),
|
||||
NodeNumber: volcengine.Int32(2),
|
||||
NodeSpec: volcengine.String(mysqlInstanceClass),
|
||||
Number: volcengine.Int32(1),
|
||||
ProjectName: volcengine.String(projectName),
|
||||
StorageChargeType: volcengine.String("PostPaid"),
|
||||
SubnetId: volcengine.String(subnetID),
|
||||
SuperAccountName: volcengine.String(mysqlUserName),
|
||||
SuperAccountPassword: volcengine.String(mysqlUserPassword),
|
||||
Tags: []*vedbm.TagForCreateDBInstanceInput{reqTags},
|
||||
VpcId: volcengine.String(vpcID),
|
||||
ZoneIds: volcengine.String(zoneID),
|
||||
}
|
||||
|
||||
resp, err := svc.CreateDBInstance(createDBInstanceInput)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if resp.InstanceId == nil {
|
||||
return "", errors.New("CreateDBInstance resp.InstanceId is nil")
|
||||
}
|
||||
|
||||
return *resp.InstanceId, nil
|
||||
}
|
||||
|
||||
func GetMySQLConnectAddress(mysqlInstanceID string) (string, string, error) {
|
||||
svc := vedbm.New(sess)
|
||||
describeDBInstanceDetailInput := &vedbm.DescribeDBInstanceDetailInput{
|
||||
InstanceId: volcengine.String(mysqlInstanceID),
|
||||
}
|
||||
|
||||
for {
|
||||
resp, err := svc.DescribeDBInstanceDetail(describeDBInstanceDetailInput)
|
||||
if resp.InstanceDetail != nil && resp.InstanceDetail.InstanceStatus != nil && *resp.InstanceDetail.InstanceStatus != "Running" {
|
||||
fmt.Printf("[MySQL] instance(%s) is %s, waiting for it to become ready... \n", mysqlInstanceID, *resp.InstanceDetail.InstanceStatus)
|
||||
time.Sleep(retryTime)
|
||||
continue
|
||||
}
|
||||
|
||||
if resp.Metadata != nil && resp.Metadata.Error != nil &&
|
||||
resp.Metadata.Error.Code == "OperationDenied.UnsupportedOperation" {
|
||||
fmt.Printf("[MySQL] instance[%s] is creating, waiting for it to become ready... \n", mysqlInstanceID)
|
||||
time.Sleep(retryTime)
|
||||
continue
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("[MySQL] failed, err: %s \n", err)
|
||||
time.Sleep(retryTime)
|
||||
continue
|
||||
}
|
||||
|
||||
if len(resp.Endpoints) == 0 {
|
||||
fmt.Printf("[MySQL] endpoints is empty, will try it later \n")
|
||||
time.Sleep(retryTime)
|
||||
continue
|
||||
}
|
||||
|
||||
if len(resp.Endpoints[0].Addresses) == 0 {
|
||||
fmt.Printf("[MySQL] endpoints[0].Addresses is nil, will try it later \n")
|
||||
time.Sleep(retryTime)
|
||||
continue
|
||||
}
|
||||
|
||||
if resp.Endpoints[0].Addresses[0].Domain == nil || resp.Endpoints[0].Addresses[0].Port == nil {
|
||||
fmt.Printf("[MySQL] endpoints[0].Addresses[0].Domain or endpoints[0].Addresses[0].Port is nil, will try it later \n")
|
||||
time.Sleep(retryTime)
|
||||
continue
|
||||
}
|
||||
|
||||
return *resp.Endpoints[0].Addresses[0].Domain, *resp.Endpoints[0].Addresses[0].Port, nil
|
||||
}
|
||||
}
|
||||
|
||||
func CreateDB(mysqlInstanceID string) error {
|
||||
svc := vedbm.New(sess)
|
||||
createDatabaseInput := &vedbm.CreateDatabaseInput{
|
||||
CharacterSetName: volcengine.String("utf8mb4"),
|
||||
DBName: volcengine.String(mysqlDBName),
|
||||
InstanceId: volcengine.String(mysqlInstanceID),
|
||||
}
|
||||
|
||||
resp, err := svc.CreateDatabase(createDatabaseInput)
|
||||
if resp.Metadata != nil && resp.Metadata.Error != nil &&
|
||||
resp.Metadata.Error.Code == "InvalidDatabaseName.Duplicate" {
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("[MySQL] CreateDB failed, err: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func CreateMySQLWhiteList(mysqlInstanceID, ts string) (string, error) {
|
||||
svc := vedbm.New(sess)
|
||||
createAllowListInput := &vedbm.CreateAllowListInput{
|
||||
AllowList: volcengine.String("172.16.0.0/12"),
|
||||
AllowListName: volcengine.String("opencoze-mysql-" + ts),
|
||||
ProjectName: volcengine.String(projectName),
|
||||
}
|
||||
|
||||
// 复制代码运行示例,请自行打印API返回值。
|
||||
resp, err := svc.CreateAllowList(createAllowListInput)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if resp.AllowListId == nil {
|
||||
return "", errors.New("[MySQL] CreateAllowList resp.AllowListId is nil")
|
||||
}
|
||||
|
||||
return *resp.AllowListId, nil
|
||||
}
|
||||
|
||||
func AssociateMySQLWhiteList(mysqlInstanceID, whitelistID string) error {
|
||||
svc := vedbm.New(sess)
|
||||
associateAllowListInput := &vedbm.AssociateAllowListInput{
|
||||
AllowListIds: volcengine.StringSlice([]string{whitelistID}),
|
||||
InstanceIds: volcengine.StringSlice([]string{mysqlInstanceID}),
|
||||
}
|
||||
|
||||
// 复制代码运行示例,请自行打印API返回值。
|
||||
_, err := svc.AssociateAllowList(associateAllowListInput)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
339
scripts/volcengine/network.go
Normal file
339
scripts/volcengine/network.go
Normal file
@@ -0,0 +1,339 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/volcengine/volcengine-go-sdk/service/vpc"
|
||||
"github.com/volcengine/volcengine-go-sdk/volcengine"
|
||||
)
|
||||
|
||||
func CreatePrivateNetwork(vName, ts, zoneID string) (string, error) {
|
||||
if os.Getenv("VE_VPC_ID") != "" {
|
||||
return os.Getenv("VE_VPC_ID"), nil
|
||||
}
|
||||
|
||||
svc := vpc.New(sess)
|
||||
|
||||
reqTags := &vpc.TagForCreateVpcInput{
|
||||
Key: volcengine.String("opencoze"),
|
||||
Value: volcengine.String("1"),
|
||||
}
|
||||
|
||||
newVpcName := vName + ts
|
||||
createVpcInput := &vpc.CreateVpcInput{
|
||||
CidrBlock: volcengine.String("172.16.0.0/12"),
|
||||
ClientToken: volcengine.String(newVpcName),
|
||||
ProjectName: volcengine.String(projectName),
|
||||
Tags: []*vpc.TagForCreateVpcInput{reqTags},
|
||||
VpcName: volcengine.String(newVpcName),
|
||||
}
|
||||
|
||||
resp, err := svc.CreateVpc(createVpcInput)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if resp.VpcId == nil {
|
||||
return "", errors.New("[VPC] VpcId is empty")
|
||||
}
|
||||
|
||||
return *resp.VpcId, nil
|
||||
}
|
||||
|
||||
func CheckVpcStatus(vpcID string) {
|
||||
svc := vpc.New(sess)
|
||||
|
||||
describeVpcAttributesInput := &vpc.DescribeVpcAttributesInput{
|
||||
VpcId: volcengine.String(vpcID),
|
||||
}
|
||||
|
||||
for {
|
||||
resp, err := svc.DescribeVpcAttributes(describeVpcAttributesInput)
|
||||
if resp.Status != nil && *resp.Status != "Available" {
|
||||
fmt.Printf("[VPC] VPC(%s) is %s, waiting for it to become ready... \n", vpcID, *resp.Status)
|
||||
time.Sleep(retryTime)
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
fmt.Printf("[VPC] get vpc id = %s failed, err= %s will retry\n", vpcID, err.Error())
|
||||
time.Sleep(retryTime)
|
||||
continue
|
||||
}
|
||||
|
||||
if resp.Status == nil {
|
||||
fmt.Printf("[VPC] get vpc id = %s failed, status is nil will retry\n", vpcID)
|
||||
time.Sleep(retryTime)
|
||||
continue
|
||||
}
|
||||
|
||||
if *resp.Status == "Available" {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func CreateSubnet(vName, ts, vpcID, zoneID string) (string, error) {
|
||||
if os.Getenv("VE_SUBNET_ID") != "" {
|
||||
return os.Getenv("VE_SUBNET_ID"), nil
|
||||
}
|
||||
|
||||
reqSubTags := &vpc.TagForCreateSubnetInput{
|
||||
Key: volcengine.String("opencoze"),
|
||||
Value: volcengine.String("1"),
|
||||
}
|
||||
|
||||
newSubnetName := vName + "-subnet-" + ts
|
||||
createSubnetInput := &vpc.CreateSubnetInput{
|
||||
CidrBlock: volcengine.String("172.16.0.0/24"),
|
||||
ClientToken: volcengine.String(newSubnetName),
|
||||
SubnetName: volcengine.String(newSubnetName),
|
||||
Tags: []*vpc.TagForCreateSubnetInput{reqSubTags},
|
||||
VpcId: volcengine.String(vpcID),
|
||||
ZoneId: volcengine.String(zoneID),
|
||||
}
|
||||
|
||||
svc := vpc.New(sess)
|
||||
resp, err := svc.CreateSubnet(createSubnetInput)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if resp.SubnetId == nil {
|
||||
return "", errors.New("[Subnet] SubnetId is empty")
|
||||
}
|
||||
|
||||
return *resp.SubnetId, nil
|
||||
}
|
||||
|
||||
func CreateNetworkACL(vName, ts, vpcID string) (string, error) {
|
||||
if os.Getenv("VE_ACL_ID") != "" {
|
||||
return os.Getenv("VE_ACL_ID"), nil
|
||||
}
|
||||
|
||||
svc := vpc.New(sess)
|
||||
|
||||
reqTags := &vpc.TagForCreateNetworkAclInput{
|
||||
Key: volcengine.String("opencoze"),
|
||||
Value: volcengine.String("1"),
|
||||
}
|
||||
|
||||
newACLName := vName + "-acl-" + ts
|
||||
|
||||
createNetworkAclInput := &vpc.CreateNetworkAclInput{
|
||||
NetworkAclName: volcengine.String(newACLName),
|
||||
ProjectName: volcengine.String(projectName),
|
||||
Tags: []*vpc.TagForCreateNetworkAclInput{reqTags},
|
||||
VpcId: volcengine.String(vpcID),
|
||||
}
|
||||
|
||||
resp, err := svc.CreateNetworkAcl(createNetworkAclInput)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if resp.NetworkAclId == nil {
|
||||
return "", errors.New("NetworkAclId is empty")
|
||||
}
|
||||
|
||||
return *resp.NetworkAclId, nil
|
||||
}
|
||||
|
||||
func CheckACLStatus(aclID string) {
|
||||
svc := vpc.New(sess)
|
||||
|
||||
describeNetworkAclAttributesInput := &vpc.DescribeNetworkAclAttributesInput{
|
||||
NetworkAclId: volcengine.String(aclID),
|
||||
}
|
||||
|
||||
for {
|
||||
resp, err := svc.DescribeNetworkAclAttributes(describeNetworkAclAttributesInput)
|
||||
if resp.NetworkAclAttribute != nil && resp.NetworkAclAttribute.Status != nil && *resp.NetworkAclAttribute.Status != "Available" {
|
||||
fmt.Printf("[ACL] ACL(%s) is %s, waiting for it to become ready... \n", aclID, *resp.NetworkAclAttribute.Status)
|
||||
time.Sleep(retryTime)
|
||||
continue
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("[ACL] will retry get acl = %s failed, err= %s\n", aclID, err.Error())
|
||||
time.Sleep(retryTime)
|
||||
continue
|
||||
}
|
||||
|
||||
if resp.NetworkAclAttribute == nil || resp.NetworkAclAttribute.Status == nil {
|
||||
fmt.Printf("[ACL] ACL(%s) Status is nil, will retry\n", aclID)
|
||||
time.Sleep(retryTime)
|
||||
continue
|
||||
}
|
||||
|
||||
if *resp.NetworkAclAttribute.Status == "Available" {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func AttachSubnetToACL(aclID, subnetID string) error {
|
||||
svc := vpc.New(sess)
|
||||
|
||||
reqResource := &vpc.ResourceForAssociateNetworkAclInput{
|
||||
ResourceId: volcengine.String(subnetID),
|
||||
}
|
||||
associateNetworkAclInput := &vpc.AssociateNetworkAclInput{
|
||||
NetworkAclId: volcengine.String(aclID),
|
||||
Resource: []*vpc.ResourceForAssociateNetworkAclInput{reqResource},
|
||||
}
|
||||
|
||||
resp, err := svc.AssociateNetworkAcl(associateNetworkAclInput)
|
||||
if resp.Metadata != nil && resp.Metadata.Error != nil &&
|
||||
resp.Metadata.Error.Code == "InvalidResource.Associated" {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func CreateSafeGroup(ts, vpcID string) (string, error) {
|
||||
if os.Getenv("VE_SAFE_GROUP_ID") != "" {
|
||||
return os.Getenv("VE_SAFE_GROUP_ID"), nil
|
||||
}
|
||||
|
||||
svc := vpc.New(sess)
|
||||
reqTags := &vpc.TagForCreateSecurityGroupInput{
|
||||
Key: volcengine.String("opencoze"),
|
||||
Value: volcengine.String("1"),
|
||||
}
|
||||
createSecurityGroupInput := &vpc.CreateSecurityGroupInput{
|
||||
ProjectName: volcengine.String(projectName),
|
||||
SecurityGroupName: volcengine.String("opencoze-sg-" + ts),
|
||||
Tags: []*vpc.TagForCreateSecurityGroupInput{reqTags},
|
||||
VpcId: volcengine.String(vpcID),
|
||||
}
|
||||
|
||||
resp, err := svc.CreateSecurityGroup(createSecurityGroupInput)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if resp.SecurityGroupId == nil {
|
||||
return "", errors.New("SecurityGroupId is empty")
|
||||
}
|
||||
|
||||
return *resp.SecurityGroupId, nil
|
||||
}
|
||||
|
||||
func CheckSafeGroupStatus(sgID string) {
|
||||
for {
|
||||
svc := vpc.New(sess)
|
||||
describeSecurityGroupAttributesInput := &vpc.DescribeSecurityGroupAttributesInput{
|
||||
SecurityGroupId: volcengine.String(sgID),
|
||||
}
|
||||
|
||||
// 复制代码运行示例,请自行打印API返回值。
|
||||
resp, err := svc.DescribeSecurityGroupAttributes(describeSecurityGroupAttributesInput)
|
||||
if err != nil {
|
||||
fmt.Printf("[SafeGroup] will retry get safe group = %s failed, err= %s\n", sgID, err.Error())
|
||||
time.Sleep(retryTime)
|
||||
continue
|
||||
}
|
||||
|
||||
if resp.Status == nil || *resp.Status != "Available" {
|
||||
fmt.Printf("[SafeGroup] safe group(%s) is %s, waiting for it to become ready... \n", sgID, *resp.Status)
|
||||
time.Sleep(retryTime)
|
||||
continue
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
func CreateSafeGroupRule(sgID string) error {
|
||||
svc := vpc.New(sess)
|
||||
|
||||
type Rule struct {
|
||||
PortStart int64
|
||||
PortEnd int64
|
||||
Protocol string
|
||||
}
|
||||
|
||||
defaultRules := []Rule{
|
||||
{
|
||||
PortStart: 8000,
|
||||
PortEnd: 10000,
|
||||
Protocol: "tcp",
|
||||
},
|
||||
{
|
||||
PortStart: 80,
|
||||
PortEnd: 80,
|
||||
Protocol: "tcp",
|
||||
},
|
||||
{
|
||||
PortStart: 22,
|
||||
PortEnd: 22,
|
||||
Protocol: "tcp",
|
||||
},
|
||||
{
|
||||
PortStart: 443,
|
||||
PortEnd: 443,
|
||||
Protocol: "tcp",
|
||||
},
|
||||
{
|
||||
PortStart: 3389,
|
||||
PortEnd: 3389,
|
||||
Protocol: "tcp",
|
||||
},
|
||||
|
||||
{
|
||||
PortStart: -1,
|
||||
PortEnd: -1,
|
||||
Protocol: "ALL",
|
||||
},
|
||||
}
|
||||
|
||||
for _, rule := range defaultRules {
|
||||
authorizeSecurityGroupIngressInput := &vpc.AuthorizeSecurityGroupIngressInput{
|
||||
CidrIp: volcengine.String("0.0.0.0/0"),
|
||||
PortEnd: volcengine.Int64(rule.PortEnd),
|
||||
PortStart: volcengine.Int64(rule.PortStart),
|
||||
Protocol: volcengine.String(rule.Protocol),
|
||||
SecurityGroupId: volcengine.String(sgID),
|
||||
}
|
||||
|
||||
if rule.PortStart == -1 {
|
||||
authorizeSecurityGroupIngressInput.SourceGroupId = &sgID
|
||||
authorizeSecurityGroupIngressInput.CidrIp = nil
|
||||
}
|
||||
|
||||
resp, err := svc.AuthorizeSecurityGroupIngress(authorizeSecurityGroupIngressInput)
|
||||
if resp != nil && resp.Metadata != nil && resp.Metadata.Error != nil &&
|
||||
resp.Metadata.Error.Code == "InvalidSecurityRule.Conflict" {
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
133
scripts/volcengine/redis.go
Normal file
133
scripts/volcengine/redis.go
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/volcengine/volcengine-go-sdk/service/redis"
|
||||
"github.com/volcengine/volcengine-go-sdk/volcengine"
|
||||
)
|
||||
|
||||
func CreateRedisAllowList(ts string) (string, error) {
|
||||
svc := redis.New(sess)
|
||||
|
||||
name := "opencoze-redis" + ts
|
||||
createAllowListInput := &redis.CreateAllowListInput{
|
||||
AllowList: volcengine.String("172.16.0.0/12"),
|
||||
AllowListName: volcengine.String(name),
|
||||
ProjectName: volcengine.String(projectName),
|
||||
}
|
||||
|
||||
resp, err := svc.CreateAllowList(createAllowListInput)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if resp.AllowListId == nil {
|
||||
return "", errors.New("CreateAllowList resp.AllowListId is nil")
|
||||
}
|
||||
|
||||
return *resp.AllowListId, nil
|
||||
}
|
||||
|
||||
func CreateRedisInstance(zoneID, allowListID, vpcID, subnetID, ts string) (string, error) {
|
||||
instanceID := os.Getenv("VE_REDIS_INSTANCE_ID")
|
||||
if instanceID != "" {
|
||||
return instanceID, nil
|
||||
}
|
||||
|
||||
svc := redis.New(sess)
|
||||
reqConfigureNodes := &redis.ConfigureNodeForCreateDBInstanceInput{
|
||||
AZ: volcengine.String(zoneID),
|
||||
}
|
||||
|
||||
reqTags := &redis.TagForCreateDBInstanceInput{
|
||||
Key: volcengine.String("opencoze"),
|
||||
Value: volcengine.String("1"),
|
||||
}
|
||||
|
||||
name := "opencoze-redis-" + ts
|
||||
createDBInstanceInput := &redis.CreateDBInstanceInput{
|
||||
AllowListIds: volcengine.StringSlice([]string{allowListID}),
|
||||
ChargeType: volcengine.String("PostPaid"),
|
||||
NoAuthMode: volcengine.String("open"),
|
||||
ConfigureNodes: []*redis.ConfigureNodeForCreateDBInstanceInput{reqConfigureNodes},
|
||||
EngineVersion: volcengine.String("7.0"),
|
||||
InstanceName: volcengine.String(name),
|
||||
MultiAZ: volcengine.String("disabled"),
|
||||
NodeNumber: volcengine.Int32(2),
|
||||
ProjectName: volcengine.String(projectName),
|
||||
RegionId: volcengine.String(region),
|
||||
ShardCapacity: volcengine.Int64(256),
|
||||
ShardNumber: volcengine.Int32(1),
|
||||
ShardedCluster: volcengine.Int32(0),
|
||||
SubnetId: volcengine.String(subnetID),
|
||||
Tags: []*redis.TagForCreateDBInstanceInput{reqTags},
|
||||
VpcId: volcengine.String(vpcID),
|
||||
}
|
||||
|
||||
resp, err := svc.CreateDBInstance(createDBInstanceInput)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if resp.InstanceId == nil {
|
||||
return "", errors.New("[Redis] CreateDBInstance resp.InstanceId is nil")
|
||||
}
|
||||
|
||||
return *resp.InstanceId, nil
|
||||
}
|
||||
|
||||
func GetRedisConnectionString(instanceID string) (string, error) {
|
||||
svc := redis.New(sess)
|
||||
describeDBInstanceDetailInput := &redis.DescribeDBInstanceDetailInput{
|
||||
InstanceId: volcengine.String(instanceID),
|
||||
}
|
||||
|
||||
for {
|
||||
resp, err := svc.DescribeDBInstanceDetail(describeDBInstanceDetailInput)
|
||||
if err != nil {
|
||||
fmt.Printf("[Redis] failed, err: %s \n", err)
|
||||
time.Sleep(retryTime)
|
||||
continue
|
||||
}
|
||||
|
||||
if resp.Status == nil || *resp.Status != "Running" {
|
||||
fmt.Printf("[Redis] instance(%s) is %s, waiting for it to become ready... \n", instanceID, *resp.Status)
|
||||
time.Sleep(retryTime)
|
||||
continue
|
||||
}
|
||||
|
||||
if len(resp.VisitAddrs) == 0 {
|
||||
fmt.Printf("[Redis] instance(%s) is creating, waiting for it to become ready... \n", instanceID)
|
||||
time.Sleep(retryTime)
|
||||
continue
|
||||
}
|
||||
|
||||
if resp.VisitAddrs[0].Address == nil || resp.VisitAddrs[0].Port == nil {
|
||||
fmt.Printf("[Redis] VisitAddrs[0].Address or VisitAddrs[0].Port is nil, will try it later \n")
|
||||
time.Sleep(retryTime)
|
||||
continue
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s:%s", *resp.VisitAddrs[0].Address, *resp.VisitAddrs[0].Port), nil
|
||||
}
|
||||
}
|
||||
307
scripts/volcengine/rocketmq.go
Normal file
307
scripts/volcengine/rocketmq.go
Normal file
@@ -0,0 +1,307 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/volcengine/volcengine-go-sdk/service/rocketmq"
|
||||
"github.com/volcengine/volcengine-go-sdk/volcengine"
|
||||
)
|
||||
|
||||
func CreateRocketMQAllowList(ts string) (string, error) {
|
||||
if os.Getenv("VE_ROCKETMQ_ALLOWLIST_ID") != "" {
|
||||
return os.Getenv("VE_ROCKETMQ_ALLOWLIST_ID"), nil
|
||||
}
|
||||
svc := rocketmq.New(sess)
|
||||
name := fmt.Sprintf("opencoze-rmq-%s", ts)
|
||||
createAllowListInput := &rocketmq.CreateAllowListInput{
|
||||
AllowList: volcengine.String("172.16.0.0/12"),
|
||||
AllowListName: volcengine.String(name),
|
||||
AllowListType: volcengine.String("IPv4"),
|
||||
}
|
||||
|
||||
resp, err := svc.CreateAllowList(createAllowListInput)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if resp.AllowListId == nil {
|
||||
return "", errors.New("CreateAllowList resp.AllowListId is nil")
|
||||
}
|
||||
|
||||
return *resp.AllowListId, nil
|
||||
}
|
||||
|
||||
func CreateRocketMQInstance(vpcID, subnetID, zoneID, ts, allowListID string) (string, error) {
|
||||
if os.Getenv("VE_ROCKETMQ_INSTANCE_ID") != "" {
|
||||
return os.Getenv("VE_ROCKETMQ_INSTANCE_ID"), nil
|
||||
}
|
||||
svc := rocketmq.New(sess)
|
||||
reqBindTags := &rocketmq.BindTagForCreateInstanceInput{
|
||||
Key: volcengine.String("opencoze"),
|
||||
Value: volcengine.String("1"),
|
||||
}
|
||||
reqChargeInfo := &rocketmq.ChargeInfoForCreateInstanceInput{
|
||||
ChargeType: volcengine.String("PostPaid"),
|
||||
}
|
||||
createInstanceInput := &rocketmq.CreateInstanceInput{
|
||||
AllowListIds: volcengine.StringSlice([]string{allowListID}),
|
||||
BindTags: []*rocketmq.BindTagForCreateInstanceInput{reqBindTags},
|
||||
ChargeInfo: reqChargeInfo,
|
||||
ComputeSpec: volcengine.String("rocketmq.n1.x2.micro"),
|
||||
FileReservedTime: volcengine.Int32(72),
|
||||
IPVersionType: volcengine.String("IPv4"),
|
||||
InstanceName: volcengine.String(fmt.Sprintf("opencoze-rmq-%s", ts)),
|
||||
NetworkTypes: volcengine.String("PrivateNetwork"),
|
||||
ProjectName: volcengine.String(projectName),
|
||||
StorageSpace: volcengine.Int32(300),
|
||||
SubnetId: volcengine.String(subnetID),
|
||||
Version: volcengine.String("4.8"),
|
||||
VpcId: volcengine.String(vpcID),
|
||||
ZoneId: volcengine.String(zoneID),
|
||||
}
|
||||
|
||||
resp, err := svc.CreateInstance(createInstanceInput)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if resp.InstanceId == nil {
|
||||
return "", errors.New("[RocketMQ] CreateInstance resp.InstanceId is nil")
|
||||
}
|
||||
|
||||
return *resp.InstanceId, nil
|
||||
}
|
||||
|
||||
func GetRocketMQConnectAddress(instanceID string) (string, error) {
|
||||
svc := rocketmq.New(sess)
|
||||
describeInstanceDetailInput := &rocketmq.DescribeInstanceDetailInput{
|
||||
InstanceId: volcengine.String(instanceID),
|
||||
}
|
||||
|
||||
for {
|
||||
resp, err := svc.DescribeInstanceDetail(describeInstanceDetailInput)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if resp.BasicInfo == nil || resp.BasicInfo.InstanceStatus == nil || *resp.BasicInfo.InstanceStatus != "Running" {
|
||||
fmt.Printf("[RocketMQ] instance(%s) is %s, waiting for it to become ready... \n", instanceID, *resp.BasicInfo.InstanceStatus)
|
||||
time.Sleep(retryTime)
|
||||
continue
|
||||
}
|
||||
|
||||
if len(resp.ConnectionInfo) == 0 || resp.ConnectionInfo[0].InternalEndpoint == nil {
|
||||
fmt.Println("[RocketMQ] DescribeInstanceDetail resp.ConnectionInfo is empty, will retry")
|
||||
time.Sleep(retryTime)
|
||||
continue
|
||||
}
|
||||
|
||||
if *resp.ConnectionInfo[0].InternalEndpoint == "" {
|
||||
fmt.Printf("[RocketMQ] instance(%s) is creating, waiting for it to become ready... \n", instanceID)
|
||||
time.Sleep(retryTime)
|
||||
continue
|
||||
}
|
||||
|
||||
return *resp.ConnectionInfo[0].InternalEndpoint, nil
|
||||
}
|
||||
}
|
||||
|
||||
func getRocketMQAccessKey(instanceID string) (string, error) {
|
||||
describeAccessKeysInput := &rocketmq.DescribeAccessKeysInput{
|
||||
InstanceId: volcengine.String(instanceID),
|
||||
PageNumber: volcengine.Int32(1),
|
||||
PageSize: volcengine.Int32(100),
|
||||
}
|
||||
|
||||
svc := rocketmq.New(sess)
|
||||
resp, err := svc.DescribeAccessKeys(describeAccessKeysInput)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
ak := ""
|
||||
for _, info := range resp.AccessKeysInfo {
|
||||
if info.AccessKey == nil || info.AllAuthority == nil {
|
||||
continue
|
||||
}
|
||||
if *info.AllAuthority == "ALL" {
|
||||
return *info.AccessKey, nil
|
||||
}
|
||||
ak = *info.AccessKey
|
||||
}
|
||||
|
||||
return ak, nil
|
||||
}
|
||||
|
||||
func CreateRocketMQAccessKey(instanceID string) (string, string, error) {
|
||||
ak, err := getRocketMQAccessKey(instanceID)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
svc := rocketmq.New(sess)
|
||||
if ak == "" {
|
||||
createAccessKeyInput := &rocketmq.CreateAccessKeyInput{
|
||||
AllAuthority: volcengine.String("ALL"),
|
||||
InstanceId: volcengine.String(instanceID),
|
||||
}
|
||||
|
||||
// 复制代码运行示例,请自行打印API返回值。
|
||||
_, err = svc.CreateAccessKey(createAccessKeyInput)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
ak, err = getRocketMQAccessKey(instanceID)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
}
|
||||
|
||||
if ak == "" {
|
||||
return "", "", errors.New("[RocketMQ] CreateRocketMQAccessKey ak is empty")
|
||||
}
|
||||
|
||||
describeSecretKeyInput := &rocketmq.DescribeSecretKeyInput{
|
||||
AccessKey: volcengine.String(ak),
|
||||
InstanceId: volcengine.String(instanceID),
|
||||
}
|
||||
|
||||
resp, err := svc.DescribeSecretKey(describeSecretKeyInput)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
if resp.SecretKey == nil {
|
||||
return "", "", errors.New("[RocketMQ] CreateRocketMQAccessKey resp.SecretKey is nil")
|
||||
}
|
||||
|
||||
return ak, *resp.SecretKey, nil
|
||||
}
|
||||
|
||||
func CreateRocketMQTopic(ak, instanceID string) error {
|
||||
svc := rocketmq.New(sess)
|
||||
describeTopicsInput := &rocketmq.DescribeTopicsInput{
|
||||
InstanceId: volcengine.String(instanceID),
|
||||
PageNumber: volcengine.Int32(1),
|
||||
PageSize: volcengine.Int32(100),
|
||||
}
|
||||
|
||||
topicNeedCreate := map[string]bool{
|
||||
"opencoze_search_resource": true,
|
||||
"opencoze_search_app": true,
|
||||
"opencoze_knowledge": true,
|
||||
}
|
||||
|
||||
resp, err := svc.DescribeTopics(describeTopicsInput)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, info := range resp.TopicsInfo {
|
||||
if info.TopicName == nil {
|
||||
continue
|
||||
}
|
||||
if topicNeedCreate[*info.TopicName] {
|
||||
topicNeedCreate[*info.TopicName] = false
|
||||
}
|
||||
}
|
||||
|
||||
reqAccessPolicies := &rocketmq.AccessPolicyForCreateTopicInput{
|
||||
AccessKey: volcengine.String(ak),
|
||||
Authority: volcengine.String("ALL"),
|
||||
}
|
||||
|
||||
for topicName, needCreate := range topicNeedCreate {
|
||||
if !needCreate {
|
||||
fmt.Printf("[RocketMQ] topic %s already exists, skip\n", topicName)
|
||||
continue
|
||||
}
|
||||
|
||||
createTopicInput := &rocketmq.CreateTopicInput{
|
||||
AccessPolicies: []*rocketmq.AccessPolicyForCreateTopicInput{reqAccessPolicies},
|
||||
InstanceId: volcengine.String(instanceID),
|
||||
MessageType: volcengine.Int32(0),
|
||||
QueueNumber: volcengine.Int32(2),
|
||||
TopicName: volcengine.String(topicName),
|
||||
}
|
||||
|
||||
// 复制代码运行示例,请自行打印API返回值。
|
||||
_, err = svc.CreateTopic(createTopicInput)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("[RocketMQ] topic %s created\n", topicName)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func CreateRocketMQGroup(instanceID string) error {
|
||||
groupNeedCreate := map[string]bool{
|
||||
"cg_search_resource": true,
|
||||
"cg_search_app": true,
|
||||
"cg_knowledge": true,
|
||||
}
|
||||
|
||||
svc := rocketmq.New(sess)
|
||||
describeGroupsInput := &rocketmq.DescribeGroupsInput{
|
||||
InstanceId: volcengine.String(instanceID),
|
||||
PageNumber: volcengine.Int32(1),
|
||||
PageSize: volcengine.Int32(100),
|
||||
}
|
||||
|
||||
resp, err := svc.DescribeGroups(describeGroupsInput)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, info := range resp.GroupsInfo {
|
||||
if info.GroupId == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if groupNeedCreate[*info.GroupId] {
|
||||
groupNeedCreate[*info.GroupId] = false
|
||||
}
|
||||
}
|
||||
|
||||
for groupName, needCreate := range groupNeedCreate {
|
||||
if !needCreate {
|
||||
fmt.Printf("[RocketMQ] group %s already exists, skip\n", groupName)
|
||||
continue
|
||||
}
|
||||
|
||||
createGroupInput := &rocketmq.CreateGroupInput{
|
||||
GroupId: volcengine.String(groupName),
|
||||
GroupType: volcengine.String("TCP"),
|
||||
InstanceId: volcengine.String(instanceID),
|
||||
}
|
||||
|
||||
_, err = svc.CreateGroup(createGroupInput)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
79
scripts/volcengine/zones.go
Normal file
79
scripts/volcengine/zones.go
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"text/tabwriter"
|
||||
|
||||
"github.com/volcengine/volcengine-go-sdk/service/rocketmq"
|
||||
)
|
||||
|
||||
func GetChosenZoneID() (string, error) {
|
||||
zoneID := os.Getenv("VE_ZONE_ID")
|
||||
if zoneID != "" {
|
||||
return zoneID, nil
|
||||
}
|
||||
|
||||
resp, err := listZoneInfos()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return chooseZone(resp), nil
|
||||
}
|
||||
|
||||
func chooseZone(resp *rocketmq.DescribeAvailabilityZonesOutput) string {
|
||||
fmt.Printf("Please choose a zone id in list: ")
|
||||
var zoneId string
|
||||
fmt.Scanln(&zoneId)
|
||||
|
||||
// zoneId := "cn-beijing-a"
|
||||
var found bool
|
||||
for _, zone := range resp.Zones {
|
||||
if zoneId == s(zone.ZoneId) {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
fmt.Printf("Zone id %s does not exist, please choose again\n", zoneId)
|
||||
return chooseZone(resp)
|
||||
}
|
||||
|
||||
return zoneId
|
||||
}
|
||||
|
||||
func listZoneInfos() (*rocketmq.DescribeAvailabilityZonesOutput, error) {
|
||||
svc := rocketmq.New(sess)
|
||||
|
||||
resp, err := svc.DescribeAvailabilityZones(&rocketmq.DescribeAvailabilityZonesInput{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fmt.Printf("AvailabilityZones:\n")
|
||||
w := tabwriter.NewWriter(os.Stdout, 0, 0, 4, ' ', 0)
|
||||
fmt.Fprintln(w, "Zone\tZoneID\tStatus\tDescription")
|
||||
for _, zone := range resp.Zones {
|
||||
fmt.Fprintf(w, "%s\t%s\t%s\t%s\n", s(zone.ZoneName), s(zone.ZoneId), s(zone.ZoneStatus), s(zone.Description))
|
||||
}
|
||||
w.Flush()
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
Reference in New Issue
Block a user