当前位置: 首页 > article >正文

go语言调用s3接口通过rgw节点创建ceph用户

这段 Go 代码是用于创建 Ceph 用户并获取其 S3 访问密钥的示例。已经过实际应用可以直接拿来使用

导入的包 

import (
	"crypto/hmac"
	"crypto/sha1"
	"encoding/json"
	"net/http"
	"net/url"
	"fmt"
	"io"
	"time"
	"errors"
	"encoding/base64"
)

这些包提供了加密、网络请求、时间处理、输入输出等功能,是实现本功能所必需的。

辅助函数:makeHMac

func makeHMac(key []byte, data []byte) []byte {
	hash := hmac.New(sha1.New, key)
	hash.Write(data)
	return hash.Sum(nil)
}

这个函数用于生成 HMAC(Hash-based Message Authentication Code),这是一种用于消息认证的安全码,可以防止信息被篡改。

数据结构定义

type Response struct {
	Keys []Credentials `json:"keys"`
}

type Credentials struct {
	AccessKey string `json:"access_key"`
	SecretKey string `json:"secret_key"`
	User      string `json:"user"`
}

Response 和 Credentials 结构体用于解析从 Ceph 返回的 JSON 数据。这些数据包含了用户的访问密钥和密钥。

主函数:CreateCephUser

func CreateCephUser(uid, display, email, accessKey, secretKey string) (s3key, secret string, err error) {
	...
}

这个函数接受用户 ID、显示名、电子邮件地址以及可选的访问密钥和密钥,返回新创建的 S3 访问密钥和密钥。

构建请求 URL

baseURL := "http://192.168.1.224:80/admin/user?format=json"
u, err := url.Parse(baseURL)
...
queryParams := url.Values{}
...
u.RawQuery = queryParams.Encode()

这部分代码构建了一个 HTTP 请求的 URL,包括必要的查询参数。

创建和发送 HTTP 请求

req, err := http.NewRequest("PUT", u.String(), nil)
...
signature := makeHMac([]byte(cephConn.Secret), []byte(strToSign))
...
resp, err := client.Do(req)

这里创建了一个 HTTP PUT 请求,用于向 Ceph 发送创建用户的命令。请求中包含了通过 HMAC 签名的授权头,确保请求的安全性。 

处理响应 

bodyBytes, err := io.ReadAll(resp.Body)
...
var response Response
if err := json.Unmarshal(bodyBytes, &response); err != nil {
	...
}

完整代码如下:

 

package ceph

import (
	"crypto/hmac"
	"crypto/sha1"
	"encoding/json"
	"net/http"
	"net/url"
	"fmt"
	"io"
	"time"
	"errors"
	"encoding/base64"
)

func makeHMac(key []byte, data []byte) []byte {
	hash := hmac.New(sha1.New, key)
	hash.Write(data)
	return hash.Sum(nil)
}

type Response struct {
	Keys []Credentials `json:"keys"`
}

type Credentials struct {
	AccessKey string `json:"access_key"`
	SecretKey string `json:"secret_key"`
	User      string `json:"user"`
}


