forked from mirrors/terraform-provider-binarylane
* Initial plan * Initial plan for separate_private_network_interface support Agent-Logs-Url: https://github.com/oscarhermoso/terraform-provider-binarylane/sessions/df438ec9-fdbb-47a3-8ebb-592ee2843eed * Add separate_private_network_interface to server resource and data source Agent-Logs-Url: https://github.com/oscarhermoso/terraform-provider-binarylane/sessions/df438ec9-fdbb-47a3-8ebb-592ee2843eed * Run go fmt and add AGENTS.md Agent-Logs-Url: https://github.com/oscarhermoso/terraform-provider-binarylane/sessions/1f274b93-d7c2-4547-a24d-8d36472c8092 * Add source_and_destination_check assertion to data source test checks Agent-Logs-Url: https://github.com/oscarhermoso/terraform-provider-binarylane/sessions/8684d505-33e7-407c-a4fb-c6260ffdb2ea * go generate: update types_gen.go with latest API schema (Action.Reason, Action.Title, Invoice.InvoiceViewUrl) Agent-Logs-Url: https://github.com/oscarhermoso/terraform-provider-binarylane/sessions/1baa947c-aaee-4c45-b2b8-9495ccf38b82 * Fix separate_private_network_interface: add ModifyPlan unknown handling and IsUnknown guard in Update Agent-Logs-Url: https://github.com/oscarhermoso/terraform-provider-binarylane/sessions/e9b9d51d-8447-48a5-8c61-9c749562c3e1 * Simplify separate_private_network_interface description and remove dead code Match the OpenAPI schema phrasing for consistency with other attribute descriptions, and drop the defensive IsUnknown guard in Update — ModifyPlan already resolves Unknown to Null/false before Update runs. --------- Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
# AGENTS.md
|
||||
|
||||
## Before starting
|
||||
|
||||
Run `go generate` to pull in the latest API schema before making changes.
|
||||
|
||||
## Code style
|
||||
|
||||
- Follow patterns in existing resources, especially `server_resource.go` and `server_data_source.go`.
|
||||
- New server attributes that map to a post-creation API action (e.g. `change_*`) follow the `source_and_destination_check` / `separate_private_network_interface` pattern: read the planned value before the first state save, call the action after creation if the value differs from the server default, and handle updates in the `Update` method.
|
||||
- Run `go fmt ./...` before finishing — the CI will fail without it.
|
||||
- Don't add `Required: false` when `Optional: true` is already set; it is redundant.
|
||||
|
||||
## Testing
|
||||
|
||||
- Tests live in `internal/provider/*_test.go`.
|
||||
- A valid `BINARYLANE_API_TOKEN` is required; tests create real servers that cost money — be conscientious.
|
||||
- **Always run the sweeper after tests**, regardless of success or failure:
|
||||
```sh
|
||||
go test -v ./internal/provider/... -sweep=all
|
||||
```
|
||||
- Run a specific test with:
|
||||
```sh
|
||||
go test -v -run TestServerResource ./internal/provider/...
|
||||
```
|
||||
- New attributes on the server resource should be exercised inside an existing test step where possible (e.g. the first step of `TestServerResource` already provisions a VPC server).
|
||||
|
||||
## Workflow
|
||||
|
||||
1. `go generate` — fetch latest OpenAPI spec and regenerate code + docs.
|
||||
2. Make changes.
|
||||
3. `go fmt ./...` — format code.
|
||||
4. `go build ./...` — verify it compiles.
|
||||
5. `go vet ./...` — catch common mistakes.
|
||||
6. Run relevant tests, then sweep.
|
||||
7. `go generate` again to regenerate docs if schema or descriptions changed.
|
||||
@@ -48,6 +48,7 @@ data "binarylane_server" "example" {
|
||||
- `public_ipv4_addresses` (List of String) The public IPv4 addresses assigned to the server.
|
||||
- `public_ipv6_addresses` (List of String) The public IPv6 addresses assigned to the server.
|
||||
- `region` (String) The slug of the selected region.
|
||||
- `separate_private_network_interface` (Boolean) This attribute can only be set if your server also has a `vpc_id` attribute set. When enabled, a separate private network interface is provided for the server's VPC traffic.
|
||||
- `size` (String) The slug of the selected size.
|
||||
- `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.
|
||||
|
||||
@@ -53,6 +53,7 @@ resource "binarylane_server" "example" {
|
||||
- `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.
|
||||
- `separate_private_network_interface` (Boolean) This attribute can only be set if your server also has a `vpc_id` attribute set. When enabled, a separate private network interface is provided for the server's VPC traffic.
|
||||
- `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))
|
||||
|
||||
@@ -1258,6 +1258,9 @@ type Action struct {
|
||||
// Progress Information about the current progress of the action. Some actions are divided into 'steps' and this may also contain information about the current and completed steps.
|
||||
Progress ActionProgress `json:"progress"`
|
||||
|
||||
// Reason A user-friendly explanation of what is happening.
|
||||
Reason string `json:"reason"`
|
||||
|
||||
// Region The region (if any) of the resource associated with this action.
|
||||
Region *Region `json:"region,omitempty"`
|
||||
|
||||
@@ -1287,6 +1290,9 @@ type Action struct {
|
||||
StartedAt time.Time `json:"started_at"`
|
||||
Status ActionStatus `json:"status"`
|
||||
|
||||
// Title A short display name for the action.
|
||||
Title string `json:"title"`
|
||||
|
||||
// Type The type of this action.
|
||||
Type string `json:"type"`
|
||||
|
||||
@@ -1764,7 +1770,7 @@ type ChangeManageOffsiteBackupCopiesType string
|
||||
type ChangeNetwork struct {
|
||||
Type ChangeNetworkType `json:"type"`
|
||||
|
||||
// VpcId If this is null the server will be moved into the default public network for the server's region.
|
||||
// VpcId If this is null the server will be moved into the public network for the server's region.
|
||||
VpcId *int64 `json:"vpc_id,omitempty"`
|
||||
}
|
||||
|
||||
@@ -2608,7 +2614,7 @@ type Invoice struct {
|
||||
// DateOverdue The date in ISO8601 format this invoice is considered overdue.
|
||||
DateOverdue time.Time `json:"date_overdue"`
|
||||
|
||||
// InvoiceDownloadUrl The download URL for the rendered version of the invoice.
|
||||
// InvoiceDownloadUrl The download URL for the PDF version of the invoice. This URL expires 24 hours after it is generated.
|
||||
InvoiceDownloadUrl *string `json:"invoice_download_url,omitempty"`
|
||||
|
||||
// InvoiceId The ID of the invoice.
|
||||
@@ -2620,6 +2626,9 @@ type Invoice struct {
|
||||
// InvoiceNumber The invoice number for this invoice.
|
||||
InvoiceNumber string `json:"invoice_number"`
|
||||
|
||||
// InvoiceViewUrl The URL for the HTML rendered version of the invoice. This URL expires 24 hours after it is generated.
|
||||
InvoiceViewUrl *string `json:"invoice_view_url,omitempty"`
|
||||
|
||||
// Paid If this is true the invoice has been paid.
|
||||
Paid bool `json:"paid"`
|
||||
|
||||
|
||||
@@ -182,7 +182,7 @@ func init() {
|
||||
return fmt.Errorf("Unexpected status code getting load balancers for test sweep: %s", listResp.Body)
|
||||
}
|
||||
|
||||
loadBalancers := listResp.JSON200.LoadBalancers
|
||||
loadBalancers := listResp.JSON200.LoadBalancers
|
||||
for _, lb := range loadBalancers {
|
||||
if strings.HasPrefix(lb.Name, "tf-test-") {
|
||||
deleteResp, err := client.DeleteLoadBalancersLoadBalancerIdWithResponse(ctx, lb.Id)
|
||||
|
||||
@@ -30,14 +30,15 @@ type serverDataSource struct {
|
||||
|
||||
type serverDataModel struct {
|
||||
resources.ServerModel
|
||||
PublicIpv4Addresses types.List `tfsdk:"public_ipv4_addresses"`
|
||||
PrivateIPv4Addresses types.List `tfsdk:"private_ipv4_addresses"`
|
||||
PublicIpv6Addresses types.List `tfsdk:"public_ipv6_addresses"`
|
||||
PrivateIpv6Addresses types.List `tfsdk:"private_ipv6_addresses"`
|
||||
Permalink types.String `tfsdk:"permalink"`
|
||||
Memory types.Int32 `tfsdk:"memory"`
|
||||
Disk types.Int32 `tfsdk:"disk"`
|
||||
SourceAndDestinationCheck types.Bool `tfsdk:"source_and_destination_check"`
|
||||
PublicIpv4Addresses types.List `tfsdk:"public_ipv4_addresses"`
|
||||
PrivateIPv4Addresses types.List `tfsdk:"private_ipv4_addresses"`
|
||||
PublicIpv6Addresses types.List `tfsdk:"public_ipv6_addresses"`
|
||||
PrivateIpv6Addresses types.List `tfsdk:"private_ipv6_addresses"`
|
||||
Permalink types.String `tfsdk:"permalink"`
|
||||
Memory types.Int32 `tfsdk:"memory"`
|
||||
Disk types.Int32 `tfsdk:"disk"`
|
||||
SourceAndDestinationCheck types.Bool `tfsdk:"source_and_destination_check"`
|
||||
SeparatePrivateNetworkInterface types.Bool `tfsdk:"separate_private_network_interface"`
|
||||
}
|
||||
|
||||
func (d *serverDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
|
||||
@@ -119,6 +120,7 @@ func (d *serverDataSource) Read(ctx context.Context, req datasource.ReadRequest,
|
||||
data.Memory = types.Int32Value(serverResp.JSON200.Server.Memory)
|
||||
data.Disk = types.Int32Value(serverResp.JSON200.Server.Disk)
|
||||
data.SourceAndDestinationCheck = types.BoolPointerValue(serverResp.JSON200.Server.Networks.SourceAndDestinationCheck)
|
||||
data.SeparatePrivateNetworkInterface = types.BoolPointerValue(serverResp.JSON200.Server.Networks.SeparatePrivateNetworkInterface)
|
||||
|
||||
if serverResp.JSON200.Server.VpcId == nil {
|
||||
data.VpcIpv4Address = types.StringNull()
|
||||
|
||||
@@ -241,6 +241,20 @@ func serverSchema(ctx context.Context) schema.Schema {
|
||||
},
|
||||
}
|
||||
|
||||
separatePrivateNicDescription := "This attribute can only be set if your server also has a `vpc_id` attribute set. " +
|
||||
"When enabled, a separate private network interface is provided for the server's VPC traffic."
|
||||
s.Attributes["separate_private_network_interface"] = schema.BoolAttribute{
|
||||
Description: separatePrivateNicDescription,
|
||||
MarkdownDescription: separatePrivateNicDescription,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Validators: []validator.Bool{
|
||||
boolvalidator.AlsoRequires(path.Expressions{
|
||||
path.MatchRoot("vpc_id"),
|
||||
}...),
|
||||
},
|
||||
}
|
||||
|
||||
privateIpv4AddressesDescription := "The private IPv4 addresses assigned to the server."
|
||||
s.Attributes["private_ipv4_addresses"] = schema.ListAttribute{
|
||||
Description: privateIpv4AddressesDescription,
|
||||
@@ -418,6 +432,15 @@ func (r *serverResource) ModifyPlan(ctx context.Context, req resource.ModifyPlan
|
||||
resp.Diagnostics.Append(resp.Plan.Set(ctx, &plan)...)
|
||||
}
|
||||
|
||||
if plan.SeparatePrivateNetworkInterface.IsUnknown() {
|
||||
if plan.VpcId.IsNull() {
|
||||
plan.SeparatePrivateNetworkInterface = types.BoolNull()
|
||||
} else {
|
||||
plan.SeparatePrivateNetworkInterface = types.BoolPointerValue(Pointer(false))
|
||||
}
|
||||
resp.Diagnostics.Append(resp.Plan.Set(ctx, &plan)...)
|
||||
}
|
||||
|
||||
if plan.VpcIpv4Address.IsUnknown() {
|
||||
if plan.VpcId.IsNull() {
|
||||
plan.VpcIpv4Address = types.StringNull()
|
||||
@@ -670,6 +693,9 @@ func (r *serverResource) Create(ctx context.Context, req resource.CreateRequest,
|
||||
plannedSourceDestCheck := data.SourceAndDestinationCheck
|
||||
serverRespSourceDestCheck := types.BoolPointerValue(serverResp.JSON200.Server.Networks.SourceAndDestinationCheck)
|
||||
data.SourceAndDestinationCheck = serverRespSourceDestCheck
|
||||
plannedSeparatePrivateNic := data.SeparatePrivateNetworkInterface
|
||||
serverRespSeparatePrivateNic := types.BoolPointerValue(serverResp.JSON200.Server.Networks.SeparatePrivateNetworkInterface)
|
||||
data.SeparatePrivateNetworkInterface = serverRespSeparatePrivateNic
|
||||
|
||||
if serverResp.JSON200.Server.VpcId == nil {
|
||||
data.VpcIpv4Address = types.StringNull()
|
||||
@@ -745,6 +771,16 @@ func (r *serverResource) Create(ctx context.Context, req resource.CreateRequest,
|
||||
data.SourceAndDestinationCheck = plannedSourceDestCheck
|
||||
}
|
||||
|
||||
// Update separate_private_network_interface if needed
|
||||
if plannedSeparatePrivateNic.Equal(types.BoolPointerValue(Pointer(true))) {
|
||||
err := r.updateSeparatePrivateNetworkInterface(ctx, data.Id.ValueInt64(), true)
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddError("Error updating separate private network interface", err.Error())
|
||||
return
|
||||
}
|
||||
data.SeparatePrivateNetworkInterface = plannedSeparatePrivateNic
|
||||
}
|
||||
|
||||
// One extra read to check the final state of enabled_advanced_features, needed because
|
||||
// some flags (like "cloud-init") are not set until the server is fully created. See #13
|
||||
diag := r.fetchServerResourceState(ctx, &data)
|
||||
@@ -1174,6 +1210,25 @@ func (r *serverResource) Update(ctx context.Context, req resource.UpdateRequest,
|
||||
}
|
||||
}
|
||||
|
||||
// Check separate_private_network_interface
|
||||
if !plan.SeparatePrivateNetworkInterface.Equal(state.SeparatePrivateNetworkInterface) {
|
||||
if !plan.SeparatePrivateNetworkInterface.IsNull() {
|
||||
err := r.updateSeparatePrivateNetworkInterface(ctx, state.Id.ValueInt64(), plan.SeparatePrivateNetworkInterface.ValueBool())
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddError("Error updating separate private network interface", err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
state.SeparatePrivateNetworkInterface = plan.SeparatePrivateNetworkInterface
|
||||
|
||||
// Save updated data into Terraform state
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Enable or disable backups
|
||||
if !plan.Backups.Equal(state.Backups) {
|
||||
if plan.Backups.ValueBool() {
|
||||
@@ -1398,6 +1453,37 @@ func (r *serverResource) updateSourceDestCheck(
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *serverResource) updateSeparatePrivateNetworkInterface(
|
||||
ctx context.Context,
|
||||
serverId int64,
|
||||
enabled bool,
|
||||
) error {
|
||||
tflog.Info(ctx, fmt.Sprintf("Changing separate private network interface for server: server_id=%d, enabled=%t",
|
||||
serverId, enabled))
|
||||
|
||||
separatePrivateNicResp, err := r.bc.client.PostServersServerIdActionsChangeSeparatePrivateNetworkInterfaceWithResponse(
|
||||
ctx,
|
||||
serverId,
|
||||
binarylane.PostServersServerIdActionsChangeSeparatePrivateNetworkInterfaceJSONRequestBody{
|
||||
Type: "change_separate_private_network_interface",
|
||||
Enabled: enabled,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error changing separate private network interface for server: server_id=%d, error: %w", serverId, err)
|
||||
}
|
||||
if separatePrivateNicResp.StatusCode() != http.StatusOK {
|
||||
return fmt.Errorf("unexpected HTTP status code changing separate private network interface for server: server_id=%d, details: %s", serverId, separatePrivateNicResp.Body)
|
||||
}
|
||||
|
||||
err = r.waitForServerAction(ctx, serverId, separatePrivateNicResp.JSON200.Action.Id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error changing separate private network interface: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *serverResource) fetchServerResourceState(ctx context.Context, state *serverResourceModel) diag.Diagnostics {
|
||||
var diags diag.Diagnostics
|
||||
|
||||
@@ -1430,6 +1516,7 @@ func (r *serverResource) fetchServerResourceState(ctx context.Context, state *se
|
||||
state.Permalink = types.StringValue(*serverResp.JSON200.Server.Permalink)
|
||||
state.PasswordChangeSupported = types.BoolValue(serverResp.JSON200.Server.PasswordChangeSupported)
|
||||
state.SourceAndDestinationCheck = types.BoolPointerValue(serverResp.JSON200.Server.Networks.SourceAndDestinationCheck)
|
||||
state.SeparatePrivateNetworkInterface = types.BoolPointerValue(serverResp.JSON200.Server.Networks.SeparatePrivateNetworkInterface)
|
||||
state.Memory = types.Int32Value(serverResp.JSON200.Server.Memory)
|
||||
state.Disk = types.Int32Value(serverResp.JSON200.Server.Disk)
|
||||
state.Backups = types.BoolValue(serverResp.JSON200.Server.NextBackupWindow != nil)
|
||||
|
||||
@@ -58,6 +58,7 @@ resource "binarylane_server" "test" {
|
||||
public_ipv4_count = 1
|
||||
ssh_keys = [binarylane_ssh_key.initial.id]
|
||||
source_and_destination_check = false
|
||||
separate_private_network_interface = true
|
||||
backups = true
|
||||
port_blocking = false
|
||||
user_data = <<EOT
|
||||
@@ -95,6 +96,7 @@ echo "Hello World" > /var/tmp/output.txt
|
||||
resource.TestCheckResourceAttrPair("binarylane_server.test", "ssh_keys.0", "binarylane_ssh_key.initial", "id"),
|
||||
resource.TestCheckResourceAttrSet("binarylane_server.test", "permalink"),
|
||||
resource.TestCheckResourceAttr("binarylane_server.test", "source_and_destination_check", "false"),
|
||||
resource.TestCheckResourceAttr("binarylane_server.test", "separate_private_network_interface", "true"),
|
||||
resource.TestCheckResourceAttr("binarylane_server.test", "backups", "true"),
|
||||
resource.TestCheckResourceAttr("binarylane_server.test", "advanced_features.emulated_hyperv", "false"),
|
||||
resource.TestCheckResourceAttr("binarylane_server.test", "advanced_features.emulated_devices", "false"),
|
||||
@@ -125,6 +127,8 @@ echo "Hello World" > /var/tmp/output.txt
|
||||
resource.TestCheckResourceAttr("data.binarylane_server.test", "disk", "20"),
|
||||
resource.TestCheckResourceAttr("data.binarylane_server.test", "backups", "true"),
|
||||
resource.TestCheckResourceAttr("data.binarylane_server.test", "port_blocking", "false"),
|
||||
resource.TestCheckResourceAttr("data.binarylane_server.test", "source_and_destination_check", "false"),
|
||||
resource.TestCheckResourceAttr("data.binarylane_server.test", "separate_private_network_interface", "true"),
|
||||
resource.TestCheckResourceAttr("data.binarylane_server.test", "advanced_features.emulated_hyperv", "false"),
|
||||
resource.TestCheckResourceAttr("data.binarylane_server.test", "advanced_features.emulated_devices", "false"),
|
||||
resource.TestCheckResourceAttr("data.binarylane_server.test", "advanced_features.nested_virt", "false"),
|
||||
@@ -214,6 +218,7 @@ EOT
|
||||
resource.TestCheckResourceAttrPair("binarylane_server.test", "ssh_keys.0", "binarylane_ssh_key.updated", "id"),
|
||||
resource.TestCheckResourceAttr("binarylane_server.test", "advanced_features.emulated_hyperv", "true"),
|
||||
resource.TestCheckNoResourceAttr("binarylane_server.test", "source_and_destination_check"),
|
||||
resource.TestCheckNoResourceAttr("binarylane_server.test", "separate_private_network_interface"),
|
||||
resource.TestCheckResourceAttr("binarylane_server.test", "backups", "false"),
|
||||
resource.TestCheckResourceAttr("binarylane_server.test", "port_blocking", "true"),
|
||||
resource.TestCheckResourceAttr("binarylane_server.test", "user_data", // test extra whitespace
|
||||
|
||||
@@ -151,14 +151,14 @@ func init() {
|
||||
for _, k := range keys {
|
||||
if strings.HasPrefix(*k.Name, "tf-test-") {
|
||||
|
||||
deleteResp, err := client.DeleteAccountKeysKeyIdWithResponse(ctx, int(k.Id))
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error deleting SSH key %d for test sweep: %w", k.Id, err)
|
||||
}
|
||||
if deleteResp.StatusCode() != http.StatusNoContent {
|
||||
return fmt.Errorf("Unexpected status %d deleting SSH key %d for test sweep: %s", deleteResp.StatusCode(), k.Id, deleteResp.Body)
|
||||
}
|
||||
log.Println("Deleted SSH key for test sweep:", k.Id)
|
||||
deleteResp, err := client.DeleteAccountKeysKeyIdWithResponse(ctx, int(k.Id))
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error deleting SSH key %d for test sweep: %w", k.Id, err)
|
||||
}
|
||||
if deleteResp.StatusCode() != http.StatusNoContent {
|
||||
return fmt.Errorf("Unexpected status %d deleting SSH key %d for test sweep: %s", deleteResp.StatusCode(), k.Id, deleteResp.Body)
|
||||
}
|
||||
log.Println("Deleted SSH key for test sweep:", k.Id)
|
||||
}
|
||||
}
|
||||
if listResp.JSON200.Links == nil || listResp.JSON200.Links.Pages.Next == nil {
|
||||
|
||||
@@ -156,17 +156,17 @@ func init() {
|
||||
}
|
||||
|
||||
vpcs := listResp.JSON200.Vpcs
|
||||
for _, vpc := range vpcs {
|
||||
if strings.HasPrefix(vpc.Name, "tf-test-") {
|
||||
for _, vpc := range vpcs {
|
||||
if strings.HasPrefix(vpc.Name, "tf-test-") {
|
||||
|
||||
deleteResp, err := client.DeleteVpcsVpcIdWithResponse(ctx, vpc.Id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error deleting VPC %d in test sweep: %w", vpc.Id, err)
|
||||
}
|
||||
if deleteResp.StatusCode() != http.StatusNoContent {
|
||||
return fmt.Errorf("Unexpected status %d deleting VPC %d for test sweep: %s", deleteResp.StatusCode(), vpc.Id, deleteResp.Body)
|
||||
}
|
||||
log.Println("Deleted VPC for test sweep:", vpc.Id)
|
||||
deleteResp, err := client.DeleteVpcsVpcIdWithResponse(ctx, vpc.Id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error deleting VPC %d in test sweep: %w", vpc.Id, err)
|
||||
}
|
||||
if deleteResp.StatusCode() != http.StatusNoContent {
|
||||
return fmt.Errorf("Unexpected status %d deleting VPC %d for test sweep: %s", deleteResp.StatusCode(), vpc.Id, deleteResp.Body)
|
||||
}
|
||||
log.Println("Deleted VPC for test sweep:", vpc.Id)
|
||||
}
|
||||
}
|
||||
if listResp.JSON200.Links == nil || listResp.JSON200.Links.Pages.Next == nil {
|
||||
|
||||
+20
-5
@@ -8,7 +8,7 @@
|
||||
"url": "https://support.binarylane.com.au/support/home",
|
||||
"email": "support@binarylane.com.au"
|
||||
},
|
||||
"version": "0.34.4",
|
||||
"version": "0.35.1",
|
||||
"x-logo": {
|
||||
"url": "https://www.binarylane.com.au/res/images/binarylane/logo.png",
|
||||
"backgroundColor": "#000000",
|
||||
@@ -1834,7 +1834,7 @@
|
||||
"x-codeSamples": [
|
||||
{
|
||||
"lang": "Curl",
|
||||
"source": "curl -X GET \"https://api.binarylane.com.au/v2/regions?page=${page}&per_page=${per_page}\" \\"
|
||||
"source": "curl -X GET \"https://api.binarylane.com.au/v2/regions?page=${page}&per_page=${per_page}\""
|
||||
}
|
||||
],
|
||||
"x-cli-command": "region list"
|
||||
@@ -5773,7 +5773,7 @@
|
||||
"ServerActions"
|
||||
],
|
||||
"summary": "Move a Server to an Existing Network",
|
||||
"description": "This is used to move a server either to an already defined virtual private cloud, or the default public network in the server's region.",
|
||||
"description": "This is used to move a server either to an already defined virtual private cloud, or the public network for the server's region.",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "server_id",
|
||||
@@ -6071,8 +6071,10 @@
|
||||
"required": [
|
||||
"id",
|
||||
"progress",
|
||||
"reason",
|
||||
"started_at",
|
||||
"status",
|
||||
"title",
|
||||
"type"
|
||||
],
|
||||
"type": "object",
|
||||
@@ -6139,6 +6141,14 @@
|
||||
"description": "The region slug (if any) of the resource associated with this action.",
|
||||
"nullable": true
|
||||
},
|
||||
"title": {
|
||||
"type": "string",
|
||||
"description": "A short display name for the action."
|
||||
},
|
||||
"reason": {
|
||||
"type": "string",
|
||||
"description": "A user-friendly explanation of what is happening."
|
||||
},
|
||||
"progress": {
|
||||
"allOf": [
|
||||
{
|
||||
@@ -7177,7 +7187,7 @@
|
||||
},
|
||||
"vpc_id": {
|
||||
"type": "integer",
|
||||
"description": "If this is null the server will be moved into the default public network for the server's region.",
|
||||
"description": "If this is null the server will be moved into the public network for the server's region.",
|
||||
"format": "int64",
|
||||
"nullable": true
|
||||
}
|
||||
@@ -9070,7 +9080,12 @@
|
||||
},
|
||||
"invoice_download_url": {
|
||||
"type": "string",
|
||||
"description": "The download URL for the rendered version of the invoice.",
|
||||
"description": "The download URL for the PDF version of the invoice. This URL expires 24 hours after it is generated.",
|
||||
"nullable": true
|
||||
},
|
||||
"invoice_view_url": {
|
||||
"type": "string",
|
||||
"description": "The URL for the HTML rendered version of the invoice. This URL expires 24 hours after it is generated.",
|
||||
"nullable": true
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user