美文网首页
BMF RESTful API总结

BMF RESTful API总结

作者: 分享放大价值 | 来源:发表于2017-06-08 10:42 被阅读60次

    导读

    • 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实现REST请求。因为文档有错误,所以只纠正这些错误的地方。

    《BMF-6.0.1-REST-API-Guide-2017.04.19》文档已经修正了这些错误

    1. BMF Controller需要开启REST端口

    文档上是这么写的:

    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 the help firewall command, or refer to the firewall command section in the ...

    这里面有两个错误:

    • 8082端口就不是REST端口,而是8443
    • 根本没有firewall这个命令

    解决办法:
    在BMF Controller进行如下操作

    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有错误

    开启了REST端口,还需要修改auth URL。
    文档里面的是:http://${CONTROLLER_IP}:8082/auth/login
    实际应该是:https://${CONTROLLER_IP}:8443/api/v1/auth/login

    把上面两个问题解决后再看文档可知,在发送REST请求之前,先要登陆拿到sesson_cookie,然后再发送请求。这个过程可以通过curl来完成(具体见文档),也可以用Python来完成。我很懒,懒得每次都敲一长串的curl命令。所以基于Sample code做了一些修改,用来做REST client。源码见最后。

    interface role 的增删查

    这里主要列一下创建、查看以及修改interface role设计到的REST URL

    创建 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的列表长度、每个元素的"name""bigtap-name"都可以根据自己需要定义

    • 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
    

    这个uri有必要多说一下,文档的Chapter 1 Page 14 BigDB REST API YANG Extensions小节提到,BMF使用REST API完成查询操作时使用了YANG模型,,REST API的请求是由prefixXPATH组成。原文如下:

    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.

    示例图

    再来看上面的uri,它在创建interface role的uri后面拼接了[key=value]部分。我们知道,URL中是不允许出现类似空格、等号、双引号等字符的,因此这个uri需要经过转码。编码之后便成了这个样子:%5Bname%3D%22${INTERFACE_NAME}%22%5D(其中,双引号必不可少)。

    • responese
      None
    查询 interface role
    • uri
    # 查询所有的interface role
    GET https://${CONTROLLER_IP}:8443/api/v1/data/controller/core/switch-config/interface
    # 根据interface name查询
    GET https://${CONTROLLER_IP}:8443/api/v1/data/controller/core/switch-config/interface%5Bname%3D%22${INTERFACE_NAME}%22%5D
    
    • response
      创建 interface role PUT的json

    lag 的增删查

    创建 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
    # 根据lag interface name查询
    https://${CONTROLLER_IP}:8443/api/v1/data/controller/core/switch-config/lag-interface%5Bname%3D%22${LAG_NAME}%22%5D
    
    • response
      创建 lag interface PUT的json

    service node 的增删查

    创建 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的列表长度、每个元素的"name""post-group""pre-group"根据自己需要定义

    • 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
    # 根据service node name查询
    GET https://${CONTROLLER_IP}:8443/api/v1/data/controller/applications/bigtap/service%5Bname%3D%22${SERVICE_NAME}%22%5D
    
    • response
      创建 service node PUT的json

    policy 的增删查

    创建 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的列表长度、每个元素的"name""rule""service"等字段都可根据自己需要定义(有一些不必要的字段可以省略,如"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
    # 根据policy name查询
    GET https://${CONTROLLER_IP}:8443/api/v1/data/controller/applications/bigtap/policy%5Bname%3D%22${POLICY_NAME}%22%5D
    
    • response
      创建 policy PUT的json

    Python版本的REST client

    import sys
    import urllib2
    import json
    import ssl
    
    
    # 根据不同环境自行修改,但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()
    

    相关文章

      网友评论

          本文标题:BMF RESTful API总结

          本文链接:https://www.haomeiwen.com/subject/glyafxtx.html