Skip to content

Commit

Permalink
Add koyeb db update --instance-type, closes #180
Browse files Browse the repository at this point in the history
  • Loading branch information
brmzkw committed Jan 30, 2024
1 parent 3b5eda1 commit 9df3695
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 10 deletions.
5 changes: 3 additions & 2 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## (unreleased)
## v3.7.1

* ...
* Add `koyeb db update <name> --instance-type <type>` to update the instance type of a database
- https://github.com/koyeb/koyeb-cli/issues/180

## v3.7.0

Expand Down
34 changes: 34 additions & 0 deletions docs/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -2092,6 +2092,7 @@ Databases
* [koyeb databases delete](#koyeb-databases-delete) - Delete database
* [koyeb databases get](#koyeb-databases-get) - Get database
* [koyeb databases list](#koyeb-databases-list) - List databases
* [koyeb databases update](#koyeb-databases-update) - Update database

## koyeb databases create

Expand Down Expand Up @@ -2224,6 +2225,39 @@ koyeb databases list [flags]



* [koyeb databases](#koyeb-databases) - Databases

## koyeb databases update

Update database

```
koyeb databases update NAME [flags]
```

### Options

```
-h, --help help for update
--instance-type string Instance type (free, small, medium or large) (default "free")
```

### Options inherited from parent commands

```
-c, --config string config file (default is $HOME/.koyeb.yaml)
-d, --debug enable the debug output
--debug-full do not hide sensitive information (tokens) in the debug output
--force-ascii only output ascii characters (no unicode emojis)
--full do not truncate output
--organization string organization ID
-o, --output output output format (yaml,json,table)
--token string API token
--url string url of the api (default "https://app.koyeb.com")
```



* [koyeb databases](#koyeb-databases) - Databases

## koyeb version
Expand Down
80 changes: 72 additions & 8 deletions pkg/koyeb/databases.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,59 @@ func NewDatabaseCmd() *cobra.Command {
return h.Create(ctx, cmd, args, createService)
}),
}
addDbServiceDefinitionFlags(createDbCmd.Flags())
addCreateDbServiceDefinitionFlags(createDbCmd.Flags())
databaseCmd.AddCommand(createDbCmd)

updateDbCmd := &cobra.Command{
Use: "update NAME",
Short: "Update database",
Args: cobra.ExactArgs(1),
RunE: WithCLIContext(func(ctx *CLIContext, cmd *cobra.Command, args []string) error {
service, err := h.ResolveDatabaseArgs(ctx, args[0])
if err != nil {
return err
}

latestDeployment, resp, err := ctx.Client.DeploymentsApi.
ListDeployments(ctx.Context).
Limit("1").
ServiceId(service).
Execute()
if err != nil {
return errors.NewCLIErrorFromAPIError(
fmt.Sprintf("Error while updating the service `%s`", args[0]),
err,
resp,
)
}
if len(latestDeployment.GetDeployments()) == 0 {
return &errors.CLIError{
What: "Error while updating the database",
Why: "we couldn't find the latest deployment of your database",
Additional: []string{
"When you create a database for the first time, it can take a few seconds for the first deployment to be created.",
"We need to fetch the configuration of this latest deployment to update your database.",
},
Orig: nil,
Solution: "Try again in a few seconds. If the problem persists, please create an issue on https://github.com/koyeb/koyeb-cli/issues/new",
}
}

updateDef := latestDeployment.GetDeployments()[0].GetDefinition()

if err := parseDbServiceDefinitionFlags(cmd.Flags(), updateDef.GetName(), &updateDef); err != nil {
return err
}

updateService := koyeb.NewUpdateServiceWithDefaults()
updateService.SetDefinition(updateDef)

return h.Update(ctx, cmd, args, service, updateService)
}),
}
addUpdateDbServiceDefinitionFlags(updateDbCmd.Flags())
databaseCmd.AddCommand(updateDbCmd)

deleteDbCmd := &cobra.Command{
Use: "delete NAME",
Short: "Delete database",
Expand All @@ -71,12 +121,18 @@ func NewDatabaseCmd() *cobra.Command {
return databaseCmd
}

func addDbServiceDefinitionFlags(flags *pflag.FlagSet) {
func addUpdateDbServiceDefinitionFlags(flags *pflag.FlagSet) {
flags.String("instance-type", "free", "Instance type (free, small, medium or large)")
}

// All the flags to create a database include the flags to update a database, plus more.
func addCreateDbServiceDefinitionFlags(flags *pflag.FlagSet) {
addUpdateDbServiceDefinitionFlags(flags)

flags.Int64("pg-version", 16, "PostgreSQL version")
flags.String("region", "fra", "Region where the database is deployed")
flags.String("db-name", "koyebdb", "Database name")
flags.String("db-owner", "koyeb-adm", "Database owner")
flags.String("instance-type", "free", "Instance type (free, small, medium or large)")
}

// parseDbServiceDefinitionFlags parses the flags to update the deployment definition.
Expand Down Expand Up @@ -111,27 +167,35 @@ func parseDbServiceDefinitionFlags(flags *pflag.FlagSet, serviceName string, def
definition.SetType(koyeb.DEPLOYMENTDEFINITIONTYPE_DATABASE)
definition.SetName(serviceName)

flagChanged := func(name string) bool {
f := flags.Lookup(name)
if f == nil {
return false
}
return f.Changed
}

if !definition.HasDatabase() {
definition.SetDatabase(*koyeb.NewDatabaseSourceWithDefaults())
}
if !definition.Database.HasNeonPostgres() {
definition.Database.SetNeonPostgres(*koyeb.NewNeonPostgresDatabaseWithDefaults())
}

if definition.Database.NeonPostgres.PgVersion == nil || flags.Lookup("pg-version").Changed {
if definition.Database.NeonPostgres.PgVersion == nil || flagChanged("pg-version") {
version, _ := flags.GetInt64("pg-version")
definition.Database.NeonPostgres.SetPgVersion(version)
}
if definition.Database.NeonPostgres.Region == nil || flags.Lookup("region").Changed {
if definition.Database.NeonPostgres.Region == nil || flagChanged("region") {
region, _ := flags.GetString("region")
definition.Database.NeonPostgres.SetRegion(region)
}
if definition.Database.NeonPostgres.InstanceType == nil || flags.Lookup("instance-type").Changed {
if definition.Database.NeonPostgres.InstanceType == nil || flagChanged("instance-type") {
instanceType, _ := flags.GetString("instance-type")
definition.Database.NeonPostgres.SetInstanceType(instanceType)
}

if len(definition.Database.NeonPostgres.Roles) == 0 || flags.Lookup("db-owner").Changed {
if len(definition.Database.NeonPostgres.Roles) == 0 || flagChanged("db-owner") {
if len(definition.Database.NeonPostgres.Roles) > 1 {
return &errors.CLIError{
What: "Error while updating the database service definition",
Expand All @@ -157,7 +221,7 @@ func parseDbServiceDefinitionFlags(flags *pflag.FlagSet, serviceName string, def
definition.Database.NeonPostgres.Roles[0].Name = &owner
}

if len(definition.Database.NeonPostgres.Databases) == 0 || flags.Lookup("db-name").Changed {
if len(definition.Database.NeonPostgres.Databases) == 0 || flagChanged("db-name") {
if len(definition.Database.NeonPostgres.Databases) > 1 {
return &errors.CLIError{
What: "Error while updating the database service definition",
Expand Down
25 changes: 25 additions & 0 deletions pkg/koyeb/databases_update.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package koyeb

import (
"fmt"

"github.com/koyeb/koyeb-api-client-go/api/v1/koyeb"
"github.com/koyeb/koyeb-cli/pkg/koyeb/errors"
"github.com/spf13/cobra"
)

func (h *DatabaseHandler) Update(ctx *CLIContext, cmd *cobra.Command, args []string, serviceId string, updateService *koyeb.UpdateService) error {
res, resp, err := ctx.Client.ServicesApi.UpdateService(ctx.Context, serviceId).Service(*updateService).Execute()
if err != nil {
return errors.NewCLIErrorFromAPIError(
fmt.Sprintf("Error while updating the service `%s`", args[0]),
err,
resp,
)
}

full := GetBoolFlags(cmd, "full")
getServiceReply := NewGetServiceReply(ctx.Mapper, &koyeb.GetServiceReply{Service: res.Service}, full)
ctx.Renderer.Render(getServiceReply)
return nil
}

0 comments on commit 9df3695

Please sign in to comment.