mirror of
https://github.com/oscarhermoso/terraform-provider-binarylane
synced 2026-10-20 05:56:05 +11:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7f5bae6b15 | |||
| 4ef9df6edf | |||
| 547763d639 | |||
| f5fecdd69c | |||
| cd85f67e28 | |||
| 50d06b967b |
@@ -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" \
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -25,9 +25,24 @@ 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.
|
||||
- `source_and_destination_check` (Boolean) This attribute can only be set if your server also has a `vpc_id` attribute set. When enabled (which is `true` by default), your server will only be able to send or receive packets that are directly addressed to one of the IP addresses associated with the Cloud Server. Generally, this is desirable behaviour because it prevents IP conflicts and other hard-to-diagnose networking faults due to incorrect network configuration. When `source_and_destination_check` is `false`, your Cloud Server will be able to send and receive packets addressed to any server. This is typically used when you want to use your Cloud Server as a VPN endpoint, a NAT server to provide internet access, or IP forwarding.
|
||||
- `ssh_keys` (List of Number) This is a list of SSH key ids. If this is null or not provided, any SSH keys that have been marked as default will be deployed (assuming the operating system supports SSH Keys). Submit an empty list to disable deployment of default keys.
|
||||
- `timeouts` (Attributes) (see [below for nested schema](#nestedatt--timeouts))
|
||||
- `user_data` (String) If provided this will be used to initialise the new server. This must be left null if the Image does not support UserData, see DistributionInfo.Features for more information.
|
||||
|
||||
@@ -35,12 +35,13 @@ resource "binarylane_server" "db" {
|
||||
|
||||
# VPN server
|
||||
resource "binarylane_server" "vpn" {
|
||||
name = "tf-example-vpc-vpn"
|
||||
region = "per"
|
||||
image = "ubuntu-24.04"
|
||||
size = "std-min"
|
||||
vpc_id = binarylane_vpc.example.id
|
||||
public_ipv4_count = 1
|
||||
name = "tf-example-vpc-vpn"
|
||||
region = "per"
|
||||
image = "ubuntu-24.04"
|
||||
size = "std-min"
|
||||
vpc_id = binarylane_vpc.example.id
|
||||
public_ipv4_count = 1
|
||||
source_and_destination_check = false
|
||||
}
|
||||
|
||||
resource "binarylane_vpc_route_entries" "example" {
|
||||
|
||||
@@ -6,13 +6,13 @@ 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-go v0.25.0
|
||||
github.com/hashicorp/terraform-plugin-log v0.9.0
|
||||
github.com/hashicorp/terraform-plugin-testing v1.10.0
|
||||
github.com/hashicorp/terraform-plugin-testing v1.11.0
|
||||
github.com/oapi-codegen/oapi-codegen/v2 v2.4.1
|
||||
github.com/oapi-codegen/runtime v1.1.1
|
||||
)
|
||||
@@ -55,12 +55,12 @@ require (
|
||||
github.com/hashicorp/go-uuid v1.0.3 // indirect
|
||||
github.com/hashicorp/go-version v1.7.0 // indirect
|
||||
github.com/hashicorp/hc-install v0.9.0 // indirect
|
||||
github.com/hashicorp/hcl/v2 v2.21.0 // indirect
|
||||
github.com/hashicorp/hcl/v2 v2.23.0 // indirect
|
||||
github.com/hashicorp/logutils v1.0.0 // indirect
|
||||
github.com/hashicorp/terraform-exec v0.21.0 // indirect
|
||||
github.com/hashicorp/terraform-json v0.23.0 // indirect
|
||||
github.com/hashicorp/terraform-plugin-codegen-spec v0.2.0 // indirect
|
||||
github.com/hashicorp/terraform-plugin-sdk/v2 v2.34.0 // indirect
|
||||
github.com/hashicorp/terraform-plugin-sdk/v2 v2.35.0 // indirect
|
||||
github.com/hashicorp/terraform-registry-address v0.2.3 // indirect
|
||||
github.com/hashicorp/terraform-svchost v0.1.1 // indirect
|
||||
github.com/hashicorp/yamux v0.1.2 // indirect
|
||||
@@ -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.28.0 // indirect
|
||||
golang.org/x/crypto v0.29.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.8.0 // indirect
|
||||
golang.org/x/sys v0.26.0 // indirect
|
||||
golang.org/x/text v0.19.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/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
|
||||
|
||||
@@ -131,8 +131,8 @@ github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKe
|
||||
github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/hc-install v0.9.0 h1:2dIk8LcvANwtv3QZLckxcjyF5w8KVtiMxu6G6eLhghE=
|
||||
github.com/hashicorp/hc-install v0.9.0/go.mod h1:+6vOP+mf3tuGgMApVYtmsnDoKWMDcFXeTxCACYZ8SFg=
|
||||
github.com/hashicorp/hcl/v2 v2.21.0 h1:lve4q/o/2rqwYOgUg3y3V2YPyD1/zkCLGjIV74Jit14=
|
||||
github.com/hashicorp/hcl/v2 v2.21.0/go.mod h1:62ZYHrXgPoX8xBnzl8QzbWq4dyDsDtfCRgIq1rbJEvA=
|
||||
github.com/hashicorp/hcl/v2 v2.23.0 h1:Fphj1/gCylPxHutVSEOf2fBOh1VE4AuLV7+kbJf3qos=
|
||||
github.com/hashicorp/hcl/v2 v2.23.0/go.mod h1:62ZYHrXgPoX8xBnzl8QzbWq4dyDsDtfCRgIq1rbJEvA=
|
||||
github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y=
|
||||
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
||||
github.com/hashicorp/terraform-exec v0.21.0 h1:uNkLAe95ey5Uux6KJdua6+cv8asgILFVWkd/RG0D2XQ=
|
||||
@@ -145,8 +145,8 @@ 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=
|
||||
@@ -157,10 +157,10 @@ github.com/hashicorp/terraform-plugin-go v0.25.0 h1:oi13cx7xXA6QciMcpcFi/rwA974r
|
||||
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=
|
||||
github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow=
|
||||
github.com/hashicorp/terraform-plugin-sdk/v2 v2.34.0 h1:kJiWGx2kiQVo97Y5IOGR4EMcZ8DtMswHhUuFibsCQQE=
|
||||
github.com/hashicorp/terraform-plugin-sdk/v2 v2.34.0/go.mod h1:sl/UoabMc37HA6ICVMmGO+/0wofkVIRxf+BMb/dnoIg=
|
||||
github.com/hashicorp/terraform-plugin-testing v1.10.0 h1:2+tmRNhvnfE4Bs8rB6v58S/VpqzGC6RCh9Y8ujdn+aw=
|
||||
github.com/hashicorp/terraform-plugin-testing v1.10.0/go.mod h1:iWRW3+loP33WMch2P/TEyCxxct/ZEcCGMquSLSCVsrc=
|
||||
github.com/hashicorp/terraform-plugin-sdk/v2 v2.35.0 h1:wyKCCtn6pBBL46c1uIIBNUOWlNfYXfXpVo16iDyLp8Y=
|
||||
github.com/hashicorp/terraform-plugin-sdk/v2 v2.35.0/go.mod h1:B0Al8NyYVr8Mp/KLwssKXG1RqnTk7FySqSn4fRuLNgw=
|
||||
github.com/hashicorp/terraform-plugin-testing v1.11.0 h1:MeDT5W3YHbONJt2aPQyaBsgQeAIckwPX41EUHXEn29A=
|
||||
github.com/hashicorp/terraform-plugin-testing v1.11.0/go.mod h1:WNAHQ3DcgV/0J+B15WTE6hDvxcUdkPPpnB1FR3M910U=
|
||||
github.com/hashicorp/terraform-registry-address v0.2.3 h1:2TAiKJ1A3MAkZlH1YI/aTVcLZRu7JseiXNRHbOAyoTI=
|
||||
github.com/hashicorp/terraform-registry-address v0.2.3/go.mod h1:lFHA76T8jfQteVfT7caREqguFrW3c4MFSPhZB7HHgUM=
|
||||
github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ=
|
||||
@@ -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.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
|
||||
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
|
||||
golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ=
|
||||
golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg=
|
||||
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.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
|
||||
golang.org/x/sync v0.9.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.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
|
||||
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
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/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.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
|
||||
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
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/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=
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -12,11 +12,13 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework-timeouts/resource/timeouts"
|
||||
"github.com/hashicorp/terraform-plugin-framework-validators/boolvalidator"
|
||||
"github.com/hashicorp/terraform-plugin-framework-validators/int32validator"
|
||||
"github.com/hashicorp/terraform-plugin-framework-validators/int64validator"
|
||||
"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"
|
||||
@@ -48,15 +50,14 @@ type serverResource struct {
|
||||
bc *BinarylaneClient
|
||||
}
|
||||
|
||||
type serverModel struct {
|
||||
resources.ServerModel
|
||||
PublicIpv4Count types.Int32 `tfsdk:"public_ipv4_count"`
|
||||
PublicIpv4Addresses types.List `tfsdk:"public_ipv4_addresses"`
|
||||
PrivateIPv4Addresses types.List `tfsdk:"private_ipv4_addresses"`
|
||||
Permalink types.String `tfsdk:"permalink"`
|
||||
Password types.String `tfsdk:"password"`
|
||||
PasswordChangeSupported types.Bool `tfsdk:"password_change_supported"`
|
||||
Timeouts timeouts.Value `tfsdk:"timeouts"`
|
||||
type serverResourceModel struct {
|
||||
serverDataModel
|
||||
|
||||
PublicIpv4Count types.Int32 `tfsdk:"public_ipv4_count"`
|
||||
SourceAndDestinationCheck types.Bool `tfsdk:"source_and_destination_check"`
|
||||
Password types.String `tfsdk:"password"`
|
||||
PasswordChangeSupported types.Bool `tfsdk:"password_change_supported"`
|
||||
Timeouts timeouts.Value `tfsdk:"timeouts"`
|
||||
}
|
||||
|
||||
func (d *serverResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) {
|
||||
@@ -135,7 +136,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"]
|
||||
@@ -185,6 +185,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),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -199,6 +200,26 @@ func (r *serverResource) Schema(ctx context.Context, _ resource.SchemaRequest, r
|
||||
Computed: true,
|
||||
}
|
||||
|
||||
sourceDestCheckDescription := "This attribute can only be set if your server also has a `vpc_id` attribute set. " +
|
||||
"When enabled (which is `true` by default), your server will only be able to send or receive " +
|
||||
"packets that are directly addressed to one of the IP addresses associated with the Cloud Server. Generally, " +
|
||||
"this is desirable behaviour because it prevents IP conflicts and other hard-to-diagnose networking faults due " +
|
||||
"to incorrect network configuration. When `source_and_destination_check` is `false`, your Cloud Server will be able " +
|
||||
"to send and receive packets addressed to any server. This is typically used when you want to use " +
|
||||
"your Cloud Server as a VPN endpoint, a NAT server to provide internet access, or IP forwarding."
|
||||
resp.Schema.Attributes["source_and_destination_check"] = &schema.BoolAttribute{
|
||||
Description: sourceDestCheckDescription,
|
||||
MarkdownDescription: sourceDestCheckDescription,
|
||||
Optional: true,
|
||||
Required: false,
|
||||
Computed: true,
|
||||
Validators: []validator.Bool{
|
||||
boolvalidator.AlsoRequires(path.Expressions{
|
||||
path.MatchRoot("vpc_id"),
|
||||
}...),
|
||||
},
|
||||
}
|
||||
|
||||
privateIpv4AddressesDescription := "The private IPv4 addresses assigned to the server."
|
||||
resp.Schema.Attributes["private_ipv4_addresses"] = &schema.ListAttribute{
|
||||
Description: privateIpv4AddressesDescription,
|
||||
@@ -240,6 +261,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,
|
||||
@@ -248,20 +321,43 @@ func (r *serverResource) Schema(ctx context.Context, _ resource.SchemaRequest, r
|
||||
}
|
||||
|
||||
func (r *serverResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
|
||||
// Creation or destruction plan
|
||||
if req.Plan.Raw.IsNull() || req.State.Raw.IsNull() {
|
||||
var plan, state serverResourceModel
|
||||
|
||||
if req.Plan.Raw.IsNull() {
|
||||
// Destruction plan, no modification needed
|
||||
return
|
||||
}
|
||||
|
||||
var plan, state serverModel
|
||||
|
||||
// Read Terraform plan data into the model
|
||||
resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
|
||||
resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
if plan.SourceAndDestinationCheck.IsUnknown() {
|
||||
if plan.VpcId.IsNull() {
|
||||
plan.SourceAndDestinationCheck = types.BoolNull()
|
||||
} else {
|
||||
plan.SourceAndDestinationCheck = types.BoolPointerValue(Pointer(true))
|
||||
}
|
||||
resp.Diagnostics.Append(resp.Plan.Set(ctx, &plan)...)
|
||||
}
|
||||
|
||||
if req.State.Raw.IsNull() {
|
||||
// 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)
|
||||
@@ -294,12 +390,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)
|
||||
@@ -337,6 +441,13 @@ func (r *serverResource) Create(ctx context.Context, req resource.CreateRequest,
|
||||
},
|
||||
}
|
||||
|
||||
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() {
|
||||
data.Password = types.StringNull()
|
||||
} else {
|
||||
@@ -374,7 +485,7 @@ func (r *serverResource) Create(ctx context.Context, req resource.CreateRequest,
|
||||
fmt.Sprintf("Received %s creating new server: name=%s. Details: %s", serverResp.Status(), data.Name.ValueString(), serverResp.Body))
|
||||
return
|
||||
}
|
||||
err = r.waitForServerAction(ctx, *serverResp.JSON200.Server.Id, createActionId, "create")
|
||||
err = r.waitForServerAction(ctx, *serverResp.JSON200.Server.Id, createActionId)
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddError("Error waiting for server to be created", err.Error())
|
||||
}
|
||||
@@ -389,6 +500,11 @@ 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
|
||||
|
||||
publicIpv4Addresses := []string{}
|
||||
privateIpv4Addresses := []string{}
|
||||
@@ -406,10 +522,23 @@ func (r *serverResource) Create(ctx context.Context, req resource.CreateRequest,
|
||||
|
||||
// Save data into Terraform state
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
|
||||
|
||||
// Update source_and_destination_check if needed
|
||||
if plannedSourceDestCheck.Equal(types.BoolPointerValue(Pointer(false))) {
|
||||
err := r.updateSourceDestCheck(ctx, data.Id.ValueInt64(), false)
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddError("Error updating source and destination check", err.Error())
|
||||
return
|
||||
}
|
||||
data.SourceAndDestinationCheck = plannedSourceDestCheck
|
||||
}
|
||||
|
||||
// Save data into Terraform state
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
|
||||
}
|
||||
|
||||
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)
|
||||
@@ -437,35 +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)
|
||||
|
||||
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())
|
||||
@@ -490,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)...)
|
||||
@@ -505,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 {
|
||||
@@ -541,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, ¤tIps, false)
|
||||
@@ -571,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()))
|
||||
|
||||
@@ -598,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, "resize")
|
||||
|
||||
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
|
||||
@@ -669,7 +831,7 @@ func (r *serverResource) Update(ctx context.Context, req resource.UpdateRequest,
|
||||
fmt.Sprintf("Received %s rebuilding server: server_id=%s. Details: %s", rebuildResp.Status(), state.Id.String(), rebuildResp.Body))
|
||||
return
|
||||
}
|
||||
err = r.waitForServerAction(ctx, state.Id.ValueInt64(), *rebuildResp.JSON200.Action.Id, "rebuild")
|
||||
err = r.waitForServerAction(ctx, state.Id.ValueInt64(), *rebuildResp.JSON200.Action.Id)
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddError("Error waiting for server to be rebuilt", err.Error())
|
||||
return
|
||||
@@ -682,10 +844,26 @@ func (r *serverResource) Update(ctx context.Context, req resource.UpdateRequest,
|
||||
// Save updated data into Terraform state
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
|
||||
}
|
||||
|
||||
// Check source_and_destination_check
|
||||
if !plan.SourceAndDestinationCheck.Equal(state.SourceAndDestinationCheck) {
|
||||
if !plan.SourceAndDestinationCheck.IsNull() {
|
||||
err := r.updateSourceDestCheck(ctx, state.Id.ValueInt64(), plan.SourceAndDestinationCheck.ValueBool())
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddError("Error updating source and destination check", err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
state.SourceAndDestinationCheck = plan.SourceAndDestinationCheck
|
||||
|
||||
// Save updated data into Terraform state
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
|
||||
}
|
||||
}
|
||||
|
||||
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)...)
|
||||
@@ -765,36 +943,41 @@ func (r *serverResource) ImportState(
|
||||
resp.Diagnostics.Append(diags...)
|
||||
}
|
||||
|
||||
func (r *serverResource) waitForServerAction(ctx context.Context, serverId int64, actionId int64, actionType string) error {
|
||||
func (r *serverResource) waitForServerAction(ctx context.Context, serverId int64, actionId int64) error {
|
||||
var lastReadyResp *binarylane.GetServersServerIdActionsActionIdResponse
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
if lastReadyResp == nil {
|
||||
return fmt.Errorf("timed out waiting for server %d to %s", serverId, actionType)
|
||||
return fmt.Errorf("timed out waiting for server action: server_id=%d, action_id=%d", serverId, actionId)
|
||||
} else {
|
||||
return fmt.Errorf("timed out waiting for server %d to %s, last response was status=%s, body: %s", serverId, actionType, lastReadyResp.Status(), lastReadyResp.Body)
|
||||
return fmt.Errorf("timed out waiting for server action: server_id=%d, action_id=%d, last response was status=%s, body: %s",
|
||||
serverId, actionId, lastReadyResp.Status(), lastReadyResp.Body)
|
||||
}
|
||||
default:
|
||||
readyResp, err := r.bc.client.GetServersServerIdActionsActionIdWithResponse(ctx, serverId, actionId)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unexpected error waiting for server %d to %s: %w", serverId, actionType, err)
|
||||
return fmt.Errorf("unexpected error waiting for server action: server_id=%d, action_id=%d, error: %w", serverId, actionId, err)
|
||||
}
|
||||
if readyResp.StatusCode() == http.StatusOK && *readyResp.JSON200.Action.Status == binarylane.Errored {
|
||||
return fmt.Errorf("server %d failed to %s with error: %s", serverId, actionType, *readyResp.JSON200.Action.ResultData)
|
||||
return fmt.Errorf("server action failed to with error: server_id=%d, action_id=%d, error: %s", serverId, actionId, *readyResp.JSON200.Action.ResultData)
|
||||
}
|
||||
if readyResp.StatusCode() == http.StatusOK && readyResp.JSON200.Action.CompletedAt != nil {
|
||||
return nil
|
||||
}
|
||||
lastReadyResp = readyResp
|
||||
tflog.Debug(ctx, fmt.Sprintf("waiting for server %d to %s: last response was status=%s, details: %s", serverId, actionType, readyResp.Status(), readyResp.Body))
|
||||
tflog.Debug(ctx,
|
||||
fmt.Sprintf("waiting for server action for server_id=%d, action_id=%d: last response was status=%s, details: %s",
|
||||
serverId, actionId, readyResp.Status(), readyResp.Body,
|
||||
),
|
||||
)
|
||||
}
|
||||
time.Sleep(time.Second * 5)
|
||||
}
|
||||
}
|
||||
|
||||
func attrsRequiringRebuild(plan *serverModel, state *serverModel) []string {
|
||||
func attrsRequiringRebuild(plan *serverResourceModel, state *serverResourceModel) []string {
|
||||
attrs := []string{}
|
||||
|
||||
if !plan.SshKeys.Equal(state.SshKeys) {
|
||||
@@ -809,3 +992,83 @@ func attrsRequiringRebuild(plan *serverModel, state *serverModel) []string {
|
||||
|
||||
return attrs
|
||||
}
|
||||
|
||||
func (r *serverResource) updateSourceDestCheck(
|
||||
ctx context.Context,
|
||||
serverId int64,
|
||||
sourceDestCheckEnabled bool,
|
||||
) error {
|
||||
tflog.Info(ctx, fmt.Sprintf("Changing source and destination check for server: server_id=%d, enabled=%t",
|
||||
serverId, sourceDestCheckEnabled))
|
||||
|
||||
sourceDestCheckResp, err := r.bc.client.PostServersServerIdActionsChangeSourceAndDestinationCheckWithResponse(
|
||||
ctx,
|
||||
serverId,
|
||||
binarylane.PostServersServerIdActionsChangeSourceAndDestinationCheckJSONRequestBody{
|
||||
Type: "change_source_and_destination_check",
|
||||
Enabled: sourceDestCheckEnabled,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error changing source and destination check for server: server_id=%d, error: %w", serverId, err)
|
||||
}
|
||||
if sourceDestCheckResp.StatusCode() != http.StatusOK {
|
||||
return fmt.Errorf("unexpected HTTP status code changing source and destination check for server: server_id=%d, details: %s", serverId, sourceDestCheckResp.Body)
|
||||
}
|
||||
|
||||
err = r.waitForServerAction(ctx, serverId, *sourceDestCheckResp.JSON200.Action.Id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error changing source and destination check: %w", err)
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@@ -56,10 +56,12 @@ 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
|
||||
user_data = <<EOT
|
||||
#cloud-config
|
||||
echo "Hello World" > /var/tmp/output.txt
|
||||
@@ -79,6 +81,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),
|
||||
@@ -91,6 +95,7 @@ echo "Hello World" > /var/tmp/output.txt
|
||||
resource.TestCheckResourceAttr("binarylane_server.test", "ssh_keys.#", "1"),
|
||||
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"),
|
||||
|
||||
// Verify data source values
|
||||
resource.TestCheckResourceAttrPair("data.binarylane_server.test", "id", "binarylane_server.test", "id"),
|
||||
@@ -98,10 +103,13 @@ 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"),
|
||||
),
|
||||
},
|
||||
// Test import by ID
|
||||
@@ -144,10 +152,12 @@ 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 = null # defaults to null when vpc_id is null
|
||||
user_data = <<EOT
|
||||
#cloud-config
|
||||
echo "Hello Whitespace" > /var/tmp/output.txt
|
||||
@@ -159,11 +169,15 @@ 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.TestCheckNoResourceAttr("binarylane_server.test", "source_and_destination_check"),
|
||||
resource.TestCheckResourceAttr("binarylane_server.test", "user_data", // test extra whitespace
|
||||
`#cloud-config
|
||||
echo "Hello Whitespace" > /var/tmp/output.txt
|
||||
|
||||
@@ -177,3 +177,7 @@ func listContainsUnknown(ctx context.Context, list types.List) bool {
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func Pointer[T any](d T) *T {
|
||||
return &d
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user