Skip to content

Commit

Permalink
GetLoadBalancerState convenience method
Browse files Browse the repository at this point in the history
Signed-off-by: Matt Siwiec <rizzza@users.noreply.github.com>
  • Loading branch information
rizzza committed Nov 16, 2023
1 parent 64a3c37 commit fb6d4da
Show file tree
Hide file tree
Showing 2 changed files with 142 additions and 0 deletions.
60 changes: 60 additions & 0 deletions pkg/metadata/metadata.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
package metadata

import (
"encoding/json"
"errors"
"fmt"

"go.infratographer.com/x/gidx"

"go.infratographer.com/load-balancer-api/pkg/client"
)

// LoadBalancerState is the state of a load balancer
type LoadBalancerState string

Expand All @@ -11,3 +21,53 @@ const (
LoadBalancerStateDeleted LoadBalancerState = "deleted"
LoadBalancerStateUpdating LoadBalancerState = "updating"
)

var (
// ErrStatusNotFound is returned when a status is not found in the payload
ErrStatusNotFound = errors.New("status not found")

// ErrInvalidStatusData is returned when the status json data is invalid
ErrInvalidStatusData = errors.New("invalid status json data")
)

// ErrUnknownLoadBalancerState is returned when the load balancer state is unknown
type ErrUnknownLoadBalancerState struct {
State string
}

func (e ErrUnknownLoadBalancerState) Error() string {
return "unknown load balancer state: " + e.State
}

// GetLoadbalancerState returns the status of a load balancer
func GetLoadbalancerState(metadataStatuses client.MetadataStatuses, statusNamespaceID gidx.PrefixedID) (LoadBalancerState, error) {
for _, status := range metadataStatuses.Edges {
if status.Node.StatusNamespaceID == statusNamespaceID.String() {
// we've found the loadbalancer status namespace we are looking fah
data := map[string]string{}
if err := json.Unmarshal(status.Node.Data, &data); err != nil {
// bad data stored in metadata-api, drop the message and move on
return "", fmt.Errorf("%w: %s", ErrInvalidStatusData, err)
}

if state, ok := data["state"]; ok {
switch state {
case string(LoadBalancerStateCreating):
fallthrough
case string(LoadBalancerStateTerminating):
fallthrough
case string(LoadBalancerStateActive):
fallthrough
case string(LoadBalancerStateDeleted):
fallthrough
case string(LoadBalancerStateUpdating):
return LoadBalancerState(state), nil
default:
return "", ErrUnknownLoadBalancerState{State: state}
}
}
}
}

return "", ErrStatusNotFound
}
82 changes: 82 additions & 0 deletions pkg/metadata/metadata_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package metadata

import (
"encoding/json"
"testing"

"github.com/stretchr/testify/assert"

"go.infratographer.com/load-balancer-api/pkg/client"
)

func TestGetLoadbalancerState(t *testing.T) {
t.Run("valid status", func(t *testing.T) {
statuses := client.MetadataStatuses{
Edges: []client.MetadataStatusEdges{
{
Node: client.MetadataStatusNode{
StatusNamespaceID: "metasns-loadbalancer-status",
Data: json.RawMessage(`{"state": "active"}`),
},
},
{
Node: client.MetadataStatusNode{
StatusNamespaceID: "metasns-some-other-namespace",
Data: json.RawMessage(`{"key": "value"}`),
},
},
},
}

state, err := GetLoadbalancerState(statuses, "metasns-loadbalancer-status")
assert.Nil(t, err)
assert.Equal(t, LoadBalancerStateActive, state)
})

t.Run("bad json data", func(t *testing.T) {
statuses := client.MetadataStatuses{
Edges: []client.MetadataStatusEdges{
{
Node: client.MetadataStatusNode{
StatusNamespaceID: "metasns-loadbalancer-status",
Data: json.RawMessage(`{"state"}`),
},
},
},
}

state, err := GetLoadbalancerState(statuses, "metasns-loadbalancer-status")
assert.NotNil(t, err)
assert.Empty(t, state)
assert.ErrorIs(t, err, ErrInvalidStatusData)
})

t.Run("status not found", func(t *testing.T) {
statuses := client.MetadataStatuses{
Edges: []client.MetadataStatusEdges{},
}

state, err := GetLoadbalancerState(statuses, "metasns-loadbalancer-status")
assert.NotNil(t, err)
assert.Empty(t, state)
assert.ErrorIs(t, err, ErrStatusNotFound)
})

t.Run("unknown state", func(t *testing.T) {
statuses := client.MetadataStatuses{
Edges: []client.MetadataStatusEdges{
{
Node: client.MetadataStatusNode{
StatusNamespaceID: "metasns-loadbalancer-status",
Data: json.RawMessage(`{"state": "unknown"}`),
},
},
},
}

state, err := GetLoadbalancerState(statuses, "metasns-loadbalancer-status")
assert.NotNil(t, err)
assert.Empty(t, state)
assert.ErrorIs(t, err, ErrUnknownLoadBalancerState{State: "unknown"})
})
}

0 comments on commit fb6d4da

Please sign in to comment.