Compare commits

..

1 Commits

Author SHA1 Message Date
dependabot[bot] 3b507277bd 🐈 Bump goreleaser/goreleaser-action
Bumps the minor-patch group with 1 update in the / directory: [goreleaser/goreleaser-action](https://github.com/goreleaser/goreleaser-action).


Updates `goreleaser/goreleaser-action` from 7.0.0 to 7.2.3
- [Release notes](https://github.com/goreleaser/goreleaser-action/releases)
- [Commits](https://github.com/goreleaser/goreleaser-action/compare/ec59f474b9834571250b370d4735c50f8e2d1e29...f06c13b6b1a9625abc9e6e439d9c05a8f2190e94)

---
updated-dependencies:
- dependency-name: goreleaser/goreleaser-action
  dependency-version: 7.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: minor-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-02 15:03:43 +00:00
9 changed files with 25 additions and 166 deletions
+1 -1
View File
@@ -38,7 +38,7 @@ jobs:
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.PASSPHRASE }}
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@ec59f474b9834571250b370d4735c50f8e2d1e29 # v7.0.0
uses: goreleaser/goreleaser-action@f06c13b6b1a9625abc9e6e439d9c05a8f2190e94 # v7.2.3
with:
args: release --clean
env:
@@ -384,11 +384,6 @@ func (r *loadBalancerResource) Delete(ctx context.Context, req resource.DeleteRe
return
}
if lbResp.StatusCode() == http.StatusNotFound {
tflog.Warn(ctx, fmt.Sprintf("Load balancer already gone, nothing to delete: id=%s, name=%s", data.Id.String(), data.Name.ValueString()))
return
}
if lbResp.StatusCode() != http.StatusNoContent {
resp.Diagnostics.AddError(
"Unexpected HTTP status code deleting load balancer",
@@ -145,12 +145,6 @@ func (r *serverFirewallRulesResource) Read(ctx context.Context, req resource.Rea
)
return
}
if fwResp.StatusCode() == http.StatusNotFound {
tflog.Warn(ctx, fmt.Sprintf("Server firewall rules not found, removing from state: server_id=%d", data.ServerId.ValueInt64()))
resp.State.RemoveResource(ctx)
return
}
if fwResp.StatusCode() != http.StatusOK {
resp.Diagnostics.AddError(
"Unexpected HTTP status code reading server firewall rules",
@@ -243,11 +237,6 @@ func (r *serverFirewallRulesResource) Delete(ctx context.Context, req resource.D
)
return
}
if serverResp.StatusCode() == http.StatusNotFound {
tflog.Warn(ctx, fmt.Sprintf("Server already gone, no firewall rules to delete: server_id=%s", data.ServerId.String()))
return
}
if serverResp.StatusCode() != http.StatusOK {
resp.Diagnostics.AddError(
"Unexpected HTTP status code deleting server firewall rules",
+24 -48
View File
@@ -3,7 +3,6 @@ package provider
import (
"context"
"encoding/json"
"errors"
"fmt"
"net/http"
"slices"
@@ -773,9 +772,8 @@ func (r *serverResource) Create(ctx context.Context, req resource.CreateRequest,
// 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
if err := r.fetchServerResourceState(ctx, &data); err != nil {
resp.Diagnostics.AddError("Error reading server", err.Error())
}
diag := r.fetchServerResourceState(ctx, &data)
resp.Diagnostics.Append(diag...)
// Save data into Terraform state
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
@@ -793,15 +791,8 @@ func (r *serverResource) Read(ctx context.Context, req resource.ReadRequest, res
// Read API call logic
tflog.Debug(ctx, fmt.Sprintf("Reading server: id=%s, name=%s", data.Id.String(), data.Name.ValueString()))
if err := r.fetchServerResourceState(ctx, &data); err != nil {
if errors.Is(err, errServerNotFound) {
tflog.Warn(ctx, fmt.Sprintf("Server not found, removing from state: id=%s, name=%s", data.Id.String(), data.Name.ValueString()))
resp.State.RemoveResource(ctx)
return
}
resp.Diagnostics.AddError("Error reading server", err.Error())
return
}
diag := r.fetchServerResourceState(ctx, &data)
resp.Diagnostics.Append(diag...)
// Get user data script
userDataResp, err := r.bc.client.GetServersServerIdUserDataWithResponse(ctx, data.Id.ValueInt64())
@@ -850,10 +841,8 @@ func (r *serverResource) Update(ctx context.Context, req resource.UpdateRequest,
return
}
if err := r.fetchServerResourceState(ctx, &state); err != nil {
resp.Diagnostics.AddError("Error reading server", err.Error())
return
}
diag := r.fetchServerResourceState(ctx, &state)
resp.Diagnostics.Append(diag...)
// Save updated data into Terraform state
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
@@ -926,10 +915,8 @@ func (r *serverResource) Update(ctx context.Context, req resource.UpdateRequest,
if !plan.VpcIpv4Address.Equal(state.VpcIpv4Address) && !plan.VpcIpv4Address.IsNull() && !plan.VpcIpv4Address.IsUnknown() {
// If VPC was just changed, IP address needs to be fetched so it can be sent in the request
if refreshNeeded {
if err := r.fetchServerResourceState(ctx, &state); err != nil {
resp.Diagnostics.AddError("Error reading server", err.Error())
return
}
diag := r.fetchServerResourceState(ctx, &state)
resp.Diagnostics.Append(diag...)
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
if resp.Diagnostics.HasError() {
return
@@ -1319,11 +1306,6 @@ func (r *serverResource) Delete(ctx context.Context, req resource.DeleteRequest,
return
}
if serverResp.StatusCode() == http.StatusNotFound {
tflog.Warn(ctx, fmt.Sprintf("Server already gone, nothing to delete: id=%s, name=%s", data.Id.String(), data.Name.ValueString()))
return
}
if serverResp.StatusCode() != http.StatusNoContent {
resp.Diagnostics.AddError(
"Unexpected HTTP status code deleting server",
@@ -1491,25 +1473,25 @@ func (r *serverResource) updateSeparatePrivateNetworkInterface(
return nil
}
// errServerNotFound reports that Binary Lane no longer has the server, so that Read can drop it
// from state instead of failing (see #69).
var errServerNotFound = errors.New("server not found")
// fetchServerResourceState reads the server and maps it into state, returning errServerNotFound
// if the server no longer exists.
func (r *serverResource) fetchServerResourceState(ctx context.Context, state *serverResourceModel) error {
func (r *serverResource) fetchServerResourceState(ctx context.Context, state *serverResourceModel) diag.Diagnostics {
var diags diag.Diagnostics
serverResp, err := r.bc.client.GetServersServerIdWithResponse(ctx, state.Id.ValueInt64())
if err != nil {
return fmt.Errorf("error reading server: id=%s, name=%s, error: %w", state.Id, state.Name.ValueString(), err)
}
if serverResp.StatusCode() == http.StatusNotFound {
return errServerNotFound
return diag.Diagnostics{
diag.NewErrorDiagnostic(
fmt.Sprintf("Error reading server: id=%s, name=%s", state.Id.String(), state.Name.ValueString()),
err.Error(),
),
}
}
if serverResp.StatusCode() != http.StatusOK {
return fmt.Errorf("unexpected HTTP status code %s reading server: id=%s, name=%s, details: %s",
serverResp.Status(), state.Id, state.Name.ValueString(), serverResp.Body)
return diag.Diagnostics{
diag.NewErrorDiagnostic(
fmt.Sprintf("Unexpected HTTP status code %s reading server: name=%s, id=%s", serverResp.Status(), state.Name.ValueString(), state.Id.String()),
string(serverResp.Body),
),
}
}
state.Id = types.Int64Value(serverResp.JSON200.Server.Id)
@@ -1542,7 +1524,7 @@ func (r *serverResource) fetchServerResourceState(ctx context.Context, state *se
}
advFeat := serverResp.JSON200.Server.AdvancedFeatures.EnabledAdvancedFeatures
advFeatValue, advFeatDiags := resources.NewAdvancedFeaturesValue(
state.AdvancedFeatures, diags = resources.NewAdvancedFeaturesValue(
resources.AdvancedFeaturesValue{}.AttributeTypes(ctx),
map[string]attr.Value{
"emulated_hyperv": types.BoolValue(slices.Contains(advFeat, "emulated-hyperv")),
@@ -1556,9 +1538,7 @@ func (r *serverResource) fetchServerResourceState(ctx context.Context, state *se
"qemu_guest_agent": types.BoolValue(slices.Contains(advFeat, "qemu-guest-agent")),
"uefi_boot": types.BoolValue(slices.Contains(advFeat, "uefi-boot")),
})
diags.Append(advFeatDiags...)
state.AdvancedFeatures = advFeatValue
if advFeatDiags.HasError() {
if diags.HasError() {
state.AdvancedFeatures = resources.NewAdvancedFeaturesValueUnknown()
}
@@ -1620,11 +1600,7 @@ func (r *serverResource) fetchServerResourceState(ctx context.Context, state *se
state.PrivateIpv6Addresses = tfPrivateIpv6Addresses
}
if diags.HasError() {
return errFromDiagnostics(diags)
}
return nil
return diags
}
func isAdvFeatChanged(config *resources.AdvancedFeaturesValue, data *resources.AdvancedFeaturesValue) bool {
-67
View File
@@ -8,7 +8,6 @@ import (
"log"
"net/http"
"regexp"
"strconv"
"strings"
"terraform-provider-binarylane/internal/binarylane"
"testing"
@@ -285,72 +284,6 @@ EOT
})
}
// TestServerResourceDeletedOutOfBand covers a server that no longer exists at Binary Lane: the
// next refresh drops it from state so a plan can re-create it, rather than failing with the 404
// and leaving the state to be edited by hand (#69).
func TestServerResourceDeletedOutOfBand(t *testing.T) {
// Must assign a password to the server or Binary Lane will send emails
password := GenerateTestPassword(t)
var serverId string
resource.ParallelTest(t, resource.TestCase{
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
Config: providerConfig + `
resource "binarylane_server" "test" {
name = "tf-test-server-out-of-band"
// TEMPORARY: "per" is intermittently returning "Unable to find a suitable host for the
// requested server configuration"
region = "mel"
image = "debian-12"
size = "std-min"
public_ipv4_count = 0
password = "` + password + `"
}
`,
Check: resource.TestCheckResourceAttrWith("binarylane_server.test", "id", func(value string) error {
serverId = value
return nil
}),
},
{
PreConfig: func() { deleteServerOutOfBand(t, serverId) },
RefreshState: true,
ExpectNonEmptyPlan: true, // the server is gone from state, so the plan re-creates it
},
},
})
}
// deleteServerOutOfBand deletes a server through the API, as if someone had removed it outside of
// Terraform.
func deleteServerOutOfBand(t *testing.T, serverId string) {
t.Helper()
client, err := binarylane.NewClientWithDefaultConfig()
if err != nil {
t.Fatalf("Error creating Binary Lane API client: %s", err)
}
id, err := strconv.ParseInt(serverId, 10, 64)
if err != nil {
t.Fatalf("Error parsing server id %q: %s", serverId, err)
}
reason := "Terraform deletion"
deleteResp, err := client.DeleteServersServerIdWithResponse(context.Background(), id, &binarylane.DeleteServersServerIdParams{
Reason: &reason,
})
if err != nil {
t.Fatalf("Error deleting server %d out of band: %s", id, err)
}
if deleteResp.StatusCode() != http.StatusNoContent {
t.Fatalf("Unexpected status %d deleting server %d out of band: %s", deleteResp.StatusCode(), id, deleteResp.Body)
}
}
func TestServerResourceRename(t *testing.T) {
// Must assign a password to the server or Binary Lane will send emails
password := GenerateTestPassword(t)
-11
View File
@@ -182,12 +182,6 @@ func (r *sshKeyResource) Read(ctx context.Context, req resource.ReadRequest, res
)
return
}
if sshResp.StatusCode() == http.StatusNotFound {
tflog.Warn(ctx, fmt.Sprintf("SSH Key not found, removing from state: id=%s, name=%s", data.Id.String(), data.Name.ValueString()))
resp.State.RemoveResource(ctx)
return
}
if sshResp.StatusCode() != http.StatusOK {
resp.Diagnostics.AddError(
"Unexpected HTTP status code getting SSH key",
@@ -270,11 +264,6 @@ func (r *sshKeyResource) Delete(ctx context.Context, req resource.DeleteRequest,
)
return
}
if sshResp.StatusCode() == http.StatusNotFound {
tflog.Warn(ctx, fmt.Sprintf("SSH Key already gone, nothing to delete: id=%s, name=%s", state.Id.String(), state.Name.ValueString()))
return
}
if sshResp.StatusCode() != http.StatusNoContent {
resp.Diagnostics.AddError(
"Unexpected HTTP status code deleting SSH Key",
-13
View File
@@ -2,14 +2,11 @@ package provider
import (
"context"
"errors"
"fmt"
"slices"
"strings"
"github.com/hashicorp/terraform-plugin-framework/attr"
d_schema "github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/diag"
r_schema "github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
)
@@ -269,13 +266,3 @@ func listContainsUnknown(ctx context.Context, list types.List) bool {
func Pointer[T any](d T) *T {
return &d
}
// errFromDiagnostics turns error diagnostics into an error, for helpers that report errors rather
// than diagnostics.
func errFromDiagnostics(diags diag.Diagnostics) error {
messages := make([]string, 0, len(diags))
for _, d := range diags.Errors() {
messages = append(messages, fmt.Sprintf("%s: %s", d.Summary(), d.Detail()))
}
return errors.New(strings.Join(messages, "; "))
}
-5
View File
@@ -230,11 +230,6 @@ func (r *vpcResource) Delete(ctx context.Context, req resource.DeleteRequest, re
return
}
if vpcResp.StatusCode() == http.StatusNotFound {
tflog.Warn(ctx, fmt.Sprintf("VPC already gone, nothing to delete: id=%d", data.Id.ValueInt64()))
return
}
if vpcResp.StatusCode() != http.StatusNoContent {
resp.Diagnostics.AddError(
"Unexpected HTTP status code deleting VPC",
@@ -217,11 +217,6 @@ func (r *vpcRouteEntriesResource) Delete(ctx context.Context, req resource.Delet
return
}
if vpcResp.StatusCode() == http.StatusNotFound {
tflog.Warn(ctx, fmt.Sprintf("VPC already gone, no route entries to delete: vpc_id=%d", data.VpcId.ValueInt64()))
return
}
if vpcResp.StatusCode() != http.StatusOK {
resp.Diagnostics.AddError(
"Unexpected HTTP status code deleting VPC route entries",