Skip to content

Commit 530511e

Browse files
GokceGKDiogoFerrao
andauthored
Onboard postgresflex backup commands (#169)
* onboard postgresflex backup commands * add docs * move backups directly under postgresflex * change used bytesize library * remove empty spaces * use constants for backup expiration offset * add expire date in list output * remove redundant backup * adapt table columns for list and describe output * generate docs * generate docs * Edit descriptions Co-authored-by: Diogo Ferrão <[email protected]> * Edit descriptions Co-authored-by: Diogo Ferrão <[email protected]> * Edit descriptions Co-authored-by: Diogo Ferrão <[email protected]> * rename backup file * add missing test cases * generate docs --------- Co-authored-by: Diogo Ferrão <[email protected]>
1 parent 2d1b914 commit 530511e

15 files changed

+1294
-1
lines changed

docs/stackit_postgresflex.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ stackit postgresflex [flags]
2929
### SEE ALSO
3030

3131
* [stackit](./stackit.md) - Manage STACKIT resources using the command line
32+
* [stackit postgresflex backup](./stackit_postgresflex_backup.md) - Provides functionality for PostgreSQL Flex instance backups
3233
* [stackit postgresflex instance](./stackit_postgresflex_instance.md) - Provides functionality for PostgreSQL Flex instances
3334
* [stackit postgresflex options](./stackit_postgresflex_options.md) - Lists PostgreSQL Flex options
3435
* [stackit postgresflex user](./stackit_postgresflex_user.md) - Provides functionality for PostgreSQL Flex users

docs/stackit_postgresflex_backup.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
## stackit postgresflex backup
2+
3+
Provides functionality for PostgreSQL Flex instance backups
4+
5+
### Synopsis
6+
7+
Provides functionality for PostgreSQL Flex instance backups.
8+
9+
```
10+
stackit postgresflex backup [flags]
11+
```
12+
13+
### Options
14+
15+
```
16+
-h, --help Help for "stackit postgresflex backup"
17+
```
18+
19+
### Options inherited from parent commands
20+
21+
```
22+
-y, --assume-yes If set, skips all confirmation prompts
23+
--async If set, runs the command asynchronously
24+
-o, --output-format string Output format, one of ["json" "pretty" "none"]
25+
-p, --project-id string Project ID
26+
--verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info")
27+
```
28+
29+
### SEE ALSO
30+
31+
* [stackit postgresflex](./stackit_postgresflex.md) - Provides functionality for PostgreSQL Flex
32+
* [stackit postgresflex backup describe](./stackit_postgresflex_backup_describe.md) - Shows details of a backup for a PostgreSQL Flex instance
33+
* [stackit postgresflex backup list](./stackit_postgresflex_backup_list.md) - Lists all backups which are available for a PostgreSQL Flex instance
34+
* [stackit postgresflex backup update-schedule](./stackit_postgresflex_backup_update-schedule.md) - Updates backup schedule for a PostgreSQL Flex instance
35+
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
## stackit postgresflex backup describe
2+
3+
Shows details of a backup for a PostgreSQL Flex instance
4+
5+
### Synopsis
6+
7+
Shows details of a backup for a PostgreSQL Flex instance.
8+
9+
```
10+
stackit postgresflex backup describe BACKUP_ID [flags]
11+
```
12+
13+
### Examples
14+
15+
```
16+
Get details of a backup with ID "xxx" for a PostgreSQL Flex instance with ID "yyy"
17+
$ stackit postgresflex backup describe xxx --instance-id yyy
18+
19+
Get details of a backup with ID "xxx" for a PostgreSQL Flex instance with ID "yyy" in a table format
20+
$ stackit postgresflex backup describe xxx --instance-id yyy --output-format pretty
21+
```
22+
23+
### Options
24+
25+
```
26+
-h, --help Help for "stackit postgresflex backup describe"
27+
--instance-id string Instance ID
28+
```
29+
30+
### Options inherited from parent commands
31+
32+
```
33+
-y, --assume-yes If set, skips all confirmation prompts
34+
--async If set, runs the command asynchronously
35+
-o, --output-format string Output format, one of ["json" "pretty" "none"]
36+
-p, --project-id string Project ID
37+
--verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info")
38+
```
39+
40+
### SEE ALSO
41+
42+
* [stackit postgresflex backup](./stackit_postgresflex_backup.md) - Provides functionality for PostgreSQL Flex instance backups
43+
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
## stackit postgresflex backup list
2+
3+
Lists all backups which are available for a PostgreSQL Flex instance
4+
5+
### Synopsis
6+
7+
Lists all backups which are available for a PostgreSQL Flex instance.
8+
9+
```
10+
stackit postgresflex backup list [flags]
11+
```
12+
13+
### Examples
14+
15+
```
16+
List all backups of instance with ID "xxx"
17+
$ stackit postgresflex backup list --instance-id xxx
18+
19+
List all backups of instance with ID "xxx" in JSON format
20+
$ stackit postgresflex backup list --instance-id xxx --output-format json
21+
22+
List up to 10 backups of instance with ID "xxx"
23+
$ stackit postgresflex backup list --instance-id xxx --limit 10
24+
```
25+
26+
### Options
27+
28+
```
29+
-h, --help Help for "stackit postgresflex backup list"
30+
--instance-id string Instance ID
31+
--limit int Maximum number of entries to list
32+
```
33+
34+
### Options inherited from parent commands
35+
36+
```
37+
-y, --assume-yes If set, skips all confirmation prompts
38+
--async If set, runs the command asynchronously
39+
-o, --output-format string Output format, one of ["json" "pretty" "none"]
40+
-p, --project-id string Project ID
41+
--verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info")
42+
```
43+
44+
### SEE ALSO
45+
46+
* [stackit postgresflex backup](./stackit_postgresflex_backup.md) - Provides functionality for PostgreSQL Flex instance backups
47+
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
## stackit postgresflex backup update-schedule
2+
3+
Updates backup schedule for a PostgreSQL Flex instance
4+
5+
### Synopsis
6+
7+
Updates backup schedule for a PostgreSQL Flex instance.
8+
9+
```
10+
stackit postgresflex backup update-schedule [flags]
11+
```
12+
13+
### Examples
14+
15+
```
16+
Update the backup schedule of a PostgreSQL Flex instance with ID "xxx"
17+
$ stackit postgresflex backup update-schedule --instance-id xxx --schedule '6 6 * * *'
18+
```
19+
20+
### Options
21+
22+
```
23+
-h, --help Help for "stackit postgresflex backup update-schedule"
24+
--instance-id string Instance ID
25+
--schedule string Backup schedule, in the cron scheduling system format e.g. '0 0 * * *'
26+
```
27+
28+
### Options inherited from parent commands
29+
30+
```
31+
-y, --assume-yes If set, skips all confirmation prompts
32+
--async If set, runs the command asynchronously
33+
-o, --output-format string Output format, one of ["json" "pretty" "none"]
34+
-p, --project-id string Project ID
35+
--verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info")
36+
```
37+
38+
### SEE ALSO
39+
40+
* [stackit postgresflex backup](./stackit_postgresflex_backup.md) - Provides functionality for PostgreSQL Flex instance backups
41+

go.mod

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ require (
66
github.com/golang-jwt/jwt/v5 v5.2.1
77
github.com/google/go-cmp v0.6.0
88
github.com/google/uuid v1.6.0
9-
github.com/jedib0t/go-pretty/v6 v6.5.8
9+
github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf
10+
github.com/jedib0t/go-pretty/v6 v6.5.6
1011
github.com/spf13/cobra v1.8.0
1112
github.com/spf13/pflag v1.0.5
1213
github.com/spf13/viper v1.18.2

go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
2424
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
2525
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
2626
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
27+
github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf h1:FtEj8sfIcaaBfAKrE1Cwb61YDtYq9JxChK1c7AKce7s=
28+
github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf/go.mod h1:yrqSXGoD/4EKfF26AOGzscPOgTTJcyAwM2rpixWT+t4=
29+
github.com/jedib0t/go-pretty/v6 v6.5.6 h1:nKXVLqPfAwY7sWcYXdNZZZ2fjqDpAtj9UeWupgfUxSg=
30+
github.com/jedib0t/go-pretty/v6 v6.5.6/go.mod h1:5LQIxa52oJ/DlDSLv0HEkWOFMDGoWkJb9ss5KqPpJBg=
2731
github.com/jedib0t/go-pretty/v6 v6.5.8 h1:8BCzJdSvUbaDuRba4YVh+SKMGcAAKdkcF3SVFbrHAtQ=
2832
github.com/jedib0t/go-pretty/v6 v6.5.8/go.mod h1:zbn98qrYlh95FIhwwsbIip0LYpwSG8SUOScs+v9/t0E=
2933
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package backup
2+
3+
import (
4+
"github.com/stackitcloud/stackit-cli/internal/cmd/postgresflex/backup/describe"
5+
"github.com/stackitcloud/stackit-cli/internal/cmd/postgresflex/backup/list"
6+
updateschedule "github.com/stackitcloud/stackit-cli/internal/cmd/postgresflex/backup/update-schedule"
7+
"github.com/stackitcloud/stackit-cli/internal/pkg/args"
8+
"github.com/stackitcloud/stackit-cli/internal/pkg/print"
9+
"github.com/stackitcloud/stackit-cli/internal/pkg/utils"
10+
11+
"github.com/spf13/cobra"
12+
)
13+
14+
func NewCmd(p *print.Printer) *cobra.Command {
15+
cmd := &cobra.Command{
16+
Use: "backup",
17+
Short: "Provides functionality for PostgreSQL Flex instance backups",
18+
Long: "Provides functionality for PostgreSQL Flex instance backups.",
19+
Args: args.NoArgs,
20+
Run: utils.CmdHelp,
21+
}
22+
addSubcommands(cmd, p)
23+
return cmd
24+
}
25+
26+
func addSubcommands(cmd *cobra.Command, p *print.Printer) {
27+
cmd.AddCommand(list.NewCmd(p))
28+
cmd.AddCommand(describe.NewCmd(p))
29+
cmd.AddCommand(updateschedule.NewCmd(p))
30+
}
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
package describe
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
"fmt"
7+
8+
"time"
9+
10+
"github.com/inhies/go-bytesize"
11+
"github.com/spf13/cobra"
12+
"github.com/stackitcloud/stackit-cli/internal/pkg/args"
13+
"github.com/stackitcloud/stackit-cli/internal/pkg/errors"
14+
"github.com/stackitcloud/stackit-cli/internal/pkg/examples"
15+
"github.com/stackitcloud/stackit-cli/internal/pkg/flags"
16+
"github.com/stackitcloud/stackit-cli/internal/pkg/globalflags"
17+
"github.com/stackitcloud/stackit-cli/internal/pkg/print"
18+
"github.com/stackitcloud/stackit-cli/internal/pkg/services/postgresflex/client"
19+
"github.com/stackitcloud/stackit-cli/internal/pkg/tables"
20+
"github.com/stackitcloud/stackit-sdk-go/services/postgresflex"
21+
)
22+
23+
const (
24+
backupIdArg = "BACKUP_ID"
25+
26+
instanceIdFlag = "instance-id"
27+
28+
backupExpireYearOffset = 0
29+
backupExpireMonthOffset = 0
30+
backupExpireDayOffset = 30
31+
)
32+
33+
type inputModel struct {
34+
*globalflags.GlobalFlagModel
35+
36+
InstanceId string
37+
BackupId string
38+
}
39+
40+
func NewCmd(p *print.Printer) *cobra.Command {
41+
cmd := &cobra.Command{
42+
Use: fmt.Sprintf("describe %s", backupIdArg),
43+
Short: "Shows details of a backup for a PostgreSQL Flex instance",
44+
Long: "Shows details of a backup for a PostgreSQL Flex instance.",
45+
Example: examples.Build(
46+
examples.NewExample(
47+
`Get details of a backup with ID "xxx" for a PostgreSQL Flex instance with ID "yyy"`,
48+
"$ stackit postgresflex backup describe xxx --instance-id yyy"),
49+
examples.NewExample(
50+
`Get details of a backup with ID "xxx" for a PostgreSQL Flex instance with ID "yyy" in a table format`,
51+
"$ stackit postgresflex backup describe xxx --instance-id yyy --output-format pretty"),
52+
),
53+
Args: args.SingleArg(backupIdArg, nil),
54+
RunE: func(cmd *cobra.Command, args []string) error {
55+
ctx := context.Background()
56+
model, err := parseInput(p, cmd, args)
57+
if err != nil {
58+
return err
59+
}
60+
61+
// Configure API client
62+
apiClient, err := client.ConfigureClient(p)
63+
if err != nil {
64+
return err
65+
}
66+
67+
// Call API
68+
req := buildRequest(ctx, model, apiClient)
69+
resp, err := req.Execute()
70+
71+
if err != nil {
72+
return fmt.Errorf("describe backup for PostgreSQL Flex instance: %w", err)
73+
}
74+
75+
return outputResult(p, cmd, model.OutputFormat, *resp.Item)
76+
},
77+
}
78+
configureFlags(cmd)
79+
return cmd
80+
}
81+
82+
func configureFlags(cmd *cobra.Command) {
83+
cmd.Flags().Var(flags.UUIDFlag(), instanceIdFlag, "Instance ID")
84+
85+
err := flags.MarkFlagsRequired(cmd, instanceIdFlag)
86+
cobra.CheckErr(err)
87+
}
88+
89+
func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inputModel, error) {
90+
backupId := inputArgs[0]
91+
92+
globalFlags := globalflags.Parse(p, cmd)
93+
if globalFlags.ProjectId == "" {
94+
return nil, &errors.ProjectIdError{}
95+
}
96+
97+
return &inputModel{
98+
GlobalFlagModel: globalFlags,
99+
InstanceId: flags.FlagToStringValue(p, cmd, instanceIdFlag),
100+
BackupId: backupId,
101+
}, nil
102+
}
103+
104+
func buildRequest(ctx context.Context, model *inputModel, apiClient *postgresflex.APIClient) postgresflex.ApiGetBackupRequest {
105+
req := apiClient.GetBackup(ctx, model.ProjectId, model.InstanceId, model.BackupId)
106+
return req
107+
}
108+
109+
func outputResult(p *print.Printer, cmd *cobra.Command, outputFormat string, backup postgresflex.Backup) error {
110+
backupStartTime, err := time.Parse(time.RFC3339, *backup.StartTime)
111+
if err != nil {
112+
return fmt.Errorf("parse backup start time: %w", err)
113+
}
114+
backupExpireDate := backupStartTime.AddDate(backupExpireYearOffset, backupExpireMonthOffset, backupExpireDayOffset).Format(time.DateOnly)
115+
116+
switch outputFormat {
117+
case print.PrettyOutputFormat:
118+
table := tables.NewTable()
119+
table.AddRow("ID", *backup.Id)
120+
table.AddSeparator()
121+
table.AddRow("START TIME", *backup.StartTime)
122+
table.AddSeparator()
123+
table.AddRow("EXPIRES AT", backupExpireDate)
124+
table.AddSeparator()
125+
table.AddRow("BACKUP SIZE", bytesize.New(float64(*backup.Size)))
126+
127+
err := table.Display(p)
128+
if err != nil {
129+
return fmt.Errorf("render table: %w", err)
130+
}
131+
132+
return nil
133+
default:
134+
details, err := json.MarshalIndent(backup, "", " ")
135+
if err != nil {
136+
return fmt.Errorf("marshal backup for PostgreSQL Flex instance: %w", err)
137+
}
138+
cmd.Println(string(details))
139+
140+
return nil
141+
}
142+
}

0 commit comments

Comments
 (0)