Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(account-service): fix giftcode concurrency issue and add realname info api #5096

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions controllers/go.work.sum

Large diffs are not rendered by default.

29 changes: 29 additions & 0 deletions controllers/pkg/database/cockroach/accountv2.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package cockroach
import (
"errors"
"fmt"
"gorm.io/gorm/clause"
"log"
"os"
"path/filepath"
Expand Down Expand Up @@ -1070,6 +1071,17 @@ func (c *Cockroach) GetGiftCodeWithCode(code string) (*types.GiftCode, error) {

func (c *Cockroach) UseGiftCode(giftCode *types.GiftCode, userID string) error {
return c.DB.Transaction(func(tx *gorm.DB) error {
var lockedGiftCode types.GiftCode
// Lock the gift code record for update
if err := tx.Clauses(clause.Locking{Strength: "UPDATE", Options: "NOWAIT"}).
Where(&types.GiftCode{ID: giftCode.ID}).First(&lockedGiftCode).Error; err != nil {
return fmt.Errorf("failed to lock gift code: %w", err)
}

if lockedGiftCode.Used {
return fmt.Errorf("gift code has already been used")
}

ops := &types.UserQueryOpts{ID: userID}
// Update the user's balance
if err := c.updateBalance(tx, ops, giftCode.CreditAmount, false, true); err != nil {
Expand Down Expand Up @@ -1104,3 +1116,20 @@ func (c *Cockroach) UseGiftCode(giftCode *types.GiftCode, userID string) error {
return nil
})
}

func (c *Cockroach) GetUserRealNameInfoByUserID(userID string) (*types.UserRealNameInfo, error) {
// get user info
ops := &types.UserQueryOpts{ID: userID}
user, err := c.GetUserCr(ops)

if err != nil {
return nil, fmt.Errorf("failed to get user: %v", err)
}

// get user realname info
var userRealNameInfo types.UserRealNameInfo
if err := c.DB.Where(&types.UserRealNameInfo{UserUID: user.UserUID}).First(&userRealNameInfo).Error; err != nil {
return nil, fmt.Errorf("failed to get user real name info: %w", err)
}
return &userRealNameInfo, nil
}
21 changes: 19 additions & 2 deletions controllers/pkg/types/global.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
package types

import (
"time"

"encoding/json"
"github.com/google/uuid"
"time"
)

type Account struct {
Expand Down Expand Up @@ -320,3 +320,20 @@ type AccountTransaction struct {
func (AccountTransaction) TableName() string {
return "AccountTransaction"
}

type UserRealNameInfo struct {
ID uuid.UUID `gorm:"column:id;type:uuid;default:gen_random_uuid();primary_key"`
UserUID uuid.UUID `gorm:"column:userUid;type:uuid;unique"`
RealName *string `gorm:"column:realName;type:text"`
IDCard *string `gorm:"column:idCard;type:text"`
Phone *string `gorm:"column:phone;type:text"`
IsVerified bool `gorm:"column:isVerified;type:boolean;default:false"`
IDVerifyFailedTimes int `gorm:"column:idVerifyFailedTimes;type:integer;default:0"`
CreatedAt time.Time `gorm:"column:createdAt;type:timestamp(3) with time zone;default:current_timestamp()"`
UpdatedAt time.Time `gorm:"column:updatedAt;type:timestamp(3) with time zone;autoUpdateTime"`
AdditionalInfo json.RawMessage `gorm:"column:additionalInfo;type:jsonb"`
}

func (UserRealNameInfo) TableName() string {
return "UserRealNameInfo"
}
9 changes: 9 additions & 0 deletions go.work.sum
Original file line number Diff line number Diff line change
Expand Up @@ -756,6 +756,7 @@ github.com/Azure/go-amqp v0.17.0/go.mod h1:9YJ3RhxRT1gquYnzpZO1vcYMMpAdJT+QEg6fw
github.com/Azure/go-amqp v0.18.1/go.mod h1:+bg0x3ce5+Q3ahCEXnCsGG3ETpDQe3MEVnOuT2ywPwc=
github.com/Azure/go-ansiterm v0.0.0-20210608223527-2377c96fe795/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
github.com/Azure/go-autorest v12.0.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs=
github.com/Azure/go-autorest/autorest v0.11.24/go.mod h1:G6kyRlFnTuSbEYkQGawPfsCswgme4iYf6rfSKUDzbCc=
github.com/Azure/go-autorest/autorest v0.11.25/go.mod h1:7l8ybrIdUmGqZMTD0sRtAr8NvbHjfofbf8RSP2q7w7U=
github.com/Azure/go-autorest/autorest v0.11.28 h1:ndAExarwr5Y+GaHE6VCaY1kyS/HwwGGyuimVhWsHOEM=
Expand All @@ -772,11 +773,15 @@ github.com/Azure/go-autorest/autorest/azure/auth v0.5.12/go.mod h1:84w/uV8E37feW
github.com/Azure/go-autorest/autorest/azure/cli v0.4.5/go.mod h1:ADQAXrkgm7acgWVUNamOgh8YNrv4p27l3Wc55oVfpzg=
github.com/Azure/go-autorest/autorest/azure/cli v0.4.6 h1:w77/uPk80ZET2F+AfQExZyEWtn+0Rk/uw17m9fv5Ajc=
github.com/Azure/go-autorest/autorest/azure/cli v0.4.6/go.mod h1:piCfgPho7BiIDdEQ1+g4VmKyD5y+p/XtSNqE6Hc4QD0=
github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw=
github.com/Azure/go-autorest/autorest/mocks v0.4.2 h1:PGN4EDXnuQbojHbU0UWoNvmu9AGVwYHG9/fkDYhtAfw=
github.com/Azure/go-autorest/autorest/to v0.4.0 h1:oXVqrxakqqV1UZdSazDOPOLvOIz+XA683u8EctwboHk=
github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE=
github.com/Azure/go-autorest/autorest/validation v0.1.0/go.mod h1:Ha3z/SqBeaalWQvokg3NZAlQTalVMtOIAs1aGK7G6u8=
github.com/Azure/go-autorest/autorest/validation v0.3.1 h1:AgyqjAd94fwNAoTjl/WQXg4VvFeRFpO+UhNyRXqF1ac=
github.com/Azure/go-autorest/autorest/validation v0.3.1/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E=
github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg=
github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo=
github.com/AzureAD/microsoft-authentication-library-for-go v0.4.0/go.mod h1:Vt9sXTKwMyGcOxSmLDMnGPgqsUg7m8pe215qMLrDXw4=
github.com/AzureAD/microsoft-authentication-library-for-go v0.5.1/go.mod h1:Vt9sXTKwMyGcOxSmLDMnGPgqsUg7m8pe215qMLrDXw4=
github.com/AzureAD/microsoft-authentication-library-for-go v0.8.1/go.mod h1:4qFor3D/HDsvBME35Xy9rwW9DecL+M2sNw1ybjPtwA0=
Expand Down Expand Up @@ -835,6 +840,8 @@ github.com/PaesslerAG/jsonpath v0.1.1/go.mod h1:lVboNxFGal/VwW6d9JzIy56bUsYAP6tH
github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8=
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 h1:wPbRQzjjwFc0ih8puEVAOFGELsn1zoIIYdxvML7mDxA=
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g=
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06/go.mod h1:7erjKLwalezA0k99cWs5L11HWOAPNjdUZ6RxH1BXbbM=
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
Expand Down Expand Up @@ -2058,6 +2065,7 @@ github.com/nelsam/hel/v2 v2.3.3/go.mod h1:1ZTGfU2PFTOd5mx22i5O0Lc2GY933lQ2wb/ggy
github.com/networkplumbing/go-nft v0.2.0/go.mod h1:HnnM+tYvlGAsMU7yoYwXEVLLiDW9gdMmb5HoGcwpuQs=
github.com/networkplumbing/go-nft v0.3.0 h1:IIc6yHjN85KyJx21p3ZEsO0iBMYHNXux22rc9Q8TfFw=
github.com/networkplumbing/go-nft v0.3.0/go.mod h1:HnnM+tYvlGAsMU7yoYwXEVLLiDW9gdMmb5HoGcwpuQs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/nightlyone/lockfile v1.0.0/go.mod h1:rywoIealpdNse2r832aiD9jRk8ErCatROs6LzC841CI=
github.com/nishanths/predeclared v0.0.0-20190419143655-18a43bb90ffc/go.mod h1:62PewwiQTlm/7Rj+cxVYqZvDIUc+JjZq6GHAC1fsObQ=
github.com/nishanths/predeclared v0.0.0-20200524104333-86fad755b4d3/go.mod h1:nt3d53pc1VYcphSCIaYAJtnPYnr3Zyn8fMq2wvPGPso=
Expand All @@ -2071,6 +2079,7 @@ github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FW
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0=
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8AyFNU9d0=
github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo=
github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw=
Expand Down
52 changes: 52 additions & 0 deletions service/account/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -976,3 +976,55 @@ func UserUsage(c *gin.Context) {
"data": usage,
})
}

// GetUserRealNameInfo
// @Summary Get user real name information
// @Description Retrieve the real name information for a user
// @Tags GetUserRealNameInfo
// @Accept json
// @Produce json
// @Param request body helper.GetRealNameInfoReq true "Get real name info request"
// @Success 200 {object} helper.GetRealNameInfoResp "Successfully retrieved user real name info"
// @Failure 400 {object} helper.ErrorMessage "Failed to parse get real name info request"
// @Failure 401 {object} helper.ErrorMessage "Authentication error"
// @Failure 500 {object} helper.ErrorMessage "Failed to get user real name info or info not found/verified"
// @Router /account/v1alpha1/real-name-info [post]
func GetUserRealNameInfo(c *gin.Context) {
// Parse the get real name info request
req, err := helper.ParseGetRealNameInfoReq(c)
if err != nil {
c.JSON(http.StatusBadRequest, helper.ErrorMessage{Error: fmt.Sprintf("failed to parse get real name info request: %v", err)})
return
}

if err := authenticateRequest(c, req); err != nil {
c.JSON(http.StatusUnauthorized, helper.ErrorMessage{Error: fmt.Sprintf("authenticate error : %v", err)})
return
}

userRealNameInfo, err := dao.DBClient.GetUserRealNameInfo(req)

if err != nil {
c.JSON(http.StatusInternalServerError, helper.ErrorMessage{Error: fmt.Sprintf("failed to get user real name info: %v", err)})
return
}

if userRealNameInfo == nil {
c.JSON(http.StatusInternalServerError, helper.ErrorMessage{Error: "user real name info not found"})
return
}

if !userRealNameInfo.IsVerified {
c.JSON(http.StatusInternalServerError, helper.ErrorMessage{Error: "user real name info is not verified"})
return
}

// Return success response
c.JSON(http.StatusOK, helper.GetRealNameInfoResp{
Data: helper.GetRealNameInfoRespData{
UserID: req.Auth.UserID,
IsRealName: userRealNameInfo.IsVerified,
},
Message: "successfully get user real name info",
})
}
24 changes: 24 additions & 0 deletions service/account/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"localRegionDomain": "192.168.0.55.nip.io",
"invoiceToken": "c2VhbG9zQDEyMy4uLg==",
"regions": [
{
"domain": "192.168.0.55.nip.io",
"accountSvc": "account-api.192.168.0.55.nip.io",
"uid": "97925cb0-c8e2-4d52-8b39-d8bf0cbb414a",
"name": {
"en": "region-a",
"zh": "区域A"
}
},
{
"domain": "192.168.0.75.nip.io",
"accountSvc": "account-api.192.168.0.75.nip.io",
"uid": "b373c0e9-7bf1-4d64-b863-bc604a4801ad",
"name": {
"en": "region-b",
"zh": "区域B"
}
}
]
}
12 changes: 12 additions & 0 deletions service/account/dao/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ type Interface interface {
GetRegions() ([]types.Region, error)
GetLocalRegion() types.Region
UseGiftCode(req *helper.UseGiftCodeReq) (*types.GiftCode, error)
GetUserRealNameInfo(req *helper.GetRealNameInfoReq) (*types.UserRealNameInfo, error)
}

type Account struct {
Expand Down Expand Up @@ -1444,3 +1445,14 @@ func (m *Account) UseGiftCode(req *helper.UseGiftCodeReq) (*types.GiftCode, erro

return giftCode, nil
}

func (m *Account) GetUserRealNameInfo(req *helper.GetRealNameInfoReq) (*types.UserRealNameInfo, error) {
// get user info
userRealNameInfo, err := m.ck.GetUserRealNameInfoByUserID(req.UserID)

if err != nil {
return nil, fmt.Errorf("failed to get user real name info: %v", err)
}

return userRealNameInfo, nil
}
26 changes: 24 additions & 2 deletions service/account/dao/interface_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -608,10 +608,10 @@ func TestAccount_UseGiftCode(t *testing.T) {
}

giftcode, err := db.UseGiftCode(&helper.UseGiftCodeReq{
Code: "DfxAffaeEf",
Code: "d-intl-TXERVADC3ASAGQJSx",
AuthBase: helper.AuthBase{
Auth: &helper.Auth{
Owner: "E1xAJ0fy4k",
UserID: "E1xAJ0fy4k",
},
},
})
Expand All @@ -623,6 +623,28 @@ func TestAccount_UseGiftCode(t *testing.T) {
t.Logf("giftcode = %+v", giftcode)
}

func TestAccount_GetUserRealNameInfo(t *testing.T) {
db, err := newAccountForTest("", os.Getenv("GLOBAL_COCKROACH_URI"), os.Getenv("LOCAL_COCKROACH_URI"))
if err != nil {
t.Fatalf("NewAccountInterface() error = %v", err)
return
}

userRealNameInfo, err := db.GetUserRealNameInfo(&helper.GetRealNameInfoReq{
AuthBase: helper.AuthBase{
Auth: &helper.Auth{
UserID: "E1xAJ0fy4k",
},
},
})

if err != nil {
t.Fatalf("GetUserRealNameInfo() error = %v", err)
return
}
t.Logf("userRealNameInfo = %+v", userRealNameInfo)
}

func init() {
// set env
os.Setenv("MONGO_URI", "")
Expand Down
1 change: 1 addition & 0 deletions service/account/helper/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const (
GetInvoicePayment = "/invoice/get-payment"
UseGiftCode = "/gift-code/use"
UserUsage = "/user-usage"
GetUserRealNameInfo = "/real-name-info"
)

// env
Expand Down
26 changes: 26 additions & 0 deletions service/account/helper/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,13 @@ type UseGiftCodeReq struct {
AuthBase `json:",inline" bson:",inline"`
}

type GetRealNameInfoReq struct {
// @Summary Authentication information
// @Description Authentication information
// @JSONSchema required
AuthBase `json:",inline" bson:",inline"`
}

type UserUsageReq struct {
// @Summary Start and end time for the request
// @Description Start and end time for the request
Expand Down Expand Up @@ -547,6 +554,25 @@ func ParseUseGiftCodeReq(c *gin.Context) (*UseGiftCodeReq, error) {
return useGiftCode, nil
}

type GetRealNameInfoRespData struct {
UserID string `json:"userID" bson:"userID" example:"user-123"`
IsRealName bool `json:"isRealName" bson:"isRealName" example:"true"`
}

type GetRealNameInfoResp struct {
Data GetRealNameInfoRespData `json:"data,omitempty" bson:"data,omitempty"`
Message string `json:"message,omitempty" bson:"message" example:"Successfully retrieved real name information"`
}

func ParseGetRealNameInfoReq(c *gin.Context) (*GetRealNameInfoReq, error) {
getRealNameInfoReq := &GetRealNameInfoReq{}
if err := c.ShouldBindJSON(getRealNameInfoReq); err != nil {
return nil, fmt.Errorf("bind json error: %v", err)
}

return getRealNameInfoReq, nil
}

func ParseUserUsageReq(c *gin.Context) (*UserUsageReq, error) {
userUsage := &UserUsageReq{}
if err := c.ShouldBindJSON(userUsage); err != nil {
Expand Down
3 changes: 2 additions & 1 deletion service/account/router/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ func RegisterPayRouter() {
POST(helper.SetStatusInvoice, api.SetStatusInvoice).
POST(helper.GetInvoicePayment, api.GetInvoicePayment).
POST(helper.UseGiftCode, api.UseGiftCode).
POST(helper.UserUsage, api.UserUsage)
POST(helper.UserUsage, api.UserUsage).
POST(helper.GetUserRealNameInfo, api.GetUserRealNameInfo)
docs.SwaggerInfo.Host = env.GetEnvWithDefault("SWAGGER_HOST", "localhost:2333")
router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerfiles.Handler))

Expand Down
19 changes: 19 additions & 0 deletions service/account/test/kubeconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM2VENDQWRHZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQ0FYRFRJME1ERXpNVEE1TVRFeU9Wb1lEekl4TWpRd01UQTNNRGt4TVRJNVdqQVZNUk13RVFZRApWUVFERXdwcmRXSmxjbTVsZEdWek1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBCndZeTcxamFzcm5FVlA1TmlSZDJJTWJyN0ZXSlFYd1p3Y3pFUnh4UzROOWRYamtOWXdKRUs0VU4wNGZkbzRxd3kKNnVXVVZ3WDZqYWJDRjU0NlV4dWE4Tk02SVZqRVNKTlI1aDByOXFmU0hXaStBVEM0N1BlVW1VdnZJcGkveXZ1NgpzRjJZVEtjeVgxUGlGOEFuMzJNMDVLYmx4WUVTTEhCV3lDcndDUHZ4QStvejE0eHlBdEJXa21tb2VOVEhnbkRKCnFYVXJ2aXhNNFdIcjdqNzZwZ05LeVF3OEJJcmpkUG9oOUFPZlpGOXhqUWphZ2szaTVnK0tyS2JYVUtuSDh2ZloKTExJNmVYV05XQUFuTW5XM0J1bjJHTFU2WStzNytPYzlkUDVubXM3cVNlRXJMQXJlZlNBSG5YaW1UZlNyd2hhRgpEUDcvRWo5UThkK0tuOEtla2ZjaHF3SURBUUFCbzBJd1FEQU9CZ05WSFE4QkFmOEVCQU1DQXFRd0R3WURWUjBUCkFRSC9CQVV3QXdFQi96QWRCZ05WSFE0RUZnUVVtRXJlL3NuZ0MyUW95bDZxTEJsd0Evd3ozcWN3RFFZSktvWkkKaHZjTkFRRUxCUUFEZ2dFQkFBWXpxV3Z4U25ZMjdCTWRoQVdZMnYvUlpFNHVhN3pMY0J0bUdJYkFaR3A4NFVYagp1Y2hUdkM2VDBhVk05T2V2Vm9tM2J6N0oxV3dMSnBVbXZyTFlGbjJXZzUwRTJBMTZzWVU5a2dLNE81S3g0R3M3Ck1GQzJja2pKWnVlSXRlTm0xMGxFUVpGWWUrYi9WRS9yVXBTSXlMUnhmazlBenF2K0RZN3ZMTjNYT1FXcHJsWUgKcUdtSW1nRjZGU3Frb0cwRnJ5ZzZXVXM2elhpYlBGY2ZuRDZyQUsrakJ6UWZNemY4b01YWHh2eE1ONkQvdXNwdQpUM3NhVEVtQlpHbGtseVpobWlObDAzZHd1dkg0S05ydW1mSVJKM0NyMXB5dDVQdm9oSjhNQW5ZQVNFV012c0VTCkdlLytxRjVpVGJsS1d1YVZHSERHWE9PeFB3T2cvNFJwQldqaTd3Yz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
server: https://192.168.0.55.nip.io:6443
name: sealos
contexts:
- context:
cluster: sealos
namespace: ns-q5y2ue2b
user: q5y2ue2b
name: q5y2ue2b@sealos
current-context: q5y2ue2b@sealos
kind: Config
preferences: {}
users:
- name: q5y2ue2b
user:
token: eyJhbGciOiJSUzI1NiIsImtpZCI6InVrQW1EWTY0M3Vzam9LSmduZWJYVlY3LUU3eUQySXpWcV9idFZxSVpsOTAifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJucy1xNXkydWUyYiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJzZWFsb3MtdG9rZW4tcTV5MnVlMmItMjNkOSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJxNXkydWUyYiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjEzNTZlNGU5LTA5NmUtNDkxZi05NzRmLTI4NDkwNTM4MTliMiIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpucy1xNXkydWUyYjpxNXkydWUyYiJ9.hfbi_pphaIcjRVmmef5neZ6SDgcjVmm9_BwYPJ7qdrBaqydy07NGdPtFDaPKehPrg4rhQbkjsntHYdvBCCCHjSI1wgO7pTL1r8_q8hp714OFMb6ZTObjEk1g2JILzCtHMfEbFm_8kzyEXfzV1p6QZjlYC1_bA6EvgxW7D5ixU9muuTOzRwRbs58FxmOOW0Mra32eJ5gC1Z_yC1Z8NPESZ54aht7q5lqCfZakMcC6P60v1bgTT_dXmkzAqzVpboKioLjFnEhyr41Ct1nW9HgPlXpEK8sGqw-V27xoRuwon7j9lOzT32HTFufbb2KD5cyvgtZBs5whIo65f6BMev9SQg
Loading