From 1256473089e0f09a541e86997fb2bd030830ddbe Mon Sep 17 00:00:00 2001 From: Gabriel Adrian Samfira Date: Wed, 24 Apr 2024 12:23:45 +0000 Subject: [PATCH] Fetch credentials from DB Do not rely on the entity object to hold updated or detailed credentials, fetch them from the DB every time. This change also ensures that we pass in the user context instead of the runner context to the DB methods. Signed-off-by: Gabriel Adrian Samfira --- .github/workflows/integration-tests.yml | 3 +- cmd/garm/main.go | 2 ++ database/sql/util.go | 13 ++++++++ params/params.go | 38 +++++++++++++++-------- runner/enterprises.go | 4 +++ runner/organizations.go | 4 +++ runner/repositories.go | 4 +++ runner/runner.go | 40 +++++++++++++++++++++---- 8 files changed, 88 insertions(+), 20 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 200485aa..95b95e8b 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -54,7 +54,7 @@ jobs: run: | set -o pipefail set -o errexit - make integration 2>&1 | tee /artifacts-logs/e2e.log + make integration 2>&1 env: GARM_BASE_URL: ${{ steps.ngrok.outputs.tunnel-url }} ORG_NAME: gsamfira @@ -68,6 +68,7 @@ jobs: run: | sudo systemctl status garm@runner || true sudo journalctl --no-pager 2>&1 > /artifacts-logs/system.log + sudo journalctl -u garm@runner --no-pager 2>&1 > /artifacts-logs/garm.log - name: Upload GARM and e2e logs if: always() diff --git a/cmd/garm/main.go b/cmd/garm/main.go index 454d766f..526e2017 100644 --- a/cmd/garm/main.go +++ b/cmd/garm/main.go @@ -151,6 +151,8 @@ func main() { ctx, stop := signal.NotifyContext(context.Background(), signals...) defer stop() + ctx = auth.GetAdminContext(ctx) + cfg, err := config.NewConfig(*conf) if err != nil { log.Fatalf("Fetching config: %+v", err) //nolint:gocritic diff --git a/database/sql/util.go b/database/sql/util.go index c291e5d9..b7f8a058 100644 --- a/database/sql/util.go +++ b/database/sql/util.go @@ -127,6 +127,11 @@ func (s *sqlDatabase) sqlToCommonOrganization(org Organization, detailed bool) ( PoolBalancerType: org.PoolBalancerType, Endpoint: endpoint, } + + if org.CredentialsID != nil { + ret.CredentialsID = *org.CredentialsID + } + if detailed { creds, err := s.sqlToCommonGithubCredentials(org.Credentials) if err != nil { @@ -172,6 +177,10 @@ func (s *sqlDatabase) sqlToCommonEnterprise(enterprise Enterprise, detailed bool Endpoint: endpoint, } + if enterprise.CredentialsID != nil { + ret.CredentialsID = *enterprise.CredentialsID + } + if detailed { creds, err := s.sqlToCommonGithubCredentials(enterprise.Credentials) if err != nil { @@ -278,6 +287,10 @@ func (s *sqlDatabase) sqlToCommonRepository(repo Repository, detailed bool) (par Endpoint: endpoint, } + if repo.CredentialsID != nil { + ret.CredentialsID = *repo.CredentialsID + } + if detailed { creds, err := s.sqlToCommonGithubCredentials(repo.Credentials) if err != nil { diff --git a/params/params.go b/params/params.go index 522dc954..f9629fc7 100644 --- a/params/params.go +++ b/params/params.go @@ -397,11 +397,15 @@ type Internal struct { } type Repository struct { - ID string `json:"id"` - Owner string `json:"owner"` - Name string `json:"name"` - Pools []Pool `json:"pool,omitempty"` - CredentialsName string `json:"credentials_name"` + ID string `json:"id"` + Owner string `json:"owner"` + Name string `json:"name"` + Pools []Pool `json:"pool,omitempty"` + // CredentialName is the name of the credentials associated with the enterprise. + // This field is now deprecated. Use CredentialsID instead. This field will be + // removed in v0.2.0. + CredentialsName string `json:"credentials_name,omitempty"` + CredentialsID uint `json:"credentials_id"` Credentials GithubCredentials `json:"credentials"` PoolManagerStatus PoolManagerStatus `json:"pool_manager_status,omitempty"` PoolBalancerType PoolBalancerType `json:"pool_balancing_type"` @@ -445,11 +449,15 @@ func (r Repository) String() string { type Repositories []Repository type Organization struct { - ID string `json:"id"` - Name string `json:"name"` - Pools []Pool `json:"pool,omitempty"` - CredentialsName string `json:"credentials_name"` + ID string `json:"id"` + Name string `json:"name"` + Pools []Pool `json:"pool,omitempty"` + // CredentialName is the name of the credentials associated with the enterprise. + // This field is now deprecated. Use CredentialsID instead. This field will be + // removed in v0.2.0. + CredentialsName string `json:"credentials_name,omitempty"` Credentials GithubCredentials `json:"credentials"` + CredentialsID uint `json:"credentials_id"` PoolManagerStatus PoolManagerStatus `json:"pool_manager_status,omitempty"` PoolBalancerType PoolBalancerType `json:"pool_balancing_type"` Endpoint GithubEndpoint `json:"endpoint"` @@ -488,11 +496,15 @@ func (o Organization) GetBalancerType() PoolBalancerType { type Organizations []Organization type Enterprise struct { - ID string `json:"id"` - Name string `json:"name"` - Pools []Pool `json:"pool,omitempty"` - CredentialsName string `json:"credentials_name"` + ID string `json:"id"` + Name string `json:"name"` + Pools []Pool `json:"pool,omitempty"` + // CredentialName is the name of the credentials associated with the enterprise. + // This field is now deprecated. Use CredentialsID instead. This field will be + // removed in v0.2.0. + CredentialsName string `json:"credentials_name,omitempty"` Credentials GithubCredentials `json:"credentials"` + CredentialsID uint `json:"credentials_id"` PoolManagerStatus PoolManagerStatus `json:"pool_manager_status,omitempty"` PoolBalancerType PoolBalancerType `json:"pool_balancing_type"` Endpoint GithubEndpoint `json:"endpoint"` diff --git a/runner/enterprises.go b/runner/enterprises.go index 8f8dbf31..7b12b245 100644 --- a/runner/enterprises.go +++ b/runner/enterprises.go @@ -54,6 +54,8 @@ func (r *Runner) CreateEnterprise(ctx context.Context, param params.CreateEnterp } }() + // Use the admin context in the pool manager. Any access control is already done above when + // updating the store. var poolMgr common.PoolManager poolMgr, err = r.poolManagerCtrl.CreateEnterprisePoolManager(r.ctx, enterprise, r.providers, r.store) if err != nil { @@ -172,6 +174,8 @@ func (r *Runner) UpdateEnterprise(ctx context.Context, enterpriseID string, para return params.Enterprise{}, errors.Wrap(err, "updating enterprise") } + // Use the admin context in the pool manager. Any access control is already done above when + // updating the store. poolMgr, err := r.poolManagerCtrl.UpdateEnterprisePoolManager(r.ctx, enterprise) if err != nil { return params.Enterprise{}, fmt.Errorf("failed to update enterprise pool manager: %w", err) diff --git a/runner/organizations.go b/runner/organizations.go index c0663505..ae2e853f 100644 --- a/runner/organizations.go +++ b/runner/organizations.go @@ -67,6 +67,8 @@ func (r *Runner) CreateOrganization(ctx context.Context, param params.CreateOrgP } }() + // Use the admin context in the pool manager. Any access control is already done above when + // updating the store. poolMgr, err := r.poolManagerCtrl.CreateOrgPoolManager(r.ctx, org, r.providers, r.store) if err != nil { return params.Organization{}, errors.Wrap(err, "creating org pool manager") @@ -201,6 +203,8 @@ func (r *Runner) UpdateOrganization(ctx context.Context, orgID string, param par return params.Organization{}, errors.Wrap(err, "updating org") } + // Use the admin context in the pool manager. Any access control is already done above when + // updating the store. poolMgr, err := r.poolManagerCtrl.UpdateOrgPoolManager(r.ctx, org) if err != nil { return params.Organization{}, fmt.Errorf("updating org pool manager: %w", err) diff --git a/runner/repositories.go b/runner/repositories.go index b2a6ef54..e316aa47 100644 --- a/runner/repositories.go +++ b/runner/repositories.go @@ -67,6 +67,8 @@ func (r *Runner) CreateRepository(ctx context.Context, param params.CreateRepoPa } }() + // Use the admin context in the pool manager. Any access control is already done above when + // updating the store. poolMgr, err := r.poolManagerCtrl.CreateRepoPoolManager(r.ctx, repo, r.providers, r.store) if err != nil { return params.Repository{}, errors.Wrap(err, "creating repo pool manager") @@ -200,6 +202,8 @@ func (r *Runner) UpdateRepository(ctx context.Context, repoID string, param para return params.Repository{}, errors.Wrap(err, "updating repo") } + // Use the admin context in the pool manager. Any access control is already done above when + // updating the store. poolMgr, err := r.poolManagerCtrl.UpdateRepoPoolManager(r.ctx, repo) if err != nil { return params.Repository{}, fmt.Errorf("failed to update pool manager: %w", err) diff --git a/runner/runner.go b/runner/runner.go index 453980a0..9873695d 100644 --- a/runner/runner.go +++ b/runner/runner.go @@ -67,6 +67,7 @@ func NewRunner(ctx context.Context, cfg config.Config, db dbCommon.Store) (*Runn poolManagerCtrl := &poolManagerCtrl{ controllerID: ctrlID.ControllerID.String(), config: cfg, + store: db, repositories: map[string]common.PoolManager{}, organizations: map[string]common.PoolManager{}, enterprises: map[string]common.PoolManager{}, @@ -92,6 +93,7 @@ type poolManagerCtrl struct { controllerID string config config.Config + store dbCommon.Store repositories map[string]common.PoolManager organizations map[string]common.PoolManager @@ -102,7 +104,12 @@ func (p *poolManagerCtrl) CreateRepoPoolManager(ctx context.Context, repo params p.mux.Lock() defer p.mux.Unlock() - cfgInternal, err := p.getInternalConfig(ctx, repo.Credentials, repo.GetBalancerType()) + creds, err := p.store.GetGithubCredentials(ctx, repo.CredentialsID, true) + if err != nil { + return nil, errors.Wrap(err, "fetching credentials") + } + + cfgInternal, err := p.getInternalConfig(ctx, creds, repo.GetBalancerType()) if err != nil { return nil, errors.Wrap(err, "fetching internal config") } @@ -130,7 +137,12 @@ func (p *poolManagerCtrl) UpdateRepoPoolManager(ctx context.Context, repo params return nil, errors.Wrapf(runnerErrors.ErrNotFound, "repository %s/%s pool manager not loaded", repo.Owner, repo.Name) } - internalCfg, err := p.getInternalConfig(ctx, repo.Credentials, repo.GetBalancerType()) + creds, err := p.store.GetGithubCredentials(ctx, repo.CredentialsID, true) + if err != nil { + return nil, errors.Wrap(err, "fetching credentials") + } + + internalCfg, err := p.getInternalConfig(ctx, creds, repo.GetBalancerType()) if err != nil { return nil, errors.Wrap(err, "fetching internal config") } @@ -175,7 +187,11 @@ func (p *poolManagerCtrl) CreateOrgPoolManager(ctx context.Context, org params.O p.mux.Lock() defer p.mux.Unlock() - cfgInternal, err := p.getInternalConfig(ctx, org.Credentials, org.GetBalancerType()) + creds, err := p.store.GetGithubCredentials(ctx, org.CredentialsID, true) + if err != nil { + return nil, errors.Wrap(err, "fetching credentials") + } + cfgInternal, err := p.getInternalConfig(ctx, creds, org.GetBalancerType()) if err != nil { return nil, errors.Wrap(err, "fetching internal config") } @@ -202,7 +218,11 @@ func (p *poolManagerCtrl) UpdateOrgPoolManager(ctx context.Context, org params.O return nil, errors.Wrapf(runnerErrors.ErrNotFound, "org %s pool manager not loaded", org.Name) } - internalCfg, err := p.getInternalConfig(ctx, org.Credentials, org.GetBalancerType()) + creds, err := p.store.GetGithubCredentials(ctx, org.CredentialsID, true) + if err != nil { + return nil, errors.Wrap(err, "fetching credentials") + } + internalCfg, err := p.getInternalConfig(ctx, creds, org.GetBalancerType()) if err != nil { return nil, errors.Wrap(err, "fetching internal config") } @@ -247,7 +267,11 @@ func (p *poolManagerCtrl) CreateEnterprisePoolManager(ctx context.Context, enter p.mux.Lock() defer p.mux.Unlock() - cfgInternal, err := p.getInternalConfig(ctx, enterprise.Credentials, enterprise.GetBalancerType()) + creds, err := p.store.GetGithubCredentials(ctx, enterprise.CredentialsID, true) + if err != nil { + return nil, errors.Wrap(err, "fetching credentials") + } + cfgInternal, err := p.getInternalConfig(ctx, creds, enterprise.GetBalancerType()) if err != nil { return nil, errors.Wrap(err, "fetching internal config") } @@ -275,7 +299,11 @@ func (p *poolManagerCtrl) UpdateEnterprisePoolManager(ctx context.Context, enter return nil, errors.Wrapf(runnerErrors.ErrNotFound, "enterprise %s pool manager not loaded", enterprise.Name) } - internalCfg, err := p.getInternalConfig(ctx, enterprise.Credentials, enterprise.GetBalancerType()) + creds, err := p.store.GetGithubCredentials(ctx, enterprise.CredentialsID, true) + if err != nil { + return nil, errors.Wrap(err, "fetching credentials") + } + internalCfg, err := p.getInternalConfig(ctx, creds, enterprise.GetBalancerType()) if err != nil { return nil, errors.Wrap(err, "fetching internal config") }