// Package v3 provides primitives to interact with the openapi HTTP API.
//
// Code generated by github.com/egoscale/v3/generator version v0.0.1 DO NOT EDIT.
package v3

import (
	"context"
	"fmt"
	"net"
	"net/http"
	"net/url"
	"time"
)

type ListAntiAffinityGroupsResponse struct {
	AntiAffinityGroups []AntiAffinityGroup `json:"anti-affinity-groups,omitempty"`
}

// FindAntiAffinityGroup attempts to find an AntiAffinityGroup by nameOrID.
func (l ListAntiAffinityGroupsResponse) FindAntiAffinityGroup(nameOrID string) (AntiAffinityGroup, error) {
	for i, elem := range l.AntiAffinityGroups {
		if string(elem.Name) == nameOrID || elem.ID.String() == nameOrID {
			return l.AntiAffinityGroups[i], nil
		}
	}

	return AntiAffinityGroup{}, fmt.Errorf("%q not found in ListAntiAffinityGroupsResponse: %w", nameOrID, ErrNotFound)
}

// List Anti-affinity Groups
func (c Client) ListAntiAffinityGroups(ctx context.Context) (*ListAntiAffinityGroupsResponse, error) {
	path := "/anti-affinity-group"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListAntiAffinityGroups: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListAntiAffinityGroups: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListAntiAffinityGroups: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-anti-affinity-groups")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListAntiAffinityGroups: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListAntiAffinityGroups: http response: %w", err)
	}

	bodyresp := &ListAntiAffinityGroupsResponse{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListAntiAffinityGroups: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type CreateAntiAffinityGroupRequest struct {
	// Anti-affinity Group description
	Description string `json:"description,omitempty" validate:"omitempty,lte=255"`
	// Anti-affinity Group name
	Name string `json:"name" validate:"required,gte=1,lte=255"`
}

// Create an Anti-affinity Group
func (c Client) CreateAntiAffinityGroup(ctx context.Context, req CreateAntiAffinityGroupRequest) (*Operation, error) {
	path := "/anti-affinity-group"

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateAntiAffinityGroup: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateAntiAffinityGroup: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateAntiAffinityGroup: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateAntiAffinityGroup: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-anti-affinity-group")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateAntiAffinityGroup: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateAntiAffinityGroup: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateAntiAffinityGroup: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Delete an Anti-affinity Group
func (c Client) DeleteAntiAffinityGroup(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/anti-affinity-group/%v", id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteAntiAffinityGroup: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteAntiAffinityGroup: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteAntiAffinityGroup: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-anti-affinity-group")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteAntiAffinityGroup: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteAntiAffinityGroup: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteAntiAffinityGroup: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve Anti-affinity Group details
func (c Client) GetAntiAffinityGroup(ctx context.Context, id UUID) (*AntiAffinityGroup, error) {
	path := fmt.Sprintf("/anti-affinity-group/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetAntiAffinityGroup: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetAntiAffinityGroup: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetAntiAffinityGroup: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-anti-affinity-group")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetAntiAffinityGroup: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetAntiAffinityGroup: http response: %w", err)
	}

	bodyresp := &AntiAffinityGroup{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetAntiAffinityGroup: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ListAPIKeysResponse struct {
	APIKeys []IAMAPIKey `json:"api-keys,omitempty"`
}

// FindIAMAPIKey attempts to find an IAMAPIKey by name.
func (l ListAPIKeysResponse) FindIAMAPIKey(name string) (IAMAPIKey, error) {
	for i, elem := range l.APIKeys {
		if string(elem.Name) == name {
			return l.APIKeys[i], nil
		}
	}

	return IAMAPIKey{}, fmt.Errorf("%q not found in ListAPIKeysResponse: %w", name, ErrNotFound)
}

// List API keys
func (c Client) ListAPIKeys(ctx context.Context) (*ListAPIKeysResponse, error) {
	path := "/api-key"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListAPIKeys: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListAPIKeys: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListAPIKeys: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-api-keys")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListAPIKeys: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListAPIKeys: http response: %w", err)
	}

	bodyresp := &ListAPIKeysResponse{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListAPIKeys: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type CreateAPIKeyRequest struct {
	// IAM API Key Name
	Name string `json:"name" validate:"required,gte=1,lte=255"`
	// IAM API Key Role ID
	RoleID UUID `json:"role-id" validate:"required"`
}

// Create a new API key
func (c Client) CreateAPIKey(ctx context.Context, req CreateAPIKeyRequest) (*IAMAPIKeyCreated, error) {
	path := "/api-key"

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateAPIKey: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateAPIKey: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateAPIKey: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateAPIKey: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-api-key")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateAPIKey: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateAPIKey: http response: %w", err)
	}

	bodyresp := &IAMAPIKeyCreated{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateAPIKey: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Delete an API key
func (c Client) DeleteAPIKey(ctx context.Context, id string) (*Operation, error) {
	path := fmt.Sprintf("/api-key/%v", id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteAPIKey: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteAPIKey: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteAPIKey: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-api-key")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteAPIKey: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteAPIKey: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteAPIKey: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Get API key
func (c Client) GetAPIKey(ctx context.Context, id string) (*IAMAPIKey, error) {
	path := fmt.Sprintf("/api-key/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetAPIKey: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetAPIKey: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetAPIKey: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-api-key")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetAPIKey: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetAPIKey: http response: %w", err)
	}

	bodyresp := &IAMAPIKey{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetAPIKey: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ListBlockStorageVolumesResponse struct {
	BlockStorageVolumes []BlockStorageVolume `json:"block-storage-volumes,omitempty"`
}

// FindBlockStorageVolume attempts to find an BlockStorageVolume by nameOrID.
func (l ListBlockStorageVolumesResponse) FindBlockStorageVolume(nameOrID string) (BlockStorageVolume, error) {
	for i, elem := range l.BlockStorageVolumes {
		if string(elem.Name) == nameOrID || elem.ID.String() == nameOrID {
			return l.BlockStorageVolumes[i], nil
		}
	}

	return BlockStorageVolume{}, fmt.Errorf("%q not found in ListBlockStorageVolumesResponse: %w", nameOrID, ErrNotFound)
}

type ListBlockStorageVolumesOpt func(url.Values)

func ListBlockStorageVolumesWithInstanceID(instanceID UUID) ListBlockStorageVolumesOpt {
	return func(q url.Values) {
		q.Add("instanceID", fmt.Sprint(instanceID))
	}
}

// List block storage volumes
func (c Client) ListBlockStorageVolumes(ctx context.Context, opts ...ListBlockStorageVolumesOpt) (*ListBlockStorageVolumesResponse, error) {
	path := "/block-storage"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListBlockStorageVolumes: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if len(opts) > 0 {
		q := request.URL.Query()
		for _, opt := range opts {
			opt(q)
		}
		request.URL.RawQuery = q.Encode()
	}

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListBlockStorageVolumes: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListBlockStorageVolumes: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-block-storage-volumes")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListBlockStorageVolumes: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListBlockStorageVolumes: http response: %w", err)
	}

	bodyresp := &ListBlockStorageVolumesResponse{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListBlockStorageVolumes: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type CreateBlockStorageVolumeRequest struct {
	// Target block storage snapshot
	BlockStorageSnapshot *BlockStorageSnapshotTarget `json:"block-storage-snapshot,omitempty"`
	Labels               Labels                      `json:"labels,omitempty"`
	// Volume name
	Name string `json:"name,omitempty" validate:"omitempty,lte=255"`
	// Volume size in GiB.
	// When a snapshot ID is supplied, this defaults to the size of the source volume, but can be set to a larger value.
	Size int64 `json:"size,omitempty" validate:"omitempty,gte=10"`
}

// Create a block storage volume
func (c Client) CreateBlockStorageVolume(ctx context.Context, req CreateBlockStorageVolumeRequest) (*Operation, error) {
	path := "/block-storage"

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateBlockStorageVolume: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateBlockStorageVolume: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateBlockStorageVolume: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateBlockStorageVolume: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-block-storage-volume")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateBlockStorageVolume: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateBlockStorageVolume: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateBlockStorageVolume: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ListBlockStorageSnapshotsResponse struct {
	BlockStorageSnapshots []BlockStorageSnapshot `json:"block-storage-snapshots,omitempty"`
}

// FindBlockStorageSnapshot attempts to find an BlockStorageSnapshot by nameOrID.
func (l ListBlockStorageSnapshotsResponse) FindBlockStorageSnapshot(nameOrID string) (BlockStorageSnapshot, error) {
	for i, elem := range l.BlockStorageSnapshots {
		if string(elem.Name) == nameOrID || elem.ID.String() == nameOrID {
			return l.BlockStorageSnapshots[i], nil
		}
	}

	return BlockStorageSnapshot{}, fmt.Errorf("%q not found in ListBlockStorageSnapshotsResponse: %w", nameOrID, ErrNotFound)
}

// List block storage snapshots
func (c Client) ListBlockStorageSnapshots(ctx context.Context) (*ListBlockStorageSnapshotsResponse, error) {
	path := "/block-storage-snapshot"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListBlockStorageSnapshots: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListBlockStorageSnapshots: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListBlockStorageSnapshots: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-block-storage-snapshots")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListBlockStorageSnapshots: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListBlockStorageSnapshots: http response: %w", err)
	}

	bodyresp := &ListBlockStorageSnapshotsResponse{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListBlockStorageSnapshots: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Delete a block storage snapshot, data will be unrecoverable
func (c Client) DeleteBlockStorageSnapshot(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/block-storage-snapshot/%v", id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteBlockStorageSnapshot: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteBlockStorageSnapshot: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteBlockStorageSnapshot: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-block-storage-snapshot")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteBlockStorageSnapshot: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteBlockStorageSnapshot: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteBlockStorageSnapshot: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve block storage snapshot details
func (c Client) GetBlockStorageSnapshot(ctx context.Context, id UUID) (*BlockStorageSnapshot, error) {
	path := fmt.Sprintf("/block-storage-snapshot/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetBlockStorageSnapshot: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetBlockStorageSnapshot: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetBlockStorageSnapshot: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-block-storage-snapshot")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetBlockStorageSnapshot: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetBlockStorageSnapshot: http response: %w", err)
	}

	bodyresp := &BlockStorageSnapshot{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetBlockStorageSnapshot: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type UpdateBlockStorageSnapshotRequest struct {
	Labels Labels `json:"labels"`
	// Snapshot name
	Name *string `json:"name,omitempty" validate:"omitempty,lte=255"`
}

// Update block storage volume snapshot
func (c Client) UpdateBlockStorageSnapshot(ctx context.Context, id UUID, req UpdateBlockStorageSnapshotRequest) (*Operation, error) {
	path := fmt.Sprintf("/block-storage-snapshot/%v", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateBlockStorageSnapshot: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateBlockStorageSnapshot: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateBlockStorageSnapshot: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateBlockStorageSnapshot: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-block-storage-snapshot")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateBlockStorageSnapshot: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateBlockStorageSnapshot: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateBlockStorageSnapshot: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Delete a block storage volume, data will be unrecoverable
func (c Client) DeleteBlockStorageVolume(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/block-storage/%v", id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteBlockStorageVolume: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteBlockStorageVolume: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteBlockStorageVolume: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-block-storage-volume")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteBlockStorageVolume: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteBlockStorageVolume: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteBlockStorageVolume: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve block storage volume details
func (c Client) GetBlockStorageVolume(ctx context.Context, id UUID) (*BlockStorageVolume, error) {
	path := fmt.Sprintf("/block-storage/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetBlockStorageVolume: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetBlockStorageVolume: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetBlockStorageVolume: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-block-storage-volume")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetBlockStorageVolume: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetBlockStorageVolume: http response: %w", err)
	}

	bodyresp := &BlockStorageVolume{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetBlockStorageVolume: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type UpdateBlockStorageVolumeRequest struct {
	Labels Labels `json:"labels"`
	// Volume name
	Name *string `json:"name,omitempty" validate:"omitempty,lte=255"`
}

// Update block storage volume
func (c Client) UpdateBlockStorageVolume(ctx context.Context, id UUID, req UpdateBlockStorageVolumeRequest) (*Operation, error) {
	path := fmt.Sprintf("/block-storage/%v", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateBlockStorageVolume: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateBlockStorageVolume: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateBlockStorageVolume: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateBlockStorageVolume: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-block-storage-volume")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateBlockStorageVolume: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateBlockStorageVolume: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateBlockStorageVolume: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type AttachBlockStorageVolumeToInstanceRequest struct {
	// Target Instance
	Instance *InstanceTarget `json:"instance" validate:"required"`
}

// Attach block storage volume to an instance
func (c Client) AttachBlockStorageVolumeToInstance(ctx context.Context, id UUID, req AttachBlockStorageVolumeToInstanceRequest) (*Operation, error) {
	path := fmt.Sprintf("/block-storage/%v:attach", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("AttachBlockStorageVolumeToInstance: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("AttachBlockStorageVolumeToInstance: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("AttachBlockStorageVolumeToInstance: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("AttachBlockStorageVolumeToInstance: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "attach-block-storage-volume-to-instance")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("AttachBlockStorageVolumeToInstance: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("AttachBlockStorageVolumeToInstance: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("AttachBlockStorageVolumeToInstance: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type CreateBlockStorageSnapshotRequest struct {
	Labels Labels `json:"labels,omitempty"`
	// Snapshot name
	Name string `json:"name,omitempty" validate:"omitempty,gte=1,lte=255"`
}

// Create a block storage snapshot
func (c Client) CreateBlockStorageSnapshot(ctx context.Context, id UUID, req CreateBlockStorageSnapshotRequest) (*Operation, error) {
	path := fmt.Sprintf("/block-storage/%v:create-snapshot", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateBlockStorageSnapshot: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateBlockStorageSnapshot: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateBlockStorageSnapshot: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateBlockStorageSnapshot: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-block-storage-snapshot")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateBlockStorageSnapshot: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateBlockStorageSnapshot: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateBlockStorageSnapshot: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Detach block storage volume
func (c Client) DetachBlockStorageVolume(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/block-storage/%v:detach", id)

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DetachBlockStorageVolume: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DetachBlockStorageVolume: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DetachBlockStorageVolume: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "detach-block-storage-volume")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DetachBlockStorageVolume: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DetachBlockStorageVolume: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DetachBlockStorageVolume: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ResizeBlockStorageVolumeRequest struct {
	// Volume size in GiB
	Size int64 `json:"size" validate:"required,gte=11"`
}

// This operation resizes a Block storage volume. Note: the volume can only grow, cannot be shrunk.
func (c Client) ResizeBlockStorageVolume(ctx context.Context, id UUID, req ResizeBlockStorageVolumeRequest) (*BlockStorageVolume, error) {
	path := fmt.Sprintf("/block-storage/%v:resize-volume", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("ResizeBlockStorageVolume: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("ResizeBlockStorageVolume: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ResizeBlockStorageVolume: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ResizeBlockStorageVolume: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "resize-block-storage-volume")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ResizeBlockStorageVolume: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ResizeBlockStorageVolume: http response: %w", err)
	}

	bodyresp := &BlockStorageVolume{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ResizeBlockStorageVolume: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type GetConsoleProxyURLResponse struct {
	Host string `json:"host,omitempty"`
	Path string `json:"path,omitempty"`
	URL  string `json:"url,omitempty"`
}

// Retrieve signed url valid for 60 seconds to connect via console-proxy websocket to VM VNC console.
func (c Client) GetConsoleProxyURL(ctx context.Context, id UUID) (*GetConsoleProxyURLResponse, error) {
	path := fmt.Sprintf("/console/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetConsoleProxyURL: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetConsoleProxyURL: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetConsoleProxyURL: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-console-proxy-url")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetConsoleProxyURL: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetConsoleProxyURL: http response: %w", err)
	}

	bodyresp := &GetConsoleProxyURLResponse{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetConsoleProxyURL: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type GetDBAASCACertificateResponse struct {
	Certificate string `json:"certificate,omitempty"`
}

// Returns a CA Certificate required to reach a DBaaS service through a TLS-protected connection.
func (c Client) GetDBAASCACertificate(ctx context.Context) (*GetDBAASCACertificateResponse, error) {
	path := "/dbaas-ca-certificate"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASCACertificate: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASCACertificate: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASCACertificate: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-ca-certificate")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASCACertificate: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASCACertificate: http response: %w", err)
	}

	bodyresp := &GetDBAASCACertificateResponse{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASCACertificate: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Delete a Grafana service
func (c Client) DeleteDBAASServiceGrafana(ctx context.Context, name string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-grafana/%v", name)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceGrafana: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceGrafana: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceGrafana: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-service-grafana")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceGrafana: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceGrafana: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceGrafana: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Get a DBaaS Grafana service
func (c Client) GetDBAASServiceGrafana(ctx context.Context, name string) (*DBAASServiceGrafana, error) {
	path := fmt.Sprintf("/dbaas-grafana/%v", name)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServiceGrafana: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceGrafana: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceGrafana: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-service-grafana")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServiceGrafana: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceGrafana: http response: %w", err)
	}

	bodyresp := &DBAASServiceGrafana{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceGrafana: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type CreateDBAASServiceGrafanaRequestMaintenanceDow string

const (
	CreateDBAASServiceGrafanaRequestMaintenanceDowSaturday  CreateDBAASServiceGrafanaRequestMaintenanceDow = "saturday"
	CreateDBAASServiceGrafanaRequestMaintenanceDowTuesday   CreateDBAASServiceGrafanaRequestMaintenanceDow = "tuesday"
	CreateDBAASServiceGrafanaRequestMaintenanceDowNever     CreateDBAASServiceGrafanaRequestMaintenanceDow = "never"
	CreateDBAASServiceGrafanaRequestMaintenanceDowWednesday CreateDBAASServiceGrafanaRequestMaintenanceDow = "wednesday"
	CreateDBAASServiceGrafanaRequestMaintenanceDowSunday    CreateDBAASServiceGrafanaRequestMaintenanceDow = "sunday"
	CreateDBAASServiceGrafanaRequestMaintenanceDowFriday    CreateDBAASServiceGrafanaRequestMaintenanceDow = "friday"
	CreateDBAASServiceGrafanaRequestMaintenanceDowMonday    CreateDBAASServiceGrafanaRequestMaintenanceDow = "monday"
	CreateDBAASServiceGrafanaRequestMaintenanceDowThursday  CreateDBAASServiceGrafanaRequestMaintenanceDow = "thursday"
)

// Automatic maintenance settings
type CreateDBAASServiceGrafanaRequestMaintenance struct {
	// Day of week for installing updates
	Dow CreateDBAASServiceGrafanaRequestMaintenanceDow `json:"dow" validate:"required"`
	// Time for installing updates, UTC
	Time string `json:"time" validate:"required,gte=8,lte=8"`
}

type CreateDBAASServiceGrafanaRequest struct {
	ForkFromService DBAASServiceName `json:"fork-from-service,omitempty" validate:"omitempty,gte=0,lte=63"`
	// Grafana settings
	GrafanaSettings *JSONSchemaGrafana `json:"grafana-settings,omitempty"`
	// Allowed CIDR address blocks for incoming connections
	IPFilter []string `json:"ip-filter,omitempty"`
	// Automatic maintenance settings
	Maintenance *CreateDBAASServiceGrafanaRequestMaintenance `json:"maintenance,omitempty"`
	// Subscription plan
	Plan string `json:"plan" validate:"required,gte=1,lte=128"`
	// Service is protected against termination and powering off
	TerminationProtection *bool `json:"termination-protection,omitempty"`
}

// Create a DBaaS Grafana service
func (c Client) CreateDBAASServiceGrafana(ctx context.Context, name string, req CreateDBAASServiceGrafanaRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-grafana/%v", name)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceGrafana: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceGrafana: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceGrafana: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceGrafana: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-service-grafana")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceGrafana: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceGrafana: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceGrafana: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type UpdateDBAASServiceGrafanaRequestMaintenanceDow string

const (
	UpdateDBAASServiceGrafanaRequestMaintenanceDowSaturday  UpdateDBAASServiceGrafanaRequestMaintenanceDow = "saturday"
	UpdateDBAASServiceGrafanaRequestMaintenanceDowTuesday   UpdateDBAASServiceGrafanaRequestMaintenanceDow = "tuesday"
	UpdateDBAASServiceGrafanaRequestMaintenanceDowNever     UpdateDBAASServiceGrafanaRequestMaintenanceDow = "never"
	UpdateDBAASServiceGrafanaRequestMaintenanceDowWednesday UpdateDBAASServiceGrafanaRequestMaintenanceDow = "wednesday"
	UpdateDBAASServiceGrafanaRequestMaintenanceDowSunday    UpdateDBAASServiceGrafanaRequestMaintenanceDow = "sunday"
	UpdateDBAASServiceGrafanaRequestMaintenanceDowFriday    UpdateDBAASServiceGrafanaRequestMaintenanceDow = "friday"
	UpdateDBAASServiceGrafanaRequestMaintenanceDowMonday    UpdateDBAASServiceGrafanaRequestMaintenanceDow = "monday"
	UpdateDBAASServiceGrafanaRequestMaintenanceDowThursday  UpdateDBAASServiceGrafanaRequestMaintenanceDow = "thursday"
)

// Automatic maintenance settings
type UpdateDBAASServiceGrafanaRequestMaintenance struct {
	// Day of week for installing updates
	Dow UpdateDBAASServiceGrafanaRequestMaintenanceDow `json:"dow" validate:"required"`
	// Time for installing updates, UTC
	Time string `json:"time" validate:"required,gte=8,lte=8"`
}

type UpdateDBAASServiceGrafanaRequest struct {
	// Grafana settings
	GrafanaSettings *JSONSchemaGrafana `json:"grafana-settings,omitempty"`
	// Allowed CIDR address blocks for incoming connections
	IPFilter []string `json:"ip-filter,omitempty"`
	// Automatic maintenance settings
	Maintenance *UpdateDBAASServiceGrafanaRequestMaintenance `json:"maintenance,omitempty"`
	// Subscription plan
	Plan string `json:"plan,omitempty" validate:"omitempty,gte=1,lte=128"`
	// Service is protected against termination and powering off
	TerminationProtection *bool `json:"termination-protection,omitempty"`
}

// Update a DBaaS Grafana service
func (c Client) UpdateDBAASServiceGrafana(ctx context.Context, name string, req UpdateDBAASServiceGrafanaRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-grafana/%v", name)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceGrafana: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceGrafana: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceGrafana: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceGrafana: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-dbaas-service-grafana")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceGrafana: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceGrafana: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceGrafana: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Initiate Grafana maintenance update
func (c Client) StartDBAASGrafanaMaintenance(ctx context.Context, name string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-grafana/%v/maintenance/start", name)

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("StartDBAASGrafanaMaintenance: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("StartDBAASGrafanaMaintenance: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("StartDBAASGrafanaMaintenance: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "start-dbaas-grafana-maintenance")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("StartDBAASGrafanaMaintenance: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("StartDBAASGrafanaMaintenance: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("StartDBAASGrafanaMaintenance: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ResetDBAASGrafanaUserPasswordRequest struct {
	Password DBAASUserPassword `json:"password,omitempty" validate:"omitempty,gte=8,lte=256"`
}

// If no password is provided one will be generated automatically.
func (c Client) ResetDBAASGrafanaUserPassword(ctx context.Context, serviceName string, username string, req ResetDBAASGrafanaUserPasswordRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-grafana/%v/user/%v/password/reset", serviceName, username)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("ResetDBAASGrafanaUserPassword: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("ResetDBAASGrafanaUserPassword: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ResetDBAASGrafanaUserPassword: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ResetDBAASGrafanaUserPassword: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reset-dbaas-grafana-user-password")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ResetDBAASGrafanaUserPassword: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ResetDBAASGrafanaUserPassword: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ResetDBAASGrafanaUserPassword: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Reveal the secrets of a DBaaS Grafana user
func (c Client) RevealDBAASGrafanaUserPassword(ctx context.Context, serviceName string, username string) (*DBAASUserGrafanaSecrets, error) {
	path := fmt.Sprintf("/dbaas-grafana/%v/user/%v/password/reveal", serviceName, username)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("RevealDBAASGrafanaUserPassword: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("RevealDBAASGrafanaUserPassword: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("RevealDBAASGrafanaUserPassword: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reveal-dbaas-grafana-user-password")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("RevealDBAASGrafanaUserPassword: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("RevealDBAASGrafanaUserPassword: http response: %w", err)
	}

	bodyresp := &DBAASUserGrafanaSecrets{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("RevealDBAASGrafanaUserPassword: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type CreateDBAASIntegrationRequest struct {
	DestService     DBAASServiceName     `json:"dest-service" validate:"required,gte=0,lte=63"`
	IntegrationType EnumIntegrationTypes `json:"integration-type" validate:"required"`
	// Integration settings
	Settings      map[string]any   `json:"settings,omitempty"`
	SourceService DBAASServiceName `json:"source-service" validate:"required,gte=0,lte=63"`
}

// Create a new DBaaS integration between two services
func (c Client) CreateDBAASIntegration(ctx context.Context, req CreateDBAASIntegrationRequest) (*Operation, error) {
	path := "/dbaas-integration"

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASIntegration: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASIntegration: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASIntegration: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASIntegration: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-integration")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASIntegration: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASIntegration: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASIntegration: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// The JSON schema representing the settings for the given integration type, source, and destination service types.
type ListDBAASIntegrationSettingsResponseSettings struct {
	AdditionalProperties *bool          `json:"additionalProperties,omitempty"`
	Properties           map[string]any `json:"properties,omitempty"`
	Title                string         `json:"title,omitempty"`
	Type                 string         `json:"type,omitempty"`
}

type ListDBAASIntegrationSettingsResponse struct {
	// The JSON schema representing the settings for the given integration type, source, and destination service types.
	Settings *ListDBAASIntegrationSettingsResponseSettings `json:"settings,omitempty"`
}

// Get DBaaS integration settings
func (c Client) ListDBAASIntegrationSettings(ctx context.Context, integrationType string, sourceType string, destType string) (*ListDBAASIntegrationSettingsResponse, error) {
	path := fmt.Sprintf("/dbaas-integration-settings/%v/%v/%v", integrationType, sourceType, destType)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListDBAASIntegrationSettings: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListDBAASIntegrationSettings: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListDBAASIntegrationSettings: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-dbaas-integration-settings")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListDBAASIntegrationSettings: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListDBAASIntegrationSettings: http response: %w", err)
	}

	bodyresp := &ListDBAASIntegrationSettingsResponse{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListDBAASIntegrationSettings: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ListDBAASIntegrationTypesResponse struct {
	DBAASIntegrationTypes []DBAASIntegrationType `json:"dbaas-integration-types,omitempty"`
}

// Get DBaaS integration types
func (c Client) ListDBAASIntegrationTypes(ctx context.Context) (*ListDBAASIntegrationTypesResponse, error) {
	path := "/dbaas-integration-types"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListDBAASIntegrationTypes: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListDBAASIntegrationTypes: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListDBAASIntegrationTypes: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-dbaas-integration-types")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListDBAASIntegrationTypes: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListDBAASIntegrationTypes: http response: %w", err)
	}

	bodyresp := &ListDBAASIntegrationTypesResponse{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListDBAASIntegrationTypes: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Delete a DBaaS Integration
func (c Client) DeleteDBAASIntegration(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-integration/%v", id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASIntegration: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASIntegration: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASIntegration: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-integration")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASIntegration: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASIntegration: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASIntegration: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Get a DBaaS Integration
func (c Client) GetDBAASIntegration(ctx context.Context, id UUID) (*DBAASIntegration, error) {
	path := fmt.Sprintf("/dbaas-integration/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASIntegration: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASIntegration: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASIntegration: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-integration")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASIntegration: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASIntegration: http response: %w", err)
	}

	bodyresp := &DBAASIntegration{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASIntegration: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type UpdateDBAASIntegrationRequest struct {
	// Integration settings
	Settings map[string]any `json:"settings" validate:"required"`
}

// Update a existing DBaaS integration
func (c Client) UpdateDBAASIntegration(ctx context.Context, id UUID, req UpdateDBAASIntegrationRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-integration/%v", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASIntegration: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASIntegration: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASIntegration: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASIntegration: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-dbaas-integration")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASIntegration: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateDBAASIntegration: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateDBAASIntegration: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Delete a Kafka service
func (c Client) DeleteDBAASServiceKafka(ctx context.Context, name string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-kafka/%v", name)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceKafka: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceKafka: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceKafka: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-service-kafka")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceKafka: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceKafka: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceKafka: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Get a DBaaS Kafka service
func (c Client) GetDBAASServiceKafka(ctx context.Context, name string) (*DBAASServiceKafka, error) {
	path := fmt.Sprintf("/dbaas-kafka/%v", name)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServiceKafka: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceKafka: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceKafka: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-service-kafka")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServiceKafka: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceKafka: http response: %w", err)
	}

	bodyresp := &DBAASServiceKafka{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceKafka: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Kafka authentication methods
type CreateDBAASServiceKafkaRequestAuthenticationMethods struct {
	// Enable certificate/SSL authentication
	Certificate *bool `json:"certificate,omitempty"`
	// Enable SASL authentication
	Sasl *bool `json:"sasl,omitempty"`
}

type CreateDBAASServiceKafkaRequestMaintenanceDow string

const (
	CreateDBAASServiceKafkaRequestMaintenanceDowSaturday  CreateDBAASServiceKafkaRequestMaintenanceDow = "saturday"
	CreateDBAASServiceKafkaRequestMaintenanceDowTuesday   CreateDBAASServiceKafkaRequestMaintenanceDow = "tuesday"
	CreateDBAASServiceKafkaRequestMaintenanceDowNever     CreateDBAASServiceKafkaRequestMaintenanceDow = "never"
	CreateDBAASServiceKafkaRequestMaintenanceDowWednesday CreateDBAASServiceKafkaRequestMaintenanceDow = "wednesday"
	CreateDBAASServiceKafkaRequestMaintenanceDowSunday    CreateDBAASServiceKafkaRequestMaintenanceDow = "sunday"
	CreateDBAASServiceKafkaRequestMaintenanceDowFriday    CreateDBAASServiceKafkaRequestMaintenanceDow = "friday"
	CreateDBAASServiceKafkaRequestMaintenanceDowMonday    CreateDBAASServiceKafkaRequestMaintenanceDow = "monday"
	CreateDBAASServiceKafkaRequestMaintenanceDowThursday  CreateDBAASServiceKafkaRequestMaintenanceDow = "thursday"
)

// Automatic maintenance settings
type CreateDBAASServiceKafkaRequestMaintenance struct {
	// Day of week for installing updates
	Dow CreateDBAASServiceKafkaRequestMaintenanceDow `json:"dow" validate:"required"`
	// Time for installing updates, UTC
	Time string `json:"time" validate:"required,gte=8,lte=8"`
}

type CreateDBAASServiceKafkaRequest struct {
	// Kafka authentication methods
	AuthenticationMethods *CreateDBAASServiceKafkaRequestAuthenticationMethods `json:"authentication-methods,omitempty"`
	// Allow incoming connections from CIDR address block, e.g. '10.20.0.0/16'
	IPFilter []string `json:"ip-filter,omitempty"`
	// Allow clients to connect to kafka_connect from the public internet for service nodes that are in a project VPC or another type of private network
	KafkaConnectEnabled *bool `json:"kafka-connect-enabled,omitempty"`
	// Kafka Connect configuration values
	KafkaConnectSettings JSONSchemaKafkaConnect `json:"kafka-connect-settings,omitempty"`
	// Enable Kafka-REST service
	KafkaRestEnabled *bool `json:"kafka-rest-enabled,omitempty"`
	// Kafka REST configuration
	KafkaRestSettings JSONSchemaKafkaRest `json:"kafka-rest-settings,omitempty"`
	// Kafka broker configuration values
	KafkaSettings JSONSchemaKafka `json:"kafka-settings,omitempty"`
	// Automatic maintenance settings
	Maintenance *CreateDBAASServiceKafkaRequestMaintenance `json:"maintenance,omitempty"`
	// Subscription plan
	Plan string `json:"plan" validate:"required,gte=1,lte=128"`
	// Enable Schema-Registry service
	SchemaRegistryEnabled *bool `json:"schema-registry-enabled,omitempty"`
	// Schema Registry configuration
	SchemaRegistrySettings JSONSchemaSchemaRegistry `json:"schema-registry-settings,omitempty"`
	// Service is protected against termination and powering off
	TerminationProtection *bool `json:"termination-protection,omitempty"`
	// Kafka major version
	Version string `json:"version,omitempty" validate:"omitempty,gte=1"`
}

// Create a DBaaS Kafka service
func (c Client) CreateDBAASServiceKafka(ctx context.Context, name string, req CreateDBAASServiceKafkaRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-kafka/%v", name)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceKafka: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceKafka: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceKafka: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceKafka: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-service-kafka")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceKafka: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceKafka: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceKafka: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Kafka authentication methods
type UpdateDBAASServiceKafkaRequestAuthenticationMethods struct {
	// Enable certificate/SSL authentication
	Certificate *bool `json:"certificate,omitempty"`
	// Enable SASL authentication
	Sasl *bool `json:"sasl,omitempty"`
}

type UpdateDBAASServiceKafkaRequestMaintenanceDow string

const (
	UpdateDBAASServiceKafkaRequestMaintenanceDowSaturday  UpdateDBAASServiceKafkaRequestMaintenanceDow = "saturday"
	UpdateDBAASServiceKafkaRequestMaintenanceDowTuesday   UpdateDBAASServiceKafkaRequestMaintenanceDow = "tuesday"
	UpdateDBAASServiceKafkaRequestMaintenanceDowNever     UpdateDBAASServiceKafkaRequestMaintenanceDow = "never"
	UpdateDBAASServiceKafkaRequestMaintenanceDowWednesday UpdateDBAASServiceKafkaRequestMaintenanceDow = "wednesday"
	UpdateDBAASServiceKafkaRequestMaintenanceDowSunday    UpdateDBAASServiceKafkaRequestMaintenanceDow = "sunday"
	UpdateDBAASServiceKafkaRequestMaintenanceDowFriday    UpdateDBAASServiceKafkaRequestMaintenanceDow = "friday"
	UpdateDBAASServiceKafkaRequestMaintenanceDowMonday    UpdateDBAASServiceKafkaRequestMaintenanceDow = "monday"
	UpdateDBAASServiceKafkaRequestMaintenanceDowThursday  UpdateDBAASServiceKafkaRequestMaintenanceDow = "thursday"
)

// Automatic maintenance settings
type UpdateDBAASServiceKafkaRequestMaintenance struct {
	// Day of week for installing updates
	Dow UpdateDBAASServiceKafkaRequestMaintenanceDow `json:"dow" validate:"required"`
	// Time for installing updates, UTC
	Time string `json:"time" validate:"required,gte=8,lte=8"`
}

type UpdateDBAASServiceKafkaRequest struct {
	// Kafka authentication methods
	AuthenticationMethods *UpdateDBAASServiceKafkaRequestAuthenticationMethods `json:"authentication-methods,omitempty"`
	// Allow incoming connections from CIDR address block, e.g. '10.20.0.0/16'
	IPFilter []string `json:"ip-filter,omitempty"`
	// Allow clients to connect to kafka_connect from the public internet for service nodes that are in a project VPC or another type of private network
	KafkaConnectEnabled *bool `json:"kafka-connect-enabled,omitempty"`
	// Kafka Connect configuration values
	KafkaConnectSettings JSONSchemaKafkaConnect `json:"kafka-connect-settings,omitempty"`
	// Enable Kafka-REST service
	KafkaRestEnabled *bool `json:"kafka-rest-enabled,omitempty"`
	// Kafka REST configuration
	KafkaRestSettings JSONSchemaKafkaRest `json:"kafka-rest-settings,omitempty"`
	// Kafka broker configuration values
	KafkaSettings JSONSchemaKafka `json:"kafka-settings,omitempty"`
	// Automatic maintenance settings
	Maintenance *UpdateDBAASServiceKafkaRequestMaintenance `json:"maintenance,omitempty"`
	// Subscription plan
	Plan string `json:"plan,omitempty" validate:"omitempty,gte=1,lte=128"`
	// Enable Schema-Registry service
	SchemaRegistryEnabled *bool `json:"schema-registry-enabled,omitempty"`
	// Schema Registry configuration
	SchemaRegistrySettings JSONSchemaSchemaRegistry `json:"schema-registry-settings,omitempty"`
	// Service is protected against termination and powering off
	TerminationProtection *bool `json:"termination-protection,omitempty"`
	// Kafka major version
	Version string `json:"version,omitempty" validate:"omitempty,gte=1"`
}

// Update a DBaaS Kafka service
func (c Client) UpdateDBAASServiceKafka(ctx context.Context, name string, req UpdateDBAASServiceKafkaRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-kafka/%v", name)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceKafka: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceKafka: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceKafka: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceKafka: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-dbaas-service-kafka")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceKafka: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceKafka: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceKafka: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Get DBaaS kafka ACL configuration
func (c Client) GetDBAASKafkaAclConfig(ctx context.Context, name string) (*DBAASKafkaAcls, error) {
	path := fmt.Sprintf("/dbaas-kafka/%v/acl-config", name)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASKafkaAclConfig: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASKafkaAclConfig: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASKafkaAclConfig: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-kafka-acl-config")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASKafkaAclConfig: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASKafkaAclConfig: http response: %w", err)
	}

	bodyresp := &DBAASKafkaAcls{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASKafkaAclConfig: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Initiate Kafka maintenance update
func (c Client) StartDBAASKafkaMaintenance(ctx context.Context, name string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-kafka/%v/maintenance/start", name)

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("StartDBAASKafkaMaintenance: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("StartDBAASKafkaMaintenance: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("StartDBAASKafkaMaintenance: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "start-dbaas-kafka-maintenance")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("StartDBAASKafkaMaintenance: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("StartDBAASKafkaMaintenance: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("StartDBAASKafkaMaintenance: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Add a Kafka Schema Registry ACL entry
func (c Client) CreateDBAASKafkaSchemaRegistryAclConfig(ctx context.Context, name string, req DBAASKafkaSchemaRegistryAclEntry) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-kafka/%v/schema-registry/acl-config", name)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASKafkaSchemaRegistryAclConfig: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASKafkaSchemaRegistryAclConfig: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASKafkaSchemaRegistryAclConfig: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASKafkaSchemaRegistryAclConfig: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-kafka-schema-registry-acl-config")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASKafkaSchemaRegistryAclConfig: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASKafkaSchemaRegistryAclConfig: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASKafkaSchemaRegistryAclConfig: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Delete a Kafka ACL entry
func (c Client) DeleteDBAASKafkaSchemaRegistryAclConfig(ctx context.Context, name string, aclID string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-kafka/%v/schema-registry/acl-config/%v", name, aclID)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASKafkaSchemaRegistryAclConfig: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASKafkaSchemaRegistryAclConfig: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASKafkaSchemaRegistryAclConfig: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-kafka-schema-registry-acl-config")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASKafkaSchemaRegistryAclConfig: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASKafkaSchemaRegistryAclConfig: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASKafkaSchemaRegistryAclConfig: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Add a Kafka topic ACL entry
func (c Client) CreateDBAASKafkaTopicAclConfig(ctx context.Context, name string, req DBAASKafkaTopicAclEntry) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-kafka/%v/topic/acl-config", name)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASKafkaTopicAclConfig: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASKafkaTopicAclConfig: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASKafkaTopicAclConfig: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASKafkaTopicAclConfig: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-kafka-topic-acl-config")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASKafkaTopicAclConfig: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASKafkaTopicAclConfig: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASKafkaTopicAclConfig: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Delete a Kafka ACL entry
func (c Client) DeleteDBAASKafkaTopicAclConfig(ctx context.Context, name string, aclID string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-kafka/%v/topic/acl-config/%v", name, aclID)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASKafkaTopicAclConfig: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASKafkaTopicAclConfig: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASKafkaTopicAclConfig: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-kafka-topic-acl-config")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASKafkaTopicAclConfig: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASKafkaTopicAclConfig: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASKafkaTopicAclConfig: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type CreateDBAASKafkaUserRequest struct {
	Username DBAASUserUsername `json:"username" validate:"required,gte=1,lte=64"`
}

// Create a DBaaS Kafka user
func (c Client) CreateDBAASKafkaUser(ctx context.Context, serviceName string, req CreateDBAASKafkaUserRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-kafka/%v/user", serviceName)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASKafkaUser: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASKafkaUser: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASKafkaUser: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASKafkaUser: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-kafka-user")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASKafkaUser: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASKafkaUser: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASKafkaUser: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Delete a DBaaS kafka user
func (c Client) DeleteDBAASKafkaUser(ctx context.Context, serviceName string, username string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-kafka/%v/user/%v", serviceName, username)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASKafkaUser: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASKafkaUser: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASKafkaUser: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-kafka-user")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASKafkaUser: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASKafkaUser: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASKafkaUser: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ResetDBAASKafkaUserPasswordRequest struct {
	Password DBAASUserPassword `json:"password,omitempty" validate:"omitempty,gte=8,lte=256"`
}

// If no password is provided one will be generated automatically.
func (c Client) ResetDBAASKafkaUserPassword(ctx context.Context, serviceName string, username string, req ResetDBAASKafkaUserPasswordRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-kafka/%v/user/%v/password/reset", serviceName, username)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("ResetDBAASKafkaUserPassword: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("ResetDBAASKafkaUserPassword: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ResetDBAASKafkaUserPassword: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ResetDBAASKafkaUserPassword: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reset-dbaas-kafka-user-password")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ResetDBAASKafkaUserPassword: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ResetDBAASKafkaUserPassword: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ResetDBAASKafkaUserPassword: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Reveal the secrets of a DBaaS Kafka user
func (c Client) RevealDBAASKafkaUserPassword(ctx context.Context, serviceName string, username string) (*DBAASUserKafkaSecrets, error) {
	path := fmt.Sprintf("/dbaas-kafka/%v/user/%v/password/reveal", serviceName, username)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("RevealDBAASKafkaUserPassword: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("RevealDBAASKafkaUserPassword: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("RevealDBAASKafkaUserPassword: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reveal-dbaas-kafka-user-password")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("RevealDBAASKafkaUserPassword: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("RevealDBAASKafkaUserPassword: http response: %w", err)
	}

	bodyresp := &DBAASUserKafkaSecrets{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("RevealDBAASKafkaUserPassword: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Get a DBaaS migration status
func (c Client) GetDBAASMigrationStatus(ctx context.Context, name string) (*DBAASMigrationStatus, error) {
	path := fmt.Sprintf("/dbaas-migration-status/%v", name)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASMigrationStatus: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASMigrationStatus: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASMigrationStatus: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-migration-status")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASMigrationStatus: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASMigrationStatus: http response: %w", err)
	}

	bodyresp := &DBAASMigrationStatus{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASMigrationStatus: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Delete a MySQL service
func (c Client) DeleteDBAASServiceMysql(ctx context.Context, name string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-mysql/%v", name)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceMysql: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceMysql: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceMysql: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-service-mysql")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceMysql: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceMysql: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceMysql: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Get a DBaaS MySQL service
func (c Client) GetDBAASServiceMysql(ctx context.Context, name string) (*DBAASServiceMysql, error) {
	path := fmt.Sprintf("/dbaas-mysql/%v", name)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServiceMysql: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceMysql: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceMysql: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-service-mysql")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServiceMysql: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceMysql: http response: %w", err)
	}

	bodyresp := &DBAASServiceMysql{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceMysql: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type CreateDBAASServiceMysqlRequestBackupSchedule struct {
	// The hour of day (in UTC) when backup for the service is started. New backup is only started if previous backup has already completed.
	BackupHour int64 `json:"backup-hour,omitempty" validate:"omitempty,gte=0,lte=23"`
	// The minute of an hour when backup for the service is started. New backup is only started if previous backup has already completed.
	BackupMinute int64 `json:"backup-minute,omitempty" validate:"omitempty,gte=0,lte=59"`
}

type CreateDBAASServiceMysqlRequestIntegrationsType string

const (
	CreateDBAASServiceMysqlRequestIntegrationsTypeReadReplica CreateDBAASServiceMysqlRequestIntegrationsType = "read_replica"
)

type CreateDBAASServiceMysqlRequestIntegrations struct {
	DestService DBAASServiceName `json:"dest-service,omitempty" validate:"omitempty,gte=0,lte=63"`
	// Integration settings
	Settings      map[string]any   `json:"settings,omitempty"`
	SourceService DBAASServiceName `json:"source-service,omitempty" validate:"omitempty,gte=0,lte=63"`
	// Integration type
	Type CreateDBAASServiceMysqlRequestIntegrationsType `json:"type" validate:"required"`
}

type CreateDBAASServiceMysqlRequestMaintenanceDow string

const (
	CreateDBAASServiceMysqlRequestMaintenanceDowSaturday  CreateDBAASServiceMysqlRequestMaintenanceDow = "saturday"
	CreateDBAASServiceMysqlRequestMaintenanceDowTuesday   CreateDBAASServiceMysqlRequestMaintenanceDow = "tuesday"
	CreateDBAASServiceMysqlRequestMaintenanceDowNever     CreateDBAASServiceMysqlRequestMaintenanceDow = "never"
	CreateDBAASServiceMysqlRequestMaintenanceDowWednesday CreateDBAASServiceMysqlRequestMaintenanceDow = "wednesday"
	CreateDBAASServiceMysqlRequestMaintenanceDowSunday    CreateDBAASServiceMysqlRequestMaintenanceDow = "sunday"
	CreateDBAASServiceMysqlRequestMaintenanceDowFriday    CreateDBAASServiceMysqlRequestMaintenanceDow = "friday"
	CreateDBAASServiceMysqlRequestMaintenanceDowMonday    CreateDBAASServiceMysqlRequestMaintenanceDow = "monday"
	CreateDBAASServiceMysqlRequestMaintenanceDowThursday  CreateDBAASServiceMysqlRequestMaintenanceDow = "thursday"
)

// Automatic maintenance settings
type CreateDBAASServiceMysqlRequestMaintenance struct {
	// Day of week for installing updates
	Dow CreateDBAASServiceMysqlRequestMaintenanceDow `json:"dow" validate:"required"`
	// Time for installing updates, UTC
	Time string `json:"time" validate:"required,gte=8,lte=8"`
}

// Migrate data from existing server
type CreateDBAASServiceMysqlRequestMigration struct {
	// Database name for bootstrapping the initial connection
	Dbname string `json:"dbname,omitempty" validate:"omitempty,gte=1,lte=63"`
	// Hostname or IP address of the server where to migrate data from
	Host string `json:"host" validate:"required,gte=1,lte=255"`
	// Comma-separated list of databases, which should be ignored during migration (supported by MySQL only at the moment)
	IgnoreDbs string              `json:"ignore-dbs,omitempty" validate:"omitempty,gte=1,lte=2048"`
	Method    EnumMigrationMethod `json:"method,omitempty"`
	// Password for authentication with the server where to migrate data from
	Password string `json:"password,omitempty" validate:"omitempty,gte=1,lte=255"`
	// Port number of the server where to migrate data from
	Port int64 `json:"port" validate:"required,gte=1,lte=65535"`
	// The server where to migrate data from is secured with SSL
	SSL *bool `json:"ssl,omitempty"`
	// User name for authentication with the server where to migrate data from
	Username string `json:"username,omitempty" validate:"omitempty,gte=1,lte=255"`
}

type CreateDBAASServiceMysqlRequest struct {
	// Custom password for admin user. Defaults to random string. This must be set only when a new service is being created.
	AdminPassword string `json:"admin-password,omitempty" validate:"omitempty,gte=8,lte=256"`
	// Custom username for admin user. This must be set only when a new service is being created.
	AdminUsername  string                                        `json:"admin-username,omitempty" validate:"omitempty,gte=1,lte=64"`
	BackupSchedule *CreateDBAASServiceMysqlRequestBackupSchedule `json:"backup-schedule,omitempty"`
	// The minimum amount of time in seconds to keep binlog entries before deletion. This may be extended for services that require binlog entries for longer than the default for example if using the MySQL Debezium Kafka connector.
	BinlogRetentionPeriod int64            `json:"binlog-retention-period,omitempty" validate:"omitempty,gte=600,lte=86400"`
	ForkFromService       DBAASServiceName `json:"fork-from-service,omitempty" validate:"omitempty,gte=0,lte=63"`
	// Service integrations to be enabled when creating the service.
	Integrations []CreateDBAASServiceMysqlRequestIntegrations `json:"integrations,omitempty"`
	// Allow incoming connections from CIDR address block, e.g. '10.20.0.0/16'
	IPFilter []string `json:"ip-filter,omitempty"`
	// Automatic maintenance settings
	Maintenance *CreateDBAASServiceMysqlRequestMaintenance `json:"maintenance,omitempty"`
	// Migrate data from existing server
	Migration *CreateDBAASServiceMysqlRequestMigration `json:"migration,omitempty"`
	// mysql.conf configuration values
	MysqlSettings JSONSchemaMysql `json:"mysql-settings,omitempty"`
	// Subscription plan
	Plan string `json:"plan" validate:"required,gte=1,lte=128"`
	// ISO time of a backup to recover from for services that support arbitrary times
	RecoveryBackupTime string `json:"recovery-backup-time,omitempty" validate:"omitempty,gte=1"`
	// Service is protected against termination and powering off
	TerminationProtection *bool `json:"termination-protection,omitempty"`
	// MySQL major version
	Version string `json:"version,omitempty" validate:"omitempty,gte=1"`
}

// Create a DBaaS MySQL service
func (c Client) CreateDBAASServiceMysql(ctx context.Context, name string, req CreateDBAASServiceMysqlRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-mysql/%v", name)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceMysql: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceMysql: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceMysql: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceMysql: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-service-mysql")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceMysql: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceMysql: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceMysql: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type UpdateDBAASServiceMysqlRequestBackupSchedule struct {
	// The hour of day (in UTC) when backup for the service is started. New backup is only started if previous backup has already completed.
	BackupHour int64 `json:"backup-hour,omitempty" validate:"omitempty,gte=0,lte=23"`
	// The minute of an hour when backup for the service is started. New backup is only started if previous backup has already completed.
	BackupMinute int64 `json:"backup-minute,omitempty" validate:"omitempty,gte=0,lte=59"`
}

type UpdateDBAASServiceMysqlRequestMaintenanceDow string

const (
	UpdateDBAASServiceMysqlRequestMaintenanceDowSaturday  UpdateDBAASServiceMysqlRequestMaintenanceDow = "saturday"
	UpdateDBAASServiceMysqlRequestMaintenanceDowTuesday   UpdateDBAASServiceMysqlRequestMaintenanceDow = "tuesday"
	UpdateDBAASServiceMysqlRequestMaintenanceDowNever     UpdateDBAASServiceMysqlRequestMaintenanceDow = "never"
	UpdateDBAASServiceMysqlRequestMaintenanceDowWednesday UpdateDBAASServiceMysqlRequestMaintenanceDow = "wednesday"
	UpdateDBAASServiceMysqlRequestMaintenanceDowSunday    UpdateDBAASServiceMysqlRequestMaintenanceDow = "sunday"
	UpdateDBAASServiceMysqlRequestMaintenanceDowFriday    UpdateDBAASServiceMysqlRequestMaintenanceDow = "friday"
	UpdateDBAASServiceMysqlRequestMaintenanceDowMonday    UpdateDBAASServiceMysqlRequestMaintenanceDow = "monday"
	UpdateDBAASServiceMysqlRequestMaintenanceDowThursday  UpdateDBAASServiceMysqlRequestMaintenanceDow = "thursday"
)

// Automatic maintenance settings
type UpdateDBAASServiceMysqlRequestMaintenance struct {
	// Day of week for installing updates
	Dow UpdateDBAASServiceMysqlRequestMaintenanceDow `json:"dow" validate:"required"`
	// Time for installing updates, UTC
	Time string `json:"time" validate:"required,gte=8,lte=8"`
}

// Migrate data from existing server
type UpdateDBAASServiceMysqlRequestMigration struct {
	// Database name for bootstrapping the initial connection
	Dbname string `json:"dbname,omitempty" validate:"omitempty,gte=1,lte=63"`
	// Hostname or IP address of the server where to migrate data from
	Host string `json:"host" validate:"required,gte=1,lte=255"`
	// Comma-separated list of databases, which should be ignored during migration (supported by MySQL only at the moment)
	IgnoreDbs string              `json:"ignore-dbs,omitempty" validate:"omitempty,gte=1,lte=2048"`
	Method    EnumMigrationMethod `json:"method,omitempty"`
	// Password for authentication with the server where to migrate data from
	Password string `json:"password,omitempty" validate:"omitempty,gte=1,lte=255"`
	// Port number of the server where to migrate data from
	Port int64 `json:"port" validate:"required,gte=1,lte=65535"`
	// The server where to migrate data from is secured with SSL
	SSL *bool `json:"ssl,omitempty"`
	// User name for authentication with the server where to migrate data from
	Username string `json:"username,omitempty" validate:"omitempty,gte=1,lte=255"`
}

type UpdateDBAASServiceMysqlRequest struct {
	BackupSchedule *UpdateDBAASServiceMysqlRequestBackupSchedule `json:"backup-schedule,omitempty"`
	// The minimum amount of time in seconds to keep binlog entries before deletion. This may be extended for services that require binlog entries for longer than the default for example if using the MySQL Debezium Kafka connector.
	BinlogRetentionPeriod int64 `json:"binlog-retention-period,omitempty" validate:"omitempty,gte=600,lte=86400"`
	// Allow incoming connections from CIDR address block, e.g. '10.20.0.0/16'
	IPFilter []string `json:"ip-filter,omitempty"`
	// Automatic maintenance settings
	Maintenance *UpdateDBAASServiceMysqlRequestMaintenance `json:"maintenance,omitempty"`
	// Migrate data from existing server
	Migration *UpdateDBAASServiceMysqlRequestMigration `json:"migration,omitempty"`
	// mysql.conf configuration values
	MysqlSettings JSONSchemaMysql `json:"mysql-settings,omitempty"`
	// Subscription plan
	Plan string `json:"plan,omitempty" validate:"omitempty,gte=1,lte=128"`
	// Service is protected against termination and powering off
	TerminationProtection *bool `json:"termination-protection,omitempty"`
}

// Update a DBaaS MySQL service
func (c Client) UpdateDBAASServiceMysql(ctx context.Context, name string, req UpdateDBAASServiceMysqlRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-mysql/%v", name)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceMysql: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceMysql: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceMysql: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceMysql: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-dbaas-service-mysql")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceMysql: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceMysql: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceMysql: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Initiate MySQL maintenance update
func (c Client) StartDBAASMysqlMaintenance(ctx context.Context, name string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-mysql/%v/maintenance/start", name)

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("StartDBAASMysqlMaintenance: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("StartDBAASMysqlMaintenance: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("StartDBAASMysqlMaintenance: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "start-dbaas-mysql-maintenance")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("StartDBAASMysqlMaintenance: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("StartDBAASMysqlMaintenance: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("StartDBAASMysqlMaintenance: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Stop a DBaaS MySQL migration
func (c Client) StopDBAASMysqlMigration(ctx context.Context, name string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-mysql/%v/migration/stop", name)

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("StopDBAASMysqlMigration: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("StopDBAASMysqlMigration: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("StopDBAASMysqlMigration: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "stop-dbaas-mysql-migration")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("StopDBAASMysqlMigration: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("StopDBAASMysqlMigration: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("StopDBAASMysqlMigration: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type CreateDBAASMysqlDatabaseRequest struct {
	DatabaseName DBAASDatabaseName `json:"database-name" validate:"required,gte=1,lte=40"`
}

// Create a DBaaS MySQL database
func (c Client) CreateDBAASMysqlDatabase(ctx context.Context, serviceName string, req CreateDBAASMysqlDatabaseRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-mysql/%v/database", serviceName)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASMysqlDatabase: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASMysqlDatabase: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASMysqlDatabase: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASMysqlDatabase: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-mysql-database")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASMysqlDatabase: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASMysqlDatabase: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASMysqlDatabase: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Delete a DBaaS MySQL database
func (c Client) DeleteDBAASMysqlDatabase(ctx context.Context, serviceName string, databaseName string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-mysql/%v/database/%v", serviceName, databaseName)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASMysqlDatabase: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASMysqlDatabase: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASMysqlDatabase: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-mysql-database")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASMysqlDatabase: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASMysqlDatabase: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASMysqlDatabase: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type CreateDBAASMysqlUserRequest struct {
	Authentication EnumMysqlAuthenticationPlugin `json:"authentication,omitempty"`
	Username       DBAASUserUsername             `json:"username" validate:"required,gte=1,lte=64"`
}

// Create a DBaaS MySQL user
func (c Client) CreateDBAASMysqlUser(ctx context.Context, serviceName string, req CreateDBAASMysqlUserRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-mysql/%v/user", serviceName)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASMysqlUser: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASMysqlUser: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASMysqlUser: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASMysqlUser: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-mysql-user")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASMysqlUser: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASMysqlUser: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASMysqlUser: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Delete a DBaaS MySQL user
func (c Client) DeleteDBAASMysqlUser(ctx context.Context, serviceName string, username string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-mysql/%v/user/%v", serviceName, username)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASMysqlUser: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASMysqlUser: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASMysqlUser: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-mysql-user")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASMysqlUser: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASMysqlUser: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASMysqlUser: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ResetDBAASMysqlUserPasswordRequest struct {
	Authentication EnumMysqlAuthenticationPlugin `json:"authentication,omitempty"`
	Password       DBAASUserPassword             `json:"password,omitempty" validate:"omitempty,gte=8,lte=256"`
}

// If no password is provided one will be generated automatically.
func (c Client) ResetDBAASMysqlUserPassword(ctx context.Context, serviceName string, username string, req ResetDBAASMysqlUserPasswordRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-mysql/%v/user/%v/password/reset", serviceName, username)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("ResetDBAASMysqlUserPassword: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("ResetDBAASMysqlUserPassword: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ResetDBAASMysqlUserPassword: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ResetDBAASMysqlUserPassword: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reset-dbaas-mysql-user-password")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ResetDBAASMysqlUserPassword: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ResetDBAASMysqlUserPassword: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ResetDBAASMysqlUserPassword: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Reveal the secrets of a DBaaS MySQL user
func (c Client) RevealDBAASMysqlUserPassword(ctx context.Context, serviceName string, username string) (*DBAASUserMysqlSecrets, error) {
	path := fmt.Sprintf("/dbaas-mysql/%v/user/%v/password/reveal", serviceName, username)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("RevealDBAASMysqlUserPassword: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("RevealDBAASMysqlUserPassword: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("RevealDBAASMysqlUserPassword: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reveal-dbaas-mysql-user-password")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("RevealDBAASMysqlUserPassword: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("RevealDBAASMysqlUserPassword: http response: %w", err)
	}

	bodyresp := &DBAASUserMysqlSecrets{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("RevealDBAASMysqlUserPassword: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Delete a OpenSearch service
func (c Client) DeleteDBAASServiceOpensearch(ctx context.Context, name string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-opensearch/%v", name)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceOpensearch: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceOpensearch: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceOpensearch: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-service-opensearch")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceOpensearch: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceOpensearch: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceOpensearch: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Get a DBaaS OpenSearch service
func (c Client) GetDBAASServiceOpensearch(ctx context.Context, name string) (*DBAASServiceOpensearch, error) {
	path := fmt.Sprintf("/dbaas-opensearch/%v", name)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServiceOpensearch: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceOpensearch: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceOpensearch: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-service-opensearch")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServiceOpensearch: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceOpensearch: http response: %w", err)
	}

	bodyresp := &DBAASServiceOpensearch{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceOpensearch: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type CreateDBAASServiceOpensearchRequestIndexPatternsSortingAlgorithm string

const (
	CreateDBAASServiceOpensearchRequestIndexPatternsSortingAlgorithmAlphabetical CreateDBAASServiceOpensearchRequestIndexPatternsSortingAlgorithm = "alphabetical"
	CreateDBAASServiceOpensearchRequestIndexPatternsSortingAlgorithmCreationDate CreateDBAASServiceOpensearchRequestIndexPatternsSortingAlgorithm = "creation_date"
)

type CreateDBAASServiceOpensearchRequestIndexPatterns struct {
	// Maximum number of indexes to keep
	MaxIndexCount int64 `json:"max-index-count,omitempty" validate:"omitempty,gte=0"`
	// fnmatch pattern
	Pattern string `json:"pattern,omitempty" validate:"omitempty,lte=1024"`
	// Deletion sorting algorithm
	SortingAlgorithm CreateDBAASServiceOpensearchRequestIndexPatternsSortingAlgorithm `json:"sorting-algorithm,omitempty"`
}

// Template settings for all new indexes
type CreateDBAASServiceOpensearchRequestIndexTemplate struct {
	// The maximum number of nested JSON objects that a single document can contain across all nested types. This limit helps to prevent out of memory errors when a document contains too many nested objects. Default is 10000.
	MappingNestedObjectsLimit int64 `json:"mapping-nested-objects-limit,omitempty" validate:"omitempty,gte=0,lte=100000"`
	// The number of replicas each primary shard has.
	NumberOfReplicas int64 `json:"number-of-replicas,omitempty" validate:"omitempty,gte=0,lte=29"`
	// The number of primary shards that an index should have.
	NumberOfShards int64 `json:"number-of-shards,omitempty" validate:"omitempty,gte=1,lte=1024"`
}

type CreateDBAASServiceOpensearchRequestMaintenanceDow string

const (
	CreateDBAASServiceOpensearchRequestMaintenanceDowSaturday  CreateDBAASServiceOpensearchRequestMaintenanceDow = "saturday"
	CreateDBAASServiceOpensearchRequestMaintenanceDowTuesday   CreateDBAASServiceOpensearchRequestMaintenanceDow = "tuesday"
	CreateDBAASServiceOpensearchRequestMaintenanceDowNever     CreateDBAASServiceOpensearchRequestMaintenanceDow = "never"
	CreateDBAASServiceOpensearchRequestMaintenanceDowWednesday CreateDBAASServiceOpensearchRequestMaintenanceDow = "wednesday"
	CreateDBAASServiceOpensearchRequestMaintenanceDowSunday    CreateDBAASServiceOpensearchRequestMaintenanceDow = "sunday"
	CreateDBAASServiceOpensearchRequestMaintenanceDowFriday    CreateDBAASServiceOpensearchRequestMaintenanceDow = "friday"
	CreateDBAASServiceOpensearchRequestMaintenanceDowMonday    CreateDBAASServiceOpensearchRequestMaintenanceDow = "monday"
	CreateDBAASServiceOpensearchRequestMaintenanceDowThursday  CreateDBAASServiceOpensearchRequestMaintenanceDow = "thursday"
)

// Automatic maintenance settings
type CreateDBAASServiceOpensearchRequestMaintenance struct {
	// Day of week for installing updates
	Dow CreateDBAASServiceOpensearchRequestMaintenanceDow `json:"dow" validate:"required"`
	// Time for installing updates, UTC
	Time string `json:"time" validate:"required,gte=8,lte=8"`
}

// OpenSearch Dashboards settings
type CreateDBAASServiceOpensearchRequestOpensearchDashboards struct {
	// Enable or disable OpenSearch Dashboards (default: true)
	Enabled *bool `json:"enabled,omitempty"`
	// Limits the maximum amount of memory (in MiB) the OpenSearch Dashboards process can use. This sets the max_old_space_size option of the nodejs running the OpenSearch Dashboards. Note: the memory reserved by OpenSearch Dashboards is not available for OpenSearch. (default: 128)
	MaxOldSpaceSize int64 `json:"max-old-space-size,omitempty" validate:"omitempty,gte=64,lte=1024"`
	// Timeout in milliseconds for requests made by OpenSearch Dashboards towards OpenSearch (default: 30000)
	OpensearchRequestTimeout int64 `json:"opensearch-request-timeout,omitempty" validate:"omitempty,gte=5000,lte=120000"`
}

type CreateDBAASServiceOpensearchRequest struct {
	ForkFromService DBAASServiceName `json:"fork-from-service,omitempty" validate:"omitempty,gte=0,lte=63"`
	// Allows you to create glob style patterns and set a max number of indexes matching this pattern you want to keep. Creating indexes exceeding this value will cause the oldest one to get deleted. You could for example create a pattern looking like 'logs.?' and then create index logs.1, logs.2 etc, it will delete logs.1 once you create logs.6. Do note 'logs.?' does not apply to logs.10. Note: Setting max_index_count to 0 will do nothing and the pattern gets ignored.
	IndexPatterns []CreateDBAASServiceOpensearchRequestIndexPatterns `json:"index-patterns,omitempty"`
	// Template settings for all new indexes
	IndexTemplate *CreateDBAASServiceOpensearchRequestIndexTemplate `json:"index-template,omitempty"`
	// Allow incoming connections from CIDR address block, e.g. '10.20.0.0/16'
	IPFilter []string `json:"ip-filter,omitempty"`
	// Aiven automation resets index.refresh_interval to default value for every index to be sure that indices are always visible to search. If it doesn't fit your case, you can disable this by setting up this flag to true.
	KeepIndexRefreshInterval *bool `json:"keep-index-refresh-interval,omitempty"`
	// Automatic maintenance settings
	Maintenance *CreateDBAASServiceOpensearchRequestMaintenance `json:"maintenance,omitempty"`
	// Maximum number of indexes to keep before deleting the oldest one
	MaxIndexCount int64 `json:"max-index-count,omitempty" validate:"omitempty,gte=0"`
	// OpenSearch Dashboards settings
	OpensearchDashboards *CreateDBAASServiceOpensearchRequestOpensearchDashboards `json:"opensearch-dashboards,omitempty"`
	// OpenSearch settings
	OpensearchSettings JSONSchemaOpensearch `json:"opensearch-settings,omitempty"`
	// Subscription plan
	Plan string `json:"plan" validate:"required,gte=1,lte=128"`
	// Name of a backup to recover from for services that support backup names
	RecoveryBackupName string `json:"recovery-backup-name,omitempty" validate:"omitempty,gte=1"`
	// Service is protected against termination and powering off
	TerminationProtection *bool `json:"termination-protection,omitempty"`
	// OpenSearch major version
	Version string `json:"version,omitempty" validate:"omitempty,gte=1"`
}

// Create a DBaaS OpenSearch service
func (c Client) CreateDBAASServiceOpensearch(ctx context.Context, name string, req CreateDBAASServiceOpensearchRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-opensearch/%v", name)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceOpensearch: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceOpensearch: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceOpensearch: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceOpensearch: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-service-opensearch")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceOpensearch: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceOpensearch: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceOpensearch: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type UpdateDBAASServiceOpensearchRequestIndexPatternsSortingAlgorithm string

const (
	UpdateDBAASServiceOpensearchRequestIndexPatternsSortingAlgorithmAlphabetical UpdateDBAASServiceOpensearchRequestIndexPatternsSortingAlgorithm = "alphabetical"
	UpdateDBAASServiceOpensearchRequestIndexPatternsSortingAlgorithmCreationDate UpdateDBAASServiceOpensearchRequestIndexPatternsSortingAlgorithm = "creation_date"
)

type UpdateDBAASServiceOpensearchRequestIndexPatterns struct {
	// Maximum number of indexes to keep
	MaxIndexCount int64 `json:"max-index-count,omitempty" validate:"omitempty,gte=0"`
	// fnmatch pattern
	Pattern string `json:"pattern,omitempty" validate:"omitempty,lte=1024"`
	// Deletion sorting algorithm
	SortingAlgorithm UpdateDBAASServiceOpensearchRequestIndexPatternsSortingAlgorithm `json:"sorting-algorithm,omitempty"`
}

// Template settings for all new indexes
type UpdateDBAASServiceOpensearchRequestIndexTemplate struct {
	// The maximum number of nested JSON objects that a single document can contain across all nested types. This limit helps to prevent out of memory errors when a document contains too many nested objects. Default is 10000.
	MappingNestedObjectsLimit int64 `json:"mapping-nested-objects-limit,omitempty" validate:"omitempty,gte=0,lte=100000"`
	// The number of replicas each primary shard has.
	NumberOfReplicas int64 `json:"number-of-replicas,omitempty" validate:"omitempty,gte=0,lte=29"`
	// The number of primary shards that an index should have.
	NumberOfShards int64 `json:"number-of-shards,omitempty" validate:"omitempty,gte=1,lte=1024"`
}

type UpdateDBAASServiceOpensearchRequestMaintenanceDow string

const (
	UpdateDBAASServiceOpensearchRequestMaintenanceDowSaturday  UpdateDBAASServiceOpensearchRequestMaintenanceDow = "saturday"
	UpdateDBAASServiceOpensearchRequestMaintenanceDowTuesday   UpdateDBAASServiceOpensearchRequestMaintenanceDow = "tuesday"
	UpdateDBAASServiceOpensearchRequestMaintenanceDowNever     UpdateDBAASServiceOpensearchRequestMaintenanceDow = "never"
	UpdateDBAASServiceOpensearchRequestMaintenanceDowWednesday UpdateDBAASServiceOpensearchRequestMaintenanceDow = "wednesday"
	UpdateDBAASServiceOpensearchRequestMaintenanceDowSunday    UpdateDBAASServiceOpensearchRequestMaintenanceDow = "sunday"
	UpdateDBAASServiceOpensearchRequestMaintenanceDowFriday    UpdateDBAASServiceOpensearchRequestMaintenanceDow = "friday"
	UpdateDBAASServiceOpensearchRequestMaintenanceDowMonday    UpdateDBAASServiceOpensearchRequestMaintenanceDow = "monday"
	UpdateDBAASServiceOpensearchRequestMaintenanceDowThursday  UpdateDBAASServiceOpensearchRequestMaintenanceDow = "thursday"
)

// Automatic maintenance settings
type UpdateDBAASServiceOpensearchRequestMaintenance struct {
	// Day of week for installing updates
	Dow UpdateDBAASServiceOpensearchRequestMaintenanceDow `json:"dow" validate:"required"`
	// Time for installing updates, UTC
	Time string `json:"time" validate:"required,gte=8,lte=8"`
}

// OpenSearch Dashboards settings
type UpdateDBAASServiceOpensearchRequestOpensearchDashboards struct {
	// Enable or disable OpenSearch Dashboards (default: true)
	Enabled *bool `json:"enabled,omitempty"`
	// Limits the maximum amount of memory (in MiB) the OpenSearch Dashboards process can use. This sets the max_old_space_size option of the nodejs running the OpenSearch Dashboards. Note: the memory reserved by OpenSearch Dashboards is not available for OpenSearch. (default: 128)
	MaxOldSpaceSize int64 `json:"max-old-space-size,omitempty" validate:"omitempty,gte=64,lte=1024"`
	// Timeout in milliseconds for requests made by OpenSearch Dashboards towards OpenSearch (default: 30000)
	OpensearchRequestTimeout int64 `json:"opensearch-request-timeout,omitempty" validate:"omitempty,gte=5000,lte=120000"`
}

type UpdateDBAASServiceOpensearchRequest struct {
	// Allows you to create glob style patterns and set a max number of indexes matching this pattern you want to keep. Creating indexes exceeding this value will cause the oldest one to get deleted. You could for example create a pattern looking like 'logs.?' and then create index logs.1, logs.2 etc, it will delete logs.1 once you create logs.6. Do note 'logs.?' does not apply to logs.10. Note: Setting max_index_count to 0 will do nothing and the pattern gets ignored.
	IndexPatterns []UpdateDBAASServiceOpensearchRequestIndexPatterns `json:"index-patterns,omitempty"`
	// Template settings for all new indexes
	IndexTemplate *UpdateDBAASServiceOpensearchRequestIndexTemplate `json:"index-template,omitempty"`
	// Allow incoming connections from CIDR address block, e.g. '10.20.0.0/16'
	IPFilter []string `json:"ip-filter,omitempty"`
	// Aiven automation resets index.refresh_interval to default value for every index to be sure that indices are always visible to search. If it doesn't fit your case, you can disable this by setting up this flag to true.
	KeepIndexRefreshInterval *bool `json:"keep-index-refresh-interval,omitempty"`
	// Automatic maintenance settings
	Maintenance *UpdateDBAASServiceOpensearchRequestMaintenance `json:"maintenance,omitempty"`
	// Maximum number of indexes to keep before deleting the oldest one
	MaxIndexCount int64 `json:"max-index-count,omitempty" validate:"omitempty,gte=0"`
	// OpenSearch Dashboards settings
	OpensearchDashboards *UpdateDBAASServiceOpensearchRequestOpensearchDashboards `json:"opensearch-dashboards,omitempty"`
	// OpenSearch settings
	OpensearchSettings JSONSchemaOpensearch `json:"opensearch-settings,omitempty"`
	// Subscription plan
	Plan string `json:"plan,omitempty" validate:"omitempty,gte=1,lte=128"`
	// Service is protected against termination and powering off
	TerminationProtection *bool `json:"termination-protection,omitempty"`
	// Version
	Version string `json:"version,omitempty"`
}

// Update a DBaaS OpenSearch service
func (c Client) UpdateDBAASServiceOpensearch(ctx context.Context, name string, req UpdateDBAASServiceOpensearchRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-opensearch/%v", name)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceOpensearch: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceOpensearch: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceOpensearch: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceOpensearch: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-dbaas-service-opensearch")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceOpensearch: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceOpensearch: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceOpensearch: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Get DBaaS OpenSearch ACL configuration
func (c Client) GetDBAASOpensearchAclConfig(ctx context.Context, name string) (*DBAASOpensearchAclConfig, error) {
	path := fmt.Sprintf("/dbaas-opensearch/%v/acl-config", name)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASOpensearchAclConfig: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASOpensearchAclConfig: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASOpensearchAclConfig: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-opensearch-acl-config")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASOpensearchAclConfig: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASOpensearchAclConfig: http response: %w", err)
	}

	bodyresp := &DBAASOpensearchAclConfig{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASOpensearchAclConfig: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Create a DBaaS OpenSearch ACL configuration
func (c Client) UpdateDBAASOpensearchAclConfig(ctx context.Context, name string, req DBAASOpensearchAclConfig) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-opensearch/%v/acl-config", name)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASOpensearchAclConfig: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASOpensearchAclConfig: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASOpensearchAclConfig: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASOpensearchAclConfig: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-dbaas-opensearch-acl-config")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASOpensearchAclConfig: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateDBAASOpensearchAclConfig: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateDBAASOpensearchAclConfig: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Initiate OpenSearch maintenance update
func (c Client) StartDBAASOpensearchMaintenance(ctx context.Context, name string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-opensearch/%v/maintenance/start", name)

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("StartDBAASOpensearchMaintenance: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("StartDBAASOpensearchMaintenance: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("StartDBAASOpensearchMaintenance: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "start-dbaas-opensearch-maintenance")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("StartDBAASOpensearchMaintenance: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("StartDBAASOpensearchMaintenance: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("StartDBAASOpensearchMaintenance: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type CreateDBAASOpensearchUserRequest struct {
	Username DBAASUserUsername `json:"username" validate:"required,gte=1,lte=64"`
}

// Create a DBaaS OpenSearch user
func (c Client) CreateDBAASOpensearchUser(ctx context.Context, serviceName string, req CreateDBAASOpensearchUserRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-opensearch/%v/user", serviceName)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASOpensearchUser: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASOpensearchUser: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASOpensearchUser: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASOpensearchUser: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-opensearch-user")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASOpensearchUser: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASOpensearchUser: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASOpensearchUser: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Delete a DBaaS OpenSearch user
func (c Client) DeleteDBAASOpensearchUser(ctx context.Context, serviceName string, username string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-opensearch/%v/user/%v", serviceName, username)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASOpensearchUser: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASOpensearchUser: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASOpensearchUser: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-opensearch-user")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASOpensearchUser: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASOpensearchUser: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASOpensearchUser: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ResetDBAASOpensearchUserPasswordRequest struct {
	Password DBAASUserPassword `json:"password,omitempty" validate:"omitempty,gte=8,lte=256"`
}

// If no password is provided one will be generated automatically.
func (c Client) ResetDBAASOpensearchUserPassword(ctx context.Context, serviceName string, username string, req ResetDBAASOpensearchUserPasswordRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-opensearch/%v/user/%v/password/reset", serviceName, username)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("ResetDBAASOpensearchUserPassword: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("ResetDBAASOpensearchUserPassword: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ResetDBAASOpensearchUserPassword: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ResetDBAASOpensearchUserPassword: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reset-dbaas-opensearch-user-password")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ResetDBAASOpensearchUserPassword: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ResetDBAASOpensearchUserPassword: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ResetDBAASOpensearchUserPassword: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Reveal the secrets of a DBaaS OpenSearch user
func (c Client) RevealDBAASOpensearchUserPassword(ctx context.Context, serviceName string, username string) (*DBAASUserOpensearchSecrets, error) {
	path := fmt.Sprintf("/dbaas-opensearch/%v/user/%v/password/reveal", serviceName, username)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("RevealDBAASOpensearchUserPassword: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("RevealDBAASOpensearchUserPassword: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("RevealDBAASOpensearchUserPassword: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reveal-dbaas-opensearch-user-password")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("RevealDBAASOpensearchUserPassword: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("RevealDBAASOpensearchUserPassword: http response: %w", err)
	}

	bodyresp := &DBAASUserOpensearchSecrets{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("RevealDBAASOpensearchUserPassword: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Delete a Postgres service
func (c Client) DeleteDBAASServicePG(ctx context.Context, name string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-postgres/%v", name)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASServicePG: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServicePG: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServicePG: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-service-pg")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASServicePG: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServicePG: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServicePG: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Get a DBaaS PostgreSQL service
func (c Client) GetDBAASServicePG(ctx context.Context, name string) (*DBAASServicePG, error) {
	path := fmt.Sprintf("/dbaas-postgres/%v", name)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServicePG: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASServicePG: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASServicePG: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-service-pg")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServicePG: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASServicePG: http response: %w", err)
	}

	bodyresp := &DBAASServicePG{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASServicePG: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type CreateDBAASServicePGRequestBackupSchedule struct {
	// The hour of day (in UTC) when backup for the service is started. New backup is only started if previous backup has already completed.
	BackupHour int64 `json:"backup-hour,omitempty" validate:"omitempty,gte=0,lte=23"`
	// The minute of an hour when backup for the service is started. New backup is only started if previous backup has already completed.
	BackupMinute int64 `json:"backup-minute,omitempty" validate:"omitempty,gte=0,lte=59"`
}

type CreateDBAASServicePGRequestIntegrationsType string

const (
	CreateDBAASServicePGRequestIntegrationsTypeReadReplica CreateDBAASServicePGRequestIntegrationsType = "read_replica"
)

type CreateDBAASServicePGRequestIntegrations struct {
	DestService DBAASServiceName `json:"dest-service,omitempty" validate:"omitempty,gte=0,lte=63"`
	// Integration settings
	Settings      map[string]any   `json:"settings,omitempty"`
	SourceService DBAASServiceName `json:"source-service,omitempty" validate:"omitempty,gte=0,lte=63"`
	// Integration type
	Type CreateDBAASServicePGRequestIntegrationsType `json:"type" validate:"required"`
}

type CreateDBAASServicePGRequestMaintenanceDow string

const (
	CreateDBAASServicePGRequestMaintenanceDowSaturday  CreateDBAASServicePGRequestMaintenanceDow = "saturday"
	CreateDBAASServicePGRequestMaintenanceDowTuesday   CreateDBAASServicePGRequestMaintenanceDow = "tuesday"
	CreateDBAASServicePGRequestMaintenanceDowNever     CreateDBAASServicePGRequestMaintenanceDow = "never"
	CreateDBAASServicePGRequestMaintenanceDowWednesday CreateDBAASServicePGRequestMaintenanceDow = "wednesday"
	CreateDBAASServicePGRequestMaintenanceDowSunday    CreateDBAASServicePGRequestMaintenanceDow = "sunday"
	CreateDBAASServicePGRequestMaintenanceDowFriday    CreateDBAASServicePGRequestMaintenanceDow = "friday"
	CreateDBAASServicePGRequestMaintenanceDowMonday    CreateDBAASServicePGRequestMaintenanceDow = "monday"
	CreateDBAASServicePGRequestMaintenanceDowThursday  CreateDBAASServicePGRequestMaintenanceDow = "thursday"
)

// Automatic maintenance settings
type CreateDBAASServicePGRequestMaintenance struct {
	// Day of week for installing updates
	Dow CreateDBAASServicePGRequestMaintenanceDow `json:"dow" validate:"required"`
	// Time for installing updates, UTC
	Time string `json:"time" validate:"required,gte=8,lte=8"`
}

// Migrate data from existing server
type CreateDBAASServicePGRequestMigration struct {
	// Database name for bootstrapping the initial connection
	Dbname string `json:"dbname,omitempty" validate:"omitempty,gte=1,lte=63"`
	// Hostname or IP address of the server where to migrate data from
	Host string `json:"host" validate:"required,gte=1,lte=255"`
	// Comma-separated list of databases, which should be ignored during migration (supported by MySQL only at the moment)
	IgnoreDbs string              `json:"ignore-dbs,omitempty" validate:"omitempty,gte=1,lte=2048"`
	Method    EnumMigrationMethod `json:"method,omitempty"`
	// Password for authentication with the server where to migrate data from
	Password string `json:"password,omitempty" validate:"omitempty,gte=1,lte=255"`
	// Port number of the server where to migrate data from
	Port int64 `json:"port" validate:"required,gte=1,lte=65535"`
	// The server where to migrate data from is secured with SSL
	SSL *bool `json:"ssl,omitempty"`
	// User name for authentication with the server where to migrate data from
	Username string `json:"username,omitempty" validate:"omitempty,gte=1,lte=255"`
}

type CreateDBAASServicePGRequest struct {
	// Custom password for admin user. Defaults to random string. This must be set only when a new service is being created.
	AdminPassword string `json:"admin-password,omitempty" validate:"omitempty,gte=8,lte=256"`
	// Custom username for admin user. This must be set only when a new service is being created.
	AdminUsername   string                                     `json:"admin-username,omitempty" validate:"omitempty,gte=1,lte=64"`
	BackupSchedule  *CreateDBAASServicePGRequestBackupSchedule `json:"backup-schedule,omitempty"`
	ForkFromService DBAASServiceName                           `json:"fork-from-service,omitempty" validate:"omitempty,gte=0,lte=63"`
	// Service integrations to be enabled when creating the service.
	Integrations []CreateDBAASServicePGRequestIntegrations `json:"integrations,omitempty"`
	// Allow incoming connections from CIDR address block, e.g. '10.20.0.0/16'
	IPFilter []string `json:"ip-filter,omitempty"`
	// Automatic maintenance settings
	Maintenance *CreateDBAASServicePGRequestMaintenance `json:"maintenance,omitempty"`
	// Migrate data from existing server
	Migration *CreateDBAASServicePGRequestMigration `json:"migration,omitempty"`
	// postgresql.conf configuration values
	PGSettings JSONSchemaPG `json:"pg-settings,omitempty"`
	// System-wide settings for pgbouncer.
	PgbouncerSettings *JSONSchemaPgbouncer `json:"pgbouncer-settings,omitempty"`
	// System-wide settings for pglookout.
	PglookoutSettings *JSONSchemaPglookout `json:"pglookout-settings,omitempty"`
	// Subscription plan
	Plan string `json:"plan" validate:"required,gte=1,lte=128"`
	// ISO time of a backup to recover from for services that support arbitrary times
	RecoveryBackupTime string `json:"recovery-backup-time,omitempty" validate:"omitempty,gte=1"`
	// Percentage of total RAM that the database server uses for shared memory buffers. Valid range is 20-60 (float), which corresponds to 20% - 60%. This setting adjusts the shared_buffers configuration value.
	SharedBuffersPercentage int64                        `json:"shared-buffers-percentage,omitempty" validate:"omitempty,gte=20,lte=60"`
	SynchronousReplication  EnumPGSynchronousReplication `json:"synchronous-replication,omitempty"`
	// Service is protected against termination and powering off
	TerminationProtection *bool `json:"termination-protection,omitempty"`
	// System-wide settings for the timescaledb extension
	TimescaledbSettings *JSONSchemaTimescaledb `json:"timescaledb-settings,omitempty"`
	Variant             EnumPGVariant          `json:"variant,omitempty"`
	Version             DBAASPGTargetVersions  `json:"version,omitempty"`
	// Sets the maximum amount of memory to be used by a query operation (such as a sort or hash table) before writing to temporary disk files, in MB. Default is 1MB + 0.075% of total RAM (up to 32MB).
	WorkMem int64 `json:"work-mem,omitempty" validate:"omitempty,gte=1,lte=1024"`
}

// Create a DBaaS PostgreSQL service
func (c Client) CreateDBAASServicePG(ctx context.Context, name string, req CreateDBAASServicePGRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-postgres/%v", name)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASServicePG: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASServicePG: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASServicePG: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASServicePG: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-service-pg")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASServicePG: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASServicePG: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASServicePG: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type UpdateDBAASServicePGRequestBackupSchedule struct {
	// The hour of day (in UTC) when backup for the service is started. New backup is only started if previous backup has already completed.
	BackupHour int64 `json:"backup-hour,omitempty" validate:"omitempty,gte=0,lte=23"`
	// The minute of an hour when backup for the service is started. New backup is only started if previous backup has already completed.
	BackupMinute int64 `json:"backup-minute,omitempty" validate:"omitempty,gte=0,lte=59"`
}

type UpdateDBAASServicePGRequestMaintenanceDow string

const (
	UpdateDBAASServicePGRequestMaintenanceDowSaturday  UpdateDBAASServicePGRequestMaintenanceDow = "saturday"
	UpdateDBAASServicePGRequestMaintenanceDowTuesday   UpdateDBAASServicePGRequestMaintenanceDow = "tuesday"
	UpdateDBAASServicePGRequestMaintenanceDowNever     UpdateDBAASServicePGRequestMaintenanceDow = "never"
	UpdateDBAASServicePGRequestMaintenanceDowWednesday UpdateDBAASServicePGRequestMaintenanceDow = "wednesday"
	UpdateDBAASServicePGRequestMaintenanceDowSunday    UpdateDBAASServicePGRequestMaintenanceDow = "sunday"
	UpdateDBAASServicePGRequestMaintenanceDowFriday    UpdateDBAASServicePGRequestMaintenanceDow = "friday"
	UpdateDBAASServicePGRequestMaintenanceDowMonday    UpdateDBAASServicePGRequestMaintenanceDow = "monday"
	UpdateDBAASServicePGRequestMaintenanceDowThursday  UpdateDBAASServicePGRequestMaintenanceDow = "thursday"
)

// Automatic maintenance settings
type UpdateDBAASServicePGRequestMaintenance struct {
	// Day of week for installing updates
	Dow UpdateDBAASServicePGRequestMaintenanceDow `json:"dow" validate:"required"`
	// Time for installing updates, UTC
	Time string `json:"time" validate:"required,gte=8,lte=8"`
}

// Migrate data from existing server
type UpdateDBAASServicePGRequestMigration struct {
	// Database name for bootstrapping the initial connection
	Dbname string `json:"dbname,omitempty" validate:"omitempty,gte=1,lte=63"`
	// Hostname or IP address of the server where to migrate data from
	Host string `json:"host" validate:"required,gte=1,lte=255"`
	// Comma-separated list of databases, which should be ignored during migration (supported by MySQL only at the moment)
	IgnoreDbs string              `json:"ignore-dbs,omitempty" validate:"omitempty,gte=1,lte=2048"`
	Method    EnumMigrationMethod `json:"method,omitempty"`
	// Password for authentication with the server where to migrate data from
	Password string `json:"password,omitempty" validate:"omitempty,gte=1,lte=255"`
	// Port number of the server where to migrate data from
	Port int64 `json:"port" validate:"required,gte=1,lte=65535"`
	// The server where to migrate data from is secured with SSL
	SSL *bool `json:"ssl,omitempty"`
	// User name for authentication with the server where to migrate data from
	Username string `json:"username,omitempty" validate:"omitempty,gte=1,lte=255"`
}

type UpdateDBAASServicePGRequest struct {
	BackupSchedule *UpdateDBAASServicePGRequestBackupSchedule `json:"backup-schedule,omitempty"`
	// Allow incoming connections from CIDR address block, e.g. '10.20.0.0/16'
	IPFilter []string `json:"ip-filter,omitempty"`
	// Automatic maintenance settings
	Maintenance *UpdateDBAASServicePGRequestMaintenance `json:"maintenance,omitempty"`
	// Migrate data from existing server
	Migration *UpdateDBAASServicePGRequestMigration `json:"migration,omitempty"`
	// postgresql.conf configuration values
	PGSettings JSONSchemaPG `json:"pg-settings,omitempty"`
	// System-wide settings for pgbouncer.
	PgbouncerSettings *JSONSchemaPgbouncer `json:"pgbouncer-settings,omitempty"`
	// System-wide settings for pglookout.
	PglookoutSettings *JSONSchemaPglookout `json:"pglookout-settings,omitempty"`
	// Subscription plan
	Plan string `json:"plan,omitempty" validate:"omitempty,gte=1,lte=128"`
	// Percentage of total RAM that the database server uses for shared memory buffers. Valid range is 20-60 (float), which corresponds to 20% - 60%. This setting adjusts the shared_buffers configuration value.
	SharedBuffersPercentage int64                        `json:"shared-buffers-percentage,omitempty" validate:"omitempty,gte=20,lte=60"`
	SynchronousReplication  EnumPGSynchronousReplication `json:"synchronous-replication,omitempty"`
	// Service is protected against termination and powering off
	TerminationProtection *bool `json:"termination-protection,omitempty"`
	// System-wide settings for the timescaledb extension
	TimescaledbSettings *JSONSchemaTimescaledb `json:"timescaledb-settings,omitempty"`
	Variant             EnumPGVariant          `json:"variant,omitempty"`
	// Version
	Version string `json:"version,omitempty"`
	// Sets the maximum amount of memory to be used by a query operation (such as a sort or hash table) before writing to temporary disk files, in MB. Default is 1MB + 0.075% of total RAM (up to 32MB).
	WorkMem int64 `json:"work-mem,omitempty" validate:"omitempty,gte=1,lte=1024"`
}

// Update a DBaaS PostgreSQL service
func (c Client) UpdateDBAASServicePG(ctx context.Context, name string, req UpdateDBAASServicePGRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-postgres/%v", name)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASServicePG: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASServicePG: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServicePG: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServicePG: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-dbaas-service-pg")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASServicePG: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServicePG: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServicePG: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Initiate PostgreSQL maintenance update
func (c Client) StartDBAASPGMaintenance(ctx context.Context, name string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-postgres/%v/maintenance/start", name)

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("StartDBAASPGMaintenance: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("StartDBAASPGMaintenance: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("StartDBAASPGMaintenance: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "start-dbaas-pg-maintenance")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("StartDBAASPGMaintenance: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("StartDBAASPGMaintenance: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("StartDBAASPGMaintenance: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Stop a DBaaS PostgreSQL migration
func (c Client) StopDBAASPGMigration(ctx context.Context, name string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-postgres/%v/migration/stop", name)

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("StopDBAASPGMigration: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("StopDBAASPGMigration: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("StopDBAASPGMigration: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "stop-dbaas-pg-migration")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("StopDBAASPGMigration: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("StopDBAASPGMigration: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("StopDBAASPGMigration: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type CreateDBAASPGConnectionPoolRequest struct {
	DatabaseName DBAASDatabaseName   `json:"database-name" validate:"required,gte=1,lte=40"`
	Mode         EnumPGPoolMode      `json:"mode,omitempty"`
	Name         DBAASPGPoolName     `json:"name" validate:"required,gte=1,lte=63"`
	Size         DBAASPGPoolSize     `json:"size,omitempty" validate:"omitempty,gte=1,lte=10000"`
	Username     DBAASPGPoolUsername `json:"username,omitempty" validate:"omitempty,gte=1,lte=64"`
}

// Create a DBaaS PostgreSQL connection pool
func (c Client) CreateDBAASPGConnectionPool(ctx context.Context, serviceName string, req CreateDBAASPGConnectionPoolRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-postgres/%v/connection-pool", serviceName)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASPGConnectionPool: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASPGConnectionPool: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASPGConnectionPool: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASPGConnectionPool: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-pg-connection-pool")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASPGConnectionPool: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASPGConnectionPool: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASPGConnectionPool: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Delete a DBaaS PostgreSQL connection pool
func (c Client) DeleteDBAASPGConnectionPool(ctx context.Context, serviceName string, connectionPoolName string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-postgres/%v/connection-pool/%v", serviceName, connectionPoolName)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASPGConnectionPool: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASPGConnectionPool: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASPGConnectionPool: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-pg-connection-pool")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASPGConnectionPool: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASPGConnectionPool: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASPGConnectionPool: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type UpdateDBAASPGConnectionPoolRequest struct {
	DatabaseName DBAASDatabaseName   `json:"database-name,omitempty" validate:"omitempty,gte=1,lte=40"`
	Mode         EnumPGPoolMode      `json:"mode,omitempty"`
	Size         DBAASPGPoolSize     `json:"size,omitempty" validate:"omitempty,gte=1,lte=10000"`
	Username     DBAASPGPoolUsername `json:"username,omitempty" validate:"omitempty,gte=1,lte=64"`
}

// Update a DBaaS PostgreSQL connection pool
func (c Client) UpdateDBAASPGConnectionPool(ctx context.Context, serviceName string, connectionPoolName string, req UpdateDBAASPGConnectionPoolRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-postgres/%v/connection-pool/%v", serviceName, connectionPoolName)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASPGConnectionPool: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASPGConnectionPool: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASPGConnectionPool: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASPGConnectionPool: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-dbaas-pg-connection-pool")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASPGConnectionPool: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateDBAASPGConnectionPool: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateDBAASPGConnectionPool: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type CreateDBAASPGDatabaseRequest struct {
	DatabaseName DBAASDatabaseName `json:"database-name" validate:"required,gte=1,lte=40"`
	// Default string sort order (LC_COLLATE) for PostgreSQL database
	LCCollate string `json:"lc-collate,omitempty" validate:"omitempty,lte=128"`
	// Default character classification (LC_CTYPE) for PostgreSQL database
	LCCtype string `json:"lc-ctype,omitempty" validate:"omitempty,lte=128"`
}

// Create a DBaaS Postgres database
func (c Client) CreateDBAASPGDatabase(ctx context.Context, serviceName string, req CreateDBAASPGDatabaseRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-postgres/%v/database", serviceName)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASPGDatabase: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASPGDatabase: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASPGDatabase: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASPGDatabase: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-pg-database")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASPGDatabase: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASPGDatabase: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASPGDatabase: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Delete a DBaaS Postgres database
func (c Client) DeleteDBAASPGDatabase(ctx context.Context, serviceName string, databaseName string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-postgres/%v/database/%v", serviceName, databaseName)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASPGDatabase: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASPGDatabase: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASPGDatabase: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-pg-database")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASPGDatabase: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASPGDatabase: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASPGDatabase: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type CreateDBAASPostgresUserRequest struct {
	AllowReplication *bool             `json:"allow-replication,omitempty"`
	Username         DBAASUserUsername `json:"username" validate:"required,gte=1,lte=64"`
}

// Create a DBaaS Postgres user
func (c Client) CreateDBAASPostgresUser(ctx context.Context, serviceName string, req CreateDBAASPostgresUserRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-postgres/%v/user", serviceName)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASPostgresUser: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASPostgresUser: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASPostgresUser: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASPostgresUser: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-postgres-user")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASPostgresUser: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASPostgresUser: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASPostgresUser: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Delete a DBaaS Postgres user
func (c Client) DeleteDBAASPostgresUser(ctx context.Context, serviceName string, username string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-postgres/%v/user/%v", serviceName, username)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASPostgresUser: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASPostgresUser: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASPostgresUser: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-postgres-user")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASPostgresUser: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASPostgresUser: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASPostgresUser: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type UpdateDBAASPostgresAllowReplicationRequest struct {
	AllowReplication *bool `json:"allow-replication,omitempty"`
}

// Update access control for one service user
func (c Client) UpdateDBAASPostgresAllowReplication(ctx context.Context, serviceName string, username string, req UpdateDBAASPostgresAllowReplicationRequest) (*DBAASPostgresUsers, error) {
	path := fmt.Sprintf("/dbaas-postgres/%v/user/%v/allow-replication", serviceName, username)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASPostgresAllowReplication: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASPostgresAllowReplication: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASPostgresAllowReplication: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASPostgresAllowReplication: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-dbaas-postgres-allow-replication")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASPostgresAllowReplication: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateDBAASPostgresAllowReplication: http response: %w", err)
	}

	bodyresp := &DBAASPostgresUsers{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateDBAASPostgresAllowReplication: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ResetDBAASPostgresUserPasswordRequest struct {
	Password DBAASUserPassword `json:"password,omitempty" validate:"omitempty,gte=8,lte=256"`
}

// If no password is provided one will be generated automatically.
func (c Client) ResetDBAASPostgresUserPassword(ctx context.Context, serviceName string, username string, req ResetDBAASPostgresUserPasswordRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-postgres/%v/user/%v/password/reset", serviceName, username)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("ResetDBAASPostgresUserPassword: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("ResetDBAASPostgresUserPassword: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ResetDBAASPostgresUserPassword: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ResetDBAASPostgresUserPassword: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reset-dbaas-postgres-user-password")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ResetDBAASPostgresUserPassword: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ResetDBAASPostgresUserPassword: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ResetDBAASPostgresUserPassword: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Reveal the secrets of a DBaaS Postgres user
func (c Client) RevealDBAASPostgresUserPassword(ctx context.Context, serviceName string, username string) (*DBAASUserPostgresSecrets, error) {
	path := fmt.Sprintf("/dbaas-postgres/%v/user/%v/password/reveal", serviceName, username)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("RevealDBAASPostgresUserPassword: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("RevealDBAASPostgresUserPassword: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("RevealDBAASPostgresUserPassword: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reveal-dbaas-postgres-user-password")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("RevealDBAASPostgresUserPassword: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("RevealDBAASPostgresUserPassword: http response: %w", err)
	}

	bodyresp := &DBAASUserPostgresSecrets{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("RevealDBAASPostgresUserPassword: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type CreateDBAASPGUpgradeCheckRequest struct {
	TargetVersion DBAASPGTargetVersions `json:"target-version" validate:"required"`
}

// Check whether you can upgrade Postgres service to a newer version
func (c Client) CreateDBAASPGUpgradeCheck(ctx context.Context, service string, req CreateDBAASPGUpgradeCheckRequest) (*DBAASTask, error) {
	path := fmt.Sprintf("/dbaas-postgres/%v/upgrade-check", service)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASPGUpgradeCheck: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASPGUpgradeCheck: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASPGUpgradeCheck: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASPGUpgradeCheck: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-pg-upgrade-check")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASPGUpgradeCheck: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASPGUpgradeCheck: http response: %w", err)
	}

	bodyresp := &DBAASTask{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASPGUpgradeCheck: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Delete a Redis service
func (c Client) DeleteDBAASServiceRedis(ctx context.Context, name string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-redis/%v", name)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceRedis: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceRedis: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceRedis: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-service-redis")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceRedis: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceRedis: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASServiceRedis: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Get a DBaaS Redis service
func (c Client) GetDBAASServiceRedis(ctx context.Context, name string) (*DBAASServiceRedis, error) {
	path := fmt.Sprintf("/dbaas-redis/%v", name)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServiceRedis: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceRedis: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceRedis: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-service-redis")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServiceRedis: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceRedis: http response: %w", err)
	}

	bodyresp := &DBAASServiceRedis{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceRedis: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type CreateDBAASServiceRedisRequestMaintenanceDow string

const (
	CreateDBAASServiceRedisRequestMaintenanceDowSaturday  CreateDBAASServiceRedisRequestMaintenanceDow = "saturday"
	CreateDBAASServiceRedisRequestMaintenanceDowTuesday   CreateDBAASServiceRedisRequestMaintenanceDow = "tuesday"
	CreateDBAASServiceRedisRequestMaintenanceDowNever     CreateDBAASServiceRedisRequestMaintenanceDow = "never"
	CreateDBAASServiceRedisRequestMaintenanceDowWednesday CreateDBAASServiceRedisRequestMaintenanceDow = "wednesday"
	CreateDBAASServiceRedisRequestMaintenanceDowSunday    CreateDBAASServiceRedisRequestMaintenanceDow = "sunday"
	CreateDBAASServiceRedisRequestMaintenanceDowFriday    CreateDBAASServiceRedisRequestMaintenanceDow = "friday"
	CreateDBAASServiceRedisRequestMaintenanceDowMonday    CreateDBAASServiceRedisRequestMaintenanceDow = "monday"
	CreateDBAASServiceRedisRequestMaintenanceDowThursday  CreateDBAASServiceRedisRequestMaintenanceDow = "thursday"
)

// Automatic maintenance settings
type CreateDBAASServiceRedisRequestMaintenance struct {
	// Day of week for installing updates
	Dow CreateDBAASServiceRedisRequestMaintenanceDow `json:"dow" validate:"required"`
	// Time for installing updates, UTC
	Time string `json:"time" validate:"required,gte=8,lte=8"`
}

// Migrate data from existing server
type CreateDBAASServiceRedisRequestMigration struct {
	// Database name for bootstrapping the initial connection
	Dbname string `json:"dbname,omitempty" validate:"omitempty,gte=1,lte=63"`
	// Hostname or IP address of the server where to migrate data from
	Host string `json:"host" validate:"required,gte=1,lte=255"`
	// Comma-separated list of databases, which should be ignored during migration (supported by MySQL only at the moment)
	IgnoreDbs string              `json:"ignore-dbs,omitempty" validate:"omitempty,gte=1,lte=2048"`
	Method    EnumMigrationMethod `json:"method,omitempty"`
	// Password for authentication with the server where to migrate data from
	Password string `json:"password,omitempty" validate:"omitempty,gte=1,lte=255"`
	// Port number of the server where to migrate data from
	Port int64 `json:"port" validate:"required,gte=1,lte=65535"`
	// The server where to migrate data from is secured with SSL
	SSL *bool `json:"ssl,omitempty"`
	// User name for authentication with the server where to migrate data from
	Username string `json:"username,omitempty" validate:"omitempty,gte=1,lte=255"`
}

type CreateDBAASServiceRedisRequest struct {
	ForkFromService DBAASServiceName `json:"fork-from-service,omitempty" validate:"omitempty,gte=0,lte=63"`
	// Allow incoming connections from CIDR address block, e.g. '10.20.0.0/16'
	IPFilter []string `json:"ip-filter,omitempty"`
	// Automatic maintenance settings
	Maintenance *CreateDBAASServiceRedisRequestMaintenance `json:"maintenance,omitempty"`
	// Migrate data from existing server
	Migration *CreateDBAASServiceRedisRequestMigration `json:"migration,omitempty"`
	// Subscription plan
	Plan string `json:"plan" validate:"required,gte=1,lte=128"`
	// Name of a backup to recover from for services that support backup names
	RecoveryBackupName string `json:"recovery-backup-name,omitempty" validate:"omitempty,gte=1"`
	// Redis settings
	RedisSettings *JSONSchemaRedis `json:"redis-settings,omitempty"`
	// Service is protected against termination and powering off
	TerminationProtection *bool `json:"termination-protection,omitempty"`
}

// Create a DBaaS Redis service
func (c Client) CreateDBAASServiceRedis(ctx context.Context, name string, req CreateDBAASServiceRedisRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-redis/%v", name)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceRedis: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceRedis: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceRedis: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceRedis: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-service-redis")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceRedis: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceRedis: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASServiceRedis: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type UpdateDBAASServiceRedisRequestMaintenanceDow string

const (
	UpdateDBAASServiceRedisRequestMaintenanceDowSaturday  UpdateDBAASServiceRedisRequestMaintenanceDow = "saturday"
	UpdateDBAASServiceRedisRequestMaintenanceDowTuesday   UpdateDBAASServiceRedisRequestMaintenanceDow = "tuesday"
	UpdateDBAASServiceRedisRequestMaintenanceDowNever     UpdateDBAASServiceRedisRequestMaintenanceDow = "never"
	UpdateDBAASServiceRedisRequestMaintenanceDowWednesday UpdateDBAASServiceRedisRequestMaintenanceDow = "wednesday"
	UpdateDBAASServiceRedisRequestMaintenanceDowSunday    UpdateDBAASServiceRedisRequestMaintenanceDow = "sunday"
	UpdateDBAASServiceRedisRequestMaintenanceDowFriday    UpdateDBAASServiceRedisRequestMaintenanceDow = "friday"
	UpdateDBAASServiceRedisRequestMaintenanceDowMonday    UpdateDBAASServiceRedisRequestMaintenanceDow = "monday"
	UpdateDBAASServiceRedisRequestMaintenanceDowThursday  UpdateDBAASServiceRedisRequestMaintenanceDow = "thursday"
)

// Automatic maintenance settings
type UpdateDBAASServiceRedisRequestMaintenance struct {
	// Day of week for installing updates
	Dow UpdateDBAASServiceRedisRequestMaintenanceDow `json:"dow" validate:"required"`
	// Time for installing updates, UTC
	Time string `json:"time" validate:"required,gte=8,lte=8"`
}

// Migrate data from existing server
type UpdateDBAASServiceRedisRequestMigration struct {
	// Database name for bootstrapping the initial connection
	Dbname string `json:"dbname,omitempty" validate:"omitempty,gte=1,lte=63"`
	// Hostname or IP address of the server where to migrate data from
	Host string `json:"host" validate:"required,gte=1,lte=255"`
	// Comma-separated list of databases, which should be ignored during migration (supported by MySQL only at the moment)
	IgnoreDbs string              `json:"ignore-dbs,omitempty" validate:"omitempty,gte=1,lte=2048"`
	Method    EnumMigrationMethod `json:"method,omitempty"`
	// Password for authentication with the server where to migrate data from
	Password string `json:"password,omitempty" validate:"omitempty,gte=1,lte=255"`
	// Port number of the server where to migrate data from
	Port int64 `json:"port" validate:"required,gte=1,lte=65535"`
	// The server where to migrate data from is secured with SSL
	SSL *bool `json:"ssl,omitempty"`
	// User name for authentication with the server where to migrate data from
	Username string `json:"username,omitempty" validate:"omitempty,gte=1,lte=255"`
}

type UpdateDBAASServiceRedisRequest struct {
	// Allow incoming connections from CIDR address block, e.g. '10.20.0.0/16'
	IPFilter []string `json:"ip-filter,omitempty"`
	// Automatic maintenance settings
	Maintenance *UpdateDBAASServiceRedisRequestMaintenance `json:"maintenance,omitempty"`
	// Migrate data from existing server
	Migration *UpdateDBAASServiceRedisRequestMigration `json:"migration,omitempty"`
	// Subscription plan
	Plan string `json:"plan,omitempty" validate:"omitempty,gte=1,lte=128"`
	// Redis settings
	RedisSettings *JSONSchemaRedis `json:"redis-settings,omitempty"`
	// Service is protected against termination and powering off
	TerminationProtection *bool `json:"termination-protection,omitempty"`
}

// Update a DBaaS Redis service
func (c Client) UpdateDBAASServiceRedis(ctx context.Context, name string, req UpdateDBAASServiceRedisRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-redis/%v", name)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceRedis: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceRedis: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceRedis: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceRedis: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-dbaas-service-redis")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceRedis: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceRedis: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateDBAASServiceRedis: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Initiate Redis maintenance update
func (c Client) StartDBAASRedisMaintenance(ctx context.Context, name string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-redis/%v/maintenance/start", name)

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("StartDBAASRedisMaintenance: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("StartDBAASRedisMaintenance: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("StartDBAASRedisMaintenance: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "start-dbaas-redis-maintenance")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("StartDBAASRedisMaintenance: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("StartDBAASRedisMaintenance: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("StartDBAASRedisMaintenance: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Stop a DBaaS Redis migration
func (c Client) StopDBAASRedisMigration(ctx context.Context, name string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-redis/%v/migration/stop", name)

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("StopDBAASRedisMigration: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("StopDBAASRedisMigration: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("StopDBAASRedisMigration: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "stop-dbaas-redis-migration")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("StopDBAASRedisMigration: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("StopDBAASRedisMigration: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("StopDBAASRedisMigration: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type CreateDBAASRedisUserRequest struct {
	Username DBAASUserUsername `json:"username" validate:"required,gte=1,lte=64"`
}

// Create a DBaaS Redis user
func (c Client) CreateDBAASRedisUser(ctx context.Context, serviceName string, req CreateDBAASRedisUserRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-redis/%v/user", serviceName)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASRedisUser: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASRedisUser: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASRedisUser: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASRedisUser: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-redis-user")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASRedisUser: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASRedisUser: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASRedisUser: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Delete a DBaaS Redis user
func (c Client) DeleteDBAASRedisUser(ctx context.Context, serviceName string, username string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-redis/%v/user/%v", serviceName, username)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASRedisUser: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASRedisUser: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASRedisUser: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-redis-user")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASRedisUser: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASRedisUser: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASRedisUser: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ResetDBAASRedisUserPasswordRequest struct {
	Password DBAASUserPassword `json:"password,omitempty" validate:"omitempty,gte=8,lte=256"`
}

// If no password is provided one will be generated automatically.
func (c Client) ResetDBAASRedisUserPassword(ctx context.Context, serviceName string, username string, req ResetDBAASRedisUserPasswordRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-redis/%v/user/%v/password/reset", serviceName, username)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("ResetDBAASRedisUserPassword: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("ResetDBAASRedisUserPassword: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ResetDBAASRedisUserPassword: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ResetDBAASRedisUserPassword: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reset-dbaas-redis-user-password")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ResetDBAASRedisUserPassword: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ResetDBAASRedisUserPassword: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ResetDBAASRedisUserPassword: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Reveal the secrets of a DBaaS Redis user
func (c Client) RevealDBAASRedisUserPassword(ctx context.Context, serviceName string, username string) (*DBAASUserRedisSecrets, error) {
	path := fmt.Sprintf("/dbaas-redis/%v/user/%v/password/reveal", serviceName, username)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("RevealDBAASRedisUserPassword: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("RevealDBAASRedisUserPassword: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("RevealDBAASRedisUserPassword: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reveal-dbaas-redis-user-password")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("RevealDBAASRedisUserPassword: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("RevealDBAASRedisUserPassword: http response: %w", err)
	}

	bodyresp := &DBAASUserRedisSecrets{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("RevealDBAASRedisUserPassword: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ListDBAASServicesResponse struct {
	DBAASServices []DBAASServiceCommon `json:"dbaas-services,omitempty"`
}

// FindDBAASServiceCommon attempts to find an DBAASServiceCommon by name.
func (l ListDBAASServicesResponse) FindDBAASServiceCommon(name string) (DBAASServiceCommon, error) {
	for i, elem := range l.DBAASServices {
		if string(elem.Name) == name {
			return l.DBAASServices[i], nil
		}
	}

	return DBAASServiceCommon{}, fmt.Errorf("%q not found in ListDBAASServicesResponse: %w", name, ErrNotFound)
}

// List DBaaS services
func (c Client) ListDBAASServices(ctx context.Context) (*ListDBAASServicesResponse, error) {
	path := "/dbaas-service"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListDBAASServices: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListDBAASServices: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListDBAASServices: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-dbaas-services")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListDBAASServices: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListDBAASServices: http response: %w", err)
	}

	bodyresp := &ListDBAASServicesResponse{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListDBAASServices: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type GetDBAASServiceLogsRequest struct {
	// How many log entries to receive at most, up to 500 (default: 100)
	Limit int64 `json:"limit,omitempty" validate:"omitempty,gte=1,lte=500"`
	// Opaque offset identifier
	Offset    string        `json:"offset,omitempty"`
	SortOrder EnumSortOrder `json:"sort-order,omitempty"`
}

// Get logs of DBaaS service
func (c Client) GetDBAASServiceLogs(ctx context.Context, serviceName string, req GetDBAASServiceLogsRequest) (*DBAASServiceLogs, error) {
	path := fmt.Sprintf("/dbaas-service-logs/%v", serviceName)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServiceLogs: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServiceLogs: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceLogs: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceLogs: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-service-logs")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServiceLogs: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceLogs: http response: %w", err)
	}

	bodyresp := &DBAASServiceLogs{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceLogs: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type GetDBAASServiceMetricsResponse struct {
	Metrics map[string]any `json:"metrics,omitempty"`
}

type GetDBAASServiceMetricsRequestPeriod string

const (
	GetDBAASServiceMetricsRequestPeriodHour  GetDBAASServiceMetricsRequestPeriod = "hour"
	GetDBAASServiceMetricsRequestPeriodWeek  GetDBAASServiceMetricsRequestPeriod = "week"
	GetDBAASServiceMetricsRequestPeriodYear  GetDBAASServiceMetricsRequestPeriod = "year"
	GetDBAASServiceMetricsRequestPeriodMonth GetDBAASServiceMetricsRequestPeriod = "month"
	GetDBAASServiceMetricsRequestPeriodDay   GetDBAASServiceMetricsRequestPeriod = "day"
)

type GetDBAASServiceMetricsRequest struct {
	// Metrics time period (default: hour)
	Period GetDBAASServiceMetricsRequestPeriod `json:"period,omitempty"`
}

// Get metrics of DBaaS service
func (c Client) GetDBAASServiceMetrics(ctx context.Context, serviceName string, req GetDBAASServiceMetricsRequest) (*GetDBAASServiceMetricsResponse, error) {
	path := fmt.Sprintf("/dbaas-service-metrics/%v", serviceName)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServiceMetrics: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServiceMetrics: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceMetrics: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceMetrics: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-service-metrics")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServiceMetrics: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceMetrics: http response: %w", err)
	}

	bodyresp := &GetDBAASServiceMetricsResponse{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceMetrics: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ListDBAASServiceTypesResponse struct {
	DBAASServiceTypes []DBAASServiceType `json:"dbaas-service-types,omitempty"`
}

// FindDBAASServiceType attempts to find an DBAASServiceType by name.
func (l ListDBAASServiceTypesResponse) FindDBAASServiceType(name string) (DBAASServiceType, error) {
	for i, elem := range l.DBAASServiceTypes {
		if string(elem.Name) == name {
			return l.DBAASServiceTypes[i], nil
		}
	}

	return DBAASServiceType{}, fmt.Errorf("%q not found in ListDBAASServiceTypesResponse: %w", name, ErrNotFound)
}

// List available service types for DBaaS
func (c Client) ListDBAASServiceTypes(ctx context.Context) (*ListDBAASServiceTypesResponse, error) {
	path := "/dbaas-service-type"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListDBAASServiceTypes: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListDBAASServiceTypes: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListDBAASServiceTypes: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-dbaas-service-types")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListDBAASServiceTypes: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListDBAASServiceTypes: http response: %w", err)
	}

	bodyresp := &ListDBAASServiceTypesResponse{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListDBAASServiceTypes: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Get a DBaaS service type
func (c Client) GetDBAASServiceType(ctx context.Context, serviceTypeName string) (*DBAASServiceType, error) {
	path := fmt.Sprintf("/dbaas-service-type/%v", serviceTypeName)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServiceType: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceType: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceType: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-service-type")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASServiceType: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceType: http response: %w", err)
	}

	bodyresp := &DBAASServiceType{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASServiceType: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Delete a DBaaS service
func (c Client) DeleteDBAASService(ctx context.Context, name string) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-service/%v", name)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASService: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASService: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDBAASService: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dbaas-service")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDBAASService: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDBAASService: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDBAASService: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Grafana configuration values
type GetDBAASSettingsGrafanaResponseSettingsGrafana struct {
	AdditionalProperties *bool          `json:"additionalProperties,omitempty"`
	Properties           map[string]any `json:"properties,omitempty"`
	Title                string         `json:"title,omitempty"`
	Type                 string         `json:"type,omitempty"`
}

type GetDBAASSettingsGrafanaResponseSettings struct {
	// Grafana configuration values
	Grafana *GetDBAASSettingsGrafanaResponseSettingsGrafana `json:"grafana,omitempty"`
}

type GetDBAASSettingsGrafanaResponse struct {
	Settings *GetDBAASSettingsGrafanaResponseSettings `json:"settings,omitempty"`
}

// Get DBaaS Grafana settings
func (c Client) GetDBAASSettingsGrafana(ctx context.Context) (*GetDBAASSettingsGrafanaResponse, error) {
	path := "/dbaas-settings-grafana"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsGrafana: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsGrafana: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsGrafana: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-settings-grafana")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsGrafana: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsGrafana: http response: %w", err)
	}

	bodyresp := &GetDBAASSettingsGrafanaResponse{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsGrafana: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Kafka broker configuration values
type GetDBAASSettingsKafkaResponseSettingsKafka struct {
	AdditionalProperties *bool          `json:"additionalProperties,omitempty"`
	Properties           map[string]any `json:"properties,omitempty"`
	Title                string         `json:"title,omitempty"`
	Type                 string         `json:"type,omitempty"`
}

// Kafka Connect configuration values
type GetDBAASSettingsKafkaResponseSettingsKafkaConnect struct {
	AdditionalProperties *bool          `json:"additionalProperties,omitempty"`
	Properties           map[string]any `json:"properties,omitempty"`
	Title                string         `json:"title,omitempty"`
	Type                 string         `json:"type,omitempty"`
}

// Kafka REST configuration
type GetDBAASSettingsKafkaResponseSettingsKafkaRest struct {
	AdditionalProperties *bool          `json:"additionalProperties,omitempty"`
	Properties           map[string]any `json:"properties,omitempty"`
	Title                string         `json:"title,omitempty"`
	Type                 string         `json:"type,omitempty"`
}

// Schema Registry configuration
type GetDBAASSettingsKafkaResponseSettingsSchemaRegistry struct {
	AdditionalProperties *bool          `json:"additionalProperties,omitempty"`
	Properties           map[string]any `json:"properties,omitempty"`
	Title                string         `json:"title,omitempty"`
	Type                 string         `json:"type,omitempty"`
}

type GetDBAASSettingsKafkaResponseSettings struct {
	// Kafka broker configuration values
	Kafka *GetDBAASSettingsKafkaResponseSettingsKafka `json:"kafka,omitempty"`
	// Kafka Connect configuration values
	KafkaConnect *GetDBAASSettingsKafkaResponseSettingsKafkaConnect `json:"kafka-connect,omitempty"`
	// Kafka REST configuration
	KafkaRest *GetDBAASSettingsKafkaResponseSettingsKafkaRest `json:"kafka-rest,omitempty"`
	// Schema Registry configuration
	SchemaRegistry *GetDBAASSettingsKafkaResponseSettingsSchemaRegistry `json:"schema-registry,omitempty"`
}

type GetDBAASSettingsKafkaResponse struct {
	Settings *GetDBAASSettingsKafkaResponseSettings `json:"settings,omitempty"`
}

// Get DBaaS Kafka settings
func (c Client) GetDBAASSettingsKafka(ctx context.Context) (*GetDBAASSettingsKafkaResponse, error) {
	path := "/dbaas-settings-kafka"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsKafka: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsKafka: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsKafka: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-settings-kafka")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsKafka: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsKafka: http response: %w", err)
	}

	bodyresp := &GetDBAASSettingsKafkaResponse{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsKafka: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// mysql.conf configuration values
type GetDBAASSettingsMysqlResponseSettingsMysql struct {
	AdditionalProperties *bool          `json:"additionalProperties,omitempty"`
	Properties           map[string]any `json:"properties,omitempty"`
	Title                string         `json:"title,omitempty"`
	Type                 string         `json:"type,omitempty"`
}

type GetDBAASSettingsMysqlResponseSettings struct {
	// mysql.conf configuration values
	Mysql *GetDBAASSettingsMysqlResponseSettingsMysql `json:"mysql,omitempty"`
}

type GetDBAASSettingsMysqlResponse struct {
	Settings *GetDBAASSettingsMysqlResponseSettings `json:"settings,omitempty"`
}

// Get DBaaS MySQL settings
func (c Client) GetDBAASSettingsMysql(ctx context.Context) (*GetDBAASSettingsMysqlResponse, error) {
	path := "/dbaas-settings-mysql"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsMysql: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsMysql: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsMysql: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-settings-mysql")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsMysql: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsMysql: http response: %w", err)
	}

	bodyresp := &GetDBAASSettingsMysqlResponse{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsMysql: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// OpenSearch configuration values
type GetDBAASSettingsOpensearchResponseSettingsOpensearch struct {
	AdditionalProperties *bool          `json:"additionalProperties,omitempty"`
	Properties           map[string]any `json:"properties,omitempty"`
	Title                string         `json:"title,omitempty"`
	Type                 string         `json:"type,omitempty"`
}

type GetDBAASSettingsOpensearchResponseSettings struct {
	// OpenSearch configuration values
	Opensearch *GetDBAASSettingsOpensearchResponseSettingsOpensearch `json:"opensearch,omitempty"`
}

type GetDBAASSettingsOpensearchResponse struct {
	Settings *GetDBAASSettingsOpensearchResponseSettings `json:"settings,omitempty"`
}

// Get DBaaS OpenSearch settings
func (c Client) GetDBAASSettingsOpensearch(ctx context.Context) (*GetDBAASSettingsOpensearchResponse, error) {
	path := "/dbaas-settings-opensearch"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsOpensearch: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsOpensearch: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsOpensearch: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-settings-opensearch")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsOpensearch: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsOpensearch: http response: %w", err)
	}

	bodyresp := &GetDBAASSettingsOpensearchResponse{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsOpensearch: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// postgresql.conf configuration values
type GetDBAASSettingsPGResponseSettingsPG struct {
	AdditionalProperties *bool          `json:"additionalProperties,omitempty"`
	Properties           map[string]any `json:"properties,omitempty"`
	Title                string         `json:"title,omitempty"`
	Type                 string         `json:"type,omitempty"`
}

// PGBouncer connection pooling settings
type GetDBAASSettingsPGResponseSettingsPgbouncer struct {
	AdditionalProperties *bool          `json:"additionalProperties,omitempty"`
	Properties           map[string]any `json:"properties,omitempty"`
	Title                string         `json:"title,omitempty"`
	Type                 string         `json:"type,omitempty"`
}

// PGLookout settings
type GetDBAASSettingsPGResponseSettingsPglookout struct {
	AdditionalProperties *bool          `json:"additionalProperties,omitempty"`
	Properties           map[string]any `json:"properties,omitempty"`
	Title                string         `json:"title,omitempty"`
	Type                 string         `json:"type,omitempty"`
}

// TimescaleDB extension configuration values
type GetDBAASSettingsPGResponseSettingsTimescaledb struct {
	AdditionalProperties *bool          `json:"additionalProperties,omitempty"`
	Properties           map[string]any `json:"properties,omitempty"`
	Title                string         `json:"title,omitempty"`
	Type                 string         `json:"type,omitempty"`
}

type GetDBAASSettingsPGResponseSettings struct {
	// postgresql.conf configuration values
	PG *GetDBAASSettingsPGResponseSettingsPG `json:"pg,omitempty"`
	// PGBouncer connection pooling settings
	Pgbouncer *GetDBAASSettingsPGResponseSettingsPgbouncer `json:"pgbouncer,omitempty"`
	// PGLookout settings
	Pglookout *GetDBAASSettingsPGResponseSettingsPglookout `json:"pglookout,omitempty"`
	// TimescaleDB extension configuration values
	Timescaledb *GetDBAASSettingsPGResponseSettingsTimescaledb `json:"timescaledb,omitempty"`
}

type GetDBAASSettingsPGResponse struct {
	Settings *GetDBAASSettingsPGResponseSettings `json:"settings,omitempty"`
}

// Get DBaaS PostgreSQL settings
func (c Client) GetDBAASSettingsPG(ctx context.Context) (*GetDBAASSettingsPGResponse, error) {
	path := "/dbaas-settings-pg"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsPG: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsPG: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsPG: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-settings-pg")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsPG: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsPG: http response: %w", err)
	}

	bodyresp := &GetDBAASSettingsPGResponse{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsPG: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Redis configuration values
type GetDBAASSettingsRedisResponseSettingsRedis struct {
	AdditionalProperties *bool          `json:"additionalProperties,omitempty"`
	Properties           map[string]any `json:"properties,omitempty"`
	Title                string         `json:"title,omitempty"`
	Type                 string         `json:"type,omitempty"`
}

type GetDBAASSettingsRedisResponseSettings struct {
	// Redis configuration values
	Redis *GetDBAASSettingsRedisResponseSettingsRedis `json:"redis,omitempty"`
}

type GetDBAASSettingsRedisResponse struct {
	Settings *GetDBAASSettingsRedisResponseSettings `json:"settings,omitempty"`
}

// Returns the default settings for Redis.
func (c Client) GetDBAASSettingsRedis(ctx context.Context) (*GetDBAASSettingsRedisResponse, error) {
	path := "/dbaas-settings-redis"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsRedis: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsRedis: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsRedis: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-settings-redis")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsRedis: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsRedis: http response: %w", err)
	}

	bodyresp := &GetDBAASSettingsRedisResponse{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASSettingsRedis: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type CreateDBAASTaskMigrationCheckRequest struct {
	// Comma-separated list of databases, which should be ignored during migration (supported by MySQL only at the moment)
	IgnoreDbs string              `json:"ignore-dbs,omitempty" validate:"omitempty,gte=1,lte=2048"`
	Method    EnumMigrationMethod `json:"method,omitempty"`
	// Service URI of the source MySQL or PostgreSQL database with admin credentials.
	SourceServiceURI string `json:"source-service-uri" validate:"required,gte=1,lte=512"`
}

// Create a DBaaS task to check migration
func (c Client) CreateDBAASTaskMigrationCheck(ctx context.Context, service string, req CreateDBAASTaskMigrationCheckRequest) (*Operation, error) {
	path := fmt.Sprintf("/dbaas-task-migration-check/%v", service)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASTaskMigrationCheck: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASTaskMigrationCheck: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDBAASTaskMigrationCheck: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDBAASTaskMigrationCheck: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dbaas-task-migration-check")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDBAASTaskMigrationCheck: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDBAASTaskMigrationCheck: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDBAASTaskMigrationCheck: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Get a DBaaS task
func (c Client) GetDBAASTask(ctx context.Context, service string, id UUID) (*DBAASTask, error) {
	path := fmt.Sprintf("/dbaas-task/%v/%v", service, id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASTask: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDBAASTask: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDBAASTask: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dbaas-task")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDBAASTask: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDBAASTask: http response: %w", err)
	}

	bodyresp := &DBAASTask{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDBAASTask: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ListDeployTargetsResponse struct {
	DeployTargets []DeployTarget `json:"deploy-targets,omitempty"`
}

// FindDeployTarget attempts to find an DeployTarget by nameOrID.
func (l ListDeployTargetsResponse) FindDeployTarget(nameOrID string) (DeployTarget, error) {
	for i, elem := range l.DeployTargets {
		if string(elem.Name) == nameOrID || elem.ID.String() == nameOrID {
			return l.DeployTargets[i], nil
		}
	}

	return DeployTarget{}, fmt.Errorf("%q not found in ListDeployTargetsResponse: %w", nameOrID, ErrNotFound)
}

// List Deploy Targets
func (c Client) ListDeployTargets(ctx context.Context) (*ListDeployTargetsResponse, error) {
	path := "/deploy-target"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListDeployTargets: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListDeployTargets: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListDeployTargets: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-deploy-targets")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListDeployTargets: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListDeployTargets: http response: %w", err)
	}

	bodyresp := &ListDeployTargetsResponse{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListDeployTargets: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve Deploy Target details
func (c Client) GetDeployTarget(ctx context.Context, id UUID) (*DeployTarget, error) {
	path := fmt.Sprintf("/deploy-target/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDeployTarget: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDeployTarget: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDeployTarget: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-deploy-target")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDeployTarget: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDeployTarget: http response: %w", err)
	}

	bodyresp := &DeployTarget{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDeployTarget: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ListDNSDomainsResponse struct {
	DNSDomains []DNSDomain `json:"dns-domains,omitempty"`
}

// FindDNSDomain attempts to find an DNSDomain by ID.
func (l ListDNSDomainsResponse) FindDNSDomain(ID string) (DNSDomain, error) {
	for i, elem := range l.DNSDomains {
		if elem.ID.String() == ID {
			return l.DNSDomains[i], nil
		}
	}

	return DNSDomain{}, fmt.Errorf("%q not found in ListDNSDomainsResponse: %w", ID, ErrNotFound)
}

// List DNS domains
func (c Client) ListDNSDomains(ctx context.Context) (*ListDNSDomainsResponse, error) {
	path := "/dns-domain"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListDNSDomains: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListDNSDomains: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListDNSDomains: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-dns-domains")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListDNSDomains: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListDNSDomains: http response: %w", err)
	}

	bodyresp := &ListDNSDomainsResponse{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListDNSDomains: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// DNS Domain
type CreateDNSDomainRequest struct {
	// Domain name
	UnicodeName string `json:"unicode-name,omitempty"`
}

// Create DNS domain
func (c Client) CreateDNSDomain(ctx context.Context, req CreateDNSDomainRequest) (*DNSDomain, error) {
	path := "/dns-domain"

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDNSDomain: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDNSDomain: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDNSDomain: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDNSDomain: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dns-domain")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDNSDomain: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDNSDomain: http response: %w", err)
	}

	bodyresp := &DNSDomain{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDNSDomain: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ListDNSDomainRecordsResponse struct {
	DNSDomainRecords []DNSDomainRecord `json:"dns-domain-records,omitempty"`
}

// FindDNSDomainRecord attempts to find an DNSDomainRecord by nameOrID.
func (l ListDNSDomainRecordsResponse) FindDNSDomainRecord(nameOrID string) (DNSDomainRecord, error) {
	for i, elem := range l.DNSDomainRecords {
		if string(elem.Name) == nameOrID || elem.ID.String() == nameOrID {
			return l.DNSDomainRecords[i], nil
		}
	}

	return DNSDomainRecord{}, fmt.Errorf("%q not found in ListDNSDomainRecordsResponse: %w", nameOrID, ErrNotFound)
}

// List DNS domain records
func (c Client) ListDNSDomainRecords(ctx context.Context, domainID UUID) (*ListDNSDomainRecordsResponse, error) {
	path := fmt.Sprintf("/dns-domain/%v/record", domainID)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListDNSDomainRecords: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListDNSDomainRecords: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListDNSDomainRecords: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-dns-domain-records")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListDNSDomainRecords: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListDNSDomainRecords: http response: %w", err)
	}

	bodyresp := &ListDNSDomainRecordsResponse{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListDNSDomainRecords: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type CreateDNSDomainRecordRequestType string

const (
	CreateDNSDomainRecordRequestTypeNS    CreateDNSDomainRecordRequestType = "NS"
	CreateDNSDomainRecordRequestTypeCAA   CreateDNSDomainRecordRequestType = "CAA"
	CreateDNSDomainRecordRequestTypeNAPTR CreateDNSDomainRecordRequestType = "NAPTR"
	CreateDNSDomainRecordRequestTypePOOL  CreateDNSDomainRecordRequestType = "POOL"
	CreateDNSDomainRecordRequestTypeA     CreateDNSDomainRecordRequestType = "A"
	CreateDNSDomainRecordRequestTypeHINFO CreateDNSDomainRecordRequestType = "HINFO"
	CreateDNSDomainRecordRequestTypeCNAME CreateDNSDomainRecordRequestType = "CNAME"
	CreateDNSDomainRecordRequestTypeSSHFP CreateDNSDomainRecordRequestType = "SSHFP"
	CreateDNSDomainRecordRequestTypeSRV   CreateDNSDomainRecordRequestType = "SRV"
	CreateDNSDomainRecordRequestTypeAAAA  CreateDNSDomainRecordRequestType = "AAAA"
	CreateDNSDomainRecordRequestTypeMX    CreateDNSDomainRecordRequestType = "MX"
	CreateDNSDomainRecordRequestTypeTXT   CreateDNSDomainRecordRequestType = "TXT"
	CreateDNSDomainRecordRequestTypeALIAS CreateDNSDomainRecordRequestType = "ALIAS"
	CreateDNSDomainRecordRequestTypeURL   CreateDNSDomainRecordRequestType = "URL"
	CreateDNSDomainRecordRequestTypeSPF   CreateDNSDomainRecordRequestType = "SPF"
)

type CreateDNSDomainRecordRequest struct {
	// DNS domain record content
	Content string `json:"content" validate:"required"`
	// DNS domain record name
	Name string `json:"name" validate:"required"`
	// DNS domain record priority
	Priority int64 `json:"priority,omitempty" validate:"omitempty,gte=0"`
	// DNS domain record TTL
	Ttl int64 `json:"ttl,omitempty" validate:"omitempty,gte=0"`
	// DNS domain record type
	Type CreateDNSDomainRecordRequestType `json:"type" validate:"required"`
}

// Create DNS domain record
func (c Client) CreateDNSDomainRecord(ctx context.Context, domainID UUID, req CreateDNSDomainRecordRequest) (*Operation, error) {
	path := fmt.Sprintf("/dns-domain/%v/record", domainID)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateDNSDomainRecord: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateDNSDomainRecord: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateDNSDomainRecord: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateDNSDomainRecord: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-dns-domain-record")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateDNSDomainRecord: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateDNSDomainRecord: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateDNSDomainRecord: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Delete DNS domain record
func (c Client) DeleteDNSDomainRecord(ctx context.Context, domainID UUID, recordID UUID) (*Operation, error) {
	path := fmt.Sprintf("/dns-domain/%v/record/%v", domainID, recordID)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDNSDomainRecord: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDNSDomainRecord: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDNSDomainRecord: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dns-domain-record")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDNSDomainRecord: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDNSDomainRecord: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDNSDomainRecord: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve DNS domain record details
func (c Client) GetDNSDomainRecord(ctx context.Context, domainID UUID, recordID UUID) (*DNSDomainRecord, error) {
	path := fmt.Sprintf("/dns-domain/%v/record/%v", domainID, recordID)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDNSDomainRecord: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDNSDomainRecord: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDNSDomainRecord: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dns-domain-record")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDNSDomainRecord: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDNSDomainRecord: http response: %w", err)
	}

	bodyresp := &DNSDomainRecord{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDNSDomainRecord: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type UpdateDNSDomainRecordRequest struct {
	// DNS domain record content
	Content string `json:"content,omitempty"`
	// DNS domain record name
	Name string `json:"name,omitempty"`
	// DNS domain record priority
	Priority int64 `json:"priority,omitempty" validate:"omitempty,gt=0"`
	// DNS domain record TTL
	Ttl int64 `json:"ttl,omitempty" validate:"omitempty,gt=0"`
}

// Update DNS domain record
func (c Client) UpdateDNSDomainRecord(ctx context.Context, domainID UUID, recordID UUID, req UpdateDNSDomainRecordRequest) (*Operation, error) {
	path := fmt.Sprintf("/dns-domain/%v/record/%v", domainID, recordID)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateDNSDomainRecord: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateDNSDomainRecord: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateDNSDomainRecord: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateDNSDomainRecord: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-dns-domain-record")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateDNSDomainRecord: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateDNSDomainRecord: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateDNSDomainRecord: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Delete DNS Domain
func (c Client) DeleteDNSDomain(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/dns-domain/%v", id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteDNSDomain: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteDNSDomain: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteDNSDomain: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-dns-domain")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteDNSDomain: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteDNSDomain: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteDNSDomain: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve DNS domain details
func (c Client) GetDNSDomain(ctx context.Context, id UUID) (*DNSDomain, error) {
	path := fmt.Sprintf("/dns-domain/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDNSDomain: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDNSDomain: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDNSDomain: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dns-domain")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDNSDomain: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDNSDomain: http response: %w", err)
	}

	bodyresp := &DNSDomain{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDNSDomain: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type GetDNSDomainZoneFileResponse struct {
	ZoneFile string `json:"zone-file,omitempty"`
}

// Retrieve DNS domain zone file
func (c Client) GetDNSDomainZoneFile(ctx context.Context, id UUID) (*GetDNSDomainZoneFileResponse, error) {
	path := fmt.Sprintf("/dns-domain/%v/zone", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetDNSDomainZoneFile: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetDNSDomainZoneFile: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetDNSDomainZoneFile: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-dns-domain-zone-file")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetDNSDomainZoneFile: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetDNSDomainZoneFile: http response: %w", err)
	}

	bodyresp := &GetDNSDomainZoneFileResponse{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetDNSDomainZoneFile: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ListElasticIPSResponse struct {
	ElasticIPS []ElasticIP `json:"elastic-ips,omitempty"`
}

// FindElasticIP attempts to find an ElasticIP by ID.
func (l ListElasticIPSResponse) FindElasticIP(ID string) (ElasticIP, error) {
	for i, elem := range l.ElasticIPS {
		if elem.ID.String() == ID {
			return l.ElasticIPS[i], nil
		}
	}

	return ElasticIP{}, fmt.Errorf("%q not found in ListElasticIPSResponse: %w", ID, ErrNotFound)
}

// List Elastic IPs
func (c Client) ListElasticIPS(ctx context.Context) (*ListElasticIPSResponse, error) {
	path := "/elastic-ip"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListElasticIPS: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListElasticIPS: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListElasticIPS: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-elastic-ips")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListElasticIPS: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListElasticIPS: http response: %w", err)
	}

	bodyresp := &ListElasticIPSResponse{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListElasticIPS: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type CreateElasticIPRequestAddressfamily string

const (
	CreateElasticIPRequestAddressfamilyInet4 CreateElasticIPRequestAddressfamily = "inet4"
	CreateElasticIPRequestAddressfamilyInet6 CreateElasticIPRequestAddressfamily = "inet6"
)

type CreateElasticIPRequest struct {
	// Elastic IP address family (default: :inet4)
	Addressfamily CreateElasticIPRequestAddressfamily `json:"addressfamily,omitempty"`
	// Elastic IP description
	Description string `json:"description,omitempty" validate:"omitempty,lte=255"`
	// Elastic IP address healthcheck
	Healthcheck *ElasticIPHealthcheck `json:"healthcheck,omitempty"`
	Labels      Labels                `json:"labels,omitempty"`
}

// Create an Elastic IP
func (c Client) CreateElasticIP(ctx context.Context, req CreateElasticIPRequest) (*Operation, error) {
	path := "/elastic-ip"

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateElasticIP: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateElasticIP: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateElasticIP: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateElasticIP: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-elastic-ip")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateElasticIP: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateElasticIP: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateElasticIP: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Delete an Elastic IP
func (c Client) DeleteElasticIP(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/elastic-ip/%v", id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteElasticIP: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteElasticIP: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteElasticIP: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-elastic-ip")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteElasticIP: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteElasticIP: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteElasticIP: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve Elastic IP details
func (c Client) GetElasticIP(ctx context.Context, id UUID) (*ElasticIP, error) {
	path := fmt.Sprintf("/elastic-ip/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetElasticIP: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetElasticIP: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetElasticIP: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-elastic-ip")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetElasticIP: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetElasticIP: http response: %w", err)
	}

	bodyresp := &ElasticIP{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetElasticIP: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type UpdateElasticIPRequest struct {
	// Elastic IP description
	Description string `json:"description,omitempty" validate:"omitempty,lte=255"`
	// Elastic IP address healthcheck
	Healthcheck *ElasticIPHealthcheck `json:"healthcheck,omitempty"`
	Labels      Labels                `json:"labels,omitempty"`
}

// Update an Elastic IP
func (c Client) UpdateElasticIP(ctx context.Context, id UUID, req UpdateElasticIPRequest) (*Operation, error) {
	path := fmt.Sprintf("/elastic-ip/%v", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateElasticIP: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateElasticIP: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateElasticIP: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateElasticIP: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-elastic-ip")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateElasticIP: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateElasticIP: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateElasticIP: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ResetElasticIPFieldField string

const (
	ResetElasticIPFieldFieldDescription ResetElasticIPFieldField = "description"
)

// Reset an Elastic IP field to its default value
func (c Client) ResetElasticIPField(ctx context.Context, id UUID, field ResetElasticIPFieldField) (*Operation, error) {
	path := fmt.Sprintf("/elastic-ip/%v/%v", id, field)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ResetElasticIPField: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ResetElasticIPField: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ResetElasticIPField: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reset-elastic-ip-field")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ResetElasticIPField: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ResetElasticIPField: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ResetElasticIPField: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type AttachInstanceToElasticIPRequest struct {
	// Target Instance
	Instance *InstanceTarget `json:"instance" validate:"required"`
}

// Attach a Compute instance to an Elastic IP
func (c Client) AttachInstanceToElasticIP(ctx context.Context, id UUID, req AttachInstanceToElasticIPRequest) (*Operation, error) {
	path := fmt.Sprintf("/elastic-ip/%v:attach", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("AttachInstanceToElasticIP: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("AttachInstanceToElasticIP: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("AttachInstanceToElasticIP: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("AttachInstanceToElasticIP: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "attach-instance-to-elastic-ip")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("AttachInstanceToElasticIP: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("AttachInstanceToElasticIP: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("AttachInstanceToElasticIP: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type DetachInstanceFromElasticIPRequest struct {
	// Target Instance
	Instance *InstanceTarget `json:"instance" validate:"required"`
}

// Detach a Compute instance from an Elastic IP
func (c Client) DetachInstanceFromElasticIP(ctx context.Context, id UUID, req DetachInstanceFromElasticIPRequest) (*Operation, error) {
	path := fmt.Sprintf("/elastic-ip/%v:detach", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("DetachInstanceFromElasticIP: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("DetachInstanceFromElasticIP: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DetachInstanceFromElasticIP: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DetachInstanceFromElasticIP: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "detach-instance-from-elastic-ip")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DetachInstanceFromElasticIP: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DetachInstanceFromElasticIP: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DetachInstanceFromElasticIP: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ListEventsOpt func(url.Values)

func ListEventsWithFrom(from time.Time) ListEventsOpt {
	return func(q url.Values) {
		q.Add("from", fmt.Sprint(from))
	}
}

func ListEventsWithTo(to time.Time) ListEventsOpt {
	return func(q url.Values) {
		q.Add("to", fmt.Sprint(to))
	}
}

// Retrieve Mutation Events for a given date range. Defaults to retrieving Events for the past 24 hours.
// Both a `from` and `to` arguments can be specified to filter Events over a specific period.
// Events will be the the most descriptive possible but not all fields are mandatory
func (c Client) ListEvents(ctx context.Context, opts ...ListEventsOpt) ([]Event, error) {
	path := "/event"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListEvents: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if len(opts) > 0 {
		q := request.URL.Query()
		for _, opt := range opts {
			opt(q)
		}
		request.URL.RawQuery = q.Encode()
	}

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListEvents: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListEvents: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-events")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListEvents: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListEvents: http response: %w", err)
	}

	bodyresp := []Event{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListEvents: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve IAM Organization Policy
func (c Client) GetIAMOrganizationPolicy(ctx context.Context) (*IAMPolicy, error) {
	path := "/iam-organization-policy"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetIAMOrganizationPolicy: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetIAMOrganizationPolicy: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetIAMOrganizationPolicy: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-iam-organization-policy")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetIAMOrganizationPolicy: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetIAMOrganizationPolicy: http response: %w", err)
	}

	bodyresp := &IAMPolicy{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetIAMOrganizationPolicy: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Update IAM Organization Policy
func (c Client) UpdateIAMOrganizationPolicy(ctx context.Context, req IAMPolicy) (*Operation, error) {
	path := "/iam-organization-policy"

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateIAMOrganizationPolicy: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateIAMOrganizationPolicy: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateIAMOrganizationPolicy: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateIAMOrganizationPolicy: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-iam-organization-policy")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateIAMOrganizationPolicy: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateIAMOrganizationPolicy: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateIAMOrganizationPolicy: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ListIAMRolesResponse struct {
	IAMRoles []IAMRole `json:"iam-roles,omitempty"`
}

// FindIAMRole attempts to find an IAMRole by nameOrID.
func (l ListIAMRolesResponse) FindIAMRole(nameOrID string) (IAMRole, error) {
	for i, elem := range l.IAMRoles {
		if string(elem.Name) == nameOrID || elem.ID.String() == nameOrID {
			return l.IAMRoles[i], nil
		}
	}

	return IAMRole{}, fmt.Errorf("%q not found in ListIAMRolesResponse: %w", nameOrID, ErrNotFound)
}

// List IAM Roles
func (c Client) ListIAMRoles(ctx context.Context) (*ListIAMRolesResponse, error) {
	path := "/iam-role"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListIAMRoles: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListIAMRoles: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListIAMRoles: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-iam-roles")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListIAMRoles: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListIAMRoles: http response: %w", err)
	}

	bodyresp := &ListIAMRolesResponse{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListIAMRoles: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type CreateIAMRoleRequest struct {
	// IAM Role description
	Description string `json:"description,omitempty" validate:"omitempty,gte=1,lte=255"`
	// Sets if the IAM Role Policy is editable or not (default: true). This setting cannot be changed after creation
	Editable *bool  `json:"editable,omitempty"`
	Labels   Labels `json:"labels,omitempty"`
	// IAM Role name
	Name string `json:"name" validate:"required,gte=1,lte=191"`
	// IAM Role permissions
	Permissions []string `json:"permissions,omitempty"`
	// Policy
	Policy *IAMPolicy `json:"policy,omitempty"`
}

// Create IAM Role
func (c Client) CreateIAMRole(ctx context.Context, req CreateIAMRoleRequest) (*Operation, error) {
	path := "/iam-role"

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateIAMRole: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateIAMRole: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateIAMRole: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateIAMRole: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-iam-role")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateIAMRole: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateIAMRole: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateIAMRole: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Delete IAM Role
func (c Client) DeleteIAMRole(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/iam-role/%v", id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteIAMRole: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteIAMRole: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteIAMRole: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-iam-role")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteIAMRole: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteIAMRole: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteIAMRole: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve IAM Role
func (c Client) GetIAMRole(ctx context.Context, id UUID) (*IAMRole, error) {
	path := fmt.Sprintf("/iam-role/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetIAMRole: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetIAMRole: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetIAMRole: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-iam-role")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetIAMRole: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetIAMRole: http response: %w", err)
	}

	bodyresp := &IAMRole{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetIAMRole: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type UpdateIAMRoleRequest struct {
	// IAM Role description
	Description string `json:"description,omitempty" validate:"omitempty,gte=1,lte=255"`
	Labels      Labels `json:"labels,omitempty"`
	// IAM Role permissions
	Permissions []string `json:"permissions,omitempty"`
}

// Update IAM Role
func (c Client) UpdateIAMRole(ctx context.Context, id UUID, req UpdateIAMRoleRequest) (*Operation, error) {
	path := fmt.Sprintf("/iam-role/%v", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateIAMRole: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateIAMRole: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateIAMRole: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateIAMRole: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-iam-role")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateIAMRole: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateIAMRole: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateIAMRole: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Update IAM Role Policy
func (c Client) UpdateIAMRolePolicy(ctx context.Context, id UUID, req IAMPolicy) (*Operation, error) {
	path := fmt.Sprintf("/iam-role/%v:policy", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateIAMRolePolicy: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateIAMRolePolicy: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateIAMRolePolicy: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateIAMRolePolicy: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-iam-role-policy")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateIAMRolePolicy: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateIAMRolePolicy: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateIAMRolePolicy: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Private Network
type ListInstancesResponseInstancesPrivateNetworks struct {
	// Private Network ID
	ID UUID `json:"id,omitempty"`
	// Private Network MAC address
	MACAddress string `json:"mac-address,omitempty"`
}

// Instance
type ListInstancesResponseInstances struct {
	// Instance creation date
	CreatedAT time.Time `json:"created-at,omitempty"`
	// Instance ID
	ID UUID `json:"id,omitempty"`
	// Compute instance type
	InstanceType *InstanceType `json:"instance-type,omitempty"`
	// Instance IPv6 address
	Ipv6Address string `json:"ipv6-address,omitempty"`
	Labels      Labels `json:"labels,omitempty"`
	// Instance MAC address
	MACAddress string `json:"mac-address,omitempty"`
	// Resource manager
	Manager *Manager `json:"manager,omitempty"`
	// Instance name
	Name string `json:"name,omitempty" validate:"omitempty,gte=1,lte=255"`
	// Instance Private Networks
	PrivateNetworks []ListInstancesResponseInstancesPrivateNetworks `json:"private-networks,omitempty"`
	// Instance public IPv4 address
	PublicIP           net.IP             `json:"public-ip,omitempty"`
	PublicIPAssignment PublicIPAssignment `json:"public-ip-assignment,omitempty"`
	// Instance Security Groups
	SecurityGroups []SecurityGroup `json:"security-groups,omitempty"`
	// SSH key
	SSHKey *SSHKey `json:"ssh-key,omitempty"`
	// Instance SSH Keys
	SSHKeys []SSHKey      `json:"ssh-keys,omitempty"`
	State   InstanceState `json:"state,omitempty"`
	// Instance template
	Template *Template `json:"template,omitempty"`
}

type ListInstancesResponse struct {
	Instances []ListInstancesResponseInstances `json:"instances,omitempty"`
}

// FindListInstancesResponseInstances attempts to find an ListInstancesResponseInstances by nameOrID.
func (l ListInstancesResponse) FindListInstancesResponseInstances(nameOrID string) (ListInstancesResponseInstances, error) {
	for i, elem := range l.Instances {
		if string(elem.Name) == nameOrID || elem.ID.String() == nameOrID {
			return l.Instances[i], nil
		}
	}

	return ListInstancesResponseInstances{}, fmt.Errorf("%q not found in ListInstancesResponse: %w", nameOrID, ErrNotFound)
}

type ListInstancesManagerType string

const (
	ListInstancesManagerTypeInstancePool ListInstancesManagerType = "instance-pool"
)

type ListInstancesOpt func(url.Values)

func ListInstancesWithManagerID(managerID UUID) ListInstancesOpt {
	return func(q url.Values) {
		q.Add("managerID", fmt.Sprint(managerID))
	}
}

func ListInstancesWithManagerType(managerType ListInstancesManagerType) ListInstancesOpt {
	return func(q url.Values) {
		q.Add("managerType", fmt.Sprint(managerType))
	}
}

func ListInstancesWithIPAddress(ipAddress string) ListInstancesOpt {
	return func(q url.Values) {
		q.Add("ipAddress", fmt.Sprint(ipAddress))
	}
}

// List Compute instances
func (c Client) ListInstances(ctx context.Context, opts ...ListInstancesOpt) (*ListInstancesResponse, error) {
	path := "/instance"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListInstances: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if len(opts) > 0 {
		q := request.URL.Query()
		for _, opt := range opts {
			opt(q)
		}
		request.URL.RawQuery = q.Encode()
	}

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListInstances: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListInstances: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-instances")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListInstances: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListInstances: http response: %w", err)
	}

	bodyresp := &ListInstancesResponse{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListInstances: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type CreateInstanceRequest struct {
	// Instance Anti-affinity Groups
	AntiAffinityGroups []AntiAffinityGroup `json:"anti-affinity-groups,omitempty"`
	// Start Instance on creation (default: true)
	AutoStart *bool `json:"auto-start,omitempty"`
	// Deploy target
	DeployTarget *DeployTarget `json:"deploy-target,omitempty"`
	// Instance disk size in GiB
	DiskSize int64 `json:"disk-size" validate:"required,gte=10,lte=51200"`
	// Compute instance type
	InstanceType *InstanceType `json:"instance-type" validate:"required"`
	// Enable IPv6. DEPRECATED: use `public-ip-assignments`.
	Ipv6Enabled *bool  `json:"ipv6-enabled,omitempty"`
	Labels      Labels `json:"labels,omitempty"`
	// Instance name
	Name               string             `json:"name,omitempty" validate:"omitempty,gte=1,lte=255"`
	PublicIPAssignment PublicIPAssignment `json:"public-ip-assignment,omitempty"`
	// Instance Security Groups
	SecurityGroups []SecurityGroup `json:"security-groups,omitempty"`
	// SSH key
	SSHKey *SSHKey `json:"ssh-key,omitempty"`
	// Instance SSH Keys
	SSHKeys []SSHKey `json:"ssh-keys,omitempty"`
	// Instance template
	Template *Template `json:"template" validate:"required"`
	// Instance Cloud-init user-data (base64 encoded)
	UserData string `json:"user-data,omitempty" validate:"omitempty,gte=1,lte=32768"`
}

// Create a Compute instance
func (c Client) CreateInstance(ctx context.Context, req CreateInstanceRequest) (*Operation, error) {
	path := "/instance"

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateInstance: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateInstance: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateInstance: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateInstance: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-instance")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateInstance: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateInstance: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateInstance: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ListInstancePoolsResponse struct {
	InstancePools []InstancePool `json:"instance-pools,omitempty"`
}

// FindInstancePool attempts to find an InstancePool by nameOrID.
func (l ListInstancePoolsResponse) FindInstancePool(nameOrID string) (InstancePool, error) {
	for i, elem := range l.InstancePools {
		if string(elem.Name) == nameOrID || elem.ID.String() == nameOrID {
			return l.InstancePools[i], nil
		}
	}

	return InstancePool{}, fmt.Errorf("%q not found in ListInstancePoolsResponse: %w", nameOrID, ErrNotFound)
}

// List Instance Pools
func (c Client) ListInstancePools(ctx context.Context) (*ListInstancePoolsResponse, error) {
	path := "/instance-pool"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListInstancePools: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListInstancePools: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListInstancePools: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-instance-pools")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListInstancePools: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListInstancePools: http response: %w", err)
	}

	bodyresp := &ListInstancePoolsResponse{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListInstancePools: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type CreateInstancePoolRequestPublicIPAssignment string

const (
	CreateInstancePoolRequestPublicIPAssignmentInet4 CreateInstancePoolRequestPublicIPAssignment = "inet4"
	CreateInstancePoolRequestPublicIPAssignmentDual  CreateInstancePoolRequestPublicIPAssignment = "dual"
	CreateInstancePoolRequestPublicIPAssignmentNone  CreateInstancePoolRequestPublicIPAssignment = "none"
)

type CreateInstancePoolRequest struct {
	// Instance Pool Anti-affinity Groups
	AntiAffinityGroups []AntiAffinityGroup `json:"anti-affinity-groups,omitempty"`
	// Deploy target
	DeployTarget *DeployTarget `json:"deploy-target,omitempty"`
	// Instance Pool description
	Description string `json:"description,omitempty" validate:"omitempty,lte=255"`
	// Instances disk size in GiB
	DiskSize int64 `json:"disk-size" validate:"required,gte=10,lte=51200"`
	// Instances Elastic IPs
	ElasticIPS []ElasticIP `json:"elastic-ips,omitempty"`
	// Prefix to apply to Instances names (default: pool)
	InstancePrefix string `json:"instance-prefix,omitempty" validate:"omitempty,gte=1,lte=30"`
	// Compute instance type
	InstanceType *InstanceType `json:"instance-type" validate:"required"`
	// Enable IPv6. DEPRECATED: use `public-ip-assignments`.
	Ipv6Enabled *bool  `json:"ipv6-enabled,omitempty"`
	Labels      Labels `json:"labels,omitempty"`
	// Minimum number of running Instances
	MinAvailable int64 `json:"min-available,omitempty" validate:"omitempty,gte=0"`
	// Instance Pool name
	Name string `json:"name" validate:"required,gte=1,lte=255"`
	// Instance Pool Private Networks
	PrivateNetworks []PrivateNetwork `json:"private-networks,omitempty"`
	// Determines public IP assignment of the Instances. Type `none` is final and can't be changed later on.
	PublicIPAssignment CreateInstancePoolRequestPublicIPAssignment `json:"public-ip-assignment,omitempty"`
	// Instance Pool Security Groups
	SecurityGroups []SecurityGroup `json:"security-groups,omitempty"`
	// Number of Instances
	Size int64 `json:"size" validate:"required,gt=0"`
	// SSH key
	SSHKey *SSHKey `json:"ssh-key,omitempty"`
	// Instances SSH Keys
	SSHKeys []SSHKey `json:"ssh-keys,omitempty"`
	// Instance template
	Template *Template `json:"template" validate:"required"`
	// Instances Cloud-init user-data
	UserData string `json:"user-data,omitempty" validate:"omitempty,gte=1"`
}

// Create an Instance Pool
func (c Client) CreateInstancePool(ctx context.Context, req CreateInstancePoolRequest) (*Operation, error) {
	path := "/instance-pool"

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateInstancePool: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateInstancePool: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateInstancePool: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateInstancePool: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-instance-pool")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateInstancePool: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateInstancePool: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateInstancePool: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Delete an Instance Pool
func (c Client) DeleteInstancePool(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/instance-pool/%v", id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteInstancePool: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteInstancePool: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteInstancePool: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-instance-pool")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteInstancePool: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteInstancePool: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteInstancePool: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve Instance Pool details
func (c Client) GetInstancePool(ctx context.Context, id UUID) (*InstancePool, error) {
	path := fmt.Sprintf("/instance-pool/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetInstancePool: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetInstancePool: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetInstancePool: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-instance-pool")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetInstancePool: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetInstancePool: http response: %w", err)
	}

	bodyresp := &InstancePool{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetInstancePool: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type UpdateInstancePoolRequestPublicIPAssignment string

const (
	UpdateInstancePoolRequestPublicIPAssignmentInet4 UpdateInstancePoolRequestPublicIPAssignment = "inet4"
	UpdateInstancePoolRequestPublicIPAssignmentDual  UpdateInstancePoolRequestPublicIPAssignment = "dual"
)

type UpdateInstancePoolRequest struct {
	// Instance Pool Anti-affinity Groups
	AntiAffinityGroups []AntiAffinityGroup `json:"anti-affinity-groups"`
	// Deploy target
	DeployTarget *DeployTarget `json:"deploy-target"`
	// Instance Pool description
	Description string `json:"description,omitempty" validate:"omitempty,lte=255"`
	// Instances disk size in GiB
	DiskSize int64 `json:"disk-size,omitempty" validate:"omitempty,gte=10,lte=51200"`
	// Instances Elastic IPs
	ElasticIPS []ElasticIP `json:"elastic-ips"`
	// Prefix to apply to Instances names (default: pool)
	InstancePrefix *string `json:"instance-prefix,omitempty"`
	// Compute instance type
	InstanceType *InstanceType `json:"instance-type,omitempty"`
	// Enable IPv6. DEPRECATED: use `public-ip-assignments`.
	Ipv6Enabled *bool  `json:"ipv6-enabled,omitempty"`
	Labels      Labels `json:"labels,omitempty"`
	// Minimum number of running Instances
	MinAvailable *int64 `json:"min-available,omitempty" validate:"omitempty,gte=0"`
	// Instance Pool name
	Name string `json:"name,omitempty" validate:"omitempty,gte=1,lte=255"`
	// Instance Pool Private Networks
	PrivateNetworks []PrivateNetwork `json:"private-networks"`
	// Determines public IP assignment of the Instances.
	PublicIPAssignment UpdateInstancePoolRequestPublicIPAssignment `json:"public-ip-assignment,omitempty"`
	// Instance Pool Security Groups
	SecurityGroups []SecurityGroup `json:"security-groups"`
	// SSH key
	SSHKey *SSHKey `json:"ssh-key"`
	// Instances SSH keys
	SSHKeys []SSHKey `json:"ssh-keys"`
	// Instance template
	Template *Template `json:"template,omitempty"`
	// Instances Cloud-init user-data
	UserData *string `json:"user-data,omitempty" validate:"omitempty,gte=1"`
}

// Update an Instance Pool
func (c Client) UpdateInstancePool(ctx context.Context, id UUID, req UpdateInstancePoolRequest) (*Operation, error) {
	path := fmt.Sprintf("/instance-pool/%v", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateInstancePool: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateInstancePool: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateInstancePool: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateInstancePool: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-instance-pool")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateInstancePool: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateInstancePool: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateInstancePool: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ResetInstancePoolFieldField string

const (
	ResetInstancePoolFieldFieldAntiAffinityGroups ResetInstancePoolFieldField = "anti-affinity-groups"
	ResetInstancePoolFieldFieldDescription        ResetInstancePoolFieldField = "description"
	ResetInstancePoolFieldFieldLabels             ResetInstancePoolFieldField = "labels"
	ResetInstancePoolFieldFieldSecurityGroups     ResetInstancePoolFieldField = "security-groups"
	ResetInstancePoolFieldFieldElasticIPS         ResetInstancePoolFieldField = "elastic-ips"
	ResetInstancePoolFieldFieldPrivateNetworks    ResetInstancePoolFieldField = "private-networks"
	ResetInstancePoolFieldFieldSSHKey             ResetInstancePoolFieldField = "ssh-key"
	ResetInstancePoolFieldFieldUserData           ResetInstancePoolFieldField = "user-data"
	ResetInstancePoolFieldFieldDeployTarget       ResetInstancePoolFieldField = "deploy-target"
	ResetInstancePoolFieldFieldIpv6Enabled        ResetInstancePoolFieldField = "ipv6-enabled"
)

// Reset an Instance Pool field to its default value
func (c Client) ResetInstancePoolField(ctx context.Context, id UUID, field ResetInstancePoolFieldField) (*Operation, error) {
	path := fmt.Sprintf("/instance-pool/%v/%v", id, field)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ResetInstancePoolField: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ResetInstancePoolField: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ResetInstancePoolField: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reset-instance-pool-field")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ResetInstancePoolField: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ResetInstancePoolField: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ResetInstancePoolField: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type EvictInstancePoolMembersRequest struct {
	Instances []UUID `json:"instances,omitempty"`
}

// This operation evicts the specified Compute instances member from the Instance Pool, shrinking it to `&lt;current pool size&gt; - &lt;# evicted members&gt;`.
func (c Client) EvictInstancePoolMembers(ctx context.Context, id UUID, req EvictInstancePoolMembersRequest) (*Operation, error) {
	path := fmt.Sprintf("/instance-pool/%v:evict", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("EvictInstancePoolMembers: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("EvictInstancePoolMembers: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("EvictInstancePoolMembers: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("EvictInstancePoolMembers: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "evict-instance-pool-members")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("EvictInstancePoolMembers: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("EvictInstancePoolMembers: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("EvictInstancePoolMembers: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ScaleInstancePoolRequest struct {
	// Number of managed Instances
	Size int64 `json:"size" validate:"required,gt=0"`
}

// Scale an Instance Pool
func (c Client) ScaleInstancePool(ctx context.Context, id UUID, req ScaleInstancePoolRequest) (*Operation, error) {
	path := fmt.Sprintf("/instance-pool/%v:scale", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("ScaleInstancePool: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("ScaleInstancePool: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ScaleInstancePool: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ScaleInstancePool: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "scale-instance-pool")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ScaleInstancePool: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ScaleInstancePool: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ScaleInstancePool: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ListInstanceTypesResponse struct {
	InstanceTypes []InstanceType `json:"instance-types,omitempty"`
}

// FindInstanceType attempts to find an InstanceType by ID.
func (l ListInstanceTypesResponse) FindInstanceType(ID string) (InstanceType, error) {
	for i, elem := range l.InstanceTypes {
		if elem.ID.String() == ID {
			return l.InstanceTypes[i], nil
		}
	}

	return InstanceType{}, fmt.Errorf("%q not found in ListInstanceTypesResponse: %w", ID, ErrNotFound)
}

// List Compute instance Types
func (c Client) ListInstanceTypes(ctx context.Context) (*ListInstanceTypesResponse, error) {
	path := "/instance-type"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListInstanceTypes: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListInstanceTypes: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListInstanceTypes: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-instance-types")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListInstanceTypes: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListInstanceTypes: http response: %w", err)
	}

	bodyresp := &ListInstanceTypesResponse{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListInstanceTypes: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve Instance Type details
func (c Client) GetInstanceType(ctx context.Context, id UUID) (*InstanceType, error) {
	path := fmt.Sprintf("/instance-type/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetInstanceType: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetInstanceType: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetInstanceType: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-instance-type")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetInstanceType: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetInstanceType: http response: %w", err)
	}

	bodyresp := &InstanceType{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetInstanceType: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Delete a Compute instance
func (c Client) DeleteInstance(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/instance/%v", id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteInstance: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteInstance: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteInstance: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-instance")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteInstance: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteInstance: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteInstance: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve Compute instance details
func (c Client) GetInstance(ctx context.Context, id UUID) (*Instance, error) {
	path := fmt.Sprintf("/instance/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetInstance: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetInstance: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetInstance: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-instance")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetInstance: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetInstance: http response: %w", err)
	}

	bodyresp := &Instance{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetInstance: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type UpdateInstanceRequest struct {
	Labels Labels `json:"labels,omitempty"`
	// Instance name
	Name               string             `json:"name,omitempty" validate:"omitempty,gte=1,lte=255"`
	PublicIPAssignment PublicIPAssignment `json:"public-ip-assignment,omitempty"`
	// Instance Cloud-init user-data (base64 encoded)
	UserData string `json:"user-data,omitempty" validate:"omitempty,gte=1,lte=32768"`
}

// Update a Compute instance
func (c Client) UpdateInstance(ctx context.Context, id UUID, req UpdateInstanceRequest) (*Operation, error) {
	path := fmt.Sprintf("/instance/%v", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateInstance: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateInstance: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateInstance: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateInstance: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-instance")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateInstance: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateInstance: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateInstance: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ResetInstanceFieldField string

const (
	ResetInstanceFieldFieldLabels ResetInstanceFieldField = "labels"
)

// Reset Instance field
func (c Client) ResetInstanceField(ctx context.Context, id UUID, field ResetInstanceFieldField) (*Operation, error) {
	path := fmt.Sprintf("/instance/%v/%v", id, field)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ResetInstanceField: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ResetInstanceField: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ResetInstanceField: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reset-instance-field")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ResetInstanceField: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ResetInstanceField: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ResetInstanceField: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Set instance destruction protection
func (c Client) AddInstanceProtection(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/instance/%v:add-protection", id)

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("AddInstanceProtection: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("AddInstanceProtection: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("AddInstanceProtection: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "add-instance-protection")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("AddInstanceProtection: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("AddInstanceProtection: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("AddInstanceProtection: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Create a Snapshot of a Compute instance
func (c Client) CreateSnapshot(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/instance/%v:create-snapshot", id)

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("CreateSnapshot: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateSnapshot: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateSnapshot: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-snapshot")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateSnapshot: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateSnapshot: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateSnapshot: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Reveal the password used during instance creation or the latest password reset.
// This is only available for VMs created against templates having the `password-enabled`
// property set to `true`.
// creation or resets.
// creation or resets.
func (c Client) RevealInstancePassword(ctx context.Context, id UUID) (*InstancePassword, error) {
	path := fmt.Sprintf("/instance/%v:password", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("RevealInstancePassword: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("RevealInstancePassword: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("RevealInstancePassword: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reveal-instance-password")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("RevealInstancePassword: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("RevealInstancePassword: http response: %w", err)
	}

	bodyresp := &InstancePassword{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("RevealInstancePassword: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Reboot a Compute instance
func (c Client) RebootInstance(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/instance/%v:reboot", id)

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("RebootInstance: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("RebootInstance: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("RebootInstance: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reboot-instance")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("RebootInstance: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("RebootInstance: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("RebootInstance: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Remove instance destruction protection
func (c Client) RemoveInstanceProtection(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/instance/%v:remove-protection", id)

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("RemoveInstanceProtection: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("RemoveInstanceProtection: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("RemoveInstanceProtection: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "remove-instance-protection")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("RemoveInstanceProtection: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("RemoveInstanceProtection: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("RemoveInstanceProtection: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ResetInstanceRequest struct {
	// Instance disk size in GiB
	DiskSize int64 `json:"disk-size,omitempty" validate:"omitempty,gte=10,lte=51200"`
	// Instance template
	Template *Template `json:"template,omitempty"`
}

// This operation re-installs a Compute instance to a base template. If target template is provided it will be used to recreated instance from. Warning: the operation wipes all data stored on the disk.
func (c Client) ResetInstance(ctx context.Context, id UUID, req ResetInstanceRequest) (*Operation, error) {
	path := fmt.Sprintf("/instance/%v:reset", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("ResetInstance: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("ResetInstance: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ResetInstance: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ResetInstance: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reset-instance")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ResetInstance: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ResetInstance: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ResetInstance: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Reset a compute instance password
func (c Client) ResetInstancePassword(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/instance/%v:reset-password", id)

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ResetInstancePassword: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ResetInstancePassword: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ResetInstancePassword: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reset-instance-password")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ResetInstancePassword: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ResetInstancePassword: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ResetInstancePassword: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ResizeInstanceDiskRequest struct {
	// Instance disk size in GiB
	DiskSize int64 `json:"disk-size" validate:"required,gte=10,lte=51200"`
}

// This operation resizes a Compute instance's disk volume. Note: the disk can only grow, cannot be shrunk.
func (c Client) ResizeInstanceDisk(ctx context.Context, id UUID, req ResizeInstanceDiskRequest) (*Operation, error) {
	path := fmt.Sprintf("/instance/%v:resize-disk", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("ResizeInstanceDisk: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("ResizeInstanceDisk: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ResizeInstanceDisk: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ResizeInstanceDisk: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "resize-instance-disk")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ResizeInstanceDisk: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ResizeInstanceDisk: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ResizeInstanceDisk: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ScaleInstanceRequest struct {
	// Compute instance type
	InstanceType *InstanceType `json:"instance-type" validate:"required"`
}

// This operation changes the Compute instance's type. Note: the new Instance Type must be within the same family (e.g. a standard instance cannot be scaled to gpu2 or storage).
func (c Client) ScaleInstance(ctx context.Context, id UUID, req ScaleInstanceRequest) (*Operation, error) {
	path := fmt.Sprintf("/instance/%v:scale", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("ScaleInstance: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("ScaleInstance: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ScaleInstance: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ScaleInstance: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "scale-instance")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ScaleInstance: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ScaleInstance: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ScaleInstance: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type StartInstanceRequestRescueProfile string

const (
	StartInstanceRequestRescueProfileNetbootEfi StartInstanceRequestRescueProfile = "netboot-efi"
	StartInstanceRequestRescueProfileNetboot    StartInstanceRequestRescueProfile = "netboot"
)

type StartInstanceRequest struct {
	// Boot in Rescue Mode, using named profile (supported: netboot, netboot-efi)
	RescueProfile StartInstanceRequestRescueProfile `json:"rescue-profile,omitempty"`
}

// This operation starts a virtual machine, potentially using a rescue profile if specified
func (c Client) StartInstance(ctx context.Context, id UUID, req StartInstanceRequest) (*Operation, error) {
	path := fmt.Sprintf("/instance/%v:start", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("StartInstance: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("StartInstance: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("StartInstance: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("StartInstance: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "start-instance")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("StartInstance: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("StartInstance: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("StartInstance: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Stop a Compute instance
func (c Client) StopInstance(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/instance/%v:stop", id)

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("StopInstance: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("StopInstance: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("StopInstance: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "stop-instance")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("StopInstance: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("StopInstance: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("StopInstance: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type RevertInstanceToSnapshotRequest struct {
	// Snapshot ID
	ID UUID `json:"id" validate:"required"`
}

// This operation reverts the snapshot to the Compute instance volume, restoring stored data as it was at the time of the snapshot.
// The Compute instance must be previously stopped.
func (c Client) RevertInstanceToSnapshot(ctx context.Context, instanceID UUID, req RevertInstanceToSnapshotRequest) (*Operation, error) {
	path := fmt.Sprintf("/instance/%v:revert-snapshot", instanceID)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("RevertInstanceToSnapshot: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("RevertInstanceToSnapshot: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("RevertInstanceToSnapshot: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("RevertInstanceToSnapshot: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "revert-instance-to-snapshot")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("RevertInstanceToSnapshot: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("RevertInstanceToSnapshot: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("RevertInstanceToSnapshot: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ListLoadBalancersResponse struct {
	LoadBalancers []LoadBalancer `json:"load-balancers,omitempty"`
}

// FindLoadBalancer attempts to find an LoadBalancer by nameOrID.
func (l ListLoadBalancersResponse) FindLoadBalancer(nameOrID string) (LoadBalancer, error) {
	for i, elem := range l.LoadBalancers {
		if string(elem.Name) == nameOrID || elem.ID.String() == nameOrID {
			return l.LoadBalancers[i], nil
		}
	}

	return LoadBalancer{}, fmt.Errorf("%q not found in ListLoadBalancersResponse: %w", nameOrID, ErrNotFound)
}

// List Load Balancers
func (c Client) ListLoadBalancers(ctx context.Context) (*ListLoadBalancersResponse, error) {
	path := "/load-balancer"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListLoadBalancers: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListLoadBalancers: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListLoadBalancers: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-load-balancers")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListLoadBalancers: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListLoadBalancers: http response: %w", err)
	}

	bodyresp := &ListLoadBalancersResponse{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListLoadBalancers: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type CreateLoadBalancerRequest struct {
	// Load Balancer description
	Description string `json:"description,omitempty" validate:"omitempty,lte=255"`
	Labels      Labels `json:"labels,omitempty"`
	// Load Balancer name
	Name string `json:"name" validate:"required,gte=1,lte=255"`
}

// Create a Load Balancer
func (c Client) CreateLoadBalancer(ctx context.Context, req CreateLoadBalancerRequest) (*Operation, error) {
	path := "/load-balancer"

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateLoadBalancer: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateLoadBalancer: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateLoadBalancer: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateLoadBalancer: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-load-balancer")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateLoadBalancer: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateLoadBalancer: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateLoadBalancer: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Delete a Load Balancer
func (c Client) DeleteLoadBalancer(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/load-balancer/%v", id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteLoadBalancer: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteLoadBalancer: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteLoadBalancer: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-load-balancer")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteLoadBalancer: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteLoadBalancer: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteLoadBalancer: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve Load Balancer details
func (c Client) GetLoadBalancer(ctx context.Context, id UUID) (*LoadBalancer, error) {
	path := fmt.Sprintf("/load-balancer/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetLoadBalancer: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetLoadBalancer: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetLoadBalancer: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-load-balancer")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetLoadBalancer: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetLoadBalancer: http response: %w", err)
	}

	bodyresp := &LoadBalancer{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetLoadBalancer: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type UpdateLoadBalancerRequest struct {
	// Load Balancer description
	Description string `json:"description,omitempty" validate:"omitempty,lte=255"`
	Labels      Labels `json:"labels,omitempty"`
	// Load Balancer name
	Name string `json:"name,omitempty" validate:"omitempty,gte=1,lte=255"`
}

// Update a Load Balancer
func (c Client) UpdateLoadBalancer(ctx context.Context, id UUID, req UpdateLoadBalancerRequest) (*Operation, error) {
	path := fmt.Sprintf("/load-balancer/%v", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateLoadBalancer: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateLoadBalancer: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateLoadBalancer: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateLoadBalancer: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-load-balancer")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateLoadBalancer: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateLoadBalancer: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateLoadBalancer: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type AddServiceToLoadBalancerRequestProtocol string

const (
	AddServiceToLoadBalancerRequestProtocolTCP AddServiceToLoadBalancerRequestProtocol = "tcp"
	AddServiceToLoadBalancerRequestProtocolUDP AddServiceToLoadBalancerRequestProtocol = "udp"
)

type AddServiceToLoadBalancerRequestStrategy string

const (
	AddServiceToLoadBalancerRequestStrategyRoundRobin AddServiceToLoadBalancerRequestStrategy = "round-robin"
	AddServiceToLoadBalancerRequestStrategyMaglevHash AddServiceToLoadBalancerRequestStrategy = "maglev-hash"
	AddServiceToLoadBalancerRequestStrategySourceHash AddServiceToLoadBalancerRequestStrategy = "source-hash"
)

type AddServiceToLoadBalancerRequest struct {
	// Load Balancer Service description
	Description string `json:"description,omitempty" validate:"omitempty,lte=255"`
	// Load Balancer Service healthcheck
	Healthcheck *LoadBalancerServiceHealthcheck `json:"healthcheck" validate:"required"`
	// Instance Pool
	InstancePool *InstancePool `json:"instance-pool" validate:"required"`
	// Load Balancer Service name
	Name string `json:"name" validate:"required,gte=1,lte=255"`
	// Port exposed on the Load Balancer's public IP
	Port int64 `json:"port" validate:"required,gte=1,lte=65535"`
	// Network traffic protocol
	Protocol AddServiceToLoadBalancerRequestProtocol `json:"protocol" validate:"required"`
	// Load balancing strategy
	Strategy AddServiceToLoadBalancerRequestStrategy `json:"strategy" validate:"required"`
	// Port on which the network traffic will be forwarded to on the receiving instance
	TargetPort int64 `json:"target-port" validate:"required,gte=1,lte=65535"`
}

// Add a Load Balancer Service
func (c Client) AddServiceToLoadBalancer(ctx context.Context, id UUID, req AddServiceToLoadBalancerRequest) (*Operation, error) {
	path := fmt.Sprintf("/load-balancer/%v/service", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("AddServiceToLoadBalancer: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("AddServiceToLoadBalancer: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("AddServiceToLoadBalancer: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("AddServiceToLoadBalancer: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "add-service-to-load-balancer")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("AddServiceToLoadBalancer: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("AddServiceToLoadBalancer: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("AddServiceToLoadBalancer: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Delete a Load Balancer Service
func (c Client) DeleteLoadBalancerService(ctx context.Context, id UUID, serviceID UUID) (*Operation, error) {
	path := fmt.Sprintf("/load-balancer/%v/service/%v", id, serviceID)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteLoadBalancerService: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteLoadBalancerService: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteLoadBalancerService: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-load-balancer-service")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteLoadBalancerService: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteLoadBalancerService: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteLoadBalancerService: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve Load Balancer Service details
func (c Client) GetLoadBalancerService(ctx context.Context, id UUID, serviceID UUID) (*LoadBalancerService, error) {
	path := fmt.Sprintf("/load-balancer/%v/service/%v", id, serviceID)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetLoadBalancerService: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetLoadBalancerService: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetLoadBalancerService: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-load-balancer-service")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetLoadBalancerService: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetLoadBalancerService: http response: %w", err)
	}

	bodyresp := &LoadBalancerService{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetLoadBalancerService: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type UpdateLoadBalancerServiceRequestProtocol string

const (
	UpdateLoadBalancerServiceRequestProtocolTCP UpdateLoadBalancerServiceRequestProtocol = "tcp"
	UpdateLoadBalancerServiceRequestProtocolUDP UpdateLoadBalancerServiceRequestProtocol = "udp"
)

type UpdateLoadBalancerServiceRequestStrategy string

const (
	UpdateLoadBalancerServiceRequestStrategyRoundRobin UpdateLoadBalancerServiceRequestStrategy = "round-robin"
	UpdateLoadBalancerServiceRequestStrategyMaglevHash UpdateLoadBalancerServiceRequestStrategy = "maglev-hash"
	UpdateLoadBalancerServiceRequestStrategySourceHash UpdateLoadBalancerServiceRequestStrategy = "source-hash"
)

type UpdateLoadBalancerServiceRequest struct {
	// Load Balancer Service description
	Description string `json:"description,omitempty" validate:"omitempty,lte=255"`
	// Load Balancer Service healthcheck
	Healthcheck *LoadBalancerServiceHealthcheck `json:"healthcheck,omitempty"`
	// Load Balancer Service name
	Name string `json:"name,omitempty" validate:"omitempty,lte=255"`
	// Port exposed on the Load Balancer's public IP
	Port int64 `json:"port,omitempty" validate:"omitempty,gte=1,lte=65535"`
	// Network traffic protocol
	Protocol UpdateLoadBalancerServiceRequestProtocol `json:"protocol,omitempty"`
	// Load balancing strategy
	Strategy UpdateLoadBalancerServiceRequestStrategy `json:"strategy,omitempty"`
	// Port on which the network traffic will be forwarded to on the receiving instance
	TargetPort int64 `json:"target-port,omitempty" validate:"omitempty,gte=1,lte=65535"`
}

// Update a Load Balancer Service
func (c Client) UpdateLoadBalancerService(ctx context.Context, id UUID, serviceID UUID, req UpdateLoadBalancerServiceRequest) (*Operation, error) {
	path := fmt.Sprintf("/load-balancer/%v/service/%v", id, serviceID)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateLoadBalancerService: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateLoadBalancerService: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateLoadBalancerService: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateLoadBalancerService: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-load-balancer-service")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateLoadBalancerService: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateLoadBalancerService: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateLoadBalancerService: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ResetLoadBalancerServiceFieldField string

const (
	ResetLoadBalancerServiceFieldFieldDescription ResetLoadBalancerServiceFieldField = "description"
)

// Reset a Load Balancer Service field to its default value
func (c Client) ResetLoadBalancerServiceField(ctx context.Context, id UUID, serviceID UUID, field ResetLoadBalancerServiceFieldField) (*Operation, error) {
	path := fmt.Sprintf("/load-balancer/%v/service/%v/%v", id, serviceID, field)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ResetLoadBalancerServiceField: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ResetLoadBalancerServiceField: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ResetLoadBalancerServiceField: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reset-load-balancer-service-field")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ResetLoadBalancerServiceField: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ResetLoadBalancerServiceField: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ResetLoadBalancerServiceField: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ResetLoadBalancerFieldField string

const (
	ResetLoadBalancerFieldFieldDescription ResetLoadBalancerFieldField = "description"
	ResetLoadBalancerFieldFieldLabels      ResetLoadBalancerFieldField = "labels"
)

// Reset a Load Balancer field to its default value
func (c Client) ResetLoadBalancerField(ctx context.Context, id UUID, field ResetLoadBalancerFieldField) (*Operation, error) {
	path := fmt.Sprintf("/load-balancer/%v/%v", id, field)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ResetLoadBalancerField: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ResetLoadBalancerField: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ResetLoadBalancerField: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reset-load-balancer-field")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ResetLoadBalancerField: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ResetLoadBalancerField: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ResetLoadBalancerField: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve Operation details
func (c Client) GetOperation(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/operation/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetOperation: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetOperation: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetOperation: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-operation")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetOperation: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetOperation: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetOperation: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve an organization
func (c Client) GetOrganization(ctx context.Context) (*Organization, error) {
	path := "/organization"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetOrganization: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetOrganization: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetOrganization: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-organization")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetOrganization: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetOrganization: http response: %w", err)
	}

	bodyresp := &Organization{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetOrganization: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ListPrivateNetworksResponse struct {
	PrivateNetworks []PrivateNetwork `json:"private-networks,omitempty"`
}

// FindPrivateNetwork attempts to find an PrivateNetwork by nameOrID.
func (l ListPrivateNetworksResponse) FindPrivateNetwork(nameOrID string) (PrivateNetwork, error) {
	for i, elem := range l.PrivateNetworks {
		if string(elem.Name) == nameOrID || elem.ID.String() == nameOrID {
			return l.PrivateNetworks[i], nil
		}
	}

	return PrivateNetwork{}, fmt.Errorf("%q not found in ListPrivateNetworksResponse: %w", nameOrID, ErrNotFound)
}

// List Private Networks
func (c Client) ListPrivateNetworks(ctx context.Context) (*ListPrivateNetworksResponse, error) {
	path := "/private-network"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListPrivateNetworks: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListPrivateNetworks: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListPrivateNetworks: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-private-networks")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListPrivateNetworks: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListPrivateNetworks: http response: %w", err)
	}

	bodyresp := &ListPrivateNetworksResponse{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListPrivateNetworks: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type CreatePrivateNetworkRequest struct {
	// Private Network description
	Description string `json:"description,omitempty" validate:"omitempty,lte=255"`
	// Private Network end IP address
	EndIP  net.IP `json:"end-ip,omitempty"`
	Labels Labels `json:"labels,omitempty"`
	// Private Network name
	Name string `json:"name" validate:"required,gte=1,lte=255"`
	// Private Network netmask
	Netmask net.IP `json:"netmask,omitempty"`
	// Private Network start IP address
	StartIP net.IP `json:"start-ip,omitempty"`
}

// Create a Private Network
func (c Client) CreatePrivateNetwork(ctx context.Context, req CreatePrivateNetworkRequest) (*Operation, error) {
	path := "/private-network"

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreatePrivateNetwork: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreatePrivateNetwork: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreatePrivateNetwork: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreatePrivateNetwork: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-private-network")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreatePrivateNetwork: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreatePrivateNetwork: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreatePrivateNetwork: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Delete a Private Network
func (c Client) DeletePrivateNetwork(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/private-network/%v", id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeletePrivateNetwork: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeletePrivateNetwork: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeletePrivateNetwork: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-private-network")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeletePrivateNetwork: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeletePrivateNetwork: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeletePrivateNetwork: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve Private Network details
func (c Client) GetPrivateNetwork(ctx context.Context, id UUID) (*PrivateNetwork, error) {
	path := fmt.Sprintf("/private-network/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetPrivateNetwork: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetPrivateNetwork: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetPrivateNetwork: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-private-network")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetPrivateNetwork: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetPrivateNetwork: http response: %w", err)
	}

	bodyresp := &PrivateNetwork{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetPrivateNetwork: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type UpdatePrivateNetworkRequest struct {
	// Private Network description
	Description string `json:"description,omitempty" validate:"omitempty,lte=255"`
	// Private Network end IP address
	EndIP  net.IP `json:"end-ip,omitempty"`
	Labels Labels `json:"labels,omitempty"`
	// Private Network name
	Name string `json:"name,omitempty" validate:"omitempty,gte=1,lte=255"`
	// Private Network netmask
	Netmask net.IP `json:"netmask,omitempty"`
	// Private Network start IP address
	StartIP net.IP `json:"start-ip,omitempty"`
}

// Update a Private Network
func (c Client) UpdatePrivateNetwork(ctx context.Context, id UUID, req UpdatePrivateNetworkRequest) (*Operation, error) {
	path := fmt.Sprintf("/private-network/%v", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdatePrivateNetwork: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdatePrivateNetwork: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdatePrivateNetwork: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdatePrivateNetwork: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-private-network")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdatePrivateNetwork: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdatePrivateNetwork: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdatePrivateNetwork: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ResetPrivateNetworkFieldField string

const (
	ResetPrivateNetworkFieldFieldLabels ResetPrivateNetworkFieldField = "labels"
)

// Reset Private Network field
func (c Client) ResetPrivateNetworkField(ctx context.Context, id UUID, field ResetPrivateNetworkFieldField) (*Operation, error) {
	path := fmt.Sprintf("/private-network/%v/%v", id, field)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ResetPrivateNetworkField: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ResetPrivateNetworkField: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ResetPrivateNetworkField: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reset-private-network-field")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ResetPrivateNetworkField: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ResetPrivateNetworkField: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ResetPrivateNetworkField: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Compute instance
type AttachInstanceToPrivateNetworkRequestInstance struct {
	// Instance ID
	ID UUID `json:"id,omitempty"`
}

type AttachInstanceToPrivateNetworkRequest struct {
	// Compute instance
	Instance *AttachInstanceToPrivateNetworkRequestInstance `json:"instance" validate:"required"`
	// Static IP address lease for the corresponding network interface
	IP net.IP `json:"ip,omitempty"`
}

// Attach a Compute instance to a Private Network
func (c Client) AttachInstanceToPrivateNetwork(ctx context.Context, id UUID, req AttachInstanceToPrivateNetworkRequest) (*Operation, error) {
	path := fmt.Sprintf("/private-network/%v:attach", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("AttachInstanceToPrivateNetwork: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("AttachInstanceToPrivateNetwork: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("AttachInstanceToPrivateNetwork: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("AttachInstanceToPrivateNetwork: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "attach-instance-to-private-network")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("AttachInstanceToPrivateNetwork: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("AttachInstanceToPrivateNetwork: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("AttachInstanceToPrivateNetwork: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type DetachInstanceFromPrivateNetworkRequest struct {
	// Instance
	Instance *Instance `json:"instance" validate:"required"`
}

// Detach a Compute instance from a Private Network
func (c Client) DetachInstanceFromPrivateNetwork(ctx context.Context, id UUID, req DetachInstanceFromPrivateNetworkRequest) (*Operation, error) {
	path := fmt.Sprintf("/private-network/%v:detach", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("DetachInstanceFromPrivateNetwork: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("DetachInstanceFromPrivateNetwork: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DetachInstanceFromPrivateNetwork: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DetachInstanceFromPrivateNetwork: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "detach-instance-from-private-network")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DetachInstanceFromPrivateNetwork: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DetachInstanceFromPrivateNetwork: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DetachInstanceFromPrivateNetwork: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type UpdatePrivateNetworkInstanceIPRequestInstance struct {
	// Instance ID
	ID UUID `json:"id" validate:"required"`
}

type UpdatePrivateNetworkInstanceIPRequest struct {
	Instance *UpdatePrivateNetworkInstanceIPRequestInstance `json:"instance,omitempty"`
	// Static IP address lease for the corresponding network interface
	IP net.IP `json:"ip,omitempty"`
}

// Update the IP address of an instance attached to a managed private network
func (c Client) UpdatePrivateNetworkInstanceIP(ctx context.Context, id UUID, req UpdatePrivateNetworkInstanceIPRequest) (*Operation, error) {
	path := fmt.Sprintf("/private-network/%v:update-ip", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdatePrivateNetworkInstanceIP: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdatePrivateNetworkInstanceIP: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdatePrivateNetworkInstanceIP: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdatePrivateNetworkInstanceIP: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-private-network-instance-ip")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdatePrivateNetworkInstanceIP: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdatePrivateNetworkInstanceIP: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdatePrivateNetworkInstanceIP: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ListQuotasResponse struct {
	Quotas []Quota `json:"quotas,omitempty"`
}

// List Organization Quotas
func (c Client) ListQuotas(ctx context.Context) (*ListQuotasResponse, error) {
	path := "/quota"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListQuotas: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListQuotas: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListQuotas: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-quotas")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListQuotas: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListQuotas: http response: %w", err)
	}

	bodyresp := &ListQuotasResponse{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListQuotas: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve Resource Quota
func (c Client) GetQuota(ctx context.Context, entity string) (*Quota, error) {
	path := fmt.Sprintf("/quota/%v", entity)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetQuota: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetQuota: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetQuota: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-quota")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetQuota: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetQuota: http response: %w", err)
	}

	bodyresp := &Quota{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetQuota: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Delete the PTR DNS record for an elastic IP
func (c Client) DeleteReverseDNSElasticIP(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/reverse-dns/elastic-ip/%v", id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteReverseDNSElasticIP: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteReverseDNSElasticIP: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteReverseDNSElasticIP: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-reverse-dns-elastic-ip")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteReverseDNSElasticIP: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteReverseDNSElasticIP: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteReverseDNSElasticIP: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Query the PTR DNS records for an elastic IP
func (c Client) GetReverseDNSElasticIP(ctx context.Context, id UUID) (*ReverseDNSRecord, error) {
	path := fmt.Sprintf("/reverse-dns/elastic-ip/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetReverseDNSElasticIP: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetReverseDNSElasticIP: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetReverseDNSElasticIP: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-reverse-dns-elastic-ip")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetReverseDNSElasticIP: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetReverseDNSElasticIP: http response: %w", err)
	}

	bodyresp := &ReverseDNSRecord{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetReverseDNSElasticIP: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type UpdateReverseDNSElasticIPRequest struct {
	DomainName string `json:"domain-name,omitempty" validate:"omitempty,gte=1,lte=253"`
}

// Update/Create the PTR DNS record for an elastic IP
func (c Client) UpdateReverseDNSElasticIP(ctx context.Context, id UUID, req UpdateReverseDNSElasticIPRequest) (*Operation, error) {
	path := fmt.Sprintf("/reverse-dns/elastic-ip/%v", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateReverseDNSElasticIP: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateReverseDNSElasticIP: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateReverseDNSElasticIP: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateReverseDNSElasticIP: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-reverse-dns-elastic-ip")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateReverseDNSElasticIP: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateReverseDNSElasticIP: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateReverseDNSElasticIP: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Delete the PTR DNS record for an instance
func (c Client) DeleteReverseDNSInstance(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/reverse-dns/instance/%v", id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteReverseDNSInstance: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteReverseDNSInstance: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteReverseDNSInstance: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-reverse-dns-instance")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteReverseDNSInstance: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteReverseDNSInstance: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteReverseDNSInstance: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Query the PTR DNS records for an instance
func (c Client) GetReverseDNSInstance(ctx context.Context, id UUID) (*ReverseDNSRecord, error) {
	path := fmt.Sprintf("/reverse-dns/instance/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetReverseDNSInstance: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetReverseDNSInstance: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetReverseDNSInstance: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-reverse-dns-instance")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetReverseDNSInstance: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetReverseDNSInstance: http response: %w", err)
	}

	bodyresp := &ReverseDNSRecord{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetReverseDNSInstance: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type UpdateReverseDNSInstanceRequest struct {
	DomainName string `json:"domain-name,omitempty" validate:"omitempty,gte=1,lte=253"`
}

// Update/Create the PTR DNS record for an instance
func (c Client) UpdateReverseDNSInstance(ctx context.Context, id UUID, req UpdateReverseDNSInstanceRequest) (*Operation, error) {
	path := fmt.Sprintf("/reverse-dns/instance/%v", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateReverseDNSInstance: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateReverseDNSInstance: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateReverseDNSInstance: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateReverseDNSInstance: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-reverse-dns-instance")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateReverseDNSInstance: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateReverseDNSInstance: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateReverseDNSInstance: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ListSecurityGroupsResponse struct {
	SecurityGroups []SecurityGroup `json:"security-groups,omitempty"`
}

// FindSecurityGroup attempts to find an SecurityGroup by nameOrID.
func (l ListSecurityGroupsResponse) FindSecurityGroup(nameOrID string) (SecurityGroup, error) {
	for i, elem := range l.SecurityGroups {
		if string(elem.Name) == nameOrID || elem.ID.String() == nameOrID {
			return l.SecurityGroups[i], nil
		}
	}

	return SecurityGroup{}, fmt.Errorf("%q not found in ListSecurityGroupsResponse: %w", nameOrID, ErrNotFound)
}

type ListSecurityGroupsVisibility string

const (
	ListSecurityGroupsVisibilityPrivate ListSecurityGroupsVisibility = "private"
	ListSecurityGroupsVisibilityPublic  ListSecurityGroupsVisibility = "public"
)

type ListSecurityGroupsOpt func(url.Values)

func ListSecurityGroupsWithVisibility(visibility ListSecurityGroupsVisibility) ListSecurityGroupsOpt {
	return func(q url.Values) {
		q.Add("visibility", fmt.Sprint(visibility))
	}
}

// Lists security groups. When visibility is set to public, lists public security groups.
// Public security groups are objects maintained by Exoscale which contain source addresses for
// relevant services hosted by Exoscale. They can be used a source in ingress rules and as a destination
// in egress rules.
func (c Client) ListSecurityGroups(ctx context.Context, opts ...ListSecurityGroupsOpt) (*ListSecurityGroupsResponse, error) {
	path := "/security-group"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListSecurityGroups: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if len(opts) > 0 {
		q := request.URL.Query()
		for _, opt := range opts {
			opt(q)
		}
		request.URL.RawQuery = q.Encode()
	}

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListSecurityGroups: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListSecurityGroups: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-security-groups")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListSecurityGroups: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListSecurityGroups: http response: %w", err)
	}

	bodyresp := &ListSecurityGroupsResponse{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListSecurityGroups: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type CreateSecurityGroupRequest struct {
	// Security Group description
	Description string `json:"description,omitempty" validate:"omitempty,lte=255"`
	// Security Group name
	Name string `json:"name" validate:"required,gte=1,lte=255"`
}

// Create a Security Group
func (c Client) CreateSecurityGroup(ctx context.Context, req CreateSecurityGroupRequest) (*Operation, error) {
	path := "/security-group"

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateSecurityGroup: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateSecurityGroup: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateSecurityGroup: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateSecurityGroup: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-security-group")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateSecurityGroup: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateSecurityGroup: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateSecurityGroup: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Delete a Security Group
func (c Client) DeleteSecurityGroup(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/security-group/%v", id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteSecurityGroup: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteSecurityGroup: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteSecurityGroup: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-security-group")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteSecurityGroup: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteSecurityGroup: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteSecurityGroup: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve Security Group details
func (c Client) GetSecurityGroup(ctx context.Context, id UUID) (*SecurityGroup, error) {
	path := fmt.Sprintf("/security-group/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetSecurityGroup: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetSecurityGroup: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetSecurityGroup: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-security-group")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetSecurityGroup: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetSecurityGroup: http response: %w", err)
	}

	bodyresp := &SecurityGroup{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetSecurityGroup: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type AddRuleToSecurityGroupRequestFlowDirection string

const (
	AddRuleToSecurityGroupRequestFlowDirectionIngress AddRuleToSecurityGroupRequestFlowDirection = "ingress"
	AddRuleToSecurityGroupRequestFlowDirectionEgress  AddRuleToSecurityGroupRequestFlowDirection = "egress"
)

// ICMP details (default: -1 (ANY))
type AddRuleToSecurityGroupRequestICMP struct {
	Code int64 `json:"code,omitempty" validate:"omitempty,gte=-1,lte=254"`
	Type int64 `json:"type,omitempty" validate:"omitempty,gte=-1,lte=254"`
}

type AddRuleToSecurityGroupRequestProtocol string

const (
	AddRuleToSecurityGroupRequestProtocolTCP    AddRuleToSecurityGroupRequestProtocol = "tcp"
	AddRuleToSecurityGroupRequestProtocolEsp    AddRuleToSecurityGroupRequestProtocol = "esp"
	AddRuleToSecurityGroupRequestProtocolICMP   AddRuleToSecurityGroupRequestProtocol = "icmp"
	AddRuleToSecurityGroupRequestProtocolUDP    AddRuleToSecurityGroupRequestProtocol = "udp"
	AddRuleToSecurityGroupRequestProtocolGre    AddRuleToSecurityGroupRequestProtocol = "gre"
	AddRuleToSecurityGroupRequestProtocolAh     AddRuleToSecurityGroupRequestProtocol = "ah"
	AddRuleToSecurityGroupRequestProtocolIpip   AddRuleToSecurityGroupRequestProtocol = "ipip"
	AddRuleToSecurityGroupRequestProtocolIcmpv6 AddRuleToSecurityGroupRequestProtocol = "icmpv6"
)

type AddRuleToSecurityGroupRequest struct {
	// Security Group rule description
	Description string `json:"description,omitempty" validate:"omitempty,lte=255"`
	// End port of the range
	EndPort int64 `json:"end-port,omitempty" validate:"omitempty,gte=1,lte=65535"`
	// Network flow direction to match
	FlowDirection AddRuleToSecurityGroupRequestFlowDirection `json:"flow-direction" validate:"required"`
	// ICMP details (default: -1 (ANY))
	ICMP *AddRuleToSecurityGroupRequestICMP `json:"icmp,omitempty"`
	// CIDR-formatted network allowed
	Network string `json:"network,omitempty"`
	// Network protocol
	Protocol AddRuleToSecurityGroupRequestProtocol `json:"protocol" validate:"required"`
	// Security Group
	SecurityGroup *SecurityGroupResource `json:"security-group,omitempty"`
	// Start port of the range
	StartPort int64 `json:"start-port,omitempty" validate:"omitempty,gte=1,lte=65535"`
}

// Create a Security Group rule
func (c Client) AddRuleToSecurityGroup(ctx context.Context, id UUID, req AddRuleToSecurityGroupRequest) (*Operation, error) {
	path := fmt.Sprintf("/security-group/%v/rules", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("AddRuleToSecurityGroup: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("AddRuleToSecurityGroup: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("AddRuleToSecurityGroup: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("AddRuleToSecurityGroup: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "add-rule-to-security-group")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("AddRuleToSecurityGroup: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("AddRuleToSecurityGroup: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("AddRuleToSecurityGroup: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Delete a Security Group rule
func (c Client) DeleteRuleFromSecurityGroup(ctx context.Context, id UUID, ruleID UUID) (*Operation, error) {
	path := fmt.Sprintf("/security-group/%v/rules/%v", id, ruleID)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteRuleFromSecurityGroup: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteRuleFromSecurityGroup: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteRuleFromSecurityGroup: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-rule-from-security-group")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteRuleFromSecurityGroup: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteRuleFromSecurityGroup: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteRuleFromSecurityGroup: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type AddExternalSourceToSecurityGroupRequest struct {
	// CIDR-formatted network to add
	Cidr string `json:"cidr" validate:"required"`
}

// Add an external source as a member of a Security Group
func (c Client) AddExternalSourceToSecurityGroup(ctx context.Context, id UUID, req AddExternalSourceToSecurityGroupRequest) (*Operation, error) {
	path := fmt.Sprintf("/security-group/%v:add-source", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("AddExternalSourceToSecurityGroup: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("AddExternalSourceToSecurityGroup: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("AddExternalSourceToSecurityGroup: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("AddExternalSourceToSecurityGroup: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "add-external-source-to-security-group")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("AddExternalSourceToSecurityGroup: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("AddExternalSourceToSecurityGroup: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("AddExternalSourceToSecurityGroup: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type AttachInstanceToSecurityGroupRequest struct {
	// Instance
	Instance *Instance `json:"instance" validate:"required"`
}

// Attach a Compute instance to a Security Group
func (c Client) AttachInstanceToSecurityGroup(ctx context.Context, id UUID, req AttachInstanceToSecurityGroupRequest) (*Operation, error) {
	path := fmt.Sprintf("/security-group/%v:attach", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("AttachInstanceToSecurityGroup: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("AttachInstanceToSecurityGroup: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("AttachInstanceToSecurityGroup: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("AttachInstanceToSecurityGroup: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "attach-instance-to-security-group")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("AttachInstanceToSecurityGroup: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("AttachInstanceToSecurityGroup: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("AttachInstanceToSecurityGroup: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type DetachInstanceFromSecurityGroupRequest struct {
	// Instance
	Instance *Instance `json:"instance" validate:"required"`
}

// Detach a Compute instance from a Security Group
func (c Client) DetachInstanceFromSecurityGroup(ctx context.Context, id UUID, req DetachInstanceFromSecurityGroupRequest) (*Operation, error) {
	path := fmt.Sprintf("/security-group/%v:detach", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("DetachInstanceFromSecurityGroup: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("DetachInstanceFromSecurityGroup: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DetachInstanceFromSecurityGroup: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DetachInstanceFromSecurityGroup: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "detach-instance-from-security-group")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DetachInstanceFromSecurityGroup: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DetachInstanceFromSecurityGroup: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DetachInstanceFromSecurityGroup: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type RemoveExternalSourceFromSecurityGroupRequest struct {
	// CIDR-formatted network to remove
	Cidr string `json:"cidr" validate:"required"`
}

// Remove an external source from a Security Group
func (c Client) RemoveExternalSourceFromSecurityGroup(ctx context.Context, id UUID, req RemoveExternalSourceFromSecurityGroupRequest) (*Operation, error) {
	path := fmt.Sprintf("/security-group/%v:remove-source", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("RemoveExternalSourceFromSecurityGroup: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("RemoveExternalSourceFromSecurityGroup: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("RemoveExternalSourceFromSecurityGroup: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("RemoveExternalSourceFromSecurityGroup: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "remove-external-source-from-security-group")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("RemoveExternalSourceFromSecurityGroup: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("RemoveExternalSourceFromSecurityGroup: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("RemoveExternalSourceFromSecurityGroup: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ListSKSClustersResponse struct {
	SKSClusters []SKSCluster `json:"sks-clusters,omitempty"`
}

// FindSKSCluster attempts to find an SKSCluster by nameOrID.
func (l ListSKSClustersResponse) FindSKSCluster(nameOrID string) (SKSCluster, error) {
	for i, elem := range l.SKSClusters {
		if string(elem.Name) == nameOrID || elem.ID.String() == nameOrID {
			return l.SKSClusters[i], nil
		}
	}

	return SKSCluster{}, fmt.Errorf("%q not found in ListSKSClustersResponse: %w", nameOrID, ErrNotFound)
}

// List SKS clusters
func (c Client) ListSKSClusters(ctx context.Context) (*ListSKSClustersResponse, error) {
	path := "/sks-cluster"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListSKSClusters: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListSKSClusters: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListSKSClusters: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-sks-clusters")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListSKSClusters: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListSKSClusters: http response: %w", err)
	}

	bodyresp := &ListSKSClustersResponse{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListSKSClusters: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type CreateSKSClusterRequestCni string

const (
	CreateSKSClusterRequestCniCalico CreateSKSClusterRequestCni = "calico"
	CreateSKSClusterRequestCniCilium CreateSKSClusterRequestCni = "cilium"
)

type CreateSKSClusterRequestLevel string

const (
	CreateSKSClusterRequestLevelStarter CreateSKSClusterRequestLevel = "starter"
	CreateSKSClusterRequestLevelPro     CreateSKSClusterRequestLevel = "pro"
)

type CreateSKSClusterRequest struct {
	// Cluster addons
	Addons []string `json:"addons,omitempty"`
	// Enable auto upgrade of the control plane to the latest patch version available
	AutoUpgrade *bool `json:"auto-upgrade,omitempty"`
	// Cluster CNI
	Cni CreateSKSClusterRequestCni `json:"cni,omitempty"`
	// Cluster description
	Description *string `json:"description,omitempty" validate:"omitempty,lte=255"`
	Labels      Labels  `json:"labels,omitempty"`
	// Cluster service level
	Level CreateSKSClusterRequestLevel `json:"level" validate:"required"`
	// Cluster name
	Name string `json:"name" validate:"required,gte=1,lte=255"`
	// SKS Cluster OpenID config map
	Oidc *SKSOidc `json:"oidc,omitempty"`
	// Control plane Kubernetes version
	Version string `json:"version" validate:"required"`
}

// Create an SKS cluster
func (c Client) CreateSKSCluster(ctx context.Context, req CreateSKSClusterRequest) (*Operation, error) {
	path := "/sks-cluster"

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateSKSCluster: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateSKSCluster: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateSKSCluster: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateSKSCluster: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-sks-cluster")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateSKSCluster: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateSKSCluster: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateSKSCluster: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// This operation returns the deprecated resources for a given cluster
func (c Client) ListSKSClusterDeprecatedResources(ctx context.Context, id UUID) ([]SKSClusterDeprecatedResource, error) {
	path := fmt.Sprintf("/sks-cluster-deprecated-resources/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListSKSClusterDeprecatedResources: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListSKSClusterDeprecatedResources: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListSKSClusterDeprecatedResources: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-sks-cluster-deprecated-resources")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListSKSClusterDeprecatedResources: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListSKSClusterDeprecatedResources: http response: %w", err)
	}

	bodyresp := []SKSClusterDeprecatedResource{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListSKSClusterDeprecatedResources: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type GenerateSKSClusterKubeconfigResponse struct {
	Kubeconfig string `json:"kubeconfig,omitempty"`
}

// This operation returns a Kubeconfig file encoded in base64.
func (c Client) GenerateSKSClusterKubeconfig(ctx context.Context, id UUID, req SKSKubeconfigRequest) (*GenerateSKSClusterKubeconfigResponse, error) {
	path := fmt.Sprintf("/sks-cluster-kubeconfig/%v", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("GenerateSKSClusterKubeconfig: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("GenerateSKSClusterKubeconfig: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GenerateSKSClusterKubeconfig: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GenerateSKSClusterKubeconfig: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "generate-sks-cluster-kubeconfig")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GenerateSKSClusterKubeconfig: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GenerateSKSClusterKubeconfig: http response: %w", err)
	}

	bodyresp := &GenerateSKSClusterKubeconfigResponse{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GenerateSKSClusterKubeconfig: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ListSKSClusterVersionsResponse struct {
	SKSClusterVersions []string `json:"sks-cluster-versions,omitempty"`
}

type ListSKSClusterVersionsOpt func(url.Values)

func ListSKSClusterVersionsWithIncludeDeprecated(includeDeprecated string) ListSKSClusterVersionsOpt {
	return func(q url.Values) {
		q.Add("includeDeprecated", fmt.Sprint(includeDeprecated))
	}
}

// List available versions for SKS clusters
func (c Client) ListSKSClusterVersions(ctx context.Context, opts ...ListSKSClusterVersionsOpt) (*ListSKSClusterVersionsResponse, error) {
	path := "/sks-cluster-version"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListSKSClusterVersions: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if len(opts) > 0 {
		q := request.URL.Query()
		for _, opt := range opts {
			opt(q)
		}
		request.URL.RawQuery = q.Encode()
	}

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListSKSClusterVersions: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListSKSClusterVersions: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-sks-cluster-versions")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListSKSClusterVersions: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListSKSClusterVersions: http response: %w", err)
	}

	bodyresp := &ListSKSClusterVersionsResponse{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListSKSClusterVersions: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Delete an SKS cluster
func (c Client) DeleteSKSCluster(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/sks-cluster/%v", id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteSKSCluster: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteSKSCluster: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteSKSCluster: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-sks-cluster")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteSKSCluster: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteSKSCluster: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteSKSCluster: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve SKS cluster details
func (c Client) GetSKSCluster(ctx context.Context, id UUID) (*SKSCluster, error) {
	path := fmt.Sprintf("/sks-cluster/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetSKSCluster: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetSKSCluster: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetSKSCluster: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-sks-cluster")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetSKSCluster: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetSKSCluster: http response: %w", err)
	}

	bodyresp := &SKSCluster{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetSKSCluster: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type UpdateSKSClusterRequest struct {
	// Cluster addons
	Addons []string `json:"addons,omitempty"`
	// Enable auto upgrade of the control plane to the latest patch version available
	AutoUpgrade *bool `json:"auto-upgrade,omitempty"`
	// Cluster description
	Description *string `json:"description,omitempty" validate:"omitempty,lte=255"`
	Labels      Labels  `json:"labels,omitempty"`
	// Cluster name
	Name string `json:"name,omitempty" validate:"omitempty,gte=1,lte=255"`
	// SKS Cluster OpenID config map
	Oidc *SKSOidc `json:"oidc"`
}

// Update an SKS cluster
func (c Client) UpdateSKSCluster(ctx context.Context, id UUID, req UpdateSKSClusterRequest) (*Operation, error) {
	path := fmt.Sprintf("/sks-cluster/%v", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateSKSCluster: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateSKSCluster: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateSKSCluster: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateSKSCluster: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-sks-cluster")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateSKSCluster: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateSKSCluster: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateSKSCluster: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type GetSKSClusterAuthorityCertResponse struct {
	Cacert string `json:"cacert,omitempty"`
}

type GetSKSClusterAuthorityCertAuthority string

const (
	GetSKSClusterAuthorityCertAuthorityControlPlane GetSKSClusterAuthorityCertAuthority = "control-plane"
	GetSKSClusterAuthorityCertAuthorityAggregation  GetSKSClusterAuthorityCertAuthority = "aggregation"
	GetSKSClusterAuthorityCertAuthorityKubelet      GetSKSClusterAuthorityCertAuthority = "kubelet"
)

// This operation returns the certificate for the given SKS cluster authority encoded in base64.
func (c Client) GetSKSClusterAuthorityCert(ctx context.Context, id UUID, authority GetSKSClusterAuthorityCertAuthority) (*GetSKSClusterAuthorityCertResponse, error) {
	path := fmt.Sprintf("/sks-cluster/%v/authority/%v/cert", id, authority)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetSKSClusterAuthorityCert: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetSKSClusterAuthorityCert: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetSKSClusterAuthorityCert: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-sks-cluster-authority-cert")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetSKSClusterAuthorityCert: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetSKSClusterAuthorityCert: http response: %w", err)
	}

	bodyresp := &GetSKSClusterAuthorityCertResponse{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetSKSClusterAuthorityCert: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type GetSKSClusterInspectionResponse map[string]any

// Helps troubleshoot common problems when deploying a kubernetes cluster. Inspections run every couple of minutes.
func (c Client) GetSKSClusterInspection(ctx context.Context, id UUID) (*GetSKSClusterInspectionResponse, error) {
	path := fmt.Sprintf("/sks-cluster/%v/inspection", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetSKSClusterInspection: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetSKSClusterInspection: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetSKSClusterInspection: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-sks-cluster-inspection")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetSKSClusterInspection: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetSKSClusterInspection: http response: %w", err)
	}

	bodyresp := &GetSKSClusterInspectionResponse{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetSKSClusterInspection: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type CreateSKSNodepoolRequest struct {
	// Nodepool addons
	Addons []string `json:"addons,omitempty"`
	// Nodepool Anti-affinity Groups
	AntiAffinityGroups []AntiAffinityGroup `json:"anti-affinity-groups,omitempty"`
	// Deploy target
	DeployTarget *DeployTarget `json:"deploy-target,omitempty"`
	// Nodepool description
	Description string `json:"description,omitempty" validate:"omitempty,lte=255"`
	// Nodepool instances disk size in GiB
	DiskSize int64 `json:"disk-size" validate:"required,gte=20,lte=51200"`
	// Prefix to apply to instances names (default: pool)
	InstancePrefix string `json:"instance-prefix,omitempty" validate:"omitempty,gte=1,lte=30"`
	// Compute instance type
	InstanceType *InstanceType `json:"instance-type" validate:"required"`
	// Kubelet image GC options
	KubeletImageGC *KubeletImageGC `json:"kubelet-image-gc,omitempty"`
	Labels         Labels          `json:"labels,omitempty"`
	// Nodepool name
	Name string `json:"name" validate:"required,gte=1,lte=255"`
	// Nodepool Private Networks
	PrivateNetworks []PrivateNetwork `json:"private-networks,omitempty"`
	// Nodepool Security Groups
	SecurityGroups []SecurityGroup `json:"security-groups,omitempty"`
	// Number of instances
	Size   int64             `json:"size" validate:"required,gt=0"`
	Taints SKSNodepoolTaints `json:"taints,omitempty"`
}

// Create a new SKS Nodepool
func (c Client) CreateSKSNodepool(ctx context.Context, id UUID, req CreateSKSNodepoolRequest) (*Operation, error) {
	path := fmt.Sprintf("/sks-cluster/%v/nodepool", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CreateSKSNodepool: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CreateSKSNodepool: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CreateSKSNodepool: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CreateSKSNodepool: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "create-sks-nodepool")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CreateSKSNodepool: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CreateSKSNodepool: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CreateSKSNodepool: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Delete an SKS Nodepool
func (c Client) DeleteSKSNodepool(ctx context.Context, id UUID, sksNodepoolID UUID) (*Operation, error) {
	path := fmt.Sprintf("/sks-cluster/%v/nodepool/%v", id, sksNodepoolID)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteSKSNodepool: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteSKSNodepool: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteSKSNodepool: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-sks-nodepool")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteSKSNodepool: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteSKSNodepool: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteSKSNodepool: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve SKS Nodepool details
func (c Client) GetSKSNodepool(ctx context.Context, id UUID, sksNodepoolID UUID) (*SKSNodepool, error) {
	path := fmt.Sprintf("/sks-cluster/%v/nodepool/%v", id, sksNodepoolID)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetSKSNodepool: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetSKSNodepool: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetSKSNodepool: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-sks-nodepool")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetSKSNodepool: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetSKSNodepool: http response: %w", err)
	}

	bodyresp := &SKSNodepool{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetSKSNodepool: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type UpdateSKSNodepoolRequest struct {
	// Nodepool Anti-affinity Groups
	AntiAffinityGroups []AntiAffinityGroup `json:"anti-affinity-groups,omitempty"`
	// Deploy target
	DeployTarget *DeployTarget `json:"deploy-target"`
	// Nodepool description
	Description string `json:"description,omitempty" validate:"omitempty,lte=255"`
	// Nodepool instances disk size in GiB
	DiskSize int64 `json:"disk-size,omitempty" validate:"omitempty,gte=20,lte=51200"`
	// Prefix to apply to managed instances names (default: pool)
	InstancePrefix string `json:"instance-prefix,omitempty" validate:"omitempty,gte=1,lte=30"`
	// Compute instance type
	InstanceType *InstanceType `json:"instance-type,omitempty"`
	Labels       Labels        `json:"labels,omitempty"`
	// Nodepool name
	Name string `json:"name,omitempty" validate:"omitempty,gte=1,lte=255"`
	// Nodepool Private Networks
	PrivateNetworks []PrivateNetwork `json:"private-networks,omitempty"`
	// Nodepool Security Groups
	SecurityGroups []SecurityGroup   `json:"security-groups,omitempty"`
	Taints         SKSNodepoolTaints `json:"taints,omitempty"`
}

// Update an SKS Nodepool
func (c Client) UpdateSKSNodepool(ctx context.Context, id UUID, sksNodepoolID UUID, req UpdateSKSNodepoolRequest) (*Operation, error) {
	path := fmt.Sprintf("/sks-cluster/%v/nodepool/%v", id, sksNodepoolID)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateSKSNodepool: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateSKSNodepool: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateSKSNodepool: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateSKSNodepool: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-sks-nodepool")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateSKSNodepool: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateSKSNodepool: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateSKSNodepool: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ResetSKSNodepoolFieldField string

const (
	ResetSKSNodepoolFieldFieldAntiAffinityGroups ResetSKSNodepoolFieldField = "anti-affinity-groups"
	ResetSKSNodepoolFieldFieldDescription        ResetSKSNodepoolFieldField = "description"
	ResetSKSNodepoolFieldFieldLabels             ResetSKSNodepoolFieldField = "labels"
	ResetSKSNodepoolFieldFieldSecurityGroups     ResetSKSNodepoolFieldField = "security-groups"
	ResetSKSNodepoolFieldFieldPrivateNetworks    ResetSKSNodepoolFieldField = "private-networks"
	ResetSKSNodepoolFieldFieldDeployTarget       ResetSKSNodepoolFieldField = "deploy-target"
)

// Reset an SKS Nodepool field to its default value
func (c Client) ResetSKSNodepoolField(ctx context.Context, id UUID, sksNodepoolID UUID, field ResetSKSNodepoolFieldField) (*Operation, error) {
	path := fmt.Sprintf("/sks-cluster/%v/nodepool/%v/%v", id, sksNodepoolID, field)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ResetSKSNodepoolField: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ResetSKSNodepoolField: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ResetSKSNodepoolField: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reset-sks-nodepool-field")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ResetSKSNodepoolField: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ResetSKSNodepoolField: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ResetSKSNodepoolField: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type EvictSKSNodepoolMembersRequest struct {
	Instances []UUID `json:"instances,omitempty"`
}

// This operation evicts the specified Compute instances member from the Nodepool, shrinking it to `&lt;current nodepool size&gt; - &lt;# evicted members&gt;`.
func (c Client) EvictSKSNodepoolMembers(ctx context.Context, id UUID, sksNodepoolID UUID, req EvictSKSNodepoolMembersRequest) (*Operation, error) {
	path := fmt.Sprintf("/sks-cluster/%v/nodepool/%v:evict", id, sksNodepoolID)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("EvictSKSNodepoolMembers: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("EvictSKSNodepoolMembers: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("EvictSKSNodepoolMembers: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("EvictSKSNodepoolMembers: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "evict-sks-nodepool-members")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("EvictSKSNodepoolMembers: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("EvictSKSNodepoolMembers: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("EvictSKSNodepoolMembers: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ScaleSKSNodepoolRequest struct {
	// Number of instances
	Size int64 `json:"size" validate:"required,gt=0"`
}

// Scale a SKS Nodepool
func (c Client) ScaleSKSNodepool(ctx context.Context, id UUID, sksNodepoolID UUID, req ScaleSKSNodepoolRequest) (*Operation, error) {
	path := fmt.Sprintf("/sks-cluster/%v/nodepool/%v:scale", id, sksNodepoolID)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("ScaleSKSNodepool: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("ScaleSKSNodepool: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ScaleSKSNodepool: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ScaleSKSNodepool: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "scale-sks-nodepool")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ScaleSKSNodepool: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ScaleSKSNodepool: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ScaleSKSNodepool: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Rotate Exoscale CCM credentials
func (c Client) RotateSKSCcmCredentials(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/sks-cluster/%v/rotate-ccm-credentials", id)

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("RotateSKSCcmCredentials: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("RotateSKSCcmCredentials: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("RotateSKSCcmCredentials: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "rotate-sks-ccm-credentials")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("RotateSKSCcmCredentials: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("RotateSKSCcmCredentials: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("RotateSKSCcmCredentials: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Rotate operators certificate authority
func (c Client) RotateSKSOperatorsCA(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/sks-cluster/%v/rotate-operators-ca", id)

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("RotateSKSOperatorsCA: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("RotateSKSOperatorsCA: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("RotateSKSOperatorsCA: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "rotate-sks-operators-ca")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("RotateSKSOperatorsCA: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("RotateSKSOperatorsCA: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("RotateSKSOperatorsCA: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type UpgradeSKSClusterRequest struct {
	// Control plane Kubernetes version
	Version string `json:"version" validate:"required"`
}

// Upgrade an SKS cluster
func (c Client) UpgradeSKSCluster(ctx context.Context, id UUID, req UpgradeSKSClusterRequest) (*Operation, error) {
	path := fmt.Sprintf("/sks-cluster/%v/upgrade", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpgradeSKSCluster: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpgradeSKSCluster: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpgradeSKSCluster: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpgradeSKSCluster: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "upgrade-sks-cluster")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpgradeSKSCluster: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpgradeSKSCluster: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpgradeSKSCluster: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Upgrade a SKS cluster to pro
func (c Client) UpgradeSKSClusterServiceLevel(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/sks-cluster/%v/upgrade-service-level", id)

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("UpgradeSKSClusterServiceLevel: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpgradeSKSClusterServiceLevel: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpgradeSKSClusterServiceLevel: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "upgrade-sks-cluster-service-level")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpgradeSKSClusterServiceLevel: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpgradeSKSClusterServiceLevel: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpgradeSKSClusterServiceLevel: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ResetSKSClusterFieldField string

const (
	ResetSKSClusterFieldFieldDescription ResetSKSClusterFieldField = "description"
	ResetSKSClusterFieldFieldLabels      ResetSKSClusterFieldField = "labels"
)

// Reset an SKS cluster field to its default value
func (c Client) ResetSKSClusterField(ctx context.Context, id UUID, field ResetSKSClusterFieldField) (*Operation, error) {
	path := fmt.Sprintf("/sks-cluster/%v/%v", id, field)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ResetSKSClusterField: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ResetSKSClusterField: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ResetSKSClusterField: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "reset-sks-cluster-field")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ResetSKSClusterField: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ResetSKSClusterField: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ResetSKSClusterField: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ListSnapshotsResponse struct {
	Snapshots []Snapshot `json:"snapshots,omitempty"`
}

// FindSnapshot attempts to find an Snapshot by nameOrID.
func (l ListSnapshotsResponse) FindSnapshot(nameOrID string) (Snapshot, error) {
	for i, elem := range l.Snapshots {
		if string(elem.Name) == nameOrID || elem.ID.String() == nameOrID {
			return l.Snapshots[i], nil
		}
	}

	return Snapshot{}, fmt.Errorf("%q not found in ListSnapshotsResponse: %w", nameOrID, ErrNotFound)
}

// List Snapshots
func (c Client) ListSnapshots(ctx context.Context) (*ListSnapshotsResponse, error) {
	path := "/snapshot"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListSnapshots: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListSnapshots: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListSnapshots: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-snapshots")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListSnapshots: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListSnapshots: http response: %w", err)
	}

	bodyresp := &ListSnapshotsResponse{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListSnapshots: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Delete a Snapshot
func (c Client) DeleteSnapshot(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/snapshot/%v", id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteSnapshot: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteSnapshot: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteSnapshot: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-snapshot")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteSnapshot: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteSnapshot: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteSnapshot: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve Snapshot details
func (c Client) GetSnapshot(ctx context.Context, id UUID) (*Snapshot, error) {
	path := fmt.Sprintf("/snapshot/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetSnapshot: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetSnapshot: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetSnapshot: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-snapshot")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetSnapshot: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetSnapshot: http response: %w", err)
	}

	bodyresp := &Snapshot{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetSnapshot: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Export a Snapshot
func (c Client) ExportSnapshot(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/snapshot/%v:export", id)

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ExportSnapshot: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ExportSnapshot: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ExportSnapshot: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "export-snapshot")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ExportSnapshot: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ExportSnapshot: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ExportSnapshot: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type PromoteSnapshotToTemplateRequest struct {
	// Template default user
	DefaultUser string `json:"default-user,omitempty" validate:"omitempty,gte=1,lte=255"`
	// Template description
	Description string `json:"description,omitempty" validate:"omitempty,lte=4096"`
	// Template name
	Name string `json:"name" validate:"required,gte=1,lte=255"`
	// Enable password-based login in the template
	PasswordEnabled *bool `json:"password-enabled,omitempty"`
	// Enable SSH key-based login in the template
	SSHKeyEnabled *bool `json:"ssh-key-enabled,omitempty"`
}

// Promote a Snapshot to a Template
func (c Client) PromoteSnapshotToTemplate(ctx context.Context, id UUID, req PromoteSnapshotToTemplateRequest) (*Operation, error) {
	path := fmt.Sprintf("/snapshot/%v:promote", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("PromoteSnapshotToTemplate: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("PromoteSnapshotToTemplate: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("PromoteSnapshotToTemplate: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("PromoteSnapshotToTemplate: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "promote-snapshot-to-template")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("PromoteSnapshotToTemplate: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("PromoteSnapshotToTemplate: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("PromoteSnapshotToTemplate: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ListSOSBucketsUsageResponse struct {
	SOSBucketsUsage []SOSBucketUsage `json:"sos-buckets-usage,omitempty"`
}

// FindSOSBucketUsage attempts to find an SOSBucketUsage by name.
func (l ListSOSBucketsUsageResponse) FindSOSBucketUsage(name string) (SOSBucketUsage, error) {
	for i, elem := range l.SOSBucketsUsage {
		if string(elem.Name) == name {
			return l.SOSBucketsUsage[i], nil
		}
	}

	return SOSBucketUsage{}, fmt.Errorf("%q not found in ListSOSBucketsUsageResponse: %w", name, ErrNotFound)
}

// List SOS Buckets Usage
func (c Client) ListSOSBucketsUsage(ctx context.Context) (*ListSOSBucketsUsageResponse, error) {
	path := "/sos-buckets-usage"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListSOSBucketsUsage: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListSOSBucketsUsage: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListSOSBucketsUsage: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-sos-buckets-usage")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListSOSBucketsUsage: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListSOSBucketsUsage: http response: %w", err)
	}

	bodyresp := &ListSOSBucketsUsageResponse{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListSOSBucketsUsage: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type GetSOSPresignedURLResponse struct {
	URL string `json:"url,omitempty"`
}

type GetSOSPresignedURLOpt func(url.Values)

func GetSOSPresignedURLWithKey(key string) GetSOSPresignedURLOpt {
	return func(q url.Values) {
		q.Add("key", fmt.Sprint(key))
	}
}

// Generates Presigned Download URL for SOS object
func (c Client) GetSOSPresignedURL(ctx context.Context, bucket string, opts ...GetSOSPresignedURLOpt) (*GetSOSPresignedURLResponse, error) {
	path := fmt.Sprintf("/sos/%v/presigned-url", bucket)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetSOSPresignedURL: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if len(opts) > 0 {
		q := request.URL.Query()
		for _, opt := range opts {
			opt(q)
		}
		request.URL.RawQuery = q.Encode()
	}

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetSOSPresignedURL: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetSOSPresignedURL: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-sos-presigned-url")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetSOSPresignedURL: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetSOSPresignedURL: http response: %w", err)
	}

	bodyresp := &GetSOSPresignedURLResponse{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetSOSPresignedURL: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ListSSHKeysResponse struct {
	SSHKeys []SSHKey `json:"ssh-keys,omitempty"`
}

// FindSSHKey attempts to find an SSHKey by name.
func (l ListSSHKeysResponse) FindSSHKey(name string) (SSHKey, error) {
	for i, elem := range l.SSHKeys {
		if string(elem.Name) == name {
			return l.SSHKeys[i], nil
		}
	}

	return SSHKey{}, fmt.Errorf("%q not found in ListSSHKeysResponse: %w", name, ErrNotFound)
}

// List SSH keys
func (c Client) ListSSHKeys(ctx context.Context) (*ListSSHKeysResponse, error) {
	path := "/ssh-key"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListSSHKeys: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListSSHKeys: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListSSHKeys: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-ssh-keys")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListSSHKeys: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListSSHKeys: http response: %w", err)
	}

	bodyresp := &ListSSHKeysResponse{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListSSHKeys: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type RegisterSSHKeyRequest struct {
	// SSH key name
	Name string `json:"name" validate:"required"`
	// Public key value
	PublicKey string `json:"public-key" validate:"required"`
}

// Import SSH key
func (c Client) RegisterSSHKey(ctx context.Context, req RegisterSSHKeyRequest) (*Operation, error) {
	path := "/ssh-key"

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("RegisterSSHKey: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("RegisterSSHKey: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("RegisterSSHKey: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("RegisterSSHKey: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "register-ssh-key")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("RegisterSSHKey: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("RegisterSSHKey: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("RegisterSSHKey: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Delete a SSH key
func (c Client) DeleteSSHKey(ctx context.Context, name string) (*Operation, error) {
	path := fmt.Sprintf("/ssh-key/%v", name)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteSSHKey: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteSSHKey: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteSSHKey: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-ssh-key")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteSSHKey: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteSSHKey: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteSSHKey: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve SSH key details
func (c Client) GetSSHKey(ctx context.Context, name string) (*SSHKey, error) {
	path := fmt.Sprintf("/ssh-key/%v", name)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetSSHKey: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetSSHKey: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetSSHKey: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-ssh-key")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetSSHKey: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetSSHKey: http response: %w", err)
	}

	bodyresp := &SSHKey{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetSSHKey: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ListTemplatesResponse struct {
	Templates []Template `json:"templates,omitempty"`
}

// FindTemplate attempts to find an Template by nameOrID.
func (l ListTemplatesResponse) FindTemplate(nameOrID string) (Template, error) {
	for i, elem := range l.Templates {
		if string(elem.Name) == nameOrID || elem.ID.String() == nameOrID {
			return l.Templates[i], nil
		}
	}

	return Template{}, fmt.Errorf("%q not found in ListTemplatesResponse: %w", nameOrID, ErrNotFound)
}

type ListTemplatesVisibility string

const (
	ListTemplatesVisibilityPrivate ListTemplatesVisibility = "private"
	ListTemplatesVisibilityPublic  ListTemplatesVisibility = "public"
)

type ListTemplatesOpt func(url.Values)

func ListTemplatesWithVisibility(visibility ListTemplatesVisibility) ListTemplatesOpt {
	return func(q url.Values) {
		q.Add("visibility", fmt.Sprint(visibility))
	}
}

func ListTemplatesWithFamily(family string) ListTemplatesOpt {
	return func(q url.Values) {
		q.Add("family", fmt.Sprint(family))
	}
}

// List Templates
func (c Client) ListTemplates(ctx context.Context, opts ...ListTemplatesOpt) (*ListTemplatesResponse, error) {
	path := "/template"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListTemplates: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if len(opts) > 0 {
		q := request.URL.Query()
		for _, opt := range opts {
			opt(q)
		}
		request.URL.RawQuery = q.Encode()
	}

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListTemplates: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListTemplates: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-templates")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListTemplates: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListTemplates: http response: %w", err)
	}

	bodyresp := &ListTemplatesResponse{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListTemplates: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type RegisterTemplateRequestBootMode string

const (
	RegisterTemplateRequestBootModeLegacy RegisterTemplateRequestBootMode = "legacy"
	RegisterTemplateRequestBootModeUefi   RegisterTemplateRequestBootMode = "uefi"
)

type RegisterTemplateRequest struct {
	// Boot mode (default: legacy)
	BootMode RegisterTemplateRequestBootMode `json:"boot-mode,omitempty"`
	// Template build
	Build string `json:"build,omitempty" validate:"omitempty,gte=1,lte=255"`
	// Template MD5 checksum
	Checksum string `json:"checksum" validate:"required,gte=1"`
	// Template default user
	DefaultUser string `json:"default-user,omitempty" validate:"omitempty,gte=1,lte=255"`
	// Template description
	Description string `json:"description,omitempty" validate:"omitempty,lte=255"`
	// Template maintainer
	Maintainer string `json:"maintainer,omitempty" validate:"omitempty,gte=1,lte=255"`
	// Template name
	Name string `json:"name" validate:"required,gte=1,lte=255"`
	// Enable password-based login
	PasswordEnabled *bool `json:"password-enabled" validate:"required"`
	// Template size
	Size int64 `json:"size,omitempty" validate:"omitempty,gt=0"`
	// Enable SSH key-based login
	SSHKeyEnabled *bool `json:"ssh-key-enabled" validate:"required"`
	// Template source URL
	URL string `json:"url" validate:"required,gte=1"`
	// Template version
	Version string `json:"version,omitempty" validate:"omitempty,gte=1,lte=255"`
}

// Register a Template
func (c Client) RegisterTemplate(ctx context.Context, req RegisterTemplateRequest) (*Operation, error) {
	path := "/template"

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("RegisterTemplate: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("RegisterTemplate: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("RegisterTemplate: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("RegisterTemplate: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "register-template")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("RegisterTemplate: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("RegisterTemplate: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("RegisterTemplate: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Delete a Template
func (c Client) DeleteTemplate(ctx context.Context, id UUID) (*Operation, error) {
	path := fmt.Sprintf("/template/%v", id)

	request, err := http.NewRequestWithContext(ctx, "DELETE", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("DeleteTemplate: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("DeleteTemplate: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("DeleteTemplate: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "delete-template")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("DeleteTemplate: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("DeleteTemplate: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("DeleteTemplate: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

// Retrieve Template details
func (c Client) GetTemplate(ctx context.Context, id UUID) (*Template, error) {
	path := fmt.Sprintf("/template/%v", id)

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("GetTemplate: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("GetTemplate: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("GetTemplate: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "get-template")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("GetTemplate: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("GetTemplate: http response: %w", err)
	}

	bodyresp := &Template{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("GetTemplate: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type CopyTemplateRequest struct {
	// Zone
	TargetZone *Zone `json:"target-zone" validate:"required"`
}

// Copy a Template from a zone to another
func (c Client) CopyTemplate(ctx context.Context, id UUID, req CopyTemplateRequest) (*Operation, error) {
	path := fmt.Sprintf("/template/%v", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("CopyTemplate: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "POST", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("CopyTemplate: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("CopyTemplate: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("CopyTemplate: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "copy-template")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("CopyTemplate: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("CopyTemplate: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("CopyTemplate: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type UpdateTemplateRequest struct {
	// Template Description
	Description string `json:"description,omitempty" validate:"omitempty,lte=255"`
	// Template name
	Name string `json:"name,omitempty" validate:"omitempty,gte=1,lte=255"`
}

// Update template attributes
func (c Client) UpdateTemplate(ctx context.Context, id UUID, req UpdateTemplateRequest) (*Operation, error) {
	path := fmt.Sprintf("/template/%v", id)

	body, err := prepareJSONBody(req)
	if err != nil {
		return nil, fmt.Errorf("UpdateTemplate: prepare Json body: %w", err)
	}

	request, err := http.NewRequestWithContext(ctx, "PUT", c.serverEndpoint+path, body)
	if err != nil {
		return nil, fmt.Errorf("UpdateTemplate: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	request.Header.Add("Content-Type", "application/json")

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("UpdateTemplate: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("UpdateTemplate: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "update-template")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("UpdateTemplate: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("UpdateTemplate: http response: %w", err)
	}

	bodyresp := &Operation{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("UpdateTemplate: prepare Json response: %w", err)
	}

	return bodyresp, nil
}

type ListZonesResponse struct {
	Zones []Zone `json:"zones,omitempty"`
}

// FindZone attempts to find an Zone by name.
func (l ListZonesResponse) FindZone(name string) (Zone, error) {
	for i, elem := range l.Zones {
		if string(elem.Name) == name {
			return l.Zones[i], nil
		}
	}

	return Zone{}, fmt.Errorf("%q not found in ListZonesResponse: %w", name, ErrNotFound)
}

// List Zones
func (c Client) ListZones(ctx context.Context) (*ListZonesResponse, error) {
	path := "/zone"

	request, err := http.NewRequestWithContext(ctx, "GET", c.serverEndpoint+path, nil)
	if err != nil {
		return nil, fmt.Errorf("ListZones: new request: %w", err)
	}
	request.Header.Add("User-Agent", UserAgent)

	if err := c.executeRequestInterceptors(ctx, request); err != nil {
		return nil, fmt.Errorf("ListZones: execute request editors: %w", err)
	}

	if err := c.signRequest(request); err != nil {
		return nil, fmt.Errorf("ListZones: sign request: %w", err)
	}

	if c.trace {
		dumpRequest(request, "list-zones")
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, fmt.Errorf("ListZones: http client do: %w", err)
	}

	if c.trace {
		dumpResponse(response)
	}

	if err := handleHTTPErrorResp(response); err != nil {
		return nil, fmt.Errorf("ListZones: http response: %w", err)
	}

	bodyresp := &ListZonesResponse{}
	if err := prepareJSONResponse(response, bodyresp); err != nil {
		return nil, fmt.Errorf("ListZones: prepare Json response: %w", err)
	}

	return bodyresp, nil
}
