Module: Xolo::Server::Mixins::TitleTedAccess

Included in:
Title
Defined in:
lib/xolo/server/mixins/title_ted_access.rb

Overview

This is mixed in to Xolo::Server::Title to define Title-related access to the Title Editor server

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(includer) ⇒ Object

when this module is included



32
33
34
# File 'lib/xolo/server/mixins/title_ted_access.rb', line 32

def self.included(includer)
  Xolo.verbose_include includer, self
end

Instance Method Details

#any_ted_changes?Boolean

Returns are there any changes to make in the Title Editor?.

Returns:

  • (Boolean)

    are there any changes to make in the Title Editor?



268
269
270
271
272
273
274
275
# File 'lib/xolo/server/mixins/title_ted_access.rb', line 268

def any_ted_changes?
  ted_attrs = Xolo::Server::Title::ATTRIBUTES.select { |_attr, deets| deets[:ted_attribute] }.keys
  # version scripts are handled differently and are not marked as
  # ted_attributes, so we need to add it here
  ted_attrs << :version_script

  (changes_for_update.keys & ted_attrs).empty? ? false : true
end

#apply_requirement_changesvoid

This method returns an undefined value.

Apply changes to the Title Editor Title Requirements and patch component criteria for all versions



225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
# File 'lib/xolo/server/mixins/title_ted_access.rb', line 225

def apply_requirement_changes
  req_change = requirement_change
  return unless req_change

  new_ea_script = changes_for_update.dig :version_script, :new

  # if either of these are nil in changes, then use the existing value
  new_app_name = changes_for_update.dig(:app_name, :new) || app_name
  new_app_bundle_id = changes_for_update.dig(:app_bundle_id, :new) || app_bundle_id

  case req_change
  when :app_to_ea
    # create the ea
    create_ted_ea new_ea_script
    # set the requirement to use the ea
    set_ted_title_requirement ea_name: ted_ea_key
    # for all versions, update the patch compotent criteria to use the ea
    set_ted_patch_component_criteria_after_update ea_name: ted_ea_key

  when :ea_to_app
    # set the requirement to use the app data
    set_ted_title_requirement app_name: new_app_name, app_bundle_id: new_app_bundle_id
    # for all versions, update the patch compotent criteria to use the app data
    set_ted_patch_component_criteria_after_update app_name: new_app_name, app_bundle_id: new_app_bundle_id
    # delete the ea
    delete_ted_ea

  when :update_app
    # set the requirement to use the new app data
    set_ted_title_requirement app_name: new_app_name, app_bundle_id: new_app_bundle_id

    # for all versions, update the patch compotent criteria to use the new app data
    set_ted_patch_component_criteria_after_update app_name: new_app_name, app_bundle_id: new_app_bundle_id

  when :update_ea
    # update the ea script
    update_ted_ea new_ea_script

  end
end

#create_and_enable_stub_patch_in_ted(new_title) ⇒ void

This method returns an undefined value.

Create and enable the stub patch, so that the title can be enabled in Jamf, and if needed, any EA accepted

Parameters:

  • new_title (Windoo::SoftwareTitle)

    The newly created title



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/xolo/server/mixins/title_ted_access.rb', line 106

def create_and_enable_stub_patch_in_ted(new_title)
  progress(
    "Title Editor: Creating Stub version #{Xolo::Server::Version::STUB_PATCH_VERSION} for title '#{title}', to allow activation in Jamf",
    log: :info
  )

  # the patch
  new_title.patches.add_patch(
    version: Xolo::Server::Version::STUB_PATCH_VERSION,
    minimumOperatingSystem: Xolo::Server::Version::DEFAULT_MIN_OS,
    releaseDate: Time.now
  )
  stub_patch = new_title.patches.first

  # the capabilites
  stub_patch.capabilities.add_criterion(
    name: Xolo::Server::Version::STUB_PATCH_CAPABILITY_CRITERION_NAME,
    operator: Xolo::Server::Version::STUB_PATCH_CAPABILITY_CRITERION_OPERATOR,
    value: Xolo::Server::Version::STUB_PATCH_CAPABILITY_CRITERION_VALUE
  )

  # the component
  stub_patch.add_component(
    name: Xolo::Server::Version::STUB_PATCH_COMPONENT_NAME,
    version: Xolo::Server::Version::STUB_PATCH_VERSION
  )

  comp = stub_patch.component
  comp.criteria.add_criterion(
    name: Xolo::Server::Version::STUB_PATCH_COMPONENT_CRITERION_NAME,
    operator: Xolo::Server::Version::STUB_PATCH_COMPONENT_CRITERION_OPERATOR,
    value: Xolo::Server::Version::STUB_PATCH_COMPONENT_CRITERION_VALUE
  )

  # enable the patch
  stub_patch.enable
