Skip to content

Commit

Permalink
feat: compute default values for template parameter (#5092)
Browse files Browse the repository at this point in the history
  • Loading branch information
richardlt authored Apr 2, 2020
1 parent dc5da00 commit 0eedf85
Show file tree
Hide file tree
Showing 49 changed files with 496 additions and 252 deletions.
2 changes: 1 addition & 1 deletion cli/cdsctl/application_key.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ var applicationKeyCreateCmd = cli.Command{
func applicationCreateKeyRun(v cli.Values) error {
key := &sdk.ApplicationKey{
Name: v.GetString("key-name"),
Type: v.GetString("key-type"),
Type: sdk.KeyType(v.GetString("key-type")),
}
if err := client.ApplicationKeyCreate(v.GetString(_ProjectKey), v.GetString(_ApplicationName), key); err != nil {
return err
Expand Down
2 changes: 1 addition & 1 deletion cli/cdsctl/environment_key.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ var environmentKeyCreateCmd = cli.Command{
func environmentCreateKeyRun(v cli.Values) error {
key := &sdk.EnvironmentKey{
Name: v.GetString("key-name"),
Type: v.GetString("key-type"),
Type: sdk.KeyType(v.GetString("key-type")),
}
if err := client.EnvironmentKeyCreate(v.GetString(_ProjectKey), v.GetString("env-name"), key); err != nil {
return err
Expand Down
2 changes: 1 addition & 1 deletion cli/cdsctl/project_key.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ var projectKeyCreateCmd = cli.Command{
func projectCreateKeyRun(v cli.Values) error {
key := &sdk.ProjectKey{
Name: v.GetString("key-name"),
Type: v.GetString("key-type"),
Type: sdk.KeyType(v.GetString("key-type")),
}
if err := client.ProjectKeyCreate(v.GetString(_ProjectKey), key); err != nil {
return err
Expand Down
32 changes: 32 additions & 0 deletions cli/cdsctl/template_apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,15 +200,23 @@ func templateApplyRun(v cli.Values) error {
}

var listRepositories []string
var listSSHKeys []string
var listPGPKeys []string
var localRepoPath string

// if there are params of type repository in list of params to fill prepare
// the list of repositories for project
var withRepository bool
var withKey bool
for _, p := range wt.Parameters {
if _, ok := params[p.Key]; !ok {
if p.Type == sdk.ParameterTypeRepository {
withRepository = true
}
if p.Type == sdk.ParameterTypeSSHKey || p.Type == sdk.ParameterTypePGPKey {
withKey = true
}
if withRepository && withKey {
break
}
}
Expand All @@ -234,6 +242,20 @@ func templateApplyRun(v cli.Values) error {
}
}
}
if withKey {
pKeys, err := client.ProjectKeysList(projectKey)
if err != nil {
return err
}
for _, k := range pKeys {
switch k.Type {
case sdk.KeyTypeSSH:
listSSHKeys = append(listSSHKeys, k.Name)
case sdk.KeyTypePGP:
listPGPKeys = append(listPGPKeys, k.Name)
}
}
}

// for each param not already fill ask for the value
for _, p := range wt.Parameters {
Expand All @@ -249,6 +271,16 @@ func templateApplyRun(v cli.Values) error {
selected := cli.AskChoice(label, listRepositories...)
choice = listRepositories[selected]
}
case sdk.ParameterTypeSSHKey:
if len(listSSHKeys) > 0 {
selected := cli.AskChoice(label, listSSHKeys...)
choice = listSSHKeys[selected]
}
case sdk.ParameterTypePGPKey:
if len(listPGPKeys) > 0 {
selected := cli.AskChoice(label, listPGPKeys...)
choice = listPGPKeys[selected]
}
case sdk.ParameterTypeBoolean:
choice = fmt.Sprintf("%t", cli.AskConfirm(fmt.Sprintf("Set value to 'true' for param '%s'", p.Key)))
}
Expand Down
71 changes: 48 additions & 23 deletions cli/cdsctl/template_bulk.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

"github.com/ovh/cds/cli"
"github.com/ovh/cds/sdk"
"github.com/ovh/cds/sdk/cdsclient"
"github.com/ovh/cds/sdk/exportentities"
)

Expand Down Expand Up @@ -387,6 +388,8 @@ func templateBulkRun(v cli.Values) error {
mprojects[wti.Project.Key] = wti.Project
}
projectRepositories := make(map[string][]string)
projectSSHKeys := make(map[string][]string)
projectPGPKeys := make(map[string][]string)

for operationKey, operation := range moperations {
// check if some params are missing for current operation
Expand All @@ -400,14 +403,14 @@ func templateBulkRun(v cli.Values) error {

if paramMissing {
// get project from map if exists else from api
if _, ok := mprojects[operationKey]; !ok {
p, err := client.ProjectGet(operation.Request.ProjectKey)
if _, ok := mprojects[operation.Request.ProjectKey]; !ok {
p, err := client.ProjectGet(operation.Request.ProjectKey, cdsclient.WithKeys())
if err != nil {
return err
}
mprojects[p.Key] = p
}
project := mprojects[operationKey]
project := mprojects[operation.Request.ProjectKey]

// for each param not already in previous request ask for the value
for _, p := range wt.Parameters {
Expand All @@ -416,40 +419,62 @@ func templateBulkRun(v cli.Values) error {

var value string
switch p.Type {
case sdk.ParameterTypeRepository:
// get the project and its repositories if not already loaded
if _, ok := projectRepositories[project.Key]; !ok {
for _, vcs := range project.VCSServers {
rs, err := client.RepositoriesList(project.Key, vcs.Name, false)
if err != nil {
return err
case sdk.ParameterTypeRepository, sdk.ParameterTypeSSHKey, sdk.ParameterTypePGPKey:
var options []string
if p.Type == sdk.ParameterTypeRepository {
// get the project and its repositories if not already loaded
if _, ok := projectRepositories[project.Key]; !ok {
for _, vcs := range project.VCSServers {
rs, err := client.RepositoriesList(project.Key, vcs.Name, false)
if err != nil {
return err
}
for _, r := range rs {
projectRepositories[project.Key] = append(projectRepositories[project.Key],
fmt.Sprintf("%s/%s", vcs.Name, r.Slug))
}
}
for _, r := range rs {
projectRepositories[project.Key] = append(projectRepositories[project.Key],
fmt.Sprintf("%s/%s", vcs.Name, r.Slug))
}
options = projectRepositories[project.Key]
} else if p.Type == sdk.ParameterTypeSSHKey {
if _, ok := projectSSHKeys[project.Key]; !ok {
var sshKeys []string
for _, k := range project.Keys {
if k.Type == sdk.KeyTypeSSH {
sshKeys = append(sshKeys, k.Name)
}
}
projectSSHKeys[project.Key] = sshKeys
}
options = projectSSHKeys[project.Key]
} else if p.Type == sdk.ParameterTypePGPKey {
if _, ok := projectPGPKeys[project.Key]; !ok {
var pgpKeys []string
for _, k := range project.Keys {
if k.Type == sdk.KeyTypePGP {
pgpKeys = append(pgpKeys, k.Name)
}
}
projectPGPKeys[project.Key] = pgpKeys
}
options = projectPGPKeys[project.Key]
}

// ask to choose a repository, if only one ask to, if no repo found ask for value
lengthRepo := len(projectRepositories[project.Key])
if lengthRepo > 1 {
if err := survey.AskOne(&survey.Select{
Message: label,
Options: projectRepositories[project.Key],
}, &value, nil); err != nil {
// ask to choose an option, if only one ask to, if no options found ask for value
if len(options) > 1 {
if err := survey.AskOne(&survey.Select{Message: label, Options: options}, &value, nil); err != nil {
return err
}
} else if lengthRepo == 1 {
} else if len(options) == 1 {
var result bool
if err := survey.AskOne(&survey.Confirm{
Message: fmt.Sprintf("Set value to '%s' for param '%s' on '%s'", projectRepositories[project.Key][0], p.Key, operationKey),
Message: fmt.Sprintf("Set value to '%s' for param '%s' on '%s'", options[0], p.Key, operationKey),
Default: true,
}, &result, nil); err != nil {
return err
}
if result {
value = projectRepositories[project.Key][0]
value = options[0]
}
}
if value == "" {
Expand Down
14 changes: 5 additions & 9 deletions cli/cdsctl/workflow_init.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ func craftApplicationFile(proj *sdk.Project, existingApp *sdk.Application, fetch
}
// The key is unknown, we have to create a new one
app.VCSPGPKey = defaultPGPKey
app.Keys[app.VCSPGPKey] = exportentities.KeyValue{Type: sdk.KeyTypePGP}
app.Keys[app.VCSPGPKey] = exportentities.KeyValue{Type: string(sdk.KeyTypePGP)}

fmt.Printf(" * using PGP Key %s/%s for application VCS settings", cli.Magenta(proj.Key), cli.Magenta(app.VCSPGPKey))
fmt.Println()
Expand All @@ -322,7 +322,7 @@ func craftApplicationFile(proj *sdk.Project, existingApp *sdk.Application, fetch
app.VCSPGPKey = opts[selected]
} else {
app.VCSPGPKey = fmt.Sprintf("app-pgp-%s", repoManagerName)
app.Keys[app.VCSPGPKey] = exportentities.KeyValue{Type: sdk.KeyTypePGP}
app.Keys[app.VCSPGPKey] = exportentities.KeyValue{Type: string(sdk.KeyTypePGP)}
}
} else if len(projectPGPKeys) == 1 {
app.VCSPGPKey = projectPGPKeys[0].Name
Expand All @@ -344,7 +344,7 @@ func craftApplicationFile(proj *sdk.Project, existingApp *sdk.Application, fetch
}

app.VCSSSHKey = defaultSSHKey
app.Keys[app.VCSSSHKey] = exportentities.KeyValue{Type: sdk.KeyTypeSSH}
app.Keys[app.VCSSSHKey] = exportentities.KeyValue{Type: string(sdk.KeyTypeSSH)}

fmt.Printf(" * using SSH Key %s/%s for application VCS settings", cli.Magenta(proj.Key), cli.Magenta(app.VCSSSHKey))
fmt.Println()
Expand All @@ -362,7 +362,7 @@ func craftApplicationFile(proj *sdk.Project, existingApp *sdk.Application, fetch
app.VCSSSHKey = opts[selected]
} else {
app.VCSSSHKey = fmt.Sprintf("app-ssh-%s", repoManagerName)
app.Keys[app.VCSSSHKey] = exportentities.KeyValue{Type: sdk.KeyTypePGP}
app.Keys[app.VCSSSHKey] = exportentities.KeyValue{Type: string(sdk.KeyTypePGP)}
}
} else if len(projectSSHKeys) == 1 {
app.VCSSSHKey = projectSSHKeys[0].Name
Expand Down Expand Up @@ -438,11 +438,7 @@ func workflowInitRun(c cli.Values) error {
}

// Check if the project is linked to a repository
proj, err := client.ProjectGet(pkey, func(r *http.Request) {
q := r.URL.Query()
q.Set("withKeys", "true")
r.URL.RawQuery = q.Encode()
})
proj, err := client.ProjectGet(pkey, cdsclient.WithKeys())
if err != nil {
return fmt.Errorf("unable to get project: %v", err)
}
Expand Down
2 changes: 1 addition & 1 deletion engine/api/application/application_exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func ExportApplication(db gorp.SqlExecutor, app sdk.Application, encryptFunc sdk
return exportentities.Application{}, sdk.WrapError(err, "unable to encrypt key")
}
ek := exportentities.EncryptedKey{
Type: k.Type,
Type: string(k.Type),
Name: k.Name,
Content: content,
}
Expand Down
2 changes: 1 addition & 1 deletion engine/api/application/application_importer.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ func Import(ctx context.Context, db gorp.SqlExecutor, store cache.Store, proj sd
return sdk.WrapError(err, "Unable to insert key %s", k.Name)
}
if msgChan != nil {
msgChan <- sdk.NewMessage(sdk.MsgAppKeyCreated, strings.ToUpper(k.Type), k.Name, app.Name)
msgChan <- sdk.NewMessage(sdk.MsgAppKeyCreated, strings.ToUpper(string(k.Type)), k.Name, app.Name)
}
}

Expand Down
2 changes: 1 addition & 1 deletion engine/api/application/application_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func ParseAndImport(ctx context.Context, db gorp.SqlExecutor, cache cache.Store,

//If the application exist and we don't want to force, raise an error
if oldApp != nil && !opts.Force {
return nil, msgList, sdk.ErrApplicationExist
return nil, msgList, sdk.WithStack(sdk.ErrApplicationExist)
}

if oldApp != nil && oldApp.FromRepository != "" && opts.FromRepository != oldApp.FromRepository {
Expand Down
4 changes: 2 additions & 2 deletions engine/api/application_import_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ func Test_postApplicationImportHandler_NewAppFromYAMLWithKeysAndSecretsAndReImpo
test.Equal(t, "MySecretValue", app.Variables[0].Value)
test.Equal(t, 2, len(app.Keys))

mKeys := make(map[string]sdk.ApplicationKey, 2)
mKeys := make(map[sdk.KeyType]sdk.ApplicationKey, 2)
mKeys[app.Keys[0].Type] = app.Keys[0]
mKeys[app.Keys[1].Type] = app.Keys[1]
rssh, ok := mKeys["ssh"]
Expand Down Expand Up @@ -493,7 +493,7 @@ func Test_postApplicationImportHandler_NewAppFromYAMLWithKeysAndSecretsAndReImpo
test.Equal(t, 1, len(app.Variables))
test.Equal(t, "MySecretValue", app.Variables[0].Value)
test.Equal(t, 2, len(app.Keys))
mKeys = make(map[string]sdk.ApplicationKey, 2)
mKeys = make(map[sdk.KeyType]sdk.ApplicationKey, 2)
mKeys[app.Keys[0].Type] = app.Keys[0]
mKeys[app.Keys[1].Type] = app.Keys[1]
rssh, ok = mKeys["ssh"]
Expand Down
7 changes: 6 additions & 1 deletion engine/api/ascode.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,10 +158,15 @@ func (api *API) postPerformImportAsCodeHandler() service.Handler {

consumer := getAPIConsumer(ctx)

var mods []workflowtemplate.TemplateRequestModifierFunc
mods := []workflowtemplate.TemplateRequestModifierFunc{
workflowtemplate.TemplateRequestModifiers.DefaultKeys(*proj),
}
if !opt.IsDefaultBranch {
mods = append(mods, workflowtemplate.TemplateRequestModifiers.Detached)
}
if opt.FromRepository != "" {
mods = append(mods, workflowtemplate.TemplateRequestModifiers.DefaultNameAndRepositories(ctx, api.mustDB(), api.Cache, *proj, opt.FromRepository))
}
wti, err := workflowtemplate.CheckAndExecuteTemplate(ctx, api.mustDB(), *consumer, *proj, &data, mods...)
if err != nil {
return err
Expand Down
2 changes: 1 addition & 1 deletion engine/api/environment/environment_exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func ExportEnvironment(db gorp.SqlExecutor, env sdk.Environment, encryptFunc sdk
return exportentities.Environment{}, sdk.WrapError(err, "Unable to encrypt key")
}
ek := exportentities.EncryptedKey{
Type: k.Type,
Type: string(k.Type),
Name: k.Name,
Content: content,
}
Expand Down
2 changes: 1 addition & 1 deletion engine/api/environment/environment_importer.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func Import(db gorp.SqlExecutor, proj sdk.Project, env *sdk.Environment, msgChan
return sdk.WrapError(err, "Unable to insert key %s", k.Name)
}
if msgChan != nil {
msgChan <- sdk.NewMessage(sdk.MsgEnvironmentKeyCreated, strings.ToUpper(k.Type), k.Name, env.Name)
msgChan <- sdk.NewMessage(sdk.MsgEnvironmentKeyCreated, strings.ToUpper(string(k.Type)), k.Name, env.Name)
}
}

Expand Down
4 changes: 1 addition & 3 deletions engine/api/event/publish_project.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,7 @@ func PublishAddProjectKey(ctx context.Context, p *sdk.Project, k sdk.ProjectKey,

// PublishDeleteProjectKey publishes an event on deleting a project key
func PublishDeleteProjectKey(ctx context.Context, p *sdk.Project, k sdk.ProjectKey, u sdk.Identifiable) {
if sdk.NeedPlaceholder(k.Type) {
k.Private = sdk.PasswordPlaceholder
}
k.Private = sdk.PasswordPlaceholder
e := sdk.EventProjectKeyDelete{
Key: k,
}
Expand Down
2 changes: 1 addition & 1 deletion engine/api/keys/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ type DecryptFunc func(gorp.SqlExecutor, int64, string) (string, error)
// Parse and decrypts an exported key
func Parse(db gorp.SqlExecutor, projID int64, kname string, kval exportentities.KeyValue, decryptFunc DecryptFunc) (*sdk.Key, error) {
k := new(sdk.Key)
k.Type = kval.Type
k.Type = sdk.KeyType(kval.Type)
k.Name = kname
if kval.Value != "" {
privateKey, err := decryptFunc(db, projID, kval.Value)
Expand Down
2 changes: 1 addition & 1 deletion engine/api/migrate/refactor_app_keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ func refactorApplicationKeys(ctx context.Context, db *gorp.DbMap, id int64) erro
if err != nil {
return err
}
k.Type = s
k.Type = sdk.KeyType(s)

s, err = stringIfValid("public", public)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion engine/api/migrate/refactor_env_keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ func refactorEnvironmentKeys(ctx context.Context, db *gorp.DbMap, id int64) erro
if err != nil {
return err
}
k.Type = s
k.Type = sdk.KeyType(s)

s, err = stringIfValid("public", public)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion engine/api/migrate/refactor_proj_keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ func refactorProjectKeys(ctx context.Context, db *gorp.DbMap, id int64) error {
if err != nil {
return err
}
k.Type = s
k.Type = sdk.KeyType(s)

s, err = stringIfValid("public", public)
if err != nil {
Expand Down
Loading

0 comments on commit 0eedf85

Please sign in to comment.