jenkins Job华为云EIP变更带宽

2023-12-26 07:04

本文主要是介绍jenkins Job华为云EIP变更带宽,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

引言:

在数字化时代,云服务资源的弹性管理是企业降低运营成本、提高效率的关键手段。通过弹性公网IP(EIP)服务,企业可以实现按需计费,优化网络支出。然而,根据业务流量的不同阶段调整计费模式,则是提升成本效益的进阶策略。本人腾讯云快十年老用户乘机吐槽一下腾讯云(由于我在大有所为的某云上面已经简单实现了更改流程):
习惯了使用apiexplorer这样的工具生成代码进行修改,参考一下友商的:
image.png
然后我的腾讯云弹性公网IP ?EIP 对吧?
image.png
这是什么样的体验?完全搜索不到?关键词EIP **弹性公网 **完全搜索不到…
image.png
image.png
最后我在这里找到了:
绑定弹性公网IP
image.png
你可以归于私有网络?是不是应该好歹独立一下…
image.png
吐槽完毕,本文将详细介绍如何使用华为云Go SDK在流量高峰时自动调整EIP带宽设置,并在峰值过后恢复原计费模式。

业务背景:

考虑到一家在线互动应用提供商,主要架构是websockt 长链接,其流量在晚高峰时段飙升,观众涌入平台进行抢红包等互动活动。活动时常大概在一个小时。在流量高峰时,固定带宽的使用能保证用户的观看体验,且相对于按流量计费,成本更为可控。因此,我们面临一个机遇,通过智能化工具调整EIP的带宽计费模式,在需要时提供稳定的网络资源和更优的财务开支。

技术方案:

服务器场景搭建在华为云上,使用了cce kubernetes服务。绑定了应用型负载均衡(负载均衡有本身的EIP公网IP),为了实现这一目标,我们选择华为云的Elastic IP服务,它提供了一系列API,允许程序化管理EIP资源。通过Go语言编写的定时任务,我们可以精确控制带宽的调整时机和规模。在本方案中,使用华为云提供的SDK,我们将编写一个Go应用程序,当业务流量达到高峰时,自动将EIP的计费模式从按流量计费调整为按带宽计费,并固定带宽大小。一小时后,系统自动将设置恢复为按流量计费,以节省成本。

代码实现:

参照以下代码实例:UpdateBandwidth 更新带宽方法:
image.png

package mainimport ("fmt""github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/basic"eip "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/eip/v2""github.com/huaweicloud/huaweicloud-sdk-go-v3/services/eip/v2/model"region "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/eip/v2/region"
)func main() {// The AK and SK used for authentication are hard-coded or stored in plaintext, which has great security risks. It is recommended that the AK and SK be stored in ciphertext in configuration files or environment variables and decrypted during use to ensure security.// In this example, AK and SK are stored in environment variables for authentication. Before running this example, set environment variables CLOUD_SDK_AK and CLOUD_SDK_SK in the local environmentak := os.Getenv("CLOUD_SDK_AK")sk := os.Getenv("CLOUD_SDK_SK")auth := basic.NewCredentialsBuilder().WithAk(ak).WithSk(sk).Build()client := eip.NewEipClient(eip.EipClientBuilder().WithRegion(region.ValueOf("cn-east-3")).WithCredential(auth).Build())request := &model.UpdatePublicipRequest{}request.Body = &model.UpdatePublicipsRequestBody{}response, err := client.UpdatePublicip(request)if err == nil {fmt.Printf("%+v\n", response)} else {fmt.Println(err)}
}

最终实现代码如下:

