Skip to content

Commit

Permalink
feat(api,cli): add endpoint to copy variable from v1 to v2 (#6931)
Browse files Browse the repository at this point in the history
  • Loading branch information
sguiheux committed May 7, 2024
1 parent 309f980 commit 21636a7
Show file tree
Hide file tree
Showing 9 changed files with 519 additions and 1 deletion.
10 changes: 10 additions & 0 deletions cli/cdsctl/experimental_project_variableset.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,22 @@ var projectVariableSetCreateCmd = cli.Command{
Args: []cli.Arg{
{Name: "name"},
},
Flags: []cli.Flag{
{Name: "application-name", Type: cli.FlagString},
},
}

func projectVariableSetCreateFunc(v cli.Values) error {
vs := sdk.ProjectVariableSet{
Name: v.GetString("name"),
}

if v.GetString("application-name") != "" {
copyReq := sdk.CopyApplicationVariableToVariableSet{
ApplicationName: v.GetString("application-name"),
VariableSetName: v.GetString("name"),
}
return client.ProjectVariableSetCreateFromApplication(context.Background(), v.GetString(_ProjectKey), copyReq)
}
return client.ProjectVariableSetCreate(context.Background(), v.GetString(_ProjectKey), &vs)
}
48 changes: 47 additions & 1 deletion cli/cdsctl/experimental_project_variableset_item.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ package main
import (
"context"
"fmt"
"strconv"

"github.com/spf13/cobra"

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

var projectVariableSetItemCmd = cli.Command{
Expand All @@ -23,6 +25,7 @@ func projectVariableSetItem() *cobra.Command {
cli.NewCommand(projectVariableSetItemCreateCmd, projectVariableSetItemCreateFunc, nil, withAllCommandModifiers()...),
cli.NewCommand(projectVariableSetItemUpdateCmd, projectVariableSetItemUpdateFunc, nil, withAllCommandModifiers()...),
cli.NewGetCommand(projectVariableSetItemShowCmd, projectVariableSetItemShowFunc, nil, withAllCommandModifiers()...),
cli.NewCommand(projectVariableSetItemFromProjectCmd, projectVariableSetItemFromProjectFunc, nil, withAllCommandModifiers()...),
})
}

Expand Down Expand Up @@ -79,6 +82,49 @@ func projectVariableSetItemDeleteFunc(v cli.Values) error {
return client.ProjectVariableSetItemDelete(context.Background(), v.GetString(_ProjectKey), v.GetString("variableset-name"), v.GetString("item-name"))
}

var projectVariableSetItemFromProjectCmd = cli.Command{
Name: "from-project",
Aliases: []string{"fp"},
Short: "Copy a project variable to the given variable set",
Example: "cdsctl X project variableset item from-project PROJECT_KEY VARIABLE_NAME MY-VARIABLESET-NAME --rename NEW_NAME",
Ctx: []cli.Arg{
{Name: _ProjectKey},
},
Args: []cli.Arg{
{Name: "variable-name"},
{Name: "variableset-name"},
},
Flags: []cli.Flag{
{
Name: "rename",
Type: cli.FlagString,
Usage: "New name for the variable",
},
{
Name: "force",
Type: cli.FlagBool,
Usage: "Create the variable set if it not exists",
},
},
}

func projectVariableSetItemFromProjectFunc(v cli.Values) error {
varName := v.GetString("variable-name")
vsName := v.GetString("variableset-name")
rename := v.GetString("rename")
force := strconv.FormatBool(v.GetBool("force"))

copyRequest := sdk.CopyProjectVariableToVariableSet{
VariableName: varName,
VariableSetName: vsName,
NewName: rename,
}
if copyRequest.NewName == "" {
copyRequest.NewName = varName
}
return client.ProjectVariableSetItemFromProjectVariable(context.Background(), v.GetString(_ProjectKey), copyRequest, cdsclient.WithQueryParameter("force", force))
}

var projectVariableSetItemCreateCmd = cli.Command{
Name: "add",
Aliases: []string{"create"},
Expand All @@ -97,7 +143,7 @@ var projectVariableSetItemCreateCmd = cli.Command{
{
Name: "force",
Type: cli.FlagBool,
Usage: "create the variable set if it not exists",
Usage: "create the variable set if it does not exists",
},
},
}
Expand Down
3 changes: 3 additions & 0 deletions engine/api/api_routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,9 @@ func (api *API) InitRouter() {
r.Handle("/v2/region", nil, r.POSTv2(api.postRegionHandler), r.GETv2(api.getRegionsHandler))
r.Handle("/v2/region/{regionIdentifier}", nil, r.GETv2(api.getRegionHandler), r.DELETEv2(api.deleteRegionHandler))

r.Handle("/v2/migrate/project/{projectKey}/variableset/item", nil, r.POSTv2(api.postMigrateProjectVariableHandler))
r.Handle("/v2/migrate/project/{projectKey}/variableset/application", nil, r.POSTv2(api.postMigrateApplicationVariableToVariableSetHandler))

r.Handle("/v2/project/{projectKey}/type/{type}/access", Scope(sdk.AuthConsumerScopeService), r.GETv2(api.getProjectV2AccessHandler))

r.Handle("/v2/project/{projectKey}/notification", nil, r.GETv2(api.getProjectNotifsHandler), r.POSTv2(api.postProjectNotificationHandler))
Expand Down
155 changes: 155 additions & 0 deletions engine/api/v2_project_variable_migrate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
package api

import (
"context"
"net/http"

"github.com/gorilla/mux"

"github.com/ovh/cds/engine/api/application"
"github.com/ovh/cds/engine/api/project"
"github.com/ovh/cds/engine/service"
"github.com/ovh/cds/sdk"
)

func (api *API) postMigrateApplicationVariableToVariableSetHandler() ([]service.RbacChecker, service.Handler) {
return service.RBAC(api.projectManage),
func(ctx context.Context, w http.ResponseWriter, req *http.Request) error {
vars := mux.Vars(req)
pKey := vars["projectKey"]

var copyRequest sdk.CopyApplicationVariableToVariableSet
if err := service.UnmarshalBody(req, &copyRequest); err != nil {
return err
}

app, err := application.LoadByName(ctx, api.mustDB(), pKey, copyRequest.ApplicationName, application.LoadOptions.WithVariablesWithClearPassword)
if err != nil {
return err
}

tx, err := api.mustDB().Begin()
if err != nil {
return sdk.WithStack(err)
}
defer tx.Rollback() //nolint

vs, err := project.LoadVariableSetByName(ctx, api.mustDB(), pKey, copyRequest.VariableSetName)
if err != nil && !sdk.ErrorIs(err, sdk.ErrNotFound) {
return err
}
if sdk.ErrorIs(err, sdk.ErrNotFound) {
vs = &sdk.ProjectVariableSet{
Name: copyRequest.VariableSetName,
ProjectKey: pKey,
}
if err := project.InsertVariableSet(ctx, tx, vs); err != nil {
return err
}
}

for _, v := range app.Variables {
itemType := sdk.ProjectVariableTypeString
if v.Type == sdk.SecretVariable {
itemType = sdk.ProjectVariableTypeSecret
}
it := &sdk.ProjectVariableSetItem{
ProjectVariableSetID: vs.ID,
Name: v.Name,
Type: itemType,
Value: v.Value,
}
switch v.Type {
case sdk.SecretVariable:
if err := project.InsertVariableSetItemSecret(ctx, tx, it); err != nil {
return err
}
default:
if err := project.InsertVariableSetItemText(ctx, tx, it); err != nil {
return err
}
}
}
if err := tx.Commit(); err != nil {
return sdk.WithStack(err)
}
return service.WriteJSON(w, nil, http.StatusOK)
}
}

func (api *API) postMigrateProjectVariableHandler() ([]service.RbacChecker, service.Handler) {
return service.RBAC(api.projectManage),
func(ctx context.Context, w http.ResponseWriter, req *http.Request) error {
vars := mux.Vars(req)
pKey := vars["projectKey"]
force := service.FormBool(req, "force")

var copyRequest sdk.CopyProjectVariableToVariableSet
if err := service.UnmarshalBody(req, &copyRequest); err != nil {
return err
}
if copyRequest.NewName == "" {
copyRequest.NewName = copyRequest.VariableName
}

proj, err := project.Load(ctx, api.mustDB(), pKey, project.LoadOptions.WithVariablesWithClearPassword)
if err != nil {
return err
}

tx, err := api.mustDB().Begin()
if err != nil {
return sdk.WithStack(err)
}
defer tx.Rollback() //nolint

vs, err := project.LoadVariableSetByName(ctx, api.mustDB(), pKey, copyRequest.VariableSetName)
if err != nil && !sdk.ErrorIs(err, sdk.ErrNotFound) {
return err
}
if sdk.ErrorIs(err, sdk.ErrNotFound) {
if force {
vs = &sdk.ProjectVariableSet{
Name: copyRequest.VariableSetName,
ProjectKey: pKey,
}
if err := project.InsertVariableSet(ctx, tx, vs); err != nil {
return err
}
} else {
return sdk.NewErrorFrom(sdk.ErrNotFound, "Variable set %s doesn't exist", copyRequest.VariableSetName)
}
}

for _, v := range proj.Variables {
if v.Name == copyRequest.VariableName {
itemType := sdk.ProjectVariableTypeString
if v.Type == sdk.SecretVariable {
itemType = sdk.ProjectVariableTypeSecret
}
it := &sdk.ProjectVariableSetItem{
ProjectVariableSetID: vs.ID,
Name: copyRequest.NewName,
Type: itemType,
Value: v.Value,
}
switch v.Type {
case sdk.SecretVariable:
if err := project.InsertVariableSetItemSecret(ctx, tx, it); err != nil {
return err
}
default:
if err := project.InsertVariableSetItemText(ctx, tx, it); err != nil {
return err
}
}
break
}
}

if err := tx.Commit(); err != nil {
return sdk.WithStack(err)
}
return service.WriteJSON(w, nil, http.StatusOK)
}
}

0 comments on commit 21636a7

Please sign in to comment.