Latest Threat Research:SANDWORM_MODE: Shai-Hulud-Style npm Worm Hijacks CI Workflows and Poisons AI Toolchains.Details
Socket
Book a DemoInstallSign in
Socket

mygithub.libinneed.workers.dev/stackitcloud/stackit-cli

Package Overview
Dependencies
Versions
172
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mygithub.libinneed.workers.dev/stackitcloud/stackit-cli - npm Package Compare versions

Comparing version
v0.1.0-beta.7
to
v0.1.0-beta.8
+15
.github/renovate.json
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["config:recommended"],
"prHourlyLimit": 10,
"labels": ["renovate"],
"repositories": ["stackitcloud/stackit-cli"],
"enabledManagers": ["gomod", "github-actions"],
"packageRules": [
{
"matchSourceUrls": ["https://github.com/stackitcloud/stackit-sdk-go"],
"groupName": "STACKIT SDK modules"
}
],
"postUpdateOptions": ["gomodTidy", "gomodUpdateImportPaths"]
}
name: Renovate
on:
schedule:
- cron: "0 0 * * *"
workflow_dispatch:
jobs:
renovate:
name: Renovate
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Self-hosted Renovate
uses: renovatebot/github-action@v40.0.3
with:
configurationFile: .github/renovate.json
token: ${{ secrets.RENOVATE_TOKEN }}
## stackit postgresflex instance create
Creates a PostgreSQL Flex instance
### Synopsis
Creates a PostgreSQL Flex instance.
```
stackit postgresflex instance create [flags]
```
### Examples
```
Create a PostgreSQL Flex instance with name "my-instance", ACL 0.0.0.0/0 (open access) and specify flavor by CPU and RAM. Other parameters are set to default values
$ stackit postgresflex instance create --name my-instance --cpu 1 --ram 4 --acl 0.0.0.0/0
Create a PostgreSQL Flex instance with name "my-instance", ACL 0.0.0.0/0 (open access) and specify flavor by ID. Other parameters are set to default values
$ stackit postgresflex instance create --name my-instance --flavor-id xxx --acl 0.0.0.0/0
Create a PostgreSQL Flex instance with name "my-instance", allow access to a specific range of IP addresses, specify flavor by CPU and RAM and set storage size to 20 GB. Other parameters are set to default values
$ stackit postgresflex instance create --name my-instance --cpu 1 --ram 4 --acl 1.2.3.0/24 --storage-size 20
```
### Options
```
--acl strings The access control list (ACL). Must contain at least one valid subnet, for instance '0.0.0.0/0' for open access (discouraged), '1.2.3.0/24 for a public IP range of an organization, '1.2.3.4/32' for a single IP range, etc. (default [])
--backup-schedule string Backup schedule (default "0 0 * * *")
--cpu int Number of CPUs
--flavor-id string ID of the flavor
-h, --help Help for "stackit postgresflex instance create"
-n, --name string Instance name
--ram int Amount of RAM (in GB)
--storage-class string Storage class (default "premium-perf2-stackit")
--storage-size int Storage size (in GB) (default 10)
--type string Instance type, one of ["Replica" "Single"] (default "Replica")
--version string PostgreSQL version. Defaults to the latest version available
```
### Options inherited from parent commands
```
-y, --assume-yes If set, skips all confirmation prompts
--async If set, runs the command asynchronously
-o, --output-format string Output format, one of ["json" "pretty"]
-p, --project-id string Project ID
```
### SEE ALSO
* [stackit postgresflex instance](./stackit_postgresflex_instance.md) - Provides functionality for PostgreSQL Flex instances
## stackit postgresflex instance delete
Deletes a PostgreSQL Flex instance
### Synopsis
Deletes a PostgreSQL Flex instance.
```
stackit postgresflex instance delete INSTANCE_ID [flags]
```
### Examples
```
Delete a PostgreSQL Flex instance with ID "xxx"
$ stackit postgresflex instance delete xxx
```
### Options
```
-h, --help Help for "stackit postgresflex instance delete"
```
### Options inherited from parent commands
```
-y, --assume-yes If set, skips all confirmation prompts
--async If set, runs the command asynchronously
-o, --output-format string Output format, one of ["json" "pretty"]
-p, --project-id string Project ID
```
### SEE ALSO
* [stackit postgresflex instance](./stackit_postgresflex_instance.md) - Provides functionality for PostgreSQL Flex instances
## stackit postgresflex instance describe
Shows details of a PostgreSQL Flex instance
### Synopsis
Shows details of a PostgreSQL Flex instance.
```
stackit postgresflex instance describe INSTANCE_ID [flags]
```
### Examples
```
Get details of a PostgreSQL Flex instance with ID "xxx"
$ stackit postgresflex instance describe xxx
Get details of a PostgreSQL Flex instance with ID "xxx" in a table format
$ stackit postgresflex instance describe xxx --output-format pretty
```
### Options
```
-h, --help Help for "stackit postgresflex instance describe"
```
### Options inherited from parent commands
```
-y, --assume-yes If set, skips all confirmation prompts
--async If set, runs the command asynchronously
-o, --output-format string Output format, one of ["json" "pretty"]
-p, --project-id string Project ID
```
### SEE ALSO
* [stackit postgresflex instance](./stackit_postgresflex_instance.md) - Provides functionality for PostgreSQL Flex instances
## stackit postgresflex instance list
Lists all PostgreSQL Flex instances
### Synopsis
Lists all PostgreSQL Flex instances.
```
stackit postgresflex instance list [flags]
```
### Examples
```
List all PostgreSQL Flex instances
$ stackit postgresflex instance list
List all PostgreSQL Flex instances in JSON format
$ stackit postgresflex instance list --output-format json
List up to 10 PostgreSQL Flex instances
$ stackit postgresflex instance list --limit 10
```
### Options
```
-h, --help Help for "stackit postgresflex instance list"
--limit int Maximum number of entries to list
```
### Options inherited from parent commands
```
-y, --assume-yes If set, skips all confirmation prompts
--async If set, runs the command asynchronously
-o, --output-format string Output format, one of ["json" "pretty"]
-p, --project-id string Project ID
```
### SEE ALSO
* [stackit postgresflex instance](./stackit_postgresflex_instance.md) - Provides functionality for PostgreSQL Flex instances
## stackit postgresflex instance update
Updates a PostgreSQL Flex instance
### Synopsis
Updates a PostgreSQL Flex instance.
```
stackit postgresflex instance update INSTANCE_ID [flags]
```
### Examples
```
Update the name of a PostgreSQL Flex instance
$ stackit postgresflex instance update xxx --name my-new-name
Update the version of a PostgreSQL Flex instance
$ stackit postgresflex instance update xxx --version 6.0
```
### Options
```
--acl strings List of IP networks in CIDR notation which are allowed to access this instance (default [])
--backup-schedule string Backup schedule
--cpu int Number of CPUs
--flavor-id string ID of the flavor
-h, --help Help for "stackit postgresflex instance update"
-n, --name string Instance name
--ram int Amount of RAM (in GB)
--storage-class string Storage class
--storage-size int Storage size (in GB)
--type string Instance type, one of ["Replica" "Single"]
--version string Version
```
### Options inherited from parent commands
```
-y, --assume-yes If set, skips all confirmation prompts
--async If set, runs the command asynchronously
-o, --output-format string Output format, one of ["json" "pretty"]
-p, --project-id string Project ID
```
### SEE ALSO
* [stackit postgresflex instance](./stackit_postgresflex_instance.md) - Provides functionality for PostgreSQL Flex instances
## stackit postgresflex instance
Provides functionality for PostgreSQL Flex instances
### Synopsis
Provides functionality for PostgreSQL Flex instances.
```
stackit postgresflex instance [flags]
```
### Options
```
-h, --help Help for "stackit postgresflex instance"
```
### Options inherited from parent commands
```
-y, --assume-yes If set, skips all confirmation prompts
--async If set, runs the command asynchronously
-o, --output-format string Output format, one of ["json" "pretty"]
-p, --project-id string Project ID
```
### SEE ALSO
* [stackit postgresflex](./stackit_postgresflex.md) - Provides functionality for PostgreSQL Flex
* [stackit postgresflex instance create](./stackit_postgresflex_instance_create.md) - Creates a PostgreSQL Flex instance
* [stackit postgresflex instance delete](./stackit_postgresflex_instance_delete.md) - Deletes a PostgreSQL Flex instance
* [stackit postgresflex instance describe](./stackit_postgresflex_instance_describe.md) - Shows details of a PostgreSQL Flex instance
* [stackit postgresflex instance list](./stackit_postgresflex_instance_list.md) - Lists all PostgreSQL Flex instances
* [stackit postgresflex instance update](./stackit_postgresflex_instance_update.md) - Updates a PostgreSQL Flex instance
## stackit postgresflex options
Lists PostgreSQL Flex options
### Synopsis
Lists PostgreSQL Flex options (flavors, versions and storages for a given flavor)
Pass one or more flags to filter what categories are shown.
```
stackit postgresflex options [flags]
```
### Examples
```
List PostgreSQL Flex flavors options
$ stackit postgresflex options --flavors
List PostgreSQL Flex available versions
$ stackit postgresflex options --versions
List PostgreSQL Flex storage options for a given flavor. The flavor ID can be retrieved by running "$ stackit postgresflex options --flavors"
$ stackit postgresflex options --storages --flavor-id <FLAVOR_ID>
```
### Options
```
--flavor-id string The flavor ID to show storages for. Only relevant when "--storages" is passed
--flavors Lists supported flavors
-h, --help Help for "stackit postgresflex options"
--storages Lists supported storages for a given flavor
--versions Lists supported versions
```
### Options inherited from parent commands
```
-y, --assume-yes If set, skips all confirmation prompts
--async If set, runs the command asynchronously
-o, --output-format string Output format, one of ["json" "pretty"]
-p, --project-id string Project ID
```
### SEE ALSO
* [stackit postgresflex](./stackit_postgresflex.md) - Provides functionality for PostgreSQL Flex
## stackit postgresflex user create
Creates a PostgreSQL Flex user
### Synopsis
Creates a PostgreSQL Flex user.
The password is only visible upon creation and cannot be retrieved later.
Alternatively, you can reset the password and access the new one by running:
$ stackit postgresflex user reset-password USER_ID --instance-id INSTANCE_ID
```
stackit postgresflex user create [flags]
```
### Examples
```
Create a PostgreSQL Flex user for instance with ID "xxx"
$ stackit postgresflex user create --instance-id xxx --username johndoe
Create a PostgreSQL Flex user for instance with ID "xxx" and permission "createdb"
$ stackit postgresflex user create --instance-id xxx --username johndoe --role createdb
```
### Options
```
-h, --help Help for "stackit postgresflex user create"
--instance-id string ID of the instance
--role strings Roles of the user, possible values are ["login" "createdb"] (default [login])
--username string Username of the user
```
### Options inherited from parent commands
```
-y, --assume-yes If set, skips all confirmation prompts
--async If set, runs the command asynchronously
-o, --output-format string Output format, one of ["json" "pretty"]
-p, --project-id string Project ID
```
### SEE ALSO
* [stackit postgresflex user](./stackit_postgresflex_user.md) - Provides functionality for PostgreSQL Flex users
## stackit postgresflex user delete
Deletes a PostgreSQL Flex user
### Synopsis
Deletes a PostgreSQL Flex user by ID.
You can get the IDs of users for an instance by running:
$ stackit postgresflex user list --instance-id <INSTANCE_ID>
```
stackit postgresflex user delete USER_ID [flags]
```
### Examples
```
Delete a PostgreSQL Flex user with ID "xxx" for instance with ID "yyy"
$ stackit postgresflex user delete xxx --instance-id yyy
```
### Options
```
-h, --help Help for "stackit postgresflex user delete"
--instance-id string Instance ID
```
### Options inherited from parent commands
```
-y, --assume-yes If set, skips all confirmation prompts
--async If set, runs the command asynchronously
-o, --output-format string Output format, one of ["json" "pretty"]
-p, --project-id string Project ID
```
### SEE ALSO
* [stackit postgresflex user](./stackit_postgresflex_user.md) - Provides functionality for PostgreSQL Flex users
## stackit postgresflex user describe
Shows details of a PostgreSQL Flex user
### Synopsis
Shows details of a PostgreSQL Flex user.
The user password is hidden inside the "host" field and replaced with asterisks, as it is only visible upon creation. You can reset it by running:
$ stackit postgresflex user reset-password USER_ID --instance-id INSTANCE_ID
```
stackit postgresflex user describe USER_ID [flags]
```
### Examples
```
Get details of a PostgreSQL Flex user with ID "xxx" of instance with ID "yyy"
$ stackit postgresflex user list xxx --instance-id yyy
Get details of a PostgreSQL Flex user with ID "xxx" of instance with ID "yyy" in table format
$ stackit postgresflex user list xxx --instance-id yyy --output-format pretty
```
### Options
```
-h, --help Help for "stackit postgresflex user describe"
--instance-id string ID of the instance
```
### Options inherited from parent commands
```
-y, --assume-yes If set, skips all confirmation prompts
--async If set, runs the command asynchronously
-o, --output-format string Output format, one of ["json" "pretty"]
-p, --project-id string Project ID
```
### SEE ALSO
* [stackit postgresflex user](./stackit_postgresflex_user.md) - Provides functionality for PostgreSQL Flex users
## stackit postgresflex user list
Lists all PostgreSQL Flex users of an instance
### Synopsis
Lists all PostgreSQL Flex users of an instance.
```
stackit postgresflex user list [flags]
```
### Examples
```
List all PostgreSQL Flex users of instance with ID "xxx"
$ stackit postgresflex user list --instance-id xxx
List all PostgreSQL Flex users of instance with ID "xxx" in JSON format
$ stackit postgresflex user list --instance-id xxx --output-format json
List up to 10 PostgreSQL Flex users of instance with ID "xxx"
$ stackit postgresflex user list --instance-id xxx --limit 10
```
### Options
```
-h, --help Help for "stackit postgresflex user list"
--instance-id string Instance ID
--limit int Maximum number of entries to list
```
### Options inherited from parent commands
```
-y, --assume-yes If set, skips all confirmation prompts
--async If set, runs the command asynchronously
-o, --output-format string Output format, one of ["json" "pretty"]
-p, --project-id string Project ID
```
### SEE ALSO
* [stackit postgresflex user](./stackit_postgresflex_user.md) - Provides functionality for PostgreSQL Flex users
## stackit postgresflex user reset-password
Resets the password of a PostgreSQL Flex user
### Synopsis
Resets the password of a PostgreSQL Flex user. The new password is returned in the response.
```
stackit postgresflex user reset-password USER_ID [flags]
```
### Examples
```
Reset the password of a PostgreSQL Flex user with ID "xxx" of instance with ID "yyy"
$ stackit postgresflex user reset-password xxx --instance-id yyy
```
### Options
```
-h, --help Help for "stackit postgresflex user reset-password"
--instance-id string ID of the instance
```
### Options inherited from parent commands
```
-y, --assume-yes If set, skips all confirmation prompts
--async If set, runs the command asynchronously
-o, --output-format string Output format, one of ["json" "pretty"]
-p, --project-id string Project ID
```
### SEE ALSO
* [stackit postgresflex user](./stackit_postgresflex_user.md) - Provides functionality for PostgreSQL Flex users
## stackit postgresflex user update
Updates a PostgreSQL Flex user
### Synopsis
Updates a PostgreSQL Flex user.
```
stackit postgresflex user update USER_ID [flags]
```
### Examples
```
Update the roles of a PostgreSQL Flex user with ID "xxx" of instance with ID "yyy"
$ stackit postgresflex user update xxx --instance-id yyy --role login
```
### Options
```
-h, --help Help for "stackit postgresflex user update"
--instance-id string ID of the instance
--role strings Roles of the user, possible values are ["login" "createdb"] (default [])
```
### Options inherited from parent commands
```
-y, --assume-yes If set, skips all confirmation prompts
--async If set, runs the command asynchronously
-o, --output-format string Output format, one of ["json" "pretty"]
-p, --project-id string Project ID
```
### SEE ALSO
* [stackit postgresflex user](./stackit_postgresflex_user.md) - Provides functionality for PostgreSQL Flex users
## stackit postgresflex user
Provides functionality for PostgreSQL Flex users
### Synopsis
Provides functionality for PostgreSQL Flex users.
```
stackit postgresflex user [flags]
```
### Options
```
-h, --help Help for "stackit postgresflex user"
```
### Options inherited from parent commands
```
-y, --assume-yes If set, skips all confirmation prompts
--async If set, runs the command asynchronously
-o, --output-format string Output format, one of ["json" "pretty"]
-p, --project-id string Project ID
```
### SEE ALSO
* [stackit postgresflex](./stackit_postgresflex.md) - Provides functionality for PostgreSQL Flex
* [stackit postgresflex user create](./stackit_postgresflex_user_create.md) - Creates a PostgreSQL Flex user
* [stackit postgresflex user delete](./stackit_postgresflex_user_delete.md) - Deletes a PostgreSQL Flex user
* [stackit postgresflex user describe](./stackit_postgresflex_user_describe.md) - Shows details of a PostgreSQL Flex user
* [stackit postgresflex user list](./stackit_postgresflex_user_list.md) - Lists all PostgreSQL Flex users of an instance
* [stackit postgresflex user reset-password](./stackit_postgresflex_user_reset-password.md) - Resets the password of a PostgreSQL Flex user
* [stackit postgresflex user update](./stackit_postgresflex_user_update.md) - Updates a PostgreSQL Flex user
## stackit postgresflex
Provides functionality for PostgreSQL Flex
### Synopsis
Provides functionality for PostgreSQL Flex.
```
stackit postgresflex [flags]
```
### Options
```
-h, --help Help for "stackit postgresflex"
```
### Options inherited from parent commands
```
-y, --assume-yes If set, skips all confirmation prompts
--async If set, runs the command asynchronously
-o, --output-format string Output format, one of ["json" "pretty"]
-p, --project-id string Project ID
```
### SEE ALSO
* [stackit](./stackit.md) - Manage STACKIT resources using the command line
* [stackit postgresflex instance](./stackit_postgresflex_instance.md) - Provides functionality for PostgreSQL Flex instances
* [stackit postgresflex options](./stackit_postgresflex_options.md) - Lists PostgreSQL Flex options
* [stackit postgresflex user](./stackit_postgresflex_user.md) - Provides functionality for PostgreSQL Flex users
package options
import (
"context"
"fmt"
"testing"
"github.com/stackitcloud/stackit-cli/internal/pkg/globalflags"
"github.com/stackitcloud/stackit-cli/internal/pkg/utils"
"github.com/google/go-cmp/cmp"
"github.com/stackitcloud/stackit-sdk-go/services/postgresflex"
)
type testCtxKey struct{}
var testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo")
type postgresFlexClientMocked struct {
listFlavorsFails bool
listVersionsFails bool
listStoragesFails bool
listFlavorsCalled bool
listVersionsCalled bool
listStoragesCalled bool
}
func (c *postgresFlexClientMocked) ListFlavorsExecute(_ context.Context, _ string) (*postgresflex.ListFlavorsResponse, error) {
c.listFlavorsCalled = true
if c.listFlavorsFails {
return nil, fmt.Errorf("list flavors failed")
}
return utils.Ptr(postgresflex.ListFlavorsResponse{
Flavors: utils.Ptr([]postgresflex.Flavor{}),
}), nil
}
func (c *postgresFlexClientMocked) ListVersionsExecute(_ context.Context, _ string) (*postgresflex.ListVersionsResponse, error) {
c.listVersionsCalled = true
if c.listVersionsFails {
return nil, fmt.Errorf("list versions failed")
}
return utils.Ptr(postgresflex.ListVersionsResponse{
Versions: utils.Ptr([]string{}),
}), nil
}
func (c *postgresFlexClientMocked) ListStoragesExecute(_ context.Context, _, _ string) (*postgresflex.ListStoragesResponse, error) {
c.listStoragesCalled = true
if c.listStoragesFails {
return nil, fmt.Errorf("list storages failed")
}
return utils.Ptr(postgresflex.ListStoragesResponse{
StorageClasses: utils.Ptr([]string{}),
StorageRange: &postgresflex.StorageRange{
Min: utils.Ptr(int64(10)),
Max: utils.Ptr(int64(100)),
},
}), nil
}
func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string {
flagValues := map[string]string{
flavorsFlag: "true",
versionsFlag: "true",
storagesFlag: "true",
flavorIdFlag: "2.4",
}
for _, mod := range mods {
mod(flagValues)
}
return flagValues
}
func fixtureInputModelAllFalse(mods ...func(model *inputModel)) *inputModel {
model := &inputModel{
GlobalFlagModel: &globalflags.GlobalFlagModel{},
Flavors: false,
Versions: false,
Storages: false,
}
for _, mod := range mods {
mod(model)
}
return model
}
func fixtureInputModelAllTrue(mods ...func(model *inputModel)) *inputModel {
model := &inputModel{
GlobalFlagModel: &globalflags.GlobalFlagModel{},
Flavors: true,
Versions: true,
Storages: true,
FlavorId: utils.Ptr("2.4"),
}
for _, mod := range mods {
mod(model)
}
return model
}
func TestParseInput(t *testing.T) {
tests := []struct {
description string
flagValues map[string]string
isValid bool
expectedModel *inputModel
}{
{
description: "all values",
flagValues: fixtureFlagValues(),
isValid: true,
expectedModel: fixtureInputModelAllTrue(),
},
{
description: "no values",
flagValues: map[string]string{},
isValid: false,
},
{
description: "some values 1",
flagValues: fixtureFlagValues(func(flagValues map[string]string) {
flagValues[storagesFlag] = "false"
delete(flagValues, flavorIdFlag)
}),
isValid: true,
expectedModel: fixtureInputModelAllFalse(func(model *inputModel) {
model.Flavors = true
model.Versions = true
}),
},
{
description: "some values 2",
flagValues: fixtureFlagValues(func(flagValues map[string]string) {
delete(flagValues, flavorsFlag)
delete(flagValues, versionsFlag)
flagValues[storagesFlag] = "true"
flagValues[flavorIdFlag] = "2.4"
}),
isValid: true,
expectedModel: fixtureInputModelAllFalse(func(model *inputModel) {
model.Storages = true
model.FlavorId = utils.Ptr("2.4")
}),
},
{
description: "storages without flavor-id",
flagValues: fixtureFlagValues(func(flagValues map[string]string) {
delete(flagValues, flavorIdFlag)
}),
isValid: false,
},
{
description: "flavor-id without storage",
flagValues: fixtureFlagValues(func(flagValues map[string]string) {
delete(flagValues, storagesFlag)
}),
isValid: true,
expectedModel: fixtureInputModelAllTrue(func(model *inputModel) {
model.Storages = false
}),
},
}
for _, tt := range tests {
t.Run(tt.description, func(t *testing.T) {
cmd := NewCmd()
err := globalflags.Configure(cmd.Flags())
if err != nil {
t.Fatalf("configure global flags: %v", err)
}
for flag, value := range tt.flagValues {
err := cmd.Flags().Set(flag, value)
if err != nil {
if !tt.isValid {
return
}
t.Fatalf("setting flag --%s=%s: %v", flag, value, err)
}
}
err = cmd.ValidateRequiredFlags()
if err != nil {
if !tt.isValid {
return
}
t.Fatalf("error validating flags: %v", err)
}
model, err := parseInput(cmd)
if err != nil {
if !tt.isValid {
return
}
t.Fatalf("error parsing flags: %v", err)
}
if !tt.isValid {
t.Fatalf("did not fail on invalid input")
}
diff := cmp.Diff(model, tt.expectedModel)
if diff != "" {
t.Fatalf("Data does not match: %s", diff)
}
})
}
}
func TestBuildAndExecuteRequest(t *testing.T) {
tests := []struct {
description string
model *inputModel
isValid bool
listFlavorsFails bool
listVersionsFails bool
listStoragesFails bool
expectListFlavorsCalled bool
expectListVersionsCalled bool
expectListStoragesCalled bool
}{
{
description: "all values",
model: fixtureInputModelAllTrue(),
isValid: true,
expectListFlavorsCalled: true,
expectListVersionsCalled: true,
expectListStoragesCalled: true,
},
{
description: "no values",
model: fixtureInputModelAllFalse(),
isValid: true,
expectListFlavorsCalled: false,
expectListVersionsCalled: false,
expectListStoragesCalled: false,
},
{
description: "only flavors",
model: fixtureInputModelAllFalse(func(model *inputModel) { model.Flavors = true }),
isValid: true,
expectListFlavorsCalled: true,
},
{
description: "only versions",
model: fixtureInputModelAllFalse(func(model *inputModel) { model.Versions = true }),
isValid: true,
expectListVersionsCalled: true,
},
{
description: "only storages",
model: fixtureInputModelAllFalse(func(model *inputModel) {
model.Storages = true
model.FlavorId = utils.Ptr("2.4")
}),
isValid: true,
expectListStoragesCalled: true,
},
{
description: "list flavors fails",
model: fixtureInputModelAllTrue(),
isValid: false,
listFlavorsFails: true,
expectListFlavorsCalled: true,
expectListVersionsCalled: false,
expectListStoragesCalled: false,
},
{
description: "list versions fails",
model: fixtureInputModelAllTrue(),
isValid: false,
listVersionsFails: true,
expectListFlavorsCalled: true,
expectListVersionsCalled: true,
expectListStoragesCalled: false,
},
{
description: "list storages fails",
model: fixtureInputModelAllTrue(),
isValid: false,
listStoragesFails: true,
expectListFlavorsCalled: true,
expectListVersionsCalled: true,
expectListStoragesCalled: true,
},
}
for _, tt := range tests {
t.Run(tt.description, func(t *testing.T) {
cmd := NewCmd()
client := &postgresFlexClientMocked{
listFlavorsFails: tt.listFlavorsFails,
listVersionsFails: tt.listVersionsFails,
listStoragesFails: tt.listStoragesFails,
}
err := buildAndExecuteRequest(testCtx, cmd, tt.model, client)
if err != nil && tt.isValid {
t.Fatalf("error building and executing request: %v", err)
}
if err == nil && !tt.isValid {
t.Fatalf("did not fail on invalid input")
}
if !tt.isValid {
return
}
if tt.expectListFlavorsCalled != client.listFlavorsCalled {
t.Fatalf("expected listFlavorsCalled to be %v, got %v", tt.expectListFlavorsCalled, client.listFlavorsCalled)
}
if tt.expectListVersionsCalled != client.listVersionsCalled {
t.Fatalf("expected listVersionsCalled to be %v, got %v", tt.expectListVersionsCalled, client.listVersionsCalled)
}
if tt.expectListStoragesCalled != client.listStoragesCalled {
t.Fatalf("expected listStoragesCalled to be %v, got %v", tt.expectListStoragesCalled, client.listStoragesCalled)
}
})
}
}
package options
import (
"context"
"encoding/json"
"fmt"
"github.com/stackitcloud/stackit-cli/internal/pkg/args"
"github.com/stackitcloud/stackit-cli/internal/pkg/examples"
"github.com/stackitcloud/stackit-cli/internal/pkg/flags"
"github.com/stackitcloud/stackit-cli/internal/pkg/globalflags"
"github.com/stackitcloud/stackit-cli/internal/pkg/pager"
"github.com/stackitcloud/stackit-cli/internal/pkg/services/postgresflex/client"
"github.com/stackitcloud/stackit-cli/internal/pkg/tables"
"github.com/spf13/cobra"
"github.com/stackitcloud/stackit-sdk-go/services/postgresflex"
)
const (
flavorsFlag = "flavors"
versionsFlag = "versions"
storagesFlag = "storages"
flavorIdFlag = "flavor-id"
)
type inputModel struct {
*globalflags.GlobalFlagModel
Flavors bool
Versions bool
Storages bool
FlavorId *string
}
type options struct {
Flavors *[]postgresflex.Flavor `json:"flavors,omitempty"`
Versions *[]string `json:"versions,omitempty"`
Storages *flavorStorages `json:"flavorStorages,omitempty"`
}
type flavorStorages struct {
FlavorId string `json:"flavorId"`
Storages *postgresflex.ListStoragesResponse `json:"storages"`
}
func NewCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "options",
Short: "Lists PostgreSQL Flex options",
Long: "Lists PostgreSQL Flex options (flavors, versions and storages for a given flavor)\nPass one or more flags to filter what categories are shown.",
Args: args.NoArgs,
Example: examples.Build(
examples.NewExample(
`List PostgreSQL Flex flavors options`,
"$ stackit postgresflex options --flavors"),
examples.NewExample(
`List PostgreSQL Flex available versions`,
"$ stackit postgresflex options --versions"),
examples.NewExample(
`List PostgreSQL Flex storage options for a given flavor. The flavor ID can be retrieved by running "$ stackit postgresflex options --flavors"`,
"$ stackit postgresflex options --storages --flavor-id <FLAVOR_ID>"),
),
RunE: func(cmd *cobra.Command, args []string) error {
ctx := context.Background()
model, err := parseInput(cmd)
if err != nil {
return err
}
// Configure API client
apiClient, err := client.ConfigureClient(cmd)
if err != nil {
return err
}
// Call API
err = buildAndExecuteRequest(ctx, cmd, model, apiClient)
if err != nil {
return fmt.Errorf("get PostgreSQL Flex options: %w", err)
}
return nil
},
}
configureFlags(cmd)
return cmd
}
func configureFlags(cmd *cobra.Command) {
cmd.Flags().Bool(flavorsFlag, false, "Lists supported flavors")
cmd.Flags().Bool(versionsFlag, false, "Lists supported versions")
cmd.Flags().Bool(storagesFlag, false, "Lists supported storages for a given flavor")
cmd.Flags().String(flavorIdFlag, "", `The flavor ID to show storages for. Only relevant when "--storages" is passed`)
}
func parseInput(cmd *cobra.Command) (*inputModel, error) {
globalFlags := globalflags.Parse(cmd)
flavors := flags.FlagToBoolValue(cmd, flavorsFlag)
versions := flags.FlagToBoolValue(cmd, versionsFlag)
storages := flags.FlagToBoolValue(cmd, storagesFlag)
flavorId := flags.FlagToStringPointer(cmd, flavorIdFlag)
if !flavors && !versions && !storages {
return nil, fmt.Errorf("%s\n\n%s",
"please specify at least one category for which to list the available options.",
"Get details on the available flags by re-running your command with the --help flag.")
}
if storages && flavorId == nil {
return nil, fmt.Errorf("%s\n\n%s\n%s",
`please specify a flavor ID to show storages for by setting the flag "--flavor-id <FLAVOR_ID>".`,
"You can get the available flavor IDs by running:",
" $ stackit postgresflex options --flavors")
}
return &inputModel{
GlobalFlagModel: globalFlags,
Flavors: flavors,
Versions: versions,
Storages: storages,
FlavorId: flags.FlagToStringPointer(cmd, flavorIdFlag),
}, nil
}
type postgresFlexOptionsClient interface {
ListFlavorsExecute(ctx context.Context, projectId string) (*postgresflex.ListFlavorsResponse, error)
ListVersionsExecute(ctx context.Context, projectId string) (*postgresflex.ListVersionsResponse, error)
ListStoragesExecute(ctx context.Context, projectId, flavorId string) (*postgresflex.ListStoragesResponse, error)
}
func buildAndExecuteRequest(ctx context.Context, cmd *cobra.Command, model *inputModel, apiClient postgresFlexOptionsClient) error {
var flavors *postgresflex.ListFlavorsResponse
var versions *postgresflex.ListVersionsResponse
var storages *postgresflex.ListStoragesResponse
var err error
if model.Flavors {
flavors, err = apiClient.ListFlavorsExecute(ctx, model.ProjectId)
if err != nil {
return fmt.Errorf("get PostgreSQL Flex flavors: %w", err)
}
}
if model.Versions {
versions, err = apiClient.ListVersionsExecute(ctx, model.ProjectId)
if err != nil {
return fmt.Errorf("get PostgreSQL Flex versions: %w", err)
}
}
if model.Storages {
storages, err = apiClient.ListStoragesExecute(ctx, model.ProjectId, *model.FlavorId)
if err != nil {
return fmt.Errorf("get PostgreSQL Flex storages: %w", err)
}
}
return outputResult(cmd, model, flavors, versions, storages)
}
func outputResult(cmd *cobra.Command, model *inputModel, flavors *postgresflex.ListFlavorsResponse, versions *postgresflex.ListVersionsResponse, storages *postgresflex.ListStoragesResponse) error {
options := &options{}
if flavors != nil {
options.Flavors = flavors.Flavors
}
if versions != nil {
options.Versions = versions.Versions
}
if storages != nil && model.FlavorId != nil {
options.Storages = &flavorStorages{
FlavorId: *model.FlavorId,
Storages: storages,
}
}
switch model.OutputFormat {
case globalflags.JSONOutputFormat:
details, err := json.MarshalIndent(options, "", " ")
if err != nil {
return fmt.Errorf("marshal PostgreSQL Flex options: %w", err)
}
cmd.Println(string(details))
return nil
default:
return outputResultAsTable(cmd, model, options)
}
}
func outputResultAsTable(cmd *cobra.Command, model *inputModel, options *options) error {
content := ""
if model.Flavors {
content += renderFlavors(*options.Flavors)
}
if model.Versions {
content += renderVersions(*options.Versions)
}
if model.Storages {
content += renderStorages(options.Storages.Storages)
}
err := pager.Display(cmd, content)
if err != nil {
return fmt.Errorf("display output: %w", err)
}
return nil
}
func renderFlavors(flavors []postgresflex.Flavor) string {
if len(flavors) == 0 {
return ""
}
table := tables.NewTable()
table.SetHeader("ID", "CPU", "MEMORY", "DESCRIPTION")
for i := range flavors {
f := flavors[i]
table.AddRow(*f.Id, *f.Cpu, *f.Memory, *f.Description)
}
return table.Render()
}
func renderVersions(versions []string) string {
if len(versions) == 0 {
return ""
}
table := tables.NewTable()
table.SetHeader("VERSION")
for i := range versions {
v := versions[i]
table.AddRow(v)
}
return table.Render()
}
func renderStorages(resp *postgresflex.ListStoragesResponse) string {
if resp.StorageClasses == nil || len(*resp.StorageClasses) == 0 {
return ""
}
storageClasses := *resp.StorageClasses
table := tables.NewTable()
table.SetHeader("MIN STORAGE", "MAX STORAGE", "STORAGE CLASS")
for i := range storageClasses {
sc := storageClasses[i]
table.AddRow(*resp.StorageRange.Min, *resp.StorageRange.Max, sc)
}
table.EnableAutoMergeOnColumns(1, 2, 3)
return table.Render()
}
+1
-0

