Skip to content

Commit

Permalink
fix(api): manage variable deletion and env keys as code (#6563)
Browse files Browse the repository at this point in the history
  • Loading branch information
sguiheux committed Jun 7, 2023
1 parent ba94642 commit b1430bc
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 49 deletions.
55 changes: 43 additions & 12 deletions engine/api/environment.go
Expand Up @@ -240,12 +240,33 @@ func (api *API) updateAsCodeEnvironmentHandler() service.Handler {
return err
}

// check application name pattern
// check environment name pattern
regexp := sdk.NamePatternRegex
if !regexp.MatchString(env.Name) {
return sdk.WrapError(sdk.ErrInvalidApplicationPattern, "Environment name %s do not respect pattern", env.Name)
}

envDB, err := environment.LoadEnvironmentByName(api.mustDB(), key, environmentName)
if err != nil {
return sdk.WrapError(err, "cannot load environment %s", environmentName)
}

// replace placeholder before export
envVarsClear, err := environment.LoadAllVariablesWithDecrytion(api.mustDB(), envDB.ID)
if err != nil {
return err
}
for i := range env.Variables {
v := &env.Variables[i]
if v.Type == sdk.SecretVariable && v.Value == sdk.PasswordPlaceholder {
for _, dbvar := range envVarsClear {
if dbvar.ID == v.ID {
v.Value = dbvar.Value
}
}
}
}

tx, err := api.mustDB().Begin()
if err != nil {
return sdk.WithStack(err)
Expand All @@ -257,11 +278,6 @@ func (api *API) updateAsCodeEnvironmentHandler() service.Handler {
return err
}

envDB, err := environment.LoadEnvironmentByName(tx, key, environmentName)
if err != nil {
return sdk.WrapError(err, "cannot load environment %s", environmentName)
}

if envDB.FromRepository == "" {
return sdk.NewErrorFrom(sdk.ErrForbidden, "current environment is not ascode")
}
Expand Down Expand Up @@ -302,15 +318,30 @@ func (api *API) updateAsCodeEnvironmentHandler() service.Handler {
}

// create keys
envKeys, err := environment.LoadAllKeysWithPrivateContent(tx, env.ID)
if err != nil {
return err
}
for i := range env.Keys {
k := &env.Keys[i]
newKey, err := keys.GenerateKey(k.Name, k.Type)
if err != nil {
return err
if k.ID == 0 {
newKey, err := keys.GenerateKey(k.Name, k.Type)
if err != nil {
return err
}
k.Public = newKey.Public
k.Private = newKey.Private
k.KeyID = newKey.KeyID
} else {
for _, kClear := range envKeys {
if kClear.ID == k.ID {
k.Public = kClear.Public
k.Private = kClear.Private
k.KeyID = kClear.KeyID
break
}
}
}
k.Public = newKey.Public
k.Private = newKey.Private
k.KeyID = newKey.KeyID
}

u := getUserConsumer(ctx)
Expand Down
6 changes: 6 additions & 0 deletions engine/api/environment/dao_key.go
Expand Up @@ -135,3 +135,9 @@ func DeleteEnvironmentKey(db gorp.SqlExecutor, envID int64, keyName string) erro
_, err := db.Exec("DELETE FROM environment_key WHERE environment_id = $1 AND name = $2", envID, keyName)
return sdk.WrapError(err, "Cannot delete key %s", keyName)
}

// DeleteAllEnvironmentKeys Delete all environment keys for the given env
func DeleteAllEnvironmentKeys(db gorp.SqlExecutor, envID int64) error {
_, err := db.Exec("DELETE FROM environment_key WHERE environment_id = $1", envID)
return sdk.WrapError(err, "Cannot delete keys from %d", envID)
}
52 changes: 17 additions & 35 deletions engine/api/environment/environment_importer.go
Expand Up @@ -67,53 +67,35 @@ func Import(db gorpmapper.SqlExecutorWithTx, proj sdk.Project, env *sdk.Environm

// ImportInto import variables and groups on an existing environment
func ImportInto(ctx context.Context, db gorpmapper.SqlExecutorWithTx, env *sdk.Environment, into *sdk.Environment, msgChan chan<- sdk.Message, u sdk.Identifiable) error {
var updateVar = func(v *sdk.EnvironmentVariable) {
log.Debug(ctx, "ImportInto> Updating var %q with value %q", v.Name, v.Value)

varBefore, errV := LoadVariable(db, into.ID, v.Name)
if errV != nil {
msgChan <- sdk.NewMessage(sdk.MsgEnvironmentVariableCannotBeUpdated, v.Name, into.Name, errV)
return
}

if err := UpdateVariable(db, into.ID, v, varBefore, u); err != nil {
msgChan <- sdk.NewMessage(sdk.MsgEnvironmentVariableCannotBeUpdated, v.Name, into.Name, err)
return
}
msgChan <- sdk.NewMessage(sdk.MsgEnvironmentVariableUpdated, v.Name, into.Name)
//Delete all Variables
if err := DeleteAllVariables(db, into.ID); err != nil {
return err
}

var insertVar = func(v *sdk.EnvironmentVariable) {
log.Debug(ctx, "ImportInto> Creating var %s", v.Name)
if err := InsertVariable(db, into.ID, v, u); err != nil {
msgChan <- sdk.NewMessage(sdk.MsgEnvironmentVariableCannotBeCreated, v.Name, into.Name, err)
return
}
msgChan <- sdk.NewMessage(sdk.MsgEnvironmentVariableCreated, v.Name, into.Name)
///Delete all Keys
if err := DeleteAllEnvironmentKeys(db, into.ID); err != nil {
return err
}

for i := range env.Variables {
log.Debug(ctx, "ImportInto> Checking >> %s", env.Variables[i].Name)
var found bool
for j := range into.Variables {
log.Debug(ctx, "ImportInto> \t with >> %s", into.Variables[j].Name)
if env.Variables[i].Name == into.Variables[j].Name {
env.Variables[i].ID = into.Variables[j].ID
found = true
updateVar(&env.Variables[i])
break
}
if err := InsertVariable(db, into.ID, &env.Variables[i], u); err != nil {
msgChan <- sdk.NewMessage(sdk.MsgEnvironmentVariableCannotBeCreated, env.Variables[i].Name, into.Name, err)
return err
}
if !found {
insertVar(&env.Variables[i])
msgChan <- sdk.NewMessage(sdk.MsgEnvironmentVariableCreated, env.Variables[i].Name, into.Name)
}

for i := range env.Keys {
if err := InsertKey(db, &env.Keys[i]); err != nil {
msgChan <- sdk.NewMessage(sdk.MsgEnvironmentKeyCannotBeCreated, sdk.SSHKeyVariable, env.Keys[i].Name, into.Name, err)
return err
}
msgChan <- sdk.NewMessage(sdk.MsgEnvironmentKeyCreated, sdk.SSHKeyVariable, env.Keys[i].Name, into.Name)
}

if err := UpdateEnvironment(db, env); err != nil {
return sdk.WrapError(err, "unable to update environment")
}

log.Debug(ctx, "ImportInto> Done")

return nil
}
2 changes: 1 addition & 1 deletion engine/api/environment/environment_importer_test.go
Expand Up @@ -129,7 +129,7 @@ func TestImportInto_Variable(t *testing.T) {
}
}

assert.True(t, v0found)
assert.False(t, v0found)
assert.True(t, v1found)
assert.True(t, v2found)
assert.True(t, v3found)
Expand Down
2 changes: 1 addition & 1 deletion engine/worker/internal/plugin/socket.go
Expand Up @@ -50,7 +50,7 @@ func createGRPCPluginSocket(ctx context.Context, pluginType string, pluginName s
//If the file doesn't exist. Download it.
fi, err := w.BaseDir().OpenFile(pluginBinaryInfos.Name, os.O_CREATE|os.O_RDWR, os.FileMode(pluginBinaryInfos.Perm))
if err != nil {
return nil, nil, sdk.WrapError(err, "unable to create the file %s", pluginBinaryInfos)
return nil, nil, sdk.WrapError(err, "unable to create the file %s", pluginBinaryInfos.Name)
}

log.Debug(ctx, "Get the binary plugin %s", pluginBinaryInfos.PluginName)
Expand Down
2 changes: 2 additions & 0 deletions sdk/messages.go
Expand Up @@ -40,6 +40,7 @@ var (
MsgEnvironmentGroupDeleted = &Message{"MsgEnvironmentGroupDeleted", trad{FR: "Le groupe %s de l'environnement %s a été supprimé", EN: "Group %s on environment %s has been deleted"}, nil, RunInfoTypInfo}
MsgEnvironmentGroupCannotBeDeleted = &Message{"MsgEnvironmentGMsgEnvironmentGroupCannotBeDeletedroupCannotBeCreated", trad{FR: "Le groupe %s de l'environnement %s n'a pu être supprimé : %s", EN: "Group %s on environment %s cannot be deleted: %s"}, nil, RunInfoTypeError}
MsgEnvironmentKeyCreated = &Message{"MsgEnvironmentKeyCreated", trad{FR: "La clé %s %s a été créée sur l'environnement %s", EN: "%s key %s created on environment %s"}, nil, RunInfoTypInfo}
MsgEnvironmentKeyCannotBeCreated = &Message{"MsgEnvironmentKeyCannotBeCreated", trad{FR: "La clé %s %s n'a pas été créée sur l'environnement %s", EN: "%s key %s cannot be created on environment %s: %v"}, nil, RunInfoTypeError}
MsgJobNotValidActionNotFound = &Message{"MsgJobNotValidActionNotFound", trad{FR: "Erreur de validation du Job %s : L'action %s à l'étape %d n'a pas été trouvée", EN: "Job %s validation Failure: Unknown action %s on step #%d"}, nil, RunInfoTypeError}
MsgJobNotValidInvalidActionParameter = &Message{"MsgJobNotValidInvalidActionParameter", trad{FR: "Erreur de validation du Job %s : Le paramètre %s de l'étape %d - %s est invalide", EN: "Job %s validation Failure: Invalid parameter %s on step #%d %s"}, nil, RunInfoTypeError}
MsgPipelineGroupUpdated = &Message{"MsgPipelineGroupUpdated", trad{FR: "Les permissions du groupe %s sur le pipeline %s on été mises à jour", EN: "Permission for group %s on pipeline %s has been updated"}, nil, RunInfoTypInfo}
Expand Down Expand Up @@ -125,6 +126,7 @@ var Messages = map[string]*Message{
MsgEnvironmentGroupDeleted.ID: MsgEnvironmentGroupDeleted,
MsgEnvironmentGroupCannotBeDeleted.ID: MsgEnvironmentGroupCannotBeDeleted,
MsgEnvironmentKeyCreated.ID: MsgEnvironmentKeyCreated,
MsgEnvironmentKeyCannotBeCreated.ID: MsgEnvironmentKeyCannotBeCreated,
MsgJobNotValidActionNotFound.ID: MsgJobNotValidActionNotFound,
MsgJobNotValidInvalidActionParameter.ID: MsgJobNotValidInvalidActionParameter,
MsgPipelineGroupUpdated.ID: MsgPipelineGroupUpdated,
Expand Down

0 comments on commit b1430bc

Please sign in to comment.