Refactor RDP proxy handling and update related tests
This commit is contained in:
@@ -9,6 +9,7 @@ import (
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -17,6 +18,17 @@ type Client struct {
|
||||
httpClient *http.Client
|
||||
}
|
||||
|
||||
type RawControlRequest struct {
|
||||
Method string `json:"method"`
|
||||
Path string `json:"path"`
|
||||
Body json.RawMessage `json:"body,omitempty"`
|
||||
}
|
||||
|
||||
type RawControlResponse struct {
|
||||
StatusCode int `json:"status_code"`
|
||||
Body json.RawMessage `json:"body,omitempty"`
|
||||
}
|
||||
|
||||
type EnrollRequest struct {
|
||||
ClusterID string `json:"cluster_id"`
|
||||
JoinToken string `json:"join_token"`
|
||||
@@ -46,14 +58,15 @@ type EnrollmentBootstrapResponse struct {
|
||||
}
|
||||
|
||||
type NodeBootstrap struct {
|
||||
NodeID string `json:"node_id"`
|
||||
ClusterID string `json:"cluster_id"`
|
||||
IdentityStatus string `json:"identity_status"`
|
||||
Certificate map[string]any `json:"certificate"`
|
||||
HeartbeatEndpoint string `json:"heartbeat_endpoint"`
|
||||
ClusterAuthority *ClusterAuthorityDescriptor `json:"cluster_authority,omitempty"`
|
||||
AuthorityPayload json.RawMessage `json:"authority_payload,omitempty"`
|
||||
AuthoritySignature *ClusterSignature `json:"authority_signature,omitempty"`
|
||||
NodeID string `json:"node_id"`
|
||||
ClusterID string `json:"cluster_id"`
|
||||
IdentityStatus string `json:"identity_status"`
|
||||
Certificate map[string]any `json:"certificate"`
|
||||
HeartbeatEndpoint string `json:"heartbeat_endpoint"`
|
||||
ClusterAuthority *ClusterAuthorityDescriptor `json:"cluster_authority,omitempty"`
|
||||
ClusterAuthorityQuorum json.RawMessage `json:"cluster_authority_quorum,omitempty"`
|
||||
AuthorityPayload json.RawMessage `json:"authority_payload,omitempty"`
|
||||
AuthoritySignature *ClusterSignature `json:"authority_signature,omitempty"`
|
||||
}
|
||||
|
||||
type HeartbeatRequest struct {
|
||||
@@ -123,6 +136,7 @@ type NodeUpdatePlan struct {
|
||||
Artifact *ReleaseArtifact `json:"artifact,omitempty"`
|
||||
AuthorityPayload json.RawMessage `json:"authority_payload,omitempty"`
|
||||
AuthoritySignature *ClusterSignature `json:"authority_signature,omitempty"`
|
||||
AuthorityQuorum *QuorumEnvelope `json:"authority_quorum,omitempty"`
|
||||
ProductionForwarding bool `json:"production_forwarding"`
|
||||
}
|
||||
|
||||
@@ -293,6 +307,26 @@ type SyntheticMeshConfig struct {
|
||||
ProductionForwarding bool `json:"production_forwarding"`
|
||||
}
|
||||
|
||||
type AdminRuntimeProjectionRequest struct {
|
||||
SchemaVersion string `json:"schema_version"`
|
||||
Method string `json:"method"`
|
||||
Path string `json:"path"`
|
||||
Query string `json:"query,omitempty"`
|
||||
Host string `json:"host,omitempty"`
|
||||
Scope string `json:"scope"`
|
||||
ServiceClass string `json:"service_class"`
|
||||
ObservedAt string `json:"observed_at"`
|
||||
}
|
||||
|
||||
type AdminRuntimeProjectionResponse struct {
|
||||
SchemaVersion string `json:"schema_version"`
|
||||
Status string `json:"status"`
|
||||
Reason string `json:"reason,omitempty"`
|
||||
StatusCode int `json:"status_code"`
|
||||
Headers map[string]string `json:"headers,omitempty"`
|
||||
Body json.RawMessage `json:"body,omitempty"`
|
||||
}
|
||||
|
||||
func (c *SyntheticMeshConfig) UnmarshalJSON(data []byte) error {
|
||||
type syntheticMeshConfigAlias SyntheticMeshConfig
|
||||
var decoded syntheticMeshConfigAlias
|
||||
@@ -448,6 +482,18 @@ type ClusterSignature struct {
|
||||
SignedAt time.Time `json:"signed_at"`
|
||||
}
|
||||
|
||||
type QuorumEnvelope struct {
|
||||
SchemaVersion string `json:"schema_version"`
|
||||
ClusterID string `json:"cluster_id"`
|
||||
Epoch string `json:"epoch"`
|
||||
Threshold int `json:"threshold"`
|
||||
PayloadSHA256 string `json:"payload_sha256"`
|
||||
QuorumSHA256 string `json:"quorum_sha256"`
|
||||
Signatures []ClusterSignature `json:"signatures"`
|
||||
AllowedScopes []string `json:"allowed_scopes,omitempty"`
|
||||
DecisionReason string `json:"decision_reason,omitempty"`
|
||||
}
|
||||
|
||||
type PeerDirectoryEntry struct {
|
||||
NodeID string `json:"node_id"`
|
||||
RouteIDs []string `json:"route_ids,omitempty"`
|
||||
@@ -744,6 +790,50 @@ func (c *Client) SyntheticMeshConfig(ctx context.Context, clusterID, nodeID stri
|
||||
return response.Config, nil
|
||||
}
|
||||
|
||||
func (c *Client) AdminRuntimeProjection(ctx context.Context, clusterID, nodeID string, request AdminRuntimeProjectionRequest) (AdminRuntimeProjectionResponse, error) {
|
||||
var response AdminRuntimeProjectionResponse
|
||||
path := fmt.Sprintf("/clusters/%s/nodes/%s/admin-runtime/projection", clusterID, nodeID)
|
||||
if err := c.postJSON(ctx, path, request, &response); err != nil {
|
||||
return AdminRuntimeProjectionResponse{}, err
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (c *Client) RawControl(ctx context.Context, request RawControlRequest) (RawControlResponse, error) {
|
||||
method := strings.ToUpper(strings.TrimSpace(request.Method))
|
||||
if method == "" {
|
||||
method = http.MethodGet
|
||||
}
|
||||
path := strings.TrimSpace(request.Path)
|
||||
if !strings.HasPrefix(path, "/") {
|
||||
return RawControlResponse{}, fmt.Errorf("control path must be relative")
|
||||
}
|
||||
var body io.Reader
|
||||
if len(request.Body) > 0 && string(request.Body) != "null" {
|
||||
body = bytes.NewReader(request.Body)
|
||||
}
|
||||
httpReq, err := http.NewRequestWithContext(ctx, method, c.baseURL+path, body)
|
||||
if err != nil {
|
||||
return RawControlResponse{}, err
|
||||
}
|
||||
if body != nil {
|
||||
httpReq.Header.Set("Content-Type", "application/json")
|
||||
}
|
||||
httpResp, err := c.httpClient.Do(httpReq)
|
||||
if err != nil {
|
||||
return RawControlResponse{}, err
|
||||
}
|
||||
defer httpResp.Body.Close()
|
||||
payload, err := io.ReadAll(io.LimitReader(httpResp.Body, 2*1024*1024))
|
||||
if err != nil {
|
||||
return RawControlResponse{}, err
|
||||
}
|
||||
if httpResp.StatusCode < 200 || httpResp.StatusCode >= 300 {
|
||||
return RawControlResponse{}, fmt.Errorf("backend returned status %d: %s", httpResp.StatusCode, string(payload))
|
||||
}
|
||||
return RawControlResponse{StatusCode: httpResp.StatusCode, Body: json.RawMessage(payload)}, nil
|
||||
}
|
||||
|
||||
func (c *Client) getJSON(ctx context.Context, path string, response any) error {
|
||||
httpReq, err := http.NewRequestWithContext(ctx, http.MethodGet, c.baseURL+path, nil)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user