mygithub.libinneed.workers.dev/stackitcloud/stackit-cli
Advanced tools
| { | ||
| "$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()) |