From 37be8851b38b269059032ab83fc723164a011c4c Mon Sep 17 00:00:00 2001 From: Denis Kirillov Date: Fri, 9 Feb 2024 17:38:14 +0300 Subject: [PATCH] [#306] Simplify namespaces configuration Resolve ns alias at the beginning of the request just once. Keep in ns map only one default ns key. Signed-off-by: Denis Kirillov --- api/handler/acl.go | 15 +++++--------- api/handler/api.go | 1 - api/middleware/reqinfo.go | 3 ++- cmd/s3-gw/app.go | 43 +++++++++++++++------------------------ cmd/s3-gw/app_settings.go | 14 ++++++------- 5 files changed, 29 insertions(+), 47 deletions(-) diff --git a/api/handler/acl.go b/api/handler/acl.go index 8a0bded..51ae2f3 100644 --- a/api/handler/acl.go +++ b/api/handler/acl.go @@ -489,8 +489,7 @@ func (h *handler) GetBucketPolicyHandler(w http.ResponseWriter, r *http.Request) return } - resolvedNamespace := h.cfg.ResolveNamespaceAlias(reqInfo.Namespace) - jsonPolicy, err := h.ape.GetPolicy(resolvedNamespace, bktInfo.CID) + jsonPolicy, err := h.ape.GetPolicy(reqInfo.Namespace, bktInfo.CID) if err != nil { if strings.Contains(err.Error(), "not found") { err = fmt.Errorf("%w: %s", errors.GetAPIError(errors.ErrNoSuchBucketPolicy), err.Error()) @@ -516,16 +515,14 @@ func (h *handler) DeleteBucketPolicyHandler(w http.ResponseWriter, r *http.Reque return } - resolvedNamespace := h.cfg.ResolveNamespaceAlias(reqInfo.Namespace) - - target := engine.NamespaceTarget(resolvedNamespace) + target := engine.NamespaceTarget(reqInfo.Namespace) chainID := getBucketChainID(bktInfo) if err = h.ape.RemoveChain(target, chainID); err != nil { h.logAndSendError(w, "failed to remove morph rule chain", reqInfo, err) return } - if err = h.ape.DeletePolicy(resolvedNamespace, bktInfo.CID); err != nil { + if err = h.ape.DeletePolicy(reqInfo.Namespace, bktInfo.CID); err != nil { h.logAndSendError(w, "failed to delete policy from storage", reqInfo, err) return } @@ -581,15 +578,13 @@ func (h *handler) PutBucketPolicyHandler(w http.ResponseWriter, r *http.Request) } } - resolvedNamespace := h.cfg.ResolveNamespaceAlias(reqInfo.Namespace) - - target := engine.NamespaceTarget(resolvedNamespace) + target := engine.NamespaceTarget(reqInfo.Namespace) if err = h.ape.AddChain(target, s3Chain); err != nil { h.logAndSendError(w, "failed to add morph rule chain", reqInfo, err) return } - if err = h.ape.PutPolicy(resolvedNamespace, bktInfo.CID, jsonPolicy); err != nil { + if err = h.ape.PutPolicy(reqInfo.Namespace, bktInfo.CID, jsonPolicy); err != nil { h.logAndSendError(w, "failed to save policy to storage", reqInfo, err) return } diff --git a/api/handler/api.go b/api/handler/api.go index 061245c..c8d0ec7 100644 --- a/api/handler/api.go +++ b/api/handler/api.go @@ -47,7 +47,6 @@ type ( IsResolveListAllow() bool BypassContentEncodingInChunks() bool MD5Enabled() bool - ResolveNamespaceAlias(namespace string) string } FrostFSID interface { diff --git a/api/middleware/reqinfo.go b/api/middleware/reqinfo.go index 2ce6d4f..c08c716 100644 --- a/api/middleware/reqinfo.go +++ b/api/middleware/reqinfo.go @@ -191,6 +191,7 @@ func GetReqLog(ctx context.Context) *zap.Logger { type RequestSettings interface { NamespaceHeader() string + ResolveNamespaceAlias(string) string } func Request(log *zap.Logger, settings RequestSettings) Func { @@ -207,7 +208,7 @@ func Request(log *zap.Logger, settings RequestSettings) Func { // set request info into context // bucket name and object will be set in reqInfo later (limitation of go-chi) reqInfo := NewReqInfo(w, r, ObjectRequest{}) - reqInfo.Namespace = r.Header.Get(settings.NamespaceHeader()) + reqInfo.Namespace = settings.ResolveNamespaceAlias(r.Header.Get(settings.NamespaceHeader())) r = r.WithContext(SetReqInfo(r.Context(), reqInfo)) // set request id into gRPC meta header diff --git a/cmd/s3-gw/app.go b/cmd/s3-gw/app.go index 57877ad..fc4ea75 100644 --- a/cmd/s3-gw/app.go +++ b/cmd/s3-gw/app.go @@ -220,18 +220,28 @@ func newAppSettings(log *Logger, v *viper.Viper, key *keys.PrivateKey) *appSetti } func (s *appSettings) update(v *viper.Viper, log *zap.Logger, key *keys.PrivateKey) { - s.setNamespaceHeader(v.GetString(cfgResolveNamespaceHeader)) // should be updated before placement policies - s.initPlacementPolicy(log, v) + s.updateNamespacesSettings(v, log) s.useDefaultXMLNamespace(v.GetBool(cfgKludgeUseDefaultXMLNS)) s.setBypassContentEncodingInChunks(v.GetBool(cfgKludgeBypassContentEncodingCheckInChunks)) s.setClientCut(v.GetBool(cfgClientCut)) s.setBufferMaxSizeForPut(v.GetUint64(cfgBufferMaxSizeForPut)) s.setMD5Enabled(v.GetBool(cfgMD5Enabled)) - s.setDefaultNamespaces(fetchDefaultNamespaces(log, v)) s.setAuthorizedControlAPIKeys(append(fetchAuthorizedKeys(log, v), key.PublicKey())) s.setPolicyDenyByDefault(v.GetBool(cfgPolicyDenyByDefault)) } +func (s *appSettings) updateNamespacesSettings(v *viper.Viper, log *zap.Logger) { + nsHeader := v.GetString(cfgResolveNamespaceHeader) + nsConfig, defaultNamespaces := fetchNamespacesConfig(log, v) + + s.mu.Lock() + defer s.mu.Unlock() + + s.namespaceHeader = nsHeader + s.defaultNamespaces = defaultNamespaces + s.namespaces = nsConfig.Namespaces +} + func (s *appSettings) BypassContentEncodingInChunks() bool { s.mu.RLock() defer s.mu.RUnlock() @@ -268,15 +278,6 @@ func (s *appSettings) setBufferMaxSizeForPut(size uint64) { s.mu.Unlock() } -func (s *appSettings) initPlacementPolicy(l *zap.Logger, v *viper.Viper) { - nsConfig := fetchNamespacesConfig(l, v) - - s.mu.Lock() - defer s.mu.Unlock() - - s.namespaces = nsConfig.Namespaces -} - func (s *appSettings) DefaultPlacementPolicy(namespace string) netmap.PlacementPolicy { s.mu.RLock() defer s.mu.RUnlock() @@ -357,33 +358,21 @@ func (s *appSettings) NamespaceHeader() string { return s.namespaceHeader } -func (s *appSettings) setNamespaceHeader(nsHeader string) { - s.mu.Lock() - s.namespaceHeader = nsHeader - s.mu.Unlock() -} - func (s *appSettings) FormContainerZone(ns string) (zone string, isDefault bool) { - if s.IsDefaultNamespace(ns) { + if len(ns) == 0 { return v2container.SysAttributeZoneDefault, true } return ns + ".ns", false } -func (s *appSettings) IsDefaultNamespace(ns string) bool { +func (s *appSettings) isDefaultNamespace(ns string) bool { s.mu.RLock() namespaces := s.defaultNamespaces s.mu.RUnlock() return slices.Contains(namespaces, ns) } -func (s *appSettings) setDefaultNamespaces(namespaces []string) { - s.mu.Lock() - s.defaultNamespaces = namespaces - s.mu.Unlock() -} - func (s *appSettings) FetchRawKeys() [][]byte { s.mu.RLock() defer s.mu.RUnlock() @@ -402,7 +391,7 @@ func (s *appSettings) setAuthorizedControlAPIKeys(keys keys.PublicKeys) { } func (s *appSettings) ResolveNamespaceAlias(namespace string) string { - if s.IsDefaultNamespace(namespace) { + if s.isDefaultNamespace(namespace) { return defaultNamespace } diff --git a/cmd/s3-gw/app_settings.go b/cmd/s3-gw/app_settings.go index c4624e2..ed6611b 100644 --- a/cmd/s3-gw/app_settings.go +++ b/cmd/s3-gw/app_settings.go @@ -515,7 +515,7 @@ func fetchDefaultNamespaces(l *zap.Logger, v *viper.Viper) []string { return defaultNamespaces } -func fetchNamespacesConfig(l *zap.Logger, v *viper.Viper) NamespacesConfig { +func fetchNamespacesConfig(l *zap.Logger, v *viper.Viper) (NamespacesConfig, []string) { defaultNSRegionMap := fetchRegionMappingPolicies(l, v) defaultNSRegionMap[defaultConstraintName] = fetchDefaultPolicy(l, v) @@ -551,15 +551,13 @@ func fetchNamespacesConfig(l *zap.Logger, v *viper.Viper) NamespacesConfig { } } - for _, name := range defaultNamespacesNames { - nsConfig.Namespaces[name] = Namespace{ - Name: name, - LocationConstraints: defaultNSValue.LocationConstraints, - CopiesNumbers: defaultNSValue.CopiesNumbers, - } + nsConfig.Namespaces[defaultNamespace] = Namespace{ + Name: defaultNamespace, + LocationConstraints: defaultNSValue.LocationConstraints, + CopiesNumbers: defaultNSValue.CopiesNumbers, } - return nsConfig + return nsConfig, defaultNamespacesNames } func readNamespacesConfig(filepath string) (NamespacesConfig, error) {