class OneviewSDK::Resource
Resource
base class that defines all common resource functionality.
Constants
- BASE_URI
- DEFAULT_REQUEST_HEADER
- UNIQUE_IDENTIFIERS
Attributes
Public Class Methods
Builds a Query string corresponding to the parameters passed @param [Hash{String=>String,OneviewSDK::Resource}] query_options Query parameters and values
to be applied to the query url. All key values should be Strings in snake case, the values could be Strings or Resources.
@option query_options [String] String Values that are Strings can be associated as usual @option query_options [String] Resources Values that are Resources can be associated as usual,
with keys representing only the resource names (like 'ethernet_network'). This method translates the SDK and Ruby standards to OneView request standard.
# File lib/oneview-sdk/resource.rb, line 336 def self.build_query(query_options) return '' if !query_options || query_options.empty? query_path = '?' query_options.each do |k, v| words = k.to_s.split('_') words.map!(&:capitalize!) words[0] = words.first.downcase new_key = words.join v = "'" + v.join(',') + "'" if v.is_a?(Array) && v.any? v.retrieve! if v.respond_to?(:retrieve!) && !v['uri'] if v.class <= OneviewSDK::Resource new_key = new_key.concat('Uri') v = v['uri'] end query_path.concat("&#{new_key}=#{v}") end query_path.sub('?&', '?') end
Make a GET request to the resource uri, and returns an array with results matching the search @param [OneviewSDK::Client] client The client object for the OneView appliance @param [Hash] attributes Hash containing the attributes name and value @param [String] uri URI of the endpoint @param [Hash] header The header options for the request (key-value pairs) @return [Array<Resource>] Results matching the search
# File lib/oneview-sdk/resource.rb, line 291 def self.find_by(client, attributes, uri = self::BASE_URI, header = self::DEFAULT_REQUEST_HEADER) all = find_with_pagination(client, uri, header) results = [] all.each do |member| temp = new(client, member) results.push(temp) if temp.like?(attributes) end results end
Make a GET request to the uri, and returns an array with all results (search using resource pagination) @param [OneviewSDK::Client] client The client object for the OneView appliance @param [String] uri URI of the endpoint @param [Hash] header The header options for the request (key-value pairs) @return [Array<Hash>] Results
# File lib/oneview-sdk/resource.rb, line 306 def self.find_with_pagination(client, uri, header = self::DEFAULT_REQUEST_HEADER) all = [] loop do response = client.rest_get(uri, header) body = client.response_handler(response) members = body['members'] break unless members all.concat(members) break unless body['nextPageUri'] && (body['nextPageUri'] != body['uri']) uri = body['nextPageUri'] end all end
Load resource from a .json or .yaml file @param [OneviewSDK::Client] client The client object for the OneView appliance @param [String] file_path The full path to the file @return [Resource] New resource created from the file contents
# File lib/oneview-sdk/resource.rb, line 271 def self.from_file(client, file_path) resource = OneviewSDK::Config.load(file_path) klass = self if klass == OneviewSDK::Resource && resource['type'] # Use correct resource class by parsing type klass = OneviewSDK # Secondary/temp class/module reference resource['type'].split('::').each do |id| c = klass.const_get(id) rescue nil klass = c if c.is_a?(Class) || c.is_a?(Module) end klass = OneviewSDK::Resource unless klass <= OneviewSDK::Resource end klass.new(client, resource['data'], resource['api_version']) end
Make a GET request to the resource base uri, and returns an array with all objects of this type @param [OneviewSDK::Client] client The client object for the OneView appliance @param [Hash] header The header options for the request (key-value pairs) @return [Array<Resource>] Results
# File lib/oneview-sdk/resource.rb, line 324 def self.get_all(client, header = self::DEFAULT_REQUEST_HEADER) find_by(client, {}, self::BASE_URI, header) end
Make a GET request to the resource base uri, query parameters and returns an array with all objects of this type @param [OneviewSDK::Client] client The client object for the OneView appliance @param [Hash] query The query options for the request (key-value pairs) @param [Hash] header The header options for the request (key-value pairs) @return [Array<Resource>] Results
# File lib/oneview-sdk/resource.rb, line 360 def self.get_all_with_query(client, query = nil) query_uri = build_query(query) if query find_with_pagination(client, "#{self::BASE_URI}/#{query_uri}") end
Create a resource object, associate it with a client, and set its properties. @param [OneviewSDK::Client] client The client object for the OneView appliance @param [Hash] params The options for this resource (key-value pairs) @param [Integer] api_ver The api version to use when interracting with this resource.
Defaults to the client.api_version if it exists, or Appliance's max API version to be used by default for requests
# File lib/oneview-sdk/resource.rb, line 34 def initialize(client, params = {}, api_ver = nil) raise InvalidClient, 'Must specify a valid client'\ unless client.is_a?(OneviewSDK::Client) || client.is_a?(OneviewSDK::ImageStreamer::Client) @client = client @logger = @client.logger @api_version = api_ver || @client.api_version if @api_version > @client.max_api_version raise UnsupportedVersion, "#{self.class.name} api_version '#{@api_version}' is greater than the client's max_api_version '#{@client.max_api_version}'" end @data ||= {} set_all(params) end
Get resource schema @param [OneviewSDK::Client] client The client object for the OneView appliance @return [Hash] Schema
# File lib/oneview-sdk/resource.rb, line 259 def self.schema(client) response = client.rest_get("#{self::BASE_URI}/schema", {}, client.api_version) client.response_handler(response) rescue StandardError => e client.logger.error('This resource does not implement the schema endpoint!') if e.message =~ /404 NOT FOUND/ raise e end
Public Instance Methods
Check equality of 2 resources. Same as eql?(other) @param [Resource] other The other resource to check equality for @return [Boolean] Whether or not the two objects are equal
# File lib/oneview-sdk/resource.rb, line 141 def ==(other) self_state = instance_variables.sort.map { |v| instance_variable_get(v) } other_state = other.instance_variables.sort.map { |v| other.instance_variable_get(v) } other.class == self.class && other_state == self_state end
Access data using hash syntax @param [String, Symbol] key Name of key to get value for @return The value of the given key. If not found, returns nil @note The key will be converted to a string
# File lib/oneview-sdk/resource.rb, line 125 def [](key) @data[key.to_s] end
Set data using hash syntax @param [String, Symbol] key Name of key to set the value for @param [Object] value to set for the given key @note The key will be converted to a string @return The value set for the given key
# File lib/oneview-sdk/resource.rb, line 134 def []=(key, value) set(key, value) end
Create the resource on OneView using the current data @note Calls the refresh method to set additional data @param [Hash] header The header options for the request (key-value pairs) @raise [OneviewSDK::IncompleteResource] if the client is not set @raise [StandardError] if the resource creation fails @return [Resource] self
# File lib/oneview-sdk/resource.rb, line 172 def create(header = self.class::DEFAULT_REQUEST_HEADER) ensure_client options = {}.merge(header).merge('body' => @data) response = @client.rest_post(self.class::BASE_URI, options, @api_version) body = @client.response_handler(response) set_all(body) self end
Delete the resource from OneView if it exists, then create it using the current data @note Calls refresh method to set additional data @param [Hash] header The header options for the request (key-value pairs) @raise [OneviewSDK::IncompleteResource] if the client is not set @raise [StandardError] if the resource creation fails @return [Resource] self
# File lib/oneview-sdk/resource.rb, line 187 def create!(header = self.class::DEFAULT_REQUEST_HEADER) temp = self.class.new(@client, @data) temp.delete(header) if temp.retrieve!(header) create(header) end
Merges the first hash data structure with the second @note both arguments should be a Ruby Hash object.
The second hash should have strings as a keys. This method will change the second argument.
@raise [StandardError] if the arguments, or one them, is not a Hash object
# File lib/oneview-sdk/resource.rb, line 83 def deep_merge!(other_data, target_data = @data) raise 'Both arguments should be a object Hash' unless other_data.is_a?(Hash) && target_data.is_a?(Hash) other_data.each do |key, value| value_target = target_data[key.to_s] if value_target.is_a?(Hash) && value.is_a?(Hash) deep_merge!(value, value_target) else target_data[key.to_s] = value end end end
Delete resource from OneView @param [Hash] header The header options for the request (key-value pairs) @return [true] if resource was deleted successfully
# File lib/oneview-sdk/resource.rb, line 223 def delete(header = self.class::DEFAULT_REQUEST_HEADER) ensure_client && ensure_uri response = @client.rest_delete(@data['uri'], header, @api_version) @client.response_handler(response) true end
Run block once for each data key-value pair
# File lib/oneview-sdk/resource.rb, line 117 def each(&block) @data.each(&block) end
Check equality of 2 resources. Same as ==(other) @param [Resource] other The other resource to check for equality @return [Boolean] Whether or not the two objects are equal
# File lib/oneview-sdk/resource.rb, line 150 def eql?(other) self == other end
Check if a resource exists @note one of the UNIQUE_IDENTIFIERS
, e.g. name or uri, must be specified in the resource @param [Hash] header The header options for the request (key-value pairs) @return [Boolean] Whether or not resource exists
# File lib/oneview-sdk/resource.rb, line 68 def exists?(header = self.class::DEFAULT_REQUEST_HEADER) retrieval_keys = self.class::UNIQUE_IDENTIFIERS.reject { |k| @data[k].nil? } raise IncompleteResource, "Must set resource #{self.class::UNIQUE_IDENTIFIERS.join(' or ')} before trying to retrieve!" if retrieval_keys.empty? retrieval_keys.each do |k| results = self.class.find_by(@client, { k => @data[k] }, self.class::BASE_URI, header) return true if results.size == 1 end false end
Check the equality of the data for the other resource with this resource. @note Does not check the client, logger, or api_version
if another resource is passed in @param [Hash, Resource] other resource or hash to compare the key-value pairs with @example Compare to hash
myResource = OneviewSDK::Resource.new(client, { name: 'res1', description: 'example'}, 200) myResource.like?(description: '') # returns false myResource.like?(name: 'res1') # returns true
@return [Boolean] Whether or not the two objects are alike
# File lib/oneview-sdk/resource.rb, line 162 def like?(other) recursive_like?(other, @data) end
Updates this object using the data that exists on OneView @note Will overwrite any data that differs from OneView @param [Hash] header The header options for the request (key-value pairs) @return [Resource] self
# File lib/oneview-sdk/resource.rb, line 197 def refresh(header = self.class::DEFAULT_REQUEST_HEADER) ensure_client && ensure_uri response = @client.rest_get(@data['uri'], header, @api_version) body = @client.response_handler(response) set_all(body) self end
Retrieve resource details based on this resource's name or URI. @note one of the UNIQUE_IDENTIFIERS
, e.g. name or uri, must be specified in the resource @param [Hash] header The header options for the request (key-value pairs) @return [Boolean] Whether or not retrieve was successful
# File lib/oneview-sdk/resource.rb, line 52 def retrieve!(header = self.class::DEFAULT_REQUEST_HEADER) retrieval_keys = self.class::UNIQUE_IDENTIFIERS.reject { |k| @data[k].nil? } raise IncompleteResource, "Must set resource #{self.class::UNIQUE_IDENTIFIERS.join(' or ')} before trying to retrieve!" if retrieval_keys.empty? retrieval_keys.each do |k| results = self.class.find_by(@client, { k => @data[k] }, self.class::BASE_URI, header) next if results.size != 1 set_all(results[0].data) return true end false end
Get resource schema @note This may not be implemented in the API for every resource. Check the API docs @return [Hash] Schema
# File lib/oneview-sdk/resource.rb, line 252 def schema self.class.schema(@client) end
Set a resource attribute with the given value and call any validation method if necessary @param [String] key attribute name @param value value to assign to the given attribute @note Keys will be converted to strings
# File lib/oneview-sdk/resource.rb, line 110 def set(key, value) method_name = "validate_#{key}" send(method_name.to_sym, value) if respond_to?(method_name.to_sym) @data[key.to_s] = value end
Set the given hash of key-value pairs as resource data attributes @param [Hash, Resource] params The options for this resource (key-value pairs or resource object) @note All top-level keys will be converted to strings @return [Resource] self
# File lib/oneview-sdk/resource.rb, line 99 def set_all(params = self.class::DEFAULT_REQUEST_HEADER) params = params.data if params.class <= Resource params = Hash[params.map { |(k, v)| [k.to_s, v] }] params.each { |key, value| set(key.to_s, value) } self end
Save resource to json or yaml file @param [String] file_path The full path to the file @param [Symbol] format The format. Options: [:json, :yml, :yaml]. Defaults to .json @note If a .yml or .yaml file extension is given in the file_path, the format will be set automatically @return [True] The Resource
was saved successfully
# File lib/oneview-sdk/resource.rb, line 235 def to_file(file_path, format = :json) format = :yml if %w[.yml .yaml].include? File.extname(file_path) temp_data = { type: self.class.name, api_version: @api_version, data: @data } case format.to_sym when :json File.open(file_path, 'w') { |f| f.write(JSON.pretty_generate(temp_data)) } when :yml, :yaml File.open(file_path, 'w') { |f| f.write(temp_data.to_yaml) } else raise InvalidFormat, "Invalid format: #{format}" end true end
Set data and save to OneView @param [Hash] attributes The attributes to add/change for this resource (key-value pairs) @param [Hash] header The header options for the request (key-value pairs) @raise [OneviewSDK::IncompleteResource] if the client or uri is not set @raise [StandardError] if the resource save fails @return [Resource] self
# File lib/oneview-sdk/resource.rb, line 211 def update(attributes = {}, header = self.class::DEFAULT_REQUEST_HEADER) set_all(attributes) ensure_client && ensure_uri options = {}.merge(header).merge('body' => @data) response = @client.rest_put(@data['uri'], options, @api_version) @client.response_handler(response) self end
Protected Instance Methods
Gets all the URIs for the specified resources @param [Array<OneviewSDK::Resource>] resources The list of resources @return [Array<String>] List of uris @raise IncompleteResource
if 'uri' is not set for each resource.
# File lib/oneview-sdk/resource.rb, line 383 def ensure_and_get_uris(resources) resources.map do |resource| resource.ensure_uri resource['uri'] end end
Fail unless @client is set for this resource.
# File lib/oneview-sdk/resource.rb, line 368 def ensure_client raise IncompleteResource, 'Please set client attribute before interacting with this resource' unless @client true end
Fail unless @data is set for this resource.
# File lib/oneview-sdk/resource.rb, line 374 def ensure_uri raise IncompleteResource, 'Please set uri attribute before interacting with this resource' unless @data['uri'] true end
Private Instance Methods
Recursive helper method for like? Allows comparison of nested hash structures
# File lib/oneview-sdk/resource.rb, line 399 def recursive_like?(other, data = @data) raise "Can't compare with object type: #{other.class}! Must respond_to :each" unless other.respond_to?(:each) other.each do |key, val| return false unless data && data.respond_to?(:[]) if val.is_a?(Hash) return false unless data.class == Hash && recursive_like?(val, data[key.to_s]) elsif val.is_a?(Array) && val.first.is_a?(Hash) data_array = data[key.to_s] || data[key.to_sym] return false unless data_array.is_a?(Array) val.each do |other_item| return false unless data_array.find { |data_item| recursive_like?(other_item, data_item) } end elsif val.to_s != data[key.to_s].to_s && val.to_s != data[key.to_sym].to_s return false end end true end