satellite/payments: move inspector commands to satellite cli

This allows to seeing logs in the output of the invoice commands.

Existing ensure-stripe-customer commands is moved from the 'reports' to
the new 'billing' root command.

Change-Id: I752c7ab6ca59bfac8e0f174a45d2ab45fc18e467
This commit is contained in:
Kaloyan Raev 2020-05-18 15:21:35 +03:00 committed by Stefan Benten
parent 47def02094
commit aac1e3c45f
8 changed files with 282 additions and 392 deletions

View File

@ -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 <period>",
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 <period>",
Short: "Creates stripe invoice line items for not consumed project records",
Args: cobra.MinimumNArgs(1),
RunE: createInvoiceItems,
}
createInvoiceCouponsCmd = &cobra.Command{
Use: "create-invoice-coupons <period>",
Short: "Creates stripe invoice line items for not consumed coupons",
Args: cobra.MinimumNArgs(1),
RunE: createInvoiceCoupons,
}
createInvoiceCreditsCmd = &cobra.Command{
Use: "create-invoice-credits <period>",
Short: "Creates stripe invoice line items for not consumed credits",
Args: cobra.MinimumNArgs(1),
RunE: createInvoiceCredits,
}
createInvoicesCmd = &cobra.Command{
Use: "create-invoices <period>",
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")

103
cmd/satellite/billing.go Normal file
View File

@ -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
}

View File

@ -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)
}

View File

@ -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
})
}

8
go.mod
View File

@ -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

17
go.sum
View File

@ -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=

View File

@ -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,

View File

@ -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
}