diff --git a/Rakefile b/Rakefile index 2fafb59f3f64de9fe8149a9ff751f061c6765e62..a233c35e75e07cd8af2c60e8e63e36986a612ff1 100644 --- a/Rakefile +++ b/Rakefile @@ -169,9 +169,10 @@ namespace :gen do end -desc "Creates json data from inputs" +desc "Creates JSON data from inputs" task "reference-api" do - invoke_script "#{REFAPI_DIR}/reference-api.rb" + require 'refrepo/gen/reference-api' + generate_reference_api end #Some scripts may return status != 0 (validators, errors, ...) diff --git a/generators/reference-api/reference-api.rb b/generators/reference-api/reference-api.rb deleted file mode 100644 index b01ad1124efb6131b71518684a5246b084bc2f1c..0000000000000000000000000000000000000000 --- a/generators/reference-api/reference-api.rb +++ /dev/null @@ -1,359 +0,0 @@ -#!/usr/bin/ruby - -if RUBY_VERSION < "2.1" - puts "This script requires ruby >= 2.1" - exit -end - -require 'pp' -require 'optparse' -require 'erb' -require 'fileutils' -require 'pathname' -require 'json' -require 'time' - -$LOAD_PATH.unshift(File.expand_path(File.join(File.dirname(__FILE__), '../../lib'))) -require 'refrepo/input_loader' -require 'refrepo/valid/input/schema' -require 'refrepo/valid/homogeneity' -require 'refrepo/valid/input/monitoring' - -# Output directory -input_data_dir = "../../input/grid5000/" -output_data_dir = "../../data/grid5000/" - -refapi_path = File.expand_path(output_data_dir, File.dirname(__FILE__)) -global_hash = load_yaml_file_hierarchy(File.expand_path(input_data_dir, File.dirname(__FILE__))) - -# Parse network equipment description and return switch name and port connected to given node -# In the network description, if the node interface is given (using "port" attribute), -# the interface parameter must be used. -def net_switch_port_lookup(site, node_uid, interface='') - site["networks"].each do |switch_uid, switch| - #pp switch_uid - switch["linecards"].each do |lc_uid,lc| - lc["ports"].each do |port_uid,port| - if port.is_a?(Hash) - switch_remote_port = port["port"] || lc["port"] || "" - switch_remote_uid = port["uid"] - else - switch_remote_port = lc["port"] || "" - switch_remote_uid = port - end - if switch_remote_uid == node_uid and switch_remote_port == interface - # Build port name from snmp_naming_pattern - # Example: '3 2 GigabitEthernet%LINECARD%/%PORT%' -> 'GigabitEthernet3/2' - port_name = lc["snmp_pattern"].sub("%LINECARD%",lc_uid.to_s).sub("%PORT%",port_uid.to_s) - return switch_uid, port_name - end - end - end - end - return nil -end - -# Creation du fichier network_equipment -def create_network_equipment(network_uid, network, refapi_path, site_uid=nil) - network["type"] = "network_equipment" - network["uid"] = network_uid - - network_path = '' - if site_uid - network_path = Pathname.new(refapi_path).join("sites", site_uid, "network_equipments") - else - network_path = Pathname.new(refapi_path).join("network_equipments") - end - network_path.mkpath() - - network["weathermap"] ||= {} - - # Change the format of linecard from Hash to Array - linecards_tmp = Marshal.load(Marshal.dump(network["linecards"])) # bkp (deep_copy) - - linecards_array = [] - network["linecards"].each do |linecard_index, linecard| - ports = [] - linecard.delete("ports").each do |port_index, port| - port = {"uid"=>port} if port.is_a? String - if port.is_a? Hash - # complete entries (see bug 8587) - if port['port'].nil? and linecard['port'] - port['port'] = linecard['port'] - end - if port['kind'].nil? and linecard['kind'] - port['kind'] = linecard['kind'] - end - end - ports[port_index] = port - end - linecard["ports"] = ports.map{|p| p || {}} - linecards_array[linecard_index] = linecard - end - network["linecards"] = linecards_array.map{|l| l || {}} - - network.delete_if {|k, v| k == "network_adapters"} - - write_json(network_path.join("#{network_uid}.json"), network) - - network["linecards"] = linecards_tmp # restore -end - -OptionParser.new do |opts| - opts.banner = "Usage: reference-api.rb" - opts.separator "" - opts.separator "This script generates the reference-api JSON (data/) from the input files (input/)." - opts.separator "It does not have any option." - opts.separator "" - - # Print an options summary. - opts.on_tail("-h", "--help", "Show this message") do - puts opts - exit - end -end.parse! - -# -# Write grid info -# - -if global_hash['uid'] - global_hash["type"] = "grid" - grid_path = Pathname.new(refapi_path) - grid_path.mkpath() - - write_json(grid_path.join("#{global_hash['uid']}.json"), - global_hash.reject {|k, v| k == "sites" || k == "network_equipments"}) -end - -puts "Generating the reference api:\n\n" -puts "Removing data directory:\n" -FileUtils.rm_rf(Pathname.new(refapi_path).join("sites")) -FileUtils.rm_rf(Pathname.new(refapi_path).join("network_equipments")) -puts "Done." - -# Generate global network_equipments (renater links) -global_hash["network_equipments"].each do |network_uid, network| - create_network_equipment(network_uid, network, refapi_path) -end - -global_hash["sites"].each do |site_uid, site| - puts "#{site_uid}:" - - # - # Write site info - # - - site["type"] = "site" - site["uid"] = site_uid - - #Move special entry "kavlan_topo" - if site["kavlan_topo"] - site["kavlans"]["topo"] = site.delete("kavlan_topo") - end - - site_path = Pathname.new(refapi_path).join("sites", site_uid) - site_path.mkpath() - - write_json(site_path.join("#{site_uid}.json"), - site.reject {|k, v| k == "clusters" || k == "networks" || k == "pdus" || k == "dom0" || k == "laptops" || k == "servers" }) - - # - # Write pdu info - # - - pdu_path = site_path.join("pdus") - pdu_path.mkpath() - site["pdus"].each do |pdu_uid, pdu| - pdu["type"] = "pdu" - pdu["uid"] = pdu_uid - - pdu_attached_nodes = {} - site.fetch("clusters", []).sort.each do |cluster_uid, cluster| - cluster["nodes"].each do |node_uid, node|# _sort_by_node_uid - node.fetch('pdu', []).each do |node_pdu| - if node_pdu["uid"] == pdu_uid - pp pdu_uid,node_uid - pdu_attached_nodes[node_pdu["port"]] = node_uid - end - end - end - end - pdu["ports"] = pdu_attached_nodes - - write_json(pdu_path.join("#{pdu_uid}.json"), pdu) - end if site.key?("pdus") - - # - # Write servers info - # - - servers_path = site_path.join("servers") - servers_path.mkpath() - site["servers"].each do |server_uid, server| - server["type"] = "server" - server["uid"] = server_uid - write_json(servers_path.join("#{server_uid}.json"), server) - end if site.key?("servers") - - # - # Write network info - # - - site.fetch("networks", []).sort.each do |network_uid, network| - create_network_equipment(network_uid, network, refapi_path, site_uid) - end - - site.fetch("clusters", []).sort.each do |cluster_uid, cluster| - puts " #{cluster_uid}" - - # - # Write cluster info - # - - cluster["type"] = "cluster" - cluster["uid"] = cluster_uid - - # On the previous version of this script, cluster["created_ad"] was generated from a Ruby Time. cluster["created_ad"] is now a Ruby Date at JSON import. - # As Date.httpdate and Time.httpdate does not behave the same with timezone, it is converted here as a Ruby time. - cluster["created_at"] = Time.parse(cluster["created_at"].to_s).httpdate - - cluster_path = Pathname.new(refapi_path).join("sites", site_uid, "clusters", cluster_uid) - cluster_path.mkpath() - - # Write cluster info w/o nodes entries - write_json(cluster_path.join("#{cluster_uid}.json"), - cluster.reject {|k, v| k == "nodes"}) - - # - # Write node info - # - - cluster_path.join("nodes").mkpath() - - cluster["nodes"].each do |node_uid, node|# _sort_by_node_uid - begin - #puts node_uid - - next if node['status'] == "retired" - - node["uid"] = node_uid - node["type"] = "node" - if node.key?("processor") - node["processor"]["cache_l1"] ||= nil - end - - # Add default keys - node["gpu"] = {} unless node.key?("gpu") - node["gpu"]["gpu"] ||= false - - node["main_memory"] = {} unless node.key?("main_memory") - - # Delete keys - #raise 'node["storage_devices"] is nil' if node["storage_devices"].nil? - Hash(node["storage_devices"]).keys.each { |key| - node["storage_devices"][key].delete("timeread") if node["storage_devices"][key].key?("timeread") - node["storage_devices"][key].delete("timewrite") if node["storage_devices"][key].key?("timewrite") - } - node.delete("status") - - # Type conversion - node["network_adapters"].each { |key, hash| hash["rate"] = hash["rate"].to_i if hash["rate"].is_a?(Float) } - - # Convert hashes to arrays - Hash(node["storage_devices"]).each { |key, hash| node["storage_devices"][key]["device"] = key; } # Add "device: sdX" within the hash - node["storage_devices"] = Hash(node["storage_devices"]).sort_by_array(["sda", "sdb", "sdc", "sdd", "sde"]).values - - node["network_adapters"].each { |key, hash| node["network_adapters"][key]["device"] = key; } # Add "device: ethX" within the hash - node["network_adapters"] = node["network_adapters"].sort_by_array(["eth0", "eth1", "eth2", "eth3", "eth4", "eth5", "eth6", "ib0", "ib1", "ib2", "ib3", "bmc"]).values - - # For each network adapters, populate "network_address", "switch" and "switch_port" from the network equipment description - node["network_adapters"].each { |network_adapter| - network_adapter["mac"] = network_adapter["mac"].downcase if network_adapter["mac"].is_a?(String) - - # infiniband properties - network_adapter["ib_switch_card"] = network_adapter.delete("line_card") if network_adapter.key?("line_card") - network_adapter["ib_switch_card_pos"] = network_adapter.delete("position") if network_adapter.key?("position") - - if network_adapter["management"] - # Management network_adapter (bmc) - network_adapter["network_address"] = "#{node_uid}-bmc.#{site_uid}.grid5000.fr" unless network_adapter.key?("network_address") - elsif network_adapter["mounted"] and /^eth[0-9]$/.match(network_adapter["device"]) - # Primary network_adapter - network_adapter["network_address"] = "#{node_uid}.#{site_uid}.grid5000.fr" if network_adapter["enabled"] - - # Interface may not be specified in Network Reference for primary network_adapter - network_adapter["switch"], network_adapter["switch_port"] = net_switch_port_lookup(site, node_uid, network_adapter["device"]) || net_switch_port_lookup(site, node_uid) - else - # Secondary network_adapter(s) - network_adapter["network_address"] = "#{node_uid}-#{network_adapter["device"]}.#{site_uid}.grid5000.fr" if network_adapter["mountable"] && !network_adapter.key?("network_address") - if network_adapter["mountable"] - switch, port = net_switch_port_lookup(site, node_uid, network_adapter["device"]) - network_adapter["switch"] = switch if switch - network_adapter["switch_port"] = port if port - end - end - # If kavlan entry is not defined here, set it node's kavlan description - network_adapter["kavlan"] ||= node["kavlan"].keys.include?(network_adapter["device"]) ? true : false rescue false - - network_adapter.delete("network_address") if network_adapter["network_address"] == 'none' - } - - node["sensors"] ||= {} - - node["monitoring"] ||= {} - node["monitoring"]["wattmeter"] ||= false # default - - # Use strings instead of boolean as possible values are: true/false/shared/etc. - node["monitoring"]["wattmeter"] = "true" if node["monitoring"]["wattmeter"] == true - node["monitoring"]["wattmeter"] = "false" if node["monitoring"]["wattmeter"] == false - - if node.key?("pdu") - - node["pdu"].each { |p| - pdu = [p].flatten - pdu.each { |item| - #See https://intranet.grid5000.fr/bugzilla/show_bug.cgi?id=7585, workaround to validate node pdu that have per_outlets = false - item.delete("port") if item["port"] == "disabled" - # Remove 'port' info if PDU are shared - item.delete("port") if node["monitoring"]["wattmeter"] == "shared" - } - } - - # Move PDU info in the right place - node["sensors"]["power"] ||= {} - node["sensors"]["power"]["via"] ||= {} - node["sensors"]["power"]["via"]["pdu"] = node.delete("pdu") - end # node.key?("pdu") - - if node["monitoring"].key?("metric") - node["sensors"]["power"] ||= {} - node["sensors"]["power"]["available"] = true - node["sensors"]["power"]["via"] ||= {} - node["sensors"]["power"]["via"]["api"] ||= {} - node["sensors"]["power"]["via"]["api"]["metric"] = node["monitoring"].delete("metric") - end - - - write_json(cluster_path.join("nodes","#{node_uid}.json"), node) - - rescue => e - puts "Error while processing #{node_uid}: #{e}" - raise - end - end - end - -end - -# -# Write the all-in-one json file -# - -# rename entry for the all-in-on json file -global_hash["sites"].each do |site_uid, site| - site["network_equipments"] = site.delete("networks") -end - -# Write global json file - Disable this for now, see https://www.grid5000.fr/mediawiki/index.php/TechTeam:CT-220 -#write_json(grid_path.join(File.expand_path("../../#{global_hash['uid']}-all.json", File.dirname(__FILE__))), global_hash) diff --git a/lib/refrepo/gen/reference-api.rb b/lib/refrepo/gen/reference-api.rb new file mode 100644 index 0000000000000000000000000000000000000000..1cbcca0a2f53b6029d10e3b70489f97d5a29397b --- /dev/null +++ b/lib/refrepo/gen/reference-api.rb @@ -0,0 +1,340 @@ +#!/usr/bin/ruby + +require 'pp' +require 'optparse' +require 'erb' +require 'fileutils' +require 'pathname' +require 'json' +require 'time' + +require 'refrepo/input_loader' +require 'refrepo/valid/input/schema' +require 'refrepo/valid/homogeneity' +require 'refrepo/valid/input/monitoring' + +# Parse network equipment description and return switch name and port connected to given node +# In the network description, if the node interface is given (using "port" attribute), +# the interface parameter must be used. +def net_switch_port_lookup(site, node_uid, interface='') + site["networks"].each do |switch_uid, switch| + #pp switch_uid + switch["linecards"].each do |lc_uid,lc| + lc["ports"].each do |port_uid,port| + if port.is_a?(Hash) + switch_remote_port = port["port"] || lc["port"] || "" + switch_remote_uid = port["uid"] + else + switch_remote_port = lc["port"] || "" + switch_remote_uid = port + end + if switch_remote_uid == node_uid and switch_remote_port == interface + # Build port name from snmp_naming_pattern + # Example: '3 2 GigabitEthernet%LINECARD%/%PORT%' -> 'GigabitEthernet3/2' + port_name = lc["snmp_pattern"].sub("%LINECARD%",lc_uid.to_s).sub("%PORT%",port_uid.to_s) + return switch_uid, port_name + end + end + end + end + return nil +end + +# Creation du fichier network_equipment +def create_network_equipment(network_uid, network, refapi_path, site_uid=nil) + network["type"] = "network_equipment" + network["uid"] = network_uid + + network_path = '' + if site_uid + network_path = Pathname.new(refapi_path).join("sites", site_uid, "network_equipments") + else + network_path = Pathname.new(refapi_path).join("network_equipments") + end + network_path.mkpath() + + network["weathermap"] ||= {} + + # Change the format of linecard from Hash to Array + linecards_tmp = Marshal.load(Marshal.dump(network["linecards"])) # bkp (deep_copy) + + linecards_array = [] + network["linecards"].each do |linecard_index, linecard| + ports = [] + linecard.delete("ports").each do |port_index, port| + port = {"uid"=>port} if port.is_a? String + if port.is_a? Hash + # complete entries (see bug 8587) + if port['port'].nil? and linecard['port'] + port['port'] = linecard['port'] + end + if port['kind'].nil? and linecard['kind'] + port['kind'] = linecard['kind'] + end + end + ports[port_index] = port + end + linecard["ports"] = ports.map{|p| p || {}} + linecards_array[linecard_index] = linecard + end + network["linecards"] = linecards_array.map{|l| l || {}} + + network.delete_if {|k, v| k == "network_adapters"} + + write_json(network_path.join("#{network_uid}.json"), network) + + network["linecards"] = linecards_tmp # restore +end + +def generate_reference_api + # Output directory + output_data_dir = "../../../data/grid5000/" + + refapi_path = File.expand_path(output_data_dir, File.dirname(__FILE__)) + global_hash = load_yaml_file_hierarchy + + # + # Write grid info + # + + if global_hash['uid'] + global_hash["type"] = "grid" + grid_path = Pathname.new(refapi_path) + grid_path.mkpath() + + write_json(grid_path.join("#{global_hash['uid']}.json"), + global_hash.reject {|k, v| k == "sites" || k == "network_equipments"}) + end + + puts "Generating the reference api:\n\n" + puts "Removing data directory:\n" + FileUtils.rm_rf(Pathname.new(refapi_path).join("sites")) + FileUtils.rm_rf(Pathname.new(refapi_path).join("network_equipments")) + puts "Done." + + # Generate global network_equipments (renater links) + global_hash["network_equipments"].each do |network_uid, network| + create_network_equipment(network_uid, network, refapi_path) + end + + global_hash["sites"].each do |site_uid, site| + puts "#{site_uid}:" + + # + # Write site info + # + + site["type"] = "site" + site["uid"] = site_uid + + #Move special entry "kavlan_topo" + if site["kavlan_topo"] + site["kavlans"]["topo"] = site.delete("kavlan_topo") + end + + site_path = Pathname.new(refapi_path).join("sites", site_uid) + site_path.mkpath() + + write_json(site_path.join("#{site_uid}.json"), + site.reject {|k, v| k == "clusters" || k == "networks" || k == "pdus" || k == "dom0" || k == "laptops" || k == "servers" }) + + # + # Write pdu info + # + + pdu_path = site_path.join("pdus") + pdu_path.mkpath() + site["pdus"].each do |pdu_uid, pdu| + pdu["type"] = "pdu" + pdu["uid"] = pdu_uid + + pdu_attached_nodes = {} + site.fetch("clusters", []).sort.each do |cluster_uid, cluster| + cluster["nodes"].each do |node_uid, node|# _sort_by_node_uid + node.fetch('pdu', []).each do |node_pdu| + if node_pdu["uid"] == pdu_uid + pp pdu_uid,node_uid + pdu_attached_nodes[node_pdu["port"]] = node_uid + end + end + end + end + pdu["ports"] = pdu_attached_nodes + + write_json(pdu_path.join("#{pdu_uid}.json"), pdu) + end if site.key?("pdus") + + # + # Write servers info + # + + servers_path = site_path.join("servers") + servers_path.mkpath() + site["servers"].each do |server_uid, server| + server["type"] = "server" + server["uid"] = server_uid + write_json(servers_path.join("#{server_uid}.json"), server) + end if site.key?("servers") + + # + # Write network info + # + + site.fetch("networks", []).sort.each do |network_uid, network| + create_network_equipment(network_uid, network, refapi_path, site_uid) + end + + site.fetch("clusters", []).sort.each do |cluster_uid, cluster| + puts " #{cluster_uid}" + + # + # Write cluster info + # + + cluster["type"] = "cluster" + cluster["uid"] = cluster_uid + + # On the previous version of this script, cluster["created_ad"] was generated from a Ruby Time. cluster["created_ad"] is now a Ruby Date at JSON import. + # As Date.httpdate and Time.httpdate does not behave the same with timezone, it is converted here as a Ruby time. + cluster["created_at"] = Time.parse(cluster["created_at"].to_s).httpdate + + cluster_path = Pathname.new(refapi_path).join("sites", site_uid, "clusters", cluster_uid) + cluster_path.mkpath() + + # Write cluster info w/o nodes entries + write_json(cluster_path.join("#{cluster_uid}.json"), + cluster.reject {|k, v| k == "nodes"}) + + # + # Write node info + # + + cluster_path.join("nodes").mkpath() + + cluster["nodes"].each do |node_uid, node|# _sort_by_node_uid + begin + #puts node_uid + + next if node['status'] == "retired" + + node["uid"] = node_uid + node["type"] = "node" + if node.key?("processor") + node["processor"]["cache_l1"] ||= nil + end + + # Add default keys + node["gpu"] = {} unless node.key?("gpu") + node["gpu"]["gpu"] ||= false + + node["main_memory"] = {} unless node.key?("main_memory") + + # Delete keys + #raise 'node["storage_devices"] is nil' if node["storage_devices"].nil? + Hash(node["storage_devices"]).keys.each { |key| + node["storage_devices"][key].delete("timeread") if node["storage_devices"][key].key?("timeread") + node["storage_devices"][key].delete("timewrite") if node["storage_devices"][key].key?("timewrite") + } + node.delete("status") + + # Type conversion + node["network_adapters"].each { |key, hash| hash["rate"] = hash["rate"].to_i if hash["rate"].is_a?(Float) } + + # Convert hashes to arrays + Hash(node["storage_devices"]).each { |key, hash| node["storage_devices"][key]["device"] = key; } # Add "device: sdX" within the hash + node["storage_devices"] = Hash(node["storage_devices"]).sort_by_array(["sda", "sdb", "sdc", "sdd", "sde"]).values + + node["network_adapters"].each { |key, hash| node["network_adapters"][key]["device"] = key; } # Add "device: ethX" within the hash + node["network_adapters"] = node["network_adapters"].sort_by_array(["eth0", "eth1", "eth2", "eth3", "eth4", "eth5", "eth6", "ib0", "ib1", "ib2", "ib3", "bmc"]).values + + # For each network adapters, populate "network_address", "switch" and "switch_port" from the network equipment description + node["network_adapters"].each { |network_adapter| + network_adapter["mac"] = network_adapter["mac"].downcase if network_adapter["mac"].is_a?(String) + + # infiniband properties + network_adapter["ib_switch_card"] = network_adapter.delete("line_card") if network_adapter.key?("line_card") + network_adapter["ib_switch_card_pos"] = network_adapter.delete("position") if network_adapter.key?("position") + + if network_adapter["management"] + # Management network_adapter (bmc) + network_adapter["network_address"] = "#{node_uid}-bmc.#{site_uid}.grid5000.fr" unless network_adapter.key?("network_address") + elsif network_adapter["mounted"] and /^eth[0-9]$/.match(network_adapter["device"]) + # Primary network_adapter + network_adapter["network_address"] = "#{node_uid}.#{site_uid}.grid5000.fr" if network_adapter["enabled"] + + # Interface may not be specified in Network Reference for primary network_adapter + network_adapter["switch"], network_adapter["switch_port"] = net_switch_port_lookup(site, node_uid, network_adapter["device"]) || net_switch_port_lookup(site, node_uid) + else + # Secondary network_adapter(s) + network_adapter["network_address"] = "#{node_uid}-#{network_adapter["device"]}.#{site_uid}.grid5000.fr" if network_adapter["mountable"] && !network_adapter.key?("network_address") + if network_adapter["mountable"] + switch, port = net_switch_port_lookup(site, node_uid, network_adapter["device"]) + network_adapter["switch"] = switch if switch + network_adapter["switch_port"] = port if port + end + end + # If kavlan entry is not defined here, set it node's kavlan description + network_adapter["kavlan"] ||= node["kavlan"].keys.include?(network_adapter["device"]) ? true : false rescue false + + network_adapter.delete("network_address") if network_adapter["network_address"] == 'none' + } + + node["sensors"] ||= {} + + node["monitoring"] ||= {} + node["monitoring"]["wattmeter"] ||= false # default + + # Use strings instead of boolean as possible values are: true/false/shared/etc. + node["monitoring"]["wattmeter"] = "true" if node["monitoring"]["wattmeter"] == true + node["monitoring"]["wattmeter"] = "false" if node["monitoring"]["wattmeter"] == false + + if node.key?("pdu") + + node["pdu"].each { |p| + pdu = [p].flatten + pdu.each { |item| + #See https://intranet.grid5000.fr/bugzilla/show_bug.cgi?id=7585, workaround to validate node pdu that have per_outlets = false + item.delete("port") if item["port"] == "disabled" + # Remove 'port' info if PDU are shared + item.delete("port") if node["monitoring"]["wattmeter"] == "shared" + } + } + + # Move PDU info in the right place + node["sensors"]["power"] ||= {} + node["sensors"]["power"]["via"] ||= {} + node["sensors"]["power"]["via"]["pdu"] = node.delete("pdu") + end # node.key?("pdu") + + if node["monitoring"].key?("metric") + node["sensors"]["power"] ||= {} + node["sensors"]["power"]["available"] = true + node["sensors"]["power"]["via"] ||= {} + node["sensors"]["power"]["via"]["api"] ||= {} + node["sensors"]["power"]["via"]["api"]["metric"] = node["monitoring"].delete("metric") + end + + + write_json(cluster_path.join("nodes","#{node_uid}.json"), node) + + rescue => e + puts "Error while processing #{node_uid}: #{e}" + raise + end + end + end + + end + + # + # Write the all-in-one json file + # + + # rename entry for the all-in-on json file + global_hash["sites"].each do |site_uid, site| + site["network_equipments"] = site.delete("networks") + end + + # Write global json file - Disable this for now, see https://www.grid5000.fr/mediawiki/index.php/TechTeam:CT-220 + #write_json(grid_path.join(File.expand_path("../../#{global_hash['uid']}-all.json", File.dirname(__FILE__))), global_hash) +end