package mainimport ("fmt""time""github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/basic""github.com/huaweicloud/huaweicloud-sdk-go-v3/core/config"eip "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/eip/v2""github.com/huaweicloud/huaweicloud-sdk-go-v3/services/eip/v2/model"region "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/eip/v2/region"
)func main() {// Replace with your own AK/SK, Region, and Project ID.ak := "xxxxx"sk := "xxxxx"projectID := "xxxxx"// Authenticate using your Access Key and Secret Key.auth := basic.NewCredentialsBuilder().WithAk(ak).WithSk(sk).WithProjectId(projectID).Build()// Create EIP client configuration.eipClient := eip.NewEipClient(eip.EipClientBuilder().WithRegion(region.ValueOf("cn-east-3")).WithCredential(auth).WithHttpConfig(config.DefaultHttpConfig()).Build(),)// Replace the bandwidthId with your actual bandwidth ID.sizeBandwidth := int32(xxx)sizeTraefikBandwidth := int32(xxxx)// Update bandwidth to 10 Mbps and set to bandwidth billing mode.if err := updateBandwidth(eipClient, bandwidthId, "", sizeBandwidth, model.GetUpdateBandwidthOptionChargeModeEnum().BANDWIDTH); err != nil {fmt.Printf("Error updating bandwidth: %s\n", err)return}// Set a timer to switch back to traffic billing mode after 1 hour.time.AfterFunc(1*time.Hour, func() {if err := updateBandwidth(eipClient, bandwidthId, "", sizeTraefikBandwidth, model.GetUpdateBandwidthOptionChargeModeEnum().TRAFFIC); err != nil {fmt.Printf("Error reverting bandwidth: %s\n", err)return}})// Block the main goroutine to not exit immediately.select {}
}// Function to update the bandwidth of an EIP.
func updateBandwidth(client *eip.EipClient, bandwidthId, name string, size int32, chargeMode model.UpdateBandwidthOptionChargeMode) error {request := &model.UpdateBandwidthRequest{BandwidthId: bandwidthId,Body: &model.UpdateBandwidthRequestBody{Bandwidth: &model.UpdateBandwidthOption{Name:       &name,Size:       &size,ChargeMode: &chargeMode,},},}response, err := client.UpdateBandwidth(request)if err != nil {return err}fmt.Printf("Update response: %+v\n", response)return nil
}

初始化EIP客户端

首先,需设置客户端认证,这涉及到基础的Access Key(AK)和Secret Key(SK)配置:

ak := "REPLACE_WITH_YOUR_AK"
sk := "REPLACE_WITH_YOUR_SK"
projectID := "REPLACE_WITH_YOUR_PROJECT_ID"auth := basic.NewCredentialsBuilder().WithAk(ak).WithSk(sk).Build()client := eip.NewEipClient(eip.EipClientBuilder().WithRegion(region.ValueOf("cn-east-3")).WithCredential(auth).Build())
...

务必保障这些敏感信息在环境变量或加密存储中,避免硬编码在应用程序中。

更新带宽函数

updateBandwidth 函数对EIP带宽大小和计费模式进行修改。

func updateBandwidth(client *eip.EipClient, bandwidthId, name string, size int32, chargeMode model.UpdateBandwidthOptionChargeMode) error {request := &model.UpdateBandwidthRequest{BandwidthId: bandwidthId,Body: &model.UpdateBandwidthRequestBody{Bandwidth: &model.UpdateBandwidthOption{Name:       &name,Size:       &size,ChargeMode: &chargeMode,},},}response, err := client.UpdateBandwidth(request)if err != nil {return err}fmt.Printf("Update response: %+v\n", response)return nil
}

这个函数构造了更新带宽的API请求,并处理响应或可能出现的错误。

使用协程和定时器

Go的并发模型让我们能够用协程(goroutines)和定时器轻松实现这个需求。

	go func() {if err := updateBandwidth(eipClient, bandwidthId, "xxxxx", sizeBandwidth, model.GetUpdateBandwidthOptionChargeModeEnum().BANDWIDTH); err != nil {fmt.Printf("更新带宽时出错: %s\n", err)return}// 设置计时器在10分钟后切换回流量计费模式。timer := time.NewTimer(1 * time.Minute)<-timer.Cif err := updateBandwidth(eipClient, bandwidthId, "xxxxxx", sizeTrafficBandwidth, model.GetUpdateBandwidthOptionChargeModeEnum().TRAFFIC); err != nil {fmt.Printf("恢复带宽时出错: %s\n", err)return}}()// 使用通道阻塞主 goroutine 无限期。避免在空的 select 语句中旋转,这是不必要的。done := make(chan struct{})<-done
}

第一版代码

完整代码如下:

