Skip to content

Commit ff38bab

Browse files
committed
feat(aws): provide a way to turn off legacy services in forge
1 parent fcfd06c commit ff38bab

File tree

2 files changed

+118
-91
lines changed

2 files changed

+118
-91
lines changed

deploy/.env.production.local.tpl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ else
4747
BASE_TRACE_SAMPLE_RATIO="1.0"
4848
fi
4949

50+
if [[ "$TF_WORKSPACE" == "forge-prod" || "$TF_WORKSPACE" == "forge-staging" || "$TF_WORKSPACE" == "warm-staging" ]]; then
51+
SUPPORT_LEGACY_SERVICES="false"
52+
else
53+
SUPPORT_LEGACY_SERVICES="true"
54+
fi
55+
5056
# Set up telemetry
5157
if [[ -z "${TELEMETRY_DISABLED-}" ]]; then
5258
if [[ -n "${HONEYCOMB_API_KEY-}" ]]; then

pkg/aws/service.go

Lines changed: 112 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,51 @@ func mustGetFloat(envVar string) float64 {
6868
return value
6969
}
7070

71+
type LegacyConfig struct {
72+
LegacyClaimsTableName string
73+
LegacyClaimsTableRegion string
74+
LegacyClaimsBucket string
75+
LegacyBlockIndexTableName string
76+
LegacyBlockIndexTableRegion string
77+
LegacyStoreTableName string
78+
LegacyStoreTableRegion string
79+
LegacyBlobRegistryTableName string
80+
LegacyBlobRegistryTableRegion string
81+
LegacyAllocationsTableName string
82+
LegacyAllocationsTableRegion string
83+
LegacyDotStorageBucketPrefixes []string // legacy .storage buckets
84+
LegacyDataBucketURL string
85+
}
86+
87+
func readLegacyConfig() LegacyConfig {
88+
var legacyDotStorageBucketPrefixes []string
89+
err := json.Unmarshal([]byte(mustGetEnv("LEGACY_DOT_STORAGE_BUCKET_PREFIXES")), &legacyDotStorageBucketPrefixes)
90+
if err != nil {
91+
panic(fmt.Errorf("parsing legacy dot storage bucket prefixes JSON: %w", err))
92+
}
93+
return LegacyConfig{
94+
LegacyClaimsTableName: mustGetEnv("LEGACY_CLAIMS_TABLE_NAME"),
95+
LegacyClaimsTableRegion: mustGetEnv("LEGACY_CLAIMS_TABLE_REGION"),
96+
LegacyClaimsBucket: mustGetEnv("LEGACY_CLAIMS_BUCKET_NAME"),
97+
LegacyBlockIndexTableName: mustGetEnv("LEGACY_BLOCK_INDEX_TABLE_NAME"),
98+
LegacyBlockIndexTableRegion: mustGetEnv("LEGACY_BLOCK_INDEX_TABLE_REGION"),
99+
LegacyStoreTableName: mustGetEnv("LEGACY_STORE_TABLE_NAME"),
100+
LegacyStoreTableRegion: mustGetEnv("LEGACY_STORE_TABLE_REGION"),
101+
LegacyBlobRegistryTableName: mustGetEnv("LEGACY_BLOB_REGISTRY_TABLE_NAME"),
102+
LegacyBlobRegistryTableRegion: mustGetEnv("LEGACY_BLOB_REGISTRY_TABLE_REGION"),
103+
LegacyAllocationsTableName: mustGetEnv("LEGACY_ALLOCATIONS_TABLE_NAME"),
104+
LegacyAllocationsTableRegion: mustGetEnv("LEGACY_ALLOCATIONS_TABLE_REGION"),
105+
LegacyDataBucketURL: mustGetEnv("LEGACY_DATA_BUCKET_URL"),
106+
LegacyDotStorageBucketPrefixes: legacyDotStorageBucketPrefixes,
107+
}
108+
}
109+
71110
// Config describes all the values required to setup AWS from the environment
72111
type Config struct {
73112
construct.ServiceConfig
74113
aws.Config
114+
LegacyConfig
115+
SupportLegacyServices bool
75116
ProvidersCacheExpirationSeconds int64
76117
NoProvidersCacheExpirationSeconds int64
77118
ClaimsCacheExpirationSeconds int64
@@ -90,19 +131,6 @@ type Config struct {
90131
NotifierTopicArn string
91132
ClaimStoreBucket string
92133
ClaimStorePrefix string
93-
LegacyClaimsTableName string
94-
LegacyClaimsTableRegion string
95-
LegacyClaimsBucket string
96-
LegacyBlockIndexTableName string
97-
LegacyBlockIndexTableRegion string
98-
LegacyStoreTableName string
99-
LegacyStoreTableRegion string
100-
LegacyBlobRegistryTableName string
101-
LegacyBlobRegistryTableRegion string
102-
LegacyAllocationsTableName string
103-
LegacyAllocationsTableRegion string
104-
LegacyDotStorageBucketPrefixes []string // legacy .storage buckets
105-
LegacyDataBucketURL string
106134
BaseTraceSampleRatio float64
107135
SentryDSN string
108136
SentryEnvironment string
@@ -177,15 +205,17 @@ func FromEnv(ctx context.Context) Config {
177205
ipniPublisherDirectAnnounceURLs = presets.IPNIAnnounceURLs
178206
}
179207

180-
var legacyDotStorageBucketPrefixes []string
181-
err = json.Unmarshal([]byte(mustGetEnv("LEGACY_DOT_STORAGE_BUCKET_PREFIXES")), &legacyDotStorageBucketPrefixes)
182-
if err != nil {
183-
panic(fmt.Errorf("parsing legacy dot storage bucket prefixes JSON: %w", err))
208+
supportLegacyServices := mustGetEnv("SUPPORT_LEGACY_SERVICES") == "true"
209+
var legacyConfig LegacyConfig
210+
if supportLegacyServices {
211+
legacyConfig = readLegacyConfig()
184212
}
185213

186214
return Config{
187-
Config: awsConfig,
188-
Signer: id,
215+
Config: awsConfig,
216+
SupportLegacyServices: supportLegacyServices,
217+
LegacyConfig: legacyConfig,
218+
Signer: id,
189219
ServiceConfig: construct.ServiceConfig{
190220
ID: id,
191221
PrivateKey: cryptoPrivKey,
@@ -246,19 +276,6 @@ func FromEnv(ctx context.Context) Config {
246276
NotifierHeadBucket: mustGetEnv("NOTIFIER_HEAD_BUCKET_NAME"),
247277
ClaimStoreBucket: mustGetEnv("CLAIM_STORE_BUCKET_NAME"),
248278
ClaimStorePrefix: os.Getenv("CLAIM_STORE_KEY_PREFIX"),
249-
LegacyClaimsTableName: mustGetEnv("LEGACY_CLAIMS_TABLE_NAME"),
250-
LegacyClaimsTableRegion: mustGetEnv("LEGACY_CLAIMS_TABLE_REGION"),
251-
LegacyClaimsBucket: mustGetEnv("LEGACY_CLAIMS_BUCKET_NAME"),
252-
LegacyBlockIndexTableName: mustGetEnv("LEGACY_BLOCK_INDEX_TABLE_NAME"),
253-
LegacyBlockIndexTableRegion: mustGetEnv("LEGACY_BLOCK_INDEX_TABLE_REGION"),
254-
LegacyStoreTableName: mustGetEnv("LEGACY_STORE_TABLE_NAME"),
255-
LegacyStoreTableRegion: mustGetEnv("LEGACY_STORE_TABLE_REGION"),
256-
LegacyBlobRegistryTableName: mustGetEnv("LEGACY_BLOB_REGISTRY_TABLE_NAME"),
257-
LegacyBlobRegistryTableRegion: mustGetEnv("LEGACY_BLOB_REGISTRY_TABLE_REGION"),
258-
LegacyAllocationsTableName: mustGetEnv("LEGACY_ALLOCATIONS_TABLE_NAME"),
259-
LegacyAllocationsTableRegion: mustGetEnv("LEGACY_ALLOCATIONS_TABLE_REGION"),
260-
LegacyDataBucketURL: mustGetEnv("LEGACY_DATA_BUCKET_URL"),
261-
LegacyDotStorageBucketPrefixes: legacyDotStorageBucketPrefixes,
262279
BaseTraceSampleRatio: mustGetFloat("BASE_TRACE_SAMPLE_RATIO"),
263280
SentryDSN: os.Getenv("SENTRY_DSN"),
264281
SentryEnvironment: os.Getenv("SENTRY_ENVIRONMENT"),
@@ -295,59 +312,9 @@ func Construct(cfg Config) (types.Service, error) {
295312

296313
publishingQueue := awspublisherqueue.NewSQSPublishingQueue(cfg.Config, cfg.SQSPublishingQueueID, cfg.PublishingBucket)
297314
queuePublisher := publisherqueue.NewQueuePublisher(publishingQueue)
298-
299-
legacyDataBucketURL, err := url.Parse(cfg.LegacyDataBucketURL)
300-
if err != nil {
301-
return nil, fmt.Errorf("parsing carpark url: %s", err)
302-
}
303-
// legacy claims mapper
304-
legacyClaimsCfg := cfg.Config.Copy()
305-
legacyClaimsCfg.Region = cfg.LegacyClaimsTableRegion
306-
legacyClaimsMapper := NewDynamoContentToClaimsMapper(dynamodb.NewFromConfig(legacyClaimsCfg), cfg.LegacyClaimsTableName)
307-
308-
// bucket fallback mapper
309-
allocationsCfg := cfg.Config.Copy()
310-
allocationsCfg.Region = cfg.LegacyAllocationsTableRegion
311-
legacyAllocationsStore := NewDynamoAllocationsTable(dynamodb.NewFromConfig(allocationsCfg), cfg.LegacyAllocationsTableName)
312-
bucketFallbackMapper := NewBucketFallbackMapper(
313-
cfg.Signer,
314-
httpClient,
315-
legacyDataBucketURL,
316-
legacyAllocationsStore,
317-
func() []delegation.Option {
318-
return []delegation.Option{delegation.WithExpiration(int(time.Now().Add(time.Hour).Unix()))}
319-
},
320-
)
321-
322-
// block index table mapper
323-
blockIndexCfg := cfg.Config.Copy()
324-
blockIndexCfg.Region = cfg.LegacyBlockIndexTableRegion
325-
legacyBlockIndexStore := NewDynamoProviderBlockIndexTable(dynamodb.NewFromConfig(blockIndexCfg), cfg.LegacyBlockIndexTableName)
326-
storeTableCfg := cfg.Config.Copy()
327-
storeTableCfg.Region = cfg.LegacyStoreTableRegion
328-
blobRegistryTableCfg := cfg.Config.Copy()
329-
blobRegistryTableCfg.Region = cfg.LegacyBlobRegistryTableRegion
330-
legacyMigratedShardChecker := NewDynamoMigratedShardChecker(
331-
cfg.LegacyStoreTableName,
332-
dynamodb.NewFromConfig(storeTableCfg),
333-
cfg.LegacyBlobRegistryTableName,
334-
dynamodb.NewFromConfig(blobRegistryTableCfg),
335-
legacyAllocationsStore,
336-
)
337-
// allow claims synthethized from the block index table to live longer after they are expired in the cache
338-
// so that the service doesn't return cached but expired delegations
339-
synthetizedClaimExp := time.Duration(cfg.ClaimsCacheExpirationSeconds)*time.Second + 1*time.Hour
340-
blockIndexTableMapper, err := NewBlockIndexTableMapper(cfg.Signer, legacyBlockIndexStore, legacyMigratedShardChecker, cfg.LegacyDataBucketURL, synthetizedClaimExp, cfg.LegacyDotStorageBucketPrefixes)
341-
if err != nil {
342-
return nil, fmt.Errorf("creating block index table mapper: %w", err)
343-
}
344-
345-
legacyClaimsBucket := contentclaims.NewStoreFromBucket(NewS3Store(legacyClaimsCfg, cfg.LegacyClaimsBucket, ""))
346-
legacyClaimsURL := fmt.Sprintf("https://%s.s3.%s.amazonaws.com/{claim}/{claim}.car", cfg.LegacyClaimsBucket, cfg.Config.Region)
347-
348315
var provIndexLog logging.EventLogger
349316
if cfg.SentryDSN != "" && cfg.SentryEnvironment != "" {
350-
err = sentry.Init(sentry.ClientOptions{
317+
err := sentry.Init(sentry.ClientOptions{
351318
Dsn: cfg.SentryDSN,
352319
Environment: cfg.SentryEnvironment,
353320
Release: build.Version,
@@ -359,26 +326,80 @@ func Construct(cfg Config) (types.Service, error) {
359326
}
360327
provIndexLog = telemetry.NewSentryLogger("providerindex")
361328
}
362-
363-
service, err := construct.Construct(
364-
cfg.ServiceConfig,
329+
opts := []construct.Option{
365330
construct.SkipNotification(),
366331
construct.WithCachingQueue(cachingQueue),
367332
construct.WithPublisherStore(publisherStore),
368333
construct.WithAsyncPublisher(queuePublisher),
369334
construct.WithStartIPNIServer(false),
370335
construct.WithClaimsStore(claimBucketStore),
371-
construct.WithLegacyClaims([]legacy.ContentToClaimsMapper{legacyClaimsMapper, bucketFallbackMapper, blockIndexTableMapper}, legacyClaimsBucket, legacyClaimsURL),
372336
construct.WithHTTPClient(httpClient),
373337
construct.WithProvidersClient(redis.NewClusterClientAdapter(providersClient)),
374338
construct.WithNoProvidersClient(noProvidersClient),
375339
construct.WithClaimsClient(claimsClient),
376340
construct.WithIndexesClient(indexesClient),
377-
construct.WithProvidersCacheOptions(redis.ExpirationTime(time.Duration(cfg.ProvidersCacheExpirationSeconds)*time.Second)),
378-
construct.WithNoProvidersCacheOptions(redis.ExpirationTime(time.Duration(cfg.NoProvidersCacheExpirationSeconds)*time.Second)),
379-
construct.WithClaimsCacheOptions(redis.ExpirationTime(time.Duration(cfg.ClaimsCacheExpirationSeconds)*time.Second)),
380-
construct.WithIndexesCacheOptions(redis.ExpirationTime(time.Duration(cfg.IndexesCacheExpirationSeconds)*time.Second)),
341+
construct.WithProvidersCacheOptions(redis.ExpirationTime(time.Duration(cfg.ProvidersCacheExpirationSeconds) * time.Second)),
342+
construct.WithNoProvidersCacheOptions(redis.ExpirationTime(time.Duration(cfg.NoProvidersCacheExpirationSeconds) * time.Second)),
343+
construct.WithClaimsCacheOptions(redis.ExpirationTime(time.Duration(cfg.ClaimsCacheExpirationSeconds) * time.Second)),
344+
construct.WithIndexesCacheOptions(redis.ExpirationTime(time.Duration(cfg.IndexesCacheExpirationSeconds) * time.Second)),
381345
construct.WithProviderIndexLogger(provIndexLog),
346+
}
347+
348+
if cfg.SupportLegacyServices {
349+
legacyDataBucketURL, err := url.Parse(cfg.LegacyDataBucketURL)
350+
if err != nil {
351+
return nil, fmt.Errorf("parsing carpark url: %s", err)
352+
}
353+
// legacy claims mapper
354+
legacyClaimsCfg := cfg.Config.Copy()
355+
legacyClaimsCfg.Region = cfg.LegacyClaimsTableRegion
356+
legacyClaimsMapper := NewDynamoContentToClaimsMapper(dynamodb.NewFromConfig(legacyClaimsCfg), cfg.LegacyClaimsTableName)
357+
358+
// bucket fallback mapper
359+
allocationsCfg := cfg.Config.Copy()
360+
allocationsCfg.Region = cfg.LegacyAllocationsTableRegion
361+
legacyAllocationsStore := NewDynamoAllocationsTable(dynamodb.NewFromConfig(allocationsCfg), cfg.LegacyAllocationsTableName)
362+
bucketFallbackMapper := NewBucketFallbackMapper(
363+
cfg.Signer,
364+
httpClient,
365+
legacyDataBucketURL,
366+
legacyAllocationsStore,
367+
func() []delegation.Option {
368+
return []delegation.Option{delegation.WithExpiration(int(time.Now().Add(time.Hour).Unix()))}
369+
},
370+
)
371+
372+
// block index table mapper
373+
blockIndexCfg := cfg.Config.Copy()
374+
blockIndexCfg.Region = cfg.LegacyBlockIndexTableRegion
375+
legacyBlockIndexStore := NewDynamoProviderBlockIndexTable(dynamodb.NewFromConfig(blockIndexCfg), cfg.LegacyBlockIndexTableName)
376+
storeTableCfg := cfg.Config.Copy()
377+
storeTableCfg.Region = cfg.LegacyStoreTableRegion
378+
blobRegistryTableCfg := cfg.Config.Copy()
379+
blobRegistryTableCfg.Region = cfg.LegacyBlobRegistryTableRegion
380+
legacyMigratedShardChecker := NewDynamoMigratedShardChecker(
381+
cfg.LegacyStoreTableName,
382+
dynamodb.NewFromConfig(storeTableCfg),
383+
cfg.LegacyBlobRegistryTableName,
384+
dynamodb.NewFromConfig(blobRegistryTableCfg),
385+
legacyAllocationsStore,
386+
)
387+
// allow claims synthethized from the block index table to live longer after they are expired in the cache
388+
// so that the service doesn't return cached but expired delegations
389+
synthetizedClaimExp := time.Duration(cfg.ClaimsCacheExpirationSeconds)*time.Second + 1*time.Hour
390+
blockIndexTableMapper, err := NewBlockIndexTableMapper(cfg.Signer, legacyBlockIndexStore, legacyMigratedShardChecker, cfg.LegacyDataBucketURL, synthetizedClaimExp, cfg.LegacyDotStorageBucketPrefixes)
391+
if err != nil {
392+
return nil, fmt.Errorf("creating block index table mapper: %w", err)
393+
}
394+
395+
legacyClaimsBucket := contentclaims.NewStoreFromBucket(NewS3Store(legacyClaimsCfg, cfg.LegacyClaimsBucket, ""))
396+
legacyClaimsURL := fmt.Sprintf("https://%s.s3.%s.amazonaws.com/{claim}/{claim}.car", cfg.LegacyClaimsBucket, cfg.Config.Region)
397+
opts = append(opts, construct.WithLegacyClaims([]legacy.ContentToClaimsMapper{legacyClaimsMapper, bucketFallbackMapper, blockIndexTableMapper}, legacyClaimsBucket, legacyClaimsURL))
398+
}
399+
400+
service, err := construct.Construct(
401+
cfg.ServiceConfig,
402+
opts...,
382403
)
383404
if err != nil {
384405
return nil, err

0 commit comments

Comments
 (0)