jenkins Job华为云EIP变更带宽

这篇具有很好参考价值的文章主要介绍了jenkins Job华为云EIP变更带宽。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

引言:

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

业务背景:

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

技术方案:

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

代码实现:

参照以下代码实例:UpdateBandwidth 更新带宽方法:
jenkins Job华为云EIP变更带宽,jenkins,linux工具,华为云,jenkins,华为云,devops,运维开发

package main

import (
	"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 environment
    ak := 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 main

import (
	"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.C

		if 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 main

import (
	"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
jenkins Job华为云EIP变更带宽,jenkins,linux工具,华为云,jenkins,华为云,devops,运维开发
可以在控制台查看代码操作,控制台对应实例生效!

继续完善代码:

上面的代码是用户传入bandwidthId,这关键一般用户不知道bandwidthId 阿?控制台用户来说一般能知道的是公网IP
jenkins Job华为云EIP变更带宽,jenkins,linux工具,华为云,jenkins,华为云,devops,运维开发
我这里想到的是使用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 main

import (
	"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.C

		if 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时候引用凭据的方式:
jenkins Job华为云EIP变更带宽,jenkins,linux工具,华为云,jenkins,华为云,devops,运维开发
最终代码如下:

package main

import (
	"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和sk
	creds := 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.C

		if 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
参数化构建,字符参数
jenkins Job华为云EIP变更带宽,jenkins,linux工具,华为云,jenkins,华为云,devops,运维开发
绑定密钥文件:
jenkins Job华为云EIP变更带宽,jenkins,linux工具,华为云,jenkins,华为云,devops,运维开发
Build Steps 执行shell

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

jenkins Job华为云EIP变更带宽,jenkins,linux工具,华为云,jenkins,华为云,devops,运维开发
输入publicIP运行程序:
jenkins Job华为云EIP变更带宽,jenkins,linux工具,华为云,jenkins,华为云,devops,运维开发
程序运行生效,但是进程没有退出:

jenkins Job华为云EIP变更带宽,jenkins,linux工具,华为云,jenkins,华为云,devops,运维开发

最终go相关代码:

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

package main

import (
	"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和sk
	creds := 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.C

		if 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 message
                os.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
}

jenkins Job华为云EIP变更带宽,jenkins,linux工具,华为云,jenkins,华为云,devops,运维开发
ok这样就简单实现了!
注:以上代码chatgpt生成,个人进行了更改整理.文章来源地址https://www.toymoban.com/news/detail-774260.html

其他想到的

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

到了这里,关于jenkins Job华为云EIP变更带宽的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • (十九)devops持续集成开发——jenkins的一些常用插件和工具的安装

    本节内容会着重介绍jenkins持续集成开发工具的一些常用插件安装以及全局工具的配置安装,并说明其主要作用。在开始插件和工具安装之前,我们要保证可以正常访问网络,并且使用国内的插件更新地址,便于插件的正常安装。官方的地址可能会导致安装失败。以下是一些可

    2024年04月27日
    浏览(36)
  • 变更jenkins工作目录

    1.变更jenkins目录需要在jenkins关闭状态下执行,使用war包启动的jenkins服务,默认工作目录是/root/.jenkins  2.变更jenkins工作目录有三种方式 2.1使用你Web容器的管理工具设置JENKINS_HOME环境参数 2.2在启动Web容器之前设置JENKINS_HOME环境变量 2.3(不推荐)更改Jenkins.war(或者在展开的Web容器

    2024年02月11日
    浏览(36)
  • Jenkins获取git文件变更列表、提交ID、提交人、提交信息

    GitLab 事件触发 Jenkins 构建只是一个启动信号,获取变更文件列表需要知晓上一次构建时某个仓库的版本号,这里 Jenkins 的插件 git-plugin 已经帮我们实现了这部分工作。所以只需要通过 git-plugin 检出代码即可。 检出代码 请自行替换 $branchName 为分支名, $relativeTarget 为检出相对

    2024年02月11日
    浏览(38)
  • EIP-2535 Diamond standard 实用工具分享

        前段时间工作对接到了这标准的协议,于是简单介绍下这个标准分享下方便前端er使用的调用工具 一、标准的诞生         在写复杂逻辑的solidity智能合约时,经常会碰到两个问题,升级和合约大小限制。         升级目前有几种proxy模式,通过delegatecall把数据存

    2024年02月14日
    浏览(66)
  • Jenkins通过命令行导出/导入job

    jenkins控制台--系统管理--工具和动作--Jenkins命令行接口 按照提示下载:jenkins-cli.jar

    2024年02月03日
    浏览(24)
  • DevOps-Jenkins

    Jenkins是一个可扩展的持续集成引擎,是一个开源软件项目,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能。 官网 场景一 研发人员上传开发好的代码到github代码仓库 需要将代码下载nginx服务器部署 手动下载再部署/使用脚本下载在部署 场景二 静态IP(可以上

    2024年02月15日
    浏览(44)
  • Jenkins 创建一个 job , 用于单独执行脚本

    目录 1.首先,在Jenkins中创建一个新的job 2.之后,会进入配置页面,在配置页面进行配置。  2.1.找到【Build Steps】,下拉菜单中选择「シェルの実行」 (执行Shell) 2.2.之后,会出现シェルスクリプト (Shell Script) 的 Area,在这里录入你想执行的 脚本 3.运行,并查看Log ・设置脚

    2024年02月12日
    浏览(30)
  • DevOps持续集成-Jenkins(4)

    DevOps概述 软件开发最初是由两个团队共同组成:(没有采用DevOps之前) 开发团队 :从头开始设计和整体系统的构建(编写代码)。需要系统不停的迭代更新。 运维团队 :将开发团队的代码进行测试通过后再部署上线。确保系统稳定运行。 没有采用DevOps的缺点: 这看似两个

    2024年02月08日
    浏览(39)
  • DevOps持续集成-Jenkins(2)

    DevOps概述 软件开发最初是由两个团队共同组成:(没有采用DevOps之前) 开发团队 :从头开始设计和整体系统的构建(编写代码)。需要系统不停的迭代更新。 运维团队 :将开发团队的代码进行测试通过后再部署上线。确保系统稳定运行。 没有采用DevOps的缺点: 这看似两个

    2024年02月08日
    浏览(46)
  • 【Jenkins】节点 node、凭据 credentials、任务 job

    Jenkins在安装并初始化完成后,会有一个主节点(Master Node),默认情况下主节点可以同时运行的任务数是2,可以在节点配置中修改(系统管理/节点和云管理)。 Jenkins中的节点(Node)是指用于执行构建任务的计算机或计算机集群。节点可以是物理计算机,也可以是虚拟机。

    2024年02月03日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包