Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
bb834a2
feat: wire mariadb sdk v3 client (MariaClientV2)
avirtopeanu-ionos Aug 5, 2026
5eba0d7
feat: add mariadb-v2 command tree with cluster/backup/version read ops
avirtopeanu-ionos Aug 5, 2026
a7559fc
feat: mariadb-v2 cluster create with create-from-backup
avirtopeanu-ionos Aug 5, 2026
d4c7007
feat: mariadb-v2 cluster update, delete and in-place restore
avirtopeanu-ionos Aug 5, 2026
eac2343
feat: mariadb-v2 docs, tests and changelog
avirtopeanu-ionos Aug 5, 2026
0f14fa4
fix: mariadb-v2 update/restore require --password, reuse existing use…
avirtopeanu-ionos Aug 5, 2026
6309865
feat: add --cores tab-completion to mariadb-v2 create and update
avirtopeanu-ionos Aug 5, 2026
b844e1b
fix: mariadb-v2 create --recovery-time accepts same friendly formats …
avirtopeanu-ionos Aug 5, 2026
d0d67c2
test: add mariadb-v2 bats integration suite
avirtopeanu-ionos Aug 5, 2026
4ce7a80
test: make mariadb-v2 bats poll for readiness instead of relying on -w
avirtopeanu-ionos Aug 5, 2026
45d4b11
fix: global --wait resolves relative hrefs via the request URL, not t…
avirtopeanu-ionos Aug 5, 2026
45a1016
test: use global -w in mariadb-v2 bats now that relative-href wait works
avirtopeanu-ionos Aug 5, 2026
5dc9bd4
test: retry datacenter delete in mariadb-v2 teardown until delete-pro…
avirtopeanu-ionos Aug 5, 2026
f78363b
doc: changelog entry for the global --wait relative-href fix
avirtopeanu-ionos Aug 5, 2026
561186d
fix: mariadb-v2 reads the mariadbv2 config-file override key so v1/v2…
avirtopeanu-ionos Aug 7, 2026
60d86ef
doc: address copilot review - correct API-generation wording and stal…
avirtopeanu-ionos Aug 7, 2026
043e069
doc: regen docs
avirtopeanu-ionos Aug 11, 2026
b2aacb0
fix: run e2e suite-existence check after PR checkout
avirtopeanu-ionos Aug 14, 2026
62ff591
ci: run unit+integration on PRs, leave BATS to /test comment
avirtopeanu-ionos Aug 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 4 additions & 15 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,6 @@
with:
go-version-file: 'go.mod'

- name: Install bats-core
run: |
git clone https://github.com/bats-core/bats-core.git
cd bats-core
sudo ./install.sh /usr/local
shell: bash
if: matrix.os == 'ubuntu-latest'

- name: Install FTPS test dependencies
# pyftpdlib is pure-Python sdist-only (no wheel); --no-binary overrides --only-binary for it
run: pip install --only-binary=:all: --no-binary=pyftpdlib 'pyftpdlib==1.5.10' 'pyOpenSSL==26.2.0'
if: matrix.os == 'ubuntu-latest'

- name: Check code format
run: make gofmt_check
if: matrix.os == 'ubuntu-latest'
Expand All @@ -64,18 +51,20 @@
- name: Run govulncheck on PR
if: matrix.os == 'ubuntu-latest'
run: |
go install golang.org/x/vuln/cmd/govulncheck@latest

Check warning on line 54 in .github/workflows/ci.yml

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Dependency versions are not predictable. Use a lock-file enforcing command instead.

See more on https://sonarcloud.io/project/issues?id=cli-ionosctl&issues=AaAAf1xfl6_uRvmO6DAy&open=AaAAf1xfl6_uRvmO6DAy&pullRequest=694
govulncheck ./...