end

#create_ted_ea(script) ⇒ void

This method returns an undefined value.

Create the EA in the Title Editor



326
327
328
329
330
331
332
333
334
335
336
337
338
# File 'lib/xolo/server/mixins/title_ted_access.rb', line 326

def create_ted_ea(script)
  # delete and recreate the EA
  progress "Title Editor: Creating Extension Attribute from version_script for title '#{title}'", log: :info

  ted_title.delete_extensionAttribute

  ted_title.add_extensionAttribute(
    key: ted_ea_key,
    displayName: ted_ea_key,
    script: script
  )
  @need_to_accept_jamf_patch_ea = true
end

#create_ted_title_requirementsvoid

This method returns an undefined value.

Create the requirements for a new title in the Title Editor Either app-based or EA-based, depending on the data in the Xolo Title.

Requirements are criteria indicating that this title (any version) is installed on a client machine.

If the Xolo Title has app_name and app_bundle_id defined, they are used as the requirement criteria and the Patch component criteria.

If the Xolo Title as a version_script defined, it returns either an empty value, or the version installed on the client It is added to the Title Editor title as the Ext Attr and used both as the requirement criterion (the value is not empty) and as a Patch Component criterion for versions (the value contains the version).



161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/xolo/server/mixins/title_ted_access.rb', line 161

def create_ted_title_requirements
  # if we have app-based requirements, set them
  if app_name && app_bundle_id
    set_ted_title_requirement app_name: app_name, app_bundle_id: app_bundle_id
  elsif version_script
    # if we have a version_script, set it
    create_ted_ea version_script_contents
    set_ted_title_requirement ea_name: ted_ea_key
  else
    raise Xolo::MissingDataError,
          'Cannot create Title Editor Title Requirements without app_name & app_bundle_id, or version_script'
  end
end

#create_title_in_tedWindoo::SoftwareTitle

Create this title in the title editor, along with a stub patch that allows us to enable it so we can activate it in Jamf and accept an EA if needed

Returns:

  • (Windoo::SoftwareTitle)


67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/xolo/server/mixins/title_ted_access.rb', line 67

def create_title_in_ted
  if subscribed?
    log_debug "Title Editor: SoftwareTitle '#{title}' is subscribed, skipping Title Editor creation"
    return
  end

  # delete an old one if its there
  ted_title&.delete if Windoo::SoftwareTitle.all_ids(cnx: ted_cnx).include? title

  new_title = Windoo::SoftwareTitle.create(
    id: title,
    name: display_name,
    publisher: publisher,
    appName: app_name,
    bundleId: app_bundle_id,
    currentVersion: Xolo::Server::Title::NEW_TITLE_CURRENT_VERSION,
    cnx: ted_cnx
  )

  progress "Title Editor: Creating SoftwareTitle '#{title}'", log: :info
  create_ted_title_requirements

  create_and_enable_stub_patch_in_ted(new_title)

  sleep 2

  # re-fetch the title from ted and enable it
  progress "Title Editor: Enabling SoftwareTitle '#{title}'", log: :info
  ted_title(refresh: true).enable

  # cache the new title object id
  self.ted_id_number = ted_title.softwareTitleId
end

#delete_ted_eavoid

This method returns an undefined value.

Delete the extension attribute from the title editor



359
360
361
362
# File 'lib/xolo/server/mixins/title_ted_access.rb', line 359

def delete_ted_ea
  progress "Title Editor: Deleting Extension Attribute (version_script) for title '#{title}'", log: :info
  ted_title.delete_extensionAttribute
end