package mainimport ("fmt""time""github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/basic""github.com/huaweicloud/huaweicloud-sdk-go-v3/core/config"eip "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/eip/v2""github.com/huaweicloud/huaweicloud-sdk-go-v3/services/eip/v2/model"region "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/eip/v2/region"
)func main() {// Replace with your own AK/SK, Region, and Project ID.ak := "xxxxxx"sk := "xxxxxx"projectID := "xxxxxx"// Authenticate using your Access Key and Secret Key.auth := basic.NewCredentialsBuilder().WithAk(ak).WithSk(sk).WithProjectId(projectID).Build()// Create EIP client configuration.eipClient := eip.NewEipClient(eip.EipClientBuilder().WithRegion(region.ValueOf("cn-east-3")).WithCredential(auth).WithHttpConfig(config.DefaultHttpConfig()).Build(),)// Replace the bandwidthId with your actual bandwidth ID.bandwidthId := "xxxx"sizeBandwidth := int32(xxx)sizeTrafficBandwidth := int32(xxx)// Update bandwidth to 10 Mbps and set to bandwidth billing mode.if err := updateBandwidth(eipClient, bandwidthId, "xxxx", sizeBandwidth, model.GetUpdateBandwidthOptionChargeModeEnum().BANDWIDTH); err != nil {fmt.Printf("Error updating bandwidth: %s\n", err)return}// Set a timer to switch back to traffic billing mode after 1 hour.time.AfterFunc(1*time.Hour, func() {if err := updateBandwidth(eipClient, bandwidthId, "xxxxx", sizeBandwidth, model.GetUpdateBandwidthOptionChargeModeEnum().TRAFFIC); err != nil {fmt.Printf("Error reverting bandwidth: %s\n", err)return}})// Block the main goroutine to not exit immediately.select {}
}// Function to update the bandwidth of an EIP.
func updateBandwidth(client *eip.EipClient, bandwidthId, name string, size int32, chargeMode model.UpdateBandwidthOptionChargeMode) error {request := &model.UpdateBandwidthRequest{BandwidthId: bandwidthId,Body: &model.UpdateBandwidthRequestBody{Bandwidth: &model.UpdateBandwidthOption{Name:       &name,Size:       &size,ChargeMode: &chargeMode,},},}response, err := client.UpdateBandwidth(request)if err != nil {return err}fmt.Printf("Update response: %+v\n", response)return nil
}

运行main.go
xreUAjVvck.png
可以在控制台查看代码操作,控制台对应实例生效!

继续完善代码:

上面的代码是用户传入bandwidthId,这关键一般用户不知道bandwidthId 阿?控制台用户来说一般能知道的是公网IP
image.png
我这里想到的是使用ListPublicips-查询弹性公网IP列表获取bandwidth_name bandwidth_id。 创建两个函数:getBandwidthIdByPublicIP getBandwidthNameByPublicIP

// 这里假设有一个通过公网IP获取带宽ID的函数
func getBandwidthIdByPublicIP(client *eip.EipClient, publicIP string) (string, error) {// 首先构造查询请求request := &model.ListPublicipsRequest{// 根据需要设置查询参数}// 调用SDK方法查询EIP详情response, err := client.ListPublicips(request)if err != nil {return "", err}// 遍历响应中的公共IP地址for _, publicip := range *response.Publicips { // 假设返回的是指针指向的切片// 检查 PublicIpAddress 是否为nil,并解引用来比较值if publicip.PublicIpAddress != nil && *publicip.PublicIpAddress == publicIP {// 检查 BandwidthId 是否为nil,并解引用来返回值if publicip.BandwidthId != nil {return *publicip.BandwidthId, nil}break // 如果 BandwidthId 为nil,则结束循环}}// 如果没有找到匹配的公共IP地址或带宽ID是nil,则返回错误return "", errors.New("public IP not found or bandwidth ID is nil")
}
func getBandwidthNameByPublicIP(client *eip.EipClient, publicIP string) (string, error) {// 首先构造查询请求request := &model.ListPublicipsRequest{// 根据需要设置查询参数}// 调用SDK方法查询EIP详情response, err := client.ListPublicips(request)if err != nil {return "", err}// 遍历响应中的公共IP地址for _, publicip := range *response.Publicips { // 假设返回的是指针指向的切片// 检查 PublicIpAddress 是否为nil,并解引用来比较值if publicip.PublicIpAddress != nil && *publicip.PublicIpAddress == publicIP {// 检查 BandwidthId 是否为nil,并解引用来返回值if publicip.BandwidthName != nil {return *publicip.BandwidthName, nil}break // 如果 BandwidthId 为nil,则结束循环}}// 如果没有找到匹配的公共IP地址或带宽ID是nil,则返回错误return "", errors.New("public IP not found or bandwidth ID is nil")
}

继续完善一下,通过运行main.go传入公网IP,固定带宽恢复按量计费后的带宽大小,以及修改为固定带宽的持续时间 。

