diff --git a/doc/ovhcloud_cloud_storage_file.md b/doc/ovhcloud_cloud_storage_file.md index 57c7aa51..98c55c6b 100644 --- a/doc/ovhcloud_cloud_storage_file.md +++ b/doc/ovhcloud_cloud_storage_file.md @@ -7,7 +7,6 @@ Manage file storage shares in the given cloud project ``` --cloud-project string Cloud project ID -h, --help help for file - --region string Region (skip region discovery if set) ``` ### Options inherited from parent commands @@ -34,4 +33,5 @@ Manage file storage shares in the given cloud project * [ovhcloud cloud storage](ovhcloud_cloud_storage.md) - Manage storage services in the given cloud project * [ovhcloud cloud storage file network](ovhcloud_cloud_storage_file_network.md) - Manage file storage share networks * [ovhcloud cloud storage file share](ovhcloud_cloud_storage_file_share.md) - Manage file storage shares +* [ovhcloud cloud storage file snapshot](ovhcloud_cloud_storage_file_snapshot.md) - Manage share snapshots diff --git a/doc/ovhcloud_cloud_storage_file_network.md b/doc/ovhcloud_cloud_storage_file_network.md index d9f63e0a..6add6078 100644 --- a/doc/ovhcloud_cloud_storage_file_network.md +++ b/doc/ovhcloud_cloud_storage_file_network.md @@ -26,7 +26,6 @@ Manage file storage share networks --output 'name+","+type' (to extract and concatenate fields in a string) --output '(nbFieldA + nbFieldB) * 10' (to compute values from numeric fields) --profile string Use a specific profile from the configuration file - --region string Region (skip region discovery if set) ``` ### SEE ALSO diff --git a/doc/ovhcloud_cloud_storage_file_network_create.md b/doc/ovhcloud_cloud_storage_file_network_create.md index 6dfbbb06..ae569b48 100644 --- a/doc/ovhcloud_cloud_storage_file_network_create.md +++ b/doc/ovhcloud_cloud_storage_file_network_create.md @@ -39,7 +39,6 @@ ovhcloud cloud storage file network create [flags] --output 'name+","+type' (to extract and concatenate fields in a string) --output '(nbFieldA + nbFieldB) * 10' (to compute values from numeric fields) --profile string Use a specific profile from the configuration file - --region string Region (skip region discovery if set) ``` ### SEE ALSO diff --git a/doc/ovhcloud_cloud_storage_file_network_delete.md b/doc/ovhcloud_cloud_storage_file_network_delete.md index e624ed04..44053a24 100644 --- a/doc/ovhcloud_cloud_storage_file_network_delete.md +++ b/doc/ovhcloud_cloud_storage_file_network_delete.md @@ -30,7 +30,6 @@ ovhcloud cloud storage file network delete [flags] --output 'name+","+type' (to extract and concatenate fields in a string) --output '(nbFieldA + nbFieldB) * 10' (to compute values from numeric fields) --profile string Use a specific profile from the configuration file - --region string Region (skip region discovery if set) ``` ### SEE ALSO diff --git a/doc/ovhcloud_cloud_storage_file_network_get.md b/doc/ovhcloud_cloud_storage_file_network_get.md index 7a47c258..07eddefa 100644 --- a/doc/ovhcloud_cloud_storage_file_network_get.md +++ b/doc/ovhcloud_cloud_storage_file_network_get.md @@ -30,7 +30,6 @@ ovhcloud cloud storage file network get [flags] --output 'name+","+type' (to extract and concatenate fields in a string) --output '(nbFieldA + nbFieldB) * 10' (to compute values from numeric fields) --profile string Use a specific profile from the configuration file - --region string Region (skip region discovery if set) ``` ### SEE ALSO diff --git a/doc/ovhcloud_cloud_storage_file_network_list.md b/doc/ovhcloud_cloud_storage_file_network_list.md index 7ffed53d..3ad1a16f 100644 --- a/doc/ovhcloud_cloud_storage_file_network_list.md +++ b/doc/ovhcloud_cloud_storage_file_network_list.md @@ -37,7 +37,6 @@ ovhcloud cloud storage file network list [flags] --output 'name+","+type' (to extract and concatenate fields in a string) --output '(nbFieldA + nbFieldB) * 10' (to compute values from numeric fields) --profile string Use a specific profile from the configuration file - --region string Region (skip region discovery if set) ``` ### SEE ALSO diff --git a/doc/ovhcloud_cloud_storage_file_share.md b/doc/ovhcloud_cloud_storage_file_share.md index aa8cddb9..b1534cc6 100644 --- a/doc/ovhcloud_cloud_storage_file_share.md +++ b/doc/ovhcloud_cloud_storage_file_share.md @@ -26,7 +26,6 @@ Manage file storage shares --output 'name+","+type' (to extract and concatenate fields in a string) --output '(nbFieldA + nbFieldB) * 10' (to compute values from numeric fields) --profile string Use a specific profile from the configuration file - --region string Region (skip region discovery if set) ``` ### SEE ALSO @@ -38,5 +37,4 @@ Manage file storage shares * [ovhcloud cloud storage file share edit](ovhcloud_cloud_storage_file_share_edit.md) - Edit the given share * [ovhcloud cloud storage file share get](ovhcloud_cloud_storage_file_share_get.md) - Get a specific share * [ovhcloud cloud storage file share list](ovhcloud_cloud_storage_file_share_list.md) - List shares -* [ovhcloud cloud storage file share snapshot](ovhcloud_cloud_storage_file_share_snapshot.md) - Manage share snapshots diff --git a/doc/ovhcloud_cloud_storage_file_share_acl.md b/doc/ovhcloud_cloud_storage_file_share_acl.md index ee15b11a..f922503d 100644 --- a/doc/ovhcloud_cloud_storage_file_share_acl.md +++ b/doc/ovhcloud_cloud_storage_file_share_acl.md @@ -26,7 +26,6 @@ Manage share access control lists --output 'name+","+type' (to extract and concatenate fields in a string) --output '(nbFieldA + nbFieldB) * 10' (to compute values from numeric fields) --profile string Use a specific profile from the configuration file - --region string Region (skip region discovery if set) ``` ### SEE ALSO diff --git a/doc/ovhcloud_cloud_storage_file_share_acl_create.md b/doc/ovhcloud_cloud_storage_file_share_acl_create.md index ff020b7b..2574e49e 100644 --- a/doc/ovhcloud_cloud_storage_file_share_acl_create.md +++ b/doc/ovhcloud_cloud_storage_file_share_acl_create.md @@ -32,7 +32,6 @@ ovhcloud cloud storage file share acl create [flags] --output 'name+","+type' (to extract and concatenate fields in a string) --output '(nbFieldA + nbFieldB) * 10' (to compute values from numeric fields) --profile string Use a specific profile from the configuration file - --region string Region (skip region discovery if set) ``` ### SEE ALSO diff --git a/doc/ovhcloud_cloud_storage_file_share_acl_delete.md b/doc/ovhcloud_cloud_storage_file_share_acl_delete.md index ddd58e83..72cc015e 100644 --- a/doc/ovhcloud_cloud_storage_file_share_acl_delete.md +++ b/doc/ovhcloud_cloud_storage_file_share_acl_delete.md @@ -30,7 +30,6 @@ ovhcloud cloud storage file share acl delete [flags] --output 'name+","+type' (to extract and concatenate fields in a string) --output '(nbFieldA + nbFieldB) * 10' (to compute values from numeric fields) --profile string Use a specific profile from the configuration file - --region string Region (skip region discovery if set) ``` ### SEE ALSO diff --git a/doc/ovhcloud_cloud_storage_file_share_acl_get.md b/doc/ovhcloud_cloud_storage_file_share_acl_get.md index 10e6f18a..742a10f4 100644 --- a/doc/ovhcloud_cloud_storage_file_share_acl_get.md +++ b/doc/ovhcloud_cloud_storage_file_share_acl_get.md @@ -30,7 +30,6 @@ ovhcloud cloud storage file share acl get [flags] --output 'name+","+type' (to extract and concatenate fields in a string) --output '(nbFieldA + nbFieldB) * 10' (to compute values from numeric fields) --profile string Use a specific profile from the configuration file - --region string Region (skip region discovery if set) ``` ### SEE ALSO diff --git a/doc/ovhcloud_cloud_storage_file_share_acl_list.md b/doc/ovhcloud_cloud_storage_file_share_acl_list.md index 62b3f345..c68af1be 100644 --- a/doc/ovhcloud_cloud_storage_file_share_acl_list.md +++ b/doc/ovhcloud_cloud_storage_file_share_acl_list.md @@ -37,7 +37,6 @@ ovhcloud cloud storage file share acl list [flags] --output 'name+","+type' (to extract and concatenate fields in a string) --output '(nbFieldA + nbFieldB) * 10' (to compute values from numeric fields) --profile string Use a specific profile from the configuration file - --region string Region (skip region discovery if set) ``` ### SEE ALSO diff --git a/doc/ovhcloud_cloud_storage_file_share_create.md b/doc/ovhcloud_cloud_storage_file_share_create.md index 8f78d94f..d270d8c4 100644 --- a/doc/ovhcloud_cloud_storage_file_share_create.md +++ b/doc/ovhcloud_cloud_storage_file_share_create.md @@ -41,7 +41,6 @@ ovhcloud cloud storage file share create [flags] --output 'name+","+type' (to extract and concatenate fields in a string) --output '(nbFieldA + nbFieldB) * 10' (to compute values from numeric fields) --profile string Use a specific profile from the configuration file - --region string Region (skip region discovery if set) ``` ### SEE ALSO diff --git a/doc/ovhcloud_cloud_storage_file_share_delete.md b/doc/ovhcloud_cloud_storage_file_share_delete.md index 064f73dc..0395c769 100644 --- a/doc/ovhcloud_cloud_storage_file_share_delete.md +++ b/doc/ovhcloud_cloud_storage_file_share_delete.md @@ -30,7 +30,6 @@ ovhcloud cloud storage file share delete [flags] --output 'name+","+type' (to extract and concatenate fields in a string) --output '(nbFieldA + nbFieldB) * 10' (to compute values from numeric fields) --profile string Use a specific profile from the configuration file - --region string Region (skip region discovery if set) ``` ### SEE ALSO diff --git a/doc/ovhcloud_cloud_storage_file_share_edit.md b/doc/ovhcloud_cloud_storage_file_share_edit.md index 085eec56..b27389d7 100644 --- a/doc/ovhcloud_cloud_storage_file_share_edit.md +++ b/doc/ovhcloud_cloud_storage_file_share_edit.md @@ -34,7 +34,6 @@ ovhcloud cloud storage file share edit [flags] --output 'name+","+type' (to extract and concatenate fields in a string) --output '(nbFieldA + nbFieldB) * 10' (to compute values from numeric fields) --profile string Use a specific profile from the configuration file - --region string Region (skip region discovery if set) ``` ### SEE ALSO diff --git a/doc/ovhcloud_cloud_storage_file_share_get.md b/doc/ovhcloud_cloud_storage_file_share_get.md index be1bbf9a..fc74e13e 100644 --- a/doc/ovhcloud_cloud_storage_file_share_get.md +++ b/doc/ovhcloud_cloud_storage_file_share_get.md @@ -30,7 +30,6 @@ ovhcloud cloud storage file share get [flags] --output 'name+","+type' (to extract and concatenate fields in a string) --output '(nbFieldA + nbFieldB) * 10' (to compute values from numeric fields) --profile string Use a specific profile from the configuration file - --region string Region (skip region discovery if set) ``` ### SEE ALSO diff --git a/doc/ovhcloud_cloud_storage_file_share_list.md b/doc/ovhcloud_cloud_storage_file_share_list.md index 8dad6874..190c8c47 100644 --- a/doc/ovhcloud_cloud_storage_file_share_list.md +++ b/doc/ovhcloud_cloud_storage_file_share_list.md @@ -37,7 +37,6 @@ ovhcloud cloud storage file share list [flags] --output 'name+","+type' (to extract and concatenate fields in a string) --output '(nbFieldA + nbFieldB) * 10' (to compute values from numeric fields) --profile string Use a specific profile from the configuration file - --region string Region (skip region discovery if set) ``` ### SEE ALSO diff --git a/doc/ovhcloud_cloud_storage_file_share_snapshot.md b/doc/ovhcloud_cloud_storage_file_snapshot.md similarity index 63% rename from doc/ovhcloud_cloud_storage_file_share_snapshot.md rename to doc/ovhcloud_cloud_storage_file_snapshot.md index 21f31289..a0b7ace1 100644 --- a/doc/ovhcloud_cloud_storage_file_share_snapshot.md +++ b/doc/ovhcloud_cloud_storage_file_snapshot.md @@ -1,4 +1,4 @@ -## ovhcloud cloud storage file share snapshot +## ovhcloud cloud storage file snapshot Manage share snapshots @@ -26,14 +26,14 @@ Manage share snapshots --output 'name+","+type' (to extract and concatenate fields in a string) --output '(nbFieldA + nbFieldB) * 10' (to compute values from numeric fields) --profile string Use a specific profile from the configuration file - --region string Region (skip region discovery if set) ``` ### SEE ALSO -* [ovhcloud cloud storage file share](ovhcloud_cloud_storage_file_share.md) - Manage file storage shares -* [ovhcloud cloud storage file share snapshot create](ovhcloud_cloud_storage_file_share_snapshot_create.md) - Create a snapshot of the given share -* [ovhcloud cloud storage file share snapshot delete](ovhcloud_cloud_storage_file_share_snapshot_delete.md) - Delete a snapshot from the given share -* [ovhcloud cloud storage file share snapshot get](ovhcloud_cloud_storage_file_share_snapshot_get.md) - Get a specific snapshot for the given share -* [ovhcloud cloud storage file share snapshot list](ovhcloud_cloud_storage_file_share_snapshot_list.md) - List snapshots for the given share +* [ovhcloud cloud storage file](ovhcloud_cloud_storage_file.md) - Manage file storage shares in the given cloud project +* [ovhcloud cloud storage file snapshot create](ovhcloud_cloud_storage_file_snapshot_create.md) - Create a snapshot of the given share +* [ovhcloud cloud storage file snapshot delete](ovhcloud_cloud_storage_file_snapshot_delete.md) - Delete a share snapshot +* [ovhcloud cloud storage file snapshot edit](ovhcloud_cloud_storage_file_snapshot_edit.md) - Edit a share snapshot +* [ovhcloud cloud storage file snapshot get](ovhcloud_cloud_storage_file_snapshot_get.md) - Get a specific share snapshot +* [ovhcloud cloud storage file snapshot list](ovhcloud_cloud_storage_file_snapshot_list.md) - List share snapshots diff --git a/doc/ovhcloud_cloud_storage_file_snapshot_create.md b/doc/ovhcloud_cloud_storage_file_snapshot_create.md new file mode 100644 index 00000000..9d354351 --- /dev/null +++ b/doc/ovhcloud_cloud_storage_file_snapshot_create.md @@ -0,0 +1,45 @@ +## ovhcloud cloud storage file snapshot create + +Create a snapshot of the given share + +``` +ovhcloud cloud storage file snapshot create [flags] +``` + +### Options + +``` + --description string Snapshot description + --editor Use a text editor to define parameters + --from-file string File containing parameters + -h, --help help for create + --init-file string Create a file with example parameters + --name string Snapshot name + --replace Replace parameters file if it already exists + --wait Wait for the snapshot to be ready before exiting +``` + +### Options inherited from parent commands + +``` + --cloud-project string Cloud project ID + -d, --debug Activate debug mode (will log all HTTP requests details) + -e, --ignore-errors Ignore errors in API calls when it is not fatal to the execution + -o, --output string Output format: json, yaml, interactive, or a custom format expression (using https://github.com/PaesslerAG/gval syntax) + Examples: + --output json + --output yaml + --output interactive + --output 'id' (to extract a single field) + --output 'nested.field.subfield' (to extract a nested field) + --output '[id, "name"]' (to extract multiple fields as an array) + --output '{"newKey": oldKey, "otherKey": nested.field}' (to extract and rename fields in an object) + --output 'name+","+type' (to extract and concatenate fields in a string) + --output '(nbFieldA + nbFieldB) * 10' (to compute values from numeric fields) + --profile string Use a specific profile from the configuration file +``` + +### SEE ALSO + +* [ovhcloud cloud storage file snapshot](ovhcloud_cloud_storage_file_snapshot.md) - Manage share snapshots + diff --git a/doc/ovhcloud_cloud_storage_file_share_snapshot_delete.md b/doc/ovhcloud_cloud_storage_file_snapshot_delete.md similarity index 79% rename from doc/ovhcloud_cloud_storage_file_share_snapshot_delete.md rename to doc/ovhcloud_cloud_storage_file_snapshot_delete.md index bf3649e5..f509df40 100644 --- a/doc/ovhcloud_cloud_storage_file_share_snapshot_delete.md +++ b/doc/ovhcloud_cloud_storage_file_snapshot_delete.md @@ -1,9 +1,9 @@ -## ovhcloud cloud storage file share snapshot delete +## ovhcloud cloud storage file snapshot delete -Delete a snapshot from the given share +Delete a share snapshot ``` -ovhcloud cloud storage file share snapshot delete [flags] +ovhcloud cloud storage file snapshot delete [flags] ``` ### Options @@ -30,10 +30,9 @@ ovhcloud cloud storage file share snapshot delete [flag --output 'name+","+type' (to extract and concatenate fields in a string) --output '(nbFieldA + nbFieldB) * 10' (to compute values from numeric fields) --profile string Use a specific profile from the configuration file - --region string Region (skip region discovery if set) ``` ### SEE ALSO -* [ovhcloud cloud storage file share snapshot](ovhcloud_cloud_storage_file_share_snapshot.md) - Manage share snapshots +* [ovhcloud cloud storage file snapshot](ovhcloud_cloud_storage_file_snapshot.md) - Manage share snapshots diff --git a/doc/ovhcloud_cloud_storage_file_share_snapshot_create.md b/doc/ovhcloud_cloud_storage_file_snapshot_edit.md similarity index 77% rename from doc/ovhcloud_cloud_storage_file_share_snapshot_create.md rename to doc/ovhcloud_cloud_storage_file_snapshot_edit.md index 1ac780ed..e3913c37 100644 --- a/doc/ovhcloud_cloud_storage_file_share_snapshot_create.md +++ b/doc/ovhcloud_cloud_storage_file_snapshot_edit.md @@ -1,17 +1,19 @@ -## ovhcloud cloud storage file share snapshot create +## ovhcloud cloud storage file snapshot edit -Create a snapshot of the given share +Edit a share snapshot ``` -ovhcloud cloud storage file share snapshot create [flags] +ovhcloud cloud storage file snapshot edit [flags] ``` ### Options ``` --description string Snapshot description - -h, --help help for create + --editor Use a text editor to define parameters + -h, --help help for edit --name string Snapshot name + --wait Wait for the snapshot to be ready before exiting ``` ### Options inherited from parent commands @@ -32,10 +34,9 @@ ovhcloud cloud storage file share snapshot create [flags] --output 'name+","+type' (to extract and concatenate fields in a string) --output '(nbFieldA + nbFieldB) * 10' (to compute values from numeric fields) --profile string Use a specific profile from the configuration file - --region string Region (skip region discovery if set) ``` ### SEE ALSO -* [ovhcloud cloud storage file share snapshot](ovhcloud_cloud_storage_file_share_snapshot.md) - Manage share snapshots +* [ovhcloud cloud storage file snapshot](ovhcloud_cloud_storage_file_snapshot.md) - Manage share snapshots diff --git a/doc/ovhcloud_cloud_storage_file_share_snapshot_get.md b/doc/ovhcloud_cloud_storage_file_snapshot_get.md similarity index 79% rename from doc/ovhcloud_cloud_storage_file_share_snapshot_get.md rename to doc/ovhcloud_cloud_storage_file_snapshot_get.md index f86954e5..aec5c51f 100644 --- a/doc/ovhcloud_cloud_storage_file_share_snapshot_get.md +++ b/doc/ovhcloud_cloud_storage_file_snapshot_get.md @@ -1,9 +1,9 @@ -## ovhcloud cloud storage file share snapshot get +## ovhcloud cloud storage file snapshot get -Get a specific snapshot for the given share +Get a specific share snapshot ``` -ovhcloud cloud storage file share snapshot get [flags] +ovhcloud cloud storage file snapshot get [flags] ``` ### Options @@ -30,10 +30,9 @@ ovhcloud cloud storage file share snapshot get [flags] --output 'name+","+type' (to extract and concatenate fields in a string) --output '(nbFieldA + nbFieldB) * 10' (to compute values from numeric fields) --profile string Use a specific profile from the configuration file - --region string Region (skip region discovery if set) ``` ### SEE ALSO -* [ovhcloud cloud storage file share snapshot](ovhcloud_cloud_storage_file_share_snapshot.md) - Manage share snapshots +* [ovhcloud cloud storage file snapshot](ovhcloud_cloud_storage_file_snapshot.md) - Manage share snapshots diff --git a/doc/ovhcloud_cloud_storage_file_share_snapshot_list.md b/doc/ovhcloud_cloud_storage_file_snapshot_list.md similarity index 84% rename from doc/ovhcloud_cloud_storage_file_share_snapshot_list.md rename to doc/ovhcloud_cloud_storage_file_snapshot_list.md index 18811e2e..62d492f9 100644 --- a/doc/ovhcloud_cloud_storage_file_share_snapshot_list.md +++ b/doc/ovhcloud_cloud_storage_file_snapshot_list.md @@ -1,9 +1,9 @@ -## ovhcloud cloud storage file share snapshot list +## ovhcloud cloud storage file snapshot list -List snapshots for the given share +List share snapshots ``` -ovhcloud cloud storage file share snapshot list [flags] +ovhcloud cloud storage file snapshot list [flags] ``` ### Options @@ -17,6 +17,7 @@ ovhcloud cloud storage file share snapshot list [flags] --filter 'startDate>="2023-12-01"' --filter 'name=~"something" && nbField>10' -h, --help help for list + --share-id string Share ID to filter snapshots by ``` ### Options inherited from parent commands @@ -37,10 +38,9 @@ ovhcloud cloud storage file share snapshot list [flags] --output 'name+","+type' (to extract and concatenate fields in a string) --output '(nbFieldA + nbFieldB) * 10' (to compute values from numeric fields) --profile string Use a specific profile from the configuration file - --region string Region (skip region discovery if set) ``` ### SEE ALSO -* [ovhcloud cloud storage file share snapshot](ovhcloud_cloud_storage_file_share_snapshot.md) - Manage share snapshots +* [ovhcloud cloud storage file snapshot](ovhcloud_cloud_storage_file_snapshot.md) - Manage share snapshots diff --git a/internal/assets/api-schemas/cloud_v2.json b/internal/assets/api-schemas/cloud_v2.json index 96101ee0..4544acf4 100644 --- a/internal/assets/api-schemas/cloud_v2.json +++ b/internal/assets/api-schemas/cloud_v2.json @@ -9526,27 +9526,20 @@ "nullable": true, "readOnly": true }, - "shareId": { - "type": "string", - "description": "ID of the parent file storage share", - "format": "uuid", - "readOnly": true - }, - "shareProto": { - "allOf": [ - { - "$ref": "#/components/schemas/publicCloud.storage.file.FileStorageProtocolEnum" + "share": { + "type": "object", + "description": "Parent file storage share", + "properties": { + "id": { + "type": "string", + "description": "ID of the parent file storage share", + "format": "uuid", + "readOnly": true } - ], - "description": "File sharing protocol of the parent share", - "readOnly": true - }, - "shareSize": { - "type": "integer", - "description": "Size of the parent share in GB at the time of the snapshot", + }, "readOnly": true }, - "snapshotSize": { + "size": { "type": "integer", "description": "Size of the snapshot in GB", "readOnly": true @@ -9562,28 +9555,28 @@ "description": "Description of the snapshot", "nullable": true }, - "location": { - "allOf": [ - { - "$ref": "#/components/schemas/publicCloud.common.Location" - } - ], - "description": "Location of the snapshot" - }, "name": { "type": "string", "description": "Desired snapshot name", "nullable": true }, - "shareId": { - "type": "string", - "description": "ID of the parent file storage share", - "format": "uuid" + "share": { + "type": "object", + "description": "Parent file storage share", + "properties": { + "id": { + "type": "string", + "description": "ID of the parent file storage share", + "format": "uuid" + } + }, + "required": [ + "id" + ] } }, "required": [ - "location", - "shareId" + "share" ] }, "publicCloud.storage.file.FileStorageSnapshotUpdate": { @@ -27239,11 +27232,10 @@ "value": { "targetSpec": { "description": "Daily backup snapshot", - "location": { - "region": "GRA1" - }, "name": "my-share-snapshot", - "shareId": "d1e2f3a4-b5c6-7890-abcd-ef1234567890" + "share": { + "id": "d1e2f3a4-b5c6-7890-abcd-ef1234567890" + } } }, "summary": "Create a snapshot of a file storage" @@ -27544,21 +27536,20 @@ "region": "GRA1" }, "name": "my-share-snapshot", - "shareId": "d1e2f3a4-b5c6-7890-abcd-ef1234567890", - "shareProto": "NFS", - "shareSize": 100, - "snapshotSize": 1 + "share": { + "id": "d1e2f3a4-b5c6-7890-abcd-ef1234567890" + }, + "size": 1 }, "currentTasks": null, "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "resourceStatus": "READY", "targetSpec": { "description": "Daily backup snapshot", - "location": { - "region": "GRA1" - }, "name": "my-share-snapshot", - "shareId": "d1e2f3a4-b5c6-7890-abcd-ef1234567890" + "share": { + "id": "d1e2f3a4-b5c6-7890-abcd-ef1234567890" + } }, "updatedAt": "2026-02-10T15:05:00Z" }, diff --git a/internal/cmd/cloud_storage_file.go b/internal/cmd/cloud_storage_file.go index c6e7940f..42da8f9f 100644 --- a/internal/cmd/cloud_storage_file.go +++ b/internal/cmd/cloud_storage_file.go @@ -6,6 +6,7 @@ package cmd import ( "github.com/ovh/ovhcloud-cli/internal/assets" + "github.com/ovh/ovhcloud-cli/internal/flags" "github.com/ovh/ovhcloud-cli/internal/services/cloud" "github.com/spf13/cobra" ) @@ -16,7 +17,6 @@ func initCloudStorageFileCommand(cloudCmd *cobra.Command) { Short: "Manage file storage shares in the given cloud project", } storageFileCmd.PersistentFlags().StringVar(&cloud.CloudProject, "cloud-project", "", "Cloud project ID") - storageFileCmd.PersistentFlags().StringVar(&cloud.ShareRegion, "region", "", "Region (skip region discovery if set)") networkCmd := &cobra.Command{ Use: "network", @@ -152,22 +152,23 @@ func initCloudStorageFileCommand(cloudCmd *cobra.Command) { Use: "snapshot", Short: "Manage share snapshots", } - shareCmd.AddCommand(snapshotCmd) + storageFileCmd.AddCommand(snapshotCmd) snapshotListCmd := &cobra.Command{ - Use: "list ", + Use: "list", Aliases: []string{"ls"}, - Short: "List snapshots for the given share", + Short: "List share snapshots", Run: cloud.ListShareSnapshots, - Args: cobra.ExactArgs(1), + Args: cobra.NoArgs, } + snapshotListCmd.Flags().String("share-id", "", "Share ID to filter snapshots by") snapshotCmd.AddCommand(withFilterFlag(snapshotListCmd)) snapshotCmd.AddCommand(&cobra.Command{ - Use: "get ", - Short: "Get a specific snapshot for the given share", + Use: "get ", + Short: "Get a specific share snapshot", Run: cloud.GetShareSnapshot, - Args: cobra.ExactArgs(2), + Args: cobra.ExactArgs(1), }) snapshotCreateCmd := &cobra.Command{ @@ -176,15 +177,31 @@ func initCloudStorageFileCommand(cloudCmd *cobra.Command) { Run: cloud.CreateShareSnapshot, Args: cobra.ExactArgs(1), } - snapshotCreateCmd.Flags().StringVar(&cloud.ShareSnapshotSpec.Description, "description", "", "Snapshot description") - snapshotCreateCmd.Flags().StringVar(&cloud.ShareSnapshotSpec.Name, "name", "", "Snapshot name") + snapshotCreateCmd.Flags().StringVar(&cloud.ShareSnapshotSpec.TargetSpec.Description, "description", "", "Snapshot description") + snapshotCreateCmd.Flags().StringVar(&cloud.ShareSnapshotSpec.TargetSpec.Name, "name", "", "Snapshot name") + snapshotCreateCmd.Flags().BoolVar(&flags.WaitForTask, "wait", false, "Wait for the snapshot to be ready before exiting") + addParameterFileFlags(snapshotCreateCmd, false, assets.CloudV2OpenapiSchema, "/publicCloud/project/{projectId}/storage/file/snapshot", "post", cloud.ShareSnapshotCreateExample, nil) + addInteractiveEditorFlag(snapshotCreateCmd) + markFlagsMutuallyExclusive(snapshotCreateCmd, "from-file", "editor") snapshotCmd.AddCommand(snapshotCreateCmd) + snapshotEditCmd := &cobra.Command{ + Use: "edit ", + Short: "Edit a share snapshot", + Run: cloud.EditShareSnapshot, + Args: cobra.ExactArgs(1), + } + snapshotEditCmd.Flags().StringVar(&cloud.ShareSnapshotEditSpec.TargetSpec.Description, "description", "", "Snapshot description") + snapshotEditCmd.Flags().StringVar(&cloud.ShareSnapshotEditSpec.TargetSpec.Name, "name", "", "Snapshot name") + snapshotEditCmd.Flags().BoolVar(&flags.WaitForTask, "wait", false, "Wait for the snapshot to be ready before exiting") + addInteractiveEditorFlag(snapshotEditCmd) + snapshotCmd.AddCommand(snapshotEditCmd) + snapshotCmd.AddCommand(&cobra.Command{ - Use: "delete ", - Short: "Delete a snapshot from the given share", + Use: "delete ", + Short: "Delete a share snapshot", Run: cloud.DeleteShareSnapshot, - Args: cobra.ExactArgs(2), + Args: cobra.ExactArgs(1), }) cloudCmd.AddCommand(storageFileCmd) diff --git a/internal/cmd/cloud_storage_file_test.go b/internal/cmd/cloud_storage_file_test.go new file mode 100644 index 00000000..492f35e7 --- /dev/null +++ b/internal/cmd/cloud_storage_file_test.go @@ -0,0 +1,92 @@ +// SPDX-FileCopyrightText: 2025 OVH SAS +// +// SPDX-License-Identifier: Apache-2.0 + +package cmd_test + +import ( + "net/http" + + "github.com/jarcoal/httpmock" + "github.com/maxatome/go-testdeep/td" + "github.com/ovh/ovhcloud-cli/internal/cmd" +) + +const shareSnapshotListResponse = `[ + { + "id": "snap-1", + "resourceStatus": "READY", + "targetSpec": { + "name": "first-snapshot", + "share": { "id": "share-1" } + } + }, + { + "id": "snap-2", + "resourceStatus": "READY", + "targetSpec": { + "name": "second-snapshot", + "share": { "id": "share-2" } + } + } +]` + +func (ms *MockSuite) TestCloudStorageFileSnapshotListCmd(assert, require *td.T) { + httpmock.RegisterResponder(http.MethodGet, + "https://eu.api.ovh.com/v2/publicCloud/project/fakeProjectID/storage/file/snapshot", + httpmock.NewStringResponder(200, shareSnapshotListResponse)) + + out, err := cmd.Execute("cloud", "storage", "file", "snapshot", "list", "--cloud-project", "fakeProjectID") + + require.CmpNoError(err) + assert.Cmp(out, td.Contains("snap-1")) + assert.Cmp(out, td.Contains("snap-2")) +} + +func (ms *MockSuite) TestCloudStorageFileSnapshotListFilteredByShareCmd(assert, require *td.T) { + httpmock.RegisterResponder(http.MethodGet, + "https://eu.api.ovh.com/v2/publicCloud/project/fakeProjectID/storage/file/snapshot", + httpmock.NewStringResponder(200, shareSnapshotListResponse)) + + out, err := cmd.Execute("cloud", "storage", "file", "snapshot", "list", "--share-id", "share-1", "--cloud-project", "fakeProjectID") + + require.CmpNoError(err) + assert.Cmp(out, td.Contains("snap-1")) + assert.Cmp(out, td.Not(td.Contains("snap-2"))) +} + +func (ms *MockSuite) TestCloudStorageFileSnapshotGetCmd(assert, require *td.T) { + httpmock.RegisterResponder(http.MethodGet, + "https://eu.api.ovh.com/v2/publicCloud/project/fakeProjectID/storage/file/snapshot/snap-1", + httpmock.NewStringResponder(200, `{ + "id": "snap-1", + "resourceStatus": "READY", + "targetSpec": { + "name": "first-snapshot", + "share": { "id": "share-1" } + }, + "currentState": { + "name": "first-snapshot", + "share": { "id": "share-1" }, + "location": { "region": "EU-WEST-PAR" }, + "size": 10 + } + }`)) + + out, err := cmd.Execute("cloud", "storage", "file", "snapshot", "get", "snap-1", "--cloud-project", "fakeProjectID") + + require.CmpNoError(err) + assert.Cmp(out, td.Contains("first-snapshot")) + assert.Cmp(out, td.Contains("share-1")) +} + +func (ms *MockSuite) TestCloudStorageFileSnapshotDeleteCmd(assert, require *td.T) { + httpmock.RegisterResponder(http.MethodDelete, + "https://eu.api.ovh.com/v2/publicCloud/project/fakeProjectID/storage/file/snapshot/snap-1", + httpmock.NewStringResponder(200, ``)) + + out, err := cmd.Execute("cloud", "storage", "file", "snapshot", "delete", "snap-1", "--cloud-project", "fakeProjectID") + + require.CmpNoError(err) + assert.Cmp(out, td.Contains("Snapshot snap-1 is being deleted")) +} diff --git a/internal/services/cloud/cloud_storage_file.go b/internal/services/cloud/cloud_storage_file.go index a8325bae..8a855e92 100644 --- a/internal/services/cloud/cloud_storage_file.go +++ b/internal/services/cloud/cloud_storage_file.go @@ -12,7 +12,6 @@ import ( "github.com/ovh/ovhcloud-cli/internal/assets" "github.com/ovh/ovhcloud-cli/internal/display" - filtersLib "github.com/ovh/ovhcloud-cli/internal/filters" "github.com/ovh/ovhcloud-cli/internal/flags" httpLib "github.com/ovh/ovhcloud-cli/internal/http" "github.com/ovh/ovhcloud-cli/internal/services/common" @@ -36,8 +35,13 @@ var ( "targetSpec.subnet.id subnetId", "resourceStatus status", } - shareSnapshotColumnsToDisplay = []string{"id", "name", "shareId", "size", "status"} - shareACLColumnsToDisplay = []string{ + shareSnapshotColumnsToDisplay = []string{ + "id", + "targetSpec.name name", + "targetSpec.share.id shareId", + "resourceStatus status", + } + shareACLColumnsToDisplay = []string{ "id", "currentState.accessLevel accessLevel", "currentState.accessTo accessTo", @@ -56,6 +60,9 @@ var ( //go:embed parameter-samples/storage-file-share-network-create.json ShareNetworkCreateExample string + //go:embed parameter-samples/storage-file-share-snapshot-create.json + ShareSnapshotCreateExample string + ShareSpec struct { TargetSpec struct { Description string `json:"description,omitempty"` @@ -99,8 +106,20 @@ var ( } ShareSnapshotSpec struct { - Description string `json:"description,omitempty"` - Name string `json:"name,omitempty"` + TargetSpec struct { + Description string `json:"description,omitempty"` + Name string `json:"name,omitempty"` + Share struct { + Id string `json:"id,omitempty"` + } `json:"share,omitzero"` + } `json:"targetSpec"` + } + + ShareSnapshotEditSpec struct { + TargetSpec struct { + Description string `json:"description,omitempty"` + Name string `json:"name,omitempty"` + } `json:"targetSpec,omitzero"` } ShareACLSpec struct { @@ -109,8 +128,6 @@ var ( AccessTo string `json:"accessTo,omitempty"` } `json:"targetSpec"` } - - ShareRegion string ) func shareV2Endpoint(projectID string) string { @@ -121,39 +138,8 @@ func shareNetworkV2Endpoint(projectID string) string { return fmt.Sprintf("/v2/publicCloud/project/%s/storage/file/network", projectID) } -// getShareRegions returns a single-element slice if --region is set, -// otherwise discovers all regions with the share feature available. -func getShareRegions(projectID string) ([]any, error) { - if ShareRegion != "" { - return []any{ShareRegion}, nil - } - return getCloudRegionsWithFeatureAvailable(projectID, "share") -} - -// findShare searches for a share across all regions and returns its endpoint and data. -func findShare(shareID string) (string, map[string]any, error) { - projectID, err := getConfiguredCloudProject() - if err != nil { - return "", nil, err - } - - regions, err := getShareRegions(projectID) - if err != nil { - return "", nil, fmt.Errorf("failed to fetch regions with share feature available: %w", err) - } - - for _, region := range regions { - var ( - share map[string]any - endpoint = fmt.Sprintf("/v1/cloud/project/%s/region/%s/share/%s", - projectID, url.PathEscape(region.(string)), url.PathEscape(shareID)) - ) - if err := httpLib.Client.Get(endpoint, &share); err == nil { - return endpoint, share, nil - } - } - - return "", nil, fmt.Errorf("no share found with ID %s", shareID) +func shareSnapshotV2Endpoint(projectID string) string { + return fmt.Sprintf("/v2/publicCloud/project/%s/storage/file/snapshot", projectID) } func ListShares(_ *cobra.Command, _ []string) { @@ -376,71 +362,126 @@ func DeleteShareACL(_ *cobra.Command, args []string) { // Snapshot commands -func ListShareSnapshots(_ *cobra.Command, args []string) { - endpoint, _, err := findShare(args[0]) +func ListShareSnapshots(cmd *cobra.Command, _ []string) { + projectID, err := getConfiguredCloudProject() if err != nil { display.OutputError(&flags.OutputFormatConfig, "%s", err) return } - var snapshots []map[string]any - if err := httpLib.Client.Get(endpoint+"/snapshot", &snapshots); err != nil { - display.OutputError(&flags.OutputFormatConfig, "failed to fetch share snapshots: %s", err) - return - } - - snapshots, err = filtersLib.FilterLines(snapshots, flags.GenericFilters) + shareID, err := cmd.Flags().GetString("share-id") if err != nil { - display.OutputError(&flags.OutputFormatConfig, "failed to filter results: %s", err) + display.OutputError(&flags.OutputFormatConfig, "%s", err) return } - display.RenderTable(snapshots, shareSnapshotColumnsToDisplay, &flags.OutputFormatConfig) + filters := append([]string{}, flags.GenericFilters...) + if shareID != "" { + filters = append(filters, fmt.Sprintf("targetSpec.share.id==%q", shareID)) + } + common.ManageListRequestNoExpand(shareSnapshotV2Endpoint(projectID), shareSnapshotColumnsToDisplay, filters) } func GetShareSnapshot(_ *cobra.Command, args []string) { - endpoint, _, err := findShare(args[0]) + projectID, err := getConfiguredCloudProject() if err != nil { display.OutputError(&flags.OutputFormatConfig, "%s", err) return } var snapshot map[string]any - if err := httpLib.Client.Get(fmt.Sprintf("%s/snapshot/%s", endpoint, url.PathEscape(args[1])), &snapshot); err != nil { + endpoint := fmt.Sprintf("%s/%s", shareSnapshotV2Endpoint(projectID), url.PathEscape(args[0])) + if err := httpLib.Client.Get(endpoint, &snapshot); err != nil { display.OutputError(&flags.OutputFormatConfig, "failed to fetch share snapshot: %s", err) return } - display.OutputObject(snapshot, args[1], shareSnapshotTemplate, &flags.OutputFormatConfig) + display.OutputObject(snapshot, args[0], shareSnapshotTemplate, &flags.OutputFormatConfig) } -func CreateShareSnapshot(_ *cobra.Command, args []string) { - endpoint, _, err := findShare(args[0]) +func CreateShareSnapshot(cmd *cobra.Command, args []string) { + projectID, err := getConfiguredCloudProject() if err != nil { display.OutputError(&flags.OutputFormatConfig, "%s", err) return } - var response map[string]any - if err := httpLib.Client.Post(endpoint+"/snapshot", ShareSnapshotSpec, &response); err != nil { - display.OutputError(&flags.OutputFormatConfig, "failed to create share snapshot: %s", err) + ShareSnapshotSpec.TargetSpec.Share.Id = args[0] + endpoint := shareSnapshotV2Endpoint(projectID) + snapshot, err := common.CreateResource( + cmd, + "/publicCloud/project/{projectId}/storage/file/snapshot", + endpoint, + ShareSnapshotCreateExample, + ShareSnapshotSpec, + assets.CloudV2OpenapiSchema, + []string{"targetSpec.share.id"}, + ) + if err != nil { + display.OutputError(&flags.OutputFormatConfig, "%s", err) + return + } + + snapshotID, _ := snapshot["id"].(string) + + if !flags.WaitForTask { + display.OutputInfo(&flags.OutputFormatConfig, snapshot, "✅ Snapshot creation started successfully for share %s (id: %s)", args[0], snapshotID) + return + } + + ready, err := waitForCloudResourceReady(fmt.Sprintf("%s/%s", endpoint, url.PathEscape(snapshotID)), 10*time.Minute) + if err != nil { + display.OutputError(&flags.OutputFormatConfig, "failed to wait for snapshot creation: %s", err) + return + } + + display.OutputInfo(&flags.OutputFormatConfig, ready, "✅ Snapshot %s created successfully for share %s", snapshotID, args[0]) +} + +func EditShareSnapshot(cmd *cobra.Command, args []string) { + projectID, err := getConfiguredCloudProject() + if err != nil { + display.OutputError(&flags.OutputFormatConfig, "%s", err) return } - display.OutputInfo(&flags.OutputFormatConfig, response, "✅ Snapshot created successfully for share %s (id: %s)", args[0], response["id"]) + endpoint := fmt.Sprintf("%s/%s", shareSnapshotV2Endpoint(projectID), url.PathEscape(args[0])) + if err := common.EditResource( + cmd, + "/publicCloud/project/{projectId}/storage/file/snapshot/{snapshotId}", + endpoint, + ShareSnapshotEditSpec, + assets.CloudV2OpenapiSchema, + ); err != nil { + display.OutputError(&flags.OutputFormatConfig, "%s", err) + return + } + + if !flags.WaitForTask { + return + } + + ready, err := waitForCloudResourceReady(endpoint, 10*time.Minute) + if err != nil { + display.OutputError(&flags.OutputFormatConfig, "failed to wait for snapshot to be ready: %s", err) + return + } + + display.OutputInfo(&flags.OutputFormatConfig, ready, "✅ Snapshot %s is now ready", args[0]) } func DeleteShareSnapshot(_ *cobra.Command, args []string) { - endpoint, _, err := findShare(args[0]) + projectID, err := getConfiguredCloudProject() if err != nil { display.OutputError(&flags.OutputFormatConfig, "%s", err) return } - if err := httpLib.Client.Delete(fmt.Sprintf("%s/snapshot/%s", endpoint, url.PathEscape(args[1])), nil); err != nil { + endpoint := fmt.Sprintf("%s/%s", shareSnapshotV2Endpoint(projectID), url.PathEscape(args[0])) + if err := httpLib.Client.Delete(endpoint, nil); err != nil { display.OutputError(&flags.OutputFormatConfig, "failed to delete share snapshot: %s", err) return } - display.OutputInfo(&flags.OutputFormatConfig, nil, "✅ Snapshot %s deleted successfully from share %s", args[1], args[0]) + display.OutputInfo(&flags.OutputFormatConfig, nil, "✅ Snapshot %s is being deleted", args[0]) } diff --git a/internal/services/cloud/parameter-samples/storage-file-share-snapshot-create.json b/internal/services/cloud/parameter-samples/storage-file-share-snapshot-create.json new file mode 100644 index 00000000..d2c9b461 --- /dev/null +++ b/internal/services/cloud/parameter-samples/storage-file-share-snapshot-create.json @@ -0,0 +1,9 @@ +{ + "targetSpec": { + "name": "my-share-snapshot", + "description": "My file share snapshot", + "share": { + "id": "00000000-0000-0000-0000-000000000000" + } + } +} diff --git a/internal/services/cloud/templates/cloud_storage_file_share_snapshot.tmpl b/internal/services/cloud/templates/cloud_storage_file_share_snapshot.tmpl index 4fefa633..43e29c5f 100644 --- a/internal/services/cloud/templates/cloud_storage_file_share_snapshot.tmpl +++ b/internal/services/cloud/templates/cloud_storage_file_share_snapshot.tmpl @@ -1,16 +1,15 @@ 🚀 Share Snapshot {{.ServiceName}} ======= +{{$state := index .Result "targetSpec"}}{{with index .Result "currentState"}}{{$state = .}}{{end}} +{{with index $state "description"}}_{{.}}_ -_{{index .Result "description"}}_ +{{end}}## General information -## General information - -**Name**: {{index .Result "name"}} -**Share ID**: {{index .Result "shareId"}} -**Share protocol**: {{index .Result "shareProtocol"}} -**Share size**: {{index .Result "shareSize"}}GB -**Size**: {{index .Result "size"}}GB -**Status**: {{index .Result "status"}} -**Created at**: {{index .Result "createdAt"}} +{{with index $state "name"}}**Name**: {{.}} +{{end}}**Share ID**: {{index $state "share" "id"}} +**Status**: {{index .Result "resourceStatus"}} +{{with index .Result "currentState"}}**Region**: {{index . "location" "region"}} +**Size**: {{index . "size"}}GB +{{end}}**Created at**: {{index .Result "createdAt"}} 💡 Use option -o json or -o yaml to get the raw output with all information \ No newline at end of file