diff --git a/.envrc b/.envrc index 9b4e215466..041e7deb8f 100644 --- a/.envrc +++ b/.envrc @@ -115,6 +115,8 @@ export CEDAR_API_URL="webmethods-apigw.cedarimpl.cms.gov" export CEDAR_API_KEY="" export CEDAR_CORE_API_VERSION="2.0.0" export CEDAR_EMAIL_ADDRESS="EnterpriseArchitecture@notCMS.gov" +export CEDAR_CACHE_EXPIRE_TIME="7d" +export CEDAR_CORE_SKIP_PROXY=false # Frontend Dev export ESLINT_NO_DEV_ERRORS=true diff --git a/cedarproxy/nginx.conf b/cedarproxy/nginx.conf index d081e15e5b..7cc861a25b 100644 --- a/cedarproxy/nginx.conf +++ b/cedarproxy/nginx.conf @@ -33,7 +33,8 @@ http { # include /etc/nginx/conf.d/*.conf; proxy_cache_path /nginxcache keys_zone=cedarcorecache:10m; - proxy_cache_valid 200 302 24h; + proxy_cache_valid 200 302 ${CEDAR_CACHE_EXPIRE_TIME}; + proxy_cache_use_stale error timeout updating http_500 http_504 server { listen 8001; diff --git a/deploy/base/cedarproxy.yaml b/deploy/base/cedarproxy.yaml index d38c57c56b..3a9745e59e 100644 --- a/deploy/base/cedarproxy.yaml +++ b/deploy/base/cedarproxy.yaml @@ -5,6 +5,7 @@ metadata: namespace: easi data: CEDAR_API_URL: webmethods-apigw.cedarimpl.cms.gov + CEDAR_CACHE_EXPIRE_TIME: "7d" --- diff --git a/deploy/base/easi.yaml b/deploy/base/easi.yaml index 5287270fa1..28c9a5c2c7 100644 --- a/deploy/base/easi.yaml +++ b/deploy/base/easi.yaml @@ -6,11 +6,11 @@ metadata: data: CEDAR_CORE_MOCK: 'true' CEDAR_INTAKE_ENABLED: 'false' - CEDAR_API_KEY: '' + CEDAR_API_KEY: "" CEDAR_PROXY_URL: "" + CEDAR_CORE_SKIP_PROXY: "false" CEDAR_API_URL: "webmethods-apigw.cedarimpl.cms.gov" CEDAR_CORE_API_VERSION: "2.0.0" - CEDAR_CACHE_INTERVAL: "30m" CEDAR_EMAIL_ADDRESS: "EnterpriseArchitecture@notCMS.gov" APP_ENV: local CLIENT_PROTOCOL: http diff --git a/docker-compose.yml b/docker-compose.yml index 124eea6da2..3b19e47241 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -22,8 +22,8 @@ services: - CEDAR_API_KEY - CEDAR_API_URL - CEDAR_PROXY_URL=cedarproxy:8001 + - CEDAR_CORE_SKIP_PROXY - CEDAR_CORE_API_VERSION - - CEDAR_CACHE_INTERVAL - CEDAR_EMAIL_ADDRESS - HTTP_PROXY - HTTPS_PROXY @@ -79,6 +79,7 @@ services: image: cedarproxy:latest environment: - CEDAR_API_URL + - CEDAR_CACHE_EXPIRE_TIME build: dockerfile: Dockerfile.cedarproxy context: ./cedarproxy/ diff --git a/pkg/appconfig/config.go b/pkg/appconfig/config.go index 227c8a268d..5b7fb4c13e 100644 --- a/pkg/appconfig/config.go +++ b/pkg/appconfig/config.go @@ -170,6 +170,9 @@ const CEDARAPIURL = "CEDAR_API_URL" // CEDARAPIKey is the key for accessing CEDAR const CEDARAPIKey = "CEDAR_API_KEY" // #nosec +// CEDARCoreSkipProxy is the key for whether to make calls directly to CEDAR Core +const CEDARCoreSkipProxy = "CEDAR_CORE_SKIP_PROXY" + // CEDAREmailAddress is the key for the env var that holds the email address that we use when notifying CEDAR of changes const CEDAREmailAddress = "CEDAR_EMAIL_ADDRESS" diff --git a/pkg/cedar/core/client.go b/pkg/cedar/core/client.go index fce9f4de3e..0cefb94fec 100644 --- a/pkg/cedar/core/client.go +++ b/pkg/cedar/core/client.go @@ -48,10 +48,14 @@ var ( cedarPath string client *Client clientOnce sync.Once + skipPurge bool ) // Purges Proxy Cache by URL using a given path func PurgeCacheByPath(ctx context.Context, path string) error { + if skipPurge { + return nil + } req, err := http.NewRequest("PURGE", cedarPath+path, nil) logger := appcontext.ZLogger(ctx) if err != nil { @@ -77,7 +81,7 @@ func PurgeCacheByPath(ctx context.Context, path string) error { } // NewClient builds the type that holds a connection to the CEDAR Core API -func NewClient(ctx context.Context, cedarHost string, cedarAPIKey string, cedarAPIVersion string, mockEnabled bool) *Client { +func NewClient(ctx context.Context, cedarHost string, cedarAPIKey string, cedarAPIVersion string, skipProxy bool, mockEnabled bool) *Client { clientOnce.Do(func() { hc := http.Client{ Transport: &loggingTransport{ @@ -87,6 +91,9 @@ func NewClient(ctx context.Context, cedarHost string, cedarAPIKey string, cedarA basePath := "/gateway/CEDAR Core API/" + cedarAPIVersion cedarPath = "http://" + cedarHost + basePath + if skipProxy { + skipPurge = true + } client = &Client{ mockEnabled: mockEnabled, auth: httptransport.APIKeyAuth( diff --git a/pkg/cedar/core/client_test.go b/pkg/cedar/core/client_test.go index cf848d42f5..3a315ba410 100644 --- a/pkg/cedar/core/client_test.go +++ b/pkg/cedar/core/client_test.go @@ -27,7 +27,7 @@ func (s *ClientTestSuite) TestClient() { ctx := appcontext.WithLogger(context.Background(), s.logger) s.Run("Instantiation successful", func() { - c := NewClient(ctx, "fake", "fake", "1.0.0", true) + c := NewClient(ctx, "fake", "fake", "1.0.0", false, true) s.NotNil(c) }) } diff --git a/pkg/cedar/core/system_summary_test.go b/pkg/cedar/core/system_summary_test.go index 775b7a2ea7..029e1d9e8b 100644 --- a/pkg/cedar/core/system_summary_test.go +++ b/pkg/cedar/core/system_summary_test.go @@ -28,7 +28,7 @@ func (s *SystemSummaryTestSuite) TestGetSystemSummary() { ctx := appcontext.WithLogger(context.Background(), s.logger) s.Run("LD defaults protects invocation of GetSystemSummary", func() { - c := NewClient(ctx, "fake", "fake", "1.0.0", true) + c := NewClient(ctx, "fake", "fake", "1.0.0", false, true) resp, err := c.GetSystemSummary(ctx) s.NoError(err) @@ -40,7 +40,7 @@ func (s *SystemSummaryTestSuite) TestGetSystemSummary() { }) s.Run("Retrieves filtered list when EUA filter is present", func() { - c := NewClient(ctx, "fake", "fake", "1.0.0", true) + c := NewClient(ctx, "fake", "fake", "1.0.0", false, true) resp, err := c.GetSystemSummary(ctx, WithEuaIDFilter("USR1")) s.NoError(err) @@ -52,7 +52,7 @@ func (s *SystemSummaryTestSuite) TestGetSystemSummary() { }) s.Run("Retrieves filtered list when Sub-System filter is present", func() { - c := NewClient(ctx, "fake", "fake", "1.0.0", true) + c := NewClient(ctx, "fake", "fake", "1.0.0", false, true) resp, err := c.GetSystemSummary(ctx, WithSubSystems("1")) s.NoError(err) @@ -68,7 +68,7 @@ func (s *SystemSummaryTestSuite) TestGetSystem() { ctx := appcontext.WithLogger(context.Background(), s.logger) s.Run("LD defaults protects invocation of GetSystem", func() { - c := NewClient(ctx, "fake", "fake", "1.0.0", true) + c := NewClient(ctx, "fake", "fake", "1.0.0", false, true) _, err := c.GetSystem(ctx, "fake") s.NoError(err) diff --git a/pkg/graph/schema.resolvers_test.go b/pkg/graph/schema.resolvers_test.go index be8508c029..88d87182c9 100644 --- a/pkg/graph/schema.resolvers_test.go +++ b/pkg/graph/schema.resolvers_test.go @@ -147,7 +147,7 @@ func TestGraphQLTestSuite(t *testing.T) { } oktaAPIClient := local.NewOktaAPIClient() - cedarCoreClient := cedarcore.NewClient(appcontext.WithLogger(context.Background(), logger), "fake", "fake", "1.0.0", true) + cedarCoreClient := cedarcore.NewClient(appcontext.WithLogger(context.Background(), logger), "fake", "fake", "1.0.0", false, true) directives := generated.DirectiveRoot{HasRole: func(ctx context.Context, obj interface{}, next graphql.Resolver, role model.Role) (res interface{}, err error) { return next(ctx) diff --git a/pkg/server/routes.go b/pkg/server/routes.go index dd15f0db65..65307800c0 100644 --- a/pkg/server/routes.go +++ b/pkg/server/routes.go @@ -121,12 +121,20 @@ func (s *Server) routes( } } + var cedarCoreURL string + if s.Config.GetBool(appconfig.CEDARCoreSkipProxy) { + cedarCoreURL = s.Config.GetString(appconfig.CEDARAPIURL) + } else { + cedarCoreURL = s.Config.GetString(appconfig.CEDARPROXYURL) + } + // set up CEDAR core API client coreClient := cedarcore.NewClient( appcontext.WithLogger(context.Background(), s.logger), - s.Config.GetString(appconfig.CEDARPROXYURL), + cedarCoreURL, s.Config.GetString(appconfig.CEDARAPIKey), s.Config.GetString(appconfig.CEDARCoreAPIVersion), + s.Config.GetBool(appconfig.CEDARCoreSkipProxy), s.Config.GetBool(appconfig.CEDARCoreMock), )