go run main.go publicIP  sizeBandwidth sizeTrafficBandwidth timerMinutes
package mainimport ("errors""fmt""os""strconv""time""github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/basic""github.com/huaweicloud/huaweicloud-sdk-go-v3/core/config"eip "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/eip/v2""github.com/huaweicloud/huaweicloud-sdk-go-v3/services/eip/v2/model"region "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/eip/v2/region"
)func main() {// Replace with your own AK/SK, Region, and Project ID.ak := "xxxxxx"sk := "xxxxxx"projectID := "xxxxxx"if len(os.Args) != 5 {fmt.Println("Usage: go run main.go <publicIP> <sizeBandwidth> <sizeTrafficBandwidth> <timerMinutes>")return}publicIP := os.Args[1]sizeBandwidth, err := strconv.Atoi(os.Args[2])if err != nil {fmt.Println("Invalid sizeBandwidth:", err)return}sizeTrafficBandwidth, err := strconv.Atoi(os.Args[3])if err != nil {fmt.Println("Invalid sizeTrafficBandwidth:", err)return}timerMinutes, err := strconv.Atoi(os.Args[4])if err != nil {fmt.Println("Invalid timerMinutes:", err)return}// Authenticate using your Access Key and Secret Key.auth := basic.NewCredentialsBuilder().WithAk(ak).WithSk(sk).WithProjectId(projectID).Build()// Create EIP client configuration.eipClient := eip.NewEipClient(eip.EipClientBuilder().WithRegion(region.ValueOf("cn-east-3")).WithCredential(auth).WithHttpConfig(config.DefaultHttpConfig()).Build(),)bandwidthId, err := getBandwidthIdByPublicIP(eipClient, publicIP)if err != nil {fmt.Println(err)return}bandwidthName, err := getBandwidthNameByPublicIP(eipClient, publicIP)if err != nil {fmt.Println(err)return}go func() {if err := updateBandwidth(eipClient, bandwidthId, bandwidthName, int32(sizeBandwidth), model.GetUpdateBandwidthOptionChargeModeEnum().BANDWIDTH); err != nil {fmt.Printf("更新带宽时出错: %s\n", err)return}// 设置计时器在10分钟后切换回流量计费模式。timer := time.NewTimer(time.Duration(timerMinutes) * time.Minute)<-timer.Cif err := updateBandwidth(eipClient, bandwidthId, bandwidthName, int32(sizeTrafficBandwidth), model.GetUpdateBandwidthOptionChargeModeEnum().TRAFFIC); err != nil {fmt.Printf("恢复带宽时出错: %s\n", err)return}}()// 使用通道阻塞主 goroutine 无限期。避免在空的 select 语句中旋转,这是不必要的。done := make(chan struct{})<-done
}// 这里假设有一个通过公网IP获取带宽ID的函数
func getBandwidthIdByPublicIP(client *eip.EipClient, publicIP string) (string, error) {// 首先构造查询请求request := &model.ListPublicipsRequest{// 根据需要设置查询参数}// 调用SDK方法查询EIP详情response, err := client.ListPublicips(request)if err != nil {return "", err}// 遍历响应中的公共IP地址for _, publicip := range *response.Publicips { // 假设返回的是指针指向的切片// 检查 PublicIpAddress 是否为nil,并解引用来比较值if publicip.PublicIpAddress != nil && *publicip.PublicIpAddress == publicIP {// 检查 BandwidthId 是否为nil,并解引用来返回值if publicip.BandwidthId != nil {return *publicip.BandwidthId, nil}break // 如果 BandwidthId 为nil,则结束循环}}// 如果没有找到匹配的公共IP地址或带宽ID是nil,则返回错误return "", errors.New("public IP not found or bandwidth ID is nil")
}
func getBandwidthNameByPublicIP(client *eip.EipClient, publicIP string) (string, error) {// 首先构造查询请求request := &model.ListPublicipsRequest{// 根据需要设置查询参数}// 调用SDK方法查询EIP详情response, err := client.ListPublicips(request)if err != nil {return "", err}// 遍历响应中的公共IP地址for _, publicip := range *response.Publicips { // 假设返回的是指针指向的切片// 检查 PublicIpAddress 是否为nil,并解引用来比较值if publicip.PublicIpAddress != nil && *publicip.PublicIpAddress == publicIP {// 检查 BandwidthId 是否为nil,并解引用来返回值if publicip.BandwidthName != nil {return *publicip.BandwidthName, nil}break // 如果 BandwidthId 为nil,则结束循环}}// 如果没有找到匹配的公共IP地址或带宽ID是nil,则返回错误return "", errors.New("public IP not found or bandwidth ID is nil")
}// Function to update the bandwidth of an EIP.
func updateBandwidth(client *eip.EipClient, bandwidthId, name string, size int32, chargeMode model.UpdateBandwidthOptionChargeMode) error {request := &model.UpdateBandwidthRequest{BandwidthId: bandwidthId,Body: &model.UpdateBandwidthRequestBody{Bandwidth: &model.UpdateBandwidthOption{Name:       &name,Size:       &size,ChargeMode: &chargeMode,},},}response, err := client.UpdateBandwidth(request)if err != nil {return err}fmt.Printf("Update response: %+v\n", response)return nil
}

