Skip to content
This repository was archived by the owner on Feb 11, 2025. It is now read-only.

Commit 03e098b

Browse files
committed
ignore vlan attachment API responses "422 Virtual network foo already ..."
Signed-off-by: Marques Johansson <mjohansson@equinix.com>
1 parent a52bd97 commit 03e098b

File tree

2 files changed

+21
-2
lines changed

2 files changed

+21
-2
lines changed

pkg/clients/metal.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"encoding/json"
2222
"fmt"
2323
"net/http"
24+
"strings"
2425

2526
"github.com/crossplane/crossplane-runtime/pkg/resource"
2627
"github.com/packethost/packngo"
@@ -42,6 +43,11 @@ type Client struct {
4243
Client *packngo.Client
4344
}
4445

46+
const (
47+
errVirtualNetworkAlreadyContents = " already "
48+
errVirtualNetworkAlreadyPrefix = "Virtual network"
49+
)
50+
4551
// NewCredentialsFromJSON parses JSON bytes returning an Equinix Metal Credentials configuration
4652
func NewCredentialsFromJSON(j []byte) (*Credentials, error) {
4753
config := &Credentials{}
@@ -113,3 +119,16 @@ func IsNotFound(err error) bool {
113119
}
114120
return false
115121
}
122+
123+
// IsAlreadyDone returns true if, during VLAN assignment operations, the API
124+
// returns an error like "422 Virtual network 1182 already assigned" or "422
125+
// Virtual network 1182 already unassigned"
126+
func IsAlreadyDone(err error) bool {
127+
if e, ok := err.(*packngo.ErrorResponse); ok && e.Response != nil {
128+
errsInOne := strings.Join(append(e.Errors, e.SingleError), "")
129+
return e.Response.StatusCode == http.StatusUnprocessableEntity &&
130+
strings.Contains(errsInOne, errVirtualNetworkAlreadyContents) &&
131+
strings.HasPrefix(errsInOne, errVirtualNetworkAlreadyPrefix)
132+
}
133+
return false
134+
}

pkg/controller/ports/assignment/managed.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ func (e *external) Create(ctx context.Context, mg resource.Managed) (managed.Ext
144144
}
145145
a.Status.SetConditions(xpv1.Creating())
146146
_, _, err := e.client.Assign(&packngo.PortAssignRequest{PortID: meta.GetExternalName(a), VirtualNetworkID: a.Spec.ForProvider.VirtualNetworkID})
147-
return managed.ExternalCreation{}, errors.Wrap(err, errCreateAssignment)
147+
return managed.ExternalCreation{}, errors.Wrap(resource.Ignore(packetclient.IsAlreadyDone, err), errCreateAssignment)
148148
}
149149

150150
func (e *external) Update(ctx context.Context, mg resource.Managed) (managed.ExternalUpdate, error) {
@@ -159,5 +159,5 @@ func (e *external) Delete(ctx context.Context, mg resource.Managed) error {
159159
}
160160
a.SetConditions(xpv1.Deleting())
161161
_, _, err := e.client.Unassign(&packngo.PortAssignRequest{PortID: meta.GetExternalName(a), VirtualNetworkID: a.Spec.ForProvider.VirtualNetworkID})
162-
return errors.Wrap(resource.Ignore(packetclient.IsNotFound, err), errDeleteAssignment)
162+
return errors.Wrap(resource.IgnoreAny(err, packetclient.IsNotFound, packetclient.IsAlreadyDone), errDeleteAssignment)
163163
}

0 commit comments

Comments
 (0)