Skip to content

Commit

Permalink
fix payment and account controller recharge failed (#1617)
Browse files Browse the repository at this point in the history
Signed-off-by: fanux <[email protected]>

Signed-off-by: fanux <[email protected]>
  • Loading branch information
fanux authored Aug 24, 2022
1 parent 4f8ec79 commit 55cdca0
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 43 deletions.
6 changes: 4 additions & 2 deletions controllers/user/api/v1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 5 additions & 29 deletions controllers/user/config/crd/bases/user.sealos.io_accounts.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,13 @@ spec:
type: object
spec:
description: AccountSpec defines the desired state of Account
properties:
balance:
description: Foo is an example field of Account. Edit account_types.go
to remove/update
format: int64
type: integer
type: object
status:
description: AccountStatus defines the observed state of Account
properties:
balance:
format: int64
type: integer
chargeList:
description: 'INSERT ADDITIONAL STATUS FIELD - define observed state
of cluster Important: Run "make" to regenerate code after modifying
Expand All @@ -56,29 +53,8 @@ spec:
status:
type: string
time:
description: Timestamp is a struct that is equivalent to Time,
but intended for protobuf marshalling/unmarshalling. It is
generated into a serialization that matches Time. Do not use
in Go structs.
properties:
nanos:
description: Non-negative fractions of a second at nanosecond
resolution. Negative second values with fractions must
still have non-negative nanos values that count forward
in time. Must be from 0 to 999,999,999 inclusive. This
field may be limited in precision depending on context.
format: int32
type: integer
seconds:
description: Represents seconds of UTC time since Unix epoch
1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z
to 9999-12-31T23:59:59Z inclusive.
format: int64
type: integer
required:
- nanos
- seconds
type: object
format: date-time
type: string
tradeNO:
type: string
type: object
Expand Down
47 changes: 35 additions & 12 deletions controllers/user/controllers/account_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,17 @@ import (
"fmt"
"time"

v1 "k8s.io/api/core/v1"

"github.com/labring/sealos/pkg/constants"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"k8s.io/apimachinery/pkg/api/errors"

"github.com/labring/sealos/pkg/pay"
"sigs.k8s.io/controller-runtime/pkg/handler"
"sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/source"

userv1 "github.com/labring/sealos/controllers/user/api/v1"
Expand Down Expand Up @@ -55,35 +60,45 @@ type AccountReconciler struct {
// For more details, check Reconcile and its Result here:
// - https://pkg.go.dev/sigs.k8s.io/[email protected]/pkg/reconcile
func (r *AccountReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
log := log.FromContext(ctx)
payment := &userv1.Payment{}
if err := r.Get(ctx, client.ObjectKey{Namespace: req.Namespace, Name: req.Name}, payment); err != nil {
return ctrl.Result{}, client.IgnoreNotFound(err)
err := r.Get(ctx, client.ObjectKey{Namespace: req.Namespace, Name: req.Name}, payment)
if errors.IsNotFound(err) {
return ctrl.Result{}, nil
}
if payment.Spec.UserID == "" || payment.Spec.Amount == 0 || payment.Status.TradeNO == "" {
if err != nil {
return ctrl.Result{}, fmt.Errorf("failed to get payment: %v", err)
}
if payment.Spec.UserID == "" || payment.Spec.Amount == 0 {
return ctrl.Result{}, fmt.Errorf("payment is invalid: %v", payment)
}
if payment.Status.TradeNO == "" {
return ctrl.Result{Requeue: true, RequeueAfter: time.Millisecond * 300}, nil
}
if payment.Status.Status == pay.StatusSuccess {
return ctrl.Result{}, nil
}

account := &userv1.Account{}
account.Name = payment.Spec.UserID
err := r.Get(ctx, req.NamespacedName, account)
account.Namespace = constants.SealosSystemNamespace
err = r.Get(ctx, client.ObjectKey{Namespace: constants.SealosSystemNamespace, Name: account.Name}, account)
if errors.IsNotFound(err) {
account.Name = payment.Spec.UserID
account.Status.Balance = 0
account.Status.ChargeList = []userv1.Charge{}
log.Info("create account", "account", account)
if err := r.Create(ctx, account); err != nil {
return ctrl.Result{}, err
return ctrl.Result{}, fmt.Errorf("create account failed: %v", err)
}
} else if err != nil {
return ctrl.Result{}, err
return ctrl.Result{}, fmt.Errorf("get account failed: %v", err)
}

status, err := pay.QueryOrder(payment.Status.TradeNO)
if err != nil {
return ctrl.Result{}, err
return ctrl.Result{}, fmt.Errorf("query order failed: %v", err)
}
log.Info(fmt.Sprintf("query order: %v", status))
switch status {
case pay.StatusSuccess:
account.Status.ChargeList = append(account.Status.ChargeList, userv1.Charge{
Expand All @@ -94,17 +109,17 @@ func (r *AccountReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct
})
account.Status.Balance += payment.Spec.Amount
if err := r.Status().Update(ctx, account); err != nil {
return ctrl.Result{}, err
return ctrl.Result{}, fmt.Errorf("update account failed: %v", err)
}
payment.Status.Status = status
if err := r.Status().Update(ctx, payment); err != nil {
return ctrl.Result{}, err
return ctrl.Result{}, fmt.Errorf("update payment failed: %v", err)
}
case pay.StatusProcessing:
case pay.StatusProcessing, pay.StatusNotPay:
return ctrl.Result{Requeue: true, RequeueAfter: time.Second}, nil
case pay.StatusFail:
if err := r.Delete(ctx, payment); err != nil {
return ctrl.Result{}, err
return ctrl.Result{}, fmt.Errorf("delete payment failed: %v", err)
}
return ctrl.Result{}, nil
default:
Expand All @@ -116,6 +131,14 @@ func (r *AccountReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct

// SetupWithManager sets up the controller with the Manager.
func (r *AccountReconciler) SetupWithManager(mgr ctrl.Manager) error {
err := r.Create(context.TODO(), &v1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: constants.SealosSystemNamespace,
},
})
if err != nil && !errors.IsAlreadyExists(err) {
return fmt.Errorf("failed to create system namespace: %v", err)
}
return ctrl.NewControllerManagedBy(mgr).
For(&userv1.Account{}).
Watches(&source.Kind{Type: &userv1.Payment{}}, &handler.EnqueueRequestForObject{}).
Expand Down
2 changes: 2 additions & 0 deletions pkg/constants/contants.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import (
"github.com/mitchellh/go-homedir"
)

const SealosSystemNamespace = "sealos-system"

const (
LvsCareStaticPodName = "kube-sealos-lvscare"
YamlFileSuffix = "yaml"
Expand Down
1 change: 1 addition & 0 deletions pkg/pay/wechat_payment.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const (

StatusSuccess = "SUCCESS"
StatusProcessing = "PROCESSING"
StatusNotPay = "NOTPAY"
StatusFail = "FAILED"

DefaultCallbackURL = "https://sealos.io/payment/wechat/callback"
Expand Down

0 comments on commit 55cdca0

Please sign in to comment.