Fix: Scope entities to endpoint
This change scopes all github entities to a github endpoint, allowing users to have the same repo/org/enterprise created for each endpoint. This way, if your username is the same on github.com and on your GHES server, and you have the same repository name or org in both places, GARM can now handle that situation. This change also fixes a leaky watcher in the pool manager. Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
This commit is contained in:
parent
f64ffa8d92
commit
cc6e985629
20 changed files with 122 additions and 71 deletions
|
|
@ -82,8 +82,8 @@ func (s *sqlDatabase) CreateEnterprise(ctx context.Context, name, credentialsNam
|
|||
return paramEnt, nil
|
||||
}
|
||||
|
||||
func (s *sqlDatabase) GetEnterprise(ctx context.Context, name string) (params.Enterprise, error) {
|
||||
enterprise, err := s.getEnterprise(ctx, name)
|
||||
func (s *sqlDatabase) GetEnterprise(ctx context.Context, name, endpointName string) (params.Enterprise, error) {
|
||||
enterprise, err := s.getEnterprise(ctx, name, endpointName)
|
||||
if err != nil {
|
||||
return params.Enterprise{}, errors.Wrap(err, "fetching enterprise")
|
||||
}
|
||||
|
|
@ -223,10 +223,10 @@ func (s *sqlDatabase) UpdateEnterprise(ctx context.Context, enterpriseID string,
|
|||
return newParams, nil
|
||||
}
|
||||
|
||||
func (s *sqlDatabase) getEnterprise(_ context.Context, name string) (Enterprise, error) {
|
||||
func (s *sqlDatabase) getEnterprise(_ context.Context, name, endpointName string) (Enterprise, error) {
|
||||
var enterprise Enterprise
|
||||
|
||||
q := s.conn.Where("name = ? COLLATE NOCASE", name).
|
||||
q := s.conn.Where("name = ? COLLATE NOCASE and endpoint_name = ? COLLATE NOCASE", name, endpointName).
|
||||
Preload("Credentials").
|
||||
Preload("Credentials.Endpoint").
|
||||
Preload("Endpoint").
|
||||
|
|
|
|||
|
|
@ -245,7 +245,7 @@ func (s *EnterpriseTestSuite) TestCreateEnterpriseDBCreateErr() {
|
|||
}
|
||||
|
||||
func (s *EnterpriseTestSuite) TestGetEnterprise() {
|
||||
enterprise, err := s.Store.GetEnterprise(s.adminCtx, s.Fixtures.Enterprises[0].Name)
|
||||
enterprise, err := s.Store.GetEnterprise(s.adminCtx, s.Fixtures.Enterprises[0].Name, s.Fixtures.Enterprises[0].Endpoint.Name)
|
||||
|
||||
s.Require().Nil(err)
|
||||
s.Require().Equal(s.Fixtures.Enterprises[0].Name, enterprise.Name)
|
||||
|
|
@ -253,14 +253,14 @@ func (s *EnterpriseTestSuite) TestGetEnterprise() {
|
|||
}
|
||||
|
||||
func (s *EnterpriseTestSuite) TestGetEnterpriseCaseInsensitive() {
|
||||
enterprise, err := s.Store.GetEnterprise(s.adminCtx, "TeSt-eNtErPriSe-1")
|
||||
enterprise, err := s.Store.GetEnterprise(s.adminCtx, "TeSt-eNtErPriSe-1", "github.com")
|
||||
|
||||
s.Require().Nil(err)
|
||||
s.Require().Equal("test-enterprise-1", enterprise.Name)
|
||||
}
|
||||
|
||||
func (s *EnterpriseTestSuite) TestGetEnterpriseNotFound() {
|
||||
_, err := s.Store.GetEnterprise(s.adminCtx, "dummy-name")
|
||||
_, err := s.Store.GetEnterprise(s.adminCtx, "dummy-name", "github.com")
|
||||
|
||||
s.Require().NotNil(err)
|
||||
s.Require().Equal("fetching enterprise: not found", err.Error())
|
||||
|
|
@ -268,15 +268,15 @@ func (s *EnterpriseTestSuite) TestGetEnterpriseNotFound() {
|
|||
|
||||
func (s *EnterpriseTestSuite) TestGetEnterpriseDBDecryptingErr() {
|
||||
s.Fixtures.SQLMock.
|
||||
ExpectQuery(regexp.QuoteMeta("SELECT * FROM `enterprises` WHERE name = ? COLLATE NOCASE AND `enterprises`.`deleted_at` IS NULL ORDER BY `enterprises`.`id` LIMIT ?")).
|
||||
WithArgs(s.Fixtures.Enterprises[0].Name, 1).
|
||||
ExpectQuery(regexp.QuoteMeta("SELECT * FROM `enterprises` WHERE (name = ? COLLATE NOCASE and endpoint_name = ? COLLATE NOCASE) AND `enterprises`.`deleted_at` IS NULL ORDER BY `enterprises`.`id` LIMIT ?")).
|
||||
WithArgs(s.Fixtures.Enterprises[0].Name, s.Fixtures.Enterprises[0].Endpoint.Name, 1).
|
||||
WillReturnRows(sqlmock.NewRows([]string{"name"}).AddRow(s.Fixtures.Enterprises[0].Name))
|
||||
|
||||
_, err := s.StoreSQLMocked.GetEnterprise(s.adminCtx, s.Fixtures.Enterprises[0].Name)
|
||||
_, err := s.StoreSQLMocked.GetEnterprise(s.adminCtx, s.Fixtures.Enterprises[0].Name, s.Fixtures.Enterprises[0].Endpoint.Name)
|
||||
|
||||
s.assertSQLMockExpectations()
|
||||
s.Require().NotNil(err)
|
||||
s.Require().Equal("fetching enterprise: missing secret", err.Error())
|
||||
s.assertSQLMockExpectations()
|
||||
}
|
||||
|
||||
func (s *EnterpriseTestSuite) TestListEnterprises() {
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ type Organization struct {
|
|||
Jobs []WorkflowJob `gorm:"foreignKey:OrgID;constraint:OnDelete:SET NULL"`
|
||||
PoolBalancerType params.PoolBalancerType `gorm:"type:varchar(64)"`
|
||||
|
||||
EndpointName *string `gorm:"index"`
|
||||
EndpointName *string `gorm:"index:idx_org_name_nocase,collate:nocase"`
|
||||
Endpoint GithubEndpoint `gorm:"foreignKey:EndpointName;constraint:OnDelete:SET NULL"`
|
||||
}
|
||||
|
||||
|
|
@ -137,7 +137,7 @@ type Enterprise struct {
|
|||
Jobs []WorkflowJob `gorm:"foreignKey:EnterpriseID;constraint:OnDelete:SET NULL"`
|
||||
PoolBalancerType params.PoolBalancerType `gorm:"type:varchar(64)"`
|
||||
|
||||
EndpointName *string `gorm:"index"`
|
||||
EndpointName *string `gorm:"index:idx_ent_name_nocase,collate:nocase"`
|
||||
Endpoint GithubEndpoint `gorm:"foreignKey:EndpointName;constraint:OnDelete:SET NULL"`
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -85,8 +85,8 @@ func (s *sqlDatabase) CreateOrganization(ctx context.Context, name, credentialsN
|
|||
return org, nil
|
||||
}
|
||||
|
||||
func (s *sqlDatabase) GetOrganization(ctx context.Context, name string) (params.Organization, error) {
|
||||
org, err := s.getOrg(ctx, name)
|
||||
func (s *sqlDatabase) GetOrganization(ctx context.Context, name, endpointName string) (params.Organization, error) {
|
||||
org, err := s.getOrg(ctx, name, endpointName)
|
||||
if err != nil {
|
||||
return params.Organization{}, errors.Wrap(err, "fetching org")
|
||||
}
|
||||
|
|
@ -252,10 +252,10 @@ func (s *sqlDatabase) getOrgByID(_ context.Context, db *gorm.DB, id string, prel
|
|||
return org, nil
|
||||
}
|
||||
|
||||
func (s *sqlDatabase) getOrg(_ context.Context, name string) (Organization, error) {
|
||||
func (s *sqlDatabase) getOrg(_ context.Context, name, endpointName string) (Organization, error) {
|
||||
var org Organization
|
||||
|
||||
q := s.conn.Where("name = ? COLLATE NOCASE", name).
|
||||
q := s.conn.Where("name = ? COLLATE NOCASE and endpoint_name = ? COLLATE NOCASE", name, endpointName).
|
||||
Preload("Credentials").
|
||||
Preload("Credentials.Endpoint").
|
||||
Preload("Endpoint").
|
||||
|
|
|
|||
|
|
@ -247,7 +247,7 @@ func (s *OrgTestSuite) TestCreateOrganizationDBCreateErr() {
|
|||
}
|
||||
|
||||
func (s *OrgTestSuite) TestGetOrganization() {
|
||||
org, err := s.Store.GetOrganization(s.adminCtx, s.Fixtures.Orgs[0].Name)
|
||||
org, err := s.Store.GetOrganization(s.adminCtx, s.Fixtures.Orgs[0].Name, s.Fixtures.Orgs[0].Endpoint.Name)
|
||||
|
||||
s.Require().Nil(err)
|
||||
s.Require().Equal(s.Fixtures.Orgs[0].Name, org.Name)
|
||||
|
|
@ -255,14 +255,14 @@ func (s *OrgTestSuite) TestGetOrganization() {
|
|||
}
|
||||
|
||||
func (s *OrgTestSuite) TestGetOrganizationCaseInsensitive() {
|
||||
org, err := s.Store.GetOrganization(s.adminCtx, "TeSt-oRg-1")
|
||||
org, err := s.Store.GetOrganization(s.adminCtx, "TeSt-oRg-1", "github.com")
|
||||
|
||||
s.Require().Nil(err)
|
||||
s.Require().Equal("test-org-1", org.Name)
|
||||
}
|
||||
|
||||
func (s *OrgTestSuite) TestGetOrganizationNotFound() {
|
||||
_, err := s.Store.GetOrganization(s.adminCtx, "dummy-name")
|
||||
_, err := s.Store.GetOrganization(s.adminCtx, "dummy-name", "github.com")
|
||||
|
||||
s.Require().NotNil(err)
|
||||
s.Require().Equal("fetching org: not found", err.Error())
|
||||
|
|
@ -270,15 +270,15 @@ func (s *OrgTestSuite) TestGetOrganizationNotFound() {
|
|||
|
||||
func (s *OrgTestSuite) TestGetOrganizationDBDecryptingErr() {
|
||||
s.Fixtures.SQLMock.
|
||||
ExpectQuery(regexp.QuoteMeta("SELECT * FROM `organizations` WHERE name = ? COLLATE NOCASE AND `organizations`.`deleted_at` IS NULL ORDER BY `organizations`.`id` LIMIT ?")).
|
||||
WithArgs(s.Fixtures.Orgs[0].Name, 1).
|
||||
ExpectQuery(regexp.QuoteMeta("SELECT * FROM `organizations` WHERE (name = ? COLLATE NOCASE and endpoint_name = ? COLLATE NOCASE) AND `organizations`.`deleted_at` IS NULL ORDER BY `organizations`.`id` LIMIT ?")).
|
||||
WithArgs(s.Fixtures.Orgs[0].Name, s.Fixtures.Orgs[0].Endpoint.Name, 1).
|
||||
WillReturnRows(sqlmock.NewRows([]string{"name"}).AddRow(s.Fixtures.Orgs[0].Name))
|
||||
|
||||
_, err := s.StoreSQLMocked.GetOrganization(s.adminCtx, s.Fixtures.Orgs[0].Name)
|
||||
_, err := s.StoreSQLMocked.GetOrganization(s.adminCtx, s.Fixtures.Orgs[0].Name, s.Fixtures.Orgs[0].Endpoint.Name)
|
||||
|
||||
s.assertSQLMockExpectations()
|
||||
s.Require().NotNil(err)
|
||||
s.Require().Equal("fetching org: missing secret", err.Error())
|
||||
s.assertSQLMockExpectations()
|
||||
}
|
||||
|
||||
func (s *OrgTestSuite) TestListOrganizations() {
|
||||
|
|
|
|||
|
|
@ -84,8 +84,8 @@ func (s *sqlDatabase) CreateRepository(ctx context.Context, owner, name, credent
|
|||
return param, nil
|
||||
}
|
||||
|
||||
func (s *sqlDatabase) GetRepository(ctx context.Context, owner, name string) (params.Repository, error) {
|
||||
repo, err := s.getRepo(ctx, owner, name)
|
||||
func (s *sqlDatabase) GetRepository(ctx context.Context, owner, name, endpointName string) (params.Repository, error) {
|
||||
repo, err := s.getRepo(ctx, owner, name, endpointName)
|
||||
if err != nil {
|
||||
return params.Repository{}, errors.Wrap(err, "fetching repo")
|
||||
}
|
||||
|
|
@ -228,10 +228,10 @@ func (s *sqlDatabase) GetRepositoryByID(ctx context.Context, repoID string) (par
|
|||
return param, nil
|
||||
}
|
||||
|
||||
func (s *sqlDatabase) getRepo(_ context.Context, owner, name string) (Repository, error) {
|
||||
func (s *sqlDatabase) getRepo(_ context.Context, owner, name, endpointName string) (Repository, error) {
|
||||
var repo Repository
|
||||
|
||||
q := s.conn.Where("name = ? COLLATE NOCASE and owner = ? COLLATE NOCASE", name, owner).
|
||||
q := s.conn.Where("name = ? COLLATE NOCASE and owner = ? COLLATE NOCASE and endpoint_name = ? COLLATE NOCASE", name, owner, endpointName).
|
||||
Preload("Credentials").
|
||||
Preload("Credentials.Endpoint").
|
||||
Preload("Endpoint").
|
||||
|
|
|
|||
|
|
@ -271,7 +271,7 @@ func (s *RepoTestSuite) TestCreateRepositoryInvalidDBCreateErr() {
|
|||
}
|
||||
|
||||
func (s *RepoTestSuite) TestGetRepository() {
|
||||
repo, err := s.Store.GetRepository(s.adminCtx, s.Fixtures.Repos[0].Owner, s.Fixtures.Repos[0].Name)
|
||||
repo, err := s.Store.GetRepository(s.adminCtx, s.Fixtures.Repos[0].Owner, s.Fixtures.Repos[0].Name, s.Fixtures.Repos[0].Endpoint.Name)
|
||||
|
||||
s.Require().Nil(err)
|
||||
s.Require().Equal(s.Fixtures.Repos[0].Owner, repo.Owner)
|
||||
|
|
@ -280,7 +280,7 @@ func (s *RepoTestSuite) TestGetRepository() {
|
|||
}
|
||||
|
||||
func (s *RepoTestSuite) TestGetRepositoryCaseInsensitive() {
|
||||
repo, err := s.Store.GetRepository(s.adminCtx, "TeSt-oWnEr-1", "TeSt-rEpO-1")
|
||||
repo, err := s.Store.GetRepository(s.adminCtx, "TeSt-oWnEr-1", "TeSt-rEpO-1", "github.com")
|
||||
|
||||
s.Require().Nil(err)
|
||||
s.Require().Equal("test-owner-1", repo.Owner)
|
||||
|
|
@ -288,7 +288,7 @@ func (s *RepoTestSuite) TestGetRepositoryCaseInsensitive() {
|
|||
}
|
||||
|
||||
func (s *RepoTestSuite) TestGetRepositoryNotFound() {
|
||||
_, err := s.Store.GetRepository(s.adminCtx, "dummy-owner", "dummy-name")
|
||||
_, err := s.Store.GetRepository(s.adminCtx, "dummy-owner", "dummy-name", "github.com")
|
||||
|
||||
s.Require().NotNil(err)
|
||||
s.Require().Equal("fetching repo: not found", err.Error())
|
||||
|
|
@ -296,15 +296,15 @@ func (s *RepoTestSuite) TestGetRepositoryNotFound() {
|
|||
|
||||
func (s *RepoTestSuite) TestGetRepositoryDBDecryptingErr() {
|
||||
s.Fixtures.SQLMock.
|
||||
ExpectQuery(regexp.QuoteMeta("SELECT * FROM `repositories` WHERE (name = ? COLLATE NOCASE and owner = ? COLLATE NOCASE) AND `repositories`.`deleted_at` IS NULL ORDER BY `repositories`.`id` LIMIT ?")).
|
||||
WithArgs(s.Fixtures.Repos[0].Name, s.Fixtures.Repos[0].Owner, 1).
|
||||
ExpectQuery(regexp.QuoteMeta("SELECT * FROM `repositories` WHERE (name = ? COLLATE NOCASE and owner = ? COLLATE NOCASE and endpoint_name = ? COLLATE NOCASE) AND `repositories`.`deleted_at` IS NULL ORDER BY `repositories`.`id` LIMIT ?")).
|
||||
WithArgs(s.Fixtures.Repos[0].Name, s.Fixtures.Repos[0].Owner, s.Fixtures.Repos[0].Endpoint.Name, 1).
|
||||
WillReturnRows(sqlmock.NewRows([]string{"name", "owner"}).AddRow(s.Fixtures.Repos[0].Name, s.Fixtures.Repos[0].Owner))
|
||||
s.Fixtures.SQLMock.
|
||||
ExpectQuery(regexp.QuoteMeta("SELECT * FROM `repositories` WHERE (name = ? COLLATE NOCASE and owner = ? COLLATE NOCASE) AND `repositories`.`deleted_at` IS NULL ORDER BY `repositories`.`id`,`repositories`.`id` LIMIT ?")).
|
||||
WithArgs(s.Fixtures.Repos[0].Name, s.Fixtures.Repos[0].Owner, 1).
|
||||
ExpectQuery(regexp.QuoteMeta("SELECT * FROM `repositories` WHERE (name = ? COLLATE NOCASE and owner = ? COLLATE NOCASE and endpoint_name = ? COLLATE NOCASE) AND `repositories`.`deleted_at` IS NULL ORDER BY `repositories`.`id`,`repositories`.`id` LIMIT ?")).
|
||||
WithArgs(s.Fixtures.Repos[0].Name, s.Fixtures.Repos[0].Owner, s.Fixtures.Repos[0].Endpoint.Name, 1).
|
||||
WillReturnRows(sqlmock.NewRows([]string{"name", "owner"}).AddRow(s.Fixtures.Repos[0].Name, s.Fixtures.Repos[0].Owner))
|
||||
|
||||
_, err := s.StoreSQLMocked.GetRepository(s.adminCtx, s.Fixtures.Repos[0].Owner, s.Fixtures.Repos[0].Name)
|
||||
_, err := s.StoreSQLMocked.GetRepository(s.adminCtx, s.Fixtures.Repos[0].Owner, s.Fixtures.Repos[0].Name, s.Fixtures.Repos[0].Endpoint.Name)
|
||||
|
||||
s.Require().NotNil(err)
|
||||
s.Require().Equal("fetching repo: missing secret", err.Error())
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue