Compare commits

...

7 Commits

Author SHA1 Message Date
Oscar Hermoso 239e48e940 🎒 allow updating of the server backups property (#55) 2024-12-15 09:30:27 +08:00
dependabot[bot] 2221f8c853 🐹 Bump golang.org/x/crypto from 0.29.0 to 0.31.0 (#54)
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.29.0 to 0.31.0.
- [Commits](https://github.com/golang/crypto/compare/v0.29.0...v0.31.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-14 09:13:10 +08:00
dependabot[bot] 95487045c4 🐹 Bump github.com/hashicorp/terraform-plugin-framework-validators (#53)
Bumps the minor-patch group with 1 update: [github.com/hashicorp/terraform-plugin-framework-validators](https://github.com/hashicorp/terraform-plugin-framework-validators).


Updates `github.com/hashicorp/terraform-plugin-framework-validators` from 0.15.0 to 0.16.0
- [Release notes](https://github.com/hashicorp/terraform-plugin-framework-validators/releases)
- [Changelog](https://github.com/hashicorp/terraform-plugin-framework-validators/blob/main/CHANGELOG.md)
- [Commits](https://github.com/hashicorp/terraform-plugin-framework-validators/compare/v0.15.0...v0.16.0)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/terraform-plugin-framework-validators
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: minor-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-14 08:58:38 +08:00
Oscar Hermoso 7f5bae6b15 💾 allow customising server memory and disk (#52) 2024-12-08 17:09:54 +08:00
Oscar Hermoso 4ef9df6edf 🧁 allow update of server vpc_id without recreating resource, update api (#51) 2024-12-08 08:20:21 +08:00
dependabot[bot] 547763d639 🐹 Bump github.com/hashicorp/terraform-plugin-docs (#49)
Bumps the minor-patch group with 1 update: [github.com/hashicorp/terraform-plugin-docs](https://github.com/hashicorp/terraform-plugin-docs).


Updates `github.com/hashicorp/terraform-plugin-docs` from 0.20.0 to 0.20.1
- [Release notes](https://github.com/hashicorp/terraform-plugin-docs/releases)
- [Changelog](https://github.com/hashicorp/terraform-plugin-docs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/hashicorp/terraform-plugin-docs/compare/v0.20.0...v0.20.1)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/terraform-plugin-docs
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-29 07:22:41 +08:00
Oscar Hermoso f5fecdd69c 👯 consistent headings/curl summary for parameters in README 2024-11-22 10:40:17 +08:00
14 changed files with 475 additions and 939 deletions
+30 -22
View File
@@ -39,9 +39,35 @@ Planned features:
- [ ] Virtual Private Cloud
- [ ] Kubernetes
## Parameters
## Server parameters
Images:
### Regions
<details>
<summary>curl for regions</summary>
```sh
curl -X GET "https://api.binarylane.com.au/v2/regions" \
-H "Authorization: Bearer $BINARYLANE_API_TOKEN" > tmp/regions.json
jq '[ .regions[] | .slug ] | sort' tmp/regions.json
```
</details>
```json
[
"bne",
"mel",
"per",
"sin",
"syd"
]
```
### Images
<details>
<summary>curl for images</summary>
```sh
curl -X GET "https://api.binarylane.com.au/v2/images?type=distribution&&page=1&per_page=200" \
@@ -49,6 +75,7 @@ curl -X GET "https://api.binarylane.com.au/v2/images?type=distribution&&page=1&p
jq '[ .images[] | .slug ] | sort' tmp/images.json
```
</details>
```json
[
@@ -78,29 +105,10 @@ jq '[ .images[] | .slug ] | sort' tmp/images.json
]
```
Regions:
```sh
curl -X GET "https://api.binarylane.com.au/v2/regions" \
-H "Authorization: Bearer $BINARYLANE_API_TOKEN" > tmp/regions.json
jq '[ .regions[] | .slug ] | sort' tmp/regions.json
```
```json
[
"bne",
"mel",
"per",
"sin",
"syd"
]
```
### Sizes
<details>
<summary>VM size</summary>
<summary>curl for sizes</summary>
```sh
curl -X GET "https://api.binarylane.com.au/v2/sizes" \
+2
View File
@@ -22,7 +22,9 @@ Provides a Binary Lane Server data source. This can be used to read existing ser
### Read-Only
- `backups` (Boolean) If true this will enable two daily backups for the server. `options.daily_backups` will override this value if provided. Setting this to false has no effect.
- `disk` (Number) The amount of storage in GB assigned to the server.
- `image` (String) The slug of the selected operating system.
- `memory` (Number) The amount of memory in MB assigned to the server.
- `name` (String) The hostname of your server, such as vps01.yourcompany.com. If not provided, the server will be created with a random name.
- `permalink` (String) A randomly generated two-word identifier assigned to servers in regions that support this feature
- `port_blocking` (Boolean) Port blocking of outgoing connections for email, SSH and Remote Desktop (TCP ports 22, 25, and 3389) is enabled by default for all new servers. If this is false port blocking will be disabled. Disabling port blocking is only available to reviewed accounts.
+14
View File
@@ -25,6 +25,20 @@ Provides a Binary Lane Server resource. This can be used to create and delete se
### Optional
- `backups` (Boolean) If true this will enable two daily backups for the server. `options.daily_backups` will override this value if provided. Setting this to false has no effect.
- `disk` (Number) The total storage in GB for this server. If specified this is the absolute value, not just the additional storage above what is included in the size.
Leave null to accept the default for the size if this is a new server or a resize to a different base size,
or to keep the current value if this a resize with the same base size but different options. Valid values:
- must be a multiple of 5
- \> 60GB must be a multiple of 10
- \> 200GB must be a multiple of 100
- `memory` (Number) The total memory in MB for this server. If specified this is the absolute value, not just the
additional memory above what is included in the size. Leave null to accept the default for the size if this is a new
server or a resize to a different base size, or to keep the current value if this a resize with the same base size
but different options. Valid values:
- must be a multiple of 128
- \> 2048MB must be a multiple of 1024
- \> 16384MB must be a multiple of 2048
- \> 24576MB must be a multiple of 4096
- `name` (String) The hostname of your server, such as vps01.yourcompany.com. If not provided, the server will be created with a random name.
- `password` (String, Sensitive) If this is provided the specified or default remote user's account password will be set to this value. Only valid if the server supports password change actions. If omitted and the server supports password change actions a random password will be generated and emailed to the account email address.
- `port_blocking` (Boolean) Port blocking of outgoing connections for email, SSH and Remote Desktop (TCP ports 22, 25, and 3389) is enabled by default for all new servers. If this is false port blocking will be disabled. Disabling port blocking is only available to reviewed accounts.
+6 -6
View File
@@ -6,10 +6,10 @@ require (
github.com/deepmap/oapi-codegen v1.16.3
github.com/hashicorp/terraform-plugin-codegen-framework v0.4.1
github.com/hashicorp/terraform-plugin-codegen-openapi v0.3.0
github.com/hashicorp/terraform-plugin-docs v0.20.0
github.com/hashicorp/terraform-plugin-docs v0.20.1
github.com/hashicorp/terraform-plugin-framework v1.13.0
github.com/hashicorp/terraform-plugin-framework-timeouts v0.4.1
github.com/hashicorp/terraform-plugin-framework-validators v0.15.0
github.com/hashicorp/terraform-plugin-framework-validators v0.16.0
github.com/hashicorp/terraform-plugin-go v0.25.0
github.com/hashicorp/terraform-plugin-log v0.9.0
github.com/hashicorp/terraform-plugin-testing v1.11.0
@@ -99,13 +99,13 @@ require (
github.com/yuin/goldmark-meta v1.1.0 // indirect
github.com/zclconf/go-cty v1.15.0 // indirect
go.abhg.dev/goldmark/frontmatter v0.2.0 // indirect
golang.org/x/crypto v0.29.0 // indirect
golang.org/x/crypto v0.31.0 // indirect
golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8 // indirect
golang.org/x/mod v0.21.0 // indirect
golang.org/x/net v0.30.0 // indirect
golang.org/x/sync v0.9.0 // indirect
golang.org/x/sys v0.27.0 // indirect
golang.org/x/text v0.20.0 // indirect
golang.org/x/sync v0.10.0 // indirect
golang.org/x/sys v0.28.0 // indirect
golang.org/x/text v0.21.0 // indirect
golang.org/x/tools v0.22.0 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38 // indirect
+12 -12
View File
@@ -145,14 +145,14 @@ github.com/hashicorp/terraform-plugin-codegen-openapi v0.3.0 h1:IKpc337XKk50QyQP
github.com/hashicorp/terraform-plugin-codegen-openapi v0.3.0/go.mod h1:tT6wl80h7nsMBw+1yZRgJXi+Ys85PUai11weDqysvp4=
github.com/hashicorp/terraform-plugin-codegen-spec v0.2.0 h1:91dQG1A/DxP6vRz9GiytDTrZTXDbhHPvmpYnAyWA/Vw=
github.com/hashicorp/terraform-plugin-codegen-spec v0.2.0/go.mod h1:fywrEKpordQypmAjz/HIfm2LuNVmyJ6KDe8XT9GdJxQ=
github.com/hashicorp/terraform-plugin-docs v0.20.0 h1:ox7rm1FN0dVZaJBUzkVVh10R1r3+FeMQWL0QopQ9d7o=
github.com/hashicorp/terraform-plugin-docs v0.20.0/go.mod h1:A/+4SVMdAkQYtIBtaxV0H7AU862TxVZk/hhKaMDQB6Y=
github.com/hashicorp/terraform-plugin-docs v0.20.1 h1:Fq7E/HrU8kuZu3hNliZGwloFWSYfWEOWnylFhYQIoys=
github.com/hashicorp/terraform-plugin-docs v0.20.1/go.mod h1:Yz6HoK7/EgzSrHPB9J/lWFzwl9/xep2OPnc5jaJDV90=
github.com/hashicorp/terraform-plugin-framework v1.13.0 h1:8OTG4+oZUfKgnfTdPTJwZ532Bh2BobF4H+yBiYJ/scw=
github.com/hashicorp/terraform-plugin-framework v1.13.0/go.mod h1:j64rwMGpgM3NYXTKuxrCnyubQb/4VKldEKlcG8cvmjU=
github.com/hashicorp/terraform-plugin-framework-timeouts v0.4.1 h1:gm5b1kHgFFhaKFhm4h2TgvMUlNzFAtUqlcOWnWPm+9E=
github.com/hashicorp/terraform-plugin-framework-timeouts v0.4.1/go.mod h1:MsjL1sQ9L7wGwzJ5RjcI6FzEMdyoBnw+XK8ZnOvQOLY=
github.com/hashicorp/terraform-plugin-framework-validators v0.15.0 h1:RXMmu7JgpFjnI1a5QjMCBb11usrW2OtAG+iOTIj5c9Y=
github.com/hashicorp/terraform-plugin-framework-validators v0.15.0/go.mod h1:Bh89/hNmqsEWug4/XWKYBwtnw3tbz5BAy1L1OgvbIaY=
github.com/hashicorp/terraform-plugin-framework-validators v0.16.0 h1:O9QqGoYDzQT7lwTXUsZEtgabeWW96zUBh47Smn2lkFA=
github.com/hashicorp/terraform-plugin-framework-validators v0.16.0/go.mod h1:Bh89/hNmqsEWug4/XWKYBwtnw3tbz5BAy1L1OgvbIaY=
github.com/hashicorp/terraform-plugin-go v0.25.0 h1:oi13cx7xXA6QciMcpcFi/rwA974rdTxjqEhXJjbAyks=
github.com/hashicorp/terraform-plugin-go v0.25.0/go.mod h1:+SYagMYadJP86Kvn+TGeV+ofr/R3g4/If0O5sO96MVw=
github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0=
@@ -319,8 +319,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ=
golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg=
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8 h1:ESSUROHIBHg7USnszlcdmjBEwdMj9VUvU+OPk4yl2mc=
golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
@@ -343,8 +343,8 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -370,8 +370,8 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
@@ -382,8 +382,8 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+8 -472
View File
@@ -197,17 +197,6 @@ type ClientInterface interface {
union json.RawMessage
}, recordId int64, body PutDomainsDomainNameRecordsRecordIdJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error)
// GetFailoverIpsServerId request
GetFailoverIpsServerId(ctx context.Context, serverId int64, params *GetFailoverIpsServerIdParams, reqEditors ...RequestEditorFn) (*http.Response, error)
// PostFailoverIpsServerIdWithBody request with any body
PostFailoverIpsServerIdWithBody(ctx context.Context, serverId int64, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error)
PostFailoverIpsServerId(ctx context.Context, serverId int64, body PostFailoverIpsServerIdJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error)
// GetFailoverIpsServerIdAvailable request
GetFailoverIpsServerIdAvailable(ctx context.Context, serverId int64, params *GetFailoverIpsServerIdAvailableParams, reqEditors ...RequestEditorFn) (*http.Response, error)
// GetImages request
GetImages(ctx context.Context, params *GetImagesParams, reqEditors ...RequestEditorFn) (*http.Response, error)
@@ -987,54 +976,6 @@ func (c *Client) PutDomainsDomainNameRecordsRecordId(ctx context.Context, domain
return c.Client.Do(req)
}
func (c *Client) GetFailoverIpsServerId(ctx context.Context, serverId int64, params *GetFailoverIpsServerIdParams, reqEditors ...RequestEditorFn) (*http.Response, error) {
req, err := NewGetFailoverIpsServerIdRequest(c.Server, serverId, params)
if err != nil {
return nil, err
}
req = req.WithContext(ctx)
if err := c.applyEditors(ctx, req, reqEditors); err != nil {
return nil, err
}
return c.Client.Do(req)
}
func (c *Client) PostFailoverIpsServerIdWithBody(ctx context.Context, serverId int64, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) {
req, err := NewPostFailoverIpsServerIdRequestWithBody(c.Server, serverId, contentType, body)
if err != nil {
return nil, err
}
req = req.WithContext(ctx)
if err := c.applyEditors(ctx, req, reqEditors); err != nil {
return nil, err
}
return c.Client.Do(req)
}
func (c *Client) PostFailoverIpsServerId(ctx context.Context, serverId int64, body PostFailoverIpsServerIdJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) {
req, err := NewPostFailoverIpsServerIdRequest(c.Server, serverId, body)
if err != nil {
return nil, err
}
req = req.WithContext(ctx)
if err := c.applyEditors(ctx, req, reqEditors); err != nil {
return nil, err
}
return c.Client.Do(req)
}
func (c *Client) GetFailoverIpsServerIdAvailable(ctx context.Context, serverId int64, params *GetFailoverIpsServerIdAvailableParams, reqEditors ...RequestEditorFn) (*http.Response, error) {
req, err := NewGetFailoverIpsServerIdAvailableRequest(c.Server, serverId, params)
if err != nil {
return nil, err
}
req = req.WithContext(ctx)
if err := c.applyEditors(ctx, req, reqEditors); err != nil {
return nil, err
}
return c.Client.Do(req)
}
func (c *Client) GetImages(ctx context.Context, params *GetImagesParams, reqEditors ...RequestEditorFn) (*http.Response, error) {
req, err := NewGetImagesRequest(c.Server, params)
if err != nil {
@@ -3920,197 +3861,6 @@ func NewPutDomainsDomainNameRecordsRecordIdRequestWithBody(server string, domain
return req, nil
}
// NewGetFailoverIpsServerIdRequest generates requests for GetFailoverIpsServerId
func NewGetFailoverIpsServerIdRequest(server string, serverId int64, params *GetFailoverIpsServerIdParams) (*http.Request, error) {
var err error
var pathParam0 string
pathParam0, err = runtime.StyleParamWithLocation("simple", false, "server_id", runtime.ParamLocationPath, serverId)
if err != nil {
return nil, err
}
serverURL, err := url.Parse(server)
if err != nil {
return nil, err
}
operationPath := fmt.Sprintf("/failover_ips/%s", pathParam0)
if operationPath[0] == '/' {
operationPath = "." + operationPath
}
queryURL, err := serverURL.Parse(operationPath)
if err != nil {
return nil, err
}
if params != nil {
queryValues := queryURL.Query()
if params.Page != nil {
if queryFrag, err := runtime.StyleParamWithLocation("form", true, "page", runtime.ParamLocationQuery, *params.Page); err != nil {
return nil, err
} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
return nil, err
} else {
for k, v := range parsed {
for _, v2 := range v {
queryValues.Add(k, v2)
}
}
}
}
if params.PerPage != nil {
if queryFrag, err := runtime.StyleParamWithLocation("form", true, "per_page", runtime.ParamLocationQuery, *params.PerPage); err != nil {
return nil, err
} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
return nil, err
} else {
for k, v := range parsed {
for _, v2 := range v {
queryValues.Add(k, v2)
}
}
}
}
queryURL.RawQuery = queryValues.Encode()
}
req, err := http.NewRequest("GET", queryURL.String(), nil)
if err != nil {
return nil, err
}
return req, nil
}
// NewPostFailoverIpsServerIdRequest calls the generic PostFailoverIpsServerId builder with application/json body
func NewPostFailoverIpsServerIdRequest(server string, serverId int64, body PostFailoverIpsServerIdJSONRequestBody) (*http.Request, error) {
var bodyReader io.Reader
buf, err := json.Marshal(body)
if err != nil {
return nil, err
}
bodyReader = bytes.NewReader(buf)
return NewPostFailoverIpsServerIdRequestWithBody(server, serverId, "application/json", bodyReader)
}
// NewPostFailoverIpsServerIdRequestWithBody generates requests for PostFailoverIpsServerId with any type of body
func NewPostFailoverIpsServerIdRequestWithBody(server string, serverId int64, contentType string, body io.Reader) (*http.Request, error) {
var err error
var pathParam0 string
pathParam0, err = runtime.StyleParamWithLocation("simple", false, "server_id", runtime.ParamLocationPath, serverId)
if err != nil {
return nil, err
}
serverURL, err := url.Parse(server)
if err != nil {
return nil, err
}
operationPath := fmt.Sprintf("/failover_ips/%s", pathParam0)
if operationPath[0] == '/' {
operationPath = "." + operationPath
}
queryURL, err := serverURL.Parse(operationPath)
if err != nil {
return nil, err
}
req, err := http.NewRequest("POST", queryURL.String(), body)
if err != nil {
return nil, err
}
req.Header.Add("Content-Type", contentType)
return req, nil
}
// NewGetFailoverIpsServerIdAvailableRequest generates requests for GetFailoverIpsServerIdAvailable
func NewGetFailoverIpsServerIdAvailableRequest(server string, serverId int64, params *GetFailoverIpsServerIdAvailableParams) (*http.Request, error) {
var err error
var pathParam0 string
pathParam0, err = runtime.StyleParamWithLocation("simple", false, "server_id", runtime.ParamLocationPath, serverId)
if err != nil {
return nil, err
}
serverURL, err := url.Parse(server)
if err != nil {
return nil, err
}
operationPath := fmt.Sprintf("/failover_ips/%s/available", pathParam0)
if operationPath[0] == '/' {
operationPath = "." + operationPath
}
queryURL, err := serverURL.Parse(operationPath)
if err != nil {
return nil, err
}
if params != nil {
queryValues := queryURL.Query()
if params.Page != nil {
if queryFrag, err := runtime.StyleParamWithLocation("form", true, "page", runtime.ParamLocationQuery, *params.Page); err != nil {
return nil, err
} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
return nil, err
} else {
for k, v := range parsed {
for _, v2 := range v {
queryValues.Add(k, v2)
}
}
}
}
if params.PerPage != nil {
if queryFrag, err := runtime.StyleParamWithLocation("form", true, "per_page", runtime.ParamLocationQuery, *params.PerPage); err != nil {
return nil, err
} else if parsed, err := url.ParseQuery(queryFrag); err != nil {
return nil, err
} else {
for k, v := range parsed {
for _, v2 := range v {
queryValues.Add(k, v2)
}
}
}
}
queryURL.RawQuery = queryValues.Encode()
}
req, err := http.NewRequest("GET", queryURL.String(), nil)
if err != nil {
return nil, err
}
return req, nil
}
// NewGetImagesRequest generates requests for GetImages
func NewGetImagesRequest(server string, params *GetImagesParams) (*http.Request, error) {
var err error
@@ -8665,17 +8415,6 @@ type ClientWithResponsesInterface interface {
union json.RawMessage
}, recordId int64, body PutDomainsDomainNameRecordsRecordIdJSONRequestBody, reqEditors ...RequestEditorFn) (*PutDomainsDomainNameRecordsRecordIdResponse, error)
// GetFailoverIpsServerIdWithResponse request
GetFailoverIpsServerIdWithResponse(ctx context.Context, serverId int64, params *GetFailoverIpsServerIdParams, reqEditors ...RequestEditorFn) (*GetFailoverIpsServerIdResponse, error)
// PostFailoverIpsServerIdWithBodyWithResponse request with any body
PostFailoverIpsServerIdWithBodyWithResponse(ctx context.Context, serverId int64, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PostFailoverIpsServerIdResponse, error)
PostFailoverIpsServerIdWithResponse(ctx context.Context, serverId int64, body PostFailoverIpsServerIdJSONRequestBody, reqEditors ...RequestEditorFn) (*PostFailoverIpsServerIdResponse, error)
// GetFailoverIpsServerIdAvailableWithResponse request
GetFailoverIpsServerIdAvailableWithResponse(ctx context.Context, serverId int64, params *GetFailoverIpsServerIdAvailableParams, reqEditors ...RequestEditorFn) (*GetFailoverIpsServerIdAvailableResponse, error)
// GetImagesWithResponse request
GetImagesWithResponse(ctx context.Context, params *GetImagesParams, reqEditors ...RequestEditorFn) (*GetImagesResponse, error)
@@ -9641,76 +9380,6 @@ func (r PutDomainsDomainNameRecordsRecordIdResponse) StatusCode() int {
return 0
}
type GetFailoverIpsServerIdResponse struct {
Body []byte
HTTPResponse *http.Response
JSON200 *FailoverIpsResponse
JSON404 *ProblemDetails
}
// Status returns HTTPResponse.Status
func (r GetFailoverIpsServerIdResponse) Status() string {
if r.HTTPResponse != nil {
return r.HTTPResponse.Status
}
return http.StatusText(0)
}
// StatusCode returns HTTPResponse.StatusCode
func (r GetFailoverIpsServerIdResponse) StatusCode() int {
if r.HTTPResponse != nil {
return r.HTTPResponse.StatusCode
}
return 0
}
type PostFailoverIpsServerIdResponse struct {
Body []byte
HTTPResponse *http.Response
JSON200 *ActionResponse
JSON400 *ValidationProblemDetails
JSON404 *ProblemDetails
}
// Status returns HTTPResponse.Status
func (r PostFailoverIpsServerIdResponse) Status() string {
if r.HTTPResponse != nil {
return r.HTTPResponse.Status
}
return http.StatusText(0)
}
// StatusCode returns HTTPResponse.StatusCode
func (r PostFailoverIpsServerIdResponse) StatusCode() int {
if r.HTTPResponse != nil {
return r.HTTPResponse.StatusCode
}
return 0
}
type GetFailoverIpsServerIdAvailableResponse struct {
Body []byte
HTTPResponse *http.Response
JSON200 *FailoverIpsResponse
JSON404 *ProblemDetails
}
// Status returns HTTPResponse.Status
func (r GetFailoverIpsServerIdAvailableResponse) Status() string {
if r.HTTPResponse != nil {
return r.HTTPResponse.Status
}
return http.StatusText(0)
}
// StatusCode returns HTTPResponse.StatusCode
func (r GetFailoverIpsServerIdAvailableResponse) StatusCode() int {
if r.HTTPResponse != nil {
return r.HTTPResponse.StatusCode
}
return 0
}
type GetImagesResponse struct {
Body []byte
HTTPResponse *http.Response
@@ -9761,6 +9430,7 @@ type GetImagesImageIdDownloadResponse struct {
Body []byte
HTTPResponse *http.Response
JSON200 *ImageDownloadResponse
JSON400 *ValidationProblemDetails
JSON404 *ProblemDetails
}
@@ -12123,41 +11793,6 @@ func (c *ClientWithResponses) PutDomainsDomainNameRecordsRecordIdWithResponse(ct
return ParsePutDomainsDomainNameRecordsRecordIdResponse(rsp)
}
// GetFailoverIpsServerIdWithResponse request returning *GetFailoverIpsServerIdResponse
func (c *ClientWithResponses) GetFailoverIpsServerIdWithResponse(ctx context.Context, serverId int64, params *GetFailoverIpsServerIdParams, reqEditors ...RequestEditorFn) (*GetFailoverIpsServerIdResponse, error) {
rsp, err := c.GetFailoverIpsServerId(ctx, serverId, params, reqEditors...)
if err != nil {
return nil, err
}
return ParseGetFailoverIpsServerIdResponse(rsp)
}
// PostFailoverIpsServerIdWithBodyWithResponse request with arbitrary body returning *PostFailoverIpsServerIdResponse
func (c *ClientWithResponses) PostFailoverIpsServerIdWithBodyWithResponse(ctx context.Context, serverId int64, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PostFailoverIpsServerIdResponse, error) {
rsp, err := c.PostFailoverIpsServerIdWithBody(ctx, serverId, contentType, body, reqEditors...)
if err != nil {
return nil, err
}
return ParsePostFailoverIpsServerIdResponse(rsp)
}
func (c *ClientWithResponses) PostFailoverIpsServerIdWithResponse(ctx context.Context, serverId int64, body PostFailoverIpsServerIdJSONRequestBody, reqEditors ...RequestEditorFn) (*PostFailoverIpsServerIdResponse, error) {
rsp, err := c.PostFailoverIpsServerId(ctx, serverId, body, reqEditors...)
if err != nil {
return nil, err
}
return ParsePostFailoverIpsServerIdResponse(rsp)
}
// GetFailoverIpsServerIdAvailableWithResponse request returning *GetFailoverIpsServerIdAvailableResponse
func (c *ClientWithResponses) GetFailoverIpsServerIdAvailableWithResponse(ctx context.Context, serverId int64, params *GetFailoverIpsServerIdAvailableParams, reqEditors ...RequestEditorFn) (*GetFailoverIpsServerIdAvailableResponse, error) {
rsp, err := c.GetFailoverIpsServerIdAvailable(ctx, serverId, params, reqEditors...)
if err != nil {
return nil, err
}
return ParseGetFailoverIpsServerIdAvailableResponse(rsp)
}
// GetImagesWithResponse request returning *GetImagesResponse
func (c *ClientWithResponses) GetImagesWithResponse(ctx context.Context, params *GetImagesParams, reqEditors ...RequestEditorFn) (*GetImagesResponse, error) {
rsp, err := c.GetImages(ctx, params, reqEditors...)
@@ -14171,112 +13806,6 @@ func ParsePutDomainsDomainNameRecordsRecordIdResponse(rsp *http.Response) (*PutD
return response, nil
}
// ParseGetFailoverIpsServerIdResponse parses an HTTP response from a GetFailoverIpsServerIdWithResponse call
func ParseGetFailoverIpsServerIdResponse(rsp *http.Response) (*GetFailoverIpsServerIdResponse, error) {
bodyBytes, err := io.ReadAll(rsp.Body)
defer func() { _ = rsp.Body.Close() }()
if err != nil {
return nil, err
}
response := &GetFailoverIpsServerIdResponse{
Body: bodyBytes,
HTTPResponse: rsp,
}
switch {
case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200:
var dest FailoverIpsResponse
if err := json.Unmarshal(bodyBytes, &dest); err != nil {
return nil, err
}
response.JSON200 = &dest
case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404:
var dest ProblemDetails
if err := json.Unmarshal(bodyBytes, &dest); err != nil {
return nil, err
}
response.JSON404 = &dest
}
return response, nil
}
// ParsePostFailoverIpsServerIdResponse parses an HTTP response from a PostFailoverIpsServerIdWithResponse call
func ParsePostFailoverIpsServerIdResponse(rsp *http.Response) (*PostFailoverIpsServerIdResponse, error) {
bodyBytes, err := io.ReadAll(rsp.Body)
defer func() { _ = rsp.Body.Close() }()
if err != nil {
return nil, err
}
response := &PostFailoverIpsServerIdResponse{
Body: bodyBytes,
HTTPResponse: rsp,
}
switch {
case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200:
var dest ActionResponse
if err := json.Unmarshal(bodyBytes, &dest); err != nil {
return nil, err
}
response.JSON200 = &dest
case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400:
var dest ValidationProblemDetails
if err := json.Unmarshal(bodyBytes, &dest); err != nil {
return nil, err
}
response.JSON400 = &dest
case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404:
var dest ProblemDetails
if err := json.Unmarshal(bodyBytes, &dest); err != nil {
return nil, err
}
response.JSON404 = &dest
}
return response, nil
}
// ParseGetFailoverIpsServerIdAvailableResponse parses an HTTP response from a GetFailoverIpsServerIdAvailableWithResponse call
func ParseGetFailoverIpsServerIdAvailableResponse(rsp *http.Response) (*GetFailoverIpsServerIdAvailableResponse, error) {
bodyBytes, err := io.ReadAll(rsp.Body)
defer func() { _ = rsp.Body.Close() }()
if err != nil {
return nil, err
}
response := &GetFailoverIpsServerIdAvailableResponse{
Body: bodyBytes,
HTTPResponse: rsp,
}
switch {
case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200:
var dest FailoverIpsResponse
if err := json.Unmarshal(bodyBytes, &dest); err != nil {
return nil, err
}
response.JSON200 = &dest
case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404:
var dest ProblemDetails
if err := json.Unmarshal(bodyBytes, &dest); err != nil {
return nil, err
}
response.JSON404 = &dest
}
return response, nil
}
// ParseGetImagesResponse parses an HTTP response from a GetImagesWithResponse call
func ParseGetImagesResponse(rsp *http.Response) (*GetImagesResponse, error) {
bodyBytes, err := io.ReadAll(rsp.Body)
@@ -14364,6 +13893,13 @@ func ParseGetImagesImageIdDownloadResponse(rsp *http.Response) (*GetImagesImageI
}
response.JSON200 = &dest
case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400:
var dest ValidationProblemDetails
if err := json.Unmarshal(bodyBytes, &dest); err != nil {
return nil, err
}
response.JSON400 = &dest
case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 404:
var dest ProblemDetails
if err := json.Unmarshal(bodyBytes, &dest); err != nil {
+12 -286
View File
@@ -8,7 +8,7 @@
"url": "https://support.binarylane.com.au",
"email": "support@binarylane.com.au"
},
"version": "0.25.0",
"version": "0.26.0",
"x-logo": {
"url": "https://www.binarylane.com.au/res/images/binarylane/logo.png",
"backgroundColor": "#000000",
@@ -1200,242 +1200,6 @@
"x-cli-command": "domain record delete"
}
},
"/failover_ips/{server_id}": {
"get": {
"tags": [
"FailoverIps"
],
"summary": "Fetch the Failover IPs for a Server",
"parameters": [
{
"name": "server_id",
"in": "path",
"description": "The target server id.",
"required": true,
"schema": {
"type": "integer",
"description": "The target server id.",
"format": "int64"
}
},
{
"name": "page",
"in": "query",
"description": "The selected page. Page numbering starts at 1",
"schema": {
"maximum": 2147483647,
"minimum": 1,
"type": "integer",
"description": "The selected page. Page numbering starts at 1",
"format": "int32",
"default": 1
}
},
{
"name": "per_page",
"in": "query",
"description": "The number of results to show per page.",
"schema": {
"maximum": 200,
"minimum": 1,
"type": "integer",
"description": "The number of results to show per page.",
"format": "int32",
"default": 20
}
}
],
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/FailoverIpsResponse"
}
}
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
},
"401": {
"description": "Unauthorized"
}
},
"x-codeSamples": [
{
"lang": "Curl",
"source": "curl -X GET \"https://api.binarylane.com.au/v2/failover_ips/${server_id}?page=${page}&per_page=${per_page}\" \\\n-H \"Authorization: Bearer ${APITOKEN}\""
}
],
"x-cli-command": "server failover-ip get"
},
"post": {
"tags": [
"FailoverIps"
],
"summary": "Sets the List of Failover IPs that are Assigned to a Server",
"description": "This overwrites the current list, i.e. submit the entire list, not just updates.\nIf NoContent is returned no changes were made.\nIf an action is returned the changes have been saved but the effect may not be complete until the action is complete. If the action does not complete the network changes can be forced by rebooting the server.",
"parameters": [
{
"name": "server_id",
"in": "path",
"description": "The target server id.",
"required": true,
"schema": {
"type": "integer",
"description": "The target server id.",
"format": "int64"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"allOf": [
{
"$ref": "#/components/schemas/FailoverIpsRequest"
}
]
}
}
}
},
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ActionResponse"
}
}
}
},
"204": {
"description": "No Content"
},
"400": {
"description": "Bad Request",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ValidationProblemDetails"
}
}
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
},
"401": {
"description": "Unauthorized"
}
},
"x-codeSamples": [
{
"lang": "Curl",
"source": "curl -X POST \"https://api.binarylane.com.au/v2/failover_ips/${server_id}\" \\\n-H \"Authorization: Bearer ${APITOKEN}\" \\\n-H \"Content-Type: application/json\" -d \"${PAYLOAD}\""
}
],
"x-cli-command": "server failover-ip update"
}
},
"/failover_ips/{server_id}/available": {
"get": {
"tags": [
"FailoverIps"
],
"summary": "Fetch a List of all Failover IPs that are Available to be Assigned to a Server",
"parameters": [
{
"name": "server_id",
"in": "path",
"description": "The target server id.",
"required": true,
"schema": {
"type": "integer",
"description": "The target server id.",
"format": "int64"
}
},
{
"name": "page",
"in": "query",
"description": "The selected page. Page numbering starts at 1",
"schema": {
"maximum": 2147483647,
"minimum": 1,
"type": "integer",
"description": "The selected page. Page numbering starts at 1",
"format": "int32",
"default": 1
}
},
{
"name": "per_page",
"in": "query",
"description": "The number of results to show per page.",
"schema": {
"maximum": 200,
"minimum": 1,
"type": "integer",
"description": "The number of results to show per page.",
"format": "int32",
"default": 20
}
}
],
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/FailoverIpsResponse"
}
}
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
},
"401": {
"description": "Unauthorized"
}
},
"x-codeSamples": [
{
"lang": "Curl",
"source": "curl -X GET \"https://api.binarylane.com.au/v2/failover_ips/${server_id}/available?page=${page}&per_page=${per_page}\" \\\n-H \"Authorization: Bearer ${APITOKEN}\""
}
],
"x-cli-command": "server failover-ip available"
}
},
"/images": {
"get": {
"tags": [
@@ -1613,6 +1377,16 @@
}
}
},
"400": {
"description": "Bad Request",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ValidationProblemDetails"
}
}
}
},
"404": {
"description": "Not Found",
"content": {
@@ -9199,7 +8973,7 @@
},
"iso": {
"type": "boolean",
"description": "If this is true the backup is an ISO image and cannot be restored. ISO images may only be attached for use as a boot disk or an additional disk.",
"description": "If this is true the backup is an ISO image and cannot be restored or downloaded. ISO images may only be attached for use as a boot disk or an additional disk.",
"readOnly": true
},
"backup_disks": {
@@ -10935,53 +10709,6 @@
},
"description": "Enable IPv6 for a Server"
},
"FailoverIpsRequest": {
"required": [
"failover_ips"
],
"type": "object",
"properties": {
"failover_ips": {
"type": "array",
"items": {
"type": "string"
},
"description": "The list of IP Failover addresses to assign to this server. This overwrites the current list, so any current IP Failover addresses that are omitted will be removed from the server."
}
}
},
"FailoverIpsResponse": {
"required": [
"failover_ips",
"meta"
],
"type": "object",
"properties": {
"meta": {
"allOf": [
{
"$ref": "#/components/schemas/Meta"
}
],
"description": "Contains metadata about the response, currently this includes the total number of items."
},
"links": {
"allOf": [
{
"$ref": "#/components/schemas/Links"
}
],
"nullable": true
},
"failover_ips": {
"type": "array",
"items": {
"type": "string"
},
"readOnly": true
}
}
},
"ForwardingRule": {
"required": [
"entry_protocol"
@@ -15008,7 +14735,6 @@
"ServerActions",
"Actions",
"DataUsages",
"FailoverIps",
"Images",
"Keys",
"ReverseNames",
+1 -40
View File
@@ -714,7 +714,7 @@ type BackupInfo struct {
// BackupDisks A list of the individual disks that make up this backup.
BackupDisks *[]BackupDisk `json:"backup_disks,omitempty"`
// Iso If this is true the backup is an ISO image and cannot be restored. ISO images may only be attached for use as a boot disk or an additional disk.
// Iso If this is true the backup is an ISO image and cannot be restored or downloaded. ISO images may only be attached for use as a boot disk or an additional disk.
Iso *bool `json:"iso,omitempty"`
// Locked If this is true the backup is locked and cannot be replaced.
@@ -1502,21 +1502,6 @@ type EnableIpv6 struct {
// EnableIpv6Type defines model for EnableIpv6.Type.
type EnableIpv6Type string
// FailoverIpsRequest defines model for FailoverIpsRequest.
type FailoverIpsRequest struct {
// FailoverIps The list of IP Failover addresses to assign to this server. This overwrites the current list, so any current IP Failover addresses that are omitted will be removed from the server.
FailoverIps []string `json:"failover_ips"`
}
// FailoverIpsResponse defines model for FailoverIpsResponse.
type FailoverIpsResponse struct {
FailoverIps *[]string `json:"failover_ips,omitempty"`
Links *Links `json:"links"`
// Meta Contains metadata about the response, currently this includes the total number of items.
Meta Meta `json:"meta"`
}
// ForwardingRule defines model for ForwardingRule.
type ForwardingRule struct {
// EntryProtocol The protocol that traffic must match for this load balancer to forward traffic according to this rule.
@@ -3214,27 +3199,6 @@ type PutDomainsDomainNameRecordsRecordIdParamsDomainName0 = int
// PutDomainsDomainNameRecordsRecordIdParamsDomainName1 defines parameters for PutDomainsDomainNameRecordsRecordId.
type PutDomainsDomainNameRecordsRecordIdParamsDomainName1 = string
// GetFailoverIpsServerIdParams defines parameters for GetFailoverIpsServerId.
type GetFailoverIpsServerIdParams struct {
// Page The selected page. Page numbering starts at 1
Page *int32 `form:"page,omitempty" json:"page,omitempty"`
// PerPage The number of results to show per page.
PerPage *int32 `form:"per_page,omitempty" json:"per_page,omitempty"`
}
// PostFailoverIpsServerIdJSONBody defines parameters for PostFailoverIpsServerId.
type PostFailoverIpsServerIdJSONBody = FailoverIpsRequest
// GetFailoverIpsServerIdAvailableParams defines parameters for GetFailoverIpsServerIdAvailable.
type GetFailoverIpsServerIdAvailableParams struct {
// Page The selected page. Page numbering starts at 1
Page *int32 `form:"page,omitempty" json:"page,omitempty"`
// PerPage The number of results to show per page.
PerPage *int32 `form:"per_page,omitempty" json:"per_page,omitempty"`
}
// GetImagesParams defines parameters for GetImages.
type GetImagesParams struct {
// Type Queries for distribution will include images that have pre-installed applications.
@@ -3522,9 +3486,6 @@ type PostDomainsDomainNameRecordsJSONRequestBody = PostDomainsDomainNameRecordsJ
// PutDomainsDomainNameRecordsRecordIdJSONRequestBody defines body for PutDomainsDomainNameRecordsRecordId for application/json ContentType.
type PutDomainsDomainNameRecordsRecordIdJSONRequestBody = PutDomainsDomainNameRecordsRecordIdJSONBody
// PostFailoverIpsServerIdJSONRequestBody defines body for PostFailoverIpsServerId for application/json ContentType.
type PostFailoverIpsServerIdJSONRequestBody = PostFailoverIpsServerIdJSONBody
// PostLoadBalancersJSONRequestBody defines body for PostLoadBalancers for application/json ContentType.
type PostLoadBalancersJSONRequestBody = PostLoadBalancersJSONBody
@@ -93,7 +93,7 @@ func (d *loadBalancerDataSource) Read(ctx context.Context, req datasource.ReadRe
return
}
diags := SetLoadBalancerModelState(ctx, &data.LoadBalancerModel, lbResp.JSON200.LoadBalancer)
diags := setLoadBalancerModelState(ctx, &data.LoadBalancerModel, lbResp.JSON200.LoadBalancer)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
+4 -4
View File
@@ -152,7 +152,7 @@ func (r *loadBalancerResource) Create(ctx context.Context, req resource.CreateRe
return
}
diags = SetLoadBalancerModelState(ctx, &data.LoadBalancerModel, lbResp.JSON200.LoadBalancer)
diags = setLoadBalancerModelState(ctx, &data.LoadBalancerModel, lbResp.JSON200.LoadBalancer)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
@@ -245,7 +245,7 @@ func (r *loadBalancerResource) Read(ctx context.Context, req resource.ReadReques
return
}
diags := SetLoadBalancerModelState(ctx, &data.LoadBalancerModel, lbResp.JSON200.LoadBalancer)
diags := setLoadBalancerModelState(ctx, &data.LoadBalancerModel, lbResp.JSON200.LoadBalancer)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
@@ -309,7 +309,7 @@ func (r *loadBalancerResource) Update(ctx context.Context, req resource.UpdateRe
return
}
diags = SetLoadBalancerModelState(ctx, &data.LoadBalancerModel, lbResp.JSON200.LoadBalancer)
diags = setLoadBalancerModelState(ctx, &data.LoadBalancerModel, lbResp.JSON200.LoadBalancer)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
@@ -414,7 +414,7 @@ func (r *loadBalancerResource) ImportState(
resp.Diagnostics.Append(diags...)
}
func SetLoadBalancerModelState(ctx context.Context, data *resources.LoadBalancerModel, lb *binarylane.LoadBalancer) diag.Diagnostics {
func setLoadBalancerModelState(ctx context.Context, data *resources.LoadBalancerModel, lb *binarylane.LoadBalancer) diag.Diagnostics {
var diags, diag diag.Diagnostics
data.Id = types.Int64Value(*lb.Id)
+39 -8
View File
@@ -30,6 +30,8 @@ type serverDataModel struct {
PublicIpv4Addresses types.List `tfsdk:"public_ipv4_addresses"`
PrivateIPv4Addresses types.List `tfsdk:"private_ipv4_addresses"`
Permalink types.String `tfsdk:"permalink"`
Memory types.Int32 `tfsdk:"memory"`
Disk types.Int32 `tfsdk:"disk"`
}
func (d *serverDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
@@ -98,6 +100,20 @@ func (d *serverDataSource) Schema(ctx context.Context, req datasource.SchemaRequ
ElementType: types.StringType,
Computed: true,
}
memoryDescription := "The amount of memory in MB assigned to the server."
resp.Schema.Attributes["memory"] = &schema.Int32Attribute{
Description: memoryDescription,
MarkdownDescription: memoryDescription,
Computed: true,
}
diskDescription := "The amount of storage in GB assigned to the server."
resp.Schema.Attributes["disk"] = &schema.Int32Attribute{
Description: diskDescription,
MarkdownDescription: diskDescription,
Computed: true,
}
}
func (d *serverDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
@@ -128,16 +144,19 @@ func (d *serverDataSource) Read(ctx context.Context, req datasource.ReadRequest,
return
}
// Set data values
data.Id = types.Int64Value(*serverResp.JSON200.Server.Id)
data.Name = types.StringValue(*serverResp.JSON200.Server.Name)
data.Image = types.StringValue(*serverResp.JSON200.Server.Image.Slug)
data.Region = types.StringValue(*serverResp.JSON200.Server.Region.Slug)
data.Size = types.StringValue(*serverResp.JSON200.Server.Size.Slug)
data.Backups = types.BoolValue(serverResp.JSON200.Server.NextBackupWindow != nil)
data.PortBlocking = types.BoolValue(serverResp.JSON200.Server.Networks.PortBlocking)
data.VpcId = types.Int64PointerValue(serverResp.JSON200.Server.VpcId)
data.Permalink = types.StringValue(*serverResp.JSON200.Server.Permalink)
var publicIpv4Addresses []string
var privateIpv4Addresses []string
data.Memory = types.Int32Value(*serverResp.JSON200.Server.Memory)
data.Disk = types.Int32Value(*serverResp.JSON200.Server.Disk)
publicIpv4Addresses := []string{}
privateIpv4Addresses := []string{}
for _, v4address := range serverResp.JSON200.Server.Networks.V4 {
if v4address.Type == "public" {
@@ -146,10 +165,22 @@ func (d *serverDataSource) Read(ctx context.Context, req datasource.ReadRequest,
privateIpv4Addresses = append(privateIpv4Addresses, v4address.IpAddress)
}
}
data.PublicIpv4Addresses, diags = types.ListValueFrom(ctx, types.StringType, publicIpv4Addresses)
resp.Diagnostics.Append(diags...)
data.PrivateIPv4Addresses, diags = types.ListValueFrom(ctx, types.StringType, privateIpv4Addresses)
resp.Diagnostics.Append(diags...)
tfPublicIpv4Addresses, diag := types.ListValueFrom(ctx, types.StringType, publicIpv4Addresses)
diags.Append(diag...)
if diag.HasError() {
data.PublicIpv4Addresses = types.ListUnknown(data.PublicIpv4Addresses.ElementType(ctx))
} else {
data.PublicIpv4Addresses = tfPublicIpv4Addresses
}
tfPrivateIpv4Addresses, diag := types.ListValueFrom(ctx, types.StringType, privateIpv4Addresses)
diags.Append(diag...)
if diag.HasError() {
data.PrivateIPv4Addresses = types.ListUnknown(data.PrivateIPv4Addresses.ElementType(ctx))
} else {
data.PrivateIPv4Addresses = tfPrivateIpv4Addresses
}
// Get user data script
userDataResp, err := d.bc.client.GetServersServerIdUserDataWithResponse(ctx, data.Id.ValueInt64())
+273 -85
View File
@@ -18,6 +18,7 @@ import (
"github.com/hashicorp/terraform-plugin-framework-validators/listvalidator"
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
@@ -49,13 +50,11 @@ type serverResource struct {
bc *BinarylaneClient
}
type serverModel struct {
resources.ServerModel
type serverResourceModel struct {
serverDataModel
PublicIpv4Count types.Int32 `tfsdk:"public_ipv4_count"`
PublicIpv4Addresses types.List `tfsdk:"public_ipv4_addresses"`
PrivateIPv4Addresses types.List `tfsdk:"private_ipv4_addresses"`
SourceAndDestinationCheck types.Bool `tfsdk:"source_and_destination_check"`
Permalink types.String `tfsdk:"permalink"`
Password types.String `tfsdk:"password"`
PasswordChangeSupported types.Bool `tfsdk:"password_change_supported"`
Timeouts timeouts.Value `tfsdk:"timeouts"`
@@ -117,10 +116,9 @@ func (r *serverResource) Schema(ctx context.Context, _ resource.SchemaRequest, r
resp.Schema.Attributes["backups"] = &schema.BoolAttribute{
Description: backups.GetDescription(),
MarkdownDescription: backups.GetMarkdownDescription(),
Optional: backups.IsOptional(),
Computed: backups.IsComputed(),
Default: booldefault.StaticBool(false), // Add default to backups
PlanModifiers: []planmodifier.Bool{boolplanmodifier.RequiresReplace()}, // TODO (#37)
Optional: true,
Computed: true,
Default: booldefault.StaticBool(false), // Add default to backups
}
user_data := resp.Schema.Attributes["user_data"]
@@ -137,7 +135,6 @@ func (r *serverResource) Schema(ctx context.Context, _ resource.SchemaRequest, r
MarkdownDescription: vpcId.GetMarkdownDescription(),
Optional: vpcId.IsOptional(),
Computed: false, // VPC ID is not computed, defined at creation
PlanModifiers: []planmodifier.Int64{int64planmodifier.RequiresReplace()},
}
portBlocking := resp.Schema.Attributes["port_blocking"]
@@ -187,6 +184,7 @@ func (r *serverResource) Schema(ctx context.Context, _ resource.SchemaRequest, r
// Default: int32default.StaticInt32(0), // TODO: Uncomment with 1.0 release (see issue #30)
Validators: []validator.Int32{
int32validator.AtLeast(0),
int32validator.AtMost(8),
},
}
@@ -262,6 +260,58 @@ func (r *serverResource) Schema(ctx context.Context, _ resource.SchemaRequest, r
},
}
memoryDescription := `The total memory in MB for this server. If specified this is the absolute value, not just the
additional memory above what is included in the size. Leave null to accept the default for the size if this is a new
server or a resize to a different base size, or to keep the current value if this a resize with the same base size
but different options.`
memoryValidValues := "Valid values must be a multiple of 128. If the value is greater than 2048MB, it must be a " +
"multiple of 1024. If the value is greater than 16384MB, it must be a multiple of 2048. If the value is greater " +
"than 24576MB, it must be a multiple of 4096."
memoryValidValuesMarkdown := ` Valid values:
- must be a multiple of 128
- \> 2048MB must be a multiple of 1024
- \> 16384MB must be a multiple of 2048
- \> 24576MB must be a multiple of 4096`
resp.Schema.Attributes["memory"] = &schema.Int32Attribute{
Description: memoryDescription + memoryValidValues,
MarkdownDescription: memoryDescription + memoryValidValuesMarkdown,
Optional: true,
Required: false,
Computed: true,
Validators: []validator.Int32{
int32validator.AtLeast(128),
MultipleOfValidator{Multiple: 128},
MultipleOfValidator{Multiple: 1024, RangeFrom: 2048, RangeTo: 16384},
MultipleOfValidator{Multiple: 2048, RangeFrom: 16384, RangeTo: 24576},
MultipleOfValidator{Multiple: 4096, RangeFrom: 24576},
},
}
diskDescription := `The total storage in GB for this server. If specified this is the absolute value, not just the additional storage above what is included in the size.
Leave null to accept the default for the size if this is a new server or a resize to a different base size,
or to keep the current value if this a resize with the same base size but different options.`
diskValidValues := "Valid values must be a multiple of 5. If the value is greater than 60GB, it must be a multiple of 10. " +
"if the value is greater than 200GB, it must be a multiple of 100. "
diskValidValuesMarkdown := ` Valid values:
- must be a multiple of 5
- \> 60GB must be a multiple of 10
- \> 200GB must be a multiple of 100`
resp.Schema.Attributes["disk"] = &schema.Int32Attribute{
Description: diskDescription + diskValidValues,
MarkdownDescription: diskDescription + diskValidValuesMarkdown,
Optional: true,
Required: false,
Computed: true,
Validators: []validator.Int32{
int32validator.AtLeast(20),
MultipleOfValidator{Multiple: 5},
MultipleOfValidator{Multiple: 10, RangeFrom: 60, RangeTo: 200},
MultipleOfValidator{Multiple: 100, RangeFrom: 200},
},
}
resp.Schema.Attributes["timeouts"] =
timeouts.Attributes(ctx, timeouts.Opts{
Create: true,
@@ -270,12 +320,13 @@ func (r *serverResource) Schema(ctx context.Context, _ resource.SchemaRequest, r
}
func (r *serverResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
var plan, state serverModel
var plan, state serverResourceModel
if req.Plan.Raw.IsNull() {
// Destruction plan, no modification needed
return
}
// Read Terraform plan data into the model
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
if resp.Diagnostics.HasError() {
@@ -295,12 +346,17 @@ func (r *serverResource) ModifyPlan(ctx context.Context, req resource.ModifyPlan
// Creation plan, no further modification needed
return
}
// Read Terraform state data into the model
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
return
}
if !plan.VpcId.Equal(state.VpcId) {
plan.PrivateIPv4Addresses = types.ListUnknown(plan.PrivateIPv4Addresses.ElementType(ctx))
}
// When IP count is changed, plan should show addition/removal of public IPs
plannedPublicIpV4Count := int(plan.PublicIpv4Count.ValueInt32())
plannedPublicIpAddresses := make([]attr.Value, plannedPublicIpV4Count)
@@ -333,12 +389,20 @@ func (r *serverResource) ModifyPlan(ctx context.Context, req resource.ModifyPlan
)
}
// Use state for unknown disk/memory values, as long as server size is the same
if (plan.Memory.IsNull() || plan.Memory.IsUnknown()) && plan.Size.Equal(state.Size) {
plan.Memory = state.Memory
}
if (plan.Disk.IsNull() || plan.Disk.IsUnknown()) && plan.Size.Equal(state.Size) {
plan.Disk = state.Disk
}
// Save data into Terraform state
resp.Diagnostics.Append(resp.Plan.Set(ctx, &plan)...)
}
func (r *serverResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
var data serverModel
var data serverResourceModel
// Read Terraform plan data into the model
diags := req.Plan.Get(ctx, &data)
@@ -374,6 +438,14 @@ func (r *serverResource) Create(ctx context.Context, req resource.CreateRequest,
Options: &binarylane.SizeOptionsRequest{
Ipv4Addresses: data.PublicIpv4Count.ValueInt32Pointer(),
},
Backups: data.Backups.ValueBoolPointer(),
}
if !data.Memory.IsNull() && !data.Memory.IsUnknown() {
body.Options.Memory = data.Memory.ValueInt32Pointer()
}
if !data.Disk.IsNull() && !data.Disk.IsUnknown() {
body.Options.Disk = data.Disk.ValueInt32Pointer()
}
if data.Password.IsNull() {
@@ -428,6 +500,8 @@ func (r *serverResource) Create(ctx context.Context, req resource.CreateRequest,
data.VpcId = types.Int64PointerValue(serverResp.JSON200.Server.VpcId)
data.Permalink = types.StringValue(*serverResp.JSON200.Server.Permalink)
data.PasswordChangeSupported = types.BoolValue(*serverResp.JSON200.Server.PasswordChangeSupported)
data.Memory = types.Int32Value(*serverResp.JSON200.Server.Memory)
data.Disk = types.Int32Value(*serverResp.JSON200.Server.Disk)
plannedSourceDestCheck := data.SourceAndDestinationCheck
serverRespSourceDestCheck := types.BoolPointerValue(serverResp.JSON200.Server.Networks.SourceAndDestinationCheck)
data.SourceAndDestinationCheck = serverRespSourceDestCheck
@@ -464,7 +538,7 @@ func (r *serverResource) Create(ctx context.Context, req resource.CreateRequest,
}
func (r *serverResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
var data serverModel
var data serverResourceModel
// Read Terraform prior state data into the model
diags := req.State.Get(ctx, &data)
@@ -492,36 +566,8 @@ func (r *serverResource) Read(ctx context.Context, req resource.ReadRequest, res
return
}
data.Id = types.Int64Value(*serverResp.JSON200.Server.Id)
data.Name = types.StringValue(*serverResp.JSON200.Server.Name)
data.Image = types.StringValue(*serverResp.JSON200.Server.Image.Slug)
data.Region = types.StringValue(*serverResp.JSON200.Server.Region.Slug)
data.Size = types.StringValue(*serverResp.JSON200.Server.Size.Slug)
data.Backups = types.BoolValue(serverResp.JSON200.Server.NextBackupWindow != nil)
data.PortBlocking = types.BoolValue(serverResp.JSON200.Server.Networks.PortBlocking)
data.VpcId = types.Int64PointerValue(serverResp.JSON200.Server.VpcId)
data.Permalink = types.StringValue(*serverResp.JSON200.Server.Permalink)
data.PasswordChangeSupported = types.BoolValue(*serverResp.JSON200.Server.PasswordChangeSupported)
data.SourceAndDestinationCheck = types.BoolPointerValue(serverResp.JSON200.Server.Networks.SourceAndDestinationCheck)
publicIpv4Addresses := []string{}
privateIpv4Addresses := []string{}
for _, v4address := range serverResp.JSON200.Server.Networks.V4 {
if v4address.Type == "public" {
publicIpv4Addresses = append(publicIpv4Addresses, v4address.IpAddress)
} else {
privateIpv4Addresses = append(privateIpv4Addresses, v4address.IpAddress)
}
}
data.PublicIpv4Addresses, diags = types.ListValueFrom(ctx, types.StringType, publicIpv4Addresses)
resp.Diagnostics.Append(diags...)
data.PrivateIPv4Addresses, diags = types.ListValueFrom(ctx, types.StringType, privateIpv4Addresses)
resp.Diagnostics.Append(diags...)
data.PublicIpv4Count = types.Int32Value(int32(len(publicIpv4Addresses)))
if resp.Diagnostics.HasError() {
return
}
diag := setServerResourceState(ctx, &data, serverResp.JSON200)
resp.Diagnostics.Append(diag...)
// Get user data script
userDataResp, err := r.bc.client.GetServersServerIdUserDataWithResponse(ctx, data.Id.ValueInt64())
@@ -546,7 +592,7 @@ func (r *serverResource) Read(ctx context.Context, req resource.ReadRequest, res
}
func (r *serverResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
var plan, state serverModel
var plan, state serverResourceModel
// Read Terraform plan data into the model
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
@@ -561,6 +607,35 @@ func (r *serverResource) Update(ctx context.Context, req resource.UpdateRequest,
defer cancel()
rebuildNeeded := len(attrsRequiringRebuild(&plan, &state)) > 0
refreshNeeded := false
defer (func() {
if !refreshNeeded {
return
}
serverResp, err := r.bc.client.GetServersServerIdWithResponse(ctx, state.Id.ValueInt64())
if err != nil {
resp.Diagnostics.AddError(
fmt.Sprintf("Error reading server: id=%s, name=%s", state.Id.String(), state.Name.ValueString()),
err.Error(),
)
return
}
if serverResp.StatusCode() != http.StatusOK {
resp.Diagnostics.AddError(
fmt.Sprintf("Unexpected HTTP status code %s reading server: name=%s, id=%s", serverResp.Status(), state.Name.ValueString(), state.Id.String()),
string(serverResp.Body),
)
return
}
diag := setServerResourceState(ctx, &state, serverResp.JSON200)
resp.Diagnostics.Append(diag...)
// Save updated data into Terraform state
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
})()
// Rename
if !plan.Name.Equal(state.Name) && !rebuildNeeded {
@@ -597,19 +672,78 @@ func (r *serverResource) Update(ctx context.Context, req resource.UpdateRequest,
state.Name = types.StringValue(plan.Name.ValueString())
}
// Change network
if !plan.VpcId.Equal(state.VpcId) {
networkResp, err := r.bc.client.PostServersServerIdActionsChangeNetworkWithResponse(
ctx,
state.Id.ValueInt64(),
binarylane.PostServersServerIdActionsChangeNetworkJSONRequestBody{
Type: "change_network",
VpcId: plan.VpcId.ValueInt64Pointer(),
},
)
if err != nil {
resp.Diagnostics.AddError(
fmt.Sprintf("Error changing network for server: server_id=%s", state.Id.String()),
err.Error())
return
}
if networkResp.StatusCode() != http.StatusOK {
resp.Diagnostics.AddError(
"Unexpected HTTP status code changing network for server",
fmt.Sprintf("Received %s changing network for server: server_id=%s. Details: %s", networkResp.Status(), state.Id.String(), networkResp.Body))
return
}
err = r.waitForServerAction(ctx, state.Id.ValueInt64(), *networkResp.JSON200.Action.Id)
if err != nil {
resp.Diagnostics.AddError("Error waiting for server to change network", err.Error())
return
}
state.VpcId = plan.VpcId
refreshNeeded = true // Refresh to get new private IP addresses
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
if resp.Diagnostics.HasError() {
return
}
}
// Resize operation
if !plan.Size.Equal(state.Size) || !plan.PublicIpv4Count.Equal(state.PublicIpv4Count) || !plan.Image.Equal(state.Image) {
if !plan.Size.Equal(state.Size) ||
!plan.Memory.IsNull() && !plan.Memory.IsUnknown() && !plan.Memory.Equal(state.Memory) ||
!plan.Disk.IsNull() && !plan.Disk.IsUnknown() && !plan.Disk.Equal(state.Disk) ||
!plan.Image.Equal(state.Image) ||
!plan.PublicIpv4Count.Equal(state.PublicIpv4Count) {
resizeReq := &binarylane.PostServersServerIdActionsResizeJSONRequestBody{
Type: "resize",
Type: "resize",
Options: &binarylane.ChangeSizeOptionsRequest{},
}
if !plan.Size.Equal(state.Size) {
if !plan.Size.Equal(state.Size) ||
!plan.Memory.IsNull() && !plan.Memory.IsUnknown() && !plan.Memory.Equal(state.Memory) ||
!plan.Disk.IsNull() && !plan.Disk.IsUnknown() && !plan.Disk.Equal(state.Disk) {
resizeReq.Size = plan.Size.ValueStringPointer()
state.Size = plan.Size
}
if !plan.PublicIpv4Count.Equal(state.PublicIpv4Count) {
resizeReq.Options = &binarylane.ChangeSizeOptionsRequest{
Ipv4Addresses: plan.PublicIpv4Count.ValueInt32Pointer(),
if !plan.Memory.IsUnknown() && !plan.Memory.IsNull() {
resizeReq.Options.Memory = plan.Memory.ValueInt32Pointer()
}
if !plan.Disk.IsNull() && !plan.Disk.IsUnknown() {
resizeReq.Options.Disk = plan.Disk.ValueInt32Pointer()
}
state.Size = plan.Size
state.Memory = plan.Memory
state.Disk = plan.Disk
}
if !plan.Image.Equal(state.Image) {
resizeReq.ChangeImage = &binarylane.ChangeImage{
Image: plan.Image.ValueStringPointer(),
}
state.Image = plan.Image
}
if !plan.PublicIpv4Count.Equal(state.PublicIpv4Count) {
resizeReq.Options.Ipv4Addresses = plan.PublicIpv4Count.ValueInt32Pointer()
if plan.PublicIpv4Count.ValueInt32() < state.PublicIpv4Count.ValueInt32() {
currentIps := []string{}
diags := state.PublicIpv4Addresses.ElementsAs(ctx, &currentIps, false)
@@ -627,12 +761,6 @@ func (r *serverResource) Update(ctx context.Context, req resource.UpdateRequest,
state.PublicIpv4Count = plan.PublicIpv4Count
state.PublicIpv4Addresses = plan.PublicIpv4Addresses
}
if !plan.Image.Equal(state.Image) {
resizeReq.ChangeImage = &binarylane.ChangeImage{
Image: plan.Image.ValueStringPointer(),
}
state.Image = plan.Image
}
tflog.Info(ctx, fmt.Sprintf("Resizing server: server_id=%s", state.Id.String()))
@@ -654,38 +782,16 @@ func (r *serverResource) Update(ctx context.Context, req resource.UpdateRequest,
fmt.Sprintf("Received %s resizing server: server_id=%s. Details: %s", resizeResp.Status(), state.Id.String(), resizeResp.Body))
return
}
err = r.waitForServerAction(ctx, state.Id.ValueInt64(), *resizeResp.JSON200.Action.Id)
if err != nil {
resp.Diagnostics.AddError("Error waiting for server to be resized", err.Error())
return
}
// Success
if state.PublicIpv4Addresses.IsUnknown() || listContainsUnknown(ctx, state.PublicIpv4Addresses) {
// New IPs may have been allocated, so we need to check the server again
serverResp, err := r.bc.client.GetServersServerIdWithResponse(ctx, state.Id.ValueInt64())
if err != nil {
resp.Diagnostics.AddError("Error checking IPs for server after resize", err.Error())
return
}
if serverResp.StatusCode() != http.StatusOK {
resp.Diagnostics.AddError("Unexpected HTTP status code checking IPs for server after resize",
fmt.Sprintf("Received %s checking IPs for server after resize: name=%s. Details: %s", serverResp.Status(), state.Name.ValueString(), serverResp.Body))
return
}
publicIpv4Addresses := []string{}
for _, v4address := range serverResp.JSON200.Server.Networks.V4 {
if v4address.Type == "public" {
publicIpv4Addresses = append(publicIpv4Addresses, v4address.IpAddress)
}
}
state.PublicIpv4Addresses, diags = types.ListValueFrom(ctx, types.StringType, publicIpv4Addresses)
resp.Diagnostics.Append(diags...)
if state.PublicIpv4Addresses.IsUnknown() || listContainsUnknown(ctx, state.PublicIpv4Addresses) || state.Memory.IsNull() || state.Memory.IsUnknown() {
refreshNeeded = true
}
// Save updated data into Terraform state
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
}
// Rebuild operation
@@ -754,10 +860,42 @@ func (r *serverResource) Update(ctx context.Context, req resource.UpdateRequest,
// Save updated data into Terraform state
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
}
// Enable or disable backups
if !plan.Backups.Equal(state.Backups) {
if plan.Backups.ValueBool() {
backupResp, err := r.bc.client.PostServersServerIdActionsEnableBackupsWithResponse(ctx, state.Id.ValueInt64(), binarylane.EnableBackups{
Type: "enable_backups",
})
if err != nil {
resp.Diagnostics.AddError("Error enabling backups", err.Error())
return
}
err = r.waitForServerAction(ctx, state.Id.ValueInt64(), *backupResp.JSON200.Action.Id)
if err != nil {
resp.Diagnostics.AddError("Error waiting for backups to be enabled", err.Error())
return
}
} else {
backupResp, err := r.bc.client.PostServersServerIdActionsDisableBackupsWithResponse(ctx, state.Id.ValueInt64(), binarylane.DisableBackups{
Type: "disable_backups",
})
if err != nil {
resp.Diagnostics.AddError("Error disabling backups", err.Error())
return
}
err = r.waitForServerAction(ctx, state.Id.ValueInt64(), *backupResp.JSON200.Action.Id)
if err != nil {
resp.Diagnostics.AddError("Error waiting for backups to be disabled", err.Error())
return
}
}
state.Backups = plan.Backups
}
}
func (r *serverResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
var data serverModel
var data serverResourceModel
// Read Terraform prior state data into the model
resp.Diagnostics.Append(req.State.Get(ctx, &data)...)
@@ -871,7 +1009,7 @@ func (r *serverResource) waitForServerAction(ctx context.Context, serverId int64
}
}
func attrsRequiringRebuild(plan *serverModel, state *serverModel) []string {
func attrsRequiringRebuild(plan *serverResourceModel, state *serverResourceModel) []string {
attrs := []string{}
if !plan.SshKeys.Equal(state.SshKeys) {
@@ -917,3 +1055,53 @@ func (r *serverResource) updateSourceDestCheck(
return nil
}
func setServerResourceState(ctx context.Context, data *serverResourceModel, serverResp *binarylane.ServerResponse) diag.Diagnostics {
var diags diag.Diagnostics
data.Id = types.Int64Value(*serverResp.Server.Id)
data.Name = types.StringValue(*serverResp.Server.Name)
data.Image = types.StringValue(*serverResp.Server.Image.Slug)
data.Region = types.StringValue(*serverResp.Server.Region.Slug)
data.Size = types.StringValue(*serverResp.Server.Size.Slug)
data.Backups = types.BoolValue(serverResp.Server.NextBackupWindow != nil)
data.PortBlocking = types.BoolValue(serverResp.Server.Networks.PortBlocking)
data.VpcId = types.Int64PointerValue(serverResp.Server.VpcId)
data.Permalink = types.StringValue(*serverResp.Server.Permalink)
data.PasswordChangeSupported = types.BoolValue(*serverResp.Server.PasswordChangeSupported)
data.SourceAndDestinationCheck = types.BoolPointerValue(serverResp.Server.Networks.SourceAndDestinationCheck)
data.Memory = types.Int32Value(*serverResp.Server.Memory)
data.Disk = types.Int32Value(*serverResp.Server.Disk)
data.Backups = types.BoolValue(serverResp.Server.NextBackupWindow != nil)
publicIpv4Addresses := []string{}
privateIpv4Addresses := []string{}
for _, v4address := range serverResp.Server.Networks.V4 {
if v4address.Type == "public" {
publicIpv4Addresses = append(publicIpv4Addresses, v4address.IpAddress)
} else {
privateIpv4Addresses = append(privateIpv4Addresses, v4address.IpAddress)
}
}
tfPublicIpv4Addresses, diag := types.ListValueFrom(ctx, types.StringType, publicIpv4Addresses)
diags.Append(diag...)
if diag.HasError() {
data.PublicIpv4Addresses = types.ListUnknown(data.PublicIpv4Addresses.ElementType(ctx))
data.PublicIpv4Count = types.Int32Unknown()
} else {
data.PublicIpv4Addresses = tfPublicIpv4Addresses
data.PublicIpv4Count = types.Int32Value(int32(len(publicIpv4Addresses)))
}
tfPrivateIpv4Addresses, diag := types.ListValueFrom(ctx, types.StringType, privateIpv4Addresses)
diags.Append(diag...)
if diag.HasError() {
data.PrivateIPv4Addresses = types.ListUnknown(data.PrivateIPv4Addresses.ElementType(ctx))
} else {
data.PrivateIPv4Addresses = tfPrivateIpv4Addresses
}
return diags
}
+18 -3
View File
@@ -56,11 +56,13 @@ resource "binarylane_server" "test" {
region = "per"
image = "debian-11"
size = "std-min"
memory = 1152
password = "` + password + `"
vpc_id = binarylane_vpc.test.id
public_ipv4_count = 1
ssh_keys = [binarylane_ssh_key.initial.id]
source_and_destination_check = false
backups = true
user_data = <<EOT
#cloud-config
echo "Hello World" > /var/tmp/output.txt
@@ -80,6 +82,8 @@ data "binarylane_server" "test" {
resource.TestCheckResourceAttr("binarylane_server.test", "region", "per"),
resource.TestCheckResourceAttr("binarylane_server.test", "image", "debian-11"),
resource.TestCheckResourceAttr("binarylane_server.test", "size", "std-min"),
resource.TestCheckResourceAttr("binarylane_server.test", "memory", "1152"),
resource.TestCheckResourceAttr("binarylane_server.test", "disk", "20"),
resource.TestCheckResourceAttrSet("binarylane_server.test", "vpc_id"),
resource.TestCheckResourceAttr("binarylane_server.test", "public_ipv4_count", "1"),
resource.TestCheckResourceAttr("binarylane_server.test", "password", password),
@@ -93,6 +97,7 @@ echo "Hello World" > /var/tmp/output.txt
resource.TestCheckResourceAttrPair("binarylane_server.test", "ssh_keys.0", "binarylane_ssh_key.initial", "id"),
resource.TestCheckResourceAttrSet("binarylane_server.test", "permalink"),
resource.TestCheckResourceAttr("binarylane_server.test", "source_and_destination_check", "false"),
resource.TestCheckResourceAttr("binarylane_server.test", "backups", "true"),
// Verify data source values
resource.TestCheckResourceAttrPair("data.binarylane_server.test", "id", "binarylane_server.test", "id"),
@@ -100,10 +105,14 @@ echo "Hello World" > /var/tmp/output.txt
resource.TestCheckResourceAttr("data.binarylane_server.test", "region", "per"),
resource.TestCheckResourceAttr("data.binarylane_server.test", "image", "debian-11"),
resource.TestCheckResourceAttr("data.binarylane_server.test", "size", "std-min"),
resource.TestCheckResourceAttrSet("data.binarylane_server.test", "vpc_id"),
resource.TestCheckResourceAttrPair("data.binarylane_server.test", "permalink", "binarylane_server.test", "permalink"),
resource.TestCheckResourceAttr("data.binarylane_server.test", "user_data", `#cloud-config
echo "Hello World" > /var/tmp/output.txt
`),
resource.TestCheckResourceAttr("data.binarylane_server.test", "memory", "1152"),
resource.TestCheckResourceAttr("data.binarylane_server.test", "disk", "20"),
resource.TestCheckResourceAttr("data.binarylane_server.test", "backups", "true"),
),
},
// Test import by ID
@@ -146,11 +155,13 @@ resource "binarylane_server" "test" {
region = "per"
image = "debian-12"
size = "std-1vcpu"
disk = "45"
password = "` + password + `"
vpc_id = binarylane_vpc.test.id
vpc_id = null
public_ipv4_count = 0
ssh_keys = [binarylane_ssh_key.updated.id]
# source_and_destination_check = true # defaults to true
# source_and_destination_check = null # defaults to null when vpc_id is not set
# backups = false # defaults to false when backups is not set
user_data = <<EOT
#cloud-config
echo "Hello Whitespace" > /var/tmp/output.txt
@@ -162,12 +173,16 @@ EOT
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("binarylane_server.test", "name", "tf-test-server-resource-2"),
resource.TestCheckResourceAttr("binarylane_server.test", "size", "std-1vcpu"),
resource.TestCheckResourceAttr("binarylane_server.test", "memory", "2048"),
resource.TestCheckResourceAttr("binarylane_server.test", "disk", "45"),
resource.TestCheckResourceAttr("binarylane_server.test", "public_ipv4_count", "0"),
resource.TestCheckResourceAttr("binarylane_server.test", "public_ipv4_addresses.#", "0"),
resource.TestCheckResourceAttr("binarylane_server.test", "image", "debian-12"),
resource.TestCheckNoResourceAttr("binarylane_server.test", "vpc_id"),
resource.TestCheckResourceAttr("binarylane_server.test", "ssh_keys.#", "1"),
resource.TestCheckResourceAttrPair("binarylane_server.test", "ssh_keys.0", "binarylane_ssh_key.updated", "id"),
resource.TestCheckResourceAttr("binarylane_server.test", "source_and_destination_check", "true"),
resource.TestCheckNoResourceAttr("binarylane_server.test", "source_and_destination_check"),
resource.TestCheckResourceAttr("binarylane_server.test", "backups", "false"),
resource.TestCheckResourceAttr("binarylane_server.test", "user_data", // test extra whitespace
`#cloud-config
echo "Hello Whitespace" > /var/tmp/output.txt
+55
View File
@@ -0,0 +1,55 @@
package provider
import (
"context"
"fmt"
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
)
var (
_ validator.Int32 = &MultipleOfValidator{}
)
type MultipleOfValidator struct {
Multiple, RangeFrom, RangeTo int32
}
func (v MultipleOfValidator) Description(ctx context.Context) string {
if v.RangeFrom == 0 {
return fmt.Sprintf(`must be a multiple of %d`, v.Multiple)
}
return fmt.Sprintf("when greater than %d, must be a multiple of %d", v.RangeFrom, v.Multiple)
}
func (v MultipleOfValidator) MarkdownDescription(ctx context.Context) string {
if v.RangeFrom == 0 {
return fmt.Sprintf(`must be a multiple of %d`, v.Multiple)
}
return fmt.Sprintf("when greater than %d, must be a multiple of %d", v.RangeFrom, v.Multiple)
}
func (v MultipleOfValidator) ValidateInt32(ctx context.Context, req validator.Int32Request, resp *validator.Int32Response) {
if req.ConfigValue.IsUnknown() || req.ConfigValue.IsNull() {
return
}
memory := req.ConfigValue.ValueInt32()
if memory%v.Multiple == 0 || v.RangeFrom != 0 && memory < v.RangeFrom || v.RangeTo != 0 && memory >= v.RangeTo {
return
}
if v.RangeFrom != 0 {
resp.Diagnostics.AddAttributeError(
req.Path,
"Not a Multiple",
fmt.Sprintf("if greater than %d, value must be a multiple of %d", v.RangeFrom, v.Multiple),
)
} else {
resp.Diagnostics.AddAttributeError(
req.Path,
"Not a Multiple",
fmt.Sprintf("value must be a multiple of %d", v.Multiple),
)
}
}