340 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			340 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			Go
		
	
	
	
| /*
 | |
|  * 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),
 | |
| 		}
 | |
| 
 | |
| 		// Copy the code to run the example, please print the API return value yourself.
 | |
| 		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
 | |
| }
 |