jenkins运行以上代码实例

最终我需要在jenkins中运行这个更改流量的任务,我将引用ak,sk引用jenkins凭据的方式:
参照之前刷新cdn时候引用凭据的方式:
image.png
最终代码如下:

package mainimport ("errors""fmt""os""strconv""time""github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/basic""github.com/huaweicloud/huaweicloud-sdk-go-v3/core/config"eip "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/eip/v2""github.com/huaweicloud/huaweicloud-sdk-go-v3/services/eip/v2/model"region "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/eip/v2/region"
)func main() {// Replace with your own AK/SK, Region, and Project ID.// 尝试从环境变量中获取ak和skcreds := os.Getenv("huaweiyun-hn-cdn")if creds == "" {fmt.Fprintln(os.Stderr, "Error: Credentials environment variable is not set.")os.Exit(1)}parts := strings.SplitN(creds, ":", 2)if len(parts) != 2 {fmt.Fprintln(os.Stderr, "Error: Invalid credential format. Expected 'AK:SK'.")os.Exit(1)}ak, sk := parts[0], parts[1]projectID := "xxxxxx"if len(os.Args) != 5 {fmt.Println("Usage: go run main.go <publicIP> <sizeBandwidth> <sizeTrafficBandwidth> <timerMinutes>")return}publicIP := os.Args[1]sizeBandwidth, err := strconv.Atoi(os.Args[2])if err != nil {fmt.Println("Invalid sizeBandwidth:", err)return}sizeTrafficBandwidth, err := strconv.Atoi(os.Args[3])if err != nil {fmt.Println("Invalid sizeTrafficBandwidth:", err)return}timerMinutes, err := strconv.Atoi(os.Args[4])if err != nil {fmt.Println("Invalid timerMinutes:", err)return}// Authenticate using your Access Key and Secret Key.auth := basic.NewCredentialsBuilder().WithAk(ak).WithSk(sk).WithProjectId(projectID).Build()// Create EIP client configuration.eipClient := eip.NewEipClient(eip.EipClientBuilder().WithRegion(region.ValueOf("cn-east-3")).WithCredential(auth).WithHttpConfig(config.DefaultHttpConfig()).Build(),)bandwidthId, err := getBandwidthIdByPublicIP(eipClient, publicIP)if err != nil {fmt.Println(err)return}bandwidthName, err := getBandwidthNameByPublicIP(eipClient, publicIP)if err != nil {fmt.Println(err)return}go func() {if err := updateBandwidth(eipClient, bandwidthId, bandwidthName, int32(sizeBandwidth), model.GetUpdateBandwidthOptionChargeModeEnum().BANDWIDTH); err != nil {fmt.Printf("更新带宽时出错: %s\n", err)return}// 设置计时器在10分钟后切换回流量计费模式。timer := time.NewTimer(time.Duration(timerMinutes) * time.Minute)<-timer.Cif err := updateBandwidth(eipClient, bandwidthId, bandwidthName, int32(sizeTrafficBandwidth), model.GetUpdateBandwidthOptionChargeModeEnum().TRAFFIC); err != nil {fmt.Printf("恢复带宽时出错: %s\n", err)return}}()// 使用通道阻塞主 goroutine 无限期。避免在空的 select 语句中旋转,这是不必要的。done := make(chan struct{})<-done
}// 这里假设有一个通过公网IP获取带宽ID的函数
func getBandwidthIdByPublicIP(client *eip.EipClient, publicIP string) (string, error) {// 首先构造查询请求request := &model.ListPublicipsRequest{// 根据需要设置查询参数}// 调用SDK方法查询EIP详情response, err := client.ListPublicips(request)if err != nil {return "", err}// 遍历响应中的公共IP地址for _, publicip := range *response.Publicips { // 假设返回的是指针指向的切片// 检查 PublicIpAddress 是否为nil,并解引用来比较值if publicip.PublicIpAddress != nil && *publicip.PublicIpAddress == publicIP {// 检查 BandwidthId 是否为nil,并解引用来返回值if publicip.BandwidthId != nil {return *publicip.BandwidthId, nil}break // 如果 BandwidthId 为nil,则结束循环}}// 如果没有找到匹配的公共IP地址或带宽ID是nil,则返回错误return "", errors.New("public IP not found or bandwidth ID is nil")
}
func getBandwidthNameByPublicIP(client *eip.EipClient, publicIP string) (string, error) {// 首先构造查询请求request := &model.ListPublicipsRequest{// 根据需要设置查询参数}// 调用SDK方法查询EIP详情response, err := client.ListPublicips(request)if err != nil {return "", err}// 遍历响应中的公共IP地址for _, publicip := range *response.Publicips { // 假设返回的是指针指向的切片// 检查 PublicIpAddress 是否为nil,并解引用来比较值if publicip.PublicIpAddress != nil && *publicip.PublicIpAddress == publicIP {// 检查 BandwidthId 是否为nil,并解引用来返回值if publicip.BandwidthName != nil {return *publicip.BandwidthName, nil}break // 如果 BandwidthId 为nil,则结束循环}}// 如果没有找到匹配的公共IP地址或带宽ID是nil,则返回错误return "", errors.New("public IP not found or bandwidth ID is nil")
}// Function to update the bandwidth of an EIP.
func updateBandwidth(client *eip.EipClient, bandwidthId, name string, size int32, chargeMode model.UpdateBandwidthOptionChargeMode) error {request := &model.UpdateBandwidthRequest{BandwidthId: bandwidthId,Body: &model.UpdateBandwidthRequestBody{Bandwidth: &model.UpdateBandwidthOption{Name:       &name,Size:       &size,ChargeMode: &chargeMode,},},}response, err := client.UpdateBandwidth(request)if err != nil {return err}fmt.Printf("Update response: %+v\n", response)return nil
}