#delete_title_from_tedInteger

Delete from the title editor

Returns:

  • (Integer)

    title editor id number



482
483
484
485
486
487
488
# File 'lib/xolo/server/mixins/title_ted_access.rb', line 482

def delete_title_from_ted
  progress "Title Editor: Deleting SoftwareTitle '#{title}'", log: :info

  ted_title&.delete if Windoo::SoftwareTitle.all_ids(cnx: ted_cnx).include? title
rescue Windoo::NoSuchItemError
  ted_id_number
end

#enable_ted_titlevoid

This method returns an undefined value.

Enable the title in the title editor when at least one patch is enabled

Re-enable the title in ted after updating any patches

TODO: Now that we are using stub patches, do we need the loop?



448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
# File 'lib/xolo/server/mixins/title_ted_access.rb', line 448

def enable_ted_title
  # Nothing to re-enabled unless we have at least one enabled patch
  return unless ted_title.patches.to_a.any?(&:enabled?)

  # re-enable the title itself, we should have at least one enabled version
  progress "Title Editor: (Re-)Enabling SoftwareTitle '#{title}'", log: :debug

  # loop until the enablement goes thru
  breaktime = Time.now + Xolo::Server::Constants::MAX_JAMF_WAIT_FOR_TITLE_EDITOR
  loop do
    raise Xolo::TimeoutError, "Title Editor: Timed out waiting for SoftwareTitle '#{title}' to enable" if Time.now > breaktime

    ted_title(refresh: true).enable
    break
  rescue Windoo::MissingDataError => e
    sleep 5
    log_debug "Title Editor: Looping up to #{Xolo::Server::Constants::MAX_JAMF_WAIT_FOR_TITLE_EDITOR} secs while re-enabling SoftwareTitle '#{title}': #{e}"

    # make sure all patches are enabled, even tho at least one should have been
    # enabled at the start of this method
    begin
      log_debug "Title Editor: Force-enablng all patches for title #{title}"
      ted_title.patches.each(&:enable)
    rescue
      nil
    end

    nil
  end
end

#reenable_all_ted_patchesvoid

This method returns an undefined value.

Re-enable all patches in the title editor



549
550
551
552
553
# File 'lib/xolo/server/mixins/title_ted_access.rb', line 549

def reenable_all_ted_patches
  # re-enable all patches, after any change, which might have disabled them
  progress "Title Editor: Re-enabling all patches for '#{title}'", log: :info
  version_objects.each { |vobj| vobj.enable_ted_patch }
end

#repair_ted_titlevoid

This method returns an undefined value.

repair this title in the title editor

  • display name

  • publisher

  • requirements, EA or App Data

  • stub version if needed

  • enabled



506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
# File 'lib/xolo/server/mixins/title_ted_access.rb', line 506

def repair_ted_title
  if subscribed?
    log_debug "Title Editor: SoftwareTitle '#{title}' is subscribed, skipping Title Editor repair"
    return
  end
  progress "Title Editor: Repairing SoftwareTitle '#{title}'", log: :info

  # TODO: version order??

  # loop through the attributes that are in the Title Editor
  Xolo::Server::Title::ATTRIBUTES.each do |attr, deets|
    ted_attribute = deets[:ted_attribute]
    next unless ted_attribute

    ted_val = ted_title.send ted_attribute
    real_val = send attr
    next if ted_val == real_val

    progress "Title Editor: Repairing title attribute '#{ted_attribute}': #{ted_val} -> #{real_val}", log: :info

    ted_title.send "#{ted_attribute}=", real_val
  end # Xolo::Server::Title::ATTRIBUTES.each

  # requirements
  create_ted_title_requirements

  # make sure there's at least one patch
  if ted_title.patches.empty?
    create_and_enable_stub_patch_in_ted(ted_title)
  else
    # repair all patches, because reparing the title might have changed the requirements
    progress "Title Editor: Re-enabling all patches for '#{title}'", log: :info
    version_objects.each do |vobj|
      vobj.repair_ted_patch
    end
  end

  ted_title.enable unless ted_title(refresh: true).enabled?
end

#requirement_changeSymbol

Are we changing any requirements, and if so, how?

Returns:

  • (Symbol)

    :app_to_ea, :ea_to_app, :update_app, :update_ea



280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
# File 'lib/xolo/server/mixins/title_ted_access.rb', line 280

def requirement_change
  # we have to change the version script, but are we just updating it,
  # or switching to it from app data?
  if changes_for_update[:version_script]

    # if we have no old value, we are switching to ea, from app data
    if changes_for_update[:version_script][:old].pix_empty?
      :app_to_ea

    # if we have no new value, we are switching from ea, to app data
    elsif changes_for_update[:version_script][:new].pix_empty?
      :ea_to_app

    # if we are here, we have both, so we are just updating the ea script
    else
      :update_ea
    end

  # if we are here, we aren't changing the ea at all, but we might be
  # updating the app data
  elsif changes_for_update[:app_name] || changes_for_update[:app_bundle_id]
    :update_app

    # and if none of that is true, we'll return nil
  end
end

#set_app_requirement(app_name, app_bundle_id) ⇒ String

Returns the progress/log message.

Returns:

  • (String)

    the progress/log message



409
410
411
412
413
414
415
416
417
418
419
420
421
422
# File 'lib/xolo/server/mixins/title_ted_access.rb', line 409

def set_app_requirement(app_name, app_bundle_id)
  # add criteria for the app name and bundle id.
  ted_title.requirements.add_criterion(
    name: 'Application Title',
    operator: 'is',
    value: app_name
  )

  ted_title.requirements.add_criterion(
    name: 'Application Bundle ID',
    operator: 'is',
    value: app_bundle_id
  )
end

#set_ea_requirement(ea_name) ⇒ String

Returns the progress/log message.

Returns:

  • (String)

    the progress/log message



397
398
399
400
401
402
403
404
405
# File 'lib/xolo/server/mixins/title_ted_access.rb', line 397

def set_ea_requirement(ea_name)
  # add criteria for the ea name
  ted_title.requirements.add_criterion(
    type: 'extensionAttribute',
    name: ea_name,
    operator: 'is not',
    value: Xolo::BLANK
  )
end

#set_ted_patch_component_criteria_after_update(app_name: nil, app_bundle_id: nil, ea_name: nil) ⇒ void

This method returns an undefined value.

update the patch compotent criteria for all versions to match changes in the title requirements



429
430
431
432
433
434
435
436
437
438
# File 'lib/xolo/server/mixins/title_ted_access.rb', line 429

def set_ted_patch_component_criteria_after_update(app_name: nil, app_bundle_id: nil, ea_name: nil)
  version_objects.each do |vers_obj|
    vers_obj.set_ted_patch_component_criteria(
      app_name: app_name,
      app_bundle_id: app_bundle_id,
      ea_name: ea_name
    )
    vers_obj.enable_ted_patch
  end
end

#set_ted_title_requirement(app_name: nil, app_bundle_id: nil, ea_name: nil) ⇒ void

This method returns an undefined value.

Set the requirements for a title in the Title Editor

If the title has an EA script, it is used as the requirement criterion (the EA should already be created in the Title Editor)

If the title has app_name and app_bundle_id, they are used as the requirement criteria

Parameters:

  • app_name (String) (defaults to: nil)

    the name of the app to use in app-based requirements, must be used with app_bundle_id, cannot be used with ea_name

  • app_bundle_id (String) (defaults to: nil)

    the bundle id of the app to use in app-based requirements must be used with app_name, cannot be used with ea_name

  • ea_name (String) (defaults to: nil)

    the name of the EA to use in EA-based requirements (the ted_ea_key) Cannot be used with app_name or app_bundle_id

Raises:



382
383
384
385
386
387
388
389
390
391
392
393
# File 'lib/xolo/server/mixins/title_ted_access.rb', line 382

def set_ted_title_requirement(app_name: nil, app_bundle_id: nil, ea_name: nil)
  raise Xolo::MissingDataError, 'Must provide either ea_name or app_name & app_bundle_id' unless (app_name && app_bundle_id) || ea_name

  type = ea_name ? 'Extension Attribute (version_script)' : 'App'

  progress "Title Editor: Setting #{type}-based Requirement for SoftwareTitle '#{title}'", log: :info

  # delete any already there
  ted_title.requirements.delete_all_criteria

  ea_name ? set_ea_requirement(ea_name) : set_app_requirement(app_name, app_bundle_id)
