+ OSS support
This commit is contained in:
parent
3d2d97f20d
commit
976b4aa7eb
11 changed files with 211 additions and 91 deletions
|
|
@ -7,9 +7,9 @@
|
||||||
"oss": {
|
"oss": {
|
||||||
"comment": "https://www.alibabacloud.com/help/zh/doc-detail/100624.htm",
|
"comment": "https://www.alibabacloud.com/help/zh/doc-detail/100624.htm",
|
||||||
"endpoint": "oss-cn-hangzhou.aliyuncs.com",
|
"endpoint": "oss-cn-hangzhou.aliyuncs.com",
|
||||||
"id": "LTAI5tLC5cnKqF2eB4L7De3S",
|
"id": "LTAI5tHXfWAMpcsobfqfeXsm",
|
||||||
"secret": "OkD17XjvjNQoiLgRyyjIsTnviULr0w",
|
"secret": "4NeGNw97nFrfmgBWZTlFE0XtYQdMQO",
|
||||||
"roleArn": "RamOssTest",
|
"roleArn": "acs:ram::31524094:role/ramosstest",
|
||||||
"sessionName": "SessionTest"
|
"sessionName": "SessionTest"
|
||||||
},
|
},
|
||||||
"cos": {},
|
"cos": {},
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"github.com/yaoapp/gou"
|
"github.com/yaoapp/gou"
|
||||||
"github.com/yaoapp/xiang/config"
|
"github.com/yaoapp/xiang/config"
|
||||||
"github.com/yaoapp/xiang/global"
|
"github.com/yaoapp/xiang/global"
|
||||||
|
"github.com/yaoapp/xiang/share"
|
||||||
)
|
)
|
||||||
|
|
||||||
var startCmd = &cobra.Command{
|
var startCmd = &cobra.Command{
|
||||||
|
|
@ -34,10 +35,10 @@ var startCmd = &cobra.Command{
|
||||||
|
|
||||||
// 打印应用目录信息
|
// 打印应用目录信息
|
||||||
fmt.Printf(color.WhiteString("\n---------------------------------"))
|
fmt.Printf(color.WhiteString("\n---------------------------------"))
|
||||||
fmt.Printf(color.GreenString("\n应用名称: %s v%s", global.App.Name, global.App.Version))
|
fmt.Printf(color.GreenString("\n应用名称: %s v%s", share.App.Name, share.App.Version))
|
||||||
fmt.Printf(color.GreenString("\n应用根目录: %s", config.Conf.Root))
|
fmt.Printf(color.GreenString("\n应用根目录: %s", config.Conf.Root))
|
||||||
fmt.Printf(color.GreenString("\n数据存储目录: %s", config.Conf.RootData))
|
fmt.Printf(color.GreenString("\n数据存储目录: %s", config.Conf.RootData))
|
||||||
fmt.Printf(color.GreenString("\n数据存储引擎: %s", global.App.Storage.Default))
|
fmt.Printf(color.GreenString("\n数据存储引擎: %s", share.App.Storage.Default))
|
||||||
fmt.Printf(color.WhiteString("\n---------------------------------\n\n"))
|
fmt.Printf(color.WhiteString("\n---------------------------------\n\n"))
|
||||||
|
|
||||||
fmt.Printf(color.GreenString("\n已注册API"))
|
fmt.Printf(color.GreenString("\n已注册API"))
|
||||||
|
|
|
||||||
|
|
@ -1,81 +0,0 @@
|
||||||
package global
|
|
||||||
|
|
||||||
import (
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
"github.com/yaoapp/kun/exception"
|
|
||||||
"github.com/yaoapp/xiang/data"
|
|
||||||
"github.com/yaoapp/xiang/xfs"
|
|
||||||
)
|
|
||||||
|
|
||||||
// App 应用信息
|
|
||||||
var App AppInfo
|
|
||||||
|
|
||||||
// AppInfo 应用信息
|
|
||||||
type AppInfo struct {
|
|
||||||
Name string `json:"name,omitempty"`
|
|
||||||
Short string `json:"short,omitempty"`
|
|
||||||
Version string `json:"version,omitempty"`
|
|
||||||
Description string `json:"description,omitempty"`
|
|
||||||
Icons map[string]string `json:"icons,omitempty"`
|
|
||||||
Storage AppStorage `json:"storage,omitempty"`
|
|
||||||
Option map[string]interface{} `json:"option,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// AppStorage 应用存储
|
|
||||||
type AppStorage struct {
|
|
||||||
Default string `json:"default"`
|
|
||||||
Buckets map[string]string `json:"buckets,omitempty"`
|
|
||||||
S3 map[string]interface{} `json:"s3,omitempty"`
|
|
||||||
OSS map[string]interface{} `json:"oss,omitempty"`
|
|
||||||
COS map[string]interface{} `json:"cos,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// LoadAppInfo 读取应用信息
|
|
||||||
func LoadAppInfo(root string) {
|
|
||||||
info := defaultAppInfo()
|
|
||||||
fs := xfs.New(root)
|
|
||||||
if fs.MustExists("/app.json") {
|
|
||||||
err := jsoniter.Unmarshal(fs.MustReadFile("/app.json"), &info)
|
|
||||||
if err != nil {
|
|
||||||
exception.New("解析应用失败 %s", 500, err).Throw()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if fs.MustExists("/xiang/icons/icon.icns") {
|
|
||||||
info.Icons["icns"] = xfs.Encode(fs.MustReadFile("/xiang/icons/icon.icns"))
|
|
||||||
}
|
|
||||||
|
|
||||||
if fs.MustExists("/xiang/icons/icon.ico") {
|
|
||||||
info.Icons["ico"] = xfs.Encode(fs.MustReadFile("/xiang/icons/icon.ico"))
|
|
||||||
}
|
|
||||||
|
|
||||||
if fs.MustExists("/xiang/icons/icon.png") {
|
|
||||||
info.Icons["png"] = xfs.Encode(fs.MustReadFile("/xiang/icons/icon.png"))
|
|
||||||
}
|
|
||||||
|
|
||||||
App = info
|
|
||||||
}
|
|
||||||
|
|
||||||
// defaultAppInfo 读取默认应用信息
|
|
||||||
func defaultAppInfo() AppInfo {
|
|
||||||
info := AppInfo{}
|
|
||||||
err := jsoniter.Unmarshal(data.MustAsset("xiang/data/app.json"), &info)
|
|
||||||
if err != nil {
|
|
||||||
exception.New("解析默认应用失败 %s", 500, err).Throw()
|
|
||||||
}
|
|
||||||
|
|
||||||
info.Version = VERSION
|
|
||||||
info.Icons["icns"] = xfs.Encode(data.MustAsset("xiang/data/icons/icon.icns"))
|
|
||||||
info.Icons["ico"] = xfs.Encode(data.MustAsset("xiang/data/icons/icon.ico"))
|
|
||||||
info.Icons["png"] = xfs.Encode(data.MustAsset("xiang/data/icons/icon.png"))
|
|
||||||
|
|
||||||
return info
|
|
||||||
}
|
|
||||||
|
|
||||||
// Public 输出公共信息
|
|
||||||
func (app AppInfo) Public() AppInfo {
|
|
||||||
app.Storage.COS = nil
|
|
||||||
app.Storage.OSS = nil
|
|
||||||
app.Storage.S3 = nil
|
|
||||||
return app
|
|
||||||
}
|
|
||||||
|
|
@ -9,11 +9,14 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
jsoniter "github.com/json-iterator/go"
|
||||||
"github.com/yaoapp/gou"
|
"github.com/yaoapp/gou"
|
||||||
"github.com/yaoapp/kun/exception"
|
"github.com/yaoapp/kun/exception"
|
||||||
"github.com/yaoapp/xiang/config"
|
"github.com/yaoapp/xiang/config"
|
||||||
"github.com/yaoapp/xiang/data"
|
"github.com/yaoapp/xiang/data"
|
||||||
|
"github.com/yaoapp/xiang/share"
|
||||||
"github.com/yaoapp/xiang/table"
|
"github.com/yaoapp/xiang/table"
|
||||||
|
"github.com/yaoapp/xiang/xfs"
|
||||||
"github.com/yaoapp/xun/capsule"
|
"github.com/yaoapp/xun/capsule"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -63,6 +66,47 @@ func Load(cfg config.Config) {
|
||||||
Conf = cfg
|
Conf = cfg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LoadAppInfo 读取应用信息
|
||||||
|
func LoadAppInfo(root string) {
|
||||||
|
info := defaultAppInfo()
|
||||||
|
fs := xfs.New(root)
|
||||||
|
if fs.MustExists("/app.json") {
|
||||||
|
err := jsoniter.Unmarshal(fs.MustReadFile("/app.json"), &info)
|
||||||
|
if err != nil {
|
||||||
|
exception.New("解析应用失败 %s", 500, err).Throw()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if fs.MustExists("/xiang/icons/icon.icns") {
|
||||||
|
info.Icons["icns"] = xfs.Encode(fs.MustReadFile("/xiang/icons/icon.icns"))
|
||||||
|
}
|
||||||
|
|
||||||
|
if fs.MustExists("/xiang/icons/icon.ico") {
|
||||||
|
info.Icons["ico"] = xfs.Encode(fs.MustReadFile("/xiang/icons/icon.ico"))
|
||||||
|
}
|
||||||
|
|
||||||
|
if fs.MustExists("/xiang/icons/icon.png") {
|
||||||
|
info.Icons["png"] = xfs.Encode(fs.MustReadFile("/xiang/icons/icon.png"))
|
||||||
|
}
|
||||||
|
|
||||||
|
share.App = info
|
||||||
|
}
|
||||||
|
|
||||||
|
// defaultAppInfo 读取默认应用信息
|
||||||
|
func defaultAppInfo() share.AppInfo {
|
||||||
|
info := share.AppInfo{}
|
||||||
|
err := jsoniter.Unmarshal(data.MustAsset("xiang/data/app.json"), &info)
|
||||||
|
if err != nil {
|
||||||
|
exception.New("解析默认应用失败 %s", 500, err).Throw()
|
||||||
|
}
|
||||||
|
|
||||||
|
info.Icons["icns"] = xfs.Encode(data.MustAsset("xiang/data/icons/icon.icns"))
|
||||||
|
info.Icons["ico"] = xfs.Encode(data.MustAsset("xiang/data/icons/icon.ico"))
|
||||||
|
info.Icons["png"] = xfs.Encode(data.MustAsset("xiang/data/icons/icon.png"))
|
||||||
|
|
||||||
|
return info
|
||||||
|
}
|
||||||
|
|
||||||
// Reload 根据配置重新加载 API, FLow, Model, Plugin
|
// Reload 根据配置重新加载 API, FLow, Model, Plugin
|
||||||
func Reload(cfg config.Config) {
|
func Reload(cfg config.Config) {
|
||||||
gou.APIs = map[string]*gou.API{}
|
gou.APIs = map[string]*gou.API{}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package global
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/yaoapp/gou"
|
"github.com/yaoapp/gou"
|
||||||
|
"github.com/yaoapp/xiang/share"
|
||||||
"github.com/yaoapp/xiang/xfs"
|
"github.com/yaoapp/xiang/xfs"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -28,13 +29,13 @@ func processPing(process *gou.Process) interface{} {
|
||||||
|
|
||||||
// processInspect 返回系统信息
|
// processInspect 返回系统信息
|
||||||
func processInspect(process *gou.Process) interface{} {
|
func processInspect(process *gou.Process) interface{} {
|
||||||
App.Icons["favicon"] = "/api/xiang/favicon.ico"
|
share.App.Icons["favicon"] = "/api/xiang/favicon.ico"
|
||||||
return App.Public()
|
return share.App.Public()
|
||||||
}
|
}
|
||||||
|
|
||||||
// processFavicon 运行模型 MustCreate
|
// processFavicon 运行模型 MustCreate
|
||||||
func processFavicon(process *gou.Process) interface{} {
|
func processFavicon(process *gou.Process) interface{} {
|
||||||
return xfs.DecodeString(App.Icons["png"])
|
return xfs.DecodeString(share.App.Icons["png"])
|
||||||
}
|
}
|
||||||
|
|
||||||
// processFileContent 返回文件内容
|
// processFileContent 返回文件内容
|
||||||
|
|
|
||||||
3
go.mod
3
go.mod
|
|
@ -3,6 +3,8 @@ module github.com/yaoapp/xiang
|
||||||
go 1.16
|
go 1.16
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1286 // indirect
|
||||||
|
github.com/aliyun/aliyun-oss-go-sdk v2.1.10+incompatible // indirect
|
||||||
github.com/caarlos0/env/v6 v6.7.1 // indirect
|
github.com/caarlos0/env/v6 v6.7.1 // indirect
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
|
||||||
github.com/elazarl/go-bindata-assetfs v1.0.1 // indirect
|
github.com/elazarl/go-bindata-assetfs v1.0.1 // indirect
|
||||||
|
|
@ -34,6 +36,7 @@ require (
|
||||||
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d // indirect
|
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d // indirect
|
||||||
golang.org/x/net v0.0.0-20211006190231-62292e806868 // indirect
|
golang.org/x/net v0.0.0-20211006190231-62292e806868 // indirect
|
||||||
golang.org/x/sys v0.0.0-20211006225509-1a26e0398eed // indirect
|
golang.org/x/sys v0.0.0-20211006225509-1a26e0398eed // indirect
|
||||||
|
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect
|
||||||
google.golang.org/genproto v0.0.0-20211005153810-c76a74d43a8e // indirect
|
google.golang.org/genproto v0.0.0-20211005153810-c76a74d43a8e // indirect
|
||||||
google.golang.org/grpc v1.41.0 // indirect
|
google.golang.org/grpc v1.41.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
|
||||||
11
go.sum
11
go.sum
|
|
@ -42,6 +42,10 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym
|
||||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||||
github.com/TylerBrock/colorjson v0.0.0-20200706003622-8a50f05110d2 h1:ZBbLwSJqkHBuFDA6DUhhse0IGJ7T5bemHyNILUjvOq4=
|
github.com/TylerBrock/colorjson v0.0.0-20200706003622-8a50f05110d2 h1:ZBbLwSJqkHBuFDA6DUhhse0IGJ7T5bemHyNILUjvOq4=
|
||||||
github.com/TylerBrock/colorjson v0.0.0-20200706003622-8a50f05110d2/go.mod h1:VSw57q4QFiWDbRnjdX8Cb3Ow0SFncRw+bA/ofY6Q83w=
|
github.com/TylerBrock/colorjson v0.0.0-20200706003622-8a50f05110d2/go.mod h1:VSw57q4QFiWDbRnjdX8Cb3Ow0SFncRw+bA/ofY6Q83w=
|
||||||
|
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1286 h1:+Ah33S/QRnOFp4dM6VV2gYDbFu3Cj4HrRy1VpOhBzm8=
|
||||||
|
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1286/go.mod h1:9CMdKNL3ynIGPpfTcdwTvIm8SGuAZYYC4jFVSSvE1YQ=
|
||||||
|
github.com/aliyun/aliyun-oss-go-sdk v2.1.10+incompatible h1:D3gwOr9qUUmyyBRDbpnATqu+EkqqmigFd3Od6xO1QUU=
|
||||||
|
github.com/aliyun/aliyun-oss-go-sdk v2.1.10+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
|
||||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||||
|
|
@ -119,6 +123,7 @@ github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfC
|
||||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||||
|
github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A=
|
||||||
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
||||||
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
||||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
|
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
|
||||||
|
|
@ -227,12 +232,15 @@ github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:
|
||||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||||
github.com/jhump/protoreflect v1.6.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74=
|
github.com/jhump/protoreflect v1.6.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74=
|
||||||
|
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
|
||||||
|
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||||
github.com/jmoiron/sqlx v1.3.1 h1:aLN7YINNZ7cYOPK3QC83dbM6KT0NMqVMw961TqrejlE=
|
github.com/jmoiron/sqlx v1.3.1 h1:aLN7YINNZ7cYOPK3QC83dbM6KT0NMqVMw961TqrejlE=
|
||||||
github.com/jmoiron/sqlx v1.3.1/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ=
|
github.com/jmoiron/sqlx v1.3.1/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ=
|
||||||
github.com/jmoiron/sqlx v1.3.4 h1:wv+0IJZfL5z0uZoUjlpKgHkgaFSYD+r9CfrXjEXsO7w=
|
github.com/jmoiron/sqlx v1.3.4 h1:wv+0IJZfL5z0uZoUjlpKgHkgaFSYD+r9CfrXjEXsO7w=
|
||||||
github.com/jmoiron/sqlx v1.3.4/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ=
|
github.com/jmoiron/sqlx v1.3.4/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ=
|
||||||
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
|
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
|
||||||
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
|
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
|
||||||
|
github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ=
|
github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ=
|
||||||
|
|
@ -640,6 +648,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
|
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs=
|
||||||
|
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||||
|
|
@ -825,6 +835,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||||
|
gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
|
||||||
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||||
gopkg.in/readline.v1 v1.0.0-20160726135117-62c6fe619375/go.mod h1:lNEQeAhU009zbRxng+XOj5ITVgY24WcbNnQopyfKoYQ=
|
gopkg.in/readline.v1 v1.0.0-20160726135117-62c6fe619375/go.mod h1:lNEQeAhU009zbRxng+XOj5ITVgY24WcbNnQopyfKoYQ=
|
||||||
gopkg.in/sourcemap.v1 v1.0.5 h1:inv58fC9f9J3TK2Y2R1NPntXEn3/wjWHkonhIUODNTI=
|
gopkg.in/sourcemap.v1 v1.0.5 h1:inv58fC9f9J3TK2Y2R1NPntXEn3/wjWHkonhIUODNTI=
|
||||||
|
|
|
||||||
41
share/app.go
Normal file
41
share/app.go
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
package share
|
||||||
|
|
||||||
|
// App 应用信息
|
||||||
|
var App AppInfo
|
||||||
|
|
||||||
|
// AppInfo 应用信息
|
||||||
|
type AppInfo struct {
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
Short string `json:"short,omitempty"`
|
||||||
|
Version string `json:"version,omitempty"`
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
|
Icons map[string]string `json:"icons,omitempty"`
|
||||||
|
Storage AppStorage `json:"storage,omitempty"`
|
||||||
|
Option map[string]interface{} `json:"option,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppStorage 应用存储
|
||||||
|
type AppStorage struct {
|
||||||
|
Default string `json:"default"`
|
||||||
|
Buckets map[string]string `json:"buckets,omitempty"`
|
||||||
|
S3 map[string]interface{} `json:"s3,omitempty"`
|
||||||
|
OSS *AppStorageOSS `json:"oss,omitempty"`
|
||||||
|
COS map[string]interface{} `json:"cos,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppStorageOSS 阿里云存储
|
||||||
|
type AppStorageOSS struct {
|
||||||
|
Endpoint string `json:"endpoint,omitempty"`
|
||||||
|
ID string `json:"id,omitempty"`
|
||||||
|
Secret string `json:"secret,omitempty"`
|
||||||
|
RoleArn string `json:"roleArn,omitempty"`
|
||||||
|
SessionName string `json:"sessionName,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Public 输出公共信息
|
||||||
|
func (app AppInfo) Public() AppInfo {
|
||||||
|
app.Storage.COS = nil
|
||||||
|
app.Storage.OSS = nil
|
||||||
|
app.Storage.S3 = nil
|
||||||
|
return app
|
||||||
|
}
|
||||||
|
|
@ -9,9 +9,12 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/aliyun/alibaba-cloud-sdk-go/services/sts"
|
||||||
"github.com/yaoapp/gou"
|
"github.com/yaoapp/gou"
|
||||||
|
"github.com/yaoapp/kun/any"
|
||||||
"github.com/yaoapp/kun/exception"
|
"github.com/yaoapp/kun/exception"
|
||||||
"github.com/yaoapp/kun/maps"
|
"github.com/yaoapp/kun/maps"
|
||||||
|
"github.com/yaoapp/xiang/share"
|
||||||
"github.com/yaoapp/xun"
|
"github.com/yaoapp/xun"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -76,7 +79,42 @@ func processReadFile(process *gou.Process) interface{} {
|
||||||
|
|
||||||
// processGetToken 上传文件到腾讯云对象存储 COS
|
// processGetToken 上传文件到腾讯云对象存储 COS
|
||||||
func processGetToken(process *gou.Process) interface{} {
|
func processGetToken(process *gou.Process) interface{} {
|
||||||
return nil
|
process.ValidateArgNums(2)
|
||||||
|
name := process.ArgsString(0, "oss")
|
||||||
|
// bucket := process.ArgsString(1)
|
||||||
|
if name != "oss" {
|
||||||
|
exception.New("暂时支持 oss 存储", 400).Throw()
|
||||||
|
}
|
||||||
|
|
||||||
|
if share.App.Storage.OSS == nil {
|
||||||
|
exception.New("未配置 OSS 存储", 400).Throw()
|
||||||
|
}
|
||||||
|
|
||||||
|
app := share.App.Storage.OSS
|
||||||
|
id := strings.Split(app.Endpoint, ".")[0]
|
||||||
|
client, err := sts.NewClientWithAccessKey(id, app.ID, app.Secret)
|
||||||
|
if err != nil {
|
||||||
|
exception.New("配置错误 %s", 400, err.Error()).Throw()
|
||||||
|
}
|
||||||
|
|
||||||
|
//构建请求对象。
|
||||||
|
request := sts.CreateAssumeRoleRequest()
|
||||||
|
request.Scheme = "https"
|
||||||
|
request.Domain = "sts.aliyuncs.com"
|
||||||
|
|
||||||
|
//设置参数。关于参数含义和设置方法,请参见API参考。
|
||||||
|
request.RoleArn = app.RoleArn
|
||||||
|
request.RoleSessionName = app.SessionName
|
||||||
|
|
||||||
|
//发起请求,并得到响应。
|
||||||
|
response, err := client.AssumeRole(request)
|
||||||
|
if err != nil {
|
||||||
|
exception.New("配置错误 %s", 400, err.Error()).Throw()
|
||||||
|
}
|
||||||
|
|
||||||
|
res := any.Of(response.Credentials).Map()
|
||||||
|
res.Set("Endpoint", app.Endpoint)
|
||||||
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
// processGetURL 返回文件CDN地址
|
// processGetURL 返回文件CDN地址
|
||||||
|
|
|
||||||
62
xfs/process_test.go
Normal file
62
xfs/process_test.go
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
package xfs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/aliyun/aliyun-oss-go-sdk/oss"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/yaoapp/gou"
|
||||||
|
"github.com/yaoapp/kun/any"
|
||||||
|
"github.com/yaoapp/xiang/share"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
share.App = share.AppInfo{
|
||||||
|
Storage: share.AppStorage{
|
||||||
|
Default: "oss",
|
||||||
|
OSS: &share.AppStorageOSS{
|
||||||
|
Endpoint: "oss-cn-hangzhou.aliyuncs.com",
|
||||||
|
ID: "LTAI5tHXfWAMpcsobfqfeXsm",
|
||||||
|
Secret: "4NeGNw97nFrfmgBWZTlFE0XtYQdMQO",
|
||||||
|
RoleArn: "acs:ram::31524094:role/ramosstest",
|
||||||
|
SessionName: "SessionTest",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func TestProcessGetToken(t *testing.T) {
|
||||||
|
|
||||||
|
args := []interface{}{
|
||||||
|
"oss",
|
||||||
|
"hh",
|
||||||
|
}
|
||||||
|
process := gou.NewProcess("xiang.fs.GetToken", args...)
|
||||||
|
response := processGetToken(process)
|
||||||
|
assert.NotNil(t, response)
|
||||||
|
res := any.Of(response).Map()
|
||||||
|
assert.True(t, res.Has("AccessKeyId"))
|
||||||
|
assert.True(t, res.Has("AccessKeySecret"))
|
||||||
|
assert.True(t, res.Has("Expiration"))
|
||||||
|
assert.True(t, res.Has("SecurityToken"))
|
||||||
|
assert.True(t, res.Has("Endpoint"))
|
||||||
|
|
||||||
|
// 使用token
|
||||||
|
client, err := oss.New(
|
||||||
|
res.Get("Endpoint").(string),
|
||||||
|
res.Get("AccessKeyId").(string),
|
||||||
|
res.Get("AccessKeySecret").(string),
|
||||||
|
oss.SecurityToken(res.Get("SecurityToken").(string)),
|
||||||
|
)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
bucket, err := client.Bucket("image-appcook")
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
// 上传字符串。
|
||||||
|
now := fmt.Sprintf("%d", time.Now().UnixNano())
|
||||||
|
err = bucket.PutObject("image-appcook/xiang/unit-test.txt", strings.NewReader(now))
|
||||||
|
assert.Nil(t, err)
|
||||||
|
}
|
||||||
|
|
@ -31,7 +31,7 @@
|
||||||
"path": "/token",
|
"path": "/token",
|
||||||
"method": "GET",
|
"method": "GET",
|
||||||
"guard": "-",
|
"guard": "-",
|
||||||
"process": "xiang.fs.processGetToken",
|
"process": "xiang.fs.GetToken",
|
||||||
"in": ["$query.name", "$query.bucket"],
|
"in": ["$query.name", "$query.bucket"],
|
||||||
"out": {
|
"out": {
|
||||||
"status": 200,
|
"status": 200,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue