initial commit for a take on having a restful core api, along with an example scripts leveraging the available API calls

This commit is contained in:
Blake J. Harnden 2018-04-30 16:20:20 -07:00
parent 44781d0aec
commit 7c6c5edf46
5 changed files with 485 additions and 0 deletions

View file

@ -52,6 +52,19 @@ def set_node_map(node_map):
_log_map()
def get_node_type(node_class):
"""
Retrieve the node type given a node class.
:param class node_class: node class to get type for
:return: node type
:rtype: core.enumerations.NodeTypes
"""
global _NODE_MAP
node_type_map = {v: k for k, v in _NODE_MAP.iteritems()}
return node_type_map.get(node_class)
def get_node_class(node_type):
"""
Retrieve the node class for a given node type.

View file

View file

@ -0,0 +1,294 @@
from flask import Flask
from flask import jsonify
from flask import request
from core import logger
from core.enumerations import EventTypes, NodeTypes, LinkTypes
from core.future.coreemu import CoreEmu
from core.future.futuredata import NodeOptions, LinkOptions, InterfaceData
from core.misc import nodeutils
app = Flask(__name__)
coreemu = CoreEmu()
def link_data_str(link, key):
value = link.get(key)
if value:
link[key] = str(value)
@app.route("/sessions")
def get_sessions():
sessions = []
for session in coreemu.sessions.itervalues():
sessions.append({
"id": session.session_id,
"nodes": session.get_node_count()
})
return jsonify(sessions=sessions)
@app.route("/sessions", methods=["POST"])
def create_session():
session = coreemu.create_session()
session.set_state(EventTypes.CONFIGURATION_STATE)
response_data = jsonify(
id=session.session_id,
url="/sessions/%s" % session.session_id
)
return response_data, 201
@app.route("/sessions/<int:session_id>", methods=["DELETE"])
def delete_session(session_id):
result = coreemu.delete_session(session_id)
if result:
return jsonify()
else:
return jsonify(error="session does not exist"), 404
@app.route("/sessions/<int:session_id>")
def get_session(session_id):
session = coreemu.sessions.get(session_id)
if not session:
return jsonify(error="session does not exist"), 404
nodes = []
for node in session.objects.itervalues():
nodes.append({
"id": node.objid,
"name": node.name,
"type": nodeutils.get_node_type(node.__class__).value,
"position": {
"x": node.position.x,
"y": node.position.y,
"z": node.position.z
},
"url": "/sessions/%s/nodes/%s" % (session_id, node.objid)
})
state = EventTypes(session.state)
return jsonify(
state=state.name,
nodes=nodes
)
@app.route("/sessions/<int:session_id>/nodes", methods=["POST"])
def create_node(session_id):
session = coreemu.sessions.get(session_id)
if not session:
return jsonify(error="session does not exist"), 404
data = request.get_json() or {}
node_type = data.get("type", NodeTypes.DEFAULT.value)
node_type = NodeTypes(node_type)
logger.info("creating node: %s - %s", node_type.name, data)
node_options = NodeOptions(
name=data.get("name"),
model=data.get("model")
)
node_options.icon = data.get("icon")
node_options.opaque = data.get("opaque")
node_options.set_position(data.get("x"), data.get("y"))
node_options.set_location(data.get("lat"), data.get("lon"), data.get("alt"))
node = session.add_node(_type=node_type, node_options=node_options)
return jsonify(
id=node.objid,
url="/sessions/%s/nodes/%s" % (session_id, node.objid)
), 201
@app.route("/sessions/<int:session_id>/nodes/<node_id>")
def get_node(session_id, node_id):
session = coreemu.sessions.get(session_id)
if not session:
return jsonify(error="session does not exist"), 404
if node_id.isdigit():
node_id = int(node_id)
node = session.objects.get(node_id)
if not node:
return jsonify(error="node does not exist"), 404
interfaces = []
for interface_id, interface in node._netif.iteritems():
net_id = None
if interface.net:
net_id = interface.net.objid
interfaces.append({
"id": interface_id,
"netid": net_id,
"name": interface.name,
"mac": str(interface.hwaddr),
"mtu": interface.mtu,
"flowid": interface.flow_id
})
return jsonify(
name=node.name,
type=nodeutils.get_node_type(node.__class__).value,
model=node.type,
interfaces=interfaces,
linksurl="/sessions/%s/nodes/%s/links" % (session_id, node.objid)
)
@app.route("/sessions/<int:session_id>/nodes/<node_id>", methods=["DELETE"])
def delete_node(session_id, node_id):
session = coreemu.sessions.get(session_id)
if not session:
return jsonify(error="session does not exist"), 404
if node_id.isdigit():
node_id = int(node_id)
node = session.objects.get(node_id)
if not node:
return jsonify(error="node does not exist"), 404
result = session.delete_node(node_id)
if result:
return jsonify()
else:
return jsonify(error="failure to delete node"), 404
@app.route("/sessions/<int:session_id>/state", methods=["PUT"])
def set_session_state(session_id):
session = coreemu.sessions.get(session_id)
if not session:
return jsonify(error="session does not exist"), 404
data = request.get_json()
try:
state = EventTypes(data["state"])
session.set_state(state)
if state == EventTypes.INSTANTIATION_STATE:
session.instantiate()
elif state == EventTypes.SHUTDOWN_STATE:
session.shutdown()
elif state == EventTypes.DATACOLLECT_STATE:
session.data_collect()
elif state == EventTypes.DEFINITION_STATE:
session.clear()
return jsonify()
except KeyError:
return jsonify(error="invalid state"), 404
@app.route("/sessions/<int:session_id>/links", methods=["POST"])
def add_link(session_id):
session = coreemu.sessions.get(session_id)
if not session:
return jsonify(error="session does not exist"), 404
data = request.get_json()
node_one = data.get("node_one")
node_two = data.get("node_two")
interface_one = None
interface_one_data = data.get("interface_one")
if interface_one_data:
interface_one = InterfaceData(
_id=interface_one_data.get("id"),
name=interface_one_data.get("name"),
mac=interface_one_data.get("mac"),
ip4=interface_one_data.get("ip4"),
ip4_mask=interface_one_data.get("ip4mask"),
ip6=interface_one_data.get("ip6"),
ip6_mask=interface_one_data.get("ip6mask"),
)
interface_two = None
interface_two_data = data.get("interface_two")
if interface_two_data:
interface_two = InterfaceData(
_id=interface_two_data.get("id"),
name=interface_two_data.get("name"),
mac=interface_two_data.get("mac"),
ip4=interface_two_data.get("ip4"),
ip4_mask=interface_two_data.get("ip4mask"),
ip6=interface_two_data.get("ip6"),
ip6_mask=interface_two_data.get("ip6mask"),
)
link_type = None
link_type_value = data.get("type")
if link_type_value is not None:
link_type = LinkTypes(link_type_value)
options_data = data.get("options")
link_options = LinkOptions(_type=link_type)
if options_data:
link_options.delay = options_data.get("delay")
link_options.bandwidth = options_data.get("bandwidth")
link_options.session = options_data.get("session")
link_options.per = options_data.get("per")
link_options.dup = options_data.get("dup")
link_options.jitter = options_data.get("jitter")
link_options.mer = options_data.get("mer")
link_options.burst = options_data.get("burst")
link_options.mburst = options_data.get("mburst")
link_options.unidirectional = options_data.get("unidirectional")
link_options.key = options_data.get("key")
link_options.opaque = options_data.get("opaque")
link_options = LinkOptions()
session.add_link(node_one, node_two, interface_one, interface_two, link_options=link_options)
return jsonify(), 201
@app.route("/sessions/<int:session_id>/links", methods=["DELETE"])
def delete_link(session_id):
session = coreemu.sessions.get(session_id)
if not session:
return jsonify(error="session does not exist"), 404
data = request.get_json()
node_one = data.get("node_one")
node_two = data.get("node_two")
interface_one = data.get("interface_one")
interface_two = data.get("interface_two")
session.delete_link(node_one, node_two, interface_one, interface_two)
return jsonify()
@app.route("/sessions/<int:session_id>/nodes/<node_id>/links")
def get_node_links(session_id, node_id):
session = coreemu.sessions.get(session_id)
if not session:
return jsonify(error="session does not exist"), 404
if node_id.isdigit():
node_id = int(node_id)
node = session.objects.get(node_id)
if not node:
return jsonify(error="node does not exist"), 404
links_data = node.all_link_data(0)
links = []
for link_data in links_data:
link = link_data._asdict()
del link["message_type"]
link_data_str(link, "interface1_ip4")
link_data_str(link, "interface1_ip6")
link_data_str(link, "interface1_mac")
link_data_str(link, "interface2_ip4")
link_data_str(link, "interface2_ip6")
link_data_str(link, "interface2_mac")
links.append(link)
return jsonify(links=links)
def start():
app.run(host="0.0.0.0")

View file

@ -0,0 +1,172 @@
import pprint
import sys
import time
import requests
class CoreRestClient(object):
def __init__(self, address):
self.base_url = "http://%s" % address
def _create_url(self, path):
return "%s%s" % (self.base_url, path)
def _delete(self, path, json_data=None):
url = self._create_url(path)
print "DELETE: %s" % url
response = requests.delete(url, json=json_data)
response_json = response.json()
pprint.pprint(response_json)
return response_json
def _post(self, path, json_data=None):
url = self._create_url(path)
print "POST: %s" % url
response = requests.post(url, json=json_data)
response_json = response.json()
pprint.pprint(response_json)
return response_json
def _put(self, path, json_data=None):
url = self._create_url(path)
print "PUT: %s" % url
response = requests.put(url, json=json_data)
response_json = response.json()
pprint.pprint(response_json)
return response_json
def _get(self, path):
url = self._create_url(path)
print "GET: %s" % url
response = requests.get(url)
response_json = response.json()
pprint.pprint(response_json)
return response_json
def create_session(self):
return self._post("/sessions")
def get_sessions(self):
return self._get("/sessions")
def get_session(self, session_id):
return self._get("/sessions/%s" % session_id)
def delete_session(self, session_id):
return self._delete("/sessions/%s" % session_id)
def set_state(self, session_id, state):
return self._put("/sessions/%s/state" % session_id, json_data={"state": state})
def add_node(self, session_id, options=None):
return self._post("/sessions/%s/nodes" % session_id, json_data=options)
def delete_node(self, session_id, node_id):
return self._delete("/sessions/%s/nodes/%s" % (session_id, node_id))
def get_node(self, session_id, node_id):
return self._get("/sessions/%s/nodes/%s" % (session_id, node_id))
def get_node_links(self, session_id, node_id):
return self._get("/sessions/%s/nodes/%s/links" % (session_id, node_id))
def add_link(self, session_id, link):
return self._post("/sessions/%s/links" % session_id, json_data=link)
def delete_link(self, session_id, link):
return self._delete("/sessions/%s/links" % session_id, json_data=link)
def main():
address = sys.argv[1]
client = CoreRestClient(address)
# create session
create_response = client.create_session()
session_id = create_response["id"]
# query all sessions
client.get_sessions()
# query session
client.get_session(session_id)
# set state to CONFIGURATION
client.set_state(session_id, 2)
# create nodes for small switch networkW
node_one_response = client.add_node(session_id)
node_one_id = node_one_response["id"]
node_two_response = client.add_node(session_id)
node_two_id = node_two_response["id"]
switch_options = {
"type": 4
}
switch_node_response = client.add_node(session_id, switch_options)
switch_id = switch_node_response["id"]
# link nodes to switch
link = {
"node_one": node_one_id,
"node_two": switch_id,
"interface_one": {
"id": 0,
"ip4": "10.0.0.2",
"ip4mask": 16
}
}
client.add_link(session_id, link)
link = {
"node_one": node_two_id,
"node_two": switch_id,
"interface_one": {
"id": 0,
"ip4": "10.0.0.3",
"ip4mask": 16
}
}
client.add_link(session_id, link)
# set state to INSTANTIATION
client.set_state(session_id, 3)
time.sleep(3)
# get node information
client.get_node(session_id, node_one_id)
client.get_node(session_id, node_two_id)
client.get_node(session_id, switch_id)
# get links informations
client.get_node_links(session_id, node_one_id)
client.get_node_links(session_id, node_two_id)
client.get_node_links(session_id, switch_id)
# delete links
delete_link = {
"node_one": node_one_id,
"node_two": switch_id,
"interface_one": 0,
}
client.delete_link(session_id, delete_link)
delete_link = {
"node_one": node_two_id,
"node_two": switch_id,
"interface_one": 0
}
client.delete_link(session_id, delete_link)
# delete nodes
client.delete_node(session_id, node_one_id)
client.delete_node(session_id, node_two_id)
client.delete_node(session_id, switch_id)
# delete session
client.delete_session(session_id)
# query all sessions
client.get_sessions()
if __name__ == "__main__":
main()

6
daemon/scripts/core-rest Normal file
View file

@ -0,0 +1,6 @@
#!/usr/bin/env python
from core.rest import corerest
if __name__ == "__main__":
corerest.start()