Adding Repo Level Settings (#1145)

pull/3490/head
Johannes Batzill 2024-03-28 03:36:15 +00:00 committed by Harness
parent 4deed68349
commit 39a998eacd
31 changed files with 1221 additions and 35 deletions

View File

@ -24,6 +24,7 @@ import (
"github.com/harness/gitness/app/auth/authz"
eventsgit "github.com/harness/gitness/app/events/git"
"github.com/harness/gitness/app/services/protection"
"github.com/harness/gitness/app/services/settings"
"github.com/harness/gitness/app/store"
"github.com/harness/gitness/app/url"
"github.com/harness/gitness/types"
@ -38,7 +39,8 @@ type Controller struct {
pullreqStore store.PullReqStore
urlProvider url.Provider
protectionManager *protection.Manager
resourceLimiter limiter.ResourceLimiter
limiter limiter.ResourceLimiter
settings *settings.Service
preReceiveExtender PreReceiveExtender
updateExtender UpdateExtender
postReceiveExtender PostReceiveExtender
@ -53,6 +55,7 @@ func NewController(
urlProvider url.Provider,
protectionManager *protection.Manager,
limiter limiter.ResourceLimiter,
settings *settings.Service,
preReceiveExtender PreReceiveExtender,
updateExtender UpdateExtender,
postReceiveExtender PostReceiveExtender,
@ -66,7 +69,8 @@ func NewController(
pullreqStore: pullreqStore,
urlProvider: urlProvider,
protectionManager: protectionManager,
resourceLimiter: limiter,
limiter: limiter,
settings: settings,
preReceiveExtender: preReceiveExtender,
updateExtender: updateExtender,
postReceiveExtender: postReceiveExtender,

View File

@ -46,7 +46,7 @@ func (c *Controller) PreReceive(
return hook.Output{}, err
}
if err := c.resourceLimiter.RepoSize(ctx, in.RepoID); err != nil {
if err := c.limiter.RepoSize(ctx, in.RepoID); err != nil {
return hook.Output{}, fmt.Errorf(
"resource limit exceeded: %w",
limiter.ErrMaxRepoSizeReached)

View File

@ -30,6 +30,7 @@ import (
"github.com/harness/gitness/app/services/importer"
"github.com/harness/gitness/app/services/keywordsearch"
"github.com/harness/gitness/app/services/protection"
"github.com/harness/gitness/app/services/settings"
"github.com/harness/gitness/app/store"
"github.com/harness/gitness/app/url"
"github.com/harness/gitness/git"
@ -56,6 +57,7 @@ type Controller struct {
pipelineStore store.PipelineStore
principalStore store.PrincipalStore
ruleStore store.RuleStore
settings *settings.Service
principalInfoCache store.PrincipalInfoCache
protectionManager *protection.Manager
git git.Interface
@ -79,6 +81,7 @@ func NewController(
pipelineStore store.PipelineStore,
principalStore store.PrincipalStore,
ruleStore store.RuleStore,
settings *settings.Service,
principalInfoCache store.PrincipalInfoCache,
protectionManager *protection.Manager,
git git.Interface,
@ -102,6 +105,7 @@ func NewController(
pipelineStore: pipelineStore,
principalStore: principalStore,
ruleStore: ruleStore,
settings: settings,
principalInfoCache: principalInfoCache,
protectionManager: protectionManager,
git: git,
@ -121,20 +125,11 @@ func (c *Controller) getRepo(
ctx context.Context,
repoRef string,
) (*types.Repository, error) {
if repoRef == "" {
return nil, usererror.BadRequest("A valid repository reference must be provided.")
}
repo, err := c.repoStore.FindByRef(ctx, repoRef)
if err != nil {
return nil, fmt.Errorf("failed to find repository: %w", err)
}
if repo.Importing {
return nil, usererror.BadRequest("Repository import is in progress.")
}
return repo, nil
return GetRepo(
ctx,
c.repoStore,
repoRef,
)
}
// getRepoCheckAccess fetches an active repo (not one that is currently being imported)
@ -146,16 +141,15 @@ func (c *Controller) getRepoCheckAccess(
reqPermission enum.Permission,
orPublic bool,
) (*types.Repository, error) {
repo, err := c.getRepo(ctx, repoRef)
if err != nil {
return nil, fmt.Errorf("failed to find repo: %w", err)
}
if err = apiauth.CheckRepo(ctx, c.authorizer, session, repo, reqPermission, orPublic); err != nil {
return nil, fmt.Errorf("access check failed: %w", err)
}
return repo, nil
return GetRepoCheckAccess(
ctx,
c.repoStore,
c.authorizer,
session,
repoRef,
reqPermission,
orPublic,
)
}
func (c *Controller) validateParentRef(parentRef string) error {

View File

@ -0,0 +1,73 @@
// Copyright 2023 Harness, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package repo
import (
"context"
"fmt"
apiauth "github.com/harness/gitness/app/api/auth"
"github.com/harness/gitness/app/api/usererror"
"github.com/harness/gitness/app/auth"
"github.com/harness/gitness/app/auth/authz"
"github.com/harness/gitness/app/store"
"github.com/harness/gitness/types"
"github.com/harness/gitness/types/enum"
)
// GetRepo fetches an active repo (not one that is currently being imported).
func GetRepo(
ctx context.Context,
repoStore store.RepoStore,
repoRef string,
) (*types.Repository, error) {
if repoRef == "" {
return nil, usererror.BadRequest("A valid repository reference must be provided.")
}
repo, err := repoStore.FindByRef(ctx, repoRef)
if err != nil {
return nil, fmt.Errorf("failed to find repository: %w", err)
}
if repo.Importing {
return nil, usererror.BadRequest("Repository import is in progress.")
}
return repo, nil
}
// GetRepoCheckAccess fetches an active repo (not one that is currently being imported)
// and checks if the current user has permission to access it.
func GetRepoCheckAccess(
ctx context.Context,
repoStore store.RepoStore,
authorizer authz.Authorizer,
session *auth.Session,
repoRef string,
reqPermission enum.Permission,
orPublic bool,
) (*types.Repository, error) {
repo, err := GetRepo(ctx, repoStore, repoRef)
if err != nil {
return nil, fmt.Errorf("failed to find repo: %w", err)
}
if err = apiauth.CheckRepo(ctx, authorizer, session, repo, reqPermission, orPublic); err != nil {
return nil, fmt.Errorf("access check failed: %w", err)
}
return repo, nil
}

View File

@ -22,6 +22,7 @@ import (
"github.com/harness/gitness/app/services/importer"
"github.com/harness/gitness/app/services/keywordsearch"
"github.com/harness/gitness/app/services/protection"
"github.com/harness/gitness/app/services/settings"
"github.com/harness/gitness/app/store"
"github.com/harness/gitness/app/url"
"github.com/harness/gitness/git"
@ -48,6 +49,7 @@ func ProvideController(
pipelineStore store.PipelineStore,
principalStore store.PrincipalStore,
ruleStore store.RuleStore,
settings *settings.Service,
principalInfoCache store.PrincipalInfoCache,
protectionManager *protection.Manager,
rpcClient git.Interface,
@ -63,7 +65,7 @@ func ProvideController(
return NewController(config, tx, urlProvider,
authorizer, repoStore,
spaceStore, pipelineStore,
principalStore, ruleStore, principalInfoCache, protectionManager,
principalStore, ruleStore, settings, principalInfoCache, protectionManager,
rpcClient, importer, codeOwners, reporeporter, indexer, limiter, mtxManager, identifierCheck, repoChecks)
}

View File

@ -0,0 +1,65 @@
// Copyright 2023 Harness, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package reposettings
import (
"context"
"github.com/harness/gitness/app/api/controller/repo"
"github.com/harness/gitness/app/auth"
"github.com/harness/gitness/app/auth/authz"
"github.com/harness/gitness/app/services/settings"
"github.com/harness/gitness/app/store"
"github.com/harness/gitness/types"
"github.com/harness/gitness/types/enum"
)
type Controller struct {
authorizer authz.Authorizer
repoStore store.RepoStore
settings *settings.Service
}
func NewController(
authorizer authz.Authorizer,
repoStore store.RepoStore,
settings *settings.Service,
) *Controller {
return &Controller{
authorizer: authorizer,
repoStore: repoStore,
settings: settings,
}
}
// getRepoCheckAccess fetches an active repo (not one that is currently being imported)
// and checks if the current user has permission to access it.
func (c *Controller) getRepoCheckAccess(
ctx context.Context,
session *auth.Session,
repoRef string,
reqPermission enum.Permission,
orPublic bool,
) (*types.Repository, error) {
return repo.GetRepoCheckAccess(
ctx,
c.repoStore,
c.authorizer,
session,
repoRef,
reqPermission,
orPublic,
)
}

View File

@ -0,0 +1,46 @@
// Copyright 2023 Harness, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package reposettings
import (
"github.com/harness/gitness/app/services/settings"
"github.com/gotidy/ptr"
)
// SecuritySettings represents the security related part of repository settings as exposed externally.
type SecuritySettings struct {
SecretScanningEnabled *bool `json:"secret_scanning_enabled"`
}
func GetDefaultSecuritySettings() *SecuritySettings {
return &SecuritySettings{
SecretScanningEnabled: ptr.Bool(settings.DefaultSecretScanningEnabled),
}
}
func GetSecuritySettingsMappings(s *SecuritySettings) []settings.SettingHandler {
return []settings.SettingHandler{
settings.Mapping(settings.KeySecretScanningEnabled, s.SecretScanningEnabled),
}
}
func GetSecuritySettingsAsKeyValues(s *SecuritySettings) []settings.KeyValue {
kvs := make([]settings.KeyValue, 0, 1)
if s.SecretScanningEnabled != nil {
kvs = append(kvs, settings.KeyValue{Key: settings.KeySecretScanningEnabled, Value: *s.SecretScanningEnabled})
}
return kvs
}

View File

@ -0,0 +1,44 @@
// Copyright 2023 Harness, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package reposettings
import (
"context"
"fmt"
"github.com/harness/gitness/app/auth"
"github.com/harness/gitness/types/enum"
)
// SecurityFind returns the security settings of a repo.
func (c *Controller) SecurityFind(
ctx context.Context,
session *auth.Session,
repoRef string,
) (*SecuritySettings, error) {
repo, err := c.getRepoCheckAccess(ctx, session, repoRef, enum.PermissionRepoView, true)
if err != nil {
return nil, err
}
out := GetDefaultSecuritySettings()
mappings := GetSecuritySettingsMappings(out)
err = c.settings.RepoMap(ctx, repo.ID, mappings...)
if err != nil {
return nil, fmt.Errorf("failed to map settings: %w", err)
}
return out, nil
}

View File

@ -0,0 +1,51 @@
// Copyright 2023 Harness, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package reposettings
import (
"context"
"fmt"
"github.com/harness/gitness/app/auth"
"github.com/harness/gitness/types/enum"
)
// SecurityUpdate updates the security settings of the repo.
func (c *Controller) SecurityUpdate(
ctx context.Context,
session *auth.Session,
repoRef string,
in *SecuritySettings,
) (*SecuritySettings, error) {
repo, err := c.getRepoCheckAccess(ctx, session, repoRef, enum.PermissionRepoEdit, false)
if err != nil {
return nil, err
}
err = c.settings.RepoSetMany(ctx, repo.ID, GetSecuritySettingsAsKeyValues(in)...)
if err != nil {
return nil, fmt.Errorf("failed to set settings: %w", err)
}
// read all settings and return complete config
out := GetDefaultSecuritySettings()
mappings := GetSecuritySettingsMappings(out)
err = c.settings.RepoMap(ctx, repo.ID, mappings...)
if err != nil {
return nil, fmt.Errorf("failed to map settings: %w", err)
}
return out, nil
}

View File

@ -0,0 +1,36 @@
// Copyright 2023 Harness, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package reposettings
import (
"github.com/harness/gitness/app/auth/authz"
"github.com/harness/gitness/app/services/settings"
"github.com/harness/gitness/app/store"
"github.com/google/wire"
)
// WireSet provides a wire set for this package.
var WireSet = wire.NewSet(
ProvideController,
)
func ProvideController(
authorizer authz.Authorizer,
repoStore store.RepoStore,
settings *settings.Service,
) *Controller {
return NewController(authorizer, repoStore, settings)
}

View File

@ -0,0 +1,43 @@
// Copyright 2023 Harness, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package reposettings
import (
"net/http"
"github.com/harness/gitness/app/api/controller/reposettings"
"github.com/harness/gitness/app/api/render"
"github.com/harness/gitness/app/api/request"
)
func HandleSecurityFind(repoSettingCtrl *reposettings.Controller) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
session, _ := request.AuthSessionFrom(ctx)
repoRef, err := request.GetRepoRefFromPath(r)
if err != nil {
render.TranslatedUserError(ctx, w, err)
return
}
settings, err := repoSettingCtrl.SecurityFind(ctx, session, repoRef)
if err != nil {
render.TranslatedUserError(ctx, w, err)
return
}
render.JSON(w, http.StatusOK, settings)
}
}

View File

@ -0,0 +1,51 @@
// Copyright 2023 Harness, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package reposettings
import (
"encoding/json"
"net/http"
"github.com/harness/gitness/app/api/controller/reposettings"
"github.com/harness/gitness/app/api/render"
"github.com/harness/gitness/app/api/request"
)
func HandleSecurityUpdate(repoSettingCtrl *reposettings.Controller) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
session, _ := request.AuthSessionFrom(ctx)
repoRef, err := request.GetRepoRefFromPath(r)
if err != nil {
render.TranslatedUserError(ctx, w, err)
return
}
in := new(reposettings.SecuritySettings)
err = json.NewDecoder(r.Body).Decode(in)
if err != nil {
render.BadRequestf(ctx, w, "Invalid request body: %s.", err)
return
}
settings, err := repoSettingCtrl.SecurityUpdate(ctx, session, repoRef, in)
if err != nil {
render.TranslatedUserError(ctx, w, err)
return
}
render.JSON(w, http.StatusOK, settings)
}
}

View File

@ -20,6 +20,7 @@ import (
"github.com/harness/gitness/app/auth/authz"
eventsgit "github.com/harness/gitness/app/events/git"
"github.com/harness/gitness/app/services/protection"
"github.com/harness/gitness/app/services/settings"
"github.com/harness/gitness/app/store"
"github.com/harness/gitness/app/url"
"github.com/harness/gitness/git"
@ -52,6 +53,7 @@ func ProvideController(
protectionManager *protection.Manager,
githookFactory hook.ClientFactory,
limiter limiter.ResourceLimiter,
settings *settings.Service,
preReceiveExtender githook.PreReceiveExtender,
updateExtender githook.UpdateExtender,
postReceiveExtender githook.PostReceiveExtender,
@ -65,6 +67,7 @@ func ProvideController(
urlProvider,
protectionManager,
limiter,
settings,
preReceiveExtender,
updateExtender,
postReceiveExtender,

View File

@ -30,6 +30,7 @@ import (
"github.com/harness/gitness/app/api/controller/principal"
"github.com/harness/gitness/app/api/controller/pullreq"
"github.com/harness/gitness/app/api/controller/repo"
"github.com/harness/gitness/app/api/controller/reposettings"
"github.com/harness/gitness/app/api/controller/secret"
"github.com/harness/gitness/app/api/controller/serviceaccount"
"github.com/harness/gitness/app/api/controller/space"
@ -51,6 +52,7 @@ import (
handlerprincipal "github.com/harness/gitness/app/api/handler/principal"
handlerpullreq "github.com/harness/gitness/app/api/handler/pullreq"
handlerrepo "github.com/harness/gitness/app/api/handler/repo"
handlerreposettings "github.com/harness/gitness/app/api/handler/reposettings"
"github.com/harness/gitness/app/api/handler/resource"
handlersecret "github.com/harness/gitness/app/api/handler/secret"
handlerserviceaccount "github.com/harness/gitness/app/api/handler/serviceaccount"
@ -97,6 +99,7 @@ func NewAPIHandler(
config *types.Config,
authenticator authn.Authenticator,
repoCtrl *repo.Controller,
repoSettingsCtrl *reposettings.Controller,
executionCtrl *execution.Controller,
logCtrl *logs.Controller,
spaceCtrl *space.Controller,
@ -139,7 +142,7 @@ func NewAPIHandler(
r.Use(middlewareauthn.Attempt(authenticator))
r.Route("/v1", func(r chi.Router) {
setupRoutesV1(r, appCtx, config, repoCtrl, executionCtrl, triggerCtrl, logCtrl, pipelineCtrl,
setupRoutesV1(r, appCtx, config, repoCtrl, repoSettingsCtrl, executionCtrl, triggerCtrl, logCtrl, pipelineCtrl,
connectorCtrl, templateCtrl, pluginCtrl, secretCtrl, spaceCtrl, pullreqCtrl,
webhookCtrl, githookCtrl, git, saCtrl, userCtrl, principalCtrl, checkCtrl, sysCtrl, uploadCtrl,
searchCtrl)
@ -167,6 +170,7 @@ func setupRoutesV1(r chi.Router,
appCtx context.Context,
config *types.Config,
repoCtrl *repo.Controller,
repoSettingsCtrl *reposettings.Controller,
executionCtrl *execution.Controller,
triggerCtrl *trigger.Controller,
logCtrl *logs.Controller,
@ -189,8 +193,8 @@ func setupRoutesV1(r chi.Router,
searchCtrl *keywordsearch.Controller,
) {
setupSpaces(r, appCtx, spaceCtrl)
setupRepos(r, repoCtrl, pipelineCtrl, executionCtrl, triggerCtrl, logCtrl, pullreqCtrl, webhookCtrl, checkCtrl,
uploadCtrl)
setupRepos(r, repoCtrl, repoSettingsCtrl, pipelineCtrl, executionCtrl, triggerCtrl,
logCtrl, pullreqCtrl, webhookCtrl, checkCtrl, uploadCtrl)
setupConnectors(r, connectorCtrl)
setupTemplates(r, templateCtrl)
setupSecrets(r, secretCtrl)
@ -248,6 +252,7 @@ func setupSpaces(r chi.Router, appCtx context.Context, spaceCtrl *space.Controll
func setupRepos(r chi.Router,
repoCtrl *repo.Controller,
repoSettingsCtrl *reposettings.Controller,
pipelineCtrl *pipeline.Controller,
executionCtrl *execution.Controller,
triggerCtrl *trigger.Controller,
@ -269,6 +274,9 @@ func setupRepos(r chi.Router,
r.Post("/purge", handlerrepo.HandlePurge(repoCtrl))
r.Post("/restore", handlerrepo.HandleRestore(repoCtrl))
r.Get("/settings/security", handlerreposettings.HandleSecurityFind(repoSettingsCtrl))
r.Patch("/settings/security", handlerreposettings.HandleSecurityUpdate(repoSettingsCtrl))
r.Post("/move", handlerrepo.HandleMove(repoCtrl))
r.Get("/service-accounts", handlerrepo.HandleListServiceAccounts(repoCtrl))

View File

@ -29,6 +29,7 @@ import (
"github.com/harness/gitness/app/api/controller/principal"
"github.com/harness/gitness/app/api/controller/pullreq"
"github.com/harness/gitness/app/api/controller/repo"
"github.com/harness/gitness/app/api/controller/reposettings"
"github.com/harness/gitness/app/api/controller/secret"
"github.com/harness/gitness/app/api/controller/serviceaccount"
"github.com/harness/gitness/app/api/controller/space"
@ -92,6 +93,7 @@ func ProvideAPIHandler(
config *types.Config,
authenticator authn.Authenticator,
repoCtrl *repo.Controller,
repoSettingsCtrl *reposettings.Controller,
executionCtrl *execution.Controller,
logCtrl *logs.Controller,
spaceCtrl *space.Controller,
@ -114,7 +116,7 @@ func ProvideAPIHandler(
searchCtrl *keywordsearch.Controller,
) APIHandler {
return NewAPIHandler(appCtx, config,
authenticator, repoCtrl, executionCtrl, logCtrl, spaceCtrl, pipelineCtrl,
authenticator, repoCtrl, repoSettingsCtrl, executionCtrl, logCtrl, spaceCtrl, pipelineCtrl,
secretCtrl, triggerCtrl, connectorCtrl, templateCtrl, pluginCtrl, pullreqCtrl, webhookCtrl,
githookCtrl, git, saCtrl, userCtrl, principalCtrl, checkCtrl, sysCtrl, blobCtrl, searchCtrl)
}

View File

@ -0,0 +1,62 @@
// Copyright 2023 Harness, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package settings
import (
"context"
"fmt"
)
// RepoGet is a helper method for getting a setting of a specific type for a repo.
func RepoGet[T any](
ctx context.Context,
s *Service,
repoID int64,
key Key,
dflt T,
) (T, error) {
var out T
ok, err := s.RepoGet(ctx, repoID, key, &out)
if err != nil {
return out, err
}
if !ok {
return dflt, nil
}
return out, nil
}
// RepoGetRequired is a helper method for getting a setting of a specific type for a repo.
// If the setting isn't found, an error is returned.
func RepoGetRequired[T any](
ctx context.Context,
s *Service,
repoID int64,
key Key,
) (T, error) {
var out T
ok, err := s.RepoGet(ctx, repoID, key, &out)
if err != nil {
return out, err
}
if !ok {
return out, fmt.Errorf("setting %q not found", key)
}
return out, nil
}

View File

@ -0,0 +1,72 @@
// Copyright 2023 Harness, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package settings
import (
"context"
"encoding/json"
"fmt"
)
// Mapping returns a SettingHandler that maps the value of the setting with the given key to the target.
func Mapping[T any](key Key, target *T) SettingHandler {
if target == nil {
panic("mapping target can't be nil")
}
return &settingHandlerMapping[T]{
key: key,
required: false,
target: target,
}
}
// MappingRequired returns a SettingHandler that maps the value of the setting with the given key to the target.
// If the setting wasn't found an error is returned.
func MappingRequired[T any](key Key, target *T) SettingHandler {
if target == nil {
panic("mapping target can't be nil")
}
return &settingHandlerMapping[T]{
key: key,
required: true,
target: target,
}
}
var _ SettingHandler = (*settingHandlerMapping[any])(nil)
// settingHandlerMapping is a setting handler that maps the value of a setting to the provided target.
type settingHandlerMapping[T any] struct {
key Key
required bool
target *T
}
func (q *settingHandlerMapping[T]) Key() Key {
return q.key
}
func (q *settingHandlerMapping[T]) Required() bool {
return q.required
}
func (q *settingHandlerMapping[T]) Handle(_ context.Context, raw []byte) error {
err := json.Unmarshal(raw, q.target)
if err != nil {
return fmt.Errorf("failed to unmarshal setting value: %w", err)
}
return nil
}

View File

@ -0,0 +1,169 @@
// Copyright 2023 Harness, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package settings
import (
"context"
"encoding/json"
"errors"
"fmt"
appstore "github.com/harness/gitness/app/store"
"github.com/harness/gitness/store"
"github.com/harness/gitness/types/enum"
)
// KeyValue is a struct used for upserting many entries.
type KeyValue struct {
Key Key
Value any
}
// SettingHandler is an abstraction of a component that's handling a single setting value as part of
// calling service.Map.
type SettingHandler interface {
Key() Key
Required() bool
Handle(ctx context.Context, raw []byte) error
}
// Service is used to enhance interaction with the settings store.
type Service struct {
settingsStore appstore.SettingsStore
}
func NewService(
settingsStore appstore.SettingsStore,
) *Service {
return &Service{
settingsStore: settingsStore,
}
}
// Set sets the value of the setting with the given key for the given scope.
func (s *Service) Set(
ctx context.Context,
scope enum.SettingsScope,
scopeID int64,
key Key,
value any,
) error {
raw, err := json.Marshal(value)
if err != nil {
return fmt.Errorf("failed to marshal setting value: %w", err)
}
err = s.settingsStore.Upsert(
ctx,
scope,
scopeID,
string(key),
raw,
)
if err != nil {
return fmt.Errorf("failed to upsert setting in store: %w", err)
}
return nil
}
// SetMany sets the value of the settings with the given keys for the given scope.
func (s *Service) SetMany(
ctx context.Context,
scope enum.SettingsScope,
scopeID int64,
keyValues ...KeyValue,
) error {
// TODO: batch upsert
for _, kv := range keyValues {
if err := s.Set(ctx, scope, scopeID, kv.Key, kv.Value); err != nil {
return fmt.Errorf("failed to set setting for key %q: %w", kv.Key, err)
}
}
return nil
}
// Get returns the value of the setting with the given key for the given scope.
func (s *Service) Get(
ctx context.Context,
scope enum.SettingsScope,
scopeID int64,
key Key,
out any,
) (bool, error) {
raw, err := s.settingsStore.Find(
ctx,
scope,
scopeID,
string(key),
)
if errors.Is(err, store.ErrResourceNotFound) {
return false, nil
}
if err != nil {
return false, fmt.Errorf("failed to find setting in store: %w", err)
}
err = json.Unmarshal(raw, &out)
if err != nil {
return false, fmt.Errorf("failed to unmarshal setting value: %w", err)
}
return true, nil
}
// Map maps all available settings using the provided handlers for the given scope.
func (s *Service) Map(
ctx context.Context,
scope enum.SettingsScope,
scopeID int64,
handlers ...SettingHandler,
) error {
if len(handlers) == 0 {
return nil
}
keys := make([]string, len(handlers))
for i, m := range handlers {
keys[i] = string(m.Key())
}
rawValues, err := s.settingsStore.FindMany(
ctx,
scope,
scopeID,
keys...,
)
if err != nil {
return fmt.Errorf("failed to find settings in store: %w", err)
}
for _, m := range handlers {
rawValue, found := rawValues[string(m.Key())]
if !found && m.Required() {
return fmt.Errorf("required setting %q not found", m.Key())
}
if !found {
continue
}
if err = m.Handle(ctx, rawValue); err != nil {
return fmt.Errorf("failed to handle value for setting %q: %w", m.Key(), err)
}
}
return nil
}

View File

@ -0,0 +1,81 @@
// Copyright 2023 Harness, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package settings
import (
"context"
"github.com/harness/gitness/types/enum"
)
// RepoSet sets the value of the setting with the given key for the given repo.
func (s *Service) RepoSet(
ctx context.Context,
repoID int64,
key Key,
value any,
) error {
return s.Set(
ctx,
enum.SettingsScopeRepo,
repoID,
key,
value,
)
}
// RepoSetMany sets the value of the settings with the given keys for the given repo.
func (s *Service) RepoSetMany(
ctx context.Context,
repoID int64,
keyValues ...KeyValue,
) error {
return s.SetMany(
ctx,
enum.SettingsScopeRepo,
repoID,
keyValues...,
)
}
// RepoGet returns the value of the setting with the given key for the given repo.
func (s *Service) RepoGet(
ctx context.Context,
repoID int64,
key Key,
out any,
) (bool, error) {
return s.Get(
ctx,
enum.SettingsScopeRepo,
repoID,
key,
out,
)
}
// RepoMap maps all available settings using the provided handlers for the given repo.
func (s *Service) RepoMap(
ctx context.Context,
repoID int64,
handlers ...SettingHandler,
) error {
return s.Map(
ctx,
enum.SettingsScopeRepo,
repoID,
handlers...,
)
}

View File

@ -0,0 +1,23 @@
// Copyright 2023 Harness, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package settings
type Key string
var (
// KeySecretScanningEnabled [bool] enables secret scanning if set to true.
KeySecretScanningEnabled Key = "secret_scanning_enabled"
DefaultSecretScanningEnabled = false
)

View File

@ -0,0 +1,31 @@
// Copyright 2023 Harness, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package settings
import (
"github.com/harness/gitness/app/store"
"github.com/google/wire"
)
var WireSet = wire.NewSet(
ProvideService,
)
func ProvideService(
settingsStore store.SettingsStore,
) *Service {
return NewService(settingsStore)
}

View File

@ -17,6 +17,7 @@ package store
import (
"context"
"encoding/json"
"time"
"github.com/harness/gitness/types"
@ -239,6 +240,35 @@ type (
ListSizeInfos(ctx context.Context) ([]*types.RepositorySizeInfo, error)
}
// SettingsStore defines the settings storage.
SettingsStore interface {
// Find returns the value of the setting with the given key for the provided scope.
Find(
ctx context.Context,
scope enum.SettingsScope,
scopeID int64,
key string,
) (json.RawMessage, error)
// FindMany returns the values of the settings with the given keys for the provided scope.
// NOTE: if a setting key doesn't exist the map just won't contain an entry for it (no error returned).
FindMany(
ctx context.Context,
scope enum.SettingsScope,
scopeID int64,
keys ...string,
) (map[string]json.RawMessage, error)
// Upsert upserts the value of the setting with the given key for the provided scope.
Upsert(
ctx context.Context,
scope enum.SettingsScope,
scopeID int64,
key string,
value json.RawMessage,
) error
}
// RepoGitInfoView defines the repository GitUID view.
RepoGitInfoView interface {
Find(ctx context.Context, id int64) (*types.RepositoryGitInfo, error)

View File

@ -0,0 +1 @@
DROP TABLE settings;

View File

@ -0,0 +1,24 @@
CREATE TABLE settings (
setting_id SERIAL PRIMARY KEY
,setting_space_id INTEGER
,setting_repo_id INTEGER
,setting_key TEXT NOT NULL
,setting_value JSON
,CONSTRAINT fk_settings_space_id FOREIGN KEY (setting_space_id)
REFERENCES spaces (space_id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE CASCADE
,CONSTRAINT fk_settings_repo_id FOREIGN KEY (setting_repo_id)
REFERENCES repositories (repo_id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE CASCADE
);
CREATE UNIQUE INDEX settings_space_id_key
ON settings(setting_space_id, LOWER(setting_key))
WHERE setting_space_id IS NOT NULL;
CREATE UNIQUE INDEX settings_repo_id_key
ON settings(setting_repo_id, LOWER(setting_key))
WHERE setting_repo_id IS NOT NULL;

View File

@ -0,0 +1 @@
DROP TABLE settings;

View File

@ -0,0 +1,24 @@
CREATE TABLE settings (
setting_id INTEGER PRIMARY KEY AUTOINCREMENT
,setting_space_id INTEGER
,setting_repo_id INTEGER
,setting_key TEXT NOT NULL
,setting_value TEXT
,CONSTRAINT fk_settings_space_id FOREIGN KEY (setting_space_id)
REFERENCES spaces (space_id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE CASCADE
,CONSTRAINT fk_settings_repo_id FOREIGN KEY (setting_repo_id)
REFERENCES repositories (repo_id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE CASCADE
);
CREATE UNIQUE INDEX settings_space_id_key
ON settings(setting_space_id, LOWER(setting_key))
WHERE setting_space_id IS NOT NULL;
CREATE UNIQUE INDEX settings_repo_id_key
ON settings(setting_repo_id, LOWER(setting_key))
WHERE setting_repo_id IS NOT NULL;

View File

@ -0,0 +1,194 @@
// Copyright 2023 Harness, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package database
import (
"context"
"encoding/json"
"fmt"
"strings"
"github.com/harness/gitness/app/store"
"github.com/harness/gitness/store/database"
"github.com/harness/gitness/store/database/dbtx"
"github.com/harness/gitness/types/enum"
"github.com/Masterminds/squirrel"
"github.com/guregu/null"
"github.com/jmoiron/sqlx"
)
var _ store.SettingsStore = (*SettingsStore)(nil)
// NewSettingsStore returns a new SettingsStore.
func NewSettingsStore(db *sqlx.DB) *SettingsStore {
return &SettingsStore{
db: db,
}
}
// SettingsStore implements store.SettingsStore backed by a relational database.
type SettingsStore struct {
db *sqlx.DB
}
// setting is an internal representation used to store setting data in the database.
type setting struct {
ID int64 `db:"setting_id"`
SpaceID null.Int `db:"setting_space_id"`
RepoID null.Int `db:"setting_repo_id"`
Key string `db:"setting_key"`
Value json.RawMessage `db:"setting_value"`
}
const (
settingsColumns = `
setting_id
,setting_space_id
,setting_repo_id
,setting_key
,setting_value`
)
func (s *SettingsStore) Find(
ctx context.Context,
scope enum.SettingsScope,
scopeID int64,
key string,
) (json.RawMessage, error) {
stmt := database.Builder.
Select(settingsColumns).
From("settings").
Where("LOWER(setting_key) = ?", strings.ToLower(key))
switch scope {
case enum.SettingsScopeSpace:
stmt = stmt.Where("setting_space_id = ?", scopeID)
case enum.SettingsScopeRepo:
stmt = stmt.Where("setting_repo_id = ?", scopeID)
default:
return nil, fmt.Errorf("setting scope %q is not supported", scope)
}
sql, args, err := stmt.ToSql()
if err != nil {
return nil, fmt.Errorf("failed to convert query to sql: %w", err)
}
db := dbtx.GetAccessor(ctx, s.db)
dst := &setting{}
if err := db.GetContext(ctx, dst, sql, args...); err != nil {
return nil, database.ProcessSQLErrorf(ctx, err, "Select query failed")
}
return dst.Value, nil
}
func (s *SettingsStore) FindMany(
ctx context.Context,
scope enum.SettingsScope,
scopeID int64,
keys ...string,
) (map[string]json.RawMessage, error) {
if len(keys) == 0 {
return map[string]json.RawMessage{}, nil
}
keysLower := make([]string, len(keys))
for i, k := range keys {
keysLower[i] = strings.ToLower(k)
}
stmt := database.Builder.
Select(settingsColumns).
From("settings").
Where(squirrel.Eq{"LOWER(setting_key)": keysLower})
switch scope {
case enum.SettingsScopeSpace:
stmt = stmt.Where("setting_space_id = ?", scopeID)
case enum.SettingsScopeRepo:
stmt = stmt.Where("setting_repo_id = ?", scopeID)
default:
return nil, fmt.Errorf("setting scope %q is not supported", scope)
}
sql, args, err := stmt.ToSql()
if err != nil {
return nil, fmt.Errorf("failed to convert query to sql: %w", err)
}
db := dbtx.GetAccessor(ctx, s.db)
dst := []*setting{}
if err := db.SelectContext(ctx, &dst, sql, args...); err != nil {
return nil, database.ProcessSQLErrorf(ctx, err, "Select query failed")
}
out := map[string]json.RawMessage{}
for _, d := range dst {
out[d.Key] = d.Value
}
return out, nil
}
func (s *SettingsStore) Upsert(ctx context.Context,
scope enum.SettingsScope,
scopeID int64,
key string,
value json.RawMessage,
) error {
stmt := database.Builder.
Insert("").
Into("settings").
Columns(
"setting_space_id",
"setting_repo_id",
"setting_key",
"setting_value",
)
switch scope {
case enum.SettingsScopeSpace:
stmt = stmt.Values(null.IntFrom(scopeID), null.Int{}, key, value)
stmt = stmt.Suffix(`ON CONFLICT (setting_space_id, LOWER(setting_key)) WHERE setting_space_id IS NOT NULL DO`)
case enum.SettingsScopeRepo:
stmt = stmt.Values(null.Int{}, null.IntFrom(scopeID), key, value)
stmt = stmt.Suffix(`ON CONFLICT (setting_repo_id, LOWER(setting_key)) WHERE setting_repo_id IS NOT NULL DO`)
default:
return fmt.Errorf("setting scope %q is not supported", scope)
}
stmt = stmt.Suffix(`
UPDATE SET
setting_value = EXCLUDED.setting_value
WHERE
settings.setting_value <> EXCLUDED.setting_value`)
sql, args, err := stmt.ToSql()
if err != nil {
return fmt.Errorf("failed to convert query to sql: %w", err)
}
db := dbtx.GetAccessor(ctx, s.db)
if _, err := db.ExecContext(ctx, sql, args...); err != nil {
return database.ProcessSQLErrorf(ctx, err, "Upsert query failed")
}
return nil
}

View File

@ -52,6 +52,7 @@ var WireSet = wire.NewSet(
ProvidePullReqFileViewStore,
ProvideWebhookStore,
ProvideWebhookExecutionStore,
ProvideSettingsStore,
ProvideCheckStore,
ProvideConnectorStore,
ProvideTemplateStore,
@ -241,3 +242,8 @@ func ProvideCheckStore(db *sqlx.DB,
) store.CheckStore {
return NewCheckStore(db, principalInfoCache)
}
// ProvideSettingsStore provides a settings store.
func ProvideSettingsStore(db *sqlx.DB) store.SettingsStore {
return NewSettingsStore(db)
}

View File

@ -22,6 +22,7 @@ import (
"github.com/harness/gitness/app/api/controller/principal"
"github.com/harness/gitness/app/api/controller/pullreq"
"github.com/harness/gitness/app/api/controller/repo"
"github.com/harness/gitness/app/api/controller/reposettings"
"github.com/harness/gitness/app/api/controller/secret"
"github.com/harness/gitness/app/api/controller/service"
"github.com/harness/gitness/app/api/controller/serviceaccount"
@ -64,6 +65,7 @@ import (
"github.com/harness/gitness/app/services/protection"
pullreqservice "github.com/harness/gitness/app/services/pullreq"
"github.com/harness/gitness/app/services/reposize"
"github.com/harness/gitness/app/services/settings"
"github.com/harness/gitness/app/services/trigger"
"github.com/harness/gitness/app/services/usergroup"
"github.com/harness/gitness/app/services/webhook"
@ -112,6 +114,7 @@ func initSystem(ctx context.Context, config *types.Config) (*cliserver.System, e
space.WireSet,
limiter.WireSet,
repo.WireSet,
reposettings.WireSet,
pullreq.WireSet,
controllerwebhook.WireSet,
serviceaccount.WireSet,
@ -181,6 +184,7 @@ func initSystem(ctx context.Context, config *types.Config) (*cliserver.System, e
cliserver.ProvideKeywordSearchConfig,
keywordsearch.WireSet,
controllerkeywordsearch.WireSet,
settings.WireSet,
usergroup.WireSet,
openapi.WireSet,
repo.ProvideRepoCheck,

View File

@ -21,6 +21,7 @@ import (
"github.com/harness/gitness/app/api/controller/principal"
pullreq2 "github.com/harness/gitness/app/api/controller/pullreq"
"github.com/harness/gitness/app/api/controller/repo"
"github.com/harness/gitness/app/api/controller/reposettings"
"github.com/harness/gitness/app/api/controller/secret"
"github.com/harness/gitness/app/api/controller/service"
"github.com/harness/gitness/app/api/controller/serviceaccount"
@ -63,6 +64,7 @@ import (
"github.com/harness/gitness/app/services/protection"
"github.com/harness/gitness/app/services/pullreq"
"github.com/harness/gitness/app/services/reposize"
"github.com/harness/gitness/app/services/settings"
trigger2 "github.com/harness/gitness/app/services/trigger"
"github.com/harness/gitness/app/services/usergroup"
"github.com/harness/gitness/app/services/webhook"
@ -126,6 +128,8 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
repoStore := database.ProvideRepoStore(db, spacePathCache, spacePathStore, spaceStore)
pipelineStore := database.ProvidePipelineStore(db)
ruleStore := database.ProvideRuleStore(db, principalInfoCache)
settingsStore := database.ProvideSettingsStore(db)
settingsService := settings.ProvideService(settingsStore)
protectionManager, err := protection.ProvideManager(ruleStore)
if err != nil {
return nil, err
@ -190,7 +194,8 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
}
repoIdentifier := check.ProvideRepoIdentifierCheck()
repoCheck := repo.ProvideRepoCheck()
repoController := repo.ProvideController(config, transactor, provider, authorizer, repoStore, spaceStore, pipelineStore, principalStore, ruleStore, principalInfoCache, protectionManager, gitInterface, repository, codeownersService, reporter, indexer, resourceLimiter, mutexManager, repoIdentifier, repoCheck)
repoController := repo.ProvideController(config, transactor, provider, authorizer, repoStore, spaceStore, pipelineStore, principalStore, ruleStore, settingsService, principalInfoCache, protectionManager, gitInterface, repository, codeownersService, reporter, indexer, resourceLimiter, mutexManager, repoIdentifier, repoCheck)
reposettingsController := reposettings.ProvideController(authorizer, repoStore, settingsService)
executionStore := database.ProvideExecutionStore(db)
checkStore := database.ProvideCheckStore(db, principalInfoCache)
stageStore := database.ProvideStageStore(db)
@ -274,7 +279,7 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
if err != nil {
return nil, err
}
githookController := githook.ProvideController(authorizer, principalStore, repoStore, reporter2, gitInterface, pullReqStore, provider, protectionManager, clientFactory, resourceLimiter, preReceiveExtender, updateExtender, postReceiveExtender)
githookController := githook.ProvideController(authorizer, principalStore, repoStore, reporter2, gitInterface, pullReqStore, provider, protectionManager, clientFactory, resourceLimiter, settingsService, preReceiveExtender, updateExtender, postReceiveExtender)
serviceaccountController := serviceaccount.NewController(principalUID, authorizer, principalStore, spaceStore, repoStore, tokenStore)
principalController := principal.ProvideController(principalStore)
v := check2.ProvideCheckSanitizers()
@ -291,7 +296,7 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
uploadController := upload.ProvideController(authorizer, repoStore, blobStore)
searcher := keywordsearch.ProvideSearcher(localIndexSearcher)
keywordsearchController := keywordsearch2.ProvideController(authorizer, searcher, repoController, spaceController)
apiHandler := router.ProvideAPIHandler(ctx, config, authenticator, repoController, executionController, logsController, spaceController, pipelineController, secretController, triggerController, connectorController, templateController, pluginController, pullreqController, webhookController, githookController, gitInterface, serviceaccountController, controller, principalController, checkController, systemController, uploadController, keywordsearchController)
apiHandler := router.ProvideAPIHandler(ctx, config, authenticator, repoController, reposettingsController, executionController, logsController, spaceController, pipelineController, secretController, triggerController, connectorController, templateController, pluginController, pullreqController, webhookController, githookController, gitInterface, serviceaccountController, controller, principalController, checkController, systemController, uploadController, keywordsearchController)
gitHandler := router.ProvideGitHandler(provider, authenticator, repoController)
openapiService := openapi.ProvideOpenAPIService()
webHandler := router.ProvideWebHandler(config, openapiService)

37
types/enum/settings.go Normal file
View File

@ -0,0 +1,37 @@
// Copyright 2023 Harness, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package enum
// SettingsScope defines the different scopes of a setting.
type SettingsScope string
func (SettingsScope) Enum() []interface{} {
return toInterfaceSlice(GetAllSettingsScopes())
}
var (
// SettingsScopeSpace defines settings stored on a space level.
SettingsScopeSpace SettingsScope = "space"
// SettingsScopeRepo defines settings stored on a repo level.
SettingsScopeRepo SettingsScope = "repo"
)
func GetAllSettingsScopes() []SettingsScope {
return []SettingsScope{
SettingsScopeSpace,
SettingsScopeRepo,
}
}