Skip to content

Commit

Permalink
Merge pull request #62 from displague/ignore-422-vlan-already
Browse files Browse the repository at this point in the history
ignore vlan attachment API responses "422 Virtual network foo already…"
  • Loading branch information
displague authored Jun 14, 2021
2 parents a52bd97 + 89f2b16 commit fd7045e
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 16 deletions.
12 changes: 7 additions & 5 deletions apis/vlan/v1alpha1/virtualnetwork_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@ type VirtualNetworkStatus struct {
// +kubebuilder:printcolumn:name="READY",type="string",JSONPath=".status.conditions[?(@.type=='Ready')].status"
// +kubebuilder:printcolumn:name="SYNCED",type="string",JSONPath=".status.conditions[?(@.type=='Synced')].status"
// +kubebuilder:printcolumn:name="ID",type="string",JSONPath=".status.atProvider.id"
// +kubebuilder:printcolumn:name="HOSTNAME",type="string",JSONPath=".spec.forProvider.hostname"
// +kubebuilder:printcolumn:name="FACILITY",type="string",JSONPath=".status.atProvider.facility"
// +kubebuilder:printcolumn:name="FACILITY",type="string",JSONPath=".status.atProvider.facilityCode"
// +kubebuilder:printcolumn:name="RECLAIM-POLICY",type="string",JSONPath=".spec.reclaimPolicy"
// +kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp"
// +kubebuilder:subresource:status
Expand Down Expand Up @@ -69,8 +68,11 @@ type VirtualNetworkList struct {
// LateInitialization should update the parameter after creation.
type VirtualNetworkParameters struct {
// +immutable
// +required
Facility string `json:"facility"`
// +optional
Facility string `json:"facility,omitempty"`

// +optional
Metro string `json:"metro,omitempty"`

// +optional
Description *string `json:"description,omitempty"`
Expand All @@ -82,6 +84,6 @@ type VirtualNetworkObservation struct {
ID string `json:"id"`
Href string `json:"href,omitempty"`
VXLAN int `json:"vxlan,omitempty"`
FacilityCode string `json:"facility_code,omitempty"`
FacilityCode string `json:"facilityCode,omitempty"`
CreatedAt *metav1.Time `json:"createdAt,omitempty"`
}
11 changes: 4 additions & 7 deletions package/crds/vlan.metal.equinix.com_virtualnetworks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@ spec:
- JSONPath: .status.atProvider.id
name: ID
type: string
- JSONPath: .spec.forProvider.hostname
name: HOSTNAME
type: string
- JSONPath: .status.atProvider.facility
- JSONPath: .status.atProvider.facilityCode
name: FACILITY
type: string
- JSONPath: .spec.reclaimPolicy
Expand Down Expand Up @@ -69,8 +66,8 @@ spec:
type: string
facility:
type: string
required:
- facility
metro:
type: string
type: object
providerConfigRef:
description: ProviderConfigReference specifies how the provider that will be used to create, observe, update, and delete this managed resource should be configured.
Expand Down Expand Up @@ -115,7 +112,7 @@ spec:
createdAt:
format: date-time
type: string
facility_code:
facilityCode:
type: string
href:
type: string
Expand Down
19 changes: 19 additions & 0 deletions pkg/clients/metal.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"encoding/json"
"fmt"
"net/http"
"strings"

"github.com/crossplane/crossplane-runtime/pkg/resource"
"github.com/packethost/packngo"
Expand All @@ -42,6 +43,11 @@ type Client struct {
Client *packngo.Client
}

const (
errVirtualNetworkAlreadyContents = " already "
errVirtualNetworkAlreadyPrefix = "Virtual network"
)

// NewCredentialsFromJSON parses JSON bytes returning an Equinix Metal Credentials configuration
func NewCredentialsFromJSON(j []byte) (*Credentials, error) {
config := &Credentials{}
Expand Down Expand Up @@ -113,3 +119,16 @@ func IsNotFound(err error) bool {
}
return false
}

// IsAlreadyDone returns true if, during VLAN assignment operations, the API
// returns an error like "422 Virtual network 1182 already assigned" or "422
// Virtual network 1182 already unassigned"
func IsAlreadyDone(err error) bool {
if e, ok := err.(*packngo.ErrorResponse); ok && e.Response != nil {
errsInOne := strings.Join(append(e.Errors, e.SingleError), "")
return e.Response.StatusCode == http.StatusUnprocessableEntity &&
strings.Contains(errsInOne, errVirtualNetworkAlreadyContents) &&
strings.HasPrefix(errsInOne, errVirtualNetworkAlreadyPrefix)
}
return false
}
1 change: 1 addition & 0 deletions pkg/clients/vlan/virtualnetwork.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ func NewClient(ctx context.Context, config *clients.Credentials) (ClientWithDefa
func CreateFromVirtualNetwork(d *v1alpha1.VirtualNetwork, projectID string) *packngo.VirtualNetworkCreateRequest {
return &packngo.VirtualNetworkCreateRequest{
Facility: d.Spec.ForProvider.Facility,
Metro: d.Spec.ForProvider.Metro,
Description: emptyIfNil(d.Spec.ForProvider.Description),
ProjectID: projectID,
}
Expand Down
8 changes: 4 additions & 4 deletions pkg/controller/ports/assignment/managed.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ package assignment

import (
"context"
"strings"
"path"

"github.com/packethost/packngo"
"github.com/pkg/errors"
Expand Down Expand Up @@ -127,7 +127,7 @@ func (e *external) Observe(ctx context.Context, mg resource.Managed) (managed.Ex
}

for _, net := range port.AttachedVirtualNetworks {
if strings.TrimPrefix(net.Href, "/virtual-networks/") == a.Spec.ForProvider.VirtualNetworkID {
if path.Base(net.Href) == a.Spec.ForProvider.VirtualNetworkID {
a.Status.SetConditions(xpv1.Available())
o.ResourceExists = true
}
Expand All @@ -144,7 +144,7 @@ func (e *external) Create(ctx context.Context, mg resource.Managed) (managed.Ext
}
a.Status.SetConditions(xpv1.Creating())
_, _, err := e.client.Assign(&packngo.PortAssignRequest{PortID: meta.GetExternalName(a), VirtualNetworkID: a.Spec.ForProvider.VirtualNetworkID})
return managed.ExternalCreation{}, errors.Wrap(err, errCreateAssignment)
return managed.ExternalCreation{}, errors.Wrap(resource.Ignore(packetclient.IsAlreadyDone, err), errCreateAssignment)
}

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

0 comments on commit fd7045e

Please sign in to comment.