diff --git a/api/credential_test.go b/api/credential_test.go index 0b0edffa36..01764f1253 100644 --- a/api/credential_test.go +++ b/api/credential_test.go @@ -25,7 +25,11 @@ import ( func TestCredentialsHandler(t *testing.T) { conf := internal.NewConfigurationWithDefaults(configx.SkipValidation()) + conf.SetForTest(t, configuration.MutatorIDTokenIsEnabled, true) conf.SetForTest(t, configuration.MutatorIDTokenJWKSURL, "file://../test/stub/jwks-rsa-multiple.json") + conf.SetForTest(t, configuration.MutatorIDTokenIssuerURL, "https://example.com") + conf.SetForTest(t, configuration.AuthenticatorAnonymousIsEnabled, true) + conf.SetForTest(t, configuration.AuthorizerAllowIsEnabled, true) r := internal.NewRegistry(conf) @@ -57,9 +61,9 @@ func TestCredentialsHandler(t *testing.T) { var j jose.JSONWebKeySet require.NoError(t, json.NewDecoder(res.Body).Decode(&j)) - assert.Len(t, j.Key("3e0edde4-12ad-425d-a783-135f46eac57e"), 1, "The public key should be broadcasted") - assert.Len(t, j.Key("81be3441-5303-4c52-b00d-bbdfadc75633"), 1, "The public key should be broadcasted") - assert.Len(t, j.Key("f4190122-ae96-4c29-8b79-56024e459d80"), 1, "The public key generated from the private key should be broadcasted") + require.Len(t, j.Key("3e0edde4-12ad-425d-a783-135f46eac57e"), 1, "The public key should be broadcasted") + require.Len(t, j.Key("81be3441-5303-4c52-b00d-bbdfadc75633"), 1, "The public key should be broadcasted") + require.Len(t, j.Key("f4190122-ae96-4c29-8b79-56024e459d80"), 1, "The public key generated from the private key should be broadcasted") assert.IsType(t, new(rsa.PublicKey), j.Key("3e0edde4-12ad-425d-a783-135f46eac57e")[0].Key, "Ensure a public key") assert.IsType(t, new(rsa.PublicKey), j.Key("f4190122-ae96-4c29-8b79-56024e459d80")[0].Key, "Ensure a public key") assert.IsType(t, new(rsa.PublicKey), j.Key("81be3441-5303-4c52-b00d-bbdfadc75633")[0].Key, "Ensure a public key") diff --git a/api/health_test.go b/api/health_test.go index 70d6ce9ba5..2b8ae5f1ae 100644 --- a/api/health_test.go +++ b/api/health_test.go @@ -10,11 +10,13 @@ import ( "testing" "time" + "github.com/ory/herodot" + "github.com/ory/oathkeeper/driver/configuration" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/ory/oathkeeper/internal" - rulereadiness "github.com/ory/oathkeeper/rule/readiness" "github.com/ory/oathkeeper/x" ) @@ -33,6 +35,17 @@ type statusError struct { func TestHealth(t *testing.T) { conf := internal.NewConfigurationWithDefaults() + conf.SetForTest(t, configuration.AccessRuleRepositories, []string{"file://../test/stub/rules.json"}) + conf.SetForTest(t, configuration.AuthorizerAllowIsEnabled, true) + conf.SetForTest(t, configuration.AuthorizerDenyIsEnabled, true) + conf.SetForTest(t, configuration.AuthenticatorNoopIsEnabled, true) + conf.SetForTest(t, configuration.AuthenticatorAnonymousIsEnabled, true) + conf.SetForTest(t, configuration.MutatorNoopIsEnabled, true) + conf.SetForTest(t, "mutators.header.config", map[string]interface{}{"headers": map[string]interface{}{}}) + conf.SetForTest(t, configuration.MutatorHeaderIsEnabled, true) + conf.SetForTest(t, configuration.MutatorIDTokenJWKSURL, "https://stub/.well-known/jwks.json") + conf.SetForTest(t, configuration.MutatorIDTokenIssuerURL, "https://stub") + conf.SetForTest(t, configuration.MutatorIDTokenIsEnabled, true) r := internal.NewRegistry(conf) router := x.NewAPIRouter() @@ -58,7 +71,7 @@ func TestHealth(t *testing.T) { require.Equal(t, http.StatusServiceUnavailable, res.StatusCode) require.NoError(t, json.NewDecoder(res.Body).Decode(&result)) assert.Empty(t, result.Status) - assert.Equal(t, rulereadiness.ErrRuleNotYetLoaded.Error(), result.Error.Message) + assert.Equal(t, herodot.ErrNotFound.ErrorField, result.Error.Message) r.Init() // Waiting for rule load and health event propagation diff --git a/cmd/health_alive.go b/cmd/health_alive.go index 8ad045140f..77c38906ad 100644 --- a/cmd/health_alive.go +++ b/cmd/health_alive.go @@ -7,9 +7,9 @@ import ( "fmt" "os" - "github.com/spf13/cobra" + "github.com/ory/oathkeeper/internal/httpclient/client/health" - "github.com/ory/oathkeeper/internal/httpclient/client/api" + "github.com/spf13/cobra" "github.com/ory/x/cmdx" ) @@ -28,7 +28,7 @@ Note: Run: func(cmd *cobra.Command, _ []string) { client := newClient(cmd) - r, err := client.API.IsInstanceAlive(api.NewIsInstanceAliveParams()) + r, err := client.Health.IsInstanceAlive(health.NewIsInstanceAliveParams()) // If err, print err and exit 1 cmdx.Must(err, "%s", err) // Print payload diff --git a/cmd/health_ready.go b/cmd/health_ready.go index 95e6c01a04..5d96e1dbe0 100644 --- a/cmd/health_ready.go +++ b/cmd/health_ready.go @@ -7,9 +7,10 @@ import ( "fmt" "os" + "github.com/ory/oathkeeper/internal/httpclient/client/health" + "github.com/spf13/cobra" - "github.com/ory/oathkeeper/internal/httpclient/client/api" "github.com/ory/x/cmdx" ) @@ -27,7 +28,7 @@ Note: Run: func(cmd *cobra.Command, args []string) { client := newClient(cmd) - r, err := client.API.IsInstanceReady(api.NewIsInstanceReadyParams()) + r, err := client.Health.IsInstanceReady(health.NewIsInstanceReadyParams()) // If err, print err and exit 1 cmdx.Must(err, "%s", err) // Print payload diff --git a/cmd/root.go b/cmd/root.go index fe36db93f0..b354b68842 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -6,10 +6,12 @@ package cmd import ( "fmt" "os" - "runtime" + "github.com/pkg/errors" "github.com/spf13/cobra" + "github.com/ory/x/cmdx" + _ "github.com/ory/jsonschema/v3/fileloader" _ "github.com/ory/jsonschema/v3/httploader" "github.com/ory/x/configx" @@ -25,7 +27,9 @@ var RootCmd = &cobra.Command{ // This is called by main.main(). It only needs to happen once to the rootCmd. func Execute() { if err := RootCmd.Execute(); err != nil { - fmt.Println(err) + if !errors.Is(err, cmdx.ErrNoPrintButFail) { + fmt.Println(err) + } os.Exit(-1) } } @@ -33,14 +37,3 @@ func Execute() { func init() { configx.RegisterFlags(RootCmd.PersistentFlags()) } - -func userHomeDir() string { - if runtime.GOOS == "windows" { - home := os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH") - if home == "" { - home = os.Getenv("USERPROFILE") - } - return home - } - return os.Getenv("HOME") -} diff --git a/cmd/root_test.go b/cmd/root_test.go index 123c43040d..ee2b765408 100644 --- a/cmd/root_test.go +++ b/cmd/root_test.go @@ -4,15 +4,18 @@ package cmd import ( + "encoding/base64" "fmt" "net/http" "os" "testing" "time" - "github.com/phayes/freeport" + "github.com/spf13/cobra" + + "github.com/ory/x/cmdx" - "github.com/stretchr/testify/assert" + "github.com/phayes/freeport" ) var apiPort, proxyPort int @@ -48,7 +51,39 @@ func init() { os.Setenv("AUTHENTICATORS_ANONYMOUS_ENABLED", "true") os.Setenv("AUTHORIZERS_ALLOW_ENABLED", "true") os.Setenv("MUTATORS_NOOP_ENABLED", "true") - os.Setenv("ACCESS_RULES_REPOSITORIES", "inline://W3siaWQiOiJ0ZXN0LXJ1bGUtNCIsInVwc3RyZWFtIjp7InByZXNlcnZlX2hvc3QiOnRydWUsInN0cmlwX3BhdGgiOiIvYXBpIiwidXJsIjoibXliYWNrZW5kLmNvbS9hcGkifSwibWF0Y2giOnsidXJsIjoibXlwcm94eS5jb20vYXBpIiwibWV0aG9kcyI6WyJHRVQiLCJQT1NUIl19LCJhdXRoZW50aWNhdG9ycyI6W3siaGFuZGxlciI6Im5vb3AifSx7ImhhbmRsZXIiOiJhbm9ueW1vdXMifV0sImF1dGhvcml6ZXIiOnsiaGFuZGxlciI6ImFsbG93In0sIm11dGF0b3JzIjpbeyJoYW5kbGVyIjoibm9vcCJ9XX1d") + os.Setenv("ACCESS_RULES_REPOSITORIES", "inline://"+base64.StdEncoding.EncodeToString([]byte(`[ + { + "id": "test-rule-4", + "upstream": { + "preserve_host": true, + "strip_path": "/api", + "url": "https://mybackend.com/api" + }, + "match": { + "url": "myproxy.com/api", + "methods": [ + "GET", + "POST" + ] + }, + "authenticators": [ + { + "handler": "noop" + }, + { + "handler": "anonymous" + } + ], + "authorizer": { + "handler": "allow" + }, + "mutators": [ + { + "handler": "noop" + } + ] + } +]`))) } func ensureOpen(t *testing.T, port int) bool { @@ -64,18 +99,28 @@ func ensureOpen(t *testing.T, port int) bool { func TestCommandLineInterface(t *testing.T) { var osArgs = make([]string, len(os.Args)) copy(osArgs, os.Args) + cmd := cmdx.CommandExecuter{ + New: func() *cobra.Command { + cp := *RootCmd + return &cp + }, + } + + // start server, and wait for the ports to be open + cmd.ExecBackground(nil, os.Stdout, os.Stderr, "serve", "--disable-telemetry") + var count = 0 + for ensureOpen(t, apiPort) && ensureOpen(t, proxyPort) { + t.Logf("Port is not yet open, retrying attempt #%d..", count) + count++ + if count > 50 { + t.FailNow() + } + time.Sleep(100 * time.Millisecond) + } for _, c := range []struct { - args []string - wait func() bool - expectErr bool + args []string }{ - { - args: []string{"serve", "--disable-telemetry"}, - wait: func() bool { - return ensureOpen(t, apiPort) && ensureOpen(t, proxyPort) - }, - }, {args: []string{"rules", fmt.Sprintf("--endpoint=http://127.0.0.1:%d/", apiPort), "list"}}, {args: []string{"rules", fmt.Sprintf("--endpoint=http://127.0.0.1:%d/", apiPort), "get", "test-rule-4"}}, {args: []string{"health", fmt.Sprintf("--endpoint=http://127.0.0.1:%d/", apiPort), "alive"}}, @@ -85,33 +130,8 @@ func TestCommandLineInterface(t *testing.T) { {args: []string{"credentials", "generate", "--alg", "HS256"}}, {args: []string{"credentials", "generate", "--alg", "RS512"}}, } { - RootCmd.SetArgs(c.args) - t.Run(fmt.Sprintf("command=%v", c.args), func(t *testing.T) { - if c.wait != nil { - go func() { - assert.Nil(t, RootCmd.Execute()) - }() - } - - if c.wait != nil { - var count = 0 - for c.wait() { - t.Logf("Port is not yet open, retrying attempt #%d..", count) - count++ - if count > 5 { - t.FailNow() - } - time.Sleep(time.Second) - } - } else { - err := RootCmd.Execute() - if c.expectErr { - assert.Error(t, err) - } else { - assert.NoError(t, err) - } - } + cmd.ExecNoErr(t, c.args...) }) } } diff --git a/cmd/rules_get.go b/cmd/rules_get.go index 796b7e4675..e8c708f964 100644 --- a/cmd/rules_get.go +++ b/cmd/rules_get.go @@ -20,13 +20,17 @@ var getCmd = &cobra.Command{ oathkeeper rules --endpoint=http://localhost:4456/ get rule-1 `, - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { cmdx.ExactArgs(cmd, args, 1) client := newClient(cmd) r, err := client.API.GetRule(api.NewGetRuleParams().WithID(args[0])) - cmdx.Must(err, "%s", err) + if err != nil { + fmt.Fprintf(cmd.ErrOrStderr(), "Could not get rule: %s", err) + return cmdx.FailSilently(cmd) + } fmt.Println(cmdx.FormatResponse(r.Payload)) + return nil }, } diff --git a/driver/configuration/config_keys.go b/driver/configuration/config_keys.go index 456480b9b3..6fac519d5c 100644 --- a/driver/configuration/config_keys.go +++ b/driver/configuration/config_keys.go @@ -43,6 +43,7 @@ const ( MutatorHydratorIsEnabled Key = "mutators.hydrator.enabled" MutatorIDTokenIsEnabled Key = "mutators.id_token.enabled" MutatorIDTokenJWKSURL Key = "mutators.id_token.config.jwks_url" + MutatorIDTokenIssuerURL Key = "mutators.id_token.config.issuer_url" ) // Authenticators diff --git a/driver/health/event_manager.go b/driver/health/event_manager.go deleted file mode 100644 index 5eaf2f8ab7..0000000000 --- a/driver/health/event_manager.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright © 2023 Ory Corp -// SPDX-License-Identifier: Apache-2.0 - -package health - -import ( - "context" - - "github.com/pkg/errors" - - "github.com/ory/x/healthx" -) - -type EventManager interface { - Dispatch(event ReadinessProbeEvent) - Watch(ctx context.Context) - HealthxReadyCheckers() healthx.ReadyCheckers -} - -var ErrEventTypeAlreadyRegistered = errors.New("event type already registered") diff --git a/driver/health/event_manager_default.go b/driver/health/event_manager_default.go deleted file mode 100644 index d4162ac9ed..0000000000 --- a/driver/health/event_manager_default.go +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright © 2023 Ory Corp -// SPDX-License-Identifier: Apache-2.0 - -package health - -import ( - "context" - "net/http" - - "github.com/pkg/errors" - - "github.com/ory/x/healthx" -) - -type DefaultHealthEventManager struct { - evtChan chan ReadinessProbeEvent - listeners []ReadinessProbe - listenerEventTypeCache map[string]ReadinessProbe -} - -func NewDefaultHealthEventManager(listeners ...ReadinessProbe) (*DefaultHealthEventManager, error) { - var listenerEventTypeCache = make(map[string]ReadinessProbe) - for _, listener := range listeners { - for _, events := range listener.EventTypes() { - if _, ok := listenerEventTypeCache[events.ReadinessProbeListenerID()]; ok { - return nil, errors.WithStack(ErrEventTypeAlreadyRegistered) - } - listenerEventTypeCache[events.ReadinessProbeListenerID()] = listener - } - } - return &DefaultHealthEventManager{ - evtChan: make(chan ReadinessProbeEvent), - listeners: listeners, - listenerEventTypeCache: listenerEventTypeCache, - }, nil -} - -func (h *DefaultHealthEventManager) Dispatch(event ReadinessProbeEvent) { - if event == nil { - return - } - go func() { - h.evtChan <- event - }() -} - -func (h *DefaultHealthEventManager) Watch(ctx context.Context) { - go func() { - for { - select { - case <-ctx.Done(): - return - case evt, ok := <-h.evtChan: - if !ok { - return - } - if listener, ok := h.listenerEventTypeCache[evt.ReadinessProbeListenerID()]; ok { - listener.EventsReceiver(evt) - } - } - } - }() -} - -func (h *DefaultHealthEventManager) HealthxReadyCheckers() healthx.ReadyCheckers { - var checkers = make(healthx.ReadyCheckers) - for _, listener := range h.listeners { - checkers[listener.ID()] = func(_ *http.Request) error { return listener.Validate() } - } - return checkers -} diff --git a/driver/health/event_manager_default_test.go b/driver/health/event_manager_default_test.go deleted file mode 100644 index 84db3d50aa..0000000000 --- a/driver/health/event_manager_default_test.go +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright © 2023 Ory Corp -// SPDX-License-Identifier: Apache-2.0 - -package health - -import ( - "context" - "testing" - "time" - - "github.com/stretchr/testify/require" -) - -const mockReadinessProbeName = "mock-readiness-probe" - -type ( - mockReadinessProbe struct { - hasReceivedEvent bool - testData string - } - mockReadinessEvent struct { - testData string - } -) - -func (m *mockReadinessProbe) ID() string { - return mockReadinessProbeName -} - -func (m *mockReadinessProbe) Validate() error { - return nil -} - -func (m *mockReadinessProbe) EventTypes() []ReadinessProbeEvent { - return []ReadinessProbeEvent{&mockReadinessEvent{}} -} - -func (m *mockReadinessProbe) EventsReceiver(evt ReadinessProbeEvent) { - switch castedEvent := evt.(type) { - case *mockReadinessEvent: - m.hasReceivedEvent = true - m.testData = castedEvent.testData - } -} - -func (m *mockReadinessEvent) ReadinessProbeListenerID() string { - return mockReadinessProbeName -} - -func TestNewDefaultHealthEventManager(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - t.Run("health event manager", func(t *testing.T) { - readinessProbe := &mockReadinessProbe{} - - // Create a new default health event manager with twice same probe - _, err := NewDefaultHealthEventManager(readinessProbe, readinessProbe) - require.Error(t, err) - - // Create a new default health event manager - hem, err := NewDefaultHealthEventManager(readinessProbe) - require.NoError(t, err) - - // Test healthx ready checkers generation - checkers := hem.HealthxReadyCheckers() - require.Len(t, checkers, 1) - _, ok := checkers[readinessProbe.ID()] - require.True(t, ok, "health checker was not found") - - // Readiness probe must be empty before event dispatch - require.False(t, readinessProbe.hasReceivedEvent) - require.Equal(t, readinessProbe.testData, "") - - // Nil events should be ignored - hem.Dispatch(nil) - require.False(t, readinessProbe.hasReceivedEvent) - - // Dispatch event without watching (should not block) - const testData = "a sample string that will be passed along the event" - hem.Dispatch(&mockReadinessEvent{ - testData: testData, - }) - - // Watching for incoming events - hem.Watch(ctx) - - // Waiting for watcher to be ready, then verify the event has been received - time.Sleep(100 * time.Millisecond) - require.True(t, readinessProbe.hasReceivedEvent) - require.Equal(t, readinessProbe.testData, testData) - - // Reset probe - readinessProbe.hasReceivedEvent = false - readinessProbe.testData = "" - - // Dispatch a new event - hem.Dispatch(&mockReadinessEvent{ - testData: testData, - }) - - // Wait for event propagation, then verify the event has been received - time.Sleep(100 * time.Millisecond) - require.True(t, readinessProbe.hasReceivedEvent) - require.Equal(t, readinessProbe.testData, testData) - cancel() - }) -} diff --git a/driver/health/readiness.go b/driver/health/readiness.go deleted file mode 100644 index a00e9edae8..0000000000 --- a/driver/health/readiness.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright © 2023 Ory Corp -// SPDX-License-Identifier: Apache-2.0 - -package health - -type ( - ReadinessProbe interface { - ID() string - Validate() error - - EventTypes() []ReadinessProbeEvent - EventsReceiver(event ReadinessProbeEvent) - } - - ReadinessProbeEvent interface { - ReadinessProbeListenerID() string - } -) diff --git a/driver/registry.go b/driver/registry.go index f805918a50..1759692d31 100644 --- a/driver/registry.go +++ b/driver/registry.go @@ -10,7 +10,6 @@ import ( "github.com/ory/x/healthx" - "github.com/ory/oathkeeper/driver/health" "github.com/ory/oathkeeper/pipeline/errors" "github.com/ory/oathkeeper/proxy" @@ -35,7 +34,7 @@ type Registry interface { BuildHash() string ProxyRequestHandler() proxy.RequestHandler - HealthEventManager() health.EventManager + HealthxReadyCheckers() healthx.ReadyCheckers HealthHandler() *healthx.Handler RuleHandler() *api.RuleHandler DecisionHandler() *api.DecisionHandler diff --git a/driver/registry_memory.go b/driver/registry_memory.go index d159a9f641..af83338707 100644 --- a/driver/registry_memory.go +++ b/driver/registry_memory.go @@ -9,7 +9,6 @@ import ( "go.opentelemetry.io/otel/trace" - "github.com/ory/oathkeeper/driver/health" "github.com/ory/oathkeeper/pipeline" pe "github.com/ory/oathkeeper/pipeline/errors" "github.com/ory/oathkeeper/proxy" @@ -30,7 +29,6 @@ import ( "github.com/ory/oathkeeper/pipeline/authz" "github.com/ory/oathkeeper/pipeline/mutate" "github.com/ory/oathkeeper/rule" - rulereadiness "github.com/ory/oathkeeper/rule/readiness" ) var _ Registry = new(RegistryMemory) @@ -65,8 +63,6 @@ type RegistryMemory struct { authorizers map[string]authz.Authorizer mutators map[string]mutate.Mutator errors map[string]pe.Handler - - healthEventManager *health.DefaultHealthEventManager } func (r *RegistryMemory) Init() { @@ -75,7 +71,6 @@ func (r *RegistryMemory) Init() { r.Logger().WithError(err).Fatal("Access rule watcher terminated with an error.") } }() - r.HealthEventManager().Watch(context.Background()) _ = r.RuleRepository() _ = r.Tracer() // make sure tracer is initialized } @@ -145,15 +140,10 @@ func (r *RegistryMemory) CredentialHandler() *api.CredentialsHandler { return r.ch } -func (r *RegistryMemory) HealthEventManager() health.EventManager { - if r.healthEventManager == nil { - var err error - rulesReadinessChecker := rulereadiness.NewReadinessHealthChecker() - if r.healthEventManager, err = health.NewDefaultHealthEventManager(rulesReadinessChecker); err != nil { - r.logger.WithError(err).Fatal("unable to instantiate new health event manager") - } +func (r *RegistryMemory) HealthxReadyCheckers() healthx.ReadyCheckers { + return healthx.ReadyCheckers{ + "rules_loaded": r.RuleRepository().ReadyChecker, } - return r.healthEventManager } func (r *RegistryMemory) HealthHandler() *healthx.Handler { @@ -161,7 +151,7 @@ func (r *RegistryMemory) HealthHandler() *healthx.Handler { defer r.RUnlock() if r.healthxHandler == nil { - r.healthxHandler = healthx.NewHandler(r.Writer(), r.BuildVersion(), r.HealthEventManager().HealthxReadyCheckers()) + r.healthxHandler = healthx.NewHandler(r.Writer(), r.BuildVersion(), r.HealthxReadyCheckers()) } return r.healthxHandler } @@ -175,7 +165,7 @@ func (r *RegistryMemory) RuleValidator() rule.Validator { func (r *RegistryMemory) RuleRepository() rule.Repository { if r.ruleRepository == nil { - r.ruleRepository = rule.NewRepositoryMemory(r, r.HealthEventManager()) + r.ruleRepository = rule.NewRepositoryMemory(r) } return r.ruleRepository } diff --git a/internal/httpclient/client/api/api_client.go b/internal/httpclient/client/api/api_client.go index 52ebb22ffe..71d4c936c8 100644 --- a/internal/httpclient/client/api/api_client.go +++ b/internal/httpclient/client/api/api_client.go @@ -34,14 +34,8 @@ type ClientService interface { GetRule(params *GetRuleParams, opts ...ClientOption) (*GetRuleOK, error) - GetVersion(params *GetVersionParams, opts ...ClientOption) (*GetVersionOK, error) - GetWellKnownJSONWebKeys(params *GetWellKnownJSONWebKeysParams, opts ...ClientOption) (*GetWellKnownJSONWebKeysOK, error) - IsInstanceAlive(params *IsInstanceAliveParams, opts ...ClientOption) (*IsInstanceAliveOK, error) - - IsInstanceReady(params *IsInstanceReadyParams, opts ...ClientOption) (*IsInstanceReadyOK, error) - ListRules(params *ListRulesParams, opts ...ClientOption) (*ListRulesOK, error) SetTransport(transport runtime.ClientTransport) @@ -131,52 +125,6 @@ func (a *Client) GetRule(params *GetRuleParams, opts ...ClientOption) (*GetRuleO panic(msg) } -/* - GetVersion gets service version - - This endpoint returns the service version typically notated using semantic versioning. - -If the service supports TLS Edge Termination, this endpoint does not require the -`X-Forwarded-Proto` header to be set. - -Be aware that if you are running multiple nodes of this service, the health status will never -refer to the cluster state, only to a single instance. -*/ -func (a *Client) GetVersion(params *GetVersionParams, opts ...ClientOption) (*GetVersionOK, error) { - // TODO: Validate the params before sending - if params == nil { - params = NewGetVersionParams() - } - op := &runtime.ClientOperation{ - ID: "getVersion", - Method: "GET", - PathPattern: "/version", - ProducesMediaTypes: []string{"application/json"}, - ConsumesMediaTypes: []string{"application/json"}, - Schemes: []string{"http", "https"}, - Params: params, - Reader: &GetVersionReader{formats: a.formats}, - Context: params.Context, - Client: params.HTTPClient, - } - for _, opt := range opts { - opt(op) - } - - result, err := a.transport.Submit(op) - if err != nil { - return nil, err - } - success, ok := result.(*GetVersionOK) - if ok { - return success, nil - } - // unexpected success response - // safeguard: normally, absent a default response, unknown success responses return an error above: so this is a codegen issue - msg := fmt.Sprintf("unexpected success response for getVersion: API contract not enforced by server. Client expected to get an error, but got: %T", result) - panic(msg) -} - /* GetWellKnownJSONWebKeys lists cryptographic keys @@ -217,102 +165,6 @@ func (a *Client) GetWellKnownJSONWebKeys(params *GetWellKnownJSONWebKeysParams, panic(msg) } -/* - IsInstanceAlive checks alive status - - This endpoint returns a 200 status code when the HTTP server is up running. - -This status does currently not include checks whether the database connection is working. - -If the service supports TLS Edge Termination, this endpoint does not require the -`X-Forwarded-Proto` header to be set. - -Be aware that if you are running multiple nodes of this service, the health status will never -refer to the cluster state, only to a single instance. -*/ -func (a *Client) IsInstanceAlive(params *IsInstanceAliveParams, opts ...ClientOption) (*IsInstanceAliveOK, error) { - // TODO: Validate the params before sending - if params == nil { - params = NewIsInstanceAliveParams() - } - op := &runtime.ClientOperation{ - ID: "isInstanceAlive", - Method: "GET", - PathPattern: "/health/alive", - ProducesMediaTypes: []string{"application/json"}, - ConsumesMediaTypes: []string{"application/json"}, - Schemes: []string{"http", "https"}, - Params: params, - Reader: &IsInstanceAliveReader{formats: a.formats}, - Context: params.Context, - Client: params.HTTPClient, - } - for _, opt := range opts { - opt(op) - } - - result, err := a.transport.Submit(op) - if err != nil { - return nil, err - } - success, ok := result.(*IsInstanceAliveOK) - if ok { - return success, nil - } - // unexpected success response - // safeguard: normally, absent a default response, unknown success responses return an error above: so this is a codegen issue - msg := fmt.Sprintf("unexpected success response for isInstanceAlive: API contract not enforced by server. Client expected to get an error, but got: %T", result) - panic(msg) -} - -/* - IsInstanceReady checks readiness status - - This endpoint returns a 200 status code when the HTTP server is up running and the environment dependencies (e.g. - -the database) are responsive as well. - -If the service supports TLS Edge Termination, this endpoint does not require the -`X-Forwarded-Proto` header to be set. - -Be aware that if you are running multiple nodes of this service, the health status will never -refer to the cluster state, only to a single instance. -*/ -func (a *Client) IsInstanceReady(params *IsInstanceReadyParams, opts ...ClientOption) (*IsInstanceReadyOK, error) { - // TODO: Validate the params before sending - if params == nil { - params = NewIsInstanceReadyParams() - } - op := &runtime.ClientOperation{ - ID: "isInstanceReady", - Method: "GET", - PathPattern: "/health/ready", - ProducesMediaTypes: []string{"application/json"}, - ConsumesMediaTypes: []string{"application/json"}, - Schemes: []string{"http", "https"}, - Params: params, - Reader: &IsInstanceReadyReader{formats: a.formats}, - Context: params.Context, - Client: params.HTTPClient, - } - for _, opt := range opts { - opt(op) - } - - result, err := a.transport.Submit(op) - if err != nil { - return nil, err - } - success, ok := result.(*IsInstanceReadyOK) - if ok { - return success, nil - } - // unexpected success response - // safeguard: normally, absent a default response, unknown success responses return an error above: so this is a codegen issue - msg := fmt.Sprintf("unexpected success response for isInstanceReady: API contract not enforced by server. Client expected to get an error, but got: %T", result) - panic(msg) -} - /* ListRules lists all rules diff --git a/internal/httpclient/client/health/health_client.go b/internal/httpclient/client/health/health_client.go new file mode 100644 index 0000000000..5e3a22b545 --- /dev/null +++ b/internal/httpclient/client/health/health_client.go @@ -0,0 +1,139 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package health + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "fmt" + + "github.com/go-openapi/runtime" + "github.com/go-openapi/strfmt" +) + +// New creates a new health API client. +func New(transport runtime.ClientTransport, formats strfmt.Registry) ClientService { + return &Client{transport: transport, formats: formats} +} + +/* +Client for health API +*/ +type Client struct { + transport runtime.ClientTransport + formats strfmt.Registry +} + +// ClientOption is the option for Client methods +type ClientOption func(*runtime.ClientOperation) + +// ClientService is the interface for Client methods +type ClientService interface { + IsInstanceAlive(params *IsInstanceAliveParams, opts ...ClientOption) (*IsInstanceAliveOK, error) + + IsInstanceReady(params *IsInstanceReadyParams, opts ...ClientOption) (*IsInstanceReadyOK, error) + + SetTransport(transport runtime.ClientTransport) +} + +/* + IsInstanceAlive checks alive status + + This endpoint returns a 200 status code when the HTTP server is up running. + +This status does currently not include checks whether the database connection is working. + +If the service supports TLS Edge Termination, this endpoint does not require the +`X-Forwarded-Proto` header to be set. + +Be aware that if you are running multiple nodes of this service, the health status will never +refer to the cluster state, only to a single instance. +*/ +func (a *Client) IsInstanceAlive(params *IsInstanceAliveParams, opts ...ClientOption) (*IsInstanceAliveOK, error) { + // TODO: Validate the params before sending + if params == nil { + params = NewIsInstanceAliveParams() + } + op := &runtime.ClientOperation{ + ID: "isInstanceAlive", + Method: "GET", + PathPattern: "/health/alive", + ProducesMediaTypes: []string{"application/json"}, + ConsumesMediaTypes: []string{"application/json"}, + Schemes: []string{"http", "https"}, + Params: params, + Reader: &IsInstanceAliveReader{formats: a.formats}, + Context: params.Context, + Client: params.HTTPClient, + } + for _, opt := range opts { + opt(op) + } + + result, err := a.transport.Submit(op) + if err != nil { + return nil, err + } + success, ok := result.(*IsInstanceAliveOK) + if ok { + return success, nil + } + // unexpected success response + // safeguard: normally, absent a default response, unknown success responses return an error above: so this is a codegen issue + msg := fmt.Sprintf("unexpected success response for isInstanceAlive: API contract not enforced by server. Client expected to get an error, but got: %T", result) + panic(msg) +} + +/* + IsInstanceReady checks readiness status + + This endpoint returns a 200 status code when the HTTP server is up running and the environment dependencies (e.g. + +the database) are responsive as well. + +If the service supports TLS Edge Termination, this endpoint does not require the +`X-Forwarded-Proto` header to be set. + +Be aware that if you are running multiple nodes of this service, the health status will never +refer to the cluster state, only to a single instance. +*/ +func (a *Client) IsInstanceReady(params *IsInstanceReadyParams, opts ...ClientOption) (*IsInstanceReadyOK, error) { + // TODO: Validate the params before sending + if params == nil { + params = NewIsInstanceReadyParams() + } + op := &runtime.ClientOperation{ + ID: "isInstanceReady", + Method: "GET", + PathPattern: "/health/ready", + ProducesMediaTypes: []string{"application/json"}, + ConsumesMediaTypes: []string{"application/json"}, + Schemes: []string{"http", "https"}, + Params: params, + Reader: &IsInstanceReadyReader{formats: a.formats}, + Context: params.Context, + Client: params.HTTPClient, + } + for _, opt := range opts { + opt(op) + } + + result, err := a.transport.Submit(op) + if err != nil { + return nil, err + } + success, ok := result.(*IsInstanceReadyOK) + if ok { + return success, nil + } + // unexpected success response + // safeguard: normally, absent a default response, unknown success responses return an error above: so this is a codegen issue + msg := fmt.Sprintf("unexpected success response for isInstanceReady: API contract not enforced by server. Client expected to get an error, but got: %T", result) + panic(msg) +} + +// SetTransport changes the transport on the client +func (a *Client) SetTransport(transport runtime.ClientTransport) { + a.transport = transport +} diff --git a/internal/httpclient/client/api/is_instance_alive_parameters.go b/internal/httpclient/client/health/is_instance_alive_parameters.go similarity index 99% rename from internal/httpclient/client/api/is_instance_alive_parameters.go rename to internal/httpclient/client/health/is_instance_alive_parameters.go index 0718f0f274..17e0369579 100644 --- a/internal/httpclient/client/api/is_instance_alive_parameters.go +++ b/internal/httpclient/client/health/is_instance_alive_parameters.go @@ -1,6 +1,6 @@ // Code generated by go-swagger; DO NOT EDIT. -package api +package health // This file was generated by the swagger tool. // Editing this file might prove futile when you re-run the swagger generate command diff --git a/internal/httpclient/client/api/is_instance_alive_responses.go b/internal/httpclient/client/health/is_instance_alive_responses.go similarity index 99% rename from internal/httpclient/client/api/is_instance_alive_responses.go rename to internal/httpclient/client/health/is_instance_alive_responses.go index 0ae846c6a8..f17a763e6b 100644 --- a/internal/httpclient/client/api/is_instance_alive_responses.go +++ b/internal/httpclient/client/health/is_instance_alive_responses.go @@ -1,6 +1,6 @@ // Code generated by go-swagger; DO NOT EDIT. -package api +package health // This file was generated by the swagger tool. // Editing this file might prove futile when you re-run the swagger generate command diff --git a/internal/httpclient/client/api/is_instance_ready_parameters.go b/internal/httpclient/client/health/is_instance_ready_parameters.go similarity index 99% rename from internal/httpclient/client/api/is_instance_ready_parameters.go rename to internal/httpclient/client/health/is_instance_ready_parameters.go index 459fac0ff0..a9290b8399 100644 --- a/internal/httpclient/client/api/is_instance_ready_parameters.go +++ b/internal/httpclient/client/health/is_instance_ready_parameters.go @@ -1,6 +1,6 @@ // Code generated by go-swagger; DO NOT EDIT. -package api +package health // This file was generated by the swagger tool. // Editing this file might prove futile when you re-run the swagger generate command diff --git a/internal/httpclient/client/api/is_instance_ready_responses.go b/internal/httpclient/client/health/is_instance_ready_responses.go similarity index 99% rename from internal/httpclient/client/api/is_instance_ready_responses.go rename to internal/httpclient/client/health/is_instance_ready_responses.go index 094c0879ab..7065a11452 100644 --- a/internal/httpclient/client/api/is_instance_ready_responses.go +++ b/internal/httpclient/client/health/is_instance_ready_responses.go @@ -1,6 +1,6 @@ // Code generated by go-swagger; DO NOT EDIT. -package api +package health // This file was generated by the swagger tool. // Editing this file might prove futile when you re-run the swagger generate command diff --git a/internal/httpclient/client/ory_oathkeeper_client.go b/internal/httpclient/client/ory_oathkeeper_client.go index f04b914e18..c43e3f6abb 100644 --- a/internal/httpclient/client/ory_oathkeeper_client.go +++ b/internal/httpclient/client/ory_oathkeeper_client.go @@ -11,6 +11,8 @@ import ( "github.com/go-openapi/strfmt" apiops "github.com/ory/oathkeeper/internal/httpclient/client/api" + "github.com/ory/oathkeeper/internal/httpclient/client/health" + "github.com/ory/oathkeeper/internal/httpclient/client/version" ) // Default ory oathkeeper HTTP client. @@ -56,6 +58,8 @@ func New(transport runtime.ClientTransport, formats strfmt.Registry) *OryOathkee cli := new(OryOathkeeper) cli.Transport = transport cli.API = apiops.New(transport, formats) + cli.Health = health.New(transport, formats) + cli.Version = version.New(transport, formats) return cli } @@ -102,6 +106,10 @@ func (cfg *TransportConfig) WithSchemes(schemes []string) *TransportConfig { type OryOathkeeper struct { API apiops.ClientService + Health health.ClientService + + Version version.ClientService + Transport runtime.ClientTransport } @@ -109,4 +117,6 @@ type OryOathkeeper struct { func (c *OryOathkeeper) SetTransport(transport runtime.ClientTransport) { c.Transport = transport c.API.SetTransport(transport) + c.Health.SetTransport(transport) + c.Version.SetTransport(transport) } diff --git a/internal/httpclient/client/api/get_version_parameters.go b/internal/httpclient/client/version/get_version_parameters.go similarity index 99% rename from internal/httpclient/client/api/get_version_parameters.go rename to internal/httpclient/client/version/get_version_parameters.go index cc91b5a58b..a1a6a7b582 100644 --- a/internal/httpclient/client/api/get_version_parameters.go +++ b/internal/httpclient/client/version/get_version_parameters.go @@ -1,6 +1,6 @@ // Code generated by go-swagger; DO NOT EDIT. -package api +package version // This file was generated by the swagger tool. // Editing this file might prove futile when you re-run the swagger generate command diff --git a/internal/httpclient/client/api/get_version_responses.go b/internal/httpclient/client/version/get_version_responses.go similarity index 99% rename from internal/httpclient/client/api/get_version_responses.go rename to internal/httpclient/client/version/get_version_responses.go index 65b842bbb7..22406de83e 100644 --- a/internal/httpclient/client/api/get_version_responses.go +++ b/internal/httpclient/client/version/get_version_responses.go @@ -1,6 +1,6 @@ // Code generated by go-swagger; DO NOT EDIT. -package api +package version // This file was generated by the swagger tool. // Editing this file might prove futile when you re-run the swagger generate command diff --git a/internal/httpclient/client/version/version_client.go b/internal/httpclient/client/version/version_client.go new file mode 100644 index 0000000000..4b05eeafe8 --- /dev/null +++ b/internal/httpclient/client/version/version_client.go @@ -0,0 +1,87 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package version + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "fmt" + + "github.com/go-openapi/runtime" + "github.com/go-openapi/strfmt" +) + +// New creates a new version API client. +func New(transport runtime.ClientTransport, formats strfmt.Registry) ClientService { + return &Client{transport: transport, formats: formats} +} + +/* +Client for version API +*/ +type Client struct { + transport runtime.ClientTransport + formats strfmt.Registry +} + +// ClientOption is the option for Client methods +type ClientOption func(*runtime.ClientOperation) + +// ClientService is the interface for Client methods +type ClientService interface { + GetVersion(params *GetVersionParams, opts ...ClientOption) (*GetVersionOK, error) + + SetTransport(transport runtime.ClientTransport) +} + +/* + GetVersion gets service version + + This endpoint returns the service version typically notated using semantic versioning. + +If the service supports TLS Edge Termination, this endpoint does not require the +`X-Forwarded-Proto` header to be set. + +Be aware that if you are running multiple nodes of this service, the health status will never +refer to the cluster state, only to a single instance. +*/ +func (a *Client) GetVersion(params *GetVersionParams, opts ...ClientOption) (*GetVersionOK, error) { + // TODO: Validate the params before sending + if params == nil { + params = NewGetVersionParams() + } + op := &runtime.ClientOperation{ + ID: "getVersion", + Method: "GET", + PathPattern: "/version", + ProducesMediaTypes: []string{"application/json"}, + ConsumesMediaTypes: []string{"application/json"}, + Schemes: []string{"http", "https"}, + Params: params, + Reader: &GetVersionReader{formats: a.formats}, + Context: params.Context, + Client: params.HTTPClient, + } + for _, opt := range opts { + opt(op) + } + + result, err := a.transport.Submit(op) + if err != nil { + return nil, err + } + success, ok := result.(*GetVersionOK) + if ok { + return success, nil + } + // unexpected success response + // safeguard: normally, absent a default response, unknown success responses return an error above: so this is a codegen issue + msg := fmt.Sprintf("unexpected success response for getVersion: API contract not enforced by server. Client expected to get an error, but got: %T", result) + panic(msg) +} + +// SetTransport changes the transport on the client +func (a *Client) SetTransport(transport runtime.ClientTransport) { + a.transport = transport +} diff --git a/middleware/definitions.go b/middleware/definitions.go index 2537ece08a..3a1dc522e1 100644 --- a/middleware/definitions.go +++ b/middleware/definitions.go @@ -17,7 +17,6 @@ import ( "github.com/ory/oathkeeper/driver" "github.com/ory/oathkeeper/driver/configuration" - "github.com/ory/oathkeeper/driver/health" "github.com/ory/oathkeeper/proxy" "github.com/ory/oathkeeper/rule" "github.com/ory/oathkeeper/x" @@ -28,7 +27,7 @@ type ( Logger() *logrusx.Logger RuleMatcher() rule.Matcher ProxyRequestHandler() proxy.RequestHandler - HealthEventManager() health.EventManager + HealthxReadyCheckers() healthx.ReadyCheckers } middleware struct{ dependencies } @@ -111,5 +110,5 @@ func New(ctx context.Context, opts ...Option) (Middleware, error) { } func (m *middleware) HealthxReadyCheckers() healthx.ReadyCheckers { - return m.HealthEventManager().HealthxReadyCheckers() + return m.dependencies.HealthxReadyCheckers() } diff --git a/middleware/grpc_middleware_test.go b/middleware/grpc_middleware_test.go index 9184d7dd22..7cc0be3d62 100644 --- a/middleware/grpc_middleware_test.go +++ b/middleware/grpc_middleware_test.go @@ -421,6 +421,15 @@ access_rules: matching_strategy: regexp repositories: - file://%s +authenticators: + noop: + enabled: true +authorizers: + allow: + enabled: true +mutators: + noop: + enabled: true `, rulesFile)) regPtr := new(driver.Registry) diff --git a/rule/fetcher_default_test.go b/rule/fetcher_default_test.go index d4f3810a95..6c21868e13 100644 --- a/rule/fetcher_default_test.go +++ b/rule/fetcher_default_test.go @@ -5,15 +5,16 @@ package rule_test import ( "context" + "encoding/base64" "fmt" "io" "net/http" "net/http/httptest" "os" "os/exec" - "path" "path/filepath" "runtime" + "strings" "testing" "time" @@ -35,7 +36,7 @@ import ( "github.com/ory/oathkeeper/rule" ) -const testRule = `[{"id":"test-rule-5","upstream":{"preserve_host":true,"strip_path":"/api","url":"mybackend.com/api"},"match":{"url":"myproxy.com/api","methods":["GET","POST"]},"authenticators":[{"handler":"noop"},{"handler":"anonymous"}],"authorizer":{"handler":"allow"},"mutators":[{"handler":"noop"}]}]` +const testRule = `[{"id":"test-rule-5","upstream":{"preserve_host":true,"strip_path":"/api","url":"https://mybackend.com/api"},"match":{"url":"myproxy.com/api","methods":["GET","POST"]},"authenticators":[{"handler":"noop"},{"handler":"anonymous"}],"authorizer":{"handler":"allow"},"mutators":[{"handler":"noop"}]}]` const testConfigPath = "../test/update" func copyToFile(t *testing.T, src string, dst *os.File) { @@ -172,6 +173,17 @@ func TestFetcherWatchConfig(t *testing.T) { go func() { configChanged <- struct{}{} }() }), ) + // set default values for all test cases + conf.SetForTest(t, configuration.AuthorizerAllowIsEnabled, true) + conf.SetForTest(t, configuration.AuthorizerDenyIsEnabled, true) + conf.SetForTest(t, configuration.AuthenticatorNoopIsEnabled, true) + conf.SetForTest(t, configuration.AuthenticatorAnonymousIsEnabled, true) + conf.SetForTest(t, configuration.MutatorNoopIsEnabled, true) + conf.SetForTest(t, configuration.MutatorHeaderIsEnabled, true) + conf.SetForTest(t, configuration.MutatorIDTokenIsEnabled, true) + conf.SetForTest(t, configuration.MutatorIDTokenJWKSURL, "https://stub/.well-known/jwks.json") + conf.SetForTest(t, configuration.MutatorIDTokenIssuerURL, "https://stub") + r := internal.NewRegistry(conf) ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { @@ -202,14 +214,32 @@ access_rules: expectedStrategy: configuration.DefaultMatchingStrategy, }, { - config: ` + config: fmt.Sprintf(` access_rules: repositories: - file://../test/stub/rules.json - file://../test/stub/rules.yaml - file:///invalid/path - - inline://W3siaWQiOiJ0ZXN0LXJ1bGUtNCIsInVwc3RyZWFtIjp7InByZXNlcnZlX2hvc3QiOnRydWUsInN0cmlwX3BhdGgiOiIvYXBpIiwidXJsIjoibXliYWNrZW5kLmNvbS9hcGkifSwibWF0Y2giOnsidXJsIjoibXlwcm94eS5jb20vYXBpIiwibWV0aG9kcyI6WyJHRVQiLCJQT1NUIl19LCJhdXRoZW50aWNhdG9ycyI6W3siaGFuZGxlciI6Im5vb3AifSx7ImhhbmRsZXIiOiJhbm9ueW1vdXMifV0sImF1dGhvcml6ZXIiOnsiaGFuZGxlciI6ImFsbG93In0sIm11dGF0b3JzIjpbeyJoYW5kbGVyIjoibm9vcCJ9XX1d - - ` + ts.URL + "\n", + - inline://%s + - %s +`, base64.StdEncoding.EncodeToString([]byte(`- id: test-rule-4 + upstream: + preserve_host: true + strip_path: "/api" + url: https://mybackend.com/api + match: + url: myproxy.com/api + methods: + - GET + - POST + authenticators: + - handler: noop + - handler: anonymous + authorizer: + handler: allow + mutators: + - handler: noop +`)), ts.URL), expectedStrategy: configuration.DefaultMatchingStrategy, expectIDs: []string{"test-rule-1", "test-rule-2", "test-rule-3", "test-rule-4", "test-rule-5", "test-rule-1-yaml"}, }, @@ -246,9 +276,7 @@ access_rules: ids[k] = r.ID } - for _, id := range tc.expectIDs { - assert.True(t, stringslice.Has(ids, id), "\nexpected: %v\nactual: %v", tc.expectIDs, ids) - } + assert.ElementsMatch(t, tc.expectIDs, ids) }) } } @@ -285,35 +313,59 @@ access_rules: configx.WithLogger(logrusx.New("", "", logrusx.ForceLevel(logrus.TraceLevel))), configx.WithConfigFiles(configFile.Name()), ) + conf.SetForTest(t, configuration.AuthenticatorNoopIsEnabled, true) + conf.SetForTest(t, configuration.AuthorizerAllowIsEnabled, true) + conf.SetForTest(t, configuration.MutatorNoopIsEnabled, true) + r := internal.NewRegistry(conf) go func() { require.NoError(t, r.RuleFetcher().Watch(ctx)) }() + const rulePattern = `{ + "id": "%s", + "upstream": { + "preserve_host": true, + "strip_path": "/api", + "url": "https://a" + }, + "match": { + "url": "a", + "methods": ["GET"] + }, + "authenticators": [{"handler": "noop"}], + "authorizer": {"handler": "allow"}, + "mutators": [{"handler": "noop"}] +}` for k, tc := range []struct { - content string - expectIDs []string + ids []string }{ - {content: "[]"}, - {content: `[{"id":"1"}]`, expectIDs: []string{"1"}}, - {content: `[{"id":"1"},{"id":"2"}]`, expectIDs: []string{"1", "2"}}, - {content: `[{"id":"2"},{"id":"3"},{"id":"4"}]`, expectIDs: []string{"2", "3", "4"}}, + {}, + {ids: []string{"1"}}, + {ids: []string{"1", "2"}}, + {ids: []string{"2", "3", "4"}}, } { t.Run(fmt.Sprintf("case=%d", k), func(t *testing.T) { + rawRules := make([]string, len(tc.ids)) + for k, id := range tc.ids { + rawRules[k] = fmt.Sprintf(rulePattern, id) + } + content := fmt.Sprintf("[%s]", strings.Join(rawRules, ",")) + repoFile.Truncate(0) - repoFile.WriteAt([]byte(tc.content), 0) + repoFile.WriteAt([]byte(content), 0) repoFile.Sync() - rules := eventuallyListRules(ctx, t, r, len(tc.expectIDs)) + actualRules := eventuallyListRules(ctx, t, r, len(tc.ids)) - ids := make([]string, len(rules)) - for k, r := range rules { + ids := make([]string, len(rawRules)) + for k, r := range actualRules { ids[k] = r.ID } - for _, id := range tc.expectIDs { - assert.True(t, stringslice.Has(ids, id), "\nexpected: %v\nactual: %v", tc.expectIDs, ids) + for _, id := range tc.ids { + assert.True(t, stringslice.Has(ids, id), "\nexpected: %v\nactual: %v", tc.ids, ids) } }) } @@ -328,7 +380,7 @@ func TestFetcherWatchRepositoryFromKubernetesConfigMap(t *testing.T) { // Set up temp dir and file to watch watchDir := t.TempDir() - watchFile := path.Join(watchDir, "access-rules.json") + watchFile := filepath.Join(watchDir, "access-rules.json") conf := internal.NewConfigurationWithDefaults( configx.SkipValidation(), @@ -339,6 +391,9 @@ func TestFetcherWatchRepositoryFromKubernetesConfigMap(t *testing.T) { // Configure watcher conf.SetForTest(t, configuration.AccessRuleRepositories, []string{"file://" + watchFile}) + conf.SetForTest(t, configuration.AuthenticatorNoopIsEnabled, true) + conf.SetForTest(t, configuration.AuthorizerAllowIsEnabled, true) + conf.SetForTest(t, configuration.MutatorNoopIsEnabled, true) // This emulates a config map update // drwxr-xr-x 2 root root 4096 Aug 1 07:42 ..2019_08_01_07_42_33.068812649 @@ -358,24 +413,24 @@ func TestFetcherWatchRepositoryFromKubernetesConfigMap(t *testing.T) { var configMapUpdate = func(t *testing.T, data string, cleanup func()) func() { // this is the equivalent of /etc/rules/..2019_08_01_07_42_33.068812649 - dir := path.Join(watchDir, ".."+uuid.New().String()) + dir := filepath.Join(watchDir, ".."+uuid.New().String()) require.NoError(t, os.Mkdir(dir, 0777)) - fp := path.Join(dir, "access-rules.json") + fp := filepath.Join(dir, "access-rules.json") require.NoError(t, os.WriteFile(fp, []byte(data), 0640)) // this is the symlink: ..data -> ..2019_08_01_07_42_33.068812649 - _ = os.Rename(path.Join(watchDir, "..data"), path.Join(watchDir, "..data_tmp")) - require.NoError(t, exec.Command("ln", "-sfn", dir, path.Join(watchDir, "..data")).Run()) + _ = os.Rename(filepath.Join(watchDir, "..data"), filepath.Join(watchDir, "..data_tmp")) + require.NoError(t, exec.Command("ln", "-sfn", dir, filepath.Join(watchDir, "..data")).Run()) if cleanup != nil { cleanup() } // symlink equivalent: access-rules.json -> ..data/access-rules.json - require.NoError(t, exec.Command("ln", "-sfn", path.Join(watchDir, "..data", "access-rules.json"), watchFile).Run()) + require.NoError(t, exec.Command("ln", "-sfn", filepath.Join(watchDir, "..data", "access-rules.json"), watchFile).Run()) t.Logf("Created access rule file at: file://%s", fp) - t.Logf("Created symbolink link at: file://%s", path.Join(watchDir, "..data")) + t.Logf("Created symbolink link at: file://%s", filepath.Join(watchDir, "..data")) return func() { if err := os.RemoveAll(dir); err != nil { @@ -392,7 +447,21 @@ func TestFetcherWatchRepositoryFromKubernetesConfigMap(t *testing.T) { for i := 0; i < 10; i++ { t.Run(fmt.Sprintf("case=%d", i), func(t *testing.T) { - cleanup = configMapUpdate(t, fmt.Sprintf(`[{"id":"%d"}]`, i), cleanup) + cleanup = configMapUpdate(t, fmt.Sprintf(`[{ + "id": "%d", + "upstream": { + "preserve_host": true, + "strip_path": "/api", + "url": "https://a" + }, + "match": { + "url": "a", + "methods": ["GET"] + }, + "authenticators": [{"handler": "noop"}], + "authorizer": {"handler": "allow"}, + "mutators": [{"handler": "noop"}] +}]`, i), cleanup) rules := eventuallyListRules(ctx, t, r, 1) @@ -411,6 +480,18 @@ func TestFetchRulesFromObjectStorage(t *testing.T) { configFile.WriteString(` authenticators: noop: { enabled: true } + anonymous: { enabled: true } +authorizers: + allow: { enabled: true } + deny: { enabled: true } +mutators: + noop: { enabled: true } + header: { enabled: true } + id_token: + enabled: true + config: + jwks_url: https://stub/.well-known/jwks.json + issuer_url: https://stub access_rules: repositories: @@ -441,8 +522,12 @@ func eventuallyListRules(ctx context.Context, t *testing.T, r rule.Registry, exp var err error assert.Eventually(t, func() bool { rules, err = r.RuleRepository().List(ctx, 500, 0) - require.NoError(t, err) + if err != nil { + t.Logf("Error listing rules: %+v", err) + return false + } return len(rules) == expectedLen }, 2*time.Second, 10*time.Millisecond) + require.Len(t, rules, expectedLen) return } diff --git a/rule/matcher_test.go b/rule/matcher_test.go index 2a18ee6a44..28ee2d051e 100644 --- a/rule/matcher_test.go +++ b/rule/matcher_test.go @@ -111,12 +111,13 @@ func TestMatcher(t *testing.T) { require.Error(t, err) } else { require.NoError(t, err) + r.matchingEngine = nil assert.EqualValues(t, *expect, *r) } } for name, matcher := range map[string]m{ - "memory": NewRepositoryMemory(new(mockRepositoryRegistry), new(mockHealthEventManager)), + "memory": NewRepositoryMemory(new(mockRepositoryRegistry)), } { t.Run(fmt.Sprintf("regexp matcher=%s", name), func(t *testing.T) { t.Run("case=empty", func(t *testing.T) { diff --git a/rule/readiness/rule_readiness.go b/rule/readiness/rule_readiness.go deleted file mode 100644 index 0fb6c7e877..0000000000 --- a/rule/readiness/rule_readiness.go +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright © 2023 Ory Corp -// SPDX-License-Identifier: Apache-2.0 - -package readiness - -import ( - "github.com/pkg/errors" - - "github.com/ory/oathkeeper/driver/health" -) - -type ( - RuleReadinessChecker struct { - hasFirstRuleLoad bool - } - - RuleLoadedEvent struct{} -) - -const ProbeName = "rule-first-load" - -var ErrRuleNotYetLoaded = errors.New("rules have not been loaded yet") - -func NewReadinessHealthChecker() *RuleReadinessChecker { - return &RuleReadinessChecker{ - hasFirstRuleLoad: false, - } -} - -func (r *RuleReadinessChecker) ID() string { - return ProbeName -} - -func (r *RuleReadinessChecker) Validate() error { - if !r.hasFirstRuleLoad { - return errors.WithStack(ErrRuleNotYetLoaded) - } - return nil -} - -func (r *RuleReadinessChecker) EventTypes() []health.ReadinessProbeEvent { - return []health.ReadinessProbeEvent{&RuleLoadedEvent{}} -} - -func (r *RuleReadinessChecker) EventsReceiver(event health.ReadinessProbeEvent) { - switch event.(type) { - case *RuleLoadedEvent: - r.hasFirstRuleLoad = true - } -} - -func (r *RuleLoadedEvent) ReadinessProbeListenerID() string { - return ProbeName -} diff --git a/rule/readiness/rule_readiness_test.go b/rule/readiness/rule_readiness_test.go deleted file mode 100644 index 79a4f39d34..0000000000 --- a/rule/readiness/rule_readiness_test.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright © 2023 Ory Corp -// SPDX-License-Identifier: Apache-2.0 - -package readiness - -import ( - "testing" - - "github.com/pkg/errors" - "github.com/stretchr/testify/assert" -) - -func TestReadinessHealthChecker(t *testing.T) { - t.Run("rule readiness probe", func(t *testing.T) { - ruleReadinessProbe := NewReadinessHealthChecker() - ruleLoadedEvent := RuleLoadedEvent{} - - assert.Equal(t, ruleReadinessProbe.ID(), ProbeName) - assert.Equal(t, ruleLoadedEvent.ReadinessProbeListenerID(), ProbeName) - - assert.True(t, errors.Is(ruleReadinessProbe.Validate(), ErrRuleNotYetLoaded)) - - evtTypes := ruleReadinessProbe.EventTypes() - assert.Len(t, evtTypes, 1) - _, ok := evtTypes[0].(*RuleLoadedEvent) - assert.True(t, ok, "actual type %T", evtTypes[0]) - - // Dispatch fake event - ruleReadinessProbe.EventsReceiver(&RuleLoadedEvent{}) - - assert.NoError(t, ruleReadinessProbe.Validate()) - }) -} diff --git a/rule/repository.go b/rule/repository.go index e0434b19dc..de1462399f 100644 --- a/rule/repository.go +++ b/rule/repository.go @@ -5,6 +5,7 @@ package rule import ( "context" + "net/http" "github.com/ory/oathkeeper/driver/configuration" ) @@ -16,4 +17,5 @@ type Repository interface { Count(context.Context) (int, error) MatchingStrategy(context.Context) (configuration.MatchingStrategy, error) SetMatchingStrategy(context.Context, configuration.MatchingStrategy) error + ReadyChecker(*http.Request) error } diff --git a/rule/repository_memory.go b/rule/repository_memory.go index 51f51cbf70..3dc90c1b03 100644 --- a/rule/repository_memory.go +++ b/rule/repository_memory.go @@ -5,15 +5,14 @@ package rule import ( "context" + "net/http" "net/url" "sync" "github.com/pkg/errors" "github.com/ory/oathkeeper/driver/configuration" - "github.com/ory/oathkeeper/driver/health" "github.com/ory/oathkeeper/helper" - rulereadiness "github.com/ory/oathkeeper/rule/readiness" "github.com/ory/oathkeeper/x" "github.com/ory/x/pagination" @@ -29,10 +28,9 @@ type repositoryMemoryRegistry interface { type RepositoryMemory struct { sync.RWMutex rules []Rule + invalidRules []Rule matchingStrategy configuration.MatchingStrategy r repositoryMemoryRegistry - - hem health.EventManager } // MatchingStrategy returns current MatchingStrategy. @@ -50,11 +48,10 @@ func (m *RepositoryMemory) SetMatchingStrategy(_ context.Context, ms configurati return nil } -func NewRepositoryMemory(r repositoryMemoryRegistry, hem health.EventManager) *RepositoryMemory { +func NewRepositoryMemory(r repositoryMemoryRegistry) *RepositoryMemory { return &RepositoryMemory{ r: r, rules: make([]Rule, 0), - hem: hem, } } @@ -94,17 +91,22 @@ func (m *RepositoryMemory) Get(ctx context.Context, id string) (*Rule, error) { } func (m *RepositoryMemory) Set(ctx context.Context, rules []Rule) error { + m.Lock() + defer m.Unlock() + + m.rules = make([]Rule, 0, len(rules)) + m.invalidRules = make([]Rule, 0) + for _, check := range rules { if err := m.r.RuleValidator().Validate(&check); err != nil { m.r.Logger().WithError(err).WithField("rule_id", check.ID). Errorf("A Rule uses a malformed configuration and all URLs matching this rule will not work. You should resolve this issue now.") + m.invalidRules = append(m.invalidRules, check) + } else { + m.rules = append(m.rules, check) } } - m.Lock() - m.rules = rules - m.hem.Dispatch(&rulereadiness.RuleLoadedEvent{}) - m.Unlock() return nil } @@ -116,15 +118,22 @@ func (m *RepositoryMemory) Match(ctx context.Context, method string, u *url.URL, m.Lock() defer m.Unlock() - var rules []Rule + var rules []*Rule for k := range m.rules { r := &m.rules[k] if matched, err := r.IsMatching(m.matchingStrategy, method, u, protocol); err != nil { return nil, errors.WithStack(err) } else if matched { - rules = append(rules, *r) + rules = append(rules, r) + } + } + for k := range m.invalidRules { + r := &m.invalidRules[k] + if matched, err := r.IsMatching(m.matchingStrategy, method, u, protocol); err != nil { + return nil, errors.WithStack(err) + } else if matched { + rules = append(rules, r) } - m.rules[k] = *r } if len(rules) == 0 { @@ -133,5 +142,16 @@ func (m *RepositoryMemory) Match(ctx context.Context, method string, u *url.URL, return nil, errors.WithStack(helper.ErrMatchesMoreThanOneRule) } - return &rules[0], nil + return rules[0], nil +} + +func (m *RepositoryMemory) ReadyChecker(r *http.Request) error { + c, err := m.Count(r.Context()) + if err != nil { + return err + } + if c == 0 { + return errors.WithStack(helper.ErrResourceNotFound.WithReason("No rules found.")) + } + return nil } diff --git a/rule/repository_test.go b/rule/repository_test.go index d2570e4aa4..475e16d788 100644 --- a/rule/repository_test.go +++ b/rule/repository_test.go @@ -7,6 +7,7 @@ import ( "context" "fmt" "math/rand" + "net/http" "reflect" "testing" @@ -17,14 +18,11 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/ory/x/healthx" - "github.com/ory/x/logrusx" "github.com/ory/x/sqlcon/dockertest" "github.com/ory/oathkeeper/driver/configuration" - "github.com/ory/oathkeeper/driver/health" ) func TestMain(m *testing.M) { @@ -41,21 +39,6 @@ func (v *validatorNoop) Validate(*Rule) error { return v.ret } -type mockHealthEventManager struct { -} - -func (m *mockHealthEventManager) Dispatch(_ health.ReadinessProbeEvent) { - -} - -func (m *mockHealthEventManager) Watch(_ context.Context) { - -} - -func (m *mockHealthEventManager) HealthxReadyCheckers() healthx.ReadyCheckers { - return nil -} - type mockRepositoryRegistry struct { v validatorNoop loggerCalled int @@ -87,9 +70,11 @@ func init() { func TestRepository(t *testing.T) { for name, repo := range map[string]Repository{ - "memory": NewRepositoryMemory(new(mockRepositoryRegistry), new(mockHealthEventManager)), + "memory": NewRepositoryMemory(new(mockRepositoryRegistry)), } { t.Run(fmt.Sprintf("repository=%s/case=valid rule", name), func(t *testing.T) { + assert.Error(t, repo.ReadyChecker(new(http.Request))) + var rules []Rule for i := 0; i < 4; i++ { var rule Rule @@ -106,6 +91,7 @@ func TestRepository(t *testing.T) { copy(inserted, rules) inserted = inserted[:len(inserted)-1] // insert all elements but the last repo.Set(context.Background(), inserted) + assert.NoError(t, repo.ReadyChecker(new(http.Request))) for _, expect := range inserted { got, err := repo.Get(context.Background(), expect.ID) @@ -153,16 +139,17 @@ func TestRepository(t *testing.T) { }) } - var index int - mr := &mockRepositoryRegistry{v: validatorNoop{ret: errors.New("this is a forced test error and can be ignored")}} + expectedErr := errors.New("this is a forced test error and can be ignored") + mr := &mockRepositoryRegistry{v: validatorNoop{ret: expectedErr}} for name, repo := range map[string]Repository{ - "memory": NewRepositoryMemory(mr, new(mockHealthEventManager)), + "memory": NewRepositoryMemory(mr), } { t.Run(fmt.Sprintf("repository=%s/case=invalid rule", name), func(t *testing.T) { var rule Rule require.NoError(t, faker.FakeData(&rule)) require.NoError(t, repo.Set(context.Background(), []Rule{rule})) - assert.Equal(t, index+1, mr.loggerCalled) + assert.Equal(t, 1, mr.loggerCalled) + assert.Error(t, repo.ReadyChecker(new(http.Request))) }) } } diff --git a/rule/testdata/TestFetchRulesFromObjectStorage-azblob.replay b/rule/testdata/TestFetchRulesFromObjectStorage-azblob.replay index cb770a65d8..07f73f5524 100644 --- a/rule/testdata/TestFetchRulesFromObjectStorage-azblob.replay +++ b/rule/testdata/TestFetchRulesFromObjectStorage-azblob.replay @@ -113,7 +113,7 @@ "2018-11-09" ] }, - "Body": "WwogIHsKICAgICJpZCI6ICJ0ZXN0LXJ1bGUtMSIsCiAgICAidXBzdHJlYW0iOiB7CiAgICAgICJwcmVzZXJ2ZV9ob3N0IjogdHJ1ZSwKICAgICAgInN0cmlwX3BhdGgiOiAiL2FwaSIsCiAgICAgICJ1cmwiOiAibXliYWNrZW5kLmNvbS9hcGkiCiAgICB9LAogICAgIm1hdGNoIjogewogICAgICAidXJsIjogIm15cHJveHkuY29tL2FwaSIsCiAgICAgICJtZXRob2RzIjogWwogICAgICAgICJHRVQiLAogICAgICAgICJQT1NUIgogICAgICBdCiAgICB9LAogICAgImF1dGhlbnRpY2F0b3JzIjogWwogICAgICB7CiAgICAgICAgImhhbmRsZXIiOiAibm9vcCIKICAgICAgfSwKICAgICAgewogICAgICAgICJoYW5kbGVyIjogImFub255bW91cyIKICAgICAgfQogICAgXSwKICAgICJhdXRob3JpemVyIjogewogICAgICAiaGFuZGxlciI6ICJhbGxvdyIKICAgIH0sCiAgICAibXV0YXRvcnMiOiBbCiAgICAgIHsKICAgICAgICAiaGFuZGxlciI6ICJub29wIgogICAgICB9CiAgICBdCiAgfSwKICB7CiAgICAiaWQiOiAidGVzdC1ydWxlLTIiLAogICAgInVwc3RyZWFtIjogewogICAgICAicHJlc2VydmVfaG9zdCI6IHRydWUsCiAgICAgICJzdHJpcF9wYXRoIjogIi9hcGkiLAogICAgICAidXJsIjogIm15YmFja2VuZC5jb20vYXBpIgogICAgfSwKICAgICJtYXRjaCI6IHsKICAgICAgInVybCI6ICJteXByb3h5LmNvbS9hcGkiLAogICAgICAibWV0aG9kcyI6IFsKICAgICAgICAiR0VUIiwKICAgICAgICAiUE9TVCIKICAgICAgXQogICAgfSwKICAgICJhdXRoZW50aWNhdG9ycyI6IFsKICAgICAgewogICAgICAgICJoYW5kbGVyIjogIm5vb3AiCiAgICAgIH0sCiAgICAgIHsKICAgICAgICAiaGFuZGxlciI6ICJhbm9ueW1vdXMiCiAgICAgIH0KICAgIF0sCiAgICAiYXV0aG9yaXplciI6IHsKICAgICAgImhhbmRsZXIiOiAiZGVueSIKICAgIH0sCiAgICAibXV0YXRvcnMiOiBbCiAgICAgIHsKICAgICAgICAiaGFuZGxlciI6ICJpZF90b2tlbiIKICAgICAgfSwKICAgICAgewogICAgICAgICJoYW5kbGVyIjogImhlYWRlcnMiLAogICAgICAgICJjb25maWciOiB7CiAgICAgICAgICAiaGVhZGVycyI6IHsKICAgICAgICAgICAgIlgtVXNlciI6ICJ7eyBwcmludCAuU3ViamVjdCB9fSIKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIF0KICB9LAogIHsKICAgICJpZCI6ICJ0ZXN0LXJ1bGUtMyIsCiAgICAidXBzdHJlYW0iOiB7CiAgICAgICJwcmVzZXJ2ZV9ob3N0IjogdHJ1ZSwKICAgICAgInN0cmlwX3BhdGgiOiAiL2FwaSIsCiAgICAgICJ1cmwiOiAibXliYWNrZW5kLmNvbS9hcGkiCiAgICB9LAogICAgIm1hdGNoIjogewogICAgICAidXJsIjogIm15cHJveHkuY29tL2FwaSIsCiAgICAgICJtZXRob2RzIjogWwogICAgICAgICJHRVQiLAogICAgICAgICJQT1NUIgogICAgICBdCiAgICB9LAogICAgImF1dGhlbnRpY2F0b3JzIjogWwogICAgICB7CiAgICAgICAgImhhbmRsZXIiOiAibm9vcCIKICAgICAgfSwKICAgICAgewogICAgICAgICJoYW5kbGVyIjogImFub255bW91cyIKICAgICAgfQogICAgXSwKICAgICJhdXRob3JpemVyIjogewogICAgICAiaGFuZGxlciI6ICJhbGxvdyIKICAgIH0sCiAgICAibXV0YXRvcnMiOiBbCiAgICAgIHsKICAgICAgICAiaGFuZGxlciI6ICJpZF90b2tlbiIsCiAgICAgICAgImNvbmZpZyI6IHsKICAgICAgICAgICJqd2tzX3VybCI6ICJodHRwOi8vc3R1Yi8iCiAgICAgICAgfQogICAgICB9CiAgICBdCiAgfQpd" + "Body": "WwogIHsKICAgICJpZCI6ICJ0ZXN0LXJ1bGUtMSIsCiAgICAidXBzdHJlYW0iOiB7CiAgICAgICJwcmVzZXJ2ZV9ob3N0IjogdHJ1ZSwKICAgICAgInN0cmlwX3BhdGgiOiAiL2FwaSIsCiAgICAgICJ1cmwiOiAiaHR0cHM6Ly9teWJhY2tlbmQuY29tL2FwaSIKICAgIH0sCiAgICAibWF0Y2giOiB7CiAgICAgICJ1cmwiOiAibXlwcm94eS5jb20vYXBpIiwKICAgICAgIm1ldGhvZHMiOiBbCiAgICAgICAgIkdFVCIsCiAgICAgICAgIlBPU1QiCiAgICAgIF0KICAgIH0sCiAgICAiYXV0aGVudGljYXRvcnMiOiBbCiAgICAgIHsKICAgICAgICAiaGFuZGxlciI6ICJub29wIgogICAgICB9LAogICAgICB7CiAgICAgICAgImhhbmRsZXIiOiAiYW5vbnltb3VzIgogICAgICB9CiAgICBdLAogICAgImF1dGhvcml6ZXIiOiB7CiAgICAgICJoYW5kbGVyIjogImFsbG93IgogICAgfSwKICAgICJtdXRhdG9ycyI6IFsKICAgICAgewogICAgICAgICJoYW5kbGVyIjogIm5vb3AiCiAgICAgIH0KICAgIF0KICB9LAogIHsKICAgICJpZCI6ICJ0ZXN0LXJ1bGUtMiIsCiAgICAidXBzdHJlYW0iOiB7CiAgICAgICJwcmVzZXJ2ZV9ob3N0IjogdHJ1ZSwKICAgICAgInN0cmlwX3BhdGgiOiAiL2FwaSIsCiAgICAgICJ1cmwiOiAiaHR0cHM6Ly9teWJhY2tlbmQuY29tL2FwaSIKICAgIH0sCiAgICAibWF0Y2giOiB7CiAgICAgICJ1cmwiOiAibXlwcm94eS5jb20vYXBpIiwKICAgICAgIm1ldGhvZHMiOiBbCiAgICAgICAgIkdFVCIsCiAgICAgICAgIlBPU1QiCiAgICAgIF0KICAgIH0sCiAgICAiYXV0aGVudGljYXRvcnMiOiBbCiAgICAgIHsKICAgICAgICAiaGFuZGxlciI6ICJub29wIgogICAgICB9LAogICAgICB7CiAgICAgICAgImhhbmRsZXIiOiAiYW5vbnltb3VzIgogICAgICB9CiAgICBdLAogICAgImF1dGhvcml6ZXIiOiB7CiAgICAgICJoYW5kbGVyIjogImRlbnkiCiAgICB9LAogICAgIm11dGF0b3JzIjogWwogICAgICB7CiAgICAgICAgImhhbmRsZXIiOiAiaWRfdG9rZW4iCiAgICAgIH0sCiAgICAgIHsKICAgICAgICAiaGFuZGxlciI6ICJoZWFkZXIiLAogICAgICAgICJjb25maWciOiB7CiAgICAgICAgICAiaGVhZGVycyI6IHsKICAgICAgICAgICAgIlgtVXNlciI6ICJ7eyBwcmludCAuU3ViamVjdCB9fSIKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIF0KICB9LAogIHsKICAgICJpZCI6ICJ0ZXN0LXJ1bGUtMyIsCiAgICAidXBzdHJlYW0iOiB7CiAgICAgICJwcmVzZXJ2ZV9ob3N0IjogdHJ1ZSwKICAgICAgInN0cmlwX3BhdGgiOiAiL2FwaSIsCiAgICAgICJ1cmwiOiAiaHR0cHM6Ly9teWJhY2tlbmQuY29tL2FwaSIKICAgIH0sCiAgICAibWF0Y2giOiB7CiAgICAgICJ1cmwiOiAibXlwcm94eS5jb20vYXBpIiwKICAgICAgIm1ldGhvZHMiOiBbCiAgICAgICAgIkdFVCIsCiAgICAgICAgIlBPU1QiCiAgICAgIF0KICAgIH0sCiAgICAiYXV0aGVudGljYXRvcnMiOiBbCiAgICAgIHsKICAgICAgICAiaGFuZGxlciI6ICJub29wIgogICAgICB9LAogICAgICB7CiAgICAgICAgImhhbmRsZXIiOiAiYW5vbnltb3VzIgogICAgICB9CiAgICBdLAogICAgImF1dGhvcml6ZXIiOiB7CiAgICAgICJoYW5kbGVyIjogImFsbG93IgogICAgfSwKICAgICJtdXRhdG9ycyI6IFsKICAgICAgewogICAgICAgICJoYW5kbGVyIjogImlkX3Rva2VuIiwKICAgICAgICAiY29uZmlnIjogewogICAgICAgICAgImp3a3NfdXJsIjogImh0dHA6Ly9zdHViLyIKICAgICAgICB9CiAgICAgIH0KICAgIF0KICB9Cl0=" } } ] diff --git a/rule/testdata/TestFetchRulesFromObjectStorage-gs.replay b/rule/testdata/TestFetchRulesFromObjectStorage-gs.replay index a2ce8d8bde..b579b6ad4a 100644 --- a/rule/testdata/TestFetchRulesFromObjectStorage-gs.replay +++ b/rule/testdata/TestFetchRulesFromObjectStorage-gs.replay @@ -90,10 +90,6 @@ "X-Goog-Generation": [ "1603997975634896" ], - "X-Goog-Hash": [ - "crc32c=idw+Sg==", - "md5=TUCA2pl9ZOFeecRQLAB2WA==" - ], "X-Goog-Metageneration": [ "1" ], @@ -110,7 +106,7 @@ "ABg5-UzHzK0bh-_7p2S6fsQRYwGthpMTiYJLqArwIgf5EH6DkKdqtJPBI1-_Lx9f-ORvOU0HxlJGGlF7svzvCBB9ggI" ] }, - "Body": "WwogIHsKICAgICJpZCI6ICJ0ZXN0LXJ1bGUtMSIsCiAgICAidXBzdHJlYW0iOiB7CiAgICAgICJwcmVzZXJ2ZV9ob3N0IjogdHJ1ZSwKICAgICAgInN0cmlwX3BhdGgiOiAiL2FwaSIsCiAgICAgICJ1cmwiOiAibXliYWNrZW5kLmNvbS9hcGkiCiAgICB9LAogICAgIm1hdGNoIjogewogICAgICAidXJsIjogIm15cHJveHkuY29tL2FwaSIsCiAgICAgICJtZXRob2RzIjogWwogICAgICAgICJHRVQiLAogICAgICAgICJQT1NUIgogICAgICBdCiAgICB9LAogICAgImF1dGhlbnRpY2F0b3JzIjogWwogICAgICB7CiAgICAgICAgImhhbmRsZXIiOiAibm9vcCIKICAgICAgfSwKICAgICAgewogICAgICAgICJoYW5kbGVyIjogImFub255bW91cyIKICAgICAgfQogICAgXSwKICAgICJhdXRob3JpemVyIjogewogICAgICAiaGFuZGxlciI6ICJhbGxvdyIKICAgIH0sCiAgICAibXV0YXRvcnMiOiBbCiAgICAgIHsKICAgICAgICAiaGFuZGxlciI6ICJub29wIgogICAgICB9CiAgICBdCiAgfSwKICB7CiAgICAiaWQiOiAidGVzdC1ydWxlLTIiLAogICAgInVwc3RyZWFtIjogewogICAgICAicHJlc2VydmVfaG9zdCI6IHRydWUsCiAgICAgICJzdHJpcF9wYXRoIjogIi9hcGkiLAogICAgICAidXJsIjogIm15YmFja2VuZC5jb20vYXBpIgogICAgfSwKICAgICJtYXRjaCI6IHsKICAgICAgInVybCI6ICJteXByb3h5LmNvbS9hcGkiLAogICAgICAibWV0aG9kcyI6IFsKICAgICAgICAiR0VUIiwKICAgICAgICAiUE9TVCIKICAgICAgXQogICAgfSwKICAgICJhdXRoZW50aWNhdG9ycyI6IFsKICAgICAgewogICAgICAgICJoYW5kbGVyIjogIm5vb3AiCiAgICAgIH0sCiAgICAgIHsKICAgICAgICAiaGFuZGxlciI6ICJhbm9ueW1vdXMiCiAgICAgIH0KICAgIF0sCiAgICAiYXV0aG9yaXplciI6IHsKICAgICAgImhhbmRsZXIiOiAiZGVueSIKICAgIH0sCiAgICAibXV0YXRvcnMiOiBbCiAgICAgIHsKICAgICAgICAiaGFuZGxlciI6ICJpZF90b2tlbiIKICAgICAgfSwKICAgICAgewogICAgICAgICJoYW5kbGVyIjogImhlYWRlcnMiLAogICAgICAgICJjb25maWciOiB7CiAgICAgICAgICAiaGVhZGVycyI6IHsKICAgICAgICAgICAgIlgtVXNlciI6ICJ7eyBwcmludCAuU3ViamVjdCB9fSIKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIF0KICB9LAogIHsKICAgICJpZCI6ICJ0ZXN0LXJ1bGUtMyIsCiAgICAidXBzdHJlYW0iOiB7CiAgICAgICJwcmVzZXJ2ZV9ob3N0IjogdHJ1ZSwKICAgICAgInN0cmlwX3BhdGgiOiAiL2FwaSIsCiAgICAgICJ1cmwiOiAibXliYWNrZW5kLmNvbS9hcGkiCiAgICB9LAogICAgIm1hdGNoIjogewogICAgICAidXJsIjogIm15cHJveHkuY29tL2FwaSIsCiAgICAgICJtZXRob2RzIjogWwogICAgICAgICJHRVQiLAogICAgICAgICJQT1NUIgogICAgICBdCiAgICB9LAogICAgImF1dGhlbnRpY2F0b3JzIjogWwogICAgICB7CiAgICAgICAgImhhbmRsZXIiOiAibm9vcCIKICAgICAgfSwKICAgICAgewogICAgICAgICJoYW5kbGVyIjogImFub255bW91cyIKICAgICAgfQogICAgXSwKICAgICJhdXRob3JpemVyIjogewogICAgICAiaGFuZGxlciI6ICJhbGxvdyIKICAgIH0sCiAgICAibXV0YXRvcnMiOiBbCiAgICAgIHsKICAgICAgICAiaGFuZGxlciI6ICJpZF90b2tlbiIsCiAgICAgICAgImNvbmZpZyI6IHsKICAgICAgICAgICJqd2tzX3VybCI6ICJodHRwOi8vc3R1Yi8iCiAgICAgICAgfQogICAgICB9CiAgICBdCiAgfQpd" + "Body": "WwogIHsKICAgICJpZCI6ICJ0ZXN0LXJ1bGUtMSIsCiAgICAidXBzdHJlYW0iOiB7CiAgICAgICJwcmVzZXJ2ZV9ob3N0IjogdHJ1ZSwKICAgICAgInN0cmlwX3BhdGgiOiAiL2FwaSIsCiAgICAgICJ1cmwiOiAiaHR0cHM6Ly9teWJhY2tlbmQuY29tL2FwaSIKICAgIH0sCiAgICAibWF0Y2giOiB7CiAgICAgICJ1cmwiOiAibXlwcm94eS5jb20vYXBpIiwKICAgICAgIm1ldGhvZHMiOiBbCiAgICAgICAgIkdFVCIsCiAgICAgICAgIlBPU1QiCiAgICAgIF0KICAgIH0sCiAgICAiYXV0aGVudGljYXRvcnMiOiBbCiAgICAgIHsKICAgICAgICAiaGFuZGxlciI6ICJub29wIgogICAgICB9LAogICAgICB7CiAgICAgICAgImhhbmRsZXIiOiAiYW5vbnltb3VzIgogICAgICB9CiAgICBdLAogICAgImF1dGhvcml6ZXIiOiB7CiAgICAgICJoYW5kbGVyIjogImFsbG93IgogICAgfSwKICAgICJtdXRhdG9ycyI6IFsKICAgICAgewogICAgICAgICJoYW5kbGVyIjogIm5vb3AiCiAgICAgIH0KICAgIF0KICB9LAogIHsKICAgICJpZCI6ICJ0ZXN0LXJ1bGUtMiIsCiAgICAidXBzdHJlYW0iOiB7CiAgICAgICJwcmVzZXJ2ZV9ob3N0IjogdHJ1ZSwKICAgICAgInN0cmlwX3BhdGgiOiAiL2FwaSIsCiAgICAgICJ1cmwiOiAiaHR0cHM6Ly9teWJhY2tlbmQuY29tL2FwaSIKICAgIH0sCiAgICAibWF0Y2giOiB7CiAgICAgICJ1cmwiOiAibXlwcm94eS5jb20vYXBpIiwKICAgICAgIm1ldGhvZHMiOiBbCiAgICAgICAgIkdFVCIsCiAgICAgICAgIlBPU1QiCiAgICAgIF0KICAgIH0sCiAgICAiYXV0aGVudGljYXRvcnMiOiBbCiAgICAgIHsKICAgICAgICAiaGFuZGxlciI6ICJub29wIgogICAgICB9LAogICAgICB7CiAgICAgICAgImhhbmRsZXIiOiAiYW5vbnltb3VzIgogICAgICB9CiAgICBdLAogICAgImF1dGhvcml6ZXIiOiB7CiAgICAgICJoYW5kbGVyIjogImRlbnkiCiAgICB9LAogICAgIm11dGF0b3JzIjogWwogICAgICB7CiAgICAgICAgImhhbmRsZXIiOiAiaWRfdG9rZW4iCiAgICAgIH0sCiAgICAgIHsKICAgICAgICAiaGFuZGxlciI6ICJoZWFkZXIiLAogICAgICAgICJjb25maWciOiB7CiAgICAgICAgICAiaGVhZGVycyI6IHsKICAgICAgICAgICAgIlgtVXNlciI6ICJ7eyBwcmludCAuU3ViamVjdCB9fSIKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIF0KICB9LAogIHsKICAgICJpZCI6ICJ0ZXN0LXJ1bGUtMyIsCiAgICAidXBzdHJlYW0iOiB7CiAgICAgICJwcmVzZXJ2ZV9ob3N0IjogdHJ1ZSwKICAgICAgInN0cmlwX3BhdGgiOiAiL2FwaSIsCiAgICAgICJ1cmwiOiAiaHR0cHM6Ly9teWJhY2tlbmQuY29tL2FwaSIKICAgIH0sCiAgICAibWF0Y2giOiB7CiAgICAgICJ1cmwiOiAibXlwcm94eS5jb20vYXBpIiwKICAgICAgIm1ldGhvZHMiOiBbCiAgICAgICAgIkdFVCIsCiAgICAgICAgIlBPU1QiCiAgICAgIF0KICAgIH0sCiAgICAiYXV0aGVudGljYXRvcnMiOiBbCiAgICAgIHsKICAgICAgICAiaGFuZGxlciI6ICJub29wIgogICAgICB9LAogICAgICB7CiAgICAgICAgImhhbmRsZXIiOiAiYW5vbnltb3VzIgogICAgICB9CiAgICBdLAogICAgImF1dGhvcml6ZXIiOiB7CiAgICAgICJoYW5kbGVyIjogImFsbG93IgogICAgfSwKICAgICJtdXRhdG9ycyI6IFsKICAgICAgewogICAgICAgICJoYW5kbGVyIjogImlkX3Rva2VuIiwKICAgICAgICAiY29uZmlnIjogewogICAgICAgICAgImp3a3NfdXJsIjogImh0dHA6Ly9zdHViLyIKICAgICAgICB9CiAgICAgIH0KICAgIF0KICB9Cl0=" } } ] diff --git a/rule/testdata/TestFetchRulesFromObjectStorage-s3.replay b/rule/testdata/TestFetchRulesFromObjectStorage-s3.replay index 115e89a260..3a46c7622c 100644 --- a/rule/testdata/TestFetchRulesFromObjectStorage-s3.replay +++ b/rule/testdata/TestFetchRulesFromObjectStorage-s3.replay @@ -97,7 +97,7 @@ "04E47FBC8B12B935" ] }, - "Body": "WwogIHsKICAgICJpZCI6ICJ0ZXN0LXJ1bGUtMSIsCiAgICAidXBzdHJlYW0iOiB7CiAgICAgICJwcmVzZXJ2ZV9ob3N0IjogdHJ1ZSwKICAgICAgInN0cmlwX3BhdGgiOiAiL2FwaSIsCiAgICAgICJ1cmwiOiAibXliYWNrZW5kLmNvbS9hcGkiCiAgICB9LAogICAgIm1hdGNoIjogewogICAgICAidXJsIjogIm15cHJveHkuY29tL2FwaSIsCiAgICAgICJtZXRob2RzIjogWwogICAgICAgICJHRVQiLAogICAgICAgICJQT1NUIgogICAgICBdCiAgICB9LAogICAgImF1dGhlbnRpY2F0b3JzIjogWwogICAgICB7CiAgICAgICAgImhhbmRsZXIiOiAibm9vcCIKICAgICAgfSwKICAgICAgewogICAgICAgICJoYW5kbGVyIjogImFub255bW91cyIKICAgICAgfQogICAgXSwKICAgICJhdXRob3JpemVyIjogewogICAgICAiaGFuZGxlciI6ICJhbGxvdyIKICAgIH0sCiAgICAibXV0YXRvcnMiOiBbCiAgICAgIHsKICAgICAgICAiaGFuZGxlciI6ICJub29wIgogICAgICB9CiAgICBdCiAgfSwKICB7CiAgICAiaWQiOiAidGVzdC1ydWxlLTIiLAogICAgInVwc3RyZWFtIjogewogICAgICAicHJlc2VydmVfaG9zdCI6IHRydWUsCiAgICAgICJzdHJpcF9wYXRoIjogIi9hcGkiLAogICAgICAidXJsIjogIm15YmFja2VuZC5jb20vYXBpIgogICAgfSwKICAgICJtYXRjaCI6IHsKICAgICAgInVybCI6ICJteXByb3h5LmNvbS9hcGkiLAogICAgICAibWV0aG9kcyI6IFsKICAgICAgICAiR0VUIiwKICAgICAgICAiUE9TVCIKICAgICAgXQogICAgfSwKICAgICJhdXRoZW50aWNhdG9ycyI6IFsKICAgICAgewogICAgICAgICJoYW5kbGVyIjogIm5vb3AiCiAgICAgIH0sCiAgICAgIHsKICAgICAgICAiaGFuZGxlciI6ICJhbm9ueW1vdXMiCiAgICAgIH0KICAgIF0sCiAgICAiYXV0aG9yaXplciI6IHsKICAgICAgImhhbmRsZXIiOiAiZGVueSIKICAgIH0sCiAgICAibXV0YXRvcnMiOiBbCiAgICAgIHsKICAgICAgICAiaGFuZGxlciI6ICJpZF90b2tlbiIKICAgICAgfSwKICAgICAgewogICAgICAgICJoYW5kbGVyIjogImhlYWRlcnMiLAogICAgICAgICJjb25maWciOiB7CiAgICAgICAgICAiaGVhZGVycyI6IHsKICAgICAgICAgICAgIlgtVXNlciI6ICJ7eyBwcmludCAuU3ViamVjdCB9fSIKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIF0KICB9LAogIHsKICAgICJpZCI6ICJ0ZXN0LXJ1bGUtMyIsCiAgICAidXBzdHJlYW0iOiB7CiAgICAgICJwcmVzZXJ2ZV9ob3N0IjogdHJ1ZSwKICAgICAgInN0cmlwX3BhdGgiOiAiL2FwaSIsCiAgICAgICJ1cmwiOiAibXliYWNrZW5kLmNvbS9hcGkiCiAgICB9LAogICAgIm1hdGNoIjogewogICAgICAidXJsIjogIm15cHJveHkuY29tL2FwaSIsCiAgICAgICJtZXRob2RzIjogWwogICAgICAgICJHRVQiLAogICAgICAgICJQT1NUIgogICAgICBdCiAgICB9LAogICAgImF1dGhlbnRpY2F0b3JzIjogWwogICAgICB7CiAgICAgICAgImhhbmRsZXIiOiAibm9vcCIKICAgICAgfSwKICAgICAgewogICAgICAgICJoYW5kbGVyIjogImFub255bW91cyIKICAgICAgfQogICAgXSwKICAgICJhdXRob3JpemVyIjogewogICAgICAiaGFuZGxlciI6ICJhbGxvdyIKICAgIH0sCiAgICAibXV0YXRvcnMiOiBbCiAgICAgIHsKICAgICAgICAiaGFuZGxlciI6ICJpZF90b2tlbiIsCiAgICAgICAgImNvbmZpZyI6IHsKICAgICAgICAgICJqd2tzX3VybCI6ICJodHRwOi8vc3R1Yi8iCiAgICAgICAgfQogICAgICB9CiAgICBdCiAgfQpd" + "Body": "WwogIHsKICAgICJpZCI6ICJ0ZXN0LXJ1bGUtMSIsCiAgICAidXBzdHJlYW0iOiB7CiAgICAgICJwcmVzZXJ2ZV9ob3N0IjogdHJ1ZSwKICAgICAgInN0cmlwX3BhdGgiOiAiL2FwaSIsCiAgICAgICJ1cmwiOiAiaHR0cHM6Ly9teWJhY2tlbmQuY29tL2FwaSIKICAgIH0sCiAgICAibWF0Y2giOiB7CiAgICAgICJ1cmwiOiAibXlwcm94eS5jb20vYXBpIiwKICAgICAgIm1ldGhvZHMiOiBbCiAgICAgICAgIkdFVCIsCiAgICAgICAgIlBPU1QiCiAgICAgIF0KICAgIH0sCiAgICAiYXV0aGVudGljYXRvcnMiOiBbCiAgICAgIHsKICAgICAgICAiaGFuZGxlciI6ICJub29wIgogICAgICB9LAogICAgICB7CiAgICAgICAgImhhbmRsZXIiOiAiYW5vbnltb3VzIgogICAgICB9CiAgICBdLAogICAgImF1dGhvcml6ZXIiOiB7CiAgICAgICJoYW5kbGVyIjogImFsbG93IgogICAgfSwKICAgICJtdXRhdG9ycyI6IFsKICAgICAgewogICAgICAgICJoYW5kbGVyIjogIm5vb3AiCiAgICAgIH0KICAgIF0KICB9LAogIHsKICAgICJpZCI6ICJ0ZXN0LXJ1bGUtMiIsCiAgICAidXBzdHJlYW0iOiB7CiAgICAgICJwcmVzZXJ2ZV9ob3N0IjogdHJ1ZSwKICAgICAgInN0cmlwX3BhdGgiOiAiL2FwaSIsCiAgICAgICJ1cmwiOiAiaHR0cHM6Ly9teWJhY2tlbmQuY29tL2FwaSIKICAgIH0sCiAgICAibWF0Y2giOiB7CiAgICAgICJ1cmwiOiAibXlwcm94eS5jb20vYXBpIiwKICAgICAgIm1ldGhvZHMiOiBbCiAgICAgICAgIkdFVCIsCiAgICAgICAgIlBPU1QiCiAgICAgIF0KICAgIH0sCiAgICAiYXV0aGVudGljYXRvcnMiOiBbCiAgICAgIHsKICAgICAgICAiaGFuZGxlciI6ICJub29wIgogICAgICB9LAogICAgICB7CiAgICAgICAgImhhbmRsZXIiOiAiYW5vbnltb3VzIgogICAgICB9CiAgICBdLAogICAgImF1dGhvcml6ZXIiOiB7CiAgICAgICJoYW5kbGVyIjogImRlbnkiCiAgICB9LAogICAgIm11dGF0b3JzIjogWwogICAgICB7CiAgICAgICAgImhhbmRsZXIiOiAiaWRfdG9rZW4iCiAgICAgIH0sCiAgICAgIHsKICAgICAgICAiaGFuZGxlciI6ICJoZWFkZXIiLAogICAgICAgICJjb25maWciOiB7CiAgICAgICAgICAiaGVhZGVycyI6IHsKICAgICAgICAgICAgIlgtVXNlciI6ICJ7eyBwcmludCAuU3ViamVjdCB9fSIKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIF0KICB9LAogIHsKICAgICJpZCI6ICJ0ZXN0LXJ1bGUtMyIsCiAgICAidXBzdHJlYW0iOiB7CiAgICAgICJwcmVzZXJ2ZV9ob3N0IjogdHJ1ZSwKICAgICAgInN0cmlwX3BhdGgiOiAiL2FwaSIsCiAgICAgICJ1cmwiOiAiaHR0cHM6Ly9teWJhY2tlbmQuY29tL2FwaSIKICAgIH0sCiAgICAibWF0Y2giOiB7CiAgICAgICJ1cmwiOiAibXlwcm94eS5jb20vYXBpIiwKICAgICAgIm1ldGhvZHMiOiBbCiAgICAgICAgIkdFVCIsCiAgICAgICAgIlBPU1QiCiAgICAgIF0KICAgIH0sCiAgICAiYXV0aGVudGljYXRvcnMiOiBbCiAgICAgIHsKICAgICAgICAiaGFuZGxlciI6ICJub29wIgogICAgICB9LAogICAgICB7CiAgICAgICAgImhhbmRsZXIiOiAiYW5vbnltb3VzIgogICAgICB9CiAgICBdLAogICAgImF1dGhvcml6ZXIiOiB7CiAgICAgICJoYW5kbGVyIjogImFsbG93IgogICAgfSwKICAgICJtdXRhdG9ycyI6IFsKICAgICAgewogICAgICAgICJoYW5kbGVyIjogImlkX3Rva2VuIiwKICAgICAgICAiY29uZmlnIjogewogICAgICAgICAgImp3a3NfdXJsIjogImh0dHA6Ly9zdHViLyIKICAgICAgICB9CiAgICAgIH0KICAgIF0KICB9Cl0=" } } ] diff --git a/spec/swagger.json b/spec/swagger.json index ea00efe6c5..6e687adf77 100755 --- a/spec/swagger.json +++ b/spec/swagger.json @@ -81,8 +81,8 @@ "get": { "description": "This endpoint returns a 200 status code when the HTTP server is up running.\nThis status does currently not include checks whether the database connection is working.\n\nIf the service supports TLS Edge Termination, this endpoint does not require the\n`X-Forwarded-Proto` header to be set.\n\nBe aware that if you are running multiple nodes of this service, the health status will never\nrefer to the cluster state, only to a single instance.", "produces": ["application/json"], - "tags": ["api"], - "summary": "Check Alive Status", + "tags": ["health"], + "summary": "Check alive status", "operationId": "isInstanceAlive", "responses": { "200": { @@ -104,8 +104,8 @@ "get": { "description": "This endpoint returns a 200 status code when the HTTP server is up running and the environment dependencies (e.g.\nthe database) are responsive as well.\n\nIf the service supports TLS Edge Termination, this endpoint does not require the\n`X-Forwarded-Proto` header to be set.\n\nBe aware that if you are running multiple nodes of this service, the health status will never\nrefer to the cluster state, only to a single instance.", "produces": ["application/json"], - "tags": ["api"], - "summary": "Check Readiness Status", + "tags": ["health"], + "summary": "Check readiness status", "operationId": "isInstanceReady", "responses": { "200": { @@ -201,8 +201,8 @@ "get": { "description": "This endpoint returns the service version typically notated using semantic versioning.\n\nIf the service supports TLS Edge Termination, this endpoint does not require the\n`X-Forwarded-Proto` header to be set.\n\nBe aware that if you are running multiple nodes of this service, the health status will never\nrefer to the cluster state, only to a single instance.", "produces": ["application/json"], - "tags": ["api"], - "summary": "Get Service Version", + "tags": ["version"], + "summary": "Get service version", "operationId": "getVersion", "responses": { "200": { diff --git a/test/reload/run.sh b/test/reload/run.sh index 484d8c7b26..c5427468da 100755 --- a/test/reload/run.sh +++ b/test/reload/run.sh @@ -34,6 +34,7 @@ waitport 6060 waitport 6061 function finish { + killall oathkeeper || true cat ./config.yaml cat ./rules.3.json || true cat ./oathkeeper.log diff --git a/test/stub/rules.json b/test/stub/rules.json index 4f0d5243ad..c8aceb098b 100644 --- a/test/stub/rules.json +++ b/test/stub/rules.json @@ -4,7 +4,7 @@ "upstream": { "preserve_host": true, "strip_path": "/api", - "url": "mybackend.com/api" + "url": "https://mybackend.com/api" }, "match": { "url": "myproxy.com/api", @@ -32,7 +32,7 @@ "upstream": { "preserve_host": true, "strip_path": "/api", - "url": "mybackend.com/api" + "url": "https://mybackend.com/api" }, "match": { "url": "myproxy.com/api", @@ -54,7 +54,7 @@ "handler": "id_token" }, { - "handler": "headers", + "handler": "header", "config": { "headers": { "X-User": "{{ print .Subject }}" @@ -68,7 +68,7 @@ "upstream": { "preserve_host": true, "strip_path": "/api", - "url": "mybackend.com/api" + "url": "https://mybackend.com/api" }, "match": { "url": "myproxy.com/api", diff --git a/test/stub/rules.yaml b/test/stub/rules.yaml index c4f0e36f8a..3f3000faa6 100644 --- a/test/stub/rules.yaml +++ b/test/stub/rules.yaml @@ -2,7 +2,7 @@ upstream: preserve_host: true strip_path: /api - url: mybackend.com/api + url: https://mybackend.com/api match: url: myproxy.com/api methods: diff --git a/test/update/config_default.yaml b/test/update/config_default.yaml index 8b1a26086c..979aa4fa50 100644 --- a/test/update/config_default.yaml +++ b/test/update/config_default.yaml @@ -1,2 +1,11 @@ access_rules: repositories: file://../test/update/rules_glob.yaml +authenticators: + anonymous: + enabled: true +authorizers: + allow: + enabled: true +mutators: + noop: + enabled: true diff --git a/test/update/config_error.yaml b/test/update/config_error.yaml index e8a0fcf790..4198f09b4c 100644 --- a/test/update/config_error.yaml +++ b/test/update/config_error.yaml @@ -1,3 +1,12 @@ access_rules: repositories: file://../test/update/rules_glob.yaml matching_strategy: UNKNOWN +authenticators: + anonymous: + enabled: true +authorizers: + allow: + enabled: true +mutators: + noop: + enabled: true diff --git a/test/update/config_glob.yaml b/test/update/config_glob.yaml index 51d4d20674..447ec8c29d 100644 --- a/test/update/config_glob.yaml +++ b/test/update/config_glob.yaml @@ -1,3 +1,12 @@ access_rules: repositories: file://../test/update/rules_glob.yaml matching_strategy: glob +authenticators: + anonymous: + enabled: true +authorizers: + allow: + enabled: true +mutators: + noop: + enabled: true diff --git a/test/update/config_no_repo.yaml b/test/update/config_no_repo.yaml index 2c1bcb9730..53f237131b 100644 --- a/test/update/config_no_repo.yaml +++ b/test/update/config_no_repo.yaml @@ -1,2 +1,11 @@ access_rules: repositories: [] +authenticators: + anonymous: + enabled: true +authorizers: + allow: + enabled: true +mutators: + noop: + enabled: true diff --git a/test/update/config_regexp.yaml b/test/update/config_regexp.yaml index 6163c6c4b5..7c84c6c300 100644 --- a/test/update/config_regexp.yaml +++ b/test/update/config_regexp.yaml @@ -1,3 +1,12 @@ access_rules: repositories: file://../test/update/rules_glob.yaml matching_strategy: regexp +authenticators: + anonymous: + enabled: true +authorizers: + allow: + enabled: true +mutators: + noop: + enabled: true diff --git a/test/update/rules_glob.yaml b/test/update/rules_glob.yaml index 3941a16436..b428d0a39d 100644 --- a/test/update/rules_glob.yaml +++ b/test/update/rules_glob.yaml @@ -4,3 +4,9 @@ methods: - GET - POST + authenticators: + - handler: anonymous + authorizer: + handler: allow + mutators: + - handler: noop