华为云CDN刷新与查询余量的Go实现及在Jenkins中的部署

news2024/11/25 22:52:22

引言

在华为云上,对CDN缓存内容进行刷新是一个常见的需求,以确保最新的内容能尽快被用户访问到。通过使用Go语言,我们可以开发一个自动化的工具来实现这一需求,并将其集成到Jenkins中以实现持续部署。下面我们将分步骤讲解如何实现。

1. 实现CDN的刷新

要用Go实现华为云CDN的刷新工作,我们需要首先安装go-sdk,这是华为云为Go开发者提供的SDK,包含了操作华为云服务的API接口。

步骤1.1 安装华为云官方Go SDK

我们可以使用go get命令来安装SDK:

go get -u github.com/huaweicloud/huaweicloud-sdk-go-v3

步骤1.2 创建CDN刷新任务

使用华为云apiexplorer查看一下cdn的实例代码:
image.png
创建刷新缓存任务实例,有V1 V2版本区别,但是看了一眼,目测代码没有什么区别,这里就继续使用v1版本了:

package main

import (
	"fmt"
	"github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/global"
    cdn "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/cdn/v1"
	"github.com/huaweicloud/huaweicloud-sdk-go-v3/services/cdn/v1/model"
    region "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/cdn/v1/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 := global.NewCredentialsBuilder().
        WithAk(ak).
        WithSk(sk).
        Build()

    client := cdn.NewCdnClient(
        cdn.CdnClientBuilder().
            WithRegion(region.ValueOf("cn-north-1")).
            WithCredential(auth).
            Build())

    request := &model.CreateRefreshTasksRequest{}
	request.Body = &model.RefreshTaskRequest{
	}
	response, err := client.CreateRefreshTasks(request)
	if err == nil {
        fmt.Printf("%+v\n", response)
    } else {
        fmt.Println(err)
    }
}

根据上面的代码做一个简单的实例,演示如何使用华为云Go SDK创建CDN刷新任务:
域名使用 传入的方式,这里就直接使用了os.Args,传递参数:

package main

import (
	"fmt"
	"github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/global"
	"github.com/huaweicloud/huaweicloud-sdk-go-v3/core/config"
	cdn "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/cdn/v1"
	"github.com/huaweicloud/huaweicloud-sdk-go-v3/services/cdn/v1/model"
	"github.com/huaweicloud/huaweicloud-sdk-go-v3/services/cdn/v1/region"
	"os"
)

func main() {
	if len(os.Args) < 2 {
		fmt.Println("Usage: go run main.go <your-cdn-url>")
		return
	}

	cdnUrl := os.Args[1]

	ak := "YOUR_ACCESS_KEY"
	sk := "YOUR_SECRET_KEY"
	auth := global.NewCredentialsBuilder().
		WithAk(ak).
		WithSk(sk).
		Build()

	hcClient := cdn.NewCdnClient(
		cdn.CdnClientBuilder().
			WithRegion(region.ValueOf("cn-north-1")).
			WithCredential(auth).
			WithHttpConfig(config.DefaultHttpConfig()).
			Build())
	// Create CDN refresh task
	createRefreshTask(hcClient, cdnUrl)
}

func createRefreshTask(hcClient *cdn.CdnClient, cdnUrl string) {
	refreshTaskRequest := &model.CreateRefreshTasksRequest{}
	typeRefreshTask := model.GetRefreshTaskRequestBodyTypeEnum().DIRECTORY
	modeRefreshTask := model.GetRefreshTaskRequestBodyModeEnum().DETECT_MODIFY_REFRESH
	zhUrlEncodeRefreshTask := false
	refreshTaskbody := &model.RefreshTaskRequestBody{
		Type:        &typeRefreshTask,
		Mode:        &modeRefreshTask,
		ZhUrlEncode: &zhUrlEncodeRefreshTask,
		Urls:        []string{cdnUrl},
	}
	refreshTaskRequest.Body = &model.RefreshTaskRequest{
		RefreshTask: refreshTaskbody,
	}
	// Create the refresh task
	response, err := hcClient.CreateRefreshTasks(refreshTaskRequest)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error creating CDN refresh task: %s\n", err)
		os.Exit(2)
	}

	fmt.Printf("CDN refresh task created successfully: %s\n", response)
}

在上述代码中,替换**YOUR_ACCESS_KEY****YOUR_SECRET_KEY**为你的华为云账号的密钥信息。
尝试运行脚本:

go run main.go https://xxx.xxx.com/

image.png
末尾以**/**单斜线结尾!
注:以上代码以刷新目录为例,且只刷新变更资源!具体参数或者其他需求可以参考:https://console.huaweicloud.com/apiexplorer/#/openapi/CDN/doc?version=v1&api=CreateRefreshTasks,文档中参数!

2. 查询file URL余量

在创建刷新任务后,我们可能还需要查询当前账户下的URL刷新余量,以确保后续操作不会受到次数限制的影响。

步骤2.1 查询CDN file URL余量

可以在上面的Go程序中继续添加以下查询余量的代码片段:
参照:https://console.huaweicloud.com/apiexplorer/#/openapi/CDN/debug?version=v1&api=ShowQuota
image.png
尝试调试,查看返回值数据结构,编写代码如下:

// 查询URL 目录余量
func queryCdnQuota(hcClient *cdn.CdnClient) {
	request := &model.ShowQuotaRequest{}
	response, err := hcClient.ShowQuota(request)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error querying CDN quota: %s\n", err)
		os.Exit(2)
	}

	// 请确保 response.Quotas 不是nil,否则可能会导致空指针异常
	if response.Quotas == nil {
		fmt.Fprintln(os.Stderr, "Error: received nil Quotas in response")
		os.Exit(2)
	}

	// 自定义类型名称的映射
	typeNameMap := map[string]string{
		"file_refresh": "缓存刷新剩余Url条数",
		"dir_refresh":  "缓存刷新剩余目录数",
	}

	// Print out the customized quota information
	fmt.Println("CDN quota information:")
	for _, quota := range *response.Quotas {
		// 检查quota.Type是否为我们关心的类型之一
		if customName, ok := typeNameMap[*quota.Type]; ok {
			remaining := *quota.QuotaLimit - *quota.Used
			fmt.Printf("- %s: %d\n", customName, remaining)
		}
	}
}

在main函数中增加一下代码:

	queryCdnQuota(hcClient)

此片段會在创建CDN刷新任务之后调用ShowQuota接口,查询并打印出当前账户的URL以及目录刷新余量信息。typeNameMap部分是我想自定义一下输出打印的名称,增加可读性!
完成代码如下:

package main

import (
	"fmt"
	"github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/global"
	"github.com/huaweicloud/huaweicloud-sdk-go-v3/core/config"
	cdn "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/cdn/v1"
	"github.com/huaweicloud/huaweicloud-sdk-go-v3/services/cdn/v1/model"
	"github.com/huaweicloud/huaweicloud-sdk-go-v3/services/cdn/v1/region"
	"os"
)

func main() {
	if len(os.Args) < 2 {
		fmt.Println("Usage: go run main.go <your-cdn-url>")
		return
	}

	cdnUrl := os.Args[1]

	ak := "YOUR_ACCESS_KEY"
	sk := "YOUR_SECRET_KEY"
	auth := global.NewCredentialsBuilder().
		WithAk(ak).
		WithSk(sk).
		Build()

	hcClient := cdn.NewCdnClient(
		cdn.CdnClientBuilder().
			WithRegion(region.ValueOf("cn-north-1")).
			WithCredential(auth).
			WithHttpConfig(config.DefaultHttpConfig()).
			Build())
	// Create CDN refresh task
	createRefreshTask(hcClient, cdnUrl)
}

func createRefreshTask(hcClient *cdn.CdnClient, cdnUrl string) {
	refreshTaskRequest := &model.CreateRefreshTasksRequest{}
	typeRefreshTask := model.GetRefreshTaskRequestBodyTypeEnum().DIRECTORY
	modeRefreshTask := model.GetRefreshTaskRequestBodyModeEnum().DETECT_MODIFY_REFRESH
	zhUrlEncodeRefreshTask := false
	refreshTaskbody := &model.RefreshTaskRequestBody{
		Type:        &typeRefreshTask,
		Mode:        &modeRefreshTask,
		ZhUrlEncode: &zhUrlEncodeRefreshTask,
		Urls:        []string{cdnUrl},
	}
	refreshTaskRequest.Body = &model.RefreshTaskRequest{
		RefreshTask: refreshTaskbody,
	}
	// Create the refresh task
	response, err := hcClient.CreateRefreshTasks(refreshTaskRequest)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error creating CDN refresh task: %s\n", err)
		os.Exit(2)
	}

	fmt.Printf("CDN refresh task created successfully: %s\n", response)
}

运行代码返回数据格式如下:

go run main.go https://xxx.xxx.com/

image.png

3. 在Jenkins节点上运行程序

一旦我们的Go程序可以正确执行CDN刷新和查询余量的操作,接下来的步骤就是在Jenkins中配置该程序的运行环境。

步骤3.1 创建一个新的Jenkins任务

在Jenkins中创建一个Freestyle项目或者Pipeline项目,此部分取决于你的工作流。为了简便说明,我们这里以Freestyle项目为例。

步骤3.2 配置构建步骤

首先添加一个参数化构建过程,传入参数:
image.png
限制一下可运行的节点:
image.png

在你的Jenkins任务配置页中,添加一个构建步骤,选择“Execute shell”(对于Linux系统)或“Execute Windows batch command”(对于Windows系统),并填入以下内容:
image.png

# 假设你的Go程序名为`main`,且已经编译到Jenkins的工作空间中
cd /home/flush-hw&&./main $dir

确保构建环境中已经安装了Go运行时,并且环境变量已经配置,这样main程序才可以在Jenkins节点上运行没有问题。
注:main要有可执行权限,复制过来要记得chmod +x main .

4. 使用Jenkins Credentials管理AK/SK密钥

为了避免在代码中硬编码敏感信息,如Access Key和Secret Key,推荐使用Jenkins的Credentials插件来管理这些密钥。

步骤4.1 添加Credentials

在Jenkins中进入Credentials管理页面,添加一个新的Credentials,选择“Secret text”,其中**Secret**字段填入AK:SK的格式。记住这里的**ID,**接下来绑定的时候会用到
image.png
image.png

步骤4.2 修改Go程序以获取Credentials

之后,你需要修改Go程序,让其从环境变量中读取AK和SK。例如:

package main

import (
	"fmt"
	"github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/global"
	"github.com/huaweicloud/huaweicloud-sdk-go-v3/core/config"
	cdn "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/cdn/v1"
	"github.com/huaweicloud/huaweicloud-sdk-go-v3/services/cdn/v1/model"
	"github.com/huaweicloud/huaweicloud-sdk-go-v3/services/cdn/v1/region"
	"os"
	"strings"
)

func main() {
	if len(os.Args) < 2 {
		fmt.Println("Usage: go run main.go <your-cdn-url>")
		return
	}

	cdnUrl := os.Args[1]

	// 尝试从环境变量中获取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]
	auth := global.NewCredentialsBuilder().
		WithAk(ak).
		WithSk(sk).
		Build()

	hcClient := cdn.NewCdnClient(
		cdn.CdnClientBuilder().
			WithRegion(region.ValueOf("cn-north-1")).
			WithCredential(auth).
			WithHttpConfig(config.DefaultHttpConfig()).
			Build())
	// Create CDN refresh task
	createRefreshTask(hcClient, cdnUrl)

	// Query remaining refresh and preload quota
	queryCdnQuota(hcClient)
}

func createRefreshTask(hcClient *cdn.CdnClient, cdnUrl string) {
	refreshTaskRequest := &model.CreateRefreshTasksRequest{}
	typeRefreshTask := model.GetRefreshTaskRequestBodyTypeEnum().DIRECTORY
	modeRefreshTask := model.GetRefreshTaskRequestBodyModeEnum().DETECT_MODIFY_REFRESH
	zhUrlEncodeRefreshTask := false
	refreshTaskbody := &model.RefreshTaskRequestBody{
		Type:        &typeRefreshTask,
		Mode:        &modeRefreshTask,
		ZhUrlEncode: &zhUrlEncodeRefreshTask,
		Urls:        []string{cdnUrl},
	}
	refreshTaskRequest.Body = &model.RefreshTaskRequest{
		RefreshTask: refreshTaskbody,
	}
	// Create the refresh task
	response, err := hcClient.CreateRefreshTasks(refreshTaskRequest)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error creating CDN refresh task: %s\n", err)
		os.Exit(2)
	}

	fmt.Printf("CDN refresh task created successfully: %s\n", response)
}
func queryCdnQuota(hcClient *cdn.CdnClient) {
	request := &model.ShowQuotaRequest{}
	response, err := hcClient.ShowQuota(request)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error querying CDN quota: %s\n", err)
		os.Exit(2)
	}

	// 请确保 response.Quotas 不是nil,否则可能会导致空指针异常
	if response.Quotas == nil {
		fmt.Fprintln(os.Stderr, "Error: received nil Quotas in response")
		os.Exit(2)
	}

	// 自定义类型名称的映射
	typeNameMap := map[string]string{
		"file_refresh": "缓存刷新剩余Url条数",
		"dir_refresh":  "缓存刷新剩余目录数",
	}

	// Print out the customized quota information
	fmt.Println("CDN quota information:")
	for _, quota := range *response.Quotas {
		// 检查quota.Type是否为我们关心的类型之一
		if customName, ok := typeNameMap[*quota.Type]; ok {
			remaining := *quota.QuotaLimit - *quota.Used
			fmt.Printf("- %s: %d\n", customName, remaining)
		}
	}
}

步骤4.3 配置Jenkins任务以传递Credentials

在Jenkins任务的构建环境配置中,使用Credentials Binding插件将新添加的Credentials绑定到相应的环境变量中。在“Build Environment”选择“Use secret text(s) or file(s)”,命名为xxx并绑定AK/SK到指定凭据:
image.png

步骤4.4 测试运行

最后,在Jenkins中运行配置好的任务,检查输出以确保CDN刷新和余量查询均运行顺利。
image.png
image.png

5. 其他的需求

1. 经常输入域名的时候忘记/单斜线,是否可以自动补全?

2. 设置改阈值?剩余量到20可以自动报警?邮件or短信

3. 优雅的pipeline?

结语

通过上述步骤,我们成功地实现了通过Go语言操作华为云CDN刷新服务的功能,并将其集成到Jenkins任务中,同时安全地管理了敏感的AK/SK凭证。这样的自动化工具对于管理大量的CDN资源来说非常有用,可以大大提高工作效率。
注:以上大纲chatgpt生成代码结构也是,代码基本也是chatgpt生成,貌似中间就有几个&指针数据格式有问题修改了一下

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1260213.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

力扣hot100 和为 K 的子数组 前缀和

&#x1f468;‍&#x1f3eb; 题目地址 &#x1f37b; AC code class Solution {public int subarraySum(int[] nums, int k){int ans 0;int n nums.length;int[] s new int[n 1];// 前缀和s[0] 0;s[1] nums[0];for (int i 2; i < n; i)s[i] s[i - 1] nums[i - 1…

Termius 一款优秀的跨平台 SSH 客户端工具

&#x1f525;&#x1f525;&#x1f525; 作为程序员或者运维管理人员&#xff0c;我们经常需要使用终端工具来进行服务器管理及各种操作&#xff0c;比如部署项目、调试代码、查看/优化服务、管理服务器等。 而实现远程服务器连接需要借助 SSH 协议来进行&#xff0c;SSH&am…

Ubuntu知识积累

修改当前Ubuntu环境下时间 sudo date --set "2023-11-21 10:01:00"查看进程 过滤bs开头的进程 ps -aux|grep Bs查看ubuntu系统的磁盘大小 要查看Ubuntu系统的磁盘大小&#xff0c;可以使用df命令。df命令用于报告文件系统的磁盘空间使用情况&#xff0c;包括每个…

ESP32-Web-Server编程- JS 基础 4

ESP32-Web-Server编程- JS 基础 4 概述 HTML 内联事件处理器&#xff0c;你永远不应该使用 HTML 事件处理器属性——因为那些已经过时了&#xff0c;使用它们是不好的做法。 在前端编程中&#xff0c;除了将期望发生的事件写为 JS 文件外&#xff0c;还可以使用一些组件自带…

springboot+vue智能企业设备管理系统05k50

智能设备管理系统主要是为了提高工作人员的工作效率和更方便快捷的满足用户&#xff0c;更好存储所有数据信息及快速方便的检索功能&#xff0c;对系统的各个模块是通过许多今天的发达系统做出合理的分析来确定考虑用户的可操作性&#xff0c;遵循开发的系统优化的原则&#xf…

电子学会C/C++编程等级考试2021年12月(三级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:我家的门牌号 我家住在一条短胡同里,这条胡同的门牌号从1开始顺序编号。 若所有的门牌号之和减去我家门牌号的两倍,恰好等于n,求我家的门牌号及总共有多少家。 数据保证有唯一解。 时间限制:1000 内存限制:65536输入 一个…

艾森股份将上市在即:募资约6亿元,张兵、蔡卡敦夫妇为实控人

11月27日&#xff0c;江苏艾森半导体材料股份有限公司&#xff08;下称“艾森股份”&#xff0c;SH:688720&#xff09;开启申购&#xff0c;将在科创板上市。本次上市&#xff0c;艾森股份的发行价为28.03元/股&#xff0c;发行数量约2203万股&#xff0c;预计募资总额约6.18亿…

C++ :const修饰成员函数

常函数&#xff1a; 常函数&#xff1a; 成员函数后加const后我们称为这个函数为常函数 常函数内不可以修改成员属性 成员属性声明时加关键字mutable后&#xff0c;在常函数中依然可以修改 属性可修改&#xff1a; class Person { public: void showPerson() …

UI自动化测试工具有哪些优势?

UI自动化测试工具通过提高测试效率、覆盖率&#xff0c;减少测试时间和成本&#xff0c;以及支持持续集成等方式&#xff0c;为软件开发团队提供了一系列重要的优势&#xff0c;有助于提升软件质量和开发效率。 自动化执行&#xff1a;UI自动化测试工具可以模拟用户与应用程序的…

访问对象的方式

创建对象自然是为了后续使用该对象&#xff0c;我们的Java程序会通过栈上的reference数据来操作堆上的具体对象。由于reference类型在《Java虚拟机规范》里面只规定了它是一个指向对象的引用&#xff0c;并没有定义这个引用应该通过什么方式去定位、访问到堆中对象的具体位置&a…

C++:OJ练习(每日练习系列)

编程题&#xff1a; 题一&#xff1a;把字符串转换成整数 把字符串转换成整数_牛客题霸_牛客网 示例1 输入&#xff1a; "2147483647" 返回值&#xff1a; 2147483647思路一&#xff1a; 第一步&#xff1a;it从str的第一个字符开始遍历&#xff0c;定义一个最后输…

记录一次如何查询mysql分库分表数据

一、前言 本次查询是在未知如何分库分表的情况下&#xff0c;对表数据进行查询&#xff0c;其中有的字段为JSON结构。需要提取JSON中某个字段的内容。 二、查询步骤 1、第一方式是将所有分表数据进行union all select * from apporder.ord_shopping_order union all sel…

线性分类器--图像表示

整个模型 图像表示 二进制图像 灰度图像 彩色图像 大多数分类算法都要求输入向量&#xff01; rbg的图像矩阵转列向量 大小为 32X32 的话&#xff0c;图像矩阵转列向量是多少维&#xff1f; 32x32x3 3072 维列向量

2024 年应该使用 Bun、Node.js 还是 Deno

2024 年应该使用 Bun、Node.js 还是 Deno 到 2024 年&#xff0c;构建基于 JavaScript 的现代 API 相对简单。我们可以使用Express.js等库并在几分钟内启动可用的 API。但是&#xff0c;现在最具挑战性的部分是选择正确的 JavaScript 引擎。 目前主流的三个运行时是&#xff…

MidJourney笔记(4)-settings

前面已经大概介绍了MidJourney的基础知识,后面我主要是基于实操来分享自己的笔记。可能内容顺序会有点乱,请大家理解。 这次主要是想讲讲settings这个命令。我们只需在控制台输入/settings,然后回车,就可以执行这个命令。 (2023年11月26日版本界面) 可能有些朋友出来的界…

前端OFD文件预览(vue案例cafe-ofd)

0、提示 下面只有vue的使用示例demo &#xff0c;官文档参考 cafe-ofd - npm 其他平台可以参考 ofd - npm 官方线上demo: ofd 1、安装包 npm install cafe-ofd --save 2、引入 import cafeOfd from cafe-ofd import cafe-ofd/package/index.css Vue.use(cafeOfd) 3、使…

unity UGUI中获取点击位置处的URL链接

需求是&#xff0c;我们在一个text组件中像写网页那样写入链接&#xff0c;然后点击这个链接&#xff0c;就能访问配置的网页啥的。比如&#xff1a; <a href"hello">链接文本</a></summary> 最终的效果如下&#xff1a; 图中&#xff0c;image区…

血的教训------入侵redis之利用python来破解redis密码

血的教训------入侵redis之利用python来破解redis密码 利用强大的python来进行redis的密码破解&#xff0c;过程不亦乐乎&#xff0c;当然也可以用shell脚本 本篇文章只供学习交流&#xff0c;请勿他用&#xff0c;谢谢。 其他相关联的文章 [1]VMware安装部署kail镜像服务器【…

WPS Office JS宏实现批量处理Word中的表格样式

由于本职工作原因&#xff0c;经常会用到office办公软件&#xff0c;经常很多内容审批后&#xff0c;需要统一修改内容或样式&#xff0c;如果Word文档中有上百页或上千页&#xff0c;则一个一个修改太麻烦了。 在接触到WPSJS宏后&#xff0c;发现工作效率大大提升&#xff1b;…

Python字典合并

合并两个有部分key相同的字典&#xff0c;相同key保留两个字典中对应key的较大值。 (笔记模板由python脚本于2023年11月27日 18:12:15创建&#xff0c;本篇笔记适合熟悉Python字典的coder翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org/ Fr…