Skip to content

Commit

Permalink
go: Add key manager worker status to node control
Browse files Browse the repository at this point in the history
  • Loading branch information
peternose committed Aug 8, 2022
1 parent c9fe2a5 commit 2aa1fa4
Show file tree
Hide file tree
Showing 5 changed files with 195 additions and 0 deletions.
7 changes: 7 additions & 0 deletions go/control/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
upgrade "github.com/oasisprotocol/oasis-core/go/upgrade/api"
commonWorker "github.com/oasisprotocol/oasis-core/go/worker/common/api"
executorWorker "github.com/oasisprotocol/oasis-core/go/worker/compute/executor/api"
keymanagerWorker "github.com/oasisprotocol/oasis-core/go/worker/keymanager/api"
storageWorker "github.com/oasisprotocol/oasis-core/go/worker/storage/api"
)

Expand Down Expand Up @@ -74,6 +75,9 @@ type Status struct {
// Registration is the node's registration status.
Registration RegistrationStatus `json:"registration"`

// Keymanager is the node's key manager worker status in case this node is a key manager node.
Keymanager *keymanagerWorker.Status `json:"keymanager,omitempty"`

// PendingUpgrades are the node's pending upgrades.
PendingUpgrades []*upgrade.PendingUpgrade `json:"pending_upgrades"`
}
Expand Down Expand Up @@ -170,6 +174,9 @@ type ControlledNode interface {
// GetRuntimeStatus returns the node's current per-runtime status.
GetRuntimeStatus(ctx context.Context) (map[common.Namespace]RuntimeStatus, error)

// GetKeyManagerStatus returns the node's key manager worker status.
GetKeymanagerStatus(ctx context.Context) (*keymanagerWorker.Status, error)

// GetPendingUpgrade returns the node's pending upgrades.
GetPendingUpgrades(ctx context.Context) ([]*upgrade.PendingUpgrade, error)
}
Expand Down
6 changes: 6 additions & 0 deletions go/control/control.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ func (c *nodeController) GetStatus(ctx context.Context) (*control.Status, error)
return nil, fmt.Errorf("failed to get runtime status: %w", err)
}

kms, err := c.node.GetKeymanagerStatus(ctx)
if err != nil {
return nil, fmt.Errorf("failed to get key manager worker status: %w", err)
}

pendingUpgrades, err := c.node.GetPendingUpgrades(ctx)
if err != nil {
return nil, fmt.Errorf("failed to get pending upgrades: %w", err)
Expand All @@ -124,6 +129,7 @@ func (c *nodeController) GetStatus(ctx context.Context) (*control.Status, error)
},
Consensus: *cs,
Runtimes: runtimes,
Keymanager: kms,
Registration: *rs,
PendingUpgrades: pendingUpgrades,
}, nil
Expand Down
9 changes: 9 additions & 0 deletions go/oasis-node/cmd/node/control.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
roothash "github.com/oasisprotocol/oasis-core/go/roothash/api"
storage "github.com/oasisprotocol/oasis-core/go/storage/api"
upgrade "github.com/oasisprotocol/oasis-core/go/upgrade/api"
keymanagerWorker "github.com/oasisprotocol/oasis-core/go/worker/keymanager/api"
"github.com/oasisprotocol/oasis-core/go/worker/registration"
)

Expand Down Expand Up @@ -183,6 +184,14 @@ func (n *Node) GetRuntimeStatus(ctx context.Context) (map[common.Namespace]contr
return runtimes, nil
}

// GetKeymanagerStatus implements control.ControlledNode.
func (n *Node) GetKeymanagerStatus(ctx context.Context) (*keymanagerWorker.Status, error) {
if n.KeymanagerWorker == nil || !n.KeymanagerWorker.Enabled() {
return nil, nil
}
return n.KeymanagerWorker.GetStatus(ctx)
}

