Skip to content

Commit

Permalink
pkg/api/api0: Add rules to request context
Browse files Browse the repository at this point in the history
  • Loading branch information
pg9182 committed Sep 14, 2023
1 parent ba1e9c2 commit b69123b
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 0 deletions.
43 changes: 43 additions & 0 deletions pkg/api/api0/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ package api0

import (
"bytes"
"context"
"crypto/rand"
"encoding/hex"
"encoding/json"
Expand All @@ -30,6 +31,7 @@ import (
"github.com/r2northstar/atlas/pkg/eax"
"github.com/r2northstar/atlas/pkg/metricsx"
"github.com/r2northstar/atlas/pkg/nspkt"
"github.com/r2northstar/atlas/pkg/nsrule"
"github.com/r2northstar/atlas/pkg/origin"
"github.com/rs/zerolog/hlog"
"golang.org/x/mod/semver"
Expand Down Expand Up @@ -110,6 +112,9 @@ type Handler struct {
// empty region and no error if no region is to be assigned.
GetRegion func(netip.Addr, ip2x.Record) (string, error)

// Rules provides a ruleset to apply.
Rules *nsrule.RuleSet

metricsInit sync.Once
metricsObj apiMetrics

Expand All @@ -127,6 +132,14 @@ type connectState struct {
gotPdata atomic.Bool
}

type rulesContextKey struct{}

type rulesContextValue struct {
e nsrule.Env
s *nsrule.RuleSet
t nsrule.Tags
}

// ServeHTTP routes requests to Handler.
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
var notPanicked bool // this lets us catch panics without swallowing them
Expand All @@ -136,6 +149,15 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}
}()

if h.Rules != nil {
r = r.WithContext(context.WithValue(r.Context(), rulesContextKey{}, &rulesContextValue{
e: nsrule.NewEnv(),
s: h.Rules,
t: make(nsrule.Tags),
}))
h.EvalRules(r, nil)
}

w.Header().Set("Server", "Atlas")

switch r.URL.Path {
Expand Down Expand Up @@ -174,6 +196,27 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
notPanicked = true
}

func (h *Handler) EvalRules(r *http.Request, update func(e nsrule.Env)) {
if v := r.Context().Value(rulesContextKey{}); v != nil {
t := time.Now()
v := v.(*rulesContextValue)
if update != nil {
update(v.e)
}
for _, err := range v.s.Evaluate(v.e, v.t) {
hlog.FromRequest(r).Warn().Err(err).Msg("failed to evaluate rule")
}
h.m().rule_evaluation_time_seconds.UpdateDuration(t)
}
}

func (h *Handler) Tags(r *http.Request) nsrule.Tags {
if v := r.Context().Value(rulesContextKey{}); v != nil {
return v.(*rulesContextValue).t
}
return nsrule.Tags{}
}

// CheckLauncherVersion checks if the r was made by NorthstarLauncher and if it
// is at least MinimumLauncherVersion.
func (h *Handler) CheckLauncherVersion(r *http.Request, client bool) bool {
Expand Down
2 changes: 2 additions & 0 deletions pkg/api/api0/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ type apiMetrics struct {
fail_other_error *metrics.Counter
http_method_not_allowed *metrics.Counter
}
rule_evaluation_time_seconds *metrics.Histogram
}

func (h *Handler) Metrics() *metrics.Set {
Expand Down Expand Up @@ -474,6 +475,7 @@ func (h *Handler) m() *apiMetrics {
mo.player_pdata_requests_total.fail_pdata_invalid = mo.set.NewCounter(`atlas_api0_player_pdata_requests_total{result="fail_pdata_invalid"}`)
mo.player_pdata_requests_total.fail_other_error = mo.set.NewCounter(`atlas_api0_player_pdata_requests_total{result="fail_other_error"}`)
mo.player_pdata_requests_total.http_method_not_allowed = mo.set.NewCounter(`atlas_api0_player_pdata_requests_total{result="http_method_not_allowed"}`)
mo.rule_evaluation_time_seconds = mo.set.NewHistogram(`atlas_api0_rule_evaluation_time_seconds`)
})

// ensure we initialized everything
Expand Down

0 comments on commit b69123b

Please sign in to comment.