end

#ted_ea_keyString

In the TitleEditor, the version script is stored as an Extension Attribute - each title can only have one. and it needs a ‘key’, which is the name used to indicate the EA in various criteria, and is the EA name in Jamf Patch. The key is jamf_obj_name_pfx on the title so for title ‘foobar’, it is ‘xolo-foobar’ or ‘xolotest-foobar’ for test servers That value is also used as the display name

Returns:

  • (String)

    The key and display name of a version script stored in the title editor as the ExtAttr for this title



318
319
320
# File 'lib/xolo/server/mixins/title_ted_access.rb', line 318

def ted_ea_key
  @ted_ea_key ||= "#{jamf_obj_name_pfx_base}#{title}"
end

#ted_title(refresh: false) ⇒ Windoo::SoftwareTitle

Returns The Windoo::SoftwareTitle object that represents this title in the title editor.

Returns:

  • (Windoo::SoftwareTitle)

    The Windoo::SoftwareTitle object that represents this title in the title editor



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/xolo/server/mixins/title_ted_access.rb', line 46

def ted_title(refresh: false)
  @ted_title = nil if refresh
  return @ted_title if @ted_title

  @ted_title =
    if Windoo::SoftwareTitle.all_ids(cnx: ted_cnx).include? title
      Windoo::SoftwareTitle.fetch id: title, cnx: ted_cnx
    else
      return if deleting?

      create_title_in_ted
    end

  @ted_title
end

#ted_title_urlString

Returns the URL for the title in the Title Editor.

Returns:

  • (String)

    the URL for the title in the Title Editor



492
493
494
495
496
# File 'lib/xolo/server/mixins/title_ted_access.rb', line 492

def ted_title_url
  return unless managed?

  "https://#{Xolo::Server.config.ted_hostname}/softwaretitles/#{ted_id_number}"
end

#update_ted_ea(script) ⇒ void

This method returns an undefined value.

Update the EA in the Title Editor the only thing we update is the script



345
346
347
348
349
350
351
352
353
354
# File 'lib/xolo/server/mixins/title_ted_access.rb', line 345

def update_ted_ea(script)
  progress "Title Editor: Updating Extension Attribute from version_script for title '#{title}'", log: :info

  if ted_title.extensionAttribute
    ted_title.extensionAttribute.script = script
    @need_to_accept_jamf_patch_ea = true
  else
    create_ted_ea(script)
  end
end

#update_title_in_tedvoid

This method returns an undefined value.

Update title in the title editor

Parameters:

  • new_data (Hash)

    The new data sent from xadm



180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
# File 'lib/xolo/server/mixins/title_ted_access.rb', line 180

def update_title_in_ted
  if subscribed?
    log_debug "Title Editor: SoftwareTitle '#{title}' is subscribed, skipping Title Editor update"
    return
  end
  return unless changes_for_update

  unless any_ted_changes?
    progress "Title Editor: No changes to make for SoftwareTitle '#{title}'", log: :info
    return
  end

  progress "Title Editor: Updating SoftwareTitle '#{title}'", log: :info

  # loop through the attributes that are in the Title Editor
  Xolo::Server::Title::ATTRIBUTES.each do |attr, deets|
    ted_attribute = deets[:ted_attribute]
    next unless ted_attribute
    next unless changes_for_update&.key? attr

    new_val = changes_for_update[attr][:new]
    old_val = changes_for_update[attr][:old]

    progress "Title Editor: Updating title attribute '#{ted_attribute}': #{old_val} -> #{new_val}", log: :info

    ted_title.send "#{ted_attribute}=", new_val
  end # Xolo::Server::Title::ATTRIBUTES.each

  # This will also apply the changes to all patch component criteria
  apply_requirement_changes

  # re-enable all patches, after any change, which might have disabled them
  reenable_all_ted_patches

  # mucking with the patches often disables the title, make sure its enabled.
  enable_ted_title

  self.ted_id_number ||= ted_title.softwareTitleId
end