From 284d6c2d5b75a589f1f8e007e68616a125e71ec8 Mon Sep 17 00:00:00 2001 From: yangwei999 <348134071@qq.com> Date: Thu, 23 May 2024 11:04:03 +0800 Subject: [PATCH 01/29] collect data ok --- cve-vulner-manager/conf/product_app.conf | 4 +- .../cve-ddd/adapter/hotpatch.go | 2 + cve-vulner-manager/cve-ddd/app/coldpatch.go | 369 ++++ .../cve-ddd/app/coldpatch_dto.go | 7 + cve-vulner-manager/cve-ddd/app/concurrency.go | 95 + cve-vulner-manager/cve-ddd/app/hotpatch.go | 25 +- .../cve-ddd/domain/backend/backend.go | 5 + .../cve-ddd/domain/bulletin/bulletin.go | 3 +- .../cve-ddd/domain/bulletins.go | 2 +- cve-vulner-manager/cve-ddd/domain/callback.go | 56 + cve-vulner-manager/cve-ddd/domain/collect.go | 51 + cve-vulner-manager/cve-ddd/domain/config.go | 9 + .../cve-ddd/domain/{cve.go => issue.go} | 28 +- .../cve-ddd/domain/latestrpm/rpm.go | 8 + .../cve-ddd/domain/majun/majun.go | 6 + cve-vulner-manager/cve-ddd/domain/obs/obs.go | 1 + .../cve-ddd/domain/repository/cve.go | 14 +- .../cve-ddd/domain/updateinfo/updateinfo.go | 1 + .../infrastructure/backendimpl/impl.go | 59 + .../infrastructure/bulletinimpl/impl.go | 6 +- .../infrastructure/bulletinimpl/xml.go | 3 +- .../infrastructure/latestrpmimpl/impl.go | 112 ++ .../cve-ddd/infrastructure/majunimpl/impl.go | 151 ++ .../cve-ddd/infrastructure/obsimpl/impl.go | 11 + .../infrastructure/repositoryimpl/callback.go | 101 ++ .../infrastructure/repositoryimpl/impl.go | 77 +- .../updateinfoimpl/collect_excel.go | 77 + cve-vulner-manager/go.mod | 17 +- cve-vulner-manager/go.sum | 1554 ++++++++++++++++- cve-vulner-manager/models/initdb.go | 6 +- cve-vulner-manager/models/modeldb.go | 20 + 31 files changed, 2835 insertions(+), 45 deletions(-) create mode 100644 cve-vulner-manager/cve-ddd/app/coldpatch.go create mode 100644 cve-vulner-manager/cve-ddd/app/coldpatch_dto.go create mode 100644 cve-vulner-manager/cve-ddd/app/concurrency.go create mode 100644 cve-vulner-manager/cve-ddd/domain/backend/backend.go create mode 100644 cve-vulner-manager/cve-ddd/domain/callback.go create mode 100644 cve-vulner-manager/cve-ddd/domain/collect.go create mode 100644 cve-vulner-manager/cve-ddd/domain/config.go rename cve-vulner-manager/cve-ddd/domain/{cve.go => issue.go} (77%) create mode 100644 cve-vulner-manager/cve-ddd/domain/latestrpm/rpm.go create mode 100644 cve-vulner-manager/cve-ddd/domain/majun/majun.go create mode 100644 cve-vulner-manager/cve-ddd/infrastructure/backendimpl/impl.go create mode 100644 cve-vulner-manager/cve-ddd/infrastructure/latestrpmimpl/impl.go create mode 100644 cve-vulner-manager/cve-ddd/infrastructure/majunimpl/impl.go create mode 100644 cve-vulner-manager/cve-ddd/infrastructure/repositoryimpl/callback.go create mode 100644 cve-vulner-manager/cve-ddd/infrastructure/updateinfoimpl/collect_excel.go diff --git a/cve-vulner-manager/conf/product_app.conf b/cve-vulner-manager/conf/product_app.conf index c71ec62..59d6324 100644 --- a/cve-vulner-manager/conf/product_app.conf +++ b/cve-vulner-manager/conf/product_app.conf @@ -280,4 +280,6 @@ openlookeng_version = "master" [majun] token = "${GITEE_MAJUN_TOKEN||xxx}" -api_token = "${MAJUN_API_TOKEN||xxx}" \ No newline at end of file +api_token = "${MAJUN_API_TOKEN||xxx}" +app_id = "${MAJUN_APP_ID||xxx}" +secret_key = "${MAJUN_SECRET_KEY||xxx}" \ No newline at end of file diff --git a/cve-vulner-manager/cve-ddd/adapter/hotpatch.go b/cve-vulner-manager/cve-ddd/adapter/hotpatch.go index 20b7805..c913d80 100644 --- a/cve-vulner-manager/cve-ddd/adapter/hotpatch.go +++ b/cve-vulner-manager/cve-ddd/adapter/hotpatch.go @@ -15,6 +15,7 @@ import ( "cvevulner/cve-ddd/app" "cvevulner/cve-ddd/infrastructure/bulletinimpl" + "cvevulner/cve-ddd/infrastructure/majunimpl" "cvevulner/cve-ddd/infrastructure/obsimpl" "cvevulner/cve-ddd/infrastructure/repositoryimpl" "cvevulner/cve-ddd/infrastructure/updateinfoimpl" @@ -39,6 +40,7 @@ func NewHotPatchAdapter() *hotPatch { bulletinimpl.NewBulletinImpl(), obsimpl.Instance(), updateinfoimpl.NewUpdateInfoImpl(), + majunimpl.NewMajunImpl(), ), } } diff --git a/cve-vulner-manager/cve-ddd/app/coldpatch.go b/cve-vulner-manager/cve-ddd/app/coldpatch.go new file mode 100644 index 0000000..53bbbe3 --- /dev/null +++ b/cve-vulner-manager/cve-ddd/app/coldpatch.go @@ -0,0 +1,369 @@ +package app + +import ( + "encoding/json" + "fmt" + "net/http" + "strings" + "sync" + "time" + + "github.com/astaxie/beego" + "github.com/opensourceways/server-common-lib/utils" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/util/sets" + + sdk "github.com/opensourceways/go-gitee/gitee" + + "cvevulner/cve-ddd/domain" + "cvevulner/cve-ddd/domain/backend" + "cvevulner/cve-ddd/domain/bulletin" + "cvevulner/cve-ddd/domain/latestrpm" + "cvevulner/cve-ddd/domain/majun" + "cvevulner/cve-ddd/domain/obs" + "cvevulner/cve-ddd/domain/repository" + "cvevulner/cve-ddd/domain/updateinfo" +) + +const ( + defaultOwner = "src-openeuler" + mergedState = "merged" +) + +var releaseDate sync.Map + +type ColdPatchService interface { + CollectCveData(CmdToCollectData) error + GenerateBulletins([]string, string) error +} + +func NewColdPatchService( + rpm latestrpm.LatestRpm, + repo repository.CveRepository, + b bulletin.Bulletin, + backend backend.Backend, + u updateinfo.UpdateInfo, + o obs.OBS, + m majun.Majun, +) *coldPatchService { + initReleaseDate() + + log := logrus.New().WithField("module", "new-security-bulletin") + + return &coldPatchService{ + obs: o, + rpm: rpm, + repo: repo, + majun: m, + bulletin: b, + backend: backend, + updateInfo: u, + log: log, + giteeToken: beego.AppConfig.String("gitee::git_token"), + } +} + +type coldPatchService struct { + obs obs.OBS + rpm latestrpm.LatestRpm + repo repository.CveRepository + majun majun.Majun + bulletin bulletin.Bulletin + backend backend.Backend + updateInfo updateinfo.UpdateInfo + + lock sync.Mutex + log *logrus.Entry + + giteeToken string +} + +// CollectCveData 数据收集接口背景: +// 1.由于数据收集任务十分耗时,只能采用异步回调的方式给调用方数据 +// 2.调用方只能按照分支分次调用,但对于收集数据逻辑来说,单个分支和全部分支的执行时间没有区别,为了提高效率,采用一次请求全量收集的方式 +// 3.调用方的请求不是串行的,可能在首次收集任务未执行完时,另外的请求就到来,因此将请求数据落库,收集完成之后统一进行处理 +// 4.调用方通过CallbackId来关联分支,因此也需要写入数据库进行记录 +func (c *coldPatchService) CollectCveData(cmd CmdToCollectData) error { + callback := domain.Callback{ + Date: cmd.Date, + Branch: cmd.Branch, + CallbackId: cmd.CallbackId, + } + callback.SetStatusProcessing() + + // 只记录错误日志,通过数据库唯一索引约束,避免重复任务 + if err := c.repo.AddCallback(callback); err != nil { + c.log.Errorf("add callback failed: %v", err) + } + + go func() { + // 防止全量收集逻辑被重复执行 + c.lock.Lock() + defer c.lock.Unlock() + + defer func() { + if r := recover(); r != nil { + c.log.Errorf("handle collect panic: %v", r) + } + }() + + _, err := c.repo.FindCollectResult("", cmd.Date) + if err != nil { + if err = c.generateCollectResult(cmd.Date); err != nil { + c.log.Errorf("generate collect result failed: %v", err) + + return + } + } + + if err = c.handleAllCollectData(); err != nil { + c.log.Errorf("handle all callback failed: %v", err) + } + }() + + select {} + return nil +} + +func (c *coldPatchService) generateCollectResult(date string) error { + dataGroupByBranch, err := c.collectAllData() + if err != nil { + return fmt.Errorf("collect all data failed: %w", err) + } + + // 生成表格并上传obs,方便相关人员查看收集的数据明细(错误只记录,不影响主要逻辑) + excelData, err := c.updateInfo.GenerateCollectExcel(dataGroupByBranch) + if err != nil { + c.log.Errorf("generate excel data failed: %v", err) + } else { + if err = c.obs.Upload(c.generateFilePath(), excelData); err != nil { + c.log.Errorf("upload excel to obs failed: %v", err) + } + } + + // 按分支保存数据库,待后续统一执行回调 + for branch, data := range dataGroupByBranch { + dto := domain.ToCallbackDTO(data) + result, err := json.Marshal(dto) // 数据都是整体使用,且只使用一次,直接序列化后入库,简化逻辑 + if err != nil { + c.log.Errorf("marshal callback dto failed: %v", err) + + continue + } + + cr := domain.CollectResult{ + Branch: branch, + Date: date, + Result: string(result), + } + + if err := c.repo.SaveCollectResult(cr); err != nil { + c.log.Errorf("save collect result failed: %v", err) + } + } + + return nil +} + +func (c *coldPatchService) handleAllCollectData() error { + callbacks, err := c.repo.GetProcessingCallback() + if err != nil { + return err + } + + for _, callback := range callbacks { + _, err1 := c.repo.FindCollectResult(callback.Branch, callback.Date) + if err1 != nil { + c.log.Errorf("find calback result failed: %v", err1) + continue + } + + //if err1 = c.majun.CollectCallback(callback.CallbackId, result); err1 != nil { + // c.log.Errorf("collect callback failed: %v", err1) + // continue + //} + + callback.SetStatusProcessed() + if err1 = c.repo.UpdateCallback(callback); err1 != nil { + c.log.Errorf("update callback failed: %v", err1) + } + } + + return nil +} + +func (c *coldPatchService) collectAllData() (map[string]domain.CollectedDataSlice, error) { + handleBranch, err := c.majun.GetReleasedBranch() + if err != nil { + return nil, fmt.Errorf("get release branch err: %w", err) + } + + issueData, err := c.repo.GetAllIssue() + if err != nil { + return nil, fmt.Errorf("get all issue data err: %w", err) + } + + allPackage, err := c.repo.GetAllPackage() + if err != nil { + return nil, fmt.Errorf("get all package err: %w", err) + } + + if err = c.rpm.InitData(handleBranch); err != nil { + return nil, fmt.Errorf("init rpm data failed:%w", err) + } + + // filter data concurrently + concurrencyInstance := NewConcurrency(c, issueData, sets.New(allPackage...), sets.New(handleBranch...)) + filteredData := concurrencyInstance.handleFilterData() + + return filteredData.GroupByBranch(handleBranch), nil +} + +func (c *coldPatchService) GenerateBulletins(cveNum []string, date string) error { + handleBranch, err := c.majun.GetReleasedBranch() + if err != nil { + return fmt.Errorf("get release branch err: %w", err) + } + + domain.InitMaintainVersion(handleBranch) + + return nil +} + +func (c *coldPatchService) generateFilePath() string { + dir := beego.AppConfig.String("obs::upload_updateinfo_dir") + + nowStr := time.Now().Format("2006-01-02-15-04-05") + + return fmt.Sprintf("%s%s/collect.xlsx", dir, nowStr) +} + +// 过滤issue的条件主要有6个,代码中注释已列出 +func (c *coldPatchService) filterData( + data *domain.CollectedData, + handleBranchSets, + packageSets sets.Set[string], +) (bool, error) { + if len(data.AffectedProduct) == 0 { + return true, nil + } + // 1.issue受影响分支与处理分支必须有交集才处理 + //(受影响分支来自issue的开发人员填写,issue信息经webhook回调时,会更新至cve_security_notice表) + intersection := handleBranchSets.Intersection(data.AffectProductSet()) + if intersection.Len() == 0 { + return true, nil + } + + // 2.不在软件包列表(定时更新的openeuler用到的软件包)的不处理 + if !packageSets.Has(data.Issue.Repo) { + return true, nil + } + + prs, _, err := c.getRelatedPR(data.Issue) + if err != nil { + return false, fmt.Errorf("get related pr of %s err: %w", data.ToLogString(), err) + } + + if len(prs) == 0 { + return true, nil + } + + needToHandleBranch := make(sets.Set[string]) + for _, pr := range prs { + if pr.State != mergedState { + continue + } + + // pr合入的目标分支 + branch := pr.Base.Ref + + // 同1,过滤无关分支 + if !intersection.Has(branch) { + continue + } + + mergeAt, err1 := time.ParseInLocation("2006-01-02T15:04:05+08:00", pr.MergedAt, time.Local) + if err1 != nil { + continue + } + + // 3.pr合入时间超过半年的不处理(为了减少数据量) + sixMonthAgo := time.Now().AddDate(0, -6, 0) + if !mergeAt.After(sixMonthAgo) { + c.log.Errorf("pr merge time of %s %s check failed", branch, data.ToLogString()) + continue + } + + buildTime, err1 := c.rpm.GetBuildTime(branch, data.Issue.Repo) + if err1 != nil { + c.log.Errorf("get build time of %s %s error:%v", branch, data.ToLogString(), err1) + continue + } + + // 4.pr合入时间必须在工程构建时间之后(pr合入后,工程会重新构建,并上传至latest_rpms仓库,如果工程因其他原因未构建,就不需要转测了) + if !buildTime.After(mergeAt) { + c.log.Errorf("build time check failed of %s %s", branch, data.ToLogString()) + continue + } + + // 5.在版本分支发布日期之前合入的pr不处理,因为已经随着新版本一起发布并修复了 + releaseTimeOfBranch, ok := releaseDate.Load(branch) + if ok { + releaseTime := releaseTimeOfBranch.(time.Time) + if releaseTime.After(mergeAt) { + _ = c.repo.SetIgnoreStatus(data.Id) + continue + } + } + + needToHandleBranch.Insert(branch) + } + + publishedBranch, err := c.backend.PublishedInfo(data.CveNum, data.Issue.Repo) + if err != nil { + err = fmt.Errorf("get published info of %s error:%w", data.ToLogString(), err) + + return false, err + } + + // 6.已经发布到官网的分支不用再处理了 + publishSets := sets.New(publishedBranch...) + diff := needToHandleBranch.Difference(publishSets) + if len(diff) == 0 { + return true, nil + } + + data.AffectedProduct = diff.UnsortedList() + + return false, nil +} + +func (c *coldPatchService) getRelatedPR(issue domain.Issue) (prs []sdk.PullRequest, code int, err error) { + endpoint := fmt.Sprintf("https://gitee.com/api/v5/repos/%v/issues/%v/pull_requests?access_token=%s&repo=%s", + defaultOwner, issue.Number, c.giteeToken, issue.Repo, + ) + req, err := http.NewRequest(http.MethodGet, endpoint, nil) + if err != nil { + return + } + + cli := utils.NewHttpClient(3) + bytes, code, err := cli.Download(req) + if err != nil { + return + } + + err = json.Unmarshal(bytes, &prs) + + return +} + +func initReleaseDate() { + releaseDateConfig := beego.AppConfig.DefaultString("excel::release_date_of_version", "") + for _, v := range strings.Split(strings.Trim(releaseDateConfig, ";"), ";") { + split := strings.Split(v, ":") + key := split[0] + value, _ := time.ParseInLocation("2006-01-02", split[1], time.Local) + releaseDate.Store(key, value.AddDate(0, 0, 1)) + } +} diff --git a/cve-vulner-manager/cve-ddd/app/coldpatch_dto.go b/cve-vulner-manager/cve-ddd/app/coldpatch_dto.go new file mode 100644 index 0000000..d490c93 --- /dev/null +++ b/cve-vulner-manager/cve-ddd/app/coldpatch_dto.go @@ -0,0 +1,7 @@ +package app + +type CmdToCollectData struct { + Branch string + Date string + CallbackId string +} diff --git a/cve-vulner-manager/cve-ddd/app/concurrency.go b/cve-vulner-manager/cve-ddd/app/concurrency.go new file mode 100644 index 0000000..e4514c2 --- /dev/null +++ b/cve-vulner-manager/cve-ddd/app/concurrency.go @@ -0,0 +1,95 @@ +package app + +import ( + "sync" + + "k8s.io/apimachinery/pkg/util/sets" + + "cvevulner/cve-ddd/domain" +) + +const concurrentNum = 10 + +func NewConcurrency(c *coldPatchService, d domain.CollectedDataSlice, p, h sets.Set[string]) *concurrency { + return &concurrency{ + data: d, + coldPatch: c, + packageSets: p, + handleBranchSets: h, + taskChan: make(chan domain.CollectedData, len(d)), + filteredChan: make(chan domain.CollectedData, len(d)), + } +} + +type concurrency struct { + data domain.CollectedDataSlice + coldPatch *coldPatchService + packageSets sets.Set[string] + handleBranchSets sets.Set[string] + + wg sync.WaitGroup + taskChan chan domain.CollectedData + filteredChan chan domain.CollectedData +} + +func (c *concurrency) handleFilterData() domain.CollectedDataSlice { + c.sendTask() + + c.handleTask() + + c.waitJob() + + return c.receiveData() +} + +func (c *concurrency) handleTask() { + for i := 1; i <= concurrentNum; i++ { + c.wg.Add(1) + + go func() { + defer c.recovery() + defer c.wg.Done() + + for v := range c.taskChan { + skip, err := c.coldPatch.filterData(&v, c.handleBranchSets, c.packageSets) + if err != nil { + c.coldPatch.log.Errorf("filter data %s failed:%v", v.CveNum, err) + continue + } + if skip { + continue + } + + c.filteredChan <- v + } + }() + } +} + +func (c *concurrency) sendTask() { + for _, v := range c.data { + c.taskChan <- v + } + + close(c.taskChan) +} + +func (c *concurrency) waitJob() { + c.wg.Wait() + close(c.filteredChan) +} + +func (c *concurrency) receiveData() domain.CollectedDataSlice { + var filteredIssueData []domain.CollectedData + for v := range c.filteredChan { + filteredIssueData = append(filteredIssueData, v) + } + + return filteredIssueData +} + +func (c *concurrency) recovery() { + if r := recover(); r != nil { + c.coldPatch.log.Errorf("handle filter data panic %v", r) + } +} diff --git a/cve-vulner-manager/cve-ddd/app/hotpatch.go b/cve-vulner-manager/cve-ddd/app/hotpatch.go index d3dd3d6..7c25b2a 100644 --- a/cve-vulner-manager/cve-ddd/app/hotpatch.go +++ b/cve-vulner-manager/cve-ddd/app/hotpatch.go @@ -10,6 +10,7 @@ import ( "cvevulner/cve-ddd/domain" "cvevulner/cve-ddd/domain/bulletin" + "cvevulner/cve-ddd/domain/majun" "cvevulner/cve-ddd/domain/obs" "cvevulner/cve-ddd/domain/repository" "cvevulner/cve-ddd/domain/updateinfo" @@ -26,13 +27,19 @@ type HotPatchService interface { GenerateBulletins([]CmdToGenerateBulletins) error } -func NewHotPatchService(r repository.CveRepository, b bulletin.Bulletin, o obs.OBS, u updateinfo.UpdateInfo, +func NewHotPatchService( + r repository.CveRepository, + b bulletin.Bulletin, + o obs.OBS, + u updateinfo.UpdateInfo, + m majun.Majun, ) *hotPatchService { return &hotPatchService{ repository: r, bulletin: b, obs: o, updateInfo: u, + majun: m, } } @@ -41,9 +48,17 @@ type hotPatchService struct { bulletin bulletin.Bulletin obs obs.OBS updateInfo updateinfo.UpdateInfo + majun majun.Majun } func (h *hotPatchService) GenerateBulletins(cmds []CmdToGenerateBulletins) error { + handleBranch, err := h.majun.GetReleasedBranch() + if err != nil { + return fmt.Errorf("get release branch err: %w", err) + } + + domain.InitMaintainVersion(handleBranch) + var cvesForUpdateInfo domain.Cves var uploadFileName []string id, err := h.generateBulletinId() @@ -58,9 +73,8 @@ func (h *hotPatchService) GenerateBulletins(cmds []CmdToGenerateBulletins) error cves, err := h.repository.FindCves( repository.Option{ - CveNum: cmd.CveNum, - Component: cmd.Component, - AffectedVersion: cmd.Branch, + CveNum: cmd.CveNum, + Component: cmd.Component, }) if err != nil { logs.Error("find cve %s, error %s", cmd.CveNum, err.Error()) @@ -73,6 +87,7 @@ func (h *hotPatchService) GenerateBulletins(cmds []CmdToGenerateBulletins) error // all cves have the same hot issue number for k := range cves { cves[k].HotIssueNum = cmd.HotIssueNum + cves[k].AffectedVersion = []string{cmd.Branch} } bulletins := cves.GenerateBulletins() @@ -82,7 +97,7 @@ func (h *hotPatchService) GenerateBulletins(cmds []CmdToGenerateBulletins) error id++ b.Identification = fmt.Sprintf("openEuler-HotPatchSA-%d-%d", util.Year(), id) - xmlData, err := h.bulletin.Generate(&b) + xmlData, err := h.bulletin.GenerateHotPatch(&b) if err != nil { logs.Error("component: %s, to xml error: %s", b.Component, err.Error()) diff --git a/cve-vulner-manager/cve-ddd/domain/backend/backend.go b/cve-vulner-manager/cve-ddd/domain/backend/backend.go new file mode 100644 index 0000000..d59772c --- /dev/null +++ b/cve-vulner-manager/cve-ddd/domain/backend/backend.go @@ -0,0 +1,5 @@ +package backend + +type Backend interface { + PublishedInfo(string, string) ([]string, error) +} diff --git a/cve-vulner-manager/cve-ddd/domain/bulletin/bulletin.go b/cve-vulner-manager/cve-ddd/domain/bulletin/bulletin.go index 18bdddf..23077b5 100644 --- a/cve-vulner-manager/cve-ddd/domain/bulletin/bulletin.go +++ b/cve-vulner-manager/cve-ddd/domain/bulletin/bulletin.go @@ -3,5 +3,6 @@ package bulletin import "cvevulner/cve-ddd/domain" type Bulletin interface { - Generate(*domain.SecurityBulletin) ([]byte, error) + GenerateColdPatch(sb *domain.SecurityBulletin) ([]byte, error) + GenerateHotPatch(*domain.SecurityBulletin) ([]byte, error) } diff --git a/cve-vulner-manager/cve-ddd/domain/bulletins.go b/cve-vulner-manager/cve-ddd/domain/bulletins.go index 7adbb1a..3568946 100644 --- a/cve-vulner-manager/cve-ddd/domain/bulletins.go +++ b/cve-vulner-manager/cve-ddd/domain/bulletins.go @@ -5,6 +5,6 @@ type SecurityBulletin struct { Identification string Date string Component string - PatchUrl []string + PatchUrl []string // use in hotpatch Cves Cves } diff --git a/cve-vulner-manager/cve-ddd/domain/callback.go b/cve-vulner-manager/cve-ddd/domain/callback.go new file mode 100644 index 0000000..9b6f794 --- /dev/null +++ b/cve-vulner-manager/cve-ddd/domain/callback.go @@ -0,0 +1,56 @@ +package domain + +const ( + StatusProcessing = "processing" + StatusProcessed = "processed" +) + +type Callback struct { + Id int64 + Date string + Branch string + Status string + CallbackId string +} + +func (c *Callback) SetStatusProcessing() { + c.Status = StatusProcessing +} + +func (c *Callback) SetStatusProcessed() { + c.Status = StatusProcessed +} + +type CollectResult struct { + Date string + Branch string + Result string +} + +type CallbackDTO struct { + CVE string `json:"CVE"` + Score float64 `json:"score"` + Version string `json:"version"` + Status string `json:"status"` + Abi string `json:"abiChange"` + Software string `json:"software"` +} + +func ToCallbackDTO(data CollectedDataSlice) []CallbackDTO { + var dto []CallbackDTO + + for _, v := range data { + t := CallbackDTO{ + CVE: v.CveNum, + Score: v.Score, + Version: v.Version, + Status: v.Issue.Status, + Abi: "否", + Software: v.Issue.Repo, + } + + dto = append(dto, t) + } + + return dto +} diff --git a/cve-vulner-manager/cve-ddd/domain/collect.go b/cve-vulner-manager/cve-ddd/domain/collect.go new file mode 100644 index 0000000..a61f9cc --- /dev/null +++ b/cve-vulner-manager/cve-ddd/domain/collect.go @@ -0,0 +1,51 @@ +package domain + +import ( + "fmt" + "time" + + "k8s.io/apimachinery/pkg/util/sets" +) + +type CollectedData struct { + Issue Issue + Id int64 + CveNum string + Score float64 + Version string + AffectedProduct []string + CreateTime time.Time +} + +func (c CollectedData) ToLogString() string { + return fmt.Sprintf("[%s %s %s]", c.CveNum, c.Issue.Number, c.Issue.Repo) +} + +func (c CollectedData) IsCreatedOneYearAgo() bool { + oneYearAgo := time.Now().AddDate(-1, 0, 0) + + return oneYearAgo.After(c.CreateTime) +} + +func (c CollectedData) AffectProductSet() sets.Set[string] { + return sets.New(c.AffectedProduct...) +} + +type CollectedDataSlice []CollectedData + +func (s CollectedDataSlice) GroupByBranch(branches []string) map[string]CollectedDataSlice { + m := make(map[string]CollectedDataSlice) + + for _, branch := range branches { + var t CollectedDataSlice + for _, v := range s { + if v.AffectProductSet().Has(branch) { + t = append(t, v) + } + } + + m[branch] = t + } + + return m +} diff --git a/cve-vulner-manager/cve-ddd/domain/config.go b/cve-vulner-manager/cve-ddd/domain/config.go new file mode 100644 index 0000000..f44aeea --- /dev/null +++ b/cve-vulner-manager/cve-ddd/domain/config.go @@ -0,0 +1,9 @@ +package domain + +import "k8s.io/apimachinery/pkg/util/sets" + +var maintainVersion sets.Set[string] + +func InitMaintainVersion(version []string) { + maintainVersion = sets.New(version...) +} diff --git a/cve-vulner-manager/cve-ddd/domain/cve.go b/cve-vulner-manager/cve-ddd/domain/issue.go similarity index 77% rename from cve-vulner-manager/cve-ddd/domain/cve.go rename to cve-vulner-manager/cve-ddd/domain/issue.go index 2ff5f28..24af5fd 100644 --- a/cve-vulner-manager/cve-ddd/domain/cve.go +++ b/cve-vulner-manager/cve-ddd/domain/issue.go @@ -1,16 +1,15 @@ package domain import ( - "cvevulner/cve-ddd/domain/dp" "cvevulner/util" ) type Cves []Cve -//CvesByComponent is group of cves by component +// CvesByComponent is group of cves by component type CvesByComponent []Cve -//CvesByVersion is group of CvesByComponent by version +// CvesByVersion is group of CvesByComponent by version type CvesByVersion []Cve type Cve struct { @@ -32,7 +31,8 @@ type Cve struct { type Issue struct { Number string - Repo string + Status string + Repo string // in src-openeuler, repo == package, name == component } func (d Cve) isAffectVersion(version string) bool { @@ -54,7 +54,7 @@ func (ds Cves) GroupByVersion() map[string]CvesByVersion { return group } -//GroupByComponent group cves by component +// GroupByComponent group cves by component func (ds Cves) groupByComponent() map[string]CvesByComponent { group := make(map[string]CvesByComponent) for _, d := range ds { @@ -64,9 +64,9 @@ func (ds Cves) groupByComponent() map[string]CvesByComponent { return group } -//GenerateBulletins CvesByComponent is a component-differentiated set of cves, -//Bulletins are consolidated into one when all issues of a component affect all versions currently maintained, -//otherwise they are split into multiple bulletins by version +// GenerateBulletins CvesByComponent is a component-differentiated set of cves, +// Bulletins are consolidated into one when all issues of a component affect all versions currently maintained, +// otherwise they are split into multiple bulletins by version func (ds Cves) GenerateBulletins() []SecurityBulletin { var securityBulletins []SecurityBulletin @@ -81,16 +81,16 @@ func (ds Cves) GenerateBulletins() []SecurityBulletin { return securityBulletins } -//IsCombined determine whether multiple cves under the same component -//need to be combined into a single bulletin +// IsCombined determine whether multiple cves under the same component +// need to be combined into a single bulletin func (dsc CvesByComponent) isCombined() bool { for _, d := range dsc { - if len(d.AffectedVersion) != len(dp.MaintainVersion) { + if len(d.AffectedVersion) != len(maintainVersion) { return false } for _, version := range d.AffectedVersion { - if !dp.MaintainVersion[version] { + if !maintainVersion.Has(version) { return false } } @@ -99,7 +99,7 @@ func (dsc CvesByComponent) isCombined() bool { return true } -//CombinedBulletin put all cves in one bulletin +// CombinedBulletin put all cves in one bulletin func (dsc CvesByComponent) combinedBulletin() SecurityBulletin { return SecurityBulletin{ AffectedVersion: dsc[0].AffectedVersion, @@ -121,7 +121,7 @@ func (dsc CvesByComponent) separatedBulletins() []SecurityBulletin { func (dsc CvesByComponent) separateByVersion() map[string]CvesByVersion { classifyByVersion := make(map[string]CvesByVersion) - for version := range dp.MaintainVersion { + for version := range maintainVersion { for _, d := range dsc { if d.isAffectVersion(version) { classifyByVersion[version] = append(classifyByVersion[version], d) diff --git a/cve-vulner-manager/cve-ddd/domain/latestrpm/rpm.go b/cve-vulner-manager/cve-ddd/domain/latestrpm/rpm.go new file mode 100644 index 0000000..d9df30c --- /dev/null +++ b/cve-vulner-manager/cve-ddd/domain/latestrpm/rpm.go @@ -0,0 +1,8 @@ +package latestrpm + +import "time" + +type LatestRpm interface { + InitData(branches []string) error + GetBuildTime(string, string) (time.Time, error) +} diff --git a/cve-vulner-manager/cve-ddd/domain/majun/majun.go b/cve-vulner-manager/cve-ddd/domain/majun/majun.go new file mode 100644 index 0000000..022289e --- /dev/null +++ b/cve-vulner-manager/cve-ddd/domain/majun/majun.go @@ -0,0 +1,6 @@ +package majun + +type Majun interface { + GetReleasedBranch() ([]string, error) + CollectCallback(string, string) error +} diff --git a/cve-vulner-manager/cve-ddd/domain/obs/obs.go b/cve-vulner-manager/cve-ddd/domain/obs/obs.go index 4308c71..7c9f8d3 100644 --- a/cve-vulner-manager/cve-ddd/domain/obs/obs.go +++ b/cve-vulner-manager/cve-ddd/domain/obs/obs.go @@ -4,4 +4,5 @@ type OBS interface { UploadToDynamicDir(fileName string, data []byte) error DownloadFromDynamicDir(fileName string) ([]byte, error) UploadUpdateInfo(fileName string, data []byte) error + Upload(path string, data []byte) error } diff --git a/cve-vulner-manager/cve-ddd/domain/repository/cve.go b/cve-vulner-manager/cve-ddd/domain/repository/cve.go index 70d61b7..dea7743 100644 --- a/cve-vulner-manager/cve-ddd/domain/repository/cve.go +++ b/cve-vulner-manager/cve-ddd/domain/repository/cve.go @@ -3,9 +3,8 @@ package repository import "cvevulner/cve-ddd/domain" type Option struct { - CveNum []string - Component string - AffectedVersion string + CveNum []string + Component string } type CveRepository interface { @@ -13,4 +12,13 @@ type CveRepository interface { MaxBulletinID() (string, error) IssueNumExist(num string) bool SaveIssueNum(num string) error + GetAllIssue() (data domain.CollectedDataSlice, err error) + SetIgnoreStatus(id int64) error + GetAllPackage() (list []string, err error) + + AddCallback(domain.Callback) error + UpdateCallback(domain.Callback) error + GetProcessingCallback() ([]domain.Callback, error) + SaveCollectResult(r domain.CollectResult) error + FindCollectResult(branch, callbackDate string) (string, error) } diff --git a/cve-vulner-manager/cve-ddd/domain/updateinfo/updateinfo.go b/cve-vulner-manager/cve-ddd/domain/updateinfo/updateinfo.go index ddfefa2..27c1ff7 100644 --- a/cve-vulner-manager/cve-ddd/domain/updateinfo/updateinfo.go +++ b/cve-vulner-manager/cve-ddd/domain/updateinfo/updateinfo.go @@ -4,4 +4,5 @@ import "cvevulner/cve-ddd/domain" type UpdateInfo interface { Generate(cves domain.CvesByVersion) ([]byte, error) + GenerateCollectExcel(map[string]domain.CollectedDataSlice) ([]byte, error) } diff --git a/cve-vulner-manager/cve-ddd/infrastructure/backendimpl/impl.go b/cve-vulner-manager/cve-ddd/infrastructure/backendimpl/impl.go new file mode 100644 index 0000000..fad14bf --- /dev/null +++ b/cve-vulner-manager/cve-ddd/infrastructure/backendimpl/impl.go @@ -0,0 +1,59 @@ +package backendimpl + +import ( + "encoding/json" + "fmt" + "net/http" + + "github.com/astaxie/beego" + "github.com/opensourceways/server-common-lib/utils" +) + +func NewBackendImpl() backendImpl { + return backendImpl{ + client: utils.NewHttpClient(3), + } +} + +type backendImpl struct { + client utils.HttpClient +} + +type Response struct { + Result []Result `json:"result"` +} + +type Result struct { + CveId string `json:"cveId"` + PackageName string `json:"packageName"` + ProductName string `json:"productName"` + Status string `json:"status"` +} + +func (impl backendImpl) PublishedInfo(cveNum, packageName string) ([]string, error) { + url := fmt.Sprintf("%s/api-cve/cve-security-notice-server/cvedatabase/getCVEProductPackageList?cveId=%s&packageName=%s", + beego.AppConfig.String("reflink::openeuler_web"), cveNum, packageName, + ) + + req, err := http.NewRequest(http.MethodGet, url, nil) + if err != nil { + return nil, err + } + + data, _, err := impl.client.Download(req) + if err != nil { + return nil, err + } + + var v Response + if err = json.Unmarshal(data, &v); err != nil { + return nil, err + } + + var ret []string + for _, item := range v.Result { + ret = append(ret, item.ProductName) + } + + return ret, nil +} diff --git a/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/impl.go b/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/impl.go index 7a70890..81008ea 100644 --- a/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/impl.go +++ b/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/impl.go @@ -40,7 +40,11 @@ func NewBulletinImpl() bulletinImpl { type bulletinImpl struct { } -func (impl bulletinImpl) Generate(sb *domain.SecurityBulletin) ([]byte, error) { +func (impl bulletinImpl) GenerateColdPatch(sb *domain.SecurityBulletin) ([]byte, error) { + return nil, nil +} + +func (impl bulletinImpl) GenerateHotPatch(sb *domain.SecurityBulletin) ([]byte, error) { data := Cvrf{ Xmlns: "http://www.icasi.org/CVRF/schema/cvrf/1.1", XmlnsCvrf: "http://www.icasi.org/CVRF/schema/cvrf/1.1", diff --git a/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/xml.go b/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/xml.go index a2d2f38..f5f35fe 100644 --- a/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/xml.go +++ b/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/xml.go @@ -12,7 +12,8 @@ type Cvrf struct { DocumentTracking DocumentTracking `xml:"DocumentTracking,omitempty"` DocumentNotes DocumentNotes `xml:"DocumentNotes,omitempty"` DocumentReferences DocumentReferences `xml:"DocumentReferences,omitempty"` - HotPatchTree HotPatchTree `xml:"HotPatchTree"` + ProductTree ProductTree `xml:"ProductTree,omitempty"` + HotPatchTree HotPatchTree `xml:"HotPatchTree,omitempty"` Vulnerability []Vulnerability `xml:"Vulnerability,omitempty"` } diff --git a/cve-vulner-manager/cve-ddd/infrastructure/latestrpmimpl/impl.go b/cve-vulner-manager/cve-ddd/infrastructure/latestrpmimpl/impl.go new file mode 100644 index 0000000..708a995 --- /dev/null +++ b/cve-vulner-manager/cve-ddd/infrastructure/latestrpmimpl/impl.go @@ -0,0 +1,112 @@ +package latestrpmimpl + +import ( + "bytes" + "encoding/base64" + "encoding/csv" + "errors" + "fmt" + "io" + "strings" + "time" + + "github.com/astaxie/beego" + "github.com/opensourceways/robot-gitee-lib/client" +) + +type PkgRPM struct { + Org string + Repo string + Branch string + PathPrefix string +} + +func NewLatestRpm() *latestRpm { + token := beego.AppConfig.String("gitee::git_token") + cli := client.NewClient(func() []byte { + return []byte(token) + }) + + rpm := PkgRPM{ + Org: "openeuler_latest_rpms", + Repo: "obs_pkg_rpms_20231109", + Branch: "master", + PathPrefix: "latest_rpm/", + } + + return &latestRpm{ + rpm: rpm, + cli: cli, + buildTime: make(map[string]map[string]time.Time), + } +} + +type latestRpm struct { + rpm PkgRPM + cli client.Client + buildTime map[string]map[string]time.Time +} + +func (l *latestRpm) InitData(branches []string) error { + for _, branch := range branches { + path := fmt.Sprintf("%s%s.csv", l.rpm.PathPrefix, branch) + content, err := l.cli.GetPathContent(l.rpm.Org, l.rpm.Repo, path, l.rpm.Branch) + if err != nil { + return err + } + + decodeContent, err := base64.StdEncoding.DecodeString(content.Content) + if err != nil { + return err + } + + l.buildTime[branch] = l.parseFile(decodeContent) + } + + return nil +} + +func (l *latestRpm) parseFile(content []byte) map[string]time.Time { + buff := bytes.NewBuffer(content) + r := csv.NewReader(buff) + + componentAndTime := make(map[string]time.Time) + for { + line, err1 := r.Read() + if err1 == io.EOF { + break + } + + if err1 != nil { + continue + } + + split := strings.Split(line[2], "") + if len(split) == 0 { + continue + } + + t, err1 := time.ParseInLocation("20060102 15-04-05", line[0], time.Local) + if err1 != nil { + continue + } + + componentAndTime[line[1]] = t + } + + return componentAndTime +} + +func (l *latestRpm) GetBuildTime(branch, component string) (time.Time, error) { + componentMap, ok := l.buildTime[branch] + if !ok { + return time.Time{}, errors.New("branch not exists") + } + + t, ok := componentMap[component] + if !ok { + return time.Time{}, errors.New("component not exists") + } + + return t, nil +} diff --git a/cve-vulner-manager/cve-ddd/infrastructure/majunimpl/impl.go b/cve-vulner-manager/cve-ddd/infrastructure/majunimpl/impl.go new file mode 100644 index 0000000..9347cc3 --- /dev/null +++ b/cve-vulner-manager/cve-ddd/infrastructure/majunimpl/impl.go @@ -0,0 +1,151 @@ +package majunimpl + +import ( + "bytes" + "crypto/hmac" + "crypto/sha256" + "encoding/base64" + "encoding/json" + "errors" + "net/http" + "strconv" + "time" + + "github.com/astaxie/beego" + "github.com/opensourceways/server-common-lib/utils" + + "cvevulner/cve-ddd/domain" +) + +const ( + urlReleaseVersion = "http://xxxx/majun-platform-release/publish/externalinterface/queryReleaseVersion" + urlCollectCallback = "http://xxx.com/majun-platform-release/publish/review/getPublishFiles/openeuler" +) + +type config struct { + AppId string + SecretKey string +} + +func NewMajunImpl() *majunImpl { + return &majunImpl{ + cfg: config{ + AppId: beego.AppConfig.String("majun::app_id"), + SecretKey: beego.AppConfig.String("majun::secret_key"), + }, + client: utils.NewHttpClient(3), + } +} + +type majunImpl struct { + cfg config + client utils.HttpClient +} + +type releaseResponse struct { + Code int `json:"code"` + Message string `json:"message"` + Result []string `json:"result"` +} + +func (impl *majunImpl) GetReleasedBranch() ([]string, error) { + req, err := impl.generateRequest(urlReleaseVersion, nil) + if err != nil { + return nil, err + } + + var v releaseResponse + _, err = impl.client.ForwardTo(req, &v) + if err != nil { + return nil, err + } + + if v.Code != http.StatusOK { + return nil, errors.New(v.Message) + } + + return v.Result, nil + + //return []string{ + // "openEuler-20.03-LTS-SP1", + // "openEuler-20.03-LTS-SP4", + // "openEuler-22.03-LTS", + // "openEuler-22.03-LTS-SP1", + // "openEuler-22.03-LTS-SP2", + // "openEuler-22.03-LTS-SP3", + //}, nil +} + +type callbackBody struct { + Code int `json:"code"` + Id string `json:"id"` + Msg string `json:"msg"` + Data []domain.CallbackDTO `json:"data"` +} + +func (impl *majunImpl) CollectCallback(id, data string) error { + var dataDTO []domain.CallbackDTO + err := json.Unmarshal([]byte(data), &dataDTO) + if err != nil { + return err + } + + body := callbackBody{ + Code: 200, + Id: id, + Msg: "success", + Data: dataDTO, + } + + payload, err := json.Marshal(body) + if err != nil { + return err + } + + req, err := impl.generateRequest(urlCollectCallback, payload) + if err != nil { + return err + } + + var v releaseResponse + _, err = impl.client.ForwardTo(req, &v) + if err != nil { + return err + } + + if v.Code != http.StatusOK { + return errors.New(v.Message) + } + + return nil +} + +func (impl *majunImpl) generateRequest(url string, body []byte) (*http.Request, error) { + timestamp := strconv.FormatInt(time.Now().UnixMilli(), 10) + sign := impl.sign(timestamp) + + var payload *bytes.Buffer + if len(body) != 0 { + payload = bytes.NewBuffer(body) + } + + req, err := http.NewRequest(http.MethodPost, url, payload) + if err != nil { + return nil, err + } + + req.Header.Set("timestamp", timestamp) + req.Header.Set("appId", impl.cfg.AppId) + req.Header.Set("sign", sign) + + return req, nil +} + +func (impl *majunImpl) sign(timestamp string) string { + msg := impl.cfg.AppId + timestamp + + mac := hmac.New(sha256.New, []byte(impl.cfg.SecretKey)) + _, _ = mac.Write([]byte(msg)) + + return base64.StdEncoding.EncodeToString(mac.Sum(nil)) +} diff --git a/cve-vulner-manager/cve-ddd/infrastructure/obsimpl/impl.go b/cve-vulner-manager/cve-ddd/infrastructure/obsimpl/impl.go index 5e1ab20..1580e10 100644 --- a/cve-vulner-manager/cve-ddd/infrastructure/obsimpl/impl.go +++ b/cve-vulner-manager/cve-ddd/infrastructure/obsimpl/impl.go @@ -95,3 +95,14 @@ func (impl obsImpl) getDynamicDir() string { return fmt.Sprintf("%s%s-%s/", impl.cfg.UpdateInfoDir, todayStr, "hotpatch") } + +func (impl obsImpl) Upload(path string, data []byte) error { + input := &obs.PutObjectInput{} + input.Bucket = impl.cfg.Bucket + input.Key = path + input.Body = bytes.NewReader(data) + + _, err := impl.cli.PutObject(input) + + return err +} diff --git a/cve-vulner-manager/cve-ddd/infrastructure/repositoryimpl/callback.go b/cve-vulner-manager/cve-ddd/infrastructure/repositoryimpl/callback.go new file mode 100644 index 0000000..72ad2fb --- /dev/null +++ b/cve-vulner-manager/cve-ddd/infrastructure/repositoryimpl/callback.go @@ -0,0 +1,101 @@ +package repositoryimpl + +import ( + "github.com/astaxie/beego/orm" + + "cvevulner/cve-ddd/domain" + "cvevulner/models" +) + +const ( + fieldStatus = "status" + fieldBranch = "branch" + fieldCollect = "collect_date" +) + +func (impl repositoryImpl) AddCallback(callback domain.Callback) error { + c := toCallbackModels(callback) + + _, err := orm.NewOrm().Insert(&c) + + return err +} + +func (impl repositoryImpl) UpdateCallback(callback domain.Callback) error { + c := toCallbackModels(callback) + + _, err := orm.NewOrm().Update(&c) + + return err +} + +func (impl repositoryImpl) GetProcessingCallback() ([]domain.Callback, error) { + c := new(models.CollectCallback) + var modelCallback []models.CollectCallback + + _, err := orm.NewOrm().QueryTable(c).Filter(fieldStatus, domain.StatusProcessing).All(&modelCallback) + if err != nil { + return nil, err + } + + var callback []domain.Callback + for _, v := range modelCallback { + t := toCallback(v) + + callback = append(callback, t) + } + + return callback, nil +} + +func (impl repositoryImpl) SaveCollectResult(r domain.CollectResult) error { + resultDO := models.CollectResult{ + Branch: r.Branch, + CollectDate: r.Date, + Result: r.Result, + } + + _, err := orm.NewOrm().Insert(&resultDO) + + return err +} + +func (impl repositoryImpl) FindCollectResult(branch, collectDate string) (string, error) { + callbackResult := new(models.CollectResult) + + query := orm.NewOrm().QueryTable(callbackResult) + if branch != "" { + query.Filter(fieldBranch, branch) + } + + if collectDate != "" { + query.Filter(fieldCollect, collectDate) + } + + err := query.One(callbackResult) + if err != nil { + return "", err + } + + return callbackResult.Result, nil +} + +func toCallbackModels(callback domain.Callback) models.CollectCallback { + return models.CollectCallback{ + Id: callback.Id, + Branch: callback.Branch, + Status: callback.Status, + CollectDate: callback.Date, + CallbackId: callback.CallbackId, + } +} + +func toCallback(m models.CollectCallback) domain.Callback { + return domain.Callback{ + Id: m.Id, + Branch: m.Branch, + Status: m.Status, + Date: m.CollectDate, + CallbackId: m.CallbackId, + } +} diff --git a/cve-vulner-manager/cve-ddd/infrastructure/repositoryimpl/impl.go b/cve-vulner-manager/cve-ddd/infrastructure/repositoryimpl/impl.go index ce6b5e3..143e772 100644 --- a/cve-vulner-manager/cve-ddd/infrastructure/repositoryimpl/impl.go +++ b/cve-vulner-manager/cve-ddd/infrastructure/repositoryimpl/impl.go @@ -29,11 +29,15 @@ func (impl repositoryImpl) FindCves(opt repository.Option) (cves domain.Cves, er from cve_vuln_center a join cve_issue_template b on a.cve_id=b.cve_id join cve_security_notice c on a.cve_id=c.cve_id -where a.cve_num in (%s) and a.organizate_id = 1 and a.pack_name = "%s" +where a.cve_num in (%s) and a.organizate_id = 1 ` + if opt.Component != "" { + sql += fmt.Sprintf(`and a.pack_name = "%s"`, opt.Component) + } + o := orm.NewOrm() cveStr := "\"" + strings.Join(opt.CveNum, "\",\"") + "\"" - if _, err = o.Raw(fmt.Sprintf(sql, cveStr, opt.Component)).QueryRows(&data); err != nil { + if _, err = o.Raw(fmt.Sprintf(sql, cveStr)).QueryRows(&data); err != nil { return } @@ -42,7 +46,6 @@ where a.cve_num in (%s) and a.organizate_id = 1 and a.pack_name = "%s" Component: opt.Component, Description: v.Description, SeverityLevel: v.CveLevel, - AffectedVersion: []string{opt.AffectedVersion}, AffectedProduct: v.AffectProduct, OpeneulerScore: v.OpeneulerScore, Theme: v.Theme, @@ -109,3 +112,71 @@ func (impl repositoryImpl) SaveIssueNum(num string) error { return err } + +type list struct { + models.IssueTemplate + AffectProduct string `orm:"column(affect_product)"` +} + +var statusMap = map[int8]string{ + 1: "待办的", + 2: "进行中", + 3: "已完成", +} + +func (impl repositoryImpl) GetAllIssue() (data domain.CollectedDataSlice, err error) { + sql := `select a.*, b.affect_product from cve_issue_template a + join cve_security_notice b on a.cve_id=b.cve_id + where a.cve_id in (select cve_id from cve_vuln_center where cve_status = 2 and is_export in (0,3) and organizate_id = 1) + and a.status < 4 +` + + var issueTemp []list + _, err = orm.NewOrm().Raw(sql).QueryRows(&issueTemp) + if err != nil { + return + } + + for _, v := range issueTemp { + t := domain.CollectedData{ + Issue: domain.Issue{ + Number: v.IssueNum, + Status: statusMap[v.Status], + Repo: v.Repo, + }, + Id: v.TemplateId, + CveNum: v.CveNum, + Score: v.OpenEulerScore, + Version: v.OwnedVersion, + AffectedProduct: strings.Split(v.AffectProduct, "/"), + CreateTime: v.CreateTime, + } + + data = append(data, t) + } + + return +} + +func (impl repositoryImpl) SetIgnoreStatus(id int64) error { + sql := fmt.Sprintf("update cve_issue_template set is_ignore = 1 where template_id = %d", id) + _, err := orm.NewOrm().Raw(sql).Exec() + + return err +} + +func (impl repositoryImpl) GetAllPackage() (list []string, err error) { + sql := "select package_name from cve_git_package_info" + + var info []models.GitPackageInfo + _, err = orm.NewOrm().Raw(sql).QueryRows(&info) + if err != nil { + return + } + + for _, v := range info { + list = append(list, v.PackageName) + } + + return +} diff --git a/cve-vulner-manager/cve-ddd/infrastructure/updateinfoimpl/collect_excel.go b/cve-vulner-manager/cve-ddd/infrastructure/updateinfoimpl/collect_excel.go new file mode 100644 index 0000000..a49001e --- /dev/null +++ b/cve-vulner-manager/cve-ddd/infrastructure/updateinfoimpl/collect_excel.go @@ -0,0 +1,77 @@ +package updateinfoimpl + +import ( + "fmt" + + "github.com/xuri/excelize/v2" + + "cvevulner/cve-ddd/domain" +) + +func (impl updateInfoImpl) GenerateCollectExcel(groupData map[string]domain.CollectedDataSlice) (ret []byte, err error) { + excel := excelize.NewFile() + + for branch, data := range groupData { + sheetIndex, _ := excel.NewSheet(branch) + excel.SetActiveSheet(sheetIndex) + if err = impl.setCollectExcelHeader(excel, branch); err != nil { + return + } + + for index, v := range data { + if err = excel.SetCellValue(branch, fmt.Sprintf("A%d", index+2), v.CveNum); err != nil { + return + } + + if err = excel.SetCellValue(branch, fmt.Sprintf("B%d", index+2), v.Issue.Number); err != nil { + return + } + + if err = excel.SetCellValue(branch, fmt.Sprintf("C%d", index+2), v.Issue.Repo); err != nil { + return + } + + if err = excel.SetCellValue(branch, fmt.Sprintf("D%d", index+2), v.Score); err != nil { + return + } + + if err = excel.SetCellValue(branch, fmt.Sprintf("E%d", index+2), v.Version); err != nil { + return + } + + if err = excel.SetCellValue(branch, fmt.Sprintf("F%d", index+2), "否"); err != nil { + return + } + } + } + + buff, err := excel.WriteToBuffer() + if err != nil { + return + } + + return buff.Bytes(), nil +} + +func (impl updateInfoImpl) setCollectExcelHeader(f *excelize.File, branch string) error { + if err := f.SetCellValue(branch, "A1", "cve编号"); err != nil { + return err + } + if err := f.SetCellValue(branch, "B1", "issue编号"); err != nil { + return err + } + if err := f.SetCellValue(branch, "C1", "issue所属仓库"); err != nil { + return err + } + if err := f.SetCellValue(branch, "D1", "score"); err != nil { + return err + } + if err := f.SetCellValue(branch, "E1", "version"); err != nil { + return err + } + if err := f.SetCellValue(branch, "F1", "abi是否变化"); err != nil { + return err + } + + return nil +} diff --git a/cve-vulner-manager/go.mod b/cve-vulner-manager/go.mod index add16da..5130a62 100644 --- a/cve-vulner-manager/go.mod +++ b/cve-vulner-manager/go.mod @@ -9,24 +9,27 @@ require ( github.com/dgrijalva/jwt-go v3.2.1-0.20210802184156-9742bd7fca1c+incompatible github.com/go-sql-driver/mysql v1.5.0 github.com/huaweicloud/huaweicloud-sdk-go-obs v3.23.4+incompatible + github.com/opensourceways/go-gitee v0.0.0-20240305060727-0df28a4f60c0 + github.com/opensourceways/robot-gitee-lib v1.0.0 github.com/opensourceways/server-common-lib v0.0.0-20231027024402-f55c66e6699c github.com/pkg/errors v0.9.1 github.com/robfig/cron/v3 v3.0.1 + github.com/sirupsen/logrus v1.9.3 github.com/smartystreets/goconvey v1.6.4 github.com/xuri/excelize/v2 v2.7.1 golang.org/x/net v0.19.0 gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df gopkg.in/yaml.v2 v2.4.0 - k8s.io/apimachinery v0.25.3 + k8s.io/apimachinery v0.26.1 ) require ( github.com/antchfx/xpath v1.2.0 // indirect + github.com/antihax/optional v1.0.0 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/cespare/xxhash/v2 v2.1.1 // indirect - github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect - github.com/golang/protobuf v1.5.2 // indirect - github.com/google/go-cmp v0.5.9 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/jtolds/gls v4.20.0+incompatible // indirect @@ -34,7 +37,7 @@ require ( github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/prometheus/client_golang v1.11.1 // indirect - github.com/prometheus/client_model v0.2.0 // indirect + github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/common v0.26.0 // indirect github.com/prometheus/procfs v0.6.0 // indirect github.com/richardlehane/mscfb v1.0.4 // indirect @@ -46,8 +49,10 @@ require ( github.com/xuri/nfp v0.0.0-20230919160717-d98342af3f05 // indirect golang.org/x/crypto v0.17.0 // indirect golang.org/x/image v0.10.0 // indirect + golang.org/x/oauth2 v0.12.0 // indirect golang.org/x/sys v0.15.0 // indirect golang.org/x/text v0.14.0 // indirect + google.golang.org/appengine v1.6.8 // indirect google.golang.org/protobuf v1.33.0 // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect sigs.k8s.io/yaml v1.3.0 // indirect diff --git a/cve-vulner-manager/go.sum b/cve-vulner-manager/go.sum index 90085c6..6270c4e 100644 --- a/cve-vulner-manager/go.sum +++ b/cve-vulner-manager/go.sum @@ -1,8 +1,616 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= +cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= +cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= +cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= +cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= +cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= +cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= +cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= +cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= +cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= +cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= +cloud.google.com/go v0.100.1/go.mod h1:fs4QogzfH5n2pBXBP9vRiU+eCny7lD2vmFZy79Iuw1U= +cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= +cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= +cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU= +cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= +cloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFOKM= +cloud.google.com/go v0.107.0/go.mod h1:wpc2eNrD7hXUTy8EKS10jkxpZBjASrORK7goS+3YX2I= +cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY= +cloud.google.com/go v0.110.2/go.mod h1:k04UEeEtb6ZBRTv3dZz4CeJC3jKGxyhl0sAiVVquxiw= +cloud.google.com/go/accessapproval v1.4.0/go.mod h1:zybIuC3KpDOvotz59lFe5qxRZx6C75OtwbisN56xYB4= +cloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw= +cloud.google.com/go/accessapproval v1.6.0/go.mod h1:R0EiYnwV5fsRFiKZkPHr6mwyk2wxUJ30nL4j2pcFY2E= +cloud.google.com/go/accesscontextmanager v1.3.0/go.mod h1:TgCBehyr5gNMz7ZaH9xubp+CE8dkrszb4oK9CWyvD4o= +cloud.google.com/go/accesscontextmanager v1.4.0/go.mod h1:/Kjh7BBu/Gh83sv+K60vN9QE5NJcd80sU33vIe2IFPE= +cloud.google.com/go/accesscontextmanager v1.6.0/go.mod h1:8XCvZWfYw3K/ji0iVnp+6pu7huxoQTLmxAbVjbloTtM= +cloud.google.com/go/accesscontextmanager v1.7.0/go.mod h1:CEGLewx8dwa33aDAZQujl7Dx+uYhS0eay198wB/VumQ= +cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw= +cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY= +cloud.google.com/go/aiplatform v1.27.0/go.mod h1:Bvxqtl40l0WImSb04d0hXFU7gDOiq9jQmorivIiWcKg= +cloud.google.com/go/aiplatform v1.35.0/go.mod h1:7MFT/vCaOyZT/4IIFfxH4ErVg/4ku6lKv3w0+tFTgXQ= +cloud.google.com/go/aiplatform v1.36.1/go.mod h1:WTm12vJRPARNvJ+v6P52RDHCNe4AhvjcIZ/9/RRHy/k= +cloud.google.com/go/aiplatform v1.37.0/go.mod h1:IU2Cv29Lv9oCn/9LkFiiuKfwrRTq+QQMbW+hPCxJGZw= +cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI= +cloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4= +cloud.google.com/go/analytics v0.17.0/go.mod h1:WXFa3WSym4IZ+JiKmavYdJwGG/CvpqiqczmL59bTD9M= +cloud.google.com/go/analytics v0.18.0/go.mod h1:ZkeHGQlcIPkw0R/GW+boWHhCOR43xz9RN/jn7WcqfIE= +cloud.google.com/go/analytics v0.19.0/go.mod h1:k8liqf5/HCnOUkbawNtrWWc+UAzyDlW89doe8TtoDsE= +cloud.google.com/go/apigateway v1.3.0/go.mod h1:89Z8Bhpmxu6AmUxuVRg/ECRGReEdiP3vQtk4Z1J9rJk= +cloud.google.com/go/apigateway v1.4.0/go.mod h1:pHVY9MKGaH9PQ3pJ4YLzoj6U5FUDeDFBllIz7WmzJoc= +cloud.google.com/go/apigateway v1.5.0/go.mod h1:GpnZR3Q4rR7LVu5951qfXPJCHquZt02jf7xQx7kpqN8= +cloud.google.com/go/apigeeconnect v1.3.0/go.mod h1:G/AwXFAKo0gIXkPTVfZDd2qA1TxBXJ3MgMRBQkIi9jc= +cloud.google.com/go/apigeeconnect v1.4.0/go.mod h1:kV4NwOKqjvt2JYR0AoIWo2QGfoRtn/pkS3QlHp0Ni04= +cloud.google.com/go/apigeeconnect v1.5.0/go.mod h1:KFaCqvBRU6idyhSNyn3vlHXc8VMDJdRmwDF6JyFRqZ8= +cloud.google.com/go/apigeeregistry v0.4.0/go.mod h1:EUG4PGcsZvxOXAdyEghIdXwAEi/4MEaoqLMLDMIwKXY= +cloud.google.com/go/apigeeregistry v0.5.0/go.mod h1:YR5+s0BVNZfVOUkMa5pAR2xGd0A473vA5M7j247o1wM= +cloud.google.com/go/apigeeregistry v0.6.0/go.mod h1:BFNzW7yQVLZ3yj0TKcwzb8n25CFBri51GVGOEUcgQsc= +cloud.google.com/go/apikeys v0.4.0/go.mod h1:XATS/yqZbaBK0HOssf+ALHp8jAlNHUgyfprvNcBIszU= +cloud.google.com/go/apikeys v0.5.0/go.mod h1:5aQfwY4D+ewMMWScd3hm2en3hCj+BROlyrt3ytS7KLI= +cloud.google.com/go/apikeys v0.6.0/go.mod h1:kbpXu5upyiAlGkKrJgQl8A0rKNNJ7dQ377pdroRSSi8= +cloud.google.com/go/appengine v1.4.0/go.mod h1:CS2NhuBuDXM9f+qscZ6V86m1MIIqPj3WC/UoEuR1Sno= +cloud.google.com/go/appengine v1.5.0/go.mod h1:TfasSozdkFI0zeoxW3PTBLiNqRmzraodCWatWI9Dmak= +cloud.google.com/go/appengine v1.6.0/go.mod h1:hg6i0J/BD2cKmDJbaFSYHFyZkgBEfQrDg/X0V5fJn84= +cloud.google.com/go/appengine v1.7.0/go.mod h1:eZqpbHFCqRGa2aCdope7eC0SWLV1j0neb/QnMJVWx6A= +cloud.google.com/go/appengine v1.7.1/go.mod h1:IHLToyb/3fKutRysUlFO0BPt5j7RiQ45nrzEJmKTo6E= +cloud.google.com/go/area120 v0.5.0/go.mod h1:DE/n4mp+iqVyvxHN41Vf1CR602GiHQjFPusMFW6bGR4= +cloud.google.com/go/area120 v0.6.0/go.mod h1:39yFJqWVgm0UZqWTOdqkLhjoC7uFfgXRC8g/ZegeAh0= +cloud.google.com/go/area120 v0.7.0/go.mod h1:a3+8EUD1SX5RUcCs3MY5YasiO1z6yLiNLRiFrykbynY= +cloud.google.com/go/area120 v0.7.1/go.mod h1:j84i4E1RboTWjKtZVWXPqvK5VHQFJRF2c1Nm69pWm9k= +cloud.google.com/go/artifactregistry v1.6.0/go.mod h1:IYt0oBPSAGYj/kprzsBjZ/4LnG/zOcHyFHjWPCi6SAQ= +cloud.google.com/go/artifactregistry v1.7.0/go.mod h1:mqTOFOnGZx8EtSqK/ZWcsm/4U8B77rbcLP6ruDU2Ixk= +cloud.google.com/go/artifactregistry v1.8.0/go.mod h1:w3GQXkJX8hiKN0v+at4b0qotwijQbYUqF2GWkZzAhC0= +cloud.google.com/go/artifactregistry v1.9.0/go.mod h1:2K2RqvA2CYvAeARHRkLDhMDJ3OXy26h3XW+3/Jh2uYc= +cloud.google.com/go/artifactregistry v1.11.1/go.mod h1:lLYghw+Itq9SONbCa1YWBoWs1nOucMH0pwXN1rOBZFI= +cloud.google.com/go/artifactregistry v1.11.2/go.mod h1:nLZns771ZGAwVLzTX/7Al6R9ehma4WUEhZGWV6CeQNQ= +cloud.google.com/go/artifactregistry v1.12.0/go.mod h1:o6P3MIvtzTOnmvGagO9v/rOjjA0HmhJ+/6KAXrmYDCI= +cloud.google.com/go/artifactregistry v1.13.0/go.mod h1:uy/LNfoOIivepGhooAUpL1i30Hgee3Cu0l4VTWHUC08= +cloud.google.com/go/asset v1.5.0/go.mod h1:5mfs8UvcM5wHhqtSv8J1CtxxaQq3AdBxxQi2jGW/K4o= +cloud.google.com/go/asset v1.7.0/go.mod h1:YbENsRK4+xTiL+Ofoj5Ckf+O17kJtgp3Y3nn4uzZz5s= +cloud.google.com/go/asset v1.8.0/go.mod h1:mUNGKhiqIdbr8X7KNayoYvyc4HbbFO9URsjbytpUaW0= +cloud.google.com/go/asset v1.9.0/go.mod h1:83MOE6jEJBMqFKadM9NLRcs80Gdw76qGuHn8m3h8oHQ= +cloud.google.com/go/asset v1.10.0/go.mod h1:pLz7uokL80qKhzKr4xXGvBQXnzHn5evJAEAtZiIb0wY= +cloud.google.com/go/asset v1.11.1/go.mod h1:fSwLhbRvC9p9CXQHJ3BgFeQNM4c9x10lqlrdEUYXlJo= +cloud.google.com/go/asset v1.12.0/go.mod h1:h9/sFOa4eDIyKmH6QMpm4eUK3pDojWnUhTgJlk762Hg= +cloud.google.com/go/asset v1.13.0/go.mod h1:WQAMyYek/b7NBpYq/K4KJWcRqzoalEsxz/t/dTk4THw= +cloud.google.com/go/assuredworkloads v1.5.0/go.mod h1:n8HOZ6pff6re5KYfBXcFvSViQjDwxFkAkmUFffJRbbY= +cloud.google.com/go/assuredworkloads v1.6.0/go.mod h1:yo2YOk37Yc89Rsd5QMVECvjaMKymF9OP+QXWlKXUkXw= +cloud.google.com/go/assuredworkloads v1.7.0/go.mod h1:z/736/oNmtGAyU47reJgGN+KVoYoxeLBoj4XkKYscNI= +cloud.google.com/go/assuredworkloads v1.8.0/go.mod h1:AsX2cqyNCOvEQC8RMPnoc0yEarXQk6WEKkxYfL6kGIo= +cloud.google.com/go/assuredworkloads v1.9.0/go.mod h1:kFuI1P78bplYtT77Tb1hi0FMxM0vVpRC7VVoJC3ZoT0= +cloud.google.com/go/assuredworkloads v1.10.0/go.mod h1:kwdUQuXcedVdsIaKgKTp9t0UJkE5+PAVNhdQm4ZVq2E= +cloud.google.com/go/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0= +cloud.google.com/go/automl v1.6.0/go.mod h1:ugf8a6Fx+zP0D59WLhqgTDsQI9w07o64uf/Is3Nh5p8= +cloud.google.com/go/automl v1.7.0/go.mod h1:RL9MYCCsJEOmt0Wf3z9uzG0a7adTT1fe+aObgSpkCt8= +cloud.google.com/go/automl v1.8.0/go.mod h1:xWx7G/aPEe/NP+qzYXktoBSDfjO+vnKMGgsApGJJquM= +cloud.google.com/go/automl v1.12.0/go.mod h1:tWDcHDp86aMIuHmyvjuKeeHEGq76lD7ZqfGLN6B0NuU= +cloud.google.com/go/baremetalsolution v0.3.0/go.mod h1:XOrocE+pvK1xFfleEnShBlNAXf+j5blPPxrhjKgnIFc= +cloud.google.com/go/baremetalsolution v0.4.0/go.mod h1:BymplhAadOO/eBa7KewQ0Ppg4A4Wplbn+PsFKRLo0uI= +cloud.google.com/go/baremetalsolution v0.5.0/go.mod h1:dXGxEkmR9BMwxhzBhV0AioD0ULBmuLZI8CdwalUxuss= +cloud.google.com/go/batch v0.3.0/go.mod h1:TR18ZoAekj1GuirsUsR1ZTKN3FC/4UDnScjT8NXImFE= +cloud.google.com/go/batch v0.4.0/go.mod h1:WZkHnP43R/QCGQsZ+0JyG4i79ranE2u8xvjq/9+STPE= +cloud.google.com/go/batch v0.7.0/go.mod h1:vLZN95s6teRUqRQ4s3RLDsH8PvboqBK+rn1oevL159g= +cloud.google.com/go/beyondcorp v0.2.0/go.mod h1:TB7Bd+EEtcw9PCPQhCJtJGjk/7TC6ckmnSFS+xwTfm4= +cloud.google.com/go/beyondcorp v0.3.0/go.mod h1:E5U5lcrcXMsCuoDNyGrpyTm/hn7ne941Jz2vmksAxW8= +cloud.google.com/go/beyondcorp v0.4.0/go.mod h1:3ApA0mbhHx6YImmuubf5pyW8srKnCEPON32/5hj+RmM= +cloud.google.com/go/beyondcorp v0.5.0/go.mod h1:uFqj9X+dSfrheVp7ssLTaRHd2EHqSL4QZmH4e8WXGGU= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/bigquery v1.42.0/go.mod h1:8dRTJxhtG+vwBKzE5OseQn/hiydoQN3EedCaOdYmxRA= +cloud.google.com/go/bigquery v1.43.0/go.mod h1:ZMQcXHsl+xmU1z36G2jNGZmKp9zNY5BUua5wDgmNCfw= +cloud.google.com/go/bigquery v1.44.0/go.mod h1:0Y33VqXTEsbamHJvJHdFmtqHvMIY28aK1+dFsvaChGc= +cloud.google.com/go/bigquery v1.47.0/go.mod h1:sA9XOgy0A8vQK9+MWhEQTY6Tix87M/ZurWFIxmF9I/E= +cloud.google.com/go/bigquery v1.48.0/go.mod h1:QAwSz+ipNgfL5jxiaK7weyOhzdoAy1zFm0Nf1fysJac= +cloud.google.com/go/bigquery v1.49.0/go.mod h1:Sv8hMmTFFYBlt/ftw2uN6dFdQPzBlREY9yBh7Oy7/4Q= +cloud.google.com/go/bigquery v1.50.0/go.mod h1:YrleYEh2pSEbgTBZYMJ5SuSr0ML3ypjRB1zgf7pvQLU= +cloud.google.com/go/billing v1.4.0/go.mod h1:g9IdKBEFlItS8bTtlrZdVLWSSdSyFUZKXNS02zKMOZY= +cloud.google.com/go/billing v1.5.0/go.mod h1:mztb1tBc3QekhjSgmpf/CV4LzWXLzCArwpLmP2Gm88s= +cloud.google.com/go/billing v1.6.0/go.mod h1:WoXzguj+BeHXPbKfNWkqVtDdzORazmCjraY+vrxcyvI= +cloud.google.com/go/billing v1.7.0/go.mod h1:q457N3Hbj9lYwwRbnlD7vUpyjq6u5U1RAOArInEiD5Y= +cloud.google.com/go/billing v1.12.0/go.mod h1:yKrZio/eu+okO/2McZEbch17O5CB5NpZhhXG6Z766ss= +cloud.google.com/go/billing v1.13.0/go.mod h1:7kB2W9Xf98hP9Sr12KfECgfGclsH3CQR0R08tnRlRbc= +cloud.google.com/go/binaryauthorization v1.1.0/go.mod h1:xwnoWu3Y84jbuHa0zd526MJYmtnVXn0syOjaJgy4+dM= +cloud.google.com/go/binaryauthorization v1.2.0/go.mod h1:86WKkJHtRcv5ViNABtYMhhNWRrD1Vpi//uKEy7aYEfI= +cloud.google.com/go/binaryauthorization v1.3.0/go.mod h1:lRZbKgjDIIQvzYQS1p99A7/U1JqvqeZg0wiI5tp6tg0= +cloud.google.com/go/binaryauthorization v1.4.0/go.mod h1:tsSPQrBd77VLplV70GUhBf/Zm3FsKmgSqgm4UmiDItk= +cloud.google.com/go/binaryauthorization v1.5.0/go.mod h1:OSe4OU1nN/VswXKRBmciKpo9LulY41gch5c68htf3/Q= +cloud.google.com/go/certificatemanager v1.3.0/go.mod h1:n6twGDvcUBFu9uBgt4eYvvf3sQ6My8jADcOVwHmzadg= +cloud.google.com/go/certificatemanager v1.4.0/go.mod h1:vowpercVFyqs8ABSmrdV+GiFf2H/ch3KyudYQEMM590= +cloud.google.com/go/certificatemanager v1.6.0/go.mod h1:3Hh64rCKjRAX8dXgRAyOcY5vQ/fE1sh8o+Mdd6KPgY8= +cloud.google.com/go/channel v1.8.0/go.mod h1:W5SwCXDJsq/rg3tn3oG0LOxpAo6IMxNa09ngphpSlnk= +cloud.google.com/go/channel v1.9.0/go.mod h1:jcu05W0my9Vx4mt3/rEHpfxc9eKi9XwsdDL8yBMbKUk= +cloud.google.com/go/channel v1.11.0/go.mod h1:IdtI0uWGqhEeatSB62VOoJ8FSUhJ9/+iGkJVqp74CGE= +cloud.google.com/go/channel v1.12.0/go.mod h1:VkxCGKASi4Cq7TbXxlaBezonAYpp1GCnKMY6tnMQnLU= +cloud.google.com/go/cloudbuild v1.3.0/go.mod h1:WequR4ULxlqvMsjDEEEFnOG5ZSRSgWOywXYDb1vPE6U= +cloud.google.com/go/cloudbuild v1.4.0/go.mod h1:5Qwa40LHiOXmz3386FrjrYM93rM/hdRr7b53sySrTqA= +cloud.google.com/go/cloudbuild v1.6.0/go.mod h1:UIbc/w9QCbH12xX+ezUsgblrWv+Cv4Tw83GiSMHOn9M= +cloud.google.com/go/cloudbuild v1.7.0/go.mod h1:zb5tWh2XI6lR9zQmsm1VRA+7OCuve5d8S+zJUul8KTg= +cloud.google.com/go/cloudbuild v1.9.0/go.mod h1:qK1d7s4QlO0VwfYn5YuClDGg2hfmLZEb4wQGAbIgL1s= +cloud.google.com/go/clouddms v1.3.0/go.mod h1:oK6XsCDdW4Ib3jCCBugx+gVjevp2TMXFtgxvPSee3OM= +cloud.google.com/go/clouddms v1.4.0/go.mod h1:Eh7sUGCC+aKry14O1NRljhjyrr0NFC0G2cjwX0cByRk= +cloud.google.com/go/clouddms v1.5.0/go.mod h1:QSxQnhikCLUw13iAbffF2CZxAER3xDGNHjsTAkQJcQA= +cloud.google.com/go/cloudtasks v1.5.0/go.mod h1:fD92REy1x5woxkKEkLdvavGnPJGEn8Uic9nWuLzqCpY= +cloud.google.com/go/cloudtasks v1.6.0/go.mod h1:C6Io+sxuke9/KNRkbQpihnW93SWDU3uXt92nu85HkYI= +cloud.google.com/go/cloudtasks v1.7.0/go.mod h1:ImsfdYWwlWNJbdgPIIGJWC+gemEGTBK/SunNQQNCAb4= +cloud.google.com/go/cloudtasks v1.8.0/go.mod h1:gQXUIwCSOI4yPVK7DgTVFiiP0ZW/eQkydWzwVMdHxrI= +cloud.google.com/go/cloudtasks v1.9.0/go.mod h1:w+EyLsVkLWHcOaqNEyvcKAsWp9p29dL6uL9Nst1cI7Y= +cloud.google.com/go/cloudtasks v1.10.0/go.mod h1:NDSoTLkZ3+vExFEWu2UJV1arUyzVDAiZtdWcsUyNwBs= +cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= +cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= +cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= +cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= +cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= +cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= +cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU= +cloud.google.com/go/compute v1.12.0/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= +cloud.google.com/go/compute v1.12.1/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= +cloud.google.com/go/compute v1.13.0/go.mod h1:5aPTS0cUNMIc1CE546K+Th6weJUNQErARyZtRXDJ8GE= +cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvjxega5vAdo= +cloud.google.com/go/compute v1.15.1/go.mod h1:bjjoF/NtFUrkD/urWfdHaKuOPDR5nWIs63rR+SXhcpA= +cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs= +cloud.google.com/go/compute v1.19.0/go.mod h1:rikpw2y+UMidAe9tISo04EHNOIf42RLYF/q8Bs93scU= +cloud.google.com/go/compute v1.19.3/go.mod h1:qxvISKp/gYnXkSAD1ppcSOveRAmzxicEv/JlizULFrI= +cloud.google.com/go/compute v1.20.1/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= +cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU= +cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM= +cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= +cloud.google.com/go/contactcenterinsights v1.3.0/go.mod h1:Eu2oemoePuEFc/xKFPjbTuPSj0fYJcPls9TFlPNnHHY= +cloud.google.com/go/contactcenterinsights v1.4.0/go.mod h1:L2YzkGbPsv+vMQMCADxJoT9YiTTnSEd6fEvCeHTYVck= +cloud.google.com/go/contactcenterinsights v1.6.0/go.mod h1:IIDlT6CLcDoyv79kDv8iWxMSTZhLxSCofVV5W6YFM/w= +cloud.google.com/go/container v1.6.0/go.mod h1:Xazp7GjJSeUYo688S+6J5V+n/t+G5sKBTFkKNudGRxg= +cloud.google.com/go/container v1.7.0/go.mod h1:Dp5AHtmothHGX3DwwIHPgq45Y8KmNsgN3amoYfxVkLo= +cloud.google.com/go/container v1.13.1/go.mod h1:6wgbMPeQRw9rSnKBCAJXnds3Pzj03C4JHamr8asWKy4= +cloud.google.com/go/container v1.14.0/go.mod h1:3AoJMPhHfLDxLvrlVWaK57IXzaPnLaZq63WX59aQBfM= +cloud.google.com/go/container v1.15.0/go.mod h1:ft+9S0WGjAyjDggg5S06DXj+fHJICWg8L7isCQe9pQA= +cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I= +cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4= +cloud.google.com/go/containeranalysis v0.7.0/go.mod h1:9aUL+/vZ55P2CXfuZjS4UjQ9AgXoSw8Ts6lemfmxBxI= +cloud.google.com/go/containeranalysis v0.9.0/go.mod h1:orbOANbwk5Ejoom+s+DUCTTJ7IBdBQJDcSylAx/on9s= +cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0= +cloud.google.com/go/datacatalog v1.5.0/go.mod h1:M7GPLNQeLfWqeIm3iuiruhPzkt65+Bx8dAKvScX8jvs= +cloud.google.com/go/datacatalog v1.6.0/go.mod h1:+aEyF8JKg+uXcIdAmmaMUmZ3q1b/lKLtXCmXdnc0lbc= +cloud.google.com/go/datacatalog v1.7.0/go.mod h1:9mEl4AuDYWw81UGc41HonIHH7/sn52H0/tc8f8ZbZIE= +cloud.google.com/go/datacatalog v1.8.0/go.mod h1:KYuoVOv9BM8EYz/4eMFxrr4DUKhGIOXxZoKYF5wdISM= +cloud.google.com/go/datacatalog v1.8.1/go.mod h1:RJ58z4rMp3gvETA465Vg+ag8BGgBdnRPEMMSTr5Uv+M= +cloud.google.com/go/datacatalog v1.12.0/go.mod h1:CWae8rFkfp6LzLumKOnmVh4+Zle4A3NXLzVJ1d1mRm0= +cloud.google.com/go/datacatalog v1.13.0/go.mod h1:E4Rj9a5ZtAxcQJlEBTLgMTphfP11/lNaAshpoBgemX8= +cloud.google.com/go/dataflow v0.6.0/go.mod h1:9QwV89cGoxjjSR9/r7eFDqqjtvbKxAK2BaYU6PVk9UM= +cloud.google.com/go/dataflow v0.7.0/go.mod h1:PX526vb4ijFMesO1o202EaUmouZKBpjHsTlCtB4parQ= +cloud.google.com/go/dataflow v0.8.0/go.mod h1:Rcf5YgTKPtQyYz8bLYhFoIV/vP39eL7fWNcSOyFfLJE= +cloud.google.com/go/dataform v0.3.0/go.mod h1:cj8uNliRlHpa6L3yVhDOBrUXH+BPAO1+KFMQQNSThKo= +cloud.google.com/go/dataform v0.4.0/go.mod h1:fwV6Y4Ty2yIFL89huYlEkwUPtS7YZinZbzzj5S9FzCE= +cloud.google.com/go/dataform v0.5.0/go.mod h1:GFUYRe8IBa2hcomWplodVmUx/iTL0FrsauObOM3Ipr0= +cloud.google.com/go/dataform v0.6.0/go.mod h1:QPflImQy33e29VuapFdf19oPbE4aYTJxr31OAPV+ulA= +cloud.google.com/go/dataform v0.7.0/go.mod h1:7NulqnVozfHvWUBpMDfKMUESr+85aJsC/2O0o3jWPDE= +cloud.google.com/go/datafusion v1.4.0/go.mod h1:1Zb6VN+W6ALo85cXnM1IKiPw+yQMKMhB9TsTSRDo/38= +cloud.google.com/go/datafusion v1.5.0/go.mod h1:Kz+l1FGHB0J+4XF2fud96WMmRiq/wj8N9u007vyXZ2w= +cloud.google.com/go/datafusion v1.6.0/go.mod h1:WBsMF8F1RhSXvVM8rCV3AeyWVxcC2xY6vith3iw3S+8= +cloud.google.com/go/datalabeling v0.5.0/go.mod h1:TGcJ0G2NzcsXSE/97yWjIZO0bXj0KbVlINXMG9ud42I= +cloud.google.com/go/datalabeling v0.6.0/go.mod h1:WqdISuk/+WIGeMkpw/1q7bK/tFEZxsrFJOJdY2bXvTQ= +cloud.google.com/go/datalabeling v0.7.0/go.mod h1:WPQb1y08RJbmpM3ww0CSUAGweL0SxByuW2E+FU+wXcM= +cloud.google.com/go/dataplex v1.3.0/go.mod h1:hQuRtDg+fCiFgC8j0zV222HvzFQdRd+SVX8gdmFcZzA= +cloud.google.com/go/dataplex v1.4.0/go.mod h1:X51GfLXEMVJ6UN47ESVqvlsRplbLhcsAt0kZCCKsU0A= +cloud.google.com/go/dataplex v1.5.2/go.mod h1:cVMgQHsmfRoI5KFYq4JtIBEUbYwc3c7tXmIDhRmNNVQ= +cloud.google.com/go/dataplex v1.6.0/go.mod h1:bMsomC/aEJOSpHXdFKFGQ1b0TDPIeL28nJObeO1ppRs= +cloud.google.com/go/dataproc v1.7.0/go.mod h1:CKAlMjII9H90RXaMpSxQ8EU6dQx6iAYNPcYPOkSbi8s= +cloud.google.com/go/dataproc v1.8.0/go.mod h1:5OW+zNAH0pMpw14JVrPONsxMQYMBqJuzORhIBfBn9uI= +cloud.google.com/go/dataproc v1.12.0/go.mod h1:zrF3aX0uV3ikkMz6z4uBbIKyhRITnxvr4i3IjKsKrw4= +cloud.google.com/go/dataqna v0.5.0/go.mod h1:90Hyk596ft3zUQ8NkFfvICSIfHFh1Bc7C4cK3vbhkeo= +cloud.google.com/go/dataqna v0.6.0/go.mod h1:1lqNpM7rqNLVgWBJyk5NF6Uen2PHym0jtVJonplVsDA= +cloud.google.com/go/dataqna v0.7.0/go.mod h1:Lx9OcIIeqCrw1a6KdO3/5KMP1wAmTc0slZWwP12Qq3c= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/datastore v1.10.0/go.mod h1:PC5UzAmDEkAmkfaknstTYbNpgE49HAgW2J1gcgUfmdM= +cloud.google.com/go/datastore v1.11.0/go.mod h1:TvGxBIHCS50u8jzG+AW/ppf87v1of8nwzFNgEZU1D3c= +cloud.google.com/go/datastream v1.2.0/go.mod h1:i/uTP8/fZwgATHS/XFu0TcNUhuA0twZxxQ3EyCUQMwo= +cloud.google.com/go/datastream v1.3.0/go.mod h1:cqlOX8xlyYF/uxhiKn6Hbv6WjwPPuI9W2M9SAXwaLLQ= +cloud.google.com/go/datastream v1.4.0/go.mod h1:h9dpzScPhDTs5noEMQVWP8Wx8AFBRyS0s8KWPx/9r0g= +cloud.google.com/go/datastream v1.5.0/go.mod h1:6TZMMNPwjUqZHBKPQ1wwXpb0d5VDVPl2/XoS5yi88q4= +cloud.google.com/go/datastream v1.6.0/go.mod h1:6LQSuswqLa7S4rPAOZFVjHIG3wJIjZcZrw8JDEDJuIs= +cloud.google.com/go/datastream v1.7.0/go.mod h1:uxVRMm2elUSPuh65IbZpzJNMbuzkcvu5CjMqVIUHrww= +cloud.google.com/go/deploy v1.4.0/go.mod h1:5Xghikd4VrmMLNaF6FiRFDlHb59VM59YoDQnOUdsH/c= +cloud.google.com/go/deploy v1.5.0/go.mod h1:ffgdD0B89tToyW/U/D2eL0jN2+IEV/3EMuXHA0l4r+s= +cloud.google.com/go/deploy v1.6.0/go.mod h1:f9PTHehG/DjCom3QH0cntOVRm93uGBDt2vKzAPwpXQI= +cloud.google.com/go/deploy v1.8.0/go.mod h1:z3myEJnA/2wnB4sgjqdMfgxCA0EqC3RBTNcVPs93mtQ= +cloud.google.com/go/dialogflow v1.15.0/go.mod h1:HbHDWs33WOGJgn6rfzBW1Kv807BE3O1+xGbn59zZWI4= +cloud.google.com/go/dialogflow v1.16.1/go.mod h1:po6LlzGfK+smoSmTBnbkIZY2w8ffjz/RcGSS+sh1el0= +cloud.google.com/go/dialogflow v1.17.0/go.mod h1:YNP09C/kXA1aZdBgC/VtXX74G/TKn7XVCcVumTflA+8= +cloud.google.com/go/dialogflow v1.18.0/go.mod h1:trO7Zu5YdyEuR+BhSNOqJezyFQ3aUzz0njv7sMx/iek= +cloud.google.com/go/dialogflow v1.19.0/go.mod h1:JVmlG1TwykZDtxtTXujec4tQ+D8SBFMoosgy+6Gn0s0= +cloud.google.com/go/dialogflow v1.29.0/go.mod h1:b+2bzMe+k1s9V+F2jbJwpHPzrnIyHihAdRFMtn2WXuM= +cloud.google.com/go/dialogflow v1.31.0/go.mod h1:cuoUccuL1Z+HADhyIA7dci3N5zUssgpBJmCzI6fNRB4= +cloud.google.com/go/dialogflow v1.32.0/go.mod h1:jG9TRJl8CKrDhMEcvfcfFkkpp8ZhgPz3sBGmAUYJ2qE= +cloud.google.com/go/dlp v1.6.0/go.mod h1:9eyB2xIhpU0sVwUixfBubDoRwP+GjeUoxxeueZmqvmM= +cloud.google.com/go/dlp v1.7.0/go.mod h1:68ak9vCiMBjbasxeVD17hVPxDEck+ExiHavX8kiHG+Q= +cloud.google.com/go/dlp v1.9.0/go.mod h1:qdgmqgTyReTz5/YNSSuueR8pl7hO0o9bQ39ZhtgkWp4= +cloud.google.com/go/documentai v1.7.0/go.mod h1:lJvftZB5NRiFSX4moiye1SMxHx0Bc3x1+p9e/RfXYiU= +cloud.google.com/go/documentai v1.8.0/go.mod h1:xGHNEB7CtsnySCNrCFdCyyMz44RhFEEX2Q7UD0c5IhU= +cloud.google.com/go/documentai v1.9.0/go.mod h1:FS5485S8R00U10GhgBC0aNGrJxBP8ZVpEeJ7PQDZd6k= +cloud.google.com/go/documentai v1.10.0/go.mod h1:vod47hKQIPeCfN2QS/jULIvQTugbmdc0ZvxxfQY1bg4= +cloud.google.com/go/documentai v1.16.0/go.mod h1:o0o0DLTEZ+YnJZ+J4wNfTxmDVyrkzFvttBXXtYRMHkM= +cloud.google.com/go/documentai v1.18.0/go.mod h1:F6CK6iUH8J81FehpskRmhLq/3VlwQvb7TvwOceQ2tbs= +cloud.google.com/go/domains v0.6.0/go.mod h1:T9Rz3GasrpYk6mEGHh4rymIhjlnIuB4ofT1wTxDeT4Y= +cloud.google.com/go/domains v0.7.0/go.mod h1:PtZeqS1xjnXuRPKE/88Iru/LdfoRyEHYA9nFQf4UKpg= +cloud.google.com/go/domains v0.8.0/go.mod h1:M9i3MMDzGFXsydri9/vW+EWz9sWb4I6WyHqdlAk0idE= +cloud.google.com/go/edgecontainer v0.1.0/go.mod h1:WgkZ9tp10bFxqO8BLPqv2LlfmQF1X8lZqwW4r1BTajk= +cloud.google.com/go/edgecontainer v0.2.0/go.mod h1:RTmLijy+lGpQ7BXuTDa4C4ssxyXT34NIuHIgKuP4s5w= +cloud.google.com/go/edgecontainer v0.3.0/go.mod h1:FLDpP4nykgwwIfcLt6zInhprzw0lEi2P1fjO6Ie0qbc= +cloud.google.com/go/edgecontainer v1.0.0/go.mod h1:cttArqZpBB2q58W/upSG++ooo6EsblxDIolxa3jSjbY= +cloud.google.com/go/errorreporting v0.3.0/go.mod h1:xsP2yaAp+OAW4OIm60An2bbLpqIhKXdWR/tawvl7QzU= +cloud.google.com/go/essentialcontacts v1.3.0/go.mod h1:r+OnHa5jfj90qIfZDO/VztSFqbQan7HV75p8sA+mdGI= +cloud.google.com/go/essentialcontacts v1.4.0/go.mod h1:8tRldvHYsmnBCHdFpvU+GL75oWiBKl80BiqlFh9tp+8= +cloud.google.com/go/essentialcontacts v1.5.0/go.mod h1:ay29Z4zODTuwliK7SnX8E86aUF2CTzdNtvv42niCX0M= +cloud.google.com/go/eventarc v1.7.0/go.mod h1:6ctpF3zTnaQCxUjHUdcfgcA1A2T309+omHZth7gDfmc= +cloud.google.com/go/eventarc v1.8.0/go.mod h1:imbzxkyAU4ubfsaKYdQg04WS1NvncblHEup4kvF+4gw= +cloud.google.com/go/eventarc v1.10.0/go.mod h1:u3R35tmZ9HvswGRBnF48IlYgYeBcPUCjkr4BTdem2Kw= +cloud.google.com/go/eventarc v1.11.0/go.mod h1:PyUjsUKPWoRBCHeOxZd/lbOOjahV41icXyUY5kSTvVY= +cloud.google.com/go/filestore v1.3.0/go.mod h1:+qbvHGvXU1HaKX2nD0WEPo92TP/8AQuCVEBXNY9z0+w= +cloud.google.com/go/filestore v1.4.0/go.mod h1:PaG5oDfo9r224f8OYXURtAsY+Fbyq/bLYoINEK8XQAI= +cloud.google.com/go/filestore v1.5.0/go.mod h1:FqBXDWBp4YLHqRnVGveOkHDf8svj9r5+mUDLupOWEDs= +cloud.google.com/go/filestore v1.6.0/go.mod h1:di5unNuss/qfZTw2U9nhFqo8/ZDSc466dre85Kydllg= +cloud.google.com/go/firestore v1.9.0/go.mod h1:HMkjKHNTtRyZNiMzu7YAsLr9K3X2udY2AMwDaMEQiiE= +cloud.google.com/go/functions v1.6.0/go.mod h1:3H1UA3qiIPRWD7PeZKLvHZ9SaQhR26XIJcC0A5GbvAk= +cloud.google.com/go/functions v1.7.0/go.mod h1:+d+QBcWM+RsrgZfV9xo6KfA1GlzJfxcfZcRPEhDDfzg= +cloud.google.com/go/functions v1.8.0/go.mod h1:RTZ4/HsQjIqIYP9a9YPbU+QFoQsAlYgrwOXJWHn1POY= +cloud.google.com/go/functions v1.9.0/go.mod h1:Y+Dz8yGguzO3PpIjhLTbnqV1CWmgQ5UwtlpzoyquQ08= +cloud.google.com/go/functions v1.10.0/go.mod h1:0D3hEOe3DbEvCXtYOZHQZmD+SzYsi1YbI7dGvHfldXw= +cloud.google.com/go/functions v1.12.0/go.mod h1:AXWGrF3e2C/5ehvwYo/GH6O5s09tOPksiKhz+hH8WkA= +cloud.google.com/go/functions v1.13.0/go.mod h1:EU4O007sQm6Ef/PwRsI8N2umygGqPBS/IZQKBQBcJ3c= +cloud.google.com/go/gaming v1.5.0/go.mod h1:ol7rGcxP/qHTRQE/RO4bxkXq+Fix0j6D4LFPzYTIrDM= +cloud.google.com/go/gaming v1.6.0/go.mod h1:YMU1GEvA39Qt3zWGyAVA9bpYz/yAhTvaQ1t2sK4KPUA= +cloud.google.com/go/gaming v1.7.0/go.mod h1:LrB8U7MHdGgFG851iHAfqUdLcKBdQ55hzXy9xBJz0+w= +cloud.google.com/go/gaming v1.8.0/go.mod h1:xAqjS8b7jAVW0KFYeRUxngo9My3f33kFmua++Pi+ggM= +cloud.google.com/go/gaming v1.9.0/go.mod h1:Fc7kEmCObylSWLO334NcO+O9QMDyz+TKC4v1D7X+Bc0= +cloud.google.com/go/gkebackup v0.2.0/go.mod h1:XKvv/4LfG829/B8B7xRkk8zRrOEbKtEam6yNfuQNH60= +cloud.google.com/go/gkebackup v0.3.0/go.mod h1:n/E671i1aOQvUxT541aTkCwExO/bTer2HDlj4TsBRAo= +cloud.google.com/go/gkebackup v0.4.0/go.mod h1:byAyBGUwYGEEww7xsbnUTBHIYcOPy/PgUWUtOeRm9Vg= +cloud.google.com/go/gkeconnect v0.5.0/go.mod h1:c5lsNAg5EwAy7fkqX/+goqFsU1Da/jQFqArp+wGNr/o= +cloud.google.com/go/gkeconnect v0.6.0/go.mod h1:Mln67KyU/sHJEBY8kFZ0xTeyPtzbq9StAVvEULYK16A= +cloud.google.com/go/gkeconnect v0.7.0/go.mod h1:SNfmVqPkaEi3bF/B3CNZOAYPYdg7sU+obZ+QTky2Myw= +cloud.google.com/go/gkehub v0.9.0/go.mod h1:WYHN6WG8w9bXU0hqNxt8rm5uxnk8IH+lPY9J2TV7BK0= +cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y977wO+hBH0= +cloud.google.com/go/gkehub v0.11.0/go.mod h1:JOWHlmN+GHyIbuWQPl47/C2RFhnFKH38jH9Ascu3n0E= +cloud.google.com/go/gkehub v0.12.0/go.mod h1:djiIwwzTTBrF5NaXCGv3mf7klpEMcST17VBTVVDcuaw= +cloud.google.com/go/gkemulticloud v0.3.0/go.mod h1:7orzy7O0S+5kq95e4Hpn7RysVA7dPs8W/GgfUtsPbrA= +cloud.google.com/go/gkemulticloud v0.4.0/go.mod h1:E9gxVBnseLWCk24ch+P9+B2CoDFJZTyIgLKSalC7tuI= +cloud.google.com/go/gkemulticloud v0.5.0/go.mod h1:W0JDkiyi3Tqh0TJr//y19wyb1yf8llHVto2Htf2Ja3Y= +cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc= +cloud.google.com/go/gsuiteaddons v1.3.0/go.mod h1:EUNK/J1lZEZO8yPtykKxLXI6JSVN2rg9bN8SXOa0bgM= +cloud.google.com/go/gsuiteaddons v1.4.0/go.mod h1:rZK5I8hht7u7HxFQcFei0+AtfS9uSushomRlg+3ua1o= +cloud.google.com/go/gsuiteaddons v1.5.0/go.mod h1:TFCClYLd64Eaa12sFVmUyG62tk4mdIsI7pAnSXRkcFo= +cloud.google.com/go/iam v0.1.0/go.mod h1:vcUNEa0pEm0qRVpmWepWaFMIAI8/hjB9mO8rNCJtF6c= +cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= +cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= +cloud.google.com/go/iam v0.6.0/go.mod h1:+1AH33ueBne5MzYccyMHtEKqLE4/kJOibtffMHDMFMc= +cloud.google.com/go/iam v0.7.0/go.mod h1:H5Br8wRaDGNc8XP3keLc4unfUUZeyH3Sfl9XpQEYOeg= +cloud.google.com/go/iam v0.8.0/go.mod h1:lga0/y3iH6CX7sYqypWJ33hf7kkfXJag67naqGESjkE= +cloud.google.com/go/iam v0.11.0/go.mod h1:9PiLDanza5D+oWFZiH1uG+RnRCfEGKoyl6yo4cgWZGY= +cloud.google.com/go/iam v0.12.0/go.mod h1:knyHGviacl11zrtZUoDuYpDgLjvr28sLQaG0YB2GYAY= +cloud.google.com/go/iam v0.13.0/go.mod h1:ljOg+rcNfzZ5d6f1nAUJ8ZIxOaZUVoS14bKCtaLZ/D0= +cloud.google.com/go/iap v1.4.0/go.mod h1:RGFwRJdihTINIe4wZ2iCP0zF/qu18ZwyKxrhMhygBEc= +cloud.google.com/go/iap v1.5.0/go.mod h1:UH/CGgKd4KyohZL5Pt0jSKE4m3FR51qg6FKQ/z/Ix9A= +cloud.google.com/go/iap v1.6.0/go.mod h1:NSuvI9C/j7UdjGjIde7t7HBz+QTwBcapPE07+sSRcLk= +cloud.google.com/go/iap v1.7.0/go.mod h1:beqQx56T9O1G1yNPph+spKpNibDlYIiIixiqsQXxLIo= +cloud.google.com/go/iap v1.7.1/go.mod h1:WapEwPc7ZxGt2jFGB/C/bm+hP0Y6NXzOYGjpPnmMS74= +cloud.google.com/go/ids v1.1.0/go.mod h1:WIuwCaYVOzHIj2OhN9HAwvW+DBdmUAdcWlFxRl+KubM= +cloud.google.com/go/ids v1.2.0/go.mod h1:5WXvp4n25S0rA/mQWAg1YEEBBq6/s+7ml1RDCW1IrcY= +cloud.google.com/go/ids v1.3.0/go.mod h1:JBdTYwANikFKaDP6LtW5JAi4gubs57SVNQjemdt6xV4= +cloud.google.com/go/iot v1.3.0/go.mod h1:r7RGh2B61+B8oz0AGE+J72AhA0G7tdXItODWsaA2oLs= +cloud.google.com/go/iot v1.4.0/go.mod h1:dIDxPOn0UvNDUMD8Ger7FIaTuvMkj+aGk94RPP0iV+g= +cloud.google.com/go/iot v1.5.0/go.mod h1:mpz5259PDl3XJthEmh9+ap0affn/MqNSP4My77Qql9o= +cloud.google.com/go/iot v1.6.0/go.mod h1:IqdAsmE2cTYYNO1Fvjfzo9po179rAtJeVGUvkLN3rLE= +cloud.google.com/go/kms v1.4.0/go.mod h1:fajBHndQ+6ubNw6Ss2sSd+SWvjL26RNo/dr7uxsnnOA= +cloud.google.com/go/kms v1.5.0/go.mod h1:QJS2YY0eJGBg3mnDfuaCyLauWwBJiHRboYxJ++1xJNg= +cloud.google.com/go/kms v1.6.0/go.mod h1:Jjy850yySiasBUDi6KFUwUv2n1+o7QZFyuUJg6OgjA0= +cloud.google.com/go/kms v1.8.0/go.mod h1:4xFEhYFqvW+4VMELtZyxomGSYtSQKzM178ylFW4jMAg= +cloud.google.com/go/kms v1.9.0/go.mod h1:qb1tPTgfF9RQP8e1wq4cLFErVuTJv7UsSC915J8dh3w= +cloud.google.com/go/kms v1.10.0/go.mod h1:ng3KTUtQQU9bPX3+QGLsflZIHlkbn8amFAMY63m8d24= +cloud.google.com/go/kms v1.10.1/go.mod h1:rIWk/TryCkR59GMC3YtHtXeLzd634lBbKenvyySAyYI= +cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic= +cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= +cloud.google.com/go/language v1.7.0/go.mod h1:DJ6dYN/W+SQOjF8e1hLQXMF21AkH2w9wiPzPCJa2MIE= +cloud.google.com/go/language v1.8.0/go.mod h1:qYPVHf7SPoNNiCL2Dr0FfEFNil1qi3pQEyygwpgVKB8= +cloud.google.com/go/language v1.9.0/go.mod h1:Ns15WooPM5Ad/5no/0n81yUetis74g3zrbeJBE+ptUY= +cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8= +cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08= +cloud.google.com/go/lifesciences v0.8.0/go.mod h1:lFxiEOMqII6XggGbOnKiyZ7IBwoIqA84ClvoezaA/bo= +cloud.google.com/go/logging v1.6.1/go.mod h1:5ZO0mHHbvm8gEmeEUHrmDlTDSu5imF6MUP9OfilNXBw= +cloud.google.com/go/logging v1.7.0/go.mod h1:3xjP2CjkM3ZkO73aj4ASA5wRPGGCRrPIAeNqVNkzY8M= +cloud.google.com/go/longrunning v0.1.1/go.mod h1:UUFxuDWkv22EuY93jjmDMFT5GPQKeFVJBIF6QlTqdsE= +cloud.google.com/go/longrunning v0.3.0/go.mod h1:qth9Y41RRSUE69rDcOn6DdK3HfQfsUI0YSmW3iIlLJc= +cloud.google.com/go/longrunning v0.4.1/go.mod h1:4iWDqhBZ70CvZ6BfETbvam3T8FMvLK+eFj0E6AaRQTo= +cloud.google.com/go/managedidentities v1.3.0/go.mod h1:UzlW3cBOiPrzucO5qWkNkh0w33KFtBJU281hacNvsdE= +cloud.google.com/go/managedidentities v1.4.0/go.mod h1:NWSBYbEMgqmbZsLIyKvxrYbtqOsxY1ZrGM+9RgDqInM= +cloud.google.com/go/managedidentities v1.5.0/go.mod h1:+dWcZ0JlUmpuxpIDfyP5pP5y0bLdRwOS4Lp7gMni/LA= +cloud.google.com/go/maps v0.1.0/go.mod h1:BQM97WGyfw9FWEmQMpZ5T6cpovXXSd1cGmFma94eubI= +cloud.google.com/go/maps v0.6.0/go.mod h1:o6DAMMfb+aINHz/p/jbcY+mYeXBoZoxTfdSQ8VAJaCw= +cloud.google.com/go/maps v0.7.0/go.mod h1:3GnvVl3cqeSvgMcpRlQidXsPYuDGQ8naBis7MVzpXsY= +cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4= +cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w= +cloud.google.com/go/mediatranslation v0.7.0/go.mod h1:LCnB/gZr90ONOIQLgSXagp8XUW1ODs2UmUMvcgMfI2I= +cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE= +cloud.google.com/go/memcache v1.5.0/go.mod h1:dk3fCK7dVo0cUU2c36jKb4VqKPS22BTkf81Xq617aWM= +cloud.google.com/go/memcache v1.6.0/go.mod h1:XS5xB0eQZdHtTuTF9Hf8eJkKtR3pVRCcvJwtm68T3rA= +cloud.google.com/go/memcache v1.7.0/go.mod h1:ywMKfjWhNtkQTxrWxCkCFkoPjLHPW6A7WOTVI8xy3LY= +cloud.google.com/go/memcache v1.9.0/go.mod h1:8oEyzXCu+zo9RzlEaEjHl4KkgjlNDaXbCQeQWlzNFJM= +cloud.google.com/go/metastore v1.5.0/go.mod h1:2ZNrDcQwghfdtCwJ33nM0+GrBGlVuh8rakL3vdPY3XY= +cloud.google.com/go/metastore v1.6.0/go.mod h1:6cyQTls8CWXzk45G55x57DVQ9gWg7RiH65+YgPsNh9s= +cloud.google.com/go/metastore v1.7.0/go.mod h1:s45D0B4IlsINu87/AsWiEVYbLaIMeUSoxlKKDqBGFS8= +cloud.google.com/go/metastore v1.8.0/go.mod h1:zHiMc4ZUpBiM7twCIFQmJ9JMEkDSyZS9U12uf7wHqSI= +cloud.google.com/go/metastore v1.10.0/go.mod h1:fPEnH3g4JJAk+gMRnrAnoqyv2lpUCqJPWOodSaf45Eo= +cloud.google.com/go/monitoring v1.7.0/go.mod h1:HpYse6kkGo//7p6sT0wsIC6IBDET0RhIsnmlA53dvEk= +cloud.google.com/go/monitoring v1.8.0/go.mod h1:E7PtoMJ1kQXWxPjB6mv2fhC5/15jInuulFdYYtlcvT4= +cloud.google.com/go/monitoring v1.12.0/go.mod h1:yx8Jj2fZNEkL/GYZyTLS4ZtZEZN8WtDEiEqG4kLK50w= +cloud.google.com/go/monitoring v1.13.0/go.mod h1:k2yMBAB1H9JT/QETjNkgdCGD9bPF712XiLTVr+cBrpw= +cloud.google.com/go/networkconnectivity v1.4.0/go.mod h1:nOl7YL8odKyAOtzNX73/M5/mGZgqqMeryi6UPZTk/rA= +cloud.google.com/go/networkconnectivity v1.5.0/go.mod h1:3GzqJx7uhtlM3kln0+x5wyFvuVH1pIBJjhCpjzSt75o= +cloud.google.com/go/networkconnectivity v1.6.0/go.mod h1:OJOoEXW+0LAxHh89nXd64uGG+FbQoeH8DtxCHVOMlaM= +cloud.google.com/go/networkconnectivity v1.7.0/go.mod h1:RMuSbkdbPwNMQjB5HBWD5MpTBnNm39iAVpC3TmsExt8= +cloud.google.com/go/networkconnectivity v1.10.0/go.mod h1:UP4O4sWXJG13AqrTdQCD9TnLGEbtNRqjuaaA7bNjF5E= +cloud.google.com/go/networkconnectivity v1.11.0/go.mod h1:iWmDD4QF16VCDLXUqvyspJjIEtBR/4zq5hwnY2X3scM= +cloud.google.com/go/networkmanagement v1.4.0/go.mod h1:Q9mdLLRn60AsOrPc8rs8iNV6OHXaGcDdsIQe1ohekq8= +cloud.google.com/go/networkmanagement v1.5.0/go.mod h1:ZnOeZ/evzUdUsnvRt792H0uYEnHQEMaz+REhhzJRcf4= +cloud.google.com/go/networkmanagement v1.6.0/go.mod h1:5pKPqyXjB/sgtvB5xqOemumoQNB7y95Q7S+4rjSOPYY= +cloud.google.com/go/networksecurity v0.5.0/go.mod h1:xS6fOCoqpVC5zx15Z/MqkfDwH4+m/61A3ODiDV1xmiQ= +cloud.google.com/go/networksecurity v0.6.0/go.mod h1:Q5fjhTr9WMI5mbpRYEbiexTzROf7ZbDzvzCrNl14nyU= +cloud.google.com/go/networksecurity v0.7.0/go.mod h1:mAnzoxx/8TBSyXEeESMy9OOYwo1v+gZ5eMRnsT5bC8k= +cloud.google.com/go/networksecurity v0.8.0/go.mod h1:B78DkqsxFG5zRSVuwYFRZ9Xz8IcQ5iECsNrPn74hKHU= +cloud.google.com/go/notebooks v1.2.0/go.mod h1:9+wtppMfVPUeJ8fIWPOq1UnATHISkGXGqTkxeieQ6UY= +cloud.google.com/go/notebooks v1.3.0/go.mod h1:bFR5lj07DtCPC7YAAJ//vHskFBxA5JzYlH68kXVdk34= +cloud.google.com/go/notebooks v1.4.0/go.mod h1:4QPMngcwmgb6uw7Po99B2xv5ufVoIQ7nOGDyL4P8AgA= +cloud.google.com/go/notebooks v1.5.0/go.mod h1:q8mwhnP9aR8Hpfnrc5iN5IBhrXUy8S2vuYs+kBJ/gu0= +cloud.google.com/go/notebooks v1.7.0/go.mod h1:PVlaDGfJgj1fl1S3dUwhFMXFgfYGhYQt2164xOMONmE= +cloud.google.com/go/notebooks v1.8.0/go.mod h1:Lq6dYKOYOWUCTvw5t2q1gp1lAp0zxAxRycayS0iJcqQ= +cloud.google.com/go/optimization v1.1.0/go.mod h1:5po+wfvX5AQlPznyVEZjGJTMr4+CAkJf2XSTQOOl9l4= +cloud.google.com/go/optimization v1.2.0/go.mod h1:Lr7SOHdRDENsh+WXVmQhQTrzdu9ybg0NecjHidBq6xs= +cloud.google.com/go/optimization v1.3.1/go.mod h1:IvUSefKiwd1a5p0RgHDbWCIbDFgKuEdB+fPPuP0IDLI= +cloud.google.com/go/orchestration v1.3.0/go.mod h1:Sj5tq/JpWiB//X/q3Ngwdl5K7B7Y0KZ7bfv0wL6fqVA= +cloud.google.com/go/orchestration v1.4.0/go.mod h1:6W5NLFWs2TlniBphAViZEVhrXRSMgUGDfW7vrWKvsBk= +cloud.google.com/go/orchestration v1.6.0/go.mod h1:M62Bevp7pkxStDfFfTuCOaXgaaqRAga1yKyoMtEoWPQ= +cloud.google.com/go/orgpolicy v1.4.0/go.mod h1:xrSLIV4RePWmP9P3tBl8S93lTmlAxjm06NSm2UTmKvE= +cloud.google.com/go/orgpolicy v1.5.0/go.mod h1:hZEc5q3wzwXJaKrsx5+Ewg0u1LxJ51nNFlext7Tanwc= +cloud.google.com/go/orgpolicy v1.10.0/go.mod h1:w1fo8b7rRqlXlIJbVhOMPrwVljyuW5mqssvBtU18ONc= +cloud.google.com/go/osconfig v1.7.0/go.mod h1:oVHeCeZELfJP7XLxcBGTMBvRO+1nQ5tFG9VQTmYS2Fs= +cloud.google.com/go/osconfig v1.8.0/go.mod h1:EQqZLu5w5XA7eKizepumcvWx+m8mJUhEwiPqWiZeEdg= +cloud.google.com/go/osconfig v1.9.0/go.mod h1:Yx+IeIZJ3bdWmzbQU4fxNl8xsZ4amB+dygAwFPlvnNo= +cloud.google.com/go/osconfig v1.10.0/go.mod h1:uMhCzqC5I8zfD9zDEAfvgVhDS8oIjySWh+l4WK6GnWw= +cloud.google.com/go/osconfig v1.11.0/go.mod h1:aDICxrur2ogRd9zY5ytBLV89KEgT2MKB2L/n6x1ooPw= +cloud.google.com/go/oslogin v1.4.0/go.mod h1:YdgMXWRaElXz/lDk1Na6Fh5orF7gvmJ0FGLIs9LId4E= +cloud.google.com/go/oslogin v1.5.0/go.mod h1:D260Qj11W2qx/HVF29zBg+0fd6YCSjSqLUkY/qEenQU= +cloud.google.com/go/oslogin v1.6.0/go.mod h1:zOJ1O3+dTU8WPlGEkFSh7qeHPPSoxrcMbbK1Nm2iX70= +cloud.google.com/go/oslogin v1.7.0/go.mod h1:e04SN0xO1UNJ1M5GP0vzVBFicIe4O53FOfcixIqTyXo= +cloud.google.com/go/oslogin v1.9.0/go.mod h1:HNavntnH8nzrn8JCTT5fj18FuJLFJc4NaZJtBnQtKFs= +cloud.google.com/go/phishingprotection v0.5.0/go.mod h1:Y3HZknsK9bc9dMi+oE8Bim0lczMU6hrX0UpADuMefr0= +cloud.google.com/go/phishingprotection v0.6.0/go.mod h1:9Y3LBLgy0kDTcYET8ZH3bq/7qni15yVUoAxiFxnlSUA= +cloud.google.com/go/phishingprotection v0.7.0/go.mod h1:8qJI4QKHoda/sb/7/YmMQ2omRLSLYSu9bU0EKCNI+Lk= +cloud.google.com/go/policytroubleshooter v1.3.0/go.mod h1:qy0+VwANja+kKrjlQuOzmlvscn4RNsAc0e15GGqfMxg= +cloud.google.com/go/policytroubleshooter v1.4.0/go.mod h1:DZT4BcRw3QoO8ota9xw/LKtPa8lKeCByYeKTIf/vxdE= +cloud.google.com/go/policytroubleshooter v1.5.0/go.mod h1:Rz1WfV+1oIpPdN2VvvuboLVRsB1Hclg3CKQ53j9l8vw= +cloud.google.com/go/policytroubleshooter v1.6.0/go.mod h1:zYqaPTsmfvpjm5ULxAyD/lINQxJ0DDsnWOP/GZ7xzBc= +cloud.google.com/go/privatecatalog v0.5.0/go.mod h1:XgosMUvvPyxDjAVNDYxJ7wBW8//hLDDYmnsNcMGq1K0= +cloud.google.com/go/privatecatalog v0.6.0/go.mod h1:i/fbkZR0hLN29eEWiiwue8Pb+GforiEIBnV9yrRUOKI= +cloud.google.com/go/privatecatalog v0.7.0/go.mod h1:2s5ssIFO69F5csTXcwBP7NPFTZvps26xGzvQ2PQaBYg= +cloud.google.com/go/privatecatalog v0.8.0/go.mod h1:nQ6pfaegeDAq/Q5lrfCQzQLhubPiZhSaNhIgfJlnIXs= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/pubsub v1.26.0/go.mod h1:QgBH3U/jdJy/ftjPhTkyXNj543Tin1pRYcdcPRnFIRI= +cloud.google.com/go/pubsub v1.27.1/go.mod h1:hQN39ymbV9geqBnfQq6Xf63yNhUAhv9CZhzp5O6qsW0= +cloud.google.com/go/pubsub v1.28.0/go.mod h1:vuXFpwaVoIPQMGXqRyUQigu/AX1S3IWugR9xznmcXX8= +cloud.google.com/go/pubsub v1.30.0/go.mod h1:qWi1OPS0B+b5L+Sg6Gmc9zD1Y+HaM0MdUr7LsupY1P4= +cloud.google.com/go/pubsublite v1.5.0/go.mod h1:xapqNQ1CuLfGi23Yda/9l4bBCKz/wC3KIJ5gKcxveZg= +cloud.google.com/go/pubsublite v1.6.0/go.mod h1:1eFCS0U11xlOuMFV/0iBqw3zP12kddMeCbj/F3FSj9k= +cloud.google.com/go/pubsublite v1.7.0/go.mod h1:8hVMwRXfDfvGm3fahVbtDbiLePT3gpoiJYJY+vxWxVM= +cloud.google.com/go/recaptchaenterprise v1.3.1/go.mod h1:OdD+q+y4XGeAlxRaMn1Y7/GveP6zmq76byL6tjPE7d4= +cloud.google.com/go/recaptchaenterprise/v2 v2.1.0/go.mod h1:w9yVqajwroDNTfGuhmOjPDN//rZGySaf6PtFVcSCa7o= +cloud.google.com/go/recaptchaenterprise/v2 v2.2.0/go.mod h1:/Zu5jisWGeERrd5HnlS3EUGb/D335f9k51B/FVil0jk= +cloud.google.com/go/recaptchaenterprise/v2 v2.3.0/go.mod h1:O9LwGCjrhGHBQET5CA7dd5NwwNQUErSgEDit1DLNTdo= +cloud.google.com/go/recaptchaenterprise/v2 v2.4.0/go.mod h1:Am3LHfOuBstrLrNCBrlI5sbwx9LBg3te2N6hGvHn2mE= +cloud.google.com/go/recaptchaenterprise/v2 v2.5.0/go.mod h1:O8LzcHXN3rz0j+LBC91jrwI3R+1ZSZEWrfL7XHgNo9U= +cloud.google.com/go/recaptchaenterprise/v2 v2.6.0/go.mod h1:RPauz9jeLtB3JVzg6nCbe12qNoaa8pXc4d/YukAmcnA= +cloud.google.com/go/recaptchaenterprise/v2 v2.7.0/go.mod h1:19wVj/fs5RtYtynAPJdDTb69oW0vNHYDBTbB4NvMD9c= +cloud.google.com/go/recommendationengine v0.5.0/go.mod h1:E5756pJcVFeVgaQv3WNpImkFP8a+RptV6dDLGPILjvg= +cloud.google.com/go/recommendationengine v0.6.0/go.mod h1:08mq2umu9oIqc7tDy8sx+MNJdLG0fUi3vaSVbztHgJ4= +cloud.google.com/go/recommendationengine v0.7.0/go.mod h1:1reUcE3GIu6MeBz/h5xZJqNLuuVjNg1lmWMPyjatzac= +cloud.google.com/go/recommender v1.5.0/go.mod h1:jdoeiBIVrJe9gQjwd759ecLJbxCDED4A6p+mqoqDvTg= +cloud.google.com/go/recommender v1.6.0/go.mod h1:+yETpm25mcoiECKh9DEScGzIRyDKpZ0cEhWGo+8bo+c= +cloud.google.com/go/recommender v1.7.0/go.mod h1:XLHs/W+T8olwlGOgfQenXBTbIseGclClff6lhFVe9Bs= +cloud.google.com/go/recommender v1.8.0/go.mod h1:PkjXrTT05BFKwxaUxQmtIlrtj0kph108r02ZZQ5FE70= +cloud.google.com/go/recommender v1.9.0/go.mod h1:PnSsnZY7q+VL1uax2JWkt/UegHssxjUVVCrX52CuEmQ= +cloud.google.com/go/redis v1.7.0/go.mod h1:V3x5Jq1jzUcg+UNsRvdmsfuFnit1cfe3Z/PGyq/lm4Y= +cloud.google.com/go/redis v1.8.0/go.mod h1:Fm2szCDavWzBk2cDKxrkmWBqoCiL1+Ctwq7EyqBCA/A= +cloud.google.com/go/redis v1.9.0/go.mod h1:HMYQuajvb2D0LvMgZmLDZW8V5aOC/WxstZHiy4g8OiA= +cloud.google.com/go/redis v1.10.0/go.mod h1:ThJf3mMBQtW18JzGgh41/Wld6vnDDc/F/F35UolRZPM= +cloud.google.com/go/redis v1.11.0/go.mod h1:/X6eicana+BWcUda5PpwZC48o37SiFVTFSs0fWAJ7uQ= +cloud.google.com/go/resourcemanager v1.3.0/go.mod h1:bAtrTjZQFJkiWTPDb1WBjzvc6/kifjj4QBYuKCCoqKA= +cloud.google.com/go/resourcemanager v1.4.0/go.mod h1:MwxuzkumyTX7/a3n37gmsT3py7LIXwrShilPh3P1tR0= +cloud.google.com/go/resourcemanager v1.5.0/go.mod h1:eQoXNAiAvCf5PXxWxXjhKQoTMaUSNrEfg+6qdf/wots= +cloud.google.com/go/resourcemanager v1.6.0/go.mod h1:YcpXGRs8fDzcUl1Xw8uOVmI8JEadvhRIkoXXUNVYcVo= +cloud.google.com/go/resourcemanager v1.7.0/go.mod h1:HlD3m6+bwhzj9XCouqmeiGuni95NTrExfhoSrkC/3EI= +cloud.google.com/go/resourcesettings v1.3.0/go.mod h1:lzew8VfESA5DQ8gdlHwMrqZs1S9V87v3oCnKCWoOuQU= +cloud.google.com/go/resourcesettings v1.4.0/go.mod h1:ldiH9IJpcrlC3VSuCGvjR5of/ezRrOxFtpJoJo5SmXg= +cloud.google.com/go/resourcesettings v1.5.0/go.mod h1:+xJF7QSG6undsQDfsCJyqWXyBwUoJLhetkRMDRnIoXA= +cloud.google.com/go/retail v1.8.0/go.mod h1:QblKS8waDmNUhghY2TI9O3JLlFk8jybHeV4BF19FrE4= +cloud.google.com/go/retail v1.9.0/go.mod h1:g6jb6mKuCS1QKnH/dpu7isX253absFl6iE92nHwlBUY= +cloud.google.com/go/retail v1.10.0/go.mod h1:2gDk9HsL4HMS4oZwz6daui2/jmKvqShXKQuB2RZ+cCc= +cloud.google.com/go/retail v1.11.0/go.mod h1:MBLk1NaWPmh6iVFSz9MeKG/Psyd7TAgm6y/9L2B4x9Y= +cloud.google.com/go/retail v1.12.0/go.mod h1:UMkelN/0Z8XvKymXFbD4EhFJlYKRx1FGhQkVPU5kF14= +cloud.google.com/go/run v0.2.0/go.mod h1:CNtKsTA1sDcnqqIFR3Pb5Tq0usWxJJvsWOCPldRU3Do= +cloud.google.com/go/run v0.3.0/go.mod h1:TuyY1+taHxTjrD0ZFk2iAR+xyOXEA0ztb7U3UNA0zBo= +cloud.google.com/go/run v0.8.0/go.mod h1:VniEnuBwqjigv0A7ONfQUaEItaiCRVujlMqerPPiktM= +cloud.google.com/go/run v0.9.0/go.mod h1:Wwu+/vvg8Y+JUApMwEDfVfhetv30hCG4ZwDR/IXl2Qg= +cloud.google.com/go/scheduler v1.4.0/go.mod h1:drcJBmxF3aqZJRhmkHQ9b3uSSpQoltBPGPxGAWROx6s= +cloud.google.com/go/scheduler v1.5.0/go.mod h1:ri073ym49NW3AfT6DZi21vLZrG07GXr5p3H1KxN5QlI= +cloud.google.com/go/scheduler v1.6.0/go.mod h1:SgeKVM7MIwPn3BqtcBntpLyrIJftQISRrYB5ZtT+KOk= +cloud.google.com/go/scheduler v1.7.0/go.mod h1:jyCiBqWW956uBjjPMMuX09n3x37mtyPJegEWKxRsn44= +cloud.google.com/go/scheduler v1.8.0/go.mod h1:TCET+Y5Gp1YgHT8py4nlg2Sew8nUHMqcpousDgXJVQc= +cloud.google.com/go/scheduler v1.9.0/go.mod h1:yexg5t+KSmqu+njTIh3b7oYPheFtBWGcbVUYF1GGMIc= +cloud.google.com/go/secretmanager v1.6.0/go.mod h1:awVa/OXF6IiyaU1wQ34inzQNc4ISIDIrId8qE5QGgKA= +cloud.google.com/go/secretmanager v1.8.0/go.mod h1:hnVgi/bN5MYHd3Gt0SPuTPPp5ENina1/LxM+2W9U9J4= +cloud.google.com/go/secretmanager v1.9.0/go.mod h1:b71qH2l1yHmWQHt9LC80akm86mX8AL6X1MA01dW8ht4= +cloud.google.com/go/secretmanager v1.10.0/go.mod h1:MfnrdvKMPNra9aZtQFvBcvRU54hbPD8/HayQdlUgJpU= +cloud.google.com/go/security v1.5.0/go.mod h1:lgxGdyOKKjHL4YG3/YwIL2zLqMFCKs0UbQwgyZmfJl4= +cloud.google.com/go/security v1.7.0/go.mod h1:mZklORHl6Bg7CNnnjLH//0UlAlaXqiG7Lb9PsPXLfD0= +cloud.google.com/go/security v1.8.0/go.mod h1:hAQOwgmaHhztFhiQ41CjDODdWP0+AE1B3sX4OFlq+GU= +cloud.google.com/go/security v1.9.0/go.mod h1:6Ta1bO8LXI89nZnmnsZGp9lVoVWXqsVbIq/t9dzI+2Q= +cloud.google.com/go/security v1.10.0/go.mod h1:QtOMZByJVlibUT2h9afNDWRZ1G96gVywH8T5GUSb9IA= +cloud.google.com/go/security v1.12.0/go.mod h1:rV6EhrpbNHrrxqlvW0BWAIawFWq3X90SduMJdFwtLB8= +cloud.google.com/go/security v1.13.0/go.mod h1:Q1Nvxl1PAgmeW0y3HTt54JYIvUdtcpYKVfIB8AOMZ+0= +cloud.google.com/go/securitycenter v1.13.0/go.mod h1:cv5qNAqjY84FCN6Y9z28WlkKXyWsgLO832YiWwkCWcU= +cloud.google.com/go/securitycenter v1.14.0/go.mod h1:gZLAhtyKv85n52XYWt6RmeBdydyxfPeTrpToDPw4Auc= +cloud.google.com/go/securitycenter v1.15.0/go.mod h1:PeKJ0t8MoFmmXLXWm41JidyzI3PJjd8sXWaVqg43WWk= +cloud.google.com/go/securitycenter v1.16.0/go.mod h1:Q9GMaLQFUD+5ZTabrbujNWLtSLZIZF7SAR0wWECrjdk= +cloud.google.com/go/securitycenter v1.18.1/go.mod h1:0/25gAzCM/9OL9vVx4ChPeM/+DlfGQJDwBy/UC8AKK0= +cloud.google.com/go/securitycenter v1.19.0/go.mod h1:LVLmSg8ZkkyaNy4u7HCIshAngSQ8EcIRREP3xBnyfag= +cloud.google.com/go/servicecontrol v1.4.0/go.mod h1:o0hUSJ1TXJAmi/7fLJAedOovnujSEvjKCAFNXPQ1RaU= +cloud.google.com/go/servicecontrol v1.5.0/go.mod h1:qM0CnXHhyqKVuiZnGKrIurvVImCs8gmqWsDoqe9sU1s= +cloud.google.com/go/servicecontrol v1.10.0/go.mod h1:pQvyvSRh7YzUF2efw7H87V92mxU8FnFDawMClGCNuAA= +cloud.google.com/go/servicecontrol v1.11.0/go.mod h1:kFmTzYzTUIuZs0ycVqRHNaNhgR+UMUpw9n02l/pY+mc= +cloud.google.com/go/servicecontrol v1.11.1/go.mod h1:aSnNNlwEFBY+PWGQ2DoM0JJ/QUXqV5/ZD9DOLB7SnUk= +cloud.google.com/go/servicedirectory v1.4.0/go.mod h1:gH1MUaZCgtP7qQiI+F+A+OpeKF/HQWgtAddhTbhL2bs= +cloud.google.com/go/servicedirectory v1.5.0/go.mod h1:QMKFL0NUySbpZJ1UZs3oFAmdvVxhhxB6eJ/Vlp73dfg= +cloud.google.com/go/servicedirectory v1.6.0/go.mod h1:pUlbnWsLH9c13yGkxCmfumWEPjsRs1RlmJ4pqiNjVL4= +cloud.google.com/go/servicedirectory v1.7.0/go.mod h1:5p/U5oyvgYGYejufvxhgwjL8UVXjkuw7q5XcG10wx1U= +cloud.google.com/go/servicedirectory v1.8.0/go.mod h1:srXodfhY1GFIPvltunswqXpVxFPpZjf8nkKQT7XcXaY= +cloud.google.com/go/servicedirectory v1.9.0/go.mod h1:29je5JjiygNYlmsGz8k6o+OZ8vd4f//bQLtvzkPPT/s= +cloud.google.com/go/servicemanagement v1.4.0/go.mod h1:d8t8MDbezI7Z2R1O/wu8oTggo3BI2GKYbdG4y/SJTco= +cloud.google.com/go/servicemanagement v1.5.0/go.mod h1:XGaCRe57kfqu4+lRxaFEAuqmjzF0r+gWHjWqKqBvKFo= +cloud.google.com/go/servicemanagement v1.6.0/go.mod h1:aWns7EeeCOtGEX4OvZUWCCJONRZeFKiptqKf1D0l/Jc= +cloud.google.com/go/servicemanagement v1.8.0/go.mod h1:MSS2TDlIEQD/fzsSGfCdJItQveu9NXnUniTrq/L8LK4= +cloud.google.com/go/serviceusage v1.3.0/go.mod h1:Hya1cozXM4SeSKTAgGXgj97GlqUvF5JaoXacR1JTP/E= +cloud.google.com/go/serviceusage v1.4.0/go.mod h1:SB4yxXSaYVuUBYUml6qklyONXNLt83U0Rb+CXyhjEeU= +cloud.google.com/go/serviceusage v1.5.0/go.mod h1:w8U1JvqUqwJNPEOTQjrMHkw3IaIFLoLsPLvsE3xueec= +cloud.google.com/go/serviceusage v1.6.0/go.mod h1:R5wwQcbOWsyuOfbP9tGdAnCAc6B9DRwPG1xtWMDeuPA= +cloud.google.com/go/shell v1.3.0/go.mod h1:VZ9HmRjZBsjLGXusm7K5Q5lzzByZmJHf1d0IWHEN5X4= +cloud.google.com/go/shell v1.4.0/go.mod h1:HDxPzZf3GkDdhExzD/gs8Grqk+dmYcEjGShZgYa9URw= +cloud.google.com/go/shell v1.6.0/go.mod h1:oHO8QACS90luWgxP3N9iZVuEiSF84zNyLytb+qE2f9A= +cloud.google.com/go/spanner v1.41.0/go.mod h1:MLYDBJR/dY4Wt7ZaMIQ7rXOTLjYrmxLE/5ve9vFfWos= +cloud.google.com/go/spanner v1.44.0/go.mod h1:G8XIgYdOK+Fbcpbs7p2fiprDw4CaZX63whnSMLVBxjk= +cloud.google.com/go/spanner v1.45.0/go.mod h1:FIws5LowYz8YAE1J8fOS7DJup8ff7xJeetWEo5REA2M= +cloud.google.com/go/speech v1.6.0/go.mod h1:79tcr4FHCimOp56lwC01xnt/WPJZc4v3gzyT7FoBkCM= +cloud.google.com/go/speech v1.7.0/go.mod h1:KptqL+BAQIhMsj1kOP2la5DSEEerPDuOP/2mmkhHhZQ= +cloud.google.com/go/speech v1.8.0/go.mod h1:9bYIl1/tjsAnMgKGHKmBZzXKEkGgtU+MpdDPTE9f7y0= +cloud.google.com/go/speech v1.9.0/go.mod h1:xQ0jTcmnRFFM2RfX/U+rk6FQNUF6DQlydUSyoooSpco= +cloud.google.com/go/speech v1.14.1/go.mod h1:gEosVRPJ9waG7zqqnsHpYTOoAS4KouMRLDFMekpJ0J0= +cloud.google.com/go/speech v1.15.0/go.mod h1:y6oH7GhqCaZANH7+Oe0BhgIogsNInLlz542tg3VqeYI= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= +cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= +cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc= +cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= +cloud.google.com/go/storage v1.28.1/go.mod h1:Qnisd4CqDdo6BGs2AD5LLnEsmSQ80wQ5ogcBBKhU86Y= +cloud.google.com/go/storage v1.29.0/go.mod h1:4puEjyTKnku6gfKoTfNOU/W+a9JyuVNxjpS5GBrB8h4= +cloud.google.com/go/storagetransfer v1.5.0/go.mod h1:dxNzUopWy7RQevYFHewchb29POFv3/AaBgnhqzqiK0w= +cloud.google.com/go/storagetransfer v1.6.0/go.mod h1:y77xm4CQV/ZhFZH75PLEXY0ROiS7Gh6pSKrM8dJyg6I= +cloud.google.com/go/storagetransfer v1.7.0/go.mod h1:8Giuj1QNb1kfLAiWM1bN6dHzfdlDAVC9rv9abHot2W4= +cloud.google.com/go/storagetransfer v1.8.0/go.mod h1:JpegsHHU1eXg7lMHkvf+KE5XDJ7EQu0GwNJbbVGanEw= +cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw= +cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g= +cloud.google.com/go/talent v1.3.0/go.mod h1:CmcxwJ/PKfRgd1pBjQgU6W3YBwiewmUzQYH5HHmSCmM= +cloud.google.com/go/talent v1.4.0/go.mod h1:ezFtAgVuRf8jRsvyE6EwmbTK5LKciD4KVnHuDEFmOOA= +cloud.google.com/go/talent v1.5.0/go.mod h1:G+ODMj9bsasAEJkQSzO2uHQWXHHXUomArjWQQYkqK6c= +cloud.google.com/go/texttospeech v1.4.0/go.mod h1:FX8HQHA6sEpJ7rCMSfXuzBcysDAuWusNNNvN9FELDd8= +cloud.google.com/go/texttospeech v1.5.0/go.mod h1:oKPLhR4n4ZdQqWKURdwxMy0uiTS1xU161C8W57Wkea4= +cloud.google.com/go/texttospeech v1.6.0/go.mod h1:YmwmFT8pj1aBblQOI3TfKmwibnsfvhIBzPXcW4EBovc= +cloud.google.com/go/tpu v1.3.0/go.mod h1:aJIManG0o20tfDQlRIej44FcwGGl/cD0oiRyMKG19IQ= +cloud.google.com/go/tpu v1.4.0/go.mod h1:mjZaX8p0VBgllCzF6wcU2ovUXN9TONFLd7iz227X2Xg= +cloud.google.com/go/tpu v1.5.0/go.mod h1:8zVo1rYDFuW2l4yZVY0R0fb/v44xLh3llq7RuV61fPM= +cloud.google.com/go/trace v1.3.0/go.mod h1:FFUE83d9Ca57C+K8rDl/Ih8LwOzWIV1krKgxg6N0G28= +cloud.google.com/go/trace v1.4.0/go.mod h1:UG0v8UBqzusp+z63o7FK74SdFE+AXpCLdFb1rshXG+Y= +cloud.google.com/go/trace v1.8.0/go.mod h1:zH7vcsbAhklH8hWFig58HvxcxyQbaIqMarMg9hn5ECA= +cloud.google.com/go/trace v1.9.0/go.mod h1:lOQqpE5IaWY0Ixg7/r2SjixMuc6lfTFeO4QGM4dQWOk= +cloud.google.com/go/translate v1.3.0/go.mod h1:gzMUwRjvOqj5i69y/LYLd8RrNQk+hOmIXTi9+nb3Djs= +cloud.google.com/go/translate v1.4.0/go.mod h1:06Dn/ppvLD6WvA5Rhdp029IX2Mi3Mn7fpMRLPvXT5Wg= +cloud.google.com/go/translate v1.5.0/go.mod h1:29YDSYveqqpA1CQFD7NQuP49xymq17RXNaUDdc0mNu0= +cloud.google.com/go/translate v1.6.0/go.mod h1:lMGRudH1pu7I3n3PETiOB2507gf3HnfLV8qlkHZEyos= +cloud.google.com/go/translate v1.7.0/go.mod h1:lMGRudH1pu7I3n3PETiOB2507gf3HnfLV8qlkHZEyos= +cloud.google.com/go/video v1.8.0/go.mod h1:sTzKFc0bUSByE8Yoh8X0mn8bMymItVGPfTuUBUyRgxk= +cloud.google.com/go/video v1.9.0/go.mod h1:0RhNKFRF5v92f8dQt0yhaHrEuH95m068JYOvLZYnJSw= +cloud.google.com/go/video v1.12.0/go.mod h1:MLQew95eTuaNDEGriQdcYn0dTwf9oWiA4uYebxM5kdg= +cloud.google.com/go/video v1.13.0/go.mod h1:ulzkYlYgCp15N2AokzKjy7MQ9ejuynOJdf1tR5lGthk= +cloud.google.com/go/video v1.14.0/go.mod h1:SkgaXwT+lIIAKqWAJfktHT/RbgjSuY6DobxEp0C5yTQ= +cloud.google.com/go/video v1.15.0/go.mod h1:SkgaXwT+lIIAKqWAJfktHT/RbgjSuY6DobxEp0C5yTQ= +cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU= +cloud.google.com/go/videointelligence v1.7.0/go.mod h1:k8pI/1wAhjznARtVT9U1llUaFNPh7muw8QyOUpavru4= +cloud.google.com/go/videointelligence v1.8.0/go.mod h1:dIcCn4gVDdS7yte/w+koiXn5dWVplOZkE+xwG9FgK+M= +cloud.google.com/go/videointelligence v1.9.0/go.mod h1:29lVRMPDYHikk3v8EdPSaL8Ku+eMzDljjuvRs105XoU= +cloud.google.com/go/videointelligence v1.10.0/go.mod h1:LHZngX1liVtUhZvi2uNS0VQuOzNi2TkY1OakiuoUOjU= +cloud.google.com/go/vision v1.2.0/go.mod h1:SmNwgObm5DpFBme2xpyOyasvBc1aPdjvMk2bBk0tKD0= +cloud.google.com/go/vision/v2 v2.2.0/go.mod h1:uCdV4PpN1S0jyCyq8sIM42v2Y6zOLkZs+4R9LrGYwFo= +cloud.google.com/go/vision/v2 v2.3.0/go.mod h1:UO61abBx9QRMFkNBbf1D8B1LXdS2cGiiCRx0vSpZoUo= +cloud.google.com/go/vision/v2 v2.4.0/go.mod h1:VtI579ll9RpVTrdKdkMzckdnwMyX2JILb+MhPqRbPsY= +cloud.google.com/go/vision/v2 v2.5.0/go.mod h1:MmaezXOOE+IWa+cS7OhRRLK2cNv1ZL98zhqFFZaaH2E= +cloud.google.com/go/vision/v2 v2.6.0/go.mod h1:158Hes0MvOS9Z/bDMSFpjwsUrZ5fPrdwuyyvKSGAGMY= +cloud.google.com/go/vision/v2 v2.7.0/go.mod h1:H89VysHy21avemp6xcf9b9JvZHVehWbET0uT/bcuY/0= +cloud.google.com/go/vmmigration v1.2.0/go.mod h1:IRf0o7myyWFSmVR1ItrBSFLFD/rJkfDCUTO4vLlJvsE= +cloud.google.com/go/vmmigration v1.3.0/go.mod h1:oGJ6ZgGPQOFdjHuocGcLqX4lc98YQ7Ygq8YQwHh9A7g= +cloud.google.com/go/vmmigration v1.5.0/go.mod h1:E4YQ8q7/4W9gobHjQg4JJSgXXSgY21nA5r8swQV+Xxc= +cloud.google.com/go/vmmigration v1.6.0/go.mod h1:bopQ/g4z+8qXzichC7GW1w2MjbErL54rk3/C843CjfY= +cloud.google.com/go/vmwareengine v0.1.0/go.mod h1:RsdNEf/8UDvKllXhMz5J40XxDrNJNN4sagiox+OI208= +cloud.google.com/go/vmwareengine v0.2.2/go.mod h1:sKdctNJxb3KLZkE/6Oui94iw/xs9PRNC2wnNLXsHvH8= +cloud.google.com/go/vmwareengine v0.3.0/go.mod h1:wvoyMvNWdIzxMYSpH/R7y2h5h3WFkx6d+1TIsP39WGY= +cloud.google.com/go/vpcaccess v1.4.0/go.mod h1:aQHVbTWDYUR1EbTApSVvMq1EnT57ppDmQzZ3imqIk4w= +cloud.google.com/go/vpcaccess v1.5.0/go.mod h1:drmg4HLk9NkZpGfCmZ3Tz0Bwnm2+DKqViEpeEpOq0m8= +cloud.google.com/go/vpcaccess v1.6.0/go.mod h1:wX2ILaNhe7TlVa4vC5xce1bCnqE3AeH27RV31lnmZes= +cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xXZmFiHmGE= +cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= +cloud.google.com/go/webrisk v1.6.0/go.mod h1:65sW9V9rOosnc9ZY7A7jsy1zoHS5W9IAXv6dGqhMQMc= +cloud.google.com/go/webrisk v1.7.0/go.mod h1:mVMHgEYH0r337nmt1JyLthzMr6YxwN1aAIEc2fTcq7A= +cloud.google.com/go/webrisk v1.8.0/go.mod h1:oJPDuamzHXgUc+b8SiHRcVInZQuybnvEW72PqTc7sSg= +cloud.google.com/go/websecurityscanner v1.3.0/go.mod h1:uImdKm2wyeXQevQJXeh8Uun/Ym1VqworNDlBXQevGMo= +cloud.google.com/go/websecurityscanner v1.4.0/go.mod h1:ebit/Fp0a+FWu5j4JOmJEV8S8CzdTkAS77oDsiSqYWQ= +cloud.google.com/go/websecurityscanner v1.5.0/go.mod h1:Y6xdCPy81yi0SQnDY1xdNTNpfY1oAgXUlcfN3B3eSng= +cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= +cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= +cloud.google.com/go/workflows v1.8.0/go.mod h1:ysGhmEajwZxGn1OhGOGKsTXc5PyxOc0vfKf5Af+to4M= +cloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT3ujaO/WwSA= +cloud.google.com/go/workflows v1.10.0/go.mod h1:fZ8LmRmZQWacon9UCX1r/g/DfAXx5VcPALq2CxzdePw= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8= +git.sr.ht/~sbinet/gg v0.3.1/go.mod h1:KGYtlADtqsqANL9ueOFkWymvzUvLMQllU5Ixo+8v3pc= github.com/360EntSecGroup-Skylar/excelize/v2 v2.3.0 h1:tDWYNCJrpNnlNg8mVdlzAzPjlPaRbsA/kS8H9LczleQ= github.com/360EntSecGroup-Skylar/excelize/v2 v2.3.0/go.mod h1:Uwb0d1GgxJieUWZG5WylTrgQ2SrldfjagAxheU8W6MQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk= github.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY= +github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk= +github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= +github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b/go.mod h1:1KcenG0jGWcpt8ov532z81sp/kMMUG485J2InIOyADM= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -10,10 +618,18 @@ github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= github.com/alicebob/miniredis v2.5.0+incompatible/go.mod h1:8HZjEj4yU0dwhYHky+DxYx+6BMjkBbe5ONFIF1MXffk= +github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/antchfx/htmlquery v1.2.4 h1:qLteofCMe/KGovBI6SQgmou2QNyedFUW+pE+BpeZ494= github.com/antchfx/htmlquery v1.2.4/go.mod h1:2xO6iu3EVWs7R2JYqBbp8YzG50gj/ofqs5/0VZoDZLc= github.com/antchfx/xpath v1.2.0 h1:mbwv7co+x0RwgeGAOHdrKy89GvHaGvxxBtPK0uF9Zr8= github.com/antchfx/xpath v1.2.0/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs= +github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/apache/arrow/go/v10 v10.0.1/go.mod h1:YvhnlEePVnBS4+0z3fhPfUy7W1Ikj0Ih0vcRo/gZ1M0= +github.com/apache/arrow/go/v11 v11.0.0/go.mod h1:Eg5OsL5H+e299f7u5ssuXsuHQVEGC4xei5aX110hRiI= +github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/astaxie/beego v1.12.3 h1:SAQkdD2ePye+v8Gn1r4X6IKZM1wd28EyUOVQ3PDSOOQ= github.com/astaxie/beego v1.12.3/go.mod h1:p3qIm0Ryx7zeBHLljmd7omloyca1s4yu1a8kM1FkpIA= github.com/beego/goyaml2 v0.0.0-20130207012346-5545475820dd/go.mod h1:1b+Y/CofkYwXMUU0OhQqGvsY2Bvgr4j6jfT699wyZKQ= @@ -22,11 +638,35 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= +github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60= github.com/casbin/casbin v1.7.0/go.mod h1:c67qKN6Oum3UF5Q1+BByfFxkwKvhwW57ITjqwtzR1KE= -github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20230310173818-32f1caf87195/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/couchbase/go-couchbase v0.0.0-20200519150804-63f3cdb75e0d/go.mod h1:TWI8EKQMs5u5jLKW/tsb9VwauIrMIxQG1r5fMsswK5U= github.com/couchbase/gomemcached v0.0.0-20200526233749-ec430f949808/go.mod h1:srVSlQLB8iXBVXHgnqemxUXqN6FCvClgCMPCsjBDR7c= github.com/couchbase/goutils v0.0.0-20180530154633-e865a1461c8a/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs= @@ -37,70 +677,229 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.1-0.20210802184156-9742bd7fca1c+incompatible h1:kFnl8B5YgOXou7f+dsklKcGSXph/nubNx7I6d6RoFuE= github.com/dgrijalva/jwt-go v3.2.1-0.20210802184156-9742bd7fca1c+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/elastic/go-elasticsearch/v6 v6.8.5/go.mod h1:UwaDJsD3rWLM5rKNFzv9hgox93HoX8utj1kxD9aFUcI= github.com/elazarl/go-bindata-assetfs v1.0.0 h1:G/bYguwHIzWq9ZoyUQqrjTmJbbYn3j3CKKpKinvZLFk= github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= +github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= +github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= +github.com/envoyproxy/go-control-plane v0.10.3/go.mod h1:fJJn/j26vwOu972OllsvAgJJM//w9BV6Fxbg2LuVd34= +github.com/envoyproxy/go-control-plane v0.11.0/go.mod h1:VnHyVMpzcLvCFt9yUz1UnCwHLhwx1WguiVDV7pTG/tI= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo= +github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w= +github.com/envoyproxy/protoc-gen-validate v0.10.0/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= +github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= +github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/glendc/gopher-json v0.0.0-20170414221815-dc4743023d0c/go.mod h1:Gja1A+xZ9BoviGJNA2E9vFkPjjsl+CoJxSXiQM1UXtw= +github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g= +github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks= +github.com/go-fonts/liberation v0.1.1/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= +github.com/go-fonts/liberation v0.2.0/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= +github.com/go-fonts/stix v0.1.0/go.mod h1:w/c1f0ldAUlJmLBvlbkvVXLAD+tAMqobIIQpmnUIzUY= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-latex/latex v0.0.0-20210118124228-b3d85cf34e07/go.mod h1:CO1AlKB2CSIqUrmQPqA0gdRIlnLEY0gK5JGjh37zN5U= +github.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81/go.mod h1:SX0U8uGpxhq9o2S/CELCSUxEWWAuoCUcVCQWv7G2OCk= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= +github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= +github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-pdf/fpdf v0.5.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= +github.com/go-pdf/fpdf v0.6.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= github.com/go-redis/redis v6.14.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= +github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/flatbuffers v2.0.8+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/s2a-go v0.1.0/go.mod h1:OJpEgntRZo8ugHpF9hkoLJbS5dSI20XZeXJ9JVywLlM= +github.com/google/s2a-go v0.1.3/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= +github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= +github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= +github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= +github.com/googleapis/enterprise-certificate-proxy v0.2.1/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= +github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= +github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= +github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= +github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= +github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= +github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo= +github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= +github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= +github.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= +github.com/googleapis/gax-go/v2 v2.8.0/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= +github.com/googleapis/gax-go/v2 v2.10.0/go.mod h1:4UOEnMCrxsSqQ940WnTiD6qJ63le2ev3xfyagutxiPw= +github.com/googleapis/gax-go/v2 v2.11.0/go.mod h1:DxmR61SGKkGLa2xigwuZIQpkCI2S5iydzRfb3peWZJI= +github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= +github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg= github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huaweicloud/huaweicloud-sdk-go-obs v3.23.4+incompatible h1:XRAk4HBDLCYEdPLWtKf5iZhOi7lfx17aY0oSO9+mcg8= github.com/huaweicloud/huaweicloud-sdk-go-obs v3.23.4+incompatible/go.mod h1:l7VUhRbTKCzdOacdT4oWCwATKyvZqUOlOqr0Ous3k4s= +github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= +github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/asmfmt v1.3.2/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j0HLHbNSE= +github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -109,31 +908,68 @@ github.com/ledisdb/ledisdb v0.0.0-20200510135210-d35789ec47e6/go.mod h1:n931TsDu github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.8.0 h1:9xohqzkUwzR4Ga4ivdTcawVS89YSDVxXMa3xJX3cGzg= github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= +github.com/lyft/protoc-gen-star v0.6.1/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= +github.com/lyft/protoc-gen-star/v2 v2.0.1/go.mod h1:RcCdONR2ScXaYnQC5tUzxzlpA3WVYF7/opLeUgcQs/o= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U= github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY= +github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3/go.mod h1:RagcQ7I8IeTMnF8JTXieKnO4Z6JCsikNEzj0DwauVzE= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= +github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= +github.com/opensourceways/go-gitee v0.0.0-20240305060727-0df28a4f60c0 h1:kTXDsvRxpOS/HFIrNRUM4H+rOgftmDr3w01rnxzTVWU= +github.com/opensourceways/go-gitee v0.0.0-20240305060727-0df28a4f60c0/go.mod h1:OExGhjyeAI6nM597rup/xn+x1YN+90AwEZBazHzGdSY= +github.com/opensourceways/robot-gitee-lib v1.0.0 h1:nv8qGg8Ns7yAvvbwwyGMoqJSV3R7QFo8/YoBfbIg5v8= +github.com/opensourceways/robot-gitee-lib v1.0.0/go.mod h1:Q4RDKbIhM+mOrXnDkeChGErGsPwhD4rUZkPOv4iX6pc= github.com/opensourceways/server-common-lib v0.0.0-20231027024402-f55c66e6699c h1:atmkPztYx7LFXhwnjrQ6IvgZXmzqFREYzpYA4qfsG9I= github.com/opensourceways/server-common-lib v0.0.0-20231027024402-f55c66e6699c/go.mod h1:1iVJ+C3L9e0GJMUhGfbegH4CecnALntzfTW29GzBGUk= github.com/pelletier/go-toml v1.0.1/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/peterh/liner v1.0.1-0.20171122030339-3681c2a91233/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc= +github.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2dXMnm1mY= +github.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= +github.com/phpdave11/gofpdi v1.0.13/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= +github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= +github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= @@ -144,8 +980,10 @@ github.com/prometheus/client_golang v1.11.1 h1:+4eQaD7vAZ6DsfsxB15hbE0odUjGI5ARs github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= +github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0 h1:iMAkS2TDoNWnKM+Kopnx/8tnEStIfpYA0ur0xQzzhMQ= @@ -155,6 +993,7 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/richardlehane/mscfb v1.0.4 h1:WULscsljNPConisD5hR0+OyZjwK46Pfyr6mPu5ZawpM= github.com/richardlehane/mscfb v1.0.4/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk= github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg= @@ -162,8 +1001,14 @@ github.com/richardlehane/msoleps v1.0.3 h1:aznSZzrwYRl3rLKRT3gUk9am7T/mLNSnJINvN github.com/richardlehane/msoleps v1.0.3/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w= +github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245/go.mod h1:pQAZKsJ8yyVxGRWYNEm9oFB8ieLgKFnamEyDmSA0BRk= github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644 h1:X+yvsM2yrEktyI+b2qND5gpH8YhURn0k8OCaeRnkINo= github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644/go.mod h1:nkxAfR/5quYxwPZhyDxgasBMnRtBZd0FCEpawpjMUFg= github.com/siddontang/go v0.0.0-20170517070808-cb568a3e5cc0/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw= @@ -172,22 +1017,35 @@ github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d/go.mod h1:AMEsy7v5z github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304 h1:Jpy1PXuP99tXNrhbq2BaPz9B+jNAvH1JPQQpG/9GCXY= github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= +github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= +github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/ssdb/gossdb v0.0.0-20180723034631-88f6b59b84ec/go.mod h1:QBvMkMya+gXctz3kmljlUCu/yB3GZ6oee+dUozsezQE= +github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/syndtr/goleveldb v0.0.0-20160425020131-cfa635847112/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0= github.com/syndtr/goleveldb v0.0.0-20181127023241-353a9fca669c/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0= github.com/ugorji/go v0.0.0-20171122102828-84cb69a8af83/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ= @@ -201,116 +1059,739 @@ github.com/xuri/excelize/v2 v2.7.1/go.mod h1:qc0+2j4TvAUrBw36ATtcTeC1VCM0fFdAXZO github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ= github.com/xuri/nfp v0.0.0-20230919160717-d98342af3f05 h1:qhbILQo1K3mphbwKh1vNm4oGezE1eF9fQWmNiIpSfI4= github.com/xuri/nfp v0.0.0-20230919160717-d98342af3f05/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/gopher-lua v0.0.0-20171031051903-609c9cd26973/go.mod h1:aEV29XrmTYFr3CiRxZeGHpkvbwq+prZduBqMaascyCU= +github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= +github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= +go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= +golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3/go.mod h1:NOZ3BPKG0ec/BKJQgnvsSFpcKLM5xXVWnvZS97DWHgE= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20220827204233-334a2380cb91/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= +golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20210216034530-4410531fe030/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20210607152325-775e3b0c77b9/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/image v0.0.0-20220302094943-723b81ca9867/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= golang.org/x/image v0.5.0/go.mod h1:FVC7BI/5Ym8R25iw5OLsgshdUBbT1h5jZTpA+mvAdZ4= golang.org/x/image v0.10.0 h1:gXjUUtwtx5yOE0VKWq1CH4IJAClq4UGgUA3i+rpON9M= golang.org/x/image v0.10.0/go.mod h1:jtrku+n79PfroUbvDdeUWMAI+heR786BofxrbiSF+J0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20221012135044-0b7e1fb9d458/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20221006150949-b44042a4b9c1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec= +golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= +golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= +golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4= +golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= +golang.org/x/oauth2 v0.12.0 h1:smVPGxink+n1ZI5pkQa8y6fZT0RW0MgCO5bFpepy4B4= +golang.org/x/oauth2 v0.12.0/go.mod h1:A74bZ3aGXgCY0qaIC9Ahg6Lglin4AMAco8cIv9baba4= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210304124612-50617c2ba197/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190927191325-030b2cf1153e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= +gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= +gonum.org/v1/gonum v0.9.3/go.mod h1:TZumC3NeyVQskjXqmyWt4S3bINhy7B4eYwW69EbyX+0= +gonum.org/v1/gonum v0.11.0/go.mod h1:fSG4YDCxxUZQJ7rKsQrj0gMOg00Il0Z96/qMA4bVQhA= +gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= +gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= +gonum.org/v1/plot v0.9.0/go.mod h1:3Pcqqmp6RHvJI72kgb8fThyUnav364FOsdDo2aGW5lY= +gonum.org/v1/plot v0.10.1/go.mod h1:VZW5OlhkL1mysU9vaqNHnsy86inf6Ot+jB3r+BczCEo= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= +google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= +google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= +google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= +google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= +google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= +google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= +google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= +google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= +google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= +google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= +google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= +google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= +google.golang.org/api v0.77.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= +google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= +google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg= +google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= +google.golang.org/api v0.85.0/go.mod h1:AqZf8Ep9uZ2pyTvgL+x0D3Zt0eoT9b5E8fmzfu6FO2g= +google.golang.org/api v0.90.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= +google.golang.org/api v0.93.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= +google.golang.org/api v0.95.0/go.mod h1:eADj+UBuxkh5zlrSntJghuNeg8HwQ1w5lTKkuqaETEI= +google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.99.0/go.mod h1:1YOf74vkVndF7pG6hIHuINsM7eWwpVTAfNMNiL91A08= +google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70= +google.golang.org/api v0.102.0/go.mod h1:3VFl6/fzoA+qNuS1N1/VfXY4LjoXN/wzeIp7TweWwGo= +google.golang.org/api v0.103.0/go.mod h1:hGtW6nK1AC+d9si/UBhw8Xli+QMOf6xyNAyJw4qU9w0= +google.golang.org/api v0.106.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= +google.golang.org/api v0.107.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= +google.golang.org/api v0.108.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= +google.golang.org/api v0.110.0/go.mod h1:7FC4Vvx1Mooxh8C5HWjzZHcavuS2f6pmJpZx60ca7iI= +google.golang.org/api v0.111.0/go.mod h1:qtFHvU9mhgTJegR31csQ+rwxyUTHOKFqCKWp1J0fdw0= +google.golang.org/api v0.114.0/go.mod h1:ifYI2ZsFK6/uGddGfAD5BMxlnkBqCmqHSDUVi45N5Yg= +google.golang.org/api v0.118.0/go.mod h1:76TtD3vkgmZ66zZzp72bUUklpmQmKlhh6sYtIjYK+5E= +google.golang.org/api v0.122.0/go.mod h1:gcitW0lvnyWjSp9nKxAbdHKIZ6vF4aajGueeslZOyms= +google.golang.org/api v0.124.0/go.mod h1:xu2HQurE5gi/3t1aFCvhPD781p0a3p11sdunTJ2BlP4= +google.golang.org/api v0.126.0/go.mod h1:mBwVAtz+87bEN6CbA1GtZPDOqY2R5ONPqJeIlvyo4Aw= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= +google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= +google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= +google.golang.org/genproto v0.0.0-20220329172620-7be39ac1afc7/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220722212130-b98a9ff5e252/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE= +google.golang.org/genproto v0.0.0-20220801145646-83ce21fca29f/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc= +google.golang.org/genproto v0.0.0-20220815135757-37a418bb8959/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220817144833-d7fd3f11b9b1/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220829144015-23454907ede3/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220829175752-36a9c930ecbf/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220913154956-18f8339a66a5/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220914142337-ca0e39ece12f/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220915135415-7fd63a7952de/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220916172020-2692e8806bfa/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220919141832-68c03719ef51/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220920201722-2b89144ce006/go.mod h1:ht8XFiar2npT/g4vkk7O0WYS1sHOHbdujxbEp7CJWbw= +google.golang.org/genproto v0.0.0-20220926165614-551eb538f295/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= +google.golang.org/genproto v0.0.0-20220926220553-6981cbe3cfce/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= +google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqwhZAwq4wsRUaVG555sVgsNmIjRtO7t/JH29U= +google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= +google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= +google.golang.org/genproto v0.0.0-20221024153911-1573dae28c9c/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= +google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= +google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c/go.mod h1:CGI5F/G+E5bKwmfYo09AXuVN4dD894kIKUFmVbP2/Fo= +google.golang.org/genproto v0.0.0-20221109142239-94d6d90a7d66/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221114212237-e4508ebdbee1/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221117204609-8f9c96812029/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221201164419-0e50fba7f41c/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221201204527-e3fa12d562f3/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221202195650-67e5cbc046fd/go.mod h1:cTsE614GARnxrLsqKREzmNYJACSWWpAWdNMwnD7c2BE= +google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230112194545-e10362b5ecf9/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230113154510-dbe35b8444a5/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230123190316-2c411cf9d197/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230124163310-31e0e69b6fc2/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230125152338-dcaf20b6aeaa/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230127162408-596548ed4efa/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230209215440-0dfe4f8abfcc/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44/go.mod h1:8B0gmkoRebU8ukX6HP+4wrVQUY1+6PkQ44BSyIlflHA= +google.golang.org/genproto v0.0.0-20230222225845-10f96fb3dbec/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw= +google.golang.org/genproto v0.0.0-20230223222841-637eb2293923/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw= +google.golang.org/genproto v0.0.0-20230303212802-e74f57abe488/go.mod h1:TvhZT5f700eVlTNwND1xoEZQeWTB2RY/65kplwl/bFA= +google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= +google.golang.org/genproto v0.0.0-20230320184635-7606e756e683/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= +google.golang.org/genproto v0.0.0-20230323212658-478b75c54725/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= +google.golang.org/genproto v0.0.0-20230330154414-c0448cd141ea/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= +google.golang.org/genproto v0.0.0-20230331144136-dcfb400f0633/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= +google.golang.org/genproto v0.0.0-20230403163135-c38d8f061ccd/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= +google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= +google.golang.org/genproto v0.0.0-20230525234025-438c736192d0/go.mod h1:9ExIQyXL5hZrHzQceCwuSYwZZ5QZBazOcprJ5rgs3lY= +google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:xZnkP7mREFX5MORlOPEzLMr+90PPZQ2QWzrVTWfAq64= +google.golang.org/genproto/googleapis/api v0.0.0-20230525234020-1aefcd67740a/go.mod h1:ts19tUU+Z0ZShN1y3aPyq2+O3d5FUNNgT6FtOzmrNn8= +google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= +google.golang.org/genproto/googleapis/api v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= +google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= +google.golang.org/genproto/googleapis/bytestream v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:ylj+BE99M198VPbBh6A8d9n3w8fChvyLK3wwBOjXBFA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234015-3fc162c6f38a/go.mod h1:xURIpW9ES5+/GZhnV6beoEtxQrnkRGIfP5VQG2tCBLc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= +google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= +google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY= +google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= +google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= +google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE= gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -318,9 +1799,68 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/apimachinery v0.25.3 h1:7o9ium4uyUOM76t6aunP0nZuex7gDf8VGwkR5RcJnQc= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= k8s.io/apimachinery v0.25.3/go.mod h1:jaF9C/iPNM1FuLl7Zuy5b9v+n35HGSh6AQ4HYRkCqwo= +k8s.io/apimachinery v0.26.1 h1:8EZ/eGJL+hY/MYCNwhmDzVqq2lPl3N3Bo8rvweJwXUQ= +k8s.io/apimachinery v0.26.1/go.mod h1:tnPmbONNJ7ByJNz9+n9kMjNP8ON+1qoAIIC70lztu74= +k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= +k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= +k8s.io/klog/v2 v2.70.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1/go.mod h1:C/N6wCaBHeBHkHUesQOQy2/MZqGgMAFPqGsGQLdbZBU= +k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= +lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= +modernc.org/cc/v3 v3.36.0/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= +modernc.org/cc/v3 v3.36.2/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= +modernc.org/cc/v3 v3.36.3/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= +modernc.org/ccgo/v3 v3.0.0-20220428102840-41399a37e894/go.mod h1:eI31LL8EwEBKPpNpA4bU1/i+sKOwOrQy8D87zWUcRZc= +modernc.org/ccgo/v3 v3.0.0-20220430103911-bc99d88307be/go.mod h1:bwdAnOoaIt8Ax9YdWGjxWsdkPcZyRPHqrOvJxaKAKGw= +modernc.org/ccgo/v3 v3.16.4/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= +modernc.org/ccgo/v3 v3.16.6/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= +modernc.org/ccgo/v3 v3.16.8/go.mod h1:zNjwkizS+fIFDrDjIAgBSCLkWbJuHF+ar3QRn+Z9aws= +modernc.org/ccgo/v3 v3.16.9/go.mod h1:zNMzC9A9xeNUepy6KuZBbugn3c0Mc9TeiJO4lgvkJDo= +modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ= +modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM= +modernc.org/libc v0.0.0-20220428101251-2d5f3daf273b/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA= +modernc.org/libc v1.16.0/go.mod h1:N4LD6DBE9cf+Dzf9buBlzVJndKr/iJHG97vGLHYnb5A= +modernc.org/libc v1.16.1/go.mod h1:JjJE0eu4yeK7tab2n4S1w8tlWd9MxXLRzheaRnAKymU= +modernc.org/libc v1.16.17/go.mod h1:hYIV5VZczAmGZAnG15Vdngn5HSF5cSkbvfz2B7GRuVU= +modernc.org/libc v1.16.19/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA= +modernc.org/libc v1.17.0/go.mod h1:XsgLldpP4aWlPlsjqKRdHPqCxCjISdHfM/yeWC5GyW0= +modernc.org/libc v1.17.1/go.mod h1:FZ23b+8LjxZs7XtFMbSzL/EhPxNbfZbErxEHc7cbD9s= +modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/memory v1.1.1/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= +modernc.org/memory v1.2.0/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= +modernc.org/memory v1.2.1/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= +modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= +modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= +modernc.org/sqlite v1.18.1/go.mod h1:6ho+Gow7oX5V+OiOQ6Tr4xeqbx13UZ6t+Fw9IRUG4d4= +modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw= +modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw= +modernc.org/tcl v1.13.1/go.mod h1:XOLfOwzhkljL4itZkK6T72ckMgvj0BDsnKNdZVUOecw= +modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= +modernc.org/z v1.5.1/go.mod h1:eWFB510QWW5Th9YGZT81s+LwvaAs3Q2yr4sP0rmLkv8= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= +sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= diff --git a/cve-vulner-manager/models/initdb.go b/cve-vulner-manager/models/initdb.go index 05e4c9a..8d9e890 100644 --- a/cve-vulner-manager/models/initdb.go +++ b/cve-vulner-manager/models/initdb.go @@ -1,16 +1,18 @@ package models import ( - "cvevulner/common" "database/sql" + "github.com/astaxie/beego" "github.com/astaxie/beego/config" "github.com/astaxie/beego/logs" "github.com/astaxie/beego/orm" _ "github.com/go-sql-driver/mysql" + + "cvevulner/common" ) -//InitDb init database +// InitDb init database func Initdb() bool { BConfig, err := config.NewConfig("ini", "conf/app.conf") if err != nil { diff --git a/cve-vulner-manager/models/modeldb.go b/cve-vulner-manager/models/modeldb.go index 5a31a4c..47d3196 100644 --- a/cve-vulner-manager/models/modeldb.go +++ b/cve-vulner-manager/models/modeldb.go @@ -1089,6 +1089,25 @@ type UpdatedAffectedBranch struct { UpdateTime string `orm:"size(32);column(updated_at);null"` } +type CollectCallback struct { + Id int64 `orm:"pk;auto;column(id)"` + Branch string `orm:"size(256);column(branch)"` + Status string `orm:"size(256);column(status)"` + CollectDate string `orm:"size(256);column(collect_date)"` + CallbackId string `orm:"size(256);column(callback_id);unique"` + CreateTime time.Time `orm:"auto_now_add;type(datetime)"` + UpdateTime time.Time `orm:"auto_now;type(datetime)"` +} + +type CollectResult struct { + Id int64 `orm:"pk;auto;column(id)"` + Branch string `orm:"size(256);column(branch)"` + CollectDate string `orm:"size(256);column(collect_date);index"` + Result string `orm:"type(text);column(result)"` + CreateTime time.Time `orm:"auto_now_add;type(datetime)"` + UpdateTime time.Time `orm:"auto_now;type(datetime)"` +} + func CreateDb() bool { BConfig, err := config.NewConfig("ini", "conf/app.conf") if err != nil { @@ -1131,6 +1150,7 @@ func CreateDb() bool { new(IssueCommunityStatistics), new(CommunityYamlConfig), new(IssueDeleteRecord), new(AuthTokenInfo), new(OriginUpstreamPatch), new(OriginUpstreamPackageUrl), new(Reviewer), new(HotPatch), new(OriginUpstreamPatchFirstTime), new(UpdatedAffectedBranch), + new(CollectCallback), new(CollectResult), ) logs.Info("table create success!") errosyn := orm.RunSyncdb("default", false, true) -- Gitee From d97674a98b84809ce8be30621caa35e56c35bf6a Mon Sep 17 00:00:00 2001 From: yangwei999 <348134071@qq.com> Date: Fri, 24 May 2024 15:06:02 +0800 Subject: [PATCH 02/29] generate security belletin --- cve-vulner-manager/cve-ddd/app/coldpatch.go | 56 +++--- .../cve-ddd/app/coldpatch_bulletin.go | 161 ++++++++++++++++++ ...oncurrency.go => coldpatch_concurrency.go} | 0 .../cve-ddd/app/coldpatch_dto.go | 6 +- cve-vulner-manager/cve-ddd/app/hotpatch.go | 7 +- .../cve-ddd/controller/baseController.go | 34 ++++ cve-vulner-manager/cve-ddd/controller/cve.go | 85 +++++++++ .../cve-ddd/controller/cve_request.go | 10 ++ .../cve-ddd/domain/bulletins.go | 40 ++++- cve-vulner-manager/cve-ddd/domain/collect.go | 4 + .../cve-ddd/domain/{issue.go => cve.go} | 48 +++--- cve-vulner-manager/cve-ddd/domain/obs/obs.go | 2 + .../cve-ddd/domain/testresult/result.go | 11 ++ .../infrastructure/bulletinimpl/config.go | 10 ++ .../infrastructure/bulletinimpl/impl.go | 160 +++++++++++++---- .../infrastructure/bulletinimpl/xml.go | 4 +- .../cve-ddd/infrastructure/majunimpl/impl.go | 50 +++--- .../cve-ddd/infrastructure/obsimpl/impl.go | 14 ++ .../infrastructure/repositoryimpl/impl.go | 5 +- .../infrastructure/testresultimpl/impl.go | 126 ++++++++++++++ cve-vulner-manager/main.go | 4 + .../routers/commentsRouter_controllers.go | 2 +- cve-vulner-manager/routers/router.go | 34 +++- 23 files changed, 748 insertions(+), 125 deletions(-) create mode 100644 cve-vulner-manager/cve-ddd/app/coldpatch_bulletin.go rename cve-vulner-manager/cve-ddd/app/{concurrency.go => coldpatch_concurrency.go} (100%) create mode 100644 cve-vulner-manager/cve-ddd/controller/baseController.go create mode 100644 cve-vulner-manager/cve-ddd/controller/cve.go create mode 100644 cve-vulner-manager/cve-ddd/controller/cve_request.go rename cve-vulner-manager/cve-ddd/domain/{issue.go => cve.go} (69%) create mode 100644 cve-vulner-manager/cve-ddd/domain/testresult/result.go create mode 100644 cve-vulner-manager/cve-ddd/infrastructure/testresultimpl/impl.go diff --git a/cve-vulner-manager/cve-ddd/app/coldpatch.go b/cve-vulner-manager/cve-ddd/app/coldpatch.go index 53bbbe3..b005ebf 100644 --- a/cve-vulner-manager/cve-ddd/app/coldpatch.go +++ b/cve-vulner-manager/cve-ddd/app/coldpatch.go @@ -22,6 +22,7 @@ import ( "cvevulner/cve-ddd/domain/majun" "cvevulner/cve-ddd/domain/obs" "cvevulner/cve-ddd/domain/repository" + "cvevulner/cve-ddd/domain/testresult" "cvevulner/cve-ddd/domain/updateinfo" ) @@ -30,10 +31,12 @@ const ( mergedState = "merged" ) -var releaseDate sync.Map +var ( + releaseDate sync.Map +) type ColdPatchService interface { - CollectCveData(CmdToCollectData) error + CollectCveData(CmdToCollectData) GenerateBulletins([]string, string) error } @@ -45,20 +48,21 @@ func NewColdPatchService( u updateinfo.UpdateInfo, o obs.OBS, m majun.Majun, + t testresult.Result, + l *logrus.Entry, ) *coldPatchService { initReleaseDate() - log := logrus.New().WithField("module", "new-security-bulletin") - return &coldPatchService{ obs: o, rpm: rpm, repo: repo, - majun: m, + maJun: m, bulletin: b, backend: backend, updateInfo: u, - log: log, + testResult: t, + log: l, giteeToken: beego.AppConfig.String("gitee::git_token"), } } @@ -67,23 +71,24 @@ type coldPatchService struct { obs obs.OBS rpm latestrpm.LatestRpm repo repository.CveRepository - majun majun.Majun - bulletin bulletin.Bulletin + maJun majun.Majun backend backend.Backend + bulletin bulletin.Bulletin + testResult testresult.Result updateInfo updateinfo.UpdateInfo - lock sync.Mutex - log *logrus.Entry + collectLock sync.Mutex + log *logrus.Entry giteeToken string } // CollectCveData 数据收集接口背景: // 1.由于数据收集任务十分耗时,只能采用异步回调的方式给调用方数据 -// 2.调用方只能按照分支分次调用,但对于收集数据逻辑来说,单个分支和全部分支的执行时间没有区别,为了提高效率,采用一次请求全量收集的方式 -// 3.调用方的请求不是串行的,可能在首次收集任务未执行完时,另外的请求就到来,因此将请求数据落库,收集完成之后统一进行处理 +// 2.调用方只能按照分支分次调用,但对于收集数据逻辑来说,单个分支仍需要遍历所有数据,为了提高效率,采用一次请求全量收集的方式 +// 3.调用方的请求不是串行的,可能在首次收集任务未执行完时,另外的请求就到来,因此将请求信息落库,收集完成之后统一进行处理 // 4.调用方通过CallbackId来关联分支,因此也需要写入数据库进行记录 -func (c *coldPatchService) CollectCveData(cmd CmdToCollectData) error { +func (c *coldPatchService) CollectCveData(cmd CmdToCollectData) { callback := domain.Callback{ Date: cmd.Date, Branch: cmd.Branch, @@ -97,9 +102,8 @@ func (c *coldPatchService) CollectCveData(cmd CmdToCollectData) error { } go func() { - // 防止全量收集逻辑被重复执行 - c.lock.Lock() - defer c.lock.Unlock() + c.collectLock.Lock() // 防止全量收集逻辑被重复执行 + defer c.collectLock.Unlock() defer func() { if r := recover(); r != nil { @@ -120,9 +124,6 @@ func (c *coldPatchService) CollectCveData(cmd CmdToCollectData) error { c.log.Errorf("handle all callback failed: %v", err) } }() - - select {} - return nil } func (c *coldPatchService) generateCollectResult(date string) error { @@ -136,7 +137,7 @@ func (c *coldPatchService) generateCollectResult(date string) error { if err != nil { c.log.Errorf("generate excel data failed: %v", err) } else { - if err = c.obs.Upload(c.generateFilePath(), excelData); err != nil { + if err = c.obs.Upload(c.generateCollectFilePath(), excelData); err != nil { c.log.Errorf("upload excel to obs failed: %v", err) } } @@ -193,7 +194,7 @@ func (c *coldPatchService) handleAllCollectData() error { } func (c *coldPatchService) collectAllData() (map[string]domain.CollectedDataSlice, error) { - handleBranch, err := c.majun.GetReleasedBranch() + handleBranch, err := c.maJun.GetReleasedBranch() if err != nil { return nil, fmt.Errorf("get release branch err: %w", err) } @@ -219,18 +220,7 @@ func (c *coldPatchService) collectAllData() (map[string]domain.CollectedDataSlic return filteredData.GroupByBranch(handleBranch), nil } -func (c *coldPatchService) GenerateBulletins(cveNum []string, date string) error { - handleBranch, err := c.majun.GetReleasedBranch() - if err != nil { - return fmt.Errorf("get release branch err: %w", err) - } - - domain.InitMaintainVersion(handleBranch) - - return nil -} - -func (c *coldPatchService) generateFilePath() string { +func (c *coldPatchService) generateCollectFilePath() string { dir := beego.AppConfig.String("obs::upload_updateinfo_dir") nowStr := time.Now().Format("2006-01-02-15-04-05") diff --git a/cve-vulner-manager/cve-ddd/app/coldpatch_bulletin.go b/cve-vulner-manager/cve-ddd/app/coldpatch_bulletin.go new file mode 100644 index 0000000..773822c --- /dev/null +++ b/cve-vulner-manager/cve-ddd/app/coldpatch_bulletin.go @@ -0,0 +1,161 @@ +package app + +import ( + "fmt" + "regexp" + "strconv" + "strings" + "time" + + "github.com/astaxie/beego" + + "cvevulner/cve-ddd/domain" + "cvevulner/cve-ddd/domain/repository" + "cvevulner/util" +) + +const ( + EOF = "\r\n" + + fileIndex = "index.txt" + fileUpdateFixed = "update_fixed.txt" +) + +var ( + regexpBulletin = regexp.MustCompile(`cvrf-openEuler-(\w+)-(\d{4})-(\d{4})\.xml`) +) + +func (c *coldPatchService) GenerateBulletins(cveNum []string, date string) error { + handleBranch, err := c.maJun.GetReleasedBranch() + if err != nil { + return fmt.Errorf("get release branch err: %w", err) + } + + domain.InitMaintainVersion(handleBranch) + + cves, err := c.repo.FindCves(repository.Option{CveNum: cveNum}) + if err != nil { + return fmt.Errorf("find cves failed: %w", err) + } + + if len(cves) == 0 { + return fmt.Errorf("no cves") + } + + if err = c.testResult.Init(handleBranch, date); err != nil { + return fmt.Errorf("init test result failed: %w", err) + } + + // 用成功转测的数据进行过滤,只发布转测成功的cve + testedCves := c.testResult.Filter(cves) + + indexContent, err := c.getIndexContent() + if err != nil { + return fmt.Errorf("get %s failed: %w", fileIndex, err) + } + + maxId, err := c.parseColdPatchMaxIDFromIndex(indexContent) + if err != nil { + return fmt.Errorf("parse max id failed: %w", err) + } + + uploadDir := c.generateUploadDir() + var updateFixedContent string + + bulletins := testedCves.GenerateBulletins() + for _, b := range bulletins { + maxId++ + + b.SetIdentificationOfColdPatch(maxId) + + b.ProductTree = c.testResult.GenerateProductTree(b.Component, b.AffectedVersion) + + xmlData, err1 := c.bulletin.GenerateColdPatch(&b) + if err1 != nil { + c.log.Errorf("generate cold patch %s failed: %v", b.Identification, err1) + continue + } + + path := uploadDir + b.CvrfFileName() + if err1 = c.obs.Upload(path, xmlData); err1 != nil { + c.log.Errorf("upload cold patch %s failed: %v", b.Identification, err1) + continue + } + + updateFixedContent += b.PathAppendToIndexFile() + EOF + } + + c.uploadIndexAndFixed(uploadDir, indexContent, updateFixedContent) + + return nil +} + +func (c *coldPatchService) uploadIndexAndFixed(uploadDir, indexContent, updateFixedContent string) { + indexContent = strings.TrimSpace(indexContent) + updateFixedContent = strings.TrimSpace(updateFixedContent) + newIndexContent := indexContent + EOF + updateFixedContent + + indexPath := uploadDir + fileIndex + updateFixedPath := uploadDir + fileUpdateFixed + + if err := c.obs.Upload(indexPath, []byte(newIndexContent)); err != nil { + c.log.Errorf("upload %s failed: %v", fileIndex, err) + } + + if err := c.obs.Upload(updateFixedPath, []byte(updateFixedContent)); err != nil { + c.log.Errorf("upload %s failed: %v", fileUpdateFixed, err) + } +} + +func (c *coldPatchService) generateUploadDir() string { + parentDir := beego.AppConfig.String("obs::upload_cvrf_dir") + + subDir := time.Now().Format("2006-01-02-15-04-05") + "-new/" + + return parentDir + subDir +} + +func (c *coldPatchService) getIndexContent() (string, error) { + cvrfdir := beego.AppConfig.String("obs::download_cvrf_dir") + content, err := c.obs.Download(cvrfdir + fileIndex) + + return string(content), err +} + +func (c *coldPatchService) parseColdPatchMaxIDFromIndex(content string) (int, error) { + split := strings.Split(content, EOF) + for i := len(split) - 1; i >= 0; i-- { + v := split[i] + if v == "" { + continue + } + + ret := regexpBulletin.FindStringSubmatch(v) + if len(ret) != 4 { + continue + } + + if ret[1] != domain.BulletinTypeSA { + continue + } + + year, err := strconv.Atoi(ret[2]) + if err != nil { + return 0, err + } + + num, err := strconv.Atoi(ret[3]) + if err != nil { + return 0, err + } + + currentYear := util.Year() + if year == currentYear { + return num, nil + } + + return 1000, nil + } + + return 0, fmt.Errorf("not match in %s", fileIndex) +} diff --git a/cve-vulner-manager/cve-ddd/app/concurrency.go b/cve-vulner-manager/cve-ddd/app/coldpatch_concurrency.go similarity index 100% rename from cve-vulner-manager/cve-ddd/app/concurrency.go rename to cve-vulner-manager/cve-ddd/app/coldpatch_concurrency.go diff --git a/cve-vulner-manager/cve-ddd/app/coldpatch_dto.go b/cve-vulner-manager/cve-ddd/app/coldpatch_dto.go index d490c93..78c0818 100644 --- a/cve-vulner-manager/cve-ddd/app/coldpatch_dto.go +++ b/cve-vulner-manager/cve-ddd/app/coldpatch_dto.go @@ -1,7 +1,7 @@ package app type CmdToCollectData struct { - Branch string - Date string - CallbackId string + Branch string `json:"branch" valid:"Required"` + Date string `json:"date" valid:"Required"` + CallbackId string `json:"callback_id" valid:"Required"` } diff --git a/cve-vulner-manager/cve-ddd/app/hotpatch.go b/cve-vulner-manager/cve-ddd/app/hotpatch.go index 7c25b2a..49680dc 100644 --- a/cve-vulner-manager/cve-ddd/app/hotpatch.go +++ b/cve-vulner-manager/cve-ddd/app/hotpatch.go @@ -39,7 +39,7 @@ func NewHotPatchService( bulletin: b, obs: o, updateInfo: u, - majun: m, + maJun: m, } } @@ -48,11 +48,11 @@ type hotPatchService struct { bulletin bulletin.Bulletin obs obs.OBS updateInfo updateinfo.UpdateInfo - majun majun.Majun + maJun majun.Majun } func (h *hotPatchService) GenerateBulletins(cmds []CmdToGenerateBulletins) error { - handleBranch, err := h.majun.GetReleasedBranch() + handleBranch, err := h.maJun.GetReleasedBranch() if err != nil { return fmt.Errorf("get release branch err: %w", err) } @@ -88,6 +88,7 @@ func (h *hotPatchService) GenerateBulletins(cmds []CmdToGenerateBulletins) error for k := range cves { cves[k].HotIssueNum = cmd.HotIssueNum cves[k].AffectedVersion = []string{cmd.Branch} + cves[k].Component = cmd.Component } bulletins := cves.GenerateBulletins() diff --git a/cve-vulner-manager/cve-ddd/controller/baseController.go b/cve-vulner-manager/cve-ddd/controller/baseController.go new file mode 100644 index 0000000..7c00aff --- /dev/null +++ b/cve-vulner-manager/cve-ddd/controller/baseController.go @@ -0,0 +1,34 @@ +package controller + +import "github.com/astaxie/beego" + +type BaseController struct { + beego.Controller +} + +type response struct { + Code int `json:"code"` + Message string `json:"message"` + Data interface{} `json:"data"` +} + +func (c BaseController) success(data interface{}) { + r := response{ + Code: 200, + Message: "success", + Data: data, + } + + c.Data["json"] = r + c.ServeJSON() +} + +func (c BaseController) fail(msg string) { + r := response{ + Code: -1, + Message: msg, + } + + c.Data["json"] = r + c.ServeJSON() +} \ No newline at end of file diff --git a/cve-vulner-manager/cve-ddd/controller/cve.go b/cve-vulner-manager/cve-ddd/controller/cve.go new file mode 100644 index 0000000..35a6df4 --- /dev/null +++ b/cve-vulner-manager/cve-ddd/controller/cve.go @@ -0,0 +1,85 @@ +package controller + +import ( + "encoding/json" + "sync/atomic" + + "github.com/astaxie/beego/validation" + "github.com/sirupsen/logrus" + + "cvevulner/cve-ddd/app" +) + +const allowConcurrency = 1 + +var concurrency atomic.Int32 + +func NewCveController(s app.ColdPatchService, l *logrus.Entry) *CveController { + return &CveController{ + Service: s, + Log: l, + } +} + +type CveController struct { + BaseController + + Log *logrus.Entry + Service app.ColdPatchService +} + +func (c *CveController) CollectCveData() { + var request CollectRequest + if err := json.Unmarshal(c.Ctx.Input.RequestBody, &request); err != nil { + c.fail(err.Error()) + + return + } + + valid := validation.Validation{} + b, err := valid.Valid(&request) + if err != nil || !b { + c.fail("param error") + + return + } + + c.Service.CollectCveData(request) + + c.success(nil) +} + +func (c *CveController) Generate() { + concurrency.Add(1) + defer concurrency.Add(-1) + + // 公告接口不允许并发访问 + if concurrency.Load() > allowConcurrency { + c.fail("job is running") + + return + } + + var request GenerateRequest + if err := json.Unmarshal(c.Ctx.Input.RequestBody, &request); err != nil { + c.fail(err.Error()) + + return + } + + valid := validation.Validation{} + b, err := valid.Valid(&request) + if err != nil || !b { + c.fail("param error") + + return + } + + err = c.Service.GenerateBulletins(request.CveNum, request.Date) + if err != nil { + c.Log.Errorf("generate bulletins failed: %v", err) + c.fail(err.Error()) + } else { + c.success(nil) + } +} diff --git a/cve-vulner-manager/cve-ddd/controller/cve_request.go b/cve-vulner-manager/cve-ddd/controller/cve_request.go new file mode 100644 index 0000000..1bf8247 --- /dev/null +++ b/cve-vulner-manager/cve-ddd/controller/cve_request.go @@ -0,0 +1,10 @@ +package controller + +import "cvevulner/cve-ddd/app" + +type CollectRequest = app.CmdToCollectData + +type GenerateRequest struct { + CveNum []string `json:"cve_num" valid:"Required"` + Date string `json:"date" valid:"Required"` +} diff --git a/cve-vulner-manager/cve-ddd/domain/bulletins.go b/cve-vulner-manager/cve-ddd/domain/bulletins.go index 3568946..cc89b2d 100644 --- a/cve-vulner-manager/cve-ddd/domain/bulletins.go +++ b/cve-vulner-manager/cve-ddd/domain/bulletins.go @@ -1,10 +1,48 @@ package domain +import ( + "fmt" + "strings" + + "cvevulner/util" +) + +const ( + BulletinTypeSA = "SA" + BulletinTypeBa = "BA" + BulletinTypeHotPatch = "HotPatchSA" +) + type SecurityBulletin struct { AffectedVersion []string Identification string Date string Component string - PatchUrl []string // use in hotpatch + PatchUrl []string // use in hotpatch + ProductTree ProductTree // use in coldpatch Cves Cves } + +type ProductTree = map[string][]Product + +type Product struct { + ID string + CPE string + FullName string +} + +func (s *SecurityBulletin) SetIdentificationOfColdPatch(id int) { + s.Identification = fmt.Sprintf("openEuler-SA-%d-%d", util.Year(), id) +} + +func (s *SecurityBulletin) CvrfFileName() string { + return fmt.Sprintf("cvrf-%s.xml", s.Identification) +} + +func (s *SecurityBulletin) PathAppendToIndexFile() string { + return fmt.Sprintf("%d/%s", util.Year(), s.CvrfFileName()) +} + +func (s *SecurityBulletin) IsColdPatch() bool { + return !strings.Contains(s.Identification, BulletinTypeHotPatch) +} diff --git a/cve-vulner-manager/cve-ddd/domain/collect.go b/cve-vulner-manager/cve-ddd/domain/collect.go index a61f9cc..f30b347 100644 --- a/cve-vulner-manager/cve-ddd/domain/collect.go +++ b/cve-vulner-manager/cve-ddd/domain/collect.go @@ -44,6 +44,10 @@ func (s CollectedDataSlice) GroupByBranch(branches []string) map[string]Collecte } } + if len(t) == 0 { + continue + } + m[branch] = t } diff --git a/cve-vulner-manager/cve-ddd/domain/issue.go b/cve-vulner-manager/cve-ddd/domain/cve.go similarity index 69% rename from cve-vulner-manager/cve-ddd/domain/issue.go rename to cve-vulner-manager/cve-ddd/domain/cve.go index 24af5fd..5a5c922 100644 --- a/cve-vulner-manager/cve-ddd/domain/issue.go +++ b/cve-vulner-manager/cve-ddd/domain/cve.go @@ -1,6 +1,8 @@ package domain import ( + "k8s.io/apimachinery/pkg/util/sets" + "cvevulner/util" ) @@ -45,9 +47,17 @@ func (d Cve) isAffectVersion(version string) bool { return false } -func (ds Cves) GroupByVersion() map[string]CvesByVersion { +// FilterAffectVersion 只处理需要发布公告的版本分支 +func (cs Cves) FilterAffectVersion() { + for k, v := range cs { + affectVersionSet := sets.New(v.AffectedVersion...) + cs[k].AffectedVersion = maintainVersion.Intersection(affectVersionSet).UnsortedList() + } +} + +func (cs Cves) GroupByVersion() map[string]CvesByVersion { group := make(map[string]CvesByVersion) - for _, cve := range ds { + for _, cve := range cs { group[cve.AffectedVersion[0]] = append(group[cve.AffectedVersion[0]], cve) } @@ -55,9 +65,9 @@ func (ds Cves) GroupByVersion() map[string]CvesByVersion { } // GroupByComponent group cves by component -func (ds Cves) groupByComponent() map[string]CvesByComponent { +func (cs Cves) groupByComponent() map[string]CvesByComponent { group := make(map[string]CvesByComponent) - for _, d := range ds { + for _, d := range cs { group[d.Component] = append(group[d.Component], d) } @@ -67,10 +77,10 @@ func (ds Cves) groupByComponent() map[string]CvesByComponent { // GenerateBulletins CvesByComponent is a component-differentiated set of cves, // Bulletins are consolidated into one when all issues of a component affect all versions currently maintained, // otherwise they are split into multiple bulletins by version -func (ds Cves) GenerateBulletins() []SecurityBulletin { +func (cs Cves) GenerateBulletins() []SecurityBulletin { var securityBulletins []SecurityBulletin - for _, dsc := range ds.groupByComponent() { + for _, dsc := range cs.groupByComponent() { if dsc.isCombined() { securityBulletins = append(securityBulletins, dsc.combinedBulletin()) } else { @@ -83,8 +93,8 @@ func (ds Cves) GenerateBulletins() []SecurityBulletin { // IsCombined determine whether multiple cves under the same component // need to be combined into a single bulletin -func (dsc CvesByComponent) isCombined() bool { - for _, d := range dsc { +func (cbc CvesByComponent) isCombined() bool { + for _, d := range cbc { if len(d.AffectedVersion) != len(maintainVersion) { return false } @@ -100,29 +110,29 @@ func (dsc CvesByComponent) isCombined() bool { } // CombinedBulletin put all cves in one bulletin -func (dsc CvesByComponent) combinedBulletin() SecurityBulletin { +func (cbc CvesByComponent) combinedBulletin() SecurityBulletin { return SecurityBulletin{ - AffectedVersion: dsc[0].AffectedVersion, + AffectedVersion: cbc[0].AffectedVersion, Date: util.Date(), - Component: dsc[0].Component, - Cves: Cves(dsc), + Component: cbc[0].Component, + Cves: Cves(cbc), } } // SeparatedBulletins split into multiple bulletins by version -func (dsc CvesByComponent) separatedBulletins() []SecurityBulletin { +func (cbc CvesByComponent) separatedBulletins() []SecurityBulletin { var sbs []SecurityBulletin - for version, ds := range dsc.separateByVersion() { + for version, ds := range cbc.separateByVersion() { sbs = append(sbs, ds.bulletinByVersion(version)) } return sbs } -func (dsc CvesByComponent) separateByVersion() map[string]CvesByVersion { +func (cbc CvesByComponent) separateByVersion() map[string]CvesByVersion { classifyByVersion := make(map[string]CvesByVersion) for version := range maintainVersion { - for _, d := range dsc { + for _, d := range cbc { if d.isAffectVersion(version) { classifyByVersion[version] = append(classifyByVersion[version], d) } @@ -132,11 +142,11 @@ func (dsc CvesByComponent) separateByVersion() map[string]CvesByVersion { return classifyByVersion } -func (dsv CvesByVersion) bulletinByVersion(version string) SecurityBulletin { +func (cbv CvesByVersion) bulletinByVersion(version string) SecurityBulletin { return SecurityBulletin{ AffectedVersion: []string{version}, Date: util.Date(), - Component: dsv[0].Component, - Cves: Cves(dsv), + Component: cbv[0].Component, + Cves: Cves(cbv), } } diff --git a/cve-vulner-manager/cve-ddd/domain/obs/obs.go b/cve-vulner-manager/cve-ddd/domain/obs/obs.go index 7c9f8d3..e3c6c96 100644 --- a/cve-vulner-manager/cve-ddd/domain/obs/obs.go +++ b/cve-vulner-manager/cve-ddd/domain/obs/obs.go @@ -4,5 +4,7 @@ type OBS interface { UploadToDynamicDir(fileName string, data []byte) error DownloadFromDynamicDir(fileName string) ([]byte, error) UploadUpdateInfo(fileName string, data []byte) error + Upload(path string, data []byte) error + Download(path string) ([]byte, error) } diff --git a/cve-vulner-manager/cve-ddd/domain/testresult/result.go b/cve-vulner-manager/cve-ddd/domain/testresult/result.go new file mode 100644 index 0000000..251c8d9 --- /dev/null +++ b/cve-vulner-manager/cve-ddd/domain/testresult/result.go @@ -0,0 +1,11 @@ +package testresult + +import ( + "cvevulner/cve-ddd/domain" +) + +type Result interface { + Init([]string, string) error + Filter(domain.Cves) domain.Cves + GenerateProductTree(string, []string) domain.ProductTree +} diff --git a/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/config.go b/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/config.go index 55b68f2..a096288 100644 --- a/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/config.go +++ b/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/config.go @@ -1 +1,11 @@ package bulletinimpl + +type Config struct { + Xmlns string + XmlnsCvrf string + DocumentType string + ContactDetails string + IssuingAuthority string + SecurityCveUrlPrefix string + SecurityBulletinUrlPrefix string +} diff --git a/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/impl.go b/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/impl.go index 81008ea..a6ecab2 100644 --- a/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/impl.go +++ b/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/impl.go @@ -14,16 +14,16 @@ import ( ) const ( - aarch64 = "aarch64" - aarch64Suffix = ".aarch64." - noarch = "noarch" - noarchSuffix = ".noarch." - x8664 = "x86_64" - x8664suffix = ".x86_64." - src = "src" - srcSuffix = ".src." - productName = "Product Name" - packageArch = "Package Arch" + src = "src" + x8664 = "x86_64" + aarch64 = "aarch64" + noarch = "noarch" + + lang = "en" + openeuler = "openEuler" + + productName = "Product Name" + packageArch = "Package Arch" ) var archs = map[string]bool{ @@ -34,22 +34,53 @@ var archs = map[string]bool{ } func NewBulletinImpl() bulletinImpl { - return bulletinImpl{} + cfg := Config{ + Xmlns: "http://www.icasi.org/CVRF/schema/cvrf/1.1", + XmlnsCvrf: "http://www.icasi.org/CVRF/schema/cvrf/1.1", + DocumentType: "Security Advisory", + ContactDetails: "openeuler-release@openeuler.org", + IssuingAuthority: "openEuler release SIG", + SecurityCveUrlPrefix: "https://www.openeuler.org/en/security/cve/detail/?", + SecurityBulletinUrlPrefix: "https://www.openeuler.org/zh/security/security-bulletins/detail/?id=", + } + + return bulletinImpl{ + cfg: cfg, + } } type bulletinImpl struct { + cfg Config } func (impl bulletinImpl) GenerateColdPatch(sb *domain.SecurityBulletin) ([]byte, error) { - return nil, nil + data := Cvrf{ + Xmlns: impl.cfg.Xmlns, + XmlnsCvrf: impl.cfg.XmlnsCvrf, + DocumentTitle: impl.documentTitle(sb), + DocumentType: impl.cfg.DocumentType, + DocumentPublisher: impl.documentPublisher(), + DocumentTracking: impl.documentTracking(sb), + DocumentNotes: impl.documentNotes(sb), + DocumentReferences: impl.documentReferences(sb), + ProductTree: impl.ProductTree(sb), + Vulnerability: impl.vulnerability(sb), + } + + bData, err := xml.MarshalIndent(data, "", "\t") + if err != nil { + return nil, err + } + + return append([]byte(xml.Header), bData...), nil } func (impl bulletinImpl) GenerateHotPatch(sb *domain.SecurityBulletin) ([]byte, error) { data := Cvrf{ - Xmlns: "http://www.icasi.org/CVRF/schema/cvrf/1.1", - XmlnsCvrf: "http://www.icasi.org/CVRF/schema/cvrf/1.1", + Xmlns: impl.cfg.Xmlns, + XmlnsCvrf: impl.cfg.XmlnsCvrf, DocumentTitle: impl.documentTitle(sb), - DocumentType: "Security Advisory", + DocumentType: impl.cfg.DocumentType, DocumentPublisher: impl.documentPublisher(), DocumentTracking: impl.documentTracking(sb), DocumentNotes: impl.documentNotes(sb), @@ -74,7 +105,7 @@ func (impl bulletinImpl) documentTitle(sb *domain.SecurityBulletin) DocumentTitl title := fmt.Sprintf("An update for %s is now available for %s", sb.Component, impl.joinVersion(sb)) return DocumentTitle{ - XmlLang: "en", + XmlLang: lang, DocumentTitle: title, } } @@ -82,12 +113,19 @@ func (impl bulletinImpl) documentTitle(sb *domain.SecurityBulletin) DocumentTitl func (impl bulletinImpl) documentPublisher() DocumentPublisher { return DocumentPublisher{ Type: "Vendor", - ContactDetails: "openeuler-security@openeuler.org", - IssuingAuthority: "openEuler security committee", + ContactDetails: impl.cfg.ContactDetails, + IssuingAuthority: impl.cfg.IssuingAuthority, } } func (impl bulletinImpl) documentTracking(sb *domain.SecurityBulletin) DocumentTracking { + var engine string + if sb.IsColdPatch() { + engine = "openEuler SA Tool V1.0" + } else { + engine = "openEuler HotPatchSA Tool V1.0" + } + return DocumentTracking{ Identification: Identification{ Id: sb.Identification, @@ -104,7 +142,7 @@ func (impl bulletinImpl) documentTracking(sb *domain.SecurityBulletin) DocumentT InitialReleaseDate: sb.Date, CurrentReleaseDate: sb.Date, Generator: Generator{ - Engine: "openEuler HotPatchSA Tool V1.0", + Engine: engine, Date: sb.Date, }, } @@ -151,42 +189,42 @@ func (impl bulletinImpl) documentNotes(sb *domain.SecurityBulletin) DocumentNote Title: "Synopsis", Type: "General", Ordinal: "1", - XmlLang: "en", + XmlLang: lang, Note: fmt.Sprintf("%s security update", sb.Component), }, { Title: "Summary", Type: "General", Ordinal: "2", - XmlLang: "en", + XmlLang: lang, Note: fmt.Sprintf("An update for %s is now available for %s", sb.Component, impl.joinVersion(sb)), }, { Title: "Description", Type: "General", Ordinal: "3", - XmlLang: "en", + XmlLang: lang, Note: strings.Trim(description, "\r\n\r\n"), }, { Title: "Topic", Type: "General", Ordinal: "4", - XmlLang: "en", + XmlLang: lang, Note: topic, }, { Title: "Severity", Type: "General", Ordinal: "5", - XmlLang: "en", + XmlLang: lang, Note: dp.SequenceSeverityLevel[highestLevelIndex], }, { Title: "Affected Component", Type: "General", Ordinal: "6", - XmlLang: "en", + XmlLang: lang, Note: sb.Component, }, }, @@ -196,13 +234,13 @@ func (impl bulletinImpl) documentNotes(sb *domain.SecurityBulletin) DocumentNote func (impl bulletinImpl) documentReferences(sb *domain.SecurityBulletin) DocumentReferences { selfUrl := []CveUrl{ { - Url: "https://www.openeuler.org/en/security/safety-bulletin/detail.html?id=" + sb.Identification, + Url: impl.cfg.SecurityBulletinUrlPrefix + sb.Identification, }, } var cveUrl, other []CveUrl for _, cve := range sb.Cves { - url := "https://www.openeuler.org/en/security/cve/detail.html?id=" + cve.CveNum + url := impl.cfg.SecurityCveUrlPrefix + fmt.Sprintf("cveId=%s&packageName=%s", cve.CveNum, sb.Component) cveUrl = append(cveUrl, CveUrl{Url: url}) otherUrl := "https://nvd.nist.gov/vuln/detail/" + cve.CveNum @@ -227,14 +265,64 @@ func (impl bulletinImpl) documentReferences(sb *domain.SecurityBulletin) Documen } } -func (impl bulletinImpl) HotPatchTree(sb *domain.SecurityBulletin) HotPatchTree { +func (impl bulletinImpl) ProductTree(sb *domain.SecurityBulletin) *ProductTree { + getCpe := func(v string) string { + t := strings.Split(v, "-") + return fmt.Sprintf("cpe:/a:%v:%v:%v", t[0], t[0], strings.Join(t[1:], "-")) + } + + var productOfVersion []FullProductName + for _, v := range sb.AffectedVersion { + productOfVersion = append(productOfVersion, FullProductName{ + ProductId: v, + Cpe: getCpe(v), + FullProductName: v, + }) + } + + branchOfVersion := OpenEulerBranch{ + Type: productName, + Name: openeuler, + FullProductName: productOfVersion, + } + + branches := []OpenEulerBranch{ + branchOfVersion, + } + + for arch, products := range sb.ProductTree { + var productOfArch []FullProductName + for _, p := range products { + productOfArch = append(productOfArch, FullProductName{ + ProductId: p.ID, + Cpe: getCpe(p.CPE), + FullProductName: p.FullName, + }) + } + + branch := OpenEulerBranch{ + Type: packageArch, + Name: arch, + FullProductName: productOfArch, + } + + branches = append(branches, branch) + } + + return &ProductTree{ + Xmlns: impl.cfg.Xmlns, + OpenEulerBranch: branches, + } +} + +func (impl bulletinImpl) HotPatchTree(sb *domain.SecurityBulletin) *HotPatchTree { affectBranchListx := strings.Split(sb.AffectedVersion[0], "-") cpe := fmt.Sprintf("cpe:/a:%s:%s:%s", affectBranchListx[0], affectBranchListx[0], strings.Join(affectBranchListx[1:], "-")) branch := []OpenEulerBranch{{ - Type: "Product Name", - Name: "openEuler", + Type: productName, + Name: openeuler, FullProductName: []FullProductName{ { ProductId: sb.AffectedVersion[0], @@ -262,13 +350,13 @@ func (impl bulletinImpl) HotPatchTree(sb *domain.SecurityBulletin) HotPatchTree } if _, ok := archs[arch]; !ok { - logs.Error("arch %s is unlegal", arch) + logs.Error("arch %s is invalid", arch) continue } b := OpenEulerBranch{ - Type: "Package Arch", + Type: packageArch, Name: arch, FullProductName: []FullProductName{ { @@ -282,7 +370,7 @@ func (impl bulletinImpl) HotPatchTree(sb *domain.SecurityBulletin) HotPatchTree branch = append(branch, b) } - return HotPatchTree{ + return &HotPatchTree{ Xmlns: "http://www.icasi.org/CVRF/schema/prod/1.1", Branch: branch, } @@ -294,13 +382,13 @@ func (impl bulletinImpl) vulnerability(sb *domain.SecurityBulletin) []Vulnerabil for k, cve := range sb.Cves { vul := Vulnerability{ Ordinal: strconv.Itoa(k + 1), - Xmlns: "http://www.icasi.org/CVRF/schema/vuln/1.1", + Xmlns: impl.cfg.Xmlns, CveNotes: CveNotes{ CveNote: CveNote{ Title: "Vulnerability Description", Type: "General", Ordinal: "1", - XmlLang: "en", + XmlLang: lang, Note: taskhandler.XmlSpecCharHand(cve.CveBrief), }, }, @@ -330,7 +418,7 @@ func (impl bulletinImpl) vulnerability(sb *domain.SecurityBulletin) []Vulnerabil Type: "Vendor Fix", Description: fmt.Sprintf("%s security update", sb.Component), Date: sb.Date, - Url: "https://www.openeuler.org/en/security/safety-bulletin/detail.html?id=" + sb.Identification, + Url: impl.cfg.SecurityBulletinUrlPrefix + sb.Identification, }, }, } diff --git a/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/xml.go b/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/xml.go index f5f35fe..be20510 100644 --- a/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/xml.go +++ b/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/xml.go @@ -12,8 +12,8 @@ type Cvrf struct { DocumentTracking DocumentTracking `xml:"DocumentTracking,omitempty"` DocumentNotes DocumentNotes `xml:"DocumentNotes,omitempty"` DocumentReferences DocumentReferences `xml:"DocumentReferences,omitempty"` - ProductTree ProductTree `xml:"ProductTree,omitempty"` - HotPatchTree HotPatchTree `xml:"HotPatchTree,omitempty"` + ProductTree *ProductTree `xml:"ProductTree,omitempty"` + HotPatchTree *HotPatchTree `xml:"HotPatchTree,omitempty"` Vulnerability []Vulnerability `xml:"Vulnerability,omitempty"` } diff --git a/cve-vulner-manager/cve-ddd/infrastructure/majunimpl/impl.go b/cve-vulner-manager/cve-ddd/infrastructure/majunimpl/impl.go index 9347cc3..f852f58 100644 --- a/cve-vulner-manager/cve-ddd/infrastructure/majunimpl/impl.go +++ b/cve-vulner-manager/cve-ddd/infrastructure/majunimpl/impl.go @@ -49,31 +49,31 @@ type releaseResponse struct { } func (impl *majunImpl) GetReleasedBranch() ([]string, error) { - req, err := impl.generateRequest(urlReleaseVersion, nil) - if err != nil { - return nil, err - } - - var v releaseResponse - _, err = impl.client.ForwardTo(req, &v) - if err != nil { - return nil, err - } - - if v.Code != http.StatusOK { - return nil, errors.New(v.Message) - } - - return v.Result, nil - - //return []string{ - // "openEuler-20.03-LTS-SP1", - // "openEuler-20.03-LTS-SP4", - // "openEuler-22.03-LTS", - // "openEuler-22.03-LTS-SP1", - // "openEuler-22.03-LTS-SP2", - // "openEuler-22.03-LTS-SP3", - //}, nil + //req, err := impl.generateRequest(urlReleaseVersion, nil) + //if err != nil { + // return nil, err + //} + // + //var v releaseResponse + //_, err = impl.client.ForwardTo(req, &v) + //if err != nil { + // return nil, err + //} + // + //if v.Code != http.StatusOK { + // return nil, errors.New(v.Message) + //} + // + //return v.Result, nil + + return []string{ + "openEuler-20.03-LTS-SP1", + "openEuler-20.03-LTS-SP4", + "openEuler-22.03-LTS", + "openEuler-22.03-LTS-SP1", + "openEuler-22.03-LTS-SP2", + "openEuler-22.03-LTS-SP3", + }, nil } type callbackBody struct { diff --git a/cve-vulner-manager/cve-ddd/infrastructure/obsimpl/impl.go b/cve-vulner-manager/cve-ddd/infrastructure/obsimpl/impl.go index 1580e10..856306d 100644 --- a/cve-vulner-manager/cve-ddd/infrastructure/obsimpl/impl.go +++ b/cve-vulner-manager/cve-ddd/infrastructure/obsimpl/impl.go @@ -3,6 +3,7 @@ package obsimpl import ( "bytes" "fmt" + "io" "io/ioutil" "strings" "time" @@ -106,3 +107,16 @@ func (impl obsImpl) Upload(path string, data []byte) error { return err } + +func (impl obsImpl) Download(path string) ([]byte, error) { + input := &obs.GetObjectInput{} + input.Bucket = impl.cfg.Bucket + input.Key = path + output, err := impl.cli.GetObject(input) + if err != nil { + return nil, err + } + defer output.Body.Close() + + return io.ReadAll(output.Body) +} diff --git a/cve-vulner-manager/cve-ddd/infrastructure/repositoryimpl/impl.go b/cve-vulner-manager/cve-ddd/infrastructure/repositoryimpl/impl.go index 143e772..9859ef6 100644 --- a/cve-vulner-manager/cve-ddd/infrastructure/repositoryimpl/impl.go +++ b/cve-vulner-manager/cve-ddd/infrastructure/repositoryimpl/impl.go @@ -42,10 +42,13 @@ where a.cve_num in (%s) and a.organizate_id = 1 } for _, v := range data { + affectVersion := strings.Split(v.AffectProduct, "/") + cve := domain.Cve{ - Component: opt.Component, + Component: v.OwnedComponent, Description: v.Description, SeverityLevel: v.CveLevel, + AffectedVersion: affectVersion, AffectedProduct: v.AffectProduct, OpeneulerScore: v.OpeneulerScore, Theme: v.Theme, diff --git a/cve-vulner-manager/cve-ddd/infrastructure/testresultimpl/impl.go b/cve-vulner-manager/cve-ddd/infrastructure/testresultimpl/impl.go new file mode 100644 index 0000000..ae74645 --- /dev/null +++ b/cve-vulner-manager/cve-ddd/infrastructure/testresultimpl/impl.go @@ -0,0 +1,126 @@ +package testresultimpl + +import ( + "bytes" + "encoding/csv" + "fmt" + "io" + "net/http" + "strings" + + "github.com/opensourceways/server-common-lib/utils" + "github.com/sirupsen/logrus" + + "cvevulner/cve-ddd/domain" +) + +func NewTestResultImpl(log *logrus.Entry) *testResultImpl { + return &testResultImpl{ + log: log, + client: utils.NewHttpClient(3), + } +} + +type testResultImpl struct { + log *logrus.Entry + client utils.HttpClient + + // map[branch]map[component][]rpm + resultCache map[string]map[string][]string +} + +func (impl *testResultImpl) Init(handleBranch []string, date string) error { + impl.resultCache = make(map[string]map[string][]string) + + for _, b := range handleBranch { + url := fmt.Sprintf("http://121.36.84.172/repo.openeuler.org/%s/%s/xxx.csv", b, date) + + req, err := http.NewRequest(http.MethodGet, url, nil) + if err != nil { + return err + } + + content, _, err := impl.client.Download(req) + if err != nil { + impl.log.Errorf("download test result of %s failed: %v", b, err) + continue // 有的分支可能没有转测,请求肯定为404,只能直接跳过了 + } + + impl.resultCache[b] = impl.parseContent(content) + } + + return nil +} + +func (impl *testResultImpl) Filter(cves domain.Cves) domain.Cves { + var filtered domain.Cves + + for _, cve := range cves { + var filteredVersion []string + for _, av := range cve.AffectedVersion { + if _, ok := impl.resultCache[av][cve.Component]; ok { + filteredVersion = append(filteredVersion, av) // 在转测数据对应的分支能找到对应的包,该cve的该分支才能发布公告 + } + } + + if len(filteredVersion) == 0 { + continue // 过滤后的受影响分支为空,整个cve都不用发布公告了 + } + + cve.AffectedVersion = filteredVersion + filtered = append(filtered, cve) + } + + return filtered +} + +func (impl *testResultImpl) GenerateProductTree(component string, affectedVersion []string) domain.ProductTree { + var tree domain.ProductTree + + for _, version := range affectedVersion { + rpms := impl.resultCache[version][component] // 生成公告前已经过滤一次了,所以组件和影响分支必定存在 + + for _, rpm := range rpms { + // example of rpm: zbar-0.22-4.oe2203.src.rpm + t := strings.Split(rpm, ".") + arch := t[len(t)-2] + productId := strings.Join(t[:len(t)-3], ".") + + product := domain.Product{ + ID: productId, + CPE: version, + FullName: rpm, + } + + tree[arch] = append(tree[arch], product) + } + } + + return tree +} + +func (impl *testResultImpl) parseContent(content []byte) map[string][]string { + buff := bytes.NewBuffer(content) + r := csv.NewReader(buff) + + componentAndRpm := make(map[string][]string) + for { + line, err := r.Read() + if err == io.EOF { + break + } + + if err != nil { + continue + } + + splitRpm := strings.Fields(line[1]) + if len(splitRpm) == 0 { + continue + } + + componentAndRpm[line[0]] = splitRpm + } + + return componentAndRpm +} diff --git a/cve-vulner-manager/main.go b/cve-vulner-manager/main.go index 0410593..fae232b 100644 --- a/cve-vulner-manager/main.go +++ b/cve-vulner-manager/main.go @@ -8,6 +8,7 @@ import ( cve_timed_task "cvevulner/cve-timed-task" "cvevulner/models" _ "cvevulner/models" + "cvevulner/routers" _ "cvevulner/routers" "cvevulner/task" "cvevulner/taskhandler" @@ -55,5 +56,8 @@ func main() { beego.BConfig.WebConfig.DirectoryIndex = true beego.BConfig.WebConfig.StaticDir["/swagger"] = "swagger" } + + routers.InitRouter() + beego.Run() } diff --git a/cve-vulner-manager/routers/commentsRouter_controllers.go b/cve-vulner-manager/routers/commentsRouter_controllers.go index 39da061..b1b9d07 100644 --- a/cve-vulner-manager/routers/commentsRouter_controllers.go +++ b/cve-vulner-manager/routers/commentsRouter_controllers.go @@ -5,7 +5,7 @@ import ( "github.com/astaxie/beego/context/param" ) -func init() { +func initComment() { beego.GlobalControllerRouter["cvevulner/controllers:CveAllIssueController"] = append(beego.GlobalControllerRouter["cvevulner/controllers:CveAllIssueController"], beego.ControllerComments{ diff --git a/cve-vulner-manager/routers/router.go b/cve-vulner-manager/routers/router.go index 71e92d0..cd4cea1 100644 --- a/cve-vulner-manager/routers/router.go +++ b/cve-vulner-manager/routers/router.go @@ -9,11 +9,24 @@ package routers import ( "github.com/astaxie/beego" + "github.com/sirupsen/logrus" "cvevulner/controllers" + "cvevulner/cve-ddd/app" + "cvevulner/cve-ddd/controller" + "cvevulner/cve-ddd/infrastructure/backendimpl" + "cvevulner/cve-ddd/infrastructure/bulletinimpl" + "cvevulner/cve-ddd/infrastructure/latestrpmimpl" + "cvevulner/cve-ddd/infrastructure/majunimpl" + "cvevulner/cve-ddd/infrastructure/obsimpl" + "cvevulner/cve-ddd/infrastructure/repositoryimpl" + "cvevulner/cve-ddd/infrastructure/testresultimpl" + "cvevulner/cve-ddd/infrastructure/updateinfoimpl" ) -func init() { +func InitRouter() { + initComment() + ns := beego.NewNamespace("/v1", beego.NSNamespace("/object", beego.NSInclude( @@ -129,4 +142,23 @@ func init() { ), ) beego.AddNamespace(ns) + + log := logrus.New().WithField("module", "new-security-bulletin") + + coldPatchService := app.NewColdPatchService( + latestrpmimpl.NewLatestRpm(), + repositoryimpl.NewRepositoryImpl(), + bulletinimpl.NewBulletinImpl(), + backendimpl.NewBackendImpl(), + updateinfoimpl.NewUpdateInfoImpl(), + obsimpl.Instance(), + majunimpl.NewMajunImpl(), + testresultimpl.NewTestResultImpl(log), + log, + ) + + NewCveController := controller.NewCveController(coldPatchService, log) + + beego.Router("/security/bulletin/collect", NewCveController, "post:CollectCveData") + beego.Router("/security/bulletin/generate", NewCveController, "post:Generate") } -- Gitee From d8425bf6d329cb0be75e4ecb2f6e29f0bd64e540 Mon Sep 17 00:00:00 2001 From: yangwei999 <348134071@qq.com> Date: Sat, 25 May 2024 17:46:08 +0800 Subject: [PATCH 03/29] refactor router --- cve-vulner-manager/cve-ddd/app/coldpatch.go | 21 +++++----- cve-vulner-manager/main.go | 2 +- cve-vulner-manager/routers/new_router.go | 44 +++++++++++++++++++++ cve-vulner-manager/routers/router.go | 34 +--------------- 4 files changed, 56 insertions(+), 45 deletions(-) create mode 100644 cve-vulner-manager/routers/new_router.go diff --git a/cve-vulner-manager/cve-ddd/app/coldpatch.go b/cve-vulner-manager/cve-ddd/app/coldpatch.go index b005ebf..3cf7cd8 100644 --- a/cve-vulner-manager/cve-ddd/app/coldpatch.go +++ b/cve-vulner-manager/cve-ddd/app/coldpatch.go @@ -31,10 +31,6 @@ const ( mergedState = "merged" ) -var ( - releaseDate sync.Map -) - type ColdPatchService interface { CollectCveData(CmdToCollectData) GenerateBulletins([]string, string) error @@ -51,9 +47,7 @@ func NewColdPatchService( t testresult.Result, l *logrus.Entry, ) *coldPatchService { - initReleaseDate() - - return &coldPatchService{ + service := &coldPatchService{ obs: o, rpm: rpm, repo: repo, @@ -65,6 +59,10 @@ func NewColdPatchService( log: l, giteeToken: beego.AppConfig.String("gitee::git_token"), } + + service.initReleaseDate() + + return service } type coldPatchService struct { @@ -80,7 +78,8 @@ type coldPatchService struct { collectLock sync.Mutex log *logrus.Entry - giteeToken string + giteeToken string + releaseDate sync.Map } // CollectCveData 数据收集接口背景: @@ -297,7 +296,7 @@ func (c *coldPatchService) filterData( } // 5.在版本分支发布日期之前合入的pr不处理,因为已经随着新版本一起发布并修复了 - releaseTimeOfBranch, ok := releaseDate.Load(branch) + releaseTimeOfBranch, ok := c.releaseDate.Load(branch) if ok { releaseTime := releaseTimeOfBranch.(time.Time) if releaseTime.After(mergeAt) { @@ -348,12 +347,12 @@ func (c *coldPatchService) getRelatedPR(issue domain.Issue) (prs []sdk.PullReque return } -func initReleaseDate() { +func (c *coldPatchService) initReleaseDate() { releaseDateConfig := beego.AppConfig.DefaultString("excel::release_date_of_version", "") for _, v := range strings.Split(strings.Trim(releaseDateConfig, ";"), ";") { split := strings.Split(v, ":") key := split[0] value, _ := time.ParseInLocation("2006-01-02", split[1], time.Local) - releaseDate.Store(key, value.AddDate(0, 0, 1)) + c.releaseDate.Store(key, value.AddDate(0, 0, 1)) } } diff --git a/cve-vulner-manager/main.go b/cve-vulner-manager/main.go index fae232b..0c6a1b5 100644 --- a/cve-vulner-manager/main.go +++ b/cve-vulner-manager/main.go @@ -57,7 +57,7 @@ func main() { beego.BConfig.WebConfig.StaticDir["/swagger"] = "swagger" } - routers.InitRouter() + routers.Init() beego.Run() } diff --git a/cve-vulner-manager/routers/new_router.go b/cve-vulner-manager/routers/new_router.go new file mode 100644 index 0000000..fb9584e --- /dev/null +++ b/cve-vulner-manager/routers/new_router.go @@ -0,0 +1,44 @@ +package routers + +import ( + "github.com/astaxie/beego" + "github.com/sirupsen/logrus" + + "cvevulner/cve-ddd/app" + "cvevulner/cve-ddd/controller" + "cvevulner/cve-ddd/infrastructure/backendimpl" + "cvevulner/cve-ddd/infrastructure/bulletinimpl" + "cvevulner/cve-ddd/infrastructure/latestrpmimpl" + "cvevulner/cve-ddd/infrastructure/majunimpl" + "cvevulner/cve-ddd/infrastructure/obsimpl" + "cvevulner/cve-ddd/infrastructure/repositoryimpl" + "cvevulner/cve-ddd/infrastructure/testresultimpl" + "cvevulner/cve-ddd/infrastructure/updateinfoimpl" +) + +func Init() { + initComment() + initController() + InitNewRouter() +} + +func InitNewRouter() { + log := logrus.New().WithField("module", "new-security-bulletin") + + coldPatchService := app.NewColdPatchService( + latestrpmimpl.NewLatestRpm(), + repositoryimpl.NewRepositoryImpl(), + bulletinimpl.NewBulletinImpl(), + backendimpl.NewBackendImpl(), + updateinfoimpl.NewUpdateInfoImpl(), + obsimpl.Instance(), + majunimpl.NewMajunImpl(), + testresultimpl.NewTestResultImpl(log), + log, + ) + + NewCveController := controller.NewCveController(coldPatchService, log) + + beego.Router("/security/bulletin/collect", NewCveController, "post:CollectCveData") + beego.Router("/security/bulletin/generate", NewCveController, "post:Generate") +} diff --git a/cve-vulner-manager/routers/router.go b/cve-vulner-manager/routers/router.go index cd4cea1..ffc146d 100644 --- a/cve-vulner-manager/routers/router.go +++ b/cve-vulner-manager/routers/router.go @@ -9,24 +9,11 @@ package routers import ( "github.com/astaxie/beego" - "github.com/sirupsen/logrus" "cvevulner/controllers" - "cvevulner/cve-ddd/app" - "cvevulner/cve-ddd/controller" - "cvevulner/cve-ddd/infrastructure/backendimpl" - "cvevulner/cve-ddd/infrastructure/bulletinimpl" - "cvevulner/cve-ddd/infrastructure/latestrpmimpl" - "cvevulner/cve-ddd/infrastructure/majunimpl" - "cvevulner/cve-ddd/infrastructure/obsimpl" - "cvevulner/cve-ddd/infrastructure/repositoryimpl" - "cvevulner/cve-ddd/infrastructure/testresultimpl" - "cvevulner/cve-ddd/infrastructure/updateinfoimpl" ) -func InitRouter() { - initComment() - +func initController() { ns := beego.NewNamespace("/v1", beego.NSNamespace("/object", beego.NSInclude( @@ -142,23 +129,4 @@ func InitRouter() { ), ) beego.AddNamespace(ns) - - log := logrus.New().WithField("module", "new-security-bulletin") - - coldPatchService := app.NewColdPatchService( - latestrpmimpl.NewLatestRpm(), - repositoryimpl.NewRepositoryImpl(), - bulletinimpl.NewBulletinImpl(), - backendimpl.NewBackendImpl(), - updateinfoimpl.NewUpdateInfoImpl(), - obsimpl.Instance(), - majunimpl.NewMajunImpl(), - testresultimpl.NewTestResultImpl(log), - log, - ) - - NewCveController := controller.NewCveController(coldPatchService, log) - - beego.Router("/security/bulletin/collect", NewCveController, "post:CollectCveData") - beego.Router("/security/bulletin/generate", NewCveController, "post:Generate") } -- Gitee From a520da136b9d175765c32a8ace10acf87798a7ec Mon Sep 17 00:00:00 2001 From: yangwei999 <348134071@qq.com> Date: Mon, 27 May 2024 10:38:40 +0800 Subject: [PATCH 04/29] compatible with hotpatch adapter --- cve-vulner-manager/cve-ddd/app/coldpatch.go | 43 +++++++++++-------- .../cve-ddd/app/coldpatch_bulletin.go | 6 +++ cve-vulner-manager/routers/new_router.go | 2 + 3 files changed, 33 insertions(+), 18 deletions(-) diff --git a/cve-vulner-manager/cve-ddd/app/coldpatch.go b/cve-vulner-manager/cve-ddd/app/coldpatch.go index 3cf7cd8..591c5a8 100644 --- a/cve-vulner-manager/cve-ddd/app/coldpatch.go +++ b/cve-vulner-manager/cve-ddd/app/coldpatch.go @@ -36,6 +36,10 @@ type ColdPatchService interface { GenerateBulletins([]string, string) error } +type HotPatchAdapter interface { + Process() +} + func NewColdPatchService( rpm latestrpm.LatestRpm, repo repository.CveRepository, @@ -45,19 +49,21 @@ func NewColdPatchService( o obs.OBS, m majun.Majun, t testresult.Result, + h HotPatchAdapter, l *logrus.Entry, ) *coldPatchService { service := &coldPatchService{ - obs: o, - rpm: rpm, - repo: repo, - maJun: m, - bulletin: b, - backend: backend, - updateInfo: u, - testResult: t, - log: l, - giteeToken: beego.AppConfig.String("gitee::git_token"), + obs: o, + rpm: rpm, + repo: repo, + maJun: m, + bulletin: b, + backend: backend, + updateInfo: u, + testResult: t, + hotPatchAdapter: h, + log: l, + giteeToken: beego.AppConfig.String("gitee::git_token"), } service.initReleaseDate() @@ -66,14 +72,15 @@ func NewColdPatchService( } type coldPatchService struct { - obs obs.OBS - rpm latestrpm.LatestRpm - repo repository.CveRepository - maJun majun.Majun - backend backend.Backend - bulletin bulletin.Bulletin - testResult testresult.Result - updateInfo updateinfo.UpdateInfo + obs obs.OBS + rpm latestrpm.LatestRpm + repo repository.CveRepository + maJun majun.Majun + backend backend.Backend + bulletin bulletin.Bulletin + testResult testresult.Result + updateInfo updateinfo.UpdateInfo + hotPatchAdapter HotPatchAdapter collectLock sync.Mutex log *logrus.Entry diff --git a/cve-vulner-manager/cve-ddd/app/coldpatch_bulletin.go b/cve-vulner-manager/cve-ddd/app/coldpatch_bulletin.go index 773822c..dabcb69 100644 --- a/cve-vulner-manager/cve-ddd/app/coldpatch_bulletin.go +++ b/cve-vulner-manager/cve-ddd/app/coldpatch_bulletin.go @@ -11,6 +11,7 @@ import ( "cvevulner/cve-ddd/domain" "cvevulner/cve-ddd/domain/repository" + "cvevulner/cve-ddd/infrastructure/obsimpl" "cvevulner/util" ) @@ -87,6 +88,11 @@ func (c *coldPatchService) GenerateBulletins(cveNum []string, date string) error c.uploadIndexAndFixed(uploadDir, indexContent, updateFixedContent) + // set upload dirname of hotpatch + obsimpl.SetDynamicDir(uploadDir) + // process hot patch + c.hotPatchAdapter.Process() + return nil } diff --git a/cve-vulner-manager/routers/new_router.go b/cve-vulner-manager/routers/new_router.go index fb9584e..8e1e93b 100644 --- a/cve-vulner-manager/routers/new_router.go +++ b/cve-vulner-manager/routers/new_router.go @@ -4,6 +4,7 @@ import ( "github.com/astaxie/beego" "github.com/sirupsen/logrus" + "cvevulner/cve-ddd/adapter" "cvevulner/cve-ddd/app" "cvevulner/cve-ddd/controller" "cvevulner/cve-ddd/infrastructure/backendimpl" @@ -34,6 +35,7 @@ func InitNewRouter() { obsimpl.Instance(), majunimpl.NewMajunImpl(), testresultimpl.NewTestResultImpl(log), + adapter.NewHotPatchAdapter(), log, ) -- Gitee From 2cef9843e4c1c0c61751e3b48befd5a5ec4d0505 Mon Sep 17 00:00:00 2001 From: yangwei999 <348134071@qq.com> Date: Mon, 27 May 2024 20:24:54 +0800 Subject: [PATCH 05/29] optimize read index.txt --- cve-vulner-manager/cve-ddd/app/coldpatch_bulletin.go | 5 +---- .../cve-ddd/infrastructure/latestrpmimpl/impl.go | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/cve-vulner-manager/cve-ddd/app/coldpatch_bulletin.go b/cve-vulner-manager/cve-ddd/app/coldpatch_bulletin.go index dabcb69..9ebcb11 100644 --- a/cve-vulner-manager/cve-ddd/app/coldpatch_bulletin.go +++ b/cve-vulner-manager/cve-ddd/app/coldpatch_bulletin.go @@ -129,12 +129,9 @@ func (c *coldPatchService) getIndexContent() (string, error) { } func (c *coldPatchService) parseColdPatchMaxIDFromIndex(content string) (int, error) { - split := strings.Split(content, EOF) + split := strings.Fields(content) for i := len(split) - 1; i >= 0; i-- { v := split[i] - if v == "" { - continue - } ret := regexpBulletin.FindStringSubmatch(v) if len(ret) != 4 { diff --git a/cve-vulner-manager/cve-ddd/infrastructure/latestrpmimpl/impl.go b/cve-vulner-manager/cve-ddd/infrastructure/latestrpmimpl/impl.go index 708a995..17aee98 100644 --- a/cve-vulner-manager/cve-ddd/infrastructure/latestrpmimpl/impl.go +++ b/cve-vulner-manager/cve-ddd/infrastructure/latestrpmimpl/impl.go @@ -81,7 +81,7 @@ func (l *latestRpm) parseFile(content []byte) map[string]time.Time { continue } - split := strings.Split(line[2], "") + split := strings.Fields(line[2]) if len(split) == 0 { continue } -- Gitee From 902ec66445b4b964c9dc3a5bfd225883bad9f4e3 Mon Sep 17 00:00:00 2001 From: yangwei999 <348134071@qq.com> Date: Tue, 28 May 2024 14:57:51 +0800 Subject: [PATCH 06/29] change collect dir --- cve-vulner-manager/cve-ddd/app/coldpatch.go | 2 +- cve-vulner-manager/cve-ddd/infrastructure/majunimpl/impl.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cve-vulner-manager/cve-ddd/app/coldpatch.go b/cve-vulner-manager/cve-ddd/app/coldpatch.go index 591c5a8..7aadfe4 100644 --- a/cve-vulner-manager/cve-ddd/app/coldpatch.go +++ b/cve-vulner-manager/cve-ddd/app/coldpatch.go @@ -231,7 +231,7 @@ func (c *coldPatchService) generateCollectFilePath() string { nowStr := time.Now().Format("2006-01-02-15-04-05") - return fmt.Sprintf("%s%s/collect.xlsx", dir, nowStr) + return fmt.Sprintf("%s%s-new/collect.xlsx", dir, nowStr) } // 过滤issue的条件主要有6个,代码中注释已列出 diff --git a/cve-vulner-manager/cve-ddd/infrastructure/majunimpl/impl.go b/cve-vulner-manager/cve-ddd/infrastructure/majunimpl/impl.go index f852f58..9a9d1cc 100644 --- a/cve-vulner-manager/cve-ddd/infrastructure/majunimpl/impl.go +++ b/cve-vulner-manager/cve-ddd/infrastructure/majunimpl/impl.go @@ -18,8 +18,8 @@ import ( ) const ( - urlReleaseVersion = "http://xxxx/majun-platform-release/publish/externalinterface/queryReleaseVersion" - urlCollectCallback = "http://xxx.com/majun-platform-release/publish/review/getPublishFiles/openeuler" + urlReleaseVersion = "https://majun.osinfra.cn/majun-platform-release/publish/externalinterface/queryReleaseVersion" + urlCollectCallback = "https://majun.osinfra.cn/majun-platform-release/publish/externalinterface/saveCveCallbackResult" ) type config struct { -- Gitee From f9791847b8858731ff0590054d8446a77254ecee Mon Sep 17 00:00:00 2001 From: yangwei999 <348134071@qq.com> Date: Tue, 28 May 2024 17:26:45 +0800 Subject: [PATCH 07/29] update golang to 1.19.4 --- cve-vulner-manager/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cve-vulner-manager/Dockerfile b/cve-vulner-manager/Dockerfile index 10c671e..ba1d7bc 100644 --- a/cve-vulner-manager/Dockerfile +++ b/cve-vulner-manager/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.18.8 as BUILDER +FROM golang:1.19.4 as BUILDER LABEL maintainer="zhangjianjun" RUN go env -w GOPROXY=https://goproxy.cn,direct -- Gitee From c0df7f604a29b00225446b60e8471de140109439 Mon Sep 17 00:00:00 2001 From: yangwei999 <348134071@qq.com> Date: Tue, 28 May 2024 19:48:32 +0800 Subject: [PATCH 08/29] fix http.request bug --- .../cve-ddd/infrastructure/majunimpl/impl.go | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/cve-vulner-manager/cve-ddd/infrastructure/majunimpl/impl.go b/cve-vulner-manager/cve-ddd/infrastructure/majunimpl/impl.go index 9a9d1cc..da6bc80 100644 --- a/cve-vulner-manager/cve-ddd/infrastructure/majunimpl/impl.go +++ b/cve-vulner-manager/cve-ddd/infrastructure/majunimpl/impl.go @@ -120,25 +120,24 @@ func (impl *majunImpl) CollectCallback(id, data string) error { return nil } -func (impl *majunImpl) generateRequest(url string, body []byte) (*http.Request, error) { +func (impl *majunImpl) generateRequest(url string, body []byte) (req *http.Request, err error) { timestamp := strconv.FormatInt(time.Now().UnixMilli(), 10) sign := impl.sign(timestamp) - var payload *bytes.Buffer if len(body) != 0 { - payload = bytes.NewBuffer(body) + req, err = http.NewRequest(http.MethodPost, url, bytes.NewBuffer(body)) + } else { + req, err = http.NewRequest(http.MethodPost, url, nil) } - - req, err := http.NewRequest(http.MethodPost, url, payload) if err != nil { - return nil, err + return } req.Header.Set("timestamp", timestamp) req.Header.Set("appId", impl.cfg.AppId) req.Header.Set("sign", sign) - return req, nil + return } func (impl *majunImpl) sign(timestamp string) string { -- Gitee From 24fdd5369f8b9293792f204f9a52884eb6cf9cf8 Mon Sep 17 00:00:00 2001 From: yangwei999 <348134071@qq.com> Date: Tue, 28 May 2024 20:28:45 +0800 Subject: [PATCH 09/29] optimize code --- .../cve-ddd/app/coldpatch_bulletin.go | 37 ++++++++++++------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/cve-vulner-manager/cve-ddd/app/coldpatch_bulletin.go b/cve-vulner-manager/cve-ddd/app/coldpatch_bulletin.go index 9ebcb11..2e5e285 100644 --- a/cve-vulner-manager/cve-ddd/app/coldpatch_bulletin.go +++ b/cve-vulner-manager/cve-ddd/app/coldpatch_bulletin.go @@ -61,9 +61,26 @@ func (c *coldPatchService) GenerateBulletins(cveNum []string, date string) error } uploadDir := c.generateUploadDir() - var updateFixedContent string bulletins := testedCves.GenerateBulletins() + + updateFixedFiles := c.handleColdPatchBulletins(bulletins, uploadDir, maxId) + + c.uploadIndexAndFixed(uploadDir, indexContent, updateFixedFiles) + + // set upload dirname of hotpatch + obsimpl.SetDynamicDir(uploadDir) + // process hot patch + c.hotPatchAdapter.Process() + + return nil +} + +func (c *coldPatchService) handleColdPatchBulletins( + bulletins []domain.SecurityBulletin, uploadDir string, maxId int, +) []string { + var updateFixedFiles []string + for _, b := range bulletins { maxId++ @@ -83,23 +100,15 @@ func (c *coldPatchService) GenerateBulletins(cveNum []string, date string) error continue } - updateFixedContent += b.PathAppendToIndexFile() + EOF + updateFixedFiles = append(updateFixedFiles, b.PathAppendToIndexFile()) } - c.uploadIndexAndFixed(uploadDir, indexContent, updateFixedContent) - - // set upload dirname of hotpatch - obsimpl.SetDynamicDir(uploadDir) - // process hot patch - c.hotPatchAdapter.Process() - - return nil + return updateFixedFiles } -func (c *coldPatchService) uploadIndexAndFixed(uploadDir, indexContent, updateFixedContent string) { - indexContent = strings.TrimSpace(indexContent) - updateFixedContent = strings.TrimSpace(updateFixedContent) - newIndexContent := indexContent + EOF + updateFixedContent +func (c *coldPatchService) uploadIndexAndFixed(uploadDir, indexContent string, updateFixedFiles []string) { + updateFixedContent := strings.TrimSpace(strings.Join(updateFixedFiles, EOF)) + newIndexContent := strings.TrimSpace(indexContent) + EOF + updateFixedContent indexPath := uploadDir + fileIndex updateFixedPath := uploadDir + fileUpdateFixed -- Gitee From 1b06fe171da8aca665dd5b8d5f4061bdfce7f332 Mon Sep 17 00:00:00 2001 From: yangwei999 <348134071@qq.com> Date: Wed, 29 May 2024 14:31:13 +0800 Subject: [PATCH 10/29] fix url of majun --- cve-vulner-manager/cve-ddd/app/coldpatch.go | 10 ++-- .../cve-ddd/app/coldpatch_bulletin.go | 53 +++++++++++-------- .../cve-ddd/infrastructure/majunimpl/impl.go | 4 +- 3 files changed, 38 insertions(+), 29 deletions(-) diff --git a/cve-vulner-manager/cve-ddd/app/coldpatch.go b/cve-vulner-manager/cve-ddd/app/coldpatch.go index 7aadfe4..98f8ca3 100644 --- a/cve-vulner-manager/cve-ddd/app/coldpatch.go +++ b/cve-vulner-manager/cve-ddd/app/coldpatch.go @@ -179,16 +179,16 @@ func (c *coldPatchService) handleAllCollectData() error { } for _, callback := range callbacks { - _, err1 := c.repo.FindCollectResult(callback.Branch, callback.Date) + result, err1 := c.repo.FindCollectResult(callback.Branch, callback.Date) if err1 != nil { c.log.Errorf("find calback result failed: %v", err1) continue } - //if err1 = c.majun.CollectCallback(callback.CallbackId, result); err1 != nil { - // c.log.Errorf("collect callback failed: %v", err1) - // continue - //} + if err1 = c.maJun.CollectCallback(callback.CallbackId, result); err1 != nil { + c.log.Errorf("collect callback failed: %v", err1) + continue + } callback.SetStatusProcessed() if err1 = c.repo.UpdateCallback(callback); err1 != nil { diff --git a/cve-vulner-manager/cve-ddd/app/coldpatch_bulletin.go b/cve-vulner-manager/cve-ddd/app/coldpatch_bulletin.go index 2e5e285..9c79f7a 100644 --- a/cve-vulner-manager/cve-ddd/app/coldpatch_bulletin.go +++ b/cve-vulner-manager/cve-ddd/app/coldpatch_bulletin.go @@ -11,7 +11,6 @@ import ( "cvevulner/cve-ddd/domain" "cvevulner/cve-ddd/domain/repository" - "cvevulner/cve-ddd/infrastructure/obsimpl" "cvevulner/util" ) @@ -55,7 +54,7 @@ func (c *coldPatchService) GenerateBulletins(cveNum []string, date string) error return fmt.Errorf("get %s failed: %w", fileIndex, err) } - maxId, err := c.parseColdPatchMaxIDFromIndex(indexContent) + maxColdPatchId, _, err := c.parseColdPatchMaxIDFromIndex(indexContent) if err != nil { return fmt.Errorf("parse max id failed: %w", err) } @@ -64,15 +63,10 @@ func (c *coldPatchService) GenerateBulletins(cveNum []string, date string) error bulletins := testedCves.GenerateBulletins() - updateFixedFiles := c.handleColdPatchBulletins(bulletins, uploadDir, maxId) + updateFixedFiles := c.handleColdPatchBulletins(bulletins, uploadDir, maxColdPatchId) c.uploadIndexAndFixed(uploadDir, indexContent, updateFixedFiles) - // set upload dirname of hotpatch - obsimpl.SetDynamicDir(uploadDir) - // process hot patch - c.hotPatchAdapter.Process() - return nil } @@ -137,7 +131,8 @@ func (c *coldPatchService) getIndexContent() (string, error) { return string(content), err } -func (c *coldPatchService) parseColdPatchMaxIDFromIndex(content string) (int, error) { +func (c *coldPatchService) parseColdPatchMaxIDFromIndex(content string, +) (maxColdPatchId, maxHotPatchId int, err error) { split := strings.Fields(content) for i := len(split) - 1; i >= 0; i-- { v := split[i] @@ -147,27 +142,41 @@ func (c *coldPatchService) parseColdPatchMaxIDFromIndex(content string) (int, er continue } - if ret[1] != domain.BulletinTypeSA { - continue + year, err1 := strconv.Atoi(ret[2]) + if err1 != nil { + return 0, 0, err1 } - year, err := strconv.Atoi(ret[2]) - if err != nil { - return 0, err + num, err1 := strconv.Atoi(ret[3]) + if err1 != nil { + return 0, 0, err1 } - num, err := strconv.Atoi(ret[3]) - if err != nil { - return 0, err + currentYear := util.Year() + if year != currentYear { + num = 1000 } - currentYear := util.Year() - if year == currentYear { - return num, nil + if ret[1] == domain.BulletinTypeSA { + maxColdPatchId = num } - return 1000, nil + if ret[1] == domain.BulletinTypeHotPatch { + maxHotPatchId = num + } + + if maxHotPatchId != 0 && maxColdPatchId != 0 { + break + } + } + + if maxHotPatchId == 0 { + maxHotPatchId = 1000 + } + + if maxColdPatchId == 0 { + maxColdPatchId = 1000 } - return 0, fmt.Errorf("not match in %s", fileIndex) + return maxColdPatchId, maxHotPatchId, nil } diff --git a/cve-vulner-manager/cve-ddd/infrastructure/majunimpl/impl.go b/cve-vulner-manager/cve-ddd/infrastructure/majunimpl/impl.go index da6bc80..cc397db 100644 --- a/cve-vulner-manager/cve-ddd/infrastructure/majunimpl/impl.go +++ b/cve-vulner-manager/cve-ddd/infrastructure/majunimpl/impl.go @@ -18,8 +18,8 @@ import ( ) const ( - urlReleaseVersion = "https://majun.osinfra.cn/majun-platform-release/publish/externalinterface/queryReleaseVersion" - urlCollectCallback = "https://majun.osinfra.cn/majun-platform-release/publish/externalinterface/saveCveCallbackResult" + urlReleaseVersion = "https://majun.osinfra.cn/api/http/majun-platform-release/publish/externalInterface/queryReleaseVersion" + urlCollectCallback = "https://majun.osinfra.cn/api/http/majun-platform-release/publish/externalInterface/saveCveCallbackResult" ) type config struct { -- Gitee From 6463ff0d7f5806ec1fe3cb84721782932d3d8a1f Mon Sep 17 00:00:00 2001 From: yangwei999 <348134071@qq.com> Date: Wed, 29 May 2024 16:34:52 +0800 Subject: [PATCH 11/29] refactor hot patch --- .../{coldpatch_bulletin.go => bulletin.go} | 156 +++++++------ cve-vulner-manager/cve-ddd/app/coldpatch.go | 44 ++-- .../cve-ddd/app/refactor_hotpatch.go | 220 ++++++++++++++++++ cve-vulner-manager/cve-ddd/controller/cve.go | 42 +++- .../cve-ddd/domain/bulletins.go | 4 + cve-vulner-manager/cve-ddd/domain/callback.go | 2 + .../cve-ddd/domain/hot_patch_issue.go | 10 + .../cve-ddd/domain/hotpatch/hotpatch.go | 7 + .../infrastructure/hotpatchimpl/impl.go | 149 ++++++++++++ cve-vulner-manager/routers/new_router.go | 37 ++- 10 files changed, 554 insertions(+), 117 deletions(-) rename cve-vulner-manager/cve-ddd/app/{coldpatch_bulletin.go => bulletin.go} (34%) create mode 100644 cve-vulner-manager/cve-ddd/app/refactor_hotpatch.go create mode 100644 cve-vulner-manager/cve-ddd/domain/hot_patch_issue.go create mode 100644 cve-vulner-manager/cve-ddd/domain/hotpatch/hotpatch.go create mode 100644 cve-vulner-manager/cve-ddd/infrastructure/hotpatchimpl/impl.go diff --git a/cve-vulner-manager/cve-ddd/app/coldpatch_bulletin.go b/cve-vulner-manager/cve-ddd/app/bulletin.go similarity index 34% rename from cve-vulner-manager/cve-ddd/app/coldpatch_bulletin.go rename to cve-vulner-manager/cve-ddd/app/bulletin.go index 9c79f7a..16886ea 100644 --- a/cve-vulner-manager/cve-ddd/app/coldpatch_bulletin.go +++ b/cve-vulner-manager/cve-ddd/app/bulletin.go @@ -8,9 +8,14 @@ import ( "time" "github.com/astaxie/beego" + "github.com/sirupsen/logrus" "cvevulner/cve-ddd/domain" + "cvevulner/cve-ddd/domain/bulletin" + "cvevulner/cve-ddd/domain/majun" + "cvevulner/cve-ddd/domain/obs" "cvevulner/cve-ddd/domain/repository" + "cvevulner/cve-ddd/domain/testresult" "cvevulner/util" ) @@ -25,98 +30,122 @@ var ( regexpBulletin = regexp.MustCompile(`cvrf-openEuler-(\w+)-(\d{4})-(\d{4})\.xml`) ) -func (c *coldPatchService) GenerateBulletins(cveNum []string, date string) error { - handleBranch, err := c.maJun.GetReleasedBranch() +type BulletinService interface { + GenerateBulletins([]string, string) (string, error) +} + +func NewBulletinService( + o obs.OBS, + r repository.CveRepository, + m majun.Majun, + b bulletin.Bulletin, + t testresult.Result, + l *logrus.Entry, +) *bulletinService { + return &bulletinService{ + obs: o, + repo: r, + maJun: m, + bulletin: b, + testResult: t, + log: l, + } +} + +type bulletinService struct { + obs obs.OBS + repo repository.CveRepository + maJun majun.Majun + bulletin bulletin.Bulletin + testResult testresult.Result + + log *logrus.Entry +} + +func (b *bulletinService) GenerateBulletins(cveNum []string, date string) (string, error) { + handleBranch, err := b.maJun.GetReleasedBranch() if err != nil { - return fmt.Errorf("get release branch err: %w", err) + return "", fmt.Errorf("get release branch err: %w", err) } domain.InitMaintainVersion(handleBranch) - cves, err := c.repo.FindCves(repository.Option{CveNum: cveNum}) + cves, err := b.repo.FindCves(repository.Option{CveNum: cveNum}) if err != nil { - return fmt.Errorf("find cves failed: %w", err) + return "", fmt.Errorf("find cves failed: %w", err) } if len(cves) == 0 { - return fmt.Errorf("no cves") + return "", fmt.Errorf("no cves") } - if err = c.testResult.Init(handleBranch, date); err != nil { - return fmt.Errorf("init test result failed: %w", err) + if err = b.testResult.Init(handleBranch, date); err != nil { + return "", fmt.Errorf("init test result failed: %w", err) } // 用成功转测的数据进行过滤,只发布转测成功的cve - testedCves := c.testResult.Filter(cves) + testedCves := b.testResult.Filter(cves) - indexContent, err := c.getIndexContent() + indexContent, err := b.getIndexContent() if err != nil { - return fmt.Errorf("get %s failed: %w", fileIndex, err) + return "", fmt.Errorf("get %s failed: %w", fileIndex, err) } - maxColdPatchId, _, err := c.parseColdPatchMaxIDFromIndex(indexContent) + maxColdPatchId, err := b.parseColdPatchMaxIDFromIndex(indexContent) if err != nil { - return fmt.Errorf("parse max id failed: %w", err) + return "", fmt.Errorf("parse max id failed: %w", err) } - uploadDir := c.generateUploadDir() + uploadDir := b.generateUploadDir() bulletins := testedCves.GenerateBulletins() - updateFixedFiles := c.handleColdPatchBulletins(bulletins, uploadDir, maxColdPatchId) - - c.uploadIndexAndFixed(uploadDir, indexContent, updateFixedFiles) - - return nil -} - -func (c *coldPatchService) handleColdPatchBulletins( - bulletins []domain.SecurityBulletin, uploadDir string, maxId int, -) []string { var updateFixedFiles []string - for _, b := range bulletins { - maxId++ + for _, v := range bulletins { + maxColdPatchId++ - b.SetIdentificationOfColdPatch(maxId) + v.SetIdentificationOfColdPatch(maxColdPatchId) - b.ProductTree = c.testResult.GenerateProductTree(b.Component, b.AffectedVersion) + v.ProductTree = b.testResult.GenerateProductTree(v.Component, v.AffectedVersion) - xmlData, err1 := c.bulletin.GenerateColdPatch(&b) + xmlData, err1 := b.bulletin.GenerateColdPatch(&v) if err1 != nil { - c.log.Errorf("generate cold patch %s failed: %v", b.Identification, err1) + b.log.Errorf("generate cold patch %s failed: %v", v.Identification, err1) continue } - path := uploadDir + b.CvrfFileName() - if err1 = c.obs.Upload(path, xmlData); err1 != nil { - c.log.Errorf("upload cold patch %s failed: %v", b.Identification, err1) + path := uploadDir + v.CvrfFileName() + if err1 = b.obs.Upload(path, xmlData); err1 != nil { + b.log.Errorf("upload cold patch %s failed: %v", v.Identification, err1) continue } - updateFixedFiles = append(updateFixedFiles, b.PathAppendToIndexFile()) + updateFixedFiles = append(updateFixedFiles, v.PathAppendToIndexFile()) } - return updateFixedFiles + b.uploadIndexAndFixed(uploadDir, indexContent, updateFixedFiles) + + return uploadDir, nil } -func (c *coldPatchService) uploadIndexAndFixed(uploadDir, indexContent string, updateFixedFiles []string) { +func (b *bulletinService) uploadIndexAndFixed(uploadDir, indexContent string, updateFixedFiles []string) { updateFixedContent := strings.TrimSpace(strings.Join(updateFixedFiles, EOF)) newIndexContent := strings.TrimSpace(indexContent) + EOF + updateFixedContent indexPath := uploadDir + fileIndex updateFixedPath := uploadDir + fileUpdateFixed - if err := c.obs.Upload(indexPath, []byte(newIndexContent)); err != nil { - c.log.Errorf("upload %s failed: %v", fileIndex, err) + if err := b.obs.Upload(indexPath, []byte(newIndexContent)); err != nil { + b.log.Errorf("upload %s failed: %v", fileIndex, err) } - if err := c.obs.Upload(updateFixedPath, []byte(updateFixedContent)); err != nil { - c.log.Errorf("upload %s failed: %v", fileUpdateFixed, err) + if err := b.obs.Upload(updateFixedPath, []byte(updateFixedContent)); err != nil { + b.log.Errorf("upload %s failed: %v", fileUpdateFixed, err) } } -func (c *coldPatchService) generateUploadDir() string { +func (b *bulletinService) generateUploadDir() string { parentDir := beego.AppConfig.String("obs::upload_cvrf_dir") subDir := time.Now().Format("2006-01-02-15-04-05") + "-new/" @@ -124,15 +153,14 @@ func (c *coldPatchService) generateUploadDir() string { return parentDir + subDir } -func (c *coldPatchService) getIndexContent() (string, error) { +func (b *bulletinService) getIndexContent() (string, error) { cvrfdir := beego.AppConfig.String("obs::download_cvrf_dir") - content, err := c.obs.Download(cvrfdir + fileIndex) + content, err := b.obs.Download(cvrfdir + fileIndex) return string(content), err } -func (c *coldPatchService) parseColdPatchMaxIDFromIndex(content string, -) (maxColdPatchId, maxHotPatchId int, err error) { +func (b *bulletinService) parseColdPatchMaxIDFromIndex(content string) (int, error) { split := strings.Fields(content) for i := len(split) - 1; i >= 0; i-- { v := split[i] @@ -142,14 +170,18 @@ func (c *coldPatchService) parseColdPatchMaxIDFromIndex(content string, continue } - year, err1 := strconv.Atoi(ret[2]) - if err1 != nil { - return 0, 0, err1 + if ret[1] != domain.BulletinTypeSA { + continue } - num, err1 := strconv.Atoi(ret[3]) - if err1 != nil { - return 0, 0, err1 + year, err := strconv.Atoi(ret[2]) + if err != nil { + return 0, err + } + + num, err := strconv.Atoi(ret[3]) + if err != nil { + return 0, err } currentYear := util.Year() @@ -157,26 +189,8 @@ func (c *coldPatchService) parseColdPatchMaxIDFromIndex(content string, num = 1000 } - if ret[1] == domain.BulletinTypeSA { - maxColdPatchId = num - } - - if ret[1] == domain.BulletinTypeHotPatch { - maxHotPatchId = num - } - - if maxHotPatchId != 0 && maxColdPatchId != 0 { - break - } - } - - if maxHotPatchId == 0 { - maxHotPatchId = 1000 - } - - if maxColdPatchId == 0 { - maxColdPatchId = 1000 + return num, nil } - return maxColdPatchId, maxHotPatchId, nil + return 0, fmt.Errorf("no match max id") } diff --git a/cve-vulner-manager/cve-ddd/app/coldpatch.go b/cve-vulner-manager/cve-ddd/app/coldpatch.go index 98f8ca3..3cfe8c9 100644 --- a/cve-vulner-manager/cve-ddd/app/coldpatch.go +++ b/cve-vulner-manager/cve-ddd/app/coldpatch.go @@ -17,12 +17,10 @@ import ( "cvevulner/cve-ddd/domain" "cvevulner/cve-ddd/domain/backend" - "cvevulner/cve-ddd/domain/bulletin" "cvevulner/cve-ddd/domain/latestrpm" "cvevulner/cve-ddd/domain/majun" "cvevulner/cve-ddd/domain/obs" "cvevulner/cve-ddd/domain/repository" - "cvevulner/cve-ddd/domain/testresult" "cvevulner/cve-ddd/domain/updateinfo" ) @@ -33,37 +31,26 @@ const ( type ColdPatchService interface { CollectCveData(CmdToCollectData) - GenerateBulletins([]string, string) error -} - -type HotPatchAdapter interface { - Process() } func NewColdPatchService( rpm latestrpm.LatestRpm, repo repository.CveRepository, - b bulletin.Bulletin, backend backend.Backend, u updateinfo.UpdateInfo, o obs.OBS, m majun.Majun, - t testresult.Result, - h HotPatchAdapter, l *logrus.Entry, ) *coldPatchService { service := &coldPatchService{ - obs: o, - rpm: rpm, - repo: repo, - maJun: m, - bulletin: b, - backend: backend, - updateInfo: u, - testResult: t, - hotPatchAdapter: h, - log: l, - giteeToken: beego.AppConfig.String("gitee::git_token"), + obs: o, + rpm: rpm, + repo: repo, + maJun: m, + backend: backend, + updateInfo: u, + log: l, + giteeToken: beego.AppConfig.String("gitee::git_token"), } service.initReleaseDate() @@ -72,15 +59,12 @@ func NewColdPatchService( } type coldPatchService struct { - obs obs.OBS - rpm latestrpm.LatestRpm - repo repository.CveRepository - maJun majun.Majun - backend backend.Backend - bulletin bulletin.Bulletin - testResult testresult.Result - updateInfo updateinfo.UpdateInfo - hotPatchAdapter HotPatchAdapter + obs obs.OBS + rpm latestrpm.LatestRpm + repo repository.CveRepository + maJun majun.Majun + backend backend.Backend + updateInfo updateinfo.UpdateInfo collectLock sync.Mutex log *logrus.Entry diff --git a/cve-vulner-manager/cve-ddd/app/refactor_hotpatch.go b/cve-vulner-manager/cve-ddd/app/refactor_hotpatch.go new file mode 100644 index 0000000..7e3ff7a --- /dev/null +++ b/cve-vulner-manager/cve-ddd/app/refactor_hotpatch.go @@ -0,0 +1,220 @@ +package app + +import ( + "fmt" + "strconv" + "strings" + "time" + + "github.com/astaxie/beego" + "github.com/sirupsen/logrus" + + "cvevulner/cve-ddd/domain" + "cvevulner/cve-ddd/domain/bulletin" + "cvevulner/cve-ddd/domain/hotpatch" + "cvevulner/cve-ddd/domain/obs" + "cvevulner/cve-ddd/domain/repository" + "cvevulner/cve-ddd/domain/updateinfo" + "cvevulner/util" +) + +const ( + fileHotPatch = "update_hot_patch.txt" +) + +type RefactorHotPatchService interface { + GenerateBulletins(string) error +} + +func NewRefactorHotPatchService( + r repository.CveRepository, + b bulletin.Bulletin, + o obs.OBS, + u updateinfo.UpdateInfo, + h hotpatch.HotPatch, + l *logrus.Entry, +) *refactorHotPatchService { + return &refactorHotPatchService{ + repository: r, + bulletin: b, + obs: o, + updateInfo: u, + hotPatch: h, + log: l, + } +} + +type refactorHotPatchService struct { + repository repository.CveRepository + bulletin bulletin.Bulletin + obs obs.OBS + updateInfo updateinfo.UpdateInfo + hotPatch hotpatch.HotPatch + + log *logrus.Entry +} + +func (h *refactorHotPatchService) GenerateBulletins(uploadDir string) error { + issues, err := h.hotPatch.GetIssueInfo() + if err != nil { + return err + } + + var cvesForUpdateInfo domain.Cves + var uploadFileName []string + + indexContent, err := h.getIndexContent(uploadDir) + if err != nil { + return fmt.Errorf("get %s failed: %w", fileIndex, err) + } + + maxHotPatchId, err := h.parseHotPatchMaxIDFromIndex(indexContent) + if err != nil { + return fmt.Errorf("parse max id failed: %w", err) + } + + for _, issue := range issues { + if exist := h.repository.IssueNumExist(issue.HotIssueNum); exist { + h.log.Errorf("issue num %s exists", issue.HotIssueNum) + continue + } + + cves, err1 := h.repository.FindCves( + repository.Option{ + CveNum: issue.CveNum, + Component: issue.Component, + }) + if err1 != nil { + h.log.Errorf("find cve %s, error %s", issue.CveNum, err.Error()) + return err + } + if len(cves) == 0 { + h.log.Errorf("find cve %s nil", issue.CveNum) + continue + } + // all cves have the same hot issue number + for k := range cves { + cves[k].HotIssueNum = issue.HotIssueNum + cves[k].AffectedVersion = []string{issue.Branch} + cves[k].Component = issue.Component + } + + bulletins := cves.GenerateBulletins() + for _, b := range bulletins { + b.PatchUrl = issue.PatchUrl + + maxHotPatchId++ + b.SetIdentificationOfHotPatch(maxHotPatchId) + + xmlData, err2 := h.bulletin.GenerateHotPatch(&b) + if err2 != nil { + h.log.Errorf("component: %s, to xml error: %s", b.Component, err.Error()) + continue + } + + path := uploadDir + b.CvrfFileName() + if err2 = h.obs.Upload(path, xmlData); err2 != nil { + h.log.Errorf("component: %s, upload to obs error: %s", b.Component, err.Error()) + + continue + } + + uploadFileName = append(uploadFileName, b.PathAppendToIndexFile()) + + cvesForUpdateInfo = append(cvesForUpdateInfo, b.Cves...) + } + + if err = h.repository.SaveIssueNum(issue.HotIssueNum); err != nil { + h.log.Errorf("save issue num %s error %s", issue.HotIssueNum, err.Error()) + } + } + + h.uploadIndexAndHotPatch(uploadDir, indexContent, uploadFileName) + + return h.uploadUpdateInfo(cvesForUpdateInfo) +} + +// getIndexContent 热补丁生成的公告文件要和冷补丁的公告文件名需上传同一个目录,追加到同一个index.txt文件下, +// 因此热补丁直接下载之前冷补丁逻辑修改后的index.txt文件 +func (h *refactorHotPatchService) getIndexContent(uploadDir string) (string, error) { + path := uploadDir + fileIndex + content, err := h.obs.Download(path) + + return string(content), err +} + +func (h *refactorHotPatchService) uploadIndexAndHotPatch(uploadDir, indexContent string, hotPatchFiles []string) { + updateHotPatchContent := strings.TrimSpace(strings.Join(hotPatchFiles, EOF)) + newIndexContent := strings.TrimSpace(indexContent) + EOF + updateHotPatchContent + + indexPath := uploadDir + fileIndex + updateFixedPath := uploadDir + fileHotPatch + + if err := h.obs.Upload(indexPath, []byte(newIndexContent)); err != nil { + h.log.Errorf("upload %s failed: %v", fileIndex, err) + } + + if err := h.obs.Upload(updateFixedPath, []byte(updateHotPatchContent)); err != nil { + h.log.Errorf("upload %s failed: %v", fileHotPatch, err) + } +} + +func (h *refactorHotPatchService) parseHotPatchMaxIDFromIndex(content string) (int, error) { + split := strings.Fields(content) + for i := len(split) - 1; i >= 0; i-- { + v := split[i] + + ret := regexpBulletin.FindStringSubmatch(v) + if len(ret) != 4 { + continue + } + + if ret[1] != domain.BulletinTypeHotPatch { + continue + } + + year, err := strconv.Atoi(ret[2]) + if err != nil { + return 0, err + } + + num, err := strconv.Atoi(ret[3]) + if err != nil { + return 0, err + } + + currentYear := util.Year() + if year != currentYear { + num = 1000 + } + + return num, nil + } + + return 0, fmt.Errorf("no match max id") +} + +func (h *refactorHotPatchService) uploadUpdateInfo(cves domain.Cves) error { + if len(cves) == 0 { + return nil + } + + dir := beego.AppConfig.String("obs::upload_updateinfo_dir") + nowStr := time.Now().Format("2006-01-02") + + for version, v := range cves.GroupByVersion() { + bytes, err := h.updateInfo.Generate(v) + if err != nil { + h.log.Errorf("generate updateinfo of %s error %s", version, err.Error()) + continue + } + + path := fmt.Sprintf("%s%s-%s/%s", dir, nowStr, "hotpatch", fmt.Sprintf("%s_updateinfo.xlsx", version)) + if err := h.obs.Upload(path, bytes); err != nil { + h.log.Errorf("version: %s, upload to obs error: %s", version, err.Error()) + continue + } + } + + return nil +} diff --git a/cve-vulner-manager/cve-ddd/controller/cve.go b/cve-vulner-manager/cve-ddd/controller/cve.go index 35a6df4..99d9026 100644 --- a/cve-vulner-manager/cve-ddd/controller/cve.go +++ b/cve-vulner-manager/cve-ddd/controller/cve.go @@ -5,6 +5,7 @@ import ( "sync/atomic" "github.com/astaxie/beego/validation" + "github.com/opensourceways/server-common-lib/utils" "github.com/sirupsen/logrus" "cvevulner/cve-ddd/app" @@ -14,18 +15,30 @@ const allowConcurrency = 1 var concurrency atomic.Int32 -func NewCveController(s app.ColdPatchService, l *logrus.Entry) *CveController { +func NewCveController( + c app.ColdPatchService, + b app.BulletinService, + h app.RefactorHotPatchService, + hl *logrus.Entry, + bl *logrus.Entry, +) *CveController { return &CveController{ - Service: s, - Log: l, + hotPatchBulletinLog: hl, + bulletinLog: bl, + ColdPatchService: c, + BulletinService: b, + HotPatchService: h, } } type CveController struct { BaseController - Log *logrus.Entry - Service app.ColdPatchService + hotPatchBulletinLog *logrus.Entry + bulletinLog *logrus.Entry + ColdPatchService app.ColdPatchService + BulletinService app.BulletinService + HotPatchService app.RefactorHotPatchService } func (c *CveController) CollectCveData() { @@ -44,7 +57,7 @@ func (c *CveController) CollectCveData() { return } - c.Service.CollectCveData(request) + c.ColdPatchService.CollectCveData(request) c.success(nil) } @@ -75,10 +88,21 @@ func (c *CveController) Generate() { return } - err = c.Service.GenerateBulletins(request.CveNum, request.Date) + mr := utils.NewMultiErrors() + uploadDir, err := c.BulletinService.GenerateBulletins(request.CveNum, request.Date) if err != nil { - c.Log.Errorf("generate bulletins failed: %v", err) - c.fail(err.Error()) + c.bulletinLog.Errorf("generate security bulletins failed: %s", err.Error()) + mr.AddError(err) + } else { + err = c.HotPatchService.GenerateBulletins(uploadDir) + if err != nil { + c.hotPatchBulletinLog.Errorf("generate hot patch security bulletins failed: %s", err.Error()) + mr.AddError(err) + } + } + + if mr.Err() != nil { + c.fail(mr.Err().Error()) } else { c.success(nil) } diff --git a/cve-vulner-manager/cve-ddd/domain/bulletins.go b/cve-vulner-manager/cve-ddd/domain/bulletins.go index cc89b2d..cdac346 100644 --- a/cve-vulner-manager/cve-ddd/domain/bulletins.go +++ b/cve-vulner-manager/cve-ddd/domain/bulletins.go @@ -35,6 +35,10 @@ func (s *SecurityBulletin) SetIdentificationOfColdPatch(id int) { s.Identification = fmt.Sprintf("openEuler-SA-%d-%d", util.Year(), id) } +func (s *SecurityBulletin) SetIdentificationOfHotPatch(id int) { + s.Identification = fmt.Sprintf("openEuler-HotPatchSA-%d-%d", util.Year(), id) +} + func (s *SecurityBulletin) CvrfFileName() string { return fmt.Sprintf("cvrf-%s.xml", s.Identification) } diff --git a/cve-vulner-manager/cve-ddd/domain/callback.go b/cve-vulner-manager/cve-ddd/domain/callback.go index 9b6f794..b6f3cac 100644 --- a/cve-vulner-manager/cve-ddd/domain/callback.go +++ b/cve-vulner-manager/cve-ddd/domain/callback.go @@ -28,6 +28,7 @@ type CollectResult struct { } type CallbackDTO struct { + IssueNum string `json:"issueId"` // 对方要issueId作为参数名 CVE string `json:"CVE"` Score float64 `json:"score"` Version string `json:"version"` @@ -41,6 +42,7 @@ func ToCallbackDTO(data CollectedDataSlice) []CallbackDTO { for _, v := range data { t := CallbackDTO{ + IssueNum: v.Issue.Number, CVE: v.CveNum, Score: v.Score, Version: v.Version, diff --git a/cve-vulner-manager/cve-ddd/domain/hot_patch_issue.go b/cve-vulner-manager/cve-ddd/domain/hot_patch_issue.go new file mode 100644 index 0000000..0016b35 --- /dev/null +++ b/cve-vulner-manager/cve-ddd/domain/hot_patch_issue.go @@ -0,0 +1,10 @@ +package domain + +type HotPatchIssue struct { + Type string + Branch string + Component string + CveNum []string + PatchUrl []string + HotIssueNum string +} diff --git a/cve-vulner-manager/cve-ddd/domain/hotpatch/hotpatch.go b/cve-vulner-manager/cve-ddd/domain/hotpatch/hotpatch.go new file mode 100644 index 0000000..1493d8c --- /dev/null +++ b/cve-vulner-manager/cve-ddd/domain/hotpatch/hotpatch.go @@ -0,0 +1,7 @@ +package hotpatch + +import "cvevulner/cve-ddd/domain" + +type HotPatch interface { + GetIssueInfo() ([]domain.HotPatchIssue, error) +} diff --git a/cve-vulner-manager/cve-ddd/infrastructure/hotpatchimpl/impl.go b/cve-vulner-manager/cve-ddd/infrastructure/hotpatchimpl/impl.go new file mode 100644 index 0000000..d7d0838 --- /dev/null +++ b/cve-vulner-manager/cve-ddd/infrastructure/hotpatchimpl/impl.go @@ -0,0 +1,149 @@ +package hotpatchimpl + +import ( + "encoding/json" + "errors" + "fmt" + "net/http" + "regexp" + "strings" + "time" + + "github.com/astaxie/beego" + "github.com/opensourceways/server-common-lib/utils" + "github.com/sirupsen/logrus" + + "cvevulner/cve-ddd/domain" + "cvevulner/util" +) + +const hotPatchIssue = "https://gitee.com/api/v5/repos/openeuler/hotpatch_meta/issues?" + + "access_token=%s&state=closed&labels=%s&sort=created&direction=desc&page=%d&per_page=20&created_at=%s" + +var ( + RegexpCve = regexp.MustCompile(`(?s:(.*?))`) + RegexpRPM = regexp.MustCompile(`热补丁路径[::](?s:(.*?))热补丁信息[::]`) + RegexpMeta = regexp.MustCompile(`热补丁元数据[::](?s:(.*?))热补丁路径[::]`) + RegexpType = regexp.MustCompile(`问题类别[::](?s:(.*?))热补丁元数据[::]`) + RegexpInfo = regexp.MustCompile(`热补丁信息[::](?s:(.*?))$`) +) + +func NewHotPatchImpl(log *logrus.Entry) *hotPatchImpl { + return &hotPatchImpl{ + log: log, + } +} + +type hotPatchImpl struct { + log *logrus.Entry +} + +func (impl hotPatchImpl) GetIssueInfo() ([]domain.HotPatchIssue, error) { + issues, err := impl.getIssues() + if err != nil { + return nil, fmt.Errorf("get hot patch issue error: %w", err) + } + + var patches []domain.HotPatchIssue + for _, v := range issues { + pat, err1 := impl.toPatchIssue(v.Body) + if err1 != nil { + impl.log.Errorf("issue number %s toPatchIssue error: %v", v.Number, err) + continue + } + pat.HotIssueNum = v.Number + + patches = append(patches, pat) + } + + return patches, nil +} + +type Issue struct { + Number string `json:"number"` + Body string `json:"body"` +} + +func (impl hotPatchImpl) getIssues() ([]Issue, error) { + var page = 1 + var issues []Issue + token := beego.AppConfig.String("gitee::git_token") + cli := utils.NewHttpClient(3) + // query the data within a month + filterCreatedTime := time.Now().AddDate(0, -1, 0).Format("20060102T1504015-") + + for { + url := fmt.Sprintf(hotPatchIssue, token, "hotpatch", page, filterCreatedTime) + req, err := http.NewRequest( + http.MethodGet, url, nil, + ) + if err != nil { + return nil, err + } + + res, _, err := cli.Download(req) + if err != nil { + return nil, err + } + + var t []Issue + if err = json.Unmarshal(res, &t); err != nil { + return nil, err + } + + if len(t) == 0 { + break + } + + issues = append(issues, t...) + + page++ + } + + return issues, nil +} + +func (impl hotPatchImpl) toPatchIssue(body string) (v domain.HotPatchIssue, err error) { + t := RegexpType.FindAllStringSubmatch(body, -1) + if len(t) == 0 { + return v, errors.New("parse type failed") + } + v.Type = strings.TrimSpace(t[0][1]) + + meta := RegexpMeta.FindAllStringSubmatch(body, -1) + if len(meta) == 0 { + return v, errors.New("parse metadata failed") + } + split := strings.Split(meta[0][1], "/") + v.Branch = split[len(split)-4] + v.Component = split[len(split)-3] + + p := RegexpRPM.FindAllStringSubmatch(body, -1) + if len(p) == 0 { + return v, errors.New("parse rpm failed") + } + v.PatchUrl = strings.Split(strings.TrimSpace(p[0][1]), "\n") + + info := RegexpInfo.FindAllStringSubmatch(body, -1) + if len(info) == 0 { + return v, errors.New("parse info failed") + } + var bys []byte + for _, s := range strings.Split(strings.TrimSpace(info[0][1]), "\n") { + bys, err = util.HTTPGetCom(strings.TrimSpace(s)) + if err != nil { + continue + } + + if cve := RegexpCve.FindAllStringSubmatch(string(bys), -1); len(cve) > 0 { + v.CveNum = strings.Split(cve[0][1], ",") + break + } + } + + if len(v.CveNum) == 0 { + return v, errors.New("parse cve num failed") + } + + return +} diff --git a/cve-vulner-manager/routers/new_router.go b/cve-vulner-manager/routers/new_router.go index 8e1e93b..20d7d3d 100644 --- a/cve-vulner-manager/routers/new_router.go +++ b/cve-vulner-manager/routers/new_router.go @@ -4,11 +4,11 @@ import ( "github.com/astaxie/beego" "github.com/sirupsen/logrus" - "cvevulner/cve-ddd/adapter" "cvevulner/cve-ddd/app" "cvevulner/cve-ddd/controller" "cvevulner/cve-ddd/infrastructure/backendimpl" "cvevulner/cve-ddd/infrastructure/bulletinimpl" + "cvevulner/cve-ddd/infrastructure/hotpatchimpl" "cvevulner/cve-ddd/infrastructure/latestrpmimpl" "cvevulner/cve-ddd/infrastructure/majunimpl" "cvevulner/cve-ddd/infrastructure/obsimpl" @@ -24,22 +24,45 @@ func Init() { } func InitNewRouter() { - log := logrus.New().WithField("module", "new-security-bulletin") + logBulletin := logrus.New().WithField("module", "new-security-bulletin") + logHotPatchBulletin := logrus.New().WithField("module", "new-hot-patch-security-bulletin") + logColdPatchCveCollect := logrus.New().WithField("module", "new-cold-patch-cve-collect") coldPatchService := app.NewColdPatchService( latestrpmimpl.NewLatestRpm(), repositoryimpl.NewRepositoryImpl(), - bulletinimpl.NewBulletinImpl(), backendimpl.NewBackendImpl(), updateinfoimpl.NewUpdateInfoImpl(), obsimpl.Instance(), majunimpl.NewMajunImpl(), - testresultimpl.NewTestResultImpl(log), - adapter.NewHotPatchAdapter(), - log, + logColdPatchCveCollect, + ) + + bulletinService := app.NewBulletinService( + obsimpl.Instance(), + repositoryimpl.NewRepositoryImpl(), + majunimpl.NewMajunImpl(), + bulletinimpl.NewBulletinImpl(), + testresultimpl.NewTestResultImpl(logBulletin), + logBulletin, ) - NewCveController := controller.NewCveController(coldPatchService, log) + hotPatchService := app.NewRefactorHotPatchService( + repositoryimpl.NewRepositoryImpl(), + bulletinimpl.NewBulletinImpl(), + obsimpl.Instance(), + updateinfoimpl.NewUpdateInfoImpl(), + hotpatchimpl.NewHotPatchImpl(logHotPatchBulletin), + logHotPatchBulletin, + ) + + NewCveController := controller.NewCveController( + coldPatchService, + bulletinService, + hotPatchService, + logHotPatchBulletin, + logBulletin, + ) beego.Router("/security/bulletin/collect", NewCveController, "post:CollectCveData") beego.Router("/security/bulletin/generate", NewCveController, "post:Generate") -- Gitee From 3e3d07865f1a80568af55f7c26e9b1b2f37650d9 Mon Sep 17 00:00:00 2001 From: yangwei999 <348134071@qq.com> Date: Thu, 30 May 2024 10:21:00 +0800 Subject: [PATCH 12/29] clear code --- .../cve-ddd/infrastructure/majunimpl/impl.go | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/cve-vulner-manager/cve-ddd/infrastructure/majunimpl/impl.go b/cve-vulner-manager/cve-ddd/infrastructure/majunimpl/impl.go index cc397db..42f82de 100644 --- a/cve-vulner-manager/cve-ddd/infrastructure/majunimpl/impl.go +++ b/cve-vulner-manager/cve-ddd/infrastructure/majunimpl/impl.go @@ -49,31 +49,31 @@ type releaseResponse struct { } func (impl *majunImpl) GetReleasedBranch() ([]string, error) { - //req, err := impl.generateRequest(urlReleaseVersion, nil) - //if err != nil { - // return nil, err - //} - // - //var v releaseResponse - //_, err = impl.client.ForwardTo(req, &v) - //if err != nil { - // return nil, err - //} - // - //if v.Code != http.StatusOK { - // return nil, errors.New(v.Message) - //} - // - //return v.Result, nil - - return []string{ - "openEuler-20.03-LTS-SP1", - "openEuler-20.03-LTS-SP4", - "openEuler-22.03-LTS", - "openEuler-22.03-LTS-SP1", - "openEuler-22.03-LTS-SP2", - "openEuler-22.03-LTS-SP3", - }, nil + req, err := impl.generateRequest(urlReleaseVersion, nil) + if err != nil { + return nil, err + } + + var v releaseResponse + _, err = impl.client.ForwardTo(req, &v) + if err != nil { + return nil, err + } + + if v.Code != http.StatusOK { + return nil, errors.New(v.Message) + } + + return v.Result, nil + + //return []string{ + // "openEuler-20.03-LTS-SP1", + // "openEuler-20.03-LTS-SP4", + // "openEuler-22.03-LTS", + // "openEuler-22.03-LTS-SP1", + // "openEuler-22.03-LTS-SP2", + // "openEuler-22.03-LTS-SP3", + //}, nil } type callbackBody struct { -- Gitee From 5347a4ef3400f2dfeba5e99612028dcca063b772 Mon Sep 17 00:00:00 2001 From: yangwei999 <348134071@qq.com> Date: Thu, 30 May 2024 11:28:46 +0800 Subject: [PATCH 13/29] fix sql bug --- .../cve-ddd/infrastructure/repositoryimpl/callback.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cve-vulner-manager/cve-ddd/infrastructure/repositoryimpl/callback.go b/cve-vulner-manager/cve-ddd/infrastructure/repositoryimpl/callback.go index 72ad2fb..1aa40c3 100644 --- a/cve-vulner-manager/cve-ddd/infrastructure/repositoryimpl/callback.go +++ b/cve-vulner-manager/cve-ddd/infrastructure/repositoryimpl/callback.go @@ -65,11 +65,11 @@ func (impl repositoryImpl) FindCollectResult(branch, collectDate string) (string query := orm.NewOrm().QueryTable(callbackResult) if branch != "" { - query.Filter(fieldBranch, branch) + query = query.Filter(fieldBranch, branch) } if collectDate != "" { - query.Filter(fieldCollect, collectDate) + query = query.Filter(fieldCollect, collectDate) } err := query.One(callbackResult) -- Gitee From 455b6134f4ba5e3b1b5833fd6513a99a72ed2347 Mon Sep 17 00:00:00 2001 From: yangwei999 <348134071@qq.com> Date: Thu, 30 May 2024 16:41:41 +0800 Subject: [PATCH 14/29] compatible test repo --- .../infrastructure/testresultimpl/impl.go | 53 ++++++++++++++----- 1 file changed, 41 insertions(+), 12 deletions(-) diff --git a/cve-vulner-manager/cve-ddd/infrastructure/testresultimpl/impl.go b/cve-vulner-manager/cve-ddd/infrastructure/testresultimpl/impl.go index ae74645..fc809cd 100644 --- a/cve-vulner-manager/cve-ddd/infrastructure/testresultimpl/impl.go +++ b/cve-vulner-manager/cve-ddd/infrastructure/testresultimpl/impl.go @@ -14,6 +14,10 @@ import ( "cvevulner/cve-ddd/domain" ) +const ( + epolBranch = "openEuler-22.03-LTS-SP1" +) + func NewTestResultImpl(log *logrus.Entry) *testResultImpl { return &testResultImpl{ log: log, @@ -29,21 +33,46 @@ type testResultImpl struct { resultCache map[string]map[string][]string } +func (impl *testResultImpl) getCsvOfRpmByBranch(branch, date string) []byte { + url := fmt.Sprintf("http://121.36.84.172/repo.openeuler.org/%s/%s/%s.csv", branch, date, branch) + + req, _ := http.NewRequest(http.MethodGet, url, nil) + + content, _, err := impl.client.Download(req) + if err != nil { + // 可能有些分支没有转测,所以出错后记录日志即可 + impl.log.Errorf("get csv rpm of [%s %s] failed: %s", branch, date, err.Error()) + } + + // 该分支特殊,csv分别在两处目录,需要额外处理,将两处的内容合并 + if branch == epolBranch { + epolContent := impl.getCsvOfRpmInEpolByBranch(branch, date) + content = append(content, epolContent...) + } + + return content +} + +func (impl *testResultImpl) getCsvOfRpmInEpolByBranch(branch, date string) []byte { + epolUrl := fmt.Sprintf("http://121.36.84.172/repo.openeuler.org/%s/EPOL/%s/main/%s.csv", branch, date, branch) + + req, _ := http.NewRequest(http.MethodGet, epolUrl, nil) + + content, _, err := impl.client.Download(req) + if err != nil { + impl.log.Errorf("get epol csv rpm of [%s %s] failed: %s", branch, date, err.Error()) + } + + return content +} + func (impl *testResultImpl) Init(handleBranch []string, date string) error { impl.resultCache = make(map[string]map[string][]string) for _, b := range handleBranch { - url := fmt.Sprintf("http://121.36.84.172/repo.openeuler.org/%s/%s/xxx.csv", b, date) - - req, err := http.NewRequest(http.MethodGet, url, nil) - if err != nil { - return err - } - - content, _, err := impl.client.Download(req) - if err != nil { - impl.log.Errorf("download test result of %s failed: %v", b, err) - continue // 有的分支可能没有转测,请求肯定为404,只能直接跳过了 + content := impl.getCsvOfRpmByBranch(b, date) + if len(content) == 0 { + continue } impl.resultCache[b] = impl.parseContent(content) @@ -75,7 +104,7 @@ func (impl *testResultImpl) Filter(cves domain.Cves) domain.Cves { } func (impl *testResultImpl) GenerateProductTree(component string, affectedVersion []string) domain.ProductTree { - var tree domain.ProductTree + tree := make(domain.ProductTree) for _, version := range affectedVersion { rpms := impl.resultCache[version][component] // 生成公告前已经过滤一次了,所以组件和影响分支必定存在 -- Gitee From 6c9c12f2d77b90adee431a2c9122c67c9e8f766a Mon Sep 17 00:00:00 2001 From: yangwei999 <348134071@qq.com> Date: Fri, 31 May 2024 09:53:20 +0800 Subject: [PATCH 15/29] clean code --- cve-vulner-manager/cve-ddd/app/bulletin.go | 48 +------------------ .../cve-ddd/app/refactor_hotpatch.go | 39 +-------------- .../cve-ddd/domain/bulletins.go | 41 ++++++++++++++++ .../cve-ddd/domain/testresult/result.go | 2 +- .../infrastructure/testresultimpl/impl.go | 4 +- 5 files changed, 46 insertions(+), 88 deletions(-) diff --git a/cve-vulner-manager/cve-ddd/app/bulletin.go b/cve-vulner-manager/cve-ddd/app/bulletin.go index 16886ea..6e457cf 100644 --- a/cve-vulner-manager/cve-ddd/app/bulletin.go +++ b/cve-vulner-manager/cve-ddd/app/bulletin.go @@ -2,8 +2,6 @@ package app import ( "fmt" - "regexp" - "strconv" "strings" "time" @@ -16,7 +14,6 @@ import ( "cvevulner/cve-ddd/domain/obs" "cvevulner/cve-ddd/domain/repository" "cvevulner/cve-ddd/domain/testresult" - "cvevulner/util" ) const ( @@ -26,10 +23,6 @@ const ( fileUpdateFixed = "update_fixed.txt" ) -var ( - regexpBulletin = regexp.MustCompile(`cvrf-openEuler-(\w+)-(\d{4})-(\d{4})\.xml`) -) - type BulletinService interface { GenerateBulletins([]string, string) (string, error) } @@ -79,9 +72,7 @@ func (b *bulletinService) GenerateBulletins(cveNum []string, date string) (strin return "", fmt.Errorf("no cves") } - if err = b.testResult.Init(handleBranch, date); err != nil { - return "", fmt.Errorf("init test result failed: %w", err) - } + b.testResult.Init(handleBranch, date) // 用成功转测的数据进行过滤,只发布转测成功的cve testedCves := b.testResult.Filter(cves) @@ -91,7 +82,7 @@ func (b *bulletinService) GenerateBulletins(cveNum []string, date string) (strin return "", fmt.Errorf("get %s failed: %w", fileIndex, err) } - maxColdPatchId, err := b.parseColdPatchMaxIDFromIndex(indexContent) + maxColdPatchId, err := domain.ParseMaxIdFromIndexTxt(indexContent, domain.BulletinTypeSA) if err != nil { return "", fmt.Errorf("parse max id failed: %w", err) } @@ -159,38 +150,3 @@ func (b *bulletinService) getIndexContent() (string, error) { return string(content), err } - -func (b *bulletinService) parseColdPatchMaxIDFromIndex(content string) (int, error) { - split := strings.Fields(content) - for i := len(split) - 1; i >= 0; i-- { - v := split[i] - - ret := regexpBulletin.FindStringSubmatch(v) - if len(ret) != 4 { - continue - } - - if ret[1] != domain.BulletinTypeSA { - continue - } - - year, err := strconv.Atoi(ret[2]) - if err != nil { - return 0, err - } - - num, err := strconv.Atoi(ret[3]) - if err != nil { - return 0, err - } - - currentYear := util.Year() - if year != currentYear { - num = 1000 - } - - return num, nil - } - - return 0, fmt.Errorf("no match max id") -} diff --git a/cve-vulner-manager/cve-ddd/app/refactor_hotpatch.go b/cve-vulner-manager/cve-ddd/app/refactor_hotpatch.go index 7e3ff7a..718efc5 100644 --- a/cve-vulner-manager/cve-ddd/app/refactor_hotpatch.go +++ b/cve-vulner-manager/cve-ddd/app/refactor_hotpatch.go @@ -2,7 +2,6 @@ package app import ( "fmt" - "strconv" "strings" "time" @@ -15,7 +14,6 @@ import ( "cvevulner/cve-ddd/domain/obs" "cvevulner/cve-ddd/domain/repository" "cvevulner/cve-ddd/domain/updateinfo" - "cvevulner/util" ) const ( @@ -68,7 +66,7 @@ func (h *refactorHotPatchService) GenerateBulletins(uploadDir string) error { return fmt.Errorf("get %s failed: %w", fileIndex, err) } - maxHotPatchId, err := h.parseHotPatchMaxIDFromIndex(indexContent) + maxHotPatchId, err := domain.ParseMaxIdFromIndexTxt(indexContent, domain.BulletinTypeHotPatch) if err != nil { return fmt.Errorf("parse max id failed: %w", err) } @@ -159,41 +157,6 @@ func (h *refactorHotPatchService) uploadIndexAndHotPatch(uploadDir, indexContent } } -func (h *refactorHotPatchService) parseHotPatchMaxIDFromIndex(content string) (int, error) { - split := strings.Fields(content) - for i := len(split) - 1; i >= 0; i-- { - v := split[i] - - ret := regexpBulletin.FindStringSubmatch(v) - if len(ret) != 4 { - continue - } - - if ret[1] != domain.BulletinTypeHotPatch { - continue - } - - year, err := strconv.Atoi(ret[2]) - if err != nil { - return 0, err - } - - num, err := strconv.Atoi(ret[3]) - if err != nil { - return 0, err - } - - currentYear := util.Year() - if year != currentYear { - num = 1000 - } - - return num, nil - } - - return 0, fmt.Errorf("no match max id") -} - func (h *refactorHotPatchService) uploadUpdateInfo(cves domain.Cves) error { if len(cves) == 0 { return nil diff --git a/cve-vulner-manager/cve-ddd/domain/bulletins.go b/cve-vulner-manager/cve-ddd/domain/bulletins.go index cdac346..3a73832 100644 --- a/cve-vulner-manager/cve-ddd/domain/bulletins.go +++ b/cve-vulner-manager/cve-ddd/domain/bulletins.go @@ -2,6 +2,8 @@ package domain import ( "fmt" + "regexp" + "strconv" "strings" "cvevulner/util" @@ -13,6 +15,10 @@ const ( BulletinTypeHotPatch = "HotPatchSA" ) +var ( + regexpBulletin = regexp.MustCompile(`cvrf-openEuler-(\w+)-(\d{4})-(\d{4})\.xml`) +) + type SecurityBulletin struct { AffectedVersion []string Identification string @@ -50,3 +56,38 @@ func (s *SecurityBulletin) PathAppendToIndexFile() string { func (s *SecurityBulletin) IsColdPatch() bool { return !strings.Contains(s.Identification, BulletinTypeHotPatch) } + +func ParseMaxIdFromIndexTxt(content, bulletinType string) (int, error) { + split := strings.Fields(content) + for i := len(split) - 1; i >= 0; i-- { + v := split[i] + + ret := regexpBulletin.FindStringSubmatch(v) + if len(ret) != 4 { + continue + } + + if ret[1] != bulletinType { + continue + } + + year, err := strconv.Atoi(ret[2]) + if err != nil { + return 0, err + } + + num, err := strconv.Atoi(ret[3]) + if err != nil { + return 0, err + } + + currentYear := util.Year() + if year != currentYear { + num = 1000 + } + + return num, nil + } + + return 0, fmt.Errorf("no match max id") +} diff --git a/cve-vulner-manager/cve-ddd/domain/testresult/result.go b/cve-vulner-manager/cve-ddd/domain/testresult/result.go index 251c8d9..350673b 100644 --- a/cve-vulner-manager/cve-ddd/domain/testresult/result.go +++ b/cve-vulner-manager/cve-ddd/domain/testresult/result.go @@ -5,7 +5,7 @@ import ( ) type Result interface { - Init([]string, string) error + Init([]string, string) Filter(domain.Cves) domain.Cves GenerateProductTree(string, []string) domain.ProductTree } diff --git a/cve-vulner-manager/cve-ddd/infrastructure/testresultimpl/impl.go b/cve-vulner-manager/cve-ddd/infrastructure/testresultimpl/impl.go index fc809cd..32ebf86 100644 --- a/cve-vulner-manager/cve-ddd/infrastructure/testresultimpl/impl.go +++ b/cve-vulner-manager/cve-ddd/infrastructure/testresultimpl/impl.go @@ -66,7 +66,7 @@ func (impl *testResultImpl) getCsvOfRpmInEpolByBranch(branch, date string) []byt return content } -func (impl *testResultImpl) Init(handleBranch []string, date string) error { +func (impl *testResultImpl) Init(handleBranch []string, date string) { impl.resultCache = make(map[string]map[string][]string) for _, b := range handleBranch { @@ -77,8 +77,6 @@ func (impl *testResultImpl) Init(handleBranch []string, date string) error { impl.resultCache[b] = impl.parseContent(content) } - - return nil } func (impl *testResultImpl) Filter(cves domain.Cves) domain.Cves { -- Gitee From c4ec394d4b064a4da793a0a263eae3237724ad88 Mon Sep 17 00:00:00 2001 From: yangwei999 <348134071@qq.com> Date: Fri, 31 May 2024 11:50:16 +0800 Subject: [PATCH 16/29] add epol attr to xml --- .../cve-ddd/domain/bulletins.go | 1 + .../infrastructure/bulletinimpl/impl.go | 1 + .../infrastructure/bulletinimpl/xml.go | 1 + .../infrastructure/testresultimpl/impl.go | 60 ++++++++++++++----- 4 files changed, 47 insertions(+), 16 deletions(-) diff --git a/cve-vulner-manager/cve-ddd/domain/bulletins.go b/cve-vulner-manager/cve-ddd/domain/bulletins.go index 3a73832..291ffcb 100644 --- a/cve-vulner-manager/cve-ddd/domain/bulletins.go +++ b/cve-vulner-manager/cve-ddd/domain/bulletins.go @@ -35,6 +35,7 @@ type Product struct { ID string CPE string FullName string + IsEpol bool } func (s *SecurityBulletin) SetIdentificationOfColdPatch(id int) { diff --git a/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/impl.go b/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/impl.go index a6ecab2..905b510 100644 --- a/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/impl.go +++ b/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/impl.go @@ -297,6 +297,7 @@ func (impl bulletinImpl) ProductTree(sb *domain.SecurityBulletin) *ProductTree { ProductId: p.ID, Cpe: getCpe(p.CPE), FullProductName: p.FullName, + IsEpol: p.IsEpol, }) } diff --git a/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/xml.go b/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/xml.go index be20510..6188a13 100644 --- a/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/xml.go +++ b/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/xml.go @@ -111,6 +111,7 @@ type FullProductName struct { XMLName xml.Name `xml:"FullProductName,omitempty"` ProductId string `xml:"ProductID,attr"` Cpe string `xml:"CPE,attr"` + IsEpol bool `xml:"EPOL,attr"` FullProductName string `xml:",innerxml"` } diff --git a/cve-vulner-manager/cve-ddd/infrastructure/testresultimpl/impl.go b/cve-vulner-manager/cve-ddd/infrastructure/testresultimpl/impl.go index 32ebf86..9c38f08 100644 --- a/cve-vulner-manager/cve-ddd/infrastructure/testresultimpl/impl.go +++ b/cve-vulner-manager/cve-ddd/infrastructure/testresultimpl/impl.go @@ -30,7 +30,12 @@ type testResultImpl struct { client utils.HttpClient // map[branch]map[component][]rpm - resultCache map[string]map[string][]string + resultCache map[string]map[string][]rpm +} + +type rpm struct { + Name string + IsEpol bool } func (impl *testResultImpl) getCsvOfRpmByBranch(branch, date string) []byte { @@ -44,12 +49,6 @@ func (impl *testResultImpl) getCsvOfRpmByBranch(branch, date string) []byte { impl.log.Errorf("get csv rpm of [%s %s] failed: %s", branch, date, err.Error()) } - // 该分支特殊,csv分别在两处目录,需要额外处理,将两处的内容合并 - if branch == epolBranch { - epolContent := impl.getCsvOfRpmInEpolByBranch(branch, date) - content = append(content, epolContent...) - } - return content } @@ -67,18 +66,41 @@ func (impl *testResultImpl) getCsvOfRpmInEpolByBranch(branch, date string) []byt } func (impl *testResultImpl) Init(handleBranch []string, date string) { - impl.resultCache = make(map[string]map[string][]string) + impl.resultCache = make(map[string]map[string][]rpm) for _, b := range handleBranch { + var cacheNormal, cacheEpol map[string][]rpm + content := impl.getCsvOfRpmByBranch(b, date) - if len(content) == 0 { + cacheNormal = impl.parseContent(content, false) + + // 该分支特殊,csv分别在两处目录,需要额外处理,将两处的内容合并 + if b == epolBranch { + epolContent := impl.getCsvOfRpmInEpolByBranch(b, date) + cacheEpol = impl.parseContent(epolContent, true) + } + + cacheMerged := impl.mergeCache(cacheNormal, cacheEpol) + if len(cacheMerged) == 0 { continue } - impl.resultCache[b] = impl.parseContent(content) + impl.resultCache[b] = cacheMerged } } +func (impl *testResultImpl) mergeCache(source ...map[string][]rpm) map[string][]rpm { + target := make(map[string][]rpm) + for _, m := range source { + for k, v := range m { + target[k] = append(target[k], v...) + } + } + + return target + +} + func (impl *testResultImpl) Filter(cves domain.Cves) domain.Cves { var filtered domain.Cves @@ -107,16 +129,17 @@ func (impl *testResultImpl) GenerateProductTree(component string, affectedVersio for _, version := range affectedVersion { rpms := impl.resultCache[version][component] // 生成公告前已经过滤一次了,所以组件和影响分支必定存在 - for _, rpm := range rpms { + for _, v := range rpms { // example of rpm: zbar-0.22-4.oe2203.src.rpm - t := strings.Split(rpm, ".") + t := strings.Split(v.Name, ".") arch := t[len(t)-2] productId := strings.Join(t[:len(t)-3], ".") product := domain.Product{ ID: productId, CPE: version, - FullName: rpm, + FullName: v.Name, + IsEpol: v.IsEpol, } tree[arch] = append(tree[arch], product) @@ -126,11 +149,11 @@ func (impl *testResultImpl) GenerateProductTree(component string, affectedVersio return tree } -func (impl *testResultImpl) parseContent(content []byte) map[string][]string { +func (impl *testResultImpl) parseContent(content []byte, fromEpol bool) map[string][]rpm { buff := bytes.NewBuffer(content) r := csv.NewReader(buff) - componentAndRpm := make(map[string][]string) + componentAndRpm := make(map[string][]rpm) for { line, err := r.Read() if err == io.EOF { @@ -146,7 +169,12 @@ func (impl *testResultImpl) parseContent(content []byte) map[string][]string { continue } - componentAndRpm[line[0]] = splitRpm + var t []rpm + for _, v := range splitRpm { + t = append(t, rpm{Name: v, IsEpol: fromEpol}) + } + + componentAndRpm[line[0]] = t } return componentAndRpm -- Gitee From 9600d161c268757a92977b6c89dd89a45b32c701 Mon Sep 17 00:00:00 2001 From: yangwei999 <348134071@qq.com> Date: Fri, 31 May 2024 15:23:25 +0800 Subject: [PATCH 17/29] add where condition to sql and omit xml --- .../cve-ddd/infrastructure/bulletinimpl/xml.go | 2 +- .../cve-ddd/infrastructure/repositoryimpl/impl.go | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/xml.go b/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/xml.go index 6188a13..b01b9e5 100644 --- a/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/xml.go +++ b/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/xml.go @@ -111,7 +111,7 @@ type FullProductName struct { XMLName xml.Name `xml:"FullProductName,omitempty"` ProductId string `xml:"ProductID,attr"` Cpe string `xml:"CPE,attr"` - IsEpol bool `xml:"EPOL,attr"` + IsEpol bool `xml:"EPOL,attr,omitempty"` FullProductName string `xml:",innerxml"` } diff --git a/cve-vulner-manager/cve-ddd/infrastructure/repositoryimpl/impl.go b/cve-vulner-manager/cve-ddd/infrastructure/repositoryimpl/impl.go index 9859ef6..c5ac2d5 100644 --- a/cve-vulner-manager/cve-ddd/infrastructure/repositoryimpl/impl.go +++ b/cve-vulner-manager/cve-ddd/infrastructure/repositoryimpl/impl.go @@ -29,7 +29,11 @@ func (impl repositoryImpl) FindCves(opt repository.Option) (cves domain.Cves, er from cve_vuln_center a join cve_issue_template b on a.cve_id=b.cve_id join cve_security_notice c on a.cve_id=c.cve_id -where a.cve_num in (%s) and a.organizate_id = 1 +where a.cve_num in (%s) +and a.cve_status = 2 +and a.is_export in (0,3) +and a.organizate_id = 1 +and b.status < 4 ` if opt.Component != "" { sql += fmt.Sprintf(`and a.pack_name = "%s"`, opt.Component) -- Gitee From 33a67e694d967c6dfc1777b4403d004fe68da634 Mon Sep 17 00:00:00 2001 From: yangwei999 <348134071@qq.com> Date: Fri, 31 May 2024 16:02:53 +0800 Subject: [PATCH 18/29] no new hot patch issue --- cve-vulner-manager/cve-ddd/app/refactor_hotpatch.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cve-vulner-manager/cve-ddd/app/refactor_hotpatch.go b/cve-vulner-manager/cve-ddd/app/refactor_hotpatch.go index 718efc5..0ca2a85 100644 --- a/cve-vulner-manager/cve-ddd/app/refactor_hotpatch.go +++ b/cve-vulner-manager/cve-ddd/app/refactor_hotpatch.go @@ -127,6 +127,10 @@ func (h *refactorHotPatchService) GenerateBulletins(uploadDir string) error { } } + if len(uploadFileName) == 0 { + return fmt.Errorf("no new hot patch issues") + } + h.uploadIndexAndHotPatch(uploadDir, indexContent, uploadFileName) return h.uploadUpdateInfo(cvesForUpdateInfo) -- Gitee From 7f43caf7e616ad6acf1907aa05aa7807a33499ac Mon Sep 17 00:00:00 2001 From: yangwei999 <348134071@qq.com> Date: Mon, 3 Jun 2024 10:33:49 +0800 Subject: [PATCH 19/29] revert old hot patch --- cve-vulner-manager/cve-ddd/adapter/hotpatch.go | 2 -- cve-vulner-manager/cve-ddd/app/hotpatch.go | 12 +++++------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/cve-vulner-manager/cve-ddd/adapter/hotpatch.go b/cve-vulner-manager/cve-ddd/adapter/hotpatch.go index c913d80..20b7805 100644 --- a/cve-vulner-manager/cve-ddd/adapter/hotpatch.go +++ b/cve-vulner-manager/cve-ddd/adapter/hotpatch.go @@ -15,7 +15,6 @@ import ( "cvevulner/cve-ddd/app" "cvevulner/cve-ddd/infrastructure/bulletinimpl" - "cvevulner/cve-ddd/infrastructure/majunimpl" "cvevulner/cve-ddd/infrastructure/obsimpl" "cvevulner/cve-ddd/infrastructure/repositoryimpl" "cvevulner/cve-ddd/infrastructure/updateinfoimpl" @@ -40,7 +39,6 @@ func NewHotPatchAdapter() *hotPatch { bulletinimpl.NewBulletinImpl(), obsimpl.Instance(), updateinfoimpl.NewUpdateInfoImpl(), - majunimpl.NewMajunImpl(), ), } } diff --git a/cve-vulner-manager/cve-ddd/app/hotpatch.go b/cve-vulner-manager/cve-ddd/app/hotpatch.go index 49680dc..ec1815f 100644 --- a/cve-vulner-manager/cve-ddd/app/hotpatch.go +++ b/cve-vulner-manager/cve-ddd/app/hotpatch.go @@ -10,7 +10,6 @@ import ( "cvevulner/cve-ddd/domain" "cvevulner/cve-ddd/domain/bulletin" - "cvevulner/cve-ddd/domain/majun" "cvevulner/cve-ddd/domain/obs" "cvevulner/cve-ddd/domain/repository" "cvevulner/cve-ddd/domain/updateinfo" @@ -32,14 +31,12 @@ func NewHotPatchService( b bulletin.Bulletin, o obs.OBS, u updateinfo.UpdateInfo, - m majun.Majun, ) *hotPatchService { return &hotPatchService{ repository: r, bulletin: b, obs: o, updateInfo: u, - maJun: m, } } @@ -48,13 +45,14 @@ type hotPatchService struct { bulletin bulletin.Bulletin obs obs.OBS updateInfo updateinfo.UpdateInfo - maJun majun.Majun } func (h *hotPatchService) GenerateBulletins(cmds []CmdToGenerateBulletins) error { - handleBranch, err := h.maJun.GetReleasedBranch() - if err != nil { - return fmt.Errorf("get release branch err: %w", err) + handleBranch := []string{ + "openEuler-20.03-LTS-SP4", + "openEuler-22.03-LTS-SP1", + "openEuler-22.03-LTS-SP3", + "openEuler-24.03-LTS", } domain.InitMaintainVersion(handleBranch) -- Gitee From 3d0ea8dba0afb35e658c9f899a37217bf0838e93 Mon Sep 17 00:00:00 2001 From: yangwei999 <348134071@qq.com> Date: Tue, 4 Jun 2024 11:19:02 +0800 Subject: [PATCH 20/29] log level --- cve-vulner-manager/conf/product_app.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cve-vulner-manager/conf/product_app.conf b/cve-vulner-manager/conf/product_app.conf index 59d6324..72944a5 100644 --- a/cve-vulner-manager/conf/product_app.conf +++ b/cve-vulner-manager/conf/product_app.conf @@ -65,7 +65,7 @@ maxconn = 3000 [log] -log_level = 5 +log_level = 6 log_dir = ./logs log_path = logs/cve.log maxlines=20000 -- Gitee From 8127256b836a8402e0d96ad00c9a5883e29299bd Mon Sep 17 00:00:00 2001 From: yangwei999 <348134071@qq.com> Date: Thu, 6 Jun 2024 11:51:24 +0800 Subject: [PATCH 21/29] fix logrus --- cve-vulner-manager/cve-ddd/controller/cve.go | 12 ++++++------ cve-vulner-manager/routers/new_router.go | 16 +++++++++++++--- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/cve-vulner-manager/cve-ddd/controller/cve.go b/cve-vulner-manager/cve-ddd/controller/cve.go index 99d9026..66f7615 100644 --- a/cve-vulner-manager/cve-ddd/controller/cve.go +++ b/cve-vulner-manager/cve-ddd/controller/cve.go @@ -23,8 +23,8 @@ func NewCveController( bl *logrus.Entry, ) *CveController { return &CveController{ - hotPatchBulletinLog: hl, - bulletinLog: bl, + HotPatchBulletinLog: hl, + BulletinLog: bl, ColdPatchService: c, BulletinService: b, HotPatchService: h, @@ -34,8 +34,8 @@ func NewCveController( type CveController struct { BaseController - hotPatchBulletinLog *logrus.Entry - bulletinLog *logrus.Entry + HotPatchBulletinLog *logrus.Entry + BulletinLog *logrus.Entry ColdPatchService app.ColdPatchService BulletinService app.BulletinService HotPatchService app.RefactorHotPatchService @@ -91,12 +91,12 @@ func (c *CveController) Generate() { mr := utils.NewMultiErrors() uploadDir, err := c.BulletinService.GenerateBulletins(request.CveNum, request.Date) if err != nil { - c.bulletinLog.Errorf("generate security bulletins failed: %s", err.Error()) + c.BulletinLog.Errorf("generate security bulletins failed: %s", err.Error()) mr.AddError(err) } else { err = c.HotPatchService.GenerateBulletins(uploadDir) if err != nil { - c.hotPatchBulletinLog.Errorf("generate hot patch security bulletins failed: %s", err.Error()) + c.HotPatchBulletinLog.Errorf("generate hot patch security bulletins failed: %s", err.Error()) mr.AddError(err) } } diff --git a/cve-vulner-manager/routers/new_router.go b/cve-vulner-manager/routers/new_router.go index 20d7d3d..eeda1ab 100644 --- a/cve-vulner-manager/routers/new_router.go +++ b/cve-vulner-manager/routers/new_router.go @@ -1,7 +1,10 @@ package routers import ( + "os" + "github.com/astaxie/beego" + "github.com/astaxie/beego/logs" "github.com/sirupsen/logrus" "cvevulner/cve-ddd/app" @@ -24,9 +27,16 @@ func Init() { } func InitNewRouter() { - logBulletin := logrus.New().WithField("module", "new-security-bulletin") - logHotPatchBulletin := logrus.New().WithField("module", "new-hot-patch-security-bulletin") - logColdPatchCveCollect := logrus.New().WithField("module", "new-cold-patch-cve-collect") + file, err := os.OpenFile("./logrus.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) + if err == nil { + logrus.SetOutput(file) + } else { + logs.Error("create log file for logrus failed: %s", err.Error()) + } + + logBulletin := logrus.WithField("module", "new-security-bulletin") + logHotPatchBulletin := logrus.WithField("module", "new-hot-patch-security-bulletin") + logColdPatchCveCollect := logrus.WithField("module", "new-cold-patch-cve-collect") coldPatchService := app.NewColdPatchService( latestrpmimpl.NewLatestRpm(), -- Gitee From 415563c585653fbb5e919bebb99ad53194723467 Mon Sep 17 00:00:00 2001 From: yangwei999 <348134071@qq.com> Date: Thu, 6 Jun 2024 12:33:30 +0800 Subject: [PATCH 22/29] return success --- cve-vulner-manager/cve-ddd/controller/cve.go | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/cve-vulner-manager/cve-ddd/controller/cve.go b/cve-vulner-manager/cve-ddd/controller/cve.go index 66f7615..3fcc57a 100644 --- a/cve-vulner-manager/cve-ddd/controller/cve.go +++ b/cve-vulner-manager/cve-ddd/controller/cve.go @@ -5,7 +5,6 @@ import ( "sync/atomic" "github.com/astaxie/beego/validation" - "github.com/opensourceways/server-common-lib/utils" "github.com/sirupsen/logrus" "cvevulner/cve-ddd/app" @@ -88,22 +87,15 @@ func (c *CveController) Generate() { return } - mr := utils.NewMultiErrors() uploadDir, err := c.BulletinService.GenerateBulletins(request.CveNum, request.Date) if err != nil { c.BulletinLog.Errorf("generate security bulletins failed: %s", err.Error()) - mr.AddError(err) } else { err = c.HotPatchService.GenerateBulletins(uploadDir) if err != nil { c.HotPatchBulletinLog.Errorf("generate hot patch security bulletins failed: %s", err.Error()) - mr.AddError(err) } } - if mr.Err() != nil { - c.fail(mr.Err().Error()) - } else { - c.success(nil) - } + c.success(nil) } -- Gitee From 43b1d4c23cbcd6f33babec545207941f7fb47cab Mon Sep 17 00:00:00 2001 From: yangwei999 <348134071@qq.com> Date: Fri, 7 Jun 2024 16:09:30 +0800 Subject: [PATCH 23/29] fix bulletin --- cve-vulner-manager/cve-ddd/app/bulletin.go | 57 +++++++++++++++++++ .../infrastructure/bulletinimpl/impl.go | 24 ++++++-- 2 files changed, 75 insertions(+), 6 deletions(-) diff --git a/cve-vulner-manager/cve-ddd/app/bulletin.go b/cve-vulner-manager/cve-ddd/app/bulletin.go index 6e457cf..d1f9bf2 100644 --- a/cve-vulner-manager/cve-ddd/app/bulletin.go +++ b/cve-vulner-manager/cve-ddd/app/bulletin.go @@ -1,12 +1,17 @@ package app import ( + "encoding/json" "fmt" + "net/http" "strings" "time" "github.com/astaxie/beego" + sdk "github.com/opensourceways/go-gitee/gitee" + "github.com/opensourceways/server-common-lib/utils" "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/util/sets" "cvevulner/cve-ddd/domain" "cvevulner/cve-ddd/domain/bulletin" @@ -42,6 +47,7 @@ func NewBulletinService( bulletin: b, testResult: t, log: l, + giteeToken: beego.AppConfig.String("gitee::git_token"), } } @@ -51,6 +57,7 @@ type bulletinService struct { maJun majun.Majun bulletin bulletin.Bulletin testResult testresult.Result + giteeToken string log *logrus.Entry } @@ -72,6 +79,9 @@ func (b *bulletinService) GenerateBulletins(cveNum []string, date string) (strin return "", fmt.Errorf("no cves") } + // 用关联pr并且合入的分支进行过滤 + cves = b.filterByRelatedPR(cves, handleBranch) + b.testResult.Init(handleBranch, date) // 用成功转测的数据进行过滤,只发布转测成功的cve @@ -150,3 +160,50 @@ func (b *bulletinService) getIndexContent() (string, error) { return string(content), err } + +func (b *bulletinService) filterByRelatedPR(cves domain.Cves, handleBranch []string) domain.Cves { + handleBranchSet := sets.NewString(handleBranch...) + + var filteredCves domain.Cves + for _, v := range cves { + prs, _, err := b.getRelatedPR(v.ColdIssue) + if err != nil { + b.log.Errorf("get related pr of %s err: %s", v.ColdIssue.Number, err.Error()) + continue + } + + relatedPrSets := sets.NewString() + for _, pr := range prs { + if pr.State == "merged" { + relatedPrSets.Insert(pr.Base.Ref) + } + } + + intersection := handleBranchSet.Intersection(relatedPrSets) + v.AffectedVersion = intersection.UnsortedList() + + filteredCves = append(filteredCves, v) + } + + return filteredCves +} + +func (b *bulletinService) getRelatedPR(issue domain.Issue) (prs []sdk.PullRequest, code int, err error) { + endpoint := fmt.Sprintf("https://gitee.com/api/v5/repos/%v/issues/%v/pull_requests?access_token=%s&repo=%s", + defaultOwner, issue.Number, b.giteeToken, issue.Repo, + ) + req, err := http.NewRequest(http.MethodGet, endpoint, nil) + if err != nil { + return + } + + cli := utils.NewHttpClient(3) + bytes, code, err := cli.Download(req) + if err != nil { + return + } + + err = json.Unmarshal(bytes, &prs) + + return +} diff --git a/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/impl.go b/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/impl.go index 905b510..c754ff2 100644 --- a/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/impl.go +++ b/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/impl.go @@ -59,7 +59,7 @@ func (impl bulletinImpl) GenerateColdPatch(sb *domain.SecurityBulletin) ([]byte, XmlnsCvrf: impl.cfg.XmlnsCvrf, DocumentTitle: impl.documentTitle(sb), DocumentType: impl.cfg.DocumentType, - DocumentPublisher: impl.documentPublisher(), + DocumentPublisher: impl.documentPublisher(sb), DocumentTracking: impl.documentTracking(sb), DocumentNotes: impl.documentNotes(sb), DocumentReferences: impl.documentReferences(sb), @@ -81,7 +81,7 @@ func (impl bulletinImpl) GenerateHotPatch(sb *domain.SecurityBulletin) ([]byte, XmlnsCvrf: impl.cfg.XmlnsCvrf, DocumentTitle: impl.documentTitle(sb), DocumentType: impl.cfg.DocumentType, - DocumentPublisher: impl.documentPublisher(), + DocumentPublisher: impl.documentPublisher(sb), DocumentTracking: impl.documentTracking(sb), DocumentNotes: impl.documentNotes(sb), DocumentReferences: impl.documentReferences(sb), @@ -110,11 +110,19 @@ func (impl bulletinImpl) documentTitle(sb *domain.SecurityBulletin) DocumentTitl } } -func (impl bulletinImpl) documentPublisher() DocumentPublisher { +func (impl bulletinImpl) documentPublisher(sb *domain.SecurityBulletin) DocumentPublisher { + details := impl.cfg.ContactDetails + authority := impl.cfg.IssuingAuthority + + if sb.IsColdPatch() { + details = "openeuler-security@openeuler.org" + authority = "openEuler security committee" + } + return DocumentPublisher{ Type: "Vendor", - ContactDetails: impl.cfg.ContactDetails, - IssuingAuthority: impl.cfg.IssuingAuthority, + ContactDetails: details, + IssuingAuthority: authority, } } @@ -379,11 +387,15 @@ func (impl bulletinImpl) HotPatchTree(sb *domain.SecurityBulletin) *HotPatchTree func (impl bulletinImpl) vulnerability(sb *domain.SecurityBulletin) []Vulnerability { var vs []Vulnerability + xmlns := impl.cfg.Xmlns + if sb.IsColdPatch() { + xmlns = "http://www.icasi.org/CVRF/schema/vuln/1.1" + } for k, cve := range sb.Cves { vul := Vulnerability{ Ordinal: strconv.Itoa(k + 1), - Xmlns: impl.cfg.Xmlns, + Xmlns: xmlns, CveNotes: CveNotes{ CveNote: CveNote{ Title: "Vulnerability Description", -- Gitee From 4592e8a778850b08f91ebf183480766f38a028b1 Mon Sep 17 00:00:00 2001 From: yangwei999 <348134071@qq.com> Date: Fri, 7 Jun 2024 17:22:08 +0800 Subject: [PATCH 24/29] fix and optimize bulletin --- .../cve-ddd/infrastructure/bulletinimpl/config.go | 2 +- .../cve-ddd/infrastructure/bulletinimpl/impl.go | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/config.go b/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/config.go index a096288..0c8be6f 100644 --- a/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/config.go +++ b/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/config.go @@ -1,8 +1,8 @@ package bulletinimpl type Config struct { - Xmlns string XmlnsCvrf string + XmlnsProd string DocumentType string ContactDetails string IssuingAuthority string diff --git a/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/impl.go b/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/impl.go index c754ff2..e25eae6 100644 --- a/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/impl.go +++ b/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/impl.go @@ -35,8 +35,8 @@ var archs = map[string]bool{ func NewBulletinImpl() bulletinImpl { cfg := Config{ - Xmlns: "http://www.icasi.org/CVRF/schema/cvrf/1.1", XmlnsCvrf: "http://www.icasi.org/CVRF/schema/cvrf/1.1", + XmlnsProd: "http://www.icasi.org/CVRF/schema/prod/1.1", DocumentType: "Security Advisory", ContactDetails: "openeuler-release@openeuler.org", IssuingAuthority: "openEuler release SIG", @@ -55,7 +55,7 @@ type bulletinImpl struct { func (impl bulletinImpl) GenerateColdPatch(sb *domain.SecurityBulletin) ([]byte, error) { data := Cvrf{ - Xmlns: impl.cfg.Xmlns, + Xmlns: impl.cfg.XmlnsCvrf, XmlnsCvrf: impl.cfg.XmlnsCvrf, DocumentTitle: impl.documentTitle(sb), DocumentType: impl.cfg.DocumentType, @@ -77,7 +77,7 @@ func (impl bulletinImpl) GenerateColdPatch(sb *domain.SecurityBulletin) ([]byte, func (impl bulletinImpl) GenerateHotPatch(sb *domain.SecurityBulletin) ([]byte, error) { data := Cvrf{ - Xmlns: impl.cfg.Xmlns, + Xmlns: impl.cfg.XmlnsCvrf, XmlnsCvrf: impl.cfg.XmlnsCvrf, DocumentTitle: impl.documentTitle(sb), DocumentType: impl.cfg.DocumentType, @@ -319,7 +319,7 @@ func (impl bulletinImpl) ProductTree(sb *domain.SecurityBulletin) *ProductTree { } return &ProductTree{ - Xmlns: impl.cfg.Xmlns, + Xmlns: impl.cfg.XmlnsProd, OpenEulerBranch: branches, } } @@ -380,14 +380,14 @@ func (impl bulletinImpl) HotPatchTree(sb *domain.SecurityBulletin) *HotPatchTree } return &HotPatchTree{ - Xmlns: "http://www.icasi.org/CVRF/schema/prod/1.1", + Xmlns: impl.cfg.XmlnsProd, Branch: branch, } } func (impl bulletinImpl) vulnerability(sb *domain.SecurityBulletin) []Vulnerability { var vs []Vulnerability - xmlns := impl.cfg.Xmlns + xmlns := impl.cfg.XmlnsCvrf if sb.IsColdPatch() { xmlns = "http://www.icasi.org/CVRF/schema/vuln/1.1" } -- Gitee From d65afe4353786d003e55fccf7363db5115e9a2ff Mon Sep 17 00:00:00 2001 From: yangwei999 <348134071@qq.com> Date: Tue, 11 Jun 2024 09:39:31 +0800 Subject: [PATCH 25/29] remove 2203-lts-next --- cve-vulner-manager/conf/product_app.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cve-vulner-manager/conf/product_app.conf b/cve-vulner-manager/conf/product_app.conf index 72944a5..424f88a 100644 --- a/cve-vulner-manager/conf/product_app.conf +++ b/cve-vulner-manager/conf/product_app.conf @@ -179,7 +179,7 @@ cve_number_t = 2018 # Create an issue's repo whitelist;1: open; 2: close issue_whitelist = 2 # List of affected branches: openEuler-20.03-LTS,openEuler-20.03-LTS-SP1 -affected_branchs = "openEuler-20.03-LTS-SP4,openEuler-22.03-LTS-SP1,openEuler-22.03-LTS-SP3,openEuler-22.03-LTS-SP4,master,openEuler-22.03-LTS-Next,openEuler-24.03-LTS,openEuler-24.03-LTS-Next" +affected_branchs = "openEuler-20.03-LTS-SP4,openEuler-22.03-LTS-SP1,openEuler-22.03-LTS-SP3,openEuler-22.03-LTS-SP4,master,openEuler-24.03-LTS,openEuler-24.03-LTS-Next" abandoned_branchs = "openEuler-20.03-LTS,openEuler-21.03,openEuler-21.09,openEuler-20.09" # Close the highest privilege of issue:1:open;2:close close_issue_privilege = 2 -- Gitee From 3f18f53dab8a1635eb38fa3da3da67cd84579ea7 Mon Sep 17 00:00:00 2001 From: yangwei999 <348134071@qq.com> Date: Thu, 13 Jun 2024 09:15:21 +0800 Subject: [PATCH 26/29] update conf --- cve-vulner-manager/conf/product_app.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cve-vulner-manager/conf/product_app.conf b/cve-vulner-manager/conf/product_app.conf index 424f88a..c360666 100644 --- a/cve-vulner-manager/conf/product_app.conf +++ b/cve-vulner-manager/conf/product_app.conf @@ -224,8 +224,8 @@ snsuffix = 1002 # example: openEuler-20.03-LTS@http://119.3.219.20:88/mkb/obs_update_info/openEuler-20.03-LTS.csv; # openEuler-20.03-LTS-SP1@http://119.3.219.20:88/mkb/obs_update_info/openEuler-20.03-LTS-SP1.csv # public sa format: openEuler-20.03-LTS@https;openEuler-20.03-LTS-SP1@https -v_pack_20_03_url = "openEuler-20.03-LTS-SP4@https;openEuler-22.03-LTS-SP1@https;openEuler-22.03-LTS-SP3@https" -release_date_of_version = "openEuler-22.03-LTS-SP2:2023-06-30;openEuler-20.03-LTS-SP4:2023-12-12;openEuler-22.03-LTS-SP3:2024-01-01" +v_pack_20_03_url = "openEuler-20.03-LTS-SP4@https;openEuler-22.03-LTS-SP1@https;openEuler-22.03-LTS-SP3@https;openEuler-24.03-LTS@https" +release_date_of_version = "openEuler-20.03-LTS-SP4:2023-12-12;openEuler-22.03-LTS-SP3:2024-01-01;openEuler-24.03-LTS:2024-05-30" # Time difference in different time zones sa_timestamp_zone = 28810 unaffect_year = 2018 -- Gitee From 642a32a6ef426fb7bc26514852aafa364e6b5cbe Mon Sep 17 00:00:00 2001 From: yangwei999 <348134071@qq.com> Date: Thu, 13 Jun 2024 09:22:21 +0800 Subject: [PATCH 27/29] update log level --- cve-vulner-manager/conf/product_app.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cve-vulner-manager/conf/product_app.conf b/cve-vulner-manager/conf/product_app.conf index c360666..3f6af35 100644 --- a/cve-vulner-manager/conf/product_app.conf +++ b/cve-vulner-manager/conf/product_app.conf @@ -65,7 +65,7 @@ maxconn = 3000 [log] -log_level = 6 +log_level = 5 log_dir = ./logs log_path = logs/cve.log maxlines=20000 -- Gitee From 2ca472938bab7ec8cb6ec77434604d3e1ceafee6 Mon Sep 17 00:00:00 2001 From: yangwei999 <348134071@qq.com> Date: Fri, 14 Jun 2024 16:39:55 +0800 Subject: [PATCH 28/29] fix pr not in src-openeuler --- cve-vulner-manager/cve-ddd/app/bulletin.go | 4 ++++ cve-vulner-manager/cve-ddd/app/coldpatch.go | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/cve-vulner-manager/cve-ddd/app/bulletin.go b/cve-vulner-manager/cve-ddd/app/bulletin.go index d1f9bf2..5eb0ab3 100644 --- a/cve-vulner-manager/cve-ddd/app/bulletin.go +++ b/cve-vulner-manager/cve-ddd/app/bulletin.go @@ -174,6 +174,10 @@ func (b *bulletinService) filterByRelatedPR(cves domain.Cves, handleBranch []str relatedPrSets := sets.NewString() for _, pr := range prs { + if pr.Base.Repo.Namespace.Path != defaultOwner { + continue + } + if pr.State == "merged" { relatedPrSets.Insert(pr.Base.Ref) } diff --git a/cve-vulner-manager/cve-ddd/app/coldpatch.go b/cve-vulner-manager/cve-ddd/app/coldpatch.go index 3cfe8c9..d6a30d5 100644 --- a/cve-vulner-manager/cve-ddd/app/coldpatch.go +++ b/cve-vulner-manager/cve-ddd/app/coldpatch.go @@ -250,6 +250,10 @@ func (c *coldPatchService) filterData( needToHandleBranch := make(sets.Set[string]) for _, pr := range prs { + if pr.Base.Repo.Namespace.Path != defaultOwner { + continue + } + if pr.State != mergedState { continue } -- Gitee From 5b6fb2e21e437ef26050803098e1c8c837538ee3 Mon Sep 17 00:00:00 2001 From: yangwei999 <348134071@qq.com> Date: Mon, 17 Jun 2024 11:17:40 +0800 Subject: [PATCH 29/29] fix xml bug for & --- cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/impl.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/impl.go b/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/impl.go index e25eae6..88c2a30 100644 --- a/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/impl.go +++ b/cve-vulner-manager/cve-ddd/infrastructure/bulletinimpl/impl.go @@ -248,7 +248,7 @@ func (impl bulletinImpl) documentReferences(sb *domain.SecurityBulletin) Documen var cveUrl, other []CveUrl for _, cve := range sb.Cves { - url := impl.cfg.SecurityCveUrlPrefix + fmt.Sprintf("cveId=%s&packageName=%s", cve.CveNum, sb.Component) + url := impl.cfg.SecurityCveUrlPrefix + fmt.Sprintf("cveId=%s&packageName=%s", cve.CveNum, sb.Component) cveUrl = append(cveUrl, CveUrl{Url: url}) otherUrl := "https://nvd.nist.gov/vuln/detail/" + cve.CveNum -- Gitee