package main

import (
	"encoding/base64"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"strings"
)

type Image struct {
	Architecture string `json:"architecture"`
	Digest       string `json:"digest"`
	ImageID      string `json:"imageId"`
	ImageName    string `json:"imageName"`
	ImageTag     string `json:"imageTag"`
	Os           string `json:"os"`
	Size         int    `json:"size"`
}

type Repository struct {
	Namespace string  `json:"namespace"`
	RepoName  string  `json:"repoName"`
	RepoFull  string  `json:"repoFullName"`
	RepoType  string  `json:"repoType"`
	Summary   Summary `json:"summary"`
}

type Summary struct {
	ImageCount int64 `json:"imageCount"`
	TotalSize  int64 `json:"totalSize"`
}

func main() {
	accessKeyId := "your_access_key_id"
	accessKeySecret := "your_access_key_secret"
	endpoint := "https://registry.cn-hangzhou.aliyuncs.com"
	namespace := "your_namespace"
	repoName := "your_repo_name"

	// get token
	tokenUrl := fmt.Sprintf("https://%s/token?namespace=%s&access_token=1&service=registry.aliyuncs.com", endpoint, namespace)
	tokenResp, err := http.Get(tokenUrl)
	if err != nil {
		fmt.Println("get token error:", err)
		return
	}
	defer tokenResp.Body.Close()
	tokenBody, err := ioutil.ReadAll(tokenResp.Body)
	if err != nil {
		fmt.Println("read token body error:", err)
		return
	}
	var tokenMap map[string]string
	err = json.Unmarshal(tokenBody, &tokenMap)
	if err != nil {
		fmt.Println("unmarshal token body error:", err)
		return
	}
	token := tokenMap["token"]

	// get repo info
	repoUrl := fmt.Sprintf("https://%s/v2/%s/%s/?last=0", endpoint, namespace, repoName)
	req, err := http.NewRequest("GET", repoUrl, nil)
	if err != nil {
		fmt.Println("new request error:", err)
		return
	}
	req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token))
	client := &http.Client{}
	repoResp, err := client.Do(req)
	if err != nil {
		fmt.Println("get repo info error:", err)
		return
	}
	defer repoResp.Body.Close()
	repoBody, err := ioutil.ReadAll(repoResp.Body)
	if err != nil {
		fmt.Println("read repo body error:", err)
		return
	}
	var repoMap map[string]interface{}
	err = json.Unmarshal(repoBody, &repoMap)
	if err != nil {
		fmt.Println("unmarshal repo body error:", err)
		return
	}
	repoInfo := Repository{
		Namespace: namespace,
		RepoName:  repoName,
		RepoFull:  fmt.Sprintf("%s/%s", namespace, repoName),
		RepoType:  "public",
		Summary: Summary{
			ImageCount: int64(repoMap["catalog"].(float64)),
			TotalSize:  0,
		},
	}

	// get image info
	imageUrl := fmt.Sprintf("https://%s/v2/%s/%s/tags/list", endpoint, namespace, repoName)
	imageReq, err := http.NewRequest("GET", imageUrl, nil)
	if err != nil {
		fmt.Println("new request error:", err)
		return
	}
	imageReq.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token))
	imageClient := &http.Client{}
	imageResp, err := imageClient.Do(imageReq)
	if err != nil {
		fmt.Println("get image info error:", err)
		return
	}
	defer imageResp.Body.Close()
	imageBody, err := ioutil.ReadAll(imageResp.Body)
	if err != nil {
		fmt.Println("read image body error:", err)
		return
	}
	var imageMap map[string]interface{}
	err = json.Unmarshal(imageBody, &imageMap)
	if err != nil {
		fmt.Println("unmarshal image body error:", err)
		return
	}
	imageList := imageMap["tags"].([]interface{})
	for _, imageName := range imageList {
		imageUrl := fmt.Sprintf("https://%s/v2/%s/%s/manifests/%s", endpoint, namespace, repoName, imageName.(string))
		req, err := http.NewRequest("GET", imageUrl, nil)
		if err != nil {
			fmt.Println("new request error:", err)
			return
		}
		req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token))
		req.Header.Set("Accept", "application/vnd.docker.distribution.manifest.v2+json")
		client := &http.Client{}
		resp, err := client.Do(req)
		if err != nil {
			fmt.Println("get image info error:", err)
			return
		}
		defer resp.Body.Close()
		body, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			fmt.Println("read body error:", err)
			return
		}
		var manifestMap map[string]interface{}
		err = json.Unmarshal(body, &manifestMap)
		if err != nil {
			fmt.Println("unmarshal manifest error:", err)
			return
		}
		configDigest := manifestMap["config"].(map[string]interface{})["digest"].(string)
		configUrl := fmt.Sprintf("https://%s/v2/%s/%s/blobs/%s", endpoint, namespace, repoName, configDigest)
		configReq, err := http.NewRequest("GET", configUrl, nil)
		if err != nil {
			fmt.Println("new request error:", err)
			return
		}
		configReq.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token))
		configClient := &http.Client{}
		configResp, err := configClient.Do(configReq)
		if err != nil {
			fmt.Println("get config error:", err)
			return
		}
		defer configResp.Body.Close()
		configBody, err := ioutil.ReadAll(configResp.Body)
		if err != nil {
			fmt.Println("read config body error:", err)
			return
		}
		var configMap map[string]interface{}
		err = json.Unmarshal(configBody, &configMap)
		if err != nil {
			fmt.Println("unmarshal config body error:", err)
			return
		}
		image := Image{
			Architecture: configMap["architecture"].(string),
			Digest:       manifestMap["config"].(map[string]interface{})["digest"].(string),
			ImageID:      manifestMap["config"].(map[string]interface{})["digest"].(string),
			ImageName:    fmt.Sprintf("%s/%s:%s", namespace, repoName, imageName),
			ImageTag:     imageName.(string),
			Os:           configMap["os"].(string),
			Size:         int(configMap["size"].(float64)),
		}
		repoInfo.Summary.TotalSize += int64(image.Size)
		fmt.Println(image)
	}

	fmt.Println(repoInfo)
}

注意事项:

  1. 需要替换 your_access_key_idyour_access_key_secret 为自己的 access key id 和 access key secret。
  2. 需要替换 your_namespaceyour_repo_name 为自己的镜像仓库命名空间和镜像仓库名称。
  3. 需要安装 github.com/json-iterator/go
请用golang写一个调用阿里云docker api方法获取镜像的所有信息方法

原文地址: https://www.cveoy.top/t/topic/fnak 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录