diff --git a/cmd/inspector/main.go b/cmd/inspector/main.go index c46e9c95b..536096399 100644 --- a/cmd/inspector/main.go +++ b/cmd/inspector/main.go @@ -13,7 +13,6 @@ import ( "os" "strconv" "strings" - "time" "github.com/spf13/cobra" "github.com/zeebo/errs" @@ -82,50 +81,15 @@ var ( Args: cobra.MinimumNArgs(4), RunE: SegmentHealth, } - paymentsCmd = &cobra.Command{ - Use: "payments", - Short: "commands for payments", - } - prepareInvoiceRecordsCmd = &cobra.Command{ - Use: "prepare-invoice-records ", - Short: "Prepares invoice project records that will be used during invoice line items creation", - Args: cobra.MinimumNArgs(1), - RunE: prepareInvoiceRecords, - } - createInvoiceItemsCmd = &cobra.Command{ - Use: "create-invoice-items ", - Short: "Creates stripe invoice line items for not consumed project records", - Args: cobra.MinimumNArgs(1), - RunE: createInvoiceItems, - } - createInvoiceCouponsCmd = &cobra.Command{ - Use: "create-invoice-coupons ", - Short: "Creates stripe invoice line items for not consumed coupons", - Args: cobra.MinimumNArgs(1), - RunE: createInvoiceCoupons, - } - createInvoiceCreditsCmd = &cobra.Command{ - Use: "create-invoice-credits ", - Short: "Creates stripe invoice line items for not consumed credits", - Args: cobra.MinimumNArgs(1), - RunE: createInvoiceCredits, - } - createInvoicesCmd = &cobra.Command{ - Use: "create-invoices ", - Short: "Creates stripe invoices for all stripe customers known to satellite", - Args: cobra.MinimumNArgs(1), - RunE: createInvoices, - } ) // Inspector gives access to overlay. type Inspector struct { - conn *rpc.Conn - identity *identity.FullIdentity - overlayclient pb.DRPCOverlayInspectorClient - irrdbclient pb.DRPCIrreparableInspectorClient - healthclient pb.DRPCHealthInspectorClient - paymentsClient pb.DRPCPaymentsClient + conn *rpc.Conn + identity *identity.FullIdentity + overlayclient pb.DRPCOverlayInspectorClient + irrdbclient pb.DRPCIrreparableInspectorClient + healthclient pb.DRPCHealthInspectorClient } // NewInspector creates a new inspector client for access to overlay. @@ -144,12 +108,11 @@ func NewInspector(ctx context.Context, address, path string) (*Inspector, error) } return &Inspector{ - conn: conn, - identity: id, - overlayclient: pb.NewDRPCOverlayInspectorClient(conn), - irrdbclient: pb.NewDRPCIrreparableInspectorClient(conn), - healthclient: pb.NewDRPCHealthInspectorClient(conn), - paymentsClient: pb.NewDRPCPaymentsClient(conn), + conn: conn, + identity: id, + overlayclient: pb.NewDRPCOverlayInspectorClient(conn), + irrdbclient: pb.NewDRPCIrreparableInspectorClient(conn), + healthclient: pb.NewDRPCHealthInspectorClient(conn), }, nil } @@ -466,181 +429,14 @@ func sortSegments(segments []*pb.IrreparableSegment) map[string][]*pb.Irreparabl return objects } -func prepareInvoiceRecords(cmd *cobra.Command, args []string) error { - ctx, _ := process.Ctx(cmd) - i, err := NewInspector(ctx, *Addr, *IdentityPath) - if err != nil { - return ErrInspectorDial.Wrap(err) - } - - defer func() { err = errs.Combine(err, i.Close()) }() - - period, err := parseDateString(args[0]) - if err != nil { - return ErrArgs.New("invalid period specified: %v", err) - } - - _, err = i.paymentsClient.PrepareInvoiceRecords(ctx, - &pb.PrepareInvoiceRecordsRequest{ - Period: period, - }, - ) - if err != nil { - return err - } - - fmt.Println("successfully created invoice project records") - return nil -} - -func createInvoiceItems(cmd *cobra.Command, args []string) error { - ctx, _ := process.Ctx(cmd) - i, err := NewInspector(ctx, *Addr, *IdentityPath) - if err != nil { - return ErrInspectorDial.Wrap(err) - } - - defer func() { err = errs.Combine(err, i.Close()) }() - - period, err := parseDateString(args[0]) - if err != nil { - return ErrArgs.New("invalid period specified: %v", err) - } - - _, err = i.paymentsClient.ApplyInvoiceRecords(ctx, - &pb.ApplyInvoiceRecordsRequest{ - Period: period, - }, - ) - if err != nil { - return err - } - - fmt.Println("successfully created invoice line items") - return nil -} - -func createInvoiceCoupons(cmd *cobra.Command, args []string) error { - ctx, _ := process.Ctx(cmd) - i, err := NewInspector(ctx, *Addr, *IdentityPath) - if err != nil { - return ErrInspectorDial.Wrap(err) - } - - defer func() { err = errs.Combine(err, i.Close()) }() - - period, err := parseDateString(args[0]) - if err != nil { - return ErrArgs.New("invalid period specified: %v", err) - } - - _, err = i.paymentsClient.ApplyInvoiceCoupons(ctx, - &pb.ApplyInvoiceCouponsRequest{ - Period: period, - }, - ) - if err != nil { - return err - } - - fmt.Println("successfully created invoice coupon line items") - return nil -} - -func createInvoiceCredits(cmd *cobra.Command, args []string) error { - ctx, _ := process.Ctx(cmd) - i, err := NewInspector(ctx, *Addr, *IdentityPath) - if err != nil { - return ErrInspectorDial.Wrap(err) - } - - defer func() { err = errs.Combine(err, i.Close()) }() - - period, err := parseDateString(args[0]) - if err != nil { - return ErrArgs.New("invalid period specified: %v", err) - } - - _, err = i.paymentsClient.ApplyInvoiceCredits(ctx, - &pb.ApplyInvoiceCreditsRequest{ - Period: period, - }, - ) - if err != nil { - return err - } - - fmt.Println("successfully created invoice credits line items") - return nil -} - -func createInvoices(cmd *cobra.Command, args []string) error { - ctx, _ := process.Ctx(cmd) - i, err := NewInspector(ctx, *Addr, *IdentityPath) - if err != nil { - return ErrInspectorDial.Wrap(err) - } - - defer func() { err = errs.Combine(err, i.Close()) }() - - period, err := parseDateString(args[0]) - if err != nil { - return ErrArgs.New("invalid period specified: %v", err) - } - - _, err = i.paymentsClient.CreateInvoices(ctx, - &pb.CreateInvoicesRequest{ - Period: period, - }, - ) - if err != nil { - return err - } - - fmt.Println("successfully created invoices") - return nil -} - -// parseDateString parses provided date string and returns corresponding time.Time. -func parseDateString(s string) (time.Time, error) { - values := strings.Split(s, "/") - - if len(values) != 2 { - return time.Time{}, errs.New("invalid date format %s, use mm/yyyy", s) - } - - month, err := strconv.ParseInt(values[0], 10, 64) - if err != nil { - return time.Time{}, errs.New("can not parse month: %v", err) - } - year, err := strconv.ParseInt(values[1], 10, 64) - if err != nil { - return time.Time{}, errs.New("can not parse year: %v", err) - } - - date := time.Date(int(year), time.Month(month), 1, 0, 0, 0, 0, time.UTC) - if date.Year() != int(year) || date.Month() != time.Month(month) || date.Day() != 1 { - return date, errs.New("dates mismatch have %s result %s", s, date) - } - - return date, nil -} - func init() { rootCmd.AddCommand(statsCmd) rootCmd.AddCommand(irreparableCmd) rootCmd.AddCommand(healthCmd) - rootCmd.AddCommand(paymentsCmd) healthCmd.AddCommand(objectHealthCmd) healthCmd.AddCommand(segmentHealthCmd) - paymentsCmd.AddCommand(prepareInvoiceRecordsCmd) - paymentsCmd.AddCommand(createInvoiceItemsCmd) - paymentsCmd.AddCommand(createInvoiceCouponsCmd) - paymentsCmd.AddCommand(createInvoiceCreditsCmd) - paymentsCmd.AddCommand(createInvoicesCmd) - objectHealthCmd.Flags().StringVar(&CSVPath, "csv-path", "stdout", "csv path where command output is written") irreparableCmd.Flags().Int32Var(&irreparableLimit, "limit", 50, "max number of results per page") diff --git a/cmd/satellite/billing.go b/cmd/satellite/billing.go new file mode 100644 index 000000000..16aa5f0b1 --- /dev/null +++ b/cmd/satellite/billing.go @@ -0,0 +1,103 @@ +// Copyright (C) 2020 Storj Labs, Inc. +// See LICENSE for copying information. + +package main + +import ( + "strconv" + "strings" + "time" + + "github.com/zeebo/errs" + "go.uber.org/zap" + + "storj.io/storj/private/dbutil" + "storj.io/storj/satellite" + "storj.io/storj/satellite/payments/stripecoinpayments" + "storj.io/storj/satellite/satellitedb" + "storj.io/storj/satellite/satellitedb/dbx" +) + +func runBillingCmd(cmdFunc func(*stripecoinpayments.Service, *dbx.DB) error) error { + // Open SatelliteDB for the Payment Service + logger := zap.L() + db, err := satellitedb.New(logger.Named("db"), runCfg.Database, satellitedb.Options{}) + if err != nil { + return errs.New("error connecting to master database on satellite: %+v", err) + } + defer func() { + err = errs.Combine(err, db.Close()) + }() + + // Open direct DB connection to execute custom queries + driver, source, implementation, err := dbutil.SplitConnStr(runCfg.Database) + if err != nil { + return err + } + if implementation != dbutil.Postgres && implementation != dbutil.Cockroach { + return errs.New("unsupported driver %q", driver) + } + + dbxDB, err := dbx.Open(driver, source) + if err != nil { + return err + } + defer func() { + err = errs.Combine(err, dbxDB.Close()) + }() + logger.Debug("Connected to:", zap.String("db source", source)) + + payments, err := setupPayments(logger, db) + if err != nil { + return err + } + + return cmdFunc(payments, dbxDB) +} + +func setupPayments(log *zap.Logger, db satellite.DB) (*stripecoinpayments.Service, error) { + pc := runCfg.Payments + + stripeClient := stripecoinpayments.NewStripeClient(log, pc.StripeCoinPayments) + + return stripecoinpayments.NewService( + log.Named("payments.stripe:service"), + stripeClient, + pc.StripeCoinPayments, + db.StripeCoinPayments(), + db.Console().Projects(), + db.ProjectAccounting(), + pc.StorageTBPrice, + pc.EgressTBPrice, + pc.ObjectPrice, + pc.BonusRate, + pc.CouponValue, + pc.CouponDuration, + pc.CouponProjectLimit, + pc.MinCoinPayment) +} + +// parseBillingPeriodFromString parses provided date string and returns corresponding time.Time. +func parseBillingPeriod(s string) (time.Time, error) { + values := strings.Split(s, "/") + + if len(values) != 2 { + return time.Time{}, errs.New("invalid date format %s, use mm/yyyy", s) + } + + month, err := strconv.ParseInt(values[0], 10, 64) + if err != nil { + return time.Time{}, errs.New("can not parse month: %v", err) + } + year, err := strconv.ParseInt(values[1], 10, 64) + if err != nil { + return time.Time{}, errs.New("can not parse year: %v", err) + } + + date := time.Date(int(year), time.Month(month), 1, 0, 0, 0, 0, time.UTC) + if date.Year() != int(year) || date.Month() != time.Month(month) || date.Day() != 1 { + return date, errs.New("dates mismatch have %s result %s", s, date) + } + + return date, nil +} diff --git a/cmd/satellite/main.go b/cmd/satellite/main.go index 9b3b5592f..999936ad7 100644 --- a/cmd/satellite/main.go +++ b/cmd/satellite/main.go @@ -32,7 +32,9 @@ import ( "storj.io/storj/satellite/compensation" "storj.io/storj/satellite/metainfo" "storj.io/storj/satellite/orders" + "storj.io/storj/satellite/payments/stripecoinpayments" "storj.io/storj/satellite/satellitedb" + "storj.io/storj/satellite/satellitedb/dbx" ) // Satellite defines satellite configuration @@ -166,6 +168,45 @@ var ( Args: cobra.ExactArgs(1), RunE: cmdRecordOneOffPayments, } + billingCmd = &cobra.Command{ + Use: "billing", + Short: "Customer billing commands", + } + 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, + } + createCustomerInvoiceItemsCmd = &cobra.Command{ + Use: "create-invoice-items [period]", + Short: "Creates stripe invoice line items", + Long: "Creates stripe invoice line items for not consumed project records.", + Args: cobra.ExactArgs(1), + RunE: cmdCreateCustomerInvoiceItems, + } + createCustomerInvoiceCouponsCmd = &cobra.Command{ + Use: "create-invoice-coupons [period]", + Short: "Adds coupons to stripe invoices", + Long: "Creates stripe invoice line items for not consumed coupons.", + Args: cobra.ExactArgs(1), + RunE: cmdCreateCustomerInvoiceCoupons, + } + createCustomerInvoiceCreditsCmd = &cobra.Command{ + Use: "create-invoice-credits [period]", + Short: "Adds credits to stripe invoices", + Long: "Creates stripe invoice line items for not consumed credits.", + Args: cobra.ExactArgs(1), + RunE: cmdCreateCustomerInvoiceCredits, + } + 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, + } runCfg Satellite setupCfg Satellite @@ -221,14 +262,20 @@ func init() { rootCmd.AddCommand(qdiagCmd) rootCmd.AddCommand(reportsCmd) rootCmd.AddCommand(compensationCmd) + rootCmd.AddCommand(billingCmd) reportsCmd.AddCommand(nodeUsageCmd) reportsCmd.AddCommand(partnerAttributionCmd) reportsCmd.AddCommand(gracefulExitCmd) reportsCmd.AddCommand(verifyGracefulExitReceiptCmd) - reportsCmd.AddCommand(stripeCustomerCmd) compensationCmd.AddCommand(generateInvoicesCmd) compensationCmd.AddCommand(recordPeriodCmd) compensationCmd.AddCommand(recordOneOffPaymentsCmd) + billingCmd.AddCommand(stripeCustomerCmd) + billingCmd.AddCommand(prepareCustomerInvoiceRecordsCmd) + billingCmd.AddCommand(createCustomerInvoiceItemsCmd) + billingCmd.AddCommand(createCustomerInvoiceCouponsCmd) + billingCmd.AddCommand(createCustomerInvoiceCreditsCmd) + billingCmd.AddCommand(createCustomerInvoicesCmd) process.Bind(runCmd, &runCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir)) process.Bind(runMigrationCmd, &runCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir)) process.Bind(runAPICmd, &runCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir)) @@ -243,8 +290,13 @@ func init() { process.Bind(recordOneOffPaymentsCmd, &recordOneOffPaymentsCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir)) process.Bind(gracefulExitCmd, &gracefulExitCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir)) process.Bind(verifyGracefulExitReceiptCmd, &verifyGracefulExitReceiptCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir)) - process.Bind(stripeCustomerCmd, &runCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir)) process.Bind(partnerAttributionCmd, &partnerAttribtionCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir)) + process.Bind(stripeCustomerCmd, &runCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir)) + process.Bind(prepareCustomerInvoiceRecordsCmd, &runCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir)) + process.Bind(createCustomerInvoiceItemsCmd, &runCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir)) + process.Bind(createCustomerInvoiceCouponsCmd, &runCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir)) + process.Bind(createCustomerInvoiceCreditsCmd, &runCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir)) + process.Bind(createCustomerInvoicesCmd, &runCfg, defaults, cfgstruct.ConfDir(confDir), cfgstruct.IdentityDir(identityDir)) } func cmdRun(cmd *cobra.Command, args []string) (err error) { @@ -570,6 +622,71 @@ func cmdValueAttribution(cmd *cobra.Command, args []string) (err error) { return reports.GenerateAttributionCSV(ctx, partnerAttribtionCfg.Database, partnerID, start, end, file) } +func cmdPrepareCustomerInvoiceRecords(cmd *cobra.Command, args []string) (err error) { + ctx, _ := process.Ctx(cmd) + + period, err := parseBillingPeriod(args[0]) + if err != nil { + return errs.New("invalid period specified: %v", err) + } + + return runBillingCmd(func(payments *stripecoinpayments.Service, _ *dbx.DB) error { + return payments.PrepareInvoiceProjectRecords(ctx, period) + }) +} + +func cmdCreateCustomerInvoiceItems(cmd *cobra.Command, args []string) (err error) { + ctx, _ := process.Ctx(cmd) + + period, err := parseBillingPeriod(args[0]) + if err != nil { + return errs.New("invalid period specified: %v", err) + } + + return runBillingCmd(func(payments *stripecoinpayments.Service, _ *dbx.DB) error { + return payments.InvoiceApplyProjectRecords(ctx, period) + }) +} + +func cmdCreateCustomerInvoiceCoupons(cmd *cobra.Command, args []string) (err error) { + ctx, _ := process.Ctx(cmd) + + period, err := parseBillingPeriod(args[0]) + if err != nil { + return errs.New("invalid period specified: %v", err) + } + + return runBillingCmd(func(payments *stripecoinpayments.Service, _ *dbx.DB) error { + return payments.InvoiceApplyCoupons(ctx, period) + }) +} + +func cmdCreateCustomerInvoiceCredits(cmd *cobra.Command, args []string) (err error) { + ctx, _ := process.Ctx(cmd) + + period, err := parseBillingPeriod(args[0]) + if err != nil { + return errs.New("invalid period specified: %v", err) + } + + return runBillingCmd(func(payments *stripecoinpayments.Service, _ *dbx.DB) error { + return payments.InvoiceApplyCredits(ctx, period) + }) +} + +func cmdCreateCustomerInvoices(cmd *cobra.Command, args []string) (err error) { + ctx, _ := process.Ctx(cmd) + + period, err := parseBillingPeriod(args[0]) + if err != nil { + return errs.New("invalid period specified: %v", err) + } + + return runBillingCmd(func(payments *stripecoinpayments.Service, _ *dbx.DB) error { + return payments.CreateInvoices(ctx, period) + }) +} + func main() { process.ExecCustomDebug(rootCmd) } diff --git a/cmd/satellite/stripe.go b/cmd/satellite/stripe.go index 0063f58e3..65c86f5c8 100644 --- a/cmd/satellite/stripe.go +++ b/cmd/satellite/stripe.go @@ -10,11 +10,7 @@ import ( "go.uber.org/zap" "storj.io/common/uuid" - "storj.io/storj/private/dbutil" - "storj.io/storj/satellite" - "storj.io/storj/satellite/payments" "storj.io/storj/satellite/payments/stripecoinpayments" - "storj.io/storj/satellite/satellitedb" "storj.io/storj/satellite/satellitedb/dbx" ) @@ -26,90 +22,35 @@ type UserData struct { // generateStripeCustomers creates missing stripe-customers for users in our database. func generateStripeCustomers(ctx context.Context) (err error) { - //Open SatelliteDB for the Payment Service - logger := zap.L() - db, err := satellitedb.New(logger.Named("db"), runCfg.Database, satellitedb.Options{}) - if err != nil { - return errs.New("error connecting to master database on satellite: %+v", err) - } - defer func() { - err = errs.Combine(err, db.Close()) - }() + return runBillingCmd(func(payments *stripecoinpayments.Service, dbxDB *dbx.DB) error { + accounts := payments.Accounts() - //Open direct DB connection to execute custom queries - driver, source, implementation, err := dbutil.SplitConnStr(runCfg.Database) - if err != nil { - return err - } - if implementation != dbutil.Postgres && implementation != dbutil.Cockroach { - return errs.New("unsupported driver %q", driver) - } - - dbxDB, err := dbx.Open(driver, source) - if err != nil { - return err - } - logger.Debug("Connected to:", zap.String("db source", source)) - defer func() { - err = errs.Combine(err, dbxDB.Close()) - }() - - handler, err := setupPayments(zap.L().Named("payments"), db) - if err != nil { - return err - } - - rows, err := dbxDB.Query(ctx, "SELECT id, email FROM users WHERE id NOT IN (SELECT user_id from stripe_customers) AND users.status=1") - if err != nil { - return err - } - defer func() { - err = errs.Combine(err, rows.Close()) - }() - var n int64 - for rows.Next() { - n++ - var user UserData - err := rows.Scan(&user.ID, &user.Email) + rows, err := dbxDB.Query(ctx, "SELECT id, email FROM users WHERE id NOT IN (SELECT user_id from stripe_customers) AND users.status=1") if err != nil { return err } + defer func() { + err = errs.Combine(err, rows.Close()) + }() + + var n int64 + for rows.Next() { + n++ + var user UserData + err := rows.Scan(&user.ID, &user.Email) + if err != nil { + return err + } + + err = accounts.Setup(ctx, user.ID, user.Email) + if err != nil { + return err + } - err = handler.Setup(ctx, user.ID, user.Email) - if err != nil { - return err } - } - logger.Info("Ensured Stripe-Customer", zap.Int64("created", n)) - return err -} - -func setupPayments(log *zap.Logger, db satellite.DB) (handler payments.Accounts, err error) { - pc := runCfg.Payments - - stripeClient := stripecoinpayments.NewStripeClient(log, pc.StripeCoinPayments) - - service, err := stripecoinpayments.NewService( - log.Named("payments.stripe:service"), - stripeClient, - pc.StripeCoinPayments, - db.StripeCoinPayments(), - db.Console().Projects(), - db.ProjectAccounting(), - pc.StorageTBPrice, - pc.EgressTBPrice, - pc.ObjectPrice, - pc.BonusRate, - pc.CouponValue, - pc.CouponDuration, - pc.CouponProjectLimit, - pc.MinCoinPayment) - - if err != nil { - return nil, err - } - - handler = service.Accounts() - - return handler, err + + zap.L().Info("Ensured Stripe-Customer", zap.Int64("created", n)) + + return err + }) } diff --git a/go.mod b/go.mod index e3c7b0d6f..3d288c9c7 100644 --- a/go.mod +++ b/go.mod @@ -11,6 +11,7 @@ require ( github.com/fatih/color v1.7.0 github.com/go-redis/redis v6.14.1+incompatible github.com/golang-migrate/migrate/v4 v4.7.0 + github.com/gomodule/redigo v2.0.0+incompatible // indirect github.com/google/go-cmp v0.4.0 github.com/gorilla/mux v1.7.1 github.com/gorilla/schema v1.1.0 @@ -21,6 +22,7 @@ require ( github.com/nsf/jsondiff v0.0.0-20160203110537-7de28ed2b6e3 github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d github.com/shopspring/decimal v0.0.0-20200105231215-408a2507e114 + github.com/sirupsen/logrus v1.5.0 // indirect github.com/spacemonkeygo/monkit/v3 v3.0.6 github.com/spf13/cast v1.3.0 github.com/spf13/cobra v0.0.6 @@ -31,11 +33,13 @@ require ( github.com/vivint/infectious v0.0.0-20190108171102-2455b059135b github.com/zeebo/errs v1.2.2 go.etcd.io/bbolt v1.3.4 - go.uber.org/zap v1.14.1 + go.uber.org/zap v1.15.0 golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 + golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e // indirect golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a - golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5 + golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd golang.org/x/time v0.0.0-20191024005414-555d28b269f0 + golang.org/x/tools v0.0.0-20200428211428-0c9eba77bc32 // indirect storj.io/common v0.0.0-20200513105542-a376f4c68993 storj.io/drpc v0.0.12 storj.io/monkit-jaeger v0.0.0-20200424180155-d5f5530ea079 diff --git a/go.sum b/go.sum index bbe907982..e1108ceaa 100644 --- a/go.sum +++ b/go.sum @@ -162,6 +162,8 @@ github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/gomodule/redigo v1.7.1-0.20190322064113-39e2c31b7ca3 h1:6amM4HsNPOvMLVc2ZnyqrjeQ92YAVWn7T4WBKK87inY= github.com/gomodule/redigo v1.7.1-0.20190322064113-39e2c31b7ca3/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= +github.com/gomodule/redigo v2.0.0+incompatible h1:K/R+8tc58AaqLkqG2Ol3Qk+DR/TlNuhuh457pBFPtt0= +github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -325,6 +327,8 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.5.0 h1:1N5EYkVAPEywqZRJd7cwnRtCb6xJx7NH3T3WUTF980Q= +github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s+Squfpo= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/spacemonkeygo/errors v0.0.0-20171212215202-9064522e9fd1 h1:xHQewZjohU9/wUsyC99navCjQDNHtTgUOM/J1jAbzfw= github.com/spacemonkeygo/errors v0.0.0-20171212215202-9064522e9fd1/go.mod h1:7NL9UAYQnRM5iKHUCld3tf02fKb5Dft+41+VckASUy0= @@ -377,6 +381,7 @@ github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhe github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/gopher-lua v0.0.0-20190206043414-8bfc7677f583 h1:SZPG5w7Qxq7bMcMVl6e3Ht2X7f+AAGQdzjkbyOnNNZ8= github.com/yuin/gopher-lua v0.0.0-20190206043414-8bfc7677f583/go.mod h1:gqRgreBUhTSL0GeU64rtZ3Uq3wtjOa/TB2YfrtkCbVQ= github.com/zeebo/admission/v2 v2.0.0 h1:220NPZzKmyfklysKFO95L7E2Gt5NwlxTWGE14VP8heE= @@ -420,6 +425,8 @@ go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.14.1 h1:nYDKopTbvAPq/NrUVZwT15y2lpROBiLLyoRTbXOYWOo= go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= +go.uber.org/zap v1.15.0 h1:ZZCA22JRF2gQE5FoNmhmrf7jeJJ2uhqDUNRYKm8dvmM= +go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -454,6 +461,8 @@ golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCc golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -477,6 +486,8 @@ golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa h1:F+8P+gmewFQYRk6JoLQLwjBCT golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -505,6 +516,7 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190426135247-a129542de9ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -517,6 +529,8 @@ golang.org/x/sys v0.0.0-20200113162924-86b910548bc1 h1:gZpLHxUX5BdYLA08Lj4YCJNN/ golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5 h1:LfCXLvNmTYH9kEmVgqbnsWfruoXZIrh4YBgqVHtDvw0= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= @@ -546,9 +560,12 @@ golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5 h1:hKsoRgsbwY1NafxrwTs+k64bikrLBkAgPir1TNCj3Zs= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200117161641-43d50277825c h1:2EA2K0k9bcvvEDlqD8xdlOhCOqq+O/p9Voqi4x9W1YU= golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200428211428-0c9eba77bc32 h1:Xvf3ZQTm5bjXPxhI7g+dwqsCqadK1rcNtwtszuatetk= +golang.org/x/tools v0.0.0-20200428211428-0c9eba77bc32/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= diff --git a/satellite/api.go b/satellite/api.go index 890eee7b7..8b3521a46 100644 --- a/satellite/api.go +++ b/satellite/api.go @@ -129,9 +129,8 @@ type API struct { } Payments struct { - Accounts payments.Accounts - Inspector *stripecoinpayments.Endpoint - Version *stripecoinpayments.VersionService + Accounts payments.Accounts + Version *stripecoinpayments.VersionService } Referrals struct { @@ -552,17 +551,11 @@ func NewAPI(log *zap.Logger, full *identity.FullIdentity, db DB, } peer.Payments.Accounts = service.Accounts() - peer.Payments.Inspector = stripecoinpayments.NewEndpoint(service) - peer.Payments.Version = stripecoinpayments.NewVersionService( peer.Log.Named("payments.stripe:version"), service, pc.StripeCoinPayments.ConversionRatesCycleInterval) - if err := pb.DRPCRegisterPayments(peer.Server.PrivateDRPC(), peer.Payments.Inspector); err != nil { - return nil, errs.Combine(err, peer.Close()) - } - peer.Services.Add(lifecycle.Item{ Name: "payments.stripe:version", Run: peer.Payments.Version.Run, diff --git a/satellite/payments/stripecoinpayments/endpoint.go b/satellite/payments/stripecoinpayments/endpoint.go deleted file mode 100644 index 5b97a2e3d..000000000 --- a/satellite/payments/stripecoinpayments/endpoint.go +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (C) 2019 Storj Labs, Inc. -// See LICENSE for copying information. - -package stripecoinpayments - -import ( - "context" - - "storj.io/common/pb" - "storj.io/common/rpc/rpcstatus" -) - -// Endpoint is stripecoinpayments private RPC server payments endpoint. -type Endpoint struct { - service *Service -} - -// NewEndpoint creates new endpoint. -func NewEndpoint(service *Service) *Endpoint { - return &Endpoint{service: service} -} - -// PrepareInvoiceRecords creates project invoice records for all satellite projects. -func (endpoint *Endpoint) PrepareInvoiceRecords(ctx context.Context, req *pb.PrepareInvoiceRecordsRequest) (_ *pb.PrepareInvoiceRecordsResponse, err error) { - defer mon.Task()(&ctx)(&err) - - err = endpoint.service.PrepareInvoiceProjectRecords(ctx, req.Period) - if err != nil { - return nil, rpcstatus.Error(rpcstatus.Internal, err.Error()) - } - - return &pb.PrepareInvoiceRecordsResponse{}, nil -} - -// ApplyInvoiceRecords creates stripe line items for all unapplied invoice project records. -func (endpoint *Endpoint) ApplyInvoiceRecords(ctx context.Context, req *pb.ApplyInvoiceRecordsRequest) (_ *pb.ApplyInvoiceRecordsResponse, err error) { - defer mon.Task()(&ctx)(&err) - - err = endpoint.service.InvoiceApplyProjectRecords(ctx, req.Period) - if err != nil { - return nil, rpcstatus.Error(rpcstatus.Internal, err.Error()) - } - - return &pb.ApplyInvoiceRecordsResponse{}, nil -} - -// ApplyInvoiceCoupons creates stripe line items for all unapplied coupons. -func (endpoint *Endpoint) ApplyInvoiceCoupons(ctx context.Context, req *pb.ApplyInvoiceCouponsRequest) (_ *pb.ApplyInvoiceCouponsResponse, err error) { - defer mon.Task()(&ctx)(&err) - - err = endpoint.service.InvoiceApplyCoupons(ctx, req.Period) - if err != nil { - return nil, rpcstatus.Error(rpcstatus.Internal, err.Error()) - } - - return &pb.ApplyInvoiceCouponsResponse{}, nil -} - -// CreateInvoices creates invoice for all user accounts on the satellite. -func (endpoint *Endpoint) CreateInvoices(ctx context.Context, req *pb.CreateInvoicesRequest) (_ *pb.CreateInvoicesResponse, err error) { - defer mon.Task()(&ctx)(&err) - - err = endpoint.service.CreateInvoices(ctx, req.Period) - if err != nil { - return nil, rpcstatus.Error(rpcstatus.Internal, err.Error()) - } - - return &pb.CreateInvoicesResponse{}, nil -} - -// ApplyInvoiceCredits creates stripe line items for all credits. -func (endpoint *Endpoint) ApplyInvoiceCredits(ctx context.Context, req *pb.ApplyInvoiceCreditsRequest) (_ *pb.ApplyInvoiceCreditsResponse, err error) { - defer mon.Task()(&ctx)(&err) - - err = endpoint.service.InvoiceApplyCredits(ctx, req.Period) - if err != nil { - return nil, rpcstatus.Error(rpcstatus.Internal, err.Error()) - } - - return &pb.ApplyInvoiceCreditsResponse{}, nil -}