mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-11-05 07:21:36 +08:00
Merge pull request #422 in YUNIONIO/onecloud from ~QIUJIAN/onecloud:feature/qj-climc-resource-fiter-and-cache to release/2.3.0
* commit 'aa5dfb79272e728a1c7ba302eeaf9fdf711fee49': minor updates Add dynamic schedtag show command 1. mcclient.resource增加readfilter和writerfilter,允许为resource增加自定义字段 2. 增加mcclient的获取的缓存,方便缓存mcclient拉取资源
This commit is contained in:
@@ -104,6 +104,15 @@ func init() {
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&DynamicschedtagDeleteOptions{}, "dynamic-schedtag-show", "Show details of a dyanmic schedtag policy", func(s *mcclient.ClientSession, args *DynamicschedtagDeleteOptions) error {
|
||||
result, err := modules.Dynamicschedtags.Get(s, args.ID, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
type DynamicSchedtagEvaluateOptions struct {
|
||||
ID string `help:"ID or name of the sched policy"`
|
||||
HOST string `help:"ID or name of the host"`
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package policy
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
|
||||
"time"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/consts"
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
@@ -76,6 +77,8 @@ func fetchPolicies() (map[string]rbacutils.SRbacPolicy, map[string]rbacutils.SRb
|
||||
policies := make(map[string]rbacutils.SRbacPolicy)
|
||||
adminPolicies := make(map[string]rbacutils.SRbacPolicy)
|
||||
|
||||
modules.Policies.SetEnableFilter(false)
|
||||
|
||||
offset := 0
|
||||
for {
|
||||
params := jsonutils.NewDict()
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
package modules
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
)
|
||||
|
||||
const (
|
||||
cacheValidPerviod = 1 * time.Minute
|
||||
)
|
||||
|
||||
type tCachedStatus int
|
||||
|
||||
const (
|
||||
cacheInit = tCachedStatus(0)
|
||||
cacheFetching = tCachedStatus(1)
|
||||
cacheComplete = tCachedStatus(2)
|
||||
)
|
||||
|
||||
type sCachedResource struct {
|
||||
key string
|
||||
cachedAt time.Time
|
||||
lock *sync.Cond
|
||||
object jsonutils.JSONObject
|
||||
status tCachedStatus
|
||||
}
|
||||
|
||||
type sCachedResourceManager struct {
|
||||
lock *sync.Mutex
|
||||
resourceCache map[string]sCachedResource
|
||||
}
|
||||
|
||||
var cachedResourceManager *sCachedResourceManager
|
||||
|
||||
func init() {
|
||||
cachedResourceManager = &sCachedResourceManager{
|
||||
lock: &sync.Mutex{},
|
||||
resourceCache: make(map[string]sCachedResource),
|
||||
}
|
||||
}
|
||||
|
||||
func cacheKey(manager Manager, idstr string) string {
|
||||
return fmt.Sprintf("%s-%s", manager.KeyString(), idstr)
|
||||
}
|
||||
|
||||
func (cm *sCachedResourceManager) getLocked(key string) *sCachedResource {
|
||||
cm.lock.Lock()
|
||||
defer cm.lock.Unlock()
|
||||
|
||||
return cm.getUnlocked(key, true)
|
||||
}
|
||||
|
||||
func (cm *sCachedResourceManager) getUnlocked(key string, alloc bool) *sCachedResource {
|
||||
_, ok := cm.resourceCache[key]
|
||||
if !ok {
|
||||
if !alloc {
|
||||
return nil
|
||||
}
|
||||
cm.resourceCache[key] = sCachedResource{
|
||||
key: key,
|
||||
lock: sync.NewCond(&sync.Mutex{}),
|
||||
status: cacheInit,
|
||||
}
|
||||
}
|
||||
obj := cm.resourceCache[key]
|
||||
return &obj
|
||||
}
|
||||
|
||||
func (cm *sCachedResourceManager) getById(manager Manager, session *mcclient.ClientSession, idstr string) (jsonutils.JSONObject, error) {
|
||||
key := cacheKey(manager, idstr)
|
||||
cacheObj := cm.getLocked(key)
|
||||
|
||||
obj := cacheObj.tryGet()
|
||||
if obj != nil {
|
||||
return obj, nil
|
||||
}
|
||||
|
||||
obj, err := manager.GetById(session, idstr, nil)
|
||||
if err != nil {
|
||||
cacheObj.notifyFail()
|
||||
return nil, err
|
||||
}
|
||||
cacheObj.notifyComplete(obj)
|
||||
return obj, nil
|
||||
}
|
||||
|
||||
func (cr *sCachedResource) isValid() bool {
|
||||
now := time.Now()
|
||||
return cr.status == cacheComplete && now.Sub(cr.cachedAt) <= cacheValidPerviod && cr.object != nil
|
||||
}
|
||||
|
||||
func (cr *sCachedResource) tryGet() jsonutils.JSONObject {
|
||||
cr.lock.L.Lock()
|
||||
defer cr.lock.L.Unlock()
|
||||
|
||||
if cr.isValid() {
|
||||
return cr.object
|
||||
}
|
||||
|
||||
for cr.status == cacheFetching {
|
||||
cr.lock.Wait()
|
||||
}
|
||||
|
||||
if cr.status == cacheComplete {
|
||||
return cr.object
|
||||
}
|
||||
|
||||
cr.status = cacheFetching
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cr *sCachedResource) notifyFail() {
|
||||
cr.lock.L.Lock()
|
||||
defer cr.lock.L.Unlock()
|
||||
|
||||
cr.status = cacheInit
|
||||
cr.object = nil
|
||||
|
||||
cr.lock.Signal()
|
||||
}
|
||||
|
||||
func (cr *sCachedResource) notifyComplete(obj jsonutils.JSONObject) {
|
||||
cr.lock.L.Lock()
|
||||
defer cr.lock.L.Unlock()
|
||||
|
||||
cr.status = cacheComplete
|
||||
cr.object = obj
|
||||
cr.cachedAt = time.Now()
|
||||
|
||||
time.AfterFunc(cacheValidPerviod, func() {
|
||||
cachedResourceManager.lock.Lock()
|
||||
defer cachedResourceManager.lock.Unlock()
|
||||
|
||||
cacheObj := cachedResourceManager.getUnlocked(cr.key, false)
|
||||
if cacheObj == nil {
|
||||
return
|
||||
}
|
||||
|
||||
cacheObj.lock.L.Lock()
|
||||
defer cacheObj.lock.L.Unlock()
|
||||
|
||||
if !cacheObj.isValid() {
|
||||
delete(cachedResourceManager.resourceCache, cr.key)
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
cr.lock.Signal()
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package modules
|
||||
|
||||
import (
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
)
|
||||
|
||||
func (this *ResourceManager) filterSingleResult(session *mcclient.ClientSession, result jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
if this.enableFilter && this.readFilter != nil {
|
||||
return this.readFilter(session, result)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (this *ResourceManager) filterListResults(session *mcclient.ClientSession, results *ListResult) (*ListResult, error) {
|
||||
if this.enableFilter && this.readFilter != nil {
|
||||
for i := 0; i < len(results.Data); i += 1 {
|
||||
val, err := this.readFilter(session, results.Data[i])
|
||||
if err == nil {
|
||||
results.Data[i] = val
|
||||
} else {
|
||||
log.Warningf("readFilter fail for %s: %s", results.Data[i], err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return results, nil
|
||||
}
|
||||
@@ -30,9 +30,14 @@ func (this *JointResourceManager) Get(s *mcclient.ClientSession, mid, sid string
|
||||
path = fmt.Sprintf("%s?%s", path, qs)
|
||||
}
|
||||
}
|
||||
return this._get(s, path, this.Keyword)
|
||||
result, err := this._get(s, path, this.Keyword)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.filterSingleResult(s, result)
|
||||
}
|
||||
|
||||
/*
|
||||
func (this *JointResourceManager) List(s *mcclient.ClientSession, params jsonutils.JSONObject) (*ListResult, error) {
|
||||
path := fmt.Sprintf("/%s", this.KeyString())
|
||||
if params != nil {
|
||||
@@ -43,6 +48,7 @@ func (this *JointResourceManager) List(s *mcclient.ClientSession, params jsonuti
|
||||
}
|
||||
return this._list(s, path, this.KeywordPlural)
|
||||
}
|
||||
*/
|
||||
|
||||
func (this *JointResourceManager) ListDescendent(s *mcclient.ClientSession, mid string, params jsonutils.JSONObject) (*ListResult, error) {
|
||||
path := fmt.Sprintf("/%s/%s/%s", this.Master.KeyString(), url.PathEscape(mid), this.Slave.KeyString())
|
||||
@@ -52,7 +58,11 @@ func (this *JointResourceManager) ListDescendent(s *mcclient.ClientSession, mid
|
||||
path = fmt.Sprintf("%s?%s", path, qs)
|
||||
}
|
||||
}
|
||||
return this._list(s, path, this.KeywordPlural)
|
||||
results, err := this._list(s, path, this.KeywordPlural)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.filterListResults(s, results)
|
||||
}
|
||||
|
||||
func (this *JointResourceManager) ListDescendent2(s *mcclient.ClientSession, sid string, params jsonutils.JSONObject) (*ListResult, error) {
|
||||
@@ -67,7 +77,11 @@ func (this *JointResourceManager) ListAscendent(s *mcclient.ClientSession, mid s
|
||||
path = fmt.Sprintf("%s?%s", path, qs)
|
||||
}
|
||||
}
|
||||
return this._list(s, path, this.KeywordPlural)
|
||||
results, err := this._list(s, path, this.KeywordPlural)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.filterListResults(s, results)
|
||||
}
|
||||
|
||||
/* func (this *JointResourceManager) Exists(s *mcclient.ClientSession, mid, sid string, params jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
@@ -83,7 +97,11 @@ func (this *JointResourceManager) ListAscendent(s *mcclient.ClientSession, mid s
|
||||
|
||||
func (this *JointResourceManager) Attach(s *mcclient.ClientSession, mid, sid string, params jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
path := fmt.Sprintf("/%s/%s/%s/%s", this.Master.KeyString(), url.PathEscape(mid), this.Slave.KeyString(), url.PathEscape(sid))
|
||||
return this._post(s, path, this.params2Body(params), this.Keyword)
|
||||
result, err := this._post(s, path, this.params2Body(s, params), this.Keyword)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.filterSingleResult(s, result)
|
||||
}
|
||||
|
||||
func (this *JointResourceManager) BatchAttach(s *mcclient.ClientSession, mid string, sids []string, params jsonutils.JSONObject) []SubmitResult {
|
||||
@@ -100,7 +118,11 @@ func (this *JointResourceManager) BatchAttach2(s *mcclient.ClientSession, mid st
|
||||
|
||||
func (this *JointResourceManager) Detach(s *mcclient.ClientSession, mid, sid string) (jsonutils.JSONObject, error) {
|
||||
path := fmt.Sprintf("/%s/%s/%s/%s", this.Master.KeyString(), url.PathEscape(mid), this.Slave.KeyString(), url.PathEscape(sid))
|
||||
return this._delete(s, path, nil, this.Keyword)
|
||||
result, err := this._delete(s, path, nil, this.Keyword)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.filterSingleResult(s, result)
|
||||
}
|
||||
|
||||
func (this *JointResourceManager) BatchDetach(s *mcclient.ClientSession, mid string, sids []string) []SubmitResult {
|
||||
@@ -117,10 +139,18 @@ func (this *JointResourceManager) BatchDetach2(s *mcclient.ClientSession, mid st
|
||||
|
||||
func (this *JointResourceManager) Update(s *mcclient.ClientSession, mid, sid string, params jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
path := fmt.Sprintf("/%s/%s/%s/%s", this.Master.KeyString(), url.PathEscape(mid), this.Slave.KeyString(), url.PathEscape(sid))
|
||||
return this._put(s, path, this.params2Body(params), this.Keyword)
|
||||
result, err := this._put(s, path, this.params2Body(s, params), this.Keyword)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.filterSingleResult(s, result)
|
||||
}
|
||||
|
||||
func (this *JointResourceManager) Patch(s *mcclient.ClientSession, mid, sid string, params jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
path := fmt.Sprintf("/%s/%s/%s/%s", this.Master.KeyString(), url.PathEscape(mid), this.Slave.KeyString(), url.PathEscape(sid))
|
||||
return this._patch(s, path, this.params2Body(params), this.Keyword)
|
||||
result, err := this._patch(s, path, this.params2Body(s, params), this.Keyword)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.filterSingleResult(s, result)
|
||||
}
|
||||
|
||||
@@ -1,10 +1,33 @@
|
||||
package modules
|
||||
|
||||
import (
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
)
|
||||
|
||||
var (
|
||||
Endpoints ResourceManager
|
||||
EndpointsV3 ResourceManager
|
||||
)
|
||||
|
||||
func endpointsV3ReadFilter(s *mcclient.ClientSession, result jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
resultDict := result.(*jsonutils.JSONDict)
|
||||
serviceId, _ := result.GetString("service_id")
|
||||
service, err := cachedResourceManager.getById(&ServicesV3, s, serviceId)
|
||||
// service, err := ServicesV3.GetById(s, serviceId, nil)
|
||||
if err == nil {
|
||||
serviceType, _ := service.Get("type")
|
||||
if serviceType != nil {
|
||||
resultDict.Add(serviceType, "service_type")
|
||||
}
|
||||
serviceName, _ := service.Get("name")
|
||||
if serviceName != nil {
|
||||
resultDict.Add(serviceName, "service_name")
|
||||
}
|
||||
}
|
||||
return resultDict, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
Endpoints = NewIdentityManager("endpoint", "endpoints",
|
||||
[]string{},
|
||||
@@ -17,8 +40,10 @@ func init() {
|
||||
EndpointsV3 = NewIdentityV3Manager("endpoint", "endpoints",
|
||||
[]string{},
|
||||
[]string{"ID", "Region_ID",
|
||||
"Service_ID", "name",
|
||||
"Service", "Service_ID", "Service_Name", "Service_Type",
|
||||
"URL", "Interface", "Enabled"})
|
||||
|
||||
EndpointsV3.SetReadFilter(endpointsV3ReadFilter)
|
||||
|
||||
register(&EndpointsV3)
|
||||
}
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
package modules
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/util/httputils"
|
||||
)
|
||||
|
||||
type SPolicyManager struct {
|
||||
@@ -14,7 +11,7 @@ type SPolicyManager struct {
|
||||
|
||||
var Policies SPolicyManager
|
||||
|
||||
func translateS2C(s jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
func policyReadFilter(session *mcclient.ClientSession, s jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
ss := s.(*jsonutils.JSONDict)
|
||||
ret := ss.CopyIncludes("id", "type")
|
||||
blobStr, err := ss.GetString("blob")
|
||||
@@ -29,7 +26,7 @@ func translateS2C(s jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func translateC2S(s jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
func policyWriteFilter(session *mcclient.ClientSession, s jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
ret := jsonutils.NewDict()
|
||||
if s.Contains("policy") {
|
||||
blobYaml, err := s.GetString("policy")
|
||||
@@ -52,92 +49,12 @@ func translateC2S(s jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (pm *SPolicyManager) Get(s *mcclient.ClientSession, id string, query jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
result, err := pm.GetById(s, id, nil)
|
||||
if err == nil {
|
||||
return result, nil
|
||||
}
|
||||
jsonErr := err.(*httputils.JSONClientError)
|
||||
if jsonErr.Code != 404 {
|
||||
return nil, err
|
||||
}
|
||||
return pm.GetByName(s, id, query)
|
||||
}
|
||||
|
||||
func (pm *SPolicyManager) GetId(s *mcclient.ClientSession, id string, params jsonutils.JSONObject) (string, error) {
|
||||
obj, err := pm.Get(s, id, params)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return obj.GetString("id")
|
||||
}
|
||||
|
||||
func (pm *SPolicyManager) GetById(s *mcclient.ClientSession, id string, query jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
result, err := pm.ResourceManager.GetById(s, id, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return translateS2C(result)
|
||||
}
|
||||
|
||||
func (pm *SPolicyManager) GetByName(s *mcclient.ClientSession, name string, query jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
params := jsonutils.NewDict()
|
||||
params.Add(jsonutils.NewString(name), "type")
|
||||
listResult, err := Policies.List(s, params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if listResult.Total == 1 {
|
||||
return listResult.Data[0], nil
|
||||
} else if listResult.Total == 0 {
|
||||
return nil, &httputils.JSONClientError{Code: 404, Class: "NotFound",
|
||||
Details: fmt.Sprintf("%d not found", name)}
|
||||
} else {
|
||||
return nil, &httputils.JSONClientError{Code: 409, Class: "Conflict",
|
||||
Details: fmt.Sprintf("multiple %d found", name)}
|
||||
}
|
||||
}
|
||||
|
||||
func (pm *SPolicyManager) Create(s *mcclient.ClientSession, params jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
data, err := translateC2S(params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result, err := pm.ResourceManager.Create(s, data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return translateS2C(result)
|
||||
}
|
||||
|
||||
func (pm *SPolicyManager) Patch(s *mcclient.ClientSession, id string, params jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
data, err := translateC2S(params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result, err := pm.ResourceManager.Patch(s, id, data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return translateS2C(result)
|
||||
}
|
||||
|
||||
func (pm *SPolicyManager) List(s *mcclient.ClientSession, params jsonutils.JSONObject) (*ListResult, error) {
|
||||
results, err := pm.ResourceManager.List(s, params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := 0; i < len(results.Data); i += 1 {
|
||||
val, _ := translateS2C(results.Data[i])
|
||||
results.Data[i] = val
|
||||
}
|
||||
return results, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
Policies = SPolicyManager{NewIdentityV3Manager("policy", "policies",
|
||||
[]string{"id", "type", "policy"},
|
||||
[]string{})}
|
||||
|
||||
Policies.SetReadFilter(policyReadFilter).SetWriteFilter(policyWriteFilter).SetNameField("type")
|
||||
|
||||
register(&Policies)
|
||||
}
|
||||
|
||||
@@ -9,14 +9,28 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
"yunion.io/x/onecloud/pkg/util/httputils"
|
||||
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
)
|
||||
|
||||
type TResourceFilter func(*mcclient.ClientSession, jsonutils.JSONObject) (jsonutils.JSONObject, error)
|
||||
|
||||
const (
|
||||
DEFAULT_NAME_FIELD_NAME = "name"
|
||||
DEFAULT_ID_FIELD_NAME = "id"
|
||||
)
|
||||
|
||||
type ResourceManager struct {
|
||||
BaseManager
|
||||
context string
|
||||
Keyword string
|
||||
KeywordPlural string
|
||||
|
||||
readFilter TResourceFilter
|
||||
writeFilter TResourceFilter
|
||||
enableFilter bool
|
||||
nameFieldName string
|
||||
idFieldName string
|
||||
}
|
||||
|
||||
func (this *ResourceManager) KeyString() string {
|
||||
@@ -39,6 +53,42 @@ func (this *ResourceManager) URLPath() string {
|
||||
return strings.Replace(this.KeywordPlural, ":", "/", -1)
|
||||
}
|
||||
|
||||
func (this *ResourceManager) SetReadFilter(filter TResourceFilter) *ResourceManager {
|
||||
this.readFilter = filter
|
||||
this.enableFilter = true
|
||||
return this
|
||||
}
|
||||
|
||||
func (this *ResourceManager) SetWriteFilter(filter TResourceFilter) *ResourceManager {
|
||||
this.writeFilter = filter
|
||||
this.enableFilter = true
|
||||
return this
|
||||
}
|
||||
|
||||
func (this *ResourceManager) SetEnableFilter(enable bool) *ResourceManager {
|
||||
this.enableFilter = enable
|
||||
return this
|
||||
}
|
||||
|
||||
func (this *ResourceManager) SetNameField(fn string) *ResourceManager {
|
||||
this.nameFieldName = fn
|
||||
return this
|
||||
}
|
||||
|
||||
func (this *ResourceManager) getNameFieldName() string {
|
||||
if len(this.nameFieldName) > 0 {
|
||||
return this.nameFieldName
|
||||
}
|
||||
return DEFAULT_NAME_FIELD_NAME
|
||||
}
|
||||
|
||||
func (this *ResourceManager) getIdFieldName() string {
|
||||
if len(this.idFieldName) > 0 {
|
||||
return this.idFieldName
|
||||
}
|
||||
return DEFAULT_ID_FIELD_NAME
|
||||
}
|
||||
|
||||
func (this *ResourceManager) ContextPath(ctxs []ManagerContext) string {
|
||||
segs := make([]string, 0)
|
||||
if len(this.context) > 0 {
|
||||
@@ -72,7 +122,11 @@ func (this *ResourceManager) GetByIdInContexts(session *mcclient.ClientSession,
|
||||
path = fmt.Sprintf("%s?%s", path, qs)
|
||||
}
|
||||
}
|
||||
return this._get(session, path, this.Keyword)
|
||||
obj, err := this._get(session, path, this.Keyword)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.filterSingleResult(session, obj)
|
||||
}
|
||||
|
||||
func (this *ResourceManager) GetByName(session *mcclient.ClientSession, name string, params jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
@@ -91,7 +145,7 @@ func (this *ResourceManager) GetByNameInContexts(session *mcclient.ClientSession
|
||||
} else {
|
||||
paramsDict = jsonutils.NewDict()
|
||||
}
|
||||
paramsDict.Add(jsonutils.NewString(name), "name")
|
||||
paramsDict.Add(jsonutils.NewString(name), this.getNameFieldName())
|
||||
results, e := this.ListInContexts(session, paramsDict, ctxs)
|
||||
if e != nil {
|
||||
return nil, e
|
||||
@@ -99,7 +153,12 @@ func (this *ResourceManager) GetByNameInContexts(session *mcclient.ClientSession
|
||||
if len(results.Data) == 0 {
|
||||
return nil, httperrors.NewNotFoundError("Name %s not found", name)
|
||||
} else if len(results.Data) == 1 {
|
||||
return results.Data[0], nil
|
||||
oname, _ := results.Data[0].GetString(this.getNameFieldName())
|
||||
if oname == name {
|
||||
return results.Data[0], nil
|
||||
} else {
|
||||
return nil, httperrors.NewNotFoundError("Name %s not found", name)
|
||||
}
|
||||
} else {
|
||||
return nil, httperrors.NewDuplicateNameError("name", name)
|
||||
}
|
||||
@@ -140,7 +199,7 @@ func (this *ResourceManager) GetIdInContexts(session *mcclient.ClientSession, id
|
||||
if e != nil {
|
||||
return "", e
|
||||
}
|
||||
return obj.GetString("id")
|
||||
return obj.GetString(this.getIdFieldName())
|
||||
}
|
||||
|
||||
func (this *ResourceManager) GetSpecific(session *mcclient.ClientSession, id string, spec string, params jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
@@ -192,7 +251,11 @@ func (this *ResourceManager) ListInContexts(session *mcclient.ClientSession, par
|
||||
path = fmt.Sprintf("%s?%s", path, qs)
|
||||
}
|
||||
}
|
||||
return this._list(session, path, this.KeywordPlural)
|
||||
results, err := this._list(session, path, this.KeywordPlural)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.filterListResults(session, results)
|
||||
}
|
||||
|
||||
func (this *ResourceManager) Head(session *mcclient.ClientSession, id string, params jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
@@ -211,12 +274,24 @@ func (this *ResourceManager) HeadInContexts(session *mcclient.ClientSession, id
|
||||
path = fmt.Sprintf("%s?%s", path, qs)
|
||||
}
|
||||
}
|
||||
return this._head(session, path, this.Keyword)
|
||||
result, err := this._head(session, path, this.Keyword)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.filterSingleResult(session, result)
|
||||
}
|
||||
|
||||
func (this *ResourceManager) params2Body(params jsonutils.JSONObject) *jsonutils.JSONDict {
|
||||
func (this *ResourceManager) params2Body(s *mcclient.ClientSession, params jsonutils.JSONObject) *jsonutils.JSONDict {
|
||||
body := jsonutils.NewDict()
|
||||
if params != nil {
|
||||
if this.enableFilter && this.writeFilter != nil {
|
||||
val, err := this.writeFilter(s, params)
|
||||
if err == nil {
|
||||
params = val
|
||||
} else {
|
||||
log.Warningf("writeFilter fail %s: %s", params, err)
|
||||
}
|
||||
}
|
||||
body.Add(params, this.Keyword)
|
||||
}
|
||||
return body
|
||||
@@ -232,7 +307,11 @@ func (this *ResourceManager) CreateInContext(session *mcclient.ClientSession, pa
|
||||
|
||||
func (this *ResourceManager) CreateInContexts(session *mcclient.ClientSession, params jsonutils.JSONObject, ctxs []ManagerContext) (jsonutils.JSONObject, error) {
|
||||
path := fmt.Sprintf("/%s", this.ContextPath(ctxs))
|
||||
return this._post(session, path, this.params2Body(params), this.Keyword)
|
||||
result, err := this._post(session, path, this.params2Body(session, params), this.Keyword)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.filterSingleResult(session, result)
|
||||
}
|
||||
|
||||
func (this *ResourceManager) BatchCreate(session *mcclient.ClientSession, params jsonutils.JSONObject, count int) []SubmitResult {
|
||||
@@ -245,7 +324,7 @@ func (this *ResourceManager) BatchCreateInContext(session *mcclient.ClientSessio
|
||||
|
||||
func (this *ResourceManager) BatchCreateInContexts(session *mcclient.ClientSession, params jsonutils.JSONObject, count int, ctxs []ManagerContext) []SubmitResult {
|
||||
path := fmt.Sprintf("/%s", this.ContextPath(ctxs))
|
||||
body := this.params2Body(params)
|
||||
body := this.params2Body(session, params)
|
||||
body.Add(jsonutils.NewInt(int64(count)), "count")
|
||||
ret := make([]SubmitResult, count)
|
||||
respbody, err := this._post(session, path, body, this.KeywordPlural)
|
||||
@@ -269,7 +348,15 @@ func (this *ResourceManager) BatchCreateInContexts(session *mcclient.ClientSessi
|
||||
} else {
|
||||
code, _ := json.Int("status")
|
||||
dat, _ := json.Get("body")
|
||||
idstr, _ := json.GetString("id")
|
||||
if this.enableFilter && this.readFilter != nil {
|
||||
val, err := this.readFilter(session, dat)
|
||||
if err != nil {
|
||||
log.Warningf("readFilter fail for %s: %s", dat, err)
|
||||
} else {
|
||||
dat = val
|
||||
}
|
||||
}
|
||||
idstr, _ := json.GetString(this.getIdFieldName())
|
||||
ret[i] = SubmitResult{Status: int(code), Id: idstr, Data: dat}
|
||||
}
|
||||
}
|
||||
@@ -290,7 +377,11 @@ func (this *ResourceManager) PutInContext(session *mcclient.ClientSession, id st
|
||||
|
||||
func (this *ResourceManager) PutInContexts(session *mcclient.ClientSession, id string, params jsonutils.JSONObject, ctxs []ManagerContext) (jsonutils.JSONObject, error) {
|
||||
path := fmt.Sprintf("/%s/%s", this.ContextPath(ctxs), url.PathEscape(id))
|
||||
return this._put(session, path, this.params2Body(params), this.Keyword)
|
||||
result, err := this._put(session, path, this.params2Body(session, params), this.Keyword)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.filterSingleResult(session, result)
|
||||
}
|
||||
|
||||
func (this *ResourceManager) BatchUpdate(session *mcclient.ClientSession, idlist []string, params jsonutils.JSONObject) []SubmitResult {
|
||||
@@ -321,7 +412,11 @@ func (this *ResourceManager) PatchInContext(session *mcclient.ClientSession, id
|
||||
|
||||
func (this *ResourceManager) PatchInContexts(session *mcclient.ClientSession, id string, params jsonutils.JSONObject, ctxs []ManagerContext) (jsonutils.JSONObject, error) {
|
||||
path := fmt.Sprintf("/%s/%s", this.ContextPath(ctxs), url.PathEscape(id))
|
||||
return this._patch(session, path, this.params2Body(params), this.Keyword)
|
||||
result, err := this._patch(session, path, this.params2Body(session, params), this.Keyword)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.filterSingleResult(session, result)
|
||||
}
|
||||
|
||||
func (this *ResourceManager) BatchPatch(session *mcclient.ClientSession, idlist []string, params jsonutils.JSONObject) []SubmitResult {
|
||||
@@ -348,7 +443,11 @@ func (this *ResourceManager) PerformActionInContext(session *mcclient.ClientSess
|
||||
|
||||
func (this *ResourceManager) PerformActionInContexts(session *mcclient.ClientSession, id string, action string, params jsonutils.JSONObject, ctxs []ManagerContext) (jsonutils.JSONObject, error) {
|
||||
path := fmt.Sprintf("/%s/%s/%s", this.ContextPath(ctxs), url.PathEscape(id), url.PathEscape(action))
|
||||
return this._post(session, path, this.params2Body(params), this.Keyword)
|
||||
result, err := this._post(session, path, this.params2Body(session, params), this.Keyword)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.filterSingleResult(session, result)
|
||||
}
|
||||
|
||||
func (this *ResourceManager) PerformClassAction(session *mcclient.ClientSession, action string, params jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
@@ -403,9 +502,13 @@ func (this *ResourceManager) deleteInContexts(session *mcclient.ClientSession, i
|
||||
}
|
||||
}
|
||||
if body != nil {
|
||||
body = this.params2Body(body)
|
||||
body = this.params2Body(session, body)
|
||||
}
|
||||
return this._delete(session, path, body, this.Keyword)
|
||||
result, err := this._delete(session, path, body, this.Keyword)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.filterSingleResult(session, result)
|
||||
}
|
||||
|
||||
func (this *ResourceManager) BatchDelete(session *mcclient.ClientSession, idlist []string, body jsonutils.JSONObject) []SubmitResult {
|
||||
|
||||
Reference in New Issue
Block a user