Merge pull request #233 from gabriel-samfira/add-balancing-strategy
Add pool balancing strategy
This commit is contained in:
commit
6bfcddca75
35 changed files with 664 additions and 184 deletions
|
|
@ -57,9 +57,10 @@ var enterpriseAddCmd = &cobra.Command{
|
|||
|
||||
newEnterpriseReq := apiClientEnterprises.NewCreateEnterpriseParams()
|
||||
newEnterpriseReq.Body = params.CreateEnterpriseParams{
|
||||
Name: enterpriseName,
|
||||
WebhookSecret: enterpriseWebhookSecret,
|
||||
CredentialsName: enterpriseCreds,
|
||||
Name: enterpriseName,
|
||||
WebhookSecret: enterpriseWebhookSecret,
|
||||
CredentialsName: enterpriseCreds,
|
||||
PoolBalancerType: params.PoolBalancerType(poolBalancerType),
|
||||
}
|
||||
response, err := apiCli.Enterprises.CreateEnterprise(newEnterpriseReq, authToken)
|
||||
if err != nil {
|
||||
|
|
@ -161,8 +162,9 @@ var enterpriseUpdateCmd = &cobra.Command{
|
|||
}
|
||||
updateEnterpriseReq := apiClientEnterprises.NewUpdateEnterpriseParams()
|
||||
updateEnterpriseReq.Body = params.UpdateEntityParams{
|
||||
WebhookSecret: repoWebhookSecret,
|
||||
CredentialsName: repoCreds,
|
||||
WebhookSecret: repoWebhookSecret,
|
||||
CredentialsName: repoCreds,
|
||||
PoolBalancerType: params.PoolBalancerType(poolBalancerType),
|
||||
}
|
||||
updateEnterpriseReq.EnterpriseID = args[0]
|
||||
response, err := apiCli.Enterprises.UpdateEnterprise(updateEnterpriseReq, authToken)
|
||||
|
|
@ -178,11 +180,13 @@ func init() {
|
|||
enterpriseAddCmd.Flags().StringVar(&enterpriseName, "name", "", "The name of the enterprise")
|
||||
enterpriseAddCmd.Flags().StringVar(&enterpriseWebhookSecret, "webhook-secret", "", "The webhook secret for this enterprise")
|
||||
enterpriseAddCmd.Flags().StringVar(&enterpriseCreds, "credentials", "", "Credentials name. See credentials list.")
|
||||
enterpriseAddCmd.Flags().StringVar(&poolBalancerType, "pool-balancer-type", string(params.PoolBalancerTypeRoundRobin), "The balancing strategy to use when creating runners in pools matching requested labels.")
|
||||
|
||||
enterpriseAddCmd.MarkFlagRequired("credentials") //nolint
|
||||
enterpriseAddCmd.MarkFlagRequired("name") //nolint
|
||||
enterpriseUpdateCmd.Flags().StringVar(&enterpriseWebhookSecret, "webhook-secret", "", "The webhook secret for this enterprise")
|
||||
enterpriseUpdateCmd.Flags().StringVar(&enterpriseCreds, "credentials", "", "Credentials name. See credentials list.")
|
||||
enterpriseUpdateCmd.Flags().StringVar(&poolBalancerType, "pool-balancer-type", "", "The balancing strategy to use when creating runners in pools matching requested labels.")
|
||||
|
||||
enterpriseCmd.AddCommand(
|
||||
enterpriseListCmd,
|
||||
|
|
@ -197,10 +201,10 @@ func init() {
|
|||
|
||||
func formatEnterprises(enterprises []params.Enterprise) {
|
||||
t := table.NewWriter()
|
||||
header := table.Row{"ID", "Name", "Credentials name", "Pool mgr running"}
|
||||
header := table.Row{"ID", "Name", "Credentials name", "Pool Balancer Type", "Pool mgr running"}
|
||||
t.AppendHeader(header)
|
||||
for _, val := range enterprises {
|
||||
t.AppendRow(table.Row{val.ID, val.Name, val.CredentialsName, val.PoolManagerStatus.IsRunning})
|
||||
t.AppendRow(table.Row{val.ID, val.Name, val.CredentialsName, val.GetBalancerType(), val.PoolManagerStatus.IsRunning})
|
||||
t.AppendSeparator()
|
||||
}
|
||||
fmt.Println(t.Render())
|
||||
|
|
@ -213,6 +217,7 @@ func formatOneEnterprise(enterprise params.Enterprise) {
|
|||
t.AppendHeader(header)
|
||||
t.AppendRow(table.Row{"ID", enterprise.ID})
|
||||
t.AppendRow(table.Row{"Name", enterprise.Name})
|
||||
t.AppendRow(table.Row{"Pool balancer type", enterprise.GetBalancerType()})
|
||||
t.AppendRow(table.Row{"Credentials", enterprise.CredentialsName})
|
||||
t.AppendRow(table.Row{"Pool manager running", enterprise.PoolManagerStatus.IsRunning})
|
||||
if !enterprise.PoolManagerStatus.IsRunning {
|
||||
|
|
|
|||
|
|
@ -163,9 +163,10 @@ var orgAddCmd = &cobra.Command{
|
|||
|
||||
newOrgReq := apiClientOrgs.NewCreateOrgParams()
|
||||
newOrgReq.Body = params.CreateOrgParams{
|
||||
Name: orgName,
|
||||
WebhookSecret: orgWebhookSecret,
|
||||
CredentialsName: orgCreds,
|
||||
Name: orgName,
|
||||
WebhookSecret: orgWebhookSecret,
|
||||
CredentialsName: orgCreds,
|
||||
PoolBalancerType: params.PoolBalancerType(poolBalancerType),
|
||||
}
|
||||
response, err := apiCli.Organizations.CreateOrg(newOrgReq, authToken)
|
||||
if err != nil {
|
||||
|
|
@ -213,8 +214,9 @@ var orgUpdateCmd = &cobra.Command{
|
|||
}
|
||||
updateOrgReq := apiClientOrgs.NewUpdateOrgParams()
|
||||
updateOrgReq.Body = params.UpdateEntityParams{
|
||||
WebhookSecret: orgWebhookSecret,
|
||||
CredentialsName: orgCreds,
|
||||
WebhookSecret: orgWebhookSecret,
|
||||
CredentialsName: orgCreds,
|
||||
PoolBalancerType: params.PoolBalancerType(poolBalancerType),
|
||||
}
|
||||
updateOrgReq.OrgID = args[0]
|
||||
response, err := apiCli.Organizations.UpdateOrg(updateOrgReq, authToken)
|
||||
|
|
@ -301,6 +303,7 @@ var orgDeleteCmd = &cobra.Command{
|
|||
|
||||
func init() {
|
||||
orgAddCmd.Flags().StringVar(&orgName, "name", "", "The name of the organization")
|
||||
orgAddCmd.Flags().StringVar(&poolBalancerType, "pool-balancer-type", string(params.PoolBalancerTypeRoundRobin), "The balancing strategy to use when creating runners in pools matching requested labels.")
|
||||
orgAddCmd.Flags().StringVar(&orgWebhookSecret, "webhook-secret", "", "The webhook secret for this organization")
|
||||
orgAddCmd.Flags().StringVar(&orgCreds, "credentials", "", "Credentials name. See credentials list.")
|
||||
orgAddCmd.Flags().BoolVar(&orgRandomWebhookSecret, "random-webhook-secret", false, "Generate a random webhook secret for this organization.")
|
||||
|
|
@ -315,6 +318,7 @@ func init() {
|
|||
|
||||
orgUpdateCmd.Flags().StringVar(&orgWebhookSecret, "webhook-secret", "", "The webhook secret for this organization")
|
||||
orgUpdateCmd.Flags().StringVar(&orgCreds, "credentials", "", "Credentials name. See credentials list.")
|
||||
orgUpdateCmd.Flags().StringVar(&poolBalancerType, "pool-balancer-type", "", "The balancing strategy to use when creating runners in pools matching requested labels.")
|
||||
|
||||
orgWebhookInstallCmd.Flags().BoolVar(&insecureOrgWebhook, "insecure", false, "Ignore self signed certificate errors.")
|
||||
orgWebhookCmd.AddCommand(
|
||||
|
|
@ -337,10 +341,10 @@ func init() {
|
|||
|
||||
func formatOrganizations(orgs []params.Organization) {
|
||||
t := table.NewWriter()
|
||||
header := table.Row{"ID", "Name", "Credentials name", "Pool mgr running"}
|
||||
header := table.Row{"ID", "Name", "Credentials name", "Pool Balancer Type", "Pool mgr running"}
|
||||
t.AppendHeader(header)
|
||||
for _, val := range orgs {
|
||||
t.AppendRow(table.Row{val.ID, val.Name, val.CredentialsName, val.PoolManagerStatus.IsRunning})
|
||||
t.AppendRow(table.Row{val.ID, val.Name, val.CredentialsName, val.GetBalancerType(), val.PoolManagerStatus.IsRunning})
|
||||
t.AppendSeparator()
|
||||
}
|
||||
fmt.Println(t.Render())
|
||||
|
|
@ -353,6 +357,7 @@ func formatOneOrganization(org params.Organization) {
|
|||
t.AppendHeader(header)
|
||||
t.AppendRow(table.Row{"ID", org.ID})
|
||||
t.AppendRow(table.Row{"Name", org.Name})
|
||||
t.AppendRow(table.Row{"Pool balancer type", org.GetBalancerType()})
|
||||
t.AppendRow(table.Row{"Credentials", org.CredentialsName})
|
||||
t.AppendRow(table.Row{"Pool manager running", org.PoolManagerStatus.IsRunning})
|
||||
if !org.PoolManagerStatus.IsRunning {
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ var (
|
|||
poolExtraSpecs string
|
||||
poolAll bool
|
||||
poolGitHubRunnerGroup string
|
||||
priority uint
|
||||
)
|
||||
|
||||
type poolPayloadGetter interface {
|
||||
|
|
@ -218,6 +219,7 @@ var poolAddCmd = &cobra.Command{
|
|||
Enabled: poolEnabled,
|
||||
RunnerBootstrapTimeout: poolRunnerBootstrapTimeout,
|
||||
GitHubRunnerGroup: poolGitHubRunnerGroup,
|
||||
Priority: priority,
|
||||
}
|
||||
|
||||
if cmd.Flags().Changed("extra-specs") {
|
||||
|
|
@ -326,6 +328,9 @@ explicitly remove them using the runner delete command.
|
|||
if cmd.Flags().Changed("max-runners") {
|
||||
poolUpdateParams.MaxRunners = &poolMaxRunners
|
||||
}
|
||||
if cmd.Flags().Changed("priority") {
|
||||
poolUpdateParams.Priority = &priority
|
||||
}
|
||||
|
||||
if cmd.Flags().Changed("min-idle-runners") {
|
||||
poolUpdateParams.MinIdleRunners = &poolMinIdleRunners
|
||||
|
|
@ -385,6 +390,7 @@ func init() {
|
|||
poolListCmd.MarkFlagsMutuallyExclusive("repo", "org", "all", "enterprise")
|
||||
|
||||
poolUpdateCmd.Flags().StringVar(&poolImage, "image", "", "The provider-specific image name to use for runners in this pool.")
|
||||
poolUpdateCmd.Flags().UintVar(&priority, "priority", 0, "When multiple pools match the same labels, priority dictates the order by which they are returned, in descending order.")
|
||||
poolUpdateCmd.Flags().StringVar(&poolFlavor, "flavor", "", "The flavor to use for this runner.")
|
||||
poolUpdateCmd.Flags().StringVar(&poolTags, "tags", "", "A comma separated list of tags to assign to this runner.")
|
||||
poolUpdateCmd.Flags().StringVar(&poolOSType, "os-type", "linux", "Operating system type (windows, linux, etc).")
|
||||
|
|
@ -400,6 +406,7 @@ func init() {
|
|||
poolUpdateCmd.MarkFlagsMutuallyExclusive("extra-specs-file", "extra-specs")
|
||||
|
||||
poolAddCmd.Flags().StringVar(&poolProvider, "provider-name", "", "The name of the provider where runners will be created.")
|
||||
poolAddCmd.Flags().UintVar(&priority, "priority", 0, "When multiple pools match the same labels, priority dictates the order by which they are returned, in descending order.")
|
||||
poolAddCmd.Flags().StringVar(&poolImage, "image", "", "The provider-specific image name to use for runners in this pool.")
|
||||
poolAddCmd.Flags().StringVar(&poolFlavor, "flavor", "", "The flavor to use for this runner.")
|
||||
poolAddCmd.Flags().StringVar(&poolRunnerPrefix, "runner-prefix", "", "The name prefix to use for runners in this pool.")
|
||||
|
|
@ -462,7 +469,7 @@ func asRawMessage(data []byte) (json.RawMessage, error) {
|
|||
|
||||
func formatPools(pools []params.Pool) {
|
||||
t := table.NewWriter()
|
||||
header := table.Row{"ID", "Image", "Flavor", "Tags", "Belongs to", "Level", "Enabled", "Runner Prefix"}
|
||||
header := table.Row{"ID", "Image", "Flavor", "Tags", "Belongs to", "Level", "Enabled", "Runner Prefix", "Priority"}
|
||||
t.AppendHeader(header)
|
||||
|
||||
for _, pool := range pools {
|
||||
|
|
@ -484,7 +491,7 @@ func formatPools(pools []params.Pool) {
|
|||
belongsTo = pool.EnterpriseName
|
||||
level = "enterprise"
|
||||
}
|
||||
t.AppendRow(table.Row{pool.ID, pool.Image, pool.Flavor, strings.Join(tags, " "), belongsTo, level, pool.Enabled, pool.GetRunnerPrefix()})
|
||||
t.AppendRow(table.Row{pool.ID, pool.Image, pool.Flavor, strings.Join(tags, " "), belongsTo, level, pool.Enabled, pool.GetRunnerPrefix(), pool.Priority})
|
||||
t.AppendSeparator()
|
||||
}
|
||||
fmt.Println(t.Render())
|
||||
|
|
@ -519,6 +526,7 @@ func formatOnePool(pool params.Pool) {
|
|||
t.AppendHeader(header)
|
||||
t.AppendRow(table.Row{"ID", pool.ID})
|
||||
t.AppendRow(table.Row{"Provider Name", pool.ProviderName})
|
||||
t.AppendRow(table.Row{"Priority", pool.Priority})
|
||||
t.AppendRow(table.Row{"Image", pool.Image})
|
||||
t.AppendRow(table.Row{"Flavor", pool.Flavor})
|
||||
t.AppendRow(table.Row{"OS Type", pool.OSType})
|
||||
|
|
|
|||
|
|
@ -164,10 +164,11 @@ var repoAddCmd = &cobra.Command{
|
|||
|
||||
newRepoReq := apiClientRepos.NewCreateRepoParams()
|
||||
newRepoReq.Body = params.CreateRepoParams{
|
||||
Owner: repoOwner,
|
||||
Name: repoName,
|
||||
WebhookSecret: repoWebhookSecret,
|
||||
CredentialsName: repoCreds,
|
||||
Owner: repoOwner,
|
||||
Name: repoName,
|
||||
WebhookSecret: repoWebhookSecret,
|
||||
CredentialsName: repoCreds,
|
||||
PoolBalancerType: params.PoolBalancerType(poolBalancerType),
|
||||
}
|
||||
response, err := apiCli.Repositories.CreateRepo(newRepoReq, authToken)
|
||||
if err != nil {
|
||||
|
|
@ -236,8 +237,9 @@ var repoUpdateCmd = &cobra.Command{
|
|||
}
|
||||
updateReposReq := apiClientRepos.NewUpdateRepoParams()
|
||||
updateReposReq.Body = params.UpdateEntityParams{
|
||||
WebhookSecret: repoWebhookSecret,
|
||||
CredentialsName: repoCreds,
|
||||
WebhookSecret: repoWebhookSecret,
|
||||
CredentialsName: repoCreds,
|
||||
PoolBalancerType: params.PoolBalancerType(poolBalancerType),
|
||||
}
|
||||
updateReposReq.RepoID = args[0]
|
||||
|
||||
|
|
@ -304,6 +306,7 @@ var repoDeleteCmd = &cobra.Command{
|
|||
|
||||
func init() {
|
||||
repoAddCmd.Flags().StringVar(&repoOwner, "owner", "", "The owner of this repository")
|
||||
repoAddCmd.Flags().StringVar(&poolBalancerType, "pool-balancer-type", string(params.PoolBalancerTypeRoundRobin), "The balancing strategy to use when creating runners in pools matching requested labels.")
|
||||
repoAddCmd.Flags().StringVar(&repoName, "name", "", "The name of the repository")
|
||||
repoAddCmd.Flags().StringVar(&repoWebhookSecret, "webhook-secret", "", "The webhook secret for this repository")
|
||||
repoAddCmd.Flags().StringVar(&repoCreds, "credentials", "", "Credentials name. See credentials list.")
|
||||
|
|
@ -320,6 +323,7 @@ func init() {
|
|||
|
||||
repoUpdateCmd.Flags().StringVar(&repoWebhookSecret, "webhook-secret", "", "The webhook secret for this repository. If you update this secret, you will have to manually update the secret in GitHub as well.")
|
||||
repoUpdateCmd.Flags().StringVar(&repoCreds, "credentials", "", "Credentials name. See credentials list.")
|
||||
repoUpdateCmd.Flags().StringVar(&poolBalancerType, "pool-balancer-type", "", "The balancing strategy to use when creating runners in pools matching requested labels.")
|
||||
|
||||
repoWebhookInstallCmd.Flags().BoolVar(&insecureRepoWebhook, "insecure", false, "Ignore self signed certificate errors.")
|
||||
|
||||
|
|
@ -343,10 +347,10 @@ func init() {
|
|||
|
||||
func formatRepositories(repos []params.Repository) {
|
||||
t := table.NewWriter()
|
||||
header := table.Row{"ID", "Owner", "Name", "Credentials name", "Pool mgr running"}
|
||||
header := table.Row{"ID", "Owner", "Name", "Credentials name", "Pool Balancer Type", "Pool mgr running"}
|
||||
t.AppendHeader(header)
|
||||
for _, val := range repos {
|
||||
t.AppendRow(table.Row{val.ID, val.Owner, val.Name, val.CredentialsName, val.PoolManagerStatus.IsRunning})
|
||||
t.AppendRow(table.Row{val.ID, val.Owner, val.Name, val.CredentialsName, val.GetBalancerType(), val.PoolManagerStatus.IsRunning})
|
||||
t.AppendSeparator()
|
||||
}
|
||||
fmt.Println(t.Render())
|
||||
|
|
@ -360,6 +364,7 @@ func formatOneRepository(repo params.Repository) {
|
|||
t.AppendRow(table.Row{"ID", repo.ID})
|
||||
t.AppendRow(table.Row{"Owner", repo.Owner})
|
||||
t.AppendRow(table.Row{"Name", repo.Name})
|
||||
t.AppendRow(table.Row{"Pool balancer type", repo.GetBalancerType()})
|
||||
t.AppendRow(table.Row{"Credentials", repo.CredentialsName})
|
||||
t.AppendRow(table.Row{"Pool manager running", repo.PoolManagerStatus.IsRunning})
|
||||
if !repo.PoolManagerStatus.IsRunning {
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ var (
|
|||
authToken runtime.ClientAuthInfoWriter
|
||||
needsInit bool
|
||||
debug bool
|
||||
poolBalancerType string
|
||||
errNeedsInitError = fmt.Errorf("please log into a garm installation first")
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import (
|
|||
)
|
||||
|
||||
type RepoStore interface {
|
||||
CreateRepository(ctx context.Context, owner, name, credentialsName, webhookSecret string) (params.Repository, error)
|
||||
CreateRepository(ctx context.Context, owner, name, credentialsName, webhookSecret string, poolBalancerType params.PoolBalancerType) (params.Repository, error)
|
||||
GetRepository(ctx context.Context, owner, name string) (params.Repository, error)
|
||||
GetRepositoryByID(ctx context.Context, repoID string) (params.Repository, error)
|
||||
ListRepositories(ctx context.Context) ([]params.Repository, error)
|
||||
|
|
@ -40,7 +40,7 @@ type RepoStore interface {
|
|||
}
|
||||
|
||||
type OrgStore interface {
|
||||
CreateOrganization(ctx context.Context, name, credentialsName, webhookSecret string) (params.Organization, error)
|
||||
CreateOrganization(ctx context.Context, name, credentialsName, webhookSecret string, poolBalancerType params.PoolBalancerType) (params.Organization, error)
|
||||
GetOrganization(ctx context.Context, name string) (params.Organization, error)
|
||||
GetOrganizationByID(ctx context.Context, orgID string) (params.Organization, error)
|
||||
ListOrganizations(ctx context.Context) ([]params.Organization, error)
|
||||
|
|
@ -58,7 +58,7 @@ type OrgStore interface {
|
|||
}
|
||||
|
||||
type EnterpriseStore interface {
|
||||
CreateEnterprise(ctx context.Context, name, credentialsName, webhookSecret string) (params.Enterprise, error)
|
||||
CreateEnterprise(ctx context.Context, name, credentialsName, webhookSecret string, poolBalancerType params.PoolBalancerType) (params.Enterprise, error)
|
||||
GetEnterprise(ctx context.Context, name string) (params.Enterprise, error)
|
||||
GetEnterpriseByID(ctx context.Context, enterpriseID string) (params.Enterprise, error)
|
||||
ListEnterprises(ctx context.Context) ([]params.Enterprise, error)
|
||||
|
|
|
|||
|
|
@ -78,9 +78,9 @@ func (_m *Store) ControllerInfo() (params.ControllerInfo, error) {
|
|||
return r0, r1
|
||||
}
|
||||
|
||||
// CreateEnterprise provides a mock function with given fields: ctx, name, credentialsName, webhookSecret
|
||||
func (_m *Store) CreateEnterprise(ctx context.Context, name string, credentialsName string, webhookSecret string) (params.Enterprise, error) {
|
||||
ret := _m.Called(ctx, name, credentialsName, webhookSecret)
|
||||
// CreateEnterprise provides a mock function with given fields: ctx, name, credentialsName, webhookSecret, poolBalancerType
|
||||
func (_m *Store) CreateEnterprise(ctx context.Context, name string, credentialsName string, webhookSecret string, poolBalancerType params.PoolBalancerType) (params.Enterprise, error) {
|
||||
ret := _m.Called(ctx, name, credentialsName, webhookSecret, poolBalancerType)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for CreateEnterprise")
|
||||
|
|
@ -88,17 +88,17 @@ func (_m *Store) CreateEnterprise(ctx context.Context, name string, credentialsN
|
|||
|
||||
var r0 params.Enterprise
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, string, string) (params.Enterprise, error)); ok {
|
||||
return rf(ctx, name, credentialsName, webhookSecret)
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, string, string, params.PoolBalancerType) (params.Enterprise, error)); ok {
|
||||
return rf(ctx, name, credentialsName, webhookSecret, poolBalancerType)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, string, string) params.Enterprise); ok {
|
||||
r0 = rf(ctx, name, credentialsName, webhookSecret)
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, string, string, params.PoolBalancerType) params.Enterprise); ok {
|
||||
r0 = rf(ctx, name, credentialsName, webhookSecret, poolBalancerType)
|
||||
} else {
|
||||
r0 = ret.Get(0).(params.Enterprise)
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, string, string, string) error); ok {
|
||||
r1 = rf(ctx, name, credentialsName, webhookSecret)
|
||||
if rf, ok := ret.Get(1).(func(context.Context, string, string, string, params.PoolBalancerType) error); ok {
|
||||
r1 = rf(ctx, name, credentialsName, webhookSecret, poolBalancerType)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
|
@ -190,9 +190,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
|
||||
func (_m *Store) CreateOrganization(ctx context.Context, name string, credentialsName string, webhookSecret string) (params.Organization, error) {
|
||||
ret := _m.Called(ctx, name, credentialsName, webhookSecret)
|
||||
// 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)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for CreateOrganization")
|
||||
|
|
@ -200,17 +200,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.Organization, error)); ok {
|
||||
return rf(ctx, name, credentialsName, webhookSecret)
|
||||
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, string, string) params.Organization); ok {
|
||||
r0 = rf(ctx, name, credentialsName, webhookSecret)
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, string, string, params.PoolBalancerType) params.Organization); ok {
|
||||
r0 = rf(ctx, name, credentialsName, webhookSecret, poolBalancerType)
|
||||
} else {
|
||||
r0 = ret.Get(0).(params.Organization)
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, string, string, string) error); ok {
|
||||
r1 = rf(ctx, name, credentialsName, webhookSecret)
|
||||
if rf, ok := ret.Get(1).(func(context.Context, string, string, string, params.PoolBalancerType) error); ok {
|
||||
r1 = rf(ctx, name, credentialsName, webhookSecret, poolBalancerType)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
|
@ -246,9 +246,9 @@ func (_m *Store) CreateOrganizationPool(ctx context.Context, orgID string, param
|
|||
return r0, r1
|
||||
}
|
||||
|
||||
// CreateRepository provides a mock function with given fields: ctx, owner, name, credentialsName, webhookSecret
|
||||
func (_m *Store) CreateRepository(ctx context.Context, owner string, name string, credentialsName string, webhookSecret string) (params.Repository, error) {
|
||||
ret := _m.Called(ctx, owner, name, credentialsName, webhookSecret)
|
||||
// CreateRepository provides a mock function with given fields: ctx, owner, name, credentialsName, webhookSecret, poolBalancerType
|
||||
func (_m *Store) CreateRepository(ctx context.Context, owner string, name string, credentialsName string, webhookSecret string, poolBalancerType params.PoolBalancerType) (params.Repository, error) {
|
||||
ret := _m.Called(ctx, owner, name, credentialsName, webhookSecret, poolBalancerType)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for CreateRepository")
|
||||
|
|
@ -256,17 +256,17 @@ func (_m *Store) CreateRepository(ctx context.Context, owner string, name string
|
|||
|
||||
var r0 params.Repository
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, string, string, string) (params.Repository, error)); ok {
|
||||
return rf(ctx, owner, name, credentialsName, webhookSecret)
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, string, string, string, params.PoolBalancerType) (params.Repository, error)); ok {
|
||||
return rf(ctx, owner, name, credentialsName, webhookSecret, poolBalancerType)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, string, string, string) params.Repository); ok {
|
||||
r0 = rf(ctx, owner, name, credentialsName, webhookSecret)
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, string, string, string, params.PoolBalancerType) params.Repository); ok {
|
||||
r0 = rf(ctx, owner, name, credentialsName, webhookSecret, poolBalancerType)
|
||||
} else {
|
||||
r0 = ret.Get(0).(params.Repository)
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, string, string, string, string) error); ok {
|
||||
r1 = rf(ctx, owner, name, credentialsName, webhookSecret)
|
||||
if rf, ok := ret.Get(1).(func(context.Context, string, string, string, string, params.PoolBalancerType) error); ok {
|
||||
r1 = rf(ctx, owner, name, credentialsName, webhookSecret, poolBalancerType)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import (
|
|||
"github.com/cloudbase/garm/params"
|
||||
)
|
||||
|
||||
func (s *sqlDatabase) CreateEnterprise(_ context.Context, name, credentialsName, webhookSecret string) (params.Enterprise, error) {
|
||||
func (s *sqlDatabase) CreateEnterprise(_ context.Context, name, credentialsName, webhookSecret string, poolBalancerType params.PoolBalancerType) (params.Enterprise, error) {
|
||||
if webhookSecret == "" {
|
||||
return params.Enterprise{}, errors.New("creating enterprise: missing secret")
|
||||
}
|
||||
|
|
@ -22,9 +22,10 @@ func (s *sqlDatabase) CreateEnterprise(_ context.Context, name, credentialsName,
|
|||
return params.Enterprise{}, errors.Wrap(err, "encoding secret")
|
||||
}
|
||||
newEnterprise := Enterprise{
|
||||
Name: name,
|
||||
WebhookSecret: secret,
|
||||
CredentialsName: credentialsName,
|
||||
Name: name,
|
||||
WebhookSecret: secret,
|
||||
CredentialsName: credentialsName,
|
||||
PoolBalancerType: poolBalancerType,
|
||||
}
|
||||
|
||||
q := s.conn.Create(&newEnterprise)
|
||||
|
|
@ -117,6 +118,10 @@ func (s *sqlDatabase) UpdateEnterprise(ctx context.Context, enterpriseID string,
|
|||
enterprise.WebhookSecret = secret
|
||||
}
|
||||
|
||||
if param.PoolBalancerType != "" {
|
||||
enterprise.PoolBalancerType = param.PoolBalancerType
|
||||
}
|
||||
|
||||
q := s.conn.Save(&enterprise)
|
||||
if q.Error != nil {
|
||||
return params.Enterprise{}, errors.Wrap(q.Error, "saving enterprise")
|
||||
|
|
@ -152,6 +157,7 @@ func (s *sqlDatabase) CreateEnterprisePool(ctx context.Context, enterpriseID str
|
|||
Enabled: param.Enabled,
|
||||
RunnerBootstrapTimeout: param.RunnerBootstrapTimeout,
|
||||
GitHubRunnerGroup: param.GitHubRunnerGroup,
|
||||
Priority: param.Priority,
|
||||
}
|
||||
|
||||
if len(param.ExtraSpecs) > 0 {
|
||||
|
|
@ -233,7 +239,7 @@ func (s *sqlDatabase) FindEnterprisePoolByTags(_ context.Context, enterpriseID s
|
|||
}
|
||||
|
||||
func (s *sqlDatabase) ListEnterprisePools(ctx context.Context, enterpriseID string) ([]params.Pool, error) {
|
||||
pools, err := s.listEntityPools(ctx, params.EnterprisePool, enterpriseID, "Tags", "Instances", "Instances.Job")
|
||||
pools, err := s.listEntityPools(ctx, params.EnterprisePool, enterpriseID, "Tags", "Instances", "Enterprise")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "fetching pools")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ func (s *EnterpriseTestSuite) SetupTest() {
|
|||
fmt.Sprintf("test-enterprise-%d", i),
|
||||
fmt.Sprintf("test-creds-%d", i),
|
||||
fmt.Sprintf("test-webhook-secret-%d", i),
|
||||
params.PoolBalancerTypeRoundRobin,
|
||||
)
|
||||
if err != nil {
|
||||
s.FailNow(fmt.Sprintf("failed to create database object (test-enterprise-%d)", i))
|
||||
|
|
@ -162,7 +163,8 @@ func (s *EnterpriseTestSuite) TestCreateEnterprise() {
|
|||
context.Background(),
|
||||
s.Fixtures.CreateEnterpriseParams.Name,
|
||||
s.Fixtures.CreateEnterpriseParams.CredentialsName,
|
||||
s.Fixtures.CreateEnterpriseParams.WebhookSecret)
|
||||
s.Fixtures.CreateEnterpriseParams.WebhookSecret,
|
||||
params.PoolBalancerTypeRoundRobin)
|
||||
|
||||
// assertions
|
||||
s.Require().Nil(err)
|
||||
|
|
@ -192,7 +194,8 @@ func (s *EnterpriseTestSuite) TestCreateEnterpriseInvalidDBPassphrase() {
|
|||
context.Background(),
|
||||
s.Fixtures.CreateEnterpriseParams.Name,
|
||||
s.Fixtures.CreateEnterpriseParams.CredentialsName,
|
||||
s.Fixtures.CreateEnterpriseParams.WebhookSecret)
|
||||
s.Fixtures.CreateEnterpriseParams.WebhookSecret,
|
||||
params.PoolBalancerTypeRoundRobin)
|
||||
|
||||
s.Require().NotNil(err)
|
||||
s.Require().Equal("encoding secret: invalid passphrase length (expected length 32 characters)", err.Error())
|
||||
|
|
@ -209,7 +212,8 @@ func (s *EnterpriseTestSuite) TestCreateEnterpriseDBCreateErr() {
|
|||
context.Background(),
|
||||
s.Fixtures.CreateEnterpriseParams.Name,
|
||||
s.Fixtures.CreateEnterpriseParams.CredentialsName,
|
||||
s.Fixtures.CreateEnterpriseParams.WebhookSecret)
|
||||
s.Fixtures.CreateEnterpriseParams.WebhookSecret,
|
||||
params.PoolBalancerTypeRoundRobin)
|
||||
|
||||
s.assertSQLMockExpectations()
|
||||
s.Require().NotNil(err)
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ func (s *InstancesTestSuite) SetupTest() {
|
|||
s.Store = db
|
||||
|
||||
// create an organization for testing purposes
|
||||
org, err := s.Store.CreateOrganization(context.Background(), "test-org", "test-creds", "test-webhookSecret")
|
||||
org, err := s.Store.CreateOrganization(context.Background(), "test-org", "test-creds", "test-webhookSecret", params.PoolBalancerTypeRoundRobin)
|
||||
if err != nil {
|
||||
s.FailNow(fmt.Sprintf("failed to create org: %s", err))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,37 +83,41 @@ type Pool struct {
|
|||
Enterprise Enterprise `gorm:"foreignKey:EnterpriseID"`
|
||||
|
||||
Instances []Instance `gorm:"foreignKey:PoolID"`
|
||||
Priority uint `gorm:"index:idx_pool_priority"`
|
||||
}
|
||||
|
||||
type Repository struct {
|
||||
Base
|
||||
|
||||
CredentialsName string
|
||||
Owner string `gorm:"index:idx_owner_nocase,unique,collate:nocase"`
|
||||
Name string `gorm:"index:idx_owner_nocase,unique,collate:nocase"`
|
||||
WebhookSecret []byte
|
||||
Pools []Pool `gorm:"foreignKey:RepoID"`
|
||||
Jobs []WorkflowJob `gorm:"foreignKey:RepoID;constraint:OnDelete:SET NULL"`
|
||||
CredentialsName string
|
||||
Owner string `gorm:"index:idx_owner_nocase,unique,collate:nocase"`
|
||||
Name string `gorm:"index:idx_owner_nocase,unique,collate:nocase"`
|
||||
WebhookSecret []byte
|
||||
Pools []Pool `gorm:"foreignKey:RepoID"`
|
||||
Jobs []WorkflowJob `gorm:"foreignKey:RepoID;constraint:OnDelete:SET NULL"`
|
||||
PoolBalancerType params.PoolBalancerType `gorm:"type:varchar(64)"`
|
||||
}
|
||||
|
||||
type Organization struct {
|
||||
Base
|
||||
|
||||
CredentialsName string
|
||||
Name string `gorm:"index:idx_org_name_nocase,collate:nocase"`
|
||||
WebhookSecret []byte
|
||||
Pools []Pool `gorm:"foreignKey:OrgID"`
|
||||
Jobs []WorkflowJob `gorm:"foreignKey:OrgID;constraint:OnDelete:SET NULL"`
|
||||
CredentialsName string
|
||||
Name string `gorm:"index:idx_org_name_nocase,collate:nocase"`
|
||||
WebhookSecret []byte
|
||||
Pools []Pool `gorm:"foreignKey:OrgID"`
|
||||
Jobs []WorkflowJob `gorm:"foreignKey:OrgID;constraint:OnDelete:SET NULL"`
|
||||
PoolBalancerType params.PoolBalancerType `gorm:"type:varchar(64)"`
|
||||
}
|
||||
|
||||
type Enterprise struct {
|
||||
Base
|
||||
|
||||
CredentialsName string
|
||||
Name string `gorm:"index:idx_ent_name_nocase,collate:nocase"`
|
||||
WebhookSecret []byte
|
||||
Pools []Pool `gorm:"foreignKey:EnterpriseID"`
|
||||
Jobs []WorkflowJob `gorm:"foreignKey:EnterpriseID;constraint:OnDelete:SET NULL"`
|
||||
CredentialsName string
|
||||
Name string `gorm:"index:idx_ent_name_nocase,collate:nocase"`
|
||||
WebhookSecret []byte
|
||||
Pools []Pool `gorm:"foreignKey:EnterpriseID"`
|
||||
Jobs []WorkflowJob `gorm:"foreignKey:EnterpriseID;constraint:OnDelete:SET NULL"`
|
||||
PoolBalancerType params.PoolBalancerType `gorm:"type:varchar(64)"`
|
||||
}
|
||||
|
||||
type Address struct {
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ import (
|
|||
"github.com/cloudbase/garm/params"
|
||||
)
|
||||
|
||||
func (s *sqlDatabase) CreateOrganization(_ context.Context, name, credentialsName, webhookSecret string) (params.Organization, error) {
|
||||
func (s *sqlDatabase) CreateOrganization(_ context.Context, name, credentialsName, webhookSecret string, poolBalancerType params.PoolBalancerType) (params.Organization, error) {
|
||||
if webhookSecret == "" {
|
||||
return params.Organization{}, errors.New("creating org: missing secret")
|
||||
}
|
||||
|
|
@ -37,9 +37,10 @@ func (s *sqlDatabase) CreateOrganization(_ context.Context, name, credentialsNam
|
|||
return params.Organization{}, fmt.Errorf("failed to encrypt string")
|
||||
}
|
||||
newOrg := Organization{
|
||||
Name: name,
|
||||
WebhookSecret: secret,
|
||||
CredentialsName: credentialsName,
|
||||
Name: name,
|
||||
WebhookSecret: secret,
|
||||
CredentialsName: credentialsName,
|
||||
PoolBalancerType: poolBalancerType,
|
||||
}
|
||||
|
||||
q := s.conn.Create(&newOrg)
|
||||
|
|
@ -121,6 +122,10 @@ func (s *sqlDatabase) UpdateOrganization(ctx context.Context, orgID string, para
|
|||
org.WebhookSecret = secret
|
||||
}
|
||||
|
||||
if param.PoolBalancerType != "" {
|
||||
org.PoolBalancerType = param.PoolBalancerType
|
||||
}
|
||||
|
||||
q := s.conn.Save(&org)
|
||||
if q.Error != nil {
|
||||
return params.Organization{}, errors.Wrap(q.Error, "saving org")
|
||||
|
|
@ -169,6 +174,7 @@ func (s *sqlDatabase) CreateOrganizationPool(ctx context.Context, orgID string,
|
|||
Enabled: param.Enabled,
|
||||
RunnerBootstrapTimeout: param.RunnerBootstrapTimeout,
|
||||
GitHubRunnerGroup: param.GitHubRunnerGroup,
|
||||
Priority: param.Priority,
|
||||
}
|
||||
|
||||
if len(param.ExtraSpecs) > 0 {
|
||||
|
|
@ -213,7 +219,7 @@ func (s *sqlDatabase) CreateOrganizationPool(ctx context.Context, orgID string,
|
|||
}
|
||||
|
||||
func (s *sqlDatabase) ListOrgPools(ctx context.Context, orgID string) ([]params.Pool, error) {
|
||||
pools, err := s.listEntityPools(ctx, params.OrganizationPool, orgID, "Tags", "Instances")
|
||||
pools, err := s.listEntityPools(ctx, params.OrganizationPool, orgID, "Tags", "Instances", "Organization")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "fetching pools")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ func (s *OrgTestSuite) SetupTest() {
|
|||
fmt.Sprintf("test-org-%d", i),
|
||||
fmt.Sprintf("test-creds-%d", i),
|
||||
fmt.Sprintf("test-webhook-secret-%d", i),
|
||||
params.PoolBalancerTypeRoundRobin,
|
||||
)
|
||||
if err != nil {
|
||||
s.FailNow(fmt.Sprintf("failed to create database object (test-org-%d)", i))
|
||||
|
|
@ -162,7 +163,8 @@ func (s *OrgTestSuite) TestCreateOrganization() {
|
|||
context.Background(),
|
||||
s.Fixtures.CreateOrgParams.Name,
|
||||
s.Fixtures.CreateOrgParams.CredentialsName,
|
||||
s.Fixtures.CreateOrgParams.WebhookSecret)
|
||||
s.Fixtures.CreateOrgParams.WebhookSecret,
|
||||
params.PoolBalancerTypeRoundRobin)
|
||||
|
||||
// assertions
|
||||
s.Require().Nil(err)
|
||||
|
|
@ -192,7 +194,8 @@ func (s *OrgTestSuite) TestCreateOrganizationInvalidDBPassphrase() {
|
|||
context.Background(),
|
||||
s.Fixtures.CreateOrgParams.Name,
|
||||
s.Fixtures.CreateOrgParams.CredentialsName,
|
||||
s.Fixtures.CreateOrgParams.WebhookSecret)
|
||||
s.Fixtures.CreateOrgParams.WebhookSecret,
|
||||
params.PoolBalancerTypeRoundRobin)
|
||||
|
||||
s.Require().NotNil(err)
|
||||
s.Require().Equal("failed to encrypt string", err.Error())
|
||||
|
|
@ -209,7 +212,8 @@ func (s *OrgTestSuite) TestCreateOrganizationDBCreateErr() {
|
|||
context.Background(),
|
||||
s.Fixtures.CreateOrgParams.Name,
|
||||
s.Fixtures.CreateOrgParams.CredentialsName,
|
||||
s.Fixtures.CreateOrgParams.WebhookSecret)
|
||||
s.Fixtures.CreateOrgParams.WebhookSecret,
|
||||
params.PoolBalancerTypeRoundRobin)
|
||||
|
||||
s.assertSQLMockExpectations()
|
||||
s.Require().NotNil(err)
|
||||
|
|
|
|||
|
|
@ -190,7 +190,9 @@ func (s *sqlDatabase) findPoolByTags(id string, poolType params.PoolType, tags [
|
|||
Group("pools.id").
|
||||
Preload("Tags").
|
||||
Having("count(1) = ?", len(tags)).
|
||||
Where(where, tags, u).Find(&pools)
|
||||
Where(where, tags, u).
|
||||
Order("priority desc").
|
||||
Find(&pools)
|
||||
|
||||
if q.Error != nil {
|
||||
if errors.Is(q.Error, gorm.ErrRecordNotFound) {
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ func (s *PoolsTestSuite) SetupTest() {
|
|||
s.Store = db
|
||||
|
||||
// create an organization for testing purposes
|
||||
org, err := s.Store.CreateOrganization(context.Background(), "test-org", "test-creds", "test-webhookSecret")
|
||||
org, err := s.Store.CreateOrganization(context.Background(), "test-org", "test-creds", "test-webhookSecret", params.PoolBalancerTypeRoundRobin)
|
||||
if err != nil {
|
||||
s.FailNow(fmt.Sprintf("failed to create org: %s", err))
|
||||
}
|
||||
|
|
@ -128,7 +128,7 @@ func (s *PoolsTestSuite) TestListAllPools() {
|
|||
|
||||
func (s *PoolsTestSuite) TestListAllPoolsDBFetchErr() {
|
||||
s.Fixtures.SQLMock.
|
||||
ExpectQuery(regexp.QuoteMeta("SELECT `pools`.`id`,`pools`.`created_at`,`pools`.`updated_at`,`pools`.`deleted_at`,`pools`.`provider_name`,`pools`.`runner_prefix`,`pools`.`max_runners`,`pools`.`min_idle_runners`,`pools`.`runner_bootstrap_timeout`,`pools`.`image`,`pools`.`flavor`,`pools`.`os_type`,`pools`.`os_arch`,`pools`.`enabled`,`pools`.`git_hub_runner_group`,`pools`.`repo_id`,`pools`.`org_id`,`pools`.`enterprise_id` FROM `pools` WHERE `pools`.`deleted_at` IS NULL")).
|
||||
ExpectQuery(regexp.QuoteMeta("SELECT `pools`.`id`,`pools`.`created_at`,`pools`.`updated_at`,`pools`.`deleted_at`,`pools`.`provider_name`,`pools`.`runner_prefix`,`pools`.`max_runners`,`pools`.`min_idle_runners`,`pools`.`runner_bootstrap_timeout`,`pools`.`image`,`pools`.`flavor`,`pools`.`os_type`,`pools`.`os_arch`,`pools`.`enabled`,`pools`.`git_hub_runner_group`,`pools`.`repo_id`,`pools`.`org_id`,`pools`.`enterprise_id`,`pools`.`priority` FROM `pools` WHERE `pools`.`deleted_at` IS NULL")).
|
||||
WillReturnError(fmt.Errorf("mocked fetching all pools error"))
|
||||
|
||||
_, err := s.StoreSQLMocked.ListAllPools(context.Background())
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ import (
|
|||
"github.com/cloudbase/garm/params"
|
||||
)
|
||||
|
||||
func (s *sqlDatabase) CreateRepository(_ context.Context, owner, name, credentialsName, webhookSecret string) (params.Repository, error) {
|
||||
func (s *sqlDatabase) CreateRepository(_ context.Context, owner, name, credentialsName, webhookSecret string, poolBalancerType params.PoolBalancerType) (params.Repository, error) {
|
||||
if webhookSecret == "" {
|
||||
return params.Repository{}, errors.New("creating repo: missing secret")
|
||||
}
|
||||
|
|
@ -37,10 +37,11 @@ func (s *sqlDatabase) CreateRepository(_ context.Context, owner, name, credentia
|
|||
return params.Repository{}, fmt.Errorf("failed to encrypt string")
|
||||
}
|
||||
newRepo := Repository{
|
||||
Name: name,
|
||||
Owner: owner,
|
||||
WebhookSecret: secret,
|
||||
CredentialsName: credentialsName,
|
||||
Name: name,
|
||||
Owner: owner,
|
||||
WebhookSecret: secret,
|
||||
CredentialsName: credentialsName,
|
||||
PoolBalancerType: poolBalancerType,
|
||||
}
|
||||
|
||||
q := s.conn.Create(&newRepo)
|
||||
|
|
@ -121,6 +122,10 @@ func (s *sqlDatabase) UpdateRepository(ctx context.Context, repoID string, param
|
|||
repo.WebhookSecret = secret
|
||||
}
|
||||
|
||||
if param.PoolBalancerType != "" {
|
||||
repo.PoolBalancerType = param.PoolBalancerType
|
||||
}
|
||||
|
||||
q := s.conn.Save(&repo)
|
||||
if q.Error != nil {
|
||||
return params.Repository{}, errors.Wrap(q.Error, "saving repo")
|
||||
|
|
@ -169,6 +174,7 @@ func (s *sqlDatabase) CreateRepositoryPool(ctx context.Context, repoID string, p
|
|||
Enabled: param.Enabled,
|
||||
RunnerBootstrapTimeout: param.RunnerBootstrapTimeout,
|
||||
GitHubRunnerGroup: param.GitHubRunnerGroup,
|
||||
Priority: param.Priority,
|
||||
}
|
||||
|
||||
if len(param.ExtraSpecs) > 0 {
|
||||
|
|
@ -213,7 +219,7 @@ func (s *sqlDatabase) CreateRepositoryPool(ctx context.Context, repoID string, p
|
|||
}
|
||||
|
||||
func (s *sqlDatabase) ListRepoPools(ctx context.Context, repoID string) ([]params.Pool, error) {
|
||||
pools, err := s.listEntityPools(ctx, params.RepositoryPool, repoID, "Tags", "Instances")
|
||||
pools, err := s.listEntityPools(ctx, params.RepositoryPool, repoID, "Tags", "Instances", "Repository")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "fetching pools")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ func (s *RepoTestSuite) SetupTest() {
|
|||
fmt.Sprintf("test-repo-%d", i),
|
||||
fmt.Sprintf("test-creds-%d", i),
|
||||
fmt.Sprintf("test-webhook-secret-%d", i),
|
||||
params.PoolBalancerTypeRoundRobin,
|
||||
)
|
||||
if err != nil {
|
||||
s.FailNow(fmt.Sprintf("failed to create database object (test-repo-%d): %v", i, err))
|
||||
|
|
@ -176,6 +177,7 @@ func (s *RepoTestSuite) TestCreateRepository() {
|
|||
s.Fixtures.CreateRepoParams.Name,
|
||||
s.Fixtures.CreateRepoParams.CredentialsName,
|
||||
s.Fixtures.CreateRepoParams.WebhookSecret,
|
||||
params.PoolBalancerTypeRoundRobin,
|
||||
)
|
||||
|
||||
// assertions
|
||||
|
|
@ -209,6 +211,7 @@ func (s *RepoTestSuite) TestCreateRepositoryInvalidDBPassphrase() {
|
|||
s.Fixtures.CreateRepoParams.Name,
|
||||
s.Fixtures.CreateRepoParams.CredentialsName,
|
||||
s.Fixtures.CreateRepoParams.WebhookSecret,
|
||||
params.PoolBalancerTypeRoundRobin,
|
||||
)
|
||||
|
||||
s.Require().NotNil(err)
|
||||
|
|
@ -228,6 +231,7 @@ func (s *RepoTestSuite) TestCreateRepositoryInvalidDBCreateErr() {
|
|||
s.Fixtures.CreateRepoParams.Name,
|
||||
s.Fixtures.CreateRepoParams.CredentialsName,
|
||||
s.Fixtures.CreateRepoParams.WebhookSecret,
|
||||
params.PoolBalancerTypeRoundRobin,
|
||||
)
|
||||
|
||||
s.assertSQLMockExpectations()
|
||||
|
|
|
|||
|
|
@ -113,11 +113,16 @@ func (s *sqlDatabase) sqlToCommonOrganization(org Organization) (params.Organiza
|
|||
}
|
||||
|
||||
ret := params.Organization{
|
||||
ID: org.ID.String(),
|
||||
Name: org.Name,
|
||||
CredentialsName: org.CredentialsName,
|
||||
Pools: make([]params.Pool, len(org.Pools)),
|
||||
WebhookSecret: string(secret),
|
||||
ID: org.ID.String(),
|
||||
Name: org.Name,
|
||||
CredentialsName: org.CredentialsName,
|
||||
Pools: make([]params.Pool, len(org.Pools)),
|
||||
WebhookSecret: string(secret),
|
||||
PoolBalancerType: org.PoolBalancerType,
|
||||
}
|
||||
|
||||
if ret.PoolBalancerType == "" {
|
||||
ret.PoolBalancerType = params.PoolBalancerTypeRoundRobin
|
||||
}
|
||||
|
||||
for idx, pool := range org.Pools {
|
||||
|
|
@ -140,11 +145,16 @@ func (s *sqlDatabase) sqlToCommonEnterprise(enterprise Enterprise) (params.Enter
|
|||
}
|
||||
|
||||
ret := params.Enterprise{
|
||||
ID: enterprise.ID.String(),
|
||||
Name: enterprise.Name,
|
||||
CredentialsName: enterprise.CredentialsName,
|
||||
Pools: make([]params.Pool, len(enterprise.Pools)),
|
||||
WebhookSecret: string(secret),
|
||||
ID: enterprise.ID.String(),
|
||||
Name: enterprise.Name,
|
||||
CredentialsName: enterprise.CredentialsName,
|
||||
Pools: make([]params.Pool, len(enterprise.Pools)),
|
||||
WebhookSecret: string(secret),
|
||||
PoolBalancerType: enterprise.PoolBalancerType,
|
||||
}
|
||||
|
||||
if ret.PoolBalancerType == "" {
|
||||
ret.PoolBalancerType = params.PoolBalancerTypeRoundRobin
|
||||
}
|
||||
|
||||
for idx, pool := range enterprise.Pools {
|
||||
|
|
@ -176,6 +186,7 @@ func (s *sqlDatabase) sqlToCommonPool(pool Pool) (params.Pool, error) {
|
|||
RunnerBootstrapTimeout: pool.RunnerBootstrapTimeout,
|
||||
ExtraSpecs: json.RawMessage(pool.ExtraSpecs),
|
||||
GitHubRunnerGroup: pool.GitHubRunnerGroup,
|
||||
Priority: pool.Priority,
|
||||
}
|
||||
|
||||
if pool.RepoID != nil {
|
||||
|
|
@ -227,12 +238,17 @@ func (s *sqlDatabase) sqlToCommonRepository(repo Repository) (params.Repository,
|
|||
}
|
||||
|
||||
ret := params.Repository{
|
||||
ID: repo.ID.String(),
|
||||
Name: repo.Name,
|
||||
Owner: repo.Owner,
|
||||
CredentialsName: repo.CredentialsName,
|
||||
Pools: make([]params.Pool, len(repo.Pools)),
|
||||
WebhookSecret: string(secret),
|
||||
ID: repo.ID.String(),
|
||||
Name: repo.Name,
|
||||
Owner: repo.Owner,
|
||||
CredentialsName: repo.CredentialsName,
|
||||
Pools: make([]params.Pool, len(repo.Pools)),
|
||||
WebhookSecret: string(secret),
|
||||
PoolBalancerType: repo.PoolBalancerType,
|
||||
}
|
||||
|
||||
if ret.PoolBalancerType == "" {
|
||||
ret.PoolBalancerType = params.PoolBalancerTypeRoundRobin
|
||||
}
|
||||
|
||||
for idx, pool := range repo.Pools {
|
||||
|
|
@ -324,6 +340,10 @@ func (s *sqlDatabase) updatePool(pool Pool, param params.UpdatePoolParams) (para
|
|||
pool.GitHubRunnerGroup = *param.GitHubRunnerGroup
|
||||
}
|
||||
|
||||
if param.Priority != nil {
|
||||
pool.Priority = *param.Priority
|
||||
}
|
||||
|
||||
if q := s.conn.Save(&pool); q.Error != nil {
|
||||
return params.Pool{}, errors.Wrap(q.Error, "saving database entry")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,22 @@ type (
|
|||
RunnerStatus string
|
||||
WebhookEndpointType string
|
||||
GithubAuthType string
|
||||
PoolBalancerType string
|
||||
)
|
||||
|
||||
const (
|
||||
// PoolBalancerTypeRoundRobin will try to cycle through the pools of an entity
|
||||
// in a round robin fashion. For example, if a repository has multiple pools that
|
||||
// match a certain set of labels, and the entity is configured to use round robin
|
||||
// balancer, the pool manager will attempt to create instances in each pool in turn
|
||||
// for each job that needs to be serviced. So job1 in pool1, job2 in pool2 and so on.
|
||||
PoolBalancerTypeRoundRobin PoolBalancerType = "roundrobin"
|
||||
// PoolBalancerTypePack will try to create instances in the first pool that matches
|
||||
// the required labels. If the pool is full, it will move on to the next pool and so on.
|
||||
PoolBalancerTypePack PoolBalancerType = "pack"
|
||||
// PoolBalancerTypeNone denotes to the default behavior of the pool manager, which is
|
||||
// to use the round robin balancer.
|
||||
PoolBalancerTypeNone PoolBalancerType = ""
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -284,6 +300,11 @@ type Pool struct {
|
|||
// GithubRunnerGroup is the github runner group in which the runners will be added.
|
||||
// The runner group must be created by someone with access to the enterprise.
|
||||
GitHubRunnerGroup string `json:"github-runner-group"`
|
||||
|
||||
// Priority is the priority of the pool. The higher the number, the higher the priority.
|
||||
// When fetching matching pools for a set of tags, the result will be sorted in descending
|
||||
// order of priority.
|
||||
Priority uint `json:"priority"`
|
||||
}
|
||||
|
||||
func (p Pool) GetID() string {
|
||||
|
|
@ -337,6 +358,7 @@ type Internal struct {
|
|||
// GithubCredentialsDetails contains all info about the credentials, except the
|
||||
// token, which is added above.
|
||||
GithubCredentialsDetails GithubCredentials `json:"gh_creds_details"`
|
||||
PoolBalancerType PoolBalancerType `json:"pool_balancing_type"`
|
||||
}
|
||||
|
||||
type Repository struct {
|
||||
|
|
@ -346,6 +368,7 @@ type Repository struct {
|
|||
Pools []Pool `json:"pool,omitempty"`
|
||||
CredentialsName string `json:"credentials_name"`
|
||||
PoolManagerStatus PoolManagerStatus `json:"pool_manager_status,omitempty"`
|
||||
PoolBalancerType PoolBalancerType `json:"pool_balancing_type"`
|
||||
// Do not serialize sensitive info.
|
||||
WebhookSecret string `json:"-"`
|
||||
}
|
||||
|
|
@ -358,6 +381,13 @@ func (r Repository) GetID() string {
|
|||
return r.ID
|
||||
}
|
||||
|
||||
func (r Repository) GetBalancerType() PoolBalancerType {
|
||||
if r.PoolBalancerType == "" {
|
||||
return PoolBalancerTypeRoundRobin
|
||||
}
|
||||
return r.PoolBalancerType
|
||||
}
|
||||
|
||||
// used by swagger client generated code
|
||||
type Repositories []Repository
|
||||
|
||||
|
|
@ -367,6 +397,7 @@ type Organization struct {
|
|||
Pools []Pool `json:"pool,omitempty"`
|
||||
CredentialsName string `json:"credentials_name"`
|
||||
PoolManagerStatus PoolManagerStatus `json:"pool_manager_status,omitempty"`
|
||||
PoolBalancerType PoolBalancerType `json:"pool_balancing_type"`
|
||||
// Do not serialize sensitive info.
|
||||
WebhookSecret string `json:"-"`
|
||||
}
|
||||
|
|
@ -379,6 +410,13 @@ func (o Organization) GetID() string {
|
|||
return o.ID
|
||||
}
|
||||
|
||||
func (o Organization) GetBalancerType() PoolBalancerType {
|
||||
if o.PoolBalancerType == "" {
|
||||
return PoolBalancerTypeRoundRobin
|
||||
}
|
||||
return o.PoolBalancerType
|
||||
}
|
||||
|
||||
// used by swagger client generated code
|
||||
type Organizations []Organization
|
||||
|
||||
|
|
@ -388,6 +426,7 @@ type Enterprise struct {
|
|||
Pools []Pool `json:"pool,omitempty"`
|
||||
CredentialsName string `json:"credentials_name"`
|
||||
PoolManagerStatus PoolManagerStatus `json:"pool_manager_status,omitempty"`
|
||||
PoolBalancerType PoolBalancerType `json:"pool_balancing_type"`
|
||||
// Do not serialize sensitive info.
|
||||
WebhookSecret string `json:"-"`
|
||||
}
|
||||
|
|
@ -400,6 +439,13 @@ func (e Enterprise) GetID() string {
|
|||
return e.ID
|
||||
}
|
||||
|
||||
func (e Enterprise) GetBalancerType() PoolBalancerType {
|
||||
if e.PoolBalancerType == "" {
|
||||
return PoolBalancerTypeRoundRobin
|
||||
}
|
||||
return e.PoolBalancerType
|
||||
}
|
||||
|
||||
// used by swagger client generated code
|
||||
type Enterprises []Enterprise
|
||||
|
||||
|
|
|
|||
|
|
@ -31,10 +31,11 @@ type InstanceRequest struct {
|
|||
}
|
||||
|
||||
type CreateRepoParams struct {
|
||||
Owner string `json:"owner"`
|
||||
Name string `json:"name"`
|
||||
CredentialsName string `json:"credentials_name"`
|
||||
WebhookSecret string `json:"webhook_secret"`
|
||||
Owner string `json:"owner"`
|
||||
Name string `json:"name"`
|
||||
CredentialsName string `json:"credentials_name"`
|
||||
WebhookSecret string `json:"webhook_secret"`
|
||||
PoolBalancerType PoolBalancerType `json:"pool_balancer_type"`
|
||||
}
|
||||
|
||||
func (c *CreateRepoParams) Validate() error {
|
||||
|
|
@ -52,13 +53,21 @@ func (c *CreateRepoParams) Validate() error {
|
|||
if c.WebhookSecret == "" {
|
||||
return errors.NewMissingSecretError("missing secret")
|
||||
}
|
||||
|
||||
switch c.PoolBalancerType {
|
||||
case PoolBalancerTypeRoundRobin, PoolBalancerTypePack, PoolBalancerTypeNone:
|
||||
default:
|
||||
return errors.NewBadRequestError("invalid pool balancer type")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type CreateOrgParams struct {
|
||||
Name string `json:"name"`
|
||||
CredentialsName string `json:"credentials_name"`
|
||||
WebhookSecret string `json:"webhook_secret"`
|
||||
Name string `json:"name"`
|
||||
CredentialsName string `json:"credentials_name"`
|
||||
WebhookSecret string `json:"webhook_secret"`
|
||||
PoolBalancerType PoolBalancerType `json:"pool_balancer_type"`
|
||||
}
|
||||
|
||||
func (c *CreateOrgParams) Validate() error {
|
||||
|
|
@ -72,13 +81,20 @@ func (c *CreateOrgParams) Validate() error {
|
|||
if c.WebhookSecret == "" {
|
||||
return errors.NewMissingSecretError("missing secret")
|
||||
}
|
||||
|
||||
switch c.PoolBalancerType {
|
||||
case PoolBalancerTypeRoundRobin, PoolBalancerTypePack, PoolBalancerTypeNone:
|
||||
default:
|
||||
return errors.NewBadRequestError("invalid pool balancer type")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type CreateEnterpriseParams struct {
|
||||
Name string `json:"name"`
|
||||
CredentialsName string `json:"credentials_name"`
|
||||
WebhookSecret string `json:"webhook_secret"`
|
||||
Name string `json:"name"`
|
||||
CredentialsName string `json:"credentials_name"`
|
||||
WebhookSecret string `json:"webhook_secret"`
|
||||
PoolBalancerType PoolBalancerType `json:"pool_balancer_type"`
|
||||
}
|
||||
|
||||
func (c *CreateEnterpriseParams) Validate() error {
|
||||
|
|
@ -91,6 +107,12 @@ func (c *CreateEnterpriseParams) Validate() error {
|
|||
if c.WebhookSecret == "" {
|
||||
return errors.NewMissingSecretError("missing secret")
|
||||
}
|
||||
|
||||
switch c.PoolBalancerType {
|
||||
case PoolBalancerTypeRoundRobin, PoolBalancerTypePack, PoolBalancerTypeNone:
|
||||
default:
|
||||
return errors.NewBadRequestError("invalid pool balancer type")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -122,6 +144,7 @@ type UpdatePoolParams struct {
|
|||
// pool will be added to.
|
||||
// The runner group must be created by someone with access to the enterprise.
|
||||
GitHubRunnerGroup *string `json:"github-runner-group,omitempty"`
|
||||
Priority *uint `json:"priority,omitempty"`
|
||||
}
|
||||
|
||||
type CreateInstanceParams struct {
|
||||
|
|
@ -159,6 +182,7 @@ type CreatePoolParams struct {
|
|||
// pool will be added to.
|
||||
// The runner group must be created by someone with access to the enterprise.
|
||||
GitHubRunnerGroup string `json:"github-runner-group"`
|
||||
Priority uint `json:"priority"`
|
||||
}
|
||||
|
||||
func (p *CreatePoolParams) Validate() error {
|
||||
|
|
@ -231,8 +255,9 @@ func (p PasswordLoginParams) Validate() error {
|
|||
}
|
||||
|
||||
type UpdateEntityParams struct {
|
||||
CredentialsName string `json:"credentials_name"`
|
||||
WebhookSecret string `json:"webhook_secret"`
|
||||
CredentialsName string `json:"credentials_name"`
|
||||
WebhookSecret string `json:"webhook_secret"`
|
||||
PoolBalancerType PoolBalancerType `json:"pool_balancer_type"`
|
||||
}
|
||||
|
||||
type InstanceUpdateMessage struct {
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ func (r *Runner) CreateEnterprise(ctx context.Context, param params.CreateEnterp
|
|||
return params.Enterprise{}, runnerErrors.NewConflictError("enterprise %s already exists", param.Name)
|
||||
}
|
||||
|
||||
enterprise, err = r.store.CreateEnterprise(ctx, param.Name, creds.Name, param.WebhookSecret)
|
||||
enterprise, err = r.store.CreateEnterprise(ctx, param.Name, creds.Name, param.WebhookSecret, param.PoolBalancerType)
|
||||
if err != nil {
|
||||
return params.Enterprise{}, errors.Wrap(err, "creating enterprise")
|
||||
}
|
||||
|
|
@ -168,6 +168,12 @@ func (r *Runner) UpdateEnterprise(ctx context.Context, enterpriseID string, para
|
|||
}
|
||||
}
|
||||
|
||||
switch param.PoolBalancerType {
|
||||
case params.PoolBalancerTypeRoundRobin, params.PoolBalancerTypePack, params.PoolBalancerTypeNone:
|
||||
default:
|
||||
return params.Enterprise{}, runnerErrors.NewBadRequestError("invalid pool balancer type: %s", param.PoolBalancerType)
|
||||
}
|
||||
|
||||
enterprise, err = r.store.UpdateEnterprise(ctx, enterpriseID, param)
|
||||
if err != nil {
|
||||
return params.Enterprise{}, errors.Wrap(err, "updating enterprise")
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ func (s *EnterpriseTestSuite) SetupTest() {
|
|||
name,
|
||||
fmt.Sprintf("test-creds-%v", i),
|
||||
fmt.Sprintf("test-webhook-secret-%v", i),
|
||||
params.PoolBalancerTypeRoundRobin,
|
||||
)
|
||||
if err != nil {
|
||||
s.FailNow(fmt.Sprintf("failed to create database object (test-enterprise-%v)", i))
|
||||
|
|
@ -169,6 +170,7 @@ func (s *EnterpriseTestSuite) TestCreateEnterprise() {
|
|||
s.Require().Nil(err)
|
||||
s.Require().Equal(s.Fixtures.CreateEnterpriseParams.Name, enterprise.Name)
|
||||
s.Require().Equal(s.Fixtures.Credentials[s.Fixtures.CreateEnterpriseParams.CredentialsName].Name, enterprise.CredentialsName)
|
||||
s.Require().Equal(params.PoolBalancerTypeRoundRobin, enterprise.PoolBalancerType)
|
||||
}
|
||||
|
||||
func (s *EnterpriseTestSuite) TestCreateEnterpriseErrUnauthorized() {
|
||||
|
|
@ -293,13 +295,16 @@ func (s *EnterpriseTestSuite) TestUpdateEnterprise() {
|
|||
s.Fixtures.PoolMgrCtrlMock.On("UpdateEnterprisePoolManager", s.Fixtures.AdminContext, mock.AnythingOfType("params.Enterprise")).Return(s.Fixtures.PoolMgrMock, nil)
|
||||
s.Fixtures.PoolMgrMock.On("Status").Return(params.PoolManagerStatus{IsRunning: true}, nil)
|
||||
|
||||
org, err := s.Runner.UpdateEnterprise(s.Fixtures.AdminContext, s.Fixtures.StoreEnterprises["test-enterprise-1"].ID, s.Fixtures.UpdateRepoParams)
|
||||
param := s.Fixtures.UpdateRepoParams
|
||||
param.PoolBalancerType = params.PoolBalancerTypePack
|
||||
org, err := s.Runner.UpdateEnterprise(s.Fixtures.AdminContext, s.Fixtures.StoreEnterprises["test-enterprise-1"].ID, param)
|
||||
|
||||
s.Fixtures.PoolMgrMock.AssertExpectations(s.T())
|
||||
s.Fixtures.PoolMgrCtrlMock.AssertExpectations(s.T())
|
||||
s.Require().Nil(err)
|
||||
s.Require().Equal(s.Fixtures.UpdateRepoParams.CredentialsName, org.CredentialsName)
|
||||
s.Require().Equal(s.Fixtures.UpdateRepoParams.WebhookSecret, org.WebhookSecret)
|
||||
s.Require().Equal(params.PoolBalancerTypePack, org.PoolBalancerType)
|
||||
}
|
||||
|
||||
func (s *EnterpriseTestSuite) TestUpdateEnterpriseErrUnauthorized() {
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ func (r *Runner) CreateOrganization(ctx context.Context, param params.CreateOrgP
|
|||
return params.Organization{}, runnerErrors.NewConflictError("organization %s already exists", param.Name)
|
||||
}
|
||||
|
||||
org, err = r.store.CreateOrganization(ctx, param.Name, creds.Name, param.WebhookSecret)
|
||||
org, err = r.store.CreateOrganization(ctx, param.Name, creds.Name, param.WebhookSecret, param.PoolBalancerType)
|
||||
if err != nil {
|
||||
return params.Organization{}, errors.Wrap(err, "creating organization")
|
||||
}
|
||||
|
|
@ -197,6 +197,12 @@ func (r *Runner) UpdateOrganization(ctx context.Context, orgID string, param par
|
|||
}
|
||||
}
|
||||
|
||||
switch param.PoolBalancerType {
|
||||
case params.PoolBalancerTypeRoundRobin, params.PoolBalancerTypePack, params.PoolBalancerTypeNone:
|
||||
default:
|
||||
return params.Organization{}, runnerErrors.NewBadRequestError("invalid pool balancer type: %s", param.PoolBalancerType)
|
||||
}
|
||||
|
||||
org, err = r.store.UpdateOrganization(ctx, orgID, param)
|
||||
if err != nil {
|
||||
return params.Organization{}, errors.Wrap(err, "updating org")
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ func (s *OrgTestSuite) SetupTest() {
|
|||
name,
|
||||
fmt.Sprintf("test-creds-%v", i),
|
||||
fmt.Sprintf("test-webhook-secret-%v", i),
|
||||
params.PoolBalancerTypeRoundRobin,
|
||||
)
|
||||
if err != nil {
|
||||
s.FailNow(fmt.Sprintf("failed to create database object (test-org-%v)", i))
|
||||
|
|
@ -169,6 +170,20 @@ func (s *OrgTestSuite) TestCreateOrganization() {
|
|||
s.Require().Nil(err)
|
||||
s.Require().Equal(s.Fixtures.CreateOrgParams.Name, org.Name)
|
||||
s.Require().Equal(s.Fixtures.Credentials[s.Fixtures.CreateOrgParams.CredentialsName].Name, org.CredentialsName)
|
||||
s.Require().Equal(params.PoolBalancerTypeRoundRobin, org.PoolBalancerType)
|
||||
}
|
||||
|
||||
func (s *OrgTestSuite) TestCreateOrganizationPoolBalancerTypePack() {
|
||||
s.Fixtures.CreateOrgParams.PoolBalancerType = params.PoolBalancerTypePack
|
||||
s.Fixtures.PoolMgrMock.On("Start").Return(nil)
|
||||
s.Fixtures.PoolMgrCtrlMock.On("CreateOrgPoolManager", s.Fixtures.AdminContext, mock.AnythingOfType("params.Organization"), s.Fixtures.Providers, s.Fixtures.Store).Return(s.Fixtures.PoolMgrMock, nil)
|
||||
|
||||
org, err := s.Runner.CreateOrganization(s.Fixtures.AdminContext, s.Fixtures.CreateOrgParams)
|
||||
|
||||
s.Fixtures.PoolMgrMock.AssertExpectations(s.T())
|
||||
s.Fixtures.PoolMgrCtrlMock.AssertExpectations(s.T())
|
||||
s.Require().Nil(err)
|
||||
s.Require().Equal(params.PoolBalancerTypePack, org.PoolBalancerType)
|
||||
}
|
||||
|
||||
func (s *OrgTestSuite) TestCreateOrganizationErrUnauthorized() {
|
||||
|
|
@ -302,6 +317,21 @@ func (s *OrgTestSuite) TestUpdateOrganization() {
|
|||
s.Require().Equal(s.Fixtures.UpdateRepoParams.WebhookSecret, org.WebhookSecret)
|
||||
}
|
||||
|
||||
func (s *OrgTestSuite) TestUpdateRepositoryBalancingType() {
|
||||
s.Fixtures.UpdateRepoParams.PoolBalancerType = params.PoolBalancerTypePack
|
||||
s.Fixtures.PoolMgrCtrlMock.On("UpdateOrgPoolManager", s.Fixtures.AdminContext, mock.AnythingOfType("params.Organization")).Return(s.Fixtures.PoolMgrMock, nil)
|
||||
s.Fixtures.PoolMgrMock.On("Status").Return(params.PoolManagerStatus{IsRunning: true}, nil)
|
||||
|
||||
param := s.Fixtures.UpdateRepoParams
|
||||
param.PoolBalancerType = params.PoolBalancerTypePack
|
||||
org, err := s.Runner.UpdateOrganization(s.Fixtures.AdminContext, s.Fixtures.StoreOrgs["test-org-1"].ID, param)
|
||||
|
||||
s.Fixtures.PoolMgrMock.AssertExpectations(s.T())
|
||||
s.Fixtures.PoolMgrCtrlMock.AssertExpectations(s.T())
|
||||
s.Require().Nil(err)
|
||||
s.Require().Equal(params.PoolBalancerTypePack, org.PoolBalancerType)
|
||||
}
|
||||
|
||||
func (s *OrgTestSuite) TestUpdateOrganizationErrUnauthorized() {
|
||||
_, err := s.Runner.UpdateOrganization(context.Background(), "dummy-org-id", s.Fixtures.UpdateRepoParams)
|
||||
|
||||
|
|
|
|||
|
|
@ -77,6 +77,13 @@ type enterprise struct {
|
|||
mux sync.Mutex
|
||||
}
|
||||
|
||||
func (e *enterprise) PoolBalancerType() params.PoolBalancerType {
|
||||
if e.cfgInternal.PoolBalancerType == "" {
|
||||
return params.PoolBalancerTypeRoundRobin
|
||||
}
|
||||
return e.cfgInternal.PoolBalancerType
|
||||
}
|
||||
|
||||
func (e *enterprise) findRunnerGroupByName(name string) (*github.EnterpriseRunnerGroup, error) {
|
||||
// nolint:golangci-lint,godox
|
||||
// TODO(gabriel-samfira): implement caching
|
||||
|
|
@ -183,10 +190,6 @@ func (e *enterprise) GetJITConfig(ctx context.Context, instance string, pool par
|
|||
return ret, jitConfig.Runner, nil
|
||||
}
|
||||
|
||||
func (e *enterprise) GithubCLI() common.GithubClient {
|
||||
return e.ghcli
|
||||
}
|
||||
|
||||
func (e *enterprise) PoolType() params.PoolType {
|
||||
return params.EnterprisePool
|
||||
}
|
||||
|
|
@ -363,14 +366,6 @@ func (e *enterprise) WebhookSecret() string {
|
|||
return e.cfg.WebhookSecret
|
||||
}
|
||||
|
||||
func (e *enterprise) FindPoolByTags(labels []string) (params.Pool, error) {
|
||||
pool, err := e.store.FindEnterprisePoolByTags(e.ctx, e.id, labels)
|
||||
if err != nil {
|
||||
return params.Pool{}, errors.Wrap(err, "fetching suitable pool")
|
||||
}
|
||||
return pool, nil
|
||||
}
|
||||
|
||||
func (e *enterprise) GetPoolByID(poolID string) (params.Pool, error) {
|
||||
pool, err := e.store.GetEnterprisePool(e.ctx, e.id, poolID)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ import (
|
|||
|
||||
commonParams "github.com/cloudbase/garm-provider-common/params"
|
||||
"github.com/cloudbase/garm/params"
|
||||
"github.com/cloudbase/garm/runner/common"
|
||||
)
|
||||
|
||||
type poolHelper interface {
|
||||
|
|
@ -35,8 +34,6 @@ type poolHelper interface {
|
|||
UninstallHook(ctx context.Context, url string) error
|
||||
GetHookInfo(ctx context.Context) (params.HookInfo, error)
|
||||
|
||||
GithubCLI() common.GithubClient
|
||||
|
||||
GetJITConfig(ctx context.Context, instanceName string, pool params.Pool, labels []string) (map[string]string, *github.Runner, error)
|
||||
|
||||
FetchDbInstances() ([]params.Instance, error)
|
||||
|
|
@ -44,11 +41,11 @@ type poolHelper interface {
|
|||
GithubURL() string
|
||||
JwtToken() string
|
||||
String() string
|
||||
FindPoolByTags(labels []string) (params.Pool, error)
|
||||
GetPoolByID(poolID string) (params.Pool, error)
|
||||
ValidateOwner(job params.WorkflowJob) error
|
||||
UpdateState(param params.UpdatePoolStateParams) error
|
||||
WebhookSecret() string
|
||||
ID() string
|
||||
PoolType() params.PoolType
|
||||
PoolBalancerType() params.PoolBalancerType
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,6 +89,13 @@ type organization struct {
|
|||
mux sync.Mutex
|
||||
}
|
||||
|
||||
func (o *organization) PoolBalancerType() params.PoolBalancerType {
|
||||
if o.cfgInternal.PoolBalancerType == "" {
|
||||
return params.PoolBalancerTypeRoundRobin
|
||||
}
|
||||
return o.cfgInternal.PoolBalancerType
|
||||
}
|
||||
|
||||
func (o *organization) findRunnerGroupByName(name string) (*github.RunnerGroup, error) {
|
||||
// nolint:golangci-lint,godox
|
||||
// TODO(gabriel-samfira): implement caching
|
||||
|
|
@ -195,10 +202,6 @@ func (o *organization) GetJITConfig(ctx context.Context, instance string, pool p
|
|||
return ret, runner, nil
|
||||
}
|
||||
|
||||
func (o *organization) GithubCLI() common.GithubClient {
|
||||
return o.ghcli
|
||||
}
|
||||
|
||||
func (o *organization) PoolType() params.PoolType {
|
||||
return params.OrganizationPool
|
||||
}
|
||||
|
|
@ -377,14 +380,6 @@ func (o *organization) WebhookSecret() string {
|
|||
return o.cfg.WebhookSecret
|
||||
}
|
||||
|
||||
func (o *organization) FindPoolByTags(labels []string) (params.Pool, error) {
|
||||
pool, err := o.store.FindOrganizationPoolByTags(o.ctx, o.id, labels)
|
||||
if err != nil {
|
||||
return params.Pool{}, errors.Wrap(err, "fetching suitable pool")
|
||||
}
|
||||
return pool, nil
|
||||
}
|
||||
|
||||
func (o *organization) GetPoolByID(poolID string) (params.Pool, error) {
|
||||
pool, err := o.store.GetOrganizationPool(o.ctx, o.id, poolID)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -1653,7 +1653,15 @@ func (r *basePoolManager) Stop() error {
|
|||
}
|
||||
|
||||
func (r *basePoolManager) RefreshState(param params.UpdatePoolStateParams) error {
|
||||
return r.helper.UpdateState(param)
|
||||
if err := r.helper.UpdateState(param); err != nil {
|
||||
return fmt.Errorf("failed to update pool state: %w", err)
|
||||
}
|
||||
// Update the tools as soon as state is updated. This should revive a stopped pool manager
|
||||
// or stop one if the supplied credentials are not okay.
|
||||
if err := r.updateTools(); err != nil {
|
||||
return fmt.Errorf("failed to update tools: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *basePoolManager) WebhookSecret() string {
|
||||
|
|
@ -1764,7 +1772,9 @@ func (r *basePoolManager) consumeQueuedJobs() error {
|
|||
return errors.Wrap(err, "listing queued jobs")
|
||||
}
|
||||
|
||||
poolsCache := poolsForTags{}
|
||||
poolsCache := poolsForTags{
|
||||
poolCacheType: r.helper.PoolBalancerType(),
|
||||
}
|
||||
|
||||
slog.DebugContext(
|
||||
r.ctx, "found queued jobs",
|
||||
|
|
|
|||
|
|
@ -91,6 +91,13 @@ type repository struct {
|
|||
mux sync.Mutex
|
||||
}
|
||||
|
||||
func (r *repository) PoolBalancerType() params.PoolBalancerType {
|
||||
if r.cfgInternal.PoolBalancerType == "" {
|
||||
return params.PoolBalancerTypeRoundRobin
|
||||
}
|
||||
return r.cfgInternal.PoolBalancerType
|
||||
}
|
||||
|
||||
// nolint:golint,revive
|
||||
// pool is used in enterprise and organzation
|
||||
func (r *repository) GetJITConfig(ctx context.Context, instance string, pool params.Pool, labels []string) (jitConfigMap map[string]string, runner *github.Runner, err error) {
|
||||
|
|
@ -154,10 +161,6 @@ func (r *repository) GetJITConfig(ctx context.Context, instance string, pool par
|
|||
return ret, runner, nil
|
||||
}
|
||||
|
||||
func (r *repository) GithubCLI() common.GithubClient {
|
||||
return r.ghcli
|
||||
}
|
||||
|
||||
func (r *repository) PoolType() params.PoolType {
|
||||
return params.RepositoryPool
|
||||
}
|
||||
|
|
@ -334,14 +337,6 @@ func (r *repository) WebhookSecret() string {
|
|||
return r.cfg.WebhookSecret
|
||||
}
|
||||
|
||||
func (r *repository) FindPoolByTags(labels []string) (params.Pool, error) {
|
||||
pool, err := r.store.FindRepositoryPoolByTags(r.ctx, r.id, labels)
|
||||
if err != nil {
|
||||
return params.Pool{}, errors.Wrap(err, "fetching suitable pool")
|
||||
}
|
||||
return pool, nil
|
||||
}
|
||||
|
||||
func (r *repository) GetPoolByID(poolID string) (params.Pool, error) {
|
||||
pool, err := r.store.GetRepositoryPool(r.ctx, r.id, poolID)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,12 @@ import (
|
|||
"github.com/cloudbase/garm/params"
|
||||
)
|
||||
|
||||
type poolCacheStore interface {
|
||||
Next() (params.Pool, error)
|
||||
Reset()
|
||||
Len() int
|
||||
}
|
||||
|
||||
type poolRoundRobin struct {
|
||||
pools []params.Pool
|
||||
next uint32
|
||||
|
|
@ -33,10 +39,11 @@ func (p *poolRoundRobin) Reset() {
|
|||
}
|
||||
|
||||
type poolsForTags struct {
|
||||
pools sync.Map
|
||||
pools sync.Map
|
||||
poolCacheType params.PoolBalancerType
|
||||
}
|
||||
|
||||
func (p *poolsForTags) Get(tags []string) (*poolRoundRobin, bool) {
|
||||
func (p *poolsForTags) Get(tags []string) (poolCacheStore, bool) {
|
||||
sort.Strings(tags)
|
||||
key := strings.Join(tags, "^")
|
||||
|
||||
|
|
@ -44,11 +51,21 @@ func (p *poolsForTags) Get(tags []string) (*poolRoundRobin, bool) {
|
|||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
return v.(*poolRoundRobin), true
|
||||
poolCache := v.(*poolRoundRobin)
|
||||
if p.poolCacheType == params.PoolBalancerTypePack {
|
||||
// When we service a list of jobs, we want to try each pool in turn
|
||||
// for each job. Pools are sorted by priority so we always start from the
|
||||
// highest priority pool and move on to the next if the first one is full.
|
||||
poolCache.Reset()
|
||||
}
|
||||
return poolCache, true
|
||||
}
|
||||
|
||||
func (p *poolsForTags) Add(tags []string, pools []params.Pool) *poolRoundRobin {
|
||||
func (p *poolsForTags) Add(tags []string, pools []params.Pool) poolCacheStore {
|
||||
sort.Slice(pools, func(i, j int) bool {
|
||||
return pools[i].Priority > pools[j].Priority
|
||||
})
|
||||
|
||||
sort.Strings(tags)
|
||||
key := strings.Join(tags, "^")
|
||||
|
||||
|
|
|
|||
228
runner/pool/util_test.go
Normal file
228
runner/pool/util_test.go
Normal file
|
|
@ -0,0 +1,228 @@
|
|||
package pool
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
runnerErrors "github.com/cloudbase/garm-provider-common/errors"
|
||||
"github.com/cloudbase/garm/params"
|
||||
)
|
||||
|
||||
func TestPoolRoundRobinRollsOver(t *testing.T) {
|
||||
p := &poolRoundRobin{
|
||||
pools: []params.Pool{
|
||||
{
|
||||
ID: "1",
|
||||
},
|
||||
{
|
||||
ID: "2",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
pool, err := p.Next()
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
if pool.ID != "1" {
|
||||
t.Fatalf("expected pool 1, got %s", pool.ID)
|
||||
}
|
||||
|
||||
pool, err = p.Next()
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
if pool.ID != "2" {
|
||||
t.Fatalf("expected pool 2, got %s", pool.ID)
|
||||
}
|
||||
|
||||
pool, err = p.Next()
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
if pool.ID != "1" {
|
||||
t.Fatalf("expected pool 1, got %s", pool.ID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPoolRoundRobinEmptyPoolErrorsOut(t *testing.T) {
|
||||
p := &poolRoundRobin{}
|
||||
|
||||
_, err := p.Next()
|
||||
if err == nil {
|
||||
t.Fatalf("expected error, got nil")
|
||||
}
|
||||
if err != runnerErrors.ErrNoPoolsAvailable {
|
||||
t.Fatalf("expected ErrNoPoolsAvailable, got %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPoolRoundRobinLen(t *testing.T) {
|
||||
p := &poolRoundRobin{
|
||||
pools: []params.Pool{
|
||||
{
|
||||
ID: "1",
|
||||
},
|
||||
{
|
||||
ID: "2",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if p.Len() != 2 {
|
||||
t.Fatalf("expected 2, got %d", p.Len())
|
||||
}
|
||||
}
|
||||
|
||||
func TestPoolRoundRobinReset(t *testing.T) {
|
||||
p := &poolRoundRobin{
|
||||
pools: []params.Pool{
|
||||
{
|
||||
ID: "1",
|
||||
},
|
||||
{
|
||||
ID: "2",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
p.Next()
|
||||
p.Reset()
|
||||
if p.next != 0 {
|
||||
t.Fatalf("expected 0, got %d", p.next)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPoolsForTagsPackGet(t *testing.T) {
|
||||
p := &poolsForTags{
|
||||
poolCacheType: params.PoolBalancerTypePack,
|
||||
}
|
||||
|
||||
pools := []params.Pool{
|
||||
{
|
||||
ID: "1",
|
||||
Priority: 0,
|
||||
},
|
||||
{
|
||||
ID: "2",
|
||||
Priority: 100,
|
||||
},
|
||||
}
|
||||
_ = p.Add([]string{"key"}, pools)
|
||||
cache, ok := p.Get([]string{"key"})
|
||||
if !ok {
|
||||
t.Fatalf("expected true, got false")
|
||||
}
|
||||
if cache.Len() != 2 {
|
||||
t.Fatalf("expected 2, got %d", cache.Len())
|
||||
}
|
||||
|
||||
poolRR, ok := cache.(*poolRoundRobin)
|
||||
if !ok {
|
||||
t.Fatalf("expected poolRoundRobin, got %v", cache)
|
||||
}
|
||||
if poolRR.next != 0 {
|
||||
t.Fatalf("expected 0, got %d", poolRR.next)
|
||||
}
|
||||
pool, err := poolRR.Next()
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
if pool.ID != "2" {
|
||||
t.Fatalf("expected pool 2, got %s", pool.ID)
|
||||
}
|
||||
|
||||
if poolRR.next != 1 {
|
||||
t.Fatalf("expected 1, got %d", poolRR.next)
|
||||
}
|
||||
// Getting the pool cache again should reset next
|
||||
cache, ok = p.Get([]string{"key"})
|
||||
if !ok {
|
||||
t.Fatalf("expected true, got false")
|
||||
}
|
||||
poolRR, ok = cache.(*poolRoundRobin)
|
||||
if !ok {
|
||||
t.Fatalf("expected poolRoundRobin, got %v", cache)
|
||||
}
|
||||
if poolRR.next != 0 {
|
||||
t.Fatalf("expected 0, got %d", poolRR.next)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPoolsForTagsRoundRobinGet(t *testing.T) {
|
||||
p := &poolsForTags{
|
||||
poolCacheType: params.PoolBalancerTypeRoundRobin,
|
||||
}
|
||||
|
||||
pools := []params.Pool{
|
||||
{
|
||||
ID: "1",
|
||||
Priority: 0,
|
||||
},
|
||||
{
|
||||
ID: "2",
|
||||
Priority: 100,
|
||||
},
|
||||
}
|
||||
_ = p.Add([]string{"key"}, pools)
|
||||
cache, ok := p.Get([]string{"key"})
|
||||
if !ok {
|
||||
t.Fatalf("expected true, got false")
|
||||
}
|
||||
if cache.Len() != 2 {
|
||||
t.Fatalf("expected 2, got %d", cache.Len())
|
||||
}
|
||||
|
||||
pool, err := cache.Next()
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
if pool.ID != "2" {
|
||||
t.Fatalf("expected pool 2, got %s", pool.ID)
|
||||
}
|
||||
// Getting the pool cache again should not reset next, and
|
||||
// should return the next pool.
|
||||
cache, ok = p.Get([]string{"key"})
|
||||
if !ok {
|
||||
t.Fatalf("expected true, got false")
|
||||
}
|
||||
pool, err = cache.Next()
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
}
|
||||
if pool.ID != "1" {
|
||||
t.Fatalf("expected pool 1, got %s", pool.ID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPoolsForTagsNoPoolsForTag(t *testing.T) {
|
||||
p := &poolsForTags{
|
||||
pools: sync.Map{},
|
||||
}
|
||||
|
||||
_, ok := p.Get([]string{"key"})
|
||||
if ok {
|
||||
t.Fatalf("expected false, got true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPoolsForTagsBalancerTypePack(t *testing.T) {
|
||||
p := &poolsForTags{
|
||||
pools: sync.Map{},
|
||||
poolCacheType: params.PoolBalancerTypePack,
|
||||
}
|
||||
|
||||
poolCache := &poolRoundRobin{}
|
||||
p.pools.Store("key", poolCache)
|
||||
|
||||
cache, ok := p.Get([]string{"key"})
|
||||
if !ok {
|
||||
t.Fatalf("expected true, got false")
|
||||
}
|
||||
if cache != poolCache {
|
||||
t.Fatalf("expected poolCache, got %v", cache)
|
||||
}
|
||||
if poolCache.next != 0 {
|
||||
t.Fatalf("expected 0, got %d", poolCache.next)
|
||||
}
|
||||
}
|
||||
|
|
@ -58,7 +58,7 @@ func (s *PoolTestSuite) SetupTest() {
|
|||
}
|
||||
|
||||
// create an organization for testing purposes
|
||||
org, err := db.CreateOrganization(context.Background(), "test-org", "test-creds", "test-webhookSecret")
|
||||
org, err := db.CreateOrganization(context.Background(), "test-org", "test-creds", "test-webhookSecret", params.PoolBalancerTypeRoundRobin)
|
||||
if err != nil {
|
||||
s.FailNow(fmt.Sprintf("failed to create org: %s", err))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ func (r *Runner) CreateRepository(ctx context.Context, param params.CreateRepoPa
|
|||
return params.Repository{}, runnerErrors.NewConflictError("repository %s/%s already exists", param.Owner, param.Name)
|
||||
}
|
||||
|
||||
repo, err = r.store.CreateRepository(ctx, param.Owner, param.Name, creds.Name, param.WebhookSecret)
|
||||
repo, err = r.store.CreateRepository(ctx, param.Owner, param.Name, creds.Name, param.WebhookSecret, param.PoolBalancerType)
|
||||
if err != nil {
|
||||
return params.Repository{}, errors.Wrap(err, "creating repository")
|
||||
}
|
||||
|
|
@ -196,6 +196,12 @@ func (r *Runner) UpdateRepository(ctx context.Context, repoID string, param para
|
|||
}
|
||||
}
|
||||
|
||||
switch param.PoolBalancerType {
|
||||
case params.PoolBalancerTypeRoundRobin, params.PoolBalancerTypePack, params.PoolBalancerTypeNone:
|
||||
default:
|
||||
return params.Repository{}, runnerErrors.NewBadRequestError("invalid pool balancer type: %s", param.PoolBalancerType)
|
||||
}
|
||||
|
||||
repo, err = r.store.UpdateRepository(ctx, repoID, param)
|
||||
if err != nil {
|
||||
return params.Repository{}, errors.Wrap(err, "updating repo")
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ func (s *RepoTestSuite) SetupTest() {
|
|||
name,
|
||||
fmt.Sprintf("test-creds-%v", i),
|
||||
fmt.Sprintf("test-webhook-secret-%v", i),
|
||||
params.PoolBalancerTypeRoundRobin,
|
||||
)
|
||||
if err != nil {
|
||||
s.FailNow(fmt.Sprintf("failed to create database object (test-repo-%v)", i))
|
||||
|
|
@ -170,6 +171,27 @@ func (s *RepoTestSuite) TestCreateRepository() {
|
|||
s.Require().Equal(s.Fixtures.CreateRepoParams.Owner, repo.Owner)
|
||||
s.Require().Equal(s.Fixtures.CreateRepoParams.Name, repo.Name)
|
||||
s.Require().Equal(s.Fixtures.Credentials[s.Fixtures.CreateRepoParams.CredentialsName].Name, repo.CredentialsName)
|
||||
s.Require().Equal(params.PoolBalancerTypeRoundRobin, repo.PoolBalancerType)
|
||||
}
|
||||
|
||||
func (s *RepoTestSuite) TestCreareRepositoryPoolBalancerTypePack() {
|
||||
// setup mocks expectations
|
||||
s.Fixtures.PoolMgrMock.On("Start").Return(nil)
|
||||
s.Fixtures.PoolMgrCtrlMock.On("CreateRepoPoolManager", s.Fixtures.AdminContext, mock.AnythingOfType("params.Repository"), s.Fixtures.Providers, s.Fixtures.Store).Return(s.Fixtures.PoolMgrMock, nil)
|
||||
|
||||
// call tested function
|
||||
param := s.Fixtures.CreateRepoParams
|
||||
param.PoolBalancerType = params.PoolBalancerTypePack
|
||||
repo, err := s.Runner.CreateRepository(s.Fixtures.AdminContext, param)
|
||||
|
||||
// assertions
|
||||
s.Fixtures.PoolMgrMock.AssertExpectations(s.T())
|
||||
s.Fixtures.PoolMgrCtrlMock.AssertExpectations(s.T())
|
||||
s.Require().Nil(err)
|
||||
s.Require().Equal(param.Owner, repo.Owner)
|
||||
s.Require().Equal(param.Name, repo.Name)
|
||||
s.Require().Equal(s.Fixtures.Credentials[s.Fixtures.CreateRepoParams.CredentialsName].Name, repo.CredentialsName)
|
||||
s.Require().Equal(params.PoolBalancerTypePack, repo.PoolBalancerType)
|
||||
}
|
||||
|
||||
func (s *RepoTestSuite) TestCreateRepositoryErrUnauthorized() {
|
||||
|
|
@ -303,11 +325,27 @@ func (s *RepoTestSuite) TestUpdateRepository() {
|
|||
s.Require().Nil(err)
|
||||
s.Require().Equal(s.Fixtures.UpdateRepoParams.CredentialsName, repo.CredentialsName)
|
||||
s.Require().Equal(s.Fixtures.UpdateRepoParams.WebhookSecret, repo.WebhookSecret)
|
||||
s.Require().Equal(params.PoolBalancerTypeRoundRobin, repo.PoolBalancerType)
|
||||
}
|
||||
|
||||
func (s *RepoTestSuite) TestUpdateRepositoryBalancingType() {
|
||||
s.Fixtures.PoolMgrCtrlMock.On("UpdateRepoPoolManager", s.Fixtures.AdminContext, mock.AnythingOfType("params.Repository")).Return(s.Fixtures.PoolMgrMock, nil)
|
||||
s.Fixtures.PoolMgrMock.On("Status").Return(params.PoolManagerStatus{IsRunning: true}, nil)
|
||||
|
||||
updateRepoParams := s.Fixtures.UpdateRepoParams
|
||||
updateRepoParams.PoolBalancerType = params.PoolBalancerTypePack
|
||||
repo, err := s.Runner.UpdateRepository(s.Fixtures.AdminContext, s.Fixtures.StoreRepos["test-repo-1"].ID, updateRepoParams)
|
||||
|
||||
s.Fixtures.PoolMgrCtrlMock.AssertExpectations(s.T())
|
||||
s.Fixtures.PoolMgrMock.AssertExpectations(s.T())
|
||||
s.Require().Nil(err)
|
||||
s.Require().Equal(updateRepoParams.CredentialsName, repo.CredentialsName)
|
||||
s.Require().Equal(updateRepoParams.WebhookSecret, repo.WebhookSecret)
|
||||
s.Require().Equal(params.PoolBalancerTypePack, repo.PoolBalancerType)
|
||||
}
|
||||
|
||||
func (s *RepoTestSuite) TestUpdateRepositoryErrUnauthorized() {
|
||||
_, err := s.Runner.UpdateRepository(context.Background(), "dummy-repo-id", s.Fixtures.UpdateRepoParams)
|
||||
|
||||
s.Require().Equal(runnerErrors.ErrUnauthorized, err)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ func (p *poolManagerCtrl) CreateRepoPoolManager(ctx context.Context, repo params
|
|||
p.mux.Lock()
|
||||
defer p.mux.Unlock()
|
||||
|
||||
cfgInternal, err := p.getInternalConfig(ctx, repo.CredentialsName)
|
||||
cfgInternal, err := p.getInternalConfig(ctx, repo.CredentialsName, repo.GetBalancerType())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "fetching internal config")
|
||||
}
|
||||
|
|
@ -126,7 +126,7 @@ 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.CredentialsName)
|
||||
internalCfg, err := p.getInternalConfig(ctx, repo.CredentialsName, repo.GetBalancerType())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "fetching internal config")
|
||||
}
|
||||
|
|
@ -171,7 +171,7 @@ func (p *poolManagerCtrl) CreateOrgPoolManager(ctx context.Context, org params.O
|
|||
p.mux.Lock()
|
||||
defer p.mux.Unlock()
|
||||
|
||||
cfgInternal, err := p.getInternalConfig(ctx, org.CredentialsName)
|
||||
cfgInternal, err := p.getInternalConfig(ctx, org.CredentialsName, org.GetBalancerType())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "fetching internal config")
|
||||
}
|
||||
|
|
@ -192,7 +192,7 @@ 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.CredentialsName)
|
||||
internalCfg, err := p.getInternalConfig(ctx, org.CredentialsName, org.GetBalancerType())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "fetching internal config")
|
||||
}
|
||||
|
|
@ -237,7 +237,7 @@ func (p *poolManagerCtrl) CreateEnterprisePoolManager(ctx context.Context, enter
|
|||
p.mux.Lock()
|
||||
defer p.mux.Unlock()
|
||||
|
||||
cfgInternal, err := p.getInternalConfig(ctx, enterprise.CredentialsName)
|
||||
cfgInternal, err := p.getInternalConfig(ctx, enterprise.CredentialsName, enterprise.GetBalancerType())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "fetching internal config")
|
||||
}
|
||||
|
|
@ -258,7 +258,7 @@ 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.CredentialsName)
|
||||
internalCfg, err := p.getInternalConfig(ctx, enterprise.CredentialsName, enterprise.GetBalancerType())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "fetching internal config")
|
||||
}
|
||||
|
|
@ -299,7 +299,7 @@ func (p *poolManagerCtrl) GetEnterprisePoolManagers() (map[string]common.PoolMan
|
|||
return p.enterprises, nil
|
||||
}
|
||||
|
||||
func (p *poolManagerCtrl) getInternalConfig(ctx context.Context, credsName string) (params.Internal, error) {
|
||||
func (p *poolManagerCtrl) getInternalConfig(ctx context.Context, credsName string, poolBalancerType params.PoolBalancerType) (params.Internal, error) {
|
||||
creds, ok := p.credentials[credsName]
|
||||
if !ok {
|
||||
return params.Internal{}, runnerErrors.NewBadRequestError("invalid credential name (%s)", credsName)
|
||||
|
|
@ -325,6 +325,7 @@ func (p *poolManagerCtrl) getInternalConfig(ctx context.Context, credsName strin
|
|||
BaseWebhookURL: p.config.Default.WebhookURL,
|
||||
ControllerWebhookURL: controllerWebhookURL,
|
||||
JWTSecret: p.config.JWTAuth.Secret,
|
||||
PoolBalancerType: poolBalancerType,
|
||||
GithubCredentialsDetails: params.GithubCredentials{
|
||||
Name: creds.Name,
|
||||
Description: creds.Description,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue