实验报表授权、GEO支持

This commit is contained in:
algotao
2025-12-13 09:16:21 +08:00
parent cbbeb04ee5
commit 765e75937d
14 changed files with 868 additions and 258 deletions

660
cmd.pb.go

File diff suppressed because it is too large Load Diff

View File

@@ -39,6 +39,9 @@ message SaasReq {
ExpList exp_list = 100; // 列出实验 ExpList exp_list = 100; // 列出实验
ExpGet exp_get = 101; // 获取实验报表 ExpGet exp_get = 101; // 获取实验报表
ExpGrantList exp_grant_list = 102; // 列出访问实验报表授权
ExpGrant exp_grant_add = 103; // 授权他人访问实验报表
ExpGrant exp_grant_delete = 104; // 取消他人访问实验报表
} }
} }
@@ -260,6 +263,14 @@ message ExpGet {
uint32 total_flag = 30; // 是否汇总0=不汇总1=汇总 uint32 total_flag = 30; // 是否汇总0=不汇总1=汇总
} }
message ExpGrantList {
}
message ExpGrant {
uint32 target_account_id = 1; // sRTA授权目标账号ID
}
// SaasRes 命令返回 // SaasRes 命令返回
message SaasRes { message SaasRes {
ErrorCode code = 1; // 返回码 ErrorCode code = 1; // 返回码
@@ -296,12 +307,16 @@ message SaasRes {
ExpListRes exp_list_res = 100; // 实验列表返回 ExpListRes exp_list_res = 100; // 实验列表返回
ExpGetRes exp_get_res = 101; // 实验报表返回 ExpGetRes exp_get_res = 101; // 实验报表返回
ExpGrantListRes exp_grant_list_res = 102; // 实验授权列表返回
ExpGrant exp_grant_add_res = 103; // 增加实验授权返回
ExpGrant exp_grant_delete_res = 104; // 实验解除授权返回
} }
} }
message DataSpace { message DataSpace {
repeated string did = 1; // 设备ID区 repeated string did = 1; // 设备ID区
repeated string wuid = 2; // OpenID区 repeated string wuid = 2; // OpenID区
repeated string geo = 7; // GEO区
} }
// InfoRes 账号信息返回 // InfoRes 账号信息返回
@@ -471,6 +486,7 @@ message ExpGetRes {
repeated ExpData exp_data = 1; // 实验数据 repeated ExpData exp_data = 1; // 实验数据
} }
// ExpData 实验数据
message ExpData { message ExpData {
uint64 time = 1; // 日期 uint64 time = 1; // 日期
uint32 bucket_id = 2; // 分桶ID uint32 bucket_id = 2; // 分桶ID
@@ -479,6 +495,7 @@ message ExpData {
map<string, uint64> group = 5; // 分组 map<string, uint64> group = 5; // 分组
} }
// ExpBaseFields 基础实验字段
message ExpBaseFields { message ExpBaseFields {
double cost = 1; // 花费 double cost = 1; // 花费
int64 exposure = 2; // 曝光量 int64 exposure = 2; // 曝光量
@@ -493,6 +510,12 @@ message ExpBaseFields {
int64 conversion_second = 11; // 深层转化量 int64 conversion_second = 11; // 深层转化量
} }
// ExpGrantListRes 授权列表返回
message ExpGrantListRes {
repeated ExpGrant from = 1; // 被授权列表
repeated ExpGrant to = 2; // 向外授权列表
}
// ErrorCode 返回码 // ErrorCode 返回码
enum ErrorCode { enum ErrorCode {
SUCC = 0; // 成功 SUCC = 0; // 成功

View File

@@ -4,3 +4,4 @@ saastool_linux
*.toml *.toml
test/ test/
*.lua *.lua
test.txt

View File

@@ -221,9 +221,9 @@ func (d *Daemon) parsePublicParams(r *http.Request) (*daemonPublicParams, error)
params.ds = strings.ToLower(strings.TrimSpace(q.Get("ds"))) params.ds = strings.ToLower(strings.TrimSpace(q.Get("ds")))
switch params.ds { switch params.ds {
case "did", "wuid": case "did", "wuid", "geo":
default: default:
return nil, fmt.Errorf("ds must use did/wuid. current is %v", params.ds) return nil, fmt.Errorf("ds must use did/wuid/geo. current is %v", params.ds)
} }
params.appid = strings.TrimSpace(q.Get("appid")) params.appid = strings.TrimSpace(q.Get("appid"))

View File

@@ -17,6 +17,8 @@ func RunExp(args ...string) error {
return RunExpList(args...) return RunExpList(args...)
case "get": case "get":
return RunExpGet(args...) return RunExpGet(args...)
case "grant":
return RunExpGrant(args...)
default: default:
err := fmt.Errorf(`unknown command "%s"`+"\n"+`Run 'saastool exp help' for usage`, name) err := fmt.Errorf(`unknown command "%s"`+"\n"+`Run 'saastool exp help' for usage`, name)
fmt.Fprintln(os.Stderr, err) fmt.Fprintln(os.Stderr, err)
@@ -31,11 +33,12 @@ func RunExpHelp(args ...string) error {
} }
const expUsage = ` const expUsage = `
Usage: saastoola exp COMMAND [OPTIONS] Usage: saastool exp COMMAND [OPTIONS]
Commands: Commands:
list List exps list List exps
get Get exp report get Get exp report
grant Experiment authorization management
"help" is the default command. "help" is the default command.

40
cmd/saastool/exp_grant.go Normal file
View File

@@ -0,0 +1,40 @@
package main
import (
"fmt"
"os"
"strings"
)
func RunExpGrant(args ...string) error {
name, args := ParseCommandName(args)
switch name {
case "", "help":
fmt.Println(strings.TrimSpace(expGrantUsage))
return nil
case "list":
return RunExpGrantList(args...)
case "add":
return RunExpGrantAdd(args...)
case "delete":
return RunExpGrantDelete(args...)
default:
err := fmt.Errorf(`unknown command "%s"`+"\n"+`Run 'saastool exp grant help' for usage`, name)
fmt.Fprintln(os.Stderr, err)
return err
}
}
const expGrantUsage = `
Usage: saastool exp grant COMMAND [OPTIONS]
Commands:
list List experiment authorization
add Add experiment authorization
delete Delete experiment authorization
"help" is the default command.
Use "saastool exp grant COMMAND -help" for more information about a command.
`

View File

@@ -0,0 +1,81 @@
package main
import (
"flag"
"fmt"
"net/http"
"os"
"git.algo.com.cn/public/saasapi"
"git.algo.com.cn/public/saasapi/pkg/saashttp"
"google.golang.org/protobuf/encoding/protojson"
)
type expGrantAddParams struct {
srtaAccountId uint32
saasHttp *saashttp.SaasClient
}
func RunExpGrantAdd(args ...string) error {
fs := flag.NewFlagSet("add", flag.ExitOnError)
cfgFile := paramConfig(fs)
srtaAccountId := paramSrtaAccountId(fs)
if err := fs.Parse(args); err != nil {
fmt.Fprintln(os.Stderr, "command line parse error", "err", err)
return err
}
if fs.NArg() > 0 {
fs.PrintDefaults()
return nil
}
if *srtaAccountId == 0 {
fmt.Fprintln(os.Stderr, "Error: sRTA account ID is required")
fs.PrintDefaults()
return fmt.Errorf("sRTA account ID is required")
}
cfg, err := LoadConfigFile(*cfgFile)
if err != nil {
fmt.Fprintln(os.Stderr, "LoadConfigFile error", "err", err)
return err
}
expGrantAddParams := expGrantAddParams{
srtaAccountId: uint32(*srtaAccountId),
saasHttp: &saashttp.SaasClient{
Client: &http.Client{},
ApiUrls: saashttp.InitAPIUrl(&cfg.ApiUrls),
Auth: &cfg.Auth,
},
}
return doExpGrantAdd(expGrantAddParams)
}
func doExpGrantAdd(params expGrantAddParams) error {
saasReq := &saasapi.SaasReq{
Cmd: &saasapi.SaasReq_ExpGrantAdd{
ExpGrantAdd: &saasapi.ExpGrant{
TargetAccountId: params.srtaAccountId,
},
},
}
res, err := params.saasHttp.ExpGrantAdd(saasReq)
if err != nil {
fmt.Fprintln(os.Stderr, "submit Exp Grant Add error", "err", err)
return err
}
if res.Code != saasapi.ErrorCode_SUCC {
fmt.Fprintln(os.Stderr, "Exp grant add failed", "code", res.Code, "status", res.Status)
return nil
}
expGrantRes := res.GetExpGrantAddRes()
fmt.Printf("exp grant add res: %v\n", protojson.Format(expGrantRes))
return nil
}

View File

@@ -0,0 +1,81 @@
package main
import (
"flag"
"fmt"
"net/http"
"os"
"git.algo.com.cn/public/saasapi"
"git.algo.com.cn/public/saasapi/pkg/saashttp"
"google.golang.org/protobuf/encoding/protojson"
)
type expGrantDeleteParams struct {
srtaAccountId uint32
saasHttp *saashttp.SaasClient
}
func RunExpGrantDelete(args ...string) error {
fs := flag.NewFlagSet("delete", flag.ExitOnError)
cfgFile := paramConfig(fs)
srtaAccountId := paramSrtaAccountId(fs)
if err := fs.Parse(args); err != nil {
fmt.Fprintln(os.Stderr, "command line parse error", "err", err)
return err
}
if fs.NArg() > 0 {
fs.PrintDefaults()
return nil
}
if *srtaAccountId == 0 {
fmt.Fprintln(os.Stderr, "Error: sRTA account ID is required")
fs.PrintDefaults()
return fmt.Errorf("sRTA account ID is required")
}
cfg, err := LoadConfigFile(*cfgFile)
if err != nil {
fmt.Fprintln(os.Stderr, "LoadConfigFile error", "err", err)
return err
}
expGrantDeleteParams := expGrantDeleteParams{
srtaAccountId: uint32(*srtaAccountId),
saasHttp: &saashttp.SaasClient{
Client: &http.Client{},
ApiUrls: saashttp.InitAPIUrl(&cfg.ApiUrls),
Auth: &cfg.Auth,
},
}
return doExpGrantDelete(expGrantDeleteParams)
}
func doExpGrantDelete(params expGrantDeleteParams) error {
saasReq := &saasapi.SaasReq{
Cmd: &saasapi.SaasReq_ExpGrantDelete{
ExpGrantDelete: &saasapi.ExpGrant{
TargetAccountId: params.srtaAccountId,
},
},
}
res, err := params.saasHttp.ExpGrantDelete(saasReq)
if err != nil {
fmt.Fprintln(os.Stderr, "submit Exp Grant Delete error", "err", err)
return err
}
if res.Code != saasapi.ErrorCode_SUCC {
fmt.Fprintln(os.Stderr, "Exp grant delete failed", "code", res.Code, "status", res.Status)
return nil
}
expGrantRes := res.GetExpGrantDeleteRes()
fmt.Printf("exp grant delete res: %v\n", protojson.Format(expGrantRes))
return nil
}

View File

@@ -0,0 +1,70 @@
package main
import (
"flag"
"fmt"
"net/http"
"os"
"git.algo.com.cn/public/saasapi"
"git.algo.com.cn/public/saasapi/pkg/saashttp"
"google.golang.org/protobuf/encoding/protojson"
)
type expGrantListParams struct {
saasHttp *saashttp.SaasClient
}
func RunExpGrantList(args ...string) error {
fs := flag.NewFlagSet("list", flag.ExitOnError)
cfgFile := paramConfig(fs)
if err := fs.Parse(args); err != nil {
fmt.Fprintln(os.Stderr, "command line parse error", "err", err)
return err
}
if fs.NArg() > 0 {
fs.PrintDefaults()
return nil
}
cfg, err := LoadConfigFile(*cfgFile)
if err != nil {
fmt.Fprintln(os.Stderr, "LoadConfigFile error", "err", err)
return err
}
expGrantListParams := expGrantListParams{
saasHttp: &saashttp.SaasClient{
Client: &http.Client{},
ApiUrls: saashttp.InitAPIUrl(&cfg.ApiUrls),
Auth: &cfg.Auth,
},
}
return doExpGrantList(expGrantListParams)
}
func doExpGrantList(params expGrantListParams) error {
saasReq := &saasapi.SaasReq{
Cmd: &saasapi.SaasReq_ExpGrantList{
ExpGrantList: &saasapi.ExpGrantList{},
},
}
res, err := params.saasHttp.ExpGrantList(saasReq)
if err != nil {
fmt.Fprintln(os.Stderr, "submit Exp Grant List error", "err", err)
return err
}
if res.Code != saasapi.ErrorCode_SUCC {
fmt.Fprintln(os.Stderr, "Exp grant list failed", "code", res.Code, "status", res.Status)
return nil
}
expGrantRes := res.GetExpGrantListRes()
fmt.Printf("exp grant list res: %v\n", protojson.Format(expGrantRes))
return nil
}

View File

@@ -74,7 +74,6 @@ func RunTaskMake(args ...string) error {
fmt.Fprintln(os.Stderr, "Error parsing block size", "err", err) fmt.Fprintln(os.Stderr, "Error parsing block size", "err", err)
fmt.Fprintln(os.Stderr, "Using default 200M") fmt.Fprintln(os.Stderr, "Using default 200M")
blockSizeNum = 200 * 1024 * 1024 blockSizeNum = 200 * 1024 * 1024
} }
if blockSizeNum < blockSizeMin || blockSizeNum > blockSizeMax { if blockSizeNum < blockSizeMin || blockSizeNum > blockSizeMax {

View File

@@ -4,7 +4,7 @@ set -e
docker buildx build --platform linux/amd64 \ docker buildx build --platform linux/amd64 \
-t rta-docker.pkg.coding.net/public/docker/saastool:latest \ -t rta-docker.pkg.coding.net/public/docker/saastool:latest \
-t rta-docker.pkg.coding.net/public/docker/saastool:2025112312 \ -t rta-docker.pkg.coding.net/public/docker/saastool:2025121210 \
-o type=registry \ -o type=registry \
-f saastool.Dockerfile \ -f saastool.Dockerfile \
../ ; ../ ;

View File

@@ -1,3 +1,8 @@
cd cmd/saastool cd cmd/saastool
go build -o ../../build/saastool go build -o ../../build/saastool
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o ../../build/saastool_linux_x64
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -o ../../build/saastool_win_x64
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -o ../../build/saastool_mac_x64
CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -o ../../build/saastool_mac_arm64
cd ../../ cd ../../

View File

@@ -26,6 +26,9 @@ const (
scriptUsePath = "/saas/script/use" scriptUsePath = "/saas/script/use"
expListPath = "/saas/exp/list" expListPath = "/saas/exp/list"
expGetPath = "/saas/exp/get" expGetPath = "/saas/exp/get"
expGrantListPath = "/saas/exp/grant/list"
expGrantAddPath = "/saas/exp/grant/add"
expGrantDeletePath = "/saas/exp/grant/delete"
grantListPath = "/saas/grant/list" grantListPath = "/saas/grant/list"
grantAddPath = "/saas/grant/add" grantAddPath = "/saas/grant/add"
grantDeletePath = "/saas/grant/delete" grantDeletePath = "/saas/grant/delete"
@@ -62,6 +65,9 @@ type ApiUrls struct {
ScriptUsePath string ScriptUsePath string
ExpListPath string ExpListPath string
ExpGetPath string ExpGetPath string
ExpGrantListPath string
ExpGrantAddPath string
ExpGrantDeletePath string
GrantListPath string GrantListPath string
GrantAddPath string GrantAddPath string
GrantDeletePath string GrantDeletePath string
@@ -204,6 +210,24 @@ func InitAPIUrl(c *ApiUrls) *ApiUrls {
r.ExpGetPath = expGetPath r.ExpGetPath = expGetPath
} }
if c.ExpGrantListPath != "" {
r.ExpGrantListPath = c.ExpGrantListPath
} else {
r.ExpGrantListPath = expGrantListPath
}
if c.ExpGrantAddPath != "" {
r.ExpGrantAddPath = c.ExpGrantAddPath
} else {
r.ExpGrantAddPath = expGrantAddPath
}
if c.ExpGrantDeletePath != "" {
r.ExpGrantDeletePath = c.ExpGrantDeletePath
} else {
r.ExpGrantDeletePath = expGrantDeletePath
}
if c.GrantListPath != "" { if c.GrantListPath != "" {
r.GrantListPath = c.GrantListPath r.GrantListPath = c.GrantListPath
} else { } else {

View File

@@ -143,6 +143,21 @@ func (c *SaasClient) GrantDelete(saasReq *saasapi.SaasReq) (saasRes *saasapi.Saa
return c.post(postUrl, saasReq) return c.post(postUrl, saasReq)
} }
func (c *SaasClient) ExpGrantList(saasReq *saasapi.SaasReq) (saasRes *saasapi.SaasRes, err error) {
postUrl := c.makeUrl(c.ApiUrls.BaseUrl, c.ApiUrls.ExpGrantListPath)
return c.post(postUrl, saasReq)
}
func (c *SaasClient) ExpGrantAdd(saasReq *saasapi.SaasReq) (saasRes *saasapi.SaasRes, err error) {
postUrl := c.makeUrl(c.ApiUrls.BaseUrl, c.ApiUrls.ExpGrantAddPath)
return c.post(postUrl, saasReq)
}
func (c *SaasClient) ExpGrantDelete(saasReq *saasapi.SaasReq) (saasRes *saasapi.SaasRes, err error) {
postUrl := c.makeUrl(c.ApiUrls.BaseUrl, c.ApiUrls.ExpGrantDeletePath)
return c.post(postUrl, saasReq)
}
func (c *SaasClient) makeUrl(baseUrl, path string, params ...string) string { func (c *SaasClient) makeUrl(baseUrl, path string, params ...string) string {
url, err := url.Parse(baseUrl) url, err := url.Parse(baseUrl)
if err != nil { if err != nil {