2019-01-24 20:15:10 +00:00
// Copyright (C) 2019 Storj Labs, Inc.
2018-07-26 15:21:35 +01:00
// See LICENSE for copying information.
package main
import (
2018-11-08 13:20:23 +00:00
"context"
2018-08-08 23:22:59 +01:00
"fmt"
2020-03-10 20:42:11 +00:00
"io"
2022-06-26 02:58:30 +01:00
mathrand "math/rand"
2018-07-26 15:21:35 +01:00
"os"
"path/filepath"
2021-10-12 22:05:54 +01:00
"strconv"
2022-05-26 00:31:42 +01:00
"strings"
2021-02-18 16:29:28 +00:00
"sync/atomic"
2018-11-08 13:20:23 +00:00
"text/tabwriter"
2020-01-10 01:12:27 +00:00
"time"
2018-07-26 15:21:35 +01:00
2021-10-12 22:05:54 +01:00
"github.com/spacemonkeygo/monkit/v3"
2018-07-26 15:21:35 +01:00
"github.com/spf13/cobra"
2018-11-15 19:06:09 +00:00
"github.com/zeebo/errs"
2019-01-15 15:02:54 +00:00
"go.uber.org/zap"
2018-10-04 22:40:34 +01:00
2019-12-27 11:48:47 +00:00
"storj.io/common/fpath"
2021-08-12 17:26:43 +01:00
"storj.io/common/lrucache"
2021-02-18 16:01:45 +00:00
"storj.io/common/pb"
"storj.io/common/peertls/tlsopts"
"storj.io/common/rpc"
2019-12-27 11:48:47 +00:00
"storj.io/common/storj"
2021-02-19 17:08:10 +00:00
"storj.io/common/sync2"
2020-03-23 19:18:20 +00:00
"storj.io/private/cfgstruct"
"storj.io/private/process"
2020-09-25 15:47:42 +01:00
_ "storj.io/private/process/googleprofiler" // This attaches google cloud profiler.
2020-03-23 19:30:31 +00:00
"storj.io/private/version"
2019-06-25 21:58:38 +01:00
"storj.io/storj/cmd/satellite/reports"
2021-04-23 14:13:51 +01:00
"storj.io/storj/private/revocation"
2020-04-01 08:12:26 +01:00
_ "storj.io/storj/private/version" // This attaches version information during release builds.
2019-01-23 19:58:44 +00:00
"storj.io/storj/satellite"
2020-12-22 14:56:48 +00:00
"storj.io/storj/satellite/accounting"
2019-10-16 17:50:29 +01:00
"storj.io/storj/satellite/accounting/live"
2020-03-10 20:42:11 +00:00
"storj.io/storj/satellite/compensation"
2021-05-13 09:14:18 +01:00
"storj.io/storj/satellite/metabase"
2023-07-07 09:31:58 +01:00
"storj.io/storj/satellite/nodeselection"
2023-04-06 12:41:14 +01:00
"storj.io/storj/satellite/payments/stripe"
2018-12-05 09:35:50 +00:00
"storj.io/storj/satellite/satellitedb"
2018-07-26 15:21:35 +01:00
)
2020-07-16 15:18:02 +01:00
// Satellite defines satellite configuration.
2019-01-07 09:48:16 +00:00
type Satellite struct {
2019-10-18 20:03:10 +01:00
Database string ` help:"satellite database connection string" releaseDefault:"postgres://" devDefault:"postgres://" `
2019-01-23 19:58:44 +00:00
2020-01-10 01:12:27 +00:00
DatabaseOptions struct {
APIKeysCache struct {
Expiration time . Duration ` help:"satellite database api key expiration" default:"60s" `
2023-03-13 15:34:28 +00:00
Capacity int ` help:"satellite database api key lru capacity" default:"10000" `
2020-01-10 01:12:27 +00:00
}
2020-06-03 14:51:02 +01:00
RevocationsCache struct {
Expiration time . Duration ` help:"macaroon revocation cache expiration" default:"5m" `
Capacity int ` help:"macaroon revocation cache capacity" default:"10000" `
}
2022-10-05 14:57:38 +01:00
MigrationUnsafe string ` help:"comma separated migration types to run during every startup (none: no migration, snapshot: creating db from latest test snapshot (for testing only), testdata: create testuser in addition to a migration, full: do the normal migration (equals to 'satellite run migration'" default:"none" hidden:"true" `
2020-01-10 01:12:27 +00:00
}
2019-01-23 19:58:44 +00:00
satellite . Config
2019-01-07 09:48:16 +00:00
}
2020-07-16 15:18:02 +01:00
// APIKeysLRUOptions returns a cache.Options based on the APIKeys LRU config.
2021-04-23 13:59:10 +01:00
func ( s * Satellite ) APIKeysLRUOptions ( ) lrucache . Options {
return lrucache . Options {
2020-01-10 01:12:27 +00:00
Expiration : s . DatabaseOptions . APIKeysCache . Expiration ,
Capacity : s . DatabaseOptions . APIKeysCache . Capacity ,
}
}
2020-07-16 15:18:02 +01:00
// RevocationLRUOptions returns a cache.Options based on the Revocations LRU config.
2021-04-23 13:59:10 +01:00
func ( s * Satellite ) RevocationLRUOptions ( ) lrucache . Options {
return lrucache . Options {
2020-06-03 14:51:02 +01:00
Expiration : s . DatabaseOptions . RevocationsCache . Expiration ,
Capacity : s . DatabaseOptions . RevocationsCache . Capacity ,
}
}
2018-07-26 15:21:35 +01:00
var (
rootCmd = & cobra . Command {
2018-08-29 19:32:41 +01:00
Use : "satellite" ,
Short : "Satellite" ,
2018-07-26 15:21:35 +01:00
}
2018-07-30 08:38:31 +01:00
runCmd = & cobra . Command {
Use : "run" ,
2018-08-29 19:32:41 +01:00
Short : "Run the satellite" ,
2018-07-30 08:38:31 +01:00
RunE : cmdRun ,
}
2019-11-02 20:09:07 +00:00
runMigrationCmd = & cobra . Command {
Use : "migration" ,
Short : "Run the satellite database migration" ,
RunE : cmdMigrationRun ,
}
2019-10-16 21:34:25 +01:00
runAPICmd = & cobra . Command {
Use : "api" ,
Short : "Run the satellite API" ,
RunE : cmdAPIRun ,
}
2023-05-17 19:18:54 +01:00
runUICmd = & cobra . Command {
Use : "ui" ,
Short : "Run the satellite UI" ,
RunE : cmdUIRun ,
}
2019-10-29 14:55:57 +00:00
runRepairerCmd = & cobra . Command {
Use : "repair" ,
Short : "Run the repair service" ,
RunE : cmdRepairerRun ,
}
2022-10-12 21:33:31 +01:00
runAuditorCmd = & cobra . Command {
Use : "auditor" ,
Short : "Run the auditor service" ,
RunE : cmdAuditorRun ,
}
2020-02-07 15:56:59 +00:00
runAdminCmd = & cobra . Command {
Use : "admin" ,
Short : "Run the satellite Admin" ,
RunE : cmdAdminRun ,
}
2020-03-12 15:40:22 +00:00
runGCCmd = & cobra . Command {
Use : "garbage-collection" ,
Short : "Run the satellite garbage collection process" ,
RunE : cmdGCRun ,
}
2022-08-29 15:16:48 +01:00
runGCBloomFilterCmd = & cobra . Command {
Use : "garbage-collection-bloom-filters" ,
Short : "Run the satellite process which collects nodes bloom filters for garbage collection" ,
RunE : cmdGCBloomFilterRun ,
}
2022-10-26 08:02:13 +01:00
runRangedLoopCmd = & cobra . Command {
Use : "ranged-loop" ,
Short : "Run the satellite segments ranged loop" ,
RunE : cmdRangedLoopRun ,
}
2018-07-30 08:38:31 +01:00
setupCmd = & cobra . Command {
2018-12-14 21:14:59 +00:00
Use : "setup" ,
Short : "Create config files" ,
RunE : cmdSetup ,
Annotations : map [ string ] string { "type" : "setup" } ,
2018-07-30 08:38:31 +01:00
}
2018-11-16 13:31:33 +00:00
qdiagCmd = & cobra . Command {
Use : "qdiag" ,
2022-04-19 10:22:05 +01:00
Short : "Repair queue Diagnostic Tool support" ,
2018-11-16 13:31:33 +00:00
RunE : cmdQDiag ,
}
2019-01-30 21:44:50 +00:00
reportsCmd = & cobra . Command {
Use : "reports" ,
Short : "Generate a report" ,
}
2019-02-27 21:55:19 +00:00
nodeUsageCmd = & cobra . Command {
Use : "storagenode-usage [start] [end]" ,
Short : "Generate a node usage report for a given period to use for payments" ,
2019-12-19 15:59:52 +00:00
Long : "Generate a node usage report for a given period to use for payments. Format dates using YYYY-MM-DD. The end date is exclusive." ,
2019-01-30 21:44:50 +00:00
Args : cobra . MinimumNArgs ( 2 ) ,
2019-02-27 21:55:19 +00:00
RunE : cmdNodeUsage ,
2019-01-30 21:44:50 +00:00
}
2019-06-25 21:58:38 +01:00
partnerAttributionCmd = & cobra . Command {
2022-05-26 00:31:42 +01:00
Use : "partner-attribution [start] [end] [user-agent,...]" ,
2019-06-25 21:58:38 +01:00
Short : "Generate a partner attribution report for a given period to use for payments" ,
2022-05-26 00:31:42 +01:00
Long : "Generate a partner attribution report for a given period to use for payments. Format dates using YYYY-MM-DD. The end date is exclusive. Optionally filter using a comma-separated list of user agents." ,
2022-01-20 21:15:13 +00:00
Args : cobra . MinimumNArgs ( 2 ) ,
2019-06-25 21:58:38 +01:00
RunE : cmdValueAttribution ,
}
2021-01-14 15:57:04 +00:00
reportsGracefulExitCmd = & cobra . Command {
2019-10-23 02:06:01 +01:00
Use : "graceful-exit [start] [end]" ,
Short : "Generate a graceful exit report" ,
2019-12-19 15:59:52 +00:00
Long : "Generate a node usage report for a given period to use for payments. Format dates using YYYY-MM-DD. The end date is exclusive." ,
2019-10-23 02:06:01 +01:00
Args : cobra . MinimumNArgs ( 2 ) ,
2021-01-14 15:57:04 +00:00
RunE : cmdReportsGracefulExit ,
2019-10-23 02:06:01 +01:00
}
2021-01-14 15:57:04 +00:00
reportsVerifyGEReceiptCmd = & cobra . Command {
2019-12-03 22:09:39 +00:00
Use : "verify-exit-receipt [storage node ID] [receipt]" ,
Short : "Verify a graceful exit receipt" ,
Long : "Verify a graceful exit receipt is valid." ,
Args : cobra . MinimumNArgs ( 2 ) ,
2021-01-14 15:57:04 +00:00
RunE : reportsVerifyGEReceipt ,
2019-12-03 22:09:39 +00:00
}
2020-03-10 20:42:11 +00:00
compensationCmd = & cobra . Command {
Use : "compensation" ,
Short : "Storage Node Compensation commands" ,
}
generateInvoicesCmd = & cobra . Command {
Use : "generate-invoices [period]" ,
Short : "Generate storage node invoices" ,
Long : "Generate storage node invoices for a pay period. Period is a UTC date formatted like YYYY-MM." ,
Args : cobra . ExactArgs ( 1 ) ,
RunE : cmdGenerateInvoices ,
}
recordPeriodCmd = & cobra . Command {
Use : "record-period [paystubs-csv] [payments-csv]" ,
Short : "Record storage node pay period" ,
Long : "Record storage node paystubs and payments for a pay period" ,
Args : cobra . ExactArgs ( 2 ) ,
RunE : cmdRecordPeriod ,
}
recordOneOffPaymentsCmd = & cobra . Command {
Use : "record-one-off-payments [payments-csv]" ,
Short : "Record one-off storage node payments" ,
Long : "Record one-off storage node payments outside of a pay period" ,
Args : cobra . ExactArgs ( 1 ) ,
RunE : cmdRecordOneOffPayments ,
}
2020-05-18 13:21:35 +01:00
billingCmd = & cobra . Command {
Use : "billing" ,
Short : "Customer billing commands" ,
}
2021-07-30 23:11:36 +01:00
applyFreeTierCouponsCmd = & cobra . Command {
Use : "apply-free-coupons" ,
Short : "Applies free tier coupon to Stripe customers" ,
Long : "Applies free tier coupon to Stripe customers without a coupon" ,
RunE : cmdApplyFreeTierCoupons ,
}
2023-06-27 23:51:02 +01:00
setInvoiceStatusCmd = & cobra . Command {
Use : "set-invoice-status [start-period] [end-period] [status]" ,
Short : "set all open invoices status" ,
Long : "set all open invoices in the specified date ranges to the provided status. Period is a UTC date formatted like YYYY-MM." ,
Args : cobra . ExactArgs ( 3 ) ,
RunE : cmdSetInvoiceStatus ,
}
createCustomerBalanceInvoiceItemsCmd = & cobra . Command {
2023-04-20 21:51:19 +01:00
Use : "create-balance-invoice-items" ,
Short : "Creates stripe invoice line items for stripe customer balance" ,
Long : "Creates stripe invoice line items for stripe customer balances obtained from past invoices and other miscellaneous charges." ,
RunE : cmdCreateCustomerBalanceInvoiceItems ,
}
2020-05-18 13:21:35 +01:00
prepareCustomerInvoiceRecordsCmd = & cobra . Command {
Use : "prepare-invoice-records [period]" ,
Short : "Prepares invoice project records" ,
Long : "Prepares invoice project records that will be used during invoice line items creation." ,
Args : cobra . ExactArgs ( 1 ) ,
RunE : cmdPrepareCustomerInvoiceRecords ,
}
2022-05-10 20:19:53 +01:00
createCustomerProjectInvoiceItemsCmd = & cobra . Command {
Use : "create-project-invoice-items [period]" ,
Short : "Creates stripe invoice line items for project charges" ,
2020-05-18 13:21:35 +01:00
Long : "Creates stripe invoice line items for not consumed project records." ,
Args : cobra . ExactArgs ( 1 ) ,
2022-05-10 20:19:53 +01:00
RunE : cmdCreateCustomerProjectInvoiceItems ,
}
2020-05-18 13:21:35 +01:00
createCustomerInvoicesCmd = & cobra . Command {
Use : "create-invoices [period]" ,
Short : "Creates stripe invoices from pending invoice items" ,
Long : "Creates stripe invoices for all stripe customers known to satellite" ,
Args : cobra . ExactArgs ( 1 ) ,
RunE : cmdCreateCustomerInvoices ,
}
2022-09-27 09:48:38 +01:00
generateCustomerInvoicesCmd = & cobra . Command {
Use : "generate-invoices [period]" ,
Short : "Performs all tasks necessary to generate Stripe invoices" ,
Long : "Performs all tasks necessary to generate Stripe invoices. Equivalent to running apply-free-coupons, prepare-invoice-records, create-project-invoice-items, and create-invoices in order. Does not finalize invoices." ,
Args : cobra . ExactArgs ( 1 ) ,
RunE : cmdGenerateCustomerInvoices ,
}
2020-06-09 16:27:02 +01:00
finalizeCustomerInvoicesCmd = & cobra . Command {
Use : "finalize-invoices" ,
Short : "Finalizes all draft stripe invoices" ,
2020-06-12 09:39:40 +01:00
Long : "Finalizes all draft stripe invoices known to satellite's stripe account." ,
2020-06-09 16:27:02 +01:00
RunE : cmdFinalizeCustomerInvoices ,
}
2023-07-07 18:39:31 +01:00
payInvoicesWithTokenCmd = & cobra . Command {
Use : "pay-customer-invoices" ,
Short : "pay open finalized invoices for customer" ,
Long : "attempts payment on any open finalized invoices for a specific user." ,
Args : cobra . ExactArgs ( 1 ) ,
RunE : cmdPayCustomerInvoices ,
}
payAllInvoicesCmd = & cobra . Command {
2022-09-13 00:16:17 +01:00
Use : "pay-invoices" ,
Short : "pay finalized invoices" ,
Long : "attempts payment on all open finalized invoices according to subscriptions settings." ,
2022-10-04 15:18:59 +01:00
Args : cobra . ExactArgs ( 1 ) ,
2023-07-07 18:39:31 +01:00
RunE : cmdPayAllInvoices ,
2022-09-13 00:16:17 +01:00
}
2020-06-12 09:39:40 +01:00
stripeCustomerCmd = & cobra . Command {
Use : "ensure-stripe-customer" ,
Short : "Ensures that we have a stripe customer for every user" ,
Long : "Ensures that we have a stripe customer for every satellite user." ,
RunE : cmdStripeCustomer ,
}
2021-01-14 15:57:04 +00:00
consistencyCmd = & cobra . Command {
Use : "consistency" ,
Short : "Readdress DB consistency issues" ,
Long : "Readdress DB consistency issues and perform data cleanups for improving the DB performance." ,
}
consistencyGECleanupCmd = & cobra . Command {
Use : "ge-cleanup-orphaned-data" ,
Short : "Cleanup Graceful Exit orphaned data" ,
Long : "Cleanup Graceful Exit data which is lingering in the transfer queue DB table on nodes which has finished the exit." ,
RunE : cmdConsistencyGECleanup ,
}
2021-02-18 15:33:49 +00:00
restoreTrashCmd = & cobra . Command {
Use : "restore-trash [node-id-1 node-id-2 node-id-3 ...]" ,
Short : "Restore trash" ,
Long : "Tell storage nodes to undo garbage collection. " +
"If node ids aren't provided, *all* nodes are used." ,
RunE : cmdRestoreTrash ,
}
2021-10-12 22:05:54 +01:00
registerLostSegments = & cobra . Command {
Use : "register-lost-segments [number_of_segments_lost]" ,
Short : "Register permanently lost segments for our statistics" ,
Long : "Send metric information through monkit indicating the (permanent) loss of some number of segments. Temporarily unavailable segments are reported automatically by the repair checker and do not need to be reported here." ,
Args : cobra . ExactArgs ( 1 ) ,
RunE : cmdRegisterLostSegments ,
}
2022-02-13 04:19:29 +00:00
fetchPiecesCmd = & cobra . Command {
Use : "fetch-pieces <stream-id> <position> <output-dir>" ,
Short : "Retrieve pieces of a segment from all responding nodes" ,
Args : cobra . ExactArgs ( 3 ) ,
RunE : cmdFetchPieces ,
}
2022-10-28 13:53:12 +01:00
repairSegmentCmd = & cobra . Command {
2022-11-21 09:41:32 +00:00
Use : "repair-segment <csv-file> or <stream-id> <position>" ,
2022-10-28 13:53:12 +01:00
Short : "Repair segment and verify all downloadable pieces" ,
2022-11-21 09:41:32 +00:00
Args : cobra . RangeArgs ( 1 , 2 ) ,
2022-10-28 13:53:12 +01:00
RunE : cmdRepairSegment ,
}
2023-03-09 16:28:16 +00:00
fixLastNetsCmd = & cobra . Command {
Use : "fix-last-nets" ,
Short : "Fix last_net entries in the database for satellites with DistinctIP=false" ,
RunE : cmdFixLastNets ,
}
2019-12-03 22:09:39 +00:00
2019-01-07 09:48:16 +00:00
runCfg Satellite
2019-01-07 11:06:10 +00:00
setupCfg Satellite
2019-01-07 09:48:16 +00:00
2018-11-16 13:31:33 +00:00
qdiagCfg struct {
2019-10-18 20:03:10 +01:00
Database string ` help:"satellite database connection string" releaseDefault:"postgres://" devDefault:"postgres://" `
2018-12-21 15:11:19 +00:00
QListLimit int ` help:"maximum segments that can be requested" default:"1000" `
2018-11-16 13:31:33 +00:00
}
2019-02-27 21:55:19 +00:00
nodeUsageCfg struct {
2019-10-18 20:03:10 +01:00
Database string ` help:"satellite database connection string" releaseDefault:"postgres://" devDefault:"postgres://" `
2019-01-30 21:44:50 +00:00
Output string ` help:"destination of report output" default:"" `
}
2020-03-10 20:42:11 +00:00
generateInvoicesCfg struct {
Database string ` help:"satellite database connection string" releaseDefault:"postgres://" devDefault:"postgres://" `
Output string ` help:"destination of report output" default:"" `
Compensation compensation . Config
2020-03-31 23:43:17 +01:00
SurgePercent int64 ` help:"surge percent for payments" default:"0" `
2020-03-10 20:42:11 +00:00
}
recordPeriodCfg struct {
Database string ` help:"satellite database connection string" releaseDefault:"postgres://" devDefault:"postgres://" `
}
recordOneOffPaymentsCfg struct {
Database string ` help:"satellite database connection string" releaseDefault:"postgres://" devDefault:"postgres://" `
}
2019-06-25 21:58:38 +01:00
partnerAttribtionCfg struct {
2019-10-18 20:03:10 +01:00
Database string ` help:"satellite database connection string" releaseDefault:"postgres://" devDefault:"postgres://" `
2019-06-25 21:58:38 +01:00
Output string ` help:"destination of report output" default:"" `
}
2021-01-14 15:57:04 +00:00
reportsGracefulExitCfg struct {
2019-12-03 22:09:39 +00:00
Database string ` help:"satellite database connection string" releaseDefault:"postgres://" devDefault:"postgres://" `
2019-10-23 02:06:01 +01:00
Output string ` help:"destination of report output" default:"" `
Completed bool ` help:"whether to output (initiated and completed) or (initiated and not completed)" default:"false" `
}
2021-01-14 15:57:04 +00:00
reportsVerifyGracefulExitReceiptCfg struct {
}
consistencyGECleanupCfg struct {
Database string ` help:"satellite database connection string" releaseDefault:"postgres://" devDefault:"postgres://" `
Before string ` help:"select only exited nodes before this UTC date formatted like YYYY-MM. Date cannot be newer than the current time (required)" `
2019-12-03 22:09:39 +00:00
}
2023-06-27 23:51:02 +01:00
setInvoiceStatusCfg struct {
DryRun bool ` help:"do not update stripe" default:"false" `
}
2021-01-14 15:57:04 +00:00
2019-03-12 12:51:06 +00:00
confDir string
identityDir string
2018-07-26 15:21:35 +01:00
)
func init ( ) {
2019-03-12 12:51:06 +00:00
defaultConfDir := fpath . ApplicationDir ( "storj" , "satellite" )
defaultIdentityDir := fpath . ApplicationDir ( "storj" , "identity" , "satellite" )
cfgstruct . SetupFlag ( zap . L ( ) , rootCmd , & confDir , "config-dir" , defaultConfDir , "main directory for satellite configuration" )
cfgstruct . SetupFlag ( zap . L ( ) , rootCmd , & identityDir , "identity-dir" , defaultIdentityDir , "main directory for satellite identity credentials" )
2019-04-19 19:17:30 +01:00
defaults := cfgstruct . DefaultsFlag ( rootCmd )
2018-07-30 08:38:31 +01:00
rootCmd . AddCommand ( runCmd )
2019-11-02 20:09:07 +00:00
runCmd . AddCommand ( runMigrationCmd )
2019-10-16 21:34:25 +01:00
runCmd . AddCommand ( runAPICmd )
2023-05-17 19:18:54 +01:00
runCmd . AddCommand ( runUICmd )
2020-02-07 15:56:59 +00:00
runCmd . AddCommand ( runAdminCmd )
2019-10-29 14:55:57 +00:00
runCmd . AddCommand ( runRepairerCmd )
2022-10-12 21:33:31 +01:00
runCmd . AddCommand ( runAuditorCmd )
2020-03-12 15:40:22 +00:00
runCmd . AddCommand ( runGCCmd )
2022-08-29 15:16:48 +01:00
runCmd . AddCommand ( runGCBloomFilterCmd )
2022-10-26 08:02:13 +01:00
runCmd . AddCommand ( runRangedLoopCmd )
2018-07-30 08:38:31 +01:00
rootCmd . AddCommand ( setupCmd )
2018-11-16 13:31:33 +00:00
rootCmd . AddCommand ( qdiagCmd )
2019-01-30 21:44:50 +00:00
rootCmd . AddCommand ( reportsCmd )
2020-03-10 20:42:11 +00:00
rootCmd . AddCommand ( compensationCmd )
2020-05-18 13:21:35 +01:00
rootCmd . AddCommand ( billingCmd )
2021-01-14 15:57:04 +00:00
rootCmd . AddCommand ( consistencyCmd )
2021-02-18 15:33:49 +00:00
rootCmd . AddCommand ( restoreTrashCmd )
2021-10-12 22:05:54 +01:00
rootCmd . AddCommand ( registerLostSegments )
2022-02-13 04:19:29 +00:00
rootCmd . AddCommand ( fetchPiecesCmd )
2022-10-28 13:53:12 +01:00
rootCmd . AddCommand ( repairSegmentCmd )
2023-03-09 16:28:16 +00:00
rootCmd . AddCommand ( fixLastNetsCmd )
2019-02-27 21:55:19 +00:00
reportsCmd . AddCommand ( nodeUsageCmd )
2019-06-25 21:58:38 +01:00
reportsCmd . AddCommand ( partnerAttributionCmd )
2021-01-14 15:57:04 +00:00
reportsCmd . AddCommand ( reportsGracefulExitCmd )
reportsCmd . AddCommand ( reportsVerifyGEReceiptCmd )
2020-03-10 20:42:11 +00:00
compensationCmd . AddCommand ( generateInvoicesCmd )
compensationCmd . AddCommand ( recordPeriodCmd )
compensationCmd . AddCommand ( recordOneOffPaymentsCmd )
2021-07-30 23:11:36 +01:00
billingCmd . AddCommand ( applyFreeTierCouponsCmd )
2023-06-27 23:51:02 +01:00
billingCmd . AddCommand ( setInvoiceStatusCmd )
billingCmd . AddCommand ( createCustomerBalanceInvoiceItemsCmd )
2020-05-18 13:21:35 +01:00
billingCmd . AddCommand ( prepareCustomerInvoiceRecordsCmd )
2022-05-10 20:19:53 +01:00
billingCmd . AddCommand ( createCustomerProjectInvoiceItemsCmd )
2020-05-18 13:21:35 +01:00
billingCmd . AddCommand ( createCustomerInvoicesCmd )
2022-09-27 09:48:38 +01:00
billingCmd . AddCommand ( generateCustomerInvoicesCmd )
2020-06-09 16:27:02 +01:00
billingCmd . AddCommand ( finalizeCustomerInvoicesCmd )
2023-07-07 18:39:31 +01:00
billingCmd . AddCommand ( payInvoicesWithTokenCmd )
billingCmd . AddCommand ( payAllInvoicesCmd )
2020-06-12 09:39:40 +01:00
billingCmd . AddCommand ( stripeCustomerCmd )
2021-01-14 15:57:04 +00:00
consistencyCmd . AddCommand ( consistencyGECleanupCmd )
Command line flags features and cleanup (#2068)
* change BindSetup to be an option to Bind
* add process.Bind to allow composite structures
* hack fix for noprefix flags
* used tagged version of structs
Before this PR, some flags were created by calling `cfgstruct.Bind` and having their fields create a flag. Once the flags were parsed, `viper` was used to acquire all the values from them and config files, and the fields in the struct were set through the flag interface.
This doesn't work for slices of things on config structs very well, since it can only set strings, and for a string slice, it turns out that the implementation in `pflag` appends an entry rather than setting it.
This changes three things:
1. Only have a `Bind` call instead of `Bind` and `BindSetup`, and make `BindSetup` an option instead.
2. Add a `process.Bind` call that takes in a `*cobra.Cmd`, binds the struct to the command's flags, and keeps track of that struct in a global map keyed by the command.
3. Use `viper` to get the values and load them into the bound configuration structs instead of using the flags to propagate the changes.
In this way, we can support whatever rich configuration we want in the config yaml files, while still getting command like flags when important.
2019-05-29 18:56:22 +01:00
process . Bind ( runCmd , & runCfg , defaults , cfgstruct . ConfDir ( confDir ) , cfgstruct . IdentityDir ( identityDir ) )
2019-11-02 20:09:07 +00:00
process . Bind ( runMigrationCmd , & runCfg , defaults , cfgstruct . ConfDir ( confDir ) , cfgstruct . IdentityDir ( identityDir ) )
2019-10-16 21:34:25 +01:00
process . Bind ( runAPICmd , & runCfg , defaults , cfgstruct . ConfDir ( confDir ) , cfgstruct . IdentityDir ( identityDir ) )
2023-05-17 19:18:54 +01:00
process . Bind ( runUICmd , & runCfg , defaults , cfgstruct . ConfDir ( confDir ) , cfgstruct . IdentityDir ( identityDir ) )
2020-02-07 15:56:59 +00:00
process . Bind ( runAdminCmd , & runCfg , defaults , cfgstruct . ConfDir ( confDir ) , cfgstruct . IdentityDir ( identityDir ) )
2019-10-29 14:55:57 +00:00
process . Bind ( runRepairerCmd , & runCfg , defaults , cfgstruct . ConfDir ( confDir ) , cfgstruct . IdentityDir ( identityDir ) )
2022-10-12 21:33:31 +01:00
process . Bind ( runAuditorCmd , & runCfg , defaults , cfgstruct . ConfDir ( confDir ) , cfgstruct . IdentityDir ( identityDir ) )
2020-03-12 15:40:22 +00:00
process . Bind ( runGCCmd , & runCfg , defaults , cfgstruct . ConfDir ( confDir ) , cfgstruct . IdentityDir ( identityDir ) )
2022-08-29 15:16:48 +01:00
process . Bind ( runGCBloomFilterCmd , & runCfg , defaults , cfgstruct . ConfDir ( confDir ) , cfgstruct . IdentityDir ( identityDir ) )
2022-10-26 08:02:13 +01:00
process . Bind ( runRangedLoopCmd , & runCfg , defaults , cfgstruct . ConfDir ( confDir ) , cfgstruct . IdentityDir ( identityDir ) )
2021-02-18 15:33:49 +00:00
process . Bind ( restoreTrashCmd , & runCfg , defaults , cfgstruct . ConfDir ( confDir ) , cfgstruct . IdentityDir ( identityDir ) )
2021-10-12 22:05:54 +01:00
process . Bind ( registerLostSegments , & runCfg , defaults , cfgstruct . ConfDir ( confDir ) , cfgstruct . IdentityDir ( identityDir ) )
2022-02-13 04:19:29 +00:00
process . Bind ( fetchPiecesCmd , & runCfg , defaults , cfgstruct . ConfDir ( confDir ) , cfgstruct . IdentityDir ( identityDir ) )
2022-11-15 10:02:14 +00:00
process . Bind ( repairSegmentCmd , & runCfg , defaults , cfgstruct . ConfDir ( confDir ) , cfgstruct . IdentityDir ( identityDir ) )
Command line flags features and cleanup (#2068)
* change BindSetup to be an option to Bind
* add process.Bind to allow composite structures
* hack fix for noprefix flags
* used tagged version of structs
Before this PR, some flags were created by calling `cfgstruct.Bind` and having their fields create a flag. Once the flags were parsed, `viper` was used to acquire all the values from them and config files, and the fields in the struct were set through the flag interface.
This doesn't work for slices of things on config structs very well, since it can only set strings, and for a string slice, it turns out that the implementation in `pflag` appends an entry rather than setting it.
This changes three things:
1. Only have a `Bind` call instead of `Bind` and `BindSetup`, and make `BindSetup` an option instead.
2. Add a `process.Bind` call that takes in a `*cobra.Cmd`, binds the struct to the command's flags, and keeps track of that struct in a global map keyed by the command.
3. Use `viper` to get the values and load them into the bound configuration structs instead of using the flags to propagate the changes.
In this way, we can support whatever rich configuration we want in the config yaml files, while still getting command like flags when important.
2019-05-29 18:56:22 +01:00
process . Bind ( setupCmd , & setupCfg , defaults , cfgstruct . ConfDir ( confDir ) , cfgstruct . IdentityDir ( identityDir ) , cfgstruct . SetupMode ( ) )
process . Bind ( qdiagCmd , & qdiagCfg , defaults , cfgstruct . ConfDir ( confDir ) , cfgstruct . IdentityDir ( identityDir ) )
process . Bind ( nodeUsageCmd , & nodeUsageCfg , defaults , cfgstruct . ConfDir ( confDir ) , cfgstruct . IdentityDir ( identityDir ) )
2020-03-10 20:42:11 +00:00
process . Bind ( generateInvoicesCmd , & generateInvoicesCfg , defaults , cfgstruct . ConfDir ( confDir ) , cfgstruct . IdentityDir ( identityDir ) )
process . Bind ( recordPeriodCmd , & recordPeriodCfg , defaults , cfgstruct . ConfDir ( confDir ) , cfgstruct . IdentityDir ( identityDir ) )
process . Bind ( recordOneOffPaymentsCmd , & recordOneOffPaymentsCfg , defaults , cfgstruct . ConfDir ( confDir ) , cfgstruct . IdentityDir ( identityDir ) )
2021-01-14 15:57:04 +00:00
process . Bind ( reportsGracefulExitCmd , & reportsGracefulExitCfg , defaults , cfgstruct . ConfDir ( confDir ) , cfgstruct . IdentityDir ( identityDir ) )
process . Bind ( reportsVerifyGEReceiptCmd , & reportsVerifyGracefulExitReceiptCfg , defaults , cfgstruct . ConfDir ( confDir ) , cfgstruct . IdentityDir ( identityDir ) )
2019-06-25 21:58:38 +01:00
process . Bind ( partnerAttributionCmd , & partnerAttribtionCfg , defaults , cfgstruct . ConfDir ( confDir ) , cfgstruct . IdentityDir ( identityDir ) )
2021-07-30 23:11:36 +01:00
process . Bind ( applyFreeTierCouponsCmd , & runCfg , defaults , cfgstruct . ConfDir ( confDir ) , cfgstruct . IdentityDir ( identityDir ) )
2023-06-27 23:51:02 +01:00
process . Bind ( setInvoiceStatusCmd , & runCfg , defaults , cfgstruct . ConfDir ( confDir ) , cfgstruct . IdentityDir ( identityDir ) )
process . Bind ( setInvoiceStatusCmd , & setInvoiceStatusCfg , defaults , cfgstruct . ConfDir ( confDir ) , cfgstruct . IdentityDir ( identityDir ) )
process . Bind ( createCustomerBalanceInvoiceItemsCmd , & runCfg , defaults , cfgstruct . ConfDir ( confDir ) , cfgstruct . IdentityDir ( identityDir ) )
2020-05-18 13:21:35 +01:00
process . Bind ( prepareCustomerInvoiceRecordsCmd , & runCfg , defaults , cfgstruct . ConfDir ( confDir ) , cfgstruct . IdentityDir ( identityDir ) )
2022-05-10 20:19:53 +01:00
process . Bind ( createCustomerProjectInvoiceItemsCmd , & runCfg , defaults , cfgstruct . ConfDir ( confDir ) , cfgstruct . IdentityDir ( identityDir ) )
2020-05-18 13:21:35 +01:00
process . Bind ( createCustomerInvoicesCmd , & runCfg , defaults , cfgstruct . ConfDir ( confDir ) , cfgstruct . IdentityDir ( identityDir ) )
2022-09-27 09:48:38 +01:00
process . Bind ( generateCustomerInvoicesCmd , & runCfg , defaults , cfgstruct . ConfDir ( confDir ) , cfgstruct . IdentityDir ( identityDir ) )
2020-06-09 16:27:02 +01:00
process . Bind ( finalizeCustomerInvoicesCmd , & runCfg , defaults , cfgstruct . ConfDir ( confDir ) , cfgstruct . IdentityDir ( identityDir ) )
2023-07-07 18:39:31 +01:00
process . Bind ( payInvoicesWithTokenCmd , & runCfg , defaults , cfgstruct . ConfDir ( confDir ) , cfgstruct . IdentityDir ( identityDir ) )
process . Bind ( payAllInvoicesCmd , & runCfg , defaults , cfgstruct . ConfDir ( confDir ) , cfgstruct . IdentityDir ( identityDir ) )
2020-06-12 09:39:40 +01:00
process . Bind ( stripeCustomerCmd , & runCfg , defaults , cfgstruct . ConfDir ( confDir ) , cfgstruct . IdentityDir ( identityDir ) )
2021-01-14 15:57:04 +00:00
process . Bind ( consistencyGECleanupCmd , & consistencyGECleanupCfg , defaults , cfgstruct . ConfDir ( confDir ) , cfgstruct . IdentityDir ( identityDir ) )
2023-03-09 16:28:16 +00:00
process . Bind ( fixLastNetsCmd , & runCfg , defaults , cfgstruct . ConfDir ( confDir ) , cfgstruct . IdentityDir ( identityDir ) )
2021-01-14 15:57:04 +00:00
if err := consistencyGECleanupCmd . MarkFlagRequired ( "before" ) ; err != nil {
panic ( err )
}
2018-07-26 15:21:35 +01:00
}
func cmdRun ( cmd * cobra . Command , args [ ] string ) ( err error ) {
2019-04-04 16:40:07 +01:00
// inert constructors only ====
2019-09-19 17:37:40 +01:00
ctx , _ := process . Ctx ( cmd )
2019-01-23 19:58:44 +00:00
log := zap . L ( )
2020-01-28 17:35:45 +00:00
runCfg . Debug . Address = * process . DebugAddrFlag
2019-01-25 14:54:54 +00:00
identity , err := runCfg . Identity . Load ( )
2019-01-23 19:58:44 +00:00
if err != nil {
2020-10-13 14:49:33 +01:00
log . Error ( "Failed to load identity." , zap . Error ( err ) )
return errs . New ( "Failed to load identity: %+v" , err )
2019-01-22 12:35:48 +00:00
}
2018-12-05 09:35:50 +00:00
2020-10-28 13:48:31 +00:00
db , err := satellitedb . Open ( ctx , log . Named ( "db" ) , runCfg . Database , satellitedb . Options {
2021-01-22 13:51:29 +00:00
ApplicationName : "satellite-core" ,
SaveRollupBatchSize : runCfg . Tally . SaveRollupBatchSize ,
ReadRollupBatchSize : runCfg . Tally . ReadRollupBatchSize ,
2020-01-15 21:45:17 +00:00
} )
2018-12-05 09:35:50 +00:00
if err != nil {
return errs . New ( "Error starting master database on satellite: %+v" , err )
}
2019-10-10 19:06:26 +01:00
defer func ( ) {
err = errs . Combine ( err , db . Close ( ) )
} ( )
2019-01-24 20:28:06 +00:00
2022-10-28 15:56:20 +01:00
metabaseDB , err := metabase . Open ( ctx , log . Named ( "metabase" ) , runCfg . Metainfo . DatabaseURL ,
runCfg . Config . Metainfo . Metabase ( "satellite-core" ) )
2020-10-29 16:54:35 +00:00
if err != nil {
return errs . New ( "Error creating metabase connection: %+v" , err )
}
defer func ( ) {
err = errs . Combine ( err , metabaseDB . Close ( ) )
} ( )
2020-10-28 14:01:41 +00:00
revocationDB , err := revocation . OpenDBFromCfg ( ctx , runCfg . Server . Config )
2019-08-19 23:10:38 +01:00
if err != nil {
return errs . New ( "Error creating revocation database: %+v" , err )
}
2019-08-20 16:04:17 +01:00
defer func ( ) {
err = errs . Combine ( err , revocationDB . Close ( ) )
} ( )
2019-08-19 23:10:38 +01:00
2021-03-24 19:22:50 +00:00
liveAccounting , err := live . OpenCache ( ctx , log . Named ( "live-accounting" ) , runCfg . LiveAccounting )
2019-10-16 17:50:29 +01:00
if err != nil {
2020-12-22 14:56:48 +00:00
if ! accounting . ErrSystemOrNetError . Has ( err ) || liveAccounting == nil {
return errs . New ( "Error instantiating live accounting cache: %w" , err )
}
log . Warn ( "Unable to connect to live accounting cache. Verify connection" ,
zap . Error ( err ) ,
)
2019-10-16 17:50:29 +01:00
}
defer func ( ) {
err = errs . Combine ( err , liveAccounting . Close ( ) )
} ( )
2023-03-07 09:29:25 +00:00
peer , err := satellite . New ( log , identity , db , metabaseDB , revocationDB , liveAccounting , version . Build , & runCfg . Config , process . AtomicLevel ( cmd ) )
2018-12-05 09:35:50 +00:00
if err != nil {
2019-04-04 16:40:07 +01:00
return err
2018-12-05 09:35:50 +00:00
}
2019-01-23 19:58:44 +00:00
2019-04-04 16:40:07 +01:00
// okay, start doing stuff ====
2020-02-21 17:41:54 +00:00
_ , err = peer . Version . Service . CheckVersion ( ctx )
2019-01-23 19:58:44 +00:00
if err != nil {
return err
2019-01-15 15:02:54 +00:00
}
2018-12-05 09:35:50 +00:00
2019-07-31 15:38:44 +01:00
if err := process . InitMetricsWithCertPath ( ctx , log , nil , runCfg . Identity . CertPath ) ; err != nil {
2020-04-13 10:31:17 +01:00
log . Warn ( "Failed to initialize telemetry batcher" , zap . Error ( err ) )
2019-04-04 16:40:07 +01:00
}
2020-12-22 10:38:32 +00:00
err = metabaseDB . CheckVersion ( ctx )
2020-04-24 20:15:27 +01:00
if err != nil {
2020-12-22 10:38:32 +00:00
log . Error ( "Failed metabase database version check." , zap . Error ( err ) )
return errs . New ( "failed metabase version check: %+v" , err )
2020-10-29 16:54:35 +00:00
}
2020-01-13 13:44:55 +00:00
err = db . CheckVersion ( ctx )
2019-11-02 20:09:07 +00:00
if err != nil {
2020-10-13 14:49:33 +01:00
log . Error ( "Failed satellite database version check." , zap . Error ( err ) )
2019-11-02 20:09:07 +00:00
return errs . New ( "Error checking version for satellitedb: %+v" , err )
}
2019-01-23 19:58:44 +00:00
runError := peer . Run ( ctx )
closeError := peer . Close ( )
2019-01-30 05:22:58 +00:00
return errs . Combine ( runError , closeError )
2018-07-26 15:21:35 +01:00
}
2019-11-02 20:09:07 +00:00
func cmdMigrationRun ( cmd * cobra . Command , args [ ] string ) ( err error ) {
2020-01-13 13:31:09 +00:00
ctx , _ := process . Ctx ( cmd )
2019-11-02 20:09:07 +00:00
log := zap . L ( )
2020-01-13 13:31:09 +00:00
2020-12-04 10:24:39 +00:00
db , err := satellitedb . Open ( ctx , log . Named ( "migration" ) , runCfg . Database , satellitedb . Options { ApplicationName : "satellite-migration" } )
2019-11-02 20:09:07 +00:00
if err != nil {
2019-11-04 19:01:02 +00:00
return errs . New ( "Error creating new master database connection for satellitedb migration: %+v" , err )
2019-11-02 20:09:07 +00:00
}
defer func ( ) {
err = errs . Combine ( err , db . Close ( ) )
} ( )
2020-04-30 07:36:59 +01:00
err = db . MigrateToLatest ( ctx )
2019-11-02 20:09:07 +00:00
if err != nil {
return errs . New ( "Error creating tables for master database on satellite: %+v" , err )
}
2019-12-05 20:42:12 +00:00
2022-10-28 15:56:20 +01:00
metabaseDB , err := metabase . Open ( ctx , log . Named ( "metabase" ) , runCfg . Metainfo . DatabaseURL ,
runCfg . Config . Metainfo . Metabase ( "satellite-migration" ) )
2020-11-05 13:30:39 +00:00
if err != nil {
return errs . New ( "Error creating metabase connection: %+v" , err )
}
defer func ( ) {
err = errs . Combine ( err , metabaseDB . Close ( ) )
} ( )
err = metabaseDB . MigrateToLatest ( ctx )
if err != nil {
return errs . New ( "Error creating metabase tables: %+v" , err )
}
2019-11-02 20:09:07 +00:00
return nil
}
2018-07-26 15:21:35 +01:00
func cmdSetup ( cmd * cobra . Command , args [ ] string ) ( err error ) {
2019-01-22 12:35:48 +00:00
setupDir , err := filepath . Abs ( confDir )
2018-08-13 19:29:13 +01:00
if err != nil {
return err
}
2019-01-14 15:57:58 +00:00
valid , _ := fpath . IsValidSetupDir ( setupDir )
if ! valid {
return fmt . Errorf ( "satellite configuration already exists (%v)" , setupDir )
2018-08-08 23:22:59 +01:00
}
2018-12-14 21:14:59 +00:00
err = os . MkdirAll ( setupDir , 0700 )
2018-07-26 15:21:35 +01:00
if err != nil {
return err
}
2019-08-05 18:01:20 +01:00
return process . SaveConfig ( cmd , filepath . Join ( setupDir , "config.yaml" ) )
2018-07-26 15:21:35 +01:00
}
2018-11-16 13:31:33 +00:00
func cmdQDiag ( cmd * cobra . Command , args [ ] string ) ( err error ) {
2020-10-28 13:48:31 +00:00
ctx , _ := process . Ctx ( cmd )
2018-11-16 13:31:33 +00:00
2018-12-21 15:11:19 +00:00
// open the master db
2020-12-04 10:24:39 +00:00
database , err := satellitedb . Open ( ctx , zap . L ( ) . Named ( "db" ) , qdiagCfg . Database , satellitedb . Options { ApplicationName : "satellite-qdiag" } )
2018-11-16 13:31:33 +00:00
if err != nil {
2018-12-21 15:11:19 +00:00
return errs . New ( "error connecting to master database on satellite: %+v" , err )
2018-11-16 13:31:33 +00:00
}
2018-12-21 15:11:19 +00:00
defer func ( ) {
err := database . Close ( )
if err != nil {
fmt . Printf ( "error closing connection to master database on satellite: %+v\n" , err )
}
} ( )
2018-11-16 13:31:33 +00:00
2019-04-16 19:14:09 +01:00
list , err := database . RepairQueue ( ) . SelectN ( context . Background ( ) , qdiagCfg . QListLimit )
2018-11-16 13:31:33 +00:00
if err != nil {
return err
}
// initialize the table header (fields)
const padding = 3
w := tabwriter . NewWriter ( os . Stdout , 0 , 0 , padding , ' ' , tabwriter . AlignRight | tabwriter . Debug )
2021-06-17 16:05:04 +01:00
fmt . Fprintln ( w , "Segment StreamID\tSegment Position\tSegment Health\t" )
2018-11-16 13:31:33 +00:00
// populate the row fields
for _ , v := range list {
2021-06-17 16:05:04 +01:00
fmt . Fprint ( w , v . StreamID . String ( ) , "\t" , v . Position . Encode ( ) , "\t" , v . SegmentHealth , "\t" )
2018-11-16 13:31:33 +00:00
}
// display the data
return w . Flush ( )
2018-11-08 13:20:23 +00:00
}
2021-01-14 15:57:04 +00:00
func reportsVerifyGEReceipt ( cmd * cobra . Command , args [ ] string ) ( err error ) {
2019-12-03 22:09:39 +00:00
ctx , _ := process . Ctx ( cmd )
identity , err := runCfg . Identity . Load ( )
if err != nil {
2020-04-13 10:31:17 +01:00
zap . L ( ) . Fatal ( "Failed to load identity." , zap . Error ( err ) )
2019-12-03 22:09:39 +00:00
}
// Check the node ID is valid
nodeID , err := storj . NodeIDFromString ( args [ 0 ] )
if err != nil {
return errs . Combine ( err , errs . New ( "Invalid node ID." ) )
}
return verifyGracefulExitReceipt ( ctx , identity , nodeID , args [ 1 ] )
}
2021-01-14 15:57:04 +00:00
func cmdReportsGracefulExit ( cmd * cobra . Command , args [ ] string ) ( err error ) {
2019-10-23 02:06:01 +01:00
ctx , _ := process . Ctx ( cmd )
2019-12-19 15:59:52 +00:00
start , end , err := reports . ParseRange ( args [ 0 ] , args [ 1 ] )
2019-10-23 02:06:01 +01:00
if err != nil {
2019-12-19 15:59:52 +00:00
return err
2019-10-23 02:06:01 +01:00
}
// send output to stdout
2021-01-14 15:57:04 +00:00
if reportsGracefulExitCfg . Output == "" {
return generateGracefulExitCSV ( ctx , reportsGracefulExitCfg . Completed , start , end , os . Stdout )
2019-10-23 02:06:01 +01:00
}
// send output to file
2021-01-14 15:57:04 +00:00
file , err := os . Create ( reportsGracefulExitCfg . Output )
2019-10-23 02:06:01 +01:00
if err != nil {
return err
}
defer func ( ) {
err = errs . Combine ( err , file . Close ( ) )
} ( )
2021-01-14 15:57:04 +00:00
return generateGracefulExitCSV ( ctx , reportsGracefulExitCfg . Completed , start , end , file )
2019-10-23 02:06:01 +01:00
}
2019-02-27 21:55:19 +00:00
func cmdNodeUsage ( cmd * cobra . Command , args [ ] string ) ( err error ) {
2019-09-19 17:37:40 +01:00
ctx , _ := process . Ctx ( cmd )
2019-01-30 21:44:50 +00:00
2019-12-19 15:59:52 +00:00
start , end , err := reports . ParseRange ( args [ 0 ] , args [ 1 ] )
2019-01-30 21:44:50 +00:00
if err != nil {
2019-12-19 15:59:52 +00:00
return err
2019-01-30 21:44:50 +00:00
}
// send output to stdout
2019-02-27 21:55:19 +00:00
if nodeUsageCfg . Output == "" {
2019-10-23 02:06:01 +01:00
return generateNodeUsageCSV ( ctx , start , end , os . Stdout )
2019-01-30 21:44:50 +00:00
}
// send output to file
2019-02-27 21:55:19 +00:00
file , err := os . Create ( nodeUsageCfg . Output )
2019-01-30 21:44:50 +00:00
if err != nil {
return err
}
defer func ( ) {
err = errs . Combine ( err , file . Close ( ) )
} ( )
2019-10-23 02:06:01 +01:00
return generateNodeUsageCSV ( ctx , start , end , file )
2019-01-30 21:44:50 +00:00
}
2020-03-10 20:42:11 +00:00
func cmdGenerateInvoices ( cmd * cobra . Command , args [ ] string ) ( err error ) {
ctx , _ := process . Ctx ( cmd )
period , err := compensation . PeriodFromString ( args [ 0 ] )
if err != nil {
return err
}
if err := runWithOutput ( generateInvoicesCfg . Output , func ( out io . Writer ) error {
return generateInvoicesCSV ( ctx , period , out )
} ) ; err != nil {
return err
}
if generateInvoicesCfg . Output != "" {
fmt . Println ( "Generated invoices" )
}
return nil
}
func cmdRecordPeriod ( cmd * cobra . Command , args [ ] string ) ( err error ) {
ctx , _ := process . Ctx ( cmd )
paystubsCount , paymentsCount , err := recordPeriod ( ctx , args [ 0 ] , args [ 1 ] )
if err != nil {
return err
}
fmt . Println ( paystubsCount , "paystubs recorded" )
fmt . Println ( paymentsCount , "payments recorded" )
return nil
}
func cmdRecordOneOffPayments ( cmd * cobra . Command , args [ ] string ) ( err error ) {
ctx , _ := process . Ctx ( cmd )
count , err := recordOneOffPayments ( ctx , args [ 0 ] )
if err != nil {
return err
}
fmt . Println ( count , "payments recorded" )
return nil
}
2019-06-25 21:58:38 +01:00
func cmdValueAttribution ( cmd * cobra . Command , args [ ] string ) ( err error ) {
2019-09-19 17:37:40 +01:00
ctx , _ := process . Ctx ( cmd )
2019-06-25 21:58:38 +01:00
log := zap . L ( ) . Named ( "satellite-cli" )
2020-04-02 13:30:43 +01:00
2022-03-16 15:50:04 +00:00
start , end , err := reports . ParseRange ( args [ 0 ] , args [ 1 ] )
2019-06-25 21:58:38 +01:00
if err != nil {
2019-12-19 15:59:52 +00:00
return err
2019-06-25 21:58:38 +01:00
}
2022-05-26 00:31:42 +01:00
var userAgents [ ] string
if len ( args ) > 2 {
userAgents = strings . Split ( args [ 2 ] , "," )
}
2019-06-25 21:58:38 +01:00
// send output to stdout
if partnerAttribtionCfg . Output == "" {
2022-05-26 00:31:42 +01:00
return reports . GenerateAttributionCSV ( ctx , partnerAttribtionCfg . Database , start , end , userAgents , os . Stdout )
2019-06-25 21:58:38 +01:00
}
// send output to file
file , err := os . Create ( partnerAttribtionCfg . Output )
if err != nil {
return err
}
defer func ( ) {
err = errs . Combine ( err , file . Close ( ) )
if err != nil {
2020-04-13 10:31:17 +01:00
log . Error ( "Error closing the output file after retrieving partner value attribution data." ,
zap . String ( "Output File" , partnerAttribtionCfg . Output ) ,
zap . Error ( err ) ,
)
2019-06-25 21:58:38 +01:00
}
} ( )
2022-05-26 00:31:42 +01:00
return reports . GenerateAttributionCSV ( ctx , partnerAttribtionCfg . Database , start , end , userAgents , file )
2019-06-25 21:58:38 +01:00
}
2023-06-27 23:51:02 +01:00
// cmdSetInvoiceStatus sets the status of all open invoices within the provided period to the provided status.
// args[0] is the start of the period in YYYY-MM format.
// args[1] is the end of the period in YYYY-MM format.
// args[2] is the status to set the invoices to.
func cmdSetInvoiceStatus ( cmd * cobra . Command , args [ ] string ) ( err error ) {
ctx , _ := process . Ctx ( cmd )
periodStart , err := parseYearMonth ( args [ 0 ] )
if err != nil {
return err
}
periodEnd , err := parseYearMonth ( args [ 1 ] )
if err != nil {
return err
}
// parseYearMonth returns the first day of the month, but we want the period end to be the last day of the month
periodEnd = periodEnd . AddDate ( 0 , 1 , - 1 )
return runBillingCmd ( ctx , func ( ctx context . Context , payments * stripe . Service , _ satellite . DB ) error {
return payments . SetInvoiceStatus ( ctx , periodStart , periodEnd , args [ 2 ] , setInvoiceStatusCfg . DryRun )
} )
}
2023-04-20 21:51:19 +01:00
func cmdCreateCustomerBalanceInvoiceItems ( cmd * cobra . Command , _ [ ] string ) ( err error ) {
ctx , _ := process . Ctx ( cmd )
return runBillingCmd ( ctx , func ( ctx context . Context , payments * stripe . Service , _ satellite . DB ) error {
return payments . CreateBalanceInvoiceItems ( ctx )
} )
}
2020-06-09 15:46:00 +01:00
func cmdPrepareCustomerInvoiceRecords ( cmd * cobra . Command , args [ ] string ) ( err error ) {
ctx , _ := process . Ctx ( cmd )
2022-10-04 15:18:59 +01:00
periodStart , err := parseYearMonth ( args [ 0 ] )
2020-06-12 15:47:16 +01:00
if err != nil {
2022-10-04 15:18:59 +01:00
return err
2020-06-12 15:47:16 +01:00
}
2023-04-06 12:41:14 +01:00
return runBillingCmd ( ctx , func ( ctx context . Context , payments * stripe . Service , _ satellite . DB ) error {
2022-10-04 15:18:59 +01:00
return payments . PrepareInvoiceProjectRecords ( ctx , periodStart )
2020-06-12 15:47:16 +01:00
} )
2020-05-18 13:21:35 +01:00
}
2022-05-10 20:19:53 +01:00
func cmdCreateCustomerProjectInvoiceItems ( cmd * cobra . Command , args [ ] string ) ( err error ) {
2020-05-18 13:21:35 +01:00
ctx , _ := process . Ctx ( cmd )
2022-10-04 15:18:59 +01:00
periodStart , err := parseYearMonth ( args [ 0 ] )
2020-06-12 15:47:16 +01:00
if err != nil {
2022-10-04 15:18:59 +01:00
return err
2020-06-12 15:47:16 +01:00
}
2023-04-06 12:41:14 +01:00
return runBillingCmd ( ctx , func ( ctx context . Context , payments * stripe . Service , _ satellite . DB ) error {
2022-10-04 15:18:59 +01:00
return payments . InvoiceApplyProjectRecords ( ctx , periodStart )
2020-06-12 15:47:16 +01:00
} )
2020-05-18 13:21:35 +01:00
}
func cmdCreateCustomerInvoices ( cmd * cobra . Command , args [ ] string ) ( err error ) {
ctx , _ := process . Ctx ( cmd )
2022-10-04 15:18:59 +01:00
periodStart , err := parseYearMonth ( args [ 0 ] )
2020-06-12 15:47:16 +01:00
if err != nil {
2022-10-04 15:18:59 +01:00
return err
2020-06-12 15:47:16 +01:00
}
2023-04-06 12:41:14 +01:00
return runBillingCmd ( ctx , func ( ctx context . Context , payments * stripe . Service , _ satellite . DB ) error {
2022-10-04 15:18:59 +01:00
return payments . CreateInvoices ( ctx , periodStart )
2020-06-12 15:47:16 +01:00
} )
2020-05-18 13:21:35 +01:00
}
2022-09-27 09:48:38 +01:00
func cmdGenerateCustomerInvoices ( cmd * cobra . Command , args [ ] string ) ( err error ) {
ctx , _ := process . Ctx ( cmd )
2022-10-04 15:18:59 +01:00
periodStart , err := parseYearMonth ( args [ 0 ] )
2022-09-27 09:48:38 +01:00
if err != nil {
2022-10-04 15:18:59 +01:00
return err
2022-09-27 09:48:38 +01:00
}
2023-04-06 12:41:14 +01:00
return runBillingCmd ( ctx , func ( ctx context . Context , payments * stripe . Service , _ satellite . DB ) error {
2022-10-04 15:18:59 +01:00
return payments . GenerateInvoices ( ctx , periodStart )
2022-09-27 09:48:38 +01:00
} )
}
2020-06-09 16:27:02 +01:00
func cmdFinalizeCustomerInvoices ( cmd * cobra . Command , args [ ] string ) ( err error ) {
ctx , _ := process . Ctx ( cmd )
2023-04-06 12:41:14 +01:00
return runBillingCmd ( ctx , func ( ctx context . Context , payments * stripe . Service , _ satellite . DB ) error {
2020-06-12 15:47:16 +01:00
return payments . FinalizeInvoices ( ctx )
} )
2020-06-09 16:27:02 +01:00
}
2022-09-13 00:16:17 +01:00
func cmdPayCustomerInvoices ( cmd * cobra . Command , args [ ] string ) ( err error ) {
ctx , _ := process . Ctx ( cmd )
2023-07-07 18:39:31 +01:00
return runBillingCmd ( ctx , func ( ctx context . Context , payments * stripe . Service , _ satellite . DB ) error {
err := payments . InvoiceApplyCustomerTokenBalance ( ctx , args [ 0 ] )
if err != nil {
return errs . New ( "error applying native token payments to invoice for customer: %v" , err )
}
return payments . PayCustomerInvoices ( ctx , args [ 0 ] )
} )
}
func cmdPayAllInvoices ( cmd * cobra . Command , args [ ] string ) ( err error ) {
ctx , _ := process . Ctx ( cmd )
2022-10-04 15:18:59 +01:00
periodStart , err := parseYearMonth ( args [ 0 ] )
2022-09-28 18:41:41 +01:00
if err != nil {
2022-10-04 15:18:59 +01:00
return err
2022-09-28 18:41:41 +01:00
}
2023-04-06 12:41:14 +01:00
return runBillingCmd ( ctx , func ( ctx context . Context , payments * stripe . Service , _ satellite . DB ) error {
2022-10-04 15:18:59 +01:00
err := payments . InvoiceApplyTokenBalance ( ctx , periodStart )
2022-09-13 00:16:17 +01:00
if err != nil {
return errs . New ( "error applying native token payments: %v" , err )
}
2022-10-04 15:18:59 +01:00
return payments . PayInvoices ( ctx , periodStart )
2022-09-13 00:16:17 +01:00
} )
}
2020-06-12 09:39:40 +01:00
func cmdStripeCustomer ( cmd * cobra . Command , args [ ] string ) ( err error ) {
ctx , _ := process . Ctx ( cmd )
return generateStripeCustomers ( ctx )
}
2021-01-14 15:57:04 +00:00
func cmdConsistencyGECleanup ( cmd * cobra . Command , args [ ] string ) error {
ctx , _ := process . Ctx ( cmd )
before , err := time . Parse ( "2006-01-02" , consistencyGECleanupCfg . Before )
if err != nil {
return errs . New ( "before flag value isn't of the expected format. %+v" , err )
}
if before . After ( time . Now ( ) ) {
return errs . New ( "before flag value cannot be newer than the current time." )
}
2021-02-10 18:09:49 +00:00
return cleanupGEOrphanedData ( ctx , before . UTC ( ) , runCfg . GracefulExit )
2021-01-14 15:57:04 +00:00
}
2021-02-18 15:33:49 +00:00
func cmdRestoreTrash ( cmd * cobra . Command , args [ ] string ) error {
ctx , _ := process . Ctx ( cmd )
log := zap . L ( )
db , err := satellitedb . Open ( ctx , log . Named ( "restore-trash" ) , runCfg . Database , satellitedb . Options { ApplicationName : "satellite-restore-trash" } )
if err != nil {
return errs . New ( "Error creating new master database connection: %+v" , err )
}
defer func ( ) {
err = errs . Combine ( err , db . Close ( ) )
} ( )
2021-02-18 16:01:45 +00:00
identity , err := runCfg . Identity . Load ( )
if err != nil {
log . Error ( "Failed to load identity." , zap . Error ( err ) )
return errs . New ( "Failed to load identity: %+v" , err )
}
revocationDB , err := revocation . OpenDBFromCfg ( ctx , runCfg . Server . Config )
if err != nil {
return errs . New ( "Error creating revocation database: %+v" , err )
}
defer func ( ) {
err = errs . Combine ( err , revocationDB . Close ( ) )
} ( )
tlsOptions , err := tlsopts . NewOptions ( identity , runCfg . Server . Config , revocationDB )
if err != nil {
return err
}
dialer := rpc . NewDefaultDialer ( tlsOptions )
2021-02-18 16:29:28 +00:00
successes := new ( int64 )
failures := new ( int64 )
2023-07-07 09:31:58 +01:00
undelete := func ( node * nodeselection . SelectedNode ) {
2021-02-18 16:29:28 +00:00
log . Info ( "starting restore trash" , zap . String ( "Node ID" , node . ID . String ( ) ) )
2021-02-18 16:01:45 +00:00
2022-06-26 02:58:30 +01:00
ctx , cancel := context . WithTimeout ( ctx , 10 * time . Second )
defer cancel ( )
2021-02-18 16:01:45 +00:00
conn , err := dialer . DialNodeURL ( ctx , storj . NodeURL {
ID : node . ID ,
2021-02-18 16:29:28 +00:00
Address : node . Address . Address ,
2021-02-18 16:01:45 +00:00
} )
if err != nil {
2021-02-18 16:29:28 +00:00
atomic . AddInt64 ( failures , 1 )
2021-02-18 16:01:45 +00:00
log . Error ( "unable to connect" , zap . String ( "Node ID" , node . ID . String ( ) ) , zap . Error ( err ) )
2021-02-18 16:29:28 +00:00
return
2021-02-18 16:01:45 +00:00
}
2021-02-18 18:25:28 +00:00
defer func ( ) {
err := conn . Close ( )
if err != nil {
log . Error ( "close failure" , zap . String ( "Node ID" , node . ID . String ( ) ) , zap . Error ( err ) )
}
} ( )
2021-02-18 16:01:45 +00:00
client := pb . NewDRPCPiecestoreClient ( conn )
_ , err = client . RestoreTrash ( ctx , & pb . RestoreTrashRequest { } )
if err != nil {
2021-02-18 16:29:28 +00:00
atomic . AddInt64 ( failures , 1 )
2021-02-18 16:01:45 +00:00
log . Error ( "unable to restore trash" , zap . String ( "Node ID" , node . ID . String ( ) ) , zap . Error ( err ) )
2021-02-18 16:29:28 +00:00
return
2021-02-18 16:01:45 +00:00
}
2021-02-18 16:29:28 +00:00
atomic . AddInt64 ( successes , 1 )
2021-02-18 16:01:45 +00:00
log . Info ( "successful restore trash" , zap . String ( "Node ID" , node . ID . String ( ) ) )
2021-02-18 16:29:28 +00:00
}
2023-07-07 09:31:58 +01:00
var nodes [ ] * nodeselection . SelectedNode
2021-02-18 15:33:49 +00:00
if len ( args ) == 0 {
2023-07-07 09:31:58 +01:00
err = db . OverlayCache ( ) . IterateAllContactedNodes ( ctx , func ( ctx context . Context , node * nodeselection . SelectedNode ) error {
2021-02-18 15:33:49 +00:00
nodes = append ( nodes , node )
return nil
} )
if err != nil {
return err
}
} else {
for _ , nodeid := range args {
parsedNodeID , err := storj . NodeIDFromString ( nodeid )
if err != nil {
return err
}
dossier , err := db . OverlayCache ( ) . Get ( ctx , parsedNodeID )
if err != nil {
return err
}
2023-07-07 09:31:58 +01:00
nodes = append ( nodes , & nodeselection . SelectedNode {
2021-02-18 15:33:49 +00:00
ID : dossier . Id ,
Address : dossier . Address ,
LastNet : dossier . LastNet ,
LastIPPort : dossier . LastIPPort ,
2021-02-19 17:08:10 +00:00
} )
2021-02-18 15:33:49 +00:00
}
}
2022-06-26 02:58:30 +01:00
mathrand . Shuffle ( len ( nodes ) , func ( i , j int ) {
nodes [ i ] , nodes [ j ] = nodes [ j ] , nodes [ i ]
} )
2021-02-19 17:08:10 +00:00
limiter := sync2 . NewLimiter ( 100 )
for _ , node := range nodes {
node := node
limiter . Go ( ctx , func ( ) { undelete ( node ) } )
}
limiter . Wait ( )
2021-02-18 16:29:28 +00:00
log . Sugar ( ) . Infof ( "restore trash complete. %d successes, %d failures" , * successes , * failures )
2021-02-18 15:33:49 +00:00
return nil
}
2021-10-12 22:05:54 +01:00
func cmdRegisterLostSegments ( cmd * cobra . Command , args [ ] string ) error {
ctx , _ := process . Ctx ( cmd )
log := zap . L ( )
numLostSegments , err := strconv . Atoi ( args [ 0 ] )
if err != nil {
log . Fatal ( "invalid numeric argument" , zap . String ( "argument" , args [ 0 ] ) )
}
if err := process . InitMetricsWithCertPath ( ctx , log , nil , runCfg . Identity . CertPath ) ; err != nil {
log . Fatal ( "Failed to initialize telemetry batcher" , zap . Error ( err ) )
}
2021-12-28 00:46:43 +00:00
scope := monkit . Default . ScopeNamed ( "segment_durability" )
scope . Meter ( "lost_segments" ) . Mark ( numLostSegments )
2021-10-12 22:05:54 +01:00
if err := process . Report ( ctx ) ; err != nil {
log . Fatal ( "could not send telemetry" , zap . Error ( err ) )
}
// we can't actually tell whether metrics is really enabled at this point;
// process.InitMetrics...() can return a nil error while disabling metrics
// entirely. make sure that's clear to the user.
log . Info ( "lost segment event(s) sent (if metrics are actually enabled)" , zap . Int ( "lost-segments" , numLostSegments ) )
return nil
}
2023-03-09 16:28:16 +00:00
func cmdFixLastNets ( cmd * cobra . Command , _ [ ] string ) ( err error ) {
ctx , _ := process . Ctx ( cmd )
log := zap . L ( )
if runCfg . Overlay . Node . DistinctIP {
log . Info ( "No fix necessary; DistinctIP=true" )
return nil
}
db , err := satellitedb . Open ( ctx , log . Named ( "db" ) , runCfg . Database , satellitedb . Options {
ApplicationName : "satellite-fix-last-nets" ,
} )
if err != nil {
return fmt . Errorf ( "error opening master database: %w" , err )
}
defer func ( ) {
err = errs . Combine ( err , db . Close ( ) )
} ( )
return db . OverlayCache ( ) . OneTimeFixLastNets ( ctx )
}
2018-07-26 15:21:35 +01:00
func main ( ) {
2020-01-28 17:35:45 +00:00
process . ExecCustomDebug ( rootCmd )
2018-07-26 15:21:35 +01:00
}