+ OSS support

This commit is contained in:
Max 2021-10-12 12:04:02 +08:00
parent 3d2d97f20d
commit 976b4aa7eb
11 changed files with 211 additions and 91 deletions

View file

@ -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": {},

View file

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

View file

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

View file

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

View file

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

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

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

View file

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

View file

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