func CreateCephUser(uid, display, email, accessKey, secretKey string) (s3key, secret string, err error){
	// session = GetCephAdminConn()
	client := &http.Client{}

	//url
	baseURL := "http://192.168.1.224:80/admin/user?format=json"

	// 创建 URL 对象
	u, err := url.Parse(baseURL)
	if err != nil {
		//.GetLogger().Errorf("Error parsing base URL: %v", err)
		return "", "", err
	}

	// 创建 URL 查询参数
	queryParams := url.Values{}
	queryParams.Add("uid", uid)
	queryParams.Add("display-name", display)
	queryParams.Add("email", email)
	queryParams.Add("user-caps", "usage=read;users=read;buckets=read,write;metadata=read")
	if accessKey != "" && secretKey != "" {
		queryParams.Add("access-key", accessKey)
		queryParams.Add("secret-key", secretKey)
	}

	// 将查询参数添加到 URL
	u.RawQuery = queryParams.Encode()

	// 创建请求
	req, err := http.NewRequest("PUT", u.String(), nil)
	if err != nil {
		//.GetLogger().Errorf("Error creating request: %v", err)
		return "", "", err
	}

	// 生成签名
	utcTime := time.Now().UTC()
	timestamp := utcTime.Format("Mon, 2 Jan 2006 15:04:05") + " +0000"
	strToSign := "PUT\n\n\n" + timestamp + "\n/admin/user"
	signature := makeHMac([]byte(cephConn.Secret), []byte(strToSign))

	req.Header.Add("Date", timestamp)
	req.Header.Add("Authorization", "AWS "+cephConn.S3key+":"+base64.StdEncoding.EncodeToString(signature))

	resp, err := client.Do(req)
	if err != nil {
		//your_logger_package.GetLogger().Errorf("Error sending request: %v", err)
		return "", "", err
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		//bodyBytes, _ := io.ReadAll(resp.Body)
		//your_logger_package.GetLogger().Warnf("Request not ok with status: %d, body: %s", resp.StatusCode, string(bodyBytes))
		return "", "", fmt.Errorf("request failed with status: %d", resp.StatusCode)
	}

	// 读取响应体内容
	bodyBytes, err := io.ReadAll(resp.Body)
	if err != nil {
		//your_logger_package.GetLogger().Errorf("Error reading response body: %v", err)
		return "", "", err
	}

	// 解析响应内容
	var response Response
	if err := json.Unmarshal(bodyBytes, &response); err != nil {
		//your_logger_package.GetLogger().Errorf("Error parsing response: %v", err)
		return "", "", err
	}

	if len(response.Keys) > 0 {
		s3key = response.Keys[0].AccessKey
		secret = response.Keys[0].SecretKey
	} else {
		return "", "", errors.New("no keys found in the response")
	}

	return s3key, secret, nil
}

由此我们可以衍生出对ceph的上传,下载,删除等功能函数,如下:

func (session *StorageSession) UploadObject(objectKey string, content []byte) error
func (session *StorageSession) DeleteObject(key string) error
func (session *StorageSession) DownloadObject(objectKey string)

完整的函数实现放在网盘了,自取:https://pan.quark.cn/s/d0a005cfb3ae


http://www.kler.cn/a/470214.html

相关文章:

  • Sam Altman发布博客,回顾OpenAI九年历程,直言目标已瞄准ASI超级人工智能
  • 人工智能训练师一级(高级技师)、二级(技师)考试指南
  • 数据传送类指令
  • 企业国外传输大文件到国内该怎么做?
  • 微服务保护—Sentinel快速入门+微服务整合 示例: 黑马商城
  • GoF23种设计模式 简介
  • 聚焦“主动医学”新路径 助力科技与医疗深度融合
  • 【数据结构与算法:八、排序】
  • HackMyVM-Alive靶机的测试报告
  • 通过shell脚本定时采集数据到HDFS
  • 深度学习,训练集准确率高,但验证集准确率一直不上升,很低的问题
  • 【人工智能中的数据科学与数据处理】——详解人工智能中的数据科学与数据处理之数据可视化技巧
  • 算法:两个升序单链表的合并
  • 起重机检测数据集VOC+YOLO格式2316张1类别
  • Adaboost:基于弱学习器组合实现强大性能提升的集成学习方法解析
  • 密码学基本理论
  • YOLOV8涨点之多尺度注意力融合(MAF)模块
  • 【异常解决】Unable to start embedded Tomcat Nacos 启动报错
  • 番外篇-CSS3新增特性
  • Nginx:反向代理
  • zephyr移植到STM32
  • 【昌哥IT课堂】MySQL8.0新特性之binlog加密与解密
  • 力扣leetcode 77 - 组合 C语言解法 递归+回溯
  • 用 HTML5 Canvas 和 JavaScript 实现流星雨特效
  • ENSP综合实验(中小型网络)
  • 解决电脑开机PcaSvc.dll出错丢失条目:PcaWallpaperAppDetect最新方法