- name: Run all tests on Ubuntu
- name: Run unit and integration tests on Ubuntu
# BATS suites are intentionally excluded here; devs trigger them per-PR
# via a `/test <suite>` comment (see e2e.yml + pr-comment-trigger.yml).
env:
BASE_BRANCH: ${{ github.base_ref }}
IONOS_USERNAME: ${{ secrets.IONOS_USERNAME }}
IONOS_PASSWORD: ${{ secrets.IONOS_PASSWORD }}
IONOS_S3_ACCESS_KEY: ${{ secrets.IONOS_S3_ACCESS_KEY }}
IONOS_S3_SECRET_KEY: ${{ secrets.IONOS_S3_SECRET_KEY }}
run: make test
run: make itest
if: matrix.os == 'ubuntu-latest'

- name: Run only unit tests on Windows
Expand Down
17 changes: 11 additions & 6 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,6 @@ jobs:
echo "Invalid PR number: $PR_NUMBER"
exit 1
fi
if [ "$SUITE" != "all" ] && [ ! -f "test/suites/${SUITE}.bats" ] && [ ! -d "test/suites/${SUITE}" ]; then
echo "Suite not found: test/suites/${SUITE}.bats (or directory test/suites/${SUITE}/)"
echo "Available suites:"
find test/suites -name '*.bats' ! -name 'setup.bats' | sed 's|test/suites/||; s|\.bats$||' | sort
exit 1
fi

- name: Checkout code
uses: actions/checkout@v4
Expand All @@ -58,6 +52,17 @@ jobs:
OUTPUT=$(git log -1 --format='%H')
echo "commit-sha=$OUTPUT" >> $GITHUB_OUTPUT

- name: Validate suite exists
env:
SUITE: ${{ github.event.inputs.suite }}
run: |
if [ "$SUITE" != "all" ] && [ ! -f "test/suites/${SUITE}.bats" ] && [ ! -d "test/suites/${SUITE}" ]; then
echo "Suite not found: test/suites/${SUITE}.bats (or directory test/suites/${SUITE}/)"
echo "Available suites:"
find test/suites -name '*.bats' ! -name 'setup.bats' | sed 's|test/suites/||; s|\.bats$||' | sort
exit 1
fi