@@ -37,2 +37,3 @@ ## stackit

* [stackit organization](./stackit_organization.md) - Provides functionality regarding organizations
* [stackit postgresflex](./stackit_postgresflex.md) - Provides functionality for PostgreSQL Flex
* [stackit project](./stackit_project.md) - Provides functionality regarding projects

@@ -39,0 +40,0 @@ * [stackit rabbitmq](./stackit_rabbitmq.md) - Provides functionality for RabbitMQ

+0
-10

@@ -29,12 +29,2 @@ # Installation

## Using `go install`
If you have [Go](https://go.dev/doc/install) 1.16+ installed, you can directly install the STACKIT CLI via:
```shell
go install github.com/stackitcloud/stackit-cli@latest
```
> For more information, please refer to the [`go install` documentation](https://go.dev/ref/mod#go-install)
## Manual installation

@@ -41,0 +31,0 @@

@@ -5,2 +5,3 @@ package postgresflex

"github.com/stackitcloud/stackit-cli/internal/cmd/postgresflex/instance"
"github.com/stackitcloud/stackit-cli/internal/cmd/postgresflex/options"
"github.com/stackitcloud/stackit-cli/internal/cmd/postgresflex/user"

@@ -29,2 +30,3 @@ "github.com/stackitcloud/stackit-cli/internal/pkg/args"

cmd.AddCommand(user.NewCmd())
cmd.AddCommand(options.NewCmd())
}

@@ -18,2 +18,3 @@ package cmd

"github.com/stackitcloud/stackit-cli/internal/cmd/organization"
"github.com/stackitcloud/stackit-cli/internal/cmd/postgresflex"
"github.com/stackitcloud/stackit-cli/internal/cmd/project"

@@ -94,2 +95,3 @@ "github.com/stackitcloud/stackit-cli/internal/cmd/rabbitmq"

cmd.AddCommand(organization.NewCmd())
cmd.AddCommand(postgresflex.NewCmd())
cmd.AddCommand(project.NewCmd())

@@ -96,0 +98,0 @@ cmd.AddCommand(rabbitmq.NewCmd())