mirror of
https://github.com/safedep/vet.git
synced 2025-12-10 13:43:01 -06:00
Merge pull request #244 from safedep/feat/cloud-report-sync-v2
feat: Add SafeDep Cloud Integration as Optional Commands
This commit is contained in:
commit
aa501a76c0
12
Makefile
12
Makefile
@ -2,7 +2,7 @@ SHELL := /bin/bash
|
|||||||
GITCOMMIT := $(shell git rev-parse HEAD)
|
GITCOMMIT := $(shell git rev-parse HEAD)
|
||||||
VERSION := "$(shell git describe --tags --abbrev=0)-$(shell git rev-parse --short HEAD)"
|
VERSION := "$(shell git describe --tags --abbrev=0)-$(shell git rev-parse --short HEAD)"
|
||||||
|
|
||||||
all: clean setup vet
|
all: quick-vet
|
||||||
|
|
||||||
linter-install:
|
linter-install:
|
||||||
go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.55.0
|
go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.55.0
|
||||||
@ -18,12 +18,6 @@ dev-setup: linter-install oapi-codegen-install protoc-install
|
|||||||
oapi-codegen:
|
oapi-codegen:
|
||||||
oapi-codegen -package insightapi -generate types ./api/insights-v1.yml > ./gen/insightapi/insights.types.go
|
oapi-codegen -package insightapi -generate types ./api/insights-v1.yml > ./gen/insightapi/insights.types.go
|
||||||
oapi-codegen -package insightapi -generate client ./api/insights-v1.yml > ./gen/insightapi/insights.client.go
|
oapi-codegen -package insightapi -generate client ./api/insights-v1.yml > ./gen/insightapi/insights.client.go
|
||||||
oapi-codegen -package cpv1trials -generate types ./api/cp-v1-trials.yml > ./gen/cpv1trials/trials.types.go
|
|
||||||
oapi-codegen -package cpv1trials -generate client ./api/cp-v1-trials.yml > ./gen/cpv1trials/trials.client.go
|
|
||||||
oapi-codegen -package cpv1 -generate types ./api/cp-v1.yml > ./gen/cpv1/cp.types.go
|
|
||||||
oapi-codegen -package cpv1 -generate client ./api/cp-v1.yml > ./gen/cpv1/cp.client.go
|
|
||||||
oapi-codegen -package syncv1 -generate types ./api/sync-v1.yml > ./gen/syncv1/sync.types.go
|
|
||||||
oapi-codegen -package syncv1 -generate client ./api/sync-v1.yml > ./gen/syncv1/sync.client.go
|
|
||||||
|
|
||||||
protoc-codegen:
|
protoc-codegen:
|
||||||
protoc -I ./api \
|
protoc -I ./api \
|
||||||
@ -76,10 +70,10 @@ setup:
|
|||||||
GO_CFLAGS=-X main.commit=$(GITCOMMIT) -X main.version=$(VERSION)
|
GO_CFLAGS=-X main.commit=$(GITCOMMIT) -X main.version=$(VERSION)
|
||||||
GO_LDFLAGS=-ldflags "-w $(GO_CFLAGS)"
|
GO_LDFLAGS=-ldflags "-w $(GO_CFLAGS)"
|
||||||
|
|
||||||
vet: oapi-codegen protoc-codegen
|
quick-vet:
|
||||||
go build ${GO_LDFLAGS}
|
go build ${GO_LDFLAGS}
|
||||||
|
|
||||||
quick-vet:
|
vet: oapi-codegen protoc-codegen
|
||||||
go build ${GO_LDFLAGS}
|
go build ${GO_LDFLAGS}
|
||||||
|
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
|
|||||||
16
README.md
16
README.md
@ -1,8 +1,9 @@
|
|||||||
<h1 align="center">
|
<h1 align="center">
|
||||||
<img alt="SafeDep Vet" src="docs/static/img/vet-logo.png" width="150" />
|
<img alt="SafeDep Vet" src="docs/static/img/vet-logo.png" width="150" />
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
🙌 Refer to <b><a href="https://safedep.io/docs/">https://safedep.io/docs</a></b> for the documentation 📖
|
Created and maintained by <b><a href="https://safedep.io/">https://safedep.io</a></b> with contributions from the community 🚀
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
[](https://goreportcard.com/report/github.com/safedep/vet)
|
[](https://goreportcard.com/report/github.com/safedep/vet)
|
||||||
@ -16,13 +17,13 @@
|
|||||||
|
|
||||||
[](https://safedep.io/docs)
|
[](https://safedep.io/docs)
|
||||||
|
|
||||||
## Automate Open Source Package Vetting in CI/CD
|
## Policy as Code for Open Source Software Supply Chain
|
||||||
|
|
||||||
`vet` is a tool for identifying risks in open source software supply chain. It
|
`vet` is a tool for identifying risks in open source software supply chain. It
|
||||||
goes beyond just vulnerabilities and provides visibility on OSS package risks
|
goes beyond just vulnerabilities and provides visibility on OSS package risks
|
||||||
due to it's license, popularity, security hygiene, and more. `vet` is designed
|
due to it's license, popularity, security hygiene, and more. `vet` is designed
|
||||||
with the goal of enabling trusted OSS package consumption by integrating with
|
with the goal of helping software development teams consume safe and trusted
|
||||||
CI/CD and `policy as code` as guardrails.
|
OSS components through automated vetting in CI/CD.
|
||||||
|
|
||||||
* [🔥 vet in action](#-vet-in-action)
|
* [🔥 vet in action](#-vet-in-action)
|
||||||
* [Getting Started](#getting-started)
|
* [Getting Started](#getting-started)
|
||||||
@ -43,6 +44,7 @@ CI/CD and `policy as code` as guardrails.
|
|||||||
* [📖 Documentation](#-documentation)
|
* [📖 Documentation](#-documentation)
|
||||||
* [🎊 Community](#-community)
|
* [🎊 Community](#-community)
|
||||||
* [💻 Development](#-development)
|
* [💻 Development](#-development)
|
||||||
|
* [Support](#support)
|
||||||
* [Star History](#star-history)
|
* [Star History](#star-history)
|
||||||
* [🔖 References](#-references)
|
* [🔖 References](#-references)
|
||||||
|
|
||||||
@ -281,6 +283,12 @@ First of all, thank you so much for showing interest in `vet`, we appreciate it
|
|||||||
|
|
||||||
Refer to [CONTRIBUTING.md](CONTRIBUTING.md)
|
Refer to [CONTRIBUTING.md](CONTRIBUTING.md)
|
||||||
|
|
||||||
|
## Support
|
||||||
|
|
||||||
|
[SafeDep](https://safedep.io) provides enterprise support for `vet`
|
||||||
|
deployments. Check out [SafeDep Cloud](https://safedep.io) for large scale
|
||||||
|
deployment and management of `vet` in your organization.
|
||||||
|
|
||||||
## Star History
|
## Star History
|
||||||
|
|
||||||
[](https://star-history.com/#safedep/vet&Date)
|
[](https://star-history.com/#safedep/vet&Date)
|
||||||
|
|||||||
@ -1,123 +0,0 @@
|
|||||||
openapi: 3.0.2
|
|
||||||
info:
|
|
||||||
title: SafeDep Control Plane API for Trials Registration
|
|
||||||
contact:
|
|
||||||
name: SafeDep API
|
|
||||||
url: 'https://safedep.io'
|
|
||||||
description: |
|
|
||||||
Trials API provide a way for obtaining an API Key for data plane service access
|
|
||||||
using an Email Address. Trials is different from Registrations as the later
|
|
||||||
allows full access to the control plane while Trials is meant to allow access
|
|
||||||
only to a time bounded (expirable) API key for quick evaluation of tools.
|
|
||||||
version: 0.0.1
|
|
||||||
servers:
|
|
||||||
- url: 'https://{apiHost}/{apiBase}'
|
|
||||||
variables:
|
|
||||||
apiHost:
|
|
||||||
default: api.safedep.io
|
|
||||||
apiBase:
|
|
||||||
default: control-plane/v1
|
|
||||||
tags:
|
|
||||||
- name: Control Plane
|
|
||||||
description: Control Plane API
|
|
||||||
paths:
|
|
||||||
/trials:
|
|
||||||
post:
|
|
||||||
description: |
|
|
||||||
Register a trial user to obtain an expirable API Key. The API key will
|
|
||||||
be generated and sent to the user over Email to ensure validity and access
|
|
||||||
to the email by the requester. System defined limits will be applied to
|
|
||||||
maximum number of trial API keys that can be generated for an email.
|
|
||||||
operationId: registerTrialUser
|
|
||||||
tags:
|
|
||||||
- Control Plane
|
|
||||||
requestBody:
|
|
||||||
description: Trial registration request
|
|
||||||
required: true
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/TrialRequest'
|
|
||||||
responses:
|
|
||||||
'201':
|
|
||||||
description: Successfully created an API key request
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/TrialResponse'
|
|
||||||
'403':
|
|
||||||
description: Access to the API is denied
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ApiError'
|
|
||||||
'429':
|
|
||||||
description: Rate limit block
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ApiError'
|
|
||||||
'500':
|
|
||||||
description: Failed due to internal server error
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ApiError'
|
|
||||||
components:
|
|
||||||
schemas:
|
|
||||||
ApiError:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
message:
|
|
||||||
type: string
|
|
||||||
description: A descriptive message about the error meant for developer consumption
|
|
||||||
type:
|
|
||||||
type: string
|
|
||||||
description: An optional service or domain specific error group
|
|
||||||
enum:
|
|
||||||
- invalid_request
|
|
||||||
- operation_failed
|
|
||||||
- internal_error
|
|
||||||
code:
|
|
||||||
type: string
|
|
||||||
description: An error code identifying the error
|
|
||||||
enum:
|
|
||||||
- api_guard_invalid_credentials
|
|
||||||
- api_guard_rate_limit_exceeded
|
|
||||||
- api_guard_unauthorized
|
|
||||||
- api_guard_error
|
|
||||||
- app_generic_error
|
|
||||||
- app_security_error
|
|
||||||
- app_insufficient_parameters
|
|
||||||
- app_feature_not_enabled
|
|
||||||
- app_package_version_not_found
|
|
||||||
params:
|
|
||||||
type: object
|
|
||||||
description: Optional error specific attributes
|
|
||||||
additionalProperties:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
key:
|
|
||||||
type: string
|
|
||||||
value:
|
|
||||||
type: string
|
|
||||||
TrialRequest:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
email:
|
|
||||||
type: string
|
|
||||||
format: email
|
|
||||||
required:
|
|
||||||
- email
|
|
||||||
TrialResponse:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
id:
|
|
||||||
type: string
|
|
||||||
minLength: 6
|
|
||||||
maxLength: 512
|
|
||||||
description: The ID of the trial registration request created in the system
|
|
||||||
expires_at:
|
|
||||||
type: string
|
|
||||||
format: date-time
|
|
||||||
description: The expiry time of the API key
|
|
||||||
113
api/cp-v1.yml
113
api/cp-v1.yml
@ -1,113 +0,0 @@
|
|||||||
openapi: 3.0.2
|
|
||||||
info:
|
|
||||||
title: SafeDep Control Plane API
|
|
||||||
contact:
|
|
||||||
name: SafeDep API
|
|
||||||
url: 'https://safedep.io'
|
|
||||||
description: |
|
|
||||||
The SafeDep Control Plane API provides configuration and management plane
|
|
||||||
access to clients for the SafeDep platform
|
|
||||||
version: 0.0.1
|
|
||||||
servers:
|
|
||||||
- url: 'https://{apiHost}/{apiBase}'
|
|
||||||
variables:
|
|
||||||
apiHost:
|
|
||||||
default: api.safedep.io
|
|
||||||
apiBase:
|
|
||||||
default: control-plane/v1
|
|
||||||
tags:
|
|
||||||
- name: Control Plane
|
|
||||||
description: Control Plane API
|
|
||||||
paths:
|
|
||||||
/auths/me:
|
|
||||||
get:
|
|
||||||
description: |
|
|
||||||
Introspection API for getting configuration information associated
|
|
||||||
with the supplied API credentials
|
|
||||||
operationId: getApiCredentialIntrospection
|
|
||||||
tags:
|
|
||||||
- Control Plane
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: API credentials introspection information
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/CredentialIntrospectionResponse'
|
|
||||||
'403':
|
|
||||||
description: Access to the API is denied
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ApiError'
|
|
||||||
'429':
|
|
||||||
description: Rate limit block
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ApiError'
|
|
||||||
'500':
|
|
||||||
description: Failed due to internal server error
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ApiError'
|
|
||||||
components:
|
|
||||||
securitySchemes:
|
|
||||||
api_key:
|
|
||||||
type: apiKey
|
|
||||||
name: Authorization
|
|
||||||
in: header
|
|
||||||
schemas:
|
|
||||||
ApiError:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
message:
|
|
||||||
type: string
|
|
||||||
description: A descriptive message about the error meant for developer consumption
|
|
||||||
type:
|
|
||||||
type: string
|
|
||||||
description: An optional service or domain specific error group
|
|
||||||
enum:
|
|
||||||
- invalid_request
|
|
||||||
- operation_failed
|
|
||||||
- internal_error
|
|
||||||
code:
|
|
||||||
type: string
|
|
||||||
description: An error code identifying the error
|
|
||||||
enum:
|
|
||||||
- api_guard_invalid_credentials
|
|
||||||
- api_guard_rate_limit_exceeded
|
|
||||||
- api_guard_unauthorized
|
|
||||||
- api_guard_error
|
|
||||||
- app_generic_error
|
|
||||||
- app_security_error
|
|
||||||
- app_insufficient_parameters
|
|
||||||
- app_feature_not_enabled
|
|
||||||
- app_package_version_not_found
|
|
||||||
params:
|
|
||||||
type: object
|
|
||||||
description: Optional error specific attributes
|
|
||||||
additionalProperties:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
key:
|
|
||||||
type: string
|
|
||||||
value:
|
|
||||||
type: string
|
|
||||||
CredentialIntrospectionResponse:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
type:
|
|
||||||
type: string
|
|
||||||
description: The entity type to which this credential belongs to
|
|
||||||
enum:
|
|
||||||
- TrialUser
|
|
||||||
- Organization
|
|
||||||
- Team
|
|
||||||
- User
|
|
||||||
expiry:
|
|
||||||
type: string
|
|
||||||
description: Expiry timestamp in RFC3399 format if expirable
|
|
||||||
required:
|
|
||||||
- type
|
|
||||||
1015
api/sync-v1.yml
1015
api/sync-v1.yml
File diff suppressed because it is too large
Load Diff
96
auth.go
96
auth.go
@ -2,7 +2,6 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/AlecAivazis/survey/v2"
|
"github.com/AlecAivazis/survey/v2"
|
||||||
@ -14,27 +13,20 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
authInsightApiBaseUrl string
|
authTenantDomain string
|
||||||
authControlPlaneApiBaseUrl string
|
|
||||||
authTrialEmail string
|
|
||||||
authCommunity bool
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func newAuthCommand() *cobra.Command {
|
func newAuthCommand() *cobra.Command {
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "auth",
|
Use: "auth",
|
||||||
Short: "Configure and verify Insights API authentication",
|
Short: "Configure vet authentication",
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
return errors.New("a valid sub-command is required")
|
return errors.New("a valid sub-command is required")
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.PersistentFlags().StringVarP(&authControlPlaneApiBaseUrl, "control-plane", "",
|
|
||||||
auth.DefaultControlPlaneApiUrl(), "Base URL of Control Plane API")
|
|
||||||
|
|
||||||
cmd.AddCommand(configureAuthCommand())
|
cmd.AddCommand(configureAuthCommand())
|
||||||
cmd.AddCommand(verifyAuthCommand())
|
cmd.AddCommand(verifyAuthCommand())
|
||||||
cmd.AddCommand(trialsRegisterCommand())
|
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
@ -46,25 +38,40 @@ func configureAuthCommand() *cobra.Command {
|
|||||||
var key string
|
var key string
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
if !authCommunity {
|
err = survey.AskOne(&survey.Password{
|
||||||
err = survey.AskOne(&survey.Password{
|
Message: "Enter the API key",
|
||||||
Message: "Enter the API key",
|
}, &key)
|
||||||
}, &key)
|
|
||||||
} else {
|
|
||||||
authInsightApiBaseUrl = auth.DefaultCommunityApiUrl()
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Fatalf("Failed to setup auth: %v", err)
|
logger.Fatalf("Failed to setup auth: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = auth.Configure(auth.Config{
|
if auth.TenantDomain() != "" && auth.TenantDomain() != authTenantDomain {
|
||||||
ApiUrl: authInsightApiBaseUrl,
|
ui.PrintWarning("Tenant domain mismatch. Existing: %s, New: %s, continue? ",
|
||||||
ApiKey: string(key),
|
auth.TenantDomain(), authTenantDomain)
|
||||||
ControlPlaneApiUrl: authControlPlaneApiBaseUrl,
|
|
||||||
Community: authCommunity,
|
|
||||||
})
|
|
||||||
|
|
||||||
|
var confirm bool
|
||||||
|
err = survey.AskOne(&survey.Confirm{
|
||||||
|
Message: "Do you want to continue?",
|
||||||
|
}, &confirm)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
logger.Fatalf("Failed to setup auth: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !confirm {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auth.SetRuntimeCloudTenant(authTenantDomain)
|
||||||
|
auth.SetRuntimeApiKey(key)
|
||||||
|
|
||||||
|
err = auth.Verify()
|
||||||
|
if err != nil {
|
||||||
|
logger.Fatalf("Failed to verify auth: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = auth.PersistApiKey(key, authTenantDomain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Fatalf("Failed to configure auth: %v", err)
|
logger.Fatalf("Failed to configure auth: %v", err)
|
||||||
}
|
}
|
||||||
@ -74,10 +81,10 @@ func configureAuthCommand() *cobra.Command {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Flags().StringVarP(&authInsightApiBaseUrl, "api", "", auth.DefaultApiUrl(),
|
cmd.Flags().StringVarP(&authTenantDomain, "tenant", "", "",
|
||||||
"Base URL of Insights API")
|
"Tenant domain for SafeDep Cloud")
|
||||||
cmd.Flags().BoolVarP(&authCommunity, "community", "", false,
|
|
||||||
"Use community API endpoint for Insights")
|
_ = cmd.MarkFlagRequired("tenant")
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
@ -90,9 +97,7 @@ func verifyAuthCommand() *cobra.Command {
|
|||||||
ui.PrintSuccess("Running in Community Mode")
|
ui.PrintSuccess("Running in Community Mode")
|
||||||
}
|
}
|
||||||
|
|
||||||
failOnError("auth/verify", auth.Verify(&auth.VerifyConfig{
|
failOnError("auth/verify", auth.Verify())
|
||||||
ControlPlaneApiUrl: authControlPlaneApiBaseUrl,
|
|
||||||
}))
|
|
||||||
|
|
||||||
ui.PrintSuccess("Authentication key is valid!")
|
ui.PrintSuccess("Authentication key is valid!")
|
||||||
return nil
|
return nil
|
||||||
@ -101,32 +106,3 @@ func verifyAuthCommand() *cobra.Command {
|
|||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func trialsRegisterCommand() *cobra.Command {
|
|
||||||
cmd := &cobra.Command{
|
|
||||||
Use: "trial",
|
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
|
||||||
client := auth.NewTrialRegistrationClient(auth.TrialConfig{
|
|
||||||
Email: authTrialEmail,
|
|
||||||
ControlPlaneApiUrl: authControlPlaneApiBaseUrl,
|
|
||||||
})
|
|
||||||
|
|
||||||
res, err := client.Execute()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Error: %v\n", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("Trial registration successful with Id:%s\n", res.Id)
|
|
||||||
fmt.Printf("Check your email (%s) for API key and usage instructions\n", authTrialEmail)
|
|
||||||
fmt.Printf("The trial API key will expire on %s\n", res.ExpiresAt.String())
|
|
||||||
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.Flags().StringVarP(&authTrialEmail, "email", "", "",
|
|
||||||
"Email address to use for sending trial API key")
|
|
||||||
|
|
||||||
return cmd
|
|
||||||
}
|
|
||||||
|
|||||||
83
cmd/cloud/key.go
Normal file
83
cmd/cloud/key.go
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
package cloud
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/safedep/vet/internal/auth"
|
||||||
|
"github.com/safedep/vet/internal/ui"
|
||||||
|
"github.com/safedep/vet/pkg/cloud"
|
||||||
|
"github.com/safedep/vet/pkg/common/logger"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
keyName string
|
||||||
|
keyDescription string
|
||||||
|
keyExpiresIn int
|
||||||
|
)
|
||||||
|
|
||||||
|
func newKeyCommand() *cobra.Command {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "key",
|
||||||
|
Short: "Manage API keys",
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
return cmd.Help()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.AddCommand(newKeyCreateCommand())
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func newKeyCreateCommand() *cobra.Command {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "create",
|
||||||
|
Short: "Create a new API key",
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
err := executeCreateKey()
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("Failed to create API key: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.Flags().StringVar(&keyName, "name", "", "Name of the API key")
|
||||||
|
cmd.Flags().StringVar(&keyDescription, "description", "", "Description of the API key")
|
||||||
|
cmd.Flags().IntVar(&keyExpiresIn, "expires-in", 30,
|
||||||
|
"Number of days after which the API key will expire")
|
||||||
|
|
||||||
|
_ = cmd.MarkFlagRequired("name")
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func executeCreateKey() error {
|
||||||
|
client, err := auth.ControlPlaneClientConnection("vet-cloud-key-create")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
keyService, err := cloud.NewApiKeyService(client)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
key, err := keyService.CreateApiKey(&cloud.CreateApiKeyRequest{
|
||||||
|
Name: keyName,
|
||||||
|
Desc: keyDescription,
|
||||||
|
ExpiryInDays: keyExpiresIn,
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
ui.PrintSuccess("API key created successfully.")
|
||||||
|
ui.PrintSuccess("Key: %s", key.Key)
|
||||||
|
ui.PrintSuccess("Expires at: %s", key.ExpiresAt.Format(time.RFC3339))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
57
cmd/cloud/login.go
Normal file
57
cmd/cloud/login.go
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
package cloud
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/cli/oauth/device"
|
||||||
|
"github.com/safedep/vet/internal/auth"
|
||||||
|
"github.com/safedep/vet/internal/ui"
|
||||||
|
"github.com/safedep/vet/pkg/common/logger"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
func newCloudLoginCommand() *cobra.Command {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "login",
|
||||||
|
Short: "Login to SafeDep cloud for management tasks",
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
err := executeDeviceAuthFlow()
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("Failed to login to the SafeDep cloud: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func executeDeviceAuthFlow() error {
|
||||||
|
code, err := device.RequestCode(http.DefaultClient,
|
||||||
|
auth.CloudIdentityServiceDeviceCodeUrl(),
|
||||||
|
auth.CloudIdentityServiceClientId(),
|
||||||
|
[]string{"offline_access", "openid", "profile", "email"},
|
||||||
|
device.WithAudience(auth.CloudIdentityServiceAudience()))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to request device code: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ui.PrintSuccess("Please visit %s and enter the code %s to authenticate",
|
||||||
|
code.VerificationURIComplete, code.UserCode)
|
||||||
|
|
||||||
|
token, err := device.Wait(context.TODO(),
|
||||||
|
http.DefaultClient, auth.CloudIdentityServiceTokenUrl(),
|
||||||
|
device.WaitOptions{
|
||||||
|
ClientID: auth.CloudIdentityServiceClientId(),
|
||||||
|
DeviceCode: code,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to authenticate: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return auth.PersistCloudTokens(token.Token,
|
||||||
|
token.RefreshToken, tenantDomain)
|
||||||
|
}
|
||||||
36
cmd/cloud/main.go
Normal file
36
cmd/cloud/main.go
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
package cloud
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/safedep/vet/internal/auth"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
var tenantDomain string
|
||||||
|
|
||||||
|
func NewCloudCommand() *cobra.Command {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "cloud",
|
||||||
|
Short: "Manage and query cloud resources (control plane)",
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
return cmd.Help()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.PersistentFlags().StringVar(&tenantDomain, "tenant", "",
|
||||||
|
"Tenant domain to use for the command")
|
||||||
|
|
||||||
|
cmd.AddCommand(newCloudLoginCommand())
|
||||||
|
cmd.AddCommand(newRegisterCommand())
|
||||||
|
cmd.AddCommand(newQueryCommand())
|
||||||
|
cmd.AddCommand(newPingCommand())
|
||||||
|
cmd.AddCommand(newWhoamiCommand())
|
||||||
|
cmd.AddCommand(newKeyCommand())
|
||||||
|
|
||||||
|
cmd.PersistentPreRun = func(cmd *cobra.Command, args []string) {
|
||||||
|
if tenantDomain != "" {
|
||||||
|
auth.SetRuntimeCloudTenant(tenantDomain)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
49
cmd/cloud/ping.go
Normal file
49
cmd/cloud/ping.go
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
package cloud
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/safedep/vet/internal/auth"
|
||||||
|
"github.com/safedep/vet/internal/ui"
|
||||||
|
"github.com/safedep/vet/pkg/cloud"
|
||||||
|
"github.com/safedep/vet/pkg/common/logger"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
func newPingCommand() *cobra.Command {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "ping",
|
||||||
|
Short: "Ping the control plane to check authentication and connectivity",
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
err := pingControlPlane()
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("Failed to ping control plane: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func pingControlPlane() error {
|
||||||
|
conn, err := auth.ControlPlaneClientConnection("vet-cloud-ping")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
pingService, err := cloud.NewPingService(conn)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
pr, err := pingService.Ping()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
ui.PrintSuccess("Ping successful. Started at %s, finished at %s",
|
||||||
|
pr.StartedAt.Format(time.RFC3339), pr.FinishedAt.Format(time.RFC3339))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
116
cmd/cloud/query.go
Normal file
116
cmd/cloud/query.go
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
package cloud
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"os"
|
||||||
|
"sort"
|
||||||
|
|
||||||
|
"github.com/jedib0t/go-pretty/v6/table"
|
||||||
|
"github.com/safedep/vet/internal/auth"
|
||||||
|
"github.com/safedep/vet/internal/ui"
|
||||||
|
"github.com/safedep/vet/pkg/cloud/query"
|
||||||
|
"github.com/safedep/vet/pkg/common/logger"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
querySql string
|
||||||
|
)
|
||||||
|
|
||||||
|
func newQueryCommand() *cobra.Command {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "query",
|
||||||
|
Short: "Query risks by executing SQL queries",
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
return cmd.Help()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.AddCommand(newQueryExecuteCommand())
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func newQueryExecuteCommand() *cobra.Command {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "execute",
|
||||||
|
Short: "Execute a query",
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
err := executeQuery()
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("Failed to execute query: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.Flags().StringVarP(&querySql, "sql", "s", "", "SQL query to execute")
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func executeQuery() error {
|
||||||
|
if querySql == "" {
|
||||||
|
return errors.New("SQL string is required")
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := auth.ControlPlaneClientConnection("vet-cloud-query")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
queryService, err := query.NewQueryService(client)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err := queryService.ExecuteSql(querySql)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return renderQueryResponseAsTable(response)
|
||||||
|
}
|
||||||
|
|
||||||
|
func renderQueryResponseAsTable(response *query.QueryResponse) error {
|
||||||
|
tbl := table.NewWriter()
|
||||||
|
tbl.SetOutputMirror(os.Stdout)
|
||||||
|
tbl.SetStyle(table.StyleLight)
|
||||||
|
|
||||||
|
if response.Count() == 0 {
|
||||||
|
logger.Infof("No results found")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
ui.PrintSuccess("Query returned %d results", response.Count())
|
||||||
|
|
||||||
|
// Header
|
||||||
|
headers := []string{}
|
||||||
|
response.GetRow(0).ForEachField(func(key string, _ interface{}) {
|
||||||
|
headers = append(headers, key)
|
||||||
|
})
|
||||||
|
|
||||||
|
sort.Strings(headers)
|
||||||
|
|
||||||
|
headerRow := []interface{}{}
|
||||||
|
for _, header := range headers {
|
||||||
|
headerRow = append(headerRow, header)
|
||||||
|
}
|
||||||
|
|
||||||
|
tbl.AppendHeader(headerRow)
|
||||||
|
|
||||||
|
// Ensure we have a consistent order of columns
|
||||||
|
response.ForEachRow(func(row *query.QueryRow) {
|
||||||
|
rowValues := []interface{}{}
|
||||||
|
for _, header := range headers {
|
||||||
|
rowValues = append(rowValues, row.GetField(header))
|
||||||
|
}
|
||||||
|
|
||||||
|
tbl.AppendRow(rowValues)
|
||||||
|
tbl.AppendSeparator()
|
||||||
|
})
|
||||||
|
|
||||||
|
tbl.Render()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
77
cmd/cloud/register.go
Normal file
77
cmd/cloud/register.go
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
package cloud
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/safedep/vet/internal/auth"
|
||||||
|
"github.com/safedep/vet/internal/ui"
|
||||||
|
"github.com/safedep/vet/pkg/cloud"
|
||||||
|
"github.com/safedep/vet/pkg/common/logger"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
registerEmail string
|
||||||
|
registerName string
|
||||||
|
registerOrgName string
|
||||||
|
registerOrgDomain string
|
||||||
|
)
|
||||||
|
|
||||||
|
func newRegisterCommand() *cobra.Command {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "register",
|
||||||
|
Short: "Register a new user and tenant",
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
err := registerUserTenant()
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("Failed to register user: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.Flags().StringVar(®isterEmail, "email", "cloud@safedep.io", "Email of the user (not required for SafeDep cloud)")
|
||||||
|
cmd.Flags().StringVar(®isterName, "name", "", "Name of the user")
|
||||||
|
cmd.Flags().StringVar(®isterOrgName, "org-name", "", "Name of the organization")
|
||||||
|
cmd.Flags().StringVar(®isterOrgDomain, "org-domain", "", "Domain of the organization")
|
||||||
|
|
||||||
|
_ = cmd.MarkFlagRequired("name")
|
||||||
|
_ = cmd.MarkFlagRequired("org-name")
|
||||||
|
_ = cmd.MarkFlagRequired("org-domain")
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func registerUserTenant() error {
|
||||||
|
conn, err := auth.ControlPlaneClientConnection("vet-cloud-register")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
onboardingService, err := cloud.NewOnboardingService(conn)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := onboardingService.Register(&cloud.RegisterRequest{
|
||||||
|
Name: registerName,
|
||||||
|
Email: registerEmail,
|
||||||
|
OrgName: registerOrgName,
|
||||||
|
OrgDomain: registerOrgDomain,
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
ui.PrintSuccess("Registered user and tenant.")
|
||||||
|
ui.PrintSuccess("Tenant domain: %s", res.TenantDomain)
|
||||||
|
|
||||||
|
err = auth.PersistTenantDomain(res.TenantDomain)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to persist tenant domain: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
54
cmd/cloud/whoami.go
Normal file
54
cmd/cloud/whoami.go
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
package cloud
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/safedep/vet/internal/auth"
|
||||||
|
"github.com/safedep/vet/internal/ui"
|
||||||
|
"github.com/safedep/vet/pkg/cloud"
|
||||||
|
"github.com/safedep/vet/pkg/common/logger"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
func newWhoamiCommand() *cobra.Command {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "whoami",
|
||||||
|
Short: "Print information about the current user",
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
err := executeWhoami()
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("Failed to execute whoami: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func executeWhoami() error {
|
||||||
|
conn, err := auth.ControlPlaneClientConnection("vet-cloud-whoami")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
userService, err := cloud.NewUserService(conn)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := userService.CurrentUserInfo()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
ui.PrintSuccess("Authenticated as: %s <%s>", res.GetUser().GetName(),
|
||||||
|
res.GetUser().GetEmail())
|
||||||
|
|
||||||
|
ui.PrintSuccess("Has access to the following tenants:")
|
||||||
|
for _, access := range res.GetAccess() {
|
||||||
|
ui.PrintSuccess(" - %s [%d]", access.GetTenant().GetDomain(),
|
||||||
|
access.GetLevel())
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@ -1,297 +0,0 @@
|
|||||||
// Package cpv1trials provides primitives to interact with the openapi HTTP API.
|
|
||||||
//
|
|
||||||
// Code generated by github.com/deepmap/oapi-codegen version v1.10.1 DO NOT EDIT.
|
|
||||||
package cpv1trials
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// RequestEditorFn is the function signature for the RequestEditor callback function
|
|
||||||
type RequestEditorFn func(ctx context.Context, req *http.Request) error
|
|
||||||
|
|
||||||
// Doer performs HTTP requests.
|
|
||||||
//
|
|
||||||
// The standard http.Client implements this interface.
|
|
||||||
type HttpRequestDoer interface {
|
|
||||||
Do(req *http.Request) (*http.Response, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Client which conforms to the OpenAPI3 specification for this service.
|
|
||||||
type Client struct {
|
|
||||||
// The endpoint of the server conforming to this interface, with scheme,
|
|
||||||
// https://api.deepmap.com for example. This can contain a path relative
|
|
||||||
// to the server, such as https://api.deepmap.com/dev-test, and all the
|
|
||||||
// paths in the swagger spec will be appended to the server.
|
|
||||||
Server string
|
|
||||||
|
|
||||||
// Doer for performing requests, typically a *http.Client with any
|
|
||||||
// customized settings, such as certificate chains.
|
|
||||||
Client HttpRequestDoer
|
|
||||||
|
|
||||||
// A list of callbacks for modifying requests which are generated before sending over
|
|
||||||
// the network.
|
|
||||||
RequestEditors []RequestEditorFn
|
|
||||||
}
|
|
||||||
|
|
||||||
// ClientOption allows setting custom parameters during construction
|
|
||||||
type ClientOption func(*Client) error
|
|
||||||
|
|
||||||
// Creates a new Client, with reasonable defaults
|
|
||||||
func NewClient(server string, opts ...ClientOption) (*Client, error) {
|
|
||||||
// create a client with sane default values
|
|
||||||
client := Client{
|
|
||||||
Server: server,
|
|
||||||
}
|
|
||||||
// mutate client and add all optional params
|
|
||||||
for _, o := range opts {
|
|
||||||
if err := o(&client); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// ensure the server URL always has a trailing slash
|
|
||||||
if !strings.HasSuffix(client.Server, "/") {
|
|
||||||
client.Server += "/"
|
|
||||||
}
|
|
||||||
// create httpClient, if not already present
|
|
||||||
if client.Client == nil {
|
|
||||||
client.Client = &http.Client{}
|
|
||||||
}
|
|
||||||
return &client, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithHTTPClient allows overriding the default Doer, which is
|
|
||||||
// automatically created using http.Client. This is useful for tests.
|
|
||||||
func WithHTTPClient(doer HttpRequestDoer) ClientOption {
|
|
||||||
return func(c *Client) error {
|
|
||||||
c.Client = doer
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithRequestEditorFn allows setting up a callback function, which will be
|
|
||||||
// called right before sending the request. This can be used to mutate the request.
|
|
||||||
func WithRequestEditorFn(fn RequestEditorFn) ClientOption {
|
|
||||||
return func(c *Client) error {
|
|
||||||
c.RequestEditors = append(c.RequestEditors, fn)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The interface specification for the client above.
|
|
||||||
type ClientInterface interface {
|
|
||||||
// RegisterTrialUser request with any body
|
|
||||||
RegisterTrialUserWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error)
|
|
||||||
|
|
||||||
RegisterTrialUser(ctx context.Context, body RegisterTrialUserJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Client) RegisterTrialUserWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) {
|
|
||||||
req, err := NewRegisterTrialUserRequestWithBody(c.Server, contentType, body)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
req = req.WithContext(ctx)
|
|
||||||
if err := c.applyEditors(ctx, req, reqEditors); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return c.Client.Do(req)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Client) RegisterTrialUser(ctx context.Context, body RegisterTrialUserJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) {
|
|
||||||
req, err := NewRegisterTrialUserRequest(c.Server, body)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
req = req.WithContext(ctx)
|
|
||||||
if err := c.applyEditors(ctx, req, reqEditors); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return c.Client.Do(req)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewRegisterTrialUserRequest calls the generic RegisterTrialUser builder with application/json body
|
|
||||||
func NewRegisterTrialUserRequest(server string, body RegisterTrialUserJSONRequestBody) (*http.Request, error) {
|
|
||||||
var bodyReader io.Reader
|
|
||||||
buf, err := json.Marshal(body)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
bodyReader = bytes.NewReader(buf)
|
|
||||||
return NewRegisterTrialUserRequestWithBody(server, "application/json", bodyReader)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewRegisterTrialUserRequestWithBody generates requests for RegisterTrialUser with any type of body
|
|
||||||
func NewRegisterTrialUserRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) {
|
|
||||||
var err error
|
|
||||||
|
|
||||||
serverURL, err := url.Parse(server)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
operationPath := fmt.Sprintf("/trials")
|
|
||||||
if operationPath[0] == '/' {
|
|
||||||
operationPath = "." + operationPath
|
|
||||||
}
|
|
||||||
|
|
||||||
queryURL, err := serverURL.Parse(operationPath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
req, err := http.NewRequest("POST", queryURL.String(), body)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
req.Header.Add("Content-Type", contentType)
|
|
||||||
|
|
||||||
return req, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Client) applyEditors(ctx context.Context, req *http.Request, additionalEditors []RequestEditorFn) error {
|
|
||||||
for _, r := range c.RequestEditors {
|
|
||||||
if err := r(ctx, req); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, r := range additionalEditors {
|
|
||||||
if err := r(ctx, req); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ClientWithResponses builds on ClientInterface to offer response payloads
|
|
||||||
type ClientWithResponses struct {
|
|
||||||
ClientInterface
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewClientWithResponses creates a new ClientWithResponses, which wraps
|
|
||||||
// Client with return type handling
|
|
||||||
func NewClientWithResponses(server string, opts ...ClientOption) (*ClientWithResponses, error) {
|
|
||||||
client, err := NewClient(server, opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &ClientWithResponses{client}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithBaseURL overrides the baseURL.
|
|
||||||
func WithBaseURL(baseURL string) ClientOption {
|
|
||||||
return func(c *Client) error {
|
|
||||||
newBaseURL, err := url.Parse(baseURL)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
c.Server = newBaseURL.String()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ClientWithResponsesInterface is the interface specification for the client with responses above.
|
|
||||||
type ClientWithResponsesInterface interface {
|
|
||||||
// RegisterTrialUser request with any body
|
|
||||||
RegisterTrialUserWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*RegisterTrialUserResponse, error)
|
|
||||||
|
|
||||||
RegisterTrialUserWithResponse(ctx context.Context, body RegisterTrialUserJSONRequestBody, reqEditors ...RequestEditorFn) (*RegisterTrialUserResponse, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type RegisterTrialUserResponse struct {
|
|
||||||
Body []byte
|
|
||||||
HTTPResponse *http.Response
|
|
||||||
JSON201 *TrialResponse
|
|
||||||
JSON403 *ApiError
|
|
||||||
JSON429 *ApiError
|
|
||||||
JSON500 *ApiError
|
|
||||||
}
|
|
||||||
|
|
||||||
// Status returns HTTPResponse.Status
|
|
||||||
func (r RegisterTrialUserResponse) Status() string {
|
|
||||||
if r.HTTPResponse != nil {
|
|
||||||
return r.HTTPResponse.Status
|
|
||||||
}
|
|
||||||
return http.StatusText(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// StatusCode returns HTTPResponse.StatusCode
|
|
||||||
func (r RegisterTrialUserResponse) StatusCode() int {
|
|
||||||
if r.HTTPResponse != nil {
|
|
||||||
return r.HTTPResponse.StatusCode
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// RegisterTrialUserWithBodyWithResponse request with arbitrary body returning *RegisterTrialUserResponse
|
|
||||||
func (c *ClientWithResponses) RegisterTrialUserWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*RegisterTrialUserResponse, error) {
|
|
||||||
rsp, err := c.RegisterTrialUserWithBody(ctx, contentType, body, reqEditors...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return ParseRegisterTrialUserResponse(rsp)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *ClientWithResponses) RegisterTrialUserWithResponse(ctx context.Context, body RegisterTrialUserJSONRequestBody, reqEditors ...RequestEditorFn) (*RegisterTrialUserResponse, error) {
|
|
||||||
rsp, err := c.RegisterTrialUser(ctx, body, reqEditors...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return ParseRegisterTrialUserResponse(rsp)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseRegisterTrialUserResponse parses an HTTP response from a RegisterTrialUserWithResponse call
|
|
||||||
func ParseRegisterTrialUserResponse(rsp *http.Response) (*RegisterTrialUserResponse, error) {
|
|
||||||
bodyBytes, err := ioutil.ReadAll(rsp.Body)
|
|
||||||
defer func() { _ = rsp.Body.Close() }()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
response := &RegisterTrialUserResponse{
|
|
||||||
Body: bodyBytes,
|
|
||||||
HTTPResponse: rsp,
|
|
||||||
}
|
|
||||||
|
|
||||||
switch {
|
|
||||||
case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 201:
|
|
||||||
var dest TrialResponse
|
|
||||||
if err := json.Unmarshal(bodyBytes, &dest); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
response.JSON201 = &dest
|
|
||||||
|
|
||||||
case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403:
|
|
||||||
var dest ApiError
|
|
||||||
if err := json.Unmarshal(bodyBytes, &dest); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
response.JSON403 = &dest
|
|
||||||
|
|
||||||
case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 429:
|
|
||||||
var dest ApiError
|
|
||||||
if err := json.Unmarshal(bodyBytes, &dest); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
response.JSON429 = &dest
|
|
||||||
|
|
||||||
case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500:
|
|
||||||
var dest ApiError
|
|
||||||
if err := json.Unmarshal(bodyBytes, &dest); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
response.JSON500 = &dest
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return response, nil
|
|
||||||
}
|
|
||||||
@ -1,159 +0,0 @@
|
|||||||
// Package cpv1trials provides primitives to interact with the openapi HTTP API.
|
|
||||||
//
|
|
||||||
// Code generated by github.com/deepmap/oapi-codegen version v1.10.1 DO NOT EDIT.
|
|
||||||
package cpv1trials
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
openapi_types "github.com/deepmap/oapi-codegen/pkg/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Defines values for ApiErrorCode.
|
|
||||||
const (
|
|
||||||
ApiErrorCodeApiGuardError ApiErrorCode = "api_guard_error"
|
|
||||||
|
|
||||||
ApiErrorCodeApiGuardInvalidCredentials ApiErrorCode = "api_guard_invalid_credentials"
|
|
||||||
|
|
||||||
ApiErrorCodeApiGuardRateLimitExceeded ApiErrorCode = "api_guard_rate_limit_exceeded"
|
|
||||||
|
|
||||||
ApiErrorCodeApiGuardUnauthorized ApiErrorCode = "api_guard_unauthorized"
|
|
||||||
|
|
||||||
ApiErrorCodeAppFeatureNotEnabled ApiErrorCode = "app_feature_not_enabled"
|
|
||||||
|
|
||||||
ApiErrorCodeAppGenericError ApiErrorCode = "app_generic_error"
|
|
||||||
|
|
||||||
ApiErrorCodeAppInsufficientParameters ApiErrorCode = "app_insufficient_parameters"
|
|
||||||
|
|
||||||
ApiErrorCodeAppPackageVersionNotFound ApiErrorCode = "app_package_version_not_found"
|
|
||||||
|
|
||||||
ApiErrorCodeAppSecurityError ApiErrorCode = "app_security_error"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Defines values for ApiErrorType.
|
|
||||||
const (
|
|
||||||
ApiErrorTypeInternalError ApiErrorType = "internal_error"
|
|
||||||
|
|
||||||
ApiErrorTypeInvalidRequest ApiErrorType = "invalid_request"
|
|
||||||
|
|
||||||
ApiErrorTypeOperationFailed ApiErrorType = "operation_failed"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ApiError defines model for ApiError.
|
|
||||||
type ApiError struct {
|
|
||||||
// An error code identifying the error
|
|
||||||
Code *ApiErrorCode `json:"code,omitempty"`
|
|
||||||
|
|
||||||
// A descriptive message about the error meant for developer consumption
|
|
||||||
Message *string `json:"message,omitempty"`
|
|
||||||
|
|
||||||
// Optional error specific attributes
|
|
||||||
Params *ApiError_Params `json:"params,omitempty"`
|
|
||||||
|
|
||||||
// An optional service or domain specific error group
|
|
||||||
Type *ApiErrorType `json:"type,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// An error code identifying the error
|
|
||||||
type ApiErrorCode string
|
|
||||||
|
|
||||||
// Optional error specific attributes
|
|
||||||
type ApiError_Params struct {
|
|
||||||
AdditionalProperties map[string]struct {
|
|
||||||
Key *string `json:"key,omitempty"`
|
|
||||||
Value *string `json:"value,omitempty"`
|
|
||||||
} `json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// An optional service or domain specific error group
|
|
||||||
type ApiErrorType string
|
|
||||||
|
|
||||||
// TrialRequest defines model for TrialRequest.
|
|
||||||
type TrialRequest struct {
|
|
||||||
Email openapi_types.Email `json:"email"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// TrialResponse defines model for TrialResponse.
|
|
||||||
type TrialResponse struct {
|
|
||||||
// The expiry time of the API key
|
|
||||||
ExpiresAt *time.Time `json:"expires_at,omitempty"`
|
|
||||||
|
|
||||||
// The ID of the trial registration request created in the system
|
|
||||||
Id *string `json:"id,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// RegisterTrialUserJSONBody defines parameters for RegisterTrialUser.
|
|
||||||
type RegisterTrialUserJSONBody TrialRequest
|
|
||||||
|
|
||||||
// RegisterTrialUserJSONRequestBody defines body for RegisterTrialUser for application/json ContentType.
|
|
||||||
type RegisterTrialUserJSONRequestBody RegisterTrialUserJSONBody
|
|
||||||
|
|
||||||
// Getter for additional properties for ApiError_Params. Returns the specified
|
|
||||||
// element and whether it was found
|
|
||||||
func (a ApiError_Params) Get(fieldName string) (value struct {
|
|
||||||
Key *string `json:"key,omitempty"`
|
|
||||||
Value *string `json:"value,omitempty"`
|
|
||||||
}, found bool) {
|
|
||||||
if a.AdditionalProperties != nil {
|
|
||||||
value, found = a.AdditionalProperties[fieldName]
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setter for additional properties for ApiError_Params
|
|
||||||
func (a *ApiError_Params) Set(fieldName string, value struct {
|
|
||||||
Key *string `json:"key,omitempty"`
|
|
||||||
Value *string `json:"value,omitempty"`
|
|
||||||
}) {
|
|
||||||
if a.AdditionalProperties == nil {
|
|
||||||
a.AdditionalProperties = make(map[string]struct {
|
|
||||||
Key *string `json:"key,omitempty"`
|
|
||||||
Value *string `json:"value,omitempty"`
|
|
||||||
})
|
|
||||||
}
|
|
||||||
a.AdditionalProperties[fieldName] = value
|
|
||||||
}
|
|
||||||
|
|
||||||
// Override default JSON handling for ApiError_Params to handle AdditionalProperties
|
|
||||||
func (a *ApiError_Params) UnmarshalJSON(b []byte) error {
|
|
||||||
object := make(map[string]json.RawMessage)
|
|
||||||
err := json.Unmarshal(b, &object)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(object) != 0 {
|
|
||||||
a.AdditionalProperties = make(map[string]struct {
|
|
||||||
Key *string `json:"key,omitempty"`
|
|
||||||
Value *string `json:"value,omitempty"`
|
|
||||||
})
|
|
||||||
for fieldName, fieldBuf := range object {
|
|
||||||
var fieldVal struct {
|
|
||||||
Key *string `json:"key,omitempty"`
|
|
||||||
Value *string `json:"value,omitempty"`
|
|
||||||
}
|
|
||||||
err := json.Unmarshal(fieldBuf, &fieldVal)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error unmarshaling field %s: %w", fieldName, err)
|
|
||||||
}
|
|
||||||
a.AdditionalProperties[fieldName] = fieldVal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Override default JSON handling for ApiError_Params to handle AdditionalProperties
|
|
||||||
func (a ApiError_Params) MarshalJSON() ([]byte, error) {
|
|
||||||
var err error
|
|
||||||
object := make(map[string]json.RawMessage)
|
|
||||||
|
|
||||||
for fieldName, field := range a.AdditionalProperties {
|
|
||||||
object[fieldName], err = json.Marshal(field)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("error marshaling '%s': %w", fieldName, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return json.Marshal(object)
|
|
||||||
}
|
|
||||||
@ -1,639 +0,0 @@
|
|||||||
// Package syncv1 provides primitives to interact with the openapi HTTP API.
|
|
||||||
//
|
|
||||||
// Code generated by github.com/deepmap/oapi-codegen version v1.10.1 DO NOT EDIT.
|
|
||||||
package syncv1
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/deepmap/oapi-codegen/pkg/runtime"
|
|
||||||
)
|
|
||||||
|
|
||||||
// RequestEditorFn is the function signature for the RequestEditor callback function
|
|
||||||
type RequestEditorFn func(ctx context.Context, req *http.Request) error
|
|
||||||
|
|
||||||
// Doer performs HTTP requests.
|
|
||||||
//
|
|
||||||
// The standard http.Client implements this interface.
|
|
||||||
type HttpRequestDoer interface {
|
|
||||||
Do(req *http.Request) (*http.Response, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Client which conforms to the OpenAPI3 specification for this service.
|
|
||||||
type Client struct {
|
|
||||||
// The endpoint of the server conforming to this interface, with scheme,
|
|
||||||
// https://api.deepmap.com for example. This can contain a path relative
|
|
||||||
// to the server, such as https://api.deepmap.com/dev-test, and all the
|
|
||||||
// paths in the swagger spec will be appended to the server.
|
|
||||||
Server string
|
|
||||||
|
|
||||||
// Doer for performing requests, typically a *http.Client with any
|
|
||||||
// customized settings, such as certificate chains.
|
|
||||||
Client HttpRequestDoer
|
|
||||||
|
|
||||||
// A list of callbacks for modifying requests which are generated before sending over
|
|
||||||
// the network.
|
|
||||||
RequestEditors []RequestEditorFn
|
|
||||||
}
|
|
||||||
|
|
||||||
// ClientOption allows setting custom parameters during construction
|
|
||||||
type ClientOption func(*Client) error
|
|
||||||
|
|
||||||
// Creates a new Client, with reasonable defaults
|
|
||||||
func NewClient(server string, opts ...ClientOption) (*Client, error) {
|
|
||||||
// create a client with sane default values
|
|
||||||
client := Client{
|
|
||||||
Server: server,
|
|
||||||
}
|
|
||||||
// mutate client and add all optional params
|
|
||||||
for _, o := range opts {
|
|
||||||
if err := o(&client); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// ensure the server URL always has a trailing slash
|
|
||||||
if !strings.HasSuffix(client.Server, "/") {
|
|
||||||
client.Server += "/"
|
|
||||||
}
|
|
||||||
// create httpClient, if not already present
|
|
||||||
if client.Client == nil {
|
|
||||||
client.Client = &http.Client{}
|
|
||||||
}
|
|
||||||
return &client, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithHTTPClient allows overriding the default Doer, which is
|
|
||||||
// automatically created using http.Client. This is useful for tests.
|
|
||||||
func WithHTTPClient(doer HttpRequestDoer) ClientOption {
|
|
||||||
return func(c *Client) error {
|
|
||||||
c.Client = doer
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithRequestEditorFn allows setting up a callback function, which will be
|
|
||||||
// called right before sending the request. This can be used to mutate the request.
|
|
||||||
func WithRequestEditorFn(fn RequestEditorFn) ClientOption {
|
|
||||||
return func(c *Client) error {
|
|
||||||
c.RequestEditors = append(c.RequestEditors, fn)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The interface specification for the client above.
|
|
||||||
type ClientInterface interface {
|
|
||||||
// CreateSyncJob request with any body
|
|
||||||
CreateSyncJobWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error)
|
|
||||||
|
|
||||||
CreateSyncJob(ctx context.Context, body CreateSyncJobJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error)
|
|
||||||
|
|
||||||
// UpdateSyncJob request with any body
|
|
||||||
UpdateSyncJobWithBody(ctx context.Context, jobId string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error)
|
|
||||||
|
|
||||||
UpdateSyncJob(ctx context.Context, jobId string, body UpdateSyncJobJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error)
|
|
||||||
|
|
||||||
// CreateJobIssue request with any body
|
|
||||||
CreateJobIssueWithBody(ctx context.Context, jobId string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error)
|
|
||||||
|
|
||||||
CreateJobIssue(ctx context.Context, jobId string, body CreateJobIssueJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Client) CreateSyncJobWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) {
|
|
||||||
req, err := NewCreateSyncJobRequestWithBody(c.Server, contentType, body)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
req = req.WithContext(ctx)
|
|
||||||
if err := c.applyEditors(ctx, req, reqEditors); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return c.Client.Do(req)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Client) CreateSyncJob(ctx context.Context, body CreateSyncJobJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) {
|
|
||||||
req, err := NewCreateSyncJobRequest(c.Server, body)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
req = req.WithContext(ctx)
|
|
||||||
if err := c.applyEditors(ctx, req, reqEditors); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return c.Client.Do(req)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Client) UpdateSyncJobWithBody(ctx context.Context, jobId string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) {
|
|
||||||
req, err := NewUpdateSyncJobRequestWithBody(c.Server, jobId, contentType, body)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
req = req.WithContext(ctx)
|
|
||||||
if err := c.applyEditors(ctx, req, reqEditors); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return c.Client.Do(req)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Client) UpdateSyncJob(ctx context.Context, jobId string, body UpdateSyncJobJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) {
|
|
||||||
req, err := NewUpdateSyncJobRequest(c.Server, jobId, body)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
req = req.WithContext(ctx)
|
|
||||||
if err := c.applyEditors(ctx, req, reqEditors); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return c.Client.Do(req)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Client) CreateJobIssueWithBody(ctx context.Context, jobId string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) {
|
|
||||||
req, err := NewCreateJobIssueRequestWithBody(c.Server, jobId, contentType, body)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
req = req.WithContext(ctx)
|
|
||||||
if err := c.applyEditors(ctx, req, reqEditors); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return c.Client.Do(req)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Client) CreateJobIssue(ctx context.Context, jobId string, body CreateJobIssueJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) {
|
|
||||||
req, err := NewCreateJobIssueRequest(c.Server, jobId, body)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
req = req.WithContext(ctx)
|
|
||||||
if err := c.applyEditors(ctx, req, reqEditors); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return c.Client.Do(req)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewCreateSyncJobRequest calls the generic CreateSyncJob builder with application/json body
|
|
||||||
func NewCreateSyncJobRequest(server string, body CreateSyncJobJSONRequestBody) (*http.Request, error) {
|
|
||||||
var bodyReader io.Reader
|
|
||||||
buf, err := json.Marshal(body)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
bodyReader = bytes.NewReader(buf)
|
|
||||||
return NewCreateSyncJobRequestWithBody(server, "application/json", bodyReader)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewCreateSyncJobRequestWithBody generates requests for CreateSyncJob with any type of body
|
|
||||||
func NewCreateSyncJobRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) {
|
|
||||||
var err error
|
|
||||||
|
|
||||||
serverURL, err := url.Parse(server)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
operationPath := fmt.Sprintf("/jobs")
|
|
||||||
if operationPath[0] == '/' {
|
|
||||||
operationPath = "." + operationPath
|
|
||||||
}
|
|
||||||
|
|
||||||
queryURL, err := serverURL.Parse(operationPath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
req, err := http.NewRequest("POST", queryURL.String(), body)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
req.Header.Add("Content-Type", contentType)
|
|
||||||
|
|
||||||
return req, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewUpdateSyncJobRequest calls the generic UpdateSyncJob builder with application/json body
|
|
||||||
func NewUpdateSyncJobRequest(server string, jobId string, body UpdateSyncJobJSONRequestBody) (*http.Request, error) {
|
|
||||||
var bodyReader io.Reader
|
|
||||||
buf, err := json.Marshal(body)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
bodyReader = bytes.NewReader(buf)
|
|
||||||
return NewUpdateSyncJobRequestWithBody(server, jobId, "application/json", bodyReader)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewUpdateSyncJobRequestWithBody generates requests for UpdateSyncJob with any type of body
|
|
||||||
func NewUpdateSyncJobRequestWithBody(server string, jobId string, contentType string, body io.Reader) (*http.Request, error) {
|
|
||||||
var err error
|
|
||||||
|
|
||||||
var pathParam0 string
|
|
||||||
|
|
||||||
pathParam0, err = runtime.StyleParamWithLocation("simple", false, "job_id", runtime.ParamLocationPath, jobId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
serverURL, err := url.Parse(server)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
operationPath := fmt.Sprintf("/jobs/%s", pathParam0)
|
|
||||||
if operationPath[0] == '/' {
|
|
||||||
operationPath = "." + operationPath
|
|
||||||
}
|
|
||||||
|
|
||||||
queryURL, err := serverURL.Parse(operationPath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
req, err := http.NewRequest("PUT", queryURL.String(), body)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
req.Header.Add("Content-Type", contentType)
|
|
||||||
|
|
||||||
return req, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewCreateJobIssueRequest calls the generic CreateJobIssue builder with application/json body
|
|
||||||
func NewCreateJobIssueRequest(server string, jobId string, body CreateJobIssueJSONRequestBody) (*http.Request, error) {
|
|
||||||
var bodyReader io.Reader
|
|
||||||
buf, err := json.Marshal(body)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
bodyReader = bytes.NewReader(buf)
|
|
||||||
return NewCreateJobIssueRequestWithBody(server, jobId, "application/json", bodyReader)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewCreateJobIssueRequestWithBody generates requests for CreateJobIssue with any type of body
|
|
||||||
func NewCreateJobIssueRequestWithBody(server string, jobId string, contentType string, body io.Reader) (*http.Request, error) {
|
|
||||||
var err error
|
|
||||||
|
|
||||||
var pathParam0 string
|
|
||||||
|
|
||||||
pathParam0, err = runtime.StyleParamWithLocation("simple", false, "job_id", runtime.ParamLocationPath, jobId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
serverURL, err := url.Parse(server)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
operationPath := fmt.Sprintf("/jobs/%s/issues", pathParam0)
|
|
||||||
if operationPath[0] == '/' {
|
|
||||||
operationPath = "." + operationPath
|
|
||||||
}
|
|
||||||
|
|
||||||
queryURL, err := serverURL.Parse(operationPath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
req, err := http.NewRequest("POST", queryURL.String(), body)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
req.Header.Add("Content-Type", contentType)
|
|
||||||
|
|
||||||
return req, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Client) applyEditors(ctx context.Context, req *http.Request, additionalEditors []RequestEditorFn) error {
|
|
||||||
for _, r := range c.RequestEditors {
|
|
||||||
if err := r(ctx, req); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, r := range additionalEditors {
|
|
||||||
if err := r(ctx, req); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ClientWithResponses builds on ClientInterface to offer response payloads
|
|
||||||
type ClientWithResponses struct {
|
|
||||||
ClientInterface
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewClientWithResponses creates a new ClientWithResponses, which wraps
|
|
||||||
// Client with return type handling
|
|
||||||
func NewClientWithResponses(server string, opts ...ClientOption) (*ClientWithResponses, error) {
|
|
||||||
client, err := NewClient(server, opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &ClientWithResponses{client}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithBaseURL overrides the baseURL.
|
|
||||||
func WithBaseURL(baseURL string) ClientOption {
|
|
||||||
return func(c *Client) error {
|
|
||||||
newBaseURL, err := url.Parse(baseURL)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
c.Server = newBaseURL.String()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ClientWithResponsesInterface is the interface specification for the client with responses above.
|
|
||||||
type ClientWithResponsesInterface interface {
|
|
||||||
// CreateSyncJob request with any body
|
|
||||||
CreateSyncJobWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateSyncJobResponse, error)
|
|
||||||
|
|
||||||
CreateSyncJobWithResponse(ctx context.Context, body CreateSyncJobJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateSyncJobResponse, error)
|
|
||||||
|
|
||||||
// UpdateSyncJob request with any body
|
|
||||||
UpdateSyncJobWithBodyWithResponse(ctx context.Context, jobId string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*UpdateSyncJobResponse, error)
|
|
||||||
|
|
||||||
UpdateSyncJobWithResponse(ctx context.Context, jobId string, body UpdateSyncJobJSONRequestBody, reqEditors ...RequestEditorFn) (*UpdateSyncJobResponse, error)
|
|
||||||
|
|
||||||
// CreateJobIssue request with any body
|
|
||||||
CreateJobIssueWithBodyWithResponse(ctx context.Context, jobId string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateJobIssueResponse, error)
|
|
||||||
|
|
||||||
CreateJobIssueWithResponse(ctx context.Context, jobId string, body CreateJobIssueJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateJobIssueResponse, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type CreateSyncJobResponse struct {
|
|
||||||
Body []byte
|
|
||||||
HTTPResponse *http.Response
|
|
||||||
JSON201 *AnyJobResponse
|
|
||||||
JSON403 *ApiError
|
|
||||||
JSON429 *ApiError
|
|
||||||
JSON500 *ApiError
|
|
||||||
}
|
|
||||||
|
|
||||||
// Status returns HTTPResponse.Status
|
|
||||||
func (r CreateSyncJobResponse) Status() string {
|
|
||||||
if r.HTTPResponse != nil {
|
|
||||||
return r.HTTPResponse.Status
|
|
||||||
}
|
|
||||||
return http.StatusText(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// StatusCode returns HTTPResponse.StatusCode
|
|
||||||
func (r CreateSyncJobResponse) StatusCode() int {
|
|
||||||
if r.HTTPResponse != nil {
|
|
||||||
return r.HTTPResponse.StatusCode
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
type UpdateSyncJobResponse struct {
|
|
||||||
Body []byte
|
|
||||||
HTTPResponse *http.Response
|
|
||||||
JSON200 *AnyJobResponse
|
|
||||||
JSON403 *ApiError
|
|
||||||
JSON429 *ApiError
|
|
||||||
JSON500 *ApiError
|
|
||||||
}
|
|
||||||
|
|
||||||
// Status returns HTTPResponse.Status
|
|
||||||
func (r UpdateSyncJobResponse) Status() string {
|
|
||||||
if r.HTTPResponse != nil {
|
|
||||||
return r.HTTPResponse.Status
|
|
||||||
}
|
|
||||||
return http.StatusText(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// StatusCode returns HTTPResponse.StatusCode
|
|
||||||
func (r UpdateSyncJobResponse) StatusCode() int {
|
|
||||||
if r.HTTPResponse != nil {
|
|
||||||
return r.HTTPResponse.StatusCode
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
type CreateJobIssueResponse struct {
|
|
||||||
Body []byte
|
|
||||||
HTTPResponse *http.Response
|
|
||||||
JSON201 *CreateIssueResponse
|
|
||||||
JSON403 *ApiError
|
|
||||||
JSON429 *ApiError
|
|
||||||
JSON500 *ApiError
|
|
||||||
}
|
|
||||||
|
|
||||||
// Status returns HTTPResponse.Status
|
|
||||||
func (r CreateJobIssueResponse) Status() string {
|
|
||||||
if r.HTTPResponse != nil {
|
|
||||||
return r.HTTPResponse.Status
|
|
||||||
}
|
|
||||||
return http.StatusText(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// StatusCode returns HTTPResponse.StatusCode
|
|
||||||
func (r CreateJobIssueResponse) StatusCode() int {
|
|
||||||
if r.HTTPResponse != nil {
|
|
||||||
return r.HTTPResponse.StatusCode
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateSyncJobWithBodyWithResponse request with arbitrary body returning *CreateSyncJobResponse
|
|
||||||
func (c *ClientWithResponses) CreateSyncJobWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateSyncJobResponse, error) {
|
|
||||||
rsp, err := c.CreateSyncJobWithBody(ctx, contentType, body, reqEditors...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return ParseCreateSyncJobResponse(rsp)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *ClientWithResponses) CreateSyncJobWithResponse(ctx context.Context, body CreateSyncJobJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateSyncJobResponse, error) {
|
|
||||||
rsp, err := c.CreateSyncJob(ctx, body, reqEditors...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return ParseCreateSyncJobResponse(rsp)
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateSyncJobWithBodyWithResponse request with arbitrary body returning *UpdateSyncJobResponse
|
|
||||||
func (c *ClientWithResponses) UpdateSyncJobWithBodyWithResponse(ctx context.Context, jobId string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*UpdateSyncJobResponse, error) {
|
|
||||||
rsp, err := c.UpdateSyncJobWithBody(ctx, jobId, contentType, body, reqEditors...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return ParseUpdateSyncJobResponse(rsp)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *ClientWithResponses) UpdateSyncJobWithResponse(ctx context.Context, jobId string, body UpdateSyncJobJSONRequestBody, reqEditors ...RequestEditorFn) (*UpdateSyncJobResponse, error) {
|
|
||||||
rsp, err := c.UpdateSyncJob(ctx, jobId, body, reqEditors...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return ParseUpdateSyncJobResponse(rsp)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateJobIssueWithBodyWithResponse request with arbitrary body returning *CreateJobIssueResponse
|
|
||||||
func (c *ClientWithResponses) CreateJobIssueWithBodyWithResponse(ctx context.Context, jobId string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*CreateJobIssueResponse, error) {
|
|
||||||
rsp, err := c.CreateJobIssueWithBody(ctx, jobId, contentType, body, reqEditors...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return ParseCreateJobIssueResponse(rsp)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *ClientWithResponses) CreateJobIssueWithResponse(ctx context.Context, jobId string, body CreateJobIssueJSONRequestBody, reqEditors ...RequestEditorFn) (*CreateJobIssueResponse, error) {
|
|
||||||
rsp, err := c.CreateJobIssue(ctx, jobId, body, reqEditors...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return ParseCreateJobIssueResponse(rsp)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseCreateSyncJobResponse parses an HTTP response from a CreateSyncJobWithResponse call
|
|
||||||
func ParseCreateSyncJobResponse(rsp *http.Response) (*CreateSyncJobResponse, error) {
|
|
||||||
bodyBytes, err := ioutil.ReadAll(rsp.Body)
|
|
||||||
defer func() { _ = rsp.Body.Close() }()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
response := &CreateSyncJobResponse{
|
|
||||||
Body: bodyBytes,
|
|
||||||
HTTPResponse: rsp,
|
|
||||||
}
|
|
||||||
|
|
||||||
switch {
|
|
||||||
case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 201:
|
|
||||||
var dest AnyJobResponse
|
|
||||||
if err := json.Unmarshal(bodyBytes, &dest); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
response.JSON201 = &dest
|
|
||||||
|
|
||||||
case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403:
|
|
||||||
var dest ApiError
|
|
||||||
if err := json.Unmarshal(bodyBytes, &dest); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
response.JSON403 = &dest
|
|
||||||
|
|
||||||
case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 429:
|
|
||||||
var dest ApiError
|
|
||||||
if err := json.Unmarshal(bodyBytes, &dest); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
response.JSON429 = &dest
|
|
||||||
|
|
||||||
case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500:
|
|
||||||
var dest ApiError
|
|
||||||
if err := json.Unmarshal(bodyBytes, &dest); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
response.JSON500 = &dest
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return response, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseUpdateSyncJobResponse parses an HTTP response from a UpdateSyncJobWithResponse call
|
|
||||||
func ParseUpdateSyncJobResponse(rsp *http.Response) (*UpdateSyncJobResponse, error) {
|
|
||||||
bodyBytes, err := ioutil.ReadAll(rsp.Body)
|
|
||||||
defer func() { _ = rsp.Body.Close() }()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
response := &UpdateSyncJobResponse{
|
|
||||||
Body: bodyBytes,
|
|
||||||
HTTPResponse: rsp,
|
|
||||||
}
|
|
||||||
|
|
||||||
switch {
|
|
||||||
case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200:
|
|
||||||
var dest AnyJobResponse
|
|
||||||
if err := json.Unmarshal(bodyBytes, &dest); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
response.JSON200 = &dest
|
|
||||||
|
|
||||||
case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403:
|
|
||||||
var dest ApiError
|
|
||||||
if err := json.Unmarshal(bodyBytes, &dest); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
response.JSON403 = &dest
|
|
||||||
|
|
||||||
case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 429:
|
|
||||||
var dest ApiError
|
|
||||||
if err := json.Unmarshal(bodyBytes, &dest); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
response.JSON429 = &dest
|
|
||||||
|
|
||||||
case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500:
|
|
||||||
var dest ApiError
|
|
||||||
if err := json.Unmarshal(bodyBytes, &dest); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
response.JSON500 = &dest
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return response, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseCreateJobIssueResponse parses an HTTP response from a CreateJobIssueWithResponse call
|
|
||||||
func ParseCreateJobIssueResponse(rsp *http.Response) (*CreateJobIssueResponse, error) {
|
|
||||||
bodyBytes, err := ioutil.ReadAll(rsp.Body)
|
|
||||||
defer func() { _ = rsp.Body.Close() }()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
response := &CreateJobIssueResponse{
|
|
||||||
Body: bodyBytes,
|
|
||||||
HTTPResponse: rsp,
|
|
||||||
}
|
|
||||||
|
|
||||||
switch {
|
|
||||||
case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 201:
|
|
||||||
var dest CreateIssueResponse
|
|
||||||
if err := json.Unmarshal(bodyBytes, &dest); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
response.JSON201 = &dest
|
|
||||||
|
|
||||||
case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 403:
|
|
||||||
var dest ApiError
|
|
||||||
if err := json.Unmarshal(bodyBytes, &dest); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
response.JSON403 = &dest
|
|
||||||
|
|
||||||
case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 429:
|
|
||||||
var dest ApiError
|
|
||||||
if err := json.Unmarshal(bodyBytes, &dest); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
response.JSON429 = &dest
|
|
||||||
|
|
||||||
case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500:
|
|
||||||
var dest ApiError
|
|
||||||
if err := json.Unmarshal(bodyBytes, &dest); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
response.JSON500 = &dest
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return response, nil
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
21
go.mod
21
go.mod
@ -3,6 +3,8 @@ module github.com/safedep/vet
|
|||||||
go 1.22.1
|
go 1.22.1
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
buf.build/gen/go/safedep/api/grpc/go v1.5.1-20241011110723-95b33664baad.1
|
||||||
|
buf.build/gen/go/safedep/api/protocolbuffers/go v1.35.1-20241011110723-95b33664baad.1
|
||||||
github.com/AlecAivazis/survey/v2 v2.3.7
|
github.com/AlecAivazis/survey/v2 v2.3.7
|
||||||
github.com/CycloneDX/cyclonedx-go v0.9.0
|
github.com/CycloneDX/cyclonedx-go v0.9.0
|
||||||
github.com/anchore/syft v1.11.1
|
github.com/anchore/syft v1.11.1
|
||||||
@ -19,22 +21,28 @@ require (
|
|||||||
github.com/google/osv-scanner v1.8.4
|
github.com/google/osv-scanner v1.8.4
|
||||||
github.com/jedib0t/go-pretty/v6 v6.5.9
|
github.com/jedib0t/go-pretty/v6 v6.5.9
|
||||||
github.com/kubescape/go-git-url v0.0.30
|
github.com/kubescape/go-git-url v0.0.30
|
||||||
|
github.com/oklog/ulid/v2 v2.1.0
|
||||||
github.com/owenrumney/go-sarif/v2 v2.3.3
|
github.com/owenrumney/go-sarif/v2 v2.3.3
|
||||||
github.com/package-url/packageurl-go v0.1.3
|
github.com/package-url/packageurl-go v0.1.3
|
||||||
github.com/safedep/dry v0.0.0-20240808054916-b31bac30d0ef
|
github.com/safedep/dry v0.0.0-20240927023913-bb455ab56626
|
||||||
github.com/sirupsen/logrus v1.9.3
|
github.com/sirupsen/logrus v1.9.3
|
||||||
github.com/smacker/go-tree-sitter v0.0.0-20240827094217-dd81d9e9be82
|
github.com/smacker/go-tree-sitter v0.0.0-20240827094217-dd81d9e9be82
|
||||||
github.com/spdx/tools-golang v0.5.5
|
github.com/spdx/tools-golang v0.5.5
|
||||||
github.com/spf13/cobra v1.8.1
|
github.com/spf13/cobra v1.8.1
|
||||||
github.com/stretchr/testify v1.9.0
|
github.com/stretchr/testify v1.9.0
|
||||||
golang.org/x/oauth2 v0.23.0
|
golang.org/x/oauth2 v0.23.0
|
||||||
google.golang.org/protobuf v1.34.2
|
google.golang.org/grpc v1.66.0
|
||||||
|
google.golang.org/protobuf v1.35.1
|
||||||
gopkg.in/yaml.v2 v2.4.0
|
gopkg.in/yaml.v2 v2.4.0
|
||||||
)
|
)
|
||||||
|
|
||||||
replace github.com/owenrumney/go-sarif/v2 v2.3.1 => github.com/safedep/go-sarif/v2 v2.3.1
|
replace github.com/owenrumney/go-sarif/v2 v2.3.1 => github.com/safedep/go-sarif/v2 v2.3.1
|
||||||
|
|
||||||
|
// https://github.com/cli/oauth/pull/68
|
||||||
|
replace github.com/cli/oauth v1.0.1 => github.com/abhisek/oauth v1.0.1-audience
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.35.1-20240508200655-46a4cf4ba109.1 // indirect
|
||||||
github.com/BurntSushi/toml v1.4.0 // indirect
|
github.com/BurntSushi/toml v1.4.0 // indirect
|
||||||
github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53 // indirect
|
github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53 // indirect
|
||||||
github.com/CloudyKit/jet/v6 v6.2.0 // indirect
|
github.com/CloudyKit/jet/v6 v6.2.0 // indirect
|
||||||
@ -88,6 +96,8 @@ require (
|
|||||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||||
github.com/gin-gonic/gin v1.10.0 // indirect
|
github.com/gin-gonic/gin v1.10.0 // indirect
|
||||||
github.com/github/go-spdx/v2 v2.3.1 // indirect
|
github.com/github/go-spdx/v2 v2.3.1 // indirect
|
||||||
|
github.com/go-logr/logr v1.4.1 // indirect
|
||||||
|
github.com/go-logr/stdr v1.2.2 // indirect
|
||||||
github.com/go-playground/locales v0.14.1 // indirect
|
github.com/go-playground/locales v0.14.1 // indirect
|
||||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||||
github.com/go-playground/validator/v10 v10.22.0 // indirect
|
github.com/go-playground/validator/v10 v10.22.0 // indirect
|
||||||
@ -105,6 +115,7 @@ require (
|
|||||||
github.com/google/uuid v1.6.0 // indirect
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
github.com/gookit/color v1.5.4 // indirect
|
github.com/gookit/color v1.5.4 // indirect
|
||||||
github.com/gorilla/css v1.0.1 // indirect
|
github.com/gorilla/css v1.0.1 // indirect
|
||||||
|
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect
|
||||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||||
@ -145,7 +156,6 @@ require (
|
|||||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||||
github.com/nwaples/rardecode v1.1.3 // indirect
|
github.com/nwaples/rardecode v1.1.3 // indirect
|
||||||
github.com/oklog/ulid/v2 v2.1.0 // indirect
|
|
||||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||||
github.com/pborman/indent v1.2.1 // indirect
|
github.com/pborman/indent v1.2.1 // indirect
|
||||||
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
|
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
|
||||||
@ -193,6 +203,10 @@ require (
|
|||||||
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
|
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
|
||||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
|
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
|
||||||
github.com/yosssi/ace v0.0.5 // indirect
|
github.com/yosssi/ace v0.0.5 // indirect
|
||||||
|
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect
|
||||||
|
go.opentelemetry.io/otel v1.24.0 // indirect
|
||||||
|
go.opentelemetry.io/otel/metric v1.24.0 // indirect
|
||||||
|
go.opentelemetry.io/otel/trace v1.24.0 // indirect
|
||||||
go.uber.org/multierr v1.11.0 // indirect
|
go.uber.org/multierr v1.11.0 // indirect
|
||||||
go.uber.org/zap v1.27.0 // indirect
|
go.uber.org/zap v1.27.0 // indirect
|
||||||
golang.org/x/arch v0.10.0 // indirect
|
golang.org/x/arch v0.10.0 // indirect
|
||||||
@ -206,7 +220,6 @@ require (
|
|||||||
golang.org/x/time v0.6.0 // indirect
|
golang.org/x/time v0.6.0 // indirect
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect
|
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect
|
||||||
google.golang.org/grpc v1.66.0 // indirect
|
|
||||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
|
|||||||
144
go.sum
144
go.sum
@ -1,3 +1,17 @@
|
|||||||
|
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.35.1-20240508200655-46a4cf4ba109.1 h1:PvjTFY+MqrYYulH74R8ddQodrEP1sThjkba8kcqO2dM=
|
||||||
|
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.35.1-20240508200655-46a4cf4ba109.1/go.mod h1:Duw/9JoXkXIydyASnLYIiufkzySThoqavOsF+IihqvM=
|
||||||
|
buf.build/gen/go/safedep/api/grpc/go v1.5.1-20241008111718-480f2b42b425.1 h1:ofDpCRg/yPfD0UMny+yaq4G5sHLNFhBH2DtIN9orEzQ=
|
||||||
|
buf.build/gen/go/safedep/api/grpc/go v1.5.1-20241008111718-480f2b42b425.1/go.mod h1:DGREO91B1aVG1+zfN4gT/ZQZ0Ykcv+TZGf18SeGDcMc=
|
||||||
|
buf.build/gen/go/safedep/api/grpc/go v1.5.1-20241009065537-4ffd9786549f.1 h1:7+y3t/2/6sEf63xCX9ErNdsuFzB0Q18PIT14aAxz5wo=
|
||||||
|
buf.build/gen/go/safedep/api/grpc/go v1.5.1-20241009065537-4ffd9786549f.1/go.mod h1:Io32CuF5oJZDSkWJVgKvfOBTqSHnC7mqh9dpqq/PSNA=
|
||||||
|
buf.build/gen/go/safedep/api/grpc/go v1.5.1-20241011110723-95b33664baad.1 h1:bUOILp76S06U58bp3EWI6qsoeEEBGGQJeMFdQ5Otc34=
|
||||||
|
buf.build/gen/go/safedep/api/grpc/go v1.5.1-20241011110723-95b33664baad.1/go.mod h1:LSghi5M4Z+uYLyo85Bs6lVpzit6ZoSph8YOyvpHL3mY=
|
||||||
|
buf.build/gen/go/safedep/api/protocolbuffers/go v1.35.1-20241008111718-480f2b42b425.1 h1:IziBLru8MusSLO2lNDzSxbVxKu0dGI8zE8vG+tCMYjI=
|
||||||
|
buf.build/gen/go/safedep/api/protocolbuffers/go v1.35.1-20241008111718-480f2b42b425.1/go.mod h1:WCxZaBpYxgWnSpauuzVhzbJawAp6uPXJPN5tbDpceQ0=
|
||||||
|
buf.build/gen/go/safedep/api/protocolbuffers/go v1.35.1-20241009065537-4ffd9786549f.1 h1:F4fk9nhlB2ZU8odF5S/w/nS8r0htIbu6eKDKDBP+kzQ=
|
||||||
|
buf.build/gen/go/safedep/api/protocolbuffers/go v1.35.1-20241009065537-4ffd9786549f.1/go.mod h1:WCxZaBpYxgWnSpauuzVhzbJawAp6uPXJPN5tbDpceQ0=
|
||||||
|
buf.build/gen/go/safedep/api/protocolbuffers/go v1.35.1-20241011110723-95b33664baad.1 h1:HMED4kNSQJgrmFZXorIP1mpVbnKxzvhMgc3BOawTtGw=
|
||||||
|
buf.build/gen/go/safedep/api/protocolbuffers/go v1.35.1-20241011110723-95b33664baad.1/go.mod h1:WCxZaBpYxgWnSpauuzVhzbJawAp6uPXJPN5tbDpceQ0=
|
||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
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.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.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||||
@ -71,9 +85,6 @@ github.com/Joker/hpp v1.0.0 h1:65+iuJYdRXv/XyN62C1uEmmOx3432rNG/rKlX6V7Kkc=
|
|||||||
github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY=
|
github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY=
|
||||||
github.com/Joker/jade v1.1.3 h1:Qbeh12Vq6BxURXT1qZBRHsDxeURB8ztcL6f3EXSGeHk=
|
github.com/Joker/jade v1.1.3 h1:Qbeh12Vq6BxURXT1qZBRHsDxeURB8ztcL6f3EXSGeHk=
|
||||||
github.com/Joker/jade v1.1.3/go.mod h1:T+2WLyt7VH6Lp0TRxQrUYEs64nRc83wkMQrfeIQKduM=
|
github.com/Joker/jade v1.1.3/go.mod h1:T+2WLyt7VH6Lp0TRxQrUYEs64nRc83wkMQrfeIQKduM=
|
||||||
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
|
|
||||||
github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0=
|
|
||||||
github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
|
|
||||||
github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0=
|
github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0=
|
||||||
github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
|
github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
|
||||||
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||||
@ -88,6 +99,8 @@ github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azu
|
|||||||
github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk=
|
github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk=
|
||||||
github.com/Shopify/goreferrer v0.0.0-20240724165105-aceaa0259138 h1:gjbp60h8IZQbN/TpDaYJedWbbD1h1aDPEwWnYWaDaUY=
|
github.com/Shopify/goreferrer v0.0.0-20240724165105-aceaa0259138 h1:gjbp60h8IZQbN/TpDaYJedWbbD1h1aDPEwWnYWaDaUY=
|
||||||
github.com/Shopify/goreferrer v0.0.0-20240724165105-aceaa0259138/go.mod h1:NYezi6wtnJtBm5btoprXc5SvAdqH0XTXWnUup0MptAI=
|
github.com/Shopify/goreferrer v0.0.0-20240724165105-aceaa0259138/go.mod h1:NYezi6wtnJtBm5btoprXc5SvAdqH0XTXWnUup0MptAI=
|
||||||
|
github.com/abhisek/oauth v1.0.1-audience h1:nFfFPI3sRc1ofYIqt12WPFmSYSHsBBo4boLVmASiQgw=
|
||||||
|
github.com/abhisek/oauth v1.0.1-audience/go.mod h1:qd/FX8ZBD6n1sVNQO3aIdRxeu5LGw9WhKnYhIIoC2A4=
|
||||||
github.com/acobaugh/osrelease v0.1.0 h1:Yb59HQDGGNhCj4suHaFQQfBps5wyoKLSSX/J/+UifRE=
|
github.com/acobaugh/osrelease v0.1.0 h1:Yb59HQDGGNhCj4suHaFQQfBps5wyoKLSSX/J/+UifRE=
|
||||||
github.com/acobaugh/osrelease v0.1.0/go.mod h1:4bFEs0MtgHNHBrmHCt67gNisnabCRAlzdVasCEGHTWY=
|
github.com/acobaugh/osrelease v0.1.0/go.mod h1:4bFEs0MtgHNHBrmHCt67gNisnabCRAlzdVasCEGHTWY=
|
||||||
github.com/adrg/xdg v0.5.0 h1:dDaZvhMXatArP1NPHhnfaQUqWBLBsmx1h1HXQdMoFCY=
|
github.com/adrg/xdg v0.5.0 h1:dDaZvhMXatArP1NPHhnfaQUqWBLBsmx1h1HXQdMoFCY=
|
||||||
@ -100,22 +113,14 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy
|
|||||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/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=
|
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
github.com/anchore/clio v0.0.0-20240522144804-d81e109008aa h1:pwlAn4O9SBUnlgfa69YcqIynbUyobLVFYu8HxSoCffA=
|
|
||||||
github.com/anchore/clio v0.0.0-20240522144804-d81e109008aa/go.mod h1:nD3H5uIvjxlfmakOBgtyFQbk5Zjp3l538kxfpHPslzI=
|
|
||||||
github.com/anchore/clio v0.0.0-20240806233806-4c50c054c508 h1:dE7xKzC2eqd7QVt95jJaIbx6Kax/0GF8R1ppsXkfpCM=
|
github.com/anchore/clio v0.0.0-20240806233806-4c50c054c508 h1:dE7xKzC2eqd7QVt95jJaIbx6Kax/0GF8R1ppsXkfpCM=
|
||||||
github.com/anchore/clio v0.0.0-20240806233806-4c50c054c508/go.mod h1:5q0B4t18buA/F3B5cd3+CQsyuyXd+4xCirEW7t5mNTk=
|
github.com/anchore/clio v0.0.0-20240806233806-4c50c054c508/go.mod h1:5q0B4t18buA/F3B5cd3+CQsyuyXd+4xCirEW7t5mNTk=
|
||||||
github.com/anchore/fangs v0.0.0-20240508143433-f016b099950f h1:NOhzafCyNYFi88qxkBFjMzQo4dRa1vDhBzx+0Uovx8Q=
|
|
||||||
github.com/anchore/fangs v0.0.0-20240508143433-f016b099950f/go.mod h1:sVpRS2yNCw6tLVpvA1QSDVWTJVpCuAm8JNZgn4Sjz/k=
|
|
||||||
github.com/anchore/fangs v0.0.0-20240904151251-ac0148f53e5d h1:gdAg7ItS+SaNi+VZBHzVZtfLgqCXQi1uM6wGS/Q9s48=
|
github.com/anchore/fangs v0.0.0-20240904151251-ac0148f53e5d h1:gdAg7ItS+SaNi+VZBHzVZtfLgqCXQi1uM6wGS/Q9s48=
|
||||||
github.com/anchore/fangs v0.0.0-20240904151251-ac0148f53e5d/go.mod h1:Xh4ObY3fmoMzOEVXwDtS1uK44JC7+nRD0n29/1KYFYg=
|
github.com/anchore/fangs v0.0.0-20240904151251-ac0148f53e5d/go.mod h1:Xh4ObY3fmoMzOEVXwDtS1uK44JC7+nRD0n29/1KYFYg=
|
||||||
github.com/anchore/go-collections v0.0.0-20240216171411-9321230ce537 h1:GjNGuwK5jWjJMyVppBjYS54eOiiSNv4Ba869k4wh72Q=
|
github.com/anchore/go-collections v0.0.0-20240216171411-9321230ce537 h1:GjNGuwK5jWjJMyVppBjYS54eOiiSNv4Ba869k4wh72Q=
|
||||||
github.com/anchore/go-collections v0.0.0-20240216171411-9321230ce537/go.mod h1:1aiktV46ATCkuVg0O573ZrH56BUawTECPETbZyBcqT8=
|
github.com/anchore/go-collections v0.0.0-20240216171411-9321230ce537/go.mod h1:1aiktV46ATCkuVg0O573ZrH56BUawTECPETbZyBcqT8=
|
||||||
github.com/anchore/go-logger v0.0.0-20230725134548-c21dafa1ec5a h1:nJ2G8zWKASyVClGVgG7sfM5mwoZlZ2zYpIzN2OhjWkw=
|
|
||||||
github.com/anchore/go-logger v0.0.0-20230725134548-c21dafa1ec5a/go.mod h1:ubLFmlsv8/DFUQrZwY5syT5/8Er3ugSr4rDFwHsE3hg=
|
|
||||||
github.com/anchore/go-logger v0.0.0-20240217160628-ee28a485904f h1:qRQCz19ioRN2FtAct4j6Lb3Nl0VolFiuHtYMezGYBn0=
|
github.com/anchore/go-logger v0.0.0-20240217160628-ee28a485904f h1:qRQCz19ioRN2FtAct4j6Lb3Nl0VolFiuHtYMezGYBn0=
|
||||||
github.com/anchore/go-logger v0.0.0-20240217160628-ee28a485904f/go.mod h1:ErB21zunlmQOE/aFPkt4Tv2Q00ttFxPZ2l87gSXxSec=
|
github.com/anchore/go-logger v0.0.0-20240217160628-ee28a485904f/go.mod h1:ErB21zunlmQOE/aFPkt4Tv2Q00ttFxPZ2l87gSXxSec=
|
||||||
github.com/anchore/go-macholibre v0.0.0-20220308212642-53e6d0aaf6fb h1:iDMnx6LIjtjZ46C0akqveX83WFzhpTD3eqOthawb5vU=
|
|
||||||
github.com/anchore/go-macholibre v0.0.0-20220308212642-53e6d0aaf6fb/go.mod h1:DmTY2Mfcv38hsHbG78xMiTDdxFtkHpgYNVDPsF2TgHk=
|
|
||||||
github.com/anchore/go-macholibre v0.0.0-20240116161251-5df1434a0b50 h1:HqAfjHHdD6P+U6iVcJl1cGYOh5YNUIffZ12fZfwMWpw=
|
github.com/anchore/go-macholibre v0.0.0-20240116161251-5df1434a0b50 h1:HqAfjHHdD6P+U6iVcJl1cGYOh5YNUIffZ12fZfwMWpw=
|
||||||
github.com/anchore/go-macholibre v0.0.0-20240116161251-5df1434a0b50/go.mod h1:xz7uczAHBrEQ3+kIb4bnsp74JqcKpBid+gznZil1X0Q=
|
github.com/anchore/go-macholibre v0.0.0-20240116161251-5df1434a0b50/go.mod h1:xz7uczAHBrEQ3+kIb4bnsp74JqcKpBid+gznZil1X0Q=
|
||||||
github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092/go.mod h1:rYqSE9HbjzpHTI74vwPvae4ZVYZd1lue2ta6xHPdblA=
|
github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092/go.mod h1:rYqSE9HbjzpHTI74vwPvae4ZVYZd1lue2ta6xHPdblA=
|
||||||
@ -125,8 +130,6 @@ github.com/anchore/go-testutils v0.0.0-20200925183923-d5f45b0d3c04 h1:VzprUTpc0v
|
|||||||
github.com/anchore/go-testutils v0.0.0-20200925183923-d5f45b0d3c04/go.mod h1:6dK64g27Qi1qGQZ67gFmBFvEHScy0/C8qhQhNe5B5pQ=
|
github.com/anchore/go-testutils v0.0.0-20200925183923-d5f45b0d3c04/go.mod h1:6dK64g27Qi1qGQZ67gFmBFvEHScy0/C8qhQhNe5B5pQ=
|
||||||
github.com/anchore/packageurl-go v0.1.1-0.20240507183024-848e011fc24f h1:B/E9ixKNCasntpoch61NDaQyGPDXLEJlL+B9B/PbdbA=
|
github.com/anchore/packageurl-go v0.1.1-0.20240507183024-848e011fc24f h1:B/E9ixKNCasntpoch61NDaQyGPDXLEJlL+B9B/PbdbA=
|
||||||
github.com/anchore/packageurl-go v0.1.1-0.20240507183024-848e011fc24f/go.mod h1:Blo6OgJNiYF41ufcgHKkbCKF2MDOMlrqhXv/ij6ocR4=
|
github.com/anchore/packageurl-go v0.1.1-0.20240507183024-848e011fc24f/go.mod h1:Blo6OgJNiYF41ufcgHKkbCKF2MDOMlrqhXv/ij6ocR4=
|
||||||
github.com/anchore/stereoscope v0.0.3-0.20240725180315-50ce3be7aa1f h1:xuBvotcht1Ns8IdaC4UuYV1U8MFln9c5ELeo5bzDEO8=
|
|
||||||
github.com/anchore/stereoscope v0.0.3-0.20240725180315-50ce3be7aa1f/go.mod h1:DcQdMes8SwpFli3rDH0v+Vd9qU9Jariq7JSHNJV5X/A=
|
|
||||||
github.com/anchore/stereoscope v0.0.3 h1:JRPHySy8S6P+Ff3IDiQ29ap1i8/laUQxDk9K1eFh/2U=
|
github.com/anchore/stereoscope v0.0.3 h1:JRPHySy8S6P+Ff3IDiQ29ap1i8/laUQxDk9K1eFh/2U=
|
||||||
github.com/anchore/stereoscope v0.0.3/go.mod h1:5DJheGPjVRsSqegTB24Zi6SCHnYQnA519yeIG+RG+I4=
|
github.com/anchore/stereoscope v0.0.3/go.mod h1:5DJheGPjVRsSqegTB24Zi6SCHnYQnA519yeIG+RG+I4=
|
||||||
github.com/anchore/syft v1.11.1 h1:uJVmZ1WuhMw2cutCsBj0aUgUZxaNlbBNimZEISFttWY=
|
github.com/anchore/syft v1.11.1 h1:uJVmZ1WuhMw2cutCsBj0aUgUZxaNlbBNimZEISFttWY=
|
||||||
@ -150,6 +153,7 @@ github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuP
|
|||||||
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
|
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
|
||||||
github.com/becheran/wildmatch-go v1.0.0 h1:mE3dGGkTmpKtT4Z+88t8RStG40yN9T+kFEGj2PZFSzA=
|
github.com/becheran/wildmatch-go v1.0.0 h1:mE3dGGkTmpKtT4Z+88t8RStG40yN9T+kFEGj2PZFSzA=
|
||||||
github.com/becheran/wildmatch-go v1.0.0/go.mod h1:gbMvj0NtVdJ15Mg/mH9uxk2R1QCistMyU7d9KFzroX4=
|
github.com/becheran/wildmatch-go v1.0.0/go.mod h1:gbMvj0NtVdJ15Mg/mH9uxk2R1QCistMyU7d9KFzroX4=
|
||||||
|
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
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 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||||
@ -163,8 +167,6 @@ github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx2
|
|||||||
github.com/bradleyjkemp/cupaloy/v2 v2.8.0 h1:any4BmKE+jGIaMpnU8YgH/I2LPiLBufr6oMMlVBbn9M=
|
github.com/bradleyjkemp/cupaloy/v2 v2.8.0 h1:any4BmKE+jGIaMpnU8YgH/I2LPiLBufr6oMMlVBbn9M=
|
||||||
github.com/bradleyjkemp/cupaloy/v2 v2.8.0/go.mod h1:bm7JXdkRd4BHJk9HpwqAI8BoAY1lps46Enkdqw6aRX0=
|
github.com/bradleyjkemp/cupaloy/v2 v2.8.0/go.mod h1:bm7JXdkRd4BHJk9HpwqAI8BoAY1lps46Enkdqw6aRX0=
|
||||||
github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
|
github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
|
||||||
github.com/bytedance/sonic v1.12.1 h1:jWl5Qz1fy7X1ioY74WqO0KjAMtAGQs4sYnjiEBiyX24=
|
|
||||||
github.com/bytedance/sonic v1.12.1/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk=
|
|
||||||
github.com/bytedance/sonic v1.12.2 h1:oaMFuRTpMHYLpCntGca65YWt5ny+wAceDERTkT2L9lg=
|
github.com/bytedance/sonic v1.12.2 h1:oaMFuRTpMHYLpCntGca65YWt5ny+wAceDERTkT2L9lg=
|
||||||
github.com/bytedance/sonic v1.12.2/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk=
|
github.com/bytedance/sonic v1.12.2/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk=
|
||||||
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||||
@ -178,7 +180,6 @@ github.com/cayleygraph/quad v1.3.0 h1:xg7HOLWWPgvZ4CcvzEpfCwq42L8mzYUR+8V0jtYoBz
|
|||||||
github.com/cayleygraph/quad v1.3.0/go.mod h1:NadtM7uMm78FskmX++XiOOrNvgkq0E1KvvhQdMseMz4=
|
github.com/cayleygraph/quad v1.3.0/go.mod h1:NadtM7uMm78FskmX++XiOOrNvgkq0E1KvvhQdMseMz4=
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
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.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
|
||||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
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.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
@ -198,13 +199,9 @@ github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38
|
|||||||
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
|
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
|
||||||
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
|
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
|
||||||
github.com/cli/browser v1.0.0/go.mod h1:IEWkHYbLjkhtjwwWlwTHW2lGxeS5gezEQBMLTwDHf5Q=
|
github.com/cli/browser v1.0.0/go.mod h1:IEWkHYbLjkhtjwwWlwTHW2lGxeS5gezEQBMLTwDHf5Q=
|
||||||
github.com/cli/oauth v1.0.1 h1:pXnTFl/qUegXHK531Dv0LNjW4mLx626eS42gnzfXJPA=
|
|
||||||
github.com/cli/oauth v1.0.1/go.mod h1:qd/FX8ZBD6n1sVNQO3aIdRxeu5LGw9WhKnYhIIoC2A4=
|
|
||||||
github.com/cli/safeexec v1.0.0/go.mod h1:Z/D4tTN8Vs5gXYHDCbaM1S/anmEDnJb1iW0+EJ5zx3Q=
|
github.com/cli/safeexec v1.0.0/go.mod h1:Z/D4tTN8Vs5gXYHDCbaM1S/anmEDnJb1iW0+EJ5zx3Q=
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
|
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
|
||||||
github.com/cloudflare/circl v1.3.9 h1:QFrlgFYf2Qpi8bSpVPK1HBvWpx16v/1TZivyo7pGuBE=
|
|
||||||
github.com/cloudflare/circl v1.3.9/go.mod h1:PDRU+oXvdD7KCtgKxW95M5Z8BpSCJXQORiZFnBQS5QU=
|
|
||||||
github.com/cloudflare/circl v1.4.0 h1:BV7h5MgrktNzytKmWjpOtdYrf0lkkbF8YMlBGPhJQrY=
|
github.com/cloudflare/circl v1.4.0 h1:BV7h5MgrktNzytKmWjpOtdYrf0lkkbF8YMlBGPhJQrY=
|
||||||
github.com/cloudflare/circl v1.4.0/go.mod h1:PDRU+oXvdD7KCtgKxW95M5Z8BpSCJXQORiZFnBQS5QU=
|
github.com/cloudflare/circl v1.4.0/go.mod h1:PDRU+oXvdD7KCtgKxW95M5Z8BpSCJXQORiZFnBQS5QU=
|
||||||
github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=
|
github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=
|
||||||
@ -225,8 +222,6 @@ github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b h1:ga8SEFjZ60pxLcmhnTh
|
|||||||
github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
|
github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
|
||||||
github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
|
github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
|
||||||
github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw=
|
github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw=
|
||||||
github.com/containerd/containerd v1.7.19 h1:/xQ4XRJ0tamDkdzrrBAUy/LE5nCcxFKdBm4EcPrSMEE=
|
|
||||||
github.com/containerd/containerd v1.7.19/go.mod h1:h4FtNYUUMB4Phr6v+xG89RYKj9XccvbNSCKjdufCrkc=
|
|
||||||
github.com/containerd/containerd v1.7.21 h1:USGXRK1eOC/SX0L195YgxTHb0a00anxajOzgfN0qrCA=
|
github.com/containerd/containerd v1.7.21 h1:USGXRK1eOC/SX0L195YgxTHb0a00anxajOzgfN0qrCA=
|
||||||
github.com/containerd/containerd v1.7.21/go.mod h1:e3Jz1rYRUZ2Lt51YrH9Rz0zPyJBOlSvB3ghr2jbVD8g=
|
github.com/containerd/containerd v1.7.21/go.mod h1:e3Jz1rYRUZ2Lt51YrH9Rz0zPyJBOlSvB3ghr2jbVD8g=
|
||||||
github.com/containerd/containerd/api v1.7.19 h1:VWbJL+8Ap4Ju2mx9c9qS1uFSB1OVYr5JJrW2yT5vFoA=
|
github.com/containerd/containerd/api v1.7.19 h1:VWbJL+8Ap4Ju2mx9c9qS1uFSB1OVYr5JJrW2yT5vFoA=
|
||||||
@ -269,28 +264,20 @@ github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5Qvfr
|
|||||||
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||||
github.com/dlclark/regexp2 v1.11.4 h1:rPYF9/LECdNymJufQKmri9gV604RvvABwgOA8un7yAo=
|
github.com/dlclark/regexp2 v1.11.4 h1:rPYF9/LECdNymJufQKmri9gV604RvvABwgOA8un7yAo=
|
||||||
github.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
github.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||||
github.com/docker/cli v27.1.1+incompatible h1:goaZxOqs4QKxznZjjBWKONQci/MywhtRv2oNn0GkeZE=
|
|
||||||
github.com/docker/cli v27.1.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
|
||||||
github.com/docker/cli v27.2.0+incompatible h1:yHD1QEB1/0vr5eBNpu8tncu8gWxg8EydFPOSKHzXSMM=
|
github.com/docker/cli v27.2.0+incompatible h1:yHD1QEB1/0vr5eBNpu8tncu8gWxg8EydFPOSKHzXSMM=
|
||||||
github.com/docker/cli v27.2.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
github.com/docker/cli v27.2.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||||
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
|
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
|
||||||
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||||
github.com/docker/docker v27.1.2+incompatible h1:AhGzR1xaQIy53qCkxARaFluI00WPGtXn0AJuoQsVYTY=
|
github.com/docker/docker v27.1.2+incompatible h1:AhGzR1xaQIy53qCkxARaFluI00WPGtXn0AJuoQsVYTY=
|
||||||
github.com/docker/docker v27.1.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
github.com/docker/docker v27.1.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||||
github.com/docker/docker-credential-helpers v0.8.1 h1:j/eKUktUltBtMzKqmfLB0PAgqYyMHOp5vfsD1807oKo=
|
|
||||||
github.com/docker/docker-credential-helpers v0.8.1/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M=
|
|
||||||
github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo=
|
github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo=
|
||||||
github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M=
|
github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M=
|
||||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
|
||||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
|
||||||
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
|
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
|
||||||
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
|
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
|
||||||
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8=
|
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8=
|
||||||
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
|
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
|
||||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||||
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||||
github.com/dop251/goja v0.0.0-20240806095544-3491d4a58fbe h1:jwFJkgsdelB87ohlXaAGSd05Cb5ALDFa9iW9IGRHcRM=
|
|
||||||
github.com/dop251/goja v0.0.0-20240806095544-3491d4a58fbe/go.mod h1:DF+w/nLMIkvRpyhd/0K+Okbh3fVZBtXLwRtS/ccAa5w=
|
|
||||||
github.com/dop251/goja v0.0.0-20240828124009-016eb7256539 h1:YIxvsQAoCLGScK2c9ag+4sFCgiQFpMzywJG6dQZFu9k=
|
github.com/dop251/goja v0.0.0-20240828124009-016eb7256539 h1:YIxvsQAoCLGScK2c9ag+4sFCgiQFpMzywJG6dQZFu9k=
|
||||||
github.com/dop251/goja v0.0.0-20240828124009-016eb7256539/go.mod h1:MxLav0peU43GgvwVgNbLAj1s/bSGboKkhuULvq/7hx4=
|
github.com/dop251/goja v0.0.0-20240828124009-016eb7256539/go.mod h1:MxLav0peU43GgvwVgNbLAj1s/bSGboKkhuULvq/7hx4=
|
||||||
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 h1:iFaUwBSo5Svw6L7HYpRu/0lE3e0BaElwnNO1qkNQxBY=
|
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 h1:iFaUwBSo5Svw6L7HYpRu/0lE3e0BaElwnNO1qkNQxBY=
|
||||||
@ -305,8 +292,8 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.m
|
|||||||
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.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.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
|
||||||
github.com/envoyproxy/go-control-plane v0.10.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPOWUZ7hQAEvzN5Pf27BkQQ=
|
github.com/envoyproxy/go-control-plane v0.10.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPOWUZ7hQAEvzN5Pf27BkQQ=
|
||||||
github.com/envoyproxy/go-control-plane v0.12.0 h1:4X+VP1GHd1Mhj6IB5mMeGbLCleqxjletLK6K0rbxyZI=
|
github.com/envoyproxy/go-control-plane v0.12.1-0.20240621013728-1eb8caab5155 h1:IgJPqnrlY2Mr4pYB6oaMKvFvwJ9H+X6CCY5x1vCTcpc=
|
||||||
github.com/envoyproxy/go-control-plane v0.12.0/go.mod h1:ZBTaoJ23lqITozF0M6G4/IragXCQKCnYbmlmtHvwRG0=
|
github.com/envoyproxy/go-control-plane v0.12.1-0.20240621013728-1eb8caab5155/go.mod h1:5Wkq+JduFtdAXihLmeTJf+tRYIT4KBc2vPXDhwVo1pA=
|
||||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||||
github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws=
|
github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws=
|
||||||
github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A=
|
github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A=
|
||||||
@ -323,7 +310,6 @@ github.com/fatih/set v0.2.1 h1:nn2CaJyknWE/6txyUDGwysr3G5QC6xWB/PtVjPBbeaA=
|
|||||||
github.com/fatih/set v0.2.1/go.mod h1:+RKtMCH+favT2+3YecHGxcc0b4KyVWA1QWWJUs4E0CI=
|
github.com/fatih/set v0.2.1/go.mod h1:+RKtMCH+favT2+3YecHGxcc0b4KyVWA1QWWJUs4E0CI=
|
||||||
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
|
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
|
||||||
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
||||||
github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g=
|
|
||||||
github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw=
|
github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw=
|
||||||
github.com/felixge/fgprof v0.9.5 h1:8+vR6yu2vvSKn08urWyEuxx75NWPEvybbkBirEpsbVY=
|
github.com/felixge/fgprof v0.9.5 h1:8+vR6yu2vvSKn08urWyEuxx75NWPEvybbkBirEpsbVY=
|
||||||
github.com/felixge/fgprof v0.9.5/go.mod h1:yKl+ERSa++RYOs32d8K6WEXCB4uXdLls4ZaZPpayhMM=
|
github.com/felixge/fgprof v0.9.5/go.mod h1:yKl+ERSa++RYOs32d8K6WEXCB4uXdLls4ZaZPpayhMM=
|
||||||
@ -345,13 +331,22 @@ github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
|
|||||||
github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
|
github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
|
||||||
github.com/github/go-spdx/v2 v2.3.1 h1:ffGuHTbHuHzWPt53n8f9o8clGutuLPObo3zB4JAjxU8=
|
github.com/github/go-spdx/v2 v2.3.1 h1:ffGuHTbHuHzWPt53n8f9o8clGutuLPObo3zB4JAjxU8=
|
||||||
github.com/github/go-spdx/v2 v2.3.1/go.mod h1:2ZxKsOhvBp+OYBDlsGnUMcchLeo2mrpEBn2L1C+U3IQ=
|
github.com/github/go-spdx/v2 v2.3.1/go.mod h1:2ZxKsOhvBp+OYBDlsGnUMcchLeo2mrpEBn2L1C+U3IQ=
|
||||||
|
github.com/gkampitakis/ciinfo v0.3.0 h1:gWZlOC2+RYYttL0hBqcoQhM7h1qNkVqvRCV1fOvpAv8=
|
||||||
|
github.com/gkampitakis/ciinfo v0.3.0/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo=
|
||||||
|
github.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZdC4M=
|
||||||
|
github.com/gkampitakis/go-diff v1.3.2/go.mod h1:LLgOrpqleQe26cte8s36HTWcTmMEur6OPYerdAAS9tk=
|
||||||
|
github.com/gkampitakis/go-snaps v0.5.7 h1:uVGjHR4t4pPHU944udMx7VKHpwepZXmvDMF+yDmI0rg=
|
||||||
|
github.com/gkampitakis/go-snaps v0.5.7/go.mod h1:ZABkO14uCuVxBHAXAfKG+bqNz+aa1bGPAg8jkI0Nk8Y=
|
||||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
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-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-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.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||||
github.com/go-kit/kit v0.9.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-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
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.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 v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||||
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
|
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
|
||||||
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||||
@ -464,8 +459,6 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi
|
|||||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
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.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.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
|
||||||
github.com/google/osv-scanner v1.8.3 h1:TVPk2aWhPK+bjp9ZPdGRphG/pwRq4nlyBqHsfQV3keQ=
|
|
||||||
github.com/google/osv-scanner v1.8.3/go.mod h1:O6tZsJMb/QYXzLjnxHBNLutjsdm8tsrmljiq1WxW8u4=
|
|
||||||
github.com/google/osv-scanner v1.8.4 h1:CScR1b8GqvgbUwG5+bvOlyeE8dtl4zNmh3IDlJE2ZeY=
|
github.com/google/osv-scanner v1.8.4 h1:CScR1b8GqvgbUwG5+bvOlyeE8dtl4zNmh3IDlJE2ZeY=
|
||||||
github.com/google/osv-scanner v1.8.4/go.mod h1:ImQyo6WCoZ10iI20zD+iqt0g8cS5gJegqN0ngT1x53M=
|
github.com/google/osv-scanner v1.8.4/go.mod h1:ImQyo6WCoZ10iI20zD+iqt0g8cS5gJegqN0ngT1x53M=
|
||||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||||
@ -484,8 +477,6 @@ github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLe
|
|||||||
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||||
github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg=
|
github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg=
|
||||||
github.com/google/pprof v0.0.0-20240227163752-401108e1b7e7/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
|
github.com/google/pprof v0.0.0-20240227163752-401108e1b7e7/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
|
||||||
github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k=
|
|
||||||
github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo=
|
|
||||||
github.com/google/pprof v0.0.0-20240903155634-a8630aee4ab9 h1:q5g0N9eal4bmJwXHC5z0QCKs8qhS35hFfq0BAYsIwZI=
|
github.com/google/pprof v0.0.0-20240903155634-a8630aee4ab9 h1:q5g0N9eal4bmJwXHC5z0QCKs8qhS35hFfq0BAYsIwZI=
|
||||||
github.com/google/pprof v0.0.0-20240903155634-a8630aee4ab9/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
|
github.com/google/pprof v0.0.0-20240903155634-a8630aee4ab9/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
|
||||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||||
@ -506,6 +497,8 @@ github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8=
|
|||||||
github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0=
|
github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0=
|
||||||
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
|
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
|
||||||
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
|
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
|
||||||
|
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI=
|
||||||
|
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8=
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||||
github.com/hashicorp/consul/api v1.11.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M=
|
github.com/hashicorp/consul/api v1.11.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M=
|
||||||
github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms=
|
github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms=
|
||||||
@ -603,7 +596,6 @@ github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgo
|
|||||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||||
github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM=
|
github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM=
|
||||||
github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||||
github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE=
|
|
||||||
github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||||
github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=
|
github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=
|
||||||
github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||||
@ -638,6 +630,8 @@ github.com/mailgun/raymond/v2 v2.0.48 h1:5dmlB680ZkFG2RN/0lvTAghrSxIESeu9/2aeDqA
|
|||||||
github.com/mailgun/raymond/v2 v2.0.48/go.mod h1:lsgvL50kgt1ylcFJYZiULi5fjPBkkhNfj4KA0W54Z18=
|
github.com/mailgun/raymond/v2 v2.0.48/go.mod h1:lsgvL50kgt1ylcFJYZiULi5fjPBkkhNfj4KA0W54Z18=
|
||||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||||
|
github.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo=
|
||||||
|
github.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg=
|
||||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||||
@ -691,9 +685,10 @@ github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5
|
|||||||
github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo=
|
github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo=
|
||||||
github.com/moby/sys/signal v0.7.0 h1:25RW3d5TnQEoKvRbEKUGay6DCQ46IxAVTT9CUMgmsSI=
|
github.com/moby/sys/signal v0.7.0 h1:25RW3d5TnQEoKvRbEKUGay6DCQ46IxAVTT9CUMgmsSI=
|
||||||
github.com/moby/sys/signal v0.7.0/go.mod h1:GQ6ObYZfqacOwTtlXvcmh9A26dVRul/hbOZn88Kg8Tg=
|
github.com/moby/sys/signal v0.7.0/go.mod h1:GQ6ObYZfqacOwTtlXvcmh9A26dVRul/hbOZn88Kg8Tg=
|
||||||
github.com/moby/sys/user v0.1.0 h1:WmZ93f5Ux6het5iituh9x2zAG7NFY9Aqi49jjE1PaQg=
|
|
||||||
github.com/moby/sys/user v0.1.0/go.mod h1:fKJhFOnsCN6xZ5gSfbM6zaHGgDJMrqt9/reuj4T7MmU=
|
|
||||||
github.com/moby/sys/user v0.3.0 h1:9ni5DlcW5an3SvRSx4MouotOygvzaXbaSrc/wGDFWPo=
|
github.com/moby/sys/user v0.3.0 h1:9ni5DlcW5an3SvRSx4MouotOygvzaXbaSrc/wGDFWPo=
|
||||||
|
github.com/moby/sys/user v0.3.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs=
|
||||||
|
github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g=
|
||||||
|
github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
@ -705,7 +700,6 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq
|
|||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/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-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||||
github.com/nwaples/rardecode v1.1.0 h1:vSxaY8vQhOcVr4mm5e8XllHWTiM4JF507A0Katqw7MQ=
|
|
||||||
github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0=
|
github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0=
|
||||||
github.com/nwaples/rardecode v1.1.3 h1:cWCaZwfM5H7nAD6PyEdcVnczzV8i/JtotnyW/dD9lEc=
|
github.com/nwaples/rardecode v1.1.3 h1:cWCaZwfM5H7nAD6PyEdcVnczzV8i/JtotnyW/dD9lEc=
|
||||||
github.com/nwaples/rardecode v1.1.3/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0=
|
github.com/nwaples/rardecode v1.1.3/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0=
|
||||||
@ -719,8 +713,8 @@ github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bl
|
|||||||
github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||||
github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaLpt7tQ7oU=
|
github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaLpt7tQ7oU=
|
||||||
github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec=
|
github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec=
|
||||||
|
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||||
github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0=
|
github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0=
|
||||||
github.com/owenrumney/go-sarif v1.1.1 h1:QNObu6YX1igyFKhdzd7vgzmw7XsWN3/6NMGuDzBgXmE=
|
|
||||||
github.com/owenrumney/go-sarif v1.1.1/go.mod h1:dNDiPlF04ESR/6fHlPyq7gHKmrM0sHUvAGjsoh8ZH0U=
|
github.com/owenrumney/go-sarif v1.1.1/go.mod h1:dNDiPlF04ESR/6fHlPyq7gHKmrM0sHUvAGjsoh8ZH0U=
|
||||||
github.com/owenrumney/go-sarif/v2 v2.3.3 h1:ubWDJcF5i3L/EIOER+ZyQ03IfplbSU1BLOE26uKQIIU=
|
github.com/owenrumney/go-sarif/v2 v2.3.3 h1:ubWDJcF5i3L/EIOER+ZyQ03IfplbSU1BLOE26uKQIIU=
|
||||||
github.com/owenrumney/go-sarif/v2 v2.3.3/go.mod h1:MSqMMx9WqlBSY7pXoOZWgEsVB4FDNfhcaXDA1j6Sr+w=
|
github.com/owenrumney/go-sarif/v2 v2.3.3/go.mod h1:MSqMMx9WqlBSY7pXoOZWgEsVB4FDNfhcaXDA1j6Sr+w=
|
||||||
@ -736,13 +730,9 @@ github.com/pborman/indent v1.2.1/go.mod h1:FitS+t35kIYtB5xWTZAPhnmrxcciEEOdbyrrp
|
|||||||
github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||||
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
|
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
|
||||||
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||||
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
|
|
||||||
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
|
||||||
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
|
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
|
||||||
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
|
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
|
||||||
github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||||
github.com/pierrec/lz4/v4 v4.1.19 h1:tYLzDnjDXh9qIxSTKHwXwOYmm9d887Y7Y1ZkyXYHAN4=
|
|
||||||
github.com/pierrec/lz4/v4 v4.1.19/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
|
||||||
github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ=
|
github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ=
|
||||||
github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||||
github.com/piprate/json-gold v0.5.0 h1:RmGh1PYboCFcchVFuh2pbSWAZy4XJaqTMU4KQYsApbM=
|
github.com/piprate/json-gold v0.5.0 h1:RmGh1PYboCFcchVFuh2pbSWAZy4XJaqTMU4KQYsApbM=
|
||||||
@ -754,6 +744,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
|
|||||||
github.com/pkg/profile v1.7.0 h1:hnbDkaNWPCLMO9wGLdBFTIZvzDrDfBM2072E1S9gJkA=
|
github.com/pkg/profile v1.7.0 h1:hnbDkaNWPCLMO9wGLdBFTIZvzDrDfBM2072E1S9gJkA=
|
||||||
github.com/pkg/profile v1.7.0/go.mod h1:8Uer0jas47ZQMJ7VD+OHknK4YDY07LPUC6dEvqDjvNo=
|
github.com/pkg/profile v1.7.0/go.mod h1:8Uer0jas47ZQMJ7VD+OHknK4YDY07LPUC6dEvqDjvNo=
|
||||||
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
|
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
|
||||||
|
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo=
|
||||||
|
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
@ -764,8 +756,6 @@ github.com/pquerna/cachecontrol v0.2.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQ
|
|||||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||||
github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
|
github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
|
||||||
github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE=
|
|
||||||
github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho=
|
|
||||||
github.com/prometheus/client_golang v1.20.3 h1:oPksm4K8B+Vt35tUhw6GbSNSgVlVSBH0qELP/7u83l4=
|
github.com/prometheus/client_golang v1.20.3 h1:oPksm4K8B+Vt35tUhw6GbSNSgVlVSBH0qELP/7u83l4=
|
||||||
github.com/prometheus/client_golang v1.20.3/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
|
github.com/prometheus/client_golang v1.20.3/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
|
||||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||||
@ -776,8 +766,6 @@ github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p
|
|||||||
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||||
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
|
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
|
||||||
github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
|
|
||||||
github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
|
|
||||||
github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0=
|
github.com/prometheus/common v0.59.1 h1:LXb1quJHWm1P6wq/U824uxYi4Sg0oGvNeUm1z5dJoX0=
|
||||||
github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0=
|
github.com/prometheus/common v0.59.1/go.mod h1:GpWM7dewqmVYcd7SmRaiWVe9SSqjf0UrwnYnpEZNuT0=
|
||||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
@ -799,11 +787,9 @@ github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99
|
|||||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||||
github.com/safedep/dry v0.0.0-20240808054916-b31bac30d0ef h1:liYqq19DtflpN4gX2aaGUN0XJJYC/xnhx703GR+CJYU=
|
github.com/safedep/dry v0.0.0-20240927023913-bb455ab56626 h1:0WadRINp2CAx5AvZkix9uFsibU9PXTtmoass7H+Z+9w=
|
||||||
github.com/safedep/dry v0.0.0-20240808054916-b31bac30d0ef/go.mod h1:OHfFlBHlJsIJyK3vsc40yaInGUxrzPhwYu8hM1h+kxs=
|
github.com/safedep/dry v0.0.0-20240927023913-bb455ab56626/go.mod h1:OHfFlBHlJsIJyK3vsc40yaInGUxrzPhwYu8hM1h+kxs=
|
||||||
github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig=
|
github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig=
|
||||||
github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ=
|
|
||||||
github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4=
|
|
||||||
github.com/sagikazarmark/locafero v0.6.0 h1:ON7AQg37yzcRPU69mt7gwhFEBwxI6P9T4Qu3N51bwOk=
|
github.com/sagikazarmark/locafero v0.6.0 h1:ON7AQg37yzcRPU69mt7gwhFEBwxI6P9T4Qu3N51bwOk=
|
||||||
github.com/sagikazarmark/locafero v0.6.0/go.mod h1:77OmuIc6VTraTXKXIs/uvUxKGUXjE1GbemJYHqdNjX0=
|
github.com/sagikazarmark/locafero v0.6.0/go.mod h1:77OmuIc6VTraTXKXIs/uvUxKGUXjE1GbemJYHqdNjX0=
|
||||||
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
|
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
|
||||||
@ -826,8 +812,6 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd
|
|||||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||||
github.com/smacker/go-tree-sitter v0.0.0-20240625050157-a31a98a7c0f6 h1:mtD4ESyObQZnRVxHFcaYp2d7jMBDa4WJRXSB1Vszj+A=
|
|
||||||
github.com/smacker/go-tree-sitter v0.0.0-20240625050157-a31a98a7c0f6/go.mod h1:q99oHDsbP0xRwmn7Vmob8gbSMNyvJ83OauXPSuHQuKE=
|
|
||||||
github.com/smacker/go-tree-sitter v0.0.0-20240827094217-dd81d9e9be82 h1:6C8qej6f1bStuePVkLSFxoU22XBS165D3klxlzRg8F4=
|
github.com/smacker/go-tree-sitter v0.0.0-20240827094217-dd81d9e9be82 h1:6C8qej6f1bStuePVkLSFxoU22XBS165D3klxlzRg8F4=
|
||||||
github.com/smacker/go-tree-sitter v0.0.0-20240827094217-dd81d9e9be82/go.mod h1:xe4pgH49k4SsmkQq5OT8abwhWmnzkhpgnXeekbx2efw=
|
github.com/smacker/go-tree-sitter v0.0.0-20240827094217-dd81d9e9be82/go.mod h1:xe4pgH49k4SsmkQq5OT8abwhWmnzkhpgnXeekbx2efw=
|
||||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
||||||
@ -845,8 +829,6 @@ github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z
|
|||||||
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
|
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
|
||||||
github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
|
github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
|
||||||
github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||||
github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
|
|
||||||
github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
|
||||||
github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w=
|
github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w=
|
||||||
github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
||||||
github.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4=
|
github.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4=
|
||||||
@ -875,7 +857,6 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
|
|||||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
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.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.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.4/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
|
||||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
@ -899,6 +880,14 @@ github.com/terminalstatic/go-xsd-validate v0.1.5 h1:RqpJnf6HGE2CB/lZB1A8BYguk8uR
|
|||||||
github.com/terminalstatic/go-xsd-validate v0.1.5/go.mod h1:18lsvYFofBflqCrvo1umpABZ99+GneNTw2kEEc8UPJw=
|
github.com/terminalstatic/go-xsd-validate v0.1.5/go.mod h1:18lsvYFofBflqCrvo1umpABZ99+GneNTw2kEEc8UPJw=
|
||||||
github.com/therootcompany/xz v1.0.1 h1:CmOtsn1CbtmyYiusbfmhmkpAAETj0wBIH6kCYaX+xzw=
|
github.com/therootcompany/xz v1.0.1 h1:CmOtsn1CbtmyYiusbfmhmkpAAETj0wBIH6kCYaX+xzw=
|
||||||
github.com/therootcompany/xz v1.0.1/go.mod h1:3K3UH1yCKgBneZYhuQUvJ9HPD19UEXEI0BWbMn8qNMY=
|
github.com/therootcompany/xz v1.0.1/go.mod h1:3K3UH1yCKgBneZYhuQUvJ9HPD19UEXEI0BWbMn8qNMY=
|
||||||
|
github.com/tidwall/gjson v1.17.3 h1:bwWLZU7icoKRG+C+0PNwIKC6FCJO/Q3p2pZvuP0jN94=
|
||||||
|
github.com/tidwall/gjson v1.17.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||||
|
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||||
|
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||||
|
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
|
||||||
|
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||||
|
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
|
||||||
|
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
|
||||||
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
|
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
|
||||||
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||||
@ -966,6 +955,8 @@ 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.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
|
||||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||||
|
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg=
|
||||||
|
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0=
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk=
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk=
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw=
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw=
|
||||||
go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo=
|
go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo=
|
||||||
@ -976,16 +967,16 @@ go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y
|
|||||||
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
|
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
|
||||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||||
|
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
||||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||||
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
|
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
|
||||||
|
go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
|
||||||
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
||||||
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||||
golang.org/x/arch v0.9.0 h1:ub9TgUInamJ8mrZIGlBG6/4TqWeMszd4N8lNorbrr6k=
|
|
||||||
golang.org/x/arch v0.9.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
|
||||||
golang.org/x/arch v0.10.0 h1:S3huipmSclq3PJMNe76NGwkBR504WFkQ5dhzWzP8ZW8=
|
golang.org/x/arch v0.10.0 h1:S3huipmSclq3PJMNe76NGwkBR504WFkQ5dhzWzP8ZW8=
|
||||||
golang.org/x/arch v0.10.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
golang.org/x/arch v0.10.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
@ -1001,8 +992,6 @@ golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5y
|
|||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||||
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
|
|
||||||
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
|
|
||||||
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
|
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
|
||||||
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
|
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
@ -1015,8 +1004,6 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
|
|||||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/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-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-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||||
golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI=
|
|
||||||
golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ=
|
|
||||||
golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e h1:I88y4caeGeuDQxgdoFPUq097j7kNfw6uvuiNxUBfcBk=
|
golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e h1:I88y4caeGeuDQxgdoFPUq097j7kNfw6uvuiNxUBfcBk=
|
||||||
golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ=
|
golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ=
|
||||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||||
@ -1048,8 +1035,6 @@ 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.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
|
|
||||||
golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
|
||||||
golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
|
golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
|
||||||
golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
@ -1099,8 +1084,6 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug
|
|||||||
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
||||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
golang.org/x/net v0.6.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.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||||
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
|
|
||||||
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
|
|
||||||
golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
|
golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
|
||||||
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
|
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
@ -1120,8 +1103,6 @@ golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ
|
|||||||
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/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-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/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-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||||
golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA=
|
|
||||||
golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
|
||||||
golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs=
|
golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs=
|
||||||
golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
@ -1203,6 +1184,7 @@ golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/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-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-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/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-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
@ -1214,8 +1196,6 @@ 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.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.5.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.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
|
|
||||||
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
|
||||||
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
|
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
|
||||||
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.25.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-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
@ -1223,8 +1203,6 @@ golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuX
|
|||||||
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
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.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
|
||||||
golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU=
|
|
||||||
golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk=
|
|
||||||
golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM=
|
golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM=
|
||||||
golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8=
|
golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8=
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
@ -1239,8 +1217,6 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
|||||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
golang.org/x/text v0.4.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.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.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||||
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
|
|
||||||
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
|
||||||
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
|
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
|
||||||
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
@ -1265,6 +1241,7 @@ golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtn
|
|||||||
golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/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-20190911174233-4f2ddba30aff/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-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/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-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-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-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
@ -1370,6 +1347,7 @@ google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfG
|
|||||||
google.golang.org/genproto v0.0.0-20200305110556-506484158171/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-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-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||||
|
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||||
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/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-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-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||||
@ -1414,12 +1392,8 @@ google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ6
|
|||||||
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||||
google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y=
|
google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y=
|
||||||
google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s=
|
google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s=
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20240812133136-8ffd90a71988 h1:+/tmTy5zAieooKIXfzDm9KiA3Bv6JBwriRN9LY+yayk=
|
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20240812133136-8ffd90a71988/go.mod h1:4+X6GvPs+25wZKbQq9qyAXrwIRExv7w0Ea6MgZLZiDM=
|
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc=
|
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc=
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I=
|
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240812133136-8ffd90a71988 h1:V71AcdLZr2p8dC9dbOIMCpqi4EmRl8wUwnJzXXLmbmc=
|
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240812133136-8ffd90a71988/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
|
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
@ -1449,8 +1423,6 @@ google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnD
|
|||||||
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
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.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.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
|
||||||
google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc=
|
|
||||||
google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ=
|
|
||||||
google.golang.org/grpc v1.66.0 h1:DibZuoBznOxbDQxRINckZcUvnCEvrW9pcWIE2yF9r1c=
|
google.golang.org/grpc v1.66.0 h1:DibZuoBznOxbDQxRINckZcUvnCEvrW9pcWIE2yF9r1c=
|
||||||
google.golang.org/grpc v1.66.0/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y=
|
google.golang.org/grpc v1.66.0/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y=
|
||||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
|
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
|
||||||
@ -1467,8 +1439,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
|
|||||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
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.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
|
||||||
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
|
google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
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-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
@ -1504,8 +1476,6 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
|
|||||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
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.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.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||||
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A=
|
|
||||||
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
|
||||||
k8s.io/utils v0.0.0-20240902221715-702e33fdd3c3 h1:b2FmK8YH+QEwq/Sy2uAEhmqL5nPfGYbJOcaqjeYYZoA=
|
k8s.io/utils v0.0.0-20240902221715-702e33fdd3c3 h1:b2FmK8YH+QEwq/Sy2uAEhmqL5nPfGYbJOcaqjeYYZoA=
|
||||||
k8s.io/utils v0.0.0-20240902221715-702e33fdd3c3/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
k8s.io/utils v0.0.0-20240902221715-702e33fdd3c3/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||||
moul.io/http2curl/v2 v2.3.0 h1:9r3JfDzWPcbIklMOs2TnIFzDYvfAZvjeavG6EzP7jYs=
|
moul.io/http2curl/v2 v2.3.0 h1:9r3JfDzWPcbIklMOs2TnIFzDYvfAZvjeavG6EzP7jYs=
|
||||||
|
|||||||
@ -5,30 +5,44 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
apiUrlEnvKey = "VET_INSIGHTS_API_URL"
|
apiUrlEnvKey = "VET_INSIGHTS_API_URL"
|
||||||
apiKeyEnvKey = "VET_INSIGHTS_API_KEY"
|
apiKeyEnvKey = "VET_API_KEY"
|
||||||
apiKeyAlternateEnvKey = "VET_API_KEY"
|
apiKeyAlternateEnvKey = "VET_INSIGHTS_API_KEY"
|
||||||
communityModeEnvKey = "VET_COMMUNITY_MODE"
|
communityModeEnvKey = "VET_COMMUNITY_MODE"
|
||||||
|
controlTowerTenantEnvKey = "VET_CONTROL_TOWER_TENANT_ID"
|
||||||
|
|
||||||
defaultApiUrl = "https://api.safedep.io/insights/v1"
|
defaultApiUrl = "https://api.safedep.io/insights/v1"
|
||||||
defaultCommunityApiUrl = "https://api.safedep.io/insights-community/v1"
|
defaultCommunityApiUrl = "https://api.safedep.io/insights-community/v1"
|
||||||
defaultControlPlaneApiUrl = "https://api.safedep.io/control-plane/v1"
|
|
||||||
defaultSyncApiUrl = "https://api.safedep.io/sync/v1"
|
// gRPC service base URL.
|
||||||
|
defaultSyncApiUrl = "https://api.safedep.io"
|
||||||
|
defaultControlPlaneApiUrl = "https://cloud.safedep.io"
|
||||||
|
|
||||||
homeRelativeConfigPath = ".safedep/vet-auth.yml"
|
homeRelativeConfigPath = ".safedep/vet-auth.yml"
|
||||||
|
|
||||||
|
cloudIdentityServiceClientId = "QtXHUN3hOdbJbCiGU8FiNCnC2KtuROCu" // gitleaks:allow
|
||||||
|
cloudIdentityServiceAudience = "https://cloud.safedep.io"
|
||||||
|
cloudIdentityServiceBaseUrl = "https://auth.safedep.io"
|
||||||
|
cloudIdentityServiceDeviceCodeUrl = "https://auth.safedep.io/oauth/device/code"
|
||||||
|
cloudIdentityServiceTokenUrl = "https://auth.safedep.io/oauth/token"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
ApiUrl string `yaml:"api_url"`
|
ApiUrl string `yaml:"api_url"`
|
||||||
ApiKey string `yaml:"api_key"`
|
ApiKey string `yaml:"api_key"`
|
||||||
Community bool `yaml:"community"`
|
Community bool `yaml:"community"`
|
||||||
ControlPlaneApiUrl string `yaml:"cp_api_url"`
|
ControlPlaneApiUrl string `yaml:"control_api_url"`
|
||||||
SyncApiUrl string `yaml:"sync_api_url"`
|
SyncApiUrl string `yaml:"sync_api_url"`
|
||||||
|
TenantDomain string `yaml:"tenant_domain"`
|
||||||
|
CloudAccessToken string `yaml:"cloud_access_token"`
|
||||||
|
CloudRefreshToken string `yaml:"cloud_refresh_token"`
|
||||||
|
CloudAccessTokenUpdatedAt time.Time `yaml:"cloud_access_token_updated_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Global config to be used during runtime
|
// Global config to be used during runtime
|
||||||
@ -38,8 +52,58 @@ func init() {
|
|||||||
loadConfiguration()
|
loadConfiguration()
|
||||||
}
|
}
|
||||||
|
|
||||||
func Configure(m Config) error {
|
func DefaultConfig() Config {
|
||||||
globalConfig = &m
|
return Config{
|
||||||
|
ApiUrl: defaultApiUrl,
|
||||||
|
Community: false,
|
||||||
|
ControlPlaneApiUrl: defaultControlPlaneApiUrl,
|
||||||
|
SyncApiUrl: defaultSyncApiUrl,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func PersistApiKey(key, domain string) error {
|
||||||
|
if globalConfig == nil {
|
||||||
|
c := DefaultConfig()
|
||||||
|
globalConfig = &c
|
||||||
|
}
|
||||||
|
|
||||||
|
if domain != "" {
|
||||||
|
globalConfig.TenantDomain = domain
|
||||||
|
}
|
||||||
|
|
||||||
|
globalConfig.ApiUrl = defaultApiUrl
|
||||||
|
globalConfig.ApiKey = key
|
||||||
|
|
||||||
|
return persistConfiguration()
|
||||||
|
}
|
||||||
|
|
||||||
|
func PersistCloudTokens(accessToken, refreshToken, domain string) error {
|
||||||
|
if globalConfig == nil {
|
||||||
|
c := DefaultConfig()
|
||||||
|
globalConfig = &c
|
||||||
|
}
|
||||||
|
|
||||||
|
// We are explicitly check for empty string for domain
|
||||||
|
// because we do not want to overwrite the domain if it is
|
||||||
|
// not provided.
|
||||||
|
if domain != "" {
|
||||||
|
globalConfig.TenantDomain = domain
|
||||||
|
}
|
||||||
|
|
||||||
|
globalConfig.CloudAccessToken = accessToken
|
||||||
|
globalConfig.CloudRefreshToken = refreshToken
|
||||||
|
globalConfig.CloudAccessTokenUpdatedAt = time.Now()
|
||||||
|
|
||||||
|
return persistConfiguration()
|
||||||
|
}
|
||||||
|
|
||||||
|
func PersistTenantDomain(domain string) error {
|
||||||
|
if globalConfig == nil {
|
||||||
|
c := DefaultConfig()
|
||||||
|
globalConfig = &c
|
||||||
|
}
|
||||||
|
|
||||||
|
globalConfig.TenantDomain = domain
|
||||||
return persistConfiguration()
|
return persistConfiguration()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,15 +115,43 @@ func DefaultCommunityApiUrl() string {
|
|||||||
return defaultCommunityApiUrl
|
return defaultCommunityApiUrl
|
||||||
}
|
}
|
||||||
|
|
||||||
func DefaultControlPlaneApiUrl() string {
|
func CloudIdentityServiceClientId() string {
|
||||||
if (globalConfig != nil) && (globalConfig.ControlPlaneApiUrl != "") {
|
return cloudIdentityServiceClientId
|
||||||
return globalConfig.ControlPlaneApiUrl
|
|
||||||
}
|
|
||||||
|
|
||||||
return defaultControlPlaneApiUrl
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func DefaultSyncApiUrl() string {
|
func CloudIdentityServiceBaseUrl() string {
|
||||||
|
return cloudIdentityServiceBaseUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
func CloudIdentityServiceDeviceCodeUrl() string {
|
||||||
|
return cloudIdentityServiceDeviceCodeUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
func CloudIdentityServiceAudience() string {
|
||||||
|
return cloudIdentityServiceAudience
|
||||||
|
}
|
||||||
|
|
||||||
|
func CloudIdentityServiceTokenUrl() string {
|
||||||
|
return cloudIdentityServiceTokenUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
func CloudAccessToken() string {
|
||||||
|
if globalConfig != nil {
|
||||||
|
return globalConfig.CloudAccessToken
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func CloudRefreshToken() string {
|
||||||
|
if globalConfig != nil {
|
||||||
|
return globalConfig.CloudRefreshToken
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func SyncApiUrl() string {
|
||||||
if (globalConfig != nil) && (globalConfig.SyncApiUrl != "") {
|
if (globalConfig != nil) && (globalConfig.SyncApiUrl != "") {
|
||||||
return globalConfig.SyncApiUrl
|
return globalConfig.SyncApiUrl
|
||||||
}
|
}
|
||||||
@ -67,19 +159,40 @@ func DefaultSyncApiUrl() string {
|
|||||||
return defaultSyncApiUrl
|
return defaultSyncApiUrl
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ControlTowerUrl() string {
|
||||||
|
if (globalConfig != nil) && (globalConfig.ControlPlaneApiUrl != "") {
|
||||||
|
return globalConfig.ControlPlaneApiUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultControlPlaneApiUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
func TenantDomain() string {
|
||||||
|
tenantFromEnv := os.Getenv(controlTowerTenantEnvKey)
|
||||||
|
if tenantFromEnv != "" {
|
||||||
|
return tenantFromEnv
|
||||||
|
}
|
||||||
|
|
||||||
|
if globalConfig != nil {
|
||||||
|
return globalConfig.TenantDomain
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
func ApiUrl() string {
|
func ApiUrl() string {
|
||||||
if url, ok := os.LookupEnv(apiUrlEnvKey); ok {
|
if url, ok := os.LookupEnv(apiUrlEnvKey); ok {
|
||||||
return url
|
return url
|
||||||
}
|
}
|
||||||
|
|
||||||
if globalConfig != nil {
|
|
||||||
return globalConfig.ApiUrl
|
|
||||||
}
|
|
||||||
|
|
||||||
if CommunityMode() {
|
if CommunityMode() {
|
||||||
return defaultCommunityApiUrl
|
return defaultCommunityApiUrl
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if globalConfig != nil {
|
||||||
|
return globalConfig.ApiUrl
|
||||||
|
}
|
||||||
|
|
||||||
return defaultApiUrl
|
return defaultApiUrl
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,6 +231,14 @@ func SetRuntimeCommunityMode() {
|
|||||||
os.Setenv(communityModeEnvKey, "true")
|
os.Setenv(communityModeEnvKey, "true")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SetRuntimeCloudTenant(domain string) {
|
||||||
|
os.Setenv(controlTowerTenantEnvKey, domain)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetRuntimeApiKey(key string) {
|
||||||
|
os.Setenv(apiKeyEnvKey, key)
|
||||||
|
}
|
||||||
|
|
||||||
func loadConfiguration() error {
|
func loadConfiguration() error {
|
||||||
path, err := os.UserHomeDir()
|
path, err := os.UserHomeDir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
54
internal/auth/grpc.go
Normal file
54
internal/auth/grpc.go
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
package auth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/safedep/vet/pkg/common/logger"
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
|
||||||
|
drygrpc "github.com/safedep/dry/adapters/grpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Create a gRPC client connection for the control plane
|
||||||
|
// based on available configuration
|
||||||
|
func ControlPlaneClientConnection(name string) (*grpc.ClientConn, error) {
|
||||||
|
return cloudClientConnection(name, ControlTowerUrl(), CloudAccessToken())
|
||||||
|
}
|
||||||
|
|
||||||
|
func SyncClientConnection(name string) (*grpc.ClientConn, error) {
|
||||||
|
return cloudClientConnection(name, SyncApiUrl(), ApiKey())
|
||||||
|
}
|
||||||
|
|
||||||
|
func cloudClientConnection(name, loc, tok string) (*grpc.ClientConn, error) {
|
||||||
|
parsedUrl, err := url.Parse(loc)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
host, port := parsedUrl.Hostname(), parsedUrl.Port()
|
||||||
|
if port == "" {
|
||||||
|
port = "443"
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Debugf("Establishing grpc connection for: %s host: %s, port: %s",
|
||||||
|
name, host, port)
|
||||||
|
|
||||||
|
headers := http.Header{}
|
||||||
|
headers.Set("x-tenant-id", TenantDomain())
|
||||||
|
|
||||||
|
vetTenantMockUser := os.Getenv("VET_CONTROL_TOWER_MOCK_USER")
|
||||||
|
if vetTenantMockUser != "" {
|
||||||
|
headers.Set("x-mock-user", vetTenantMockUser)
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := drygrpc.GrpcClient(name, host, port,
|
||||||
|
tok, headers, []grpc.DialOption{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to create gRPC client: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return client, nil
|
||||||
|
}
|
||||||
@ -1,77 +0,0 @@
|
|||||||
package auth
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/deepmap/oapi-codegen/pkg/types"
|
|
||||||
"github.com/safedep/dry/utils"
|
|
||||||
"github.com/safedep/vet/gen/cpv1trials"
|
|
||||||
"github.com/safedep/vet/pkg/common/logger"
|
|
||||||
|
|
||||||
apierr "github.com/safedep/dry/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
type TrialConfig struct {
|
|
||||||
Email string
|
|
||||||
ControlPlaneApiUrl string
|
|
||||||
}
|
|
||||||
|
|
||||||
type trialRegistrationResponse struct {
|
|
||||||
Id string
|
|
||||||
ExpiresAt time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
type trialRegistrationClient struct {
|
|
||||||
config TrialConfig
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewTrialRegistrationClient(config TrialConfig) *trialRegistrationClient {
|
|
||||||
return &trialRegistrationClient{config: config}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (client *trialRegistrationClient) Execute() (*trialRegistrationResponse, error) {
|
|
||||||
if utils.IsEmptyString(client.config.Email) {
|
|
||||||
return nil, errors.New("email is required")
|
|
||||||
}
|
|
||||||
|
|
||||||
if utils.IsEmptyString(client.config.ControlPlaneApiUrl) {
|
|
||||||
return nil, errors.New("control plane API is required")
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.Infof("Trial registrations using Control Plane: %s",
|
|
||||||
client.config.ControlPlaneApiUrl)
|
|
||||||
|
|
||||||
cpClient, err := cpv1trials.NewClientWithResponses(client.config.ControlPlaneApiUrl)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.Infof("Trial registration requesting API key for: %s",
|
|
||||||
client.config.Email)
|
|
||||||
|
|
||||||
res, err := cpClient.RegisterTrialUserWithResponse(context.Background(),
|
|
||||||
cpv1trials.RegisterTrialUserJSONRequestBody{
|
|
||||||
Email: types.Email(client.config.Email),
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if res.HTTPResponse.StatusCode != http.StatusCreated {
|
|
||||||
if err, ok := apierr.UnmarshalApiError(res.Body); ok {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
return nil, fmt.Errorf("unexpected status code:%d from control plane",
|
|
||||||
res.HTTPResponse.StatusCode)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return &trialRegistrationResponse{
|
|
||||||
Id: utils.SafelyGetValue(res.JSON201.Id),
|
|
||||||
ExpiresAt: utils.SafelyGetValue(res.JSON201.ExpiresAt),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
@ -1,62 +1,24 @@
|
|||||||
package auth
|
package auth
|
||||||
|
|
||||||
import (
|
import "github.com/safedep/vet/pkg/cloud"
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
apierr "github.com/safedep/dry/errors"
|
// Verify authentication to the data plane using
|
||||||
"github.com/safedep/dry/utils"
|
// API key and Ping Service.
|
||||||
"github.com/safedep/vet/gen/cpv1"
|
func Verify() error {
|
||||||
"github.com/safedep/vet/pkg/common/logger"
|
conn, err := SyncClientConnection("vet-auth-verify")
|
||||||
)
|
|
||||||
|
|
||||||
type VerifyConfig struct {
|
|
||||||
ControlPlaneApiUrl string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify function takes config and current API key available
|
|
||||||
// from this package and returns an error if auth is invalid
|
|
||||||
func Verify(config *VerifyConfig) error {
|
|
||||||
if CommunityMode() {
|
|
||||||
logger.Infof("Skipping auth verify due to community mode enabled")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.Infof("Verifying auth token using Control Plane: %s", config.ControlPlaneApiUrl)
|
|
||||||
|
|
||||||
client, err := cpv1.NewClientWithResponses(config.ControlPlaneApiUrl)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
authKeyApplier := func(ctx context.Context, req *http.Request) error {
|
pingService, err := cloud.NewPingService(conn)
|
||||||
req.Header.Set("Authorization", ApiKey())
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := client.GetApiCredentialIntrospectionWithResponse(context.Background(),
|
|
||||||
authKeyApplier)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if resp.StatusCode() != http.StatusOK {
|
_, err = pingService.Ping()
|
||||||
if err, ok := apierr.UnmarshalApiError(resp.Body); ok {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
} else {
|
|
||||||
return fmt.Errorf("unexpected status code:%d from control plane",
|
|
||||||
resp.HTTPResponse.StatusCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if resp.JSON200 == nil {
|
|
||||||
return fmt.Errorf("invalid nil response from server")
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.Infof("Current auth token is valid with expiry: %s",
|
|
||||||
utils.SafelyGetValue(resp.JSON200.Expiry))
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
17
main.go
17
main.go
@ -7,6 +7,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/safedep/dry/utils"
|
"github.com/safedep/dry/utils"
|
||||||
|
"github.com/safedep/vet/cmd/cloud"
|
||||||
"github.com/safedep/vet/internal/ui"
|
"github.com/safedep/vet/internal/ui"
|
||||||
"github.com/safedep/vet/pkg/common/logger"
|
"github.com/safedep/vet/pkg/common/logger"
|
||||||
"github.com/safedep/vet/pkg/exceptions"
|
"github.com/safedep/vet/pkg/exceptions"
|
||||||
@ -23,17 +24,10 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var banner string = `
|
var banner string = `
|
||||||
.----------------. .----------------. .----------------.
|
Yb dP 888888 888888
|
||||||
| .--------------. || .--------------. || .--------------. |
|
Yb dP 88__ 88
|
||||||
| | ____ ____ | || | _________ | || | _________ | |
|
YbdP 88"" 88
|
||||||
| ||_ _| |_ _| | || | |_ ___ | | || | | _ _ | | |
|
YP 888888 88
|
||||||
| | \ \ / / | || | | |_ \_| | || | |_/ | | \_| | |
|
|
||||||
| | \ \ / / | || | | _| _ | || | | | | |
|
|
||||||
| | \ ' / | || | _| |___/ | | || | _| |_ | |
|
|
||||||
| | \_/ | || | |_________| | || | |_____| | |
|
|
||||||
| | | || | | || | | |
|
|
||||||
| '--------------' || '--------------' || '--------------' |
|
|
||||||
'----------------' '----------------' '----------------'
|
|
||||||
|
|
||||||
`
|
`
|
||||||
|
|
||||||
@ -64,6 +58,7 @@ func main() {
|
|||||||
cmd.AddCommand(newCodeCommand())
|
cmd.AddCommand(newCodeCommand())
|
||||||
cmd.AddCommand(newVersionCommand())
|
cmd.AddCommand(newVersionCommand())
|
||||||
cmd.AddCommand(newConnectCommand())
|
cmd.AddCommand(newConnectCommand())
|
||||||
|
cmd.AddCommand(cloud.NewCloudCommand())
|
||||||
|
|
||||||
cobra.OnInitialize(func() {
|
cobra.OnInitialize(func() {
|
||||||
printBanner()
|
printBanner()
|
||||||
|
|||||||
3
pkg/cloud/cloud.go
Normal file
3
pkg/cloud/cloud.go
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
// Package cloud contains the services for interacting with SafeDep
|
||||||
|
// Cloud. It uses SafeDep gRPC API for communication.
|
||||||
|
package cloud
|
||||||
47
pkg/cloud/key.go
Normal file
47
pkg/cloud/key.go
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
package cloud
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"buf.build/gen/go/safedep/api/grpc/go/safedep/services/controltower/v1/controltowerv1grpc"
|
||||||
|
controltowerv1 "buf.build/gen/go/safedep/api/protocolbuffers/go/safedep/services/controltower/v1"
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
type apiKeyService struct {
|
||||||
|
conn *grpc.ClientConn
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewApiKeyService(conn *grpc.ClientConn) (*apiKeyService, error) {
|
||||||
|
return &apiKeyService{conn: conn}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateApiKeyRequest struct {
|
||||||
|
Name string
|
||||||
|
Desc string
|
||||||
|
ExpiryInDays int
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateApiKeyResponse struct {
|
||||||
|
Key string
|
||||||
|
ExpiresAt time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *apiKeyService) CreateApiKey(req *CreateApiKeyRequest) (*CreateApiKeyResponse, error) {
|
||||||
|
keyService := controltowerv1grpc.NewApiKeyServiceClient(a.conn)
|
||||||
|
res, err := keyService.CreateApiKey(context.Background(), &controltowerv1.CreateApiKeyRequest{
|
||||||
|
Name: req.Name,
|
||||||
|
Description: &req.Desc,
|
||||||
|
ExpiryDays: int32(req.ExpiryInDays),
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &CreateApiKeyResponse{
|
||||||
|
Key: res.GetKey(),
|
||||||
|
ExpiresAt: res.GetExpiresAt().AsTime(),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
46
pkg/cloud/onboarding.go
Normal file
46
pkg/cloud/onboarding.go
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
package cloud
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"buf.build/gen/go/safedep/api/grpc/go/safedep/services/controltower/v1/controltowerv1grpc"
|
||||||
|
controltowerv1 "buf.build/gen/go/safedep/api/protocolbuffers/go/safedep/services/controltower/v1"
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
type onboardingService struct {
|
||||||
|
conn *grpc.ClientConn
|
||||||
|
}
|
||||||
|
|
||||||
|
type RegisterRequest struct {
|
||||||
|
Email string
|
||||||
|
Name string
|
||||||
|
OrgName string
|
||||||
|
OrgDomain string
|
||||||
|
}
|
||||||
|
|
||||||
|
type RegisterResponse struct {
|
||||||
|
TenantDomain string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewOnboardingService(conn *grpc.ClientConn) (*onboardingService, error) {
|
||||||
|
return &onboardingService{conn}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *onboardingService) Register(req *RegisterRequest) (*RegisterResponse, error) {
|
||||||
|
onbService := controltowerv1grpc.NewOnboardingServiceClient(s.conn)
|
||||||
|
res, err := onbService.OnboardUser(context.Background(), &controltowerv1.OnboardUserRequest{
|
||||||
|
Email: req.Email,
|
||||||
|
Name: req.Name,
|
||||||
|
OrganizationName: req.OrgName,
|
||||||
|
OrganizationDomain: req.OrgDomain,
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &RegisterResponse{
|
||||||
|
TenantDomain: res.GetTenant().GetDomain(),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
42
pkg/cloud/ping.go
Normal file
42
pkg/cloud/ping.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package cloud
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"buf.build/gen/go/safedep/api/grpc/go/safedep/services/controltower/v1/controltowerv1grpc"
|
||||||
|
controltowerv1 "buf.build/gen/go/safedep/api/protocolbuffers/go/safedep/services/controltower/v1"
|
||||||
|
"github.com/oklog/ulid/v2"
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
type pingService struct {
|
||||||
|
conn *grpc.ClientConn
|
||||||
|
}
|
||||||
|
|
||||||
|
type PingResponse struct {
|
||||||
|
StartedAt time.Time
|
||||||
|
FinishedAt time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPingService(conn *grpc.ClientConn) (*pingService, error) {
|
||||||
|
return &pingService{conn: conn}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *pingService) Ping() (*PingResponse, error) {
|
||||||
|
pr := PingResponse{
|
||||||
|
StartedAt: time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
|
pingService := controltowerv1grpc.NewPingServiceClient(p.conn)
|
||||||
|
_, err := pingService.Ping(context.Background(), &controltowerv1.PingRequest{
|
||||||
|
Id: ulid.MustNew(ulid.Now(), nil).String(),
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
pr.FinishedAt = time.Now()
|
||||||
|
return &pr, nil
|
||||||
|
}
|
||||||
42
pkg/cloud/query/query_service.go
Normal file
42
pkg/cloud/query/query_service.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package query
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"buf.build/gen/go/safedep/api/grpc/go/safedep/services/controltower/v1/controltowerv1grpc"
|
||||||
|
controltowerv1 "buf.build/gen/go/safedep/api/protocolbuffers/go/safedep/services/controltower/v1"
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
type queryService struct {
|
||||||
|
client *grpc.ClientConn
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewQueryService(client *grpc.ClientConn) (*queryService, error) {
|
||||||
|
return &queryService{client: client}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *queryService) ExecuteSql(sql string) (*QueryResponse, error) {
|
||||||
|
queryServiceClient := controltowerv1grpc.NewQueryServiceClient(q.client)
|
||||||
|
|
||||||
|
res, err := queryServiceClient.QueryBySql(context.Background(), &controltowerv1.QueryBySqlRequest{
|
||||||
|
Query: sql,
|
||||||
|
PageSize: 100,
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var response QueryResponse
|
||||||
|
for _, row := range res.Rows {
|
||||||
|
rowMap := make(map[string]interface{})
|
||||||
|
for key, val := range row.Fields {
|
||||||
|
rowMap[key] = val.GetStringValue()
|
||||||
|
}
|
||||||
|
|
||||||
|
response = append(response, rowMap)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &response, nil
|
||||||
|
}
|
||||||
48
pkg/cloud/query/response.go
Normal file
48
pkg/cloud/query/response.go
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
package query
|
||||||
|
|
||||||
|
type QueryRow map[string]interface{}
|
||||||
|
type QueryResponse []QueryRow
|
||||||
|
|
||||||
|
func (q *QueryResponse) Count() int {
|
||||||
|
if q == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return len(*q)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *QueryResponse) GetRow(index int) *QueryRow {
|
||||||
|
if q.Count() <= index {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &(*q)[index]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *QueryResponse) ForEachRow(fn func(*QueryRow)) {
|
||||||
|
if q == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, row := range *q {
|
||||||
|
fn(&row)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *QueryRow) ForEachField(fn func(string, interface{})) {
|
||||||
|
if q == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for key, val := range *q {
|
||||||
|
fn(key, val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *QueryRow) GetField(key string) interface{} {
|
||||||
|
if q == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return (*q)[key]
|
||||||
|
}
|
||||||
27
pkg/cloud/user.go
Normal file
27
pkg/cloud/user.go
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package cloud
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"buf.build/gen/go/safedep/api/grpc/go/safedep/services/controltower/v1/controltowerv1grpc"
|
||||||
|
controltowerv1 "buf.build/gen/go/safedep/api/protocolbuffers/go/safedep/services/controltower/v1"
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
type userService struct {
|
||||||
|
conn *grpc.ClientConn
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewUserService(conn *grpc.ClientConn) (*userService, error) {
|
||||||
|
return &userService{conn: conn}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *userService) CurrentUserInfo() (*controltowerv1.GetUserInfoResponse, error) {
|
||||||
|
userService := controltowerv1grpc.NewUserServiceClient(s.conn)
|
||||||
|
res, err := userService.GetUserInfo(context.Background(), &controltowerv1.GetUserInfoRequest{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
@ -3,10 +3,12 @@ package models
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"hash/fnv"
|
"hash/fnv"
|
||||||
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
packagev1 "buf.build/gen/go/safedep/api/protocolbuffers/go/safedep/messages/package/v1"
|
||||||
"github.com/google/osv-scanner/pkg/lockfile"
|
"github.com/google/osv-scanner/pkg/lockfile"
|
||||||
"github.com/safedep/vet/gen/insightapi"
|
"github.com/safedep/vet/gen/insightapi"
|
||||||
|
|
||||||
@ -28,17 +30,59 @@ const (
|
|||||||
EcosystemSpdxSBOM = "SpdxSbom"
|
EcosystemSpdxSBOM = "SpdxSbom"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type ManifestSourceType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
ManifestSourceLocal = ManifestSourceType("local")
|
||||||
|
ManifestSourceGitRepository = ManifestSourceType("git_repository")
|
||||||
|
)
|
||||||
|
|
||||||
|
// We now have different sources from where a package
|
||||||
|
// manifest can be identified. For example, local, github,
|
||||||
|
// and may be in future within containers or archives like
|
||||||
|
// JAR. So we need to store additional internal metadata
|
||||||
|
type PackageManifestSource struct {
|
||||||
|
// The source type of this package namespace
|
||||||
|
Type ManifestSourceType
|
||||||
|
|
||||||
|
// The namespace of the package manifest. Examples:
|
||||||
|
// - Directory when source is local
|
||||||
|
// - GitHub repo URL when source is GitHub
|
||||||
|
Namespace string
|
||||||
|
|
||||||
|
// The namespace relative path of the package manifest
|
||||||
|
Path string
|
||||||
|
|
||||||
|
// Explicit override the display path
|
||||||
|
DisplayPath string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ps PackageManifestSource) GetDisplayPath() string {
|
||||||
|
switch ps.Type {
|
||||||
|
case ManifestSourceLocal:
|
||||||
|
return filepath.Join(ps.Namespace, ps.Path)
|
||||||
|
default:
|
||||||
|
return ps.DisplayPath
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ps PackageManifestSource) GetNamespace() string {
|
||||||
|
return ps.Namespace
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ps PackageManifestSource) GetPath() string {
|
||||||
|
return ps.Path
|
||||||
|
}
|
||||||
|
|
||||||
// Represents a package manifest that contains a list
|
// Represents a package manifest that contains a list
|
||||||
// of packages. Example: pom.xml, requirements.txt
|
// of packages. Example: pom.xml, requirements.txt
|
||||||
type PackageManifest struct {
|
type PackageManifest struct {
|
||||||
|
// The source of the package manifest
|
||||||
|
Source PackageManifestSource `json:"source"`
|
||||||
|
|
||||||
// Filesystem path of this manifest
|
// Filesystem path of this manifest
|
||||||
Path string `json:"path"`
|
Path string `json:"path"`
|
||||||
|
|
||||||
// When we scan non-path entities like Github org / repo
|
|
||||||
// then only path doesn't make sense, which is more local
|
|
||||||
// temporary file path
|
|
||||||
DisplayPath string `json:"display_path"`
|
|
||||||
|
|
||||||
// Ecosystem to interpret this manifest
|
// Ecosystem to interpret this manifest
|
||||||
Ecosystem string `json:"ecosystem"`
|
Ecosystem string `json:"ecosystem"`
|
||||||
|
|
||||||
@ -52,8 +96,30 @@ type PackageManifest struct {
|
|||||||
m sync.Mutex
|
m sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use NewPackageManifest* initializers
|
||||||
func NewPackageManifest(path, ecosystem string) *PackageManifest {
|
func NewPackageManifest(path, ecosystem string) *PackageManifest {
|
||||||
|
return NewPackageManifestFromLocal(path, ecosystem)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPackageManifestFromLocal(path, ecosystem string) *PackageManifest {
|
||||||
|
return newPackageManifest(PackageManifestSource{
|
||||||
|
Type: ManifestSourceLocal,
|
||||||
|
Namespace: filepath.Dir(path),
|
||||||
|
Path: filepath.Base(path),
|
||||||
|
}, path, ecosystem)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPackageManifestFromGitHub(repo, repoRelativePath, realPath, ecosystem string) *PackageManifest {
|
||||||
|
return newPackageManifest(PackageManifestSource{
|
||||||
|
Type: ManifestSourceGitRepository,
|
||||||
|
Namespace: repo,
|
||||||
|
Path: repoRelativePath,
|
||||||
|
}, realPath, ecosystem)
|
||||||
|
}
|
||||||
|
|
||||||
|
func newPackageManifest(source PackageManifestSource, path, ecosystem string) *PackageManifest {
|
||||||
return &PackageManifest{
|
return &PackageManifest{
|
||||||
|
Source: source,
|
||||||
Path: path,
|
Path: path,
|
||||||
Ecosystem: ecosystem,
|
Ecosystem: ecosystem,
|
||||||
Packages: make([]*Package, 0),
|
Packages: make([]*Package, 0),
|
||||||
@ -61,6 +127,16 @@ func NewPackageManifest(path, ecosystem string) *PackageManifest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parsers usually create a package manifest from file, readers
|
||||||
|
// have the context to set the source correct. Example: GitHub reader
|
||||||
|
func (p *PackageManifest) UpdateSourceAsGitRepository(repo, repoRelativePath string) {
|
||||||
|
p.Source = PackageManifestSource{
|
||||||
|
Type: ManifestSourceGitRepository,
|
||||||
|
Namespace: repo,
|
||||||
|
Path: repoRelativePath,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (pm *PackageManifest) AddPackage(pkg *Package) {
|
func (pm *PackageManifest) AddPackage(pkg *Package) {
|
||||||
pm.m.Lock()
|
pm.m.Lock()
|
||||||
defer pm.m.Unlock()
|
defer pm.m.Unlock()
|
||||||
@ -73,22 +149,22 @@ func (pm *PackageManifest) AddPackage(pkg *Package) {
|
|||||||
pm.DependencyGraph.AddNode(pkg)
|
pm.DependencyGraph.AddNode(pkg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (pm *PackageManifest) GetSource() PackageManifestSource {
|
||||||
|
return pm.Source
|
||||||
|
}
|
||||||
|
|
||||||
func (pm *PackageManifest) GetPath() string {
|
func (pm *PackageManifest) GetPath() string {
|
||||||
return pm.Path
|
return pm.Path
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pm *PackageManifest) SetDisplayPath(path string) {
|
func (pm *PackageManifest) SetDisplayPath(path string) {
|
||||||
pm.DisplayPath = path
|
pm.Source.DisplayPath = path
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDisplayPath returns the [DisplayPath] if available or fallsback
|
// GetDisplayPath returns the [DisplayPath] if available or fallsback
|
||||||
// to [Path]
|
// to [Path]
|
||||||
func (pm *PackageManifest) GetDisplayPath() string {
|
func (pm *PackageManifest) GetDisplayPath() string {
|
||||||
if len(pm.DisplayPath) > 0 {
|
return pm.Source.GetDisplayPath()
|
||||||
return pm.DisplayPath
|
|
||||||
}
|
|
||||||
|
|
||||||
return pm.GetPath()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPackages returns the list of packages in this manifest
|
// GetPackages returns the list of packages in this manifest
|
||||||
@ -111,6 +187,25 @@ func (pm *PackageManifest) GetPackagesCount() int {
|
|||||||
return len(pm.GetPackages())
|
return len(pm.GetPackages())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (pm *PackageManifest) GetControlTowerSpecEcosystem() packagev1.Ecosystem {
|
||||||
|
switch pm.Ecosystem {
|
||||||
|
case EcosystemCargo:
|
||||||
|
return packagev1.Ecosystem_ECOSYSTEM_CARGO
|
||||||
|
case EcosystemGo:
|
||||||
|
return packagev1.Ecosystem_ECOSYSTEM_GO
|
||||||
|
case EcosystemMaven:
|
||||||
|
return packagev1.Ecosystem_ECOSYSTEM_MAVEN
|
||||||
|
case EcosystemNpm:
|
||||||
|
return packagev1.Ecosystem_ECOSYSTEM_NPM
|
||||||
|
case EcosystemRubyGems:
|
||||||
|
return packagev1.Ecosystem_ECOSYSTEM_RUBYGEMS
|
||||||
|
case EcosystemPyPI:
|
||||||
|
return packagev1.Ecosystem_ECOSYSTEM_PYPI
|
||||||
|
default:
|
||||||
|
return packagev1.Ecosystem_ECOSYSTEM_UNSPECIFIED
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (pm *PackageManifest) GetSpecEcosystem() modelspec.Ecosystem {
|
func (pm *PackageManifest) GetSpecEcosystem() modelspec.Ecosystem {
|
||||||
switch pm.Ecosystem {
|
switch pm.Ecosystem {
|
||||||
case EcosystemCargo:
|
case EcosystemCargo:
|
||||||
@ -216,6 +311,37 @@ func (p *Package) DependencyPath() []*Package {
|
|||||||
return dg.PathToRoot(p)
|
return dg.PathToRoot(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Package) GetDependencies() ([]*Package, error) {
|
||||||
|
graph := p.GetDependencyGraph()
|
||||||
|
if graph == nil {
|
||||||
|
return nil, fmt.Errorf("dependency graph not available")
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies := []*Package{}
|
||||||
|
|
||||||
|
nodes := graph.GetNodes()
|
||||||
|
for _, node := range nodes {
|
||||||
|
if node.Root {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if node.Data == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.GetName() != node.Data.GetName() &&
|
||||||
|
p.GetVersion() != node.Data.GetVersion() &&
|
||||||
|
p.GetSpecEcosystem() != node.Data.GetSpecEcosystem() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies = append(dependencies, node.Children...)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return dependencies, nil
|
||||||
|
}
|
||||||
|
|
||||||
func NewPackageDetail(ecosystem, name, version string) lockfile.PackageDetails {
|
func NewPackageDetail(ecosystem, name, version string) lockfile.PackageDetails {
|
||||||
return lockfile.PackageDetails{
|
return lockfile.PackageDetails{
|
||||||
Ecosystem: lockfile.Ecosystem(ecosystem),
|
Ecosystem: lockfile.Ecosystem(ecosystem),
|
||||||
|
|||||||
@ -129,7 +129,9 @@ func (p *githubReader) processTopLevelLockfiles(ctx context.Context, client *git
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pm.UpdateSourceAsGitRepository(gitUrl.GetHttpCloneURL(), entry.GetPath())
|
||||||
pm.SetDisplayPath(entry.GetURL())
|
pm.SetDisplayPath(entry.GetURL())
|
||||||
|
|
||||||
err = handler(pm, NewManifestModelReader(pm))
|
err = handler(pm, NewManifestModelReader(pm))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -179,6 +181,7 @@ func (p *githubReader) processRemoteDependencyGraph(ctx context.Context, client
|
|||||||
|
|
||||||
// Override the display path because local path of the downloaded
|
// Override the display path because local path of the downloaded
|
||||||
// SBOM does not actually have a meaning
|
// SBOM does not actually have a meaning
|
||||||
|
manifest.UpdateSourceAsGitRepository(gitUrl.GetHttpCloneURL(), "<github-dependency-graph>")
|
||||||
manifest.SetDisplayPath(gitUrl.GetHttpCloneURL())
|
manifest.SetDisplayPath(gitUrl.GetHttpCloneURL())
|
||||||
|
|
||||||
return handler(manifest, NewManifestModelReader(manifest))
|
return handler(manifest, NewManifestModelReader(manifest))
|
||||||
|
|||||||
42
pkg/reporter/ci/ci.go
Normal file
42
pkg/reporter/ci/ci.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package ci
|
||||||
|
|
||||||
|
import "net/url"
|
||||||
|
|
||||||
|
type gitRefType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
Branch = gitRefType("branch")
|
||||||
|
Tag = gitRefType("tag")
|
||||||
|
PullRequest = gitRefType("pull_request")
|
||||||
|
)
|
||||||
|
|
||||||
|
// Introspector defines a contract for implementing
|
||||||
|
// runtime information collector from various CI environments.
|
||||||
|
// This is modeled based on the default environments in GHA. But
|
||||||
|
// we will keep this minimal and add extended interfaces for
|
||||||
|
// additional CI specific information.
|
||||||
|
// https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/store-information-in-variables#default-environment-variables
|
||||||
|
type Introspector interface {
|
||||||
|
// Returns the URL of the repository for which the CI job is running
|
||||||
|
GetRepositoryURL() (url.URL, error)
|
||||||
|
|
||||||
|
// Returns the repository name for which the CI job is running
|
||||||
|
GetRepositoryName() (string, error)
|
||||||
|
|
||||||
|
// Returns the event that triggered the CI job
|
||||||
|
GetEvent() (gitRefType, error)
|
||||||
|
|
||||||
|
// Returns the GitRef for which the CI job is running
|
||||||
|
// This is fulled formed e.g. refs/heads/master
|
||||||
|
GetGitRef() (string, error)
|
||||||
|
|
||||||
|
// Get the ref name for which the CI job is running
|
||||||
|
// This is the short form of the GitRef e.g. master
|
||||||
|
GetRefName() (string, error)
|
||||||
|
|
||||||
|
// Get the git ref type for which the CI job is running
|
||||||
|
GetRefType() (string, error)
|
||||||
|
|
||||||
|
// GitSHA returns the commit SHA for which the CI job is running
|
||||||
|
GetGitSHA() (string, error)
|
||||||
|
}
|
||||||
1
pkg/reporter/ci/git.go
Normal file
1
pkg/reporter/ci/git.go
Normal file
@ -0,0 +1 @@
|
|||||||
|
package ci
|
||||||
@ -34,12 +34,16 @@ var events []analyzer.AnalyzerEvent = []analyzer.AnalyzerEvent{
|
|||||||
CheckType: checks.CheckType_CheckTypeLicense,
|
CheckType: checks.CheckType_CheckTypeLicense,
|
||||||
},
|
},
|
||||||
Manifest: &models.PackageManifest{
|
Manifest: &models.PackageManifest{
|
||||||
DisplayPath: "displayPath1",
|
Source: models.PackageManifestSource{
|
||||||
|
DisplayPath: "displayPath1",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Package: &models.Package{
|
Package: &models.Package{
|
||||||
PackageDetails: models.NewPackageDetail("ecosystem1", "name1", "version1"),
|
PackageDetails: models.NewPackageDetail("ecosystem1", "name1", "version1"),
|
||||||
Manifest: &models.PackageManifest{
|
Manifest: &models.PackageManifest{
|
||||||
DisplayPath: "displayPath1",
|
Source: models.PackageManifestSource{
|
||||||
|
DisplayPath: "displayPath1",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Insights: &insightapi.PackageVersionInsight{
|
Insights: &insightapi.PackageVersionInsight{
|
||||||
Licenses: &licenses,
|
Licenses: &licenses,
|
||||||
@ -55,12 +59,16 @@ var events []analyzer.AnalyzerEvent = []analyzer.AnalyzerEvent{
|
|||||||
CheckType: checks.CheckType_CheckTypeVulnerability,
|
CheckType: checks.CheckType_CheckTypeVulnerability,
|
||||||
},
|
},
|
||||||
Manifest: &models.PackageManifest{
|
Manifest: &models.PackageManifest{
|
||||||
DisplayPath: "displayPath2",
|
Source: models.PackageManifestSource{
|
||||||
|
DisplayPath: "displayPath1",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Package: &models.Package{
|
Package: &models.Package{
|
||||||
PackageDetails: models.NewPackageDetail("ecosystem2", "name2", "version2"),
|
PackageDetails: models.NewPackageDetail("ecosystem2", "name2", "version2"),
|
||||||
Manifest: &models.PackageManifest{
|
Manifest: &models.PackageManifest{
|
||||||
DisplayPath: "displayPath2",
|
Source: models.PackageManifestSource{
|
||||||
|
DisplayPath: "displayPath1",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Insights: &insightapi.PackageVersionInsight{
|
Insights: &insightapi.PackageVersionInsight{
|
||||||
Vulnerabilities: &[]insightapi.PackageVulnerability{
|
Vulnerabilities: &[]insightapi.PackageVulnerability{
|
||||||
@ -81,12 +89,16 @@ var events []analyzer.AnalyzerEvent = []analyzer.AnalyzerEvent{
|
|||||||
CheckType: checks.CheckType_CheckTypePopularity,
|
CheckType: checks.CheckType_CheckTypePopularity,
|
||||||
},
|
},
|
||||||
Manifest: &models.PackageManifest{
|
Manifest: &models.PackageManifest{
|
||||||
DisplayPath: "displayPath3",
|
Source: models.PackageManifestSource{
|
||||||
|
DisplayPath: "displayPath2",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Package: &models.Package{
|
Package: &models.Package{
|
||||||
PackageDetails: models.NewPackageDetail("ecosystem3", "name3", "version3"),
|
PackageDetails: models.NewPackageDetail("ecosystem3", "name3", "version3"),
|
||||||
Manifest: &models.PackageManifest{
|
Manifest: &models.PackageManifest{
|
||||||
DisplayPath: "displayPath3",
|
Source: models.PackageManifestSource{
|
||||||
|
DisplayPath: "displayPath3",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Insights: &insightapi.PackageVersionInsight{
|
Insights: &insightapi.PackageVersionInsight{
|
||||||
Projects: &[]insightapi.PackageProjectInfo{
|
Projects: &[]insightapi.PackageProjectInfo{
|
||||||
|
|||||||
@ -2,21 +2,23 @@ package reporter
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"strings"
|
||||||
"net/http"
|
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
api_errors "github.com/safedep/dry/errors"
|
"buf.build/gen/go/safedep/api/grpc/go/safedep/services/controltower/v1/controltowerv1grpc"
|
||||||
|
packagev1 "buf.build/gen/go/safedep/api/protocolbuffers/go/safedep/messages/package/v1"
|
||||||
|
policyv1 "buf.build/gen/go/safedep/api/protocolbuffers/go/safedep/messages/policy/v1"
|
||||||
|
vulnerabilityv1 "buf.build/gen/go/safedep/api/protocolbuffers/go/safedep/messages/vulnerability/v1"
|
||||||
|
controltowerv1 "buf.build/gen/go/safedep/api/protocolbuffers/go/safedep/services/controltower/v1"
|
||||||
"github.com/safedep/dry/utils"
|
"github.com/safedep/dry/utils"
|
||||||
"github.com/safedep/vet/gen/syncv1"
|
"github.com/safedep/vet/gen/checks"
|
||||||
"github.com/safedep/vet/internal/auth"
|
|
||||||
"github.com/safedep/vet/pkg/analyzer"
|
"github.com/safedep/vet/pkg/analyzer"
|
||||||
"github.com/safedep/vet/pkg/common/logger"
|
"github.com/safedep/vet/pkg/common/logger"
|
||||||
"github.com/safedep/vet/pkg/models"
|
"github.com/safedep/vet/pkg/models"
|
||||||
"github.com/safedep/vet/pkg/policy"
|
"github.com/safedep/vet/pkg/policy"
|
||||||
"github.com/safedep/vet/pkg/readers"
|
"github.com/safedep/vet/pkg/readers"
|
||||||
|
"google.golang.org/grpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -26,84 +28,164 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type SyncReporterConfig struct {
|
type SyncReporterConfig struct {
|
||||||
|
// gRPC connection for ControlTower
|
||||||
|
ClientConnection *grpc.ClientConn
|
||||||
|
|
||||||
|
// Enable multi-project syncing
|
||||||
|
// In this case, a new project is created per package manifest
|
||||||
|
EnableMultiProjectSync bool
|
||||||
|
|
||||||
// Required
|
// Required
|
||||||
ProjectName string
|
ProjectName string
|
||||||
StreamName string
|
ProjectVersion string
|
||||||
TriggerEvent string
|
TriggerEvent string
|
||||||
|
|
||||||
// Optional or auto-discovered from environment
|
// Optional or auto-discovered from environment
|
||||||
ProjectSource string
|
GitRef string
|
||||||
GitRef string
|
GitRefName string
|
||||||
GitRefName string
|
GitRefType string
|
||||||
GitRefType string
|
GitSha string
|
||||||
GitSha string
|
|
||||||
|
|
||||||
// Performance
|
// Performance
|
||||||
WorkerCount int
|
WorkerCount int
|
||||||
|
|
||||||
// Internal config
|
// Tool details
|
||||||
toolName string
|
ToolName string
|
||||||
toolVersion string
|
ToolVersion string
|
||||||
toolType string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type syncIssueWrapper struct {
|
type syncSession struct {
|
||||||
retries int
|
sessionId string
|
||||||
issue any
|
toolServiceClient controltowerv1grpc.ToolServiceClient
|
||||||
|
}
|
||||||
|
|
||||||
|
type syncSessionPool struct {
|
||||||
|
mu sync.RWMutex
|
||||||
|
syncSessions map[string]syncSession
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only use this session
|
||||||
|
func (s *syncSessionPool) addPrimarySession(sessionId string, client controltowerv1grpc.ToolServiceClient) {
|
||||||
|
s.mu.Lock()
|
||||||
|
defer s.mu.Unlock()
|
||||||
|
|
||||||
|
s.syncSessions["*"] = syncSession{
|
||||||
|
sessionId: sessionId,
|
||||||
|
toolServiceClient: client,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *syncSessionPool) hasKeyedSession(key string) bool {
|
||||||
|
s.mu.RLock()
|
||||||
|
defer s.mu.RUnlock()
|
||||||
|
|
||||||
|
_, ok := s.syncSessions[key]
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *syncSessionPool) addKeyedSession(key, sessionId string, client controltowerv1grpc.ToolServiceClient) {
|
||||||
|
s.mu.Lock()
|
||||||
|
defer s.mu.Unlock()
|
||||||
|
|
||||||
|
s.syncSessions[key] = syncSession{
|
||||||
|
sessionId: sessionId,
|
||||||
|
toolServiceClient: client,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *syncSessionPool) getSession(key string) (*syncSession, error) {
|
||||||
|
s.mu.RLock()
|
||||||
|
defer s.mu.RUnlock()
|
||||||
|
|
||||||
|
if s, ok := s.syncSessions["*"]; ok {
|
||||||
|
return &s, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if s, ok := s.syncSessions[key]; ok {
|
||||||
|
return &s, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, fmt.Errorf("session not found for key: %s", key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *syncSessionPool) forEach(f func(key string, session *syncSession) error) error {
|
||||||
|
s.mu.RLock()
|
||||||
|
defer s.mu.RUnlock()
|
||||||
|
|
||||||
|
for key, session := range s.syncSessions {
|
||||||
|
err := f(key, &session)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type workItem struct {
|
||||||
|
pkg *models.Package
|
||||||
|
event *analyzer.AnalyzerEvent
|
||||||
}
|
}
|
||||||
|
|
||||||
type syncReporter struct {
|
type syncReporter struct {
|
||||||
client *syncv1.ClientWithResponses
|
config *SyncReporterConfig
|
||||||
config *SyncReporterConfig
|
workQueue chan *workItem
|
||||||
issueChannel chan *syncIssueWrapper
|
done chan bool
|
||||||
done chan bool
|
wg sync.WaitGroup
|
||||||
wg sync.WaitGroup
|
client *grpc.ClientConn
|
||||||
jobId string
|
sessions *syncSessionPool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSyncReporter(config SyncReporterConfig) (Reporter, error) {
|
func NewSyncReporter(config SyncReporterConfig) (Reporter, error) {
|
||||||
apiKeyApplier := func(ctx context.Context, req *http.Request) error {
|
if config.ClientConnection == nil {
|
||||||
req.Header.Set("Authorization", auth.ApiKey())
|
return nil, fmt.Errorf("missing gRPC client connection")
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Use hysterix as the API client with retries, backoff
|
// TODO: Auto-discover config using CI environment variables
|
||||||
// connection pooling etc.
|
// if enabled by the user
|
||||||
|
|
||||||
client, err := syncv1.NewClientWithResponses(auth.DefaultSyncApiUrl(),
|
syncSessionPool := syncSessionPool{
|
||||||
syncv1.WithRequestEditorFn(apiKeyApplier))
|
syncSessions: make(map[string]syncSession),
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to initialize client for sync reporter: %w", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
config.TriggerEvent = string(syncv1.CreateJobRequestTriggerEventManual)
|
trigger := controltowerv1.ToolTrigger_TOOL_TRIGGER_MANUAL
|
||||||
config.ProjectSource = string(syncv1.CreateJobRequestProjectSourceOther)
|
source := packagev1.ProjectSourceType_PROJECT_SOURCE_TYPE_UNSPECIFIED
|
||||||
config.toolType = string(syncv1.CreateJobRequestToolTypeOssVet)
|
|
||||||
config.toolName = syncReporterToolName
|
|
||||||
config.toolVersion = "FIXME"
|
|
||||||
|
|
||||||
// TODO: Use an interface to auto-discover environmental details
|
// A multi-project sync is required for cases like GitHub org where
|
||||||
// if not provided and update config
|
// we are scanning multiple repositories
|
||||||
|
if !config.EnableMultiProjectSync {
|
||||||
|
logger.Debugf("Report Sync: Creating tool session for project: %s, version: %s",
|
||||||
|
config.ProjectName, config.ProjectVersion)
|
||||||
|
|
||||||
err = validateSyncReporterConfig(&config)
|
// Refactor this into a common session creator function
|
||||||
if err != nil {
|
toolServiceClient := controltowerv1grpc.NewToolServiceClient(config.ClientConnection)
|
||||||
return nil, fmt.Errorf("failed to validate sync reporter config : %w", err)
|
toolSessionRes, err := toolServiceClient.CreateToolSession(context.Background(),
|
||||||
}
|
&controltowerv1.CreateToolSessionRequest{
|
||||||
|
ToolName: config.ToolName,
|
||||||
|
ToolVersion: config.ToolVersion,
|
||||||
|
ProjectName: config.ProjectName,
|
||||||
|
ProjectVersion: &config.ProjectVersion,
|
||||||
|
ProjectSource: &source,
|
||||||
|
Trigger: &trigger,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to create tool session: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
jobId, err := createJobForSyncReportSession(client, &config)
|
logger.Debugf("Report Sync: Tool data upload session ID: %s",
|
||||||
if err != nil {
|
toolSessionRes.GetToolSession().GetToolSessionId())
|
||||||
return nil, fmt.Errorf("failed to create job for sync reporter: %w", err)
|
|
||||||
|
syncSessionPool.addPrimarySession(toolSessionRes.GetToolSession().GetToolSessionId(),
|
||||||
|
toolServiceClient)
|
||||||
}
|
}
|
||||||
|
|
||||||
done := make(chan bool)
|
done := make(chan bool)
|
||||||
issuesChan := make(chan *syncIssueWrapper, 100000)
|
|
||||||
|
|
||||||
self := &syncReporter{
|
self := &syncReporter{
|
||||||
config: &config,
|
config: &config,
|
||||||
client: client,
|
done: done,
|
||||||
issueChannel: issuesChan,
|
workQueue: make(chan *workItem, 1000),
|
||||||
jobId: jobId,
|
client: config.ClientConnection,
|
||||||
done: done,
|
sessions: &syncSessionPool,
|
||||||
}
|
}
|
||||||
|
|
||||||
self.startWorkers()
|
self.startWorkers()
|
||||||
@ -115,20 +197,50 @@ func (s *syncReporter) Name() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *syncReporter) AddManifest(manifest *models.PackageManifest) {
|
func (s *syncReporter) AddManifest(manifest *models.PackageManifest) {
|
||||||
|
manifestSessionKey := manifest.Path
|
||||||
|
if s.config.EnableMultiProjectSync && !s.sessions.hasKeyedSession(manifestSessionKey) {
|
||||||
|
projectName := manifest.GetSource().GetNamespace()
|
||||||
|
projectVersion := "main"
|
||||||
|
|
||||||
|
source := packagev1.ProjectSourceType_PROJECT_SOURCE_TYPE_UNSPECIFIED
|
||||||
|
trigger := controltowerv1.ToolTrigger_TOOL_TRIGGER_MANUAL
|
||||||
|
|
||||||
|
logger.Debugf("Report Sync: Creating tool session for project: %s, version: %s",
|
||||||
|
projectName, projectVersion)
|
||||||
|
|
||||||
|
// Refactor this into a common session creator function
|
||||||
|
toolServiceClient := controltowerv1grpc.NewToolServiceClient(s.client)
|
||||||
|
toolSessionRes, err := toolServiceClient.CreateToolSession(context.Background(),
|
||||||
|
&controltowerv1.CreateToolSessionRequest{
|
||||||
|
ToolName: s.config.ToolName,
|
||||||
|
ToolVersion: s.config.ToolVersion,
|
||||||
|
ProjectName: projectName,
|
||||||
|
ProjectVersion: &projectVersion,
|
||||||
|
ProjectSource: &source,
|
||||||
|
Trigger: &trigger,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("failed to create tool session for project: %s/%s: %v",
|
||||||
|
projectName, projectVersion, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Debugf("Report Sync: Tool data upload session ID: %s",
|
||||||
|
toolSessionRes.GetToolSession().GetToolSessionId())
|
||||||
|
|
||||||
|
s.sessions.addKeyedSession(manifestSessionKey,
|
||||||
|
toolSessionRes.GetToolSession().GetToolSessionId(), toolServiceClient)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// We are ignoring the error here because we are asynchronously handling the sync of Manifest
|
// We are ignoring the error here because we are asynchronously handling the sync of Manifest
|
||||||
_ = readers.NewManifestModelReader(manifest).EnumPackages(func(pkg *models.Package) error {
|
_ = readers.NewManifestModelReader(manifest).EnumPackages(func(pkg *models.Package) error {
|
||||||
|
s.queuePackage(pkg)
|
||||||
s.queuePackageDependencyIssue(manifest, pkg)
|
|
||||||
s.queuePackageMetadataIssue(manifest, pkg)
|
|
||||||
s.queuePackageLicenseIssue(manifest, pkg)
|
|
||||||
s.queuePackageVulnerabilityIssue(manifest, pkg)
|
|
||||||
s.queuePackageScorecardIssue(manifest, pkg)
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *syncReporter) AddAnalyzerEvent(event *analyzer.AnalyzerEvent) {
|
func (s *syncReporter) AddAnalyzerEvent(event *analyzer.AnalyzerEvent) {
|
||||||
|
s.queueEvent(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *syncReporter) AddPolicyEvent(event *policy.PolicyEvent) {
|
func (s *syncReporter) AddPolicyEvent(event *policy.PolicyEvent) {
|
||||||
@ -138,12 +250,30 @@ func (s *syncReporter) Finish() error {
|
|||||||
s.wg.Wait()
|
s.wg.Wait()
|
||||||
close(s.done)
|
close(s.done)
|
||||||
|
|
||||||
return nil
|
return s.sessions.forEach(func(_ string, session *syncSession) error {
|
||||||
|
logger.Debugf("Report Sync: Completing tool session: %s", session.sessionId)
|
||||||
|
|
||||||
|
_, err := session.toolServiceClient.CompleteToolSession(context.Background(),
|
||||||
|
&controltowerv1.CompleteToolSessionRequest{
|
||||||
|
ToolSession: &controltowerv1.ToolSession{
|
||||||
|
ToolSessionId: session.sessionId,
|
||||||
|
},
|
||||||
|
|
||||||
|
Status: controltowerv1.CompleteToolSessionRequest_STATUS_SUCCESS,
|
||||||
|
})
|
||||||
|
|
||||||
|
return err
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *syncReporter) queueIssueForSync(issue *syncIssueWrapper) {
|
func (s *syncReporter) queueEvent(event *analyzer.AnalyzerEvent) {
|
||||||
s.wg.Add(1)
|
s.wg.Add(1)
|
||||||
s.issueChannel <- issue
|
s.workQueue <- &workItem{event: event}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *syncReporter) queuePackage(pkg *models.Package) {
|
||||||
|
s.wg.Add(1)
|
||||||
|
s.workQueue <- &workItem{pkg: pkg}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *syncReporter) startWorkers() {
|
func (s *syncReporter) startWorkers() {
|
||||||
@ -160,10 +290,17 @@ func (s *syncReporter) startWorkers() {
|
|||||||
func (s *syncReporter) syncReportWorker() {
|
func (s *syncReporter) syncReportWorker() {
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case issue := <-s.issueChannel:
|
case item := <-s.workQueue:
|
||||||
err := s.syncReportIssue(issue)
|
if item.event != nil {
|
||||||
if err != nil {
|
err := s.syncEvent(item.event)
|
||||||
logger.Errorf("failed to sync issue: %v", err)
|
if err != nil {
|
||||||
|
logger.Errorf("failed to sync event: %v", err)
|
||||||
|
}
|
||||||
|
} else if item.pkg != nil {
|
||||||
|
err := s.syncPackage(item.pkg)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("failed to sync package: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case <-s.done:
|
case <-s.done:
|
||||||
return
|
return
|
||||||
@ -171,270 +308,212 @@ func (s *syncReporter) syncReportWorker() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *syncReporter) syncReportIssue(iw *syncIssueWrapper) error {
|
func (s *syncReporter) syncEvent(event *analyzer.AnalyzerEvent) error {
|
||||||
defer s.wg.Done()
|
defer s.wg.Done()
|
||||||
|
|
||||||
res, err := s.client.CreateJobIssueWithResponse(context.Background(), s.jobId, iw.issue)
|
pkg := event.Package
|
||||||
|
filter := event.Filter
|
||||||
|
|
||||||
|
if pkg == nil || filter == nil || pkg.Manifest == nil {
|
||||||
|
return fmt.Errorf("failed to sync event: invalid event data")
|
||||||
|
}
|
||||||
|
|
||||||
|
manifestSessionKey := pkg.Manifest.Path
|
||||||
|
session, err := s.sessions.getSession(manifestSessionKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("failed to get session for package: %s/%s/%s: %w",
|
||||||
|
pkg.Manifest.Ecosystem, pkg.GetName(), pkg.GetVersion(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer res.HTTPResponse.Body.Close()
|
checkType := policyv1.RuleCheck_RULE_CHECK_UNSPECIFIED
|
||||||
|
switch filter.GetCheckType() {
|
||||||
if res.HTTPResponse.StatusCode != http.StatusCreated {
|
case checks.CheckType_CheckTypeVulnerability:
|
||||||
apiErr, _ := api_errors.UnmarshalApiError(res.Body)
|
checkType = policyv1.RuleCheck_RULE_CHECK_VULNERABILITY
|
||||||
if apiErr.Retriable() && (iw.retries < syncReporterMaxRetries) {
|
case checks.CheckType_CheckTypeLicense:
|
||||||
iw.retries++
|
checkType = policyv1.RuleCheck_RULE_CHECK_LICENSE
|
||||||
s.queueIssueForSync(iw)
|
case checks.CheckType_CheckTypeMalware:
|
||||||
return nil
|
checkType = policyv1.RuleCheck_RULE_CHECK_MALWARE
|
||||||
}
|
case checks.CheckType_CheckTypeMaintenance:
|
||||||
|
checkType = policyv1.RuleCheck_RULE_CHECK_MAINTENANCE
|
||||||
return fmt.Errorf("invalid response code %d from Issue API : %w",
|
case checks.CheckType_CheckTypePopularity:
|
||||||
res.HTTPResponse.StatusCode, err)
|
checkType = policyv1.RuleCheck_RULE_CHECK_POPULARITY
|
||||||
|
case checks.CheckType_CheckTypeSecurityScorecard:
|
||||||
|
checkType = policyv1.RuleCheck_RULE_CHECK_PROJECT_SCORECARD
|
||||||
|
default:
|
||||||
|
logger.Warnf("unsupported check type: %s", filter.GetCheckType())
|
||||||
}
|
}
|
||||||
|
|
||||||
response := utils.SafelyGetValue(res.JSON201)
|
namespace := pkg.Manifest.GetSource().GetNamespace()
|
||||||
logger.Debugf("Synced issued with ID: %s", response.Id)
|
req := controltowerv1.PublishPolicyViolationRequest{
|
||||||
|
ToolSession: &controltowerv1.ToolSession{
|
||||||
|
ToolSessionId: session.sessionId,
|
||||||
|
},
|
||||||
|
|
||||||
|
Manifest: &packagev1.PackageManifest{
|
||||||
|
Ecosystem: pkg.Manifest.GetControlTowerSpecEcosystem(),
|
||||||
|
Namespace: &namespace,
|
||||||
|
Name: pkg.Manifest.GetSource().GetPath(),
|
||||||
|
},
|
||||||
|
|
||||||
|
PackageVersion: &packagev1.PackageVersion{
|
||||||
|
Package: &packagev1.Package{
|
||||||
|
Ecosystem: pkg.Manifest.GetControlTowerSpecEcosystem(),
|
||||||
|
Name: pkg.Name,
|
||||||
|
},
|
||||||
|
|
||||||
|
Version: pkg.Version,
|
||||||
|
},
|
||||||
|
|
||||||
|
Violation: &policyv1.Violation{
|
||||||
|
Rule: &policyv1.Rule{
|
||||||
|
Name: filter.GetName(),
|
||||||
|
Description: filter.GetSummary(),
|
||||||
|
Value: filter.GetValue(),
|
||||||
|
Check: checkType,
|
||||||
|
},
|
||||||
|
|
||||||
|
Evidences: []*policyv1.ViolationEvidence{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = session.toolServiceClient.PublishPolicyViolation(context.Background(), &req)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to publish policy violation: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *syncReporter) buildPackageIssue(issueType syncv1.IssueIssueType,
|
func (s *syncReporter) syncPackage(pkg *models.Package) error {
|
||||||
manifest *models.PackageManifest, pkg *models.Package) syncv1.PackageIssue {
|
defer s.wg.Done()
|
||||||
ecosystem := syncv1.PackageIssueManifestEcosystem(manifest.Ecosystem)
|
|
||||||
return syncv1.PackageIssue{
|
manifestSessionKey := pkg.Manifest.Path
|
||||||
Issue: syncv1.Issue{
|
session, err := s.sessions.getSession(manifestSessionKey)
|
||||||
IssueType: issueType,
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to get session for package: %s/%s/%s: %w",
|
||||||
|
pkg.Manifest.Ecosystem, pkg.GetName(), pkg.GetVersion(), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build the base package manifest and package
|
||||||
|
req := controltowerv1.PublishPackageInsightRequest{
|
||||||
|
ToolSession: &controltowerv1.ToolSession{
|
||||||
|
ToolSessionId: session.sessionId,
|
||||||
},
|
},
|
||||||
ManifestEcosystem: &ecosystem,
|
|
||||||
ManifestPath: &manifest.Path,
|
|
||||||
PackageName: &pkg.Name,
|
|
||||||
PackageVersion: &pkg.Version,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *syncReporter) queuePackageDependencyIssue(manifest *models.PackageManifest, pkg *models.Package) {
|
Manifest: &packagev1.PackageManifest{
|
||||||
issue := syncv1.IssuePackageDependency{
|
Ecosystem: pkg.Manifest.GetControlTowerSpecEcosystem(),
|
||||||
PackageIssue: s.buildPackageIssue(syncv1.IssueIssueTypePackageDependency,
|
Namespace: &pkg.Manifest.Path,
|
||||||
manifest, pkg),
|
Name: pkg.Manifest.GetDisplayPath(),
|
||||||
|
},
|
||||||
|
|
||||||
|
PackageVersion: &packagev1.PackageVersion{
|
||||||
|
Package: &packagev1.Package{
|
||||||
|
Ecosystem: pkg.Manifest.GetControlTowerSpecEcosystem(),
|
||||||
|
Name: pkg.Name,
|
||||||
|
},
|
||||||
|
|
||||||
|
Version: pkg.Version,
|
||||||
|
},
|
||||||
|
|
||||||
|
PackageVersionInsight: &packagev1.PackageVersionInsight{
|
||||||
|
Dependencies: []*packagev1.PackageVersion{},
|
||||||
|
Vulnerabilities: []*vulnerabilityv1.Vulnerability{},
|
||||||
|
ProjectInsights: []*packagev1.ProjectInsight{},
|
||||||
|
Licenses: &packagev1.LicenseMetaList{
|
||||||
|
Licenses: []*packagev1.LicenseMeta{},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if pkg.Parent != nil {
|
// Add package dependencies
|
||||||
issue.ParentPackageName = &pkg.Parent.Name
|
dependencies, err := pkg.GetDependencies()
|
||||||
issue.ParentPackageVersion = &pkg.Parent.Version
|
if err != nil {
|
||||||
}
|
logger.Warnf("failed to get dependencies for package: %s/%s/%s: %s",
|
||||||
|
pkg.Manifest.Ecosystem, pkg.GetName(), pkg.GetVersion(), err.Error())
|
||||||
|
} else {
|
||||||
|
for _, child := range dependencies {
|
||||||
|
req.PackageVersionInsight.Dependencies = append(req.PackageVersionInsight.Dependencies, &packagev1.PackageVersion{
|
||||||
|
Package: &packagev1.Package{
|
||||||
|
Ecosystem: child.Manifest.GetControlTowerSpecEcosystem(),
|
||||||
|
Name: child.GetName(),
|
||||||
|
},
|
||||||
|
|
||||||
iw := syncIssueWrapper{issue: issue}
|
Version: child.GetVersion(),
|
||||||
s.queueIssueForSync(&iw)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *syncReporter) queuePackageMetadataIssue(manifest *models.PackageManifest, pkg *models.Package) {
|
|
||||||
insights := utils.SafelyGetValue(pkg.Insights)
|
|
||||||
projects := utils.SafelyGetValue(insights.Projects)
|
|
||||||
|
|
||||||
for _, project := range projects {
|
|
||||||
issue := syncv1.IssuePackageSource{
|
|
||||||
PackageIssue: s.buildPackageIssue(syncv1.IssueIssueTypePackageSourceInfo,
|
|
||||||
manifest, pkg),
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceType := utils.SafelyGetValue(project.Type)
|
|
||||||
issueSourceType := syncv1.IssuePackageSourceSourceTypeOther
|
|
||||||
|
|
||||||
switch sourceType {
|
|
||||||
case "GITHUB":
|
|
||||||
issueSourceType = syncv1.IssuePackageSourceSourceTypeGithub
|
|
||||||
case "BITBUCKET":
|
|
||||||
issueSourceType = syncv1.IssuePackageSourceSourceTypeBitbucket
|
|
||||||
case "GITLAB":
|
|
||||||
issueSourceType = syncv1.IssuePackageSourceSourceTypeGitlab
|
|
||||||
}
|
|
||||||
|
|
||||||
issue.SourceType = &issueSourceType
|
|
||||||
issue.SourceUrl = project.Link
|
|
||||||
issue.SourceDisplayName = project.DisplayName
|
|
||||||
issue.SourceForks = project.Forks
|
|
||||||
issue.SourceStars = project.Stars
|
|
||||||
|
|
||||||
s.queueIssueForSync(&syncIssueWrapper{issue: issue})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *syncReporter) queuePackageLicenseIssue(manifest *models.PackageManifest, pkg *models.Package) {
|
|
||||||
insights := utils.SafelyGetValue(pkg.Insights)
|
|
||||||
licenses := utils.SafelyGetValue(insights.Licenses)
|
|
||||||
|
|
||||||
for _, license := range licenses {
|
|
||||||
licenseId := syncv1.IssuePackageLicenseLicenseId(license)
|
|
||||||
issue := syncv1.IssuePackageLicense{
|
|
||||||
PackageIssue: s.buildPackageIssue(syncv1.IssueIssueTypePackageLicense,
|
|
||||||
manifest, pkg),
|
|
||||||
LicenseId: &licenseId,
|
|
||||||
}
|
|
||||||
|
|
||||||
s.queueIssueForSync(&syncIssueWrapper{issue: issue})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *syncReporter) queuePackageVulnerabilityIssue(manifest *models.PackageManifest, pkg *models.Package) {
|
|
||||||
insights := utils.SafelyGetValue(pkg.Insights)
|
|
||||||
vulnerabilities := utils.SafelyGetValue(insights.Vulnerabilities)
|
|
||||||
|
|
||||||
for _, vuln := range vulnerabilities {
|
|
||||||
issue := syncv1.IssuePackageVulnerability{
|
|
||||||
PackageIssue: s.buildPackageIssue(syncv1.IssueIssueTypePackageVulnerability,
|
|
||||||
manifest, pkg),
|
|
||||||
}
|
|
||||||
|
|
||||||
severities := []struct {
|
|
||||||
Risk *syncv1.IssuePackageCommonVulnerabilitySeveritiesRisk `json:"risk,omitempty"`
|
|
||||||
Score *string `json:"score,omitempty"`
|
|
||||||
Type *syncv1.IssuePackageCommonVulnerabilitySeveritiesType `json:"type,omitempty"`
|
|
||||||
}{}
|
|
||||||
|
|
||||||
issue.Vulnerability = &syncv1.IssuePackageCommonVulnerability{
|
|
||||||
Id: vuln.Id,
|
|
||||||
Summary: vuln.Summary,
|
|
||||||
Aliases: vuln.Aliases,
|
|
||||||
Related: vuln.Related,
|
|
||||||
}
|
|
||||||
|
|
||||||
insightsVulnSeverities := utils.SafelyGetValue(vuln.Severities)
|
|
||||||
for _, severity := range insightsVulnSeverities {
|
|
||||||
sRisk := syncv1.IssuePackageCommonVulnerabilitySeveritiesRisk(utils.SafelyGetValue(severity.Risk))
|
|
||||||
sType := syncv1.IssuePackageCommonVulnerabilitySeveritiesType(utils.SafelyGetValue(severity.Type))
|
|
||||||
|
|
||||||
severities = append(severities, struct {
|
|
||||||
Risk *syncv1.IssuePackageCommonVulnerabilitySeveritiesRisk `json:"risk,omitempty"`
|
|
||||||
Score *string `json:"score,omitempty"`
|
|
||||||
Type *syncv1.IssuePackageCommonVulnerabilitySeveritiesType `json:"type,omitempty"`
|
|
||||||
}{
|
|
||||||
Score: severity.Score,
|
|
||||||
Risk: &sRisk,
|
|
||||||
Type: &sType,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
issue.Vulnerability.Severities = &severities
|
|
||||||
s.queueIssueForSync(&syncIssueWrapper{issue: issue})
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
func (s *syncReporter) queuePackageScorecardIssue(manifest *models.PackageManifest, pkg *models.Package) {
|
// Get the insights
|
||||||
insights := utils.SafelyGetValue(pkg.Insights)
|
insights := utils.SafelyGetValue(pkg.Insights)
|
||||||
|
|
||||||
// Basic sanity test to fail fast if Scorecard is unavailable
|
// Add vulnerabilities. We will publish only the minimum required information.
|
||||||
if (insights.Scorecard == nil) || (insights.Scorecard.Content == nil) {
|
// The backend should have its own VDB to enrich the data.
|
||||||
return
|
vulnerabilities := utils.SafelyGetValue(insights.Vulnerabilities)
|
||||||
|
for _, v := range vulnerabilities {
|
||||||
|
vId := utils.SafelyGetValue(v.Id)
|
||||||
|
vulnerability := vulnerabilityv1.Vulnerability{
|
||||||
|
Id: &vulnerabilityv1.VulnerabilityIdentifier{
|
||||||
|
Value: vId,
|
||||||
|
},
|
||||||
|
Summary: utils.SafelyGetValue(v.Summary),
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.HasPrefix(vId, "CVE-") {
|
||||||
|
vulnerability.Id.Type = vulnerabilityv1.VulnerabilityIdentifierType_VULNERABILITY_IDENTIFIER_TYPE_CVE
|
||||||
|
} else if strings.HasPrefix(vId, "OSV-") {
|
||||||
|
vulnerability.Id.Type = vulnerabilityv1.VulnerabilityIdentifierType_VULNERABILITY_IDENTIFIER_TYPE_OSV
|
||||||
|
}
|
||||||
|
|
||||||
|
req.PackageVersionInsight.Vulnerabilities = append(req.PackageVersionInsight.Vulnerabilities, &vulnerability)
|
||||||
}
|
}
|
||||||
|
|
||||||
scorecard := utils.SafelyGetValue(insights.Scorecard)
|
// Add project information
|
||||||
scorecardContent := utils.SafelyGetValue(scorecard.Content)
|
project := utils.SafelyGetValue(insights.Projects)
|
||||||
scorecardRepo := utils.SafelyGetValue(scorecardContent.Repository)
|
for _, p := range project {
|
||||||
scorecardChecks := utils.SafelyGetValue(scorecardContent.Checks)
|
stars := int64(utils.SafelyGetValue(p.Stars))
|
||||||
|
forks := int64(utils.SafelyGetValue(p.Forks))
|
||||||
|
issues := int64(utils.SafelyGetValue(p.Issues))
|
||||||
|
|
||||||
date := utils.SafelyGetValue(scorecardContent.Date).Format("2006-01-02")
|
vt := packagev1.ProjectSourceType_PROJECT_SOURCE_TYPE_UNSPECIFIED
|
||||||
repo := struct {
|
switch utils.SafelyGetValue(p.Type) {
|
||||||
Commit *string `json:"commit,omitempty"`
|
case "GITHUB":
|
||||||
Name *string `json:"name,omitempty"`
|
vt = packagev1.ProjectSourceType_PROJECT_SOURCE_TYPE_GITHUB
|
||||||
}{
|
case "GITLAB":
|
||||||
Commit: scorecardRepo.Commit,
|
vt = packagev1.ProjectSourceType_PROJECT_SOURCE_TYPE_GITLAB
|
||||||
Name: scorecardRepo.Name,
|
}
|
||||||
}
|
|
||||||
|
|
||||||
checks := []struct {
|
req.PackageVersionInsight.ProjectInsights = append(req.PackageVersionInsight.ProjectInsights, &packagev1.ProjectInsight{
|
||||||
Details *[]string `json:"details,omitempty"`
|
Project: &packagev1.Project{
|
||||||
Documentation *struct {
|
Type: vt,
|
||||||
Short *string `json:"short,omitempty"`
|
Name: utils.SafelyGetValue(p.Name),
|
||||||
Url *string `json:"url,omitempty"`
|
Url: utils.SafelyGetValue(p.Link),
|
||||||
} `json:"documentation,omitempty"`
|
},
|
||||||
Name *string `json:"name,omitempty"`
|
|
||||||
Reason *string `json:"reason,omitempty"`
|
|
||||||
Score *int `json:"score"`
|
|
||||||
}{}
|
|
||||||
|
|
||||||
for _, check := range scorecardChecks {
|
Stars: &stars,
|
||||||
// We have to do this stupid type conversion because Scorecard check score seems
|
Forks: &forks,
|
||||||
// be to int / float32 in different specs. We are good with downsizing width because
|
Issues: &packagev1.ProjectInsight_IssueStat{
|
||||||
// scorecard score is max 10
|
Total: issues,
|
||||||
checkScore := utils.SafelyGetValue(check.Score)
|
},
|
||||||
checkScoreInt := int(math.Round(float64(checkScore)))
|
|
||||||
|
|
||||||
checks = append(checks, struct {
|
|
||||||
Details *[]string `json:"details,omitempty"`
|
|
||||||
Documentation *struct {
|
|
||||||
Short *string `json:"short,omitempty"`
|
|
||||||
Url *string `json:"url,omitempty"`
|
|
||||||
} `json:"documentation,omitempty"`
|
|
||||||
Name *string `json:"name,omitempty"`
|
|
||||||
Reason *string `json:"reason,omitempty"`
|
|
||||||
Score *int `json:"score"`
|
|
||||||
}{
|
|
||||||
Details: check.Details,
|
|
||||||
Name: (*string)(check.Name),
|
|
||||||
Reason: check.Reason,
|
|
||||||
Score: &checkScoreInt,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
issue := &syncv1.IssuePackageScorecard{
|
licenses := utils.SafelyGetValue(insights.Licenses)
|
||||||
PackageIssue: s.buildPackageIssue(syncv1.IssueIssueTypePackageOpenssfScorecard,
|
for _, license := range licenses {
|
||||||
manifest, pkg),
|
req.PackageVersionInsight.Licenses.Licenses = append(req.PackageVersionInsight.Licenses.Licenses, &packagev1.LicenseMeta{
|
||||||
Date: &date,
|
LicenseId: string(license),
|
||||||
Score: scorecardContent.Score,
|
Name: string(license),
|
||||||
Repo: &repo,
|
})
|
||||||
Checks: &checks,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
s.queueIssueForSync(&syncIssueWrapper{issue: issue})
|
// OpenSSF
|
||||||
}
|
// We can't use vet's collected scorecard because its data model is wrong. There is
|
||||||
|
// not a single scorecard per package. Rather there is a scorecard per project. Since
|
||||||
|
// a package may be related to multiple projects, we will have multiple related scorecards.
|
||||||
|
|
||||||
func validateSyncReporterConfig(config *SyncReporterConfig) error {
|
_, err = session.toolServiceClient.PublishPackageInsight(context.Background(), &req)
|
||||||
if utils.IsEmptyString(config.ProjectName) {
|
if err != nil {
|
||||||
return errors.New("project name not in config")
|
return fmt.Errorf("failed to publish package insight: %w", err)
|
||||||
}
|
|
||||||
|
|
||||||
if utils.IsEmptyString(config.StreamName) {
|
|
||||||
return errors.New("stream name not in config")
|
|
||||||
}
|
|
||||||
|
|
||||||
if utils.IsEmptyString(config.TriggerEvent) {
|
|
||||||
return errors.New("trigger event not in config")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func createJobForSyncReportSession(client *syncv1.ClientWithResponses,
|
|
||||||
config *SyncReporterConfig) (string, error) {
|
|
||||||
|
|
||||||
jobConfig := syncv1.CreateSyncJobJSONRequestBody{
|
|
||||||
ProjectName: config.ProjectName,
|
|
||||||
ProjectSource: syncv1.CreateJobRequestProjectSource(config.ProjectSource),
|
|
||||||
StreamName: config.StreamName,
|
|
||||||
TriggerEvent: syncv1.CreateJobRequestTriggerEvent(config.TriggerEvent),
|
|
||||||
ToolType: syncv1.CreateJobRequestToolType(config.toolType),
|
|
||||||
ToolName: config.toolName,
|
|
||||||
ToolVersion: config.toolVersion,
|
|
||||||
GitRefType: (*syncv1.CreateJobRequestGitRefType)(&config.GitRefType),
|
|
||||||
GitRef: &config.GitRef,
|
|
||||||
GitRefName: &config.GitRefName,
|
|
||||||
GitSha: &config.GitSha,
|
|
||||||
}
|
|
||||||
|
|
||||||
job, err := client.CreateSyncJobWithResponse(context.Background(), jobConfig)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
defer job.HTTPResponse.Body.Close()
|
|
||||||
|
|
||||||
if job.HTTPResponse.StatusCode != http.StatusCreated {
|
|
||||||
err, _ = api_errors.UnmarshalApiError(job.Body)
|
|
||||||
return "", fmt.Errorf("invalid response code %d from Job API : %w",
|
|
||||||
job.HTTPResponse.StatusCode, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
res := utils.SafelyGetValue(job.JSON201)
|
|
||||||
return utils.SafelyGetValue(res.Id), nil
|
|
||||||
}
|
|
||||||
|
|||||||
22
scan.go
22
scan.go
@ -51,6 +51,7 @@ var (
|
|||||||
disableAuthVerifyBeforeScan bool
|
disableAuthVerifyBeforeScan bool
|
||||||
syncReport bool
|
syncReport bool
|
||||||
syncReportProject string
|
syncReportProject string
|
||||||
|
syncEnableMultiProject bool
|
||||||
graphReportDirectory string
|
graphReportDirectory string
|
||||||
syncReportStream string
|
syncReportStream string
|
||||||
listExperimentalParsers bool
|
listExperimentalParsers bool
|
||||||
@ -140,7 +141,9 @@ func newScanCommand() *cobra.Command {
|
|||||||
"Enable syncing report data to cloud")
|
"Enable syncing report data to cloud")
|
||||||
cmd.Flags().StringVarP(&syncReportProject, "report-sync-project", "", "",
|
cmd.Flags().StringVarP(&syncReportProject, "report-sync-project", "", "",
|
||||||
"Project name to use in cloud")
|
"Project name to use in cloud")
|
||||||
cmd.Flags().StringVarP(&syncReportStream, "report-sync-stream", "", "",
|
cmd.Flags().BoolVarP(&syncEnableMultiProject, "report-sync-multi-project", "", false,
|
||||||
|
"Lazily create cloud sessions for multiple projects (per manifest)")
|
||||||
|
cmd.Flags().StringVarP(&syncReportStream, "report-sync-project-version", "", "",
|
||||||
"Project stream name (e.g. branch) to use in cloud")
|
"Project stream name (e.g. branch) to use in cloud")
|
||||||
cmd.Flags().StringArrayVarP(&trustedRegistryUrls, "trusted-registry", "", []string{},
|
cmd.Flags().StringArrayVarP(&trustedRegistryUrls, "trusted-registry", "", []string{},
|
||||||
"Trusted registry URLs to use for package manifest verification")
|
"Trusted registry URLs to use for package manifest verification")
|
||||||
@ -175,9 +178,7 @@ func listParsersCommand() *cobra.Command {
|
|||||||
|
|
||||||
func startScan() {
|
func startScan() {
|
||||||
if !disableAuthVerifyBeforeScan {
|
if !disableAuthVerifyBeforeScan {
|
||||||
err := auth.Verify(&auth.VerifyConfig{
|
err := auth.Verify()
|
||||||
ControlPlaneApiUrl: auth.DefaultControlPlaneApiUrl(),
|
|
||||||
})
|
|
||||||
|
|
||||||
// We will fallback to community mode by default to provide
|
// We will fallback to community mode by default to provide
|
||||||
// a seamless user experience
|
// a seamless user experience
|
||||||
@ -393,9 +394,18 @@ func internalStartScan() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if syncReport {
|
if syncReport {
|
||||||
|
clientConn, err := auth.SyncClientConnection("vet-sync")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
rp, err := reporter.NewSyncReporter(reporter.SyncReporterConfig{
|
rp, err := reporter.NewSyncReporter(reporter.SyncReporterConfig{
|
||||||
ProjectName: syncReportProject,
|
ToolName: "vet",
|
||||||
StreamName: syncReportStream,
|
ToolVersion: version,
|
||||||
|
ProjectName: syncReportProject,
|
||||||
|
ProjectVersion: syncReportStream,
|
||||||
|
EnableMultiProjectSync: syncEnableMultiProject,
|
||||||
|
ClientConnection: clientConn,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@ -7,8 +7,6 @@ export E2E_ROOT="$E2E_THIS_DIR/../../"
|
|||||||
export E2E_FIXTURES="$E2E_THIS_DIR/fixtures"
|
export E2E_FIXTURES="$E2E_THIS_DIR/fixtures"
|
||||||
export E2E_VET_BINARY="$E2E_ROOT/vet"
|
export E2E_VET_BINARY="$E2E_ROOT/vet"
|
||||||
|
|
||||||
$E2E_VET_BINARY auth configure --community
|
|
||||||
|
|
||||||
bash $E2E_THIS_DIR/scenario-1-vet-scans-vet.sh
|
bash $E2E_THIS_DIR/scenario-1-vet-scans-vet.sh
|
||||||
bash $E2E_THIS_DIR/scenario-2-vet-scan-demo-client-java.sh
|
bash $E2E_THIS_DIR/scenario-2-vet-scan-demo-client-java.sh
|
||||||
bash $E2E_THIS_DIR/scenario-3-filter-fail-fast.sh
|
bash $E2E_THIS_DIR/scenario-3-filter-fail-fast.sh
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user