Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: cache bug #1885

Merged
merged 3 commits into from
Dec 2, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 20 additions & 14 deletions enclave-manager/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ type WebServer struct {
engineServiceClient *kurtosis_engine_rpc_api_bindingsconnect.EngineServiceClient
enforceAuth bool
instanceConfig *kurtosis_backend_server_rpc_api_bindings.GetCloudInstanceConfigResponse
apiKey *string
instanceConfigMap map[string]*kurtosis_backend_server_rpc_api_bindings.GetCloudInstanceConfigResponse
apiKeyMap map[string]*string
}

func NewWebserver(enforceAuth bool) (*WebServer, error) {
Expand All @@ -57,6 +58,8 @@ func NewWebserver(enforceAuth bool) (*WebServer, error) {
enforceAuth: enforceAuth,
instanceConfigMutex: &sync.RWMutex{},
apiKeyMutex: &sync.RWMutex{},
apiKeyMap: map[string]*string{},
instanceConfigMap: map[string]*kurtosis_backend_server_rpc_api_bindings.GetCloudInstanceConfigResponse{},
}, nil
}

Expand Down Expand Up @@ -92,7 +95,7 @@ func (c *WebServer) ValidateRequestAuthorization(
return false, stacktrace.NewError("An internal error has occurred. An empty API key was found")
}

instanceConfig, err := c.GetCloudInstanceConfig(ctx, auth.ApiKey)
instanceConfig, err := c.GetCloudInstanceConfig(ctx, reqToken, auth.ApiKey)
if err != nil {
return false, stacktrace.Propagate(err, "Failed to retrieve the instance config")
}
Expand All @@ -103,7 +106,9 @@ func (c *WebServer) ValidateRequestAuthorization(
}
reqHost = splitHost[0]
if instanceConfig.LaunchResult.PublicDns != reqHost {
return false, stacktrace.NewError("Instance config public dns '%s' does not match the request host '%s'", instanceConfig.LaunchResult.PublicDns, reqHost)
delete(c.apiKeyMap, reqToken)
delete(c.instanceConfigMap, reqToken)
return false, stacktrace.NewError("either the requested instance does not exist or the user is not authorized to access the resource")
}

return true, nil
Expand Down Expand Up @@ -413,11 +418,12 @@ func (c *WebServer) createKurtosisCloudBackendClient(

func (c *WebServer) GetCloudInstanceConfig(
ctx context.Context,
jwtToken string,
apiKey string,
) (*kurtosis_backend_server_rpc_api_bindings.GetCloudInstanceConfigResponse, error) {
// Check if we have already fetched the instance config, if so return the cache
if c.instanceConfig != nil {
return c.instanceConfig, nil
if c.instanceConfigMap[jwtToken] != nil {
return c.instanceConfigMap[jwtToken], nil
}

// We have not yet fetched the instance configuration, so we write lock, make the external call and cache the result
Expand Down Expand Up @@ -452,7 +458,7 @@ func (c *WebServer) GetCloudInstanceConfig(
return nil, stacktrace.Propagate(err, "Failed to get the instance config")
}

c.instanceConfig = getInstanceConfigResponse.Msg
c.instanceConfigMap[jwtToken] = getInstanceConfigResponse.Msg

return getInstanceConfigResponse.Msg, nil
}
Expand All @@ -468,21 +474,21 @@ func (c *WebServer) ConvertJwtTokenToApiKey(
if err != nil {
return nil, stacktrace.Propagate(err, "Failed to create the Cloud backend client")
}
request := &connect.Request[kurtosis_backend_server_rpc_api_bindings.GetOrCreateApiKeyRequest]{
Msg: &kurtosis_backend_server_rpc_api_bindings.GetOrCreateApiKeyRequest{
AccessToken: jwtToken,
},
}

if c.apiKey != nil {
if c.apiKeyMap[jwtToken] != nil {
return &Authentication{
ApiKey: *c.apiKey,
ApiKey: *c.apiKeyMap[jwtToken],
JwtToken: jwtToken,
}, nil
} else {
c.apiKeyMutex.Lock()
defer c.apiKeyMutex.Unlock()

request := &connect.Request[kurtosis_backend_server_rpc_api_bindings.GetOrCreateApiKeyRequest]{
Msg: &kurtosis_backend_server_rpc_api_bindings.GetOrCreateApiKeyRequest{
AccessToken: jwtToken,
},
}
result, err := (*client).GetOrCreateApiKey(ctx, request)
if err != nil {
return nil, stacktrace.Propagate(err, "Failed to get the API key")
Expand All @@ -494,7 +500,7 @@ func (c *WebServer) ConvertJwtTokenToApiKey(
}

if len(result.Msg.ApiKey) > 0 {
c.apiKey = &result.Msg.ApiKey
c.apiKeyMap[jwtToken] = &result.Msg.ApiKey
return &Authentication{
ApiKey: result.Msg.ApiKey,
JwtToken: jwtToken,
Expand Down