Skip to content

Commit

Permalink
Add LongPollWait command (#8)
Browse files Browse the repository at this point in the history
  • Loading branch information
johnmaguire authored May 15, 2024
1 parent b6321fe commit 5dd626b
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 1 deletion.
22 changes: 22 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,28 @@ func (c *Client) CheckForUpdate(ctx context.Context, creds Credentials) (bool, e
return result.Data.UpdateAvailable, nil
}

// LongPollWait sends a signed message to a DNClient API endpoint that will block, returning only
// if there is an action the client should take before the timeout (config updates, debug commands)
func (c *Client) LongPollWait(ctx context.Context, creds Credentials, supportedActions []string) (string, error) {
value, err := json.Marshal(message.LongPollWaitRequest{
SupportedActions: supportedActions,
})
if err != nil {
return "", fmt.Errorf("failed to marshal DNClient message: %s", err)
}

respBody, err := c.postDNClient(ctx, message.LongPollWait, value, creds.HostID, creds.Counter, creds.PrivateKey)
if err != nil {
return "", fmt.Errorf("failed to post message to dnclient api: %w", err)
}
result := message.LongPollWaitResponseWrapper{}
err = json.Unmarshal(respBody, &result)
if err != nil {
return "", fmt.Errorf("failed to interpret API response: %s", err)
}
return result.Data.Action, nil
}

func (c *Client) DoUpdateWithTimeout(ctx context.Context, t time.Duration, creds Credentials) ([]byte, []byte, *Credentials, error) {
toCtx, cancel := context.WithTimeout(ctx, t)
defer cancel()
Expand Down
17 changes: 16 additions & 1 deletion dnapitest/dnapitest.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,8 @@ func (s *Server) handlerDNClient(w http.ResponseWriter, r *http.Request) {
return
}

if msg.Type == message.DoUpdate {
switch msg.Type {
case message.DoUpdate:
var updateKeys message.DoUpdateRequest
err = json.Unmarshal(msg.Value, &updateKeys)
if err != nil {
Expand All @@ -169,6 +170,20 @@ func (s *Server) handlerDNClient(w http.ResponseWriter, r *http.Request) {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
case message.LongPollWait:
var longPoll message.LongPollWaitRequest
err = json.Unmarshal(msg.Value, &longPoll)
if err != nil {
s.errors = append(s.errors, fmt.Errorf("failed to unmarshal LongPollWaitRequest: %w", err))
http.Error(w, "failed to unmarshal LongPollWaitRequest", http.StatusInternalServerError)
return
}

if len(longPoll.SupportedActions) == 0 {
s.errors = append(s.errors, fmt.Errorf("no supported actions"))
http.Error(w, "no supported actions", http.StatusInternalServerError)
return
}
}

// return the associated response
Expand Down
23 changes: 23 additions & 0 deletions message/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
const (
CheckForUpdate = "CheckForUpdate"
DoUpdate = "DoUpdate"
LongPollWait = "LongPollWait"
)

// EndpointV1 is the version 1 DNClient API endpoint.
Expand Down Expand Up @@ -73,6 +74,28 @@ type DoUpdateResponse struct {
TrustedKeys []byte `json:"trustedKeys"`
}

// LongPollWaitResponseWrapper contains a response to LongPollWawit inside "data."
type LongPollWaitResponseWrapper struct {
Data LongPollWaitResponse `json:"data"`
}

// LongPollWaitRequest is the request message associated with a LongPollWait call.
type LongPollWaitRequest struct {
SupportedActions []string `json:"supportedActions"`
}

// DNClientLongPollResponse is the response message associated with a LongPollWait call.
type LongPollWaitResponse struct {
Action string `json:"action"` // e.g. NoOp, StreamLogs, DoUpdate
}

type ClientInfo struct {
Identifier string `json:"identifier"`
Version string `json:"version"`
OS string `json:"os"`
Architecture string `json:"architecture"`
}

// EnrollEndpoint is the REST enrollment endpoint.
const EnrollEndpoint = "/v2/enroll"

Expand Down

0 comments on commit 5dd626b

Please sign in to comment.