導(dǎo)讀
- BMF RESTful API 文檔勘誤
- interface role 的增刪查
- lag 的增刪查
- service node 的增刪查
- policy 的增刪查
- Python版本的REST client
BMF RESTful API 文檔勘誤
在《BMF-6.0.0-REST-API-Guide-2017.03.07》文檔的Chapter 1 page16給出了介紹,如何用curl或者Python實(shí)現(xiàn)REST請(qǐng)求。因?yàn)槲臋n有錯(cuò)誤耕挨,所以只糾正這些錯(cuò)誤的地方厢塘。
注《BMF-6.0.1-REST-API-Guide-2017.04.19》文檔已經(jīng)修正了這些錯(cuò)誤
1. BMF Controller需要開(kāi)啟REST端口
文檔上是這么寫(xiě)的:
Note: By default, port 8082 is not enabled on the controller firewall. To enable this port, enter the
firewall allow port 8082
command from the BMF controller config mode. For details about limiting access to specific source or destination addresses, enter thehelp firewall
command, or refer to thefirewall
command section in the ...
這里面有兩個(gè)錯(cuò)誤:
- 8082端口就不是REST端口,而是8443
- 根本沒(méi)有
firewall
這個(gè)命令
解決辦法:
在BMF Controller進(jìn)行如下操作
BMF6> enable
BMF6# config
BMF6(config)# controller
BMF6(config-controller)# access-control
BMF6(config-controller-access)# access-list api
BMF6(config-controller-access-list)# <ACL ID侈询,自己指定> permit from <IP>
2. REST auth URL有錯(cuò)誤
開(kāi)啟了REST端口舌涨,還需要修改auth URL。
文檔里面的是:http://${CONTROLLER_IP}:8082/auth/login
實(shí)際應(yīng)該是:https://${CONTROLLER_IP}:8443/api/v1/auth/login
把上面兩個(gè)問(wèn)題解決后再看文檔可知扔字,在發(fā)送REST請(qǐng)求之前囊嘉,先要登陸拿到sesson_cookie,然后再發(fā)送請(qǐng)求革为。這個(gè)過(guò)程可以通過(guò)curl
來(lái)完成(具體見(jiàn)文檔)扭粱,也可以用Python來(lái)完成。我很懶篷角,懶得每次都敲一長(zhǎng)串的curl
命令焊刹。所以基于Sample code做了一些修改,用來(lái)做REST client。源碼見(jiàn)最后虐块。
interface role 的增刪查
這里主要列一下創(chuàng)建俩滥、查看以及修改interface role設(shè)計(jì)到的REST URL
創(chuàng)建 interface role
- uri
PUT https://${CONTROLLER_IP}:8443/api/v1/data/controller/core/switch-config/interface
- json
[
{
"analytics" : true,
"bigtap-name" : "Filter",
"breakout" : false,
"name" : "ethernet1",
"optics-always-enabled" : false,
"role" : "filter",
"shutdown" : false
},
{
"analytics" : true,
"bigtap-name" : "Delivery",
"breakout" : false,
"name" : "ethernet2",
"optics-always-enabled" : false,
"role" : "delivery",
"shutdown" : false
},
{
"analytics" : true,
"bigtap-name" : "Service-ingress",
"breakout" : false,
"name" : "ethernet3",
"optics-always-enabled" : false,
"role" : "service",
"shutdown" : false
},
{
"analytics" : true,
"bigtap-name" : "Service-egress",
"breakout" : false,
"name" : "ethernet4",
"optics-always-enabled" : false,
"role" : "service",
"shutdown" : false
}
]
注 json的列表長(zhǎng)度、每個(gè)元素的
"name"
和"bigtap-name"
都可以根據(jù)自己需要定義
- response
None
刪除 interface role
- uri
DELETE https://${CONTROLLER_IP}:8443/api/v1/data/controller/core/switch-config/interface%5Bname%3D%22${INTERFACE_NAME}%22%5D
這個(gè)uri有必要多說(shuō)一下贺奠,文檔的Chapter 1 Page 14 BigDB REST API YANG Extensions小節(jié)提到霜旧,BMF使用REST API完成查詢操作時(shí)使用了YANG模型儡率,挂据,REST API的請(qǐng)求是由prefix
和XPATH
組成儿普。原文如下:
Note BigDB REST API uses YANG schema language to define resources, which are naturally mapped into an XML structure. BigDB REST API uses XPATH as a query language to query and manipulate resources. XPATH location path and predicates are encoded within URIs of REST API call. In other words, each rest URI contains an XPATH that selects a set of data nodes within the resources tree defined by the YANG schema. For sample XPATH queries, see the sample queries in the REST API section.
再來(lái)看上面的uri,它在創(chuàng)建interface role的uri后面拼接了[key=value]部分。我們知道广恢,URL中是不允許出現(xiàn)類似空格呀潭、等號(hào)钉迷、雙引號(hào)等字符的,因此這個(gè)uri需要經(jīng)過(guò)轉(zhuǎn)碼蜗侈。編碼之后便成了這個(gè)樣子:%5Bname%3D%22${INTERFACE_NAME}%22%5D
(其中篷牌,雙引號(hào)必不可少)。
- responese
None
查詢 interface role
- uri
# 查詢所有的interface role
GET https://${CONTROLLER_IP}:8443/api/v1/data/controller/core/switch-config/interface
# 根據(jù)interface name查詢
GET https://${CONTROLLER_IP}:8443/api/v1/data/controller/core/switch-config/interface%5Bname%3D%22${INTERFACE_NAME}%22%5D
- response
創(chuàng)建 interface role PUT的json
lag 的增刪查
創(chuàng)建 lag interface
- uri
PUT https://${CONTROLLER_IP}:8443/api/v1/data/controller/core/switch-config/lag-interface%5Bname%3D%22${LAG_NAME}%22%5D
- json
{
"hash-type" : "autoconfig",
"member" : [ {
"name" : "ethernet23"
}, {
"name" : "ethernet24"
} ],
"name" : "LAG-1"
}
- response
None
刪除 lag interface
- uri
DELETE https://${CONTROLLER_IP}:8443/api/v1/data/controller/core/switch-config/lag-interface%5Bname%3D%22${LAG_NAME}%22%5D
- response
None
查看 lag interface
- uri
# 查看所有的lag interface
GET https://${CONTROLLER_IP}:8443/api/v1/data/controller/core/switch-config/lag-interface
# 根據(jù)lag interface name查詢
https://${CONTROLLER_IP}:8443/api/v1/data/controller/core/switch-config/lag-interface%5Bname%3D%22${LAG_NAME}%22%5D
- response
創(chuàng)建 lag interface PUT的json
service node 的增刪查
創(chuàng)建 service node
- uri
POST https://${CONTROLLER_IP}:8443/api/v1/data/controller/applications/bigtap/service
- json
[
{
"max-from-service-bandwidth-bps" : 1000000000,
"max-to-service-bandwidth-bps" : 1000000000,
"name" : "WAF",
"post-group" : [ {
"bigtap-name" : "Service-egress"
} ],
"pre-group" : [ {
"bigtap-name" : "Service-ingress"
} ],
"total-from-service-bps" : 0,
"total-to-service-bps" : 0
},
{
"max-from-service-bandwidth-bps" : 1000000000,
"max-to-service-bandwidth-bps" : 1000000000,
"name" : "NF",
"post-group" : [ {
"bigtap-name" : "Service-egress"
} ],
"pre-group" : [ {
"bigtap-name" : "Service-ingress"
} ],
"total-from-service-bps" : 0,
"total-to-service-bps" : 0
}
]
json的列表長(zhǎng)度踏幻、每個(gè)元素的
"name"
枷颊、"post-group"
和"pre-group"
根據(jù)自己需要定義
- response
None
刪除 service node
- uri
DELETE https://${CONTROLLER_IP}:8443/api/v1/data/controller/applications/bigtap/service%5Bname%3D%22${SERVICE_NAME}%22%5D
- response
None
查看 service node
- uri
# 查看所有的service node
GET https://${CONTROLLER_IP}:8443/api/v1/data/controller/applications/bigtap/service
# 根據(jù)service node name查詢
GET https://${CONTROLLER_IP}:8443/api/v1/data/controller/applications/bigtap/service%5Bname%3D%22${SERVICE_NAME}%22%5D
- response
創(chuàng)建 service node PUT的json
policy 的增刪查
創(chuàng)建 policy
- uri
POST https://${CONTROLLER_IP}:8443/api/v1/data/controller/applications/bigtap/policy
- json
[
{
"action" : "forward",
"delivery-group" : [ {
"bigtap-name" : "Delivery"
} ],
"delivery-mode" : "custom",
"duration" : 0,
"expired-delivery-count" : false,
"expired-time" : false,
"filter-group" : [ {
"bigtap-name" : "Filter"
} ],
"filter-mode" : "custom",
"inactive" : false,
"name" : "SSH",
"policy-description" : "SSH policy",
"priority" : 100,
"rule" : [ {
"dst-ip" : "172.16.1.1",
"dst-ip-mask" : "255.255.255.0",
"dst-tp-port-max" : 23,
"dst-tp-port-min" : 22,
"ether-type" : 2048,
"ip-fragment" : true,
"ip-proto" : 6,
"sequence" : 1,
"src-ip" : "172.16.0.1",
"src-ip-mask" : "255.255.255.0",
"src-tp-port-max" : 50025,
"src-tp-port-min" : 50022,
"tcp-flags" : 63,
"tcp-flags-mask" : 63
} ],
"service" : [ {
"name" : "WAF",
"optional" : false,
"sequence" : 1
} ],
"start-time" : "2017-06-02T14:26:00+08:00"
}
]
json的列表長(zhǎng)度、每個(gè)元素的
"name"
该面、"rule"
夭苗、"service"
等字段都可根據(jù)自己需要定義(有一些不必要的字段可以省略,如"start-time"
隔缀、"policy-description"
等)
- response
None
刪除 policy
- uri
DELETE https://${CONTROLLER_IP}:8443/api/v1/data/controller/applications/bigtap/policy%5Bname%3D%22${POLICY_NAME}%22%5D
- response
None
查看 policy
- uri
# 查看全部policy
GET https://${CONTROLLER_IP}:8443/api/v1/data/controller/applications/bigtap/policy
# 根據(jù)policy name查詢
GET https://${CONTROLLER_IP}:8443/api/v1/data/controller/applications/bigtap/policy%5Bname%3D%22${POLICY_NAME}%22%5D
- response
創(chuàng)建 policy PUT的json
Python版本的REST client
import sys
import urllib2
import json
import ssl
# 根據(jù)不同環(huán)境自行修改题造,但PORT是固定的
BIGTAP_CONTROLLER =
PORT = "8443"
USER =
PASSWORD =
def rest_request(url, obj=None, verb="GET", session=None):
headers = {"Content-type": "application/json"}
if session:
headers["Cookie"] = "session_cookie=%s" % session
request = urllib2.Request(url, obj, headers)
request.get_method = lambda: verb
# skip certificate check
context = ssl._create_unverified_context()
response = urllib2.urlopen(request, context=context)
return response.read()
def get_session_cookie():
url_login = "https://%s:%s/api/v1/auth/login" % (BIGTAP_CONTROLLER, PORT)
data = {"password": str(PASSWORD), "user": str(USER)}
output = rest_request(str(url_login), obj=json.dumps(data), verb="POST")
auth_obj = json.loads(output)
# print "Login complete %s" % auth_obj["session_cookie"]
return auth_obj["session_cookie"]
def delete_session(session_cookie=None):
url_delete_session = "https://%s:%s/api/v1/data/controller/core/aaa/session" % (BIGTAP_CONTROLLER, PORT)
rest_response = rest_request(url_delete_session, verb="DELETE", session=session_cookie)
print rest_response
def make_rest_call(rest_uri_path, session_cookie, method, data=None):
# check whether rest_uri_path need quote (DELETE verb)
pos = rest_uri_path.find('[')
if pos != -1:
rest_uri_path = rest_uri_path[:pos] + urllib2.quote(rest_uri_path[pos:])
url = "https://%s:%s/api/v1/data/controller/%s" % (BIGTAP_CONTROLLER, PORT, rest_uri_path)
print "=" * 50
print "Requesting URI:\n%s %s" % (method, url)
if not data:
rest_response = rest_request(url, verb=method, session=session_cookie)
else:
rest_response = rest_request(url, verb=method, obj=json.dumps(data), session=session_cookie)
print "=" * 50
print "Response:\n%s" % rest_response
def usage():
print """
python rest_client.py <rest_uri> <method> [json_file]
<rest_uri> RESTful API request url
<method> POST|GET|PUT|DELETE
NOTICE: If method=POST|PUT, you have to specify json data file
<json_file> json data file path
For example: python rest_client.py 'applications/bigtap/policy' GET
python rest_client.py 'applications/bigtap/policy' POST ssh_policy.json
python rest_client.py 'applications/bigtap/policy[name="SSH"]' DELETE
"""
def main():
if len(sys.argv) >= 3:
rest_uri_path = sys.argv[1]
method = sys.argv[2]
session_cookie = get_session_cookie()
if method == "POST" or method == "PUT":
if len(sys.argv) != 4:
print "ERROR usage! You have specify %s json data" % method
usage()
sys.exit(1)
json_data = json.loads(open(sys.argv[3],"r").read())
make_rest_call(rest_uri_path, session_cookie, method, json_data)
else:
make_rest_call(rest_uri_path, session_cookie, method)
delete_session(session_cookie)
else:
usage()
if __name__ == "__main__":
main()