Class: MiqAeMethodService::MiqAeServiceModelBase

Inherits:
Object
  • Object
show all
Extended by:
DRbUndumped
Includes:
DRbUndumped, MiqAeServiceObjectCommon, MiqAeServiceRbac, Vmdb::Logging
Defined in:
lib/miq_automation_engine/engine/miq_ae_method_service/miq_ae_service_model_base.rb

Direct Known Subclasses

MiqAeServiceAccount, MiqAeServiceArbitrationProfile, MiqAeServiceArbitrationRecord, MiqAeServiceAuthentication, MiqAeServiceAuthenticationAllowAll, MiqAeServiceAuthenticationGithub, MiqAeServiceAuthenticationGoogle, MiqAeServiceAuthenticationHtpasswd, MiqAeServiceAuthenticationLdap, MiqAeServiceAuthenticationOpenId, MiqAeServiceAuthenticationRequestHeader, MiqAeServiceAvailabilityZone, MiqAeServiceClassification, MiqAeServiceCloudNetwork, MiqAeServiceCloudObjectStoreContainer, MiqAeServiceCloudObjectStoreObject, MiqAeServiceCloudResourceQuota, MiqAeServiceCloudSubnet, MiqAeServiceCloudTenant, MiqAeServiceCloudVolume, MiqAeServiceCloudVolumeBackup, MiqAeServiceCloudVolumeSnapshot, MiqAeServiceCompliance, MiqAeServiceComplianceDetail, MiqAeServiceConfigurationLocation, MiqAeServiceConfigurationOrganization, MiqAeServiceConfigurationProfile, MiqAeServiceConfigurationScriptBase, MiqAeServiceConfigurationTag, MiqAeServiceConfiguredSystem, MiqAeServiceContainer, MiqAeServiceContainerBuild, MiqAeServiceContainerBuildPod, MiqAeServiceContainerCondition, MiqAeServiceContainerDefinition, MiqAeServiceContainerDeployment, MiqAeServiceContainerDeploymentNode, MiqAeServiceContainerEnvVar, MiqAeServiceContainerGroup, MiqAeServiceContainerImage, MiqAeServiceContainerImageRegistry, MiqAeServiceContainerLimit, MiqAeServiceContainerLimitItem, MiqAeServiceContainerNode, MiqAeServiceContainerPortConfig, MiqAeServiceContainerProject, MiqAeServiceContainerQuota, MiqAeServiceContainerReplicator, MiqAeServiceContainerRoute, MiqAeServiceContainerService, MiqAeServiceContainerVolume, MiqAeServiceCustomizationScript, MiqAeServiceCustomizationSpec, MiqAeServiceCustomizationTemplate, MiqAeServiceDisk, MiqAeServiceEmsCluster, MiqAeServiceEmsFolder, MiqAeServiceEventStream, MiqAeServiceExtManagementSystem, MiqAeServiceFilesystem, MiqAeServiceFirewallRule, MiqAeServiceFlavor, MiqAeServiceFloatingIp, MiqAeServiceGenericObject, MiqAeServiceGenericObjectDefinition, MiqAeServiceGuestApplication, MiqAeServiceGuestDevice, MiqAeServiceHardware, MiqAeServiceHost, MiqAeServiceHostAggregate, MiqAeServiceIsoImage, MiqAeServiceJob, MiqAeServiceLan, MiqAeServiceLoadBalancer, MiqAeServiceManageIQ_Providers_DatawarehouseManager, MiqAeServiceManageIQ_Providers_Hawkular_DatawarehouseManager, MiqAeServiceManageIQ_Providers_Hawkular_MiddlewareManager, MiqAeServiceMiqAeNamespace, MiqAeServiceMiqGroup, MiqAeServiceMiqPolicy, MiqAeServiceMiqRequest, MiqAeServiceMiqRequestTask, MiqAeServiceMiqServer, MiqAeServiceNetwork, MiqAeServiceNetworkPort, MiqAeServiceNetworkRouter, MiqAeServiceNotification, MiqAeServiceNotificationType, MiqAeServiceOperatingSystem, MiqAeServiceOperatingSystemFlavor, MiqAeServiceOrchestrationStack, MiqAeServiceOrchestrationStackOutput, MiqAeServiceOrchestrationStackParameter, MiqAeServiceOrchestrationStackResource, MiqAeServiceOrchestrationTemplate, MiqAeServicePartition, MiqAeServicePersistentVolume, MiqAeServicePersistentVolumeClaim, MiqAeServiceProvider, MiqAeServicePxeImage, MiqAeServicePxeImageType, MiqAeServicePxeServer, MiqAeServiceResourceGroup, MiqAeServiceResourcePool, MiqAeServiceSecurityGroup, MiqAeServiceService, MiqAeServiceServiceResource, MiqAeServiceServiceTemplate, MiqAeServiceSnapshot, MiqAeServiceStorage, MiqAeServiceStorageFile, MiqAeServiceStorageProfile, MiqAeServiceSwitch, MiqAeServiceTenant, MiqAeServiceTenantQuota, MiqAeServiceUser, MiqAeServiceVmOrTemplate, MiqAeServiceVolume, MiqAeServiceWindowsImage

