diff --git a/doc/ovhcloud_cloud_managed-database_edit.md b/doc/ovhcloud_cloud_managed-database_edit.md index 059efc89..6e7aa7a3 100644 --- a/doc/ovhcloud_cloud_managed-database_edit.md +++ b/doc/ovhcloud_cloud_managed-database_edit.md @@ -20,6 +20,22 @@ There are two ways to define the edition parameters: ovhcloud cloud managed-database edit --editor --description "My database cluster" +Network update: + + You can switch a database service between public and private networks without recreating it. + + To switch from public to private network: + + ovhcloud cloud managed-database edit --network-id --subnet-id + + To switch from private to public network: + + ovhcloud cloud managed-database edit --public-network + + Note: --public-network is mutually exclusive with --network-id and --subnet-id. + Changing the network triggers a service rebuild. The service will be temporarily unavailable + during the transition. + ``` ovhcloud cloud managed-database edit [flags] @@ -38,7 +54,10 @@ ovhcloud cloud managed-database edit [flags] -h, --help help for edit --ip-restrictions strings IP blocks authorized to access the cluster (CIDR format) --maintenance-time string Time on which maintenances can start every day + --network-id string Private network ID --plan string Plan of the cluster + --public-network Switch the service to public network + --subnet-id string Private subnet ID --version string Version of the engine deployed on the cluster ``` diff --git a/internal/cmd/cloud_managed_database.go b/internal/cmd/cloud_managed_database.go index fb14349b..dc1d3ec1 100644 --- a/internal/cmd/cloud_managed_database.go +++ b/internal/cmd/cloud_managed_database.go @@ -317,6 +317,22 @@ There are two ways to define the edition parameters: Note that it is also possible to override values in the presented examples using command line flags like the following: ovhcloud cloud managed-database edit --editor --description "My database cluster" + +Network update: + + You can switch a database service between public and private networks without recreating it. + + To switch from public to private network: + + ovhcloud cloud managed-database edit --network-id --subnet-id + + To switch from private to public network: + + ovhcloud cloud managed-database edit --public-network + + Note: --public-network is mutually exclusive with --network-id and --subnet-id. + Changing the network triggers a service rebuild. The service will be temporarily unavailable + during the transition. `, ValidArgsFunction: completion.CloudResources("/v1/cloud/project/%s/database"), Run: cloud.EditManagedDatabase, @@ -336,6 +352,11 @@ There are two ways to define the edition parameters: // Network configuration managedDatabaseEditCmd.Flags().StringSliceVar(&cloud.ManagedDatabaseSpec.CLIIPRestrictions, "ip-restrictions", nil, "IP blocks authorized to access the cluster (CIDR format)") + managedDatabaseEditCmd.Flags().StringVar(&cloud.ManagedDatabaseSpec.CLINetworkID, "network-id", "", "Private network ID") + managedDatabaseEditCmd.Flags().StringVar(&cloud.ManagedDatabaseSpec.CLISubnetID, "subnet-id", "", "Private subnet ID") + managedDatabaseEditCmd.Flags().BoolVar(&cloud.ManagedDatabaseSpec.CLIPublicNetwork, "public-network", false, "Switch the service to public network") + managedDatabaseEditCmd.MarkFlagsMutuallyExclusive("public-network", "network-id") + managedDatabaseEditCmd.MarkFlagsMutuallyExclusive("public-network", "subnet-id") // Common flags for other mean to define parameters addInteractiveEditorFlag(managedDatabaseEditCmd) diff --git a/internal/services/cloud/cloud_managed_database.go b/internal/services/cloud/cloud_managed_database.go index b828686d..7bcc932c 100644 --- a/internal/services/cloud/cloud_managed_database.go +++ b/internal/services/cloud/cloud_managed_database.go @@ -87,6 +87,9 @@ var ( Engine string `json:"-"` CLIIPRestrictions []string `json:"-"` CLINodesList []string `json:"-"` + CLINetworkID string `json:"-"` + CLISubnetID string `json:"-"` + CLIPublicNetwork bool `json:"-"` } ManagedDatabaseDatabaseSpec struct { @@ -236,13 +239,29 @@ func EditManagedDatabase(cmd *cobra.Command, args []string) { ManagedDatabaseSpec.IPRestrictions = append(ManagedDatabaseSpec.IPRestrictions, managedDatabaseIPRestriction{IP: restriction}) } - // Edit resource + // Build extra network fields that bypass the OpenAPI filter + var networkFields map[string]any + if ManagedDatabaseSpec.CLIPublicNetwork { + networkFields = map[string]any{ + "networkId": nil, + "subnetId": nil, + } + } else if ManagedDatabaseSpec.CLINetworkID != "" { + networkFields = map[string]any{ + "networkId": ManagedDatabaseSpec.CLINetworkID, + "subnetId": ManagedDatabaseSpec.CLISubnetID, + } + } + + endpoint := fmt.Sprintf("/v1/cloud/project/%s/database/%s/%s", projectID, url.PathEscape(databaseService["engine"].(string)), url.PathEscape(args[0])) + if err := common.EditResource( cmd, fmt.Sprintf("/cloud/project/{serviceName}/database/%s/{clusterId}", url.PathEscape(databaseService["engine"].(string))), - fmt.Sprintf("/v1/cloud/project/%s/database/%s/%s", projectID, url.PathEscape(databaseService["engine"].(string)), url.PathEscape(args[0])), + endpoint, ManagedDatabaseSpec, assets.CloudOpenapiSchema, + networkFields, ); err != nil { display.OutputError(&flags.OutputFormatConfig, "%s", err) return diff --git a/internal/services/common/common.go b/internal/services/common/common.go index f0689fcb..36f61553 100644 --- a/internal/services/common/common.go +++ b/internal/services/common/common.go @@ -221,7 +221,7 @@ func CreateResource(cmd *cobra.Command, path, endpoint, defaultExample string, return createdResource, nil } -func EditResource(cmd *cobra.Command, path, url string, cliParams any, openapiSpec []byte) error { +func EditResource(cmd *cobra.Command, path, url string, cliParams any, openapiSpec []byte, extraFields ...map[string]any) error { if cmd.Flags().NFlag() == 0 { display.OutputInfo(&flags.OutputFormatConfig, nil, "🟠 No parameters given, nothing to edit") return nil @@ -282,6 +282,13 @@ func EditResource(cmd *cobra.Command, path, url string, cliParams any, openapiSp return fmt.Errorf("failed to extract writable properties: %w", err) } + // Inject extra fields that bypass the OpenAPI filter + for _, extra := range extraFields { + for k, v := range extra { + editableBody[k] = v + } + } + // If editor not needed, update the resource directly if !flags.ParametersViaEditor { if err := httpLib.Client.Put(url, editableBody, nil); err != nil {