// GetPendingUpgrades implements control.ControlledNode.
func (n *Node) GetPendingUpgrades(ctx context.Context) ([]*upgrade.PendingUpgrade, error) {
return n.Upgrader.PendingUpgrades(ctx)
Expand Down
100 changes: 100 additions & 0 deletions go/worker/keymanager/api/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package api

import (
"fmt"

core "github.com/libp2p/go-libp2p-core"

"github.com/oasisprotocol/oasis-core/go/common"
)

// StatusState is the concise status state of the key manager worker.
type StatusState uint8

const (
// StatusStateReady is the ready status state.
StatusStateReady StatusState = iota
// StatusStateStarting is the starting status state.
StatusStateStarting
// StatusStateStopped is the stopped status state.
StatusStateStopped
// StatusStateDisabled is the disabled status state.
StatusStateDisabled
)

// String returns a string representation of a status state.
func (s StatusState) String() string {
switch s {
case StatusStateReady:
return "ready"
case StatusStateStarting:
return "starting"
case StatusStateStopped:
return "stopped"
case StatusStateDisabled:
return "disabled"
default:
return "[invalid status state]"
}
}

// MarshalText encodes a StatusState into text form.
func (s StatusState) MarshalText() ([]byte, error) {
switch s {
case StatusStateReady:
return []byte(StatusStateReady.String()), nil
case StatusStateStarting:
return []byte(StatusStateStarting.String()), nil
case StatusStateStopped:
return []byte(StatusStateStopped.String()), nil
case StatusStateDisabled:
return []byte(StatusStateDisabled.String()), nil
default:
return nil, fmt.Errorf("invalid StatusState: %d", s)
}
}

// UnmarshalText decodes a text slice into a StatusState.
func (s *StatusState) UnmarshalText(text []byte) error {
switch string(text) {
case StatusStateReady.String():
*s = StatusStateReady
case StatusStateStarting.String():
*s = StatusStateStarting
case StatusStateStopped.String():
*s = StatusStateStopped
case StatusStateDisabled.String():
*s = StatusStateDisabled
default:
return fmt.Errorf("invalid StatusState: %s", string(text))
}
return nil
}

// RuntimeAccessList is an access control lists for a runtime.
type RuntimeAccessList struct {
// RuntimeID is the runtime ID of the runtime this access list is for.
RuntimeID common.Namespace `json:"runtime_id"`

// Peers is a list of peers that are allowed to call protected methods.
Peers []core.PeerID `json:"peers"`
}

// Status is the key manager worker status.
type Status struct {
// Status is a concise status of the key manager worker.
Status StatusState `json:"status"`

// MayGenerate returns whether the enclave can generate a master secret.
MayGenerate bool `json:"may_generate"`

// RuntimeID is the runtime ID of the key manager.
RuntimeID *common.Namespace `json:"runtime_id"`
// ClientRuntimes is a list of compute runtimes that use this key manager.
ClientRuntimes []common.Namespace `json:"client_runtimes"`

// AccessList is per-runtime list of peers that are allowed to call protected methods.
AccessList []RuntimeAccessList `json:"access_list"`
// PrivatePeers is a list of peers that are always allowed to call protected methods.
PrivatePeers []core.PeerID `json:"private_peers"`
}
73 changes: 73 additions & 0 deletions go/worker/keymanager/status.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package keymanager

import (
"context"

"github.com/libp2p/go-libp2p-core/peer"

"github.com/oasisprotocol/oasis-core/go/common"
"github.com/oasisprotocol/oasis-core/go/worker/keymanager/api"
)

// GetStatus returns the key manager worker status.
func (w *Worker) GetStatus(ctx context.Context) (*api.Status, error) {
var initialized, stopped bool
select {
case <-w.Initialized():
initialized = true
default:
}
select {
case <-w.Quit():
stopped = true
default:
}

var ss api.StatusState
switch {
case !w.enabled:
ss = api.StatusStateDisabled
case stopped:
ss = api.StatusStateStopped
case initialized:
ss = api.StatusStateReady
default:
ss = api.StatusStateStarting
}

var rid *common.Namespace
if w.runtime != nil {
id := w.runtime.ID()
rid = &id
}

rts := make([]common.Namespace, 0, len(w.clientRuntimes))
for rt := range w.clientRuntimes {
rts = append(rts, rt)
}

ps := make([]peer.ID, 0, len(w.privatePeers))
for p := range w.privatePeers {
ps = append(ps, p)
}

w.RLock()
al := make([]api.RuntimeAccessList, 0, len(w.accessListByRuntime))
for rt, ps := range w.accessListByRuntime {
ral := api.RuntimeAccessList{
RuntimeID: rt,
Peers: ps,
}
al = append(al, ral)
}
w.RUnlock()

return &api.Status{
Status: ss,
MayGenerate: w.mayGenerate,
RuntimeID: rid,
ClientRuntimes: rts,
AccessList: al,
PrivatePeers: ps,
}, nil
}

0 comments on commit 2aa1fa4

Please sign in to comment.