Constant Summary collapse

SERVICE_MODEL_PATH =
Rails.root.join("lib/miq_automation_engine/service_models")
SERVICE_MODEL_GLOB =
SERVICE_MODEL_PATH.join("miq_ae_service_*.rb")
EXPOSED_ATTR_BLACK_LIST =
[/password/, /^auth_key$/]
DELIMS =

Convert URI Excluded US-ASCII Characters to underscores

The following is a synopsis of section 2.4.3 from www.ietf.org/rfc/rfc2396.txt

control     = <US-ASCII coded characters 00-1F and 7F hexadecimal>
space       = <US-ASCII coded character 20 hexadecimal>
delims      = "<" | ">" | "#" | "%" | <">
unwise      = "{" | "}" | "|" | "\" | "^" | "[" | "]" | "`"
['<', '>', '#', '%', "\""]
UNWISE =
['{', '}', '|', "\\", '^', '[', ']', "\`"]

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Vmdb::Logging

#_log

Methods included from MiqAeServiceObjectCommon

#[], #[]=, #attributes, #attributes=, #class_name, #current_field_name, #current_field_type, #current_message, #decrypt, #id, #instance_name, #name, #namespace, #parent

Constructor Details

#initialize(obj) ⇒ MiqAeServiceModelBase

Returns a new instance of MiqAeServiceModelBase

Parameters:

  • obj (Integer, ActiveRecord::Base)

    The object id or ActiveRecord instance to wrap in a service model

Raises:

  • (ArgumentError)

191
192
193
194
195
196
197
198
199
# File 'lib/miq_automation_engine/engine/miq_ae_method_service/miq_ae_service_model_base.rb', line 191

def initialize(obj)
  ar_klass = self.class.send(:model)
  raise ArgumentError.new("#{ar_klass.name} Nil Object specified") if obj.nil?
  if obj.kind_of?(ActiveRecord::Base) && !obj.kind_of?(ar_klass)
    raise ArgumentError.new("#{ar_klass.name} Object expected, but received #{obj.class.name}")
  end
  @object = obj.kind_of?(ar_klass) ? obj : ar_method { self.class.find_ar_object_by_id(obj.to_i) }
  raise MiqAeException::ServiceNotFound, "#{ar_klass.name} Object [#{obj}] not found" if @object.nil?
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(m, *args) ⇒ Object


174
175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'lib/miq_automation_engine/engine/miq_ae_method_service/miq_ae_service_model_base.rb', line 174

def method_missing(m, *args)
  #
  # Normalize result of any method call
  #  e.g. normalized_ldap_group, will call ldap_group method and normalize the result
  #
  prefix = 'normalized_'
  if m.to_s.starts_with?(prefix)
    method = m.to_s[prefix.length..-1]
    result = MiqAeServiceModelBase.wrap_results(object_send(method, *args))
    return MiqAeServiceModelBase.normalize(result)
  end

  super
end

Class Method Details

.ar_base_modelObject


105
106
107
# File 'lib/miq_automation_engine/engine/miq_ae_method_service/miq_ae_service_model_base.rb', line 105

def self.ar_base_model
  send(:model).base_model
end

.ar_methodObject


282
283
284
285
286
287
288
289
290
291
292
# File 'lib/miq_automation_engine/engine/miq_ae_method_service/miq_ae_service_model_base.rb', line 282

def self.ar_method
  # In UI Worker, query caching is enabled.  This causes problems in Automate DRb Server (e.g. reload does not refetch from SQL)
  ActiveRecord::Base.connection.clear_query_cache if ActiveRecord::Base.connection.query_cache_enabled
  yield
rescue Exception => err
  $miq_ae_logger.error("MiqAeServiceModelBase.ar_method raised: <#{err.class}>: <#{err.message}>")
  $miq_ae_logger.error(err.backtrace.join("\n"))
  raise
ensure
  ActiveRecord::Base.connection_pool.release_connection rescue nil
end

.association(*args) ⇒ Object


61
62
63
# File 'lib/miq_automation_engine/engine/miq_ae_method_service/miq_ae_service_model_base.rb', line 61

def self.association(*args)
  args.each { |method_name| self.association = method_name }
end

.association=(meth) ⇒ Object


65
66
67
68
# File 'lib/miq_automation_engine/engine/miq_ae_method_service/miq_ae_service_model_base.rb', line 65

def self.association=(meth)
  @associations ||= []
  @associations << meth.to_s unless @associations.include?(meth.to_s)
end

.associationsObject


51
52
53
54
55
# File 'lib/miq_automation_engine/engine/miq_ae_method_service/miq_ae_service_model_base.rb', line 51

def self.associations
  @associations ||= []
  super_assoc = superclass.respond_to?(:associations) ? superclass.associations : []
  (super_assoc + @associations).sort
end

.base_classObject


70
71
72
73
74
# File 'lib/miq_automation_engine/engine/miq_ae_method_service/miq_ae_service_model_base.rb', line 70

def self.base_class
  @base_class ||= begin
    MiqAeMethodService.const_get("MiqAeService#{model.base_class.name}")
  end
end

.base_modelObject


76
77
78
79
80
# File 'lib/miq_automation_engine/engine/miq_ae_method_service/miq_ae_service_model_base.rb', line 76

def self.base_model
  @base_model ||= begin
    MiqAeMethodService.const_get("MiqAeService#{model.base_model.name}")
  end
end

.inherited(subclass) ⇒ Object


41
42
43
44
45
46
47
48
49
# File 'lib/miq_automation_engine/engine/miq_ae_method_service/miq_ae_service_model_base.rb', line 41

def self.inherited(subclass)
  subclass.class_eval do
    model.attribute_names.each do |attr|
      next if EXPOSED_ATTR_BLACK_LIST.any? { |rexp| attr =~ rexp }
      next if subclass.base_class != self && method_defined?(attr)
      expose attr
    end
  end
end

.method_missing(m, *args) ⇒ Object


17
18
19
20
21
22
# File 'lib/miq_automation_engine/engine/miq_ae_method_service/miq_ae_service_model_base.rb', line 17

def self.method_missing(m, *args)
  return wrap_results(filter_objects(model.send(m, *args))) if class_method_exposed?(m)
  super
rescue ActiveRecord::RecordNotFound
  raise MiqAeException::ServiceNotFound, "Service Model not found"
end

.model_name_from_active_record_model(ar_model) ⇒ Object


92
93
94
# File 'lib/miq_automation_engine/engine/miq_ae_method_service/miq_ae_service_model_base.rb', line 92

def self.model_name_from_active_record_model(ar_model)
  "MiqAeMethodService::MiqAeService#{ar_model.name.gsub(/::/, '_')}"
end

.model_name_from_file(filename) ⇒ Object


88
89
90
# File 'lib/miq_automation_engine/engine/miq_ae_method_service/miq_ae_service_model_base.rb', line 88

def self.model_name_from_file(filename)
  File.basename(filename, '.*').split('-').map(&:camelize).join('_')
end

.normalize(str) ⇒ Object


155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/miq_automation_engine/engine/miq_ae_method_service/miq_ae_service_model_base.rb', line 155

def self.normalize(str)
  return str unless str.kind_of?(String)

  arr = str.each_char.collect do |c|
    if DELIMS.include?(c) || UNWISE.include?(c) || c == ' '
      '_'
    else
      ordinal = c.ord
      if (ordinal >= 0x00 && ordinal <= 0x1F) || ordinal == 0x7F
        '_'
      else
        c
      end
    end
  end

  arr.join
end

.respond_to_missing?(method_name, include_private = false) ⇒ Boolean

Returns:

  • (Boolean)

24
25
26
# File 'lib/miq_automation_engine/engine/miq_ae_method_service/miq_ae_service_model_base.rb', line 24

def self.respond_to_missing?(method_name, include_private = false)
  class_method_exposed?(method_name.to_sym) || super
end

.service_modelsObject


96
97
98
99
100
101
102
103
# File 'lib/miq_automation_engine/engine/miq_ae_method_service/miq_ae_service_model_base.rb', line 96

def self.service_models
  Dir.glob(MiqAeMethodService::MiqAeServiceModelBase::SERVICE_MODEL_GLOB).collect do |f|
    model_name = MiqAeMethodService::MiqAeServiceModelBase.model_name_from_file(f)
    next if model_name == "MiqAeServiceMethods"

    "MiqAeMethodService::#{model_name}".constantize
  end.compact!
end

.taggable?Boolean

Returns:

  • (Boolean)

249
250
251
# File 'lib/miq_automation_engine/engine/miq_ae_method_service/miq_ae_service_model_base.rb', line 249

def self.taggable?
  model.respond_to?(:tags)
end

.wrap_results(results) ⇒ Object


127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/miq_automation_engine/engine/miq_ae_method_service/miq_ae_service_model_base.rb', line 127

def self.wrap_results(results)
  ar_method do
    if results.kind_of?(Array) || results.kind_of?(ActiveRecord::Relation)
      results.collect { |r| wrap_results(r) }
    elsif results.kind_of?(ActiveRecord::Base)
      klass = MiqAeMethodService.const_get("MiqAeService#{results.class.name.gsub(/::/, '_')}")
      klass.new(results)
    else
      results
    end
  end
end

Instance Method Details

#ar_method(&block) ⇒ Object


294
295
296
# File 'lib/miq_automation_engine/engine/miq_ae_method_service/miq_ae_service_model_base.rb', line 294

def ar_method(&block)
  self.class.ar_method(&block)
end

#associationsObject


57
58
59
# File 'lib/miq_automation_engine/engine/miq_ae_method_service/miq_ae_service_model_base.rb', line 57

def associations
  self.class.associations
end

#inspectObject


210
211
212
# File 'lib/miq_automation_engine/engine/miq_ae_method_service/miq_ae_service_model_base.rb', line 210

def inspect
  ar_method { "\#<#{self.class.name.demodulize}:0x#{object_id.to_s(16)} @object=#{@object.inspect}, @virtual_columns=#{virtual_column_names.inspect}, @associations=#{associations.inspect}>" }
end

#inspect_allObject


214
215
216
# File 'lib/miq_automation_engine/engine/miq_ae_method_service/miq_ae_service_model_base.rb', line 214

def inspect_all
  ar_method { "\#<#{self.class.name.demodulize}:0x#{object_id.to_s(16)} @object=#{@object.inspect}, @virtual_columns=#{virtual_columns_inspect}, @associations=#{associations.inspect}>" }
end

#model_suffixObject


278
279
280
# File 'lib/miq_automation_engine/engine/miq_ae_method_service/miq_ae_service_model_base.rb', line 278

def model_suffix
  @object.class.model_suffix
end

#object_classObject


274
275
276
# File 'lib/miq_automation_engine/engine/miq_ae_method_service/miq_ae_service_model_base.rb', line 274

def object_class
  object_send(:class)
end

#object_send(name, *params) ⇒ Object


263
264
265
266
267
268
269
270
271
272
# File 'lib/miq_automation_engine/engine/miq_ae_method_service/miq_ae_service_model_base.rb', line 263

def object_send(name, *params)
  ar_method do
    begin
      @object.public_send(name, *params)
    rescue Exception => err
      $miq_ae_logger.error("The following error occurred during instance method <#{name}> for AR object <#{@object.inspect}>")
      raise
    end
  end
end

#reloadObject


258
259
260
261
# File 'lib/miq_automation_engine/engine/miq_ae_method_service/miq_ae_service_model_base.rb', line 258

def reload
  object_send(:reload)
  self # Return self to prevent the internal object from being returned
end

#tag_assign(tag) ⇒ Object


229
230
231
232
233
234
235
# File 'lib/miq_automation_engine/engine/miq_ae_method_service/miq_ae_service_model_base.rb', line 229

def tag_assign(tag)
  verify_taggable_model
  ar_method do
    Classification.classify_by_tag(@object, "/managed/#{tag}")
    true
  end
end

#tag_unassign(tag) ⇒ Object


237
238
239
240
241
242
243
# File 'lib/miq_automation_engine/engine/miq_ae_method_service/miq_ae_service_model_base.rb', line 237

def tag_unassign(tag)
  verify_taggable_model
  ar_method do
    Classification.unclassify_by_tag(@object, "/managed/#{tag}")
    true
  end
end

#taggable?Boolean

Returns:

  • (Boolean)

245
246
247
# File 'lib/miq_automation_engine/engine/miq_ae_method_service/miq_ae_service_model_base.rb', line 245

def taggable?
  self.class.taggable?
end

#tagged_with?(category, name) ⇒ Boolean

Returns:

  • (Boolean)

218
219
220
221
# File 'lib/miq_automation_engine/engine/miq_ae_method_service/miq_ae_service_model_base.rb', line 218

def tagged_with?(category, name)
  verify_taggable_model
  object_send(:is_tagged_with?, name.to_s, :ns => "/managed/#{category}")
end

#tags(category = nil) ⇒ Object


223
224
225
226
227
# File 'lib/miq_automation_engine/engine/miq_ae_method_service/miq_ae_service_model_base.rb', line 223

def tags(category = nil)
  verify_taggable_model
  ns = category.nil? ? "/managed" : "/managed/#{category}"
  object_send(:tag_list, :ns => ns).split
end

#virtual_column_namesObject


206
207
208
# File 'lib/miq_automation_engine/engine/miq_ae_method_service/miq_ae_service_model_base.rb', line 206

def virtual_column_names
  @object.class.virtual_attribute_names.sort
end

#virtual_columns_inspectObject


201
202
203
204
# File 'lib/miq_automation_engine/engine/miq_ae_method_service/miq_ae_service_model_base.rb', line 201

def virtual_columns_inspect
  arr = @object.class.virtual_attribute_names.sort.collect { |vc| "#{vc}: #{@object.send(vc).inspect}" }
  "<#{arr.join(', ')}>"
end

#wrap_results(results) ⇒ Object


140
141
142
# File 'lib/miq_automation_engine/engine/miq_ae_method_service/miq_ae_service_model_base.rb', line 140

def wrap_results(results)
  self.class.wrap_results(results)
end