github.com/vnpaycloud-console/gophercloud/v2@v2.0.5/openstack/db/v1/instances/requests.go (about) 1 package instances 2 3 import ( 4 "context" 5 6 "github.com/vnpaycloud-console/gophercloud/v2" 7 db "github.com/vnpaycloud-console/gophercloud/v2/openstack/db/v1/databases" 8 "github.com/vnpaycloud-console/gophercloud/v2/openstack/db/v1/users" 9 "github.com/vnpaycloud-console/gophercloud/v2/pagination" 10 ) 11 12 // CreateOptsBuilder is the top-level interface for create options. 13 type CreateOptsBuilder interface { 14 ToInstanceCreateMap() (map[string]any, error) 15 } 16 17 // DatastoreOpts represents the configuration for how an instance stores data. 18 type DatastoreOpts struct { 19 Version string `json:"version"` 20 Type string `json:"type"` 21 } 22 23 // ToMap converts a DatastoreOpts to a map[string]string (for a request body) 24 func (opts DatastoreOpts) ToMap() (map[string]any, error) { 25 return gophercloud.BuildRequestBody(opts, "") 26 } 27 28 // NetworkOpts is used within CreateOpts to control a new server's network attachments. 29 type NetworkOpts struct { 30 // UUID of a nova-network to attach to the newly provisioned server. 31 // Required unless Port is provided. 32 UUID string `json:"net-id,omitempty"` 33 34 // Port of a neutron network to attach to the newly provisioned server. 35 // Required unless UUID is provided. 36 Port string `json:"port-id,omitempty"` 37 38 // V4FixedIP [optional] specifies a fixed IPv4 address to be used on this network. 39 V4FixedIP string `json:"v4-fixed-ip,omitempty"` 40 41 // V6FixedIP [optional] specifies a fixed IPv6 address to be used on this network. 42 V6FixedIP string `json:"v6-fixed-ip,omitempty"` 43 } 44 45 // ToMap converts a NetworkOpts to a map[string]string (for a request body) 46 func (opts NetworkOpts) ToMap() (map[string]any, error) { 47 return gophercloud.BuildRequestBody(opts, "") 48 } 49 50 // CreateOpts is the struct responsible for configuring a new database instance. 51 type CreateOpts struct { 52 // The availability zone of the instance. 53 AvailabilityZone string `json:"availability_zone,omitempty"` 54 // ID of the configuration group that you want to attach to the instance. 55 Configuration string `json:"configuration,omitempty"` 56 // Either the integer UUID (in string form) of the flavor, or its URI 57 // reference as specified in the response from the List() call. Required. 58 FlavorRef string 59 // Specifies the volume size in gigabytes (GB). The value must be between 1 60 // and 300. Required. 61 Size int 62 // Specifies the volume type. 63 VolumeType string 64 // Name of the instance to create. The length of the name is limited to 65 // 255 characters and any characters are permitted. Optional. 66 Name string 67 // A slice of database information options. 68 Databases db.CreateOptsBuilder 69 // A slice of user information options. 70 Users users.CreateOptsBuilder 71 // Options to configure the type of datastore the instance will use. This is 72 // optional, and if excluded will default to MySQL. 73 Datastore *DatastoreOpts 74 // Networks dictates how this server will be attached to available networks. 75 Networks []NetworkOpts 76 } 77 78 // ToInstanceCreateMap will render a JSON map. 79 func (opts CreateOpts) ToInstanceCreateMap() (map[string]any, error) { 80 if opts.Size > 300 || opts.Size < 1 { 81 err := gophercloud.ErrInvalidInput{} 82 err.Argument = "instances.CreateOpts.Size" 83 err.Value = opts.Size 84 err.Info = "Size (GB) must be between 1-300" 85 return nil, err 86 } 87 88 if opts.FlavorRef == "" { 89 return nil, gophercloud.ErrMissingInput{Argument: "instances.CreateOpts.FlavorRef"} 90 } 91 92 instance := map[string]any{ 93 "flavorRef": opts.FlavorRef, 94 } 95 96 if opts.AvailabilityZone != "" { 97 instance["availability_zone"] = opts.AvailabilityZone 98 } 99 100 if opts.Configuration != "" { 101 instance["configuration"] = opts.Configuration 102 } 103 104 if opts.Name != "" { 105 instance["name"] = opts.Name 106 } 107 if opts.Databases != nil { 108 dbs, err := opts.Databases.ToDBCreateMap() 109 if err != nil { 110 return nil, err 111 } 112 instance["databases"] = dbs["databases"] 113 } 114 if opts.Users != nil { 115 users, err := opts.Users.ToUserCreateMap() 116 if err != nil { 117 return nil, err 118 } 119 instance["users"] = users["users"] 120 } 121 if opts.Datastore != nil { 122 datastore, err := opts.Datastore.ToMap() 123 if err != nil { 124 return nil, err 125 } 126 instance["datastore"] = datastore 127 } 128 129 if len(opts.Networks) > 0 { 130 networks := make([]map[string]any, len(opts.Networks)) 131 for i, net := range opts.Networks { 132 var err error 133 networks[i], err = net.ToMap() 134 if err != nil { 135 return nil, err 136 } 137 } 138 instance["nics"] = networks 139 } 140 141 volume := map[string]any{ 142 "size": opts.Size, 143 } 144 145 if opts.VolumeType != "" { 146 volume["type"] = opts.VolumeType 147 } 148 149 instance["volume"] = volume 150 151 return map[string]any{"instance": instance}, nil 152 } 153 154 // Create asynchronously provisions a new database instance. It requires the 155 // user to specify a flavor and a volume size. The API service then provisions 156 // the instance with the requested flavor and sets up a volume of the specified 157 // size, which is the storage for the database instance. 158 // 159 // Although this call only allows the creation of 1 instance per request, you 160 // can create an instance with multiple databases and users. The default 161 // binding for a MySQL instance is port 3306. 162 func Create(ctx context.Context, client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { 163 b, err := opts.ToInstanceCreateMap() 164 if err != nil { 165 r.Err = err 166 return 167 } 168 resp, err := client.Post(ctx, baseURL(client), &b, &r.Body, &gophercloud.RequestOpts{OkCodes: []int{200}}) 169 _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) 170 return 171 } 172 173 // List retrieves the status and information for all database instances. 174 func List(client *gophercloud.ServiceClient) pagination.Pager { 175 return pagination.NewPager(client, baseURL(client), func(r pagination.PageResult) pagination.Page { 176 return InstancePage{pagination.LinkedPageBase{PageResult: r}} 177 }) 178 } 179 180 // Get retrieves the status and information for a specified database instance. 181 func Get(ctx context.Context, client *gophercloud.ServiceClient, id string) (r GetResult) { 182 resp, err := client.Get(ctx, resourceURL(client, id), &r.Body, nil) 183 _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) 184 return 185 } 186 187 // Delete permanently destroys the database instance. 188 func Delete(ctx context.Context, client *gophercloud.ServiceClient, id string) (r DeleteResult) { 189 resp, err := client.Delete(ctx, resourceURL(client, id), nil) 190 _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) 191 return 192 } 193 194 // EnableRootUser enables the login from any host for the root user and 195 // provides the user with a generated root password. 196 func EnableRootUser(ctx context.Context, client *gophercloud.ServiceClient, id string) (r EnableRootUserResult) { 197 resp, err := client.Post(ctx, userRootURL(client, id), nil, &r.Body, &gophercloud.RequestOpts{OkCodes: []int{200}}) 198 _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) 199 return 200 } 201 202 // IsRootEnabled checks an instance to see if root access is enabled. It returns 203 // True if root user is enabled for the specified database instance or False 204 // otherwise. 205 func IsRootEnabled(ctx context.Context, client *gophercloud.ServiceClient, id string) (r IsRootEnabledResult) { 206 resp, err := client.Get(ctx, userRootURL(client, id), &r.Body, nil) 207 _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) 208 return 209 } 210 211 // Restart will restart only the MySQL Instance. Restarting MySQL will 212 // erase any dynamic configuration settings that you have made within MySQL. 213 // The MySQL service will be unavailable until the instance restarts. 214 func Restart(ctx context.Context, client *gophercloud.ServiceClient, id string) (r ActionResult) { 215 b := map[string]any{"restart": struct{}{}} 216 resp, err := client.Post(ctx, actionURL(client, id), &b, nil, nil) 217 _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) 218 return 219 } 220 221 // Resize changes the memory size of the instance, assuming a valid 222 // flavorRef is provided. It will also restart the MySQL service. 223 func Resize(ctx context.Context, client *gophercloud.ServiceClient, id, flavorRef string) (r ActionResult) { 224 b := map[string]any{"resize": map[string]string{"flavorRef": flavorRef}} 225 resp, err := client.Post(ctx, actionURL(client, id), &b, nil, nil) 226 _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) 227 return 228 } 229 230 // ResizeVolume will resize the attached volume for an instance. It supports 231 // only increasing the volume size and does not support decreasing the size. 232 // The volume size is in gigabytes (GB) and must be an integer. 233 func ResizeVolume(ctx context.Context, client *gophercloud.ServiceClient, id string, size int) (r ActionResult) { 234 b := map[string]any{"resize": map[string]any{"volume": map[string]int{"size": size}}} 235 resp, err := client.Post(ctx, actionURL(client, id), &b, nil, nil) 236 _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) 237 return 238 } 239 240 // AttachConfigurationGroup will attach configuration group to the instance 241 func AttachConfigurationGroup(ctx context.Context, client *gophercloud.ServiceClient, instanceID string, configID string) (r ConfigurationResult) { 242 b := map[string]any{"instance": map[string]any{"configuration": configID}} 243 resp, err := client.Put(ctx, resourceURL(client, instanceID), &b, nil, &gophercloud.RequestOpts{OkCodes: []int{202}}) 244 _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) 245 return 246 } 247 248 // DetachConfigurationGroup will dettach configuration group from the instance 249 func DetachConfigurationGroup(ctx context.Context, client *gophercloud.ServiceClient, instanceID string) (r ConfigurationResult) { 250 b := map[string]any{"instance": map[string]any{}} 251 resp, err := client.Put(ctx, resourceURL(client, instanceID), &b, nil, &gophercloud.RequestOpts{OkCodes: []int{202}}) 252 _, r.Header, r.Err = gophercloud.ParseResponse(resp, err) 253 return 254 }