Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(api): manage variable deletion and env keys as code #6563

Merged
merged 7 commits into from
Jun 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 43 additions & 12 deletions engine/api/environment.go
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no more msgChan <- sdk.NewMessage ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed :)

}
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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