diff --git a/.codeclimate.yml b/.codeclimate.yml
new file mode 100644
index 0000000..d12b62a
--- /dev/null
+++ b/.codeclimate.yml
@@ -0,0 +1,4 @@
+exclude_paths:
+- "**/doc"
+- "ui/app/bower_components"
+- "**/.yardoc"
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a722ca7..08fd740 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,12 @@
+## 0.9.0
+- Refactor. Removed unused files and functions.
+- Hide credentials from logs.
+- Implemented missing WICM calls.
+- UI VNFD JSON editor.
+- UI included progress bar in instance status
+- Calculation of creation time of each resource in a stack. Saved in the VNFR.
+- Updated Dockerfile and Vagrant according last updates.
+
## 0.8.0
- Changed authentication method. No external entity is required for authentication.
- Authentication between modules enabled when environment is production using JWT.
diff --git a/Dockerfile b/Dockerfile
index dadcc68..97bd689 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -35,7 +35,7 @@ WORKDIR /root
RUN apt-get -q -y install curl
# Clone the conf files into the docker container
-RUN git clone https://github.com/jbatalle/TeNOR /root/TeNOR
+RUN git clone https://github.com/T-NOVA/TeNOR /root/TeNOR
ENV RAILS_ENV development
WORKDIR /root/TeNOR
@@ -43,6 +43,7 @@ RUN bundle --version
RUN cat Gemfile
RUN gem install bundle
RUN bundle install
+RUN sed -i 's/rake db:seed/bundle exec rake db:seed/g' tenor_install.sh
RUN ./tenor_install.sh 1
RUN chown -R mongodb:mongodb /var/lib/mongodb
diff --git a/Vagrantfile b/Vagrantfile
index 644330d..20d7e9d 100644
--- a/Vagrantfile
+++ b/Vagrantfile
@@ -11,8 +11,7 @@ Vagrant.configure(2) do |config|
vb.customize ['modifyvm', :id, '--natdnsproxy1', 'on']
end
- # config.vm.network :forwarded_port, guest: 4000, host: 4000 # tenor port
- config.vm.network :forwarded_port, guest: 8000, host: 8000 # gatekeeper port
+ config.vm.network :forwarded_port, guest: 4000, host: 4000 # tenor port
config.vm.network :forwarded_port, guest: 9000, host: 9000 # tenor UI port
config.vm.network :forwarded_port, guest: 27017, host: 27017 # tenor UI port
@@ -36,7 +35,7 @@ Vagrant.configure(2) do |config|
rvm group add rvm vagrant
rvm fix-permissions
cd ~
- git clone https://github.com/TeNOR/TeNOR.git
+ git clone https://github.com/T-NOVA/TeNOR.git
cd TeNOR/
./dependencies/install_dependencies.sh y y n
diff --git a/dependencies/dialog_install_dependencies.sh b/dependencies/dialog_install_dependencies.sh
deleted file mode 100755
index 49b4e74..0000000
--- a/dependencies/dialog_install_dependencies.sh
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/bin/bash
-# Author: Wojciech Mąka
-#
-#
-#
-installation () {
-echo $1
- if [ $1 -eq 0 ] #install mongodb
- then
- echo -e -n "\033[1;36mChecking if mongodb is installed"
- mongod --version > /dev/null 2>&1
- MONGO_IS_INSTALLED=$?
- if [ $MONGO_IS_INSTALLED -eq 0 ]; then
- echo ">>> MongoDB already installed"
- else
- echo "Do you want to install mongodb? (y/n)"
- read install
- if [ "$install" = "y" ]; then
- echo -e -n "\033[1;31mMongodb is not installed... Installing..."
- install_mongodb
- fi
- fi
-
- prog=2
- return $prog
- fi
- if [ $1 -eq 1 ] #install gatekeeper
- then
- echo "Install gatekeeper"
-
- prog=4
- return $prog
- fi
- if [ $1 -eq 2 ] #install ruby
- then
-
- prog=6
- return $prog
- fi
- if [ $1 -eq 3 ] #install npm
- then
-
- prog=100
- return $prog
- fi
-}
-
-tmpv=${0%/*}
-echo $tmpv
-cd $tmpv
-
-dialog --title "Installing prerequisites..." \
---backtitle "Installing prerequisites..." \
---msgbox "This installer will install all dependecies needed for buildig: couchdb-qt, " 10 40
-
-cmd=(dialog --separate-output --checklist "Select options:" 22 76 16)
- options=(1 "Mongo DB" on # any option can be set to default to "on"
- 2 "Gatekeeper" on
- 3 "Ruby" on
- 4 "NodeJS / NPM" on
- 5 "RabbitMQ" off)
- choices=$("${cmd[@]}" "${options[@]}" 2>&1 >/dev/tty)
- clear
-
-phase=0
-prog=0
-{
-for choice in $choices
-do
- echo $choice
- phase=$choice
- installation $phase
- prog=$?
- echo $prog
- phase=$[$phase+1]
-done
-} | dialog --title "Installing prerequisites..." \
- --backtitle "Installing prerequisites..." \
- --gauge "Installation in progress... " 10 40 $prog
\ No newline at end of file
diff --git a/end_to_end.rb b/end_to_end.rb
index 4b7b113..348f1ae 100644
--- a/end_to_end.rb
+++ b/end_to_end.rb
@@ -13,7 +13,7 @@
@OPENSTACK_DNS = ENV['OPENSTACK_DNS']
if @OPENSTACK_HOST.nil?
- puts "Execute the environment script! (. ./end_to_end_env.sh)"
+ puts "Execute the environment script! (. ./env_end_to_end.sh)"
exit
end
@@ -41,7 +41,7 @@ def end_to_end_script()
puts "Removing PoPs if exists...."
pops_names = ["admin_v2", "admin_v3", "non_admin_v2", "non_admin_v3"]
pops_names.each do |pop|
- remove_pops_if_exists(pop)
+ #remove_pops_if_exists(pop)
end
puts "All PoPs are removed\n"
@@ -121,6 +121,7 @@ def end_to_end_script()
puts errors if errors
recover_state(errors) if errors
@e2e[:instances] << {:id => ns_instance_id, :status => "INIT"}
+ break
end
pop = @e2e[:pops].find { |p| p[:name] == "admin_v2"}
#ns_instance, errors = create_instance(pop[:id])
@@ -150,7 +151,7 @@ def end_to_end_script()
if @e2e[:instances].find {|ins| ins[:status] != "INSTANTIATED"}
next
else
- puts "All instantiated???"
+ puts "All instances are INSTANTIATED"
counter = 30
break
end
@@ -164,7 +165,7 @@ def end_to_end_script()
puts "All instances created correctly..."
- puts "Removing..."
+ puts "Start removing of instances..."
@e2e[:instances].each do |instances|
delete_instance(instances[:id])
@@ -244,10 +245,12 @@ def check_if_descriptors(vnf_id, ns_id)
def create_descriptors()
puts "Creating descriptors"
vnfd = File.read('vnfd-validator/assets/samples/vnfd_example.json')
+ puts
begin
response = JSON.parse(RestClient.post "#{@tenor}/vnfs", vnfd, :content_type => :json)
rescue RestClient::ExceptionWithResponse => e
puts e
+ puts "Using the created VNFD"
response = {'vnfd' => {}}
response['vnfd']['id'] = JSON.parse(vnfd)['vnfd']['id']
rescue => e
@@ -263,6 +266,11 @@ def create_descriptors()
nsd = File.read('nsd-validator/assets/samples/nsd_example.json')
begin
response = JSON.parse(RestClient.post "#{@tenor}/network-services", nsd, :content_type => :json)
+ rescue RestClient::ExceptionWithResponse => e
+ puts e
+ puts "Using the created NSD"
+ response = {'nsd' => {}}
+ response['nsd']['id'] = JSON.parse(nsd)['nsd']['id']
rescue => e
puts "Error...."
puts e
@@ -293,8 +301,6 @@ def delete_descriptors()
end
puts "Remving VNFD...."
if !@e2e[:vnfd_id].nil?
- puts @e2e[:vnfd_id].to_s
- puts "#{@tenor}/vnfs/" + @e2e[:vnfd_id].to_s
begin
response = RestClient.delete "#{@tenor}/vnfs/" + @e2e[:vnfd_id].to_s
rescue => e
@@ -351,7 +357,7 @@ def recover_state(error)
end
@e2e[:instances].each do |instances|
- delete_instance(instances)
+ delete_instance(instances[:id])
end
exit
diff --git a/hot-generator/config/config.yml.sample b/hot-generator/config/config.yml.sample
index 6647753..8654119 100644
--- a/hot-generator/config/config.yml.sample
+++ b/hot-generator/config/config.yml.sample
@@ -9,7 +9,7 @@ timeout: 30
max_persistent_conns: 512
daemonize: false
logger_host: 127.0.0.1
-logger_port: 5228
+logger_port: 24224
port_security: false
dependencies: []
diff --git a/hot-generator/models/vnfd_to_hot.rb b/hot-generator/models/vnfd_to_hot.rb
index 3fc1ea6..3c9f25d 100644
--- a/hot-generator/models/vnfd_to_hot.rb
+++ b/hot-generator/models/vnfd_to_hot.rb
@@ -16,550 +16,536 @@
# limitations under the License.
#
class VnfdToHot
-
- # Initializes VnfdToHot object
- #
- # @param [String] name the name for the HOT
- # @param [String] description the description for the HOT
- def initialize(name, description, public_network_id)
- @hot = Hot.new(description)
- @name = name
- @outputs = {}
- @type = ""
- @vnfr_id = ""
- @public_network_id = public_network_id
- end
-
- # Converts VNFD to HOT
- #
- # @param [Hash] vnfd the VNFD
- # @param [String] tnova_flavour the T-NOVA flavour to generate the HOT for
- # @param [Array] networks_id the IDs of the networks created by NS Manager
- # @param [String] security_group_id the ID of the T-NOVA security group
- # @return [HOT] returns an HOT object
- def build(vnfd, tnova_flavour, networks_id, routers_id, security_group_id, vnfr_id, dns, flavours)
- # Parse needed outputs
- parse_outputs(vnfd['vnf_lifecycle_events'].find { |lifecycle| lifecycle['flavor_id_ref'] == tnova_flavour }['events'])
-
- @type = vnfd['type']
- @vnfr_id = vnfr_id
-
- key = create_key_pair(SecureRandom.urlsafe_base64(9))
- router_id = routers_id[0]['id']
-
- # Get T-NOVA deployment flavour
- deployment_information = vnfd['deployment_flavours'].detect { |flavour| flavour['id'] == tnova_flavour }
- raise CustomException::NoFlavorError, "Flavor #{tnova_flavour} not found" if deployment_information.nil?
-
- # Get the vlinks references for the deployment flavour
- vlinks = deployment_information['vlink_reference']
-
- networks_id = []
- router_interfaces = []
-
- vlinks.each do |vlink|
- vlink_json = vnfd['vlinks'].detect { |vl| vl['id'] == vlink }
- if !vlink_json['existing_net_id'].nil?
- networks_id << {'id' => vlink, 'alias' => vlink_json['alias'], 'heat_id' => vlink_json['existing_net_id']}
- else
- net_name, router_interface = create_networks(vlink_json, dns, router_id)
- networks_id << {'id' => vlink, 'alias' => vlink_json['alias'], 'heat' => vlink}
- router_interfaces << router_interface
- end
+ # Initializes VnfdToHot object
+ #
+ # @param [String] name the name for the HOT
+ # @param [String] description the description for the HOT
+ def initialize(name, description, public_network_id)
+ @hot = Hot.new(description)
+ @name = name
+ @outputs = {}
+ @type = ''
+ @vnfr_id = ''
+ @public_network_id = public_network_id
end
- deployment_information['vdu_reference'].each do |vdu_ref|
- # Get VDU for deployment
- vdu = vnfd['vdu'].detect { |vdu| vdu['id'] == vdu_ref }
-
- if vdu['vm_image_format'] == 'openstack_id'
- image_name = vdu['vm_image']
- else
- image_name = {get_resource: create_image(vdu)}
- end
- if flavours.detect { |fl| fl['id'] == vdu_ref }
- flavor_name = flavours.find { |fl| fl['id'] == vdu_ref }['flavour_id']
- else
- flavor_name = {get_resource: create_flavor(vdu)}
- end
-
- #ports = create_ports(vdu['id'], vdu['connection_points'], vnfd['vlinks'], networks_id, security_group_id)
- nets = []
- vdu['connection_points'].each do |connection_point|
- l = networks_id.find { |vlink| vlink['id'] == connection_point['vlink_ref'] }
- nets << {:network => {get_resource: l['heat']}}
- end
-
- #create AutoScalingGroup if the VNF can scale
- if (vdu['scale_in_out']['maximum'] > 10)
- #generate template for server
- nested_template = generate_nested_template(vdu, vnfd, networks_id, security_group_id, nets, router_interfaces, router_id)
-
- #save template in folder
- name = vnfd['id'].to_s
- filename = "assets/templates/" + name + ".yaml"
- File.open(filename, 'w') { |file| file.write(nested_template.to_yaml) }
-
- url = HotGenerator.manager + "/files/" + name + ".yaml"
- properties = {
- :image => image_name,
- :flavor => flavor_name
- }
+ # Converts VNFD to HOT
+ #
+ # @param [Hash] vnfd the VNFD
+ # @param [String] tnova_flavour the T-NOVA flavour to generate the HOT for
+ # @param [Array] networks_id the IDs of the networks created by NS Manager
+ # @param [String] security_group_id the ID of the T-NOVA security group
+ # @return [HOT] returns an HOT object
+ def build(vnfd, tnova_flavour, networks_id, routers_id, security_group_id, vnfr_id, dns, flavours)
+ # Parse needed outputs
+ parse_outputs(vnfd['vnf_lifecycle_events'].find { |lifecycle| lifecycle['flavor_id_ref'] == tnova_flavour }['events'])
+
+ @type = vnfd['type']
+ @vnfr_id = vnfr_id
+
+ key = create_key_pair(SecureRandom.urlsafe_base64(9))
+ router_id = routers_id[0]['id']
+
+ # Get T-NOVA deployment flavour
+ deployment_information = vnfd['deployment_flavours'].detect { |flavour| flavour['id'] == tnova_flavour }
+ raise CustomException::NoFlavorError, "Flavor #{tnova_flavour} not found" if deployment_information.nil?
+
+ # Get the vlinks references for the deployment flavour
+ vlinks = deployment_information['vlink_reference']
+
+ networks_id = []
+ router_interfaces = []
+
+ vlinks.each do |vlink|
+ vlink_json = vnfd['vlinks'].detect { |vl| vl['id'] == vlink }
+ if !vlink_json['existing_net_id'].nil?
+ networks_id << { 'id' => vlink, 'alias' => vlink_json['alias'], 'heat_id' => vlink_json['existing_net_id'] }
+ else
+ net_name, router_interface = create_networks(vlink_json, dns, router_id)
+ networks_id << { 'id' => vlink, 'alias' => vlink_json['alias'], 'heat' => vlink }
+ router_interfaces << router_interface
+ end
+ end
+
+ deployment_information['vdu_reference'].each do |vdu_ref|
+ # Get VDU for deployment
+ vdu = vnfd['vdu'].detect { |vdu| vdu['id'] == vdu_ref }
+
+ image_name = if vdu['vm_image_format'] == 'openstack_id'
+ vdu['vm_image']
+ else
+ { get_resource: create_image(vdu) }
+ end
+ if flavours.detect { |fl| fl['id'] == vdu_ref }
+ flavor_name = flavours.find { |fl| fl['id'] == vdu_ref }['flavour_id']
+ else
+ flavor_name = { get_resource: create_flavor(vdu) }
+ end
+
+ # ports = create_ports(vdu['id'], vdu['connection_points'], vnfd['vlinks'], networks_id, security_group_id)
+ nets = []
+ vdu['connection_points'].each do |connection_point|
+ l = networks_id.find { |vlink| vlink['id'] == connection_point['vlink_ref'] }
+ nets << { network: { get_resource: l['heat'] } }
+ end
+
+ # create AutoScalingGroup if the VNF can scale
+ if vdu['scale_in_out']['maximum'] > 10
+ # generate template for server
+ nested_template = generate_nested_template(vdu, vnfd, networks_id, security_group_id, nets, router_interfaces, router_id)
+
+ # save template in folder
+ name = vnfd['id'].to_s
+ filename = 'assets/templates/' + name + '.yaml'
+ File.open(filename, 'w') { |file| file.write(nested_template.to_yaml) }
+ url = HotGenerator.manager + '/files/' + name + '.yaml'
+ properties = {
+ image: image_name,
+ flavor: flavor_name
+ }
+
+ networks_id.each do |net|
+ properties[net['heat']] = { 'get_resource' => net['heat'] }
+ end
+ router_interfaces.each do |iface|
+ properties[iface] = { 'get_resource' => iface }
+ end
+ # properties['depends_on'] = router_interfaces
+
+ scaled_resource = GenericResource.new(vdu['id'], url, properties, router_interfaces)
+ auto_scale_group = create_autoscale_group(60, vdu['scale_in_out']['maximum'], vdu['scale_in_out']['minimum'], 1, scaled_resource)
+ scale_out_policy = create_scale_policy(auto_scale_group, 1)
+ scale_in_policy = create_scale_policy(auto_scale_group, -1)
+ @hot.outputs_list << Output.new("#{vdu['id']}#scale_out_url", 'Url of scale out.', get_attr: [scale_out_policy, 'alarm_url'])
+ @hot.outputs_list << Output.new("#{vdu['id']}#scale_in_url", 'Url of scale in.', get_attr: [scale_in_policy, 'alarm_url'])
+ @hot.outputs_list << Output.new("#{vdu['id']}#scale_group", "#{vdu['id']} ID", get_resource: auto_scale_group)
+ else
+ ports = create_ports(vdu['id'], vdu['connection_points'], vnfd['vlinks'], networks_id, security_group_id, router_interfaces)
+ create_server(vdu, image_name, flavor_name, ports, key, false)
+ end
+ end
+
+ # puts @hot.to_yaml
+
+ @hot
+ end
+
+ def generate_nested_template(vdu, vnfd, networks_id, security_group_id, _nets, router_interfaces, _router_id)
+ hot = Hot.new('server')
+ hot.parameters_list = []
+ outputs_list = {}
+ hot.parameters_list << Parameter.new('image', '', 'string')
+ hot.parameters_list << Parameter.new('flavor', '', 'string')
+ # for each network, create a parameter
networks_id.each do |net|
- properties[net['heat']] = {"get_resource" => net['heat']}
+ hot.parameters_list << Parameter.new(net['heat'], '', 'string')
end
router_interfaces.each do |iface|
- properties[iface] = {"get_resource" => iface}
+ hot.parameters_list << Parameter.new(iface, '', 'string')
end
- #properties['depends_on'] = router_interfaces
-
- scaled_resource = GenericResource.new(vdu['id'], url, properties, router_interfaces)
- auto_scale_group = create_autoscale_group(60, vdu['scale_in_out']['maximum'], vdu['scale_in_out']['minimum'], 1, scaled_resource)
- scale_out_policy = create_scale_policy(auto_scale_group, 1)
- scale_in_policy = create_scale_policy(auto_scale_group, -1)
- @hot.outputs_list << Output.new("#{vdu['id']}#scale_out_url", "Url of scale out.", {get_attr: [scale_out_policy, 'alarm_url']})
- @hot.outputs_list << Output.new("#{vdu['id']}#scale_in_url", "Url of scale in.", {get_attr: [scale_in_policy, 'alarm_url']})
- @hot.outputs_list << Output.new("#{vdu['id']}#scale_group", "#{vdu['id']} ID", {get_resource: auto_scale_group})
- else
- ports = create_ports(vdu['id'], vdu['connection_points'], vnfd['vlinks'], networks_id, security_group_id, router_interfaces)
- create_server(vdu, image_name, flavor_name, ports, key, false)
- end
- end
- #puts @hot.to_yaml
+ arr = []
+ router_interfaces.each do |iface|
+ arr << { 'get_param' => iface }
+ end
- @hot
- end
+ ports = []
+ connection_points = vdu['connection_points']
+ vlinks = vnfd['vlinks']
+ vdu_id = vdu['id']
+ auto_scale_name = get_resource_name
+ connection_points.each do |connection_point|
+ vlink = vlinks.find { |vlink| vlink['id'] == connection_point['vlink_ref'] }
+ # detect, and return error if not.
+ network = networks_id.detect { |network| network['alias'] == vlink['alias'] }
+ next if network.nil?
+ port_name = (connection_point['id']).to_s
+ ports << { 'port' => { 'get_resource' => port_name } }
+ if vlink['existing_net_id']
+ if vlink['port_security_enabled']
+ hot.resources_list << Port.new(port_name, network['heat_id'], security_group_id)
+ else
+ hot.resources_list << Port.new(port_name, network['heat_id'])
+ end
+ else
+ if vlink['port_security_enabled']
+ hot.resources_list << Port.new(port_name, { 'get_param' => network['heat'] }, security_group_id)
+ else
+ hot.resources_list << Port.new(port_name, 'get_param' => network['heat'])
+ end
+ end
+ # router_interface_name = get_resource_name_nested(hot)
+ # hot.resources_list << RouterInterface.new(router_interface_name, router_id, nil, {"get_resource" => port_name})
- def generate_nested_template(vdu, vnfd, networks_id, security_group_id, nets, router_interfaces, router_id)
- hot = Hot.new("server")
- hot.parameters_list = []
- outputs_list = {}
- hot.parameters_list << Parameter.new('image', '', 'string')
- hot.parameters_list << Parameter.new('flavor', '', 'string')
- #for each network, create a parameter
- networks_id.each do |net|
- hot.parameters_list << Parameter.new(net['heat'], '', 'string')
- end
- router_interfaces.each do |iface|
- hot.parameters_list << Parameter.new(iface, '', 'string')
- end
+ # Check if it's necessary to create an output for this resource
+ if outputs_list.key?('ip') && outputs_list['ip'].include?(port_name)
+ hot.outputs_list << Output.new("#{port_name}#ip", "#{port_name} IP address", 'get_attr' => [port_name, 'fixed_ips', 0, 'ip_address'])
+ end
- arr = []
- router_interfaces.each do |iface|
- arr << {"get_param" => iface}
+ # Check if the port has a Floating IP
+ if vlink['access']
+ floating_ip_name = get_resource_name_nested(hot)
+ # TODO: Receive the floating ip pool name?
+ hot.resources_list << FloatingIp.new(floating_ip_name, @public_network_id)
+ hot.resources_list << FloatingIpAssociation.new(get_resource_name_nested(hot), { 'get_resource' => floating_ip_name }, { 'get_resource' => port_name }, [])
+ hot.outputs_list << Output.new("#{vdu_id}##{connection_point['id']}#PublicIp", "#{port_name} Floating IP", 'get_attr' => [floating_ip_name, 'floating_ip_address'])
+ @hot.outputs_list << Output.new("#{vdu_id}##{connection_point['id']}#PublicIp", "#{port_name} Nested outputs_list", 'get_attr' => [auto_scale_name, 'outputs_list', "#{vdu_id}##{connection_point['id']}#PublicIp"])
+ else
+ hot.outputs_list << Output.new("#{vdu_id}##{connection_point['id']}#PrivateIp", "#{port_name} Private IP", 'get_attr' => [port_name, 'fixed_ips', 0, 'ip_address'])
+ @hot.outputs_list << Output.new("#{vdu_id}##{connection_point['id']}#fixed_ips#0#ip_address", "#{port_name} Nested outputs_list", 'get_attr' => [auto_scale_name, 'outputs_list', "#{vdu_id}##{connection_point['id']}#PrivateIp"])
+ end
+ end
+
+ hot.resources_list << Server.new(
+ vdu['id'],
+ { 'get_param' => 'flavor' },
+ { 'get_param' => 'image' },
+ ports,
+ add_wait_condition2(vdu, hot),
+ nil
+ )
+ hot.outputs_list << Output.new("#{vdu['id']}#id", "#{vdu['id']} ID", 'get_resource' => vdu['id'])
+ @hot.outputs_list << Output.new("#{vdu['id']}#vdus", "#{vdu['id']} ID", 'get_attr' => [auto_scale_name, 'outputs_list', "#{vdu['id']}#id"])
+ hot
end
- ports = []
- connection_points = vdu['connection_points']
- vlinks = vnfd['vlinks']
- vdu_id = vdu['id']
- auto_scale_name = get_resource_name
- connection_points.each do |connection_point|
- vlink = vlinks.find { |vlink| vlink['id'] == connection_point['vlink_ref'] }
- #detect, and return error if not.
- network = networks_id.detect { |network| network['alias'] == vlink['alias'] }
- if network != nil
- port_name = "#{connection_point['id']}"
- ports << {"port" => {"get_resource" => port_name}}
- if vlink['existing_net_id']
- if vlink['port_security_enabled']
- hot.resources_list << Port.new(port_name, network['heat_id'], security_group_id)
- else
- hot.resources_list << Port.new(port_name, network['heat_id'])
- end
- else
- if vlink['port_security_enabled']
- hot.resources_list << Port.new(port_name, {"get_param" => network['heat']}, security_group_id)
- else
- hot.resources_list << Port.new(port_name, {"get_param" => network['heat']})
- end
+ def create_networks(vlink, dns_server, router_id)
+ network_name = create_network(vlink['id'], vlink['alias'], vlink['port_security_enabled'])
+ cidr = if vlink['net_segment'] && vlink['net_segment'] != ''
+ vlink['net_segment']
+ else
+ '192.' + rand(256).to_s + '.' + rand(256).to_s + '.0/24'
+ end
+ subnet_name = create_subnet(vlink['id'], dns_server, cidr)
+ if vlink['connectivity_type'] == 'E-LAN'
+ # create_router_interface(router_id, subnet_name)
+ elsif vlink['connectivity_type'] == 'E-LINE'
+ # nothig to do
end
- #router_interface_name = get_resource_name_nested(hot)
- #hot.resources_list << RouterInterface.new(router_interface_name, router_id, nil, {"get_resource" => port_name})
- # Check if it's necessary to create an output for this resource
- if outputs_list.has_key?('ip') && outputs_list['ip'].include?(port_name)
- hot.outputs_list << Output.new("#{port_name}#ip", "#{port_name} IP address", {"get_attr" => [port_name, 'fixed_ips', 0, 'ip_address']})
- end
+ router_interface = create_router_interface(router_id, subnet_name, nil)
- # Check if the port has a Floating IP
- if vlink['access']
- floating_ip_name = get_resource_name_nested(hot)
- # TODO: Receive the floating ip pool name?
- hot.resources_list << FloatingIp.new(floating_ip_name, @public_network_id)
- hot.resources_list << FloatingIpAssociation.new(get_resource_name_nested(hot), {"get_resource" => floating_ip_name}, {"get_resource" => port_name}, [])
- hot.outputs_list << Output.new("#{vdu_id}##{connection_point['id']}#PublicIp", "#{port_name} Floating IP", {"get_attr" => [floating_ip_name, 'floating_ip_address']})
- @hot.outputs_list << Output.new("#{vdu_id}##{connection_point['id']}#PublicIp", "#{port_name} Nested outputs_list", {"get_attr" => [auto_scale_name, 'outputs_list', "#{vdu_id}##{connection_point['id']}#PublicIp"]})
- else
- hot.outputs_list << Output.new("#{vdu_id}##{connection_point['id']}#PrivateIp", "#{port_name} Private IP", {"get_attr" => [port_name,'fixed_ips',0,'ip_address']})
- @hot.outputs_list << Output.new("#{vdu_id}##{connection_point['id']}#fixed_ips#0#ip_address", "#{port_name} Nested outputs_list", {"get_attr" => [auto_scale_name, 'outputs_list', "#{vdu_id}##{connection_point['id']}#PrivateIp"]})
- end
- end
+ [network_name, router_interface]
+ end
+ def create_network(resource_name, network_name, port_security_enabled)
+ name = get_resource_name
+ @hot.resources_list << Network.new(resource_name, network_name, port_security_enabled)
+ name
end
- hot.resources_list << Server.new(
- vdu['id'],
- {"get_param" => 'flavor'},
- {"get_param" => 'image'},
- ports,
- add_wait_condition2(vdu, hot),
- nil)
- hot.outputs_list << Output.new("#{vdu['id']}#id", "#{vdu['id']} ID", {"get_resource" => vdu['id']})
- @hot.outputs_list << Output.new("#{vdu['id']}#vdus", "#{vdu['id']} ID", {"get_attr" => [auto_scale_name, 'outputs_list', "#{vdu['id']}#id"]})
- hot
- end
-
- def create_networks(vlink, dns_server, router_id)
- network_name = create_network(vlink['id'], vlink['alias'], vlink['port_security_enabled'])
- if vlink['net_segment'] && vlink['net_segment'] != ""
- cidr = vlink['net_segment']
- else
- cidr = "192." + rand(256).to_s + "." + rand(256).to_s + ".0/24"
+ def create_subnet(network_name, dns_server, cidr)
+ name = get_resource_name
+ @hot.resources_list << Subnet.new(name, { get_resource: network_name }, dns_server, cidr)
+ name
end
- subnet_name = create_subnet(vlink['id'], dns_server, cidr)
- if vlink['connectivity_type'] == 'E-LAN'
- #create_router_interface(router_id, subnet_name)
- elsif vlink['connectivity_type'] == 'E-LINE'
- #nothig to do
+
+ def create_router_interface(router_id, subnet_name, port_name)
+ name = get_resource_name
+ @hot.resources_list << RouterInterface.new(name, router_id, { get_resource: subnet_name }, get_resource: port_name)
+ name
end
- router_interface = create_router_interface(router_id, subnet_name, nil)
-
- return network_name, router_interface
- end
-
- def create_network(resource_name, network_name, port_security_enabled)
- name = get_resource_name
- @hot.resources_list << Network.new(resource_name, network_name, port_security_enabled)
- name
- end
-
- def create_subnet(network_name, dns_server, cidr)
- name = get_resource_name
- @hot.resources_list << Subnet.new(name, {get_resource: network_name}, dns_server, cidr)
- name
- end
-
- def create_router_interface(router_id, subnet_name, port_name)
- name = get_resource_name
- @hot.resources_list << RouterInterface.new(name, router_id, {get_resource: subnet_name}, {get_resource: port_name})
- name
- end
-
- # Parse the outputs from the VNFD and builds an outputs hash
- #
- # @param [Hash] events the VNF lifecycle events
- def parse_outputs(events)
- outputs = []
-
- events.each do |event, event_info|
- unless event_info.nil? || event_info['template_file'].nil?
- raise CustomException::InvalidTemplateFileFormat, "Template file format not supported" unless event_info['template_file_format'].downcase == 'json'
- JSON.parse(event_info['template_file']).each do |id, output|
- unless outputs.include?(output)
- outputs << output
-
- match = output.delete(' ').match(/^get_attr\[(.*)\]$/i).to_a
- if match.size == 0
- puts output
- puts "The match is null."
- else
- string = match[1].split(",").map(&:strip)
- if string.size == 0
- puts "Error getting the 'get_attr' of " + match[1]
- else
- get_attr = {get_attr: []}
- string.each_with_index do |type, i|
- if CommonMethods.is_num?(type)
- get_attr[:get_attr] << type.to_i
- else
- get_attr[:get_attr] << type
- end
+ # Parse the outputs from the VNFD and builds an outputs hash
+ #
+ # @param [Hash] events the VNF lifecycle events
+ def parse_outputs(events)
+ outputs = []
+
+ events.each do |_event, event_info|
+ next if event_info.nil? || event_info['template_file'].nil?
+ raise CustomException::InvalidTemplateFileFormat, 'Template file format not supported' unless event_info['template_file_format'].casecmp('json').zero?
+ JSON.parse(event_info['template_file']).each do |_id, output|
+ next if outputs.include?(output)
+ outputs << output
+
+ match = output.delete(' ').match(/^get_attr\[(.*)\]$/i).to_a
+ if match.empty?
+ puts output
+ puts 'The match is null.'
+ else
+ string = match[1].split(',').map(&:strip)
+ if string.empty?
+ puts "Error getting the 'get_attr' of " + match[1]
+ else
+ get_attr = { get_attr: [] }
+ string.each_with_index do |type, _i|
+ get_attr[:get_attr] << if CommonMethods.is_num?(type)
+ type.to_i
+ else
+ type
+ end
+ end
+
+ if @outputs.key?(match[2])
+ @outputs[match[2]] << match[1]
+ else
+ @outputs[match[2]] = [match[1]]
+ end
+ if string[1] == 'fixed_ips'
+ # @hot.outputs_list << Output.new(id, "", get_attr)
+ end
+ if string[1] != 'PublicIp'
+ # @hot.outputs_list << Output.new(id, "", get_attr)
+ end
+ end
end
+ end
+ end
+ end
+
+ # Creates an HEAT key pair resource
+ #
+ # @param [Hash] keypair_name the Name of the KeyPair
+ # @return [String] the name of the created resource
+ def create_key_pair(keypair_name)
+ name = get_resource_name
+
+ @hot.resources_list << KeyPair.new(name, keypair_name)
+ @hot.outputs_list << Output.new('private_key', 'Private key', get_attr: [name, 'private_key'])
+ name
+ end
- if @outputs.has_key?(match[2])
- @outputs[match[2]] << match[1]
+ # Creates an HEAT image resource from the VNFD
+ #
+ # @param [Hash] vdu the VDU from the VNFD
+ # @return [String] the name of the created resource
+ def create_image(vdu)
+ name = get_resource_name
+
+ raise CustomException::NoExtensionError, "#{vdu['vm_image']} does not have a file extension" if vdu['vm_image_format'].empty?
+ raise CustomException::InvalidExtensionError, "#{vdu['vm_image']} has an invalid extension. Allowed extensions: ami, ari, aki, vhd, vmdk, raw, qcow2, vdi and iso" unless %w(ami ari aki vhd vmdk raw qcow2 vdi iso).include? vdu['vm_image_format']
+
+ @hot.resources_list << Image.new(name, vdu['vm_image_format'], vdu['vm_image'])
+ name
+ end
+
+ # Creates an HEAT port resource from the VNFD
+ #
+ # @param [String] vdu_id the VDU ID from the VNFD
+ # @param [String] vnfc_id the VNFC ID from the VNFD
+ # @param [Array] vnfcs the list of VNFCS for the VDU
+ # @param [Array] networks_id the IDs of the networks created by NS Manager
+ # @param [String] security_group_id the ID of the T-NOVA security group
+ # @return [Array] a list of ports
+ def create_ports(vdu_id, connection_points, vlinks, networks_id, security_group_id, router_interfaces)
+ ports = []
+
+ connection_points.each do |connection_point|
+ vlink = vlinks.find { |vlink| vlink['id'] == connection_point['vlink_ref'] }
+ # detect, and return error if not.
+ network = networks_id.detect { |network| network['alias'] == vlink['alias'] }
+ next if network.nil?
+ port_name = (connection_point['id']).to_s
+ ports << { port: { get_resource: port_name } }
+ if vlink['existing_net_id']
+ if vlink['port_security_enabled']
+ @hot.resources_list << Port.new(port_name, network['heat_id'], security_group_id)
else
- @outputs[match[2]] = [match[1]]
- end
- if string[1] == 'fixed_ips'
- #@hot.outputs_list << Output.new(id, "", get_attr)
+ @hot.resources_list << Port.new(port_name, network['heat_id'])
end
- if string[1] != 'PublicIp'
- #@hot.outputs_list << Output.new(id, "", get_attr)
+ else
+ if vlink['port_security_enabled']
+ @hot.resources_list << Port.new(port_name, { get_resource: network['heat'] }, security_group_id)
+ else
+ @hot.resources_list << Port.new(port_name, get_resource: network['heat'])
end
- end
end
- end
+
+ # Check if it's necessary to create an output for this resource
+ if @outputs.key?('ip') && @outputs['ip'].include?(port_name)
+ @hot.outputs_list << Output.new("#{port_name}#ip", "#{port_name} IP address", get_attr: [port_name, 'fixed_ips', 0, 'ip_address'])
+ end
+
+ # Check if the port has a Floating IP
+ if vlink['access']
+ floating_ip_name = get_resource_name
+ # TODO: Receive the floating ip pool name?
+ @hot.resources_list << FloatingIp.new(floating_ip_name, @public_network_id)
+ @hot.resources_list << FloatingIpAssociation.new(get_resource_name, { get_resource: floating_ip_name }, { get_resource: port_name }, router_interfaces)
+ # @hot.outputs_list << Output.new("#{port_name}#floating_ip", "#{port_name} Floating IP", {get_attr: [floating_ip_name, 'floating_ip_address']})
+ @hot.outputs_list << Output.new("#{vdu_id}##{connection_point['id']}#PublicIp", "#{port_name} Floating IP", get_attr: [floating_ip_name, 'floating_ip_address'])
+ @hot.outputs_list << Output.new("#{vdu_id}##{connection_point['id']}#fixed_ips#0#ip_address", "#{port_name} private address", 'get_attr' => [port_name, 'fixed_ips', 0, 'ip_address'])
+ else
+ @hot.outputs_list << Output.new("#{vdu_id}##{connection_point['id']}#fixed_ips#0#ip_address", "#{port_name} private address", 'get_attr' => [port_name, 'fixed_ips', 0, 'ip_address'])
+ end
end
- end
+
+ ports
+ end
+
+ # Creates an HEAT flavor resource from the VNFD
+ #
+ # @param [Hash] vdu the VDU from the VNFD
+ # @return [String] the name of the created resource
+ def create_flavor(vdu)
+ name = get_resource_name
+ storage_info = vdu['resource_requirements']['storage']
+ @hot.resources_list << Flavor.new(
+ name,
+ unit_converter(storage_info['size'], storage_info['size_unit'], 'gb'),
+ unit_converter(vdu['resource_requirements']['memory'], vdu['resource_requirements']['memory_unit'], 'mb'),
+ vdu['resource_requirements']['vcpus']
+ )
+ name
end
- end
-
- # Creates an HEAT key pair resource
- #
- # @param [Hash] keypair_name the Name of the KeyPair
- # @return [String] the name of the created resource
- def create_key_pair(keypair_name)
- name = get_resource_name
-
- @hot.resources_list << KeyPair.new(name, keypair_name)
- @hot.outputs_list << Output.new("private_key", "Private key", {get_attr: [name, 'private_key']})
- name
- end
-
- # Creates an HEAT image resource from the VNFD
- #
- # @param [Hash] vdu the VDU from the VNFD
- # @return [String] the name of the created resource
- def create_image(vdu)
- name = get_resource_name
-
- raise CustomException::NoExtensionError, "#{vdu['vm_image']} does not have a file extension" if vdu['vm_image_format'].empty?
- raise CustomException::InvalidExtensionError, "#{vdu['vm_image']} has an invalid extension. Allowed extensions: ami, ari, aki, vhd, vmdk, raw, qcow2, vdi and iso" unless ['ami', 'ari', 'aki', 'vhd', 'vmdk', 'raw', 'qcow2', 'vdi', 'iso'].include? vdu['vm_image_format']
-
- @hot.resources_list << Image.new(name, vdu['vm_image_format'], vdu['vm_image'])
- name
- end
-
- # Creates an HEAT port resource from the VNFD
- #
- # @param [String] vdu_id the VDU ID from the VNFD
- # @param [String] vnfc_id the VNFC ID from the VNFD
- # @param [Array] vnfcs the list of VNFCS for the VDU
- # @param [Array] networks_id the IDs of the networks created by NS Manager
- # @param [String] security_group_id the ID of the T-NOVA security group
- # @return [Array] a list of ports
- def create_ports(vdu_id, connection_points, vlinks, networks_id, security_group_id, router_interfaces)
- ports = []
-
- connection_points.each do |connection_point|
- vlink = vlinks.find { |vlink| vlink['id'] == connection_point['vlink_ref'] }
- #detect, and return error if not.
- network = networks_id.detect { |network| network['alias'] == vlink['alias'] }
- if network != nil
- port_name = "#{connection_point['id']}"
- ports << {port: {get_resource: port_name}}
- if vlink['existing_net_id']
- if vlink['port_security_enabled']
- @hot.resources_list << Port.new(port_name, network['heat_id'], security_group_id)
- else
- @hot.resources_list << Port.new(port_name, network['heat_id'])
- end
+
+ # Creates an HEAT server resource from the VNFD
+ #
+ # @param [Hash] vdu the VDU from the VNFD
+ # @param [String] image_name the image resource name
+ # @param [String] flavour_name the flavour resource name
+ # @param [Array] ports list of the ports resource
+ def create_server(vdu, image, flavour_name, ports, key_name, scale)
+ if scale
+ server = Server.new(
+ vdu['id'],
+ flavour_name,
+ image,
+ ports,
+ add_wait_condition(vdu),
+ get_resource: key_name
+ )
else
- if vlink['port_security_enabled']
- @hot.resources_list << Port.new(port_name, {get_resource: network['heat']}, security_group_id)
- else
- @hot.resources_list << Port.new(port_name, {get_resource: network['heat']})
- end
+ @hot.resources_list << Server.new(
+ vdu['id'],
+ flavour_name,
+ image,
+ ports,
+ add_wait_condition(vdu),
+ get_resource: key_name
+ )
+ @hot.outputs_list << Output.new("#{vdu['id']}#id", "#{vdu['id']} ID", get_resource: vdu['id'])
end
- # Check if it's necessary to create an output for this resource
- if @outputs.has_key?('ip') && @outputs['ip'].include?(port_name)
- @hot.outputs_list << Output.new("#{port_name}#ip", "#{port_name} IP address", {get_attr: [port_name, 'fixed_ips', 0, 'ip_address']})
+ server
+ end
+
+ # Adds a Wait Condition resource to the VDU
+ #
+ # @param [Hash] vdu the VDU from the VNFD
+ # @return [Hash] the user_data script with the Wait Condition
+ def add_wait_condition(vdu)
+ wc_handle_name = get_resource_name
+
+ # if vdu['wc_notify']
+ if @type != 'vSA'
+ @hot.resources_list << WaitConditionHandle.new(wc_handle_name)
+ @hot.resources_list << WaitCondition.new(get_resource_name, wc_handle_name, 2000)
end
+ # end
- # Check if the port has a Floating IP
- if vlink['access']
- floating_ip_name = get_resource_name
- # TODO: Receive the floating ip pool name?
- @hot.resources_list << FloatingIp.new(floating_ip_name, @public_network_id)
- @hot.resources_list << FloatingIpAssociation.new(get_resource_name, {get_resource: floating_ip_name}, {get_resource: port_name}, router_interfaces)
- # @hot.outputs_list << Output.new("#{port_name}#floating_ip", "#{port_name} Floating IP", {get_attr: [floating_ip_name, 'floating_ip_address']})
- @hot.outputs_list << Output.new("#{vdu_id}##{connection_point['id']}#PublicIp", "#{port_name} Floating IP", {get_attr: [floating_ip_name, 'floating_ip_address']})
- @hot.outputs_list << Output.new("#{vdu_id}##{connection_point['id']}#fixed_ips#0#ip_address", "#{port_name} private address", {"get_attr" => [port_name,'fixed_ips',0,'ip_address']})
- else
- @hot.outputs_list << Output.new("#{vdu_id}##{connection_point['id']}#fixed_ips#0#ip_address", "#{port_name} private address", {"get_attr" => [port_name,'fixed_ips',0,'ip_address']})
+ wc_notify = ''
+ wc_notify = "\nwc_notify --data-binary '{\"status\": \"SUCCESS\"}'\n"
+ if vdu['wc_notify']
+ wc_notify = "\nwc_notify --data-binary '{\"status\": \"SUCCESS\"}'\n"
+ end
+ if @type == 'vSBC'
+ wc_notify = ''
+ elsif @type == 'vSA'
+ wc_notify = '\n echo "tenor_url: http://10.10.1.61:4000/vnf-provisioning/' + @vnfr_id + '/stack/create_complete" > /etc/tenor.cfg'
+ wc_notify = '\n echo curl -XPOST http://10.10.1.61:4000/vnf-provisioning/' + @vnfr_id + '/stack/create_complete -d "info" '
+ wc_notify = ''
+ wc_notify += "\nwc_notify --data-binary '{\"status\": \"SUCCESS\"}'\n"
end
- end
+ # if vdu['wc_notify']
+ shell = '#!/bin/bash'
+ shell = '#!/bin/tcsh' if @type == 'vSA'
+ if @type != 'vSA'
+ bootstrap_script = vdu.key?('bootstrap_script') ? vdu['bootstrap_script'] : shell
+ {
+ str_replace: {
+ params: {
+ wc_notify: {
+ get_attr: [wc_handle_name, 'curl_cli']
+ }
+ },
+ template: bootstrap_script + wc_notify
+ }
+ }
+ else
+ bootstrap_script = '#!/bin/bash' + wc_notify
+ end
+ # end
end
- ports
- end
-
- # Creates an HEAT flavor resource from the VNFD
- #
- # @param [Hash] vdu the VDU from the VNFD
- # @return [String] the name of the created resource
- def create_flavor(vdu)
- name = get_resource_name
- storage_info = vdu['resource_requirements']['storage']
- @hot.resources_list << Flavor.new(
- name,
- unit_converter(storage_info['size'], storage_info['size_unit'], 'gb'),
- unit_converter(vdu['resource_requirements']['memory'], vdu['resource_requirements']['memory_unit'], 'mb'),
- vdu['resource_requirements']['vcpus'])
- name
- end
-
- # Creates an HEAT server resource from the VNFD
- #
- # @param [Hash] vdu the VDU from the VNFD
- # @param [String] image_name the image resource name
- # @param [String] flavour_name the flavour resource name
- # @param [Array] ports list of the ports resource
- def create_server(vdu, image, flavour_name, ports, key_name, scale)
- if scale
- server = Server.new(
- vdu['id'],
- flavour_name,
- image,
- ports,
- add_wait_condition(vdu),
- {get_resource: key_name})
- else
- @hot.resources_list << Server.new(
- vdu['id'],
- flavour_name,
- image,
- ports,
- add_wait_condition(vdu),
- {get_resource: key_name})
- @hot.outputs_list << Output.new("#{vdu['id']}#id", "#{vdu['id']} ID", {get_resource: vdu['id']})
- end
+ def add_wait_condition2(vdu, hot)
+ wc_handle_name = get_resource_name_nested(hot)
- server
- end
-
- # Adds a Wait Condition resource to the VDU
- #
- # @param [Hash] vdu the VDU from the VNFD
- # @return [Hash] the user_data script with the Wait Condition
- def add_wait_condition(vdu)
- wc_handle_name = get_resource_name
-
- #if vdu['wc_notify']
- if @type != 'vSA'
- @hot.resources_list << WaitConditionHandle.new(wc_handle_name)
- @hot.resources_list << WaitCondition.new(get_resource_name, wc_handle_name, 2000)
- end
- #end
-
- wc_notify = ""
- wc_notify = "\nwc_notify --data-binary '{\"status\": \"SUCCESS\"}'\n"
- if vdu['wc_notify']
- wc_notify = "\nwc_notify --data-binary '{\"status\": \"SUCCESS\"}'\n"
- end
- if @type == 'vSBC'
- wc_notify = ""
- elsif @type == 'vSA'
- wc_notify = '\n echo "tenor_url: http://10.10.1.61:4000/vnf-provisioning/'+ @vnfr_id +'/stack/create_complete" > /etc/tenor.cfg'
- wc_notify = '\n echo curl -XPOST http://10.10.1.61:4000/vnf-provisioning/'+ @vnfr_id +'/stack/create_complete -d "info" '
- wc_notify = ""
- wc_notify = wc_notify + "\nwc_notify --data-binary '{\"status\": \"SUCCESS\"}'\n"
- end
+ # if vdu['wc_notify']
+ if @type != 'vSA' && !vdu['wc_notify'].nil?
+ hot.resources_list << WaitConditionHandle.new(wc_handle_name)
+ hot.resources_list << WaitCondition.new(get_resource_name_nested(hot), wc_handle_name, 2000)
+ # end
+ end
+
+ wc_notify = ''
+ wc_notify = "\nwc_notify --data-binary '{\"status\": \"SUCCESS\"}'\n"
+ if vdu['wc_notify']
+ wc_notify = "\nwc_notify --data-binary '{\"status\": \"SUCCESS\"}'\n"
+ end
- #if vdu['wc_notify']
- shell = "#!/bin/bash"
- if @type == 'vSA'
- shell = "#!/bin/tcsh"
- end
- if @type != 'vSA'
- bootstrap_script = vdu.has_key?('bootstrap_script') ? vdu['bootstrap_script'] : shell
+ shell = '#!/bin/bash'
+ shell = '#!/bin/tcsh' if @type == 'vSA'
+
+ bootstrap_script = vdu.key?('bootstrap_script') ? vdu['bootstrap_script'] : shell
{
- str_replace: {
- params: {
- wc_notify: {
- get_attr: [wc_handle_name, 'curl_cli']
+ 'str_replace' => {
+ 'params' => {
+ 'wc_notify' => {
+ 'get_attr' => [wc_handle_name, 'curl_cli']
}
},
- template: bootstrap_script + wc_notify
+ 'template' => bootstrap_script + wc_notify
}
}
- else
- bootstrap_script = "#!/bin/bash" + wc_notify
- end
- #end
- end
-
- def add_wait_condition2(vdu, hot)
- wc_handle_name = get_resource_name_nested(hot)
-
- #if vdu['wc_notify']
- if @type != 'vSA' && !vdu['wc_notify'].nil?
- hot.resources_list << WaitConditionHandle.new(wc_handle_name)
- hot.resources_list << WaitCondition.new(get_resource_name_nested(hot), wc_handle_name, 2000)
- #end
end
- wc_notify = ""
- wc_notify = "\nwc_notify --data-binary '{\"status\": \"SUCCESS\"}'\n"
- if vdu['wc_notify']
- wc_notify = "\nwc_notify --data-binary '{\"status\": \"SUCCESS\"}'\n"
+ # Generates a new resource name
+ #
+ # @return [String] the generated resource name
+ def get_resource_name
+ @name + '_' + @hot.resources_list.length.to_s unless @name.empty?
end
- shell = "#!/bin/bash"
- if @type == 'vSA'
- shell = "#!/bin/tcsh"
+ def get_resource_name_nested(hot)
+ @name + '_nested_' + hot.resources_list.length.to_s unless @name.empty?
end
- bootstrap_script = vdu.has_key?('bootstrap_script') ? vdu['bootstrap_script'] : shell
- {
- "str_replace" => {
- "params" => {
- "wc_notify" => {
- "get_attr" => [wc_handle_name, 'curl_cli']
- }
- },
- "template" => bootstrap_script + wc_notify
- }
- }
- end
-
- # Generates a new resource name
- #
- # @return [String] the generated resource name
- def get_resource_name
- @name + '_' + @hot.resources_list.length.to_s unless @name.empty?
- end
-
- def get_resource_name_nested(hot)
- @name + '_nested_' + hot.resources_list.length.to_s unless @name.empty?
- end
-
- # Converts a value to another unit
- #
- # @param [Numeric] value the value to convert
- # @param [String] input_unit the unit to convert from
- # @param [String] output_unit the unit to convert to
- # @return [Numeric] the converted value
- def unit_converter(value, input_unit, output_unit)
- return 0 if value == 0
- return value if input_unit.downcase == output_unit.downcase
-
- if input_unit.downcase == 'gb'
- if output_unit.downcase == 'mb'
- return value * 1024
- end
- else
- if input_unit.downcase == 'mb'
- if output_unit.downcase == 'gb'
- return value / 1024
- end
- else
- if input_unit.downcase == 'tb'
- if output_unit.downcase == 'gb'
- return value * 1024
- end
+ # Converts a value to another unit
+ #
+ # @param [Numeric] value the value to convert
+ # @param [String] input_unit the unit to convert from
+ # @param [String] output_unit the unit to convert to
+ # @return [Numeric] the converted value
+ def unit_converter(value, input_unit, output_unit)
+ return 0 if value == 0
+ return value if input_unit.casecmp(output_unit.downcase).zero?
+
+ if input_unit.casecmp('gb').zero?
+ return value * 1024 if output_unit.casecmp('mb').zero?
+ else
+ if input_unit.casecmp('mb').zero?
+ return value / 1024 if output_unit.casecmp('gb').zero?
+ else
+ if input_unit.casecmp('tb').zero?
+ return value * 1024 if output_unit.casecmp('gb').zero?
+ end
+ end
end
- end
end
- end
-
- def create_autoscale_group(cooldown, max_size, min_size, desired_capacity, resource)
- name = get_resource_name
- @hot.resources_list << AutoScalingGroup.new(name, cooldown, max_size, min_size, desired_capacity, resource)
- name
- end
- def create_scale_policy(auto_scaling_group, scaling_adjustment)
- name = get_resource_name
- @hot.resources_list << ScalingPolicy.new(name, {get_resource: auto_scaling_group}, scaling_adjustment)
- name
- end
+ def create_autoscale_group(cooldown, max_size, min_size, desired_capacity, resource)
+ name = get_resource_name
+ @hot.resources_list << AutoScalingGroup.new(name, cooldown, max_size, min_size, desired_capacity, resource)
+ name
+ end
+ def create_scale_policy(auto_scaling_group, scaling_adjustment)
+ name = get_resource_name
+ @hot.resources_list << ScalingPolicy.new(name, { get_resource: auto_scaling_group }, scaling_adjustment)
+ name
+ end
end
diff --git a/hot-generator/routes/hot.rb b/hot-generator/routes/hot.rb
index a8de88e..566f48a 100644
--- a/hot-generator/routes/hot.rb
+++ b/hot-generator/routes/hot.rb
@@ -17,197 +17,193 @@
#
# @see OrchestratorHotGenerator
class HotGenerator < Sinatra::Application
+ # @method post_hot_flavour
+ # @overload post '/hot/:flavour'
+ # Convert a VNFD into a HOT
+ # @param [String] flavour the T-NOVA flavour to generate the HOT
+ # @param [JSON] the VNFD to convert
+ # Convert a VNFD into a HOT
+ post '/hot/:flavour' do
+ # Return if content-type is invalid
+ halt 415 unless request.content_type == 'application/json'
+
+ # Validate JSON format
+ provision_info = JSON.parse(request.body.read)
+ # return 400, errors.to_json if errors
- # @method post_hot_flavour
- # @overload post '/hot/:flavour'
- # Convert a VNFD into a HOT
- # @param [String] flavour the T-NOVA flavour to generate the HOT
- # @param [JSON] the VNFD to convert
- # Convert a VNFD into a HOT
- post '/hot/:flavour' do
- # Return if content-type is invalid
- halt 415 unless request.content_type == 'application/json'
+ vnf = provision_info['vnf']
+
+ networks_id = provision_info['networks_id']
+ halt 400, 'Networks ID not found' if networks_id.nil?
- # Validate JSON format
- provision_info = JSON.parse(request.body.read)
- #return 400, errors.to_json if errors
+ routers_id = provision_info['routers_id']
+ halt 400, 'Routers ID not found' if routers_id.nil?
- vnf = provision_info['vnf']
+ security_group_id = nil if provision_info['security_group_id'].nil?
- networks_id = provision_info['networks_id']
- halt 400, 'Networks ID not found' if networks_id.nil?
+ vnfr_id = provision_info['vnfr_id']
+ halt 400, 'Vnfr ID not found' if vnfr_id.nil?
- routers_id = provision_info['routers_id']
- halt 400, 'Routers ID not found' if routers_id.nil?
+ logger.debug 'Networks IDs: ' + networks_id.to_json
+ logger.debug 'Security Group ID: ' + security_group_id.to_json
- if provision_info['security_group_id'].nil?
- security_group_id = nil
- end
+ dns_server = provision_info['dns_server']
+ halt 400, 'DNS server not found' if dns_server.nil?
- vnfr_id = provision_info['vnfr_id']
- halt 400, 'Vnfr ID not found' if vnfr_id.nil?
+ public_network_id = provision_info['public_network_id']
+ halt 400, 'Public Network ID not found' if public_network_id.nil?
- logger.debug 'Networks IDs: ' + networks_id.to_json
- logger.debug 'Security Group ID: ' + security_group_id.to_json
+ flavours = provision_info['flavours']
+ # TODO: if flavour is not an array, return 400
+ # halt 400, 'Public Network ID not found' if flavours.nil?
- dns_server = provision_info['dns_server']
- halt 400, 'DNS server not found' if dns_server.nil?
+ # Build a HOT template
+ logger.debug 'T-NOVA flavour: ' + params[:flavour]
+ hot = CommonMethods.generate_hot_template(vnf['vnfd'], params[:flavour], networks_id, routers_id, security_group_id, vnfr_id, dns_server, public_network_id, flavours)
- public_network_id = provision_info['public_network_id']
- halt 400, 'Public Network ID not found' if public_network_id.nil?
+ halt 200, hot.to_json
+ end
- flavours = provision_info['flavours']
- # TODO if flavour is not an array, return 400
- #halt 400, 'Public Network ID not found' if flavours.nil?
+ # @method post_networkhot_flavour
+ # @overload post '/networkhot/:flavour'
+ # Build a HOT to create the networks
+ # @param [String] flavour the T-NOVA flavour to generate the HOT
+ # @param [JSON] the networks information
+ # Convert a VNFD into a HOT
+ post '/networkhot/:flavour' do
+ # Return if content-type is invalid
+ halt 415 unless request.content_type == 'application/json'
- # Build a HOT template
- logger.debug 'T-NOVA flavour: ' + params[:flavour]
- hot = CommonMethods.generate_hot_template(vnf['vnfd'], params[:flavour], networks_id, routers_id, security_group_id, vnfr_id, dns_server, public_network_id, flavours)
+ # Validate JSON format
+ networkInfo = JSON.parse(request.body.read)
+ # return 400, errors.to_json if errors
- halt 200, hot.to_json
- end
+ nsr_id = networkInfo['nsr_id']
+ halt 400, 'NSR ID not found' if nsr_id.nil?
- # @method post_networkhot_flavour
- # @overload post '/networkhot/:flavour'
- # Build a HOT to create the networks
- # @param [String] flavour the T-NOVA flavour to generate the HOT
- # @param [JSON] the networks information
- # Convert a VNFD into a HOT
- post '/networkhot/:flavour' do
- # Return if content-type is invalid
- halt 415 unless request.content_type == 'application/json'
+ nsd = networkInfo['nsd']
+ halt 400, 'NSD not found' if nsd.nil?
- # Validate JSON format
- networkInfo = JSON.parse(request.body.read)
- #return 400, errors.to_json if errors
+ public_net_id = networkInfo['public_net_id']
+ halt 400, 'Public network ID not found' if public_net_id.nil?
- nsr_id = networkInfo['nsr_id']
- halt 400, 'NSR ID not found' if nsr_id.nil?
+ dns_server = networkInfo['dns_server']
+ halt 400, 'DNS server not found' if dns_server.nil?
- nsd = networkInfo['nsd']
- halt 400, 'NSD not found' if nsd.nil?
+ # Build a HOT template
+ logger.debug 'T-NOVA flavour: ' + params[:flavour]
+ hot = CommonMethods.generate_network_hot_template(nsd, public_net_id, dns_server, params[:flavour], nsr_id)
- public_net_id = networkInfo['public_net_id']
- halt 400, 'Public network ID not found' if public_net_id.nil?
+ halt 200, hot.to_json
+ end
- dns_server = networkInfo['dns_server']
- halt 400, 'DNS server not found' if dns_server.nil?
+ # @method post_wicmhot
+ # @overload post '/wicmhot'
+ # Build a HOT to create the WICM-SFC integration
+ # Convert a VNFD into a HOT
+ post '/wicmhot' do
+ # Return if content-type is invalid
+ halt 415 unless request.content_type == 'application/json'
- # Build a HOT template
- logger.debug 'T-NOVA flavour: ' + params[:flavour]
- hot = CommonMethods.generate_network_hot_template(nsd, public_net_id, dns_server, params[:flavour], nsr_id)
+ # Validate JSON format
+ provider_info = JSON.parse(request.body.read)
+ # return 400, errors.to_json if errors
- halt 200, hot.to_json
- end
+ # Build a HOT template
+ hot = CommonMethods.generate_wicm_hot_template(provider_info)
- # @method post_wicmhot
- # @overload post '/wicmhot'
- # Build a HOT to create the WICM-SFC integration
- # Convert a VNFD into a HOT
- post '/wicmhot' do
- # Return if content-type is invalid
- halt 415 unless request.content_type == 'application/json'
+ halt 200, hot.to_json
+ end
- # Validate JSON format
- provider_info = JSON.parse(request.body.read)
- #return 400, errors.to_json if errors
+ # @method post_networkhot_flavour
+ # @overload post '/networkhot/:flavour'
+ # Build a HOT to create the networks
+ # @param [String] flavour the T-NOVA flavour to generate the HOT
+ # @param [JSON] the networks information
+ # Convert a VNFD into a HOT
+ post '/scale/:flavour' do
+ # Return if content-type is invalid
+ halt 415 unless request.content_type == 'application/json'
- # Build a HOT template
- hot = CommonMethods.generate_wicm_hot_template(provider_info)
+ # Validate JSON format
+ provision_info = JSON.parse(request.body.read)
+ # return 400, errors.to_json if errors
- halt 200, hot.to_json
- end
+ vnf = provision_info['vnf']
- # @method post_networkhot_flavour
- # @overload post '/networkhot/:flavour'
- # Build a HOT to create the networks
- # @param [String] flavour the T-NOVA flavour to generate the HOT
- # @param [JSON] the networks information
- # Convert a VNFD into a HOT
- post '/scale/:flavour' do
- # Return if content-type is invalid
- halt 415 unless request.content_type == 'application/json'
+ networks_id = provision_info['networks_id']
+ halt 400, 'Networks ID not found' if networks_id.nil?
- # Validate JSON format
- provision_info = JSON.parse(request.body.read)
- #return 400, errors.to_json if errors
+ security_group_id = provision_info['security_group_id']
+ halt 400, 'Security group ID not found' if security_group_id.nil?
- vnf = provision_info['vnf']
+ vdus_deployed_info = provision_info['vdus_deployed_info']
+ halt 400, 'VDUs info not found' if vdus_deployed_info.nil?
- networks_id = provision_info['networks_id']
- halt 400, 'Networks ID not found' if networks_id.nil?
+ public_network_id = provision_info['public_network_id']
+ halt 400, 'Public Network ID not found' if public_network_id.nil?
- security_group_id = provision_info['security_group_id']
- halt 400, 'Security group ID not found' if security_group_id.nil?
+ logger.debug 'Networks IDs: ' + networks_id.to_json
+ logger.debug 'Security Group ID: ' + security_group_id.to_json
- vdus_deployed_info= provision_info['vdus_deployed_info']
- halt 400, 'VDUs info not found' if vdus_deployed_info.nil?
+ # Build a HOT template
+ logger.debug 'Scale T-NOVA flavour: ' + params[:flavour]
+ hot = CommonMethods.generate_hot_template_scaling(vnf['vnfd'], params[:flavour], networks_id, security_group_id, public_network_id, vdus_deployed_info)
- public_network_id = provision_info['public_network_id']
- halt 400, 'Public Network ID not found' if public_network_id.nil?
+ halt 200, hot.to_json
+ end
- logger.debug 'Networks IDs: ' + networks_id.to_json
- logger.debug 'Security Group ID: ' + security_group_id.to_json
+ # @method post_netflochot
+ # @overload post '/netfloc'
+ # Build a HOT to create the Netfloc integration
+ # Convert a VNFFG into a HOT
+ post '/netfloc' do
+ # Return if content-type is invalid
+ halt 415 unless request.content_type == 'application/json'
- # Build a HOT template
- logger.debug 'Scale T-NOVA flavour: ' + params[:flavour]
- hot = CommonMethods.generate_hot_template_scaling(vnf['vnfd'], params[:flavour], networks_id, security_group_id, public_network_id, vdus_deployed_info)
+ # Validate JSON format
+ provision_info = JSON.parse(request.body.read)
+ # return 400, errors.to_json if errors
- halt 200, hot.to_json
- end
+ ports = provision_info['ports']
+ halt 400, 'Ports not found' if ports.nil?
- # @method post_netflochot
- # @overload post '/netfloc'
- # Build a HOT to create the Netfloc integration
- # Convert a VNFFG into a HOT
- post '/netfloc' do
- # Return if content-type is invalid
- halt 415 unless request.content_type == 'application/json'
+ odl_username = provision_info['odl_username']
+ halt 400, 'ODL username not found' if odl_username.nil?
- # Validate JSON format
- provision_info = JSON.parse(request.body.read)
- #return 400, errors.to_json if errors
+ odl_password = provision_info['odl_password']
+ halt 400, 'ODL password not found' if odl_password.nil?
- ports = provision_info['ports']
- halt 400, 'Ports not found' if ports.nil?
+ netfloc_ip_port = provision_info['netfloc_ip_port']
+ halt 400, 'Netfloc IP not found' if netfloc_ip_port.nil?
- odl_username = provision_info['odl_username']
- halt 400, 'ODL username not found' if odl_username.nil?
+ # Build a HOT template
+ hot = CommonMethods.generate_netfloc_hot_template(ports, odl_username, odl_password, netfloc_ip_port)
- odl_password = provision_info['odl_password']
- halt 400, 'ODL password not found' if odl_password.nil?
+ halt 200, hot.to_json
+ end
- netfloc_ip_port = provision_info['netfloc_ip_port']
- halt 400, 'Netfloc IP not found' if netfloc_ip_port.nil?
+ # @method post_userhot
+ # @overload post '/userhot'
+ # Build a HOT to create the Users and Projects
+ post '/userhot' do
+ # Return if content-type is invalid
+ halt 415 unless request.content_type == 'application/json'
- # Build a HOT template
- hot = CommonMethods.generate_netfloc_hot_template(ports, odl_username, odl_password, netfloc_ip_port)
+ # Validate JSON format
+ credentials_info = JSON.parse(request.body.read)
- halt 200, hot.to_json
- end
+ halt 400, 'Username not found' if credentials_info['username'].nil?
+ halt 400, 'Password not found' if credentials_info['password'].nil?
+ halt 400, 'Project name not found' if credentials_info['project_name'].nil?
- # @method post_userhot
- # @overload post '/userhot'
- # Build a HOT to create the Users and Projects
- post '/userhot' do
- # Return if content-type is invalid
- halt 415 unless request.content_type == 'application/json'
+ # Build a HOT template
+ hot = CommonMethods.generate_user_hot_template(credentials_info)
- # Validate JSON format
- credentials_info = JSON.parse(request.body.read)
-
- halt 400, 'Username not found' if credentials_info['username'].nil?
- halt 400, 'Password not found' if credentials_info['password'].nil?
- halt 400, 'Project name not found' if credentials_info['project_name'].nil?
-
- # Build a HOT template
- hot = CommonMethods.generate_user_hot_template(credentials_info)
-
- halt 200, hot.to_json
- end
-
- get '/files/:file_name' do
- File.read(File.join('assets/templates', params[:file_name]))
- end
+ halt 200, hot.to_json
+ end
+ get '/files/:file_name' do
+ File.read(File.join('assets/templates', params[:file_name]))
+ end
end
diff --git a/ns-catalogue/.rspec b/ns-catalogue/.rspec
new file mode 100644
index 0000000..83e16f8
--- /dev/null
+++ b/ns-catalogue/.rspec
@@ -0,0 +1,2 @@
+--color
+--require spec_helper
diff --git a/ns-catalogue/config/config.yml.sample b/ns-catalogue/config/config.yml.sample
index 900c57f..3e0ee87 100644
--- a/ns-catalogue/config/config.yml.sample
+++ b/ns-catalogue/config/config.yml.sample
@@ -13,5 +13,4 @@ logger_host: 127.0.0.1
logger_port: 24224
nsd_validator: localhost:4015
-
dependencies: [nsd_validator]
diff --git a/ns-catalogue/routes/ns.rb b/ns-catalogue/routes/ns.rb
index 681f240..4063bcb 100644
--- a/ns-catalogue/routes/ns.rb
+++ b/ns-catalogue/routes/ns.rb
@@ -16,159 +16,156 @@
# limitations under the License.
# @see NsCatalogue
class Catalogue < NsCatalogue
-
- # @method get_network_services
- # @overload get '/network-services'
- # Returns a list of NSs
- get '/' do
- params[:offset] ||= 1
- params[:limit] ||= 20
-
- # Only accept positive numbers
- params[:offset] = 1 if params[:offset].to_i < 1
- params[:limit] = 2 if params[:limit].to_i < 1
-
- # Get paginated list
- nss = Ns.paginate(:page => params[:offset], :limit => params[:limit])
-
- # Build HTTP Link Header
- headers['Link'] = build_http_link(params[:offset].to_i, params[:limit])
-
- begin
- return 200, nss.to_json
- rescue
- logger.error "Error Establishing a Database Connection"
- return 500, "Error Establishing a Database Connection"
+ # @method get_network_services
+ # @overload get '/network-services'
+ # Returns a list of NSs
+ get '/' do
+ params[:offset] ||= 1
+ params[:limit] ||= 20
+
+ # Only accept positive numbers
+ params[:offset] = 1 if params[:offset].to_i < 1
+ params[:limit] = 2 if params[:limit].to_i < 1
+
+ # Get paginated list
+ nss = Ns.paginate(page: params[:offset], limit: params[:limit])
+
+ # Build HTTP Link Header
+ headers['Link'] = build_http_link(params[:offset].to_i, params[:limit])
+
+ begin
+ return 200, nss.to_json
+ rescue
+ logger.error 'Error Establishing a Database Connection'
+ return 500, 'Error Establishing a Database Connection'
+ end
end
- end
-
- # @method get_network_services_id
- # @overload get '/network-services/:external_ns_id'
- # Show a NS
- # @param [Integer] external_ns_id NS external ID
- get '/:id' do |id|
- begin
- ns = Ns.find_by({"nsd.id" => id})
- rescue Mongoid::Errors::DocumentNotFound => e
- logger.error 'NSD not found.'
- halt 404
- end
- return 200, ns.nsd.to_json
- #NsSerializer.new(ns).to_json
- end
-
- # @method post_network_services
- # @overload post '/network-services'
- # Post a NS in JSON format
- # @param [JSON] NS in JSON format
- post '/' do
- # Return if content-type is invalid
- return 415 unless request.content_type == 'application/json'
-
- # Validate JSON format
- ns, errors = parse_json(request.body.read)
- return 400, errors.to_json if errors
-
- # Validate NS
- return 400, 'ERROR: NSD not found' unless ns.has_key?('nsd')
-
- # Validate NSD
- begin
- RestClient.post settings.nsd_validator + '/nsds', ns.to_json, :content_type => :json
- rescue Errno::ECONNREFUSED
- logger.error 'NSD Validator unreachable'
- halt 500, 'NSD Validator unreachable'
- rescue => e
- logger.error e
- halt e.response.code, e.response.body
+ # @method get_network_services_id
+ # @overload get '/network-services/:external_ns_id'
+ # Show a NS
+ # @param [Integer] external_ns_id NS external ID
+ get '/:id' do |id|
+ begin
+ ns = Ns.find_by('nsd.id' => id)
+ rescue Mongoid::Errors::DocumentNotFound => e
+ logger.error 'NSD not found.'
+ halt 404
+ end
+ return 200, ns.nsd.to_json
+ # NsSerializer.new(ns).to_json
end
- begin
- ns = Ns.find_by({"nsd.id" => ns['nsd']['id'], "nsd.version" => ns['nsd']['version'], "nsd.vendor" => ns['nsd']['vendor']})
- logger.error ns
- if ns != nil
- logger.error 'ERROR: Duplicated NS ID, Version or Vendor'
- return 409, 'ERROR: Duplicated NS ID, Version or Vendor'
- end
- rescue Mongoid::Errors::DocumentNotFound => e
+ # @method post_network_services
+ # @overload post '/network-services'
+ # Post a NS in JSON format
+ # @param [JSON] NS in JSON format
+ post '/' do
+ # Return if content-type is invalid
+ return 415 unless request.content_type == 'application/json'
+
+ # Validate JSON format
+ ns, errors = parse_json(request.body.read)
+ return 400, errors.to_json if errors
+
+ # Validate NS
+ return 400, 'ERROR: NSD not found' unless ns.key?('nsd')
+
+ # Validate NSD
+ begin
+ RestClient.post settings.nsd_validator + '/nsds', ns.to_json, content_type: :json
+ rescue Errno::ECONNREFUSED
+ logger.error 'NSD Validator unreachable'
+ halt 500, 'NSD Validator unreachable'
+ rescue => e
+ logger.error e
+ halt e.response.code, e.response.body
+ end
+
+ begin
+ ns = Ns.find_by('nsd.id' => ns['nsd']['id'], 'nsd.version' => ns['nsd']['version'], 'nsd.vendor' => ns['nsd']['vendor'])
+ logger.error ns
+ unless ns.nil?
+ logger.error 'ERROR: Duplicated NS ID, Version or Vendor'
+ return 409, 'ERROR: Duplicated NS ID, Version or Vendor'
+ end
+ rescue Mongoid::Errors::DocumentNotFound => e
+ end
+
+ # Save to BD
+ begin
+ new_ns = Ns.create!(ns)
+ rescue Moped::Errors::OperationFailure => e
+ return 400, 'ERROR: Duplicated NS ID' if e.message.include? 'E11000'
+ rescue => e
+ logger.error 'Some other error.'
+ logger.error e
+ end
+
+ return 200, new_ns.to_json
end
- # Save to BD
- begin
- new_ns = Ns.create!(ns)
- rescue Moped::Errors::OperationFailure => e
- return 400, 'ERROR: Duplicated NS ID' if e.message.include? 'E11000'
- rescue => e
- logger.error "Some other error."
- logger.error e
+ # @method put_nss
+ # @overload put '/network-services/:id'
+ # Update a NS
+ # @param [JSON] NS in JSON format
+ put '/:external_ns_id' do
+ # Return if content-type is invalid
+ return 415 unless request.content_type == 'application/json'
+
+ # Validate JSON format
+ new_ns, errors = parse_json(request.body.read)
+ return 400, errors.to_json if errors
+
+ begin
+ ns = Ns.find_by('nsd.id' => params[:external_ns_id])
+ rescue Mongoid::Errors::DocumentNotFound => e
+ return 400, 'This NSD no exists'
+ end
+
+ nsd = {}
+ prng = Random.new
+ new_ns['id'] = new_ns['id'] + prng.rand(1000).to_s
+ nsd['nsd'] = new_ns
+
+ # Validate NSD
+ begin
+ RestClient.post settings.nsd_validator + '/nsds', nsd.to_json, content_type: :json
+ rescue => e
+ logger.error e.response
+ return e.response.code, e.response.body
+ end
+
+ begin
+ new_ns = Ns.create!(nsd)
+ rescue Moped::Errors::OperationFailure => e
+ return 400, 'ERROR: Duplicated NS ID' if e.message.include? 'E11000'
+ end
+
+ return 200, new_ns.to_json
end
- return 200, new_ns.to_json
- end
-
- # @method put_nss
- # @overload put '/network-services/:id'
- # Update a NS
- # @param [JSON] NS in JSON format
- put '/:external_ns_id' do
-
- # Return if content-type is invalid
- return 415 unless request.content_type == 'application/json'
-
- # Validate JSON format
- new_ns, errors = parse_json(request.body.read)
- return 400, errors.to_json if errors
-
- begin
- ns = Ns.find_by({"nsd.id" => params[:external_ns_id]})
- rescue Mongoid::Errors::DocumentNotFound => e
- return 400, 'This NSD no exists'
- end
-
- nsd = {}
- prng = Random.new
- new_ns['id'] = new_ns['id'] + prng.rand(1000).to_s
- nsd['nsd'] = new_ns
-
- # Validate NSD
- begin
- RestClient.post settings.nsd_validator + '/nsds', nsd.to_json, :content_type => :json
- rescue => e
- logger.error e.response
- return e.response.code, e.response.body
+ # @method delete_ns_id
+ # @overload delete '/network-services/:external_vnf_id'
+ # Delete a NS by its ID
+ # @param [Integer] external_ns_id NS external ID
+ delete '/:external_ns_id' do
+ begin
+ # ns = Ns.find( params[:external_ns_id] )
+ ns = Ns.find_by('nsd.id' => params[:external_ns_id])
+ rescue Mongoid::Errors::DocumentNotFound => e
+ halt 404
+ end
+ ns.destroy
+ return 200
end
- begin
- new_ns = Ns.create!(nsd)
- rescue Moped::Errors::OperationFailure => e
- return 400, 'ERROR: Duplicated NS ID' if e.message.include? 'E11000'
- end
-
- return 200, new_ns.to_json
- end
-
- # @method delete_ns_id
- # @overload delete '/network-services/:external_vnf_id'
- # Delete a NS by its ID
- # @param [Integer] external_ns_id NS external ID
- delete '/:external_ns_id' do
- begin
- #ns = Ns.find( params[:external_ns_id] )
- ns = Ns.find_by({"nsd.id" => params[:external_ns_id]})
- rescue Mongoid::Errors::DocumentNotFound => e
- halt 404
- end
- ns.destroy
- return 200
- end
-
- get '/vnf/:vnf_id' do
- begin
- nss = Ns.find_by({"nsd.vnfds" => params[:vnf_id]})
- rescue Mongoid::Errors::DocumentNotFound => e
- halt 404, "No services using this VNFD"
+ get '/vnf/:vnf_id' do
+ begin
+ nss = Ns.find_by('nsd.vnfds' => params[:vnf_id])
+ rescue Mongoid::Errors::DocumentNotFound => e
+ halt 404, 'No services using this VNFD'
+ end
+ return 200, nss.to_json
end
- return 200, nss.to_json
- end
end
diff --git a/ns-manager/config/config.yml.sample b/ns-manager/config/config.yml.sample
index e14a10c..7ae657c 100644
--- a/ns-manager/config/config.yml.sample
+++ b/ns-manager/config/config.yml.sample
@@ -11,14 +11,3 @@ daemonize: false
threaded: true
logger_host: 127.0.0.1
logger_port: 24224
-
-#ns_catalogue: http://localhost:4011
-#ns_provisioner: http://localhost:4012
-#ns_monitoring: http://localhost:4014
-#ns_sla_enforcment: http://localhost:4016
-
-gatekeeper: http://localhost:8000
-gk_token:
-gk_user: t-nova-admin
-gk_user_id: 1
-gk_pass: Eq7K8h9gpg
diff --git a/ns-manager/helpers/config.rb b/ns-manager/helpers/config.rb
index 3bdbb10..f4493dd 100644
--- a/ns-manager/helpers/config.rb
+++ b/ns-manager/helpers/config.rb
@@ -17,177 +17,112 @@
#
# @see ServiceConfigurationHelper
module ServiceConfigurationHelper
-
- def is_port_open?(ip, port)
- begin
- Timeout::timeout(1) do
- begin
- s = TCPSocket.new(ip, port)
- s.close
- return true
- rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
- return false
- end
- end
- rescue Timeout::Error
- end
- return false
- end
-
- def self.get_module(name)
- begin
- service = Service.find_by(name: name)
- rescue Mongoid::Errors::DocumentNotFound => e
- return 500, name + " not registred."
+ def self.is_port_open?(ip, port)
+ begin
+ Timeout.timeout(1) do
+ begin
+ s = TCPSocket.new(ip, port)
+ s.close
+ return true
+ rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
+ return false
+ end
+ end
+ rescue Timeout::Error
+ end
+ false
end
- service.host = service.host + ":" + service.port.to_s
- service
- end
-
- def registerService(json)
- @json = JSON.parse(json)
- @json[:type] = "internal"
-
- AuthenticationHelper.loginGK()
- gkServices = AuthenticationHelper.getGKServices()
- index = 0
- while index < gkServices['shortname'].length do
- if gkServices['shortname'][index] == @json['name']
+ def self.get_module_by_id(id)
begin
- @service = ServiceModel.find_by(:name => @json['name'])
- @json['service_key'] = gkServices['service-key'][index]
- serviceUri = @json['host'] + ":" + @json['port'].to_s
- AuthenticationHelper.sendServiceAuth(serviceUri, gkServices['service-key'][index])
- @service.update_attributes(@json)
- return "Service updated"
+ s = Service.find(id)
rescue Mongoid::Errors::DocumentNotFound => e
- @json['service_key'] = gkServices['service-key'][index]
- @service = ServiceModel.create!(@json)
- serviceUri = @json['host'] + ":" + @json['port'].to_s
- AuthenticationHelper.sendServiceAuth(serviceUri, gkServices['service-key'][index])
- return "Service registered"
+ return 500, name + ' not registred.'
end
- end
- index +=1
+ s
end
- if index === gkServices['shortname'].length
- begin
- @service = ServiceModel.find_by(:name => @json['name'])
- key = registerServiceinGK(@json['name'])
- metadata = JSON.parse(key)
- @json['service_key'] = gkServices['service-key'][index]
- access = @json['host'] + ":" + @json['port'].to_s
- AuthenticationHelper.sendServiceAuth(access, metadata["info"][0]["service-key"])
- @service.update_attributes(@json)
- return "Service updated"
- rescue Mongoid::Errors::DocumentNotFound => e
+ def self.get_module(name)
begin
- key = registerServiceinGK(@json['name'])
- metadata = JSON.parse(key)
- @json['service_key'] = gkServices['service-key'][index]
- access = @json['host'] + ":" + @json['port'].to_s
- AuthenticationHelper.sendServiceAuth(access, metadata["info"][0]["service-key"])
- @service = ServiceModel.create!(@json)
- return "Service registered"
- rescue => e
- logger.error e
- halt 500, {'Content-Type' => 'text/plain'}, "Error registering the service"
+ s = Service.find_by(name: name)
+ rescue Mongoid::Errors::DocumentNotFound => e
+ return 500, name + ' not registred.'
end
- end
+ s.host = s.host + ':' + s.port.to_s
+ s
end
- end
- def registerExternalService()
- @json = JSON.parse(json)
- @json[:type] = "external"
- begin
- @service = ServiceModel.find_by(:name => @json['name'])
- @service.update_attributes(@json)
- return "Service updated"
- rescue Mongoid::Errors::DocumentNotFound => e
- begin
- @service = ServiceModel.create!(@json)
- return "Service registered"
- rescue => e
- logger.error e
- halt 500, {'Content-Type' => 'text/plain'}, "Error registering the service"
- end
+ def self.get_module_by_type(type)
+ begin
+ s = Service.find_by(type: type)
+ rescue Mongoid::Errors::DocumentNotFound => e
+ return 500, name + ' not registred.'
+ end
+ s.host + ':' + s.port.to_s
end
- end
-
- def unregisterService(name)
- settings.services[name] = nil
- ServiceModel.find_by(name: params["microservice"]).delete
- end
- def updateService(service)
- @service = ServiceModel.find_by(name: params["name"])
- @service.update_attributes(@json)
- end
-
- # Unregister all the services
- def unRegisterAllService
- ServiceModel.delete_all
- end
-
- # Check if the token of service is correct
- def auth(key)
- #TODO
- #return response
- status 201
- end
+ def self.get_modules
+ begin
+ services = Service.all
+ rescue => e
+ logger.error e
+ end
+ services
+ end
- def self.getServices()
- begin
- @services = ServiceModel.all
- rescue => e
- puts e
+ def self.publishModules
+ services = get_modules
+ services.each do |service|
+ logger.debug 'Sending dependencies to ' + service['name']
+ if service['type'] == ''
+ service['depends_on'].each do |serv|
+ begin
+ logger.debug "Checking if dependant Services of #{serv} is Up and Running...."
+ s = Service.where(name: serv).first
+ next if s.nil?
+ dependant_status = is_port_open?(s['host'], s['port'])
+ if dependant_status == false
+ logger.debug "Service found but is down."
+ s.destroy
+ else
+ dep = { name: s['name'], host: s['host'], port: s['port'], token: s['token'], depends_on: s['depends_on'] }
+ send_dependencies_to_module(service, dep)
+ begin
+ RestClient.post service['host'] + ':' + service['port'] + '/gk_dependencies', dep.to_json, content_type: :json, 'X-Auth-Token' => service['token']
+ rescue => e
+ logger.error e
+ end
+ end
+ rescue Mongoid::Errors::DocumentNotFound => e
+ logger.error 'Service not found.'
+ end
+ end
+ elsif service['type'] == 'manager'
+ send_dependencies_to_manager(service, service['depends_on'])
+ end
+ end
end
- return @services
- end
- def self.getService(name)
- begin
- @service = ServiceModel.find_by(:name => name)
- rescue => e
- puts e
+ def self.send_dependencies_to_module(s, dep)
+ begin
+ RestClient.post s['host'] + ':' + s['port'] + '/gk_dependencies', dep.to_json, :content_type => :json, 'X-Auth-Token' => s['token']
+ rescue => e
+ logger.error e
+ end
end
- return @service
- end
- def self.publishServices
- services = getServices()
- services.each do |service|
- logger.debug "Sending dependencies to " + service['name']
- if service['type'] == "internal"
- begin
- RestClient.post service['host'] + ":" + service['port'] + "/gk_dependencies", services.to_json, :content_type => :json
- rescue => e
- #logger.error e
- #puts e
- #halt 500, {'Content-Type' => 'text/plain'}, "Error sending dependencies to " +service['name']
+ def self.send_dependencies_to_manager(manager, depends_on)
+ depends_on.each do |dep|
+ begin
+ RestClient.post manager[:host] + ':' + manager[:port].to_s + '/modules/services', dep.to_json, :content_type => :json, 'X-Auth-Token' => manager['token']
+ rescue => e
+ logger.error e
+ end
end
- end
end
- end
- def self.publishService(name)
- services = getServices
- service = getService(name)
- begin
- RestClient.post service['host'] + ":" + service['port'] + "/gk_dependencies", services.to_json, :content_type => :json
- rescue => e
- #logger.error e
- puts e
- #halt 500, {'Content-Type' => 'text/plain'}, "Error sending dependencies to " +service['name']
+ # Global, memoized, lazy initialized instance of a logger
+ def self.logger
+ @logger ||= TnovaManager.logger
end
-
- end
-
- # Global, memoized, lazy initialized instance of a logger
- def self.logger
- @logger ||= TnovaManager.logger
- end
end
diff --git a/ns-manager/helpers/dc.rb b/ns-manager/helpers/dc.rb
index 77068d9..5ee5bbe 100644
--- a/ns-manager/helpers/dc.rb
+++ b/ns-manager/helpers/dc.rb
@@ -16,7 +16,7 @@
# limitations under the License.
#
# @see ApplicationHelper
-module GatekeeperHelper
+module DcHelper
# Get list of PoPs
#
@@ -24,7 +24,7 @@ module GatekeeperHelper
# @return [String] the object converted into the expected format.
def getDcs()
begin
- return 200, Dc.all.to_json
+ return Dc.all.to_json
rescue => e
logger.error e
logger.error 'Error Establishing a Database Connection'
diff --git a/ns-manager/helpers/mapping.rb b/ns-manager/helpers/mapping.rb
new file mode 100644
index 0000000..ce73d45
--- /dev/null
+++ b/ns-manager/helpers/mapping.rb
@@ -0,0 +1,68 @@
+#
+# TeNOR - NS Manager
+#
+# Copyright 2014-2016 i2CAT Foundation, Portugal Telecom Inovação
+#
+# 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.
+#
+# @see ApplicationHelper
+module MappingHelper
+
+ # Get list of Mapping Algorithms
+ #
+ # @param [Symbol] format the format type, `:text` or `:html`
+ # @return [String] the object converted into the expected format.
+ def getMappings()
+ begin
+ return 200, Mapping.all.to_json
+ rescue => e
+ logger.error e
+ logger.error 'Error Establishing a Database Connection'
+ return 500, 'Error Establishing a Database Connection'
+ end
+ end
+
+ # Get a Mapping
+ #
+ # @param [Symbol] format the format type, `:text` or `:html`
+ # @return [String] the object converted into the expected format.
+ def getMapping(id)
+ begin
+ dc = Mapping.find(id)
+ rescue Mongoid::Errors::DocumentNotFound => e
+ logger.error 'mapping not found'
+ return 404
+ end
+ return dc.to_json
+ end
+
+ def saveMapping(mapping)
+ begin
+ mapping = Mapping.find_by(name: mapping['name'])
+ halt 409, 'DC Duplicated. Use PUT for update.'
+ # i es.update_attributes!(:host => pop_info['host'], :port => pop_info['port'], :token => @token, :depends_on => serv_reg['depends_on'])
+ rescue Mongoid::Errors::DocumentNotFound => e
+ begin
+ mapping = Mapping.create!(mapping)
+ rescue => e
+ puts 'ERROR.................'
+ puts e
+ end
+ rescue => e
+ puts e
+ logger.error 'Error saving mapping.'
+ halt 400
+ end
+ end
+
+end
diff --git a/ns-manager/main.rb b/ns-manager/main.rb
index a1be991..91287b1 100644
--- a/ns-manager/main.rb
+++ b/ns-manager/main.rb
@@ -47,36 +47,17 @@ class TnovaManager < Sinatra::Application
before do
env['rack.logger'] = settings.logger
-
-=begin
- if settings.environment == 'development'
- @client_token = 'test-token-client-id'
- return
- end
-
- pass if request.path_info == '/'
- # Validate every request with Gatekeeper
- @client_token = request.env['HTTP_X_AUTH_TOKEN']
- begin
- response = RestClient.get "#{settings.gatekeeper}/token/validate/#{@client_token}", 'X-Auth-Service-Key' => settings.service_key, :content_type => :json
- rescue Errno::ECONNREFUSED
- halt 500, 'Gatekeeper unreachable'
- rescue => e
- # logger.error e.response
- halt e.response.code, e.response.body
- end
-=end
end
helpers ApplicationHelper
helpers ServiceConfigurationHelper
helpers AuthenticationHelper
- helpers GatekeeperHelper
+ helpers DcHelper
helpers StatisticsHelper
helpers VimHelper
- #AuthenticationHelper.loginGK
- #ServiceConfigurationHelper.publishServices
+ #publish services
+ ServiceConfigurationHelper.publishModules
get '/' do
return 200, JSON.pretty_generate(interfaces_list)
diff --git a/ns-manager/models/init.rb b/ns-manager/models/init.rb
index 1613f6b..b1513e2 100644
--- a/ns-manager/models/init.rb
+++ b/ns-manager/models/init.rb
@@ -1,4 +1,4 @@
-require_relative 'serviceModel'#deprecated
+#require_relative 'serviceModel'#deprecated
require_relative 'statisticModel'
require_relative 'perfomanceStatisticModel'
require_relative 'mongoid_prefixable'
diff --git a/ns-manager/models/service.rb b/ns-manager/models/service.rb
index 9571f1d..f8161a4 100644
--- a/ns-manager/models/service.rb
+++ b/ns-manager/models/service.rb
@@ -5,6 +5,9 @@ class Service
validates :name, presence: true, uniqueness: true
field :host, type: String
field :port, type: String
+ field :path, type: String
field :token, type: String
field :depends_on, type: Array, default: []
+ field :type, type: String
+ field :status, type: String
end
diff --git a/ns-manager/models/serviceModel.rb b/ns-manager/models/serviceModel.rb
deleted file mode 100644
index 1619b93..0000000
--- a/ns-manager/models/serviceModel.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-class ServiceModel
-
- include Mongoid::Document
-
- field :name, type: String
- field :host, type: String
- field :port, type: String
- field :path, type: String
- field :type, type: String
- field :service_key, type: String
- index({:name => 1}, {unique: true})
-end
diff --git a/ns-manager/routes/authentication.rb b/ns-manager/routes/authentication.rb
index 71edd0f..49bf00b 100644
--- a/ns-manager/routes/authentication.rb
+++ b/ns-manager/routes/authentication.rb
@@ -108,17 +108,35 @@ class TeNORAuthentication < TnovaManager
post '/:uid/reset_password' do
user = User.where(email: params[:email]).first
user.password_reset_hash = BCrypt::Engine.generate_salt
- recoverPassMail(user.email, password_reset_hash)
+ #recoverPassMail(user.email, password_reset_hash)
end
- put '/:uid/update_password' do
- user = User.where(email: params[:email], password_reset_hash: params[:verification_code]).first
- user.password = params[:password]
- user.password_salt = BCrypt::Engine.generate_salt
- user.password_hash = BCrypt::Engine.hash_secret(params[:password], user.password_salt)
- if user.password == password_confirmation
- user.password_reset_hash = ''
- user.save!
+ put '/:uid/update_password' do |uid|
+
+ return 415 unless request.content_type == 'application/json'
+ credentials, errors = parse_json(request.body.read)
+ logger.error errors if errors
+ halt 400 if errors
+
+ begin
+ user = User.find_by(id: uid)
+ rescue Mongoid::Errors::DocumentNotFound => e
+ logger.error 'User not found.'
+ halt 401
+ end
+
+ if user.password_hash == BCrypt::Engine.hash_secret(credentials['old_password'], user.password_salt)
+ logger.debug "Old password is correct."
+ if credentials['password'] == credentials['re_password']
+ user.password = credentials['password']
+ user.password_salt = BCrypt::Engine.generate_salt
+ user.password_hash = BCrypt::Engine.hash_secret(credentials['password'], user.password_salt)
+ user.save!
+ else
+ halt 404, "New passwords don't match."
+ end
+ else
+ halt 404, "Old password doesn't match."
end
status 200
end
diff --git a/ns-manager/routes/config.rb b/ns-manager/routes/config.rb
index 5912280..6fc6a20 100644
--- a/ns-manager/routes/config.rb
+++ b/ns-manager/routes/config.rb
@@ -17,7 +17,9 @@
#
# @see TnovaManager
class ServiceConfiguration < TnovaManager
- # /modules/services
+ # @method get_modules_services
+ # @overload get '/modules/services'
+ # Retrieve the microservices list
get '/services' do
begin
return 200, Service.all.to_json
@@ -28,6 +30,9 @@ class ServiceConfiguration < TnovaManager
end
end
+ # @method get_modules_services_id
+ # @overload get '/modules/services:id'
+ # Retrieve a microservice given an id
get '/services/:id' do |id|
begin
service = Service.find(id)
@@ -35,19 +40,38 @@ class ServiceConfiguration < TnovaManager
logger.error 'DC not found'
return 404
end
- return service.to_json
+ service.to_json
end
+ # @method get_modules_services_name
+ # @overload get '/modules/services/:name'
+ # Retrieve the token of a microservice given a name
get '/services/name/:name' do |name|
begin
- service = Service.find_by(:name => name)
+ service = Service.find_by(name: name)
rescue Mongoid::Errors::DocumentNotFound => e
logger.error 'DC not found'
return 404
end
- return service['token']
+ service['token']
end
+ # @method get_modules_services_type
+ # @overload get '/modules/services/:type'
+ # Retrieve the microservices list by type
+ get '/services/type/:type' do |type|
+ begin
+ services = Service.where(:type => type)
+ rescue Mongoid::Errors::DocumentNotFound => e
+ logger.error 'DC not found'
+ return 404
+ end
+ services.to_json
+ end
+
+ # @method post_modules_services
+ # @overload post '/modules/services'
+ # Register a new microservice
post '/services' do
return 415 unless request.content_type == 'application/json'
serv_reg, errors = parse_json(request.body.read)
@@ -57,16 +81,19 @@ class ServiceConfiguration < TnovaManager
name: serv_reg['name'],
host: serv_reg['host'],
port: serv_reg['port'],
+ path: serv_reg['path'],
token: @token,
- depends_on: serv_reg['depends_on']
+ depends_on: serv_reg['depends_on'],
+ type: serv_reg['type']
}
- logger.debug serv
+ logger.debug 'Registring a new service: ' + serv_reg['name']
begin
s = Service.find_by(name: serv_reg['name'])
- s.update_attributes!(host: serv_reg['host'], port: serv_reg['port'], token: @token, depends_on: serv_reg['depends_on'])
+ s.update_attributes!(host: serv_reg['host'], port: serv_reg['port'], token: @token, depends_on: serv_reg['depends_on'], type: serv_reg['type'])
rescue Mongoid::Errors::DocumentNotFound => e
Service.create!(serv)
rescue => e
+ logger.error e
logger.error 'Error saving service.'
halt 404
end
@@ -76,122 +103,47 @@ class ServiceConfiguration < TnovaManager
logger.debug "Checking if dependant Services of #{serv} is Up and Running...."
s = Service.where(name: serv).first
next if s.nil?
- dependant_status = is_port_open?(s['host'], s['port'])
+ dependant_status = ServiceConfigurationHelper.is_port_open?(s['host'], s['port'])
if dependant_status == false
logger.debug "Service found but is down."
s.destroy
else
- depends_on << { name: s['name'], host: s['host'], port: s['port'], token: s['token'] }
+ depends_on << { name: s['name'], host: s['host'], port: s['port'], token: s['token'], depends_on: s['depends_on'] }
end
rescue Mongoid::Errors::DocumentNotFound => e
- logger.error 'User not found.'
- # halt 404
+ logger.error 'Service not found.'
end
end
- logger.debug 'Find service that has this module as dependency:'
- # Service
+ logger.debug 'Find services that have this module as dependency:'
dependencies = Service.any_of(depends_on: serv[:name]).entries
logger.debug dependencies
if dependencies.any?
dependencies.each do |dependency|
- begin
- RestClient.post dependency['host'] + ':' + dependency['port'] + '/gk_dependencies', serv.to_json, :content_type => :json, 'X-Auth-Token' => dependency['token']
- rescue => e
- # logger.error e
- puts e
- # halt 500, {'Content-Type' => 'text/plain'}, "Error sending dependencies to " +service['name']
- end
+ ServiceConfigurationHelper.send_dependencies_to_module(dependency, serv)
end
end
+
+ if serv[:type] == 'manager'
+ logger.debug "Sending dependencies to VNF Manager..."
+ ServiceConfigurationHelper.send_dependencies_to_manager(serv, depends_on)
+ end
halt 201, { depends_on: depends_on }.to_json
end
put '/services' do
end
+ # @method delete_modules_services_name
+ # @overload delete '/modules/services/:name'
+ # Remove a microservice
delete '/services/:name' do |name|
begin
- Service.find_by(:name => name).destroy
+ Service.find_by(name: name).destroy
rescue Mongoid::Errors::DocumentNotFound => e
halt 404
end
halt 200
end
- # DEPRECATED..............
-
- # @method post_configs_registerService
- # @overload post '/configs/registerService'
- # Register a microservice
- post '/registerService' do
- return registerService(request.body.read)
- end
-
- # @method post_configs_registerExternalService
- # @overload post '/configs/registerExternalService'
- # Register a external service
- post '/registerExternalService' do
- return registerExternalService(request.body.read)
- end
-
- # @method post_configs_unRegisterService
- # @overload post '/configs/unRegisterService/:service_id'
- # Unregister a service
- post '/unRegisterService/:microservice' do
- logger.info('Unregister service ' + params['microservice'])
- unregisterService(params['microservice'])
- logger.info('Service ' + @json['name'] + ' unregistred correctly')
- end
-
- # @method delete_configs_services
- # @overload delete '/configs/services/:microservice'
- # Delete a registered service
- delete '/services/:microservice' do
- ServiceModel.find_by(name: params['microservice']).delete
- end
-
- # @method get_configs_services
- # @overload get '/configs/services'
- # Get all available services
- get '/services' do
- if params['name']
- return ServiceModel.find_by(name: params['name']).to_json
- else
- return ServiceModel.all.to_json
- end
- end
-
- # @method put_configs_services
- # @overload put '/configs/services'
- # Update service information
- put '/services' do
- updateService(request.body.read)
- return 'Correct update.'
- end
-
- # @method put_configs_services
- # @overload put '/configs/services/:name/status'
- # Update service status
- put '/services/:name/status' do
- @service = ServiceModel.find_by(name: params['name'])
- @service.update_attribute(:status, request.body.read)
- return 'Correct update.'
- end
-
- # @method get_configs_services_publish_microservice
- # @overload get '/configs/services/:name/status'
- # Get dependencies for specific microservice, asyncrhonous call
- post '/services/publish/:microservice' do
- name = params[:microservice]
-
- registerService(request.body.read)
-
- Thread.new do
- logger.debug 'Publishing `' + name + '` to other services services...'
- ServiceConfigurationHelper.publishServices
- end
-
- return 200
- end
end
diff --git a/ns-manager/routes/dc.rb b/ns-manager/routes/dc.rb
index 18eb8ef..6b21c2d 100644
--- a/ns-manager/routes/dc.rb
+++ b/ns-manager/routes/dc.rb
@@ -35,7 +35,6 @@ class DcController < TnovaManager
# @overload get '/pops/dc/:id'
# Returns a DC
get '/dc/:id' do |id|
- puts Dc.all.to_json
begin
dc = Dc.find(id.to_i)
rescue Mongoid::Errors::DocumentNotFound => e
@@ -81,14 +80,12 @@ class DcController < TnovaManager
description: pop_info['description'],
extra_info: pop_info['extra_info']
}
- logger.debug serv
begin
dc = Dc.find_by(name: pop_info['name'])
halt 409, 'DC Duplicated. Use PUT for update.'
# i es.update_attributes!(:host => pop_info['host'], :port => pop_info['port'], :token => @token, :depends_on => serv_reg['depends_on'])
rescue Mongoid::Errors::DocumentNotFound => e
begin
- puts serv
dc = Dc.create!(serv)
rescue => e
puts 'ERROR.................'
@@ -103,7 +100,20 @@ class DcController < TnovaManager
halt 201, { id: dc._id }.to_json
end
- put '/services' do
+ put '/dc/:id' do |id|
+ return 415 unless request.content_type == 'application/json'
+ pop_info, errors = parse_json(request.body.read)
+
+ begin
+ dc = Dc.find(id.to_i)
+ rescue Mongoid::Errors::DocumentNotFound => e
+ logger.error 'DC not found'
+ return 404
+ end
+
+ dc.update_attributes(pop_info)
+
+ halt 200
end
# @method delete_pops_dc_id
diff --git a/ns-manager/routes/mapping.rb b/ns-manager/routes/mapping.rb
new file mode 100644
index 0000000..4f6a4af
--- /dev/null
+++ b/ns-manager/routes/mapping.rb
@@ -0,0 +1,54 @@
+#
+# TeNOR - NS Manager
+#
+# Copyright 2014-2016 i2CAT Foundation, Portugal Telecom Inovação
+#
+# 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.
+#
+# @see MappingController
+class MappingController < TnovaManager
+
+ # @method get_mapping
+ # @overload get '/logs/*'
+ # Get logs from fluentd-mongodb. Different strings allowed in order to filter the required data
+ # @param [string]
+ get '/' do
+ modules = ["ns_manager", "ns_catalogue", "ns_provisioner", "ns_monitoring", "nsd_validator", "vnf_manager", "vnf_catalogue", "vnf_provisioner", "vnf_monitoring", "hot_generator", "vnfd_validator"]
+ response = []
+ params['from'] = Time.at(params['from'].to_i)
+ params['until'] = Time.at(params['until'].to_i)
+ if !params['module'].nil?
+ if !params['severity'].nil? && params['from'].nil?
+ response = Tenor.prefix(params['module']).where(severity: params['severity'].downcase)
+ elsif !params['severity'].nil? && !params['from'].nil?
+ response = Tenor.prefix(params['module']).where(severity: params['severity'].downcase).where(:time.gte => params['from'], :time.lte => params['until'])
+ elsif params['severity'].nil? && !params['from'].nil?
+ response = Tenor.prefix(params['module']).where(:time.gte => params['from'], :time.lte => params['until'])
+ else
+ response = Tenor.prefix(params['module']).all
+ end
+ else
+ if !params['severity'].nil? && params['from'].nil?
+ modules.each { |x| response.concat(Tenor.prefix(x).where(severity: params['severity'].downcase))}
+ elsif !params['severity'].nil? && !params['from'].nil?
+ modules.each { |x| response.concat(Tenor.prefix(x).where(severity: params['severity'].downcase).where(:time.gte => params['from'], :time.lte => params['until']))}
+ elsif params['severity'].nil? && !params['from'].nil?
+ modules.each { |x| response.concat(Tenor.prefix(x).where(:time.gte => params['from'], :time.lte => params['until']))}
+ else
+ modules.each { |x| response.concat(Tenor.prefix(x).all)}
+ end
+ end
+
+ response.to_json
+ end
+end
diff --git a/ns-manager/routes/monitoring.rb b/ns-manager/routes/monitoring.rb
index 024d08f..4a665b1 100644
--- a/ns-manager/routes/monitoring.rb
+++ b/ns-manager/routes/monitoring.rb
@@ -26,18 +26,12 @@ class NsMonitoring < TnovaManager
# @param [string] metric
get '/:instance_id/monitoring-data/' do
if params['instance_type'] == 'ns'
- begin
- @service = ServiceModel.find_by(name: "ns_monitoring")
- rescue Mongoid::Errors::DocumentNotFound => e
- halt 500, {'Content-Type' => "text/plain"}, "Microservice unrechable."
- end
+ monitoring, errors = ServiceConfigurationHelper.get_module('ns_monitoring')
+ halt 500, errors if errors
composedUrl = "/ns-monitoring/"+params['instance_id'].to_s+"/monitoring-data/?"+request.env['QUERY_STRING']
elsif params['instance_type'] == 'vnf'
- begin
- @service = ServiceModel.find_by(name: "vnf_manager")
- rescue Mongoid::Errors::DocumentNotFound => e
- halt 500, {'Content-Type' => "text/plain"}, "Microservice unrechable."
- end
+ monitoring, errors = ServiceConfigurationHelper.get_module('vnf_manager')
+ halt 500, errors if errors
composedUrl = "/vnf-monitoring/"+params['instance_id'].to_s+"/monitoring-data/?"+request.env['QUERY_STRING']
end
@@ -45,7 +39,7 @@ class NsMonitoring < TnovaManager
#composedUrl = composedUrl + "/" + params["metric"]
end
begin
- response = RestClient.get @service.host.to_s + ":" + @service.port.to_s + composedUrl.to_s, 'X-Auth-Token' => @client_token, :content_type => :json
+ response = RestClient.get monitoring.host + composedUrl.to_s, 'X-Auth-Token' => monitoring.token, :content_type => :json
rescue Errno::ECONNREFUSED
halt 500, 'NS Monitoring unreachable'
rescue => e
@@ -81,23 +75,17 @@ class NsMonitoring < TnovaManager
get '/:instance_id/monitoring-data/last100/' do
if params['instance_type'] == 'ns'
- begin
- @service = ServiceModel.find_by(name: "ns_monitoring")
- rescue Mongoid::Errors::DocumentNotFound => e
- halt 500, {'Content-Type' => "text/plain"}, "Microservice unrechable."
- end
+ monitoring, errors = ServiceConfigurationHelper.get_module('ns_monitoring')
+ halt 500, errors if errors
composedUrl = "/ns-monitoring/"+params['instance_id'].to_s+"/monitoring-data/last100/?"+request.env['QUERY_STRING']
elsif params['instance_type'] == 'vnf'
- begin
- @service = ServiceModel.find_by(name: "vnf_manager")
- rescue Mongoid::Errors::DocumentNotFound => e
- halt 500, {'Content-Type' => "text/plain"}, "Microservice unrechable."
- end
+ monitoring, errors = ServiceConfigurationHelper.get_module('vnf_manager')
+ halt 500, errors if errors
composedUrl = "/vnf-monitoring/"+params['instance_id'].to_s+"/monitoring-data/last100/?"+request.env['QUERY_STRING']
end
begin
- response = RestClient.get @service.host.to_s + ":" + @service.port.to_s + composedUrl.to_s, 'X-Auth-Token' => @client_token, :content_type => :json
+ response = RestClient.get monitoring.host + composedUrl.to_s, 'X-Auth-Token' => monitoring.token, :content_type => :json
rescue Errno::ECONNREFUSED
halt 500, 'NS Monitoring unreachable'
rescue => e
diff --git a/ns-manager/routes/ns_provisioning.rb b/ns-manager/routes/ns_provisioning.rb
index b994779..45085b8 100644
--- a/ns-manager/routes/ns_provisioning.rb
+++ b/ns-manager/routes/ns_provisioning.rb
@@ -45,17 +45,33 @@ class NsProvisioner < TnovaManager
end
logger.info "INSTANTIATION INFO: " + instantiation_info.to_s
+
pop_list = []
+ mapping_info = {}
if instantiation_info['pop_id'].nil?
pop_list = JSON.parse(getDcs())
if pop_list.empty?
halt 400, "No PoPs registereds."
end
+ if !instantiation_info['mapping_id'].nil?
+ #using the Mapping algorithm specified in the instantiation request
+ mapping = ServiceConfigurationHelper.get_module_by_id(instantiation_info['mapping_id'])
+ mapping_info = mapping.host + ":" + mapping.port.to_s + mapping.path
+ elsif pop_list.size > 1
+ #using the first mapping algorithm
+ mapping, errors = ServiceConfigurationHelper.get_module_by_type('mapping')
+ mapping_info = mapping.host + ":" + mapping.port.to_s + mapping.path
+ else
+ #deploy to the unic PoP
+ end
else
- pop_list = []
+ #deploying the Instance into the requested PoP
pop_list << JSON.parse(getDc(instantiation_info['pop_id']))
end
+ infr_repo_url, errors = ServiceConfigurationHelper.get_module_by_type('infr_repo')
+ infr_repo_url = nil if errors
+
provisioning = {
:nsd => JSON.parse(nsd),
:customer_id => instantiation_info['customer_id'],
@@ -63,9 +79,8 @@ class NsProvisioner < TnovaManager
:callback_url => instantiation_info['callbackUrl'],
:flavour => instantiation_info['flavour'],
:pop_list => pop_list,
- #:pop_id => instantiation_info['pop_id'],
- #:pop_info => pop_info,
- :mapping_id => instantiation_info['mapping_id']
+ :mapping => mapping_info,
+ :infr_repo_url => infr_repo_url
}
begin
response = RestClient.post provisioner.host + request.fullpath, provisioning.to_json, 'X-Auth-Token' => provisioner.token, :content_type => :json
diff --git a/ns-manager/routes/vnfs.rb b/ns-manager/routes/vnfs.rb
index b637bc8..179edbe 100644
--- a/ns-manager/routes/vnfs.rb
+++ b/ns-manager/routes/vnfs.rb
@@ -124,7 +124,7 @@ class VNFCatalogue < TnovaManager
rescue => e
logger.error e.response
# halt e.response.code, e.response.body
- logger.error 'Any network service is using this VNF.'
+ logger.error 'No network services using this VNF.'
end
begin
diff --git a/ns-manager/spec/auth_spec.rb b/ns-manager/spec/auth_spec.rb
index 48b3999..130bb3d 100644
--- a/ns-manager/spec/auth_spec.rb
+++ b/ns-manager/spec/auth_spec.rb
@@ -90,7 +90,6 @@ def app
context 'given a valid token' do
let(:response) { post '/validation', {token: token.token}.to_json, rack_env={'CONTENT_TYPE' => 'application/json'} }
it 'responds with a 200' do
- puts token.token
expect(response.status).to eq 200
end
end
@@ -132,6 +131,71 @@ def app
end
end
+ #update user password
+ describe 'PUT /auth' do
+ let(:user) { create :user }
+
+ context 'given a missing header credentials' do
+ let(:response) { put '/invalid_id/update_password', {name: 'teste'}.to_json, rack_env={'CONTENT_TYPE' => 'application/x-www-form-urlencoded'} }
+
+ it 'responds with a 415' do
+ expect(response.status).to eq 415
+ end
+
+ it 'responds with an empty body' do
+ expect(response.body).to be_empty
+ end
+ end
+
+ context 'given an invalid user id' do
+ let(:response) { put '/invalid_id/update_password', {name: 'teste'}.to_json, rack_env={'CONTENT_TYPE' => 'application/json'} }
+
+ it 'responds with a 404' do
+ expect(response.status).to eq 401
+ end
+
+ it 'responds with an empty body' do
+ expect(response.body).to be_empty
+ end
+ end
+
+ context 'given a valid user id but invalid passwords' do
+ let(:response) { put '/' + user.id.to_s + '/update_password', {old_password: "secret2", password: "secret2", re_password: "secret2"}.to_json, rack_env={'CONTENT_TYPE' => 'application/json'} }
+
+ it 'responds with a 404' do
+ expect(response.status).to eq 404
+ end
+
+ it 'response body should contain a String' do
+ expect(response.body).to be_a String
+ end
+ end
+
+ context 'given a valid user id but invalid passwords' do
+ let(:response) { put '/' + user.id.to_s + '/update_password', {old_password: "secret", password: "secret2", re_password: "secret3"}.to_json, rack_env={'CONTENT_TYPE' => 'application/json'} }
+
+ it 'responds with a 404' do
+ expect(response.status).to eq 404
+ end
+
+ it 'response body should contain a String' do
+ expect(response.body).to be_a String
+ end
+ end
+
+ context 'given a valid user id and valid passwords' do
+ let(:response) { put '/' + user.id.to_s + '/update_password', {old_password: "secret", password: "secret2", re_password: "secret2"}.to_json, rack_env={'CONTENT_TYPE' => 'application/json'} }
+
+ it 'responds with a 200' do
+ expect(response.status).to eq 200
+ end
+
+ it 'response body should be empty' do
+ expect(response.body).to be_empty
+ end
+ end
+ end
+
=begin
describe 'POST /auth' do
context 'given an invalid content type' do
@@ -198,6 +262,4 @@ def app
end
end
=end
- describe 'PUT /auth/:id' do
- end
end
diff --git a/ns-manager/spec/dc_spec.rb b/ns-manager/spec/dc_spec.rb
index c658ef7..920c1e6 100644
--- a/ns-manager/spec/dc_spec.rb
+++ b/ns-manager/spec/dc_spec.rb
@@ -173,5 +173,60 @@ def app
end
describe 'PUT /dc/:id' do
+ let(:dc) { create :dc }
+
+ context 'given an invalid content type' do
+ let(:response) { put '/dc/' + dc._id.to_s, {name: 'teste'}.to_json, rack_env={'CONTENT_TYPE' => 'application/x-www-form-urlencoded'} }
+
+ it 'responds with a 415' do
+ expect(response.status).to eq 415
+ end
+
+ it 'responds with an empty body' do
+ expect(response.body).to be_empty
+ end
+ end
+
+ context 'given an invalid DC id' do
+ let(:response) { put '/dc/invalidId', {name: "name", host: "host", user: "user", password: "", tenant_name: "tenan", extra_info: "extra..."}.to_json, rack_env={'CONTENT_TYPE' => 'application/json'} }
+
+ it 'responds with a 404' do
+ expect(response.status).to eq 404
+ end
+
+ it 'responds with an empty body' do
+ expect(response.body).to be_empty
+ end
+ end
+
+ context 'given a valid DC' do
+ let(:response) { put '/dc/' + dc._id.to_s, {name: "name222", host: "host222", user: "user", password: "", tenant_name: "tenan", extra_info: "extra..."}.to_json, rack_env={'CONTENT_TYPE' => 'application/json'} }
+
+ it 'responds with a 200' do
+ expect(response.status).to eq 200
+ end
+
+ it 'responds with an empty body' do
+ expect(response.body).to be_empty
+ end
+ end
+
+ context 'given a valid DC' do
+ let(:response) { get '/dc/' + dc._id.to_s }
+
+ it 'responds with a 200' do
+ expect(response.status).to eq 200
+ end
+
+ it 'response body should contain a Hash (DC)' do
+ expect(JSON.parse response.body).to be_a Hash
+ end
+
+ it 'response body should be equal than the PUT request' do
+ skip "is skipped" do
+ end
+ end
+
+ end
end
end
diff --git a/ns-monitoring-repository/config/config.yml.sample b/ns-monitoring-repository/config/config.yml.sample
index e31644b..707b354 100644
--- a/ns-monitoring-repository/config/config.yml.sample
+++ b/ns-monitoring-repository/config/config.yml.sample
@@ -12,7 +12,4 @@ threaded: true
logger_host: 127.0.0.1
logger_port: 24224
-gk:
-service_key:
-
dependencies: []
diff --git a/ns-monitoring/config/config.yml.sample b/ns-monitoring/config/config.yml.sample
index 6d3694b..74765c8 100644
--- a/ns-monitoring/config/config.yml.sample
+++ b/ns-monitoring/config/config.yml.sample
@@ -12,11 +12,4 @@ threaded: true
logger_host: 127.0.0.1
logger_port: 24224
-vnf_manager: http://localhost:4567
-ns_provisioner: 10.10.1.61:4012
-ns_monitoring_repo: 10.10.1.61:4017
-
-gk:
-service_key:
-
-dependencies: [ns_monitoring_repo, ns_provisioner, vnf_manager]
+dependencies: [ns_monitoring_repo, vnf_manager]
diff --git a/ns-monitoring/helpers/expression_evaluator.rb b/ns-monitoring/helpers/expression_evaluator.rb
index 7184d29..2607e26 100644
--- a/ns-monitoring/helpers/expression_evaluator.rb
+++ b/ns-monitoring/helpers/expression_evaluator.rb
@@ -18,9 +18,7 @@
# @see NSMonitoring
module ExpressionEvaluatorHelper
def self.calc_expression(formula, values)
- if values.size == 1
- return values[0]
- end
+ return values[0] if values.size == 1
operations = formula.split('(')[0]
response = 0
@@ -56,15 +54,15 @@ def find_max(values)
def find_avg(values)
val = 0
values.each do |v|
- val = val + v
+ val += v
end
- val/values.size
+ val / values.size
end
def find_sum(values)
val = 0
values.each do |v|
- val = val + v
+ val += v
end
val
end
diff --git a/ns-monitoring/helpers/monitoring.rb b/ns-monitoring/helpers/monitoring.rb
index 2d4e0b1..54e386d 100644
--- a/ns-monitoring/helpers/monitoring.rb
+++ b/ns-monitoring/helpers/monitoring.rb
@@ -17,167 +17,164 @@
#
# @see NSMonitoring
module MonitoringHelper
+ @conn = Bunny.new
+ @conn.start
+ @channel = @conn.create_channel
+ @@testThreads = []
+
+ # Checks if a JSON message is valid
+ #
+ # @param [JSON] message some JSON message
+ # @return [Hash, nil] if the parsed message is a valid JSON
+ # @return [Hash, String] if the parsed message is an invalid JSON
+ def parse_json(message)
+ # Check JSON message format
+ begin
+ parsed_message = JSON.parse(message) # parse json message
+ rescue JSON::ParserError => e
+ # If JSON not valid, return with errors
+ logger.error "JSON parsing: #{e}"
+ return message, e.to_s + "\n"
+ end
- @conn = Bunny.new
- @conn.start
- @channel = @conn.create_channel
- @@testThreads = []
-
- # Checks if a JSON message is valid
- #
- # @param [JSON] message some JSON message
- # @return [Hash, nil] if the parsed message is a valid JSON
- # @return [Hash, String] if the parsed message is an invalid JSON
- def parse_json(message)
- # Check JSON message format
- begin
- parsed_message = JSON.parse(message) # parse json message
- rescue JSON::ParserError => e
- # If JSON not valid, return with errors
- logger.error "JSON parsing: #{e.to_s}"
- return message, e.to_s + "\n"
+ [parsed_message, nil]
end
- return parsed_message, nil
- end
-
- # Subcription thread method
- #
- # @param [JSON] message monitoring information
- def self.subcriptionThread(monitoring)
- logger.info "Subcription thread for NSr: " + monitoring['nsi_id'].to_s
- nsi_id = monitoring['nsi_id'].to_s
- vnf_instances = monitoring['vnf_instances']
- parameters = monitoring['parameters']
-
- ch = @channel
- vnf_instances.each do |vnf_instance|
- logger.debug "VNF_Instance_id: " + vnf_instance['vnfr_id']
- begin
- t = ch.queue(vnf_instance['vnfr_id'], :exclusive => false).subscribe do |delivery_info, metadata, payload|
-
- logger.info "Receving subcription data of" + vnf_instance['vnfr_id'].to_s
- measurements = JSON.parse(payload)
- logger.debug measurements.to_json
-
- begin
- @queue = VnfQueue.find_or_create_by(:nsi_id => nsi_id, :vnfi_id => vnf_instance['vnfr_id'], :parameter_id => measurements['type'])
- @queue.update_attributes({:value => measurements['value'], :timestamp => measurements['timestamp'], :unit => measurements['unit']})
- rescue => e
- puts e
- end
- logger.debug @queue
- begin
- @list_vnfs_parameters = VnfQueue.where(:nsi_id => nsi_id, :parameter_id => measurements['type'])
- if @list_vnfs_parameters.length == vnf_instances.length
- #logger.debug "Lisf of vnfs_params is equal."
- logger.debug @list_vnfs_parameters.to_json
- param = parameters.find {|p| p['name'] == measurements['type'] }
- if param.nil?
- logger.debug "Params outside the SLA (assurance parameters field)"
- calculation = measurements['value']
- else
- logger.info "Params inside the SLA (checking SLA)..."
- values = []
- @list_vnfs_parameters.each do |p|
- values << p['value']
+ # Subcription thread method
+ #
+ # @param [JSON] message monitoring information
+ def self.subcriptionThread(monitoring)
+ logger.info 'Subcription thread for NSr: ' + monitoring['nsi_id'].to_s
+ nsi_id = monitoring['nsi_id'].to_s
+ vnf_instances = monitoring['vnf_instances']
+ parameters = monitoring['parameters']
+
+ ch = @channel
+ vnf_instances.each do |vnf_instance|
+ logger.debug 'VNF_Instance_id: ' + vnf_instance['vnfr_id']
+ begin
+ t = ch.queue(vnf_instance['vnfr_id'], exclusive: false).subscribe do |_delivery_info, _metadata, payload|
+ logger.info 'Receving subcription data of' + vnf_instance['vnfr_id'].to_s
+ measurements = JSON.parse(payload)
+ logger.debug measurements.to_json
+
+ begin
+ @queue = VnfQueue.find_or_create_by(nsi_id: nsi_id, vnfi_id: vnf_instance['vnfr_id'], parameter_id: measurements['type'])
+ @queue.update_attributes(value: measurements['value'], timestamp: measurements['timestamp'], unit: measurements['unit'])
+ rescue => e
+ puts e
+ end
+ logger.debug @queue
+ begin
+ @list_vnfs_parameters = VnfQueue.where(nsi_id: nsi_id, parameter_id: measurements['type'])
+ if @list_vnfs_parameters.length == vnf_instances.length
+ # logger.debug "Lisf of vnfs_params is equal."
+ logger.debug @list_vnfs_parameters.to_json
+ param = parameters.find { |p| p['name'] == measurements['type'] }
+ if param.nil?
+ logger.debug 'Params outside the SLA (assurance parameters field)'
+ calculation = measurements['value']
+ else
+ logger.info 'Params inside the SLA (checking SLA)...'
+ values = []
+ @list_vnfs_parameters.each do |p|
+ values << p['value']
+ end
+
+ logger.debug 'Send to Expression Evaluator.'
+ calculation = ExpressionEvaluatorHelper.calc_expression(param['formula'], values)
+ logger.debug 'Calculation response: ' + calculation.to_s
+
+ begin
+ sla = Sla.find_by!(nsi_id: nsi_id)
+ sla_breach = sla.process_reading(param, calculation)
+ # if sla_breach
+ # logger.info "Breach reached!"
+ # end
+ rescue ActiveRecord::RecordNotFound => e
+ logger.error 'SLA information not found for NSR ' + nsi_id
+ # return 404, "Could not find an SLA for NS Instance ID #{nsi_id}"
+ end
+
+ # logger.debug "Calculation: " + calculation
+ # if SlaHelper.check_breach_sla(param['value'], calculation)
+ # SlaHelper.process_breach()
+ # end
+ end
+ ns_measurement = {
+ instance_id: nsi_id,
+ type: @queue['parameter_id'],
+ unit: @queue['unit'],
+ value: calculation,
+ timestamp: @queue['timestamp']
+ }
+ logger.debug ns_measurement
+
+ q = ch.queue('ns_monitoring')
+ q.publish(ns_measurement.to_json, persistent: true)
+
+ VnfQueue.destroy_all(nsi_id: nsi_id, parameter_id: measurements['parameter_id'])
+ else
+ logger.error 'NO equal. Wait next value'
+ end
+ rescue => e
+ puts e
+ end
end
+ logger.debug 'Adding to queue'
+ @@testThreads << { vnfi_id: vnf_instance['vnfr_id'], queue: t }
+ rescue Interrupt => _
+ logger.error 'THREAD INTERRUPTION ...'
+ conn.close
+ end
+ end
+ end
- logger.debug "Send to Expression Evaluator."
- calculation = ExpressionEvaluatorHelper.calc_expression(param['formula'], values)
- logger.debug "Calculation response: " + calculation.to_s
+ def self.startSubcription
+ logger.info 'Getting list of instances...'
+ begin
+ response = RestClient.get Sinatra::Application.settings.manager + '/ns-instances', content_type: :json
+ @ns_instances = JSON.parse(response)
+ logger.info 'Creating a monitoring thread for each instance...'
+ @ns_instances.each do |instance|
begin
- sla = Sla.find_by!(nsi_id: nsi_id)
- sla_breach = sla.process_reading(param, calculation)
- #if sla_breach
- #logger.info "Breach reached!"
- #end
- rescue ActiveRecord::RecordNotFound => e
- logger.error "SLA information not found for NSR " + nsi_id
- #return 404, "Could not find an SLA for NS Instance ID #{nsi_id}"
+ monitoring = NsMonitoringParameter.find_by('nsi_id' => instance['id'])
+ nsi_id = monitoring['nsi_id'].to_s
+ logger.info 'Creating thread for NS instance ' + nsi_id.to_s
+ logger.debug monitoring # to remove
+
+ Thread.new do
+ Thread.current['name'] = nsi_id
+ MonitoringHelper.subcriptionThread(monitoring)
+ Thread.stop
+ end
+ rescue Mongoid::Errors::DocumentNotFound => e
+ logger.debug 'No monitoring configuration in the BD for NSr_id ' + instance['id']
end
-
- #logger.debug "Calculation: " + calculation
- #if SlaHelper.check_breach_sla(param['value'], calculation)
- #SlaHelper.process_breach()
- #end
- end
- ns_measurement = {
- :instance_id => nsi_id,
- :type => @queue['parameter_id'],
- :unit => @queue['unit'],
- :value => calculation,
- :timestamp => @queue['timestamp']
- }
- logger.debug ns_measurement
-
- q = ch.queue("ns_monitoring")
- q.publish(ns_measurement.to_json, :persistent => true)
-
- VnfQueue.destroy_all(:nsi_id => nsi_id, :parameter_id => measurements['parameter_id'])
- else
- logger.error "NO equal. Wait next value"
end
- rescue => e
+ rescue => e
+ puts 'Error!'
puts e
- end
-
end
- logger.debug "Adding to queue"
- @@testThreads << {:vnfi_id => vnf_instance['vnfr_id'], :queue => t}
- rescue Interrupt => _
- logger.error "THREAD INTERRUPTION ..."
- conn.close
- end
end
- end
-
- def self.startSubcription()
- logger.info "Getting list of instances..."
- begin
- response = RestClient.get Sinatra::Application.settings.ns_provisioner + '/ns-instances', :content_type => :json
- @ns_instances = JSON.parse(response)
- logger.info "Creating a monitoring thread for each instance..."
- @ns_instances.each do |instance|
+ def destroy_monitoring_data(nsi_id)
+ logger.error 'Destroy Monitoring Data of ' + nsi_id
begin
- monitoring = NsMonitoringParameter.find_by("nsi_id" => instance['id'])
- nsi_id = monitoring['nsi_id'].to_s
- logger.info "Creating thread for NS instance " + nsi_id.to_s
- logger.debug monitoring # to remove
-
- Thread.new {
- Thread.current["name"] = nsi_id;
- MonitoringHelper.subcriptionThread(monitoring)
- Thread.stop
- }
- rescue Mongoid::Errors::DocumentNotFound => e
- logger.debug "No monitoring configuration in the BD for NSr_id " + instance['id']
+ response = RestClient.delete settings.ns_monitoring_repo + "/ns-monitoring/#{nsi_id}", content_type: :json
+ rescue => e
+ logger.error e.response
+ # return e.response.code, e.response.body
end
- end
- rescue => e
- puts "Error!"
- puts e
end
- end
-
- def destroy_monitoring_data(nsi_id)
- logger.error "Destroy Monitoring Data of " + nsi_id
- begin
- response = RestClient.delete settings.ns_monitoring_repo + "/ns-monitoring/#{nsi_id}", content_type: :json
- rescue => e
- logger.error e.response
- # return e.response.code, e.response.body
- end
- end
- def self.logger
- Logging.logger
- end
+ def self.logger
+ Logging.logger
+ end
- # Global, memoized, lazy initialized instance of a logger
- def self.logger
- @logger ||= Logger.new(STDOUT)
- end
+ # Global, memoized, lazy initialized instance of a logger
+ def self.logger
+ @logger ||= Logger.new(STDOUT)
+ end
end
diff --git a/ns-monitoring/helpers/sla.rb b/ns-monitoring/helpers/sla.rb
index 3548e92..7eefa33 100644
--- a/ns-monitoring/helpers/sla.rb
+++ b/ns-monitoring/helpers/sla.rb
@@ -17,53 +17,51 @@
#
# @see NSMonitoring
module SlaHelper
+ def self.process_breach
+ puts 'BREACh.'
+ logger.info 'SLA Breach!'
- def self.process_breach()
- puts "BREACh."
- logger.info "SLA Breach!"
+ logger.info 'Inform to NS Manager about this.'
- logger.info "Inform to NS Manager about this."
+ puts Sinatra::Application.settings.manager
- puts Sinatra::Application.settings.manager
+ begin
+ response = RestClient.get settings.vnf_provisioning + '/vnf-provisioning/vnf-instances/' + vnfr_id, content_type: :json, accept: :json
+ rescue => e
+ puts e
+ end
+ end
- begin
- response = RestClient.get settings.vnf_provisioning + "/vnf-provisioning/vnf-instances/" + vnfr_id, :content_type => :json, :accept => :json
- rescue => e
- puts e
- end
-
- end
-
- # Check if the value is inside the threshold
- # Threshold format: GT(#integer), LE(#integer)...
- def self.check_breach_sla(threshold, value)
- operation = threshold.split("(")[0]
- threshold = threshold.split("(")[1].split(")")[0]
- response = false
+ # Check if the value is inside the threshold
+ # Threshold format: GT(#integer), LE(#integer)...
+ def self.check_breach_sla(threshold, value)
+ operation = threshold.split('(')[0]
+ threshold = threshold.split('(')[1].split(')')[0]
+ response = false
- case operation
- when 'GT'
- response = threshold.to_f < value.to_f
- when 'LT'
- response = threshold.to_f > value.to_f
- when 'GE'
- response = threshold.to_f <= value.to_f
- when 'LE'
- response = threshold.to_f >= value.to_f
- when 'EQ'
- response = threshold.to_f == value.to_f
- when 'NE'
- response = threshold.to_f != value.to_f
+ case operation
+ when 'GT'
+ response = threshold.to_f < value.to_f
+ when 'LT'
+ response = threshold.to_f > value.to_f
+ when 'GE'
+ response = threshold.to_f <= value.to_f
+ when 'LE'
+ response = threshold.to_f >= value.to_f
+ when 'EQ'
+ response = threshold.to_f == value.to_f
+ when 'NE'
+ response = threshold.to_f != value.to_f
+ end
+ response
end
- return response
- end
- def self.logger
- Logging.logger
- end
+ def self.logger
+ Logging.logger
+ end
- # Global, memoized, lazy initialized instance of a logger
- def self.logger
- @logger ||= Logger.new(STDOUT)
- end
+ # Global, memoized, lazy initialized instance of a logger
+ def self.logger
+ @logger ||= Logger.new(STDOUT)
+ end
end
diff --git a/ns-monitoring/models/sla.rb b/ns-monitoring/models/sla.rb
index fa1d130..d47c41a 100644
--- a/ns-monitoring/models/sla.rb
+++ b/ns-monitoring/models/sla.rb
@@ -1,62 +1,63 @@
class Sla < ActiveRecord::Base
- has_many :parameters
-# has_many :breaches
+ has_many :parameters
+ # has_many :breaches
- validates_presence_of :nsi_id
+ validates_presence_of :nsi_id
- def includes?(param_id)
- self.parameters.select {|parameter| parameter[:id] == param_id}
- end
+ def includes?(param_id)
+ parameters.select { |parameter| parameter[:id] == param_id }
+ end
+
+ def process_reading(parameter_values, reading)
+ # parameter = Parameter.where("sla_id = ? AND parameter_id = ?", self.id, parameter_values['id']).first
+ parameter = Parameter.where('sla_id = ? AND name = ?', id, parameter_values['name']).first
+
+ unless parameter.nil?
+ if SlaHelper.check_breach_sla(parameter['threshold'], reading)
+ @breach = process_breach(parameter, reading)
+ end
+ end
+ @breach
+ # TODO: the above is instant processing, must process along a time-interval
+ end
- def process_reading(parameter_values, reading)
- #parameter = Parameter.where("sla_id = ? AND parameter_id = ?", self.id, parameter_values['id']).first
- parameter = Parameter.where("sla_id = ? AND name = ?", self.id, parameter_values['name']).first
+ private
- unless parameter.nil?
- if SlaHelper.check_breach_sla(parameter['threshold'], reading)
- @breach = process_breach(parameter, reading)
- end
+ def process_breach(parameter, reading)
+ store_breach(parameter, reading)
+ notify_ns_manager @breach
end
- @breach
- # TODO: the above is instant processing, must process along a time-interval
- end
-
- private
-
- def process_breach(parameter, reading)
- store_breach(parameter, reading)
- notify_ns_manager @breach
- end
-
- def store_breach(parameter, reading)
- @breach = Breach.create(nsi_id: self.nsi_id, external_parameter_id: parameter.id, value: reading)
- end
-
- def notify_ns_manager(breach)
- self
- puts "SLA Breach!"
- puts breach.inspect
- puts self.inspect
- puts "NSR:ID: " self.nsr_id
-
- request = {
- parameter_id: breach.external_parameter_id
- }
-
- puts "Inform to NS Manager about this."
- return
- begin
- response = RestClient.post Sinatra::Application.settings.manager + "/ns-instances/scaling/" +self.nsr_id + "/auto_scale", :content_type => :json, :accept => :json
- rescue => e
- puts e
+
+ def store_breach(parameter, reading)
+ @breach = Breach.create(nsi_id: nsi_id, external_parameter_id: parameter.id, value: reading)
+ end
+
+ def notify_ns_manager(breach)
+ self
+ puts 'SLA Breach!'
+ puts breach.inspect
+ puts inspect
+ puts 'NSR:ID: ' + nsi_id
+
+ request = {
+ parameter_id: breach.external_parameter_id
+ }
+
+ puts 'Inform to NS Manager about this.'
+ puts Sinatra::Application.settings.manager + '/ns-instances/scaling/' + nsi_id + '/auto_scale'
+ # Thread.new {
+ begin
+ response = RestClient.post Sinatra::Application.settings.manager + '/ns-instances/scaling/' + nsi_id + '/auto_scale', request.to_json, content_type: :json, accept: :json
+ rescue => e
+ puts e
+ end
+ puts response
+ # }
+ # auto_scale_policy: [
+ # {
+ # criteria: [{"assurance_parameter_id": "assurance_parameter_id" }],
+ # actions: [ {"type": "scaling_out"}]
+ # }
+ # ]
end
-=begin
-auto_scale_policy: [
-{
-criteria: [{"assurance_parameter_id": "assurance_parameter_id" }],
-actions: [ {"type": "scaling_out"}]
-}
-]
-=end
- end
end
diff --git a/ns-monitoring/routes/monitoring.rb b/ns-monitoring/routes/monitoring.rb
index 78cf27d..d952e03 100644
--- a/ns-monitoring/routes/monitoring.rb
+++ b/ns-monitoring/routes/monitoring.rb
@@ -99,7 +99,7 @@ class NSMonitoring < Sinatra::Application
# Unsubcribe ns instance
# @param [Integer] external_ns_id NS external ID
post '/monitoring-data/unsubscribe/:nsi_id' do |nsi_id|
- logger.info "Unsubcribe " + nsi_id
+ logger.info 'Unsubcribe ' + nsi_id
begin
monMetrics = NsMonitoringParameter.find_by('nsi_id' => nsi_id)
rescue Mongoid::Errors::DocumentNotFound => e
@@ -132,7 +132,7 @@ class NSMonitoring < Sinatra::Application
monMetrics.destroy
sla.destroy
- halt 200, "Correct unsubcription."
+ halt 200, 'Correct unsubcription.'
end
# This interface is with the VNF Monitoring micro-service, upon successfully receiving a monitoring parameter reading for a given VNF instance.
diff --git a/ns-provisioning/config/config.yml.sample b/ns-provisioning/config/config.yml.sample
index 45c2703..ef586e1 100644
--- a/ns-provisioning/config/config.yml.sample
+++ b/ns-provisioning/config/config.yml.sample
@@ -12,23 +12,17 @@ threaded: true
logger_host: 127.0.0.1
logger_port: 24224
-mapping: http://localhost:4042
-sla_enforcement: http://localhost:4016
-
#optional fields
default_tenant: true
default_user_name: tenor_user
default_user_password: secretsecret
default_tenant_name: tenor_tenant
+ns_monitoring: localhost:4014
+vnf_manager: localhost:4567
+hot_generator: localhost:4571
dependencies: [ns_monitoring, vnf_manager, wicm, mAPI, mapping, hot_generator, infr_repository, netfloc]
-gk:
-service_key:
-
-#infr_repo: http://10.10.1.1:8080
-#wicm: http://10.30.0.12:12891
-
netfloc:
odl_username: admin
odl_password: admin
diff --git a/ns-provisioning/helpers/authentication.rb b/ns-provisioning/helpers/authentication.rb
deleted file mode 100644
index 23be6cb..0000000
--- a/ns-provisioning/helpers/authentication.rb
+++ /dev/null
@@ -1,97 +0,0 @@
-#
-# TeNOR - NS Provisioning
-#
-# Copyright 2014-2016 i2CAT Foundation, Portugal Telecom Inovação
-#
-# 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.
-#
-# @see NSProvisioner
-module AuthenticationHelper
-
- def authenticate(keystone_url, tenant_name, username, password)
- keystone_version = URI(keystone_url).path.split('/').last
- if keystone_version == 'v2.0'
- user_authentication, errors = authentication_v2(keystone_url, tenant_name, username, password)
- logger.error errors if errors
- return 400, errors.to_json if errors
- tenant_id = user_authentication['access']['token']['tenant']['id']
- user_id = user_authentication['access']['user']['id']
- token = user_authentication['access']['token']['id']
- elsif keystone_version == 'v3'
- user_authentication, errors = authentication_v3(keystone_url, tenant_name, username, password)
- logger.error errors if errors
- return 400, errors.to_json if errors
- if !user_authentication['token']['project'].nil?
- tenant_id = user_authentication['token']['project']['id']
- user_id = user_authentication['token']['user']['id']
- token = user_authentication['token']['id']
- else
- errors = "No project found with the authentication."
- return 400, errors.to_json if errors
- end
- end
- {:tenant_id => tenant_id, :user_id => user_id, :token => token}
- end
-
- def generate_credentials(instance, keystone_url, popUrls, tenant_id, user_id, token)
- keystone_version = URI(keystone_url).path.split('/').last
- if keystone_version == 'v2.0'
- credentials, errors = generate_v2_credentials(instance, popUrls, tenant_id, user_id, token)
- return 400, errors if errors
- elsif keystone_version == 'v3'
- credentials, errors = generate_v3_credentials(instance, popUrls, tenant_id, user_id, token)
- return 400, errors if errors
- end
- credentials
- end
-
- def create_user_and_project(heat_api, instance_id, project_name, username, password, tenant_id, token)
- generated_credentials = {}
- generated_credentials['password'] = password
- generated_credentials['tenant_name'] = project_name
- generated_credentials['username'] = username
-
- hot_generator_message = {
- project_name: generated_credentials['tenant_name'],
- username: generated_credentials['username'],
- password: generated_credentials['password'],
- domain: nil
- }
-
- logger.info 'Generating user HOT template...'
- hot, errors = generateUserHotTemplate(hot_generator_message)
- return handleError(@instance, errors) if errors
-
- logger.info 'Send user template to HEAT Orchestration'
- stack_name = 'user_' + @instance['id'].to_s
- template = { stack_name: stack_name, template: hot }
- stack, errors = sendStack(heat_api, tenant_id, template, token)
- return handleError(@instance, errors) if errors
- stack_id = stack['stack']['id']
- stack_url = stack['stack']['links'][0]['href']
-
- logger.info 'Checking user stack creation...'
- stack_info, errors = create_stack_wait(heat_api, tenant_id, stack_name, token, 'NS User')
- return handleError(@instance, errors) if errors
-
- logger.info 'User stack CREATE_COMPLETE. Reading user information from stack...'
- sleep(3)
- stack_info, errors = getStackInfo(heat_api, tenant_id, stack_name, token)
- return handleError(@instance, errors) if errors
- tenant_id = stack_info['stack']['outputs'].find{ |res| res['output_key'] == 'project_id' }['output_value']
- user_id = stack_info['stack']['outputs'].find{ |res| res['output_key'] == 'user_id' }['output_value']
-
- return stack_url, tenant_id, user_id
- end
-
-end
diff --git a/ns-provisioning/helpers/hot.rb b/ns-provisioning/helpers/hot.rb
index 7698c7b..2b19977 100644
--- a/ns-provisioning/helpers/hot.rb
+++ b/ns-provisioning/helpers/hot.rb
@@ -72,11 +72,8 @@ def sendStack(url, tenant_id, template, tenant_token)
return 500, error
rescue RestClient::ExceptionWithResponse => e
logger.error e
- logger.error e.response.body
- return e.response.code, e.response.body
- rescue RestClient::ExceptionWithResponse => e
- # logger.error e
logger.error e.response
+ logger.error e.response.body if e.response
error = { 'info' => 'Error creating the network stack.' }
return 500, error
end
@@ -258,7 +255,7 @@ def delete_stack_with_wait(stack_url, auth_token)
def generateUserHotTemplate(hot_generator_message)
begin
- response = RestClient.post settings.hot_generator + "/userhot", hot_generator_message.to_json, content_type: :json, accept: :json
+ response = RestClient.post settings.hot_generator + '/userhot', hot_generator_message.to_json, content_type: :json, accept: :json
rescue Errno::ECONNREFUSED
error = { 'info' => 'HOT Generator unrechable.' }
return 500, error
diff --git a/ns-provisioning/helpers/init.rb b/ns-provisioning/helpers/init.rb
index 59e9cd5..4d61603 100644
--- a/ns-provisioning/helpers/init.rb
+++ b/ns-provisioning/helpers/init.rb
@@ -15,7 +15,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
-#require_relative 'utils'
require_relative 'ns'
require_relative 'vim'
require_relative 'monitoring'
@@ -24,6 +23,6 @@
require_relative 'hot'
require_relative 'utils'
require_relative 'instantiation'
-require_relative 'authentication'
-require_relative 'keystone_v2'
-require_relative 'keystone_v3'
+require_relative 'keystone/authentication'
+require_relative 'keystone/keystone_v2'
+require_relative 'keystone/keystone_v3'
diff --git a/ns-provisioning/helpers/instantiation.rb b/ns-provisioning/helpers/instantiation.rb
index 8221e88..7f106a3 100644
--- a/ns-provisioning/helpers/instantiation.rb
+++ b/ns-provisioning/helpers/instantiation.rb
@@ -17,7 +17,6 @@
#
# @see NSProvisioner
module InstantiationHelper
-
# Create an authentication to PoP_id
#
# @param [JSON] instance NSR instance
@@ -26,7 +25,7 @@ module InstantiationHelper
# @param [JSON] callback_url Callback url in case of error happens
# @return [Hash, nil] authentication
# @return [Hash, String] if the parsed message is an invalid JSON
- def create_authentication(instance, nsd_id, pop_info, callback_url)
+ def create_authentication(instance, _nsd_id, pop_info, _callback_url)
@instance = instance
logger.info 'Authentication not created for this PoP. Starting creation of credentials.'
@@ -38,7 +37,7 @@ def create_authentication(instance, nsd_id, pop_info, callback_url)
pop_auth['urls'] = popUrls
# create credentials for pop_id
- if popUrls[:keystone].nil? || popUrls[:orch].nil? #|| popUrls[:tenant].nil?
+ if popUrls[:keystone].nil? || popUrls[:orch].nil? # || popUrls[:tenant].nil?
return handleError(@instance, 'Internal error: Keystone and/or openstack urls missing.')
end
@@ -56,29 +55,17 @@ def create_authentication(instance, nsd_id, pop_info, callback_url)
token = credentials[:token]
if !pop_info['is_admin']
- pop_auth['username'] = pop_info['user']
- pop_auth['tenant_name'] = pop_info['tenant_name']
- pop_auth['password'] = pop_info['password']
- pop_auth['tenant_id'] = tenant_id
- pop_auth['user_id'] = user_id
- pop_auth['token'] = token
+ pop_auth['username'] = pop_info['user']
+ pop_auth['tenant_name'] = pop_info['tenant_name']
+ pop_auth['password'] = pop_info['password']
+ pop_auth['tenant_id'] = tenant_id
+ pop_auth['user_id'] = user_id
+ pop_auth['token'] = token
else
- #generate credentials
+ # generate credentials
credentials, errors = generate_credentials(@instance, keystone_url, popUrls, tenant_id, user_id, token)
return 400, errors if errors
pop_auth = pop_auth.merge(credentials)
-=begin
- keystone_version = URI(keystone_url).path.split('/').last
- if keystone_version == 'v2.0'
- credentials, errors = generate_v2_credentials(@instance, popUrls, tenant_id, user_id, token)
- return 400, errors if errors
- pop_auth = pop_auth.merge(credentials)
- elsif keystone_version == 'v3'
- pop_auth, errors = generate_v3_credentials(@instance, popUrls, tenant_id, user_id, token)
- return 400, errors if errors
- pop_auth = pop_auth.merge(credentials)
- end
-=end
end
end
pop_auth
@@ -119,13 +106,13 @@ def instantiate_vnf(instance, nsd_id, vnf, slaInfo)
auth: {
url: {
keystone: popUrls[:keystone],
- orch: popUrls[:orch],# to remove
+ orch: popUrls[:orch], # to remove
heat: popUrls[:orch],
compute: popUrls[:compute]
},
tenant_id: pop_auth['tenant_id'],
token: pop_auth['token'],
- is_admin: pop_auth['is_admin']
+ is_admin: pop_auth['is_admin']
},
reserved_resources: @instance['resource_reservation'].find { |resources| resources[:pop_id] == pop_id },
security_group_id: pop_auth['security_group_id'],
@@ -138,18 +125,17 @@ def instantiate_vnf(instance, nsd_id, vnf, slaInfo)
begin
response = RestClient.post settings.vnf_manager + '/vnf-provisioning/vnf-instances', vnf_provisioning_info.to_json, content_type: :json
-=begin rescue RestClient::ExceptionWithResponse => e
- puts "Excepion with response"
- puts e
- logger.error e
- logger.error e.response
- if !e.response.nil?
- logger.error e.response.body
- end
- #return e.response.code, e.response.body
- logger.error 'Handle error.'
- return
-=end
+ # rescue RestClient::ExceptionWithResponse => e
+ # puts "Excepion with response"
+ # puts e
+ # logger.error e
+ # logger.error e.response
+ # if !e.response.nil?
+ # logger.error e.response.body
+ # end
+ # #return e.response.code, e.response.body
+ # logger.error 'Handle error.'
+ # return
rescue => e
@instance.push(lifecycle_event_history: 'ERROR_CREATING ' + vnf_id.to_s + ' VNF')
@instance.update_attribute('status', 'ERROR_CREATING')
@@ -177,7 +163,7 @@ def instantiate_vnf(instance, nsd_id, vnf, slaInfo)
end
end
logger.error 'Handle error.'
- return 400, "Error wiht the VNF"
+ return 400, 'Error wiht the VNF'
end
vnf_manager_response, errors = parse_json(response)
diff --git a/ns-provisioning/helpers/keystone/authentication.rb b/ns-provisioning/helpers/keystone/authentication.rb
new file mode 100644
index 0000000..57f1d10
--- /dev/null
+++ b/ns-provisioning/helpers/keystone/authentication.rb
@@ -0,0 +1,95 @@
+#
+# TeNOR - NS Provisioning
+#
+# Copyright 2014-2016 i2CAT Foundation, Portugal Telecom Inovação
+#
+# 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.
+#
+# @see NSProvisioner
+module AuthenticationHelper
+ def authenticate(keystone_url, tenant_name, username, password)
+ keystone_version = URI(keystone_url).path.split('/').last
+ if keystone_version == 'v2.0'
+ user_authentication, errors = authentication_v2(keystone_url, tenant_name, username, password)
+ logger.error errors if errors
+ return 400, errors.to_json if errors
+ tenant_id = user_authentication['access']['token']['tenant']['id']
+ user_id = user_authentication['access']['user']['id']
+ token = user_authentication['access']['token']['id']
+ elsif keystone_version == 'v3'
+ user_authentication, errors = authentication_v3(keystone_url, tenant_name, username, password)
+ logger.error errors if errors
+ return 400, errors.to_json if errors
+ if !user_authentication['token']['project'].nil?
+ tenant_id = user_authentication['token']['project']['id']
+ user_id = user_authentication['token']['user']['id']
+ token = user_authentication['token']['id']
+ else
+ errors = 'No project found with the authentication.'
+ return 400, errors.to_json if errors
+ end
+ end
+ { tenant_id: tenant_id, user_id: user_id, token: token }
+ end
+
+ def generate_credentials(instance, keystone_url, popUrls, tenant_id, user_id, token)
+ keystone_version = URI(keystone_url).path.split('/').last
+ if keystone_version == 'v2.0'
+ credentials, errors = generate_v2_credentials(instance, popUrls, tenant_id, user_id, token)
+ return 400, errors if errors
+ elsif keystone_version == 'v3'
+ credentials, errors = generate_v3_credentials(instance, popUrls, tenant_id, user_id, token)
+ return 400, errors if errors
+ end
+ credentials
+ end
+
+ def create_user_and_project(heat_api, _instance_id, project_name, username, password, tenant_id, token)
+ generated_credentials = {}
+ generated_credentials['password'] = password
+ generated_credentials['tenant_name'] = project_name
+ generated_credentials['username'] = username
+
+ hot_generator_message = {
+ project_name: generated_credentials['tenant_name'],
+ username: generated_credentials['username'],
+ password: generated_credentials['password'],
+ domain: nil
+ }
+
+ logger.info 'Generating user HOT template...'
+ hot, errors = generateUserHotTemplate(hot_generator_message)
+ return handleError(@instance, errors) if errors
+
+ logger.info 'Send user template to HEAT Orchestration'
+ stack_name = 'user_' + @instance['id'].to_s
+ template = { stack_name: stack_name, template: hot }
+ stack, errors = sendStack(heat_api, tenant_id, template, token)
+ return handleError(@instance, errors) if errors
+ stack_id = stack['stack']['id']
+ stack_url = stack['stack']['links'][0]['href']
+
+ logger.info 'Checking user stack creation...'
+ stack_info, errors = create_stack_wait(heat_api, tenant_id, stack_name, token, 'NS User')
+ return handleError(@instance, errors) if errors
+
+ logger.info 'User stack CREATE_COMPLETE. Reading user information from stack...'
+ sleep(3)
+ stack_info, errors = getStackInfo(heat_api, tenant_id, stack_name, token)
+ return handleError(@instance, errors) if errors
+ tenant_id = stack_info['stack']['outputs'].find { |res| res['output_key'] == 'project_id' }['output_value']
+ user_id = stack_info['stack']['outputs'].find { |res| res['output_key'] == 'user_id' }['output_value']
+
+ [stack_url, tenant_id, user_id]
+ end
+end
diff --git a/ns-provisioning/helpers/keystone_v2.rb b/ns-provisioning/helpers/keystone/keystone_v2.rb
similarity index 100%
rename from ns-provisioning/helpers/keystone_v2.rb
rename to ns-provisioning/helpers/keystone/keystone_v2.rb
diff --git a/ns-provisioning/helpers/keystone_v3.rb b/ns-provisioning/helpers/keystone/keystone_v3.rb
similarity index 99%
rename from ns-provisioning/helpers/keystone_v3.rb
rename to ns-provisioning/helpers/keystone/keystone_v3.rb
index aa9fb72..3ae9084 100644
--- a/ns-provisioning/helpers/keystone_v3.rb
+++ b/ns-provisioning/helpers/keystone/keystone_v3.rb
@@ -17,7 +17,6 @@
#
# @see NSProvisioner
module Authenticationv3Helper
-
def generate_v3_credentials(instance, popUrls, tenant_id, user_id, token)
@instance = instance
pop_auth = {}
diff --git a/ns-provisioning/helpers/mapping.rb b/ns-provisioning/helpers/mapping.rb
index 2732cab..98bc688 100644
--- a/ns-provisioning/helpers/mapping.rb
+++ b/ns-provisioning/helpers/mapping.rb
@@ -17,50 +17,63 @@
#
# @see MappingHelper
module MappingHelper
+ # Call the Service Mapping for service allocation
+ #
+ # @param [JSON] Microservice information
+ # @return [Hash, nil] if the parsed message is a valid JSON
+ # @return [Hash, String] if the parsed message is an invalid JSON
+ def callMapping(mapping_host, ms, _nsd)
+ begin
+ response = RestClient.post mapping_host, ms.to_json, content_type: :json
+ # response = RestClient.post settings.mapping + '/mapper', ms.to_json, content_type: :json
+ rescue => e
+ logger.error e
+ if defined?(e.response).nil?
+ # halt 400, "NS-Mapping unavailable"
+ end
+ logger.error e.response
+ return 500, 'Service Mapping error.'
+ # halt e.response.code, e.response.body
+ end
+ logger.info response
- # Call the Service Mapping for service allocation
- #
- # @param [JSON] Microservice information
- # @return [Hash, nil] if the parsed message is a valid JSON
- # @return [Hash, String] if the parsed message is an invalid JSON
- def callMapping(ms, nsd)
+ mapping, errors = parse_json(response.body)
+ return 400, errors if errors
- begin
- response = RestClient.post settings.mapping + '/mapper', ms.to_json, :content_type => :json
- rescue => e
- logger.error e
- if (defined?(e.response)).nil?
- #halt 400, "NS-Mapping unavailable"
- end
- return 500, "Service Mapping error."
- #halt e.response.code, e.response.body
+ mapping
end
- mapping, errors = parse_json(response.body)
- return 400, errors if errors
+ # When the Mapping is not required, only one pop or is selected manually, use the same format for the response
+ def getMappingResponse(nsd, pop_id)
+ vnf_mapping = []
+ nsd['vnfds'].each do |vnf_id|
+ vnf_mapping << { 'maps_to_PoP' => "/pop/#{pop_id}", 'vnf' => '/' + vnf_id.to_s }
+ end
- return mapping
- end
-
- # When the Mapping is not required, only one pop or is selected manually, use the same format for the response
- def getMappingResponse(nsd, pop_id)
- vnf_mapping = []
- nsd['vnfds'].each do |vnf_id|
- vnf_mapping << {"maps_to_PoP" => "/pop/#{pop_id}", "vnf" => "/" + vnf_id.to_s}
- end
-
- mapping = {
- "created_at" => "Thu Nov 5 10:13:25 2015",
- "links_mapping" =>
+ mapping = {
+ 'created_at' => 'Thu Nov 5 10:13:25 2015',
+ 'links_mapping' =>
[
{
- "vld_id" => "vld1",
- "maps_to_link" => "/pop/link/85b0bc34-dff0-4399-8435-4fb2ed65790a"
+ 'vld_id' => 'vld1',
+ 'maps_to_link' => '/pop/link/85b0bc34-dff0-4399-8435-4fb2ed65790a'
}
],
- "vnf_mapping" => vnf_mapping
- }
- return mapping
- end
+ 'vnf_mapping' => vnf_mapping
+ }
+ mapping
+ end
+ def replace_pop_name_by_pop_id(mapping, pops)
+ mapping['vnf_mapping'].each do |m|
+ found_pops = pops.find{ |q| q['name'] == m['maps_to_PoP'].split("/pop/")[1] }
+ puts found_pops
+ if found_pops.nil?
+ return 400, "The PoP from Mapping cannot be matched to a PoP in TeNOR."
+ else
+ m['maps_to_PoP'] = "/pop/" + pops.find{ |q| q['name'] == m['maps_to_PoP'].split("/pop/")[1] }['id'].to_s
+ end
+ end
+ mapping
+ end
end
diff --git a/ns-provisioning/helpers/monitoring.rb b/ns-provisioning/helpers/monitoring.rb
index 7aa50fd..197f2cb 100644
--- a/ns-provisioning/helpers/monitoring.rb
+++ b/ns-provisioning/helpers/monitoring.rb
@@ -17,72 +17,67 @@
#
# @see OrchestratorNsProvisioner
module MonitoringHelper
+ # Prepare the monitoring data and sends to the NS Monitoring
+ #
+ # @param [JSON] message the NSD
+ # @param [JSON] message the NSR id
+ # @param [JSON] message the ns instance
+ # @return [Hash, nil] if the parsed message is a valid JSON
+ # @return [Hash, String] if the parsed message is an invalid JSON
+ def monitoringData(nsd, nsi_id, instance)
+ monitoring = { nsi_id: nsi_id }
- # Prepare the monitoring data and sends to the NS Monitoring
- #
- # @param [JSON] message the NSD
- # @param [JSON] message the NSR id
- # @param [JSON] message the ns instance
- # @return [Hash, nil] if the parsed message is a valid JSON
- # @return [Hash, String] if the parsed message is an invalid JSON
- def monitoringData(nsd, nsi_id, instance)
+ vnfs = nsd['vnfds']
+ monitor = nsd['monitoring_parameters']
- monitoring = {:nsi_id => nsi_id}
+ paramsVnf = []
+ paramsNs = []
+ sla = nsd['sla']
+ sla.each do |s|
+ assurance_parameters = s['assurance_parameters']
+ assurance_parameters.each_with_index do |x, i|
+ paramsVnf << { id: i + 1, name: x['name'], unit: x['unit'] }
+ paramsNs << { id: i + 1, name: x['name'], formula: x['formula'], value: x['value'] }
+ end
+ end
+ monitoring[:parameters] = paramsNs
+ vnf_instances = []
+ instance['vnfrs'].each do |x|
+ vnf_instances << { id: x['vnfd_id'], parameters: paramsVnf, vnfr_id: x['vnfr_id'] }
+ end
+ monitoring[:vnf_instances] = vnf_instances
- vnfs = nsd['vnfds']
- monitor = nsd['monitoring_parameters']
+ # puts JSON.pretty_generate(monitoring)
- paramsVnf = []
- paramsNs = []
- sla = nsd['sla']
- sla.each {|s|
- assurance_parameters = s['assurance_parameters']
- assurance_parameters.each_with_index {|x, i|
- paramsVnf << {:id => i+1, :name => x['name'], :unit => x['unit']}
- paramsNs << {:id => i+1, :name => x['name'], :formula => x['formula'], :value => x['value']}
- }
- }
- monitoring[:parameters] = paramsNs
- vnf_instances = []
- instance['vnfrs'].each {|x|
- vnf_instances << {:id => x['vnfd_id'], :parameters => paramsVnf, :vnfr_id => x['vnfr_id']}
- }
- monitoring[:vnf_instances] = vnf_instances
+ begin
+ response = RestClient.post settings.ns_monitoring + '/ns-monitoring/monitoring-parameters', monitoring.to_json, content_type: :json
+ rescue Errno::ECONNREFUSED
+ puts 'NS Monitoring unreachable'
+ # halt 500, 'NS Monitoring unreachable'
+ rescue => e
+ logger.error e
+ # halt e.response.code, e.response.body
+ end
- #puts JSON.pretty_generate(monitoring)
-
- begin
- response = RestClient.post settings.ns_monitoring + '/ns-monitoring/monitoring-parameters', monitoring.to_json, :content_type => :json
- rescue Errno::ECONNREFUSED
- puts 'NS Monitoring unreachable'
-# halt 500, 'NS Monitoring unreachable'
- rescue => e
- logger.error e
- #halt e.response.code, e.response.body
+ # return monitoring
end
- #return monitoring
- end
-
- def sla_enforcement(nsd, instance_id)
- parameters = []
+ def sla_enforcement(nsd, instance_id)
+ parameters = []
- nsd['sla'].each do |sla|
- #sla['id']
- sla['assurance_parameters'].each do |assurance_parameter|
- parameters.push({:param_name => assurance_parameter['param_name'], :minimum => nil, :maximum => nil})
- end
-
- end
- sla = {:nsi_id => instance_id, :parameters => parameters}
- begin
- response = RestClient.post settings.sla_enforcement + "/sla-enforcement/slas", sla.to_json, :content_type => :json
- rescue => e
- logger.error e
- if (defined?(e.response)).nil?
- halt 503, "SLA-Enforcement unavailable"
- end
- halt e.response.code, e.response.body
+ nsd['sla'].each do |sla|
+ # sla['id']
+ sla['assurance_parameters'].each do |assurance_parameter|
+ parameters.push(param_name: assurance_parameter['param_name'], minimum: nil, maximum: nil)
+ end
+ end
+ sla = { nsi_id: instance_id, parameters: parameters }
+ begin
+ response = RestClient.post settings.sla_enforcement + '/sla-enforcement/slas', sla.to_json, content_type: :json
+ rescue => e
+ logger.error e
+ halt 503, 'SLA-Enforcement unavailable' if defined?(e.response).nil?
+ halt e.response.code, e.response.body
+ end
end
- end
end
diff --git a/ns-provisioning/helpers/ns.rb b/ns-provisioning/helpers/ns.rb
index 449f7c8..f664870 100644
--- a/ns-provisioning/helpers/ns.rb
+++ b/ns-provisioning/helpers/ns.rb
@@ -131,21 +131,21 @@ def recoverState(instance, _error)
end
unless settings.default_tenant && !popUrls[:is_admin]
- logger.info "Removing user stack...."
+ logger.info 'Removing user stack....'
stack_url = auth_info['stack_url']
- logger.debug 'Removing user reserved stack...'
if !auth_info['stack_url'].nil?
response, errors = delete_stack_with_wait(auth_info['stack_url'], token)
logger.error errors if errors
return 400, errors if errors
- logger.info "User and tenant removed correctly."
+ logger.info 'User and tenant removed correctly.'
else
- logger.info "No user and tenant to remove."
+ logger.info 'No user and tenant to remove.'
end
end
- logger.info "REMOVED: User " + auth_info['user_id'].to_s + " and tenant '" + auth_info['tenant_id'].to_s
+ logger.info 'REMOVED: User ' + auth_info['user_id'].to_s + " and tenant '" + auth_info['tenant_id'].to_s
end
+ logger.debug "Tenants and users removed correctly."
message = {
code: 200,
@@ -168,69 +168,57 @@ def instantiate(instance, nsd, instantiation_info)
callback_url = @instance['notification']
flavour = @instance['service_deployment_flavour']
pop_list = instantiation_info['pop_list']
- #pop_id = instantiation_info['pop_id']
- mapping_id = instantiation_info['mapping_id']
+ mapping_info = instantiation_info['mapping']
nap_id = instantiation_info['nap_id']
customer_id = instantiation_info['customer_id']
+ infr_repo_url = instantiation_info['infr_repo_url']
slaInfo = nsd['sla'].find { |sla| sla['sla_key'] == flavour }
if slaInfo.nil?
- return generateMarketplaceResponse(callbackUrl, generateError(nsd['id'], 'FAILED', 'Internal error: SLA inconsistency'))
+ return handleError(@instance, 'Internal error: SLA inconsistency')
end
sla_id = nsd['sla'].find { |sla| sla['sla_key'] == flavour }['id']
logger.debug 'SLA id: ' + sla_id
- infr_repo_url = if settings.environment == 'development'
- { 'host' => '', 'port' => '' }
- else
- settings.infr_repository
- end
-
- logger.info 'List of available PoPs: ' + pop_list.to_s
- if pop_list.size == 1 || mapping_id.nil?
+ if pop_list.size == 1 && mapping_info.empty?
pop_id = pop_list[0]['id']
- elsif !mapping_id.nil?
- # call specified mapping with the id
- # TODO
- end
-
- if !pop_id.nil?
- logger.debug 'Deploy to PoP id: ' + pop_id.to_s
+ logger.info 'Deploy to PoP id: ' + pop_id.to_s
mapping = getMappingResponse(nsd, pop_id)
- else
+ elsif !mapping_info.empty?
+ logger.info "Calling Mapping algorithm "
+ logger.info mapping_info
+ if infr_repo_url.nil?
+ return handleError(@instance, 'Internal error: Infrastructure Repository not reachable.')
+ end
+
ms = {
NS_id: nsd['id'],
- tenor_api: settings.manager,
- infr_repo_api: infr_repo_url,
- development: true,
NS_sla: sla_id,
- overcommitting: 'true'
+ tenor_api: settings.manager,
+ infr_repo_api: infr_repo_url#,
+ #development: true,
+ #overcommitting: 'true'
}
- mapping, errors = callMapping(ms, nsd)
- # mapping Mapper PoPs with gatekeeper PoPs.
- return generateMarketplaceResponse(callback_url, generateError(nsd['id'], 'FAILED', 'Internal error: Mapping not reachable.')) if errors
+ logger.info ms
+ mapping, errors = callMapping(mapping_info, ms, nsd)
+ if mapping['vnf_mapping']
+ mapping, errors = replace_pop_name_by_pop_id(mapping, pop_list)
+ return handleError(@instance, errors) if errors
+ else
+ return handleError(@instance, 'Internal error: Mapping: not enough resources.')
+ end
+ return handleError(@instance, 'Internal error: Mapping not reachable.') if errors
end
@instance.update_attribute('mapping_time', DateTime.now.iso8601(3).to_s)
-
- unless mapping['vnf_mapping']
- generateMarketplaceResponse(callback_url, generateError(nsd['id'], 'FAILED', 'Internal error: Mapping: not enough resources.'))
- return
- end
-
- if @instance.nil?
- generateMarketplaceResponse(callback_url, generateError(nsd['id'], 'FAILED', 'Internal error: instance is null.'))
- return
- end
-
@instance.push(lifecycle_event_history: 'MAPPED FOUND')
@instance['vnfrs'] = []
- @instance['authentication'] = []
+ #@instance['authentication'] = []
+ @instance.update_attribute('status', 'CREATING AUTHENTICATIONS')
# if mapping of all VNFs are in the same PoP. Create Authentication and network 1 time
mapping['vnf_mapping'].each do |vnf|
-
logger.info 'Start authentication process of ' + vnf.to_s
pop_id = vnf['maps_to_PoP'].gsub('/pop/', '')
pop_info = pop_list.find { |p| p['id'] == pop_id.to_i }
@@ -241,13 +229,16 @@ def instantiate(instance, nsd, instantiation_info)
next unless authentication.nil?
pop_auth, errors = create_authentication(@instance, nsd['id'], pop_info, callback_url)
return handleError(@instance, errors) if errors
- @instance['authentication'] << pop_auth
+ #@instance['authentication'] << pop_auth
+ @instance.push(authentication: pop_auth)
end
logger.info 'Authentication generated'
# check if @instance['authentication'] has the credentials for each PoP in mapping['vnf_mapping'] ? compare sizes?
+ @instance.update_attribute('status', 'CREATING NETWORKS')
+
# generate networks in each PoP?
if @instance['authentication'].size > 1
logger.info 'More than 1 PoP is defined. WICM is required.'
@@ -298,7 +289,7 @@ def instantiate(instance, nsd, instantiation_info)
return handleError(@instance, errors) if errors
resource_reservation = @instance['resource_reservation']
- resource_reservation << { wicm_stack: stack, pop_id: pop_auth['pop_id'] }
+ resource_reservation << { wicm_stack: stack, pop_id: pop_auth['pop_id'] }
@instance.update_attribute('resource_reservation', resource_reservation)
end
end
@@ -308,7 +299,7 @@ def instantiate(instance, nsd, instantiation_info)
# generate networks for this PoP
if @instance['authentication'].nil?
- return handleError(@instance, "Authentication not valid.")
+ return handleError(@instance, 'Authentication not valid.')
end
pop_auth = @instance['authentication'][0]
@@ -328,7 +319,7 @@ def instantiate(instance, nsd, instantiation_info)
hot, errors = generateNetworkHotTemplate(sla_id, hot_generator_message)
return handleError(@instance, errors) if errors
- logger.info 'Send network template to HEAT Orchestration'
+ logger.info 'Sending network template to HEAT Orchestration'
stack_name = 'network_' + @instance['id'].to_s
template = { stack_name: stack_name, template: hot }
stack, errors = sendStack(popUrls[:orch], pop_auth['tenant_id'], template, tenant_token)
@@ -336,14 +327,14 @@ def instantiate(instance, nsd, instantiation_info)
stack_id = stack['stack']['id']
- #save stack_url in reserved resurces
- logger.info "Saving reserved stack...."
+ # save stack_url in reserved resurces
+ logger.info 'Saving reserved stack....'
@resource_reservation = @instance['resource_reservation']
resource_reservation = []
resource_reservation << {
ports: [],
- network_stack: {:id => stack_id, :stack_url => stack['stack']['links'][0]['href']},
+ network_stack: { id: stack_id, stack_url: stack['stack']['links'][0]['href'] },
public_network_id: publicNetworkId,
dns_server: popUrls[:dns],
pop_id: pop_auth['pop_id'],
@@ -377,20 +368,20 @@ def instantiate(instance, nsd, instantiation_info)
@instance.push(lifecycle_event_history: 'NETWORK CREATED')
@instance.update_attribute('vlr', networks)
- #get array
- object = @resource_reservation.find {|s| s[:network_stack][:id] == stack['stack']['id'] }
- #remove array
+ # get array
+ object = @resource_reservation.find { |s| s[:network_stack][:id] == stack['stack']['id'] }
+ # remove array
@instance.pull(resource_reservation: object)
- #add array
- resource_reservation = resource_reservation.find {|s| s[:network_stack][:id] == stack['stack']['id'] }
+ # add array
+ resource_reservation = resource_reservation.find { |s| s[:network_stack][:id] == stack['stack']['id'] }
resource_reservation[:routers] = routers
resource_reservation[:networks] = networks
@instance.push(resource_reservation: resource_reservation)
end
+ #instantiate each VNF
@instance.update_attribute('status', 'INSTANTIATING VNFs')
vnfrs = []
- # for each VNF, instantiate
mapping['vnf_mapping'].each do |vnf|
response, errors = instantiate_vnf(@instance, nsd['id'], vnf, slaInfo)
return handleError(@instance, errors) if errors
diff --git a/ns-provisioning/helpers/pop.rb b/ns-provisioning/helpers/pop.rb
index 25ea544..bccf39d 100644
--- a/ns-provisioning/helpers/pop.rb
+++ b/ns-provisioning/helpers/pop.rb
@@ -17,7 +17,6 @@
#
# @see NsProvisioner
module PopHelper
-
# Returns the information of PoPs
#
# @param [String] message the pop id
@@ -62,38 +61,13 @@ def getPopUrls(extraInfo)
popUrls[:compute] = item.split('=')[1]
elsif key == 'orch-endpoint'
popUrls[:orch] = item.split('=')[1]
- elsif key == 'tenant-name'#deprecated
- popUrls[:tenant] = item.split('=')[1]
elsif key == 'dns'
popUrls[:dns] << item.split('=')[1] unless item.split('=')[1].nil?
- elsif key == 'isAdmin'#deprecated
- popUrls[:is_admin] = false
- popUrls[:is_admin] = true if item.split('=')[1].to_s == 'true'
end
end
popUrls
end
- # Returns all the registered PoPs
- #
- # @return [Hash, nil] if the parsed message is a valid JSON
- # @return [Hash, String] if the parsed message is an invalid JSON
- def getPops
- begin
- response = RestClient.get "#{settings.manager}/gatekeeper/dc", content_type: :json
- rescue => e
- logger.error e
- logger.error 'PoP no exists?'
- return 400, 'no exists'
- end
- popInfo, errors = parse_json(response)
- return 400, errors if errors
-
- logger.error popInfo
-
- popInfo
- end
-
# Returns an object with the properties of a PoP
# @param [string] The extra information in string
# @return [Hash] The PoP information in hash format
diff --git a/ns-provisioning/helpers/vim.rb b/ns-provisioning/helpers/vim.rb
index 045b65b..bc2e9cd 100644
--- a/ns-provisioning/helpers/vim.rb
+++ b/ns-provisioning/helpers/vim.rb
@@ -17,29 +17,6 @@
#
# @see NSProvisioner
module VimHelper
-
- #deprecated
- def deleteTenant(keystoneUrl, tenant_id, token)
- begin
- response = RestClient.delete keystoneUrl + '/tenants/' + tenant_id, :content_type => :json, :'X-Auth-Token' => token
- rescue => e
- logger.error e
- logger.error e.response.body
- end
- nil
- end
-#deprecated
- def deleteUser(keystoneUrl, user_id, token)
- begin
- response = RestClient.delete keystoneUrl + '/users/' + user_id, :content_type => :json, :'X-Auth-Token' => token
- rescue => e
- logger.error e
- # logger.error e.response.body
- end
-
- nil
- end
-
def getAdminRole(keystoneUrl, token)
begin
response = RestClient.get keystoneUrl + '/OS-KSADM/roles', :content_type => :json, :'X-Auth-Token' => token
@@ -77,9 +54,7 @@ def publicNetworkId(neutronUrl, token)
if network.nil?
network = networks['networks'].find { |role| role['router:external'] }
end
- if network.nil?
- return 400, "No external network defined in Openstack."
- end
+ return 400, 'No external network defined in Openstack.' if network.nil?
network['id']
end
diff --git a/ns-provisioning/models/nsr.rb b/ns-provisioning/models/nsr.rb
index ec2324e..c928259 100644
--- a/ns-provisioning/models/nsr.rb
+++ b/ns-provisioning/models/nsr.rb
@@ -52,5 +52,6 @@ class Nsr
field :mapping_time, type: Time
field :instantiation_start_time, type: Time
field :instantiation_end_time, type: Time
+ field :authentication, type: Array
end
diff --git a/ns-provisioning/routes/ns.rb b/ns-provisioning/routes/ns.rb
index 1832e74..c35f154 100644
--- a/ns-provisioning/routes/ns.rb
+++ b/ns-provisioning/routes/ns.rb
@@ -17,15 +17,14 @@
#
# @see NsProvisioning
class Provisioner < NsProvisioning
-
# @method get_ns_instances
# @overload get "/ns-instances"
# Gets all ns-instances
get '/' do
instances = if params[:status]
- Nsr.where(status: params[:status])
- else
- Nsr.all
+ Nsr.where(status: params[:status])
+ else
+ Nsr.all
end
return instances.to_json
@@ -82,7 +81,8 @@ class Provisioner < NsProvisioning
notification: instantiation_info['callback_url'],
lifecycle_event_history: ['INIT'],
audit_log: [],
- marketplace_callback: instantiation_info['callback_url']
+ marketplace_callback: instantiation_info['callback_url'],
+ authentication: []
}
@instance = Nsr.new(instance)
@@ -133,6 +133,7 @@ class Provisioner < NsProvisioning
if params[:status] === 'terminate'
logger.info 'Starting thread for removing VNF and NS instances.'
+ @nsInstance.update_attribute('status', 'DELETING')
Thread.abort_on_exception = false
Thread.new do
# operation = proc {
@@ -141,12 +142,13 @@ class Provisioner < NsProvisioning
logger.info 'Pop_id: ' + vnf['pop_id'].to_s
raise 'VNF not defined' if vnf['pop_id'].nil?
- popInfo, errors = getPopInfo(vnf['pop_id'])
+ pop_info, errors = getPopInfo(vnf['pop_id'])
+ logger.errors if errors
raise 400, errors if errors
- if popInfo == 400
+ if pop_info == 400
logger.error 'Pop id no exists.'
- return
+ return
end
pop_auth = @nsInstance['authentication'].find { |pop| pop['pop_id'] == vnf['pop_id'] }
@@ -345,6 +347,18 @@ class Provisioner < NsProvisioning
end
end
+ if @instance['resource_reservation'].find { |resource| resource.has_key?('wicm_stack')}
+ logger.info 'Starting traffic redirection in the WICM'
+ Thread.new do
+ begin
+ response = RestClient.put settings.wicm + '/vnf-connectivity/' + nsr_id, '', content_type: :json, accept: :json
+ rescue => e
+ logger.error e
+ end
+ logger.info response
+ end
+ end
+
logger.info 'Starting monitoring workflow...'
Thread.new do
sleep(5)
diff --git a/ns-provisioning/routes/scaling.rb b/ns-provisioning/routes/scaling.rb
index c81d449..c0df5b0 100644
--- a/ns-provisioning/routes/scaling.rb
+++ b/ns-provisioning/routes/scaling.rb
@@ -17,118 +17,103 @@
#
# @see NsProvisioner
class Scaling < NsProvisioning
-
- # @method post_ns_instances_scale_out
- # @overload post '/ns-instances/scaling/:id/scale_out'
- # Post a Scale out request
- # @param [JSON]
- post "/:id/scale_out" do
-
- halt 415 unless request.content_type == 'application/json'
-
- begin
- instance = Nsr.find(params["id"])
- rescue Mongoid::Errors::DocumentNotFound => e
- halt(404)
+ # @method post_ns_instances_scale_out
+ # @overload post '/ns-instances/scaling/:id/scale_out'
+ # Post a Scale out request
+ # @param [JSON]
+ post '/:id/scale_out' do |id|
+ halt 415 unless request.content_type == 'application/json'
+
+ begin
+ instance = Nsr.find(id)
+ rescue Mongoid::Errors::DocumentNotFound => e
+ halt(404)
+ end
+
+ instance['vnfrs'].each do |vnf|
+ logger.info 'Scale out VNF ' + vnf['vnfr_id'].to_s
+
+ puts 'Pop_id: ' + vnf['pop_id'].to_s
+ raise 'VNF not defined' if vnf['pop_id'].nil?
+
+ pop_info = getPopInfo(vnf['pop_id'])
+ if pop_info == 400
+ logger.error 'Pop id no exists.'
+ return
+ end
+
+ pop_auth = instance['authentication'].find { |pop| pop['pop_id'] == vnf['pop_id'] }
+ pop_urls = pop_auth['urls']
+
+ scale = {
+ auth => {
+ tenant => pop_auth['tenant_name'],
+ username => pop_auth['username'],
+ password => pop_auth['password'],
+ url => {
+ keystone => pop_urls[:keystone],
+ heat => pop_urls[:orch]
+ }
+ }
+ }
+ begin
+ response = RestClient.post settings.vnf_manager + '/vnf-instances/scaling/' + vnf['vnfr_id'] + '/scale_out', scale.to_json, content_type => :json
+ rescue => e
+ logger.error e
+ end
+
+ logger.debug response
+ end
+ halt 200, 'Scale out done.'
end
- instance['vnfrs'].each do |vnf|
- puts vnf
- logger.info "Scale out VNF " + vnf['vnfr_id'].to_s
-
- puts "Pop_id: " + vnf['pop_id'].to_s
- if vnf['pop_id'].nil?
- raise "VNF not defined"
- end
-
- popInfo = getPopInfo(vnf['pop_id'])
- if popInfo == 400
- logger.error "Pop id no exists."
- return
- raise "Pop id no exists."
- end
-
- pop_auth = instance['authentication'].find { |pop| pop['pop_id'] == vnf['pop_id'] }
- popUrls = pop_auth['urls']
-
- scale = {
- :auth => {
- :tenant => pop_auth['tenant_name'],
- :username => pop_auth['username'],
- :password => pop_auth['password'],
- :url => {
- :keystone => popUrls[:keystone],
- :heat => popUrls[:orch],
- }
- }
- }
- begin
- response = RestClient.post settings.vnf_manager + '/vnf-instances/scaling/' + vnf['vnfr_id'] + '/scale_out', scale.to_json, :content_type => :json
- rescue => e
- logger.error e
- end
-
- logger.debug response
-
+ # @method post_ns_instances_scale_in
+ # @overload post '/ns-instances/scaling/:id/scale_in'
+ # Post a Scale in request
+ # @param [JSON]
+ post '/:id/scale_in' do |id|
+ halt 415 unless request.content_type == 'application/json'
+
+ begin
+ instance = Nsr.find(id)
+ rescue Mongoid::Errors::DocumentNotFound => e
+ halt(404)
+ end
+
+ instance['vnfrs'].each do |vnf|
+ logger.info 'Scale in VNF ' + vnf['vnfr_id'].to_s
+
+ puts 'Pop_id: ' + vnf['pop_id'].to_s
+ raise 'VNF not defined' if vnf['pop_id'].nil?
+
+ pop_info = getPopInfo(vnf['pop_id'])
+ if pop_info == 400
+ logger.error 'Pop id no exists.'
+ return
+ end
+
+ pop_auth = instance['authentication'].find { |pop| pop['pop_id'] == vnf['pop_id'] }
+ pop_urls = pop_auth['urls']
+
+ scale = {
+ auth => {
+ tenant => pop_auth['tenant_name'],
+ username => pop_auth['username'],
+ password => pop_auth['password'],
+ url => {
+ keystone => pop_urls[:keystone],
+ heat => pop_urls[:orch]
+ }
+ }
+ }
+ begin
+ response = RestClient.post settings.vnf_manager + '/vnf-instances/scaling/' + vnf['vnfr_id'] + '/scale_in', scale.to_json, content_type => :json
+ rescue => e
+ logger.error e
+ end
+
+ logger.debug response
+ end
+ halt 200, 'Scale in done.'
end
- halt 200, "Scale out done."
-
- end
-
- # @method post_ns_instances_scale_in
- # @overload post '/ns-instances/scaling/:id/scale_in'
- # Post a Scale in request
- # @param [JSON]
- post "/:id/scale_in" do
-
- halt 415 unless request.content_type == 'application/json'
-
- begin
- instance = Nsr.find(params["id"])
- rescue Mongoid::Errors::DocumentNotFound => e
- halt(404)
- end
-
- instance['vnfrs'].each do |vnf|
- puts vnf
- logger.info "Scale in VNF " + vnf['vnfr_id'].to_s
-
- puts "Pop_id: " + vnf['pop_id'].to_s
- if vnf['pop_id'].nil?
- raise "VNF not defined"
- end
-
- popInfo = getPopInfo(vnf['pop_id'])
- if popInfo == 400
- logger.error "Pop id no exists."
- return
- raise "Pop id no exists."
- end
-
- pop_auth = instance['authentication'].find { |pop| pop['pop_id'] == vnf['pop_id'] }
- popUrls = pop_auth['urls']
-
- scale = {
- :auth => {
- :tenant => pop_auth['tenant_name'],
- :username => pop_auth['username'],
- :password => pop_auth['password'],
- :url => {
- :keystone => popUrls[:keystone],
- :heat => popUrls[:orch],
- }
- }
- }
- begin
- response = RestClient.post settings.vnf_manager + '/vnf-instances/scaling/' + vnf['vnfr_id'] + '/scale_in', scale.to_json, :content_type => :json
- rescue => e
- logger.error e
- end
-
- logger.debug response
-
- end
- halt 200, "Scale in done."
- end
-
end
diff --git a/nsd-validator/config/config.yml.sample b/nsd-validator/config/config.yml.sample
index 319e7b4..29b55dd 100644
--- a/nsd-validator/config/config.yml.sample
+++ b/nsd-validator/config/config.yml.sample
@@ -15,7 +15,4 @@ logger_port: 24224
xml_schema: assets/schemas/nsd.xsd
json_schema: assets/schemas/nsd_schema.json
-gk:
-service_key:
-
dependencies: []
diff --git a/sinatra-gkauth-gem/lib/sinatra/gk_auth.rb b/sinatra-gkauth-gem/lib/sinatra/gk_auth.rb
index 95ce891..6a4c63c 100644
--- a/sinatra-gkauth-gem/lib/sinatra/gk_auth.rb
+++ b/sinatra-gkauth-gem/lib/sinatra/gk_auth.rb
@@ -6,12 +6,17 @@
module Sinatra
module Gk_Auth
module Helpers
+ puts 'Loaded 1....'
$time = 5
$max_retries = 150 # in seconds
def initialize
sleep(2)
puts 'Initializing gem GK...'
- service_info = { name: settings.servicename, host: settings.address, port: settings.port, depends_on: settings.dependencies, secret: settings.servicename }
+ begin
+ service_info = { name: settings.servicename, host: settings.address, port: settings.port, depends_on: settings.dependencies, secret: settings.servicename, type: settings.type}
+ rescue
+ service_info = { name: settings.servicename, host: settings.address, port: settings.port, depends_on: settings.dependencies, secret: settings.servicename, type: "" }
+ end
publish_service(service_info) if settings.environment != 'development'
if settings.environment == 'development'
@@ -28,14 +33,13 @@ def publish_service(service_info)
begin
response = RestClient.post settings.manager + '/modules/services', service_info.to_json, accept: :json, content_type: :json
rescue => e
- puts 'Error registring or receiving dependencies to the Manager, waiting: ' + $time.to_s + ' seconds for next rety...'
+ puts 'Error registring or receiving dependencies to the Manager, waiting: ' + $time.to_s + ' seconds for next retry...'
puts e
sleep($time) # wait $time seconds
$time = $time * 2
$time = 5 if $time > $max_retries
publish_service(service_info)
end
- puts response
return if response.nil?
services, errors = parse_json(response)
return 400, errors.to_json if errors
@@ -95,40 +99,20 @@ def self.registered(app)
app.helpers Gk_Auth::Helpers
app.before do
- # env['rack.logger'] = app.settings.logger
- return if request.path_info == '/gk_credentials'
-
return if settings.environment == 'development'
authorized?
end
- # to be removed...
- app.post '/gk_credentials' do
- # credentials = {gk_url: url, service_key: key}
- return 415 unless request.content_type == 'application/json'
- credentials, errors = parse_json(request.body.read)
- return 400, errors.to_json if errors
-
- app.set :gk, credentials['gk_url']
- app.set :service_key, credentials['service_key']
-
- updateValues('gk', credentials['gk_url'])
- updateValues('service_key', credentials['service_key'])
-
- return 200
- end
-
app.post '/gk_dependencies' do
return 415 unless request.content_type == 'application/json'
- services, errors = parse_json(request.body.read)
+ ms, errors = parse_json(request.body.read)
return 400, errors.to_json if errors
return 200 if settings.dependencies.nil?
- service = services
- unless settings.dependencies.detect { |sv| sv == service['name'] }.nil?
- app.set service['name'], service['host'].to_s + ':' + service['port'].to_s
- app.set service['name'] + '_token', service['token'].to_s
+ unless settings.dependencies.detect { |sv| sv == ms['name'] }.nil?
+ app.set ms['name'], ms['host'].to_s + ':' + ms['port'].to_s
+ app.set ms['name'] + '_token', ms['token'].to_s
end
return 200
diff --git a/tenor_development.sh b/tenor_development.sh
index 45d6945..614cfa4 100755
--- a/tenor_development.sh
+++ b/tenor_development.sh
@@ -1,10 +1,9 @@
#!/bin/bash
SESSION='nsmanager'
SESSION2='vnfmanager'
-SESSION3='gatekeeper'
-SESSION4='ui'
+SESSION3='ui'
-byobu -2 new-session -d -s $SESSION4
+byobu -2 new-session -d -s $SESSION3
echo "Starting User Interface..."
byobu rename-window 'UI'
byobu send-keys "cd ui" C-m
diff --git a/tenor_install.sh b/tenor_install.sh
index e04d17a..f024472 100755
--- a/tenor_install.sh
+++ b/tenor_install.sh
@@ -241,6 +241,7 @@ configureFiles(){
configureIps $1
+ printf "Removing old config files...."
rm **/config/config.yml
for folder in $(find . -type d \( -name "ns*" -o -name "vnf*" -o -name "hot-generator" \) ); do
diff --git a/ui/README.md b/ui/README.md
index d617fdb..d8a6c85 100644
--- a/ui/README.md
+++ b/ui/README.md
@@ -17,7 +17,7 @@ Copy the sample config file:
Run `cp app/config.js.sample app/config.js`
And edit the config.js with the correct IPs.
-The UI uses the Gatekeeper Authentication. By default the UI has preconfigured the default user and password of Gatekeeper. If the admin password is different, please update the file app.rb.
+The UI uses the TeNOR Authentication. By default the UI has preconfigured the default user and password.
3. Execute the UI
Run `rake start` and the server will listen on port 9000 by default.
diff --git a/ui/apis/gk.rb b/ui/apis/gk.rb
deleted file mode 100644
index 9f2c899..0000000
--- a/ui/apis/gk.rb
+++ /dev/null
@@ -1,144 +0,0 @@
-require 'sinatra/base'
-require 'json'
-require 'rest-client'
-
-class App::Gk < Sinatra::Base
-
- get '/rest/gk/api/*' do
-
- host = request.env["HTTP_X_HOST"]
- token = request.env["HTTP_X_AUTH_TOKEN"]
-
- begin
- response = RestClient.get host + "/" + params[:splat][0], :content_type => :json, :'X-Auth-Token' => token
- rescue Errno::ECONNREFUSED
- halt 500, "Errno::ECONNREFUSED"
- rescue RestClient::Unauthorized => e
- puts e
- halt 401, "Unauthorized"
- rescue => e
- puts "ERROR"
- puts e
- halt 400
- end
- return response
- end
-
- post '/rest/gk/api/token/' do
-
- host = request.env["HTTP_X_HOST"]
- username = request.env["HTTP_X_AUTH_UID"]
- passwd = request.env["HTTP_X_AUTH_PASSWORD"]
-
- #given user name, look database
- admin_user = {:uid => App.admin_user_uid, :passwd => App.admin_user_passwd}
- admin_token = loginToGk(host, admin_user)
- users_list, users_ids = getListUsers(host, admin_token)
- index_position = users_list.find_index { |name| name == username }
- if index_position.nil?
- puts "User not found."
- halt 400, "User not found"
- end
- uid = users_ids[index_position]
-
- begin
- response = RestClient.post host + "/token/", "", :content_type => :json, :'X-Auth-Uid' => uid, :'X-Auth-Password' => passwd
- rescue Errno::ECONNREFUSED
- halt 500, "Errno::ECONNREFUSED"
- rescue => e
- puts "ERROR"
- puts e
- halt 400, "Login failed."
- end
- response = JSON.parse(response)
- response['uid'] = uid
- return response.to_json
- end
-
- post '/rest/gk/api/*' do
-
- host = request.env["HTTP_X_HOST"]
- token = request.env["HTTP_X_AUTH_TOKEN"]
- body = request.body.read
-
- begin
- response = RestClient.post host + "/" + params[:splat][0], body, :content_type => :json, :'X-Auth-Token' => token
- rescue Errno::ECONNREFUSED
- halt 500, "Errno::ECONNREFUSED"
- rescue => e
- puts "ERROR"
- puts e
- halt e.response.code, e.response.body
- end
- return response
- end
-
- put '/rest/gk/api/*' do
-
- host = request.env["HTTP_X_HOST"]
- token = request.env["HTTP_X_AUTH_TOKEN"]
- body = request.body.read
-
- begin
- response = RestClient.put host + "/" + params[:splat][0], body, :content_type => :json, :'X-Auth-Token' => token
- rescue Errno::ECONNREFUSED
- halt 500, "Errno::ECONNREFUSED"
- rescue => e
- puts "ERROR"
- puts e
- halt 400
- end
- return response
-
- end
-
- delete '/rest/gk/api/*' do
-
- host = request.env["HTTP_X_HOST"]
- token = request.env["HTTP_X_AUTH_TOKEN"]
-
- begin
- response = RestClient.delete host + "/" + params[:splat][0], :content_type => :json, :'X-Auth-Token' => token
- rescue Errno::ECONNREFUSED
- halt 500, "Errno::ECONNREFUSED"
- rescue => e
- puts "ERROR"
- puts e
- halt 400
- end
- return response
-
- end
-
- def loginToGk(host, user)
- puts host + "/token/"
- puts user[:uid]
- puts user[:passwd]
- begin
- response = RestClient.post host + "/token/", "", :content_type => :json, :'X-Auth-Uid' => user[:uid], :'X-Auth-Password' => user[:passwd]
- rescue Errno::ECONNREFUSED
- halt 500, "Errno::ECONNREFUSED"
- rescue => e
- puts "ERROR"
- puts e.response
- halt 400
- end
- response = JSON.parse(response)
- return response['token']['id']
- end
-
- def getListUsers(host, token)
- begin
- response = RestClient.get host + "/admin/user/", :content_type => :json, :'X-Auth-Token' => token
- rescue Errno::ECONNREFUSED
- halt 500, "Errno::ECONNREFUSED"
- rescue => e
- puts "ERROR"
- puts e
- halt 400
- end
- response = JSON.parse(response)
- return response['userlist'], response['userids']
- end
-
-end
diff --git a/ui/apis/proxy.rb b/ui/apis/proxy.rb
index d743382..83320b7 100644
--- a/ui/apis/proxy.rb
+++ b/ui/apis/proxy.rb
@@ -9,7 +9,7 @@ class App::Proxy < Sinatra::Base
host = request.env["HTTP_X_HOST"]
begin
- response = RestClient.get host + "/" + params[:splat][0] + "?" + request.env['QUERY_STRING'], :content_type => :json
+ response = RestClient.get host + "/" + params[:splat][0] + "?" + request.env['QUERY_STRING'], :accept => request.env["HTTP_ACCEPT"]
rescue Errno::ECONNREFUSED
halt 500, "Errno::ECONNREFUSED"
rescue => e
@@ -21,15 +21,9 @@ class App::Proxy < Sinatra::Base
end
post '/rest/api/*' do
- puts "POST........."
-puts request.env["HTTP_X_AUTH_TOKEN"]
host = request.env["HTTP_X_HOST"]
body = request.body.read
- puts params[:splat][0]
- puts host
- puts body
-
begin
response = RestClient.post host + "/" + params[:splat][0], body, :content_type => :json, :'X-Auth-Token' => request.env["HTTP_X_AUTH_TOKEN"]
rescue Errno::ECONNREFUSED
diff --git a/ui/app.rb b/ui/app.rb
index 93e856a..2e9d154 100644
--- a/ui/app.rb
+++ b/ui/app.rb
@@ -8,8 +8,6 @@ class App < Sinatra::Base
configure do
#set :root, File.dirname(__FILE__)
set :public_folder, 'app'
- set :admin_user_uid, 1
- set :admin_user_passwd, "Eq7K8h9gpg"
end
configure :development do
@@ -33,9 +31,8 @@ class App < Sinatra::Base
end
get '/bower_components/*' do
- puts "Bower"
tpl = 'bower_components/' + params[:splat][0]
File.read(File.join('bower_components', params[:splat][0]))
end
-end
\ No newline at end of file
+end
diff --git a/ui/app/bower_components/angular/.bower.json b/ui/app/bower_components/angular/.bower.json
index ff3b166..ab17812 100644
--- a/ui/app/bower_components/angular/.bower.json
+++ b/ui/app/bower_components/angular/.bower.json
@@ -1,17 +1,18 @@
{
"name": "angular",
- "version": "1.4.1",
+ "version": "1.5.8",
+ "license": "MIT",
"main": "./angular.js",
"ignore": [],
"dependencies": {},
"homepage": "https://github.com/angular/bower-angular",
- "_release": "1.4.1",
+ "_release": "1.5.8",
"_resolution": {
"type": "version",
- "tag": "v1.4.1",
- "commit": "00565b0834478e6a5b4d8ca0373b109c9d963f4b"
+ "tag": "v1.5.8",
+ "commit": "7e0e546eb6caedbb298c91a9f6bf7de7eeaa4ad2"
},
"_source": "https://github.com/angular/bower-angular.git",
- "_target": "^1.0.8",
+ "_target": ">=1.0.8",
"_originalSource": "angular"
}
\ No newline at end of file
diff --git a/ui/app/bower_components/angular/LICENSE.md b/ui/app/bower_components/angular/LICENSE.md
new file mode 100644
index 0000000..2c395ee
--- /dev/null
+++ b/ui/app/bower_components/angular/LICENSE.md
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2016 Angular
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/ui/app/bower_components/angular/angular.js b/ui/app/bower_components/angular/angular.js
index c147ec5..54f6558 100644
--- a/ui/app/bower_components/angular/angular.js
+++ b/ui/app/bower_components/angular/angular.js
@@ -1,9 +1,9 @@
/**
- * @license AngularJS v1.4.1
- * (c) 2010-2015 Google, Inc. http://angularjs.org
+ * @license AngularJS v1.5.8
+ * (c) 2010-2016 Google, Inc. http://angularjs.org
* License: MIT
*/
-(function(window, document, undefined) {'use strict';
+(function(window) {'use strict';
/**
* @description
@@ -57,7 +57,7 @@ function minErr(module, ErrorConstructor) {
return match;
});
- message += '\nhttp://errors.angularjs.org/1.4.1/' +
+ message += '\nhttp://errors.angularjs.org/1.5.8/' +
(module ? module + '/' : '') + code;
for (i = SKIP_INDEXES, paramPrefix = '?'; i < templateArgs.length; i++, paramPrefix = '&') {
@@ -126,7 +126,6 @@ function minErr(module, ErrorConstructor) {
includes: true,
arrayRemove: true,
copy: true,
- shallowCopy: true,
equals: true,
csp: true,
jq: true,
@@ -171,6 +170,7 @@ function minErr(module, ErrorConstructor) {
* @ngdoc module
* @name ng
* @module ng
+ * @installation
* @description
*
* # ng (core module)
@@ -188,29 +188,9 @@ var REGEX_STRING_REGEXP = /^\/(.+)\/([a-z]*)$/;
// This is used so that it's possible for internal tests to create mock ValidityStates.
var VALIDITY_STATE_PROPERTY = 'validity';
-/**
- * @ngdoc function
- * @name angular.lowercase
- * @module ng
- * @kind function
- *
- * @description Converts the specified string to lowercase.
- * @param {string} string String to be converted to lowercase.
- * @returns {string} Lowercased string.
- */
-var lowercase = function(string) {return isString(string) ? string.toLowerCase() : string;};
var hasOwnProperty = Object.prototype.hasOwnProperty;
-/**
- * @ngdoc function
- * @name angular.uppercase
- * @module ng
- * @kind function
- *
- * @description Converts the specified string to uppercase.
- * @param {string} string String to be converted to uppercase.
- * @returns {string} Uppercased string.
- */
+var lowercase = function(string) {return isString(string) ? string.toLowerCase() : string;};
var uppercase = function(string) {return isString(string) ? string.toUpperCase() : string;};
@@ -230,7 +210,7 @@ var manualUppercase = function(s) {
// String#toLowerCase and String#toUpperCase don't produce correct results in browsers with Turkish
// locale, for this reason we need to detect this case and redefine lowercase/uppercase methods
-// with correct but slower alternatives.
+// with correct but slower alternatives. See https://github.com/angular/angular.js/issues/11387
if ('i' !== 'I'.toLowerCase()) {
lowercase = manualLowercase;
uppercase = manualUppercase;
@@ -257,7 +237,7 @@ var
* documentMode is an IE-only property
* http://msdn.microsoft.com/en-us/library/ie/cc196988(v=vs.85).aspx
*/
-msie = document.documentMode;
+msie = window.document.documentMode;
/**
@@ -267,20 +247,25 @@ msie = document.documentMode;
* String ...)
*/
function isArrayLike(obj) {
- if (obj == null || isWindow(obj)) {
- return false;
- }
+
+ // `null`, `undefined` and `window` are not array-like
+ if (obj == null || isWindow(obj)) return false;
+
+ // arrays, strings and jQuery/jqLite objects are array like
+ // * jqLite is either the jQuery or jqLite constructor function
+ // * we have to check the existence of jqLite first as this method is called
+ // via the forEach method when constructing the jqLite object in the first place
+ if (isArray(obj) || isString(obj) || (jqLite && obj instanceof jqLite)) return true;
// Support: iOS 8.2 (not reproducible in simulator)
// "length" in obj used to prevent JIT error (gh-11508)
var length = "length" in Object(obj) && obj.length;
- if (obj.nodeType === NODE_TYPE_ELEMENT && length) {
- return true;
- }
+ // NodeList objects (with `item` method) and
+ // other objects with suitable length characteristics are array-like
+ return isNumber(length) &&
+ (length >= 0 && ((length - 1) in obj || obj instanceof Array) || typeof obj.item == 'function');
- return isString(obj) || isArray(obj) || length === 0 ||
- typeof length === 'number' && length > 0 && (length - 1) in obj;
}
/**
@@ -300,7 +285,7 @@ function isArrayLike(obj) {
*
* Unlike ES262's
* [Array.prototype.forEach](http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.18),
- * Providing 'undefined' or 'null' values for `obj` will not throw a TypeError, but rather just
+ * providing 'undefined' or 'null' values for `obj` will not throw a TypeError, but rather just
* return the value provided.
*
```js
@@ -377,7 +362,7 @@ function forEachSorted(obj, iterator, context) {
* @returns {function(*, string)}
*/
function reverseParams(iteratorFn) {
- return function(value, key) { iteratorFn(key, value); };
+ return function(value, key) {iteratorFn(key, value);};
}
/**
@@ -421,8 +406,18 @@ function baseExtend(dst, objs, deep) {
var src = obj[key];
if (deep && isObject(src)) {
- if (!isObject(dst[key])) dst[key] = isArray(src) ? [] : {};
- baseExtend(dst[key], [src], true);
+ if (isDate(src)) {
+ dst[key] = new Date(src.valueOf());
+ } else if (isRegExp(src)) {
+ dst[key] = new RegExp(src);
+ } else if (src.nodeName) {
+ dst[key] = src.cloneNode(true);
+ } else if (isElement(src)) {
+ dst[key] = src.clone();
+ } else {
+ if (!isObject(dst[key])) dst[key] = isArray(src) ? [] : {};
+ baseExtend(dst[key], [src], true);
+ }
} else {
dst[key] = src;
}
@@ -520,18 +515,33 @@ noop.$inject = [];
* functional style.
*
```js
- function transformer(transformationFn, value) {
- return (transformationFn || angular.identity)(value);
- };
+ function transformer(transformationFn, value) {
+ return (transformationFn || angular.identity)(value);
+ };
+
+ // E.g.
+ function getResult(fn, input) {
+ return (fn || angular.identity)(input);
+ };
+
+ getResult(function(n) { return n * 2; }, 21); // returns 42
+ getResult(null, 21); // returns 21
+ getResult(undefined, 21); // returns 21
```
- * @param {*} value to be returned.
- * @returns {*} the value passed in.
+ *
+ * @param {*} value to be returned.
+ * @returns {*} the value passed in.
*/
function identity($) {return $;}
identity.$inject = [];
-function valueFn(value) {return function() {return value;};}
+function valueFn(value) {return function valueRef() {return value;};}
+
+function hasCustomToString(obj) {
+ return isFunction(obj.toString) && obj.toString !== toString;
+}
+
/**
* @ngdoc function
@@ -728,9 +738,13 @@ function isPromiseLike(obj) {
}
-var TYPED_ARRAY_REGEXP = /^\[object (Uint8(Clamped)?)|(Uint16)|(Uint32)|(Int8)|(Int16)|(Int32)|(Float(32)|(64))Array\]$/;
+var TYPED_ARRAY_REGEXP = /^\[object (?:Uint8|Uint8Clamped|Uint16|Uint32|Int8|Int16|Int32|Float32|Float64)Array\]$/;
function isTypedArray(value) {
- return TYPED_ARRAY_REGEXP.test(toString.call(value));
+ return value && isNumber(value.length) && TYPED_ARRAY_REGEXP.test(toString.call(value));
+}
+
+function isArrayBuffer(obj) {
+ return toString.call(obj) === '[object ArrayBuffer]';
}
@@ -761,8 +775,8 @@ var escapeForRegexp = function(s) {
*/
function isElement(node) {
return !!(node &&
- (node.nodeName // we are a direct element
- || (node.prop && node.attr && node.find))); // we have an on and find method part of jQuery API
+ (node.nodeName // We are a direct element.
+ || (node.prop && node.attr && node.find))); // We have an on and find method part of jQuery API.
}
/**
@@ -770,7 +784,7 @@ function isElement(node) {
* @returns {object} in the form of {key1:true, key2:true, ...}
*/
function makeMap(str) {
- var obj = {}, items = str.split(","), i;
+ var obj = {}, items = str.split(','), i;
for (i = 0; i < items.length; i++) {
obj[items[i]] = true;
}
@@ -807,7 +821,13 @@ function arrayRemove(array, value) {
* * If a destination is provided, all of its elements (for arrays) or properties (for objects)
* are deleted and then all elements/properties from the source are copied to it.
* * If `source` is not an object or array (inc. `null` and `undefined`), `source` is returned.
- * * If `source` is identical to 'destination' an exception will be thrown.
+ * * If `source` is identical to `destination` an exception will be thrown.
+ *
+ *
+ *
form = {{user | json}}-
master = {{master | json}}-
{{ $ctrl.log | json }}', + * controller: function() { + * var previousValue; + * this.log = []; + * this.$doCheck = function() { + * var currentValue = this.date && this.date.valueOf(); + * if (previousValue !== currentValue) { + * this.log.push('doCheck: date mutated: ' + this.date); + * previousValue = currentValue; + * } + * }; + * } + * }); + *
{{ items }}+ *
{{ $ctrl.log | json }}', + * controller: function() { + * this.log = []; + * + * this.$doCheck = function() { + * if (this.items_ref !== this.items) { + * this.log.push('doCheck: items changed'); + * this.items_ref = this.items; + * } + * if (!angular.equals(this.items_clone, this.items)) { + * this.log.push('doCheck: items mutated'); + * this.items_clone = angular.copy(this.items); + * } + * }; + * } + * }); + *