| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384 |
- // Copyright 2019 Yunion
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- package modulebase
- import (
- "fmt"
- "sort"
- "strings"
- "sync"
- "yunion.io/x/jsonutils"
- "yunion.io/x/log"
- "yunion.io/x/pkg/errors"
- "yunion.io/x/pkg/util/httputils"
- "yunion.io/x/pkg/util/printutils"
- "yunion.io/x/pkg/util/sets"
- "yunion.io/x/onecloud/pkg/mcclient"
- )
- type IBaseManager interface {
- Version() string
- // GetApiVersion() string
- GetKeyword() string
- KeyString() string
- ServiceType() string
- EndpointType() string
- GetColumns(session *mcclient.ClientSession) []string
- List(session *mcclient.ClientSession, params jsonutils.JSONObject) (*printutils.ListResult, error)
- }
- type ManagerContext struct {
- InstanceManager Manager
- InstanceId string
- }
- type Manager interface {
- IBaseManager
- /* resource list
- GET <base_url>/<resource_plural_keyword>
- e.g GET <base_url>/alarms
- querystring stores in params
- e.g. GET <base_url>/alarms?limit=20&offset=20&search=test
- return list of resources in json format
- { "<resource_plural_keyword>": [ {object details}, {object details}, ...] }, limit: 20, offset: 20, total: 2000}
- */
- // List(session *mcclient.ClientSession, params jsonutils.JSONObject) (*ListResult, error)
- /*
- resource list in a context
- GET <base_url>/<context_plural_keyword>/<context_id>/<resource_plural_keyword>?querystring
- e.g. GET <base_url>/nodes/1/labels?name=xxx
- ListInContext(s, params, &modules.Labels, label_id)
- return:
- { "<resource_plural_keyword>": [ {object details}, {object details}, ...] }, limit: 20, offset: 20, total: 2000}
- */
- ListInContext(session *mcclient.ClientSession, params jsonutils.JSONObject, ctx Manager, ctxid string) (*printutils.ListResult, error)
- ListInContexts(session *mcclient.ClientSession, params jsonutils.JSONObject, ctxs []ManagerContext) (*printutils.ListResult, error)
- /*
- GET <base_url>/<resource_plural_keyword>/<resource_id>
- e.g GET <base_url>/alarams/1
- */
- Get(session *mcclient.ClientSession, id string, params jsonutils.JSONObject) (jsonutils.JSONObject, error)
- GetInContext(session *mcclient.ClientSession, id string, params jsonutils.JSONObject, ctx Manager, ctxid string) (jsonutils.JSONObject, error)
- GetInContexts(session *mcclient.ClientSession, id string, params jsonutils.JSONObject, ctxs []ManagerContext) (jsonutils.JSONObject, error)
- GetId(session *mcclient.ClientSession, id string, params jsonutils.JSONObject) (string, error)
- GetIdInContext(session *mcclient.ClientSession, id string, params jsonutils.JSONObject, ctx Manager, ctxid string) (string, error)
- GetIdInContexts(session *mcclient.ClientSession, id string, params jsonutils.JSONObject, ctxs []ManagerContext) (string, error)
- GetById(session *mcclient.ClientSession, id string, params jsonutils.JSONObject) (jsonutils.JSONObject, error)
- GetByIdInContext(session *mcclient.ClientSession, id string, params jsonutils.JSONObject, ctx Manager, ctxid string) (jsonutils.JSONObject, error)
- GetByIdInContexts(session *mcclient.ClientSession, id string, params jsonutils.JSONObject, ctxs []ManagerContext) (jsonutils.JSONObject, error)
- GetByName(session *mcclient.ClientSession, id string, params jsonutils.JSONObject) (jsonutils.JSONObject, error)
- GetByNameInContext(session *mcclient.ClientSession, id string, params jsonutils.JSONObject, ctx Manager, ctxid string) (jsonutils.JSONObject, error)
- GetByNameInContexts(session *mcclient.ClientSession, id string, params jsonutils.JSONObject, ctxs []ManagerContext) (jsonutils.JSONObject, error)
- /*
- HEAD <base_url>/<resource_plural_keyword>/<resource_id>
- e.g HEAD <base_url>/alarams/1
- */
- Head(session *mcclient.ClientSession, id string, params jsonutils.JSONObject) (jsonutils.JSONObject, error)
- HeadInContext(session *mcclient.ClientSession, id string, params jsonutils.JSONObject, ctx Manager, ctxid string) (jsonutils.JSONObject, error)
- HeadInContexts(session *mcclient.ClientSession, id string, params jsonutils.JSONObject, ctxs []ManagerContext) (jsonutils.JSONObject, error)
- BatchGet(session *mcclient.ClientSession, idlist []string, params jsonutils.JSONObject) []printutils.SubmitResult
- BatchGetInContext(session *mcclient.ClientSession, idlist []string, params jsonutils.JSONObject, ctx Manager, ctxid string) []printutils.SubmitResult
- BatchGetInContexts(session *mcclient.ClientSession, idlist []string, params jsonutils.JSONObject, ctxs []ManagerContext) []printutils.SubmitResult
- GetSpecific(session *mcclient.ClientSession, id string, spec string, params jsonutils.JSONObject) (jsonutils.JSONObject, error)
- GetSpecificInContext(session *mcclient.ClientSession, id string, spec string, params jsonutils.JSONObject, ctx Manager, ctxid string) (jsonutils.JSONObject, error)
- GetSpecificInContexts(session *mcclient.ClientSession, id string, spec string, params jsonutils.JSONObject, ctxs []ManagerContext) (jsonutils.JSONObject, error)
- /*
- POST <base_url>/<resource_plural_keyword>/<resource_id>
- e.g POST <base_url>/alarams/1
- */
- Create(session *mcclient.ClientSession, params jsonutils.JSONObject) (jsonutils.JSONObject, error)
- CreateInContext(session *mcclient.ClientSession, params jsonutils.JSONObject, ctx Manager, ctxid string) (jsonutils.JSONObject, error)
- CreateInContexts(session *mcclient.ClientSession, params jsonutils.JSONObject, ctxs []ManagerContext) (jsonutils.JSONObject, error)
- BatchCreate(session *mcclient.ClientSession, params jsonutils.JSONObject, count int) []printutils.SubmitResult
- BatchCreateInContext(session *mcclient.ClientSession, params jsonutils.JSONObject, count int, ctx Manager, ctxid string) []printutils.SubmitResult
- BatchCreateInContexts(session *mcclient.ClientSession, params jsonutils.JSONObject, count int, ctxs []ManagerContext) []printutils.SubmitResult
- Update(session *mcclient.ClientSession, id string, params jsonutils.JSONObject) (jsonutils.JSONObject, error)
- Put(session *mcclient.ClientSession, id string, params jsonutils.JSONObject) (jsonutils.JSONObject, error)
- PutSpecific(session *mcclient.ClientSession, id string, spec string, query jsonutils.JSONObject, params jsonutils.JSONObject) (jsonutils.JSONObject, error)
- PutInContext(session *mcclient.ClientSession, id string, params jsonutils.JSONObject, ctx Manager, ctxid string) (jsonutils.JSONObject, error)
- PutInContexts(session *mcclient.ClientSession, id string, params jsonutils.JSONObject, ctxs []ManagerContext) (jsonutils.JSONObject, error)
- BatchUpdate(session *mcclient.ClientSession, idlist []string, params jsonutils.JSONObject) []printutils.SubmitResult
- BatchParamsUpdate(session *mcclient.ClientSession, idlist []string, params []jsonutils.JSONObject) []printutils.SubmitResult
- BatchPut(session *mcclient.ClientSession, idlist []string, params jsonutils.JSONObject) []printutils.SubmitResult
- BatchPutInContext(session *mcclient.ClientSession, idlist []string, params jsonutils.JSONObject, ctx Manager, ctxid string) []printutils.SubmitResult
- BatchPutInContexts(session *mcclient.ClientSession, idlist []string, params jsonutils.JSONObject, ctxs []ManagerContext) []printutils.SubmitResult
- Patch(session *mcclient.ClientSession, id string, params jsonutils.JSONObject) (jsonutils.JSONObject, error)
- PatchInContext(session *mcclient.ClientSession, id string, params jsonutils.JSONObject, ctx Manager, ctxid string) (jsonutils.JSONObject, error)
- PatchInContexts(session *mcclient.ClientSession, id string, params jsonutils.JSONObject, ctxs []ManagerContext) (jsonutils.JSONObject, error)
- BatchPatch(session *mcclient.ClientSession, idlist []string, params jsonutils.JSONObject) []printutils.SubmitResult
- BatchPatchInContext(session *mcclient.ClientSession, idlist []string, params jsonutils.JSONObject, ctx Manager, ctxid string) []printutils.SubmitResult
- BatchPatchInContexts(session *mcclient.ClientSession, idlist []string, params jsonutils.JSONObject, ctxs []ManagerContext) []printutils.SubmitResult
- PerformAction(session *mcclient.ClientSession, id string, action string, params jsonutils.JSONObject) (jsonutils.JSONObject, error)
- PerformClassAction(session *mcclient.ClientSession, action string, params jsonutils.JSONObject) (jsonutils.JSONObject, error)
- PerformActionInContext(session *mcclient.ClientSession, id string, action string, params jsonutils.JSONObject, ctx Manager, ctxid string) (jsonutils.JSONObject, error)
- PerformActionInContexts(session *mcclient.ClientSession, id string, action string, params jsonutils.JSONObject, ctxs []ManagerContext) (jsonutils.JSONObject, error)
- BatchPerformAction(session *mcclient.ClientSession, idlist []string, action string, params jsonutils.JSONObject) []printutils.SubmitResult
- BatchPerformActionInContext(session *mcclient.ClientSession, idlist []string, action string, params jsonutils.JSONObject, ctx Manager, ctxid string) []printutils.SubmitResult
- BatchPerformActionInContexts(session *mcclient.ClientSession, idlist []string, action string, params jsonutils.JSONObject, ctxs []ManagerContext) []printutils.SubmitResult
- Delete(session *mcclient.ClientSession, id string, body jsonutils.JSONObject) (jsonutils.JSONObject, error)
- DeleteWithParam(session *mcclient.ClientSession, id string, query jsonutils.JSONObject, body jsonutils.JSONObject) (jsonutils.JSONObject, error)
- DeleteInContext(session *mcclient.ClientSession, id string, body jsonutils.JSONObject, ctx Manager, ctxid string) (jsonutils.JSONObject, error)
- DeleteInContextWithParam(session *mcclient.ClientSession, id string, query jsonutils.JSONObject, body jsonutils.JSONObject, ctx Manager, ctxid string) (jsonutils.JSONObject, error)
- DeleteInContexts(session *mcclient.ClientSession, id string, body jsonutils.JSONObject, ctxs []ManagerContext) (jsonutils.JSONObject, error)
- DeleteInContextsWithParam(session *mcclient.ClientSession, id string, query jsonutils.JSONObject, body jsonutils.JSONObject, ctxs []ManagerContext) (jsonutils.JSONObject, error)
- BatchDelete(session *mcclient.ClientSession, idlist []string, body jsonutils.JSONObject) []printutils.SubmitResult
- BatchDeleteWithParam(session *mcclient.ClientSession, idlist []string, query jsonutils.JSONObject, body jsonutils.JSONObject) []printutils.SubmitResult
- BatchDeleteInContext(session *mcclient.ClientSession, idlist []string, body jsonutils.JSONObject, ctx Manager, ctxid string) []printutils.SubmitResult
- BatchDeleteInContextWithParam(session *mcclient.ClientSession, idlist []string, query jsonutils.JSONObject, body jsonutils.JSONObject, ctx Manager, ctxid string) []printutils.SubmitResult
- BatchDeleteInContexts(session *mcclient.ClientSession, idlist []string, body jsonutils.JSONObject, ctxs []ManagerContext) []printutils.SubmitResult
- BatchDeleteInContextsWithParam(session *mcclient.ClientSession, idlist []string, query jsonutils.JSONObject, body jsonutils.JSONObject, ctxs []ManagerContext) []printutils.SubmitResult
- GetSpecificMethods() sets.String
- }
- type IResourceManager interface {
- Manager
- GetMetadata(session *mcclient.ClientSession, id string, params jsonutils.JSONObject) (jsonutils.JSONObject, error)
- SetMetadata(session *mcclient.ClientSession, id string, params jsonutils.JSONObject) (jsonutils.JSONObject, error)
- }
- type JointManager interface {
- IBaseManager
- MasterManager() Manager
- SlaveManager() Manager
- Get(s *mcclient.ClientSession, mid, sid string, params jsonutils.JSONObject) (jsonutils.JSONObject, error)
- ListDescendent(s *mcclient.ClientSession, mid string, params jsonutils.JSONObject) (*printutils.ListResult, error)
- ListDescendent2(s *mcclient.ClientSession, sid string, params jsonutils.JSONObject) (*printutils.ListResult, error)
- ListAscendent(s *mcclient.ClientSession, mid string, params jsonutils.JSONObject) (*printutils.ListResult, error)
- Attach(s *mcclient.ClientSession, mid, sid string, params jsonutils.JSONObject) (jsonutils.JSONObject, error)
- BatchAttach(s *mcclient.ClientSession, mid string, sids []string, params jsonutils.JSONObject) []printutils.SubmitResult
- BatchAttach2(s *mcclient.ClientSession, mid string, sids []string, params jsonutils.JSONObject) []printutils.SubmitResult
- Detach(s *mcclient.ClientSession, mid, sid string, query jsonutils.JSONObject) (jsonutils.JSONObject, error)
- BatchDetach(s *mcclient.ClientSession, mid string, sids []string) []printutils.SubmitResult
- BatchDetach2(s *mcclient.ClientSession, mid string, sids []string) []printutils.SubmitResult
- Update(s *mcclient.ClientSession, mid, sid string, query jsonutils.JSONObject, params jsonutils.JSONObject) (jsonutils.JSONObject, error)
- BatchUpdate(s *mcclient.ClientSession, mid string, sids []string, query jsonutils.JSONObject, params jsonutils.JSONObject) []printutils.SubmitResult
- Patch(s *mcclient.ClientSession, mid, sid string, query jsonutils.JSONObject, params jsonutils.JSONObject) (jsonutils.JSONObject, error)
- BatchPatch(s *mcclient.ClientSession, mid string, sids []string, query jsonutils.JSONObject, params jsonutils.JSONObject) []printutils.SubmitResult
- }
- var (
- modules map[string][]IBaseManager
- jointModules map[string][]JointManager
- )
- func resourceKey(mod IBaseManager) string {
- return fmt.Sprintf("%s-%s", mod.ServiceType(), mod.KeyString())
- }
- func resourceKey2(mod IBaseManager) string {
- return mod.KeyString()
- }
- func jointResourceKey(mod1, mod2 IBaseManager) string {
- return fmt.Sprintf("%s-%s-%s", mod1.ServiceType(), mod1.KeyString(), mod2.KeyString())
- }
- func jointResourceKey2(mod1, mod2 IBaseManager) string {
- return fmt.Sprintf("%s-%s", mod1.KeyString(), mod2.KeyString())
- }
- func ensureModuleNotRegistered(mod, newMod IBaseManager, isFatal bool) bool {
- modSvcType := mod.ServiceType()
- newModSvcType := newMod.ServiceType()
- if mod == newMod {
- if isFatal {
- log.Fatalf("Module %#v duplicate registered, service type: %q", mod, modSvcType)
- } else {
- return false
- }
- }
- if modSvcType != newModSvcType {
- if isFatal {
- log.Fatalf("Module %#v already registered, service type is %q.\nSo new module %#v can't be registered, service type is %q", mod, modSvcType, newMod, newModSvcType)
- } else {
- return false
- }
- }
- return true
- }
- func Register(m IBaseManager) {
- if modules == nil {
- modules = make(map[string][]IBaseManager)
- }
- for i, key := range []string{
- resourceKey(m),
- resourceKey2(m),
- } {
- fatal := false
- if i == 0 {
- fatal = true
- }
- mods, ok := modules[key]
- if !ok {
- mods = make([]IBaseManager, 0)
- }
- skip := false
- for i := range mods {
- if !ensureModuleNotRegistered(mods[i], m, fatal) {
- skip = true
- break
- }
- }
- if !skip {
- mods = append(mods, m)
- modules[key] = mods
- }
- }
- }
- func RegisterJointModule(mod IBaseManager) {
- jointMod, ok := mod.(JointManager)
- if ok { // also a joint manager
- for _, jointKey := range []string{
- jointResourceKey(jointMod.MasterManager(), jointMod.SlaveManager()),
- jointResourceKey2(jointMod.MasterManager(), jointMod.SlaveManager()),
- } {
- jointMods, ok := jointModules[jointKey]
- if !ok {
- jointMods = make([]JointManager, 0)
- }
- skip := false
- for i := range jointMods {
- if !ensureModuleNotRegistered(jointMods[i], jointMod, false) {
- skip = true
- break
- }
- }
- if !skip {
- jointModules[jointKey] = append(jointMods, jointMod)
- }
- }
- }
- }
- var jointModulesLock *sync.Mutex
- func init() {
- jointModulesLock = &sync.Mutex{}
- }
- func registerAllJointModules() {
- jointModulesLock.Lock()
- defer jointModulesLock.Unlock()
- if jointModules == nil {
- jointModules = make(map[string][]JointManager)
- for modname := range modules {
- for i := range modules[modname] {
- RegisterJointModule(modules[modname][i])
- }
- }
- }
- }
- func _getModule(session *mcclient.ClientSession, name string) (IBaseManager, error) {
- mods, ok := modules[name]
- if !ok {
- return nil, fmt.Errorf("No such module %s", name)
- }
- if len(mods) == 1 {
- return mods[0], nil
- }
- for _, mod := range mods {
- url, e := session.GetServiceURL(mod.ServiceType(), mod.EndpointType(), httputils.POST)
- if e != nil {
- return nil, errors.Wrap(e, "session.GetServiceURL")
- }
- _, ver := mcclient.SplitVersionedURL(url)
- log.Debugf("url: %s ver: %s mod.Version: %s", url, ver, mod.Version())
- if strings.EqualFold(ver, mod.Version()) {
- return mod, nil
- }
- }
- return nil, fmt.Errorf("Version mismatch")
- }
- func GetModule(session *mcclient.ClientSession, name string) (Manager, error) {
- bm, e := _getModule(session, name)
- if e != nil {
- return nil, e
- }
- m, ok := bm.(Manager)
- if ok {
- return m, nil
- } else {
- return nil, fmt.Errorf("Module %s not a Manager", name)
- }
- }
- func GetJointModule(session *mcclient.ClientSession, name string) (JointManager, error) {
- bm, e := _getModule(session, name)
- if e != nil {
- return nil, e
- }
- m, ok := bm.(JointManager)
- if ok {
- return m, nil
- } else {
- return nil, fmt.Errorf("Module %s not a Manager", name)
- }
- }
- func GetJointModule2(session *mcclient.ClientSession, mod1 Manager, mod2 Manager) (JointManager, error) {
- registerAllJointModules()
- for _, key := range []string{
- jointResourceKey(mod1, mod2),
- jointResourceKey2(mod1, mod2),
- } {
- mods, ok := jointModules[key]
- if !ok {
- continue
- }
- for _, mod := range mods {
- url, e := session.GetServiceVersionURL(mod.ServiceType(), mod.EndpointType(), httputils.POST)
- if e != nil {
- return nil, e
- }
- _, ver := mcclient.SplitVersionedURL(url)
- if strings.EqualFold(ver, mod.Version()) {
- return mod, nil
- }
- }
- return nil, fmt.Errorf("Version mismatch")
- }
- return nil, fmt.Errorf("No such joint module: %s", jointResourceKey(mod1, mod2))
- }
- func GetRegisterdModules() ([]string, []string) {
- registerAllJointModules()
- ret := make([]string, 0)
- for k := range modules {
- ret = append(ret, k)
- }
- sort.Strings(ret)
- ret2 := make([]string, 0)
- for k := range jointModules {
- ret2 = append(ret2, k)
- }
- sort.Strings(ret2)
- return ret, ret2
- }
|