Enable orgs

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
This commit is contained in:
Gabriel Adrian Samfira 2025-05-16 22:43:21 +00:00
parent 5dfcfc542e
commit 6a168ba813
22 changed files with 125 additions and 77 deletions

View file

@ -348,9 +348,9 @@ func (_m *Store) CreateOrUpdateJob(ctx context.Context, job params.Job) (params.
return r0, r1
}
// CreateOrganization provides a mock function with given fields: ctx, name, credentialsName, webhookSecret, poolBalancerType
func (_m *Store) CreateOrganization(ctx context.Context, name string, credentialsName string, webhookSecret string, poolBalancerType params.PoolBalancerType) (params.Organization, error) {
ret := _m.Called(ctx, name, credentialsName, webhookSecret, poolBalancerType)
// CreateOrganization provides a mock function with given fields: ctx, name, credentials, webhookSecret, poolBalancerType
func (_m *Store) CreateOrganization(ctx context.Context, name string, credentials params.ForgeCredentials, webhookSecret string, poolBalancerType params.PoolBalancerType) (params.Organization, error) {
ret := _m.Called(ctx, name, credentials, webhookSecret, poolBalancerType)
if len(ret) == 0 {
panic("no return value specified for CreateOrganization")
@ -358,17 +358,17 @@ func (_m *Store) CreateOrganization(ctx context.Context, name string, credential
var r0 params.Organization
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, string, string, string, params.PoolBalancerType) (params.Organization, error)); ok {
return rf(ctx, name, credentialsName, webhookSecret, poolBalancerType)
if rf, ok := ret.Get(0).(func(context.Context, string, params.ForgeCredentials, string, params.PoolBalancerType) (params.Organization, error)); ok {
return rf(ctx, name, credentials, webhookSecret, poolBalancerType)
}
if rf, ok := ret.Get(0).(func(context.Context, string, string, string, params.PoolBalancerType) params.Organization); ok {
r0 = rf(ctx, name, credentialsName, webhookSecret, poolBalancerType)
if rf, ok := ret.Get(0).(func(context.Context, string, params.ForgeCredentials, string, params.PoolBalancerType) params.Organization); ok {
r0 = rf(ctx, name, credentials, webhookSecret, poolBalancerType)
} else {
r0 = ret.Get(0).(params.Organization)
}
if rf, ok := ret.Get(1).(func(context.Context, string, string, string, params.PoolBalancerType) error); ok {
r1 = rf(ctx, name, credentialsName, webhookSecret, poolBalancerType)
if rf, ok := ret.Get(1).(func(context.Context, string, params.ForgeCredentials, string, params.PoolBalancerType) error); ok {
r1 = rf(ctx, name, credentials, webhookSecret, poolBalancerType)
} else {
r1 = ret.Error(1)
}

View file

@ -47,7 +47,7 @@ type RepoStore interface {
}
type OrgStore interface {
CreateOrganization(ctx context.Context, name, credentialsName, webhookSecret string, poolBalancerType params.PoolBalancerType) (params.Organization, error)
CreateOrganization(ctx context.Context, name string, credentials params.ForgeCredentials, webhookSecret string, poolBalancerType params.PoolBalancerType) (org params.Organization, err error)
GetOrganization(ctx context.Context, name, endpointName string) (params.Organization, error)
GetOrganizationByID(ctx context.Context, orgID string) (params.Organization, error)
ListOrganizations(ctx context.Context) ([]params.Organization, error)

View file

@ -268,7 +268,11 @@ func (s *sqlDatabase) getGiteaCredentialsByName(ctx context.Context, tx *gorm.DB
if detailed {
q = q.
Preload("Repositories").
Preload("Organizations")
Preload("Organizations").
Preload("Repositories.GiteaCredentials").
Preload("Organizations.GiteaCredentials").
Preload("Repositories.Credentials").
Preload("Organizations.Credentials")
}
userID, err := getUIDFromContext(ctx)
@ -304,7 +308,11 @@ func (s *sqlDatabase) GetGiteaCredentials(ctx context.Context, id uint, detailed
if detailed {
q = q.
Preload("Repositories").
Preload("Organizations")
Preload("Organizations").
Preload("Repositories.GiteaCredentials").
Preload("Organizations.GiteaCredentials").
Preload("Repositories.Credentials").
Preload("Organizations.Credentials")
}
if !auth.IsAdmin(ctx) {

View file

@ -544,7 +544,7 @@ func (s *GithubTestSuite) TestDeleteCredentialsFailsIfReposOrgsOrEntitiesUseIt()
err = s.db.DeleteRepository(ctx, repo.ID)
s.Require().NoError(err)
org, err := s.db.CreateOrganization(ctx, "test-org", creds.Name, "superSecret@123BlaBla", params.PoolBalancerTypeRoundRobin)
org, err := s.db.CreateOrganization(ctx, "test-org", creds, "superSecret@123BlaBla", params.PoolBalancerTypeRoundRobin)
s.Require().NoError(err)
s.Require().NotNil(org)

View file

@ -84,7 +84,7 @@ func (s *InstancesTestSuite) SetupTest() {
creds := garmTesting.CreateTestGithubCredentials(adminCtx, "new-creds", db, s.T(), githubEndpoint)
// create an organization for testing purposes
org, err := s.Store.CreateOrganization(s.adminCtx, "test-org", creds.Name, "test-webhookSecret", params.PoolBalancerTypeRoundRobin)
org, err := s.Store.CreateOrganization(s.adminCtx, "test-org", creds, "test-webhookSecret", params.PoolBalancerTypeRoundRobin)
if err != nil {
s.FailNow(fmt.Sprintf("failed to create org: %s", err))
}

View file

@ -29,7 +29,7 @@ import (
"github.com/cloudbase/garm/params"
)
func (s *sqlDatabase) CreateOrganization(ctx context.Context, name, credentialsName, webhookSecret string, poolBalancerType params.PoolBalancerType) (org params.Organization, err error) {
func (s *sqlDatabase) CreateOrganization(ctx context.Context, name string, credentials params.ForgeCredentials, webhookSecret string, poolBalancerType params.PoolBalancerType) (param params.Organization, err error) {
if webhookSecret == "" {
return params.Organization{}, errors.New("creating org: missing secret")
}
@ -40,7 +40,7 @@ func (s *sqlDatabase) CreateOrganization(ctx context.Context, name, credentialsN
defer func() {
if err == nil {
s.sendNotify(common.OrganizationEntityType, common.CreateOperation, org)
s.sendNotify(common.OrganizationEntityType, common.CreateOperation, param)
}
}()
newOrg := Organization{
@ -50,37 +50,37 @@ func (s *sqlDatabase) CreateOrganization(ctx context.Context, name, credentialsN
}
err = s.conn.Transaction(func(tx *gorm.DB) error {
creds, err := s.getGithubCredentialsByName(ctx, tx, credentialsName, false)
if err != nil {
return errors.Wrap(err, "creating org")
switch credentials.ForgeType {
case params.GithubEndpointType:
newOrg.CredentialsID = &credentials.ID
case params.GiteaEndpointType:
newOrg.GiteaCredentialsID = &credentials.ID
default:
return errors.Wrap(runnerErrors.ErrBadRequest, "unsupported credentials type")
}
if creds.EndpointName == nil {
return errors.Wrap(runnerErrors.ErrUnprocessable, "credentials have no endpoint")
}
newOrg.CredentialsID = &creds.ID
newOrg.EndpointName = creds.EndpointName
newOrg.EndpointName = &credentials.Endpoint.Name
q := tx.Create(&newOrg)
if q.Error != nil {
return errors.Wrap(q.Error, "creating org")
}
newOrg.Credentials = creds
newOrg.Endpoint = creds.Endpoint
return nil
})
if err != nil {
return params.Organization{}, errors.Wrap(err, "creating org")
}
org, err = s.sqlToCommonOrganization(newOrg, true)
org, err := s.getOrgByID(ctx, s.conn, newOrg.ID.String(), "Pools", "Endpoint", "Credentials", "GiteaCredentials", "Credentials.Endpoint", "GiteaCredentials.Endpoint")
if err != nil {
return params.Organization{}, errors.Wrap(err, "creating org")
}
org.WebhookSecret = webhookSecret
return org, nil
param, err = s.sqlToCommonOrganization(org, true)
if err != nil {
return params.Organization{}, errors.Wrap(err, "creating org")
}
return param, nil
}
func (s *sqlDatabase) GetOrganization(ctx context.Context, name, endpointName string) (params.Organization, error) {
@ -101,7 +101,9 @@ func (s *sqlDatabase) ListOrganizations(_ context.Context) ([]params.Organizatio
var orgs []Organization
q := s.conn.
Preload("Credentials").
Preload("GiteaCredentials").
Preload("Credentials.Endpoint").
Preload("GiteaCredentials.Endpoint").
Preload("Endpoint").
Find(&orgs)
if q.Error != nil {
@ -121,7 +123,7 @@ func (s *sqlDatabase) ListOrganizations(_ context.Context) ([]params.Organizatio
}
func (s *sqlDatabase) DeleteOrganization(ctx context.Context, orgID string) (err error) {
org, err := s.getOrgByID(ctx, s.conn, orgID, "Endpoint", "Credentials", "Credentials.Endpoint")
org, err := s.getOrgByID(ctx, s.conn, orgID, "Endpoint", "Credentials", "Credentials.Endpoint", "GiteaCredentials", "GiteaCredentials.Endpoint")
if err != nil {
return errors.Wrap(err, "fetching org")
}
@ -201,7 +203,7 @@ func (s *sqlDatabase) UpdateOrganization(ctx context.Context, orgID string, para
return params.Organization{}, errors.Wrap(err, "saving org")
}
org, err = s.getOrgByID(ctx, s.conn, orgID, "Endpoint", "Credentials", "Credentials.Endpoint")
org, err = s.getOrgByID(ctx, s.conn, orgID, "Endpoint", "Credentials", "Credentials.Endpoint", "GiteaCredentials", "GiteaCredentials.Endpoint")
if err != nil {
return params.Organization{}, errors.Wrap(err, "updating enterprise")
}
@ -213,7 +215,7 @@ func (s *sqlDatabase) UpdateOrganization(ctx context.Context, orgID string, para
}
func (s *sqlDatabase) GetOrganizationByID(ctx context.Context, orgID string) (params.Organization, error) {
org, err := s.getOrgByID(ctx, s.conn, orgID, "Pools", "Credentials", "Endpoint", "Credentials.Endpoint")
org, err := s.getOrgByID(ctx, s.conn, orgID, "Pools", "Credentials", "Endpoint", "Credentials.Endpoint", "GiteaCredentials", "GiteaCredentials.Endpoint")
if err != nil {
return params.Organization{}, errors.Wrap(err, "fetching org")
}
@ -254,7 +256,9 @@ func (s *sqlDatabase) getOrg(_ context.Context, name, endpointName string) (Orga
q := s.conn.Where("name = ? COLLATE NOCASE and endpoint_name = ? COLLATE NOCASE", name, endpointName).
Preload("Credentials").
Preload("GiteaCredentials").
Preload("Credentials.Endpoint").
Preload("GiteaCredentials.Endpoint").
Preload("Endpoint").
First(&org)
if q.Error != nil {

View file

@ -100,7 +100,7 @@ func (s *OrgTestSuite) SetupTest() {
org, err := db.CreateOrganization(
s.adminCtx,
fmt.Sprintf("test-org-%d", i),
s.testCreds.Name,
s.testCreds,
fmt.Sprintf("test-webhook-secret-%d", i),
params.PoolBalancerTypeRoundRobin,
)
@ -179,7 +179,7 @@ func (s *OrgTestSuite) TestCreateOrganization() {
org, err := s.Store.CreateOrganization(
s.adminCtx,
s.Fixtures.CreateOrgParams.Name,
s.Fixtures.CreateOrgParams.CredentialsName,
s.testCreds,
s.Fixtures.CreateOrgParams.WebhookSecret,
params.PoolBalancerTypeRoundRobin)
@ -210,7 +210,7 @@ func (s *OrgTestSuite) TestCreateOrganizationInvalidDBPassphrase() {
_, err = sqlDB.CreateOrganization(
s.adminCtx,
s.Fixtures.CreateOrgParams.Name,
s.Fixtures.CreateOrgParams.CredentialsName,
s.testCreds,
s.Fixtures.CreateOrgParams.WebhookSecret,
params.PoolBalancerTypeRoundRobin)
@ -220,15 +220,6 @@ func (s *OrgTestSuite) TestCreateOrganizationInvalidDBPassphrase() {
func (s *OrgTestSuite) TestCreateOrganizationDBCreateErr() {
s.Fixtures.SQLMock.ExpectBegin()
s.Fixtures.SQLMock.
ExpectQuery(regexp.QuoteMeta("SELECT * FROM `github_credentials` WHERE user_id = ? AND name = ? AND `github_credentials`.`deleted_at` IS NULL ORDER BY `github_credentials`.`id` LIMIT ?")).
WithArgs(s.adminUserID, s.Fixtures.Orgs[0].CredentialsName, 1).
WillReturnRows(sqlmock.NewRows([]string{"id", "endpoint_name"}).
AddRow(s.testCreds.ID, s.githubEndpoint.Name))
s.Fixtures.SQLMock.ExpectQuery(regexp.QuoteMeta("SELECT * FROM `github_endpoints` WHERE `github_endpoints`.`name` = ? AND `github_endpoints`.`deleted_at` IS NULL")).
WithArgs(s.testCreds.Endpoint.Name).
WillReturnRows(sqlmock.NewRows([]string{"name"}).
AddRow(s.githubEndpoint.Name))
s.Fixtures.SQLMock.
ExpectExec(regexp.QuoteMeta("INSERT INTO `organizations`")).
WillReturnError(fmt.Errorf("creating org mock error"))
@ -237,7 +228,7 @@ func (s *OrgTestSuite) TestCreateOrganizationDBCreateErr() {
_, err := s.StoreSQLMocked.CreateOrganization(
s.adminCtx,
s.Fixtures.CreateOrgParams.Name,
s.Fixtures.CreateOrgParams.CredentialsName,
s.testCreds,
s.Fixtures.CreateOrgParams.WebhookSecret,
params.PoolBalancerTypeRoundRobin)

View file

@ -81,7 +81,7 @@ func (s *PoolsTestSuite) SetupTest() {
creds := garmTesting.CreateTestGithubCredentials(adminCtx, "new-creds", db, s.T(), githubEndpoint)
// create an organization for testing purposes
org, err := s.Store.CreateOrganization(s.adminCtx, "test-org", creds.Name, "test-webhookSecret", params.PoolBalancerTypeRoundRobin)
org, err := s.Store.CreateOrganization(s.adminCtx, "test-org", creds, "test-webhookSecret", params.PoolBalancerTypeRoundRobin)
if err != nil {
s.FailNow(fmt.Sprintf("failed to create org: %s", err))
}

View file

@ -48,7 +48,7 @@ func (s *ScaleSetsTestSuite) SetupTest() {
s.creds = garmTesting.CreateTestGithubCredentials(adminCtx, "new-creds", db, s.T(), githubEndpoint)
// create an organization for testing purposes
s.org, err = s.Store.CreateOrganization(s.adminCtx, "test-org", s.creds.Name, "test-webhookSecret", params.PoolBalancerTypeRoundRobin)
s.org, err = s.Store.CreateOrganization(s.adminCtx, "test-org", s.creds, "test-webhookSecret", params.PoolBalancerTypeRoundRobin)
if err != nil {
s.FailNow(fmt.Sprintf("failed to create org: %s", err))
}

View file

@ -151,16 +151,24 @@ func (s *sqlDatabase) sqlToCommonOrganization(org Organization, detailed bool) (
UpdatedAt: org.UpdatedAt,
}
var forgeCreds params.ForgeCredentials
if org.CredentialsID != nil {
ret.CredentialsID = *org.CredentialsID
forgeCreds, err = s.sqlToCommonForgeCredentials(org.Credentials)
}
if org.GiteaCredentialsID != nil {
ret.CredentialsID = *org.GiteaCredentialsID
forgeCreds, err = s.sqlGiteaToCommonForgeCredentials(org.GiteaCredentials)
}
if err != nil {
return params.Organization{}, errors.Wrap(err, "converting credentials")
}
if detailed {
creds, err := s.sqlToCommonForgeCredentials(org.Credentials)
if err != nil {
return params.Organization{}, errors.Wrap(err, "converting credentials")
}
ret.Credentials = creds
ret.Credentials = forgeCreds
ret.CredentialsName = forgeCreds.Name
}
if ret.PoolBalancerType == "" {

View file

@ -92,6 +92,14 @@ func WithEntityPoolFilter(ghEntity params.ForgeEntity) dbCommon.PayloadFilterFun
// in pools that belong to it.
func WithEntityScaleSetFilter(ghEntity params.ForgeEntity) dbCommon.PayloadFilterFunc {
return func(payload dbCommon.ChangePayload) bool {
forgeType, err := ghEntity.GetForgeType()
if err != nil {
return false
}
if forgeType != params.GiteaEndpointType {
return false
}
switch payload.EntityType {
case dbCommon.ScaleSetEntityType:
scaleSet, ok := payload.Payload.(params.ScaleSet)

View file

@ -713,7 +713,7 @@ func (s *WatcherStoreTestSuite) TestOrgWatcher() {
creds := garmTesting.CreateTestGithubCredentials(s.ctx, "test-creds", s.store, s.T(), ep)
s.T().Cleanup(func() { s.store.DeleteGithubCredentials(s.ctx, creds.ID) })
org, err := s.store.CreateOrganization(s.ctx, "test-org", creds.Name, "test-secret", params.PoolBalancerTypeRoundRobin)
org, err := s.store.CreateOrganization(s.ctx, "test-org", creds, "test-secret", params.PoolBalancerTypeRoundRobin)
s.Require().NoError(err)
s.Require().NotEmpty(org.ID)