- name: Create Pending Status Check
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand Down
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Versioning follows [SemVer](https://semver.org/). Sections: **Added**, **Changed

### Added
- Support for `dbaas in-memory-db-v2` has been added.
- `dbaas mariadb-v2`: a second-generation MariaDB command tree built on the MariaDB v3 API, alongside the existing `dbaas mariadb` (the two coexist, same convention as `postgres`/`postgres-v2`). It adds `cluster` (list/get/create/update/delete/restore), `backup` (list/get) with a `backup location` sub-tree (list/get), and `version` (list/get). Highlights: point-in-time `cluster restore` and `cluster create --backup-id` (recovery window navigated with `--recovery-time`), configurable `--backup-location` and `--backup-retention-days` (1–365), `--logs-enabled`/`--metrics-enabled`, list/`delete --all` spanning all locations by default, and tab-completion for versions, clusters, backups, and backup locations.
- Confidential Computing support:
- `image upload --confidential` uploads to the `/confidential-images/` FTP directory. Restricted to QCOW2 images (which must carry a `LAUNCH_ARTIFACTS` partition). `cloud-init`, all hot-plug/hot-unplug, and legacy BIOS are set server-side for confidential images and are immutable — they are omitted from the update request (the API rejects them regardless of value), and passing any of these flags explicitly is rejected up front.
- `server create --confidential` creates a Confidential VM from a confidential boot image. Requires `--type ENTERPRISE` and `--image-id` (a private, SEV-SNP image; `--image-id` tab-completion is filtered to these). A boot volume is built from the image and attached in the same request (size it with `--size`/`--storage-type`), so the API can derive `cores` and `cpuFamily` from the image's `launch-config.json` — `--cores` and `--cpu-family` must not be set.
Expand All @@ -28,7 +29,7 @@ Versioning follows [SemVer](https://semver.org/). Sections: **Added**, **Changed
- Consistent `delete --all` across all resources: Bulk deletion now prints a preview of every resource that will be deleted (with identifying details such as name, ID, public IP, location, and description), confirms per item, reports per-item success, and ends with a `deleted / skipped / failed` summary instead of staying silent unless an error occurred. On regional APIs the preview and deletion span all locations by default (use `--location` to target one). This also fixes a bug where when deleting certain resources and answering 'no' for only one of them, all the remaining resources would be skipped.

### Fixed
- Global `--wait` (`-w`) now polls the transport-captured request URL (the exact URL the SDK called) instead of the `href` returned in the response body. Some APIs (e.g. In-Memory DB v3) return a body `href` missing the version basepath (`.../clusters/{id}` instead of `.../v2/clusters/{id}`), which made `-w` fail immediately with `client error (HTTP 400) while polling resource state`. For well-behaved APIs the two URLs are identical, so behavior is unchanged there.
- Global `--wait` (`-w`) now polls the transport-captured request URL (the exact URL the SDK called) instead of the `href` returned in the response body. Some APIs return a body `href` missing the version basepath — In-Memory DB v3 returns `.../clusters/{id}` instead of `.../v2/clusters/{id}` (making `-w` fail immediately with `client error (HTTP 400) while polling resource state`), and MariaDB v3 returns a relative `/clusters/{id}` (making `-w` hang until timeout). For well-behaved APIs the two URLs are identical, so behavior is unchanged there.
- Removed the non-existent `gb/txl` location from the In-Memory DB location list; listing across all locations no longer warns about an unresolvable host.
- Config-file endpoint overrides for regional products (e.g. `object-storage`) now apply regardless of whether the location is spelled with slashes (`eu/central/3`) or dashes (`eu-central-3`). Previously the lookup was case-exact on separators, so an override written in one convention was ignored when the command used the other, silently falling back to the default endpoint.
- `dbaas mariadb cluster delete --all --name` and `dbaas mongo cluster delete --all --name` now filter by the given name. The `--name` flag was previously registered as a boolean and could not accept a value, so the filter never applied.
Expand Down
2 changes: 2 additions & 0 deletions commands/dbaas/dbaas.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"github.com/ionos-cloud/ionosctl/v6/commands/dbaas/inmemorydb"
inmemorydb_v2 "github.com/ionos-cloud/ionosctl/v6/commands/dbaas/inmemorydb-v2"
"github.com/ionos-cloud/ionosctl/v6/commands/dbaas/mariadb"
mariadb_v2 "github.com/ionos-cloud/ionosctl/v6/commands/dbaas/mariadb-v2"
"github.com/ionos-cloud/ionosctl/v6/commands/dbaas/mongo"
"github.com/ionos-cloud/ionosctl/v6/commands/dbaas/postgres"
"github.com/ionos-cloud/ionosctl/v6/commands/dbaas/postgres-v2"
Expand All @@ -25,6 +26,7 @@ func DataBaseServiceCmd() *core.Command {
dbaasCmd.AddCommand(postgres_v2.Root())
dbaasCmd.AddCommand(mongo.DBaaSMongoCmd())
dbaasCmd.AddCommand(mariadb.Root())
dbaasCmd.AddCommand(mariadb_v2.Root())
dbaasCmd.AddCommand(inmemorydb.Root())
dbaasCmd.AddCommand(inmemorydb_v2.Root())
return dbaasCmd
Expand Down
45 changes: 45 additions & 0 deletions commands/dbaas/mariadb-v2/backup/backup.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package backup

import (
"github.com/ionos-cloud/ionosctl/v6/commands/dbaas/mariadb-v2/backup/location"
"github.com/ionos-cloud/ionosctl/v6/internal/constants"
"github.com/ionos-cloud/ionosctl/v6/internal/core"
"github.com/ionos-cloud/ionosctl/v6/internal/printer/table"
"github.com/spf13/cobra"
)

var backupCols = []table.Column{
{Name: "BackupId", JSONPath: "id", Default: true},
{Name: "ClusterId", JSONPath: "properties.clusterId", Default: true},
{Name: "ClusterName", JSONPath: "properties.clusterName", Default: true},
{Name: "Version", JSONPath: "properties.mariadbClusterVersion", Default: true},
{Name: "Location", JSONPath: "properties.location", Default: true},
{Name: "EarliestRecoveryTargetTime", JSONPath: "properties.earliestRecoveryTargetTime", Default: true},
}

func BackupCmd() *core.Command {
backupCmd := &core.Command{
Command: &cobra.Command{
Use: "backup",
Aliases: []string{"b", "backups"},
Short: "MariaDB Backup Operations",
Long: `The sub-commands of ` + "`ionosctl dbaas mariadb-v2 backup`" + ` allow you to view MariaDB Cluster Backups.

A backup is not a single point in time — it represents a recovery WINDOW starting at its earliestRecoveryTargetTime and extending to the present. The cluster can be restored to any moment within that window. Use ` + "`--recovery-time`" + ` on ` + "`cluster restore`" + ` (or ` + "`cluster create --backup-id`" + `) to zoom into a specific point; omit it to use the latest point.`,
TraverseChildren: true,
},
}

backupCmd.Command.PersistentFlags().StringSlice(constants.ArgCols, nil, table.ColsMessage(backupCols))
_ = backupCmd.Command.RegisterFlagCompletionFunc(
constants.ArgCols, func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return table.AllCols(backupCols), cobra.ShellCompDirectiveNoFileComp
},
)

backupCmd.AddCommand(BackupListCmd())
backupCmd.AddCommand(BackupGetCmd())
backupCmd.AddCommand(location.LocationCmd())

return backupCmd
}
53 changes: 53 additions & 0 deletions commands/dbaas/mariadb-v2/backup/get.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package backup

import (
"context"
"fmt"

"github.com/ionos-cloud/ionosctl/v6/commands/dbaas/mariadb-v2/completer"
"github.com/ionos-cloud/ionosctl/v6/internal/client"
"github.com/ionos-cloud/ionosctl/v6/internal/constants"
"github.com/ionos-cloud/ionosctl/v6/internal/core"
"github.com/ionos-cloud/ionosctl/v6/internal/printer/table"
"github.com/spf13/viper"
)

func BackupGetCmd() *core.Command {
ctx := context.TODO()
get := core.NewCommand(ctx, nil, core.CommandBuilder{
Namespace: "dbaas-mariadb-v2",
Resource: "backup",
Verb: "get",
Aliases: []string{"g"},
ShortDesc: "Get a MariaDB Backup",
Example: "ionosctl dbaas mariadb-v2 backup get --backup-id <backup-id>",
LongDesc: "Use this command to retrieve details about a MariaDB Backup by using its ID.\n\nThe backup represents a recovery WINDOW: earliestRecoveryTargetTime bounds the start of the range you can restore to (the window extends to the present). Pass a timestamp inside that range as `--recovery-time` on `cluster restore` / `cluster create --backup-id` to zoom into a specific point; omit it to use the latest.\n\nRequired values to run command:\n\n* Backup Id",
PreCmdRun: PreRunBackupId,
CmdRun: RunBackupGet,
InitClient: true,
})

get.AddUUIDFlag(constants.FlagBackupId, constants.FlagIdShort, "", "The unique ID of the Backup", core.RequiredFlagOption(),
core.WithCompletion(completer.BackupIds, constants.MariaDBApiRegionalURL, constants.MariaDBLocations),
)
return get
}

func PreRunBackupId(c *core.PreCommandConfig) error {
return c.CheckRequiredFlagsAndLocation(constants.FlagBackupId)
}

func RunBackupGet(c *core.CommandConfig) error {
backupId := viper.GetString(core.GetFlagName(c.NS, constants.FlagBackupId))
c.Verbose("Getting Backup %v...", backupId)

backup, _, err := client.Must().MariaClientV2.BackupsApi.BackupsFindById(
context.Background(), backupId).Execute()
if err != nil {
return fmt.Errorf("could not get backup: %w", err)
}

cols, _ := c.Command.Command.Flags().GetStringSlice(constants.ArgCols)

return c.Out(table.Sprint(backupCols, backup, cols))
}
51 changes: 51 additions & 0 deletions commands/dbaas/mariadb-v2/backup/list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package backup

import (
"context"

"github.com/ionos-cloud/ionosctl/v6/internal/constants"
"github.com/ionos-cloud/ionosctl/v6/internal/core"
mariadb "github.com/ionos-cloud/sdk-go-bundle/products/dbaas/mariadb/v3"
"github.com/ionos-cloud/sdk-go-bundle/shared"
"github.com/spf13/viper"
)

func BackupListCmd() *core.Command {
ctx := context.TODO()
listEnv := core.NewCommand(ctx, nil, core.CommandBuilder{
Namespace: "dbaas-mariadb-v2",
Resource: "backup",
Verb: "list",
Aliases: []string{"ls", "l"},
ShortDesc: "List MariaDB Backups",
LongDesc: "Use this command to retrieve a list of MariaDB Backups. You can filter by cluster ID using `--cluster-id`.\n\nEach backup is a recovery WINDOW: the EarliestRecoveryTargetTime column shows the start of the range you can restore to (the window extends to the present). Zoom into a specific point with `--recovery-time` on `cluster restore` / `cluster create --backup-id`.",
Example: "ionosctl dbaas mariadb-v2 backup list",
PreCmdRun: core.NoPreRun,
CmdRun: RunBackupList,
InitClient: true,
})
listEnv.AddStringFlag(constants.FlagClusterId, "", "", "Response filter to list only the backups of the specified cluster")
listEnv.AddInt32Flag(constants.FlagLimit, "", 100, "The maximum number of elements to return")
listEnv.AddInt32Flag(constants.FlagOffset, "", 0, "The first element to return")
return listEnv
}

func RunBackupList(c *core.CommandConfig) error {
return c.ListAllLocations(backupCols, func(cfg *shared.Configuration) (any, error) {
apiClient := mariadb.NewAPIClient(cfg)
req := apiClient.BackupsApi.BackupsGet(context.Background())

if fn := core.GetFlagName(c.NS, constants.FlagClusterId); viper.IsSet(fn) {
req = req.FilterClusterId(viper.GetString(fn))
}
if fn := core.GetFlagName(c.NS, constants.FlagLimit); viper.IsSet(fn) {
req = req.Limit(viper.GetInt32(fn))
}
if fn := core.GetFlagName(c.NS, constants.FlagOffset); viper.IsSet(fn) {
req = req.Offset(viper.GetInt32(fn))
}

backups, _, err := req.Execute()
return backups, err
})
}
50 changes: 50 additions & 0 deletions commands/dbaas/mariadb-v2/backup/location/get.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package location

import (
"context"

"github.com/ionos-cloud/ionosctl/v6/commands/dbaas/mariadb-v2/completer"
"github.com/ionos-cloud/ionosctl/v6/internal/client"
"github.com/ionos-cloud/ionosctl/v6/internal/constants"
"github.com/ionos-cloud/ionosctl/v6/internal/core"
"github.com/ionos-cloud/ionosctl/v6/internal/printer/table"
"github.com/spf13/viper"
)

func LocationGetCmd() *core.Command {
ctx := context.TODO()
cmd := core.NewCommand(ctx, nil, core.CommandBuilder{
Namespace: "dbaas-mariadb-v2",
Resource: "location",
Verb: "get",
Aliases: []string{"g"},
ShortDesc: "Get a MariaDB Backup Location",
LongDesc: "Use this command to retrieve details about a MariaDB Backup Location by using its ID.\n\nRequired values to run command:\n\n* Backup Location Id",
Example: "ionosctl dbaas mariadb-v2 backup location get --backup-location-id <backup-location-id>",
PreCmdRun: PreRunLocationId,
CmdRun: RunLocationGet,
InitClient: true,
})
cmd.AddStringFlag(constants.FlagBackupLocationId, constants.FlagIdShort, "", "The ID of the MariaDB Backup Location", core.RequiredFlagOption(),
core.WithCompletion(completer.BackupLocationIds, constants.MariaDBApiRegionalURL, constants.MariaDBLocations),
)
return cmd
}

func PreRunLocationId(c *core.PreCommandConfig) error {
return core.CheckRequiredFlags(c.Command, c.NS, constants.FlagBackupLocationId)
}

func RunLocationGet(c *core.CommandConfig) error {
cols, _ := c.Command.Command.Flags().GetStringSlice(constants.ArgCols)
locationId := viper.GetString(core.GetFlagName(c.NS, constants.FlagBackupLocationId))

c.Verbose("Getting Backup Location...")

location, _, err := client.Must().MariaClientV2.BackupLocationsApi.BackuplocationsFindById(context.Background(), locationId).Execute()
if err != nil {
return err
}

return c.Out(table.Sprint(locationCols, location, cols))
}
47 changes: 47 additions & 0 deletions commands/dbaas/mariadb-v2/backup/location/list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package location

import (
"context"

"github.com/ionos-cloud/ionosctl/v6/internal/client"
"github.com/ionos-cloud/ionosctl/v6/internal/constants"
"github.com/ionos-cloud/ionosctl/v6/internal/core"
"github.com/ionos-cloud/ionosctl/v6/internal/printer/table"
"github.com/spf13/viper"
)

func LocationListCmd() *core.Command {
ctx := context.TODO()
cmd := core.NewCommand(ctx, nil, core.CommandBuilder{
Namespace: "dbaas-mariadb-v2",
Resource: "location",
Verb: "list",
Aliases: []string{"ls", "l"},
ShortDesc: "List MariaDB Backup Locations",
LongDesc: "Use this command to retrieve a list of Object Storage locations where backups can be stored.",
Example: "ionosctl dbaas mariadb-v2 backup location list",
PreCmdRun: core.NoPreRun,
CmdRun: RunLocationList,
InitClient: true,
})
cmd.AddInt32Flag(constants.FlagLimit, "", 100, "The maximum number of elements to return")
cmd.AddInt32Flag(constants.FlagOffset, "", 0, "The first element to return")
return cmd
}

func RunLocationList(c *core.CommandConfig) error {
req := client.Must().MariaClientV2.BackupLocationsApi.BackuplocationsGet(context.Background())
if fn := core.GetFlagName(c.NS, constants.FlagLimit); viper.IsSet(fn) {
req = req.Limit(viper.GetInt32(fn))
}
if fn := core.GetFlagName(c.NS, constants.FlagOffset); viper.IsSet(fn) {
req = req.Offset(viper.GetInt32(fn))
}
locations, _, err := req.Execute()
if err != nil {
return err
}

cols, _ := c.Command.Command.Flags().GetStringSlice(constants.ArgCols)
return c.Out(table.Sprint(locationCols, locations, cols, table.WithPrefix("items")))
}
37 changes: 37 additions & 0 deletions commands/dbaas/mariadb-v2/backup/location/location.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package location

import (
"github.com/ionos-cloud/ionosctl/v6/internal/constants"
"github.com/ionos-cloud/ionosctl/v6/internal/core"
"github.com/ionos-cloud/ionosctl/v6/internal/printer/table"
"github.com/spf13/cobra"
)

var locationCols = []table.Column{
{Name: "BackupLocationId", JSONPath: "id", Default: true},
{Name: "Location", JSONPath: "properties.location", Default: true},
}

func LocationCmd() *core.Command {
locationCmd := &core.Command{
Command: &cobra.Command{
Use: "location",
Aliases: []string{"loc", "locations"},
Short: "MariaDB Backup Location Operations",
Long: "The sub-commands of `ionosctl dbaas mariadb-v2 backup location` allow you to list the supported Object Storage locations where backups can be stored.",
TraverseChildren: true,
},
}

locationCmd.Command.PersistentFlags().StringSlice(constants.ArgCols, nil, table.ColsMessage(locationCols))
_ = locationCmd.Command.RegisterFlagCompletionFunc(
constants.ArgCols, func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return table.AllCols(locationCols), cobra.ShellCompDirectiveNoFileComp
},
)

locationCmd.AddCommand(LocationListCmd())
locationCmd.AddCommand(LocationGetCmd())

return locationCmd
}
Loading
Loading