From dc75170d734debbe8a5de88cc71b52c3e53fd45e Mon Sep 17 00:00:00 2001 From: mbuil Date: Tue, 10 Nov 2015 13:43:09 +0100 Subject: Moves the VnfManagerSimulator code to one specific folder so it is not in the root of the OPNFV SFC repository Change-Id: I7e5003a69e3514f6b0bf0968758aec167fc052a4 --- INFO | 21 - LICENSE | 13 - NAME/__init__.py | 0 README | 1 - VnfMgrSim/INFO | 21 + VnfMgrSim/LICENSE | 13 + VnfMgrSim/NAME/__init__.py | 0 VnfMgrSim/README | 1 + VnfMgrSim/setup.py | 23 ++ VnfMgrSim/tests/NAME_tests.py | 11 + VnfMgrSim/tests/__init__.py | 0 VnfMgrSim/vnfmgr/vnfmgr_main.py | 72 ++++ VnfMgrSim/vnfmgr/vnfmgr_odl/__init__.py | 0 .../sample_config/RestConf-RSP-HttpPost.json | 7 + .../sample_config/RestConf-SFCs-HttpPut.json | 22 ++ .../sample_config/RestConf-SFFs-HttpPut.json | 75 ++++ .../sample_config/RestConf-SFPs-HttpPut.json | 12 + .../sample_config/RestConf-SFs-HttpPut.json | 38 ++ VnfMgrSim/vnfmgr/vnfmgr_odl/vnfmgr_odl.py | 440 +++++++++++++++++++++ VnfMgrSim/vnfmgr/vnfmgr_os/__init__.py | 0 VnfMgrSim/vnfmgr/vnfmgr_os/vnfmgr_os.py | 68 ++++ setup.py | 23 -- tests/NAME_tests.py | 11 - tests/__init__.py | 0 vnfmgr/vnfmgr_main.py | 72 ---- vnfmgr/vnfmgr_odl/__init__.py | 0 .../sample_config/RestConf-RSP-HttpPost.json | 7 - .../sample_config/RestConf-SFCs-HttpPut.json | 22 -- .../sample_config/RestConf-SFFs-HttpPut.json | 75 ---- .../sample_config/RestConf-SFPs-HttpPut.json | 12 - .../sample_config/RestConf-SFs-HttpPut.json | 38 -- vnfmgr/vnfmgr_odl/vnfmgr_odl.py | 440 --------------------- vnfmgr/vnfmgr_os/__init__.py | 0 vnfmgr/vnfmgr_os/vnfmgr_os.py | 68 ---- 34 files changed, 803 insertions(+), 803 deletions(-) delete mode 100644 INFO delete mode 100644 LICENSE delete mode 100644 NAME/__init__.py delete mode 100644 README create mode 100644 VnfMgrSim/INFO create mode 100644 VnfMgrSim/LICENSE create mode 100644 VnfMgrSim/NAME/__init__.py create mode 100644 VnfMgrSim/README create mode 100644 VnfMgrSim/setup.py create mode 100644 VnfMgrSim/tests/NAME_tests.py create mode 100644 VnfMgrSim/tests/__init__.py create mode 100755 VnfMgrSim/vnfmgr/vnfmgr_main.py create mode 100644 VnfMgrSim/vnfmgr/vnfmgr_odl/__init__.py create mode 100755 VnfMgrSim/vnfmgr/vnfmgr_odl/sample_config/RestConf-RSP-HttpPost.json create mode 100755 VnfMgrSim/vnfmgr/vnfmgr_odl/sample_config/RestConf-SFCs-HttpPut.json create mode 100755 VnfMgrSim/vnfmgr/vnfmgr_odl/sample_config/RestConf-SFFs-HttpPut.json create mode 100755 VnfMgrSim/vnfmgr/vnfmgr_odl/sample_config/RestConf-SFPs-HttpPut.json create mode 100755 VnfMgrSim/vnfmgr/vnfmgr_odl/sample_config/RestConf-SFs-HttpPut.json create mode 100755 VnfMgrSim/vnfmgr/vnfmgr_odl/vnfmgr_odl.py create mode 100644 VnfMgrSim/vnfmgr/vnfmgr_os/__init__.py create mode 100755 VnfMgrSim/vnfmgr/vnfmgr_os/vnfmgr_os.py delete mode 100644 setup.py delete mode 100644 tests/NAME_tests.py delete mode 100644 tests/__init__.py delete mode 100755 vnfmgr/vnfmgr_main.py delete mode 100644 vnfmgr/vnfmgr_odl/__init__.py delete mode 100755 vnfmgr/vnfmgr_odl/sample_config/RestConf-RSP-HttpPost.json delete mode 100755 vnfmgr/vnfmgr_odl/sample_config/RestConf-SFCs-HttpPut.json delete mode 100755 vnfmgr/vnfmgr_odl/sample_config/RestConf-SFFs-HttpPut.json delete mode 100755 vnfmgr/vnfmgr_odl/sample_config/RestConf-SFPs-HttpPut.json delete mode 100755 vnfmgr/vnfmgr_odl/sample_config/RestConf-SFs-HttpPut.json delete mode 100755 vnfmgr/vnfmgr_odl/vnfmgr_odl.py delete mode 100644 vnfmgr/vnfmgr_os/__init__.py delete mode 100755 vnfmgr/vnfmgr_os/vnfmgr_os.py diff --git a/INFO b/INFO deleted file mode 100644 index 76298d34..00000000 --- a/INFO +++ /dev/null @@ -1,21 +0,0 @@ -Project: Service Function Chaining (sfc) -Project Creation Date: May 5, 2015 -Project Category: Collaborative Development -Lifecycle State: Incubation -Primary Contact: Brady Johnson (brady.allen.johnson@ericsson.com) -Project Lead: Brady Johnson (brady.allen.johnson@ericsson.com) -Jira Name: Service Function Chaining -Jira Prefix: sfc -Mailing list tag: [sfc] -IRC: #opnfv-sfc -repository: sfc - -Committers: -brady.allen.johnson@ericsson.com -rapenno@gmail.com -paulq@cisco.com -jguichar@cisco.com -shague@redhat.com -tnadeau@Brocade.com -vmurgai@cavium.com -kkoushik@brocade.com diff --git a/LICENSE b/LICENSE deleted file mode 100644 index eab09245..00000000 --- a/LICENSE +++ /dev/null @@ -1,13 +0,0 @@ -Copyright 2015 Open Platform for NFV Project, Inc. and its contributors - - 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. diff --git a/NAME/__init__.py b/NAME/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/README b/README deleted file mode 100644 index 04d252a4..00000000 --- a/README +++ /dev/null @@ -1 +0,0 @@ -This code deploys the ODL-Openstack maanger. diff --git a/VnfMgrSim/INFO b/VnfMgrSim/INFO new file mode 100644 index 00000000..76298d34 --- /dev/null +++ b/VnfMgrSim/INFO @@ -0,0 +1,21 @@ +Project: Service Function Chaining (sfc) +Project Creation Date: May 5, 2015 +Project Category: Collaborative Development +Lifecycle State: Incubation +Primary Contact: Brady Johnson (brady.allen.johnson@ericsson.com) +Project Lead: Brady Johnson (brady.allen.johnson@ericsson.com) +Jira Name: Service Function Chaining +Jira Prefix: sfc +Mailing list tag: [sfc] +IRC: #opnfv-sfc +repository: sfc + +Committers: +brady.allen.johnson@ericsson.com +rapenno@gmail.com +paulq@cisco.com +jguichar@cisco.com +shague@redhat.com +tnadeau@Brocade.com +vmurgai@cavium.com +kkoushik@brocade.com diff --git a/VnfMgrSim/LICENSE b/VnfMgrSim/LICENSE new file mode 100644 index 00000000..eab09245 --- /dev/null +++ b/VnfMgrSim/LICENSE @@ -0,0 +1,13 @@ +Copyright 2015 Open Platform for NFV Project, Inc. and its contributors + + 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. diff --git a/VnfMgrSim/NAME/__init__.py b/VnfMgrSim/NAME/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/VnfMgrSim/README b/VnfMgrSim/README new file mode 100644 index 00000000..04d252a4 --- /dev/null +++ b/VnfMgrSim/README @@ -0,0 +1 @@ +This code deploys the ODL-Openstack maanger. diff --git a/VnfMgrSim/setup.py b/VnfMgrSim/setup.py new file mode 100644 index 00000000..9ff16995 --- /dev/null +++ b/VnfMgrSim/setup.py @@ -0,0 +1,23 @@ +import os +from setuptools import setup + +# Utility function to read the README file. +# Used for the long_description. It's nice, because now 1) we have a top level +# README file and 2) it's easier to type in the README file than to put a raw +# string in below ... +def read(fname): + return open(os.path.join(os.path.dirname(__file__), fname)).read() + +setup( + name = "vnf manager simulator", + version = "1.0", + author = "Manuel Buil, Brady A. Johnson", + author_email = "manuel.buil@ericsson.com, brady.allen.johnson@ericsson.com", + description = ("A script which simulates an orchestrator"), + license = "Apache License Version 2.0", + keywords = "example documentation tutorial", + url = "https://gerrit.opnfv.org/gerrit/#/c/2519", + packages = [".."], + scripts = [".."], + long_description=read('README'), +) diff --git a/VnfMgrSim/tests/NAME_tests.py b/VnfMgrSim/tests/NAME_tests.py new file mode 100644 index 00000000..9f83104c --- /dev/null +++ b/VnfMgrSim/tests/NAME_tests.py @@ -0,0 +1,11 @@ +from nose.tools import * +import NAME + +def setup(): + print "SETUP!" + +def teardown(): + print "TEAR DOWN!" + +def test_basic(): + print "I RAN!" diff --git a/VnfMgrSim/tests/__init__.py b/VnfMgrSim/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/VnfMgrSim/vnfmgr/vnfmgr_main.py b/VnfMgrSim/vnfmgr/vnfmgr_main.py new file mode 100755 index 00000000..b5ab8be1 --- /dev/null +++ b/VnfMgrSim/vnfmgr/vnfmgr_main.py @@ -0,0 +1,72 @@ +################################################################# +# # +# Copyright 2015 Ericsson AB # +# All Rights Reserved # +# # +# Author: Manuel Buil # +# Version: 0.1 # +# # +################################################################# + +import pdb +from vnfmgr_os.vnfmgr_os import OpenStack_API +import vnfmgr_odl.vnfmgr_odl as odlscript +import time +import json + +if __name__ == "__main__": + #OpenStack environment information + authurl = "http://localhost:5000/v2.0" + adminTenantName = 'admin' + adminTenantUser = 'admin' + adminTenantPass = 'abc123' + tenantName = adminTenantName + tenantUser = adminTenantUser + tenantPass = adminTenantPass + + openstack = OpenStack_API(authurl, tenantName, tenantUser, tenantPass) + + # 1 - Get the SF type + # Provide the file with the SFC configuration + file_json = "vnfmgr_odl/sample_config/RestConf-SFCs-HttpPut.json" + # Read the config files which refer to SF + json_data=open(file_json).read() + data = json.loads(json_data) + pdb.set_trace() + + # Grab the SF type + chains = data['service-function-chains']['service-function-chain'] + for chain in chains: + SFs = chain['sfc-service-function'] + for SF in SFs: + sf_type = SF['type'] + name = SF['name'] + #2 - Search the image in glance with that SF type + image = openstack.find_image(sf_type) + if image == None: + print("There is no image with that sf_name") + exit(1) + # 3 - Boot the VM without network + flavor = 1 + print("About to deploy") + vm = openstack.create_vm(name,image,flavor) + if vm == None: + print("Problems to deploy the VM") + exit(1) + + #Make the call to ODL to deploy SFC + context = odlscript.Context() + context.set_path_prefix_paths("vnfmgr_odl/sample_config") + pdb.set_trace() + odlscript.send_rest(context, "PUT", context.rest_url_sf_sel, context.rest_path_sf_sel) + odlscript.send_rest(context, "PUT", context.rest_url_sf, context.rest_path_sf) + odlscript.send_rest(context, "PUT", context.rest_url_sff, context.rest_path_sff) + odlscript.send_rest(context, "PUT", context.rest_url_sfc, context.rest_path_sfc) + odlscript.send_rest(context, "PUT", context.rest_url_sfp, context.rest_path_sfp) + time.sleep(1); + odlscript.send_rest(context, "POST", context.rest_url_rsp_rpc, context.rest_path_rsp) + + + #TO DO + # Check if the SF_VM already exists before creating it + # Network of the VM diff --git a/VnfMgrSim/vnfmgr/vnfmgr_odl/__init__.py b/VnfMgrSim/vnfmgr/vnfmgr_odl/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/VnfMgrSim/vnfmgr/vnfmgr_odl/sample_config/RestConf-RSP-HttpPost.json b/VnfMgrSim/vnfmgr/vnfmgr_odl/sample_config/RestConf-RSP-HttpPost.json new file mode 100755 index 00000000..998d1e07 --- /dev/null +++ b/VnfMgrSim/vnfmgr/vnfmgr_odl/sample_config/RestConf-RSP-HttpPost.json @@ -0,0 +1,7 @@ +{ + "input": { + "name": "sfc-path-1", + "parent-service-function-path": "sfc-path-1", + "symmetric": true + } +} diff --git a/VnfMgrSim/vnfmgr/vnfmgr_odl/sample_config/RestConf-SFCs-HttpPut.json b/VnfMgrSim/vnfmgr/vnfmgr_odl/sample_config/RestConf-SFCs-HttpPut.json new file mode 100755 index 00000000..34449647 --- /dev/null +++ b/VnfMgrSim/vnfmgr/vnfmgr_odl/sample_config/RestConf-SFCs-HttpPut.json @@ -0,0 +1,22 @@ +{ + "service-function-chains": { + "service-function-chain": [ + { + "name": "sfc-chain-1", + "symmetric": true, + "sfc-service-function": [ + { + "name": "firewall-abstract1", + "type": "service-function-type:firewall" + }, + { + "name": "firewall-abstract2", + "type": "service-function-type:firewall" + } + ] + } + + ] + } +} + diff --git a/VnfMgrSim/vnfmgr/vnfmgr_odl/sample_config/RestConf-SFFs-HttpPut.json b/VnfMgrSim/vnfmgr/vnfmgr_odl/sample_config/RestConf-SFFs-HttpPut.json new file mode 100755 index 00000000..191fd540 --- /dev/null +++ b/VnfMgrSim/vnfmgr/vnfmgr_odl/sample_config/RestConf-SFFs-HttpPut.json @@ -0,0 +1,75 @@ +{ + "service-function-forwarders": { + "service-function-forwarder": [ + { + "name": "SFF2", + "sff-data-plane-locator": [ + { + "name": "sff2-dp1", + "service-function-forwarder-ovs:ovs-bridge": {}, + "data-plane-locator": { + "transport": "service-locator:vxlan-gpe", + "port": 6633, + "ip": "192.168.1.100" + }, + "service-function-forwarder-ovs:ovs-options": { + "nshc1": "flow", + "nsp": "flow", + "key": "flow", + "remote-ip": "flow", + "nsi": "flow", + "nshc2": "flow", + "nshc3": "flow", + "dst-port": "6633", + "nshc4": "flow" + } + } + ], + "service-function-forwarder-ovs:ovs-bridge": { + "bridge-name": "ovs-br2" + }, + "service-function-dictionary": [ + { + "name": "firewall-2", + "type": "service-function-type:firewall", + "sff-sf-data-plane-locator": { + "service-function-forwarder-ovs:ovs-bridge": {}, + "transport": "service-locator:vxlan-gpe", + "port": 6633, + "ip": "192.168.1.11" + } + }, + { + "name": "firewall-3", + "type": "service-function-type:firewall", + "sff-sf-data-plane-locator": { + "service-function-forwarder-ovs:ovs-bridge": {}, + "transport": "service-locator:vxlan-gpe", + "port": 6633, + "ip": "192.168.1.12" + } + } + ], + "ip-mgmt-address": "192.168.1.100", + "service-node": "" + }, + { + "name": "SFF-CL", + "sff-data-plane-locator": [ + { + "name": "ovs-br1", + "service-function-forwarder-ovs:ovs-bridge": {}, + "data-plane-locator": { + "transport": "service-locator:vxlan-gpe", + "port": 30001, + "ip": "192.168.1.50" + } + } + ], + "rest-uri": "http://192.168.1.50:5000", + "ip-mgmt-address": "192.168.1.50", + "service-node": "" + } + ] + } +} diff --git a/VnfMgrSim/vnfmgr/vnfmgr_odl/sample_config/RestConf-SFPs-HttpPut.json b/VnfMgrSim/vnfmgr/vnfmgr_odl/sample_config/RestConf-SFPs-HttpPut.json new file mode 100755 index 00000000..da1f2c45 --- /dev/null +++ b/VnfMgrSim/vnfmgr/vnfmgr_odl/sample_config/RestConf-SFPs-HttpPut.json @@ -0,0 +1,12 @@ +{ + "service-function-paths": { + "service-function-path": [ + { + "name": "sfc-path-1", + "service-chain-name": "sfc-chain-1", + "transport-type": "service-locator:vxlan-gpe", + "symmetric": true + } + ] + } +} diff --git a/VnfMgrSim/vnfmgr/vnfmgr_odl/sample_config/RestConf-SFs-HttpPut.json b/VnfMgrSim/vnfmgr/vnfmgr_odl/sample_config/RestConf-SFs-HttpPut.json new file mode 100755 index 00000000..1ea27e79 --- /dev/null +++ b/VnfMgrSim/vnfmgr/vnfmgr_odl/sample_config/RestConf-SFs-HttpPut.json @@ -0,0 +1,38 @@ +{ + "service-functions": { + "service-function": [ + { + "name": "firewall-2", + "sf-data-plane-locator": [ + { + "name": "firewall-2-dp1", + "ip": "192.168.1.11", + "port": 6633, + "transport": "service-locator:vxlan-gpe", + "service-function-forwarder": "SFF2" + } + ], + "rest-uri": "http://192.168.1.11:5000", + "nsh-aware": true, + "ip-mgmt-address": "192.168.1.11", + "type": "service-function-type:firewall" + }, + { + "name": "firewall-3", + "sf-data-plane-locator": [ + { + "name": "firewall-3-dp1", + "ip": "192.168.1.12", + "port": 6633, + "transport": "service-locator:vxlan-gpe", + "service-function-forwarder": "SFF2" + } + ], + "rest-uri": "http://192.168.1.12:5000", + "nsh-aware": true, + "ip-mgmt-address": "192.168.1.12", + "type": "service-function-type:firewall" + } + ] + } +} diff --git a/VnfMgrSim/vnfmgr/vnfmgr_odl/vnfmgr_odl.py b/VnfMgrSim/vnfmgr/vnfmgr_odl/vnfmgr_odl.py new file mode 100755 index 00000000..4d35aebb --- /dev/null +++ b/VnfMgrSim/vnfmgr/vnfmgr_odl/vnfmgr_odl.py @@ -0,0 +1,440 @@ +#! /usr/bin/env python + +__author__ = "Brady Johnson" +__copyright__ = "Copyright(c) 2015, Ericsson, Inc." +__license__ = "Apache License version 2.0" +__version__ = "0.1" +__email__ = "brady.allen.johnson@ericsson.com" +__status__ = "beta" +import pdb +import os +import time +import requests +import json +import argparse + +PUT = 'PUT' +GET = 'GET' +POST = 'POST' + +class Context(object): + """ + Context class to hold the configuration as specified on the command line + """ + def __init__(self): + self.rest_path_prefix = 'sampleConfig' + self.rest_path_sf = 'RestConf-SFs-HttpPut.json' + self.rest_path_sf_sel = 'RestConf-SFselect-HttpPut.json' + self.rest_path_sfc = 'RestConf-SFCs-HttpPut.json' + self.rest_path_sff = 'RestConf-SFFs-HttpPut.json' + self.rest_path_sfp = 'RestConf-SFPs-HttpPut.json' + self.rest_path_acl = 'RestConf-ACLs-HttpPut.json' + self.rest_path_rsp = 'RestConf-RSP-HttpPost.json' + + self.rest_url_sf = 'config/service-function:service-functions/' + self.rest_url_sf_sel = 'config/service-function-scheduler-type:service-function-scheduler-types/' + self.rest_url_sfc = 'config/service-function-chain:service-function-chains/' + self.rest_url_sff = 'config/service-function-forwarder:service-function-forwarders/' + self.rest_url_sfp = 'config/service-function-path:service-function-paths/' + self.rest_url_rsp = 'operational/rendered-service-path:rendered-service-paths/' + self.rest_url_rsp_rpc = 'operations/rendered-service-path:create-rendered-path' + self.rest_url_acl = 'config/ietf-acl:access-lists/' + + self.http_headers = {'Content-Type' : 'application/json', 'Cache-Control' : 'no-cache'} + self.http_server = 'localhost' + self.url_base = '' + self.http_port = '8181' + self.interractive = True + self.user = 'admin' + self.pw = 'admin' + self.batch_sf = False + self.batch_sf_sel = False + self.batch_sfc = False + self.batch_sff = False + self.batch_sfp = False + self.batch_acl = False + self.batch_rsp = False + self.batch_query = False + + def set_path_prefix_paths(self, path_prefix): + self.rest_path_prefix = path_prefix + self.rest_path_sf = os.path.join(self.rest_path_prefix, self.rest_path_sf) + self.rest_path_sf_sel = os.path.join(self.rest_path_prefix, self.rest_path_sf_sel) + self.rest_path_sfc = os.path.join(self.rest_path_prefix, self.rest_path_sfc) + self.rest_path_sff = os.path.join(self.rest_path_prefix, self.rest_path_sff) + self.rest_path_sfp = os.path.join(self.rest_path_prefix, self.rest_path_sfp) + self.rest_path_acl = os.path.join(self.rest_path_prefix, self.rest_path_acl) + self.rest_path_rsp = os.path.join(self.rest_path_prefix, self.rest_path_rsp) + + +def get_cmd_line(context): + """ + Create a command-line parser, parse the command line args, and process them. + Populate the Context object with the processed command-line args. + """ + + opts = argparse.ArgumentParser() + + # Batch or Interractive mode + opts.add_argument('--interractive', '-i', + dest='interractive', + action='store_true', + help='Interractive mode, default') + opts.add_argument('--batch', '-b', + dest='batch', + action='store_true', + help='Batch mode, overrides interractive mode') + + # Where to send the messages + opts.add_argument('--http-server', '-s', + default=context.http_server, + dest='http_server', + help='HTTP server address') + opts.add_argument('--http-port', + default=context.http_port, + dest='http_port', + help='HTTP server port') + + # Batch mode, which message(s) to send + opts.add_argument('--send-sf', '-1', + dest='send_sf', + action='store_true', + help='Send an SF REST JSON PUT message') + opts.add_argument('--send-sf-sel', + dest='send_sf_sel', + action='store_true', + help='Send an SF Selection REST JSON PUT message') + opts.add_argument('--send-sfc', '-2', + dest='send_sfc', + action='store_true', + help='Send an SFC REST JSON PUT message') + opts.add_argument('--send-sff', '-3', + dest='send_sff', + action='store_true', + help='Send an SFF REST JSON PUT message') + opts.add_argument('--send-sfp', '-4', + dest='send_sfp', + action='store_true', + help='Send an SFP REST JSON PUT message') + opts.add_argument('--send-acl', '-5', + dest='send_acl', + action='store_true', + help='Send an ACL REST JSON PUT message') + opts.add_argument('--send-rsp', '-6', + dest='send_rsp', + action='store_true', + help='Send an RSP REST JSON POST RPC message') + opts.add_argument('--send-all', '-7', + dest='send_all', + action='store_true', + help='Send all (SF, SFF, SFC, SFP, RSP, ACL) REST JSON messages') + opts.add_argument('--query-sfc', '-q', + dest='query_sfc', + action='store_true', + help='Query all SFC objects') + + # Paths to the rest JSON files + opts.add_argument('--rest-path-prefix', '-prefix', + default=context.rest_path_prefix, + dest='rest_path_prefix', + help='Path prefix where the REST JSON files are located') + opts.add_argument('--rest-path-sf-sel', + default=context.rest_path_sf_sel, + dest='rest_path_sf_sel', + help='Name of the SF Selection REST JSON file, relative to configured prefix') + opts.add_argument('--rest-path-sf', '-n', + default=context.rest_path_sf, + dest='rest_path_sf', + help='Name of the SF REST JSON file, relative to configured prefix') + opts.add_argument('--rest-path-sfc', '-c', + default=context.rest_path_sfc, + dest='rest_path_sfc', + help='Name of the SFC REST JSON file, relative to configured prefix') + opts.add_argument('--rest-path-sff', '-f', + default=context.rest_path_sff, + dest='rest_path_sff', + help='Name of the SFF REST JSON file, relative toconfigured prefix') + opts.add_argument('--rest-path-sfp', '-p', + default=context.rest_path_sfp, + dest='rest_path_sfp', + help='Name of the SFP REST JSON file, relative to configured prefix') + opts.add_argument('--rest-path-rsp', '-r', + default=context.rest_path_rsp, + dest='rest_path_rsp', + help='Name of the RSP REST JSON file, relative to configured prefix') + opts.add_argument('--rest-path-acl', '-a', + default=context.rest_path_acl, + dest='rest_path_acl', + help='Name of the ACL REST JSON file, relative to configured prefix') + + args = opts.parse_args() + + context.http_server = args.http_server + context.http_port = args.http_port + context.url_base = 'http://%s:%s/restconf/' % (context.http_server, context.http_port) + + context.rest_path_prefix = args.rest_path_prefix + context.rest_path_sf = args.rest_path_sf + context.rest_path_sf_sel = args.rest_path_sf_sel + context.rest_path_sfc = args.rest_path_sfc + context.rest_path_sff = args.rest_path_sff + context.rest_path_sfp = args.rest_path_sfp + context.rest_path_acl = args.rest_path_acl + context.rest_path_rsp = args.rest_path_rsp + context.set_path_prefix_paths(context.rest_path_prefix) + + for path in [context.rest_path_sf, context.rest_path_sfc, context.rest_path_sff, context.rest_path_sfp]: + print '\tUsing REST file: %s' % path + + if args.batch: + context.interractive = False + if args.send_all: + context.batch_sf = True + context.batch_sf_sel = True + context.batch_sfc = True + context.batch_sff = True + context.batch_sfp = True + context.batch_rsp = True + # TODO deactivated for now + #context.batch_acl = True + else: + context.batch_sf = args.send_sf + context.batch_sf_sel = args.send_sf_sel + context.batch_sfc = args.send_sfc + context.batch_sff = args.send_sff + context.batch_sfp = args.send_sfp + context.batch_rsp = args.send_rsp + # TODO deactivated for now + #context.batch_acl = args.send_acl + context.batch_query = args.query_sfc + + return True + + +def send_rest(context, operation, rest_url, rest_file=None): + """ + Send an HTTP REST message + Keyword arguments: + context -- specifies the destination IP/Port and user/pw + operation -- specifies if the HTTP OP is one of: GET, PUT, or POST + rest_url -- the operation URL + rest_file -- for PUT and POST operations, specifies where the JSON input is found + """ + + complete_url = '%s%s' % (context.url_base, rest_url) + + if rest_file: + if not os.path.exists(rest_file): + print 'REST file [%s] does not exists' % rest_file + return False + + try: + if operation == GET: + r = requests.get(url = complete_url, + headers = context.http_headers, + auth=(context.user, context.pw)) + + print '\nHTTP GET %s\nresult: %s' % (rest_url, r.status_code) + #if len(r.text) > 1: + if r.status_code >= 200 and r.status_code <= 299: + print json.dumps(json.loads(r.text), indent=4, separators=(',', ': ')) + + elif operation == PUT: + if not rest_file: + print 'ERROR trying to PUT with empty REST file' + return False + + r = requests.put(url = complete_url, + auth=(context.user, context.pw), + data = json.dumps(json.load(open(rest_file, 'r'))), + headers = context.http_headers) + print '\nHTTP PUT %s\nresult: %s' % (rest_url, r.status_code) + + elif operation == POST: + if not rest_file: + print 'ERROR trying to POST with empty REST file' + return False + + post_list = json.load(open(rest_file, 'r')) + if len(post_list) > 1: + # This allows for multiple RSPs to be sent from one JSON file + for entry in post_list: + r = requests.post(url = complete_url, + auth=(context.user, context.pw), + data = json.dumps(entry), + headers = context.http_headers) + print '\nHTTP POST %s\nresult: %s' % (rest_url, r.status_code) + else: + r = requests.post(url = complete_url, + auth=(context.user, context.pw), + data = json.dumps(post_list), + headers = context.http_headers) + print '\nHTTP POST %s\nresult: %s' % (rest_url, r.status_code) + else: + print 'ERROR: Invalid Operation: %s' % (operation) + + except requests.exceptions.ConnectionError as ce: + print 'ERROR connecting: %s' % (ce) + return False + except Exception as e: + print 'ERROR Exception: %s' % (e) + return False + except: + print 'ERROR unkown exception raised' + return False + + return True + +def validate_rest(context): + """ + For each JSON input file in context, validate the JSON syntax. + No validation checking is made on parameter names or types. + """ + + print '' + for path in [context.rest_path_sf, + context.rest_path_sfc, + context.rest_path_sff, + context.rest_path_sfp, + context.rest_path_rsp, + context.rest_path_sf_sel]: + if os.path.exists(path): + print 'Validating JSON file: %s' % path + try: + json.load(open(path, 'r')) + except ValueError as ve: + print '\tValidation error [%s]' % ve + return False + + return True + +def batch(context): + """ + Launch the application in batch mode and perform + the operations as specified in the Context object. + """ + + # The order of these if's is important + # If send-all was set, then each of these needs to be sent, in order + if context.batch_sf_sel: + send_rest(context, PUT, context.rest_url_sf_sel, context.rest_path_sf_sel) + if context.batch_sf: + send_rest(context, PUT, context.rest_url_sf, context.rest_path_sf) + if context.batch_sff: + send_rest(context, PUT, context.rest_url_sff, context.rest_path_sff) + if context.batch_sfc: + send_rest(context, PUT, context.rest_url_sfc, context.rest_path_sfc) + if context.batch_sfp: + send_rest(context, PUT, context.rest_url_sfp, context.rest_path_sfp) + if context.batch_rsp: + send_rest(context, POST, context.rest_url_rsp_rpc, context.rest_path_rsp) + if context.batch_acl: + send_rest(context, PUT, context.rest_url_acl, context.rest_path_acl) + + if context.batch_query: + send_rest(context, GET, context.rest_url_sf_sel) + send_rest(context, GET, context.rest_url_sf) + send_rest(context, GET, context.rest_url_sff) + send_rest(context, GET, context.rest_url_sfc) + send_rest(context, GET, context.rest_url_sfp) + send_rest(context, GET, context.rest_url_rsp) + # TODO deactivated for now + #send_rest(context, GET, context.rest_url_acl) + + +def CLI(context): + """ + Run a simple Command Line Interface. + The Context object is used for sending rest messages + """ + + option = '1' + while option != '0': + print '\n\nChoose Option to perform:' + print ' 0) Quit' + print ' 1) Send SF REST' + print ' 2) Send SFC REST' + print ' 3) Send SFF REST' + print ' 4) Send SFP REST' + print ' 5) Send RSP REST' + print ' 6) Send ACL REST' + print ' 7) Send all ordered: (SFsel, SF, SFF, SFC, SFP, RSP)' + print ' 8) Query all: (SFsel, SF, SFF, SFC, SFP, RSP)' + print ' 9) Change config file path, currently [%s]' % (context.rest_path_prefix) + print '10) Validate config files JSON syntax' + + option = raw_input('=> ') + + if option == '1': + send_rest(context, PUT, context.rest_url_sf, context.rest_path_sf) + elif option == '2': + send_rest(context, PUT, context.rest_url_sfc, context.rest_path_sfc) + elif option == '3': + send_rest(context, PUT, context.rest_url_sff, context.rest_path_sff) + elif option == '4': + send_rest(context, PUT, context.rest_url_sfp, context.rest_path_sfp) + elif option == '5': + send_rest(context, POST, context.rest_url_rsp_rpc, context.rest_path_rsp) + elif option == '6': + send_rest(context, PUT, context.rest_url_acl, context.rest_path_acl) + elif option == '7': + pdb.set_trace() + send_rest(context, PUT, context.rest_url_sf_sel, context.rest_path_sf_sel) + send_rest(context, PUT, context.rest_url_sf, context.rest_path_sf) + send_rest(context, PUT, context.rest_url_sff, context.rest_path_sff) + send_rest(context, PUT, context.rest_url_sfc, context.rest_path_sfc) + send_rest(context, PUT, context.rest_url_sfp, context.rest_path_sfp) + time.sleep(1); + send_rest(context, POST, context.rest_url_rsp_rpc, context.rest_path_rsp) + # TODO ACL deactivated for now + # Need to wait until the SFC creates the RSP internally before sending the ACL + #print 'Sleeping 2 seconds while RSP being created' + #time.sleep(2); + #send_rest(context, PUT, context.rest_url_acl, context.rest_path_acl) + elif option == '8': + send_rest(context, GET, context.rest_url_sf_sel) + send_rest(context, GET, context.rest_url_sf) + send_rest(context, GET, context.rest_url_sff) + send_rest(context, GET, context.rest_url_sfc) + send_rest(context, GET, context.rest_url_sfp) + send_rest(context, GET, context.rest_url_rsp) + send_rest(context, GET, context.rest_url_acl) + elif option == '9': + path_prefix = raw_input('Enter path => ') + if not os.path.exists(path_prefix): + print 'ERROR: path does not exist: [%s]' % (path_prefix) + else: + context.set_path_prefix_paths(path_prefix) + elif option == '10': + validate_rest(context) + elif option != '0': + print 'ERROR: Invalid option %s' % (option) + + +def main(): + """ + Main entry point into the VnfMgrSim application. + Command line arguments are expected. + Example invocations: + To display application command-line help: + vnfmgr_odl.py --help + To start the application in interractive mode: + vnfmgr_odl.py -prefix + To start the application in batch mode and send an SF JSON REST message: + vnfmgr_odl.py -b -prefix --send-sf + """ + + context = Context() + if not get_cmd_line(context): + return 1 + + if context.interractive: + CLI(context) + else: + batch(context) + + return 0 + +if __name__ == '__main__': + main() + diff --git a/VnfMgrSim/vnfmgr/vnfmgr_os/__init__.py b/VnfMgrSim/vnfmgr/vnfmgr_os/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/VnfMgrSim/vnfmgr/vnfmgr_os/vnfmgr_os.py b/VnfMgrSim/vnfmgr/vnfmgr_os/vnfmgr_os.py new file mode 100755 index 00000000..00678503 --- /dev/null +++ b/VnfMgrSim/vnfmgr/vnfmgr_os/vnfmgr_os.py @@ -0,0 +1,68 @@ +################################################################# +# # +# Copyright 2015 Ericsson AB # +# All Rights Reserved # +# # +# Author: Manuel Buil # +# Version: 0.1 # +# # +################################################################# + +import pdb + +from novaclient.v2 import client as nova +from novaclient import exceptions as novaexceptions +from keystoneclient.v2_0 import client as keystone +from glanceclient import client as glance + + +class OpenStack_API: + def __init__(self, authurl, tenantName, tenantUser, tenantPass): + self.authurl=authurl + self.tenantName=tenantName + self.tenantUser=tenantUser + self.tenantPass=tenantPass + + def get_token(self): + # Establish connection to Openstack controller + osconn = keystone.Client(username=self.tenantUser, password=self.tenantPass, tenant_name=self.tenantName, auth_url=self.authurl) + token = osconn.auth_token + return token + + def get_endpoint(self,service_type, endpoint_type): + # Establish connection to Openstack controller + osconn = keystone.Client(username=self.tenantUser, password=self.tenantPass, tenant_name=self.tenantName, auth_url=self.authurl) + endpoint = osconn.service_catalog.url_for(service_type=service_type, endpoint_type=endpoint_type) + return endpoint + + def find_image(self,SF_type): + # Find in glance the image that matches the SF we want to deploy + token = self.get_token() + endpoint = self.get_endpoint('image','publicURL') + osconn = glance.Client('1',endpoint=endpoint,token=token) + image_list = osconn.images.list() + for item in image_list: + try: + image_type = item.properties.get('image_type', None) + image_id=None + if (image_type == SF_type): + image_id = item.id + break + except: + print("Errrorr") + + #Search image which matches the SF type + return image_id + + def create_vm(self, name, image, flavor, nics=None): + # Establish connection to Openstack controller + osconn = nova.Client(self.tenantUser, self.tenantPass, self.tenantName, self.authurl, service_type="compute") + try: + if nics is None: + vm = osconn.servers.create(name,image,flavor) + else: + vm = osconn.servers.create(name,image,flavor,nics) + except: + print("Something wrong happened while creating the VM") + vm = None + return vm diff --git a/setup.py b/setup.py deleted file mode 100644 index 9ff16995..00000000 --- a/setup.py +++ /dev/null @@ -1,23 +0,0 @@ -import os -from setuptools import setup - -# Utility function to read the README file. -# Used for the long_description. It's nice, because now 1) we have a top level -# README file and 2) it's easier to type in the README file than to put a raw -# string in below ... -def read(fname): - return open(os.path.join(os.path.dirname(__file__), fname)).read() - -setup( - name = "vnf manager simulator", - version = "1.0", - author = "Manuel Buil, Brady A. Johnson", - author_email = "manuel.buil@ericsson.com, brady.allen.johnson@ericsson.com", - description = ("A script which simulates an orchestrator"), - license = "Apache License Version 2.0", - keywords = "example documentation tutorial", - url = "https://gerrit.opnfv.org/gerrit/#/c/2519", - packages = [".."], - scripts = [".."], - long_description=read('README'), -) diff --git a/tests/NAME_tests.py b/tests/NAME_tests.py deleted file mode 100644 index 9f83104c..00000000 --- a/tests/NAME_tests.py +++ /dev/null @@ -1,11 +0,0 @@ -from nose.tools import * -import NAME - -def setup(): - print "SETUP!" - -def teardown(): - print "TEAR DOWN!" - -def test_basic(): - print "I RAN!" diff --git a/tests/__init__.py b/tests/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/vnfmgr/vnfmgr_main.py b/vnfmgr/vnfmgr_main.py deleted file mode 100755 index b5ab8be1..00000000 --- a/vnfmgr/vnfmgr_main.py +++ /dev/null @@ -1,72 +0,0 @@ -################################################################# -# # -# Copyright 2015 Ericsson AB # -# All Rights Reserved # -# # -# Author: Manuel Buil # -# Version: 0.1 # -# # -################################################################# - -import pdb -from vnfmgr_os.vnfmgr_os import OpenStack_API -import vnfmgr_odl.vnfmgr_odl as odlscript -import time -import json - -if __name__ == "__main__": - #OpenStack environment information - authurl = "http://localhost:5000/v2.0" - adminTenantName = 'admin' - adminTenantUser = 'admin' - adminTenantPass = 'abc123' - tenantName = adminTenantName - tenantUser = adminTenantUser - tenantPass = adminTenantPass - - openstack = OpenStack_API(authurl, tenantName, tenantUser, tenantPass) - - # 1 - Get the SF type - # Provide the file with the SFC configuration - file_json = "vnfmgr_odl/sample_config/RestConf-SFCs-HttpPut.json" - # Read the config files which refer to SF - json_data=open(file_json).read() - data = json.loads(json_data) - pdb.set_trace() - - # Grab the SF type - chains = data['service-function-chains']['service-function-chain'] - for chain in chains: - SFs = chain['sfc-service-function'] - for SF in SFs: - sf_type = SF['type'] - name = SF['name'] - #2 - Search the image in glance with that SF type - image = openstack.find_image(sf_type) - if image == None: - print("There is no image with that sf_name") - exit(1) - # 3 - Boot the VM without network - flavor = 1 - print("About to deploy") - vm = openstack.create_vm(name,image,flavor) - if vm == None: - print("Problems to deploy the VM") - exit(1) - - #Make the call to ODL to deploy SFC - context = odlscript.Context() - context.set_path_prefix_paths("vnfmgr_odl/sample_config") - pdb.set_trace() - odlscript.send_rest(context, "PUT", context.rest_url_sf_sel, context.rest_path_sf_sel) - odlscript.send_rest(context, "PUT", context.rest_url_sf, context.rest_path_sf) - odlscript.send_rest(context, "PUT", context.rest_url_sff, context.rest_path_sff) - odlscript.send_rest(context, "PUT", context.rest_url_sfc, context.rest_path_sfc) - odlscript.send_rest(context, "PUT", context.rest_url_sfp, context.rest_path_sfp) - time.sleep(1); - odlscript.send_rest(context, "POST", context.rest_url_rsp_rpc, context.rest_path_rsp) - - - #TO DO - # Check if the SF_VM already exists before creating it - # Network of the VM diff --git a/vnfmgr/vnfmgr_odl/__init__.py b/vnfmgr/vnfmgr_odl/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/vnfmgr/vnfmgr_odl/sample_config/RestConf-RSP-HttpPost.json b/vnfmgr/vnfmgr_odl/sample_config/RestConf-RSP-HttpPost.json deleted file mode 100755 index 998d1e07..00000000 --- a/vnfmgr/vnfmgr_odl/sample_config/RestConf-RSP-HttpPost.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "input": { - "name": "sfc-path-1", - "parent-service-function-path": "sfc-path-1", - "symmetric": true - } -} diff --git a/vnfmgr/vnfmgr_odl/sample_config/RestConf-SFCs-HttpPut.json b/vnfmgr/vnfmgr_odl/sample_config/RestConf-SFCs-HttpPut.json deleted file mode 100755 index 34449647..00000000 --- a/vnfmgr/vnfmgr_odl/sample_config/RestConf-SFCs-HttpPut.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "service-function-chains": { - "service-function-chain": [ - { - "name": "sfc-chain-1", - "symmetric": true, - "sfc-service-function": [ - { - "name": "firewall-abstract1", - "type": "service-function-type:firewall" - }, - { - "name": "firewall-abstract2", - "type": "service-function-type:firewall" - } - ] - } - - ] - } -} - diff --git a/vnfmgr/vnfmgr_odl/sample_config/RestConf-SFFs-HttpPut.json b/vnfmgr/vnfmgr_odl/sample_config/RestConf-SFFs-HttpPut.json deleted file mode 100755 index 191fd540..00000000 --- a/vnfmgr/vnfmgr_odl/sample_config/RestConf-SFFs-HttpPut.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "service-function-forwarders": { - "service-function-forwarder": [ - { - "name": "SFF2", - "sff-data-plane-locator": [ - { - "name": "sff2-dp1", - "service-function-forwarder-ovs:ovs-bridge": {}, - "data-plane-locator": { - "transport": "service-locator:vxlan-gpe", - "port": 6633, - "ip": "192.168.1.100" - }, - "service-function-forwarder-ovs:ovs-options": { - "nshc1": "flow", - "nsp": "flow", - "key": "flow", - "remote-ip": "flow", - "nsi": "flow", - "nshc2": "flow", - "nshc3": "flow", - "dst-port": "6633", - "nshc4": "flow" - } - } - ], - "service-function-forwarder-ovs:ovs-bridge": { - "bridge-name": "ovs-br2" - }, - "service-function-dictionary": [ - { - "name": "firewall-2", - "type": "service-function-type:firewall", - "sff-sf-data-plane-locator": { - "service-function-forwarder-ovs:ovs-bridge": {}, - "transport": "service-locator:vxlan-gpe", - "port": 6633, - "ip": "192.168.1.11" - } - }, - { - "name": "firewall-3", - "type": "service-function-type:firewall", - "sff-sf-data-plane-locator": { - "service-function-forwarder-ovs:ovs-bridge": {}, - "transport": "service-locator:vxlan-gpe", - "port": 6633, - "ip": "192.168.1.12" - } - } - ], - "ip-mgmt-address": "192.168.1.100", - "service-node": "" - }, - { - "name": "SFF-CL", - "sff-data-plane-locator": [ - { - "name": "ovs-br1", - "service-function-forwarder-ovs:ovs-bridge": {}, - "data-plane-locator": { - "transport": "service-locator:vxlan-gpe", - "port": 30001, - "ip": "192.168.1.50" - } - } - ], - "rest-uri": "http://192.168.1.50:5000", - "ip-mgmt-address": "192.168.1.50", - "service-node": "" - } - ] - } -} diff --git a/vnfmgr/vnfmgr_odl/sample_config/RestConf-SFPs-HttpPut.json b/vnfmgr/vnfmgr_odl/sample_config/RestConf-SFPs-HttpPut.json deleted file mode 100755 index da1f2c45..00000000 --- a/vnfmgr/vnfmgr_odl/sample_config/RestConf-SFPs-HttpPut.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "service-function-paths": { - "service-function-path": [ - { - "name": "sfc-path-1", - "service-chain-name": "sfc-chain-1", - "transport-type": "service-locator:vxlan-gpe", - "symmetric": true - } - ] - } -} diff --git a/vnfmgr/vnfmgr_odl/sample_config/RestConf-SFs-HttpPut.json b/vnfmgr/vnfmgr_odl/sample_config/RestConf-SFs-HttpPut.json deleted file mode 100755 index 1ea27e79..00000000 --- a/vnfmgr/vnfmgr_odl/sample_config/RestConf-SFs-HttpPut.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "service-functions": { - "service-function": [ - { - "name": "firewall-2", - "sf-data-plane-locator": [ - { - "name": "firewall-2-dp1", - "ip": "192.168.1.11", - "port": 6633, - "transport": "service-locator:vxlan-gpe", - "service-function-forwarder": "SFF2" - } - ], - "rest-uri": "http://192.168.1.11:5000", - "nsh-aware": true, - "ip-mgmt-address": "192.168.1.11", - "type": "service-function-type:firewall" - }, - { - "name": "firewall-3", - "sf-data-plane-locator": [ - { - "name": "firewall-3-dp1", - "ip": "192.168.1.12", - "port": 6633, - "transport": "service-locator:vxlan-gpe", - "service-function-forwarder": "SFF2" - } - ], - "rest-uri": "http://192.168.1.12:5000", - "nsh-aware": true, - "ip-mgmt-address": "192.168.1.12", - "type": "service-function-type:firewall" - } - ] - } -} diff --git a/vnfmgr/vnfmgr_odl/vnfmgr_odl.py b/vnfmgr/vnfmgr_odl/vnfmgr_odl.py deleted file mode 100755 index 4d35aebb..00000000 --- a/vnfmgr/vnfmgr_odl/vnfmgr_odl.py +++ /dev/null @@ -1,440 +0,0 @@ -#! /usr/bin/env python - -__author__ = "Brady Johnson" -__copyright__ = "Copyright(c) 2015, Ericsson, Inc." -__license__ = "Apache License version 2.0" -__version__ = "0.1" -__email__ = "brady.allen.johnson@ericsson.com" -__status__ = "beta" -import pdb -import os -import time -import requests -import json -import argparse - -PUT = 'PUT' -GET = 'GET' -POST = 'POST' - -class Context(object): - """ - Context class to hold the configuration as specified on the command line - """ - def __init__(self): - self.rest_path_prefix = 'sampleConfig' - self.rest_path_sf = 'RestConf-SFs-HttpPut.json' - self.rest_path_sf_sel = 'RestConf-SFselect-HttpPut.json' - self.rest_path_sfc = 'RestConf-SFCs-HttpPut.json' - self.rest_path_sff = 'RestConf-SFFs-HttpPut.json' - self.rest_path_sfp = 'RestConf-SFPs-HttpPut.json' - self.rest_path_acl = 'RestConf-ACLs-HttpPut.json' - self.rest_path_rsp = 'RestConf-RSP-HttpPost.json' - - self.rest_url_sf = 'config/service-function:service-functions/' - self.rest_url_sf_sel = 'config/service-function-scheduler-type:service-function-scheduler-types/' - self.rest_url_sfc = 'config/service-function-chain:service-function-chains/' - self.rest_url_sff = 'config/service-function-forwarder:service-function-forwarders/' - self.rest_url_sfp = 'config/service-function-path:service-function-paths/' - self.rest_url_rsp = 'operational/rendered-service-path:rendered-service-paths/' - self.rest_url_rsp_rpc = 'operations/rendered-service-path:create-rendered-path' - self.rest_url_acl = 'config/ietf-acl:access-lists/' - - self.http_headers = {'Content-Type' : 'application/json', 'Cache-Control' : 'no-cache'} - self.http_server = 'localhost' - self.url_base = '' - self.http_port = '8181' - self.interractive = True - self.user = 'admin' - self.pw = 'admin' - self.batch_sf = False - self.batch_sf_sel = False - self.batch_sfc = False - self.batch_sff = False - self.batch_sfp = False - self.batch_acl = False - self.batch_rsp = False - self.batch_query = False - - def set_path_prefix_paths(self, path_prefix): - self.rest_path_prefix = path_prefix - self.rest_path_sf = os.path.join(self.rest_path_prefix, self.rest_path_sf) - self.rest_path_sf_sel = os.path.join(self.rest_path_prefix, self.rest_path_sf_sel) - self.rest_path_sfc = os.path.join(self.rest_path_prefix, self.rest_path_sfc) - self.rest_path_sff = os.path.join(self.rest_path_prefix, self.rest_path_sff) - self.rest_path_sfp = os.path.join(self.rest_path_prefix, self.rest_path_sfp) - self.rest_path_acl = os.path.join(self.rest_path_prefix, self.rest_path_acl) - self.rest_path_rsp = os.path.join(self.rest_path_prefix, self.rest_path_rsp) - - -def get_cmd_line(context): - """ - Create a command-line parser, parse the command line args, and process them. - Populate the Context object with the processed command-line args. - """ - - opts = argparse.ArgumentParser() - - # Batch or Interractive mode - opts.add_argument('--interractive', '-i', - dest='interractive', - action='store_true', - help='Interractive mode, default') - opts.add_argument('--batch', '-b', - dest='batch', - action='store_true', - help='Batch mode, overrides interractive mode') - - # Where to send the messages - opts.add_argument('--http-server', '-s', - default=context.http_server, - dest='http_server', - help='HTTP server address') - opts.add_argument('--http-port', - default=context.http_port, - dest='http_port', - help='HTTP server port') - - # Batch mode, which message(s) to send - opts.add_argument('--send-sf', '-1', - dest='send_sf', - action='store_true', - help='Send an SF REST JSON PUT message') - opts.add_argument('--send-sf-sel', - dest='send_sf_sel', - action='store_true', - help='Send an SF Selection REST JSON PUT message') - opts.add_argument('--send-sfc', '-2', - dest='send_sfc', - action='store_true', - help='Send an SFC REST JSON PUT message') - opts.add_argument('--send-sff', '-3', - dest='send_sff', - action='store_true', - help='Send an SFF REST JSON PUT message') - opts.add_argument('--send-sfp', '-4', - dest='send_sfp', - action='store_true', - help='Send an SFP REST JSON PUT message') - opts.add_argument('--send-acl', '-5', - dest='send_acl', - action='store_true', - help='Send an ACL REST JSON PUT message') - opts.add_argument('--send-rsp', '-6', - dest='send_rsp', - action='store_true', - help='Send an RSP REST JSON POST RPC message') - opts.add_argument('--send-all', '-7', - dest='send_all', - action='store_true', - help='Send all (SF, SFF, SFC, SFP, RSP, ACL) REST JSON messages') - opts.add_argument('--query-sfc', '-q', - dest='query_sfc', - action='store_true', - help='Query all SFC objects') - - # Paths to the rest JSON files - opts.add_argument('--rest-path-prefix', '-prefix', - default=context.rest_path_prefix, - dest='rest_path_prefix', - help='Path prefix where the REST JSON files are located') - opts.add_argument('--rest-path-sf-sel', - default=context.rest_path_sf_sel, - dest='rest_path_sf_sel', - help='Name of the SF Selection REST JSON file, relative to configured prefix') - opts.add_argument('--rest-path-sf', '-n', - default=context.rest_path_sf, - dest='rest_path_sf', - help='Name of the SF REST JSON file, relative to configured prefix') - opts.add_argument('--rest-path-sfc', '-c', - default=context.rest_path_sfc, - dest='rest_path_sfc', - help='Name of the SFC REST JSON file, relative to configured prefix') - opts.add_argument('--rest-path-sff', '-f', - default=context.rest_path_sff, - dest='rest_path_sff', - help='Name of the SFF REST JSON file, relative toconfigured prefix') - opts.add_argument('--rest-path-sfp', '-p', - default=context.rest_path_sfp, - dest='rest_path_sfp', - help='Name of the SFP REST JSON file, relative to configured prefix') - opts.add_argument('--rest-path-rsp', '-r', - default=context.rest_path_rsp, - dest='rest_path_rsp', - help='Name of the RSP REST JSON file, relative to configured prefix') - opts.add_argument('--rest-path-acl', '-a', - default=context.rest_path_acl, - dest='rest_path_acl', - help='Name of the ACL REST JSON file, relative to configured prefix') - - args = opts.parse_args() - - context.http_server = args.http_server - context.http_port = args.http_port - context.url_base = 'http://%s:%s/restconf/' % (context.http_server, context.http_port) - - context.rest_path_prefix = args.rest_path_prefix - context.rest_path_sf = args.rest_path_sf - context.rest_path_sf_sel = args.rest_path_sf_sel - context.rest_path_sfc = args.rest_path_sfc - context.rest_path_sff = args.rest_path_sff - context.rest_path_sfp = args.rest_path_sfp - context.rest_path_acl = args.rest_path_acl - context.rest_path_rsp = args.rest_path_rsp - context.set_path_prefix_paths(context.rest_path_prefix) - - for path in [context.rest_path_sf, context.rest_path_sfc, context.rest_path_sff, context.rest_path_sfp]: - print '\tUsing REST file: %s' % path - - if args.batch: - context.interractive = False - if args.send_all: - context.batch_sf = True - context.batch_sf_sel = True - context.batch_sfc = True - context.batch_sff = True - context.batch_sfp = True - context.batch_rsp = True - # TODO deactivated for now - #context.batch_acl = True - else: - context.batch_sf = args.send_sf - context.batch_sf_sel = args.send_sf_sel - context.batch_sfc = args.send_sfc - context.batch_sff = args.send_sff - context.batch_sfp = args.send_sfp - context.batch_rsp = args.send_rsp - # TODO deactivated for now - #context.batch_acl = args.send_acl - context.batch_query = args.query_sfc - - return True - - -def send_rest(context, operation, rest_url, rest_file=None): - """ - Send an HTTP REST message - Keyword arguments: - context -- specifies the destination IP/Port and user/pw - operation -- specifies if the HTTP OP is one of: GET, PUT, or POST - rest_url -- the operation URL - rest_file -- for PUT and POST operations, specifies where the JSON input is found - """ - - complete_url = '%s%s' % (context.url_base, rest_url) - - if rest_file: - if not os.path.exists(rest_file): - print 'REST file [%s] does not exists' % rest_file - return False - - try: - if operation == GET: - r = requests.get(url = complete_url, - headers = context.http_headers, - auth=(context.user, context.pw)) - - print '\nHTTP GET %s\nresult: %s' % (rest_url, r.status_code) - #if len(r.text) > 1: - if r.status_code >= 200 and r.status_code <= 299: - print json.dumps(json.loads(r.text), indent=4, separators=(',', ': ')) - - elif operation == PUT: - if not rest_file: - print 'ERROR trying to PUT with empty REST file' - return False - - r = requests.put(url = complete_url, - auth=(context.user, context.pw), - data = json.dumps(json.load(open(rest_file, 'r'))), - headers = context.http_headers) - print '\nHTTP PUT %s\nresult: %s' % (rest_url, r.status_code) - - elif operation == POST: - if not rest_file: - print 'ERROR trying to POST with empty REST file' - return False - - post_list = json.load(open(rest_file, 'r')) - if len(post_list) > 1: - # This allows for multiple RSPs to be sent from one JSON file - for entry in post_list: - r = requests.post(url = complete_url, - auth=(context.user, context.pw), - data = json.dumps(entry), - headers = context.http_headers) - print '\nHTTP POST %s\nresult: %s' % (rest_url, r.status_code) - else: - r = requests.post(url = complete_url, - auth=(context.user, context.pw), - data = json.dumps(post_list), - headers = context.http_headers) - print '\nHTTP POST %s\nresult: %s' % (rest_url, r.status_code) - else: - print 'ERROR: Invalid Operation: %s' % (operation) - - except requests.exceptions.ConnectionError as ce: - print 'ERROR connecting: %s' % (ce) - return False - except Exception as e: - print 'ERROR Exception: %s' % (e) - return False - except: - print 'ERROR unkown exception raised' - return False - - return True - -def validate_rest(context): - """ - For each JSON input file in context, validate the JSON syntax. - No validation checking is made on parameter names or types. - """ - - print '' - for path in [context.rest_path_sf, - context.rest_path_sfc, - context.rest_path_sff, - context.rest_path_sfp, - context.rest_path_rsp, - context.rest_path_sf_sel]: - if os.path.exists(path): - print 'Validating JSON file: %s' % path - try: - json.load(open(path, 'r')) - except ValueError as ve: - print '\tValidation error [%s]' % ve - return False - - return True - -def batch(context): - """ - Launch the application in batch mode and perform - the operations as specified in the Context object. - """ - - # The order of these if's is important - # If send-all was set, then each of these needs to be sent, in order - if context.batch_sf_sel: - send_rest(context, PUT, context.rest_url_sf_sel, context.rest_path_sf_sel) - if context.batch_sf: - send_rest(context, PUT, context.rest_url_sf, context.rest_path_sf) - if context.batch_sff: - send_rest(context, PUT, context.rest_url_sff, context.rest_path_sff) - if context.batch_sfc: - send_rest(context, PUT, context.rest_url_sfc, context.rest_path_sfc) - if context.batch_sfp: - send_rest(context, PUT, context.rest_url_sfp, context.rest_path_sfp) - if context.batch_rsp: - send_rest(context, POST, context.rest_url_rsp_rpc, context.rest_path_rsp) - if context.batch_acl: - send_rest(context, PUT, context.rest_url_acl, context.rest_path_acl) - - if context.batch_query: - send_rest(context, GET, context.rest_url_sf_sel) - send_rest(context, GET, context.rest_url_sf) - send_rest(context, GET, context.rest_url_sff) - send_rest(context, GET, context.rest_url_sfc) - send_rest(context, GET, context.rest_url_sfp) - send_rest(context, GET, context.rest_url_rsp) - # TODO deactivated for now - #send_rest(context, GET, context.rest_url_acl) - - -def CLI(context): - """ - Run a simple Command Line Interface. - The Context object is used for sending rest messages - """ - - option = '1' - while option != '0': - print '\n\nChoose Option to perform:' - print ' 0) Quit' - print ' 1) Send SF REST' - print ' 2) Send SFC REST' - print ' 3) Send SFF REST' - print ' 4) Send SFP REST' - print ' 5) Send RSP REST' - print ' 6) Send ACL REST' - print ' 7) Send all ordered: (SFsel, SF, SFF, SFC, SFP, RSP)' - print ' 8) Query all: (SFsel, SF, SFF, SFC, SFP, RSP)' - print ' 9) Change config file path, currently [%s]' % (context.rest_path_prefix) - print '10) Validate config files JSON syntax' - - option = raw_input('=> ') - - if option == '1': - send_rest(context, PUT, context.rest_url_sf, context.rest_path_sf) - elif option == '2': - send_rest(context, PUT, context.rest_url_sfc, context.rest_path_sfc) - elif option == '3': - send_rest(context, PUT, context.rest_url_sff, context.rest_path_sff) - elif option == '4': - send_rest(context, PUT, context.rest_url_sfp, context.rest_path_sfp) - elif option == '5': - send_rest(context, POST, context.rest_url_rsp_rpc, context.rest_path_rsp) - elif option == '6': - send_rest(context, PUT, context.rest_url_acl, context.rest_path_acl) - elif option == '7': - pdb.set_trace() - send_rest(context, PUT, context.rest_url_sf_sel, context.rest_path_sf_sel) - send_rest(context, PUT, context.rest_url_sf, context.rest_path_sf) - send_rest(context, PUT, context.rest_url_sff, context.rest_path_sff) - send_rest(context, PUT, context.rest_url_sfc, context.rest_path_sfc) - send_rest(context, PUT, context.rest_url_sfp, context.rest_path_sfp) - time.sleep(1); - send_rest(context, POST, context.rest_url_rsp_rpc, context.rest_path_rsp) - # TODO ACL deactivated for now - # Need to wait until the SFC creates the RSP internally before sending the ACL - #print 'Sleeping 2 seconds while RSP being created' - #time.sleep(2); - #send_rest(context, PUT, context.rest_url_acl, context.rest_path_acl) - elif option == '8': - send_rest(context, GET, context.rest_url_sf_sel) - send_rest(context, GET, context.rest_url_sf) - send_rest(context, GET, context.rest_url_sff) - send_rest(context, GET, context.rest_url_sfc) - send_rest(context, GET, context.rest_url_sfp) - send_rest(context, GET, context.rest_url_rsp) - send_rest(context, GET, context.rest_url_acl) - elif option == '9': - path_prefix = raw_input('Enter path => ') - if not os.path.exists(path_prefix): - print 'ERROR: path does not exist: [%s]' % (path_prefix) - else: - context.set_path_prefix_paths(path_prefix) - elif option == '10': - validate_rest(context) - elif option != '0': - print 'ERROR: Invalid option %s' % (option) - - -def main(): - """ - Main entry point into the VnfMgrSim application. - Command line arguments are expected. - Example invocations: - To display application command-line help: - vnfmgr_odl.py --help - To start the application in interractive mode: - vnfmgr_odl.py -prefix - To start the application in batch mode and send an SF JSON REST message: - vnfmgr_odl.py -b -prefix --send-sf - """ - - context = Context() - if not get_cmd_line(context): - return 1 - - if context.interractive: - CLI(context) - else: - batch(context) - - return 0 - -if __name__ == '__main__': - main() - diff --git a/vnfmgr/vnfmgr_os/__init__.py b/vnfmgr/vnfmgr_os/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/vnfmgr/vnfmgr_os/vnfmgr_os.py b/vnfmgr/vnfmgr_os/vnfmgr_os.py deleted file mode 100755 index 00678503..00000000 --- a/vnfmgr/vnfmgr_os/vnfmgr_os.py +++ /dev/null @@ -1,68 +0,0 @@ -################################################################# -# # -# Copyright 2015 Ericsson AB # -# All Rights Reserved # -# # -# Author: Manuel Buil # -# Version: 0.1 # -# # -################################################################# - -import pdb - -from novaclient.v2 import client as nova -from novaclient import exceptions as novaexceptions -from keystoneclient.v2_0 import client as keystone -from glanceclient import client as glance - - -class OpenStack_API: - def __init__(self, authurl, tenantName, tenantUser, tenantPass): - self.authurl=authurl - self.tenantName=tenantName - self.tenantUser=tenantUser - self.tenantPass=tenantPass - - def get_token(self): - # Establish connection to Openstack controller - osconn = keystone.Client(username=self.tenantUser, password=self.tenantPass, tenant_name=self.tenantName, auth_url=self.authurl) - token = osconn.auth_token - return token - - def get_endpoint(self,service_type, endpoint_type): - # Establish connection to Openstack controller - osconn = keystone.Client(username=self.tenantUser, password=self.tenantPass, tenant_name=self.tenantName, auth_url=self.authurl) - endpoint = osconn.service_catalog.url_for(service_type=service_type, endpoint_type=endpoint_type) - return endpoint - - def find_image(self,SF_type): - # Find in glance the image that matches the SF we want to deploy - token = self.get_token() - endpoint = self.get_endpoint('image','publicURL') - osconn = glance.Client('1',endpoint=endpoint,token=token) - image_list = osconn.images.list() - for item in image_list: - try: - image_type = item.properties.get('image_type', None) - image_id=None - if (image_type == SF_type): - image_id = item.id - break - except: - print("Errrorr") - - #Search image which matches the SF type - return image_id - - def create_vm(self, name, image, flavor, nics=None): - # Establish connection to Openstack controller - osconn = nova.Client(self.tenantUser, self.tenantPass, self.tenantName, self.authurl, service_type="compute") - try: - if nics is None: - vm = osconn.servers.create(name,image,flavor) - else: - vm = osconn.servers.create(name,image,flavor,nics) - except: - print("Something wrong happened while creating the VM") - vm = None - return vm -- cgit 1.2.3-korg