騰訊藍鯨CMDB開源代碼二次開發輸出文檔


目錄

1 本地啟動cmdb

2 cmdb數據庫表設計

3 代碼模塊介紹

4 功能介紹

5 請求調用流程

6 新增接口

7 cmdb如何操作mongo數據庫

 

 

一  本地啟動cmdb

 服務器啟動回顧

部署cmdb的時候,輸入./start.sh 就可以啟動12個服務,那么針對這12個服務進行分析一下。首先看一下啟動后輸出的內容:

image.png

 

這里的配置參數,是根據運行的配置腳本所生成的,如:

image.png

生成配置文件位置:

configcenter/src/bin/build/3.2.17/cmdb_adminserver/configures/*

 

二  打開cmdb項目,把上一步cmdb_adminserver/configures/下生成的所有配置文件覆蓋到configcenter/resources/configures/目錄中 (即替換配置文件)。

 

然后修改configcenter/resources/configures/migrate.conf文件 

image.png

 

三、本地啟動項目


cmdb是微服務框架,把平台拆分成了12個服務,本次我們啟動hostServer服務,其他服務啟動類似。

 

啟動hostServer的main方法(host.go文件):

image.png

 

啟動的的時候配置參數:Program arguments

例如:

--addrport=127.0.0.1:60001 --logtostderr=false --log-dir=./logs --v=3 --regdiscv=127.0.0.1:2181

每個服務啟動時 Program arguments 參數不同 可參考服務啟動時顯示的參數進行配置

image.png

 

 

二 cmdb數據庫表設計

 

 

表名

關聯業務

接口

備注

cc_ApplicationBase

基礎資源-業務信息存儲

 

 

cc_AsstDes

模型管理-關聯類型數據存儲

 

 

cc_History

-

 

 

cc_HostBase

基礎資源-主機數據存儲

 

 

cc_HostFavourite

-

 

 

cc_idgenerator

生成ID的,記錄每種記錄最大的ID,類似mysql 主鍵的auto_increment

 

 

cc_InsAsst

-

 

 

cc_ModuleBase

業務資源-業務拓撲中的葉子節點數據

 

 

cc_ModuleHostConfig

主機分配到具體業務模塊表,bk_module_id是cc_ModuleBase.bk_module_id

 

 

cc_Netcollect_Device

-

 

 

cc_Netcollect_Property

-

 

 

cc_ObjAsst

模型與模型之間的關聯關系,見模型管理-模型拓撲

 

 

cc_ObjAttDes

模型的所有字段

 

 

cc_ObjClassification

存儲模型分組數據,針對模型管理-新建分組業務

 

 

cc_ObjDes

存儲模型數據,針對模型管理-模型-新建模型業務

 

 

cc_ObjectBase

自定義模型的實例

 

 

cc_ObjectUnique

-

 

 

cc_UserGroupPrivilege

當添加用戶權限的時候,
表里面才顯示數據

 

通過group_id字段關聯

cc_UserGroup

添加用戶權限管理

 

 

cc_UserCustom

用戶自定義收藏模塊

 

index_v4_recently
存儲最近添加唯一標識


cc_UserAPI

-

 

 

cc_TopoGraphics

存儲模塊在拓撲圖中的位置
 用戶刪除位置,數據表還是保留當前字段,位置置空

 

 


cc_System

系統

 

 

cc_Subscription

事件推送

 

 

cc_SetBase

業務資源-> 業務拓撲

 

 

cc_PropertyGroup

 

 

 

cc_Process

業務資源-> 進程管理 存儲進程

 

bk_biz_id 對應 cc_ApplicationBase

表中的bk_biz_id

cc_ProcOpTask

-

 

 

cc_ProcInstanceModel

-

 

 

cc_ProcInstanceDetail

-

 

 


cc_Proc2Module

-

 

 

cc_Privilege

-

 

 

cc_PlatBase

-

 

 

 

 三 模塊介紹

 

ui:                            前端代碼 

web_server                 后端服務,所有請求入口

api_server :             接口層,這一層是系統的api服務網關 

scene_server/         業務場景模塊,基於資源管理對應用場景的封裝

     admin_server     把配置文件放入zk

     event_server      事件訂閱

     host_server        主機

     topo_server        模型,實例,業務,模塊等

     proc_server        進程  

source_controller   :源管理模塊,把資源類型進行了抽象,每一類資源由一類微服務進程來管理

       auditController   審計

       hostController    主機

       objectController 對象

       procController    進程

storage:                  提供系統所需的資源存儲等系統服務

apimachinery :      根據要操作的資源生成新的url,調用source_controller

 四、

 

請求執行過程:

 
api_server
1  http   --->   api_server(網關)  
 
2 api_server(網關)   -->  scene_server下的xxServer/service/service.go文件中
 
scene_server
3  service.go文件接收路由並調用響應的方法A
 
4  方法A處理邏輯包括驗證頭信息請求參數,最后調用apimachinery
 
apimachinery
5 在apimachinery中會生成一個新的URL 並根據這個URL向source_controller發起請求
 
source_controller
6 source_controller/XXcontroller/service/service.go接收請求 並調用響應方法B
 
storage
7  B方法調用了storage中的方法
 
 ------------------------------------------
v3.2.17
 
 

藍鯨CMDB文檔

 

 

 

 

 

本地啟動cmdb

一、服務器啟動回顧

部署cmdb的時候,輸入./start.sh 就可以啟動12個服務,那么針對這12個服務進行分析一下。首先看一下啟動后輸出的內容:

image.png

 

這里的配置參數,是根據運行的配置腳本所生成的,如:

image.png

生成配置文件位置:

configcenter/src/bin/build/3.2.17/cmdb_adminserver/configures/*

 

二  打開cmdb項目,把上一步cmdb_adminserver/configures/下生成的所有配置文件覆蓋到configcenter/resources/configures/目錄中 (即替換配置文件)。

 

然后修改configcenter/resources/configures/migrate.conf文件 

image.png

 

三、本地啟動項目


cmdb是微服務框架,把平台拆分成了12個服務,本次我們啟動hostServer服務,其他服務啟動類似。

 

啟動hostServer的main方法(host.go文件):

image.png

 

啟動的的時候配置參數:Program arguments

例如:

--addrport=127.0.0.1:60001 --logtostderr=false --log-dir=./logs --v=3 --regdiscv=127.0.0.1:2181

每個服務啟動時 Program arguments 參數不同 可參考服務啟動時顯示的參數進行配置

image.png

 

 

 

CMDB數據庫表設計

1表功能

表名

關聯業務

接口

備注

cc_ApplicationBase

基礎資源-業務信息存儲

 

 

cc_AsstDes

模型管理-關聯類型數據存儲

 

 

cc_History

-

 

 

cc_HostBase

基礎資源-主機數據存儲

 

 

cc_HostFavourite

-

 

 

cc_idgenerator

生成ID的,記錄每種記錄最大的ID,類似mysql 主鍵的auto_increment

 

 

cc_InsAsst

-

 

 

cc_ModuleBase

業務資源-業務拓撲中的葉子節點數據

 

 

cc_ModuleHostConfig

主機分配到具體業務模塊表,bk_module_id是cc_ModuleBase.bk_module_id

 

 

cc_Netcollect_Device

-

 

 

cc_Netcollect_Property

-

 

 

cc_ObjAsst

模型與模型之間的關聯關系,見模型管理-模型拓撲

 

 

cc_ObjAttDes

模型的所有字段

 

 

cc_ObjClassification

存儲模型分組數據,針對模型管理-新建分組業務

 

 

cc_ObjDes

存儲模型數據,針對模型管理-模型-新建模型業務

 

 

cc_ObjectBase

自定義模型的實例

 

 

cc_ObjectUnique

-

 

 

cc_UserGroupPrivilege

當添加用戶權限的時候,
表里面才顯示數據

 

通過group_id字段關聯

cc_UserGroup

添加用戶權限管理

 

 

cc_UserCustom

用戶自定義收藏模塊

 

index_v4_recently
存儲最近添加唯一標識


cc_UserAPI

-

 

 

cc_TopoGraphics

存儲模塊在拓撲圖中的位置
 用戶刪除位置,數據表還是保留當前字段,位置置空

 

 


cc_System

系統

 

 

cc_Subscription

事件推送

 

 

cc_SetBase

業務資源-> 業務拓撲

 

 

cc_PropertyGroup

 

 

 

cc_Process

業務資源-> 進程管理 存儲進程

 

bk_biz_id 對應 cc_ApplicationBase

表中的bk_biz_id

cc_ProcOpTask

-

 

 

cc_ProcInstanceModel

-

 

 

cc_ProcInstanceDetail

-

 

 


cc_Proc2Module

-

 

 

cc_Privilege

-

 

 

cc_PlatBase

-

 

 

 

2 名詞介紹

資源名稱:

biz:   業務線

set:集群

module:模塊

host:主機

 

字段描述:

bk_supplier_id :供應商ID  默認為0 ,不做變動

bk_host_id  :     主機id

bk_obj_id.   :     模型id, 模型的唯一標識,如,szone,redis,set,module

 

關鍵詞:

association 關聯類型

object_association模型關聯

inst_association     實例關聯

privilege              權限

inst                      模型實例

object                 對象:如 module,set等

classification      模型分類

custom_query:userapi  自定義api

favorites            主機收藏

 

 

 

 

 

模塊介紹

 

ui:                            前端代碼 

web_server                 后端服務,所有請求入口

api_server :             接口層,這一層是系統的api服務網關 

scene_server/         業務場景模塊,基於資源管理對應用場景的封裝

     admin_server     把配置文件放入zk

     event_server      事件訂閱

     host_server        主機

     topo_server        模型,實例,業務,模塊等

     proc_server        進程  

source_controller   :源管理模塊,把資源類型進行了抽象,每一類資源由一類微服務進程來管理

       auditController   審計

       hostController    主機

       objectController 對象

       procController    進程

storage:                  提供系統所需的資源存儲等系統服務

apimachinery :      根據要操作的資源生成新的url,調用source_controller

 

功能介紹

 

1 常用方法

法/文件

作用

位置

詳細位置

FindSingleObject(bk_obj_id)

查找是否存在此模型

Topo_server

topo_server  /core/operation/object.go

condition.CreateCondition()

創建一個結構體存儲查詢條件

common/condition/condition.go

 

dbInst :=

   logic.Instance.

       Table(tName).

        Find(condition).

            Sort(sort).

              Start(uint64(skip)).

                  Limit(uint64(limit))

將查詢條件賦值給結構體賦值

解析:

logic   是一個結構體,Instance是結構體中的一個字段

Instance同時還是一個接口,Table是其中一個實現方法

Table()的返回值是Collection

Collection是一個結構體,掛在其結體下的方法有find

Sort,Start,Limit返回值是 Find這個結構體

src/source_controller/hostcontroller/logics/object.go 

GetObjectByCondition()方法

dbInst.All() 即Find.All()

dbInst.One() 即Find.One()

查詢數據庫

解析:one() 和All()這兩個方法都掛在Find結構體下,而在上一行中已經將查詢條件賦值給Find,所以當調用All方法時,可直接從Find中取值進行查詢盡行查詢

例如:f.dbc.DB(f.dbname).C(f.collName).Find(f.filter).One(result)

src/storage/dal/mongo/mgo_mongo.go

 

 

 

2 UI:

前端 VUE:

cmdb vue組件庫:https://magicbox.bk.tencent.com/components_vue/2.0/example/index.html#/

 

前端vue 代碼規范使用 Eslint插件,如不按照規范編寫則編譯報錯:

部分規則如下:

不要有多個連續空行。

關鍵字后面要有一個空格,

函數參數列表括號前面要有一個空格。

始終使用 === 不使用 ==,

逗號后面有一個空格。

else 與它的大括號同行

始終處理函數的 err 參數

瀏覽器全局變量始終添加前綴 window.

var 聲明,每個聲明占一行

無多余逗號

逗號必須放在當前行的末尾

. 應當與屬性同行

文件以空行結尾

鍵名和鍵值之間要有空格

構造函數的名字以大寫字母開始

…..等等

若要關閉Eslint驗證:

src/ui/build/webpack.base.conf.js 文件中 注釋掉eslint

image.png

 

 

 

前端請求示例:

請求調用流程:

getHostList()------>

search()—> getHostList()  ———>

searchHost()

 

 

 

方法位置

ui/src/views/resource/index.vue

 ui/src/components/hosts/table/index.vue

ui/src/store/modules/api/host-search.js

 

 

 

功能

頁面:獲取所有主機

調用子組件中的方法

接收參數 ,發送http請求

 

 

 

 

 

文件介紹

位置

作用

 

 

 

 

src/ui/src/components

Vue組件,方便復用

 

 

 

 

ui/src/store/modules/api/*

封裝URL,接收參數,向后台發請求

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

src/ui/src/views /*

所有頁面

 

 

 

 

ui/src/views/index/index.vue

首頁

 

 

 

 

ui/src/views/business/index.vue

基礎資源/業務

 

 

 

 

ui/src/views/resource/index.vue

基礎資源/主機

 

 

 

 

ui/src/views/hosts/index.vue

業務資源/主機

 

 

 

 

ui/src/views/eventpush/index.vue

模型管理/事件推送

 

 

 

 

ui/src/views/topology/index.vue

業務資源/業務拓撲

 

 

 

 

ui/src/views/custom-query/index.vue

 業務資源/動態分組

 

 

 

 

ui/src/views/process/index.vue

業務資源/進程管理

 

 

 

 

ui/src/views/audit/index.vue

審計與分析/操作審計

 

 

 

 

ui/src/views/model-association/index.vue

模型管理/關聯模型

 

 

 

 

ui/src/views/model-manage/index.vue

模型管理/模型

 

 

 

 

ui/src/views/model-topology/index.vue

模型管理/模型拓撲

 

 

 

 

ui/src/views/business-model/index.vue

模型管理/業務模型

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

3 web_server

文件

作用

 

 

 

 

src/web_server/service/service.go

接收所有請求

 

 

 

 

src/web_server/middleware/login.go

中間件:判斷請求是否已經登陸,以及是否需要轉發到api_server

 

 

 

 

 

 

 

 

 

 

 

 

 

4 api_server:網關,對請求分類,轉發進入sence_server

文件

作用

       

api_server/service/v3/uri.go

對請求進行分類:topo,host,event,proc

       

api_server/service/v3/service.go

根據請求類別,對請求進行轉發

       
           

 

 

5 sence_server:業務處理,調用apimachinery 向資源層發起請求

 

文件

做用

隸屬接口

     

 

 

 

 

XX__server/service/service.go

接收路由請求,請求入口

       

 

 

 

 

XX__server/service/*

請求響應方法

     

 

 

 

 

 

topo_server/service/*

對set,module,biz,privite相關請求進行響應

 

 

 

 

 

 

 

 

topo_server/service/inst_module.go

topo_server/service/inst_set.go

topo_server/service/inst_business 

對模塊,

集群,

業務初步邏輯處理

       

 

 

 

 

topo_server/core/operation/inst_module.go

對modul進一步邏輯處理

ModuleOperationInterface

     

 

 

 

 

topo_server/core/operation/inst.go

邏輯處理結束的對象,向下級服務發起crud請求:module,set,biz,自定義模型,等對象

       

 

 

 

 

topo_server/service/privilege.go

用戶權限相關請求進行響應

       

 

 

 

 

topo_server/core/privilege/privilege.go

對用戶權限的邏輯處理

 

 

 

 

 

 

 

 

 

 

 

6 apimachinery :向資源層發起請求

文件/方法

作用

       

apimachinery/objcontroller/inst/inst.go

對object的增刪改查請求進行處理:module ,set,biz,自定義對象 等

       

apimachinery/objcontroller/privilege/api.go

權限,角色相關接口

       

apimachinery/objcontroller/privilege/privilege.go

權限,角色,相關接口實現方法

 

 

 

 

 

 

 

7 controller :對資源(數據庫)進行操作

 

操作方式:

在每個微服務下通常有三個文件夾 :app,service,logics

image.png

Service文件夾: 下主要是請求入口,已及請求的響應方法,進行邏輯處理,然后調用logics文件夾下的方法

Logics文件夾:  下通常有一個都有一個logics.go文件,logics.go文件中都有一個結構體Logics 如:

                type Logics struct{

                    Instance dal.RDB

                   } 

              Logics文件夾中的所有方法都掛在結構體Logics下,如 func (lgc *Logics) DelModule(); 

       Logics結構體中的Instance 是對數據操作的一些接口如:

        type RDB interface {

                   Clone() RDB

                   // Table collection 操作 

                   Table(collection string) Table

                   // StartTransaction 開啟新事務

                  StartTransaction(ctx context.Context) (RDB, error)

                   }

       所以通過結構體Logics,Logics文件夾下的方法可以實現對數據庫的操作。

 

文件

作用

 

 

 

 

auditcontroller

收集和查詢 操作記錄(審計)

 

 

 

 

hostcontroller

主機相關操作

 

 

 

 

objectcontroller

Set, module,biz,自定義模型等操作

 

 

 

 

proccontroller

進程相關操作

 

 

 

 

source_controller/objectcontroller/service/inst_action.go

對實例進行增刪改查:module,set,biz等

 

 

 

 

source_controller/objectcontroller/service/common.go

對數據庫操作的通用方法

 

 

 

 

objectcontroller/service/*

對權限,角色,模型,biz相關接口進行響應

 

 

 

 

objectcontroller/service/privilege_action.go

對用戶組權限進行增刪改查

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

8 common

文件

 

 

 

 

 

src/common/*

封裝了對數據庫操作的方法

 

 

 

 

src/common/condition

封裝查詢條件,如sort,limit,start,fiels

 

 

 

 

src/common/conf

讀取解析配置文件

 

 

 

 

src/common/mapstr

將condition的fields字段轉換成map

 

 

 

 

 

 

 

 

 

 

 

 

 

 

請求調用流程

1 執行流程

HTTP----  /*  ----web_server

http請求首先進入web_server 在其中會驗證登陸等信息

 

web_server---------/api/v3/*--------> api_server 

web_server中/api/v3的請求會被轉發到api_server,在api_server中請求被分類,以host資源為例:/api/v3/*   會轉換成/host/v3/* 向下一層服務發起請求

 

api_server----/host/v3/*------->scene_server----調用--->apimachinery(類似SDK)

api_server向scene_server發起請求,在scene_server中處理業務邏輯,scene_server調用apimachinery向下一級服務發起請求,在apimachinery中url會根據資源類型作出更改,以更改后的url向資源層發請求

 

apimachinery ---------> source_controller ---------調用------ storage

apimachinery向source_controller發起請求,source_controller中調用storage封裝的方法完成對數據庫的操作

 

-------------------------------------------------------------------------------------------------------

ps:由於api_server只處理url路徑是 /api/v3/* 的請求,所以部分請求 url 不是 /api/v3/開頭則不會進入api_server,而是進入web_server進行處理。web_server通過調用apimachinery,向source_controller發起請求 來完成對資源的操作。

 

 

 

 

 

 

2  介紹

 

api_server 將收到的請求處理,分為四類轉發進入sence_server下的四個微服務,分別是,topo,host,proc,event 四大類。

例如:/api/v3/biz/...在api_server   中請求會被轉成    /topo/v3/biz/...

 

topo類包括:audit,biz,topo,identifier,inst,module,object,objects,/object/attr,objectatt,set,                        privilege

host類包括:host,hosts,userapi,usercustom,/findmany/modulehost

event類包括:event

proc類包括:proc

 

 

 

3 CMDB API請求示例

 

ps:每個微服務下都有一個../service/service.go文件作為請求入口

 

3.1 獲取主機基礎信息詳情

  • API: GET /api/{version}/hosts/{bk_supplier_account}/{bk_host_id}
  • http://localhost:8083/api/v3/hosts/0/77
  • 功能說明:獲取77號主機基礎信息詳情
  • input body: 無

 http請求-------->  api_server

api_server: 在src/api_server/service/v3/service.go 中接收所有跟路徑是/api/v3/ 的請求

                    請求變成/host/v3/hosts/0/77 進入下一個服務

api_server ------> scene_server : 

scene_server:    在src/scene_server/host_server/service/service.go   接收所有跟路徑是/host/v3 的路由

                           其中/hosts/{bk_supplier_account}/{bk_host_id} 接收到請求 並調用     

                           GetHostInstanceProperties()方法:獲取參數,處理參數

                          在 src/apimachinery/hostcontroller/host/api.go文件GetHostByID()方法中 進入下一級服務,                            跳轉路徑:/host/v3/host/77

 scene_server-------source_controller:

 source_controller:在src/source_controller/hostcontroller/service/service.go文件中接收所有跟路徑   

                                為/host/v3的路由,/host/v3/host/{bk_host_id} 接收請求,並調用GetHostByID()方法

                                 最后調用storage,src/storage/dal/mongo/mgo_mongo.go文件中One()方法完成數據庫

                               查詢 。

 

3.2 查詢業務線

 

  API: POST /api/{version}/biz/search/{bk_supplier_account}

  參數:{ "condition": {}}

   condition 參數為業務的任意屬性,如果不寫代表搜索全部數據

  例:  http://localhost:8083/api/v3/biz/search/0

    apiServer 接收請求並轉換成:/topo/v3/app/search/0

    topo_server 接收請求並調用 SearchBusiness方法------ 調用FindBusiness()(實現方法在本 頁)----  FindOriginInst(實現方法在本頁)......

                            最后調用在 src/apimachinery/objcontroller/inst/inst.go。SearchObjects方法  

   請求變成/insts/biz/search

   TopoConroller

   調用SearchInstObjects方法響應,然后調用src/source_controller/objectcontroller/service/common.go        GetObjectByCondition方法

 

 

 3.3 查詢模型實例

API POST /api/{version}/inst/association/search/owner/{bk_supplier_account}/object/{bk_obj_id}

 參數{

   "condition":{

        "bk_weblogic":[

            {

                "field":"bk_inst_name",

                "operator":"$regex",

                "value":"qq"

            }

        ]

    }

}

 

 

例:http://localhost:8083/api/v3/inst/association/search/owner/0/object/redis

api_server 收到請求轉化成 /topo/v3/inst/association/search/owner/0/object/redis進入下一服務

業務場景 :topo_server

     src/scene_server/topo_server/service/service_initfunc.go 接收請求 轉到           

     SearchInstByAssociation方法---    FindInstByAssociationInst----FindInst----FindOriginInst---    

                      c.clientSet.ObjectController().Instance().SearchObjects()----

    src/apimachinery/objcontroller/inst/inst.go SearchObjects()生成URL:/insts/object/search 進入   

     下一級服務.

資源管理 :object_controller

     /insts/{obj_type}/search 接收請求 調用響應方法SearchInstObjects()------  GetHostByCondition---all()              

             

3.4 條件查詢主機 

API: POST /api/{version}/hosts/search

參數:可根據根據set 、host、biz、module等模型屬性進行查詢

 

{  "page":{  "start":0,  "limit":10,  "sort":"bk_host_id"  },  "pattern":"",  "bk_biz_id":2,  "ip":{  "flag":"bk_host_innerip|bk_host_outerip",  "exact":1,  "data":[  ]  },  "condition":[  {  "bk_obj_id":"host",  "fields":[  ],  "condition":[  ]  },  {  "bk_obj_id":"module",  "fields":[  ],  "condition":[  ]  },  {  "bk_obj_id":"set",  "fields":[  ],  "condition":[  ]  },  {  "bk_obj_id":"biz",  "fields":[  ],  "condition":[  {  "field":"default",  "operator":"$ne",  "value":1  }  ]  }  ] }

 

示例:

localhost:8083/api/v3/hosts/search

參數:{}

 

api_sever 接收請求 (生成url:/host/v3/hosts/search)---->

sence_service(src/scene_server/host_server/service/service.go )------SearchHost()---s.Logics.SearchHost()----SearchHostByConds()----sh.searchByHostConds()-------sh.lgc.CoreAPI.HostController().Host().GetHosts:  path=src/apimachinery/hostcontroller/host/api.go

url==/hosts/search

進入 host_controller

src/source_controller/hostcontroller/service/service.go-----GetHosts()--GetObjectByCondition()---all()

 

 

3.5 創建模塊

POST /api/{version}/module/{bk_biz_id}/{bk_set_id}

input body:

{

    "bk_module_name":"cc_module",

    "bk_supplier_account":"0",

    "bk_parent_id":0

}

示例:

localhost:8083/api/v3/module/3/2

參數:{ "bk_module_name":"devops"}

http  ---------> api_server ----  跳入下一服務,URL:/topo/v3/module/3/2

//查詢模型類型是否存在

topo_server :/module/{app_id}/{set_id} 接收上一請求------>CreateModule()方法

                        -------FindSingleObject()//查詢 --- 跳入下一服務,url:/insts/module/search

object_controller:/insts/{obj_type}/search 接收上一請求------>SearchInstObjects                       

//創建模型

topo_server:    ------ModuleOperation().CreateModule()

object_controller:         /insts/{obj_type}接收請求

 

3.6 創建集群

API: POST /api/{version}/set/{bk_biz_id}

參數

{

   "bk_set_name":"wefd",  集群名字

   "bk_parent_id":0,          集群上級id 可以是業務線 ,或者其他,具體參照拓撲模型

   "bk_biz_id":1               業務線

}

示例:localhost:8083/api/v3/set/3

topo_server  /set/{app_id} 接收請求

 

新增接口流程

1 簡介版

查詢主機:localhost:8083/api/v3/hosts/selectAll

1  url 設計: 以/api/v3/{type}/….  開頭的請求會被web_server轉發進入 api_server

2  type 代表資源類型 根據type 類型 被轉發進入sence_server

3  在host_server中編寫請求 /host/v3/hosts/selectAll的入口,以及響應方法selectAll(),在selectAll()中處理 

    調用資源層完成,業務邏輯的處理

4  selectAll()方法調用src/apimachinery  中的httpclient 向controller發起請求

     所以在src/apimachinery/hostcontroller/host/api.go 中編寫方法 ,使用httpClient向host_controller 發起請

    求

    請求的url 設計沒有規定 如 subPath := "/hosts/myJob

     則完整請求是 localhost:8083/host/v3/hosts/myJob

5 在hostcontroller中 編寫請求    /host/v3/hosts/myJob的 路由入口

 

6  編寫myJob的響應方法 查詢數據 返回數據

 

ps  : 從第4步開始 src/apimachinery  中的httpclient 向controller發起請求 只是純粹的對資源進行操作,不包含業務邏輯,所以 一般情況下 只需要變動sence_server,無需變動apimachinery 和controller

 

 

 

 

2 實操版

 

1  url 設計: 以/api/v3/{type}/….  開頭的請求會被web_server轉發進入 api_server

 

2  type 代表資源類型 可以為:

biz,topo,identifier,inst,module,objectset,privilege,host,hosts,userapi,usercustom, event proc等,具體請見src/api_server/service/v3/uri.go 中資源划分

 

3 新增接口查詢主機,假設 url設計為:localhost:8083/api/v3/hosts/selectAll,在api_server中 會根據url中的關鍵詞hosts ,判定要操作的資源是host,所以url  從 /api/v3/hosts/selectAll     變成  /host/v3/hosts/selectAll

 

 

4 在host_server中,src/scene_server/host_server/service/service.go 接收所有/host/{version}

的請求

所以在此文件中編寫/host/v3/hosts/selectAll請求入口

api.Route(api.POST("/hosts/selectAll").To(s.SelectAllHost))

----------------

響應方法:

func (s *Service) SelectAllHost(req *restful.Request, resp *restful.Response) {

//獲取頭信息

pheader := req.Request.Header

// new 出一個結構體 存儲查詢參數

body := new(meta.HostCommonSearch)

//獲取講請求中的參數 解析賦值到 結構體body中

json.NewDecoder(req.Request.Body).Decode(body)

 

// 獲得頭信息pheader 和 傳遞的參數body后  調用下個方法SearchHost() 進行查詢

host, err := s.Logics.SearchHost(pheader, body)

 

}

 

 


Ps: SearchHost()方法掛在結構體Logics下,Logics結構體中有接口可以調用下一個微服務

 

func (lgc *Logics)SearchHost(phader http.Header,body Body) (*metadata.GetHostsResult, error) {

   //從傳入的body中 獲取到參數 賦值在 結構體 metadata.QueryInput中

   query := metadata.QueryInput{

      Start:     body.start,

      Limit:     body.limit,

      Sort:      common.BKHostInnerIPField,

      Fields:    common.BKHostInnerIPField,

   }

 

//  把查詢參數query 傳給apimacheniry,由apimacheniry 向controller發起請求

  lgc.CoreAPI.HostController().Host().MyjobSpimachinery()

   

}

 

編寫 MyjobSpimachinery方法:

在src/apimachinery/hostcontroller/host/api.go 中編寫 方法 MyjobSpimachinery(),

 

在MyjobSpimachinery中

         subPath為要跳轉的路由入口,可自己設計

         metadata.GetHostsResult返回值類型

         .Do() 進行跳轉

         .Into() 把查詢結果放進new 出來的結構體,並return

代碼如下:

 

func (t *hostctrl) MyjobSpimachinery(ctx context.Context, h http.Header, opt *metadata.QueryInput) (resp *metadata.GetHostsResult, err error) {  resp = new(metadata.GetHostsResult)  subPath := "/hosts/myJob"  err = t.client.Post().  WithContext(ctx).  Body(opt).  SubResource(subPath).  WithHeaders(h).  Do().  Into(resp)  return }

 

 

 

-------------------------------------------------------------------

5  在src/source_controller/hostcontroller/service/service.go中接收所有請求是/host/v3 的請求

所以在此文件中編寫/hosts/myJob 的入口

api.Route(api.POST("/hosts/myJob").To(s.MyJob))

響應方法:

func (s *Service) MyJob(req *restful.Request, resp *restful.Response) {

   //獲取參數調用數據庫進行查詢

 

}

6.

 

 

 

 

CMDB中對mongo的操作

1、

cmdb對mongo的常規操作進行了一層封裝,方便之后的CRUD,在代碼中發現最常見的一種查詢方式如下:

lgc.Instance.Table("表名"). Find(map) .All(ctx,&results);

map代表查詢條件,通過這行代碼完成查詢並且把查詢結果賦值給results,下面將對這行代碼進行解釋

 

觀察結構體Logics

type Logics struct {

   Instance dal.RDB

   Cache    *redis.Client

   *backbone.Engine

}

發現Logics下 Instance dal.RDB 是一個interface ,其實現方法 有對db的一些操作  如下

type RDB interface {

   Clone() RDB

   // Table collection 操作

   Table(collection string) Table

   // StartTransaction 開啟新事務

   StartTransaction(ctx context.Context) (RDB, error)

   // Commit 提交事務

   Commit(context.Context) error

   // Abort 取消事務

   Abort(context.Context) error

}

 

其中Table(collection string) Table是一個interface,其實現方法有

type Table interface {

   // Find 查詢多個並反序列化到 Result

   Find(filter Filter) Find

   // Aggregate 聚合查詢

   AggregateOne(ctx context.Context, pipeline interface{}, result interface{}) error

   AggregateAll(ctx context.Context, pipeline interface{}, result interface{}) error

   // Insert 插入數據, docs 可以為 單個數據 或者 多個數據

   Insert(ctx context.Context, docs interface{}) error

   // Update 更新數據

   Update(ctx context.Context, filter Filter, doc interface{}) error

   // Delete 刪除數據

   Delete(ctx context.Context, filter Filter) error

}

 

觀察上面結構體總結如下:

Logics   是一個結構體,Instance是結構體中的一個字段。

即:Logics.Instance

Instance同時還是一個接口,Table是其中一個實現方法。

 即 :Logics.Instance.Table(“表名”)

Table(name String)的返回值是CollectionCollection是一個結構體指定了要操作的表名。

 

Find(map)方法掛在Collection結構體下,Find方法將Collection 和map(查詢條件)放入Find結構對應的字段。 返回Find結構體 。

即: inst :=  Logics.Instance.Table(“表名”).Find(map)

此時inst 是一個指定了查尋條件和 要操作的表名的Find結構體

 

All()方法 掛在Find結構體下:  

 Logics.Instance.Table(“表名”).Find(map).all(results)

進行最終查詢。

 

在以上的操作中只是為了將各種查詢條件放入Find結構中,最終All()方法從Find結構體中取出查詢條件進行查詢,將結果賦值給results;

All 方法代碼如下:

func (f *Find) All(result interface{}) error {

   f.dbc.Refresh()

   query := f.dbc.DB(f.dbname).C(f.collName).Find(f.filter)

   query = query.Select(f.projection)

   query = query.Skip(int(f.start))

   query = query.Limit(int(f.limit))

   query = query.Sort(f.sort...)

    //執行查詢,若是查詢出錯 返回錯誤信息

   return query.All(result)

}

實操:

1 查詢內網ip是121.21.13.14的主機

首先創建一個map存放查詢條件

condition:=make(map[string]interface{})

condition["bk_host_innerip"]="121.21.13.14"

condition["bk_host_id"]="host"

然后定義一個可變的 map數組接收查詢結果

results := make([]map[string]interface{}, 0)

最后進行查詢

lgc.Instance.

   //指定查詢的表

   Table("cc_HostBase").

          //查詢條件   

             Find(condition)

                 //進行查詢

                .All(ctx,&results);

find方法只是為了將查詢條件賦值給Find結構體,最后的All方法從Find結構體中取出查詢條件編寫查詢語句進行查詢

 

2  插入一條信息進入表cc_HostBase中

//創建插入信息

inputc := input.(map[string]interface{})

inputc[“name”]=“張三"

//開始插入

lgc.Instance.

   //指定查詢的表

   Table("cc_HostBase").

                 //進行查詢

                .insert(ctx,inputc);

 

 

 

3 在上文查詢語句 Logics.Instance.Table(“表名”).Find(map).all(results)中,將查詢條件放在map中,但並不能完全滿足需求,例如:查詢主機id 不等於"23"的主機,或者大於/小於某個值時都無法用簡單的map進行封裝查詢條件,而在cmdb中還有另外一種存放查詢條件的結構體

3.1 查詢條件放在結構體condition中

type condition struct {

   start        int64

   limit        int64

   sort         string

   fields       []Field

   or           []OR

   filterFields []string

}

// 上面這個結構體 調用下面這個接口的實現方法

type Condition interface {

   SetPage(page types.MapStr) error

   SetStart(start int64)

   GetStart() int64

   SetLimit(limit int64)

   GetLimit() int64

   SetSort(sort string)

   GetSort() string

   SetFields(fields []string)

   GetFields() []string

   Field(fieldName string) Field

   NewOR() OR

   Parse(data types.MapStr) error

   ToMapStr() types.MapStr

}

 

接口Condition 有Field 字段,其中字段fields 是個interface 其實現方法有

type Field interface {

   Eq(val interface{}) Condition

   NotEq(val interface{}) Condition

   Like(val interface{}) Condition

   In(val interface{}) Condition

   NotIn(val interface{}) Condition

   Lt(val interface{}) Condition

   Lte(val interface{}) Condition

   Gt(val interface{}) Condition

   NotGt(val interface{}) Condition

   Gte(val interface{}) Condition

   ToMapStr() types.MapStr

}

所以:cond.Field(字段").NotEq("條件")

如:

// 創建condition結構體

cond := condition.CreateCondition()

//查詢內網ip不等於121.21.13.14的機器

cond.Field(“bk_host_innerIp").NotEq("121.21.13.14")

//創建結構體condMapStr

var condMapStr mapstr.MapStr= mapstr.New()

//將conf 進行一些轉化

condMapStr.Merge(cond.ToMapStr())

//condMapStr放着查詢條件,作為參數放入Find中進行查詢

err:= lgc.Instance.Table("cc_HostBase"). Find(condMapStr) .All(ctx,&results);

 

 

Redis在cmdb中的作用

 

redis在cmdb中主要用於事件訂閱

1 redis的ident文件夾下中存放的信息有:

   業務信息,主機信息,模塊信息,集群信息,進程信息

image.png

 

image.png

 

2 redis中的信息同步:

  2.1 以上信息並非是實時更新,event_server負責從mongo數據庫中同步最新的數據,大概每隔1分鍾向redis中同步一次信息。

   2.2  在event_server啟動時調用app.Run()方法------   errCh <- distribution.Start(ctx, cache, db, rpccli)------------chErr <- ih.StartHandleInsts()中代碼片段:

go func() {

   ih.fetchHostCache()

   for range time.Tick(time.Second * 60) {

      ih.fetchHostCache()

   }

}()

可設置redis中的信息多久和mongo同步一次 

 

 2.3 新增訂閱事件,刪除訂閱事件,會時時同步到redis,redis中記錄的只是 訂閱事件id

 

image.png

 

3 event_server 直接調用storage 操作數據庫,不再調用controller 

event_server : 事件訂閱服務

請求入口:src/scene_server/event_server/service/service.go:

    //查詢訂閱事件

api.Route(api.POST("/subscribe/search/{ownerID}/{appID}").To(s.Query))

//只測試連通性

api.Route(api.POST("/subscribe/ping").To(s.Ping))

//測試推送

api.Route(api.POST("/subscribe/telnet").To(s.Telnet))

//新增訂閱事件

api.Route(api.POST("/subscribe/{ownerID}/{appID}").To(s.Subscribe))

//刪除訂閱事件

api.Route(api.DELETE("/subscribe/{ownerID}/{appID}/{subscribeID}").To(s.UnSubscribe))

//修改訂閱事件

api.Route(api.PUT("/subscribe/{ownerID}/{appID}/{subscribeID}").To(s.Rebook))

 

4 生產者--消費者

 

1生產者:

type Service struct {

   Core     *backbone.Engine

   Instance dal.RDB

   Cache    *redis.Client

}

 

在結構體Service中有  Cache    *redis.Client 

 

當對資源進行增刪改查時,在controller中操作成功后,會向redis中新增一個消息 如下:

ec := eventclient.NewEventContextByReq(req.Request.Header, cli.Cache)

ec.InsertEvent(metadata.EventTypeInstData, objType, metadata.EventActionUpdate, newData)

 

lpush(key,value) 將消息放入redis

 

這時在redis中,如圖4個消息存放於隊列中等待被消費:

image.png

 

 

2 消費者

 

在 src/scene_server/event_server/identifier/identifier.go :

handleInstLoop方法:

服務啟動的時候 調用handleInstLoop()方法,其中for循環中ih.popEventInst()會和redis建立連接,並從redis中根據key獲取到值

for {

   event := ih.popEventInst()

   if nil == event {

      time.Sleep(time.Second * 2)

      continue

   } 

 

上面for循環內的代碼會不停的向redis建立連接取值,當value為空時,繼續建立連接會造成資源浪費,所以在ih.popEventInst()中,從redis中取值時並未使用rpop,而是使用了阻塞命令brpop,當value為空時線程會阻塞在那

image.png

 

審計信息的記錄

8/10

審計操作是在業務邏輯層完成的操作:

Sence_server ————調用———— src/apimachinery/auditcontroller ——跳轉——— audit_controller

在業務邏輯層中(server)處理業務后,根據返回的結果新增操作的審計信息

apimachinery 內封裝的有新增審計信息方法:

 

新增業務操作      AddBusinessLog()

查詢審計信息   GetAuditLog ()

新增主機操作   AddHostLog()

新增模塊操作   AddModuleLog()

新增對象操作   AddObjectLog()

新增進程操作   AddProcLog()

新增集群操作   AddSetLog()

 

server 調用apimachinery 封裝的方法,上述方法之外的操作不記錄審計。

 

具體新增審計代碼(1):

 

type Service struct {

   *options.Config

   *backbone.Engine

   *logics.Logics

   disc discovery.DiscoveryInterface

}

 

 

type Engine struct {

   sync.Mutex

   ServerInfo types.ServerInfo

   CoreAPI    apimachinery.ClientSetInterface

   SvcDisc    ServiceDiscoverInterface

   Language   language.CCLanguageIf

   CCErr      errors.CCErrorIf

}

 

aResult, err := service.CoreAPI.AuditController().AddHostLogs(context.Background(), common.BKDefaultOwnerID, appID, user, pheader, log)

 

通過結構體Service   調用CoreAPI 即apimachinery 內封裝的方法 

 

 

 

9/10

具體新增審計代碼(2)

在topo_server 中 

src/scene_server/topo_server/service/service_initfunc.go 可以接收請求有:

新增biz,

新增module,

新增set,

新增Inst 

以上請求的響應方法處理邏輯之后,最終都要調用src/scene_server/topo_server/core/operation/inst.go下的

func (c *commonInst) CreateInst(){}方法。

 

CreateInst中 新增審計信息 如下:

 

NewSupplementary().Audit(...).CommitCreateLog(...)

 

CommitCreateLog方法———commitSnapshot()在commitSnapshot中根據參數不同調用AuditController()中封裝好的審計方法

 image.png

 

src/common/tablenames.go   所用到的表名,每個表名在這里都有一個變量表示;數據庫查詢時不直接寫查詢的表名,而是使用表名所代表的變量

 

 

association 關聯關系

 

在topo_server;

src/scene_server/topo_server/service/service_initfunc.go:中有着所有關聯關系的入口,分類如下

 

1  關聯類型:創建一種關聯關系用於實例間關聯事被引用

 

image.png

 

查詢關聯類型

"/topo/association/type/action/search

 新增關聯類型

 "/topo/association/type/action/create

更新一個關聯類型

  "/topo/association/type/{id}/action/update

刪除一個關聯類型

  "/topo/association/type/{id}/action/delete

 

2 主機和模型實例關聯關系

 

image.png

 

/inst/association/action/search

/inst/association/action/create

/inst/association/{association_id}/action/delete

 

10/10

 

3模型拓撲關聯關系

 

image.png

 

/object/association/action/search


/object/association/action/create


/object/association/{id}/action/update


/object/association/{id}/action/delete

 

權限管理

 

 

1 創建角色,添加成員

 

image.png

 

創建角色時,選擇擁有此角色的成員;  也稱新建用戶分組

 

topo_server.  API: POST /api/{version}/topo/privilege/group/{bk_supplier_account}

參數:分組名,分組成員

{

    "group_name":"管理員",

    "user_list":"owen;tt"

}

 

 

 

src/apimachinery/objcontroller/privilege/privilege.go:  CreateUserGroup() 跳轉進入object——controller

image.png

 

 

src/source_controller/objectcontroller/service/service.go:接收請求

api.Route(api.POST("/privilege/group/{bk_supplier_account}").To(s.CreateUserGroup))

 

表:cc_Usergroup

image.png

 

 

 

2 添加的成員必須時 已經存在的賬戶  :查詢現有的的用戶

web_server :ws.GET("/user/list", s.GetUserList)

————— src/web_server/middleware/user/public.go :GetUserList

———— — —  src/web_server/middleware/user/plugins/method/self/userinfo.go :GetUserList

 

image.png

 

在cmdb開源代碼中,不支持多用戶,在代碼固定了一個 admin 用戶

 

 

3  編輯用戶分組權限

 

image.png

 

API: POST /api/{version}/topo/privilege/group/detail/{bk_supplier_account}/{group_id}

參數:

{bk_middleware: {

    bk_tomcat: ["search", "update", "delete"], 

        redis: ["search", "update", "delete”]

}

}

 

 

 

4 查詢用戶權限:

 

 

API: GET /api/{version}/topo/privilege/user/detail/{bk_supplier_account}/{user_name}

http://localhost:8083/api/v3/topo/privilege/user/detail/0/admin  獲取用戶admin的權限

 

 

   


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM