Skip to content

Commit

Permalink
cleanup(pkg): switch to use master go-github to get rid of internal v…
Browse files Browse the repository at this point in the history
…ariables API client.

Signed-off-by: Federico Di Pierro <[email protected]>
  • Loading branch information
FedeDP committed Feb 7, 2023
1 parent cefbe9d commit 82b8049
Show file tree
Hide file tree
Showing 9 changed files with 177 additions and 249 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.17

require (
github.com/1Password/connect-sdk-go v1.5.0
github.com/google/go-github/v49 v49.1.0
github.com/google/go-github/v50 v50.0.1-0.20230206142857-c855eb5fc7dc
github.com/jamesruan/sodium v1.0.14
github.com/sirupsen/logrus v1.9.0
github.com/stretchr/testify v1.7.1
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-github/v49 v49.1.0 h1:LFkMgawGQ8dfzWLH/rNE0b3u1D3n6/dw7ZmrN3b+YFY=
github.com/google/go-github/v49 v49.1.0/go.mod h1:MUUzHPrhGniB6vUKa27y37likpipzG+BXXJbG04J334=
github.com/google/go-github/v50 v50.0.1-0.20230206142857-c855eb5fc7dc h1:esNLurCJatadpveRicS7nPz+rwO0JIqvda+pP+MEL5Q=
github.com/google/go-github/v50 v50.0.1-0.20230206142857-c855eb5fc7dc/go.mod h1:Ev4Tre8QoKiolvbpOSG3FIi4Mlon3S2Nt9W5JYqKiwA=
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.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
Expand Down
106 changes: 5 additions & 101 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@ package main

import (
"context"
"encoding/base64"
"github.com/FedeDP/GhEnvSet/pkg/config"
"github.com/FedeDP/GhEnvSet/pkg/poiana"
"github.com/google/go-github/v49/github"
"github.com/stretchr/testify/assert"
"testing"
)
Expand All @@ -25,125 +23,31 @@ orgs:
- secret2
`

type MockVariableService struct {
variables map[string]string
}

func (m MockVariableService) ListRepoVariables(ctx context.Context, owner, repo string) (*poiana.Variables, error) {
vars := make([]*poiana.Variable, 0)
for key, val := range m.variables {
vars = append(vars, &poiana.Variable{
Name: key,
Value: val,
})
}

return &poiana.Variables{
TotalCount: len(m.variables),
Variables: vars,
}, nil
}

func (m MockVariableService) DeleteRepoVariable(ctx context.Context, owner, repo, name string) error {
delete(m.variables, name)
return nil
}

func (m MockVariableService) CreateOrUpdateRepoVariable(ctx context.Context, owner, repo string, variable *poiana.Variable) error {
m.variables[variable.Name] = variable.Value
return nil
}

func newMockVariableService() poiana.ActionsVarsService {
mServ := &MockVariableService{variables: make(map[string]string, 0)}
// Initial variable set
_ = mServ.CreateOrUpdateRepoVariable(context.Background(), "", "", &poiana.Variable{
Name: "var0",
Value: "value0",
CreatedAt: github.Timestamp{},
UpdatedAt: github.Timestamp{},
})
return mServ
}

type MockSecretsService struct {
secrets map[string]*github.EncryptedSecret
}

func (m MockSecretsService) ListRepoSecrets(ctx context.Context, owner, repo string) (*github.Secrets, error) {
secs := make([]*github.Secret, 0)
for key, _ := range m.secrets {
secs = append(secs, &github.Secret{
Name: key,
})
}

return &github.Secrets{
TotalCount: len(m.secrets),
Secrets: secs,
}, nil
}

func (m MockSecretsService) DeleteRepoSecret(ctx context.Context, owner, repo, name string) error {
delete(m.secrets, name)
return nil
}

func (m MockSecretsService) CreateOrUpdateRepoSecret(ctx context.Context, owner, repo string, eSecret *github.EncryptedSecret) error {
m.secrets[eSecret.Name] = eSecret
return nil
}

func newMockSecretsService() poiana.ActionsSecretsService {
mServ := &MockSecretsService{secrets: make(map[string]*github.EncryptedSecret, 0)}
_ = mServ.CreateOrUpdateRepoSecret(context.Background(), "", "", &github.EncryptedSecret{
Name: "secret0",
KeyID: "testing",
})
return mServ
}

type MockPublicKeyProvider struct{}

func (pk *MockPublicKeyProvider) GetPublicKey(ctx context.Context, orgName string, repoName string) (*github.PublicKey, error) {
keyID := "testing"
key := base64.StdEncoding.EncodeToString([]byte("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")) // 32B key
pKey := github.PublicKey{
KeyID: &keyID,
Key: &key,
}
return &pKey, nil
}

func newMockPublicKeyProvider() poiana.PublicKeyProvider {
return &MockPublicKeyProvider{}
}

func TestMainLoop(t *testing.T) {
ctx := context.Background()

conf, err := config.FromData(testYAML)
assert.NoError(t, err)

mockVarServ := newMockVariableService()
mockSecServ := newMockSecretsService()
mockPKeyProv := newMockPublicKeyProvider()
mockVarServ := poiana.NewMockVariableService()
mockSecServ := poiana.NewMockSecretsService()
mockPKeyProv := poiana.NewMockPublicKeyProvider()
provider, err := poiana.NewMockSecretsProvider(map[string]string{"secret0": "value0", "secret1": "value1", "secret2": "value2"})
assert.NoError(t, err)

err = conf.Loop(mockVarServ, mockSecServ, provider, mockPKeyProv, false)
assert.NoError(t, err)

// Check repo variables
vars, err := mockVarServ.ListRepoVariables(ctx, "", "")
vars, _, err := mockVarServ.ListRepoVariables(ctx, "", "", nil)
assert.NoError(t, err)
assert.Equal(t, vars.TotalCount, len(conf.Orgs["FedeDP"].Repos["GhEnvSet"].Actions.Variables))
for _, v := range vars.Variables {
assert.Equal(t, conf.Orgs["FedeDP"].Repos["GhEnvSet"].Actions.Variables[v.Name], v.Value)
}

// Check repo secrets
secs, err := mockSecServ.ListRepoSecrets(ctx, "", "")
secs, _, err := mockSecServ.ListRepoSecrets(ctx, "", "", nil)
assert.NoError(t, err)
assert.Equal(t, secs.TotalCount, len(conf.Orgs["FedeDP"].Repos["GhEnvSet"].Actions.Secrets))
for _, sec := range secs.Secrets {
Expand Down
31 changes: 19 additions & 12 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import (
"context"
"encoding/base64"
"github.com/FedeDP/GhEnvSet/pkg/poiana"
"net/http"
"os"
"strings"

"github.com/google/go-github/v49/github"
"github.com/google/go-github/v50/github"
"github.com/jamesruan/sodium"
"github.com/sirupsen/logrus"
"gopkg.in/yaml.v3"
Expand Down Expand Up @@ -56,7 +57,7 @@ func syncSecrets(ctx context.Context,

// Step 1: load repo secrets
logrus.Infof("listing secrets for repo '%s/%s'...", orgName, repoName)
secs, err := service.ListRepoSecrets(ctx, orgName, repoName)
secs, _, err := service.ListRepoSecrets(ctx, orgName, repoName, nil)
if err != nil {
return err
}
Expand All @@ -72,7 +73,7 @@ func syncSecrets(ctx context.Context,
}
if !found {
logrus.Infof("deleting secret '%s' for repo '%s/%s'...", existentSec.Name, orgName, repoName)
err = service.DeleteRepoSecret(ctx, orgName, repoName, existentSec.Name)
_, err = service.DeleteRepoSecret(ctx, orgName, repoName, existentSec.Name)
if err != nil {
return err
}
Expand All @@ -95,10 +96,7 @@ func syncSecrets(ctx context.Context,
secBytes := sodium.Bytes(secValue)
encSecBytes := secBytes.SealedBox(sodium.BoxPublicKey{Bytes: keyBytes})
encSecBytesB64 := base64.StdEncoding.EncodeToString(([]byte)(encSecBytes))
if err != nil {
return err
}
err = service.CreateOrUpdateRepoSecret(ctx, orgName, repoName, &github.EncryptedSecret{
_, err = service.CreateOrUpdateRepoSecret(ctx, orgName, repoName, &github.EncryptedSecret{
Name: secName,
KeyID: pKey.GetKeyID(),
EncryptedValue: encSecBytesB64,
Expand All @@ -117,7 +115,7 @@ func syncVariables(ctx context.Context,
variables map[string]string) error {
// Step 1: load repo variables
logrus.Infof("listing variables for repo '%s/%s'...", orgName, repoName)
vars, err := service.ListRepoVariables(ctx, orgName, repoName)
vars, _, err := service.ListRepoVariables(ctx, orgName, repoName, nil)
if err != nil {
return err
}
Expand All @@ -127,7 +125,7 @@ func syncVariables(ctx context.Context,
_, ok := variables[existentVar.Name]
if !ok {
logrus.Infof("deleting variable '%s' for repo '%s/%s'...", existentVar.Name, orgName, repoName)
err = service.DeleteRepoVariable(ctx, orgName, repoName, existentVar.Name)
_, err = service.DeleteRepoVariable(ctx, orgName, repoName, existentVar.Name)
if err != nil {
return err
}
Expand All @@ -137,12 +135,21 @@ func syncVariables(ctx context.Context,
// Step 3: add or update all conf-listed variables
for newVarName, newVarValue := range variables {
logrus.Infof("adding/updating variable '%s' in repo '%s/%s'...", newVarName, orgName, repoName)
err = service.CreateOrUpdateRepoVariable(ctx, orgName, repoName, &poiana.Variable{
resp, err := service.UpdateRepoVariable(ctx, orgName, repoName, &github.ActionsVariable{
Name: newVarName,
Value: newVarValue,
})
if err != nil {
return err
// Update returns StatusNoContent when successful
if resp.StatusCode != http.StatusNoContent {
_, err = service.CreateRepoVariable(ctx, orgName, repoName, &github.ActionsVariable{
Name: newVarName,
Value: newVarValue,
})
}
if err != nil {
return err
}
}
}
return nil
Expand All @@ -164,7 +171,7 @@ func (g *GithubConfig) Loop(
for repoName, repo := range org.Repos {
// fetch encryption key
logrus.Infof("retrieving public key for repo '%s/%s'...", orgName, repoName)
pKey, err := pKeyProvider.GetPublicKey(ctx, orgName, repoName)
pKey, _, err := pKeyProvider.GetRepoPublicKey(ctx, orgName, repoName)
if err == nil {
if dryRun {
logrus.Infoln("Would have synced secrets")
Expand Down
41 changes: 3 additions & 38 deletions pkg/poiana/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,38 +6,10 @@ import (
"net/http"
"os"

"github.com/google/go-github/v49/github"
"github.com/google/go-github/v50/github"
)

// Variable represents a repository action variable.
type Variable struct {
Name string `json:"name"`
Value string `json:"value"`
CreatedAt github.Timestamp `json:"created_at"`
UpdatedAt github.Timestamp `json:"updated_at"`
}

type Variables struct {
TotalCount int `json:"total_count"`
Variables []*Variable `json:"variables"`
}

type actionsService struct {
*github.ActionsService
client *github.Client
}

type Client struct {
*github.Client
Actions *actionsService
}

func (a *actionsService) GetPublicKey(ctx context.Context, orgName string, repoName string) (*github.PublicKey, error) {
pKey, _, err := a.GetRepoPublicKey(ctx, orgName, repoName)
return pKey, err
}

func NewClient(ctx context.Context, tokenFile string) (*Client, error) {
func NewClient(ctx context.Context, tokenFile string) (*github.Client, error) {
ghTokBytes, err := os.ReadFile(tokenFile)
if err != nil {
return nil, err
Expand All @@ -50,12 +22,5 @@ func NewClient(ctx context.Context, tokenFile string) (*Client, error) {
)
tc = oauth2.NewClient(ctx, ts)
}
ghCl := github.NewClient(tc)
return &Client{
Client: ghCl,
Actions: &actionsService{
ActionsService: ghCl.Actions,
client: ghCl,
},
}, nil
return github.NewClient(tc), nil
}
25 changes: 5 additions & 20 deletions pkg/poiana/secrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package poiana
import (
"context"

"github.com/google/go-github/v49/github"
"github.com/google/go-github/v50/github"
)

// SecretsProvider retrieves secrets with a given key
Expand All @@ -14,26 +14,11 @@ type SecretsProvider interface {
}

type PublicKeyProvider interface {
GetPublicKey(context.Context, string, string) (*github.PublicKey, error)
GetRepoPublicKey(ctx context.Context, orgName string, repoName string) (*github.PublicKey, *github.Response, error)
}

type ActionsSecretsService interface {
ListRepoSecrets(ctx context.Context, owner, repo string) (*github.Secrets, error)
DeleteRepoSecret(ctx context.Context, owner, repo, name string) error
CreateOrUpdateRepoSecret(ctx context.Context, owner, repo string, eSecret *github.EncryptedSecret) error
}

func (s *actionsService) ListRepoSecrets(ctx context.Context, owner, repo string) (*github.Secrets, error) {
secrets, _, err := s.ActionsService.ListRepoSecrets(ctx, owner, repo, nil)
return secrets, err
}

func (s *actionsService) DeleteRepoSecret(ctx context.Context, owner, repo, name string) error {
_, err := s.ActionsService.DeleteRepoSecret(ctx, owner, repo, name)
return err
}

func (s *actionsService) CreateOrUpdateRepoSecret(ctx context.Context, owner, repo string, eSecret *github.EncryptedSecret) error {
_, err := s.ActionsService.CreateOrUpdateRepoSecret(ctx, owner, repo, eSecret)
return err
ListRepoSecrets(ctx context.Context, owner, repo string, opts *github.ListOptions) (*github.Secrets, *github.Response, error)
DeleteRepoSecret(ctx context.Context, owner, repo, name string) (*github.Response, error)
CreateOrUpdateRepoSecret(ctx context.Context, owner, repo string, eSecret *github.EncryptedSecret) (*github.Response, error)
}
Loading

0 comments on commit 82b8049

Please sign in to comment.