mirror of
https://github.com/pomerium/pomerium.git
synced 2025-04-28 18:06:34 +02:00
core/zero: add report-usage API (#5276)
This commit is contained in:
parent
790c11b368
commit
1e5f623c0e
4 changed files with 276 additions and 0 deletions
|
@ -107,6 +107,11 @@ type ClientInterface interface {
|
|||
ExchangeClusterIdentityTokenWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error)
|
||||
|
||||
ExchangeClusterIdentityToken(ctx context.Context, body ExchangeClusterIdentityTokenJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error)
|
||||
|
||||
// ReportUsageWithBody request with any body
|
||||
ReportUsageWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error)
|
||||
|
||||
ReportUsage(ctx context.Context, body ReportUsageJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error)
|
||||
}
|
||||
|
||||
func (c *Client) GetClusterBootstrapConfig(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) {
|
||||
|
@ -193,6 +198,30 @@ func (c *Client) ExchangeClusterIdentityToken(ctx context.Context, body Exchange
|
|||
return c.Client.Do(req)
|
||||
}
|
||||
|
||||
func (c *Client) ReportUsageWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) {
|
||||
req, err := NewReportUsageRequestWithBody(c.Server, contentType, body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req = req.WithContext(ctx)
|
||||
if err := c.applyEditors(ctx, req, reqEditors); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c.Client.Do(req)
|
||||
}
|
||||
|
||||
func (c *Client) ReportUsage(ctx context.Context, body ReportUsageJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) {
|
||||
req, err := NewReportUsageRequest(c.Server, body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req = req.WithContext(ctx)
|
||||
if err := c.applyEditors(ctx, req, reqEditors); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c.Client.Do(req)
|
||||
}
|
||||
|
||||
// NewGetClusterBootstrapConfigRequest generates requests for GetClusterBootstrapConfig
|
||||
func NewGetClusterBootstrapConfigRequest(server string) (*http.Request, error) {
|
||||
var err error
|
||||
|
@ -368,6 +397,46 @@ func NewExchangeClusterIdentityTokenRequestWithBody(server string, contentType s
|
|||
return req, nil
|
||||
}
|
||||
|
||||
// NewReportUsageRequest calls the generic ReportUsage builder with application/json body
|
||||
func NewReportUsageRequest(server string, body ReportUsageJSONRequestBody) (*http.Request, error) {
|
||||
var bodyReader io.Reader
|
||||
buf, err := json.Marshal(body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bodyReader = bytes.NewReader(buf)
|
||||
return NewReportUsageRequestWithBody(server, "application/json", bodyReader)
|
||||
}
|
||||
|
||||
// NewReportUsageRequestWithBody generates requests for ReportUsage with any type of body
|
||||
func NewReportUsageRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) {
|
||||
var err error
|
||||
|
||||
serverURL, err := url.Parse(server)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
operationPath := fmt.Sprintf("/reportUsage")
|
||||
if operationPath[0] == '/' {
|
||||
operationPath = "." + operationPath
|
||||
}
|
||||
|
||||
queryURL, err := serverURL.Parse(operationPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("POST", queryURL.String(), body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req.Header.Add("Content-Type", contentType)
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
func (c *Client) applyEditors(ctx context.Context, req *http.Request, additionalEditors []RequestEditorFn) error {
|
||||
for _, r := range c.RequestEditors {
|
||||
if err := r(ctx, req); err != nil {
|
||||
|
@ -429,6 +498,11 @@ type ClientWithResponsesInterface interface {
|
|||
ExchangeClusterIdentityTokenWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*ExchangeClusterIdentityTokenResp, error)
|
||||
|
||||
ExchangeClusterIdentityTokenWithResponse(ctx context.Context, body ExchangeClusterIdentityTokenJSONRequestBody, reqEditors ...RequestEditorFn) (*ExchangeClusterIdentityTokenResp, error)
|
||||
|
||||
// ReportUsageWithBodyWithResponse request with any body
|
||||
ReportUsageWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*ReportUsageResp, error)
|
||||
|
||||
ReportUsageWithResponse(ctx context.Context, body ReportUsageJSONRequestBody, reqEditors ...RequestEditorFn) (*ReportUsageResp, error)
|
||||
}
|
||||
|
||||
type GetClusterBootstrapConfigResp struct {
|
||||
|
@ -551,6 +625,27 @@ func (r ExchangeClusterIdentityTokenResp) StatusCode() int {
|
|||
return 0
|
||||
}
|
||||
|
||||
type ReportUsageResp struct {
|
||||
Body []byte
|
||||
HTTPResponse *http.Response
|
||||
}
|
||||
|
||||
// Status returns HTTPResponse.Status
|
||||
func (r ReportUsageResp) Status() string {
|
||||
if r.HTTPResponse != nil {
|
||||
return r.HTTPResponse.Status
|
||||
}
|
||||
return http.StatusText(0)
|
||||
}
|
||||
|
||||
// StatusCode returns HTTPResponse.StatusCode
|
||||
func (r ReportUsageResp) StatusCode() int {
|
||||
if r.HTTPResponse != nil {
|
||||
return r.HTTPResponse.StatusCode
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// GetClusterBootstrapConfigWithResponse request returning *GetClusterBootstrapConfigResp
|
||||
func (c *ClientWithResponses) GetClusterBootstrapConfigWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetClusterBootstrapConfigResp, error) {
|
||||
rsp, err := c.GetClusterBootstrapConfig(ctx, reqEditors...)
|
||||
|
@ -612,6 +707,23 @@ func (c *ClientWithResponses) ExchangeClusterIdentityTokenWithResponse(ctx conte
|
|||
return ParseExchangeClusterIdentityTokenResp(rsp)
|
||||
}
|
||||
|
||||
// ReportUsageWithBodyWithResponse request with arbitrary body returning *ReportUsageResp
|
||||
func (c *ClientWithResponses) ReportUsageWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*ReportUsageResp, error) {
|
||||
rsp, err := c.ReportUsageWithBody(ctx, contentType, body, reqEditors...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ParseReportUsageResp(rsp)
|
||||
}
|
||||
|
||||
func (c *ClientWithResponses) ReportUsageWithResponse(ctx context.Context, body ReportUsageJSONRequestBody, reqEditors ...RequestEditorFn) (*ReportUsageResp, error) {
|
||||
rsp, err := c.ReportUsage(ctx, body, reqEditors...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ParseReportUsageResp(rsp)
|
||||
}
|
||||
|
||||
// ParseGetClusterBootstrapConfigResp parses an HTTP response from a GetClusterBootstrapConfigWithResponse call
|
||||
func ParseGetClusterBootstrapConfigResp(rsp *http.Response) (*GetClusterBootstrapConfigResp, error) {
|
||||
bodyBytes, err := io.ReadAll(rsp.Body)
|
||||
|
@ -812,6 +924,22 @@ func ParseExchangeClusterIdentityTokenResp(rsp *http.Response) (*ExchangeCluster
|
|||
return response, nil
|
||||
}
|
||||
|
||||
// ParseReportUsageResp parses an HTTP response from a ReportUsageWithResponse call
|
||||
func ParseReportUsageResp(rsp *http.Response) (*ReportUsageResp, error) {
|
||||
bodyBytes, err := io.ReadAll(rsp.Body)
|
||||
defer func() { _ = rsp.Body.Close() }()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response := &ReportUsageResp{
|
||||
Body: bodyBytes,
|
||||
HTTPResponse: rsp,
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
// GetHTTPResponse implements apierror.APIResponse
|
||||
func (r *GetClusterBootstrapConfigResp) GetHTTPResponse() *http.Response {
|
||||
return r.HTTPResponse
|
||||
|
@ -951,3 +1079,16 @@ func (r *ExchangeClusterIdentityTokenResp) GetInternalServerError() (string, boo
|
|||
}
|
||||
return r.JSON500.Error, true
|
||||
}
|
||||
|
||||
// GetHTTPResponse implements apierror.APIResponse
|
||||
func (r *ReportUsageResp) GetHTTPResponse() *http.Response {
|
||||
return r.HTTPResponse
|
||||
}
|
||||
|
||||
// GetValue implements apierror.APIResponse
|
||||
func (r *ReportUsageResp) GetValue() *EmptyResponse {
|
||||
if r.StatusCode()/100 != 2 {
|
||||
return nil
|
||||
}
|
||||
return &EmptyResponse{}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
// Code generated by github.com/oapi-codegen/oapi-codegen/v2 version v2.3.0 DO NOT EDIT.
|
||||
package cluster
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
BearerAuthScopes = "bearerAuth.Scopes"
|
||||
)
|
||||
|
@ -95,6 +99,18 @@ type GetBundlesResponse struct {
|
|||
Bundles []Bundle `json:"bundles"`
|
||||
}
|
||||
|
||||
// ReportUsageRequest defines model for ReportUsageRequest.
|
||||
type ReportUsageRequest struct {
|
||||
Users []ReportUsageUser `json:"users"`
|
||||
}
|
||||
|
||||
// ReportUsageUser defines model for ReportUsageUser.
|
||||
type ReportUsageUser struct {
|
||||
LastSignedInAt time.Time `json:"lastSignedInAt"`
|
||||
PseudonymousEmail string `json:"pseudonymousEmail"`
|
||||
PseudonymousId string `json:"pseudonymousId"`
|
||||
}
|
||||
|
||||
// BundleId defines model for bundleId.
|
||||
type BundleId = string
|
||||
|
||||
|
@ -103,3 +119,6 @@ type ReportClusterResourceBundleStatusJSONRequestBody = BundleStatus
|
|||
|
||||
// ExchangeClusterIdentityTokenJSONRequestBody defines body for ExchangeClusterIdentityToken for application/json ContentType.
|
||||
type ExchangeClusterIdentityTokenJSONRequestBody = ExchangeTokenRequest
|
||||
|
||||
// ReportUsageJSONRequestBody defines body for ReportUsage for application/json ContentType.
|
||||
type ReportUsageJSONRequestBody = ReportUsageRequest
|
||||
|
|
|
@ -149,6 +149,21 @@ paths:
|
|||
schema:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
|
||||
/reportUsage:
|
||||
post:
|
||||
description: Report usage for the cluster
|
||||
operationId: reportUsage
|
||||
tags: [usage]
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ReportUsageRequest"
|
||||
responses:
|
||||
"204":
|
||||
description: OK
|
||||
|
||||
components:
|
||||
parameters:
|
||||
bundleId:
|
||||
|
@ -279,3 +294,26 @@ components:
|
|||
$ref: "#/components/schemas/Bundle"
|
||||
required:
|
||||
- bundles
|
||||
ReportUsageRequest:
|
||||
type: object
|
||||
properties:
|
||||
users:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/ReportUsageUser"
|
||||
required:
|
||||
- users
|
||||
ReportUsageUser:
|
||||
type: object
|
||||
properties:
|
||||
lastSignedInAt:
|
||||
type: string
|
||||
format: "date-time"
|
||||
pseudonymousEmail:
|
||||
type: string
|
||||
pseudonymousId:
|
||||
type: string
|
||||
required:
|
||||
- lastSignedInAt
|
||||
- pseudonymousEmail
|
||||
- pseudonymousId
|
||||
|
|
|
@ -31,6 +31,9 @@ type ServerInterface interface {
|
|||
|
||||
// (POST /exchangeToken)
|
||||
ExchangeClusterIdentityToken(w http.ResponseWriter, r *http.Request)
|
||||
|
||||
// (POST /reportUsage)
|
||||
ReportUsage(w http.ResponseWriter, r *http.Request)
|
||||
}
|
||||
|
||||
// Unimplemented server implementation that returns http.StatusNotImplemented for each endpoint.
|
||||
|
@ -62,6 +65,11 @@ func (_ Unimplemented) ExchangeClusterIdentityToken(w http.ResponseWriter, r *ht
|
|||
w.WriteHeader(http.StatusNotImplemented)
|
||||
}
|
||||
|
||||
// (POST /reportUsage)
|
||||
func (_ Unimplemented) ReportUsage(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusNotImplemented)
|
||||
}
|
||||
|
||||
// ServerInterfaceWrapper converts contexts to parameters.
|
||||
type ServerInterfaceWrapper struct {
|
||||
Handler ServerInterface
|
||||
|
@ -176,6 +184,23 @@ func (siw *ServerInterfaceWrapper) ExchangeClusterIdentityToken(w http.ResponseW
|
|||
handler.ServeHTTP(w, r.WithContext(ctx))
|
||||
}
|
||||
|
||||
// ReportUsage operation middleware
|
||||
func (siw *ServerInterfaceWrapper) ReportUsage(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
|
||||
ctx = context.WithValue(ctx, BearerAuthScopes, []string{})
|
||||
|
||||
handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
siw.Handler.ReportUsage(w, r)
|
||||
}))
|
||||
|
||||
for i := len(siw.HandlerMiddlewares) - 1; i >= 0; i-- {
|
||||
handler = siw.HandlerMiddlewares[i](handler)
|
||||
}
|
||||
|
||||
handler.ServeHTTP(w, r.WithContext(ctx))
|
||||
}
|
||||
|
||||
type UnescapedCookieParamError struct {
|
||||
ParamName string
|
||||
Err error
|
||||
|
@ -304,6 +329,9 @@ func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handl
|
|||
r.Group(func(r chi.Router) {
|
||||
r.Post(options.BaseURL+"/exchangeToken", wrapper.ExchangeClusterIdentityToken)
|
||||
})
|
||||
r.Group(func(r chi.Router) {
|
||||
r.Post(options.BaseURL+"/reportUsage", wrapper.ReportUsage)
|
||||
})
|
||||
|
||||
return r
|
||||
}
|
||||
|
@ -490,6 +518,22 @@ func (response ExchangeClusterIdentityToken500JSONResponse) VisitExchangeCluster
|
|||
return json.NewEncoder(w).Encode(response)
|
||||
}
|
||||
|
||||
type ReportUsageRequestObject struct {
|
||||
Body *ReportUsageJSONRequestBody
|
||||
}
|
||||
|
||||
type ReportUsageResponseObject interface {
|
||||
VisitReportUsageResponse(w http.ResponseWriter) error
|
||||
}
|
||||
|
||||
type ReportUsage204Response struct {
|
||||
}
|
||||
|
||||
func (response ReportUsage204Response) VisitReportUsageResponse(w http.ResponseWriter) error {
|
||||
w.WriteHeader(204)
|
||||
return nil
|
||||
}
|
||||
|
||||
// StrictServerInterface represents all server handlers.
|
||||
type StrictServerInterface interface {
|
||||
|
||||
|
@ -507,6 +551,9 @@ type StrictServerInterface interface {
|
|||
|
||||
// (POST /exchangeToken)
|
||||
ExchangeClusterIdentityToken(ctx context.Context, request ExchangeClusterIdentityTokenRequestObject) (ExchangeClusterIdentityTokenResponseObject, error)
|
||||
|
||||
// (POST /reportUsage)
|
||||
ReportUsage(ctx context.Context, request ReportUsageRequestObject) (ReportUsageResponseObject, error)
|
||||
}
|
||||
|
||||
type StrictHandlerFunc = strictnethttp.StrictHTTPHandlerFunc
|
||||
|
@ -675,3 +722,34 @@ func (sh *strictHandler) ExchangeClusterIdentityToken(w http.ResponseWriter, r *
|
|||
sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response))
|
||||
}
|
||||
}
|
||||
|
||||
// ReportUsage operation middleware
|
||||
func (sh *strictHandler) ReportUsage(w http.ResponseWriter, r *http.Request) {
|
||||
var request ReportUsageRequestObject
|
||||
|
||||
var body ReportUsageJSONRequestBody
|
||||
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
|
||||
sh.options.RequestErrorHandlerFunc(w, r, fmt.Errorf("can't decode JSON body: %w", err))
|
||||
return
|
||||
}
|
||||
request.Body = &body
|
||||
|
||||
handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) {
|
||||
return sh.ssi.ReportUsage(ctx, request.(ReportUsageRequestObject))
|
||||
}
|
||||
for _, middleware := range sh.middlewares {
|
||||
handler = middleware(handler, "ReportUsage")
|
||||
}
|
||||
|
||||
response, err := handler(r.Context(), w, r, request)
|
||||
|
||||
if err != nil {
|
||||
sh.options.ResponseErrorHandlerFunc(w, r, err)
|
||||
} else if validResponse, ok := response.(ReportUsageResponseObject); ok {
|
||||
if err := validResponse.VisitReportUsageResponse(w); err != nil {
|
||||
sh.options.ResponseErrorHandlerFunc(w, r, err)
|
||||
}
|
||||
} else if response != nil {
|
||||
sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response))
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue