mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-05-13 21:31:32 +00:00
fix(iam): preserve CreatedAt across boots + paginate ListProviders
Two medium-priority issues gemini flagged on the read-only IAM API: 1. The static-config bootstrap was setting CreatedAt = time.Now() on every server start, so the IAM GetOpenIDConnectProvider response's CreateDate shifted on each restart even when backed by a persistent store. Look up the existing record via GetProviderByARN first and preserve its CreatedAt; only the UpdatedAt advances. 2. FilerOIDCProviderStore.ListProviders had a hardcoded Limit: 1000 that silently truncated above that. Stream-paginate via StartFromFileName, returning io.EOF naturally and surfacing all other errors instead of swallowing them. Addresses two gemini medium reviews on PR #9319.
This commit is contained in:
@@ -286,16 +286,24 @@ func (m *IAMManager) initOIDCProviderStore(config *IAMConfig) error {
|
||||
continue
|
||||
}
|
||||
clientIDs := extractClientIDs(pc.Config)
|
||||
now := time.Now()
|
||||
ctx := context.Background()
|
||||
// Preserve CreatedAt across reboots when a persistent store already
|
||||
// has this provider — IAM's GetOpenIDConnectProvider response
|
||||
// shouldn't shift its CreateDate every time the server restarts.
|
||||
now := time.Now().UTC()
|
||||
createdAt := now
|
||||
if existing, err := store.GetProviderByARN(ctx, m.getFilerAddress(), arn); err == nil && existing != nil && !existing.CreatedAt.IsZero() {
|
||||
createdAt = existing.CreatedAt
|
||||
}
|
||||
rec := &OIDCProviderRecord{
|
||||
AccountID: accountID,
|
||||
ARN: arn,
|
||||
URL: issuer,
|
||||
ClientIDs: clientIDs,
|
||||
CreatedAt: now,
|
||||
CreatedAt: createdAt,
|
||||
UpdatedAt: now,
|
||||
}
|
||||
if err := store.StoreProvider(context.Background(), m.getFilerAddress(), rec); err != nil {
|
||||
if err := store.StoreProvider(ctx, m.getFilerAddress(), rec); err != nil {
|
||||
glog.Warningf("mirror static OIDC provider %s into store: %v", pc.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,9 @@ import (
|
||||
"crypto/sha1"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strings"
|
||||
@@ -281,30 +283,49 @@ func (f *FilerOIDCProviderStore) ListProviders(ctx context.Context, filerAddress
|
||||
|
||||
var out []*OIDCProviderRecord
|
||||
err := f.withFilerClient(filerAddress, func(client filer_pb.SeaweedFilerClient) error {
|
||||
stream, err := client.ListEntries(ctx, &filer_pb.ListEntriesRequest{
|
||||
Directory: f.basePath,
|
||||
Limit: 1000,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("list OIDC providers: %v", err)
|
||||
}
|
||||
// Stream-paginate via StartFromFileName so deployments with more
|
||||
// than 1000 providers don't get a silently truncated list.
|
||||
const pageSize = 1000
|
||||
startFrom := ""
|
||||
for {
|
||||
resp, err := stream.Recv()
|
||||
stream, err := client.ListEntries(ctx, &filer_pb.ListEntriesRequest{
|
||||
Directory: f.basePath,
|
||||
Limit: pageSize,
|
||||
StartFromFileName: startFrom,
|
||||
InclusiveStartFrom: false,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("list OIDC providers: %v", err)
|
||||
}
|
||||
lastName := ""
|
||||
pageCount := 0
|
||||
for {
|
||||
resp, recvErr := stream.Recv()
|
||||
if recvErr != nil {
|
||||
if errors.Is(recvErr, io.EOF) {
|
||||
break
|
||||
}
|
||||
return fmt.Errorf("recv OIDC provider entry: %w", recvErr)
|
||||
}
|
||||
if resp.Entry == nil || resp.Entry.IsDirectory {
|
||||
continue
|
||||
}
|
||||
lastName = resp.Entry.Name
|
||||
pageCount++
|
||||
if !strings.HasSuffix(resp.Entry.Name, ".json") {
|
||||
continue
|
||||
}
|
||||
var rec OIDCProviderRecord
|
||||
if err := json.Unmarshal(resp.Entry.Content, &rec); err != nil {
|
||||
glog.Warningf("skipping malformed OIDC provider record %s: %v", resp.Entry.Name, err)
|
||||
continue
|
||||
}
|
||||
out = append(out, &rec)
|
||||
}
|
||||
if pageCount < pageSize {
|
||||
break
|
||||
}
|
||||
if resp.Entry == nil || resp.Entry.IsDirectory {
|
||||
continue
|
||||
}
|
||||
if !strings.HasSuffix(resp.Entry.Name, ".json") {
|
||||
continue
|
||||
}
|
||||
var rec OIDCProviderRecord
|
||||
if err := json.Unmarshal(resp.Entry.Content, &rec); err != nil {
|
||||
glog.Warningf("skipping malformed OIDC provider record %s: %v", resp.Entry.Name, err)
|
||||
continue
|
||||
}
|
||||
out = append(out, &rec)
|
||||
startFrom = lastName
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user