From f65925a644eb1d285689207b4480d9617e74b214 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Franti=C5=A1ek=20Dvo=C5=99=C3=A1k?= Date: Mon, 20 Jun 2016 08:48:27 +0200 Subject: [PATCH] Network topology (partial unfinished work). --- .rubocop.yml | 3 +- Gemfile.devel | 1 + application.rb | 3 +- etc/now.yml | 1 + lib/api.rb | 26 ++++- lib/nebula.rb | 34 +++++- lib/topology.rb | 50 +++++++++ lib/zone.rb | 20 ++++ models/generated/network.rb | 258 ++++++++++++++++++++++++++++++++++++++++++ models/generated/range.rb | 208 ++++++++++++++++++++++++++++++++++ models/network.rb | 266 +------------------------------------------- models/range.rb | 207 +--------------------------------- 12 files changed, 600 insertions(+), 477 deletions(-) create mode 100644 lib/topology.rb create mode 100644 lib/zone.rb create mode 100644 models/generated/network.rb create mode 100644 models/generated/range.rb diff --git a/.rubocop.yml b/.rubocop.yml index f297369..5d6484a 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -3,8 +3,7 @@ AllCops: DisplayStyleGuide: true Exclude: # exclude generated code (maybe we'll rewrite it anyway one day) - - models/network.rb - - models/range.rb + - models/generated/*.rb # Assignment Branch Condition size for initialize is too high # Perceived complexity for deep_merge is too high diff --git a/Gemfile.devel b/Gemfile.devel index 7ba90f6..21851c0 100644 --- a/Gemfile.devel +++ b/Gemfile.devel @@ -1,5 +1,6 @@ source 'https://rubygems.org' +gem 'ipaddress' gem 'opennebula' gem 'sinatra' gem 'sinatra-cross_origin' diff --git a/application.rb b/application.rb index bd44200..0f58510 100644 --- a/application.rb +++ b/application.rb @@ -1,12 +1,13 @@ require 'logger' -Dir['./models/*.rb'].each do |file| +Dir['./models/generated/*.rb', './models/*.rb'].each do |file| require file end require './version' require './lib/error' require './lib/server_cipher_auth' require './lib/config' +require './lib/topology' require './lib/nebula' require './lib/api' diff --git a/etc/now.yml b/etc/now.yml index 83b94aa..7763415 100644 --- a/etc/now.yml +++ b/etc/now.yml @@ -2,6 +2,7 @@ opennebula: admin_user: 'nowadmin' admin_password: 'the-best-strongest-password-ever' endpoint: http://localhost:2633/RPC2 + super_user: 'oneadmin' topology: 0: bridge: br0 diff --git a/lib/api.rb b/lib/api.rb index f3c4b2d..ff72496 100644 --- a/lib/api.rb +++ b/lib/api.rb @@ -6,12 +6,14 @@ require ::File.expand_path('../../version', __FILE__) module Now # HTTP REST API between NOW and rOCCI server class Application < Sinatra::Base - attr_accessor :nebula + attr_accessor :nebula, :config, :topology register Sinatra::CrossOrigin def initialize super + @config = $config @nebula = Now::Nebula.new($config) + @topology = nil end configure do @@ -32,6 +34,13 @@ module Now nebula.switch_user(user) end end + + def topology + switch_user(config['opennebula']['super_user']) + clusters = nebula.list_clusters + networks = nebula.list_networks + @topology = Topology.new(networks, clusters) + end end get '/' do @@ -44,7 +53,18 @@ module Now begin switch_user(params['user']) networks = nebula.list_networks - JSON.pretty_generate(networks) + JSON.pretty_generate(networks.map(&:to_hash)) + rescue NowError => e + logger.error "[HTTP #{e.code}] #{e.message}" + halt e.code, e.message + end + end + + put '/network' do + cross_origin + begin + topology + JSON.pretty_generate(topology.networks.map(&:to_hash)) rescue NowError => e logger.error "[HTTP #{e.code}] #{e.message}" halt e.code, e.message @@ -56,7 +76,7 @@ module Now begin switch_user(params['user']) network = nebula.get(params['id']) - JSON.pretty_generate(network) + JSON.pretty_generate(network.to_hash) rescue NowError => e logger.error "[HTTP #{e.code}] #{e.message}" halt e.code, e.message diff --git a/lib/nebula.rb b/lib/nebula.rb index a5c6ca0..e89c702 100644 --- a/lib/nebula.rb +++ b/lib/nebula.rb @@ -58,7 +58,7 @@ module Now vn_pool.each do |vn| begin network = parse_network(vn) - networks << network.to_hash + networks << network rescue NowError => e logger.warn "[code #{e.code}] #{e.message}, skipping" end @@ -67,6 +67,30 @@ module Now return networks end + # Get list of clusters from OpenNebula + # + # @return [{{}}] Map of clusters + def list_clusters + cl_pool = OpenNebula::ClusterPool.new(@ctx) + check(cl_pool.info) + + clusters = {} + cl_pool.each do |cl| + begin + #logger.debug "[#{__method__}] #{cl.to_xml}" + cluster = {} + if !cl['NAME'].nil? && !cl['NAME'].empty? + cluster[:name] = cl['NAME'] + end + clusters[cl.id] = cluster + rescue NowError => e + logger.warn "[code #{e.code}] #{e.message}, skipping" + end + end + + return clusters + end + def get(network_id) vn_generic = OpenNebula::VirtualNetwork.build_xml(network_id) vn = OpenNebula::VirtualNetwork.new(vn_generic, @ctx) @@ -74,7 +98,7 @@ module Now network = parse_network(vn) - return network.to_hash + return network end private @@ -152,11 +176,11 @@ module Now return range end - def parse_cluster(vn_id, vn) + def parse_network_cluster(vn_id, vn) cluster = nil vn.each('CLUSTERS/ID') do |cluster_xml| id = cluster_xml.text - logger.debug "[parse_cluster] cluster: #{id}" + logger.debug "[parse_network_cluster] cluster: #{id}" if !cluster.nil? raise NowError.new(501), "Multiple clusters assigned to network #{vn_id}" end @@ -180,7 +204,7 @@ module Now end range = parse_ranges(id, vn) - zone = parse_cluster(id, vn) + zone = parse_network_cluster(id, vn) network = Network.new( id: id, title: title, diff --git a/lib/topology.rb b/lib/topology.rb new file mode 100644 index 0000000..7364dae --- /dev/null +++ b/lib/topology.rb @@ -0,0 +1,50 @@ +require 'ipaddress' + +module Now + + # Network topology as collection of zones. + class Topology + attr_accessor :config, :logger, :networks, :zones + + # @param [Now::Network[]] + # @param [{}] clusters from OpenNebula + def initialize(networks, clusters) + @config = $config + @logger = $logger + + @zones = {} + clusters.each do |id_cluster, cluster| + cluster_conf = config['topology'][id_cluster] + logger.debug "[topology] #{id_cluster} cluster OpenNebula: #{cluster}" + logger.debug "[topology] #{id_cluster} cluster topology: #{cluster_conf}" + ranges = [] + if !cluster_conf.nil? + if cluster_conf['ranges'] + + end + end + zone = Now::Zone.new(cluster: clusters[id_cluster]) + zone[id_cluster] = zone + end + @networks = networks + end + + private + + # @param [String] string in the format of "IP/MASK/SUBMASK" + # @return [Now::Range] + def parse_conf_range(s) + parts = s.split %r/\// + if parts.length != 3 + raise NowError(500), "Invalid network allocation specification \"#{s}\", IP/MASK/SUBMASK required" + end + cidr = "#{parts[0]}/#{parts[1]}" + mask = parts[2] + address = IPAddress.parse cidr + + return Now::Range() + end + + end + +end diff --git a/lib/zone.rb b/lib/zone.rb new file mode 100644 index 0000000..2f54538 --- /dev/null +++ b/lib/zone.rb @@ -0,0 +1,20 @@ +module Now + + # Network zone - a container with network parameters, available address ranges, and management of allocations. + class Zone + attr_accessor :config, :id, :params + attr_accessor :ranges, :avail, :allocated + + # @param [{}] cluster from OpenNebula + # @param[Now::Range[]] + def initialize(cluster, ranges) + @config = $config + @id = cluster[:id] + @params = cluster[:params] + @ranges = @avail = ranges + @allocated = {} + end + + end + +end diff --git a/models/generated/network.rb b/models/generated/network.rb new file mode 100644 index 0000000..e3e357a --- /dev/null +++ b/models/generated/network.rb @@ -0,0 +1,258 @@ +=begin +Network Orchestrator API + +OpenAPI spec version: 0.0.0 + +Generated by: https://github.com/swagger-api/swagger-codegen.git + +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. + +=end + +require 'date' + +module SwaggerClient + # Network object + class Network + # OpenNebula ID + attr_accessor :id + + # Network title + attr_accessor :title + + # Network summary + attr_accessor :description + + # Owner + attr_accessor :user + + # VLAN ID + attr_accessor :vlan + + attr_accessor :range + + # Availability zone (cluster) + attr_accessor :zone + + + # Attribute mapping from ruby-style variable name to JSON key. + def self.attribute_map + { + :'id' => :'id', + :'title' => :'title', + :'description' => :'description', + :'user' => :'user', + :'vlan' => :'vlan', + :'range' => :'range', + :'zone' => :'zone' + } + end + + # Attribute type mapping. + def self.swagger_types + { + :'id' => :'Integer', + :'title' => :'String', + :'description' => :'String', + :'user' => :'String', + :'vlan' => :'Integer', + :'range' => :'Range', + :'zone' => :'String' + } + end + + # Initializes the object + # @param [Hash] attributes Model attributes in the form of hash + def initialize(attributes = {}) + return unless attributes.is_a?(Hash) + + # convert string to symbol for hash key + attributes = attributes.each_with_object({}){|(k,v), h| h[k.to_sym] = v} + + if attributes.has_key?(:'id') + self.id = attributes[:'id'] + end + + if attributes.has_key?(:'title') + self.title = attributes[:'title'] + end + + if attributes.has_key?(:'description') + self.description = attributes[:'description'] + end + + if attributes.has_key?(:'user') + self.user = attributes[:'user'] + end + + if attributes.has_key?(:'vlan') + self.vlan = attributes[:'vlan'] + end + + if attributes.has_key?(:'range') + self.range = attributes[:'range'] + end + + if attributes.has_key?(:'zone') + self.zone = attributes[:'zone'] + end + + end + + # Show invalid properties with the reasons. Usually used together with valid? + # @return Array for valid properies with the reasons + def list_invalid_properties + invalid_properties = Array.new + return invalid_properties + end + + # Check to see if the all the properties in the model are valid + # @return true if the model is valid + def valid? + return false if @id.nil? + return true + end + + # Checks equality by comparing each attribute. + # @param [Object] Object to be compared + def ==(o) + return true if self.equal?(o) + self.class == o.class && + id == o.id && + title == o.title && + description == o.description && + user == o.user && + vlan == o.vlan && + range == o.range && + zone == o.zone + end + + # @see the `==` method + # @param [Object] Object to be compared + def eql?(o) + self == o + end + + # Calculates hash code according to all attributes. + # @return [Fixnum] Hash code + def hash + [id, title, description, user, vlan, range, zone].hash + end + + # Builds the object from hash + # @param [Hash] attributes Model attributes in the form of hash + # @return [Object] Returns the model itself + def build_from_hash(attributes) + return nil unless attributes.is_a?(Hash) + self.class.swagger_types.each_pair do |key, type| + if type =~ /^Array<(.*)>/i + # check to ensure the input is an array given that the the attribute + # is documented as an array but the input is not + if attributes[self.class.attribute_map[key]].is_a?(Array) + self.send("#{key}=", attributes[self.class.attribute_map[key]].map{ |v| _deserialize($1, v) } ) + end + elsif !attributes[self.class.attribute_map[key]].nil? + self.send("#{key}=", _deserialize(type, attributes[self.class.attribute_map[key]])) + end # or else data not found in attributes(hash), not an issue as the data can be optional + end + + self + end + + # Deserializes the data based on type + # @param string type Data type + # @param string value Value to be deserialized + # @return [Object] Deserialized data + def _deserialize(type, value) + case type.to_sym + when :DateTime + DateTime.parse(value) + when :Date + Date.parse(value) + when :String + value.to_s + when :Integer + value.to_i + when :Float + value.to_f + when :BOOLEAN + if value.to_s =~ /^(true|t|yes|y|1)$/i + true + else + false + end + when :Object + # generic object (usually a Hash), return directly + value + when /\AArray<(?.+)>\z/ + inner_type = Regexp.last_match[:inner_type] + value.map { |v| _deserialize(inner_type, v) } + when /\AHash<(?.+), (?.+)>\z/ + k_type = Regexp.last_match[:k_type] + v_type = Regexp.last_match[:v_type] + {}.tap do |hash| + value.each do |k, v| + hash[_deserialize(k_type, k)] = _deserialize(v_type, v) + end + end + else # model + temp_model = SwaggerClient.const_get(type).new + temp_model.build_from_hash(value) + end + end + + # Returns the string representation of the object + # @return [String] String presentation of the object + def to_s + to_hash.to_s + end + + # to_body is an alias to to_hash (backward compatibility) + # @return [Hash] Returns the object in the form of hash + def to_body + to_hash + end + + # Returns the object in the form of hash + # @return [Hash] Returns the object in the form of hash + def to_hash + hash = {} + self.class.attribute_map.each_pair do |attr, param| + value = self.send(attr) + next if value.nil? + hash[param] = _to_hash(value) + end + hash + end + + # Outputs non-array value in the form of hash + # For object, use to_hash. Otherwise, just return the value + # @param [Object] value Any valid value + # @return [Hash] Returns the value in the form of hash + def _to_hash(value) + if value.is_a?(Array) + value.compact.map{ |v| _to_hash(v) } + elsif value.is_a?(Hash) + {}.tap do |hash| + value.each { |k, v| hash[k] = _to_hash(v) } + end + elsif value.respond_to? :to_hash + value.to_hash + else + value + end + end + + end + +end diff --git a/models/generated/range.rb b/models/generated/range.rb new file mode 100644 index 0000000..4169195 --- /dev/null +++ b/models/generated/range.rb @@ -0,0 +1,208 @@ +=begin +Network Orchestrator API + +OpenAPI spec version: 0.0.0 + +Generated by: https://github.com/swagger-api/swagger-codegen.git + +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. + +=end + +require 'date' + +module SwaggerClient + # Address range + class Range + # Address range (CIDR notation) + attr_accessor :address + + # Address allocation type (static, dynamic) + attr_accessor :allocation + + + # Attribute mapping from ruby-style variable name to JSON key. + def self.attribute_map + { + :'address' => :'address', + :'allocation' => :'allocation' + } + end + + # Attribute type mapping. + def self.swagger_types + { + :'address' => :'String', + :'allocation' => :'String' + } + end + + # Initializes the object + # @param [Hash] attributes Model attributes in the form of hash + def initialize(attributes = {}) + return unless attributes.is_a?(Hash) + + # convert string to symbol for hash key + attributes = attributes.each_with_object({}){|(k,v), h| h[k.to_sym] = v} + + if attributes.has_key?(:'address') + self.address = attributes[:'address'] + end + + if attributes.has_key?(:'allocation') + self.allocation = attributes[:'allocation'] + end + + end + + # Show invalid properties with the reasons. Usually used together with valid? + # @return Array for valid properies with the reasons + def list_invalid_properties + invalid_properties = Array.new + return invalid_properties + end + + # Check to see if the all the properties in the model are valid + # @return true if the model is valid + def valid? + return true + end + + # Checks equality by comparing each attribute. + # @param [Object] Object to be compared + def ==(o) + return true if self.equal?(o) + self.class == o.class && + address == o.address && + allocation == o.allocation + end + + # @see the `==` method + # @param [Object] Object to be compared + def eql?(o) + self == o + end + + # Calculates hash code according to all attributes. + # @return [Fixnum] Hash code + def hash + [address, allocation].hash + end + + # Builds the object from hash + # @param [Hash] attributes Model attributes in the form of hash + # @return [Object] Returns the model itself + def build_from_hash(attributes) + return nil unless attributes.is_a?(Hash) + self.class.swagger_types.each_pair do |key, type| + if type =~ /^Array<(.*)>/i + # check to ensure the input is an array given that the the attribute + # is documented as an array but the input is not + if attributes[self.class.attribute_map[key]].is_a?(Array) + self.send("#{key}=", attributes[self.class.attribute_map[key]].map{ |v| _deserialize($1, v) } ) + end + elsif !attributes[self.class.attribute_map[key]].nil? + self.send("#{key}=", _deserialize(type, attributes[self.class.attribute_map[key]])) + end # or else data not found in attributes(hash), not an issue as the data can be optional + end + + self + end + + # Deserializes the data based on type + # @param string type Data type + # @param string value Value to be deserialized + # @return [Object] Deserialized data + def _deserialize(type, value) + case type.to_sym + when :DateTime + DateTime.parse(value) + when :Date + Date.parse(value) + when :String + value.to_s + when :Integer + value.to_i + when :Float + value.to_f + when :BOOLEAN + if value.to_s =~ /^(true|t|yes|y|1)$/i + true + else + false + end + when :Object + # generic object (usually a Hash), return directly + value + when /\AArray<(?.+)>\z/ + inner_type = Regexp.last_match[:inner_type] + value.map { |v| _deserialize(inner_type, v) } + when /\AHash<(?.+), (?.+)>\z/ + k_type = Regexp.last_match[:k_type] + v_type = Regexp.last_match[:v_type] + {}.tap do |hash| + value.each do |k, v| + hash[_deserialize(k_type, k)] = _deserialize(v_type, v) + end + end + else # model + temp_model = SwaggerClient.const_get(type).new + temp_model.build_from_hash(value) + end + end + + # Returns the string representation of the object + # @return [String] String presentation of the object + def to_s + to_hash.to_s + end + + # to_body is an alias to to_hash (backward compatibility) + # @return [Hash] Returns the object in the form of hash + def to_body + to_hash + end + + # Returns the object in the form of hash + # @return [Hash] Returns the object in the form of hash + def to_hash + hash = {} + self.class.attribute_map.each_pair do |attr, param| + value = self.send(attr) + next if value.nil? + hash[param] = _to_hash(value) + end + hash + end + + # Outputs non-array value in the form of hash + # For object, use to_hash. Otherwise, just return the value + # @param [Object] value Any valid value + # @return [Hash] Returns the value in the form of hash + def _to_hash(value) + if value.is_a?(Array) + value.compact.map{ |v| _to_hash(v) } + elsif value.is_a?(Hash) + {}.tap do |hash| + value.each { |k, v| hash[k] = _to_hash(v) } + end + elsif value.respond_to? :to_hash + value.to_hash + else + value + end + end + + end + +end diff --git a/models/network.rb b/models/network.rb index ba966db..e9ea042 100644 --- a/models/network.rb +++ b/models/network.rb @@ -1,268 +1,8 @@ -=begin -Network Orchestrator API - -OpenAPI spec version: 0.0.0 - -Partially generated by: https://github.com/swagger-api/swagger-codegen.git - -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. - -=end - -require 'date' - module Now - # Network object - class Network - # OpenNebula ID - attr_accessor :id - - # Network title - attr_accessor :title - - # Network summary - attr_accessor :description - - # Owner - attr_accessor :user - - # VLAN ID - attr_accessor :vlan - - attr_accessor :range - - # Network state (active, inactive, error) - attr_accessor :state - - # Availability zone (cluster) - attr_accessor :zone - - - # Attribute mapping from ruby-style variable name to JSON key. - def self.attribute_map - { - :'id' => :'id', - :'title' => :'title', - :'description' => :'description', - :'user' => :'user', - :'vlan' => :'vlan', - :'range' => :'range', - :'state' => :'state', - :'zone' => :'zone' - } - end - - # Attribute type mapping. - def self.swagger_types - { - :'id' => :'Integer', - :'title' => :'String', - :'description' => :'String', - :'user' => :'String', - :'vlan' => :'Integer', - :'range' => :'Range', - :'state' => :'String', - :'zone' => :'String' - } - end - - # Initializes the object - # @param [Hash] attributes Model attributes in the form of hash - def initialize(attributes = {}) - return unless attributes.is_a?(Hash) - - # convert string to symbol for hash key - attributes = attributes.each_with_object({}){|(k,v), h| h[k.to_sym] = v} - - if attributes.has_key?(:'id') - self.id = attributes[:'id'] - end - - if attributes.has_key?(:'title') - self.title = attributes[:'title'] - end - - if attributes.has_key?(:'description') - self.description = attributes[:'description'] - end - - if attributes.has_key?(:'user') - self.user = attributes[:'user'] - end - - if attributes.has_key?(:'vlan') - self.vlan = attributes[:'vlan'] - end - - if attributes.has_key?(:'range') - self.range = attributes[:'range'] - end - - if attributes.has_key?(:'state') - self.state = attributes[:'state'] - end - - if attributes.has_key?(:'zone') - self.zone = attributes[:'zone'] - end - - end - - # Show invalid properties with the reasons. Usually used together with valid? - # @return Array for valid properies with the reasons - def list_invalid_properties - invalid_properties = Array.new - return invalid_properties - end - - # Check to see if the all the properties in the model are valid - # @return true if the model is valid - def valid? - return false if @id.nil? - return true - end - - # Checks equality by comparing each attribute. - # @param [Object] Object to be compared - def ==(o) - return true if self.equal?(o) - self.class == o.class && - id == o.id && - title == o.title && - description == o.description && - user == o.user && - vlan == o.vlan && - range == o.range && - state == o.state && - zone == o.zone - end - - # @see the `==` method - # @param [Object] Object to be compared - def eql?(o) - self == o - end - - # Calculates hash code according to all attributes. - # @return [Fixnum] Hash code - def hash - [id, title, description, user, vlan, range, state, zone].hash - end - - # Builds the object from hash - # @param [Hash] attributes Model attributes in the form of hash - # @return [Object] Returns the model itself - def build_from_hash(attributes) - return nil unless attributes.is_a?(Hash) - self.class.swagger_types.each_pair do |key, type| - if type =~ /^Array<(.*)>/i - # check to ensure the input is an array given that the the attribute - # is documented as an array but the input is not - if attributes[self.class.attribute_map[key]].is_a?(Array) - self.send("#{key}=", attributes[self.class.attribute_map[key]].map{ |v| _deserialize($1, v) } ) - end - elsif !attributes[self.class.attribute_map[key]].nil? - self.send("#{key}=", _deserialize(type, attributes[self.class.attribute_map[key]])) - end # or else data not found in attributes(hash), not an issue as the data can be optional - end - - self - end - - # Deserializes the data based on type - # @param string type Data type - # @param string value Value to be deserialized - # @return [Object] Deserialized data - def _deserialize(type, value) - case type.to_sym - when :DateTime - DateTime.parse(value) - when :Date - Date.parse(value) - when :String - value.to_s - when :Integer - value.to_i - when :Float - value.to_f - when :BOOLEAN - if value.to_s =~ /^(true|t|yes|y|1)$/i - true - else - false - end - when :Object - # generic object (usually a Hash), return directly - value - when /\AArray<(?.+)>\z/ - inner_type = Regexp.last_match[:inner_type] - value.map { |v| _deserialize(inner_type, v) } - when /\AHash<(?.+), (?.+)>\z/ - k_type = Regexp.last_match[:k_type] - v_type = Regexp.last_match[:v_type] - {}.tap do |hash| - value.each do |k, v| - hash[_deserialize(k_type, k)] = _deserialize(v_type, v) - end - end - else # model - temp_model = Now.const_get(type).new - temp_model.build_from_hash(value) - end - end - - # Returns the string representation of the object - # @return [String] String presentation of the object - def to_s - to_hash.to_s - end - - # to_body is an alias to to_hash (backward compatibility) - # @return [Hash] Returns the object in the form of hash - def to_body - to_hash - end - - # Returns the object in the form of hash - # @return [Hash] Returns the object in the form of hash - def to_hash - hash = {} - self.class.attribute_map.each_pair do |attr, param| - value = self.send(attr) - next if value.nil? - hash[param] = _to_hash(value) - end - hash - end - - # Outputs non-array value in the form of hash - # For object, use to_hash. Otherwise, just return the value - # @param [Object] value Any valid value - # @return [Hash] Returns the value in the form of hash - def _to_hash(value) - if value.is_a?(Array) - value.compact.map{ |v| _to_hash(v) } - elsif value.is_a?(Hash) - {}.tap do |hash| - value.each { |k, v| hash[k] = _to_hash(v) } - end - elsif value.respond_to? :to_hash - value.to_hash - else - value - end - end + # Network object + class Network < SwaggerClient::Network + attr_accessor :bridge, :type, :device, :ranges end end diff --git a/models/range.rb b/models/range.rb index 0b4f556..fd69d3a 100644 --- a/models/range.rb +++ b/models/range.rb @@ -1,208 +1,9 @@ -=begin -Network Orchestrator API - -OpenAPI spec version: 0.0.0 - -Partially generated by: https://github.com/swagger-api/swagger-codegen.git - -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. - -=end - -require 'date' - module Now - # Address range - class Range - # Address range (CIDR notation) - attr_accessor :address - - # Address allocation type (static, dynamic) - attr_accessor :allocation - - - # Attribute mapping from ruby-style variable name to JSON key. - def self.attribute_map - { - :'address' => :'address', - :'allocation' => :'allocation' - } - end - - # Attribute type mapping. - def self.swagger_types - { - :'address' => :'String', - :'allocation' => :'String' - } - end - - # Initializes the object - # @param [Hash] attributes Model attributes in the form of hash - def initialize(attributes = {}) - return unless attributes.is_a?(Hash) - - # convert string to symbol for hash key - attributes = attributes.each_with_object({}){|(k,v), h| h[k.to_sym] = v} - - if attributes.has_key?(:'address') - self.address = attributes[:'address'] - end - - if attributes.has_key?(:'allocation') - self.allocation = attributes[:'allocation'] - end - - end - - # Show invalid properties with the reasons. Usually used together with valid? - # @return Array for valid properies with the reasons - def list_invalid_properties - invalid_properties = Array.new - return invalid_properties - end - - # Check to see if the all the properties in the model are valid - # @return true if the model is valid - def valid? - return true - end - - # Checks equality by comparing each attribute. - # @param [Object] Object to be compared - def ==(o) - return true if self.equal?(o) - self.class == o.class && - address == o.address && - allocation == o.allocation - end - - # @see the `==` method - # @param [Object] Object to be compared - def eql?(o) - self == o - end - - # Calculates hash code according to all attributes. - # @return [Fixnum] Hash code - def hash - [address, allocation].hash - end - - # Builds the object from hash - # @param [Hash] attributes Model attributes in the form of hash - # @return [Object] Returns the model itself - def build_from_hash(attributes) - return nil unless attributes.is_a?(Hash) - self.class.swagger_types.each_pair do |key, type| - if type =~ /^Array<(.*)>/i - # check to ensure the input is an array given that the the attribute - # is documented as an array but the input is not - if attributes[self.class.attribute_map[key]].is_a?(Array) - self.send("#{key}=", attributes[self.class.attribute_map[key]].map{ |v| _deserialize($1, v) } ) - end - elsif !attributes[self.class.attribute_map[key]].nil? - self.send("#{key}=", _deserialize(type, attributes[self.class.attribute_map[key]])) - end # or else data not found in attributes(hash), not an issue as the data can be optional - end - - self - end - - # Deserializes the data based on type - # @param string type Data type - # @param string value Value to be deserialized - # @return [Object] Deserialized data - def _deserialize(type, value) - case type.to_sym - when :DateTime - DateTime.parse(value) - when :Date - Date.parse(value) - when :String - value.to_s - when :Integer - value.to_i - when :Float - value.to_f - when :BOOLEAN - if value.to_s =~ /^(true|t|yes|y|1)$/i - true - else - false - end - when :Object - # generic object (usually a Hash), return directly - value - when /\AArray<(?.+)>\z/ - inner_type = Regexp.last_match[:inner_type] - value.map { |v| _deserialize(inner_type, v) } - when /\AHash<(?.+), (?.+)>\z/ - k_type = Regexp.last_match[:k_type] - v_type = Regexp.last_match[:v_type] - {}.tap do |hash| - value.each do |k, v| - hash[_deserialize(k_type, k)] = _deserialize(v_type, v) - end - end - else # model - temp_model = Now.const_get(type).new - temp_model.build_from_hash(value) - end - end - - # Returns the string representation of the object - # @return [String] String presentation of the object - def to_s - to_hash.to_s - end - - # to_body is an alias to to_hash (backward compatibility) - # @return [Hash] Returns the object in the form of hash - def to_body - to_hash - end - - # Returns the object in the form of hash - # @return [Hash] Returns the object in the form of hash - def to_hash - hash = {} - self.class.attribute_map.each_pair do |attr, param| - value = self.send(attr) - next if value.nil? - hash[param] = _to_hash(value) - end - hash - end - - # Outputs non-array value in the form of hash - # For object, use to_hash. Otherwise, just return the value - # @param [Object] value Any valid value - # @return [Hash] Returns the value in the form of hash - def _to_hash(value) - if value.is_a?(Array) - value.compact.map{ |v| _to_hash(v) } - elsif value.is_a?(Hash) - {}.tap do |hash| - value.each { |k, v| hash[k] = _to_hash(v) } - end - elsif value.respond_to? :to_hash - value.to_hash - else - value - end - end + # Address range + class Range < SwaggerClient::Range + # network mask for the allocated networks + attr_accessor :prefix end end -- 1.8.2.3