mirror of
https://github.com/harness/drone.git
synced 2025-05-10 05:01:41 +08:00
address comments
This commit is contained in:
parent
f4ea3d714e
commit
01fffd56a3
@ -91,14 +91,14 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
|
|||||||
executionStore := database.ProvideExecutionStore(db)
|
executionStore := database.ProvideExecutionStore(db)
|
||||||
pipelineStore := database.ProvidePipelineStore(db)
|
pipelineStore := database.ProvidePipelineStore(db)
|
||||||
executionController := execution.ProvideController(db, authorizer, executionStore, pipelineStore, spaceStore)
|
executionController := execution.ProvideController(db, authorizer, executionStore, pipelineStore, spaceStore)
|
||||||
|
secretStore := database.ProvideSecretStore(db)
|
||||||
|
spaceController := space.ProvideController(db, provider, pathUID, authorizer, pathStore, pipelineStore, secretStore, spaceStore, repoStore, principalStore, repoController, membershipStore)
|
||||||
|
pipelineController := pipeline.ProvideController(db, pathUID, pathStore, repoStore, authorizer, pipelineStore, spaceStore)
|
||||||
encrypter, err := database.ProvideEncryptor(databaseConfig)
|
encrypter, err := database.ProvideEncryptor(databaseConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
secretStore := database.ProvideSecretStore(encrypter, db)
|
secretController := secret.ProvideController(db, pathUID, pathStore, encrypter, secretStore, authorizer, spaceStore)
|
||||||
spaceController := space.ProvideController(db, provider, pathUID, authorizer, pathStore, pipelineStore, secretStore, spaceStore, repoStore, principalStore, repoController, membershipStore)
|
|
||||||
pipelineController := pipeline.ProvideController(db, pathUID, pathStore, repoStore, authorizer, pipelineStore, spaceStore)
|
|
||||||
secretController := secret.ProvideController(db, pathUID, pathStore, secretStore, authorizer, spaceStore)
|
|
||||||
pullReqStore := database.ProvidePullReqStore(db, principalInfoCache)
|
pullReqStore := database.ProvidePullReqStore(db, principalInfoCache)
|
||||||
pullReqActivityStore := database.ProvidePullReqActivityStore(db, principalInfoCache)
|
pullReqActivityStore := database.ProvidePullReqActivityStore(db, principalInfoCache)
|
||||||
codeCommentView := database.ProvideCodeCommentView(db)
|
codeCommentView := database.ProvideCodeCommentView(db)
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
package secret
|
package secret
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/harness/gitness/encrypt"
|
||||||
"github.com/harness/gitness/internal/auth/authz"
|
"github.com/harness/gitness/internal/auth/authz"
|
||||||
"github.com/harness/gitness/internal/store"
|
"github.com/harness/gitness/internal/store"
|
||||||
"github.com/harness/gitness/types/check"
|
"github.com/harness/gitness/types/check"
|
||||||
@ -16,6 +17,7 @@ type Controller struct {
|
|||||||
db *sqlx.DB
|
db *sqlx.DB
|
||||||
uidCheck check.PathUID
|
uidCheck check.PathUID
|
||||||
pathStore store.PathStore
|
pathStore store.PathStore
|
||||||
|
encrypter encrypt.Encrypter
|
||||||
secretStore store.SecretStore
|
secretStore store.SecretStore
|
||||||
authorizer authz.Authorizer
|
authorizer authz.Authorizer
|
||||||
spaceStore store.SpaceStore
|
spaceStore store.SpaceStore
|
||||||
@ -26,6 +28,7 @@ func NewController(
|
|||||||
uidCheck check.PathUID,
|
uidCheck check.PathUID,
|
||||||
authorizer authz.Authorizer,
|
authorizer authz.Authorizer,
|
||||||
pathStore store.PathStore,
|
pathStore store.PathStore,
|
||||||
|
encrypter encrypt.Encrypter,
|
||||||
secretStore store.SecretStore,
|
secretStore store.SecretStore,
|
||||||
spaceStore store.SpaceStore,
|
spaceStore store.SpaceStore,
|
||||||
) *Controller {
|
) *Controller {
|
||||||
@ -33,6 +36,7 @@ func NewController(
|
|||||||
db: db,
|
db: db,
|
||||||
uidCheck: uidCheck,
|
uidCheck: uidCheck,
|
||||||
pathStore: pathStore,
|
pathStore: pathStore,
|
||||||
|
encrypter: encrypter,
|
||||||
secretStore: secretStore,
|
secretStore: secretStore,
|
||||||
authorizer: authorizer,
|
authorizer: authorizer,
|
||||||
spaceStore: spaceStore,
|
spaceStore: spaceStore,
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/harness/gitness/encrypt"
|
||||||
apiauth "github.com/harness/gitness/internal/api/auth"
|
apiauth "github.com/harness/gitness/internal/api/auth"
|
||||||
"github.com/harness/gitness/internal/api/usererror"
|
"github.com/harness/gitness/internal/api/usererror"
|
||||||
"github.com/harness/gitness/internal/auth"
|
"github.com/harness/gitness/internal/auth"
|
||||||
@ -66,6 +67,10 @@ func (c *Controller) Create(ctx context.Context, session *auth.Session, in *Crea
|
|||||||
Updated: now,
|
Updated: now,
|
||||||
Version: 0,
|
Version: 0,
|
||||||
}
|
}
|
||||||
|
secret, err = enc(c.encrypter, secret)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("could not encrypt secret: %w", err)
|
||||||
|
}
|
||||||
err = c.secretStore.Create(ctx, secret)
|
err = c.secretStore.Create(ctx, secret)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("secret creation failed: %w", err)
|
return fmt.Errorf("secret creation failed: %w", err)
|
||||||
@ -97,3 +102,31 @@ func (c *Controller) sanitizeCreateInput(in *CreateInput) error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// helper function returns the same secret with encrypted data.
|
||||||
|
func enc(encrypt encrypt.Encrypter, secret *types.Secret) (*types.Secret, error) {
|
||||||
|
if secret == nil {
|
||||||
|
return nil, fmt.Errorf("cannot encrypt a nil secret")
|
||||||
|
}
|
||||||
|
s := *secret
|
||||||
|
ciphertext, err := encrypt.Encrypt(secret.Data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
s.Data = string(ciphertext)
|
||||||
|
return &s, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// helper function returns the same secret with decrypted data.
|
||||||
|
func dec(encrypt encrypt.Encrypter, secret *types.Secret) (*types.Secret, error) {
|
||||||
|
if secret == nil {
|
||||||
|
return nil, fmt.Errorf("cannot decrypt a nil secret")
|
||||||
|
}
|
||||||
|
s := *secret
|
||||||
|
plaintext, err := encrypt.Decrypt([]byte(secret.Data))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
s.Data = plaintext
|
||||||
|
return &s, nil
|
||||||
|
}
|
||||||
|
@ -16,12 +16,12 @@ import (
|
|||||||
func (c *Controller) Delete(ctx context.Context, session *auth.Session, spaceRef string, uid string) error {
|
func (c *Controller) Delete(ctx context.Context, session *auth.Session, spaceRef string, uid string) error {
|
||||||
space, err := c.spaceStore.FindByRef(ctx, spaceRef)
|
space, err := c.spaceStore.FindByRef(ctx, spaceRef)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("could not find space: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = apiauth.CheckSecret(ctx, c.authorizer, session, space.Path, uid, enum.PermissionSecretDelete)
|
err = apiauth.CheckSecret(ctx, c.authorizer, session, space.Path, uid, enum.PermissionSecretDelete)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("failed to authorize: %w", err)
|
||||||
}
|
}
|
||||||
err = c.secretStore.DeleteByUID(ctx, space.ID, uid)
|
err = c.secretStore.DeleteByUID(ctx, space.ID, uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -6,6 +6,7 @@ package secret
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
apiauth "github.com/harness/gitness/internal/api/auth"
|
apiauth "github.com/harness/gitness/internal/api/auth"
|
||||||
"github.com/harness/gitness/internal/auth"
|
"github.com/harness/gitness/internal/auth"
|
||||||
@ -21,11 +22,19 @@ func (c *Controller) Find(
|
|||||||
) (*types.Secret, error) {
|
) (*types.Secret, error) {
|
||||||
space, err := c.spaceStore.FindByRef(ctx, spaceRef)
|
space, err := c.spaceStore.FindByRef(ctx, spaceRef)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("could not find space: %w", err)
|
||||||
}
|
}
|
||||||
err = apiauth.CheckSecret(ctx, c.authorizer, session, space.Path, uid, enum.PermissionSecretView)
|
err = apiauth.CheckSecret(ctx, c.authorizer, session, space.Path, uid, enum.PermissionSecretView)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("failed to authorize: %w", err)
|
||||||
}
|
}
|
||||||
return c.secretStore.FindByUID(ctx, space.ID, uid)
|
secret, err := c.secretStore.FindByUID(ctx, space.ID, uid)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("could not find secret: %w", err)
|
||||||
|
}
|
||||||
|
secret, err = dec(c.encrypter, secret)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("could not decrypt secret: %w", err)
|
||||||
|
}
|
||||||
|
return secret, nil
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ package secret
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
apiauth "github.com/harness/gitness/internal/api/auth"
|
apiauth "github.com/harness/gitness/internal/api/auth"
|
||||||
"github.com/harness/gitness/internal/auth"
|
"github.com/harness/gitness/internal/auth"
|
||||||
@ -25,20 +26,21 @@ func (c *Controller) Update(
|
|||||||
session *auth.Session,
|
session *auth.Session,
|
||||||
spaceRef string,
|
spaceRef string,
|
||||||
uid string,
|
uid string,
|
||||||
in *UpdateInput) (*types.Secret, error) {
|
in *UpdateInput,
|
||||||
|
) (*types.Secret, error) {
|
||||||
space, err := c.spaceStore.FindByRef(ctx, spaceRef)
|
space, err := c.spaceStore.FindByRef(ctx, spaceRef)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("could not find space: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = apiauth.CheckSecret(ctx, c.authorizer, session, space.Path, uid, enum.PermissionSecretEdit)
|
err = apiauth.CheckSecret(ctx, c.authorizer, session, space.Path, uid, enum.PermissionSecretEdit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("failed to authorize: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
secret, err := c.secretStore.FindByUID(ctx, space.ID, uid)
|
secret, err := c.secretStore.FindByUID(ctx, space.ID, uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("could not find secret: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.secretStore.UpdateOptLock(ctx, secret, func(original *types.Secret) error {
|
return c.secretStore.UpdateOptLock(ctx, secret, func(original *types.Secret) error {
|
||||||
@ -46,7 +48,11 @@ func (c *Controller) Update(
|
|||||||
original.Description = in.Description
|
original.Description = in.Description
|
||||||
}
|
}
|
||||||
if in.Data != "" {
|
if in.Data != "" {
|
||||||
original.Data = in.Data // will get encrypted at db layer
|
data, err := c.encrypter.Encrypt(original.Data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
original.Data = string(data)
|
||||||
}
|
}
|
||||||
if in.UID != "" {
|
if in.UID != "" {
|
||||||
original.UID = in.UID
|
original.UID = in.UID
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
package secret
|
package secret
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/harness/gitness/encrypt"
|
||||||
"github.com/harness/gitness/internal/auth/authz"
|
"github.com/harness/gitness/internal/auth/authz"
|
||||||
"github.com/harness/gitness/internal/store"
|
"github.com/harness/gitness/internal/store"
|
||||||
"github.com/harness/gitness/types/check"
|
"github.com/harness/gitness/types/check"
|
||||||
@ -21,9 +22,10 @@ var WireSet = wire.NewSet(
|
|||||||
func ProvideController(db *sqlx.DB,
|
func ProvideController(db *sqlx.DB,
|
||||||
uidCheck check.PathUID,
|
uidCheck check.PathUID,
|
||||||
pathStore store.PathStore,
|
pathStore store.PathStore,
|
||||||
|
encrypter encrypt.Encrypter,
|
||||||
secretStore store.SecretStore,
|
secretStore store.SecretStore,
|
||||||
authorizer authz.Authorizer,
|
authorizer authz.Authorizer,
|
||||||
spaceStore store.SpaceStore,
|
spaceStore store.SpaceStore,
|
||||||
) *Controller {
|
) *Controller {
|
||||||
return NewController(db, uidCheck, authorizer, pathStore, secretStore, spaceStore)
|
return NewController(db, uidCheck, authorizer, pathStore, encrypter, secretStore, spaceStore)
|
||||||
}
|
}
|
||||||
|
@ -35,21 +35,21 @@ func (c *Controller) ListPipelines(
|
|||||||
var pipelines []types.Pipeline
|
var pipelines []types.Pipeline
|
||||||
|
|
||||||
err = dbtx.New(c.db).WithTx(ctx, func(ctx context.Context) (err error) {
|
err = dbtx.New(c.db).WithTx(ctx, func(ctx context.Context) (err error) {
|
||||||
var dbErr error
|
count, err = c.pipelineStore.Count(ctx, space.ID, pagination)
|
||||||
count, dbErr = c.pipelineStore.Count(ctx, space.ID, pagination)
|
if err != nil {
|
||||||
if dbErr != nil {
|
err = fmt.Errorf("failed to count child executions: %w", err)
|
||||||
return fmt.Errorf("failed to count child executions: %w", err)
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
pipelines, dbErr = c.pipelineStore.List(ctx, space.ID, pagination)
|
pipelines, err = c.pipelineStore.List(ctx, space.ID, pagination)
|
||||||
if dbErr != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to list child executions: %w", err)
|
err = fmt.Errorf("failed to count child executions: %w", err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
return
|
||||||
return dbErr
|
|
||||||
}, dbtx.TxDefaultReadOnly)
|
}, dbtx.TxDefaultReadOnly)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return pipelines, count, err
|
return pipelines, count, fmt.Errorf("failed to list pipelines: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return pipelines, count, nil
|
return pipelines, count, nil
|
||||||
|
@ -35,21 +35,21 @@ func (c *Controller) ListSecrets(
|
|||||||
var secrets []types.Secret
|
var secrets []types.Secret
|
||||||
|
|
||||||
err = dbtx.New(c.db).WithTx(ctx, func(ctx context.Context) (err error) {
|
err = dbtx.New(c.db).WithTx(ctx, func(ctx context.Context) (err error) {
|
||||||
var dbErr error
|
count, err = c.secretStore.Count(ctx, space.ID, pagination)
|
||||||
count, dbErr = c.secretStore.Count(ctx, space.ID, pagination)
|
if err != nil {
|
||||||
if dbErr != nil {
|
err = fmt.Errorf("failed to count child executions: %w", err)
|
||||||
return fmt.Errorf("failed to count child executions: %w", err)
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
secrets, dbErr = c.secretStore.List(ctx, space.ID, pagination)
|
secrets, err = c.secretStore.List(ctx, space.ID, pagination)
|
||||||
if dbErr != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to list child executions: %w", err)
|
err = fmt.Errorf("failed to list child executions: %w", err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
return
|
||||||
return dbErr
|
|
||||||
}, dbtx.TxDefaultReadOnly)
|
}, dbtx.TxDefaultReadOnly)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return secrets, count, err
|
return secrets, count, fmt.Errorf("failed to list secrets: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return secrets, count, nil
|
return secrets, count, nil
|
||||||
|
@ -13,9 +13,6 @@ import (
|
|||||||
"github.com/harness/gitness/internal/paths"
|
"github.com/harness/gitness/internal/paths"
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
|
||||||
* Deletes a secret.
|
|
||||||
*/
|
|
||||||
func HandleDelete(secretCtrl *secret.Controller) http.HandlerFunc {
|
func HandleDelete(secretCtrl *secret.Controller) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
|
@ -14,9 +14,6 @@ import (
|
|||||||
"github.com/harness/gitness/internal/paths"
|
"github.com/harness/gitness/internal/paths"
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
|
||||||
* Updates an existing secret.
|
|
||||||
*/
|
|
||||||
func HandleUpdate(secretCtrl *secret.Controller) http.HandlerFunc {
|
func HandleUpdate(secretCtrl *secret.Controller) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
|
@ -450,7 +450,7 @@ type (
|
|||||||
Create(ctx context.Context, pipeline *types.Pipeline) error
|
Create(ctx context.Context, pipeline *types.Pipeline) error
|
||||||
|
|
||||||
// Update tries to update a pipeline in the datastore
|
// Update tries to update a pipeline in the datastore
|
||||||
Update(ctx context.Context, pipeline *types.Pipeline) (*types.Pipeline, error)
|
Update(ctx context.Context, pipeline *types.Pipeline) error
|
||||||
|
|
||||||
// List lists the pipelines present in a parent space ID in the datastore.
|
// List lists the pipelines present in a parent space ID in the datastore.
|
||||||
List(ctx context.Context, spaceID int64, pagination types.Pagination) ([]types.Pipeline, error)
|
List(ctx context.Context, spaceID int64, pagination types.Pagination) ([]types.Pipeline, error)
|
||||||
@ -490,7 +490,7 @@ type (
|
|||||||
mutateFn func(secret *types.Secret) error) (*types.Secret, error)
|
mutateFn func(secret *types.Secret) error) (*types.Secret, error)
|
||||||
|
|
||||||
// Update tries to update a secret.
|
// Update tries to update a secret.
|
||||||
Update(ctx context.Context, secret *types.Secret) (*types.Secret, error)
|
Update(ctx context.Context, secret *types.Secret) error
|
||||||
|
|
||||||
// Delete deletes a secret given an ID.
|
// Delete deletes a secret given an ID.
|
||||||
Delete(ctx context.Context, id int64) error
|
Delete(ctx context.Context, id int64) error
|
||||||
@ -510,7 +510,7 @@ type (
|
|||||||
Create(ctx context.Context, execution *types.Execution) error
|
Create(ctx context.Context, execution *types.Execution) error
|
||||||
|
|
||||||
// Update tries to update an execution.
|
// Update tries to update an execution.
|
||||||
Update(ctx context.Context, execution *types.Execution) (*types.Execution, error)
|
Update(ctx context.Context, execution *types.Execution) error
|
||||||
|
|
||||||
// UpdateOptLock updates the execution using the optimistic locking mechanism.
|
// UpdateOptLock updates the execution using the optimistic locking mechanism.
|
||||||
UpdateOptLock(ctx context.Context, exectuion *types.Execution,
|
UpdateOptLock(ctx context.Context, exectuion *types.Execution,
|
||||||
|
@ -33,10 +33,6 @@ type executionStore struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
executionQueryBase = `
|
|
||||||
SELECT` + executionColumns + `
|
|
||||||
FROM executions`
|
|
||||||
|
|
||||||
executionColumns = `
|
executionColumns = `
|
||||||
execution_id
|
execution_id
|
||||||
,execution_pipeline_id
|
,execution_pipeline_id
|
||||||
@ -74,8 +70,26 @@ const (
|
|||||||
,execution_updated
|
,execution_updated
|
||||||
,execution_version
|
,execution_version
|
||||||
`
|
`
|
||||||
|
)
|
||||||
|
|
||||||
executionInsertStmt = `
|
// Find returns an execution given a pipeline ID and an execution number.
|
||||||
|
func (s *executionStore) Find(ctx context.Context, pipelineID int64, executionNum int64) (*types.Execution, error) {
|
||||||
|
const findQueryStmt = `
|
||||||
|
SELECT` + executionColumns + `
|
||||||
|
FROM executions
|
||||||
|
WHERE execution_pipeline_id = $1 AND execution_number = $2`
|
||||||
|
db := dbtx.GetAccessor(ctx, s.db)
|
||||||
|
|
||||||
|
dst := new(types.Execution)
|
||||||
|
if err := db.GetContext(ctx, dst, findQueryStmt, pipelineID, executionNum); err != nil {
|
||||||
|
return nil, database.ProcessSQLErrorf(err, "Failed to find execution")
|
||||||
|
}
|
||||||
|
return dst, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create creates a new execution in the datastore.
|
||||||
|
func (s *executionStore) Create(ctx context.Context, execution *types.Execution) error {
|
||||||
|
const executionInsertStmt = `
|
||||||
INSERT INTO executions (
|
INSERT INTO executions (
|
||||||
execution_pipeline_id
|
execution_pipeline_id
|
||||||
,execution_repo_id
|
,execution_repo_id
|
||||||
@ -147,58 +161,6 @@ const (
|
|||||||
,:execution_updated
|
,:execution_updated
|
||||||
,:execution_version
|
,:execution_version
|
||||||
) RETURNING execution_id`
|
) RETURNING execution_id`
|
||||||
|
|
||||||
executionUpdateStmt = `
|
|
||||||
UPDATE executions
|
|
||||||
SET
|
|
||||||
execution_trigger = :execution_trigger
|
|
||||||
,execution_parent = :execution_parent
|
|
||||||
,execution_status = :execution_status
|
|
||||||
,execution_error = :execution_error
|
|
||||||
,execution_event = :execution_event
|
|
||||||
,execution_action = :execution_action
|
|
||||||
,execution_link = :execution_link
|
|
||||||
,execution_timestamp = :execution_timestamp
|
|
||||||
,execution_title = :execution_title
|
|
||||||
,execution_message = :execution_message
|
|
||||||
,execution_before = :execution_before
|
|
||||||
,execution_after = :execution_after
|
|
||||||
,execution_ref = :execution_ref
|
|
||||||
,execution_source_repo = :execution_source_repo
|
|
||||||
,execution_source = :execution_source
|
|
||||||
,execution_target = :execution_target
|
|
||||||
,execution_author = :execution_author
|
|
||||||
,execution_author_name = :execution_author_name
|
|
||||||
,execution_author_email = :execution_author_email
|
|
||||||
,execution_author_avatar = :execution_author_avatar
|
|
||||||
,execution_sender = :execution_sender
|
|
||||||
,execution_params = :execution_params
|
|
||||||
,execution_cron = :execution_cron
|
|
||||||
,execution_deploy = :execution_deploy
|
|
||||||
,execution_deploy_id = :execution_deploy_id
|
|
||||||
,execution_debug = :execution_debug
|
|
||||||
,execution_started = :execution_started
|
|
||||||
,execution_finished = :execution_finished
|
|
||||||
,execution_updated = :execution_updated
|
|
||||||
,execution_version = :execution_version
|
|
||||||
WHERE execution_id = :execution_id AND execution_version = :execution_version - 1`
|
|
||||||
)
|
|
||||||
|
|
||||||
// Find returns an execution given a pipeline ID and an execution number.
|
|
||||||
func (s *executionStore) Find(ctx context.Context, pipelineID int64, executionNum int64) (*types.Execution, error) {
|
|
||||||
const findQueryStmt = executionQueryBase + `
|
|
||||||
WHERE execution_pipeline_id = $1 AND execution_number = $2`
|
|
||||||
db := dbtx.GetAccessor(ctx, s.db)
|
|
||||||
|
|
||||||
dst := new(types.Execution)
|
|
||||||
if err := db.GetContext(ctx, dst, findQueryStmt, pipelineID, executionNum); err != nil {
|
|
||||||
return nil, database.ProcessSQLErrorf(err, "Failed to find execution")
|
|
||||||
}
|
|
||||||
return dst, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create creates a new execution in the datastore.
|
|
||||||
func (s *executionStore) Create(ctx context.Context, execution *types.Execution) error {
|
|
||||||
db := dbtx.GetAccessor(ctx, s.db)
|
db := dbtx.GetAccessor(ctx, s.db)
|
||||||
|
|
||||||
query, arg, err := db.BindNamed(executionInsertStmt, execution)
|
query, arg, err := db.BindNamed(executionInsertStmt, execution)
|
||||||
@ -214,7 +176,18 @@ func (s *executionStore) Create(ctx context.Context, execution *types.Execution)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update tries to update an execution in the datastore with optimistic locking.
|
// Update tries to update an execution in the datastore with optimistic locking.
|
||||||
func (s *executionStore) Update(ctx context.Context, execution *types.Execution) (*types.Execution, error) {
|
func (s *executionStore) Update(ctx context.Context, execution *types.Execution) error {
|
||||||
|
const executionUpdateStmt = `
|
||||||
|
UPDATE executions
|
||||||
|
SET
|
||||||
|
,execution_status = :execution_status
|
||||||
|
,execution_error = :execution_error
|
||||||
|
,execution_event = :execution_event
|
||||||
|
,execution_started = :execution_started
|
||||||
|
,execution_finished = :execution_finished
|
||||||
|
,execution_updated = :execution_updated
|
||||||
|
,execution_version = :execution_version
|
||||||
|
WHERE execution_id = :execution_id AND execution_version = :execution_version - 1`
|
||||||
updatedAt := time.Now()
|
updatedAt := time.Now()
|
||||||
|
|
||||||
execution.Version++
|
execution.Version++
|
||||||
@ -224,24 +197,24 @@ func (s *executionStore) Update(ctx context.Context, execution *types.Execution)
|
|||||||
|
|
||||||
query, arg, err := db.BindNamed(executionUpdateStmt, execution)
|
query, arg, err := db.BindNamed(executionUpdateStmt, execution)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, database.ProcessSQLErrorf(err, "Failed to bind execution object")
|
return database.ProcessSQLErrorf(err, "Failed to bind execution object")
|
||||||
}
|
}
|
||||||
|
|
||||||
result, err := db.ExecContext(ctx, query, arg...)
|
result, err := db.ExecContext(ctx, query, arg...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, database.ProcessSQLErrorf(err, "Failed to update execution")
|
return database.ProcessSQLErrorf(err, "Failed to update execution")
|
||||||
}
|
}
|
||||||
|
|
||||||
count, err := result.RowsAffected()
|
count, err := result.RowsAffected()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, database.ProcessSQLErrorf(err, "Failed to get number of updated rows")
|
return database.ProcessSQLErrorf(err, "Failed to get number of updated rows")
|
||||||
}
|
}
|
||||||
|
|
||||||
if count == 0 {
|
if count == 0 {
|
||||||
return nil, gitness_store.ErrVersionConflict
|
return gitness_store.ErrVersionConflict
|
||||||
}
|
}
|
||||||
|
|
||||||
return execution, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateOptLock updates the pipeline using the optimistic locking mechanism.
|
// UpdateOptLock updates the pipeline using the optimistic locking mechanism.
|
||||||
@ -251,16 +224,12 @@ func (s *executionStore) UpdateOptLock(ctx context.Context,
|
|||||||
for {
|
for {
|
||||||
dup := *execution
|
dup := *execution
|
||||||
|
|
||||||
fmt.Println(dup.Status)
|
|
||||||
|
|
||||||
err := mutateFn(&dup)
|
err := mutateFn(&dup)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("dup.Status after: ", dup.Status)
|
err = s.Update(ctx, &dup)
|
||||||
|
|
||||||
execution, err = s.Update(ctx, &dup)
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return &dup, nil
|
return &dup, nil
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
CREATE TABLE IF NOT EXISTS pipelines (
|
CREATE TABLE IF NOT EXISTS pipelines (
|
||||||
pipeline_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
pipeline_id INTEGER PRIMARY KEY AUTOINCREMENT
|
||||||
pipeline_description TEXT,
|
,pipeline_description TEXT NOT NULL
|
||||||
pipeline_space_id INTEGER NOT NULL,
|
,pipeline_space_id INTEGER NOT NULL
|
||||||
pipeline_uid TEXT NOT NULL,
|
,pipeline_uid TEXT NOT NULL
|
||||||
pipeline_seq INTEGER NOT NULL DEFAULT 0,
|
,pipeline_seq INTEGER NOT NULL DEFAULT 0
|
||||||
pipeline_repo_id INTEGER,
|
,pipeline_repo_id INTEGER
|
||||||
pipeline_repo_type TEXT NOT NULL,
|
,pipeline_repo_type TEXT NOT NULL
|
||||||
pipeline_repo_name TEXT,
|
,pipeline_repo_name TEXT
|
||||||
pipeline_default_branch TEXT,
|
,pipeline_default_branch TEXT
|
||||||
pipeline_config_path TEXT NOT NULL,
|
,pipeline_config_path TEXT NOT NULL
|
||||||
pipeline_created INTEGER NOT NULL,
|
,pipeline_created INTEGER NOT NULL
|
||||||
pipeline_updated INTEGER NOT NULL,
|
,pipeline_updated INTEGER NOT NULL
|
||||||
pipeline_version INTEGER NOT NULL,
|
,pipeline_version INTEGER NOT NULL
|
||||||
|
|
||||||
-- Ensure unique combination of UID and ParentID
|
-- Ensure unique combination of UID and ParentID
|
||||||
UNIQUE (pipeline_space_id, pipeline_uid),
|
UNIQUE (pipeline_space_id, pipeline_uid),
|
||||||
@ -30,67 +30,67 @@ CREATE TABLE IF NOT EXISTS pipelines (
|
|||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS executions (
|
CREATE TABLE IF NOT EXISTS executions (
|
||||||
execution_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
execution_id INTEGER PRIMARY KEY AUTOINCREMENT
|
||||||
execution_pipeline_id INTEGER NOT NULL,
|
,execution_pipeline_id INTEGER NOT NULL
|
||||||
execution_repo_id INTEGER,
|
,execution_repo_id INTEGER
|
||||||
execution_trigger TEXT,
|
,execution_trigger TEXT
|
||||||
execution_number INTEGER NOT NULL,
|
,execution_number INTEGER NOT NULL
|
||||||
execution_parent INTEGER,
|
,execution_parent INTEGER
|
||||||
execution_status TEXT,
|
,execution_status TEXT
|
||||||
execution_error TEXT,
|
,execution_error TEXT
|
||||||
execution_event TEXT,
|
,execution_event TEXT
|
||||||
execution_action TEXT,
|
,execution_action TEXT
|
||||||
execution_link TEXT,
|
,execution_link TEXT
|
||||||
execution_timestamp INTEGER,
|
,execution_timestamp INTEGER
|
||||||
execution_title TEXT,
|
,execution_title TEXT
|
||||||
execution_message TEXT,
|
,execution_message TEXT
|
||||||
execution_before TEXT,
|
,execution_before TEXT
|
||||||
execution_after TEXT,
|
,execution_after TEXT
|
||||||
execution_ref TEXT,
|
,execution_ref TEXT
|
||||||
execution_source_repo TEXT,
|
,execution_source_repo TEXT
|
||||||
execution_source TEXT,
|
,execution_source TEXT
|
||||||
execution_target TEXT,
|
,execution_target TEXT
|
||||||
execution_author TEXT,
|
,execution_author TEXT
|
||||||
execution_author_name TEXT,
|
,execution_author_name TEXT
|
||||||
execution_author_email TEXT,
|
,execution_author_email TEXT
|
||||||
execution_author_avatar TEXT,
|
,execution_author_avatar TEXT
|
||||||
execution_sender TEXT,
|
,execution_sender TEXT
|
||||||
execution_params TEXT,
|
,execution_params TEXT
|
||||||
execution_cron TEXT,
|
,execution_cron TEXT
|
||||||
execution_deploy TEXT,
|
,execution_deploy TEXT
|
||||||
execution_deploy_id INTEGER,
|
,execution_deploy_id INTEGER
|
||||||
execution_debug BOOLEAN NOT NULL DEFAULT 0,
|
,execution_debug BOOLEAN NOT NULL DEFAULT 0
|
||||||
execution_started INTEGER,
|
,execution_started INTEGER
|
||||||
execution_finished INTEGER,
|
,execution_finished INTEGER
|
||||||
execution_created INTEGER NOT NULL,
|
,execution_created INTEGER NOT NULL
|
||||||
execution_updated INTEGER NOT NULL,
|
,execution_updated INTEGER NOT NULL
|
||||||
execution_version INTEGER NOT NULL,
|
,execution_version INTEGER NOT NULL
|
||||||
|
|
||||||
-- Ensure unique combination of pipeline ID and number
|
-- Ensure unique combination of pipeline ID and number
|
||||||
UNIQUE (execution_pipeline_id, execution_number),
|
UNIQUE (execution_pipeline_id, execution_number),
|
||||||
|
|
||||||
-- Foreign key to pipelines table
|
-- Foreign key to pipelines table
|
||||||
CONSTRAINT fk_executions_pipeline_id FOREIGN KEY (execution_pipeline_id)
|
CONSTRAINT fk_executions_pipeline_id FOREIGN KEY (,execution_pipeline_id)
|
||||||
REFERENCES pipelines (pipeline_id) MATCH SIMPLE
|
REFERENCES pipelines (pipeline_id) MATCH SIMPLE
|
||||||
ON UPDATE NO ACTION
|
ON UPDATE NO ACTION
|
||||||
ON DELETE CASCADE
|
ON DELETE CASCADE
|
||||||
|
|
||||||
-- Foreign key to repositories table
|
-- Foreign key to repositories table
|
||||||
CONSTRAINT fk_executions_repo_id FOREIGN KEY (execution_repo_id)
|
CONSTRAINT fk_executions_repo_id FOREIGN KEY (,execution_repo_id)
|
||||||
REFERENCES repositories (repo_id) MATCH SIMPLE
|
REFERENCES repositories (repo_id) MATCH SIMPLE
|
||||||
ON UPDATE NO ACTION
|
ON UPDATE NO ACTION
|
||||||
ON DELETE CASCADE
|
ON DELETE CASCADE
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS secrets (
|
CREATE TABLE IF NOT EXISTS secrets (
|
||||||
secret_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
secret_id INTEGER PRIMARY KEY AUTOINCREMENT
|
||||||
secret_uid TEXT NOT NULL,
|
,secret_uid TEXT NOT NULL
|
||||||
secret_space_id INTEGER NOT NULL,
|
,secret_space_id INTEGER NOT NULL
|
||||||
secret_description TEXT,
|
,secret_description TEXT NOT NULL
|
||||||
secret_data BLOB NOT NULL,
|
,secret_data BLOB NOT NULL
|
||||||
secret_created INTEGER NOT NULL,
|
,secret_created INTEGER NOT NULL
|
||||||
secret_updated INTEGER NOT NULL,
|
,secret_updated INTEGER NOT NULL
|
||||||
secret_version INTEGER NOT NULL,
|
,secret_version INTEGER NOT NULL
|
||||||
|
|
||||||
-- Ensure unique combination of space ID and UID
|
-- Ensure unique combination of space ID and UID
|
||||||
UNIQUE (secret_space_id, secret_uid),
|
UNIQUE (secret_space_id, secret_uid),
|
||||||
|
@ -43,51 +43,6 @@ const (
|
|||||||
,pipeline_updated
|
,pipeline_updated
|
||||||
,pipeline_version
|
,pipeline_version
|
||||||
`
|
`
|
||||||
|
|
||||||
pipelineInsertStmt = `
|
|
||||||
INSERT INTO pipelines (
|
|
||||||
pipeline_description
|
|
||||||
,pipeline_space_id
|
|
||||||
,pipeline_uid
|
|
||||||
,pipeline_seq
|
|
||||||
,pipeline_repo_id
|
|
||||||
,pipeline_repo_type
|
|
||||||
,pipeline_repo_name
|
|
||||||
,pipeline_default_branch
|
|
||||||
,pipeline_config_path
|
|
||||||
,pipeline_created
|
|
||||||
,pipeline_updated
|
|
||||||
,pipeline_version
|
|
||||||
) VALUES (
|
|
||||||
:pipeline_description,
|
|
||||||
:pipeline_space_id,
|
|
||||||
:pipeline_uid,
|
|
||||||
:pipeline_seq,
|
|
||||||
:pipeline_repo_id,
|
|
||||||
:pipeline_repo_type,
|
|
||||||
:pipeline_repo_name,
|
|
||||||
:pipeline_default_branch,
|
|
||||||
:pipeline_config_path,
|
|
||||||
:pipeline_created,
|
|
||||||
:pipeline_updated,
|
|
||||||
:pipeline_version
|
|
||||||
) RETURNING pipeline_id`
|
|
||||||
|
|
||||||
pipelineUpdateStmt = `
|
|
||||||
UPDATE pipelines
|
|
||||||
SET
|
|
||||||
pipeline_description = :pipeline_description,
|
|
||||||
pipeline_space_id = :pipeline_space_id,
|
|
||||||
pipeline_uid = :pipeline_uid,
|
|
||||||
pipeline_seq = :pipeline_seq,
|
|
||||||
pipeline_repo_id = :pipeline_repo_id,
|
|
||||||
pipeline_repo_type = :pipeline_repo_type,
|
|
||||||
pipeline_repo_name = :pipeline_repo_name,
|
|
||||||
pipeline_default_branch = :pipeline_default_branch,
|
|
||||||
pipeline_config_path = :pipeline_config_path,
|
|
||||||
pipeline_updated = :pipeline_updated,
|
|
||||||
pipeline_version = :pipeline_version
|
|
||||||
WHERE pipeline_id = :pipeline_id AND pipeline_version = :pipeline_version - 1`
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewPipelineStore returns a new PipelineStore.
|
// NewPipelineStore returns a new PipelineStore.
|
||||||
@ -129,6 +84,34 @@ func (s *pipelineStore) FindByUID(ctx context.Context, spaceID int64, uid string
|
|||||||
|
|
||||||
// Create creates a pipeline.
|
// Create creates a pipeline.
|
||||||
func (s *pipelineStore) Create(ctx context.Context, pipeline *types.Pipeline) error {
|
func (s *pipelineStore) Create(ctx context.Context, pipeline *types.Pipeline) error {
|
||||||
|
const pipelineInsertStmt = `
|
||||||
|
INSERT INTO pipelines (
|
||||||
|
pipeline_description
|
||||||
|
,pipeline_space_id
|
||||||
|
,pipeline_uid
|
||||||
|
,pipeline_seq
|
||||||
|
,pipeline_repo_id
|
||||||
|
,pipeline_repo_type
|
||||||
|
,pipeline_repo_name
|
||||||
|
,pipeline_default_branch
|
||||||
|
,pipeline_config_path
|
||||||
|
,pipeline_created
|
||||||
|
,pipeline_updated
|
||||||
|
,pipeline_version
|
||||||
|
) VALUES (
|
||||||
|
:pipeline_description,
|
||||||
|
:pipeline_space_id,
|
||||||
|
:pipeline_uid,
|
||||||
|
:pipeline_seq,
|
||||||
|
:pipeline_repo_id,
|
||||||
|
:pipeline_repo_type,
|
||||||
|
:pipeline_repo_name,
|
||||||
|
:pipeline_default_branch,
|
||||||
|
:pipeline_config_path,
|
||||||
|
:pipeline_created,
|
||||||
|
:pipeline_updated,
|
||||||
|
:pipeline_version
|
||||||
|
) RETURNING pipeline_id`
|
||||||
db := dbtx.GetAccessor(ctx, s.db)
|
db := dbtx.GetAccessor(ctx, s.db)
|
||||||
|
|
||||||
query, arg, err := db.BindNamed(pipelineInsertStmt, pipeline)
|
query, arg, err := db.BindNamed(pipelineInsertStmt, pipeline)
|
||||||
@ -144,7 +127,18 @@ func (s *pipelineStore) Create(ctx context.Context, pipeline *types.Pipeline) er
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update updates a pipeline.
|
// Update updates a pipeline.
|
||||||
func (s *pipelineStore) Update(ctx context.Context, pipeline *types.Pipeline) (*types.Pipeline, error) {
|
func (s *pipelineStore) Update(ctx context.Context, pipeline *types.Pipeline) error {
|
||||||
|
const pipelineUpdateStmt = `
|
||||||
|
UPDATE pipelines
|
||||||
|
SET
|
||||||
|
pipeline_description = :pipeline_description,
|
||||||
|
pipeline_uid = :pipeline_uid,
|
||||||
|
pipeline_seq = :pipeline_seq,
|
||||||
|
pipeline_default_branch = :pipeline_default_branch,
|
||||||
|
pipeline_config_path = :pipeline_config_path,
|
||||||
|
pipeline_updated = :pipeline_updated,
|
||||||
|
pipeline_version = :pipeline_version
|
||||||
|
WHERE pipeline_id = :pipeline_id AND pipeline_version = :pipeline_version - 1`
|
||||||
updatedAt := time.Now()
|
updatedAt := time.Now()
|
||||||
|
|
||||||
pipeline.Version++
|
pipeline.Version++
|
||||||
@ -154,24 +148,24 @@ func (s *pipelineStore) Update(ctx context.Context, pipeline *types.Pipeline) (*
|
|||||||
|
|
||||||
query, arg, err := db.BindNamed(pipelineUpdateStmt, pipeline)
|
query, arg, err := db.BindNamed(pipelineUpdateStmt, pipeline)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, database.ProcessSQLErrorf(err, "Failed to bind pipeline object")
|
return database.ProcessSQLErrorf(err, "Failed to bind pipeline object")
|
||||||
}
|
}
|
||||||
|
|
||||||
result, err := db.ExecContext(ctx, query, arg...)
|
result, err := db.ExecContext(ctx, query, arg...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, database.ProcessSQLErrorf(err, "Failed to update pipeline")
|
return database.ProcessSQLErrorf(err, "Failed to update pipeline")
|
||||||
}
|
}
|
||||||
|
|
||||||
count, err := result.RowsAffected()
|
count, err := result.RowsAffected()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, database.ProcessSQLErrorf(err, "Failed to get number of updated rows")
|
return database.ProcessSQLErrorf(err, "Failed to get number of updated rows")
|
||||||
}
|
}
|
||||||
|
|
||||||
if count == 0 {
|
if count == 0 {
|
||||||
return nil, gitness_store.ErrVersionConflict
|
return gitness_store.ErrVersionConflict
|
||||||
}
|
}
|
||||||
|
|
||||||
return pipeline, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// List lists all the pipelines present in a space.
|
// List lists all the pipelines present in a space.
|
||||||
@ -219,7 +213,7 @@ func (s *pipelineStore) UpdateOptLock(ctx context.Context,
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
pipeline, err = s.Update(ctx, &dup)
|
err = s.Update(ctx, &dup)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return &dup, nil
|
return &dup, nil
|
||||||
}
|
}
|
||||||
@ -296,7 +290,7 @@ func (s *pipelineStore) IncrementSeqNum(ctx context.Context, pipeline *types.Pip
|
|||||||
for {
|
for {
|
||||||
var err error
|
var err error
|
||||||
pipeline.Seq++
|
pipeline.Seq++
|
||||||
pipeline, err = s.Update(ctx, pipeline)
|
err = s.Update(ctx, pipeline)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return pipeline, nil
|
return pipeline, nil
|
||||||
} else if !errors.Is(err, gitness_store.ErrVersionConflict) {
|
} else if !errors.Is(err, gitness_store.ErrVersionConflict) {
|
||||||
|
@ -10,7 +10,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/harness/gitness/encrypt"
|
|
||||||
"github.com/harness/gitness/internal/store"
|
"github.com/harness/gitness/internal/store"
|
||||||
gitness_store "github.com/harness/gitness/store"
|
gitness_store "github.com/harness/gitness/store"
|
||||||
"github.com/harness/gitness/store/database"
|
"github.com/harness/gitness/store/database"
|
||||||
@ -38,8 +37,48 @@ const (
|
|||||||
secret_updated,
|
secret_updated,
|
||||||
secret_version
|
secret_version
|
||||||
`
|
`
|
||||||
|
)
|
||||||
|
|
||||||
secretInsertStmt = `
|
// NewSecretStore returns a new SecretStore.
|
||||||
|
func NewSecretStore(db *sqlx.DB) *secretStore {
|
||||||
|
return &secretStore{
|
||||||
|
db: db,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type secretStore struct {
|
||||||
|
db *sqlx.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find returns a secret given a secret ID.
|
||||||
|
func (s *secretStore) Find(ctx context.Context, id int64) (*types.Secret, error) {
|
||||||
|
const findQueryStmt = secretQueryBase + `
|
||||||
|
WHERE secret_id = $1`
|
||||||
|
db := dbtx.GetAccessor(ctx, s.db)
|
||||||
|
|
||||||
|
dst := new(types.Secret)
|
||||||
|
if err := db.GetContext(ctx, dst, findQueryStmt, id); err != nil {
|
||||||
|
return nil, database.ProcessSQLErrorf(err, "Failed to find secret")
|
||||||
|
}
|
||||||
|
return dst, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindByUID returns a secret in a given space with a given UID.
|
||||||
|
func (s *secretStore) FindByUID(ctx context.Context, spaceID int64, uid string) (*types.Secret, error) {
|
||||||
|
const findQueryStmt = secretQueryBase + `
|
||||||
|
WHERE secret_space_id = $1 AND secret_uid = $2`
|
||||||
|
db := dbtx.GetAccessor(ctx, s.db)
|
||||||
|
|
||||||
|
dst := new(types.Secret)
|
||||||
|
if err := db.GetContext(ctx, dst, findQueryStmt, spaceID, uid); err != nil {
|
||||||
|
return nil, database.ProcessSQLErrorf(err, "Failed to find secret")
|
||||||
|
}
|
||||||
|
return dst, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create creates a secret.
|
||||||
|
func (s *secretStore) Create(ctx context.Context, secret *types.Secret) error {
|
||||||
|
const secretInsertStmt = `
|
||||||
INSERT INTO secrets (
|
INSERT INTO secrets (
|
||||||
secret_description,
|
secret_description,
|
||||||
secret_space_id,
|
secret_space_id,
|
||||||
@ -57,67 +96,8 @@ const (
|
|||||||
:secret_updated,
|
:secret_updated,
|
||||||
:secret_version
|
:secret_version
|
||||||
) RETURNING secret_id`
|
) RETURNING secret_id`
|
||||||
|
|
||||||
secretUpdateStmt = `
|
|
||||||
UPDATE secrets
|
|
||||||
SET
|
|
||||||
secret_description = :secret_description,
|
|
||||||
secret_space_id = :secret_space_id,
|
|
||||||
secret_uid = :secret_uid,
|
|
||||||
secret_data = :secret_data,
|
|
||||||
secret_updated = :secret_updated,
|
|
||||||
secret_version = :secret_version
|
|
||||||
WHERE secret_id = :secret_id AND secret_version = :secret_version - 1`
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewSecretStore returns a new SecretStore.
|
|
||||||
func NewSecretStore(enc encrypt.Encrypter, db *sqlx.DB) *secretStore {
|
|
||||||
return &secretStore{
|
|
||||||
db: db,
|
|
||||||
enc: enc,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type secretStore struct {
|
|
||||||
db *sqlx.DB
|
|
||||||
enc encrypt.Encrypter
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find returns a secret given a secret ID.
|
|
||||||
func (s *secretStore) Find(ctx context.Context, id int64) (*types.Secret, error) {
|
|
||||||
const findQueryStmt = secretQueryBase + `
|
|
||||||
WHERE secret_id = $1`
|
|
||||||
db := dbtx.GetAccessor(ctx, s.db)
|
db := dbtx.GetAccessor(ctx, s.db)
|
||||||
|
|
||||||
dst := new(types.Secret)
|
|
||||||
if err := db.GetContext(ctx, dst, findQueryStmt, id); err != nil {
|
|
||||||
return nil, database.ProcessSQLErrorf(err, "Failed to find secret")
|
|
||||||
}
|
|
||||||
return dec(s.enc, dst)
|
|
||||||
}
|
|
||||||
|
|
||||||
// FindByUID returns a secret in a given space with a given UID.
|
|
||||||
func (s *secretStore) FindByUID(ctx context.Context, spaceID int64, uid string) (*types.Secret, error) {
|
|
||||||
const findQueryStmt = secretQueryBase + `
|
|
||||||
WHERE secret_space_id = $1 AND secret_uid = $2`
|
|
||||||
db := dbtx.GetAccessor(ctx, s.db)
|
|
||||||
|
|
||||||
dst := new(types.Secret)
|
|
||||||
if err := db.GetContext(ctx, dst, findQueryStmt, spaceID, uid); err != nil {
|
|
||||||
return nil, database.ProcessSQLErrorf(err, "Failed to find secret")
|
|
||||||
}
|
|
||||||
return dec(s.enc, dst)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create creates a secret.
|
|
||||||
func (s *secretStore) Create(ctx context.Context, secret *types.Secret) error {
|
|
||||||
db := dbtx.GetAccessor(ctx, s.db)
|
|
||||||
|
|
||||||
secret, err := enc(s.enc, secret)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
query, arg, err := db.BindNamed(secretInsertStmt, secret)
|
query, arg, err := db.BindNamed(secretInsertStmt, secret)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return database.ProcessSQLErrorf(err, "Failed to bind secret object")
|
return database.ProcessSQLErrorf(err, "Failed to bind secret object")
|
||||||
@ -130,7 +110,16 @@ func (s *secretStore) Create(ctx context.Context, secret *types.Secret) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *secretStore) Update(ctx context.Context, secret *types.Secret) (*types.Secret, error) {
|
func (s *secretStore) Update(ctx context.Context, secret *types.Secret) error {
|
||||||
|
const secretUpdateStmt = `
|
||||||
|
UPDATE secrets
|
||||||
|
SET
|
||||||
|
secret_description = :secret_description,
|
||||||
|
secret_uid = :secret_uid,
|
||||||
|
secret_data = :secret_data,
|
||||||
|
secret_updated = :secret_updated,
|
||||||
|
secret_version = :secret_version
|
||||||
|
WHERE secret_id = :secret_id AND secret_version = :secret_version - 1`
|
||||||
updatedAt := time.Now()
|
updatedAt := time.Now()
|
||||||
|
|
||||||
secret.Version++
|
secret.Version++
|
||||||
@ -138,31 +127,26 @@ func (s *secretStore) Update(ctx context.Context, secret *types.Secret) (*types.
|
|||||||
|
|
||||||
db := dbtx.GetAccessor(ctx, s.db)
|
db := dbtx.GetAccessor(ctx, s.db)
|
||||||
|
|
||||||
secret, err := enc(s.enc, secret)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
query, arg, err := db.BindNamed(secretUpdateStmt, secret)
|
query, arg, err := db.BindNamed(secretUpdateStmt, secret)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, database.ProcessSQLErrorf(err, "Failed to bind secret object")
|
return database.ProcessSQLErrorf(err, "Failed to bind secret object")
|
||||||
}
|
}
|
||||||
|
|
||||||
result, err := db.ExecContext(ctx, query, arg...)
|
result, err := db.ExecContext(ctx, query, arg...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, database.ProcessSQLErrorf(err, "Failed to update secret")
|
return database.ProcessSQLErrorf(err, "Failed to update secret")
|
||||||
}
|
}
|
||||||
|
|
||||||
count, err := result.RowsAffected()
|
count, err := result.RowsAffected()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, database.ProcessSQLErrorf(err, "Failed to get number of updated rows")
|
return database.ProcessSQLErrorf(err, "Failed to get number of updated rows")
|
||||||
}
|
}
|
||||||
|
|
||||||
if count == 0 {
|
if count == 0 {
|
||||||
return nil, gitness_store.ErrVersionConflict
|
return gitness_store.ErrVersionConflict
|
||||||
}
|
}
|
||||||
|
|
||||||
return secret, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateOptLock updates the pipeline using the optimistic locking mechanism.
|
// UpdateOptLock updates the pipeline using the optimistic locking mechanism.
|
||||||
@ -177,7 +161,7 @@ func (s *secretStore) UpdateOptLock(ctx context.Context,
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
secret, err = s.Update(ctx, &dup)
|
err = s.Update(ctx, &dup)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return &dup, nil
|
return &dup, nil
|
||||||
}
|
}
|
||||||
@ -276,31 +260,3 @@ func (s *secretStore) Count(ctx context.Context, parentID int64, filter types.Pa
|
|||||||
}
|
}
|
||||||
return count, nil
|
return count, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// helper function returns the same secret with encrypted data.
|
|
||||||
func enc(encrypt encrypt.Encrypter, secret *types.Secret) (*types.Secret, error) {
|
|
||||||
if secret == nil {
|
|
||||||
return nil, fmt.Errorf("cannot encrypt a nil secret")
|
|
||||||
}
|
|
||||||
s := *secret
|
|
||||||
ciphertext, err := encrypt.Encrypt(secret.Data)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
s.Data = string(ciphertext)
|
|
||||||
return &s, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// helper function returns the same secret with decrypted data.
|
|
||||||
func dec(encrypt encrypt.Encrypter, secret *types.Secret) (*types.Secret, error) {
|
|
||||||
if secret == nil {
|
|
||||||
return nil, fmt.Errorf("cannot decrypt a nil secret")
|
|
||||||
}
|
|
||||||
s := *secret
|
|
||||||
plaintext, err := encrypt.Decrypt([]byte(secret.Data))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
s.Data = plaintext
|
|
||||||
return &s, nil
|
|
||||||
}
|
|
||||||
|
@ -105,8 +105,8 @@ func ProvidePipelineStore(db *sqlx.DB) store.PipelineStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ProvideSecretStore provides a secret store.
|
// ProvideSecretStore provides a secret store.
|
||||||
func ProvideSecretStore(enc encrypt.Encrypter, db *sqlx.DB) store.SecretStore {
|
func ProvideSecretStore(db *sqlx.DB) store.SecretStore {
|
||||||
return NewSecretStore(enc, db)
|
return NewSecretStore(db)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProvideExecutionStore provides an execution store.
|
// ProvideExecutionStore provides an execution store.
|
||||||
|
@ -8,9 +8,10 @@ import (
|
|||||||
context "context"
|
context "context"
|
||||||
reflect "reflect"
|
reflect "reflect"
|
||||||
|
|
||||||
gomock "github.com/golang/mock/gomock"
|
|
||||||
user "github.com/harness/gitness/internal/api/controller/user"
|
user "github.com/harness/gitness/internal/api/controller/user"
|
||||||
types "github.com/harness/gitness/types"
|
types "github.com/harness/gitness/types"
|
||||||
|
|
||||||
|
gomock "github.com/golang/mock/gomock"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MockClient is a mock of Client interface.
|
// MockClient is a mock of Client interface.
|
||||||
|
@ -8,9 +8,10 @@ import (
|
|||||||
context "context"
|
context "context"
|
||||||
reflect "reflect"
|
reflect "reflect"
|
||||||
|
|
||||||
gomock "github.com/golang/mock/gomock"
|
|
||||||
types "github.com/harness/gitness/types"
|
types "github.com/harness/gitness/types"
|
||||||
enum "github.com/harness/gitness/types/enum"
|
enum "github.com/harness/gitness/types/enum"
|
||||||
|
|
||||||
|
gomock "github.com/golang/mock/gomock"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MockPrincipalStore is a mock of PrincipalStore interface.
|
// MockPrincipalStore is a mock of PrincipalStore interface.
|
||||||
|
Loading…
Reference in New Issue
Block a user