go build main.go,编译为可执行程序!将可执行程序放在工作节点上,jenkins 做了一个demo
参数化构建,字符参数
image.png
绑定密钥文件:
image.png
Build Steps 执行shell

cd /home/eip-hw&&./main $publicIP $sizeBandwidth $sizeTrafficBandwidth $timerMinutes

image.png
输入publicIP运行程序:
image.png
程序运行生效,但是进程没有退出:

image.png

最终go相关代码:

继续完善一下代码,当程序运行完成后,退出程序。输出Bandwidth update successful, exiting:

package mainimport ("errors""fmt""os""strconv""time""strings""github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/basic""github.com/huaweicloud/huaweicloud-sdk-go-v3/core/config"eip "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/eip/v2""github.com/huaweicloud/huaweicloud-sdk-go-v3/services/eip/v2/model"region "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/eip/v2/region"
)func main() {// Replace with your own AK/SK, Region, and Project ID.// 尝试从环境变量中获取ak和skcreds := os.Getenv("xxxxxx")if creds == "" {fmt.Fprintln(os.Stderr, "Error: Credentials environment variable is not set.")os.Exit(1)}parts := strings.SplitN(creds, ":", 2)if len(parts) != 2 {fmt.Fprintln(os.Stderr, "Error: Invalid credential format. Expected 'AK:SK'.")os.Exit(1)}ak, sk := parts[0], parts[1]projectID := "xxxxxx"if len(os.Args) != 5 {fmt.Println("Usage: go run main.go <publicIP> <sizeBandwidth> <sizeTrafficBandwidth> <timerMinutes>")return}publicIP := os.Args[1]sizeBandwidth, err := strconv.Atoi(os.Args[2])if err != nil {fmt.Println("Invalid sizeBandwidth:", err)return}sizeTrafficBandwidth, err := strconv.Atoi(os.Args[3])if err != nil {fmt.Println("Invalid sizeTrafficBandwidth:", err)return}timerMinutes, err := strconv.Atoi(os.Args[4])if err != nil {fmt.Println("Invalid timerMinutes:", err)return}// Authenticate using your Access Key and Secret Key.auth := basic.NewCredentialsBuilder().WithAk(ak).WithSk(sk).WithProjectId(projectID).Build()// Create EIP client configuration.eipClient := eip.NewEipClient(eip.EipClientBuilder().WithRegion(region.ValueOf("cn-east-3")).WithCredential(auth).WithHttpConfig(config.DefaultHttpConfig()).Build(),)bandwidthId, err := getBandwidthIdByPublicIP(eipClient, publicIP)if err != nil {fmt.Println(err)return}bandwidthName, err := getBandwidthNameByPublicIP(eipClient, publicIP)if err != nil {fmt.Println(err)return}go func() {if err := updateBandwidth(eipClient, bandwidthId, bandwidthName, int32(sizeBandwidth), model.GetUpdateBandwidthOptionChargeModeEnum().BANDWIDTH); err != nil {fmt.Printf("更新带宽时出错: %s\n", err)os.Exit(1)return}// 设置计时器在10分钟后切换回流量计费模式。timer := time.NewTimer(time.Duration(timerMinutes) * time.Minute)<-timer.Cif err := updateBandwidth(eipClient, bandwidthId, bandwidthName, int32(sizeTrafficBandwidth), model.GetUpdateBandwidthOptionChargeModeEnum().TRAFFIC); err != nil {fmt.Printf("恢复带宽时出错: %s\n", err)os.Exit(1)return}fmt.Println("Bandwidth update successful, exiting.") // Log success messageos.Exit(0) // Exit the process after success}()// 使用通道阻塞主 goroutine 无限期。避免在空的 select 语句中旋转,这是不必要的。done := make(chan struct{})<-done
}// 这里假设有一个通过公网IP获取带宽ID的函数
func getBandwidthIdByPublicIP(client *eip.EipClient, publicIP string) (string, error) {// 首先构造查询请求request := &model.ListPublicipsRequest{// 根据需要设置查询参数}// 调用SDK方法查询EIP详情response, err := client.ListPublicips(request)if err != nil {return "", err}// 遍历响应中的公共IP地址for _, publicip := range *response.Publicips { // 假设返回的是指针指向的切片// 检查 PublicIpAddress 是否为nil,并解引用来比较值if publicip.PublicIpAddress != nil && *publicip.PublicIpAddress == publicIP {// 检查 BandwidthId 是否为nil,并解引用来返回值if publicip.BandwidthId != nil {return *publicip.BandwidthId, nil}break // 如果 BandwidthId 为nil,则结束循环}}// 如果没有找到匹配的公共IP地址或带宽ID是nil,则返回错误return "", errors.New("public IP not found or bandwidth ID is nil")
}
func getBandwidthNameByPublicIP(client *eip.EipClient, publicIP string) (string, error) {// 首先构造查询请求request := &model.ListPublicipsRequest{// 根据需要设置查询参数}// 调用SDK方法查询EIP详情response, err := client.ListPublicips(request)if err != nil {return "", err}// 遍历响应中的公共IP地址for _, publicip := range *response.Publicips { // 假设返回的是指针指向的切片// 检查 PublicIpAddress 是否为nil,并解引用来比较值if publicip.PublicIpAddress != nil && *publicip.PublicIpAddress == publicIP {// 检查 BandwidthId 是否为nil,并解引用来返回值if publicip.BandwidthName != nil {return *publicip.BandwidthName, nil}break // 如果 BandwidthId 为nil,则结束循环}}// 如果没有找到匹配的公共IP地址或带宽ID是nil,则返回错误return "", errors.New("public IP not found or bandwidth ID is nil")
}// Function to update the bandwidth of an EIP.
func updateBandwidth(client *eip.EipClient, bandwidthId, name string, size int32, chargeMode model.UpdateBandwidthOptionChargeMode) error {request := &model.UpdateBandwidthRequest{BandwidthId: bandwidthId,Body: &model.UpdateBandwidthRequestBody{Bandwidth: &model.UpdateBandwidthOption{Name:       &name,Size:       &size,ChargeMode: &chargeMode,},},}response, err := client.UpdateBandwidth(request)if err != nil {return err}fmt.Printf("Update response: %+v\n", response)return nil
}

image.png
ok这样就简单实现了!
注:以上代码chatgpt生成,个人进行了更改整理.

其他想到的

  1. 修改一下程序,检测流量计费,当带宽到xxx的时候自动切换带宽?
  2. 支持一下更多类型的切换方式?比如固定带宽的直接10变更 5 20,不恢复流量计费?

这篇关于jenkins Job华为云EIP变更带宽的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/538503

相关文章

Python MySQL如何通过Binlog获取变更记录恢复数据

《PythonMySQL如何通过Binlog获取变更记录恢复数据》本文介绍了如何使用Python和pymysqlreplication库通过MySQL的二进制日志(Binlog)获取数据库的变更记录... 目录python mysql通过Binlog获取变更记录恢复数据1.安装pymysqlreplicat

解决systemctl reload nginx重启Nginx服务报错:Job for nginx.service invalid问题

《解决systemctlreloadnginx重启Nginx服务报错:Jobfornginx.serviceinvalid问题》文章描述了通过`systemctlstatusnginx.se... 目录systemctl reload nginx重启Nginx服务报错:Job for nginx.javas

springboot整合 xxl-job及使用步骤

《springboot整合xxl-job及使用步骤》XXL-JOB是一个分布式任务调度平台,用于解决分布式系统中的任务调度和管理问题,文章详细介绍了XXL-JOB的架构,包括调度中心、执行器和Web... 目录一、xxl-job是什么二、使用步骤1. 下载并运行管理端代码2. 访问管理页面,确认是否启动成功

Jenkins中自动化部署Spring Boot项目的全过程

《Jenkins中自动化部署SpringBoot项目的全过程》:本文主要介绍如何使用Jenkins从Git仓库拉取SpringBoot项目并进行自动化部署,通过配置Jenkins任务,实现项目的... 目录准备工作启动 Jenkins配置 Jenkins创建及配置任务源码管理构建触发器构建构建后操作构建任务

你的华为手机升级了吗? 鸿蒙NEXT多连推5.0.123版本变化颇多

《你的华为手机升级了吗?鸿蒙NEXT多连推5.0.123版本变化颇多》现在的手机系统更新可不仅仅是修修补补那么简单了,华为手机的鸿蒙系统最近可是动作频频,给用户们带来了不少惊喜... 为了让用户的使用体验变得很好,华为手机不仅发布了一系列给力的新机,还在操作系统方面进行了疯狂的发力。尤其是近期,不仅鸿蒙O

SpringBoot整合Canal+RabbitMQ监听数据变更详解

《SpringBoot整合Canal+RabbitMQ监听数据变更详解》在现代分布式系统中,实时获取数据库的变更信息是一个常见的需求,本文将介绍SpringBoot如何通过整合Canal和Rabbit... 目录需求步骤环境搭建整合SpringBoot与Canal实现客户端Canal整合RabbitMQSp

速盾:直播 cdn 服务器带宽?

在当今数字化时代,直播已经成为了一种非常流行的娱乐和商业活动形式。为了确保直播的流畅性和高质量,直播平台通常会使用 CDN(Content Delivery Network,内容分发网络)服务器来分发直播流。而 CDN 服务器的带宽则是影响直播质量的一个重要因素。下面我们就来探讨一下速盾视角下的直播 CDN 服务器带宽问题。 一、直播对带宽的需求 高清视频流 直播通常需要传输高清视频

Jenkins构建Maven聚合工程,指定构建子模块

一、设置单独编译构建子模块 配置: 1、Root POM指向父pom.xml 2、Goals and options指定构建模块的参数: mvn -pl project1/project1-son -am clean package 单独构建project1-son项目以及它所依赖的其它项目。 说明: mvn clean package -pl 父级模块名/子模块名 -am参数

jenkins 插件执行shell命令时,提示“Command not found”处理方法

首先提示找不到“Command not found,可能我们第一反应是查看目标机器是否已支持该命令,不过如果相信能找到这里来的朋友估计遇到的跟我一样,其实目标机器是没有问题的通过一些远程工具执行shell命令是可以执行。奇怪的就是通过jenkinsSSH插件无法执行,经一番折腾各种搜索发现是jenkins没有加载/etc/profile导致。 【解决办法】: 需要在jenkins调用shell脚

Jenkins 插件 地址证书报错问题解决思路

问题提示摘要: SunCertPathBuilderException: unable to find valid certification path to requested target...... 网上很多的解决方式是更新站点的地址,我这里修改了一个日本的地址(清华镜像也好),其实发现是解决不了上述的报错问题的,其实,最终拉去插件的时候,会提示证书的问题,几经周折找到了其中一遍博文