Skip to content

Commit 5dd626b

Browse files
authored
Add LongPollWait command (#8)
1 parent b6321fe commit 5dd626b

3 files changed

Lines changed: 61 additions & 1 deletion

File tree

client.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,28 @@ func (c *Client) CheckForUpdate(ctx context.Context, creds Credentials) (bool, e
168168
return result.Data.UpdateAvailable, nil
169169
}
170170

171+
// LongPollWait sends a signed message to a DNClient API endpoint that will block, returning only
172+
// if there is an action the client should take before the timeout (config updates, debug commands)
173+
func (c *Client) LongPollWait(ctx context.Context, creds Credentials, supportedActions []string) (string, error) {
174+
value, err := json.Marshal(message.LongPollWaitRequest{
175+
SupportedActions: supportedActions,
176+
})
177+
if err != nil {
178+
return "", fmt.Errorf("failed to marshal DNClient message: %s", err)
179+
}
180+
181+
respBody, err := c.postDNClient(ctx, message.LongPollWait, value, creds.HostID, creds.Counter, creds.PrivateKey)
182+
if err != nil {
183+
return "", fmt.Errorf("failed to post message to dnclient api: %w", err)
184+
}
185+
result := message.LongPollWaitResponseWrapper{}
186+
err = json.Unmarshal(respBody, &result)
187+
if err != nil {
188+
return "", fmt.Errorf("failed to interpret API response: %s", err)
189+
}
190+
return result.Data.Action, nil
191+
}
192+
171193
func (c *Client) DoUpdateWithTimeout(ctx context.Context, t time.Duration, creds Credentials) ([]byte, []byte, *Credentials, error) {
172194
toCtx, cancel := context.WithTimeout(ctx, t)
173195
defer cancel()

dnapitest/dnapitest.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,8 @@ func (s *Server) handlerDNClient(w http.ResponseWriter, r *http.Request) {
155155
return
156156
}
157157

158-
if msg.Type == message.DoUpdate {
158+
switch msg.Type {
159+
case message.DoUpdate:
159160
var updateKeys message.DoUpdateRequest
160161
err = json.Unmarshal(msg.Value, &updateKeys)
161162
if err != nil {
@@ -169,6 +170,20 @@ func (s *Server) handlerDNClient(w http.ResponseWriter, r *http.Request) {
169170
http.Error(w, err.Error(), http.StatusInternalServerError)
170171
return
171172
}
173+
case message.LongPollWait:
174+
var longPoll message.LongPollWaitRequest
175+
err = json.Unmarshal(msg.Value, &longPoll)
176+
if err != nil {
177+
s.errors = append(s.errors, fmt.Errorf("failed to unmarshal LongPollWaitRequest: %w", err))
178+
http.Error(w, "failed to unmarshal LongPollWaitRequest", http.StatusInternalServerError)
179+
return
180+
}
181+
182+
if len(longPoll.SupportedActions) == 0 {
183+
s.errors = append(s.errors, fmt.Errorf("no supported actions"))
184+
http.Error(w, "no supported actions", http.StatusInternalServerError)
185+
return
186+
}
172187
}
173188

174189
// return the associated response

message/message.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
const (
1111
CheckForUpdate = "CheckForUpdate"
1212
DoUpdate = "DoUpdate"
13+
LongPollWait = "LongPollWait"
1314
)
1415

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

77+
// LongPollWaitResponseWrapper contains a response to LongPollWawit inside "data."
78+
type LongPollWaitResponseWrapper struct {
79+
Data LongPollWaitResponse `json:"data"`
80+
}
81+
82+
// LongPollWaitRequest is the request message associated with a LongPollWait call.
83+
type LongPollWaitRequest struct {
84+
SupportedActions []string `json:"supportedActions"`
85+
}
86+
87+
// DNClientLongPollResponse is the response message associated with a LongPollWait call.
88+
type LongPollWaitResponse struct {
89+
Action string `json:"action"` // e.g. NoOp, StreamLogs, DoUpdate
90+
}
91+
92+
type ClientInfo struct {
93+
Identifier string `json:"identifier"`
94+
Version string `json:"version"`
95+
OS string `json:"os"`
96+
Architecture string `json:"architecture"`
97+
}
98+
7699
// EnrollEndpoint is the REST enrollment endpoint.
77100
const EnrollEndpoint = "/v2/enroll"
78101

0 commit comments

Comments
 (0)