Merge pull request #173 from gabriel-samfira/switch-to-seal-unseal

Switch to seal unseal
This commit is contained in:
Gabriel 2023-08-28 11:42:25 +03:00 committed by GitHub
commit f463a41ce2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
310 changed files with 11006 additions and 1967 deletions

View file

@ -17,7 +17,7 @@ func (s *sqlDatabase) CreateEnterprise(ctx context.Context, name, credentialsNam
if webhookSecret == "" {
return params.Enterprise{}, errors.New("creating enterprise: missing secret")
}
secret, err := util.Aes256EncodeString(webhookSecret, s.cfg.Passphrase)
secret, err := util.Seal([]byte(webhookSecret), []byte(s.cfg.Passphrase))
if err != nil {
return params.Enterprise{}, errors.Wrap(err, "encoding secret")
}
@ -110,7 +110,7 @@ func (s *sqlDatabase) UpdateEnterprise(ctx context.Context, enterpriseID string,
}
if param.WebhookSecret != "" {
secret, err := util.Aes256EncodeString(param.WebhookSecret, s.cfg.Passphrase)
secret, err := util.Seal([]byte(param.WebhookSecret), []byte(s.cfg.Passphrase))
if err != nil {
return params.Enterprise{}, errors.Wrap(err, "encoding secret")
}
@ -192,7 +192,7 @@ func (s *sqlDatabase) CreateEnterprisePool(ctx context.Context, enterpriseID str
return params.Pool{}, errors.Wrap(err, "fetching pool")
}
return s.sqlToCommonPool(pool), nil
return s.sqlToCommonPool(pool)
}
func (s *sqlDatabase) GetEnterprisePool(ctx context.Context, enterpriseID, poolID string) (params.Pool, error) {
@ -200,7 +200,7 @@ func (s *sqlDatabase) GetEnterprisePool(ctx context.Context, enterpriseID, poolI
if err != nil {
return params.Pool{}, errors.Wrap(err, "fetching pool")
}
return s.sqlToCommonPool(pool), nil
return s.sqlToCommonPool(pool)
}
func (s *sqlDatabase) DeleteEnterprisePool(ctx context.Context, enterpriseID, poolID string) error {
@ -240,7 +240,10 @@ func (s *sqlDatabase) ListEnterprisePools(ctx context.Context, enterpriseID stri
ret := make([]params.Pool, len(pools))
for idx, pool := range pools {
ret[idx] = s.sqlToCommonPool(pool)
ret[idx], err = s.sqlToCommonPool(pool)
if err != nil {
return nil, errors.Wrap(err, "fetching pools")
}
}
return ret, nil
@ -254,7 +257,11 @@ func (s *sqlDatabase) ListEnterpriseInstances(ctx context.Context, enterpriseID
ret := []params.Instance{}
for _, pool := range pools {
for _, instance := range pool.Instances {
ret = append(ret, s.sqlToParamsInstance(instance))
paramsInstance, err := s.sqlToParamsInstance(instance)
if err != nil {
return nil, errors.Wrap(err, "fetching instance")
}
ret = append(ret, paramsInstance)
}
}
return ret, nil

View file

@ -59,7 +59,7 @@ func (s *sqlDatabase) CreateInstance(ctx context.Context, poolID string, param p
return params.Instance{}, errors.Wrap(q.Error, "creating instance")
}
return s.sqlToParamsInstance(newInstance), nil
return s.sqlToParamsInstance(newInstance)
}
func (s *sqlDatabase) getInstanceByID(ctx context.Context, instanceID string) (Instance, error) {
@ -128,7 +128,7 @@ func (s *sqlDatabase) GetPoolInstanceByName(ctx context.Context, poolID string,
return params.Instance{}, errors.Wrap(err, "fetching instance")
}
return s.sqlToParamsInstance(instance), nil
return s.sqlToParamsInstance(instance)
}
func (s *sqlDatabase) GetInstanceByName(ctx context.Context, instanceName string) (params.Instance, error) {
@ -137,7 +137,7 @@ func (s *sqlDatabase) GetInstanceByName(ctx context.Context, instanceName string
return params.Instance{}, errors.Wrap(err, "fetching instance")
}
return s.sqlToParamsInstance(instance), nil
return s.sqlToParamsInstance(instance)
}
func (s *sqlDatabase) DeleteInstance(ctx context.Context, poolID string, instanceName string) error {
@ -255,7 +255,7 @@ func (s *sqlDatabase) UpdateInstance(ctx context.Context, instanceID string, par
}
}
return s.sqlToParamsInstance(instance), nil
return s.sqlToParamsInstance(instance)
}
func (s *sqlDatabase) ListPoolInstances(ctx context.Context, poolID string) ([]params.Instance, error) {
@ -273,7 +273,10 @@ func (s *sqlDatabase) ListPoolInstances(ctx context.Context, poolID string) ([]p
ret := make([]params.Instance, len(instances))
for idx, inst := range instances {
ret[idx] = s.sqlToParamsInstance(inst)
ret[idx], err = s.sqlToParamsInstance(inst)
if err != nil {
return nil, errors.Wrap(err, "converting instance")
}
}
return ret, nil
}
@ -286,8 +289,12 @@ func (s *sqlDatabase) ListAllInstances(ctx context.Context) ([]params.Instance,
return nil, errors.Wrap(q.Error, "fetching instances")
}
ret := make([]params.Instance, len(instances))
var err error
for idx, instance := range instances {
ret[idx] = s.sqlToParamsInstance(instance)
ret[idx], err = s.sqlToParamsInstance(instance)
if err != nil {
return nil, errors.Wrap(err, "converting instance")
}
}
return ret, nil
}

View file

@ -32,7 +32,7 @@ func (s *sqlDatabase) CreateOrganization(ctx context.Context, name, credentialsN
if webhookSecret == "" {
return params.Organization{}, errors.New("creating org: missing secret")
}
secret, err := util.Aes256EncodeString(webhookSecret, s.cfg.Passphrase)
secret, err := util.Seal([]byte(webhookSecret), []byte(s.cfg.Passphrase))
if err != nil {
return params.Organization{}, fmt.Errorf("failed to encrypt string")
}
@ -114,7 +114,7 @@ func (s *sqlDatabase) UpdateOrganization(ctx context.Context, orgID string, para
}
if param.WebhookSecret != "" {
secret, err := util.Aes256EncodeString(param.WebhookSecret, s.cfg.Passphrase)
secret, err := util.Seal([]byte(param.WebhookSecret), []byte(s.cfg.Passphrase))
if err != nil {
return params.Organization{}, fmt.Errorf("saving org: failed to encrypt string: %w", err)
}
@ -209,7 +209,7 @@ func (s *sqlDatabase) CreateOrganizationPool(ctx context.Context, orgId string,
return params.Pool{}, errors.Wrap(err, "fetching pool")
}
return s.sqlToCommonPool(pool), nil
return s.sqlToCommonPool(pool)
}
func (s *sqlDatabase) ListOrgPools(ctx context.Context, orgID string) ([]params.Pool, error) {
@ -220,7 +220,10 @@ func (s *sqlDatabase) ListOrgPools(ctx context.Context, orgID string) ([]params.
ret := make([]params.Pool, len(pools))
for idx, pool := range pools {
ret[idx] = s.sqlToCommonPool(pool)
ret[idx], err = s.sqlToCommonPool(pool)
if err != nil {
return nil, errors.Wrap(err, "fetching pool")
}
}
return ret, nil
@ -231,7 +234,7 @@ func (s *sqlDatabase) GetOrganizationPool(ctx context.Context, orgID, poolID str
if err != nil {
return params.Pool{}, errors.Wrap(err, "fetching pool")
}
return s.sqlToCommonPool(pool), nil
return s.sqlToCommonPool(pool)
}
func (s *sqlDatabase) DeleteOrganizationPool(ctx context.Context, orgID, poolID string) error {
@ -262,7 +265,11 @@ func (s *sqlDatabase) ListOrgInstances(ctx context.Context, orgID string) ([]par
ret := []params.Instance{}
for _, pool := range pools {
for _, instance := range pool.Instances {
ret = append(ret, s.sqlToParamsInstance(instance))
paramsInstance, err := s.sqlToParamsInstance(instance)
if err != nil {
return nil, errors.Wrap(err, "fetching instance")
}
ret = append(ret, paramsInstance)
}
}
return ret, nil

View file

@ -41,8 +41,12 @@ func (s *sqlDatabase) ListAllPools(ctx context.Context) ([]params.Pool, error) {
}
ret := make([]params.Pool, len(pools))
var err error
for idx, val := range pools {
ret[idx] = s.sqlToCommonPool(val)
ret[idx], err = s.sqlToCommonPool(val)
if err != nil {
return nil, errors.Wrap(err, "converting pool")
}
}
return ret, nil
}
@ -52,7 +56,7 @@ func (s *sqlDatabase) GetPoolByID(ctx context.Context, poolID string) (params.Po
if err != nil {
return params.Pool{}, errors.Wrap(err, "fetching pool by ID")
}
return s.sqlToCommonPool(pool), nil
return s.sqlToCommonPool(pool)
}
func (s *sqlDatabase) DeletePoolByID(ctx context.Context, poolID string) error {
@ -197,7 +201,10 @@ func (s *sqlDatabase) findPoolByTags(id string, poolType params.PoolType, tags [
ret := make([]params.Pool, len(pools))
for idx, val := range pools {
ret[idx] = s.sqlToCommonPool(val)
ret[idx], err = s.sqlToCommonPool(val)
if err != nil {
return nil, errors.Wrap(err, "converting pool")
}
}
return ret, nil

View file

@ -32,7 +32,7 @@ func (s *sqlDatabase) CreateRepository(ctx context.Context, owner, name, credent
if webhookSecret == "" {
return params.Repository{}, errors.New("creating repo: missing secret")
}
secret, err := util.Aes256EncodeString(webhookSecret, s.cfg.Passphrase)
secret, err := util.Seal([]byte(webhookSecret), []byte(s.cfg.Passphrase))
if err != nil {
return params.Repository{}, fmt.Errorf("failed to encrypt string")
}
@ -114,7 +114,7 @@ func (s *sqlDatabase) UpdateRepository(ctx context.Context, repoID string, param
}
if param.WebhookSecret != "" {
secret, err := util.Aes256EncodeString(param.WebhookSecret, s.cfg.Passphrase)
secret, err := util.Seal([]byte(param.WebhookSecret), []byte(s.cfg.Passphrase))
if err != nil {
return params.Repository{}, fmt.Errorf("saving repo: failed to encrypt string: %w", err)
}
@ -209,7 +209,7 @@ func (s *sqlDatabase) CreateRepositoryPool(ctx context.Context, repoId string, p
return params.Pool{}, errors.Wrap(err, "fetching pool")
}
return s.sqlToCommonPool(pool), nil
return s.sqlToCommonPool(pool)
}
func (s *sqlDatabase) ListRepoPools(ctx context.Context, repoID string) ([]params.Pool, error) {
@ -220,7 +220,10 @@ func (s *sqlDatabase) ListRepoPools(ctx context.Context, repoID string) ([]param
ret := make([]params.Pool, len(pools))
for idx, pool := range pools {
ret[idx] = s.sqlToCommonPool(pool)
ret[idx], err = s.sqlToCommonPool(pool)
if err != nil {
return nil, errors.Wrap(err, "fetching pool")
}
}
return ret, nil
@ -231,7 +234,7 @@ func (s *sqlDatabase) GetRepositoryPool(ctx context.Context, repoID, poolID stri
if err != nil {
return params.Pool{}, errors.Wrap(err, "fetching pool")
}
return s.sqlToCommonPool(pool), nil
return s.sqlToCommonPool(pool)
}
func (s *sqlDatabase) DeleteRepositoryPool(ctx context.Context, repoID, poolID string) error {
@ -263,7 +266,11 @@ func (s *sqlDatabase) ListRepoInstances(ctx context.Context, repoID string) ([]p
ret := []params.Instance{}
for _, pool := range pools {
for _, instance := range pool.Instances {
ret = append(ret, s.sqlToParamsInstance(instance))
paramsInstance, err := s.sqlToParamsInstance(instance)
if err != nil {
return nil, errors.Wrap(err, "fetching instance")
}
ret = append(ret, paramsInstance)
}
}
return ret, nil

View file

@ -28,14 +28,19 @@ import (
commonParams "github.com/cloudbase/garm-provider-common/params"
)
func (s *sqlDatabase) sqlToParamsInstance(instance Instance) params.Instance {
func (s *sqlDatabase) sqlToParamsInstance(instance Instance) (params.Instance, error) {
var id string
if instance.ProviderID != nil {
id = *instance.ProviderID
}
var labels []string
_ = json.Unmarshal(instance.AditionalLabels, &labels)
if len(instance.AditionalLabels) > 0 {
if err := json.Unmarshal(instance.AditionalLabels, &labels); err != nil {
return params.Instance{}, errors.Wrap(err, "unmarshalling labels")
}
}
ret := params.Instance{
ID: instance.ID.String(),
ProviderID: id,
@ -74,7 +79,7 @@ func (s *sqlDatabase) sqlToParamsInstance(instance Instance) params.Instance {
EventLevel: msg.EventLevel,
})
}
return ret
return ret, nil
}
func (s *sqlDatabase) sqlAddressToParamsAddress(addr Address) commonParams.Address {
@ -88,7 +93,7 @@ func (s *sqlDatabase) sqlToCommonOrganization(org Organization) (params.Organiza
if len(org.WebhookSecret) == 0 {
return params.Organization{}, errors.New("missing secret")
}
secret, err := util.Aes256DecodeString(org.WebhookSecret, s.cfg.Passphrase)
secret, err := util.Unseal(org.WebhookSecret, []byte(s.cfg.Passphrase))
if err != nil {
return params.Organization{}, errors.Wrap(err, "decrypting secret")
}
@ -98,11 +103,14 @@ func (s *sqlDatabase) sqlToCommonOrganization(org Organization) (params.Organiza
Name: org.Name,
CredentialsName: org.CredentialsName,
Pools: make([]params.Pool, len(org.Pools)),
WebhookSecret: secret,
WebhookSecret: string(secret),
}
for idx, pool := range org.Pools {
ret.Pools[idx] = s.sqlToCommonPool(pool)
ret.Pools[idx], err = s.sqlToCommonPool(pool)
if err != nil {
return params.Organization{}, errors.Wrap(err, "converting pool")
}
}
return ret, nil
@ -112,7 +120,7 @@ func (s *sqlDatabase) sqlToCommonEnterprise(enterprise Enterprise) (params.Enter
if len(enterprise.WebhookSecret) == 0 {
return params.Enterprise{}, errors.New("missing secret")
}
secret, err := util.Aes256DecodeString(enterprise.WebhookSecret, s.cfg.Passphrase)
secret, err := util.Unseal(enterprise.WebhookSecret, []byte(s.cfg.Passphrase))
if err != nil {
return params.Enterprise{}, errors.Wrap(err, "decrypting secret")
}
@ -122,17 +130,20 @@ func (s *sqlDatabase) sqlToCommonEnterprise(enterprise Enterprise) (params.Enter
Name: enterprise.Name,
CredentialsName: enterprise.CredentialsName,
Pools: make([]params.Pool, len(enterprise.Pools)),
WebhookSecret: secret,
WebhookSecret: string(secret),
}
for idx, pool := range enterprise.Pools {
ret.Pools[idx] = s.sqlToCommonPool(pool)
ret.Pools[idx], err = s.sqlToCommonPool(pool)
if err != nil {
return params.Enterprise{}, errors.Wrap(err, "converting pool")
}
}
return ret, nil
}
func (s *sqlDatabase) sqlToCommonPool(pool Pool) params.Pool {
func (s *sqlDatabase) sqlToCommonPool(pool Pool) (params.Pool, error) {
ret := params.Pool{
ID: pool.ID.String(),
ProviderName: pool.ProviderName,
@ -174,11 +185,15 @@ func (s *sqlDatabase) sqlToCommonPool(pool Pool) params.Pool {
ret.Tags[idx] = s.sqlToCommonTags(*val)
}
var err error
for idx, inst := range pool.Instances {
ret.Instances[idx] = s.sqlToParamsInstance(inst)
ret.Instances[idx], err = s.sqlToParamsInstance(inst)
if err != nil {
return params.Pool{}, errors.Wrap(err, "converting instance")
}
}
return ret
return ret, nil
}
func (s *sqlDatabase) sqlToCommonTags(tag Tag) params.Tag {
@ -192,7 +207,7 @@ func (s *sqlDatabase) sqlToCommonRepository(repo Repository) (params.Repository,
if len(repo.WebhookSecret) == 0 {
return params.Repository{}, errors.New("missing secret")
}
secret, err := util.Aes256DecodeString(repo.WebhookSecret, s.cfg.Passphrase)
secret, err := util.Unseal(repo.WebhookSecret, []byte(s.cfg.Passphrase))
if err != nil {
return params.Repository{}, errors.Wrap(err, "decrypting secret")
}
@ -203,11 +218,14 @@ func (s *sqlDatabase) sqlToCommonRepository(repo Repository) (params.Repository,
Owner: repo.Owner,
CredentialsName: repo.CredentialsName,
Pools: make([]params.Pool, len(repo.Pools)),
WebhookSecret: secret,
WebhookSecret: string(secret),
}
for idx, pool := range repo.Pools {
ret.Pools[idx] = s.sqlToCommonPool(pool)
ret.Pools[idx], err = s.sqlToCommonPool(pool)
if err != nil {
return params.Repository{}, errors.Wrap(err, "converting pool")
}
}
return ret, nil
@ -311,5 +329,5 @@ func (s *sqlDatabase) updatePool(pool Pool, param params.UpdatePoolParams) (para
}
}
return s.sqlToCommonPool(pool), nil
return s.sqlToCommonPool(pool)
}

19
go.mod
View file

@ -4,13 +4,13 @@ go 1.20
require (
github.com/BurntSushi/toml v1.2.1
github.com/cloudbase/garm-provider-common v0.0.0-20230726155746-1e24ecc05fcc
github.com/cloudbase/garm-provider-common v0.0.0-20230825065515-e2653248f5b9
github.com/go-openapi/errors v0.20.4
github.com/go-openapi/runtime v0.26.0
github.com/go-openapi/strfmt v0.21.7
github.com/go-openapi/swag v0.22.4
github.com/golang-jwt/jwt v3.2.2+incompatible
github.com/google/go-github/v53 v53.2.0
github.com/google/go-github/v54 v54.0.0
github.com/google/uuid v1.3.0
github.com/gorilla/handlers v1.5.1
github.com/gorilla/mux v1.8.0
@ -24,9 +24,9 @@ require (
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.14.0
github.com/spf13/cobra v1.7.1-0.20230723113155-fd865a44e3c4
github.com/stretchr/testify v1.8.2
golang.org/x/crypto v0.7.0
golang.org/x/oauth2 v0.8.0
github.com/stretchr/testify v1.8.4
golang.org/x/crypto v0.12.0
golang.org/x/oauth2 v0.11.0
golang.org/x/sync v0.1.0
gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0
gopkg.in/natefinch/lumberjack.v2 v2.2.1
@ -76,6 +76,7 @@ require (
github.com/mattn/go-runewidth v0.0.14 // indirect
github.com/mattn/go-sqlite3 v1.14.16 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/minio/sio v0.3.1 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/oklog/ulid v1.3.1 // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect
@ -96,11 +97,11 @@ require (
go.mongodb.org/mongo-driver v1.11.3 // indirect
go.opentelemetry.io/otel v1.14.0 // indirect
go.opentelemetry.io/otel/trace v1.14.0 // indirect
golang.org/x/net v0.10.0 // indirect
golang.org/x/sys v0.8.0 // indirect
golang.org/x/term v0.8.0 // indirect
golang.org/x/net v0.14.0 // indirect
golang.org/x/sys v0.11.0 // indirect
golang.org/x/term v0.11.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.30.0 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/errgo.v1 v1.0.1 // indirect
gopkg.in/httprequest.v1 v1.2.1 // indirect
gopkg.in/macaroon.v2 v2.1.0 // indirect

40
go.sum
View file

@ -25,8 +25,8 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn
github.com/chzyer/test v1.0.0 h1:p3BQDXSxOhOG0P9z6/hGnII4LGiEPOYBhs8asl/fC04=
github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cloudbase/garm-provider-common v0.0.0-20230726155746-1e24ecc05fcc h1:LnSj5+iakacm98afpOgSmjcQOMf45Nk/2YHhlWlqXOM=
github.com/cloudbase/garm-provider-common v0.0.0-20230726155746-1e24ecc05fcc/go.mod h1:RKzgL0MXkNeGfloQpE2swz/y4LWJr5+2Wd45bSXPB0k=
github.com/cloudbase/garm-provider-common v0.0.0-20230825065515-e2653248f5b9 h1:qp2gyH//y2xa5HZbkoIoVS6dRUT/aKgVzKKMJJy5xyY=
github.com/cloudbase/garm-provider-common v0.0.0-20230825065515-e2653248f5b9/go.mod h1:3XNTd7WcFtXDqi0Cm2aX4RkKXdW3+9eOguMOyp605/Q=
github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I=
github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs=
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
@ -150,8 +150,8 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-github/v53 v53.2.0 h1:wvz3FyF53v4BK+AsnvCmeNhf8AkTaeh2SoYu/XUvTtI=
github.com/google/go-github/v53 v53.2.0/go.mod h1:XhFRObz+m/l+UCm9b7KSIC3lT3NWSXGt7mOsAWEloao=
github.com/google/go-github/v54 v54.0.0 h1:OZdXwow4EAD5jEo5qg+dGFH2DpkyZvVsAehjvJuUL/c=
github.com/google/go-github/v54 v54.0.0/go.mod h1:Sw1LXWHhXRZtzJ9LI5fyJg9wbQzYvFhW8W5P2yaAQ7s=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@ -241,6 +241,8 @@ github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/microsoft/go-mssqldb v0.17.0 h1:Fto83dMZPnYv1Zwx5vHHxpNraeEaUlQ/hhHLgZiaenE=
github.com/minio/sio v0.3.1 h1:d59r5RTHb1OsQaSl1EaTWurzMMDRLA5fgNmjzD4eVu4=
github.com/minio/sio v0.3.1/go.mod h1:S0ovgVgc+sTlQyhiXA1ppBLv7REM7TYi5yyq2qL/Y6o=
github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
@ -316,8 +318,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
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.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/teris-io/shortid v0.0.0-20220617161101-71ec9f2aa569 h1:xzABM9let0HLLqFypcxvLmlvEciCHL7+Lv+4vwZqecI=
github.com/teris-io/shortid v0.0.0-20220617161101-71ec9f2aa569/go.mod h1:2Ly+NIftZN4de9zRmENdYbvPQeaVIYKWpLFStLFEBgI=
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
@ -348,8 +350,8 @@ golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
@ -367,11 +369,11 @@ golang.org/x/net v0.0.0-20200505041828-1ed23360d12c/go.mod h1:qpuaurCH72eLCgpAm/
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8=
golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE=
golang.org/x/oauth2 v0.11.0 h1:vPL4xzxBM4niKCW6g9whtaWVXTJf1U5e4aZxxFx/gbU=
golang.org/x/oauth2 v0.11.0/go.mod h1:LdF7O/8bLR/qWK9DrpXmbHLTouvRHK0SgJl0GmDBchk=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -403,18 +405,18 @@ golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0=
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
@ -450,8 +452,8 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0 h1:FVCohIoYO7IJoDDVpV2pdq7SgrMH6wHnuTyrdrxJNoY=
gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0/go.mod h1:OdE7CF6DbADk7lN8LIKRzRJTTZXIjtWgA5THM5lhBAw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View file

@ -22,7 +22,7 @@ import (
"github.com/cloudbase/garm/util/appdefaults"
"github.com/google/go-github/v53/github"
"github.com/google/go-github/v54/github"
"github.com/google/uuid"
)

View file

@ -5,7 +5,7 @@ package mocks
import (
context "context"
github "github.com/google/go-github/v53/github"
github "github.com/google/go-github/v54/github"
mock "github.com/stretchr/testify/mock"
)

View file

@ -5,7 +5,7 @@ package mocks
import (
context "context"
github "github.com/google/go-github/v53/github"
github "github.com/google/go-github/v54/github"
mock "github.com/stretchr/testify/mock"
)

View file

@ -5,7 +5,7 @@ package mocks
import (
context "context"
github "github.com/google/go-github/v53/github"
github "github.com/google/go-github/v54/github"
mock "github.com/stretchr/testify/mock"
)

View file

@ -5,7 +5,7 @@ package mocks
import (
context "context"
github "github.com/google/go-github/v53/github"
github "github.com/google/go-github/v54/github"
mock "github.com/stretchr/testify/mock"
)

View file

@ -3,7 +3,7 @@ package common
import (
"context"
"github.com/google/go-github/v53/github"
"github.com/google/go-github/v54/github"
)
type OrganizationHooks interface {

View file

@ -6,7 +6,7 @@ import (
runnerErrors "github.com/cloudbase/garm-provider-common/errors"
"github.com/cloudbase/garm/params"
"github.com/google/go-github/v53/github"
"github.com/google/go-github/v54/github"
"github.com/pkg/errors"
)

View file

@ -13,7 +13,7 @@ import (
"github.com/cloudbase/garm/runner/common"
"github.com/cloudbase/garm/util"
"github.com/google/go-github/v53/github"
"github.com/google/go-github/v54/github"
"github.com/pkg/errors"
)

View file

@ -20,7 +20,7 @@ import (
"github.com/cloudbase/garm/params"
"github.com/cloudbase/garm/runner/common"
"github.com/google/go-github/v53/github"
"github.com/google/go-github/v54/github"
)
type poolHelper interface {

View file

@ -28,7 +28,7 @@ import (
"github.com/cloudbase/garm/runner/common"
"github.com/cloudbase/garm/util"
"github.com/google/go-github/v53/github"
"github.com/google/go-github/v54/github"
"github.com/pkg/errors"
)

View file

@ -34,7 +34,7 @@ import (
"github.com/cloudbase/garm/params"
"github.com/cloudbase/garm/runner/common"
"github.com/google/go-github/v53/github"
"github.com/google/go-github/v54/github"
"github.com/google/uuid"
"github.com/pkg/errors"
"golang.org/x/sync/errgroup"

View file

@ -28,7 +28,7 @@ import (
"github.com/cloudbase/garm/runner/common"
"github.com/cloudbase/garm/util"
"github.com/google/go-github/v53/github"
"github.com/google/go-github/v54/github"
"github.com/pkg/errors"
)

View file

@ -26,7 +26,7 @@ import (
"github.com/cloudbase/garm/params"
"github.com/cloudbase/garm/runner/common"
"github.com/google/go-github/v53/github"
"github.com/google/go-github/v54/github"
lxd "github.com/lxc/lxd/client"
"github.com/lxc/lxd/shared/api"
"github.com/pkg/errors"

View file

@ -5,7 +5,7 @@ import (
"fmt"
"log"
"github.com/google/go-github/v53/github"
"github.com/google/go-github/v54/github"
"golang.org/x/oauth2"
)

View file

@ -24,7 +24,7 @@ import (
"github.com/cloudbase/garm/params"
"github.com/cloudbase/garm/runner/common"
"github.com/google/go-github/v53/github"
"github.com/google/go-github/v54/github"
"github.com/pkg/errors"
"golang.org/x/oauth2"
)

View file

@ -40,7 +40,6 @@ if [ -z "$METADATA_URL" ];then
echo "no token is available and METADATA_URL is not set"
exit 1
fi
GITHUB_TOKEN=$(curl --retry 5 --retry-delay 5 --retry-connrefused --fail -s -X GET -H 'Accept: application/json' -H "Authorization: Bearer ${BEARER_TOKEN}" "${METADATA_URL}/runner-registration-token/")
function call() {
PAYLOAD="$1"
@ -53,11 +52,18 @@ function sendStatus() {
call "{\"status\": \"installing\", \"message\": \"$MSG\"}"
}
{{- if .UseJITConfig }}
function success() {
MSG="$1"
call "{\"status\": \"idle\", \"message\": \"$MSG\"}"
}
{{- else}}
function success() {
MSG="$1"
ID=$2
call "{\"status\": \"idle\", \"message\": \"$MSG\", \"agent_id\": $ID}"
}
{{- end}}
function fail() {
MSG="$1"
@ -105,16 +111,6 @@ function downloadAndExtractRunner() {
# chown {{ .RunnerUsername }}:{{ .RunnerGroup }} -R /home/{{ .RunnerUsername }}/actions-runner/ || fail "failed to change owner"
}
TEMP_TOKEN=""
GH_RUNNER_GROUP="{{.GitHubRunnerGroup}}"
# $RUNNER_GROUP_OPT will be added to the config.sh line. If it's empty, nothing happens
# if it holds a value, it will be part of the command.
RUNNER_GROUP_OPT=""
if [ ! -z $GH_RUNNER_GROUP ];then
RUNNER_GROUP_OPT="--runnergroup=$GH_RUNNER_GROUP"
fi
CACHED_RUNNER=$(getCachedToolsPath)
if [ -z "$CACHED_RUNNER" ];then
downloadAndExtractRunner
@ -130,11 +126,46 @@ fi
sendStatus "configuring runner"
{{- if .UseJITConfig }}
function getRunnerFile() {
curl --retry 5 --retry-delay 5 \
--retry-connrefused --fail -s \
-X GET -H 'Accept: application/json' \
-H "Authorization: Bearer ${BEARER_TOKEN}" \
"${METADATA_URL}/$1" -o "$2"
}
sendStatus "downloading JIT credentials"
getRunnerFile "credentials/runner" "/home/{{ .RunnerUsername }}/actions-runner/.runner" || fail "failed to get runner file"
getRunnerFile "credentials/credentials" "/home/{{ .RunnerUsername }}/actions-runner/.credentials" || fail "failed to get credentials file"
getRunnerFile "credentials/credentials_rsaparams" "/home/{{ .RunnerUsername }}/actions-runner/.credentials_rsaparams" || fail "failed to get credentials_rsaparams file"
getRunnerFile "system/service-name" "/home/{{ .RunnerUsername }}/actions-runner/.service" || fail "failed to get service name file"
sed -i 's/$/\.service/' /home/{{ .RunnerUsername }}/actions-runner/.service
SVC_NAME=$(cat /home/{{ .RunnerUsername }}/actions-runner/.service)
sendStatus "generating systemd unit file"
getRunnerFile "systemd/unit-file?runAsUser={{ .RunnerUsername }}" "$SVC_NAME" || fail "failed to get service file"
sudo mv $SVC_NAME /etc/systemd/system/ || fail "failed to move service file"
sendStatus "enabling runner service"
cp /home/{{ .RunnerUsername }}/actions-runner/bin/runsvc.sh /home/{{ .RunnerUsername }}/actions-runner/ || fail "failed to copy runsvc.sh"
sudo chown {{ .RunnerUsername }}:{{ .RunnerGroup }} -R /home/{{ .RunnerUsername }} || fail "failed to change owner"
sudo systemctl daemon-reload || fail "failed to reload systemd"
sudo systemctl enable $SVC_NAME
{{- else}}
GITHUB_TOKEN=$(curl --retry 5 --retry-delay 5 --retry-connrefused --fail -s -X GET -H 'Accept: application/json' -H "Authorization: Bearer ${BEARER_TOKEN}" "${METADATA_URL}/runner-registration-token/")
set +e
attempt=1
while true; do
ERROUT=$(mktemp)
./config.sh --unattended --url "{{ .RepoURL }}" --token "$GITHUB_TOKEN" $RUNNER_GROUP_OPT --name "{{ .RunnerName }}" --labels "{{ .RunnerLabels }}" --ephemeral 2>$ERROUT
{{- if .GitHubRunnerGroup }}
./config.sh --unattended --url "{{ .RepoURL }}" --token "$GITHUB_TOKEN" --runnergroup {{.GitHubRunnerGroup}} --name "{{ .RunnerName }}" --labels "{{ .RunnerLabels }}" --ephemeral 2>$ERROUT
{{- else}}
./config.sh --unattended --url "{{ .RepoURL }}" --token "$GITHUB_TOKEN" --name "{{ .RunnerName }}" --labels "{{ .RunnerLabels }}" --ephemeral 2>$ERROUT
{{- end}}
if [ $? -eq 0 ]; then
rm $ERROUT || true
sendStatus "runner successfully configured after $attempt attempt(s)"
@ -161,12 +192,17 @@ set -e
sendStatus "installing runner service"
sudo ./svc.sh install {{ .RunnerUsername }} || fail "failed to install service"
{{- end}}
if [ -e "/sys/fs/selinux" ];then
sudo chcon -h user_u:object_r:bin_t /home/runner/ || fail "failed to change selinux context"
sudo chcon -R -h {{ .RunnerUsername }}:object_r:bin_t /home/runner/* || fail "failed to change selinux context"
fi
{{- if .UseJITConfig }}
sudo systemctl start $SVC_NAME || fail "failed to start service"
success "runner successfully installed"
{{- else}}
sendStatus "starting service"
sudo ./svc.sh start || fail "failed to start service"
@ -176,8 +212,8 @@ if [ $? -ne 0 ];then
fail "failed to get agent ID"
fi
set -e
success "runner successfully installed" $AGENT_ID
{{- end}}
`
var WindowsSetupScriptTemplate = `#ps1_sysnative
@ -263,10 +299,10 @@ function Import-Certificate() {
[CmdletBinding()]
param (
[parameter(Mandatory=$true)]
[string]$CertificatePath,
[parameter(Mandatory=$true)]
$CertificateData,
[parameter(Mandatory=$false)]
[System.Security.Cryptography.X509Certificates.StoreLocation]$StoreLocation="LocalMachine",
[parameter(Mandatory=$true)]
[parameter(Mandatory=$false)]
[System.Security.Cryptography.X509Certificates.StoreName]$StoreName="TrustedPublisher"
)
PROCESS
@ -274,8 +310,7 @@ function Import-Certificate() {
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store(
$StoreName, $StoreLocation)
$store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2(
$CertificatePath)
$cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new($CertificateData)
$store.Add($cert)
}
}
@ -298,14 +333,22 @@ function Update-GarmStatus() {
param (
[parameter(Mandatory=$true)]
[string]$Message,
[parameter(Mandatory=$false)]
[int64]$AgentID=0,
[parameter(Mandatory=$false)]
[string]$Status="installing",
[parameter(Mandatory=$true)]
[string]$CallbackURL
)
PROCESS{
$body = @{
"status"="installing"
"status"=$Status
"message"=$Message
}
if ($AgentID -ne 0) {
$body["AgentID"] = $AgentID
}
Invoke-APICall -Payload $body -CallbackURL $CallbackURL | Out-Null
}
}
@ -321,12 +364,7 @@ function Invoke-GarmSuccess() {
[string]$CallbackURL
)
PROCESS{
$body = @{
"status"="idle"
"message"=$Message
"agent_id"=$AgentID
}
Invoke-APICall -Payload $body -CallbackURL $CallbackURL | Out-Null
Update-GarmStatus -Message $Message -AgentID $AgentID -CallbackURL $CallbackURL -Status "idle" | Out-Null
}
}
@ -339,18 +377,11 @@ function Invoke-GarmFailure() {
[string]$CallbackURL
)
PROCESS{
$body = @{
"status"="failed"
"message"=$Message
}
Invoke-APICall -Payload $body -CallbackURL $CallbackURL | Out-Null
Update-GarmStatus -Message $Message -CallbackURL $CallbackURL -Status "failed" | Out-Null
Throw $Message
}
}
$PEMData = @"
{{.CABundle}}
"@
$GHRunnerGroup = "{{.GitHubRunnerGroup}}"
function Install-Runner() {
@ -369,12 +400,13 @@ function Install-Runner() {
Throw "missing metadata URL"
}
if($PEMData.Trim().Length -gt 0){
Set-Content $env:TMP\garm-ca.pem $PEMData
Import-Certificate -CertificatePath $env:TMP\garm-ca.pem
$bundle = wget -UseBasicParsing -Headers @{"Accept"="application/json"; "Authorization"="Bearer $Token"} -Uri $MetadataURL/system/cert-bundle
$converted = ConvertFrom-Json $bundle
foreach ($i in $converted.root_certificates.psobject.Properties){
$data = [System.Convert]::FromBase64String($i.Value)
Import-Certificate -CertificateData $data -StoreName Root -StoreLocation LocalMachine
}
$GithubRegistrationToken = Invoke-WebRequest -UseBasicParsing -Headers @{"Accept"="application/json"; "Authorization"="Bearer $Token"} -Uri $MetadataURL/runner-registration-token/
Update-GarmStatus -CallbackURL $CallbackURL -Message "downloading tools from $DownloadURL"
$downloadToken="{{.TempDownloadToken}}"
@ -393,17 +425,42 @@ function Install-Runner() {
Update-GarmStatus -CallbackURL $CallbackURL -Message "extracting runner"
Add-Type -AssemblyName System.IO.Compression.FileSystem
[System.IO.Compression.ZipFile]::ExtractToDirectory($downloadPath, "$runnerDir")
$runnerGroupOpt = ""
if ($GHRunnerGroup.Length -gt 0){
$runnerGroupOpt = "--runnergroup $GHRunnerGroup"
}
Update-GarmStatus -CallbackURL $CallbackURL -Message "configuring and starting runner"
cd $runnerDir
./config.cmd --unattended --url "{{ .RepoURL }}" --token $GithubRegistrationToken $runnerGroupOpt --name "{{ .RunnerName }}" --labels "{{ .RunnerLabels }}" --ephemeral --runasservice
{{- if .UseJITConfig }}
Update-GarmStatus -CallbackURL $CallbackURL -Message "downloading JIT credentials"
wget -UseBasicParsing -Headers @{"Accept"="application/json"; "Authorization"="Bearer $Token"} -Uri $MetadataURL/credentials/runner -OutFile (Join-Path $runnerDir ".runner")
wget -UseBasicParsing -Headers @{"Accept"="application/json"; "Authorization"="Bearer $Token"} -Uri $MetadataURL/credentials/credentials -OutFile (Join-Path $runnerDir ".credentials")
Add-Type -AssemblyName System.Security
$rsaData = (wget -UseBasicParsing -Headers @{"Accept"="application/json"; "Authorization"="Bearer $Token"} -Uri $MetadataURL/credentials/credentials_rsaparams)
$encodedBytes = [System.Text.Encoding]::UTF8.GetBytes($rsaData)
$protectedBytes = [Security.Cryptography.ProtectedData]::Protect( $encodedBytes, $null, [Security.Cryptography.DataProtectionScope]::LocalMachine )
[System.IO.File]::WriteAllBytes((Join-Path $runnerDir ".credentials_rsaparams"), $protectedBytes)
$serviceNameFile = (Join-Path $runnerDir ".service")
wget -UseBasicParsing -Headers @{"Accept"="application/json"; "Authorization"="Bearer $Token"} -Uri $MetadataURL/system/service-name -OutFile $serviceNameFile
Update-GarmStatus -CallbackURL $CallbackURL -Message "Creating system service"
$SVC_NAME=(gc -raw $serviceNameFile)
New-Service -Name "$SVC_NAME" -BinaryPathName "C:\runner\bin\RunnerService.exe" -DisplayName "$SVC_NAME" -Description "GitHub Actions Runner ($SVC_NAME)" -StartupType Automatic
Start-Service "$SVC_NAME"
Update-GarmStatus -Message "runner successfully installed" -CallbackURL $CallbackURL -Status "idle" | Out-Null
{{- else }}
$GithubRegistrationToken = Invoke-WebRequest -UseBasicParsing -Headers @{"Accept"="application/json"; "Authorization"="Bearer $Token"} -Uri $MetadataURL/runner-registration-token/
{{- if .GitHubRunnerGroup }}
./config.cmd --unattended --url "{{ .RepoURL }}" --token $GithubRegistrationToken --runnergroup {{.GitHubRunnerGroup}} --name "{{ .RunnerName }}" --labels "{{ .RunnerLabels }}" --ephemeral --runasservice
{{- else}}
./config.cmd --unattended --url "{{ .RepoURL }}" --token $GithubRegistrationToken --name "{{ .RunnerName }}" --labels "{{ .RunnerLabels }}" --ephemeral --runasservice
{{- end}}
$agentInfoFile = Join-Path $runnerDir ".runner"
$agentInfo = ConvertFrom-Json (gc -raw $agentInfoFile)
Invoke-GarmSuccess -CallbackURL $CallbackURL -Message "runner successfully installed" -AgentID $agentInfo.agentId
{{- end }}
} catch {
Invoke-GarmFailure -CallbackURL $CallbackURL -Message $_
}
@ -452,6 +509,8 @@ type InstallRunnerParams struct {
// This option is useful for situations in which you're supplying your own template and you need
// to pass in information that is not available in the default template.
ExtraContext map[string]string
// UseJITConfig indicates whether to attempt to configure the runner using JIT or a registration token.
UseJITConfig bool
}
func InstallRunnerScript(installParams InstallRunnerParams, osType params.OSType, tpl string) ([]byte, error) {

View file

@ -8,7 +8,7 @@ import (
"github.com/cloudbase/garm-provider-common/defaults"
commonParams "github.com/cloudbase/garm-provider-common/params"
"github.com/google/go-github/v53/github"
"github.com/google/go-github/v54/github"
"github.com/pkg/errors"
)
@ -105,6 +105,7 @@ func GetRunnerInstallScript(bootstrapParams commonParams.BootstrapInstance, tool
GitHubRunnerGroup: bootstrapParams.GitHubRunnerGroup,
ExtraContext: extraSpecs.ExtraContext,
EnableBootDebug: bootstrapParams.UserDataOptions.EnableBootDebug,
UseJITConfig: bootstrapParams.JitConfigEnabled,
}
if bootstrapParams.CACertBundle != nil && len(bootstrapParams.CACertBundle) > 0 {

View file

@ -3,7 +3,7 @@ package params
import (
"encoding/json"
"github.com/google/go-github/v53/github"
"github.com/google/go-github/v54/github"
)
type (
@ -104,6 +104,12 @@ type BootstrapInstance struct {
// UserDataOptions are the options for the user data generation.
UserDataOptions UserDataOptions `json:"user_data_options"`
// JitConfigEnabled is a flag that indicates if the runner should be configured to use
// just-in-time configuration. If set to true, providers must attempt to fetch the JIT configuration
// from the metadata service instead of the runner registration token. The runner registration token
// is not available if the runner is configured to use JIT.
JitConfigEnabled bool `json:"jit_config_enabled"`
}
type Address struct {

View file

@ -0,0 +1,156 @@
package util
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"crypto/sha256"
"encoding/json"
"fmt"
"io"
"github.com/minio/sio"
"github.com/pkg/errors"
"golang.org/x/crypto/hkdf"
)
type Envelope struct {
Nonce [32]byte `json:"nonce"`
Data []byte `json:"data"`
}
// Seal will encrypt the given data using a derived key from the given passphrase.
// This function is meant to be used with small datasets like passwords, keys and
// secrets of any type, before they are saved to disk.
func Seal(data []byte, passphrase []byte) ([]byte, error) {
if len(passphrase) != 32 {
return nil, fmt.Errorf("invalid passphrase length (expected length 32 characters)")
}
var nonce [32]byte
if _, err := io.ReadFull(rand.Reader, nonce[:]); err != nil {
return nil, fmt.Errorf("failed to read random data: %w", err)
}
// derive an encryption key from the master key and the nonce
var key [32]byte
kdf := hkdf.New(sha256.New, passphrase, nonce[:], nil)
if _, err := io.ReadFull(kdf, key[:]); err != nil {
return nil, fmt.Errorf("failed to derive encryption key: %w", err)
}
input := bytes.NewReader(data)
output := bytes.NewBuffer(nil)
if _, err := sio.Encrypt(output, input, sio.Config{Key: key[:]}); err != nil {
return nil, fmt.Errorf("failed to encrypt data: %w", err)
}
envelope := Envelope{
Data: output.Bytes(),
Nonce: nonce,
}
asJs, err := json.Marshal(envelope)
if err != nil {
return nil, fmt.Errorf("failed to marshal envelope: %w", err)
}
return asJs, nil
}
// Unseal will decrypt the given data using a derived key from the given passphrase.
// This function is meant to be used with small datasets like passwords, keys and
// secrets of any type, after they are read from disk.
func Unseal(data []byte, passphrase []byte) ([]byte, error) {
if len(passphrase) != 32 {
return nil, fmt.Errorf("invalid passphrase length (expected length 32 characters)")
}
var envelope Envelope
if err := json.Unmarshal(data, &envelope); err != nil {
return Aes256Decode(data, string(passphrase))
}
// derive an encryption key from the master key and the nonce
var key [32]byte
kdf := hkdf.New(sha256.New, passphrase, envelope.Nonce[:], nil)
if _, err := io.ReadFull(kdf, key[:]); err != nil {
return nil, fmt.Errorf("failed to derive encryption key: %w", err)
}
input := bytes.NewReader(envelope.Data)
output := bytes.NewBuffer(nil)
if _, err := sio.Decrypt(output, input, sio.Config{Key: key[:]}); err != nil {
return nil, fmt.Errorf("failed to decrypt data: %w", err)
}
return output.Bytes(), nil
}
func Aes256Encode(target []byte, passphrase string) ([]byte, error) {
if len(passphrase) != 32 {
return nil, fmt.Errorf("invalid passphrase length (expected length 32 characters)")
}
block, err := aes.NewCipher([]byte(passphrase))
if err != nil {
return nil, errors.Wrap(err, "creating cipher")
}
aesgcm, err := cipher.NewGCM(block)
if err != nil {
return nil, errors.Wrap(err, "creating new aead")
}
nonce := make([]byte, aesgcm.NonceSize())
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
return nil, errors.Wrap(err, "creating nonce")
}
ciphertext := aesgcm.Seal(nonce, nonce, target, nil)
return ciphertext, nil
}
func Aes256EncodeString(target string, passphrase string) ([]byte, error) {
if len(passphrase) != 32 {
return nil, fmt.Errorf("invalid passphrase length (expected length 32 characters)")
}
return Aes256Encode([]byte(target), passphrase)
}
func Aes256Decode(target []byte, passphrase string) ([]byte, error) {
if len(passphrase) != 32 {
return nil, fmt.Errorf("invalid passphrase length (expected length 32 characters)")
}
block, err := aes.NewCipher([]byte(passphrase))
if err != nil {
return nil, errors.Wrap(err, "creating cipher")
}
aesgcm, err := cipher.NewGCM(block)
if err != nil {
return nil, errors.Wrap(err, "creating new aead")
}
nonceSize := aesgcm.NonceSize()
if len(target) < nonceSize {
return nil, fmt.Errorf("failed to decrypt text")
}
nonce, ciphertext := target[:nonceSize], target[nonceSize:]
plaintext, err := aesgcm.Open(nil, nonce, ciphertext, nil)
if err != nil {
return nil, fmt.Errorf("failed to decrypt text")
}
return plaintext, nil
}
func Aes256DecodeString(target []byte, passphrase string) (string, error) {
data, err := Aes256Decode(target, passphrase)
if err != nil {
return "", err
}
return string(data), nil
}

View file

@ -17,8 +17,6 @@ package util
import (
"bytes"
"compress/gzip"
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"encoding/base64"
"encoding/binary"
@ -37,7 +35,7 @@ import (
commonParams "github.com/cloudbase/garm-provider-common/params"
"github.com/google/go-github/v53/github"
"github.com/google/go-github/v54/github"
"github.com/google/uuid"
gorillaHandlers "github.com/gorilla/handlers"
"github.com/pkg/errors"
@ -244,59 +242,6 @@ func GetRandomString(n int) (string, error) {
return string(data), nil
}
func Aes256EncodeString(target string, passphrase string) ([]byte, error) {
if len(passphrase) != 32 {
return nil, fmt.Errorf("invalid passphrase length (expected length 32 characters)")
}
toEncrypt := []byte(target)
block, err := aes.NewCipher([]byte(passphrase))
if err != nil {
return nil, errors.Wrap(err, "creating cipher")
}
aesgcm, err := cipher.NewGCM(block)
if err != nil {
return nil, errors.Wrap(err, "creating new aead")
}
nonce := make([]byte, aesgcm.NonceSize())
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
return nil, errors.Wrap(err, "creating nonce")
}
ciphertext := aesgcm.Seal(nonce, nonce, toEncrypt, nil)
return ciphertext, nil
}
func Aes256DecodeString(target []byte, passphrase string) (string, error) {
if len(passphrase) != 32 {
return "", fmt.Errorf("invalid passphrase length (expected length 32 characters)")
}
block, err := aes.NewCipher([]byte(passphrase))
if err != nil {
return "", errors.Wrap(err, "creating cipher")
}
aesgcm, err := cipher.NewGCM(block)
if err != nil {
return "", errors.Wrap(err, "creating new aead")
}
nonceSize := aesgcm.NonceSize()
if len(target) < nonceSize {
return "", fmt.Errorf("failed to decrypt text")
}
nonce, ciphertext := target[:nonceSize], target[nonceSize:]
plaintext, err := aesgcm.Open(nil, nonce, ciphertext, nil)
if err != nil {
return "", fmt.Errorf("failed to decrypt text")
}
return string(plaintext), nil
}
// PaswsordToBcrypt returns a bcrypt hash of the specified password using the default cost
func PaswsordToBcrypt(password string) (string, error) {
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)

View file

@ -1,167 +0,0 @@
// Copyright 2018 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"encoding/json"
)
// Event represents a GitHub event.
type Event struct {
Type *string `json:"type,omitempty"`
Public *bool `json:"public,omitempty"`
RawPayload *json.RawMessage `json:"payload,omitempty"`
Repo *Repository `json:"repo,omitempty"`
Actor *User `json:"actor,omitempty"`
Org *Organization `json:"org,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
ID *string `json:"id,omitempty"`
}
func (e Event) String() string {
return Stringify(e)
}
// ParsePayload parses the event payload. For recognized event types,
// a value of the corresponding struct type will be returned.
func (e *Event) ParsePayload() (payload interface{}, err error) {
switch *e.Type {
case "BranchProtectionRuleEvent":
payload = &BranchProtectionRuleEvent{}
case "CheckRunEvent":
payload = &CheckRunEvent{}
case "CheckSuiteEvent":
payload = &CheckSuiteEvent{}
case "CodeScanningAlertEvent":
payload = &CodeScanningAlertEvent{}
case "CommitCommentEvent":
payload = &CommitCommentEvent{}
case "ContentReferenceEvent":
payload = &ContentReferenceEvent{}
case "CreateEvent":
payload = &CreateEvent{}
case "DeleteEvent":
payload = &DeleteEvent{}
case "DeployKeyEvent":
payload = &DeployKeyEvent{}
case "DeploymentEvent":
payload = &DeploymentEvent{}
case "DeploymentProtectionRuleEvent":
payload = &DeploymentProtectionRuleEvent{}
case "DeploymentStatusEvent":
payload = &DeploymentStatusEvent{}
case "DiscussionEvent":
payload = &DiscussionEvent{}
case "DiscussionCommentEvent":
payload = &DiscussionCommentEvent{}
case "ForkEvent":
payload = &ForkEvent{}
case "GitHubAppAuthorizationEvent":
payload = &GitHubAppAuthorizationEvent{}
case "GollumEvent":
payload = &GollumEvent{}
case "InstallationEvent":
payload = &InstallationEvent{}
case "InstallationRepositoriesEvent":
payload = &InstallationRepositoriesEvent{}
case "IssueCommentEvent":
payload = &IssueCommentEvent{}
case "IssuesEvent":
payload = &IssuesEvent{}
case "LabelEvent":
payload = &LabelEvent{}
case "MarketplacePurchaseEvent":
payload = &MarketplacePurchaseEvent{}
case "MemberEvent":
payload = &MemberEvent{}
case "MembershipEvent":
payload = &MembershipEvent{}
case "MergeGroupEvent":
payload = &MergeGroupEvent{}
case "MetaEvent":
payload = &MetaEvent{}
case "MilestoneEvent":
payload = &MilestoneEvent{}
case "OrganizationEvent":
payload = &OrganizationEvent{}
case "OrgBlockEvent":
payload = &OrgBlockEvent{}
case "PackageEvent":
payload = &PackageEvent{}
case "PageBuildEvent":
payload = &PageBuildEvent{}
case "PingEvent":
payload = &PingEvent{}
case "ProjectEvent":
payload = &ProjectEvent{}
case "ProjectCardEvent":
payload = &ProjectCardEvent{}
case "ProjectColumnEvent":
payload = &ProjectColumnEvent{}
case "PublicEvent":
payload = &PublicEvent{}
case "PullRequestEvent":
payload = &PullRequestEvent{}
case "PullRequestReviewEvent":
payload = &PullRequestReviewEvent{}
case "PullRequestReviewCommentEvent":
payload = &PullRequestReviewCommentEvent{}
case "PullRequestReviewThreadEvent":
payload = &PullRequestReviewThreadEvent{}
case "PullRequestTargetEvent":
payload = &PullRequestTargetEvent{}
case "PushEvent":
payload = &PushEvent{}
case "ReleaseEvent":
payload = &ReleaseEvent{}
case "RepositoryEvent":
payload = &RepositoryEvent{}
case "RepositoryDispatchEvent":
payload = &RepositoryDispatchEvent{}
case "RepositoryImportEvent":
payload = &RepositoryImportEvent{}
case "RepositoryVulnerabilityAlertEvent":
payload = &RepositoryVulnerabilityAlertEvent{}
case "SecretScanningAlertEvent":
payload = &SecretScanningAlertEvent{}
case "SecurityAdvisoryEvent":
payload = &SecurityAdvisoryEvent{}
case "StarEvent":
payload = &StarEvent{}
case "StatusEvent":
payload = &StatusEvent{}
case "TeamEvent":
payload = &TeamEvent{}
case "TeamAddEvent":
payload = &TeamAddEvent{}
case "UserEvent":
payload = &UserEvent{}
case "WatchEvent":
payload = &WatchEvent{}
case "WorkflowDispatchEvent":
payload = &WorkflowDispatchEvent{}
case "WorkflowJobEvent":
payload = &WorkflowJobEvent{}
case "WorkflowRunEvent":
payload = &WorkflowRunEvent{}
}
err = json.Unmarshal(*e.RawPayload, &payload)
return payload, err
}
// Payload returns the parsed event payload. For recognized event types,
// a value of the corresponding struct type will be returned.
//
// Deprecated: Use ParsePayload instead, which returns an error
// rather than panics if JSON unmarshaling raw payload fails.
func (e *Event) Payload() (payload interface{}) {
var err error
payload, err = e.ParsePayload()
if err != nil {
panic(err)
}
return payload
}

View file

@ -11,13 +11,17 @@
178inaba <masahiro.furudate@gmail.com>
2BFL <imqksl@gmail.com>
413x <dedifferentiator@gmail.com>
6543 <6543@obermui.de>
Abed Kibbe <abed.kibbe@gmail.com>
Abhinav Gupta <mail@abhinavg.net>
Abhishek Veeramalla <abhishek.veeramalla@gmail.com>
aboy <b1011211@gmail.com>
Adam Kohring <ajkohring@gmail.com>
adrienzieba <adrien.zieba@appdirect.com>
afdesk <work@afdesk.com>
Ahmad Nurus S <ahmadnurus.sh@gmail.com>
Ahmed Hagy <a.akram93@gmail.com>
Aidan <aidan@artificial.com>
Aidan Steele <aidan.steele@glassechidna.com.au>
Ainsley Chong <ainsley.chong@gmail.com>
ajz01 <azdenek@yahoo.com>
@ -26,6 +30,7 @@ Akhil Mohan <akhilerm@gmail.com>
Alec Thomas <alec@swapoff.org>
Aleks Clark <aleks.clark@gmail.com>
Alex Bramley <a.bramley@gmail.com>
Alex Ellis <alexellis2@gmail.com>
Alex Orr <Alexorr.CSE@gmail.com>
Alex Su <alexsu@17.media>
Alex Unger <zyxancf@gmail.com>
@ -51,6 +56,7 @@ Anton Nguyen <afnguyen85@gmail.com>
Anubha Kushwaha <anubha_bt2k14@dtu.ac.in>
appilon <apilon@hashicorp.com>
aprp <doelaudi@gmail.com>
apurwaj2 <apurwaj2@gmail.com>
Aravind <aravindkp@outlook.in>
Arda Kuyumcu <kuyumcuarda@gmail.com>
Arıl Bozoluk <arilbozoluk@hotmail.com>
@ -60,12 +66,15 @@ Austin Dizzy <dizzy@wow.com>
Azuka Okuleye <azuka@zatechcorp.com>
Ben Batha <bhbatha@gmail.com>
Benjamen Keroack <benjamen@dollarshaveclub.com>
Berkay Tacyildiz <berkaytacyildiz@gmail.com>
Beshr Kayali <beshrkayali@gmail.com>
Beyang Liu <beyang.liu@gmail.com>
Billy Keyes <bluekeyes@gmail.com>
Billy Lynch <wlynch92@gmail.com>
Bingtan Lu <lubingtan@126.com>
Bjorn Neergaard <bjorn@neersighted.com>
Björn Häuser <b.haeuser@rebuy.de>
Bo Huang <bo.huang@datadoghq.com>
boljen <bol.christophe@gmail.com>
Bracken <abdawson@gmail.com>
Brad Harris <bmharris@gmail.com>
@ -74,6 +83,7 @@ Bradley Falzon <brad@teambrad.net>
Bradley McAllister <brad.mcallister@hotmail.com>
Brandon Butler <b.butler@chia.net>
Brandon Cook <phylake@gmail.com>
Brandon Stubbs <brstubbs1@gmail.com>
Brett Kuhlman <kuhlman-labs@github.com>
Brett Logan <lindluni@github.com>
Brian Egizi <brian@mojotech.com>
@ -96,6 +106,7 @@ Chris Schaefer <chris@dtzq.com>
chrisforrette <chris@chrisforrette.com>
Christian Bargmann <chris@cbrgm.net>
Christian Muehlhaeuser <muesli@gmail.com>
Christoph Jerolimov <jerolimov@gmail.com>
Christoph Sassenberg <defsprite@gmail.com>
CI Monk <ci-monk@protonmail.com>
Colin Misare <github.com/cmisare>
@ -125,12 +136,14 @@ Derek Jobst <derekjobst@gmail.com>
DeviousLab <deviouslab@gmail.com>
Dhi Aurrahman <diorahman@rockybars.com>
Diego Lapiduz <diego.lapiduz@cfpb.gov>
Diogo Vilela <be0x74a@gmail.com>
Dmitri Shuralyov <shurcooL@gmail.com>
dmnlk <seikima2demon@gmail.com>
Don Petersen <don@donpetersen.net>
Doug Turner <doug.turner@gmail.com>
Drew Fradette <drew.fradette@gmail.com>
Dustin Deus <deusdustin@gmail.com>
Dustin Lish <dustin.lish@onepeloton.com>
Eivind <eivindkn@gmail.com>
Eli Uriegas <seemethere101@gmail.com>
Elliott Beach <elliott2.71828@gmail.com>
@ -141,10 +154,12 @@ eperm <staffordworrell@gmail.com>
Erick Fejta <erick@fejta.com>
Erik Nobel <hendrik.nobel@transferwise.com>
erwinvaneyk <erwinvaneyk@gmail.com>
Evan Anderson <evan.k.anderson@gmail.com>
Evan Elias <evanjelias@gmail.com>
Fabian Holler <fabian.holler@simplesurance.de>
Fabrice <fabrice.vaillant@student.ecp.fr>
Fatema-Moaiyadi <fatema.i.moaiyadi@gmail.com>
Federico Di Pierro <nierro92@gmail.com>
Felix Geisendörfer <felix@debuggable.com>
Filippo Valsorda <hi@filippo.io>
Florian Forster <ff@octo.it>
@ -155,6 +170,7 @@ Francisco Guimarães <francisco.cpg@gmail.com>
François de Metz <francois@2metz.fr>
Fredrik Jönsson <fredrik.jonsson@izettle.com>
Gabriel <samfiragabriel@gmail.com>
Gal Ofri <galmenashofri@gmail.com>
Garrett Squire <garrettsquire@gmail.com>
George Kontridze <george.kontridze@gmail.com>
Georgy Buranov <gburanov@gmail.com>
@ -163,6 +179,7 @@ Gnahz <p@oath.pl>
Google Inc.
Grachev Mikhail <work@mgrachev.com>
griffin_stewie <panterathefamilyguy@gmail.com>
guangwu <guoguangwu@magic-shield.com>
Guillaume Jacquet <guillaume.jacquet@gmail.com>
Guz Alexander <kalimatas@gmail.com>
Guðmundur Bjarni Ólafsson <gudmundur@github.com>
@ -178,6 +195,7 @@ huydx <doxuanhuy@gmail.com>
i2bskn <i2bskn@gmail.com>
Iain Steers <iainsteers@gmail.com>
Ikko Ashimine <eltociear@gmail.com>
Ilia Choly <ilia.choly@gmail.com>
Ioannis Georgoulas <igeorgoulas21@gmail.com>
Isao Jonas <isao.jonas@gmail.com>
ishan upadhyay <ishanupadhyay412@gmail.com>
@ -189,11 +207,15 @@ Jameel Haffejee <RC1140@republiccommandos.co.za>
James Bowes <jbowes@repl.ca>
James Cockbain <james.cockbain@ibm.com>
James Loh <github@jloh.co>
James Maguire <jvm986@gmail.com>
James Turley <jamesturley1905@googlemail.com>
Jamie West <jamieianwest@hotmail.com>
Jan Kosecki <jan.kosecki91@gmail.com>
Jan Švábík <jansvabik@jansvabik.cz>
Jason Field <Jason@avon-lea.co.uk>
Javier Campanini <jcampanini@palantir.com>
Jef LeCompte <jeffreylec@gmail.com>
Jeff Wenzbauer <jeff.wenzbauer@niceincontact.com>
Jens Rantil <jens.rantil@gmail.com>
Jeremy Morris <jeremylevanmorris@gmail.com>
Jesse Haka <haka.jesse@gmail.com>
@ -208,7 +230,9 @@ John Engelman <john.r.engelman@gmail.com>
John Jones <john@exthilion.org>
John Liu <john.liu@mongodb.com>
Jordan Brockopp <jdbro94@gmail.com>
Jordan Burandt <jordanburandt@gmail.com>
Jordan Sussman <jordansail22@gmail.com>
Jorge Gómez Reus <j-g1996@live.com>
Joshua Bezaleel Abednego <joshua.bezaleel@gmail.com>
João Cerqueira <joao@cerqueira.io>
JP Phillips <jonphill9@gmail.com>
@ -222,14 +246,17 @@ Justin Abrahms <justin@abrah.ms>
Justin Toh <tohjustin@hotmail.com>
Jusung Lee <e.jusunglee@gmail.com>
jzhoucliqr <jzhou@cliqr.com>
k0ral <mail@cmoreau.info>
k1rnt <eru08tera15mora@gmail.com>
kadern0 <kaderno@gmail.com>
Karthik Sundari <karthiksundari2315@gmail.com>
Katrina Owen <kytrinyx@github.com>
Kautilya Tripathi <tripathi.kautilya@gmail.com>
Keita Urashima <ursm@ursm.jp>
Kevin Burke <kev@inburke.com>
Kevin Wang <kwangsan@gmail.com>
Kevin Zhao <kzhao@lyft.com>
kgalli <mail@kgalli.de>
Kirill <g4s8.public@gmail.com>
Konrad Malawski <konrad.malawski@project13.pl>
Kookheon Kwon <kucuny@gmail.com>
@ -239,19 +266,24 @@ Kshitij Saraogi <KshitijSaraogi@gmail.com>
Kumar Saurabh <itsksaurabh@gmail.com>
Kyle Kurz <kyle@doublekaudio.com>
kyokomi <kyoko1220adword@gmail.com>
Lars Lehtonen <lars.lehtonen@gmail.com>
Laurent Verdoïa <verdoialaurent@gmail.com>
leopoldwang <leopold.wang@gmail.com>
Liam Galvin <liam@liam-galvin.co.uk>
Lluis Campos <lluis.campos@northern.tech>
Lovro Mažgon <lovro.mazgon@gmail.com>
Loïs Postula <lois@postu.la>
Luca Campese <me@campesel.net>
Lucas Alcantara <lucasalcantaraf@gmail.com>
Lucas Martin-King <lmartinking@gmail.com>
Luis Davim <luis.davim@sendoso.com>
Luke Evers <me@lukevers.com>
Luke Hinds <luke@stacklok.com>
Luke Kysow <lkysow@gmail.com>
Luke Roberts <email@luke-roberts.co.uk>
Luke Young <luke@hydrantlabs.org>
lynn [they] <lynncyrin@gmail.com>
Magnus Kulke <mkulke@gmail.com>
Maksim Zhylinski <uzzable@gmail.com>
Marc Binder <marcandrebinder@gmail.com>
Marcelo Carlos <marcelo@permutive.com>
@ -266,9 +298,11 @@ Matija Horvat <horvat2112@gmail.com>
Matin Rahmanian <itsmatinx@gmail.com>
Matt <alpmatthew@gmail.com>
Matt Brender <mjbrender@gmail.com>
Matt Dainty <matt@bodgit-n-scarper.com>
Matt Gaunt <matt@gauntface.co.uk>
Matt Landis <landis.matt@gmail.com>
Matt Moore <mattmoor@vmware.com>
Matt Simons <mattsimons@ntlworld.com>
Maxime Bury <maxime.bury@gmail.com>
Michael Meng <mmeng@lyft.com>
Michael Spiegel <michael.m.spiegel@gmail.com>
@ -277,26 +311,33 @@ Michał Glapa <michal.glapa@gmail.com>
Michelangelo Morrillo <michelangelo@morrillo.it>
Miguel Elias dos Santos <migueleliasweb@gmail.com>
Mike Chen <mchen300@gmail.com>
mohammad ali <2018cs92@student.uet.edu.pk>
Mohammed AlDujaili <avainer11@gmail.com>
Mukundan Senthil <mukundan314@gmail.com>
Munia Balayil <munia.247@gmail.com>
Mustafa Abban <mustafaabban@utexas.edu>
Nadav Kaner <nadavkaner1@gmail.com>
Naoki Kanatani <k12naoki@gmail.com>
Nathan VanBenschoten <nvanbenschoten@gmail.com>
Navaneeth Suresh <navaneeths1998@gmail.com>
Neal Caffery <neal1991@sina.com>
Neil O'Toole <neilotoole@apache.org>
Nick Miyake <nmiyake@palantir.com>
Nick Platt <hello@nickplatt.co.uk>
Nick Spragg <nick.spragg@bbc.co.uk>
Nicolas Chapurlat <nc@coorganix.com>
Nikhita Raghunath <nikitaraghunath@gmail.com>
Nilesh Singh <nilesh.singh24@outlook.com>
Noah Hanjun Lee <noah.lee@buzzvil.com>
Noah Zoschke <noah+sso2@convox.com>
ns-cweber <cweber@narrativescience.com>
nxya <nathacutlan@gmail.com>
Ole Orhagen <ole.orhagen@northern.tech>
Oleg Kovalov <iamolegkovalov@gmail.com>
Ondřej Kupka <ondra.cap@gmail.com>
Ori Talmor <talmorori@gmail.com>
Osama Faqhruldin <onfaqhru@gmail.com>
oslowalk <den.cs@pm.me>
Pablo Pérez Schröder <pablo.perezschroder@wetransfer.com>
Palash Nigam <npalash25@gmail.com>
Panagiotis Moustafellos <pmoust@gmail.com>
@ -307,6 +348,7 @@ parkhyukjun89 <park.hyukjun89@gmail.com>
Pat Alwell <pat.alwell@gmail.com>
Patrick DeVivo <patrick.devivo@gmail.com>
Patrick Marabeas <patrick@marabeas.io>
Patrik Nordlén <patriki@gmail.com>
Pavel Dvoinos <pavel.dvoinos@transferwise.com>
Pavel Shtanko <pavel.shtanko@gmail.com>
Pete Wagner <thepwagner@github.com>
@ -323,6 +365,7 @@ Quinn Slack <qslack@qslack.com>
Rackspace US, Inc.
Radek Simko <radek.simko@gmail.com>
Radliński Ignacy <radlinsk@student.agh.edu.pl>
Rafael Aramizu Gomes <rafael.aramizu@mercadolivre.com>
Rajat Jindal <rajatjindal83@gmail.com>
Rajendra arora <rajendraarora16@yahoo.com>
Rajkumar <princegosavi12@gmail.com>
@ -351,6 +394,7 @@ Ryo Nakao <nakabonne@gmail.com>
Saaarah <sarah.liusy@gmail.com>
Safwan Olaimat <safwan.olaimat@gmail.com>
Sahil Dua <sahildua2305@gmail.com>
Sai Ravi Teja Chintakrindi <srt2712@gmail.com>
saisi <saisi@users.noreply.github.com>
Sam Minnée <sam@silverstripe.com>
Sandeep Sukhani <sandeep.d.sukhani@gmail.com>
@ -377,6 +421,7 @@ Sho Okada <shokada3@gmail.com>
Shrikrishna Singh <krishnasingh.ss30@gmail.com>
Simon Davis <sdavis@hashicorp.com>
sona-tar <sona.zip@gmail.com>
soniachikh <sonia.chikh@gmail.com>
SoundCloud, Ltd.
Sridhar Mocherla <srmocher@microsoft.com>
SriVignessh Pss <sriknowledge@gmail.com>
@ -387,6 +432,7 @@ Suhaib Mujahid <suhaibmujahid@gmail.com>
sushmita wable <sw09007@gmail.com>
Szymon Kodrebski <simonkey007@gmail.com>
Søren Hansen <soren@dinero.dk>
T.J. Corrigan <tjcorr@github.com>
Takashi Yoneuchi <takashi.yoneuchi@shift-js.info>
Takayuki Watanabe <takanabe.w@gmail.com>
Taketoshi Fujiwara <fujiwara@leapmind.io>
@ -398,6 +444,7 @@ Theofilos Petsios <theofilos.pe@gmail.com>
Thomas Aidan Curran <thomas@ory.sh>
Thomas Bruyelle <thomas.bruyelle@gmail.com>
Tim Rogers <timrogers@github.com>
Timothy O'Brien <obrien.timothy.a@gmail.com>
Timothée Peignier <timothee.peignier@tryphon.org>
Tingluo Huang <tingluohuang@github.com>
tkhandel <tarunkhandelwal.iitr@gmail.com>
@ -410,11 +457,15 @@ Vaibhav Singh <vaibhav.singh.14cse@bml.edu.in>
Varadarajan Aravamudhan <varadaraajan@gmail.com>
Victor Castell <victor@victorcastell.com>
Victor Vrantchan <vrancean+github@gmail.com>
Victory Osikwemhe <osikwemhev@gmail.com>
vikkyomkar <vikky.omkar@samsung.com>
Vivek <y.vivekanand@gmail.com>
Vlad Ungureanu <vladu@palantir.com>
Wasim Thabraze <wasim@thabraze.me>
Weslei Juan Moser Pereira <wesleimsr@gmail.com>
Wheeler Law <wheeler.law@outlook.com>
Will Maier <wcmaier@gmail.com>
Will Norris <will@tailscale.com>
Willem D'Haeseleer <dhwillem@gmail.com>
William Bailey <mail@williambailey.org.uk>
William Cooke <pipeston@gmail.com>
@ -422,12 +473,15 @@ Xabi <xmartinez1702@gmail.com>
xibz <impactbchang@gmail.com>
Yann Malet <yann.malet@gmail.com>
Yannick Utard <yannickutard@gmail.com>
Yarden Shoham <git@yardenshoham.com>
Yicheng Qin <qycqycqycqycqyc@gmail.com>
Yosuke Akatsuka <yosuke.akatsuka@access-company.com>
Yumikiyo Osanai <yumios.art@gmail.com>
Yurii Soldak <ysoldak@gmail.com>
Yusef Mohamadi <yuseferi@gmail.com>
Yusuke Kuoka <ykuoka@gmail.com>
Zach Latta <zach@zachlatta.com>
zhouhaibing089 <zhouhaibing089@gmail.com>
六开箱 <lkxed@outlook.com>
缘生 <i@ysicing.me>
蒋航 <hang.jiang@daocloud.io>

View file

@ -58,6 +58,7 @@ type GenerateJITConfigRequest struct {
// JITRunnerConfig represents encoded JIT configuration that can be used to bootstrap a self-hosted runner.
type JITRunnerConfig struct {
Runner *Runner `json:"runner,omitempty"`
EncodedJITConfig *string `json:"encoded_jit_config,omitempty"`
}

View file

@ -46,6 +46,7 @@ type WorkflowRun struct {
Repository *Repository `json:"repository,omitempty"`
HeadRepository *Repository `json:"head_repository,omitempty"`
Actor *User `json:"actor,omitempty"`
TriggeringActor *User `json:"triggering_actor,omitempty"`
}
// WorkflowRuns represents a slice of repository action workflow run.

View file

@ -7,7 +7,6 @@ package github
import (
"context"
"fmt"
)
// AdminStats represents a variety of stats of a GitHub Enterprise
@ -155,7 +154,7 @@ func (s RepoStats) String() string {
//
// GitHub API docs: https://docs.github.com/en/rest/enterprise-admin/admin_stats/
func (s *AdminService) GetAdminStats(ctx context.Context) (*AdminStats, *Response, error) {
u := fmt.Sprintf("enterprise/stats/all")
u := "enterprise/stats/all"
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err

View file

@ -122,6 +122,12 @@ type AlertListOptions struct {
// Return code scanning alerts for a specific branch reference. The ref must be formatted as heads/<branch name>.
Ref string `url:"ref,omitempty"`
// If specified, only code scanning alerts with this severity will be returned. Possible values are: critical, high, medium, low, warning, note, error.
Severity string `url:"severity,omitempty"`
// The name of a code scanning tool. Only results by this tool will be listed.
ToolName string `url:"tool_name,omitempty"`
ListCursorOptions
// Add ListOptions so offset pagination with integer type "page" query parameter is accepted

View file

@ -126,7 +126,7 @@ type ListCodespacesOptions struct {
//
// GitHub API docs: https://docs.github.com/en/rest/codespaces/codespaces?apiVersion=2022-11-28#list-codespaces-for-the-authenticated-user
func (s *CodespacesService) List(ctx context.Context, opts *ListCodespacesOptions) (*ListCodespaces, *Response, error) {
u := fmt.Sprint("user/codespaces")
u := "user/codespaces"
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err

View file

@ -76,6 +76,7 @@ type ListAlertsOptions struct {
Sort *string `url:"sort,omitempty"`
Direction *string `url:"direction,omitempty"`
ListOptions
ListCursorOptions
}

View file

@ -144,8 +144,25 @@ func (s *DependabotService) CreateOrUpdateRepoSecret(ctx context.Context, owner,
//
// GitHub API docs: https://docs.github.com/en/rest/dependabot/secrets#create-or-update-an-organization-secret
func (s *DependabotService) CreateOrUpdateOrgSecret(ctx context.Context, org string, eSecret *DependabotEncryptedSecret) (*Response, error) {
repoIDs := make([]string, len(eSecret.SelectedRepositoryIDs))
for i, secret := range eSecret.SelectedRepositoryIDs {
repoIDs[i] = fmt.Sprintf("%v", secret)
}
params := struct {
*DependabotEncryptedSecret
SelectedRepositoryIDs []string `json:"selected_repository_ids,omitempty"`
}{
DependabotEncryptedSecret: eSecret,
SelectedRepositoryIDs: repoIDs,
}
url := fmt.Sprintf("orgs/%v/dependabot/secrets/%v", org, eSecret.Name)
return s.putSecret(ctx, url, eSecret)
req, err := s.client.NewRequest("PUT", url, params)
if err != nil {
return nil, err
}
return s.client.Do(ctx, req, nil)
}
func (s *DependabotService) deleteSecret(ctx context.Context, url string) (*Response, error) {

View file

@ -0,0 +1,80 @@
// Copyright 2023 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"context"
"fmt"
)
type DependencyGraphService service
// SBOM represents a software bill of materials, which describes the
// packages/libraries that a repository depends on.
type SBOM struct {
SBOM *SBOMInfo `json:"sbom,omitempty"`
}
// CreationInfo represents when the SBOM was created and who created it.
type CreationInfo struct {
Created *Timestamp `json:"created,omitempty"`
Creators []string `json:"creators,omitempty"`
}
// RepoDependencies represents the dependencies of a repo.
type RepoDependencies struct {
SPDXID *string `json:"SPDXID,omitempty"`
// Package name
Name *string `json:"name,omitempty"`
VersionInfo *string `json:"versionInfo,omitempty"`
DownloadLocation *string `json:"downloadLocation,omitempty"`
FilesAnalyzed *bool `json:"filesAnalyzed,omitempty"`
LicenseConcluded *string `json:"licenseConcluded,omitempty"`
LicenseDeclared *string `json:"licenseDeclared,omitempty"`
}
// SBOMInfo represents a software bill of materials (SBOM) using SPDX.
// SPDX is an open standard for SBOMs that
// identifies and catalogs components, licenses, copyrights, security
// references, and other metadata relating to software.
type SBOMInfo struct {
SPDXID *string `json:"SPDXID,omitempty"`
SPDXVersion *string `json:"spdxVersion,omitempty"`
CreationInfo *CreationInfo `json:"creationInfo,omitempty"`
// Repo name
Name *string `json:"name,omitempty"`
DataLicense *string `json:"dataLicense,omitempty"`
DocumentDescribes []string `json:"documentDescribes,omitempty"`
DocumentNamespace *string `json:"documentNamespace,omitempty"`
// List of packages dependencies
Packages []*RepoDependencies `json:"packages,omitempty"`
}
func (s SBOM) String() string {
return Stringify(s)
}
// GetSBOM fetches the software bill of materials for a repository.
//
// GitHub API docs: https://docs.github.com/en/rest/dependency-graph/sboms
func (s *DependencyGraphService) GetSBOM(ctx context.Context, owner, repo string) (*SBOM, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/dependency-graph/sbom", owner, repo)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
var sbom *SBOM
resp, err := s.client.Do(ctx, req, &sbom)
if err != nil {
return nil, resp, err
}
return sbom, resp, nil
}

View file

@ -8,7 +8,7 @@ Package github provides a client for using the GitHub API.
Usage:
import "github.com/google/go-github/v53/github" // with go modules enabled (GO111MODULE=on or outside GOPATH)
import "github.com/google/go-github/v54/github" // with go modules enabled (GO111MODULE=on or outside GOPATH)
import "github.com/google/go-github/github" // with go modules disabled
Construct a new GitHub client, then use the various services on the client to

54
vendor/github.com/google/go-github/v54/github/event.go generated vendored Normal file
View file

@ -0,0 +1,54 @@
// Copyright 2018 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"encoding/json"
)
// Event represents a GitHub event.
type Event struct {
Type *string `json:"type,omitempty"`
Public *bool `json:"public,omitempty"`
RawPayload *json.RawMessage `json:"payload,omitempty"`
Repo *Repository `json:"repo,omitempty"`
Actor *User `json:"actor,omitempty"`
Org *Organization `json:"org,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
ID *string `json:"id,omitempty"`
}
func (e Event) String() string {
return Stringify(e)
}
// ParsePayload parses the event payload. For recognized event types,
// a value of the corresponding struct type will be returned.
func (e *Event) ParsePayload() (interface{}, error) {
// It would be nice if e.Type were the snake_case name of the event,
// but the existing interface uses the struct name instead.
payload := EventForType(typeToMessageMapping[e.GetType()])
if err := json.Unmarshal(e.GetRawPayload(), &payload); err != nil {
return nil, err
}
return payload, nil
}
// Payload returns the parsed event payload. For recognized event types,
// a value of the corresponding struct type will be returned.
//
// Deprecated: Use ParsePayload instead, which returns an error
// rather than panics if JSON unmarshaling raw payload fails.
func (e *Event) Payload() (payload interface{}) {
var err error
payload, err = e.ParsePayload()
if err != nil {
panic(err)
}
return payload
}

View file

@ -165,8 +165,10 @@ type DeployKeyEvent struct {
//
// GitHub API docs: https://docs.github.com/en/developers/webhooks-and-events/webhook-events-and-payloads#deployment
type DeploymentEvent struct {
Deployment *Deployment `json:"deployment,omitempty"`
Repo *Repository `json:"repository,omitempty"`
Deployment *Deployment `json:"deployment,omitempty"`
Repo *Repository `json:"repository,omitempty"`
Workflow *Workflow `json:"workflow,omitempty"`
WorkflowRun *WorkflowRun `json:"workflow_run,omitempty"`
// The following fields are only populated by Webhook events.
Sender *User `json:"sender,omitempty"`
@ -505,6 +507,38 @@ type InstallationRepositoriesEvent struct {
Installation *Installation `json:"installation,omitempty"`
}
// InstallationLoginChange represents a change in login on an installation.
type InstallationLoginChange struct {
From *string `json:"from,omitempty"`
}
// InstallationSlugChange represents a change in slug on an installation.
type InstallationSlugChange struct {
From *string `json:"from,omitempty"`
}
// InstallationChanges represents a change in slug or login on an installation.
type InstallationChanges struct {
Login *InstallationLoginChange `json:"login,omitempty"`
Slug *InstallationSlugChange `json:"slug,omitempty"`
}
// InstallationTargetEvent is triggered when there is activity on an installation from a user or organization account.
// The Webhook event name is "installation_target".
//
// GitHub API docs: https://docs.github.com/en/webhooks-and-events/webhooks/webhook-events-and-payloads#installation_target
type InstallationTargetEvent struct {
Account *User `json:"account,omitempty"`
Action *string `json:"action,omitempty"`
Changes *InstallationChanges `json:"changes,omitempty"`
Enterprise *Enterprise `json:"enterprise,omitempty"`
Installation *Installation `json:"installation,omitempty"`
Organization *Organization `json:"organization,omitempty"`
Repository *Repository `json:"repository,omitempty"`
Sender *User `json:"sender,omitempty"`
TargetType *string `json:"target_type,omitempty"`
}
// IssueCommentEvent is triggered when an issue comment is created on an issue
// or pull request.
// The Webhook event name is "issue_comment".
@ -774,6 +808,74 @@ type PageBuildEvent struct {
Installation *Installation `json:"installation,omitempty"`
}
// PersonalAccessTokenRequestEvent occurs when there is activity relating to a
// request for a fine-grained personal access token to access resources that
// belong to a resource owner that requires approval for token access.
// The webhook event name is "personal_access_token_request".
//
// GitHub API docs: https://docs.github.com/en/webhooks-and-events/webhooks/webhook-events-and-payloads#personal_access_token_request
type PersonalAccessTokenRequestEvent struct {
// Action is the action that was performed. Possible values are:
// "approved", "cancelled", "created" or "denied"
Action *string `json:"action,omitempty"`
PersonalAccessTokenRequest *PersonalAccessTokenRequest `json:"personal_access_token_request,omitempty"`
Org *Organization `json:"organization,omitempty"`
Sender *User `json:"sender,omitempty"`
Installation *Installation `json:"installation,omitempty"`
}
// PersonalAccessTokenRequest contains the details of a PersonalAccessTokenRequestEvent.
type PersonalAccessTokenRequest struct {
// Unique identifier of the request for access via fine-grained personal
// access token. Used as the pat_request_id parameter in the list and review
// API calls.
ID *int64 `json:"id,omitempty"`
Owner *User `json:"owner,omitempty"`
// New requested permissions, categorized by type of permission.
PermissionsAdded *PersonalAccessTokenPermissions `json:"permissions_added,omitempty"`
// Requested permissions that elevate access for a previously approved
// request for access, categorized by type of permission.
PermissionsUpgraded *PersonalAccessTokenPermissions `json:"permissions_upgraded,omitempty"`
// Permissions requested, categorized by type of permission.
// This field incorporates permissions_added and permissions_upgraded.
PermissionsResult *PersonalAccessTokenPermissions `json:"permissions_result,omitempty"`
// Type of repository selection requested. Possible values are:
// "none", "all" or "subset"
RepositorySelection *string `json:"repository_selection,omitempty"`
// The number of repositories the token is requesting access to.
// This field is only populated when repository_selection is subset.
RepositoryCount *int64 `json:"repository_count,omitempty"`
// An array of repository objects the token is requesting access to.
// This field is only populated when repository_selection is subset.
Repositories []*Repository `json:"repositories,omitempty"`
// Date and time when the request for access was created.
CreatedAt *Timestamp `json:"created_at,omitempty"`
// Whether the associated fine-grained personal access token has expired.
TokenExpired *bool `json:"token_expired,omitempty"`
// Date and time when the associated fine-grained personal access token expires.
TokenExpiresAt *Timestamp `json:"token_expires_at,omitempty"`
// Date and time when the associated fine-grained personal access token was last used for authentication.
TokenLastUsedAt *Timestamp `json:"token_last_used_at,omitempty"`
}
// PersonalAccessTokenPermissions represents the original or newly requested
// scope of permissions for a fine-grained personal access token within a PersonalAccessTokenRequest.
type PersonalAccessTokenPermissions struct {
Org map[string]string `json:"organization,omitempty"`
Repo map[string]string `json:"repository,omitempty"`
Other map[string]string `json:"other,omitempty"`
}
// PingEvent is triggered when a Webhook is added to GitHub.
//
// GitHub API docs: https://developer.github.com/webhooks/#ping-event
@ -842,6 +944,77 @@ type ProjectColumnEvent struct {
Installation *Installation `json:"installation,omitempty"`
}
// ProjectV2Event is triggered when there is activity relating to an organization-level project.
// The Webhook event name is "projects_v2".
//
// GitHub API docs: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#projects_v2
type ProjectV2Event struct {
Action *string `json:"action,omitempty"`
ProjectsV2 *ProjectsV2 `json:"projects_v2,omitempty"`
// The following fields are only populated by Webhook events.
Installation *Installation `json:"installation,omitempty"`
Org *Organization `json:"organization,omitempty"`
Sender *User `json:"sender,omitempty"`
}
// ProjectsV2 represents a projects v2 project.
type ProjectsV2 struct {
ID *int64 `json:"id,omitempty"`
NodeID *string `json:"node_id,omitempty"`
Owner *User `json:"owner,omitempty"`
Creator *User `json:"creator,omitempty"`
Title *string `json:"title,omitempty"`
Description *string `json:"description,omitempty"`
Public *bool `json:"public,omitempty"`
ClosedAt *Timestamp `json:"closed_at,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
DeletedAt *Timestamp `json:"deleted_at,omitempty"`
Number *int `json:"number,omitempty"`
ShortDescription *string `json:"short_description,omitempty"`
DeletedBy *User `json:"deleted_by,omitempty"`
}
// ProjectV2ItemEvent is triggered when there is activity relating to an item on an organization-level project.
// The Webhook event name is "projects_v2_item".
//
// GitHub API docs: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#projects_v2_item
type ProjectV2ItemEvent struct {
Action *string `json:"action,omitempty"`
Changes *ProjectV2ItemChange `json:"changes,omitempty"`
ProjectV2Item *ProjectV2Item `json:"projects_v2_item,omitempty"`
// The following fields are only populated by Webhook events.
Installation *Installation `json:"installation,omitempty"`
Org *Organization `json:"organization,omitempty"`
Sender *User `json:"sender,omitempty"`
}
// ProjectV2ItemChange represents a project v2 item change.
type ProjectV2ItemChange struct {
ArchivedAt *ArchivedAt `json:"archived_at,omitempty"`
}
// ArchivedAt represents an archiving date change.
type ArchivedAt struct {
From *Timestamp `json:"from,omitempty"`
To *Timestamp `json:"to,omitempty"`
}
// ProjectsV2 represents an item belonging to a project.
type ProjectV2Item struct {
ID *int64 `json:"id,omitempty"`
NodeID *string `json:"node_id,omitempty"`
ProjectNodeID *string `json:"project_node_id,omitempty"`
ContentNodeID *string `json:"content_node_id,omitempty"`
ContentType *string `json:"content_type,omitempty"`
Creator *User `json:"creator,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
ArchivedAt *Timestamp `json:"archived_at,omitempty"`
}
// PublicEvent is triggered when a private repository is open sourced.
// According to GitHub: "Without a doubt: the best GitHub event."
// The Webhook event name is "public".
@ -1225,6 +1398,31 @@ type SecretScanningAlertEvent struct {
Installation *Installation `json:"installation,omitempty"`
}
// SecurityAndAnalysisEvent is triggered when code security and analysis features
// are enabled or disabled for a repository.
//
// GitHub API docs: https://docs.github.com/en/webhooks-and-events/webhooks/webhook-events-and-payloads#security_and_analysis
type SecurityAndAnalysisEvent struct {
Changes *SecurityAndAnalysisChange `json:"changes,omitempty"`
Enterprise *Enterprise `json:"enterprise,omitempty"`
Installation *Installation `json:"installation,omitempty"`
Organization *Organization `json:"organization,omitempty"`
Repository *Repository `json:"repository,omitempty"`
Sender *User `json:"sender,omitempty"`
}
// SecurityAndAnalysisChange represents the changes when security and analysis
// features are enabled or disabled for a repository.
type SecurityAndAnalysisChange struct {
From *SecurityAndAnalysisChangeFrom `json:"from,omitempty"`
}
// SecurityAndAnalysisChangeFrom represents which change was made when security
// and analysis features are enabled or disabled for a repository.
type SecurityAndAnalysisChangeFrom struct {
SecurityAndAnalysis *SecurityAndAnalysis `json:"security_and_analysis,omitempty"`
}
// StarEvent is triggered when a star is added or removed from a repository.
// The Webhook event name is "star".
//

View file

@ -28,7 +28,7 @@ import (
)
const (
Version = "v53.2.0"
Version = "v54.0.0"
defaultAPIVersion = "2022-11-28"
defaultBaseURL = "https://api.github.com/"
@ -126,9 +126,6 @@ const (
// https://developer.github.com/changes/2019-04-24-vulnerability-alerts/
mediaTypeRequiredVulnerabilityAlertsPreview = "application/vnd.github.dorian-preview+json"
// https://developer.github.com/changes/2019-06-04-automated-security-fixes/
mediaTypeRequiredAutomatedSecurityFixesPreview = "application/vnd.github.london-preview+json"
// https://developer.github.com/changes/2019-05-29-update-branch-api/
mediaTypeUpdatePullRequestBranchPreview = "application/vnd.github.lydian-preview+json"
@ -179,36 +176,38 @@ type Client struct {
common service // Reuse a single struct instead of allocating one for each service on the heap.
// Services used for talking to different parts of the GitHub API.
Actions *ActionsService
Activity *ActivityService
Admin *AdminService
Apps *AppsService
Authorizations *AuthorizationsService
Billing *BillingService
Checks *ChecksService
CodeScanning *CodeScanningService
Codespaces *CodespacesService
Dependabot *DependabotService
Enterprise *EnterpriseService
Gists *GistsService
Git *GitService
Gitignores *GitignoresService
Interactions *InteractionsService
IssueImport *IssueImportService
Issues *IssuesService
Licenses *LicensesService
Marketplace *MarketplaceService
Migrations *MigrationService
Organizations *OrganizationsService
Projects *ProjectsService
PullRequests *PullRequestsService
Reactions *ReactionsService
Repositories *RepositoriesService
SCIM *SCIMService
Search *SearchService
SecretScanning *SecretScanningService
Teams *TeamsService
Users *UsersService
Actions *ActionsService
Activity *ActivityService
Admin *AdminService
Apps *AppsService
Authorizations *AuthorizationsService
Billing *BillingService
Checks *ChecksService
CodeScanning *CodeScanningService
Codespaces *CodespacesService
Dependabot *DependabotService
DependencyGraph *DependencyGraphService
Enterprise *EnterpriseService
Gists *GistsService
Git *GitService
Gitignores *GitignoresService
Interactions *InteractionsService
IssueImport *IssueImportService
Issues *IssuesService
Licenses *LicensesService
Marketplace *MarketplaceService
Migrations *MigrationService
Organizations *OrganizationsService
Projects *ProjectsService
PullRequests *PullRequestsService
Reactions *ReactionsService
Repositories *RepositoriesService
SCIM *SCIMService
Search *SearchService
SecretScanning *SecretScanningService
SecurityAdvisories *SecurityAdvisoriesService
Teams *TeamsService
Users *UsersService
}
type service struct {
@ -328,6 +327,7 @@ func NewClient(httpClient *http.Client) *Client {
c.CodeScanning = (*CodeScanningService)(&c.common)
c.Codespaces = (*CodespacesService)(&c.common)
c.Dependabot = (*DependabotService)(&c.common)
c.DependencyGraph = (*DependencyGraphService)(&c.common)
c.Enterprise = (*EnterpriseService)(&c.common)
c.Gists = (*GistsService)(&c.common)
c.Git = (*GitService)(&c.common)
@ -346,6 +346,7 @@ func NewClient(httpClient *http.Client) *Client {
c.SCIM = (*SCIMService)(&c.common)
c.Search = (*SearchService)(&c.common)
c.SecretScanning = (*SecretScanningService)(&c.common)
c.SecurityAdvisories = (*SecurityAdvisoriesService)(&c.common)
c.Teams = (*TeamsService)(&c.common)
c.Users = (*UsersService)(&c.common)
return c
@ -1052,7 +1053,7 @@ func (ae *AcceptedError) Is(target error) bool {
if !ok {
return false
}
return bytes.Compare(ae.Raw, v.Raw) == 0
return bytes.Equal(ae.Raw, v.Raw)
}
// AbuseRateLimitError occurs when GitHub returns 403 Forbidden response with the

View file

@ -22,6 +22,8 @@ import (
"mime"
"net/http"
"net/url"
"reflect"
"sort"
"strings"
)
@ -43,69 +45,86 @@ const (
var (
// eventTypeMapping maps webhooks types to their corresponding go-github struct types.
eventTypeMapping = map[string]string{
"branch_protection_rule": "BranchProtectionRuleEvent",
"check_run": "CheckRunEvent",
"check_suite": "CheckSuiteEvent",
"code_scanning_alert": "CodeScanningAlertEvent",
"commit_comment": "CommitCommentEvent",
"content_reference": "ContentReferenceEvent",
"create": "CreateEvent",
"delete": "DeleteEvent",
"deploy_key": "DeployKeyEvent",
"deployment": "DeploymentEvent",
"deployment_status": "DeploymentStatusEvent",
"deployment_protection_rule": "DeploymentProtectionRuleEvent",
"discussion": "DiscussionEvent",
"discussion_comment": "DiscussionCommentEvent",
"fork": "ForkEvent",
"github_app_authorization": "GitHubAppAuthorizationEvent",
"gollum": "GollumEvent",
"installation": "InstallationEvent",
"installation_repositories": "InstallationRepositoriesEvent",
"issue_comment": "IssueCommentEvent",
"issues": "IssuesEvent",
"label": "LabelEvent",
"marketplace_purchase": "MarketplacePurchaseEvent",
"member": "MemberEvent",
"membership": "MembershipEvent",
"merge_group": "MergeGroupEvent",
"meta": "MetaEvent",
"milestone": "MilestoneEvent",
"organization": "OrganizationEvent",
"org_block": "OrgBlockEvent",
"package": "PackageEvent",
"page_build": "PageBuildEvent",
"ping": "PingEvent",
"project": "ProjectEvent",
"project_card": "ProjectCardEvent",
"project_column": "ProjectColumnEvent",
"public": "PublicEvent",
"pull_request": "PullRequestEvent",
"pull_request_review": "PullRequestReviewEvent",
"pull_request_review_comment": "PullRequestReviewCommentEvent",
"pull_request_review_thread": "PullRequestReviewThreadEvent",
"pull_request_target": "PullRequestTargetEvent",
"push": "PushEvent",
"repository": "RepositoryEvent",
"repository_dispatch": "RepositoryDispatchEvent",
"repository_import": "RepositoryImportEvent",
"repository_vulnerability_alert": "RepositoryVulnerabilityAlertEvent",
"release": "ReleaseEvent",
"secret_scanning_alert": "SecretScanningAlertEvent",
"security_advisory": "SecurityAdvisoryEvent",
"star": "StarEvent",
"status": "StatusEvent",
"team": "TeamEvent",
"team_add": "TeamAddEvent",
"user": "UserEvent",
"watch": "WatchEvent",
"workflow_dispatch": "WorkflowDispatchEvent",
"workflow_job": "WorkflowJobEvent",
"workflow_run": "WorkflowRunEvent",
eventTypeMapping = map[string]interface{}{
"branch_protection_rule": &BranchProtectionRuleEvent{},
"check_run": &CheckRunEvent{},
"check_suite": &CheckSuiteEvent{},
"code_scanning_alert": &CodeScanningAlertEvent{},
"commit_comment": &CommitCommentEvent{},
"content_reference": &ContentReferenceEvent{},
"create": &CreateEvent{},
"delete": &DeleteEvent{},
"deploy_key": &DeployKeyEvent{},
"deployment": &DeploymentEvent{},
"deployment_status": &DeploymentStatusEvent{},
"deployment_protection_rule": &DeploymentProtectionRuleEvent{},
"discussion": &DiscussionEvent{},
"discussion_comment": &DiscussionCommentEvent{},
"fork": &ForkEvent{},
"github_app_authorization": &GitHubAppAuthorizationEvent{},
"gollum": &GollumEvent{},
"installation": &InstallationEvent{},
"installation_repositories": &InstallationRepositoriesEvent{},
"installation_target": &InstallationTargetEvent{},
"issue_comment": &IssueCommentEvent{},
"issues": &IssuesEvent{},
"label": &LabelEvent{},
"marketplace_purchase": &MarketplacePurchaseEvent{},
"member": &MemberEvent{},
"membership": &MembershipEvent{},
"merge_group": &MergeGroupEvent{},
"meta": &MetaEvent{},
"milestone": &MilestoneEvent{},
"organization": &OrganizationEvent{},
"org_block": &OrgBlockEvent{},
"package": &PackageEvent{},
"page_build": &PageBuildEvent{},
"personal_access_token_request": &PersonalAccessTokenRequestEvent{},
"ping": &PingEvent{},
"project": &ProjectEvent{},
"project_card": &ProjectCardEvent{},
"project_column": &ProjectColumnEvent{},
"projects_v2": &ProjectV2Event{},
"projects_v2_item": &ProjectV2ItemEvent{},
"public": &PublicEvent{},
"pull_request": &PullRequestEvent{},
"pull_request_review": &PullRequestReviewEvent{},
"pull_request_review_comment": &PullRequestReviewCommentEvent{},
"pull_request_review_thread": &PullRequestReviewThreadEvent{},
"pull_request_target": &PullRequestTargetEvent{},
"push": &PushEvent{},
"repository": &RepositoryEvent{},
"repository_dispatch": &RepositoryDispatchEvent{},
"repository_import": &RepositoryImportEvent{},
"repository_vulnerability_alert": &RepositoryVulnerabilityAlertEvent{},
"release": &ReleaseEvent{},
"secret_scanning_alert": &SecretScanningAlertEvent{},
"security_advisory": &SecurityAdvisoryEvent{},
"security_and_analysis": &SecurityAndAnalysisEvent{},
"star": &StarEvent{},
"status": &StatusEvent{},
"team": &TeamEvent{},
"team_add": &TeamAddEvent{},
"user": &UserEvent{},
"watch": &WatchEvent{},
"workflow_dispatch": &WorkflowDispatchEvent{},
"workflow_job": &WorkflowJobEvent{},
"workflow_run": &WorkflowRunEvent{},
}
// forward mapping of event types to the string names of the structs
messageToTypeName = make(map[string]string, len(eventTypeMapping))
// Inverse map of the above
typeToMessageMapping = make(map[string]string, len(eventTypeMapping))
)
func init() {
for k, v := range eventTypeMapping {
typename := reflect.TypeOf(v).Elem().Name()
messageToTypeName[k] = typename
typeToMessageMapping[typename] = k
}
}
// genMAC generates the HMAC signature for a message provided the secret key
// and hashFunc.
func genMAC(message, key []byte, hashFunc func() hash.Hash) []byte {
@ -294,7 +313,7 @@ func DeliveryID(r *http.Request) string {
// }
// }
func ParseWebHook(messageType string, payload []byte) (interface{}, error) {
eventType, ok := eventTypeMapping[messageType]
eventType, ok := messageToTypeName[messageType]
if !ok {
return nil, fmt.Errorf("unknown X-Github-Event in message: %v", messageType)
}
@ -305,3 +324,28 @@ func ParseWebHook(messageType string, payload []byte) (interface{}, error) {
}
return event.ParsePayload()
}
// WebhookTypes returns a sorted list of all the known GitHub event type strings
// supported by go-github.
func MessageTypes() []string {
types := make([]string, 0, len(eventTypeMapping))
for t := range eventTypeMapping {
types = append(types, t)
}
sort.Strings(types)
return types
}
// EventForType returns an empty struct matching the specified GitHub event type.
// If messageType does not match any known event types, it returns nil.
func EventForType(messageType string) interface{} {
prototype := eventTypeMapping[messageType]
if prototype == nil {
return nil
}
// return a _copy_ of the pointed-to-object. Unfortunately, for this we
// need to use reflection. If we store the actual objects in the map,
// we still need to use reflection to convert from `any` to the actual
// type, so this was deemed the lesser of two evils. (#2865)
return reflect.New(reflect.TypeOf(prototype).Elem()).Interface()
}

Some files were not shown because too many files have changed in this diff Show more