agent: stub out auditing functionality in OSS
This commit is contained in:
parent
8afa406177
commit
c3d24d7c3e
|
@ -16,6 +16,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/hashicorp/go-connlimit"
|
"github.com/hashicorp/go-connlimit"
|
||||||
|
@ -178,6 +179,10 @@ type Agent struct {
|
||||||
// In-memory sink used for collecting metrics
|
// In-memory sink used for collecting metrics
|
||||||
MemSink *metrics.InmemSink
|
MemSink *metrics.InmemSink
|
||||||
|
|
||||||
|
// Eventer provides a backend for handling event logging. APIs are provided on the agent for interacting with
|
||||||
|
// this reloadable type
|
||||||
|
Eventer atomic.Value
|
||||||
|
|
||||||
// delegate is either a *consul.Server or *consul.Client
|
// delegate is either a *consul.Server or *consul.Client
|
||||||
// depending on the configuration
|
// depending on the configuration
|
||||||
delegate delegate
|
delegate delegate
|
||||||
|
@ -430,7 +435,10 @@ func (a *Agent) Start() error {
|
||||||
// waiting to discover a consul server
|
// waiting to discover a consul server
|
||||||
consulCfg.ServerUp = a.sync.SyncFull.Trigger
|
consulCfg.ServerUp = a.sync.SyncFull.Trigger
|
||||||
|
|
||||||
a.initEnterprise(consulCfg)
|
err = a.initEnterprise(consulCfg)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to start Consul enterprise component: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
tlsConfigurator, err := tlsutil.NewConfigurator(c.ToTLSUtilConfig(), a.logger)
|
tlsConfigurator, err := tlsutil.NewConfigurator(c.ToTLSUtilConfig(), a.logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -4101,6 +4109,11 @@ func (a *Agent) ReloadConfig(newCfg *config.RuntimeConfig) error {
|
||||||
// concurrent due to both gaining a full lock on the stateLock
|
// concurrent due to both gaining a full lock on the stateLock
|
||||||
a.config.ConfigEntryBootstrap = newCfg.ConfigEntryBootstrap
|
a.config.ConfigEntryBootstrap = newCfg.ConfigEntryBootstrap
|
||||||
|
|
||||||
|
err := a.reloadEnterprise(newCfg)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// create the config for the rpc server/client
|
// create the config for the rpc server/client
|
||||||
consulCfg, err := a.consulConfig()
|
consulCfg, err := a.consulConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -9,14 +9,26 @@ import (
|
||||||
"github.com/hashicorp/consul/api"
|
"github.com/hashicorp/consul/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
// fillAgentServiceEnterpriseMeta stub
|
// fillAgentServiceEnterpriseMeta is a noop stub for the func defined agent_ent.go
|
||||||
func fillAgentServiceEnterpriseMeta(_ *api.AgentService, _ *structs.EnterpriseMeta) {}
|
func fillAgentServiceEnterpriseMeta(_ *api.AgentService, _ *structs.EnterpriseMeta) {}
|
||||||
|
|
||||||
// fillHealthCheckEnterpriseMeta stub
|
// fillHealthCheckEnterpriseMeta is a noop stub for the func defined agent_ent.go
|
||||||
func fillHealthCheckEnterpriseMeta(_ *api.HealthCheck, _ *structs.EnterpriseMeta) {}
|
func fillHealthCheckEnterpriseMeta(_ *api.HealthCheck, _ *structs.EnterpriseMeta) {}
|
||||||
|
|
||||||
func (a *Agent) initEnterprise(consulCfg *consul.Config) {
|
// initEnterprise is a noop stub for the func defined agent_ent.go
|
||||||
|
func (a *Agent) initEnterprise(consulCfg *consul.Config) error {
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// loadEnterpriseTokens is a noop stub for the func defined agent_ent.go
|
||||||
func (a *Agent) loadEnterpriseTokens(conf *config.RuntimeConfig) {
|
func (a *Agent) loadEnterpriseTokens(conf *config.RuntimeConfig) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reloadEnterprise is a noop stub for the func defined agent_ent.go
|
||||||
|
func (a *Agent) reloadEnterprise(conf *config.RuntimeConfig) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteEvent is a noop stub for the func defined agent_ent.go
|
||||||
|
func (a *Agent) WriteEvent(eventType string, payload interface{}) {
|
||||||
|
}
|
||||||
|
|
|
@ -1004,7 +1004,7 @@ func (b *Builder) Build() (rt RuntimeConfig, err error) {
|
||||||
return rt, nil
|
return rt, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate performs semantical validation of the runtime configuration.
|
// Validate performs semantic validation of the runtime configuration.
|
||||||
func (b *Builder) Validate(rt RuntimeConfig) error {
|
func (b *Builder) Validate(rt RuntimeConfig) error {
|
||||||
// reDatacenter defines a regexp for a valid datacenter name
|
// reDatacenter defines a regexp for a valid datacenter name
|
||||||
var reDatacenter = regexp.MustCompile("^[a-z0-9_-]+$")
|
var reDatacenter = regexp.MustCompile("^[a-z0-9_-]+$")
|
||||||
|
|
|
@ -188,6 +188,7 @@ type Config struct {
|
||||||
AdvertiseAddrWAN *string `json:"advertise_addr_wan,omitempty" hcl:"advertise_addr_wan" mapstructure:"advertise_addr_wan"`
|
AdvertiseAddrWAN *string `json:"advertise_addr_wan,omitempty" hcl:"advertise_addr_wan" mapstructure:"advertise_addr_wan"`
|
||||||
AdvertiseAddrWANIPv4 *string `json:"advertise_addr_wan_ipv4,omitempty" hcl:"advertise_addr_wan_ipv4" mapstructure:"advertise_addr_wan_ipv4"`
|
AdvertiseAddrWANIPv4 *string `json:"advertise_addr_wan_ipv4,omitempty" hcl:"advertise_addr_wan_ipv4" mapstructure:"advertise_addr_wan_ipv4"`
|
||||||
AdvertiseAddrWANIPv6 *string `json:"advertise_addr_wan_ipv6,omitempty" hcl:"advertise_addr_wan_ipv6" mapstructure:"advertise_addr_ipv6"`
|
AdvertiseAddrWANIPv6 *string `json:"advertise_addr_wan_ipv6,omitempty" hcl:"advertise_addr_wan_ipv6" mapstructure:"advertise_addr_ipv6"`
|
||||||
|
Audit Audit `json:"audit,omitempty" hcl:"audit" mapstructure:"audit"`
|
||||||
Autopilot Autopilot `json:"autopilot,omitempty" hcl:"autopilot" mapstructure:"autopilot"`
|
Autopilot Autopilot `json:"autopilot,omitempty" hcl:"autopilot" mapstructure:"autopilot"`
|
||||||
BindAddr *string `json:"bind_addr,omitempty" hcl:"bind_addr" mapstructure:"bind_addr"`
|
BindAddr *string `json:"bind_addr,omitempty" hcl:"bind_addr" mapstructure:"bind_addr"`
|
||||||
Bootstrap *bool `json:"bootstrap,omitempty" hcl:"bootstrap" mapstructure:"bootstrap"`
|
Bootstrap *bool `json:"bootstrap,omitempty" hcl:"bootstrap" mapstructure:"bootstrap"`
|
||||||
|
@ -367,6 +368,24 @@ type AdvertiseAddrsConfig struct {
|
||||||
SerfWAN *string `json:"serf_wan,omitempty" hcl:"serf_wan" mapstructure:"serf_wan"`
|
SerfWAN *string `json:"serf_wan,omitempty" hcl:"serf_wan" mapstructure:"serf_wan"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AuditSink can be provided multiple times to define pipelines for auditing
|
||||||
|
type AuditSink struct {
|
||||||
|
Name *string `json:"name,omitempty" hcl:"name" mapstructure:"name"`
|
||||||
|
Type *string `json:"type,omitempty" hcl:"type" mapstructure:"type"`
|
||||||
|
Format *string `json:"format,omitempty" hcl:"format" mapstructure:"format"`
|
||||||
|
Path *string `json:"path,omitempty" hcl:"path" mapstructure:"path"`
|
||||||
|
DeliveryGuarantee *string `json:"delivery_guarantee,omitempty" hcl:"delivery_guarantee" mapstructure:"delivery_guarantee"`
|
||||||
|
RotateBytes *int `json:"rotate_bytes,omitempty" hcl:"rotate_bytes" mapstructure:"rotate_bytes"`
|
||||||
|
RotateDuration *string `json:"rotate_duration,omitempty" hcl:"rotate_duration" mapstructure:"rotate_duration"`
|
||||||
|
RotateMaxFiles *int `json:"rotate_max_files,omitempty" hcl:"rotate_max_files" mapstructure:"rotate_max_files"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Audit allows us to enable and define destinations for auditing
|
||||||
|
type Audit struct {
|
||||||
|
Enabled *bool `json:"enabled,omitempty" hcl:"enabled" mapstructure:"enabled"`
|
||||||
|
Sinks map[string]AuditSink `json:"sink,omitempty" hcl:"sink" mapstructure:"sink"`
|
||||||
|
}
|
||||||
|
|
||||||
type Autopilot struct {
|
type Autopilot struct {
|
||||||
CleanupDeadServers *bool `json:"cleanup_dead_servers,omitempty" hcl:"cleanup_dead_servers" mapstructure:"cleanup_dead_servers"`
|
CleanupDeadServers *bool `json:"cleanup_dead_servers,omitempty" hcl:"cleanup_dead_servers" mapstructure:"cleanup_dead_servers"`
|
||||||
DisableUpgradeMigration *bool `json:"disable_upgrade_migration,omitempty" hcl:"disable_upgrade_migration" mapstructure:"disable_upgrade_migration"`
|
DisableUpgradeMigration *bool `json:"disable_upgrade_migration,omitempty" hcl:"disable_upgrade_migration" mapstructure:"disable_upgrade_migration"`
|
||||||
|
|
|
@ -3884,6 +3884,20 @@ func TestFullConfig(t *testing.T) {
|
||||||
},
|
},
|
||||||
"advertise_addr": "17.99.29.16",
|
"advertise_addr": "17.99.29.16",
|
||||||
"advertise_addr_wan": "78.63.37.19",
|
"advertise_addr_wan": "78.63.37.19",
|
||||||
|
"audit": {
|
||||||
|
"enabled": true,
|
||||||
|
"sink": {
|
||||||
|
"test": {
|
||||||
|
"type": "file",
|
||||||
|
"format": "json",
|
||||||
|
"delivery_guarantee": "best-effort",
|
||||||
|
"path": "/test/path",
|
||||||
|
"rotate_bytes": 0,
|
||||||
|
"rotate_max_files": 0,
|
||||||
|
"rotate_duration": "0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"autopilot": {
|
"autopilot": {
|
||||||
"cleanup_dead_servers": true,
|
"cleanup_dead_servers": true,
|
||||||
"disable_upgrade_migration": true,
|
"disable_upgrade_migration": true,
|
||||||
|
@ -4515,6 +4529,18 @@ func TestFullConfig(t *testing.T) {
|
||||||
}
|
}
|
||||||
advertise_addr = "17.99.29.16"
|
advertise_addr = "17.99.29.16"
|
||||||
advertise_addr_wan = "78.63.37.19"
|
advertise_addr_wan = "78.63.37.19"
|
||||||
|
audit {
|
||||||
|
enabled = true
|
||||||
|
sink "test" {
|
||||||
|
type = "file"
|
||||||
|
format = "json"
|
||||||
|
delivery_guarantee = "best-effort"
|
||||||
|
path = "/test/path"
|
||||||
|
rotate_bytes = 0
|
||||||
|
rotate_max_files = 0
|
||||||
|
rotate_duration = "0"
|
||||||
|
}
|
||||||
|
}
|
||||||
autopilot = {
|
autopilot = {
|
||||||
cleanup_dead_servers = true
|
cleanup_dead_servers = true
|
||||||
disable_upgrade_migration = true
|
disable_upgrade_migration = true
|
||||||
|
@ -6158,6 +6184,9 @@ func TestSanitize(t *testing.T) {
|
||||||
"AEInterval": "0s",
|
"AEInterval": "0s",
|
||||||
"AdvertiseAddrLAN": "",
|
"AdvertiseAddrLAN": "",
|
||||||
"AdvertiseAddrWAN": "",
|
"AdvertiseAddrWAN": "",
|
||||||
|
"Audit": {
|
||||||
|
"enabled": false
|
||||||
|
},
|
||||||
"AutopilotCleanupDeadServers": false,
|
"AutopilotCleanupDeadServers": false,
|
||||||
"AutopilotDisableUpgradeMigration": false,
|
"AutopilotDisableUpgradeMigration": false,
|
||||||
"AutopilotLastContactThreshold": "0s",
|
"AutopilotLastContactThreshold": "0s",
|
||||||
|
|
|
@ -523,7 +523,7 @@ func (c *Config) CheckACL() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultConfig returns a sane default configuration.
|
// DefaultConfig returns a default configuration.
|
||||||
func DefaultConfig() *Config {
|
func DefaultConfig() *Config {
|
||||||
hostname, err := os.Hostname()
|
hostname, err := os.Hostname()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -399,6 +399,10 @@ var (
|
||||||
func (s *HTTPServer) wrap(handler endpoint, methods []string) http.HandlerFunc {
|
func (s *HTTPServer) wrap(handler endpoint, methods []string) http.HandlerFunc {
|
||||||
httpLogger := s.agent.logger.Named(logging.HTTP)
|
httpLogger := s.agent.logger.Named(logging.HTTP)
|
||||||
return func(resp http.ResponseWriter, req *http.Request) {
|
return func(resp http.ResponseWriter, req *http.Request) {
|
||||||
|
|
||||||
|
// Audit log the request
|
||||||
|
reqPayload := s.auditReq(req)
|
||||||
|
|
||||||
setHeaders(resp, s.agent.config.HTTPResponseHeaders)
|
setHeaders(resp, s.agent.config.HTTPResponseHeaders)
|
||||||
setTranslateAddr(resp, s.agent.config.TranslateWANAddrs)
|
setTranslateAddr(resp, s.agent.config.TranslateWANAddrs)
|
||||||
|
|
||||||
|
@ -476,33 +480,44 @@ func (s *HTTPServer) wrap(handler endpoint, methods []string) http.HandlerFunc {
|
||||||
"from", req.RemoteAddr,
|
"from", req.RemoteAddr,
|
||||||
"error", err,
|
"error", err,
|
||||||
)
|
)
|
||||||
|
var httpCode int
|
||||||
switch {
|
switch {
|
||||||
case isForbidden(err):
|
case isForbidden(err):
|
||||||
resp.WriteHeader(http.StatusForbidden)
|
httpCode = http.StatusForbidden
|
||||||
|
resp.WriteHeader(httpCode)
|
||||||
fmt.Fprint(resp, err.Error())
|
fmt.Fprint(resp, err.Error())
|
||||||
case structs.IsErrRPCRateExceeded(err):
|
case structs.IsErrRPCRateExceeded(err):
|
||||||
resp.WriteHeader(http.StatusTooManyRequests)
|
httpCode = http.StatusTooManyRequests
|
||||||
|
resp.WriteHeader(httpCode)
|
||||||
case isMethodNotAllowed(err):
|
case isMethodNotAllowed(err):
|
||||||
// RFC2616 states that for 405 Method Not Allowed the response
|
// RFC2616 states that for 405 Method Not Allowed the response
|
||||||
// MUST include an Allow header containing the list of valid
|
// MUST include an Allow header containing the list of valid
|
||||||
// methods for the requested resource.
|
// methods for the requested resource.
|
||||||
// https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
|
// https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
|
||||||
addAllowHeader(err.(MethodNotAllowedError).Allow)
|
addAllowHeader(err.(MethodNotAllowedError).Allow)
|
||||||
resp.WriteHeader(http.StatusMethodNotAllowed) // 405
|
httpCode = http.StatusMethodNotAllowed
|
||||||
|
resp.WriteHeader(httpCode) // 405
|
||||||
fmt.Fprint(resp, err.Error())
|
fmt.Fprint(resp, err.Error())
|
||||||
case isBadRequest(err):
|
case isBadRequest(err):
|
||||||
resp.WriteHeader(http.StatusBadRequest)
|
httpCode = http.StatusBadRequest
|
||||||
|
resp.WriteHeader(httpCode)
|
||||||
fmt.Fprint(resp, err.Error())
|
fmt.Fprint(resp, err.Error())
|
||||||
case isNotFound(err):
|
case isNotFound(err):
|
||||||
resp.WriteHeader(http.StatusNotFound)
|
httpCode = http.StatusNotFound
|
||||||
|
resp.WriteHeader(httpCode)
|
||||||
fmt.Fprintf(resp, err.Error())
|
fmt.Fprintf(resp, err.Error())
|
||||||
case isTooManyRequests(err):
|
case isTooManyRequests(err):
|
||||||
resp.WriteHeader(http.StatusTooManyRequests)
|
httpCode = http.StatusTooManyRequests
|
||||||
|
resp.WriteHeader(httpCode)
|
||||||
fmt.Fprint(resp, err.Error())
|
fmt.Fprint(resp, err.Error())
|
||||||
default:
|
default:
|
||||||
resp.WriteHeader(http.StatusInternalServerError)
|
httpCode = http.StatusInternalServerError
|
||||||
|
resp.WriteHeader(httpCode)
|
||||||
fmt.Fprint(resp, err.Error())
|
fmt.Fprint(resp, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Audit log the error response
|
||||||
|
s.auditResp(reqPayload, httpCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
@ -577,6 +592,10 @@ func (s *HTTPServer) wrap(handler endpoint, methods []string) http.HandlerFunc {
|
||||||
}
|
}
|
||||||
resp.Header().Set("Content-Type", contentType)
|
resp.Header().Set("Content-Type", contentType)
|
||||||
resp.WriteHeader(httpCode)
|
resp.WriteHeader(httpCode)
|
||||||
|
|
||||||
|
// Audit log the success response
|
||||||
|
s.auditResp(reqPayload, httpCode)
|
||||||
|
|
||||||
resp.Write(buf)
|
resp.Write(buf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -925,10 +944,7 @@ func (s *HTTPServer) parseDC(req *http.Request, dc *string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// parseTokenInternal is used to parse the ?token query param or the X-Consul-Token header or
|
// parseTokenInternal is used to parse the ?token query param or the X-Consul-Token header or
|
||||||
// Authorization Bearer token (RFC6750) and
|
// Authorization Bearer token (RFC6750).
|
||||||
// optionally resolve proxy tokens to real ACL tokens. If the token is invalid or not specified it will populate
|
|
||||||
// the token with the agents UserToken (acl_token in the consul configuration)
|
|
||||||
// Parsing has the following priority: ?token, X-Consul-Token and last "Authorization: Bearer "
|
|
||||||
func (s *HTTPServer) parseTokenInternal(req *http.Request, token *string) {
|
func (s *HTTPServer) parseTokenInternal(req *http.Request, token *string) {
|
||||||
tok := ""
|
tok := ""
|
||||||
if other := req.URL.Query().Get("token"); other != "" {
|
if other := req.URL.Query().Get("token"); other != "" {
|
||||||
|
@ -949,25 +965,33 @@ func (s *HTTPServer) parseTokenInternal(req *http.Request, token *string) {
|
||||||
|
|
||||||
// <Scheme> must be "Bearer"
|
// <Scheme> must be "Bearer"
|
||||||
if strings.ToLower(scheme) == "bearer" {
|
if strings.ToLower(scheme) == "bearer" {
|
||||||
// Since Bearer tokens shouldnt contain spaces (rfc6750#section-2.1)
|
// Since Bearer tokens shouldn't contain spaces (rfc6750#section-2.1)
|
||||||
// "value" is tokenized, only the first item is used
|
// "value" is tokenized, only the first item is used
|
||||||
tok = strings.TrimSpace(strings.Split(value, " ")[0])
|
tok = strings.TrimSpace(strings.Split(value, " ")[0])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if tok != "" {
|
*token = tok
|
||||||
*token = tok
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseTokenResolveProxy passes through to parseTokenInternal and optionally resolves proxy tokens to real ACL tokens.
|
||||||
|
// If the token is invalid or not specified it will populate the token with the agents UserToken (acl_token in the
|
||||||
|
// consul configuration)
|
||||||
|
func (s *HTTPServer) parseTokenResolveProxy(req *http.Request, token *string) {
|
||||||
|
s.parseTokenInternal(req, token) // parseTokenInternal modifies *token
|
||||||
|
if token != nil && *token == "" {
|
||||||
|
*token = s.agent.tokens.UserToken()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
return
|
||||||
*token = s.agent.tokens.UserToken()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// parseToken is used to parse the ?token query param or the X-Consul-Token header or
|
// parseToken is used to parse the ?token query param or the X-Consul-Token header or
|
||||||
// Authorization Bearer token header (RFC6750)
|
// Authorization Bearer token header (RFC6750). This function is used widely in Consul's endpoints
|
||||||
func (s *HTTPServer) parseToken(req *http.Request, token *string) {
|
func (s *HTTPServer) parseToken(req *http.Request, token *string) {
|
||||||
s.parseTokenInternal(req, token)
|
s.parseTokenResolveProxy(req, token)
|
||||||
}
|
}
|
||||||
|
|
||||||
func sourceAddrFromRequest(req *http.Request) string {
|
func sourceAddrFromRequest(req *http.Request) string {
|
||||||
|
@ -1027,7 +1051,7 @@ func (s *HTTPServer) parseMetaFilter(req *http.Request) map[string]string {
|
||||||
func (s *HTTPServer) parseInternal(resp http.ResponseWriter, req *http.Request, dc *string, b structs.QueryOptionsCompat) bool {
|
func (s *HTTPServer) parseInternal(resp http.ResponseWriter, req *http.Request, dc *string, b structs.QueryOptionsCompat) bool {
|
||||||
s.parseDC(req, dc)
|
s.parseDC(req, dc)
|
||||||
var token string
|
var token string
|
||||||
s.parseTokenInternal(req, &token)
|
s.parseTokenResolveProxy(req, &token)
|
||||||
b.SetToken(token)
|
b.SetToken(token)
|
||||||
var filter string
|
var filter string
|
||||||
s.parseFilter(req, &filter)
|
s.parseFilter(req, &filter)
|
||||||
|
|
|
@ -52,3 +52,14 @@ func parseACLAuthMethodEnterpriseMeta(req *http.Request, _ *structs.ACLAuthMetho
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// auditReq is a noop stub for the corresponding func in http_ent.go
|
||||||
|
func (s *HTTPServer) auditReq(req *http.Request) interface{} {
|
||||||
|
// note(kit): We return an nil here so we can pass it to auditResp. Auditing the response requires the
|
||||||
|
// request object for context, so we have it pass it even when it's disabled
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// auditResp is a noop stub for the corresponding func in http_ent.go
|
||||||
|
func (s *HTTPServer) auditResp(reqPayload interface{}, httpCode int) {
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue