补充secret模块
This commit is contained in:
parent
eff870aa6f
commit
749ea2e4c6
29
devcloud-mini/cmdb/apps/secret/impl/impl.go
Normal file
29
devcloud-mini/cmdb/apps/secret/impl/impl.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package impl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/infraboard/mcube/v2/ioc"
|
||||||
|
ioc_mongo "github.com/infraboard/mcube/v2/ioc/config/mongo"
|
||||||
|
"gitlab.com/go-course-project/go17/devcloud-mini/cmdb/apps/secret"
|
||||||
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
ioc.Controller().Registry(&SecretServiceImpl{})
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ secret.Service = (*SecretServiceImpl)(nil)
|
||||||
|
|
||||||
|
type SecretServiceImpl struct {
|
||||||
|
ioc.ObjectImpl
|
||||||
|
col *mongo.Collection
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SecretServiceImpl) Name() string {
|
||||||
|
return secret.AppName
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SecretServiceImpl) Init() error {
|
||||||
|
// 定义使用的集合
|
||||||
|
s.col = ioc_mongo.DB().Collection("secrets")
|
||||||
|
return nil
|
||||||
|
}
|
31
devcloud-mini/cmdb/apps/secret/impl/secret.go
Normal file
31
devcloud-mini/cmdb/apps/secret/impl/secret.go
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
package impl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/infraboard/mcube/v2/types"
|
||||||
|
"gitlab.com/go-course-project/go17/devcloud-mini/cmdb/apps/secret"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CreateSecret implements secret.Service.
|
||||||
|
func (s *SecretServiceImpl) CreateSecret(context.Context, *secret.CreateSecretRequest) (*secret.Secret, error) {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// DescribeSecret implements secret.Service.
|
||||||
|
func (s *SecretServiceImpl) DescribeSecret(context.Context, *secret.DescribeSecretRequeset) (*secret.Secret, error) {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// QuerySecret implements secret.Service.
|
||||||
|
func (s *SecretServiceImpl) QuerySecret(context.Context, *secret.QuerySecretRequest) (*types.Set[*secret.Secret], error) {
|
||||||
|
set := types.New[*secret.Secret]()
|
||||||
|
fmt.Println(set)
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// SyncResource implements secret.Service.
|
||||||
|
func (s *SecretServiceImpl) SyncResource(context.Context, *secret.SyncResourceRequest, secret.SyncResourceHandleFunc) error {
|
||||||
|
panic("unimplemented")
|
||||||
|
}
|
78
devcloud-mini/cmdb/apps/secret/interface.go
Normal file
78
devcloud-mini/cmdb/apps/secret/interface.go
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
package secret
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/infraboard/mcube/v2/http/request"
|
||||||
|
"github.com/infraboard/mcube/v2/ioc"
|
||||||
|
"github.com/infraboard/mcube/v2/tools/pretty"
|
||||||
|
"github.com/infraboard/mcube/v2/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
AppName = "secret"
|
||||||
|
SECRET_KEY = "23gs6gxHrz1kNEvshRmunkXbwIiaEcYfh+EMu+e9ewA="
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetService() Service {
|
||||||
|
return ioc.Controller().Get(AppName).(Service)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Service interface {
|
||||||
|
// 用于Secret的管理(后台管理员配置)
|
||||||
|
// 创建secret
|
||||||
|
CreateSecret(context.Context, *CreateSecretRequest) (*Secret, error)
|
||||||
|
// 查询secret
|
||||||
|
QuerySecret(context.Context, *QuerySecretRequest) (*types.Set[*Secret], error)
|
||||||
|
// 查询详情, 已解密,API层需要脱敏
|
||||||
|
DescribeSecret(context.Context, *DescribeSecretRequeset) (*Secret, error)
|
||||||
|
|
||||||
|
// 怎么API怎么设计
|
||||||
|
// 同步阿里云所有资源, 10分钟,30分钟 ...
|
||||||
|
// 这个接口调用持续30分钟...
|
||||||
|
// Req ---> <---- Resp: 能快速响应的同步调用
|
||||||
|
|
||||||
|
// Stream API
|
||||||
|
SyncResource(context.Context, *SyncResourceRequest, SyncResourceHandleFunc) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type SyncResourceHandleFunc func(ResourceResponse)
|
||||||
|
|
||||||
|
type ResourceResponse struct {
|
||||||
|
Success bool
|
||||||
|
InstanceId string `json:"instance_id"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t ResourceResponse) String() string {
|
||||||
|
return pretty.ToJSON(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewQuerySecretRequest() *QuerySecretRequest {
|
||||||
|
return &QuerySecretRequest{
|
||||||
|
PageRequest: request.NewDefaultPageRequest(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type QuerySecretRequest struct {
|
||||||
|
// 分页请求
|
||||||
|
*request.PageRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDescribeSecretRequeset(id string) *DescribeSecretRequeset {
|
||||||
|
return &DescribeSecretRequeset{
|
||||||
|
Id: id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type DescribeSecretRequeset struct {
|
||||||
|
Id string `json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSyncResourceRequest() *SyncResourceRequest {
|
||||||
|
return &SyncResourceRequest{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type SyncResourceRequest struct {
|
||||||
|
Id string `json:"id"`
|
||||||
|
}
|
101
devcloud-mini/cmdb/apps/secret/model.go
Normal file
101
devcloud-mini/cmdb/apps/secret/model.go
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
package secret
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/infraboard/mcube/v2/crypto/cbc"
|
||||||
|
"github.com/infraboard/mcube/v2/tools/pretty"
|
||||||
|
"github.com/infraboard/mcube/v2/types"
|
||||||
|
"gitlab.com/go-course-project/go17/devcloud-mini/cmdb/apps/resource"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewSecretSet() *types.Set[*Secret] {
|
||||||
|
return types.New[*Secret]()
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSecret(in *CreateSecretRequest) *Secret {
|
||||||
|
// hash版本的UUID
|
||||||
|
// Vendor Address ApiKey
|
||||||
|
uid := uuid.NewMD5(uuid.Nil, fmt.Appendf(nil, "%d.%s.%s", in.Vendor, in.Address, in.ApiKey)).String()
|
||||||
|
return &Secret{
|
||||||
|
Id: uid,
|
||||||
|
UpdateAt: time.Now().Unix(),
|
||||||
|
CreateSecretRequest: in,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Secret struct {
|
||||||
|
Id string `json:"id" bson:"_id"`
|
||||||
|
UpdateAt int64 `json:"update_at" bson:"update_at"`
|
||||||
|
*CreateSecretRequest `bson:"inline"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Secret) String() string {
|
||||||
|
return pretty.ToJSON(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCreateSecretRequest() *CreateSecretRequest {
|
||||||
|
return &CreateSecretRequest{
|
||||||
|
Regions: []string{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateSecretRequest struct {
|
||||||
|
// 名称
|
||||||
|
Name string `json:"name"`
|
||||||
|
//
|
||||||
|
Vendor resource.VENDOR `json:"vendor"`
|
||||||
|
// Vmware
|
||||||
|
Address string `json:"address"`
|
||||||
|
//
|
||||||
|
ApiKey string `json:"api_key"`
|
||||||
|
//
|
||||||
|
ApiSecret string `json:"api_secret"`
|
||||||
|
//
|
||||||
|
isEncrypted bool
|
||||||
|
|
||||||
|
// 资源所在区域
|
||||||
|
Regions []string `json:"regions"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *CreateSecretRequest) SetIsEncrypted(v bool) {
|
||||||
|
r.isEncrypted = v
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *CreateSecretRequest) EncryptedApiSecret() error {
|
||||||
|
if r.isEncrypted {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// Hash, 对称,非对称
|
||||||
|
// 对称加密 AES(cbc)
|
||||||
|
// @v1,xxxx@xxxxx
|
||||||
|
|
||||||
|
cipherText, err := cbc.MustNewAESCBCCihper([]byte(SECRET_KEY)).Encrypt([]byte(r.ApiSecret))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
r.ApiSecret = base64.StdEncoding.EncodeToString(cipherText)
|
||||||
|
r.SetIsEncrypted(true)
|
||||||
|
return nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *CreateSecretRequest) DecryptedApiSecret() error {
|
||||||
|
if r.isEncrypted {
|
||||||
|
cipherdText, err := base64.StdEncoding.DecodeString(r.ApiSecret)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
plainText, err := cbc.MustNewAESCBCCihper([]byte(SECRET_KEY)).Decrypt([]byte(cipherdText))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
r.ApiSecret = string(plainText)
|
||||||
|
r.SetIsEncrypted(false)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
12
devcloud-mini/cmdb/apps/secret/model_test.go
Normal file
12
devcloud-mini/cmdb/apps/secret/model_test.go
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package secret
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/infraboard/mcube/v2/crypto/cbc"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestMustGenRandomKey(t *testing.T) {
|
||||||
|
t.Logf("%s", base64.StdEncoding.EncodeToString(cbc.MustGenRandomKey(cbc.AES_KEY_LEN_32)))
|
||||||
|
}
|
@ -1,36 +1,57 @@
|
|||||||
<mxfile host="65bd71144e">
|
<mxfile host="65bd71144e">
|
||||||
<diagram id="7pEBGre3FdwmhDWsT8h2" name="第 1 页">
|
<diagram id="7pEBGre3FdwmhDWsT8h2" name="第 1 页">
|
||||||
<mxGraphModel dx="873" dy="479" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
|
<mxGraphModel dx="873" dy="464" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
|
||||||
<root>
|
<root>
|
||||||
<mxCell id="0"/>
|
<mxCell id="0"/>
|
||||||
<mxCell id="1" parent="0"/>
|
<mxCell id="1" parent="0"/>
|
||||||
<mxCell id="10" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="2" target="9">
|
<mxCell id="10" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="2" target="9" edge="1">
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="2" value="resource<div><br></div><div>资源管理</div>" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
<mxCell id="2" value="resource<div><br></div><div>资源管理</div>" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
<mxGeometry x="170" y="230" width="190" height="90" as="geometry"/>
|
<mxGeometry x="170" y="230" width="190" height="90" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="5" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="3" target="2">
|
<mxCell id="5" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="3" target="2" edge="1">
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="3" value="<div>secret</div><div><br></div><div>资源账号: sync</div>" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
<mxCell id="3" value="<div>secret</div><div><br></div><div>资源账号: sync</div>" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
<mxGeometry x="460" y="230" width="190" height="90" as="geometry"/>
|
<mxGeometry x="460" y="230" width="190" height="90" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="6" style="edgeStyle=none;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;" edge="1" parent="1" source="4" target="2">
|
<mxCell id="6" style="edgeStyle=none;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;" parent="1" source="4" target="2" edge="1">
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="4" value="<div>tags</div><div><br></div><div>资源管理</div>" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
<mxCell id="4" value="<div>tags</div><div><br></div><div>资源管理</div>" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
<mxGeometry x="170" y="370" width="190" height="90" as="geometry"/>
|
<mxGeometry x="170" y="370" width="190" height="90" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="8" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="7" target="2">
|
<mxCell id="8" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="7" target="2" edge="1">
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="7" value="资源检索" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
<mxCell id="7" value="资源检索" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
<mxGeometry x="25" y="80" width="480" height="60" as="geometry"/>
|
<mxGeometry x="25" y="80" width="480" height="60" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="9" value="prom<div>资源发现</div>" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
<mxCell id="9" value="prom<div>资源发现</div>" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||||
<mxGeometry x="10" y="230" width="110" height="90" as="geometry"/>
|
<mxGeometry x="10" y="230" width="110" height="90" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
|
<mxCell id="11" value="Controller" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="70" y="660" width="350" height="60" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="12" value="<span style="color: rgb(0, 0, 0);">&nbsp;Secret: ApiSecret</span>" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="170" y="760" width="150" height="80" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="13" value="加密" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="70" y="785" width="60" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="15" value="secret" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="280" y="675" width="60" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="17" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="16" target="15">
|
||||||
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="16" value="" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="354" y="675" width="60" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
|
<mxCell id="18" value="Text" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
||||||
|
<mxGeometry x="470" y="675" width="60" height="30" as="geometry"/>
|
||||||
|
</mxCell>
|
||||||
</root>
|
</root>
|
||||||
</mxGraphModel>
|
</mxGraphModel>
|
||||||
</diagram>
|
</diagram>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user