mirror of
https://github.com/kubescape/kubescape.git
synced 2026-04-15 06:58:11 +00:00
* Interfaces are unchanged
* Deprecated: low-level API funcs marked for deprecation:
HttpPost, HttpGetter, HttpDelete (an augmented version of the KS Cloud
client will expose the post report API, which is currently the sole
use-case of low-level API)
* Doc: the package is now godoc-friendly
* Style & code layout:
* listed all exposed types via aliases, for clarity/less confusing
imports
* unexported private types
* factorized query param logic
* factorized type <-> JSON using generic func & io.Reader
* "utils" are now limited to a few common utility functions
* centralized hard-coded strings as (unexported) constants
* concision: use higher-level http definitions such as constants,
cookie methods, etc
* included type-safety guards to verify that interfaces are
actually implemented by the exported types
* Tests: existing test assertions are unchanged
* tests are beefed-up to assert proper authentication flow (token & cookie).
* added unit tests for utility methods
* Perf:
* unmarshalling API responses is now flowing without extraneous memory allocation via string representation
* request headers are now passed withot extraneous map allocation
* JSON operations are now fully supported by jsoniter (no longer use encoding/json)
* Changes in functionality:
* the client is now fully extensible with KSCloudOption
* use the option functor idiom to keep constructors short
* methods that used to mute errors (i.e. return nil, nil) now bubble up errors
* the captured cookie is now captured in full, not just its value
(other cookie parameters returned are stored)
* added a request/response dump option, for debugging
* added support for SubmitReport and retrieval of UI url's
* backported utm changes (reports use case)
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
203 lines
4.4 KiB
Go
203 lines
4.4 KiB
Go
package getter
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
"net/http/httputil"
|
|
"time"
|
|
)
|
|
|
|
type (
|
|
// KSCloudOption allows to configure the behavior of the KS Cloud client.
|
|
KSCloudOption func(*ksCloudOptions)
|
|
|
|
// ksCloudOptions holds all the configurable parts of the KS Cloud client.
|
|
ksCloudOptions struct {
|
|
httpClient *http.Client
|
|
cloudReportURL string
|
|
cloudUIURL string
|
|
timeout *time.Duration
|
|
withTrace bool
|
|
}
|
|
|
|
// request option instructs post/get/delete to alter the outgoing request
|
|
requestOption func(*requestOptions)
|
|
|
|
// requestOptions knows how to enrich a request with headers
|
|
requestOptions struct {
|
|
withJSON bool
|
|
withToken string
|
|
withCookie *http.Cookie
|
|
withTrace bool
|
|
headers map[string]string
|
|
reqContext context.Context
|
|
}
|
|
)
|
|
|
|
// KS Cloud client options
|
|
|
|
// WithHTTPClient overrides the default http.Client used by the KS Cloud client.
|
|
func WithHTTPClient(client *http.Client) KSCloudOption {
|
|
return func(o *ksCloudOptions) {
|
|
o.httpClient = client
|
|
}
|
|
}
|
|
|
|
// WithTimeout sets a global timeout on a operations performed by the KS Cloud client.
|
|
//
|
|
// A value of 0 means no timeout.
|
|
//
|
|
// The default is 61s.
|
|
func WithTimeout(timeout time.Duration) KSCloudOption {
|
|
duration := timeout
|
|
|
|
return func(o *ksCloudOptions) {
|
|
o.timeout = &duration
|
|
}
|
|
}
|
|
|
|
// WithReportURL specifies the URL to post reports.
|
|
func WithReportURL(u string) KSCloudOption {
|
|
return func(o *ksCloudOptions) {
|
|
o.cloudReportURL = u
|
|
}
|
|
}
|
|
|
|
// WithFrontendURL specifies the URL to access the KS Cloud UI.
|
|
func WithFrontendURL(u string) KSCloudOption {
|
|
return func(o *ksCloudOptions) {
|
|
o.cloudUIURL = u
|
|
}
|
|
}
|
|
|
|
// WithTrace toggles requests dump for inspection & debugging.
|
|
func WithTrace(enabled bool) KSCloudOption {
|
|
return func(o *ksCloudOptions) {
|
|
o.withTrace = enabled
|
|
}
|
|
}
|
|
|
|
var defaultClient = &http.Client{
|
|
Timeout: 61 * time.Second,
|
|
}
|
|
|
|
// ksCloudOptionsWithDefaults sets defaults for the KS client and applies overrides.
|
|
func ksCloudOptionsWithDefaults(opts []KSCloudOption) *ksCloudOptions {
|
|
options := &ksCloudOptions{
|
|
httpClient: defaultClient,
|
|
}
|
|
|
|
for _, apply := range opts {
|
|
apply(options)
|
|
}
|
|
|
|
if options.timeout != nil {
|
|
// non-default timeout (0 means no timeout)
|
|
// clone the client and override the timeout
|
|
client := *options.httpClient
|
|
client.Timeout = *options.timeout
|
|
options.httpClient = &client
|
|
}
|
|
|
|
return options
|
|
}
|
|
|
|
// http request options
|
|
|
|
// withContentJSON sets JSON content type for a request
|
|
func withContentJSON(enabled bool) requestOption {
|
|
return func(o *requestOptions) {
|
|
o.withJSON = enabled
|
|
}
|
|
}
|
|
|
|
// withToken sets an Authorization header for a request
|
|
func withToken(token string) requestOption {
|
|
return func(o *requestOptions) {
|
|
o.withToken = token
|
|
}
|
|
}
|
|
|
|
// withCookie sets an authentication cookie for a request
|
|
func withCookie(cookie *http.Cookie) requestOption {
|
|
return func(o *requestOptions) {
|
|
o.withCookie = cookie
|
|
}
|
|
}
|
|
|
|
// withExtraHeaders adds extra headers to a request
|
|
func withExtraHeaders(headers map[string]string) requestOption {
|
|
return func(o *requestOptions) {
|
|
o.headers = headers
|
|
}
|
|
}
|
|
|
|
/* not used yet
|
|
// withContext sets the context of a request.
|
|
//
|
|
// By default, context.Background() is used.
|
|
func withContext(ctx context.Context) requestOption {
|
|
return func(o *requestOptions) {
|
|
o.reqContext = ctx
|
|
}
|
|
}
|
|
*/
|
|
|
|
// withTrace dumps requests for debugging
|
|
func withTrace(enabled bool) requestOption {
|
|
return func(o *requestOptions) {
|
|
o.withTrace = enabled
|
|
}
|
|
}
|
|
|
|
func (o *requestOptions) setHeaders(req *http.Request) {
|
|
if o.withJSON {
|
|
req.Header.Set("Content-Type", "application/json")
|
|
}
|
|
|
|
if len(o.withToken) > 0 {
|
|
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", o.withToken))
|
|
}
|
|
|
|
if o.withCookie != nil {
|
|
req.AddCookie(o.withCookie)
|
|
}
|
|
|
|
for k, v := range o.headers {
|
|
req.Header.Set(k, v)
|
|
}
|
|
}
|
|
|
|
// traceReq dumps the content of an outgoing request for inspecting or debugging the client.
|
|
func (o *requestOptions) traceReq(req *http.Request) {
|
|
if !o.withTrace {
|
|
return
|
|
}
|
|
|
|
dump, _ := httputil.DumpRequestOut(req, true)
|
|
log.Printf("%s\n", dump)
|
|
}
|
|
|
|
// traceResp dumps the content of an API response for inspecting or debugging the client.
|
|
func (o *requestOptions) traceResp(resp *http.Response) {
|
|
if !o.withTrace {
|
|
return
|
|
}
|
|
|
|
dump, _ := httputil.DumpResponse(resp, true)
|
|
log.Printf("%s\n", dump)
|
|
}
|
|
|
|
func requestOptionsWithDefaults(opts []requestOption) *requestOptions {
|
|
o := &requestOptions{
|
|
reqContext: context.Background(),
|
|
}
|
|
for _, apply := range opts {
|
|
apply(o)
|
|
}
|
|
|
|
return o
|
|
}
|