xolo-admin 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE.txt +177 -0
- data/README.md +5 -0
- data/bin/xadm +114 -0
- data/lib/xolo/admin/command_line.rb +432 -0
- data/lib/xolo/admin/configuration.rb +196 -0
- data/lib/xolo/admin/connection.rb +191 -0
- data/lib/xolo/admin/cookie_jar.rb +81 -0
- data/lib/xolo/admin/credentials.rb +212 -0
- data/lib/xolo/admin/highline_terminal.rb +81 -0
- data/lib/xolo/admin/interactive.rb +762 -0
- data/lib/xolo/admin/jamf_pro.rb +75 -0
- data/lib/xolo/admin/options.rb +1139 -0
- data/lib/xolo/admin/processing.rb +1329 -0
- data/lib/xolo/admin/progress_history.rb +117 -0
- data/lib/xolo/admin/title.rb +285 -0
- data/lib/xolo/admin/title_editor.rb +57 -0
- data/lib/xolo/admin/validate.rb +1032 -0
- data/lib/xolo/admin/version.rb +221 -0
- data/lib/xolo/admin.rb +139 -0
- data/lib/xolo-admin.rb +8 -0
- metadata +139 -0
|
@@ -0,0 +1,1139 @@
|
|
|
1
|
+
# Copyright 2025 Pixar
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the terms set forth in the LICENSE.txt file available at
|
|
4
|
+
# at the root of this project.
|
|
5
|
+
#
|
|
6
|
+
|
|
7
|
+
# frozen_string_literal: true
|
|
8
|
+
|
|
9
|
+
# we need these to be loaded before we load
|
|
10
|
+
require 'xolo/admin/title'
|
|
11
|
+
require 'xolo/admin/version'
|
|
12
|
+
|
|
13
|
+
module Xolo
|
|
14
|
+
|
|
15
|
+
module Admin
|
|
16
|
+
|
|
17
|
+
# A module for defining the CLI and Interactive options for xadm.
|
|
18
|
+
#
|
|
19
|
+
# The general structure of xadm commands is:
|
|
20
|
+
# xadm [global options] command [command options] [command arguments]
|
|
21
|
+
# in that order.
|
|
22
|
+
#
|
|
23
|
+
# The global options are things that affect the overall behavior of xadm,
|
|
24
|
+
# like --walkthru, --quiet, --json, and --debug.
|
|
25
|
+
#
|
|
26
|
+
# The command is the action to be taken, like 'add-title', 'edit-version',
|
|
27
|
+
# 'list-titles', etc.
|
|
28
|
+
#
|
|
29
|
+
# The command options are specific to the command, and are defined in the
|
|
30
|
+
# COMMANDS hash below.
|
|
31
|
+
#
|
|
32
|
+
# The command arguments are the things the command operates on, like the
|
|
33
|
+
# title name, or the title name and version.
|
|
34
|
+
#
|
|
35
|
+
module Options
|
|
36
|
+
|
|
37
|
+
# Constants
|
|
38
|
+
#########################
|
|
39
|
+
#########################
|
|
40
|
+
|
|
41
|
+
# These options affect the overall behavior of xadm. They must come
|
|
42
|
+
# before the command.
|
|
43
|
+
#
|
|
44
|
+
# NOTE: Optimist automatically provides --version -v and --help -h
|
|
45
|
+
GLOBAL_OPTIONS = {
|
|
46
|
+
walkthru: {
|
|
47
|
+
label: 'Run Interactively',
|
|
48
|
+
walkthru: false,
|
|
49
|
+
cli: :w,
|
|
50
|
+
desc: <<~ENDDESC
|
|
51
|
+
Run xadm in interactive mode when adding or editing titles or versions.
|
|
52
|
+
This causes xadm to present an interactive, menu-and-
|
|
53
|
+
prompt-driven interface. All command-options given on the
|
|
54
|
+
command line are ignored, and will be gathered
|
|
55
|
+
interactively.
|
|
56
|
+
The 'config' command is always interactive, even without --walkthru.
|
|
57
|
+
ENDDESC
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
auto_confirm: {
|
|
61
|
+
label: 'Auto Approve',
|
|
62
|
+
cli: :a,
|
|
63
|
+
walkthru: false,
|
|
64
|
+
desc: <<~ENDDESC
|
|
65
|
+
Do not ask for confirmation before making changes or using server-
|
|
66
|
+
admin commands.
|
|
67
|
+
This is mostly used for automating xadm.
|
|
68
|
+
Ignored if using --walkthru: if you're interactive you must confirm
|
|
69
|
+
your changes.
|
|
70
|
+
WARNING: Be careful that all values are correct.
|
|
71
|
+
ENDDESC
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
proxy_admin: {
|
|
75
|
+
label: 'Proxy Admin',
|
|
76
|
+
cli: :p,
|
|
77
|
+
walkthru: false,
|
|
78
|
+
type: :string,
|
|
79
|
+
validate: false,
|
|
80
|
+
desc: <<~ENDDESC
|
|
81
|
+
Used for automated workflows that connect to the xolo server using a
|
|
82
|
+
service account, not a user account. Most such automations have a way to
|
|
83
|
+
ascertain the identity of the user triggering the automation. They can use
|
|
84
|
+
that name here, and then it will be used on the server combined with the
|
|
85
|
+
actually authenticated service acct name for use in logging and status.
|
|
86
|
+
|
|
87
|
+
For example, if you have a CI/CD job that runs xadm commands, it will
|
|
88
|
+
connect to the xolo server using a service account such as 'xolo-cicd-runner'.
|
|
89
|
+
That job can get the name of the user triggering the job from an environment
|
|
90
|
+
variable, (or elsewhere) and pass that as the value of this option, like so:
|
|
91
|
+
|
|
92
|
+
xadm --proxy-admin $CICD_USER_NAME add-version my-title 1.2.3 [options...]
|
|
93
|
+
|
|
94
|
+
On the xolo server, the user will be recorded as
|
|
95
|
+
|
|
96
|
+
cicduser-via-xolo-cicd-runner
|
|
97
|
+
|
|
98
|
+
which will be used as the "added_by" value for the new version, and will show up
|
|
99
|
+
in the various logs.
|
|
100
|
+
ENDDESC
|
|
101
|
+
},
|
|
102
|
+
|
|
103
|
+
quiet: {
|
|
104
|
+
label: 'Quiet',
|
|
105
|
+
cli: :q,
|
|
106
|
+
walkthru: false,
|
|
107
|
+
desc: <<~ENDDESC
|
|
108
|
+
Run xadm in quiet mode
|
|
109
|
+
When used with add-, edit-, delete-, and release-
|
|
110
|
+
commands, nothing will be printed to standard output.
|
|
111
|
+
|
|
112
|
+
Ignored for other commands, the purpose of which is to print
|
|
113
|
+
something to standard output.
|
|
114
|
+
Also ignored if --debug is given
|
|
115
|
+
|
|
116
|
+
WARNING: For long-running processes, you may not see server errors!
|
|
117
|
+
ENDDESC
|
|
118
|
+
},
|
|
119
|
+
|
|
120
|
+
json: {
|
|
121
|
+
label: 'JSON',
|
|
122
|
+
cli: :j,
|
|
123
|
+
walkthru: false,
|
|
124
|
+
desc: <<~ENDDESC
|
|
125
|
+
For commands that output lists or info about titles and versions,
|
|
126
|
+
such as 'list-titles' or 'info <title> <version>',
|
|
127
|
+
return the data as raw JSON.
|
|
128
|
+
ENDDESC
|
|
129
|
+
},
|
|
130
|
+
|
|
131
|
+
debug: {
|
|
132
|
+
label: 'Debug',
|
|
133
|
+
cli: :d,
|
|
134
|
+
walkthru: false,
|
|
135
|
+
desc: <<~ENDDESC
|
|
136
|
+
Run xadm in debug mode
|
|
137
|
+
This causes more verbose output and full backtraces
|
|
138
|
+
to be printed on errors. Overrides --quiet
|
|
139
|
+
ENDDESC
|
|
140
|
+
}
|
|
141
|
+
}.freeze
|
|
142
|
+
|
|
143
|
+
# The xadm commands
|
|
144
|
+
#############################
|
|
145
|
+
|
|
146
|
+
# TODO: add commands for:
|
|
147
|
+
# - upload a manifest for a version
|
|
148
|
+
# - get the status of an MDM command given a uuid
|
|
149
|
+
# - get the code of a version script
|
|
150
|
+
# - get the code of an uninstall script
|
|
151
|
+
# - output the contents of a previous progress stream file, if it still exists
|
|
152
|
+
|
|
153
|
+
LIST_TITLES_CMD = 'list-titles'
|
|
154
|
+
ADD_TITLE_CMD = 'add-title'
|
|
155
|
+
EDIT_TITLE_CMD = 'edit-title'
|
|
156
|
+
DELETE_TITLE_CMD = 'delete-title'
|
|
157
|
+
FREEZE_TITLE_CMD = 'freeze'
|
|
158
|
+
THAW_TITLE_CMD = 'thaw'
|
|
159
|
+
LIST_FROZEN_CMD = 'list-frozen'
|
|
160
|
+
|
|
161
|
+
LIST_VERSIONS_CMD = 'list-versions'
|
|
162
|
+
ADD_VERSION_CMD = 'add-version'
|
|
163
|
+
EDIT_VERSION_CMD = 'edit-version'
|
|
164
|
+
RELEASE_VERSION_CMD = 'release'
|
|
165
|
+
DELETE_VERSION_CMD = 'delete-version'
|
|
166
|
+
DEPLOY_VERSION_CMD = 'deploy'
|
|
167
|
+
|
|
168
|
+
INFO_CMD = 'info' # info on a title or version
|
|
169
|
+
SEARCH_CMD = 'search' # search for titles
|
|
170
|
+
CHANGELOG_CMD = 'changelog' # show the changelog for a title
|
|
171
|
+
REPORT_CMD = 'report' # report on installations
|
|
172
|
+
REPAIR_CMD = 'repair' # run repair on titles or versions
|
|
173
|
+
CONFIG_CMD = 'config' # configure xadm
|
|
174
|
+
|
|
175
|
+
LIST_GROUPS_CMD = 'list-groups'
|
|
176
|
+
LIST_CATEGORIES_CMD = 'list-categories'
|
|
177
|
+
SAVE_CLIENT_CODE_CMD = 'save-client'
|
|
178
|
+
|
|
179
|
+
SERVER_STATUS_CMD = 'server-status'
|
|
180
|
+
HELP_CMD = 'help'
|
|
181
|
+
|
|
182
|
+
# server-admin commands
|
|
183
|
+
SERVER_CLEANUP_CMD = 'run-server-cleanup'
|
|
184
|
+
UPDATE_CLIENT_DATA_CMD = 'update-client-data'
|
|
185
|
+
ROTATE_SERVER_LOGS_CMD = 'rotate-server-logs'
|
|
186
|
+
SET_SERVER_LOG_LEVEL_CMD = 'set-server-log-level'
|
|
187
|
+
SHUTDOWN_SERVER_CMD = 'shutdown-server'
|
|
188
|
+
|
|
189
|
+
# various strings for the commands and opts
|
|
190
|
+
|
|
191
|
+
HELP_OPT = '--help'
|
|
192
|
+
|
|
193
|
+
DFT_CMD_TITLE_ARG_BANNER = " title: The unique name of a title in Xolo, e.g. 'google-chrome'"
|
|
194
|
+
DFT_CMD_VERSION_ARG_BANNER = " version: The version of the title you are working with. e.g. '12.34.5'"
|
|
195
|
+
|
|
196
|
+
TARGET_TITLE_PLACEHOLDER = Xolo::Admin::Title::TARGET_TITLE_PLACEHOLDER
|
|
197
|
+
TARGET_VERSION_PLACEHOLDER = 'TARGET_VERSION_PH'
|
|
198
|
+
|
|
199
|
+
PATCH_REPORT_OPTIONS = {
|
|
200
|
+
summary: {
|
|
201
|
+
label: 'Summary Only',
|
|
202
|
+
cli: :S,
|
|
203
|
+
type: :boolean,
|
|
204
|
+
validate: :validate_boolean,
|
|
205
|
+
default: false,
|
|
206
|
+
desc: <<~ENDDESC
|
|
207
|
+
Show a summary only: how many installs of each version, and how many in total.
|
|
208
|
+
ENDDESC
|
|
209
|
+
},
|
|
210
|
+
|
|
211
|
+
os: {
|
|
212
|
+
label: 'Show Operating System Version',
|
|
213
|
+
cli: :o,
|
|
214
|
+
type: :boolean,
|
|
215
|
+
validate: :validate_boolean,
|
|
216
|
+
default: false,
|
|
217
|
+
desc: <<~ENDDESC
|
|
218
|
+
Report the Operating System Version of the computer.
|
|
219
|
+
ENDDESC
|
|
220
|
+
},
|
|
221
|
+
|
|
222
|
+
building: {
|
|
223
|
+
label: 'Show Building',
|
|
224
|
+
cli: :b,
|
|
225
|
+
type: :boolean,
|
|
226
|
+
validate: :validate_boolean,
|
|
227
|
+
default: false,
|
|
228
|
+
desc: <<~ENDDESC
|
|
229
|
+
Report the Building of the computer.
|
|
230
|
+
ENDDESC
|
|
231
|
+
},
|
|
232
|
+
|
|
233
|
+
dept: {
|
|
234
|
+
label: 'Show Department',
|
|
235
|
+
cli: :d,
|
|
236
|
+
type: :boolean,
|
|
237
|
+
validate: :validate_boolean,
|
|
238
|
+
default: false,
|
|
239
|
+
desc: <<~ENDDESC
|
|
240
|
+
Report the Department of the computer.
|
|
241
|
+
ENDDESC
|
|
242
|
+
},
|
|
243
|
+
|
|
244
|
+
site: {
|
|
245
|
+
label: 'Show Site',
|
|
246
|
+
cli: :s,
|
|
247
|
+
type: :boolean,
|
|
248
|
+
validate: :validate_boolean,
|
|
249
|
+
default: false,
|
|
250
|
+
desc: <<~ENDDESC
|
|
251
|
+
Report the Site of the computer.
|
|
252
|
+
ENDDESC
|
|
253
|
+
},
|
|
254
|
+
|
|
255
|
+
frozen: {
|
|
256
|
+
label: 'Show Frozen Status',
|
|
257
|
+
cli: :f,
|
|
258
|
+
type: :boolean,
|
|
259
|
+
validate: :validate_boolean,
|
|
260
|
+
default: false,
|
|
261
|
+
desc: <<~ENDDESC
|
|
262
|
+
Report whether or not the computer is frozen for the title.
|
|
263
|
+
ENDDESC
|
|
264
|
+
},
|
|
265
|
+
|
|
266
|
+
id: {
|
|
267
|
+
label: 'Show Jamf ID',
|
|
268
|
+
cli: :i,
|
|
269
|
+
type: :boolean,
|
|
270
|
+
validate: :validate_boolean,
|
|
271
|
+
default: false,
|
|
272
|
+
desc: <<~ENDDESC
|
|
273
|
+
Report the Jamf ID of the computer.
|
|
274
|
+
ENDDESC
|
|
275
|
+
}
|
|
276
|
+
}.freeze
|
|
277
|
+
|
|
278
|
+
FREEZE_THAW_OPTIONS = {
|
|
279
|
+
users: {
|
|
280
|
+
label: 'Targets are usernames not computers',
|
|
281
|
+
cli: :u,
|
|
282
|
+
type: :boolean,
|
|
283
|
+
validate: :validate_boolean,
|
|
284
|
+
default: false,
|
|
285
|
+
desc: <<~ENDDESC
|
|
286
|
+
The targets of the command are usernames, not computers. All computers assigned to the user will be affected.
|
|
287
|
+
Default is false, targets are computer names.
|
|
288
|
+
ENDDESC
|
|
289
|
+
}
|
|
290
|
+
}.freeze
|
|
291
|
+
|
|
292
|
+
DEPLOY_VERSION_OPTIONS = {
|
|
293
|
+
groups: {
|
|
294
|
+
label: 'Computer group whose computers will be targeted',
|
|
295
|
+
cli: :g,
|
|
296
|
+
validate: :validate_deploy_groups,
|
|
297
|
+
type: :string,
|
|
298
|
+
multi: true,
|
|
299
|
+
readline_prompt: 'Group Name',
|
|
300
|
+
readline: :jamf_computer_group_names,
|
|
301
|
+
desc: <<~ENDDESC
|
|
302
|
+
One or more Jamf Computer Group names or ids whose members will receive the MDM deployment.
|
|
303
|
+
|
|
304
|
+
When using the --groups CLI option, you can specify more than one group by using the option more than once, or by providing a single option value with the groups separated by commas.
|
|
305
|
+
ENDDESC
|
|
306
|
+
}
|
|
307
|
+
}.freeze
|
|
308
|
+
|
|
309
|
+
REPAIR_OPTIONS = {
|
|
310
|
+
versions: {
|
|
311
|
+
label: 'Repair all versions',
|
|
312
|
+
cli: :v,
|
|
313
|
+
type: :boolean,
|
|
314
|
+
validate: :validate_boolean,
|
|
315
|
+
default: false,
|
|
316
|
+
desc: <<~ENDDESC
|
|
317
|
+
When repairing a title, also repair all of its versions.
|
|
318
|
+
ENDDESC
|
|
319
|
+
}
|
|
320
|
+
}.freeze
|
|
321
|
+
|
|
322
|
+
SERVER_STATUS_OPTIONS = {
|
|
323
|
+
extended: {
|
|
324
|
+
label: 'Show Extended Status',
|
|
325
|
+
cli: :e,
|
|
326
|
+
type: :boolean,
|
|
327
|
+
validate: :validate_boolean,
|
|
328
|
+
default: false,
|
|
329
|
+
desc: <<~ENDDESC
|
|
330
|
+
Include more status information about the server, including the current
|
|
331
|
+
GEM_PATH, $LOAD_PATH, current object locks, and existing threads.
|
|
332
|
+
ENDDESC
|
|
333
|
+
}
|
|
334
|
+
}.freeze
|
|
335
|
+
|
|
336
|
+
SEARCH_TITLES_OPTIONS = {
|
|
337
|
+
summary: {
|
|
338
|
+
label: 'Show less detail, one line per matching title',
|
|
339
|
+
cli: :s,
|
|
340
|
+
type: :boolean,
|
|
341
|
+
validate: :validate_boolean,
|
|
342
|
+
default: false,
|
|
343
|
+
desc: <<~ENDDESC
|
|
344
|
+
Show only one line per matching title, with just the title name, display name,
|
|
345
|
+
publisher, contact email, and versions.
|
|
346
|
+
ENDDESC
|
|
347
|
+
}
|
|
348
|
+
}.freeze
|
|
349
|
+
|
|
350
|
+
# The commands that xadm understands
|
|
351
|
+
# For each command there is a hash of details, with these possible keys:
|
|
352
|
+
#
|
|
353
|
+
# - desc: [String] a one-line description of the command
|
|
354
|
+
#
|
|
355
|
+
# - display: [String] The command with any arguments, but no options.
|
|
356
|
+
# If no more specific usage: is defined, this is used in the help output
|
|
357
|
+
# to build the 'usage' line: "#{executable_file} #{cmd_display} [options]"
|
|
358
|
+
#
|
|
359
|
+
# - usage: [String] If the usage line generated with the display: value is inaccurate,
|
|
360
|
+
# you can define one explicitly here to override it.
|
|
361
|
+
#
|
|
362
|
+
# - arg_banner: [String] a line of help text defining the arguments taken by the command.
|
|
363
|
+
# Defaults to Xolo::Admin::Options::DFT_CMD_TITLE_ARG_BANNER
|
|
364
|
+
# Will automatically append Xolo::Admin::Options::DFT_CMD_VERSION_ARG_BANNER if
|
|
365
|
+
# the command is a version command. If ths command takes no args, set this to :none
|
|
366
|
+
#
|
|
367
|
+
# - target: [Symbol] Most commands operate on either titles, versions, or both. Set this
|
|
368
|
+
# to one of :title, :version, or :title_or_version to let xadm apply revelant state.
|
|
369
|
+
# Leave unset if the command doesn't take anything
|
|
370
|
+
#
|
|
371
|
+
# - confirmation: [Boolean] does this action require confirmation? (Are you sure?)
|
|
372
|
+
# Confirmation can be overriden with the --auto-confirm global opt, as is needed
|
|
373
|
+
# for using xadm in an automated workflow
|
|
374
|
+
#
|
|
375
|
+
# - opts: [Hash] The keys and details about all the options that can be given to this
|
|
376
|
+
# command. It is usually a constant from some other part of Xolo::Admin.
|
|
377
|
+
# See {Xolo::Core::BaseClasses::Title::ATTRIBUTES} for info about the contents
|
|
378
|
+
# of this Hash. If the command takes no options, set this to an empty hash '{}'
|
|
379
|
+
#
|
|
380
|
+
# - walkthru_header: A string displayed above the main walkthru menu describing what
|
|
381
|
+
# is happening. E.g. 'Editing Title foobar'.
|
|
382
|
+
# Use TARGET_TITLE_PLACEHOLDER and TARGET_VERSION_PLACEHOLDER as needed to sub in the
|
|
383
|
+
# names of the targets.
|
|
384
|
+
#
|
|
385
|
+
# - no_login: [Boolean] By default, xadm will connect to the xolo server. If that isn't
|
|
386
|
+
# needed for this command, set this to true.
|
|
387
|
+
#
|
|
388
|
+
# - process_method: [Symbol] The name of a method defined in Xolo::Admin::Processing.
|
|
389
|
+
# This method will be called to do the actual work of the command, after processing all
|
|
390
|
+
# the arguments and options.
|
|
391
|
+
#
|
|
392
|
+
# - streamed_response: [Boolean] Used for long-running server processes, like delete_title
|
|
393
|
+
# or delete_version. When true, we don't expect a final JSON response from the server, but
|
|
394
|
+
# instead a link to a stream of status messages, which we just print out as they arrive.
|
|
395
|
+
#
|
|
396
|
+
###### Arguments vs options:
|
|
397
|
+
#
|
|
398
|
+
# We're using a more formal definition of these terms here.
|
|
399
|
+
#
|
|
400
|
+
# An argument is a value taken by a command - the thing the command will
|
|
401
|
+
# operate upon. This is usually a title, or a title and a version.
|
|
402
|
+
#
|
|
403
|
+
# An option is something that defines or modifies what the command will do
|
|
404
|
+
# with the argument(s). Options always begin with '-' or '--'
|
|
405
|
+
#
|
|
406
|
+
COMMANDS = {
|
|
407
|
+
|
|
408
|
+
LIST_TITLES_CMD => {
|
|
409
|
+
desc: 'List all software titles.',
|
|
410
|
+
display: LIST_TITLES_CMD,
|
|
411
|
+
opts: {},
|
|
412
|
+
arg_banner: :none,
|
|
413
|
+
process_method: :list_titles,
|
|
414
|
+
target: :none
|
|
415
|
+
},
|
|
416
|
+
|
|
417
|
+
ADD_TITLE_CMD => {
|
|
418
|
+
desc: 'Add a new software title',
|
|
419
|
+
display: "#{ADD_TITLE_CMD} title",
|
|
420
|
+
opts: Xolo::Admin::Title.cli_opts,
|
|
421
|
+
walkthru_header: "Adding Xolo Title '#{TARGET_TITLE_PLACEHOLDER}'",
|
|
422
|
+
target: :title,
|
|
423
|
+
process_method: :add_title,
|
|
424
|
+
streamed_response: true,
|
|
425
|
+
confirmation: true
|
|
426
|
+
},
|
|
427
|
+
|
|
428
|
+
EDIT_TITLE_CMD => {
|
|
429
|
+
desc: 'Edit an exising software title',
|
|
430
|
+
display: "#{EDIT_TITLE_CMD} title",
|
|
431
|
+
opts: Xolo::Admin::Title.cli_opts,
|
|
432
|
+
walkthru_header: "Editing Xolo Title '#{TARGET_TITLE_PLACEHOLDER}'",
|
|
433
|
+
process_method: :edit_title,
|
|
434
|
+
target: :title,
|
|
435
|
+
streamed_response: true,
|
|
436
|
+
confirmation: true
|
|
437
|
+
},
|
|
438
|
+
|
|
439
|
+
DELETE_TITLE_CMD => {
|
|
440
|
+
desc: 'Delete a software title, and all of its versions',
|
|
441
|
+
display: "#{DELETE_TITLE_CMD} title",
|
|
442
|
+
opts: {},
|
|
443
|
+
process_method: :delete_title,
|
|
444
|
+
target: :title,
|
|
445
|
+
streamed_response: true,
|
|
446
|
+
confirmation: true
|
|
447
|
+
},
|
|
448
|
+
|
|
449
|
+
FREEZE_TITLE_CMD => {
|
|
450
|
+
desc: 'Prevent computers from updating the currently installed version of a title.',
|
|
451
|
+
long_desc: <<~ENDLONG,
|
|
452
|
+
The target computers are added to a static group that is excluded from
|
|
453
|
+
all policies and patch policies related to this title and its versions.
|
|
454
|
+
If a computer doesn't have any version of the title, this will prevent
|
|
455
|
+
it from being installed via xolo (it will be 'frozen' in that state).
|
|
456
|
+
ENDLONG
|
|
457
|
+
display: "#{FREEZE_TITLE_CMD} title [--users] target [target ...] ",
|
|
458
|
+
opts: FREEZE_THAW_OPTIONS,
|
|
459
|
+
process_method: :freeze,
|
|
460
|
+
target: :title,
|
|
461
|
+
confirmation: true
|
|
462
|
+
},
|
|
463
|
+
|
|
464
|
+
THAW_TITLE_CMD => {
|
|
465
|
+
desc: 'Un-freeze computers, allowing them to resume updates of a title.',
|
|
466
|
+
ong_desc: <<~ENDLONG,
|
|
467
|
+
The target computers are removed from the static group that is excluded from
|
|
468
|
+
all policies and patch policies related to this title and its versions.
|
|
469
|
+
This will allow installation and updates to resume.
|
|
470
|
+
ENDLONG
|
|
471
|
+
display: "#{THAW_TITLE_CMD} title [--users] target [target ...]",
|
|
472
|
+
opts: FREEZE_THAW_OPTIONS,
|
|
473
|
+
process_method: :thaw,
|
|
474
|
+
target: :title,
|
|
475
|
+
confirmation: true
|
|
476
|
+
},
|
|
477
|
+
|
|
478
|
+
LIST_FROZEN_CMD => {
|
|
479
|
+
desc: 'List all computers that are frozen for a title.',
|
|
480
|
+
display: "#{LIST_FROZEN_CMD} title",
|
|
481
|
+
opts: {},
|
|
482
|
+
target: :title,
|
|
483
|
+
process_method: :list_frozen
|
|
484
|
+
},
|
|
485
|
+
|
|
486
|
+
LIST_VERSIONS_CMD => {
|
|
487
|
+
desc: 'List all versions of a title.',
|
|
488
|
+
display: "#{LIST_VERSIONS_CMD} title",
|
|
489
|
+
opts: {},
|
|
490
|
+
target: :title,
|
|
491
|
+
process_method: :list_versions
|
|
492
|
+
},
|
|
493
|
+
|
|
494
|
+
ADD_VERSION_CMD => {
|
|
495
|
+
desc: 'Add a new version to a title, making it available for piloting',
|
|
496
|
+
display: "#{ADD_VERSION_CMD} title version",
|
|
497
|
+
long_desc: <<~ENDLONG,
|
|
498
|
+
The version will be automatically installed or updated on any computers
|
|
499
|
+
in the 'pilot-groups' defined for the version. To manually install it
|
|
500
|
+
on other computers, you must use 'xolo install <title> <version>'.
|
|
501
|
+
ENDLONG
|
|
502
|
+
opts: Xolo::Admin::Version.cli_opts,
|
|
503
|
+
walkthru_header: "Adding Version '#{TARGET_VERSION_PLACEHOLDER}' to Xolo Title '#{TARGET_TITLE_PLACEHOLDER}'",
|
|
504
|
+
process_method: :add_version,
|
|
505
|
+
target: :version,
|
|
506
|
+
streamed_response: true,
|
|
507
|
+
confirmation: true
|
|
508
|
+
},
|
|
509
|
+
|
|
510
|
+
EDIT_VERSION_CMD => {
|
|
511
|
+
desc: 'Edit a version of a title',
|
|
512
|
+
display: "#{EDIT_VERSION_CMD} title version",
|
|
513
|
+
opts: Xolo::Admin::Version.cli_opts,
|
|
514
|
+
walkthru_header: "Editing Version '#{TARGET_VERSION_PLACEHOLDER}' of Xolo Title '#{TARGET_TITLE_PLACEHOLDER}'",
|
|
515
|
+
target: :version,
|
|
516
|
+
process_method: :edit_version,
|
|
517
|
+
streamed_response: true,
|
|
518
|
+
confirmation: true
|
|
519
|
+
},
|
|
520
|
+
|
|
521
|
+
RELEASE_VERSION_CMD => {
|
|
522
|
+
desc: "Take a version out of pilot and make it 'live'.",
|
|
523
|
+
long_desc: <<~ENDLONG,
|
|
524
|
+
Once released, the version will be updated on all computers
|
|
525
|
+
where it is installed. It will also be the version installed
|
|
526
|
+
manually on a computer when running 'xolo install <title>'.
|
|
527
|
+
ENDLONG
|
|
528
|
+
display: "#{RELEASE_VERSION_CMD} title version",
|
|
529
|
+
opts: {},
|
|
530
|
+
target: :version,
|
|
531
|
+
process_method: :release_version,
|
|
532
|
+
streamed_response: true,
|
|
533
|
+
confirmation: true
|
|
534
|
+
},
|
|
535
|
+
|
|
536
|
+
DELETE_VERSION_CMD => {
|
|
537
|
+
desc: 'Delete a version from a title.',
|
|
538
|
+
display: "#{DELETE_VERSION_CMD} title version",
|
|
539
|
+
opts: {},
|
|
540
|
+
target: :version,
|
|
541
|
+
process_method: :delete_version,
|
|
542
|
+
streamed_response: true,
|
|
543
|
+
confirmation: true
|
|
544
|
+
},
|
|
545
|
+
|
|
546
|
+
# TODO: allow uploading of manifests for xolo versions, to be used
|
|
547
|
+
# instead of the one generated by the server.
|
|
548
|
+
DEPLOY_VERSION_CMD => {
|
|
549
|
+
desc: 'Use MDM to install a version on one or more computers or computer groups.',
|
|
550
|
+
long_desc: <<~ENDLONG,
|
|
551
|
+
An MDM 'InstallEnterpriseApplication' command will be sent to the target computers to
|
|
552
|
+
install the version. If the version is already installed, it will be updated immediately.
|
|
553
|
+
Computers in any excluded-groups for the target will be removed from the list of targets
|
|
554
|
+
before the MDM command is sent.
|
|
555
|
+
|
|
556
|
+
Computers can be specified by name, serial number, or Jamf ID. Groups can be specified by
|
|
557
|
+
name or ID.
|
|
558
|
+
|
|
559
|
+
NOTE: Any automated installs (via Pilot or Release groups) will happen eventually anyway.
|
|
560
|
+
All Macs with the title already installed will also get new versions automatically.
|
|
561
|
+
Use of this command is only needed if you want to install a version manually and immediately
|
|
562
|
+
without connecting to the target computers.
|
|
563
|
+
|
|
564
|
+
The package for the version must be a signed 'Distribution Package', like those built with
|
|
565
|
+
'productbuild', not a 'Component Package', as is generated by 'pkgbuild'.
|
|
566
|
+
When you upload the .pkg to Xolo, it will automatically get a basic manifest needed for
|
|
567
|
+
the MDM command.
|
|
568
|
+
ENDLONG
|
|
569
|
+
display: "#{DEPLOY_VERSION_CMD} title version [computer ...]",
|
|
570
|
+
opts: DEPLOY_VERSION_OPTIONS,
|
|
571
|
+
target: :version,
|
|
572
|
+
process_method: :deploy_version,
|
|
573
|
+
confirmation: true
|
|
574
|
+
},
|
|
575
|
+
|
|
576
|
+
SEARCH_CMD => {
|
|
577
|
+
desc: 'Search for titles.',
|
|
578
|
+
long_desc: <<~ENDLONG,
|
|
579
|
+
Matches text in title, display name, publisher, app name, bundle ID, or description. Displays all those values, plus current versions, for each matching title.
|
|
580
|
+
ENDLONG
|
|
581
|
+
display: "#{SEARCH_CMD} title",
|
|
582
|
+
opts: SEARCH_TITLES_OPTIONS,
|
|
583
|
+
target: :title,
|
|
584
|
+
process_method: :search_titles
|
|
585
|
+
},
|
|
586
|
+
|
|
587
|
+
INFO_CMD => {
|
|
588
|
+
desc: 'Show details about a title, or a version of a title',
|
|
589
|
+
display: "#{INFO_CMD} title [version]",
|
|
590
|
+
opts: {},
|
|
591
|
+
target: :title_or_version,
|
|
592
|
+
process_method: :show_info
|
|
593
|
+
},
|
|
594
|
+
|
|
595
|
+
REPORT_CMD => {
|
|
596
|
+
desc: 'Show a patch-report for a title, or a version of a title',
|
|
597
|
+
long_desc: <<~ENDDESC,
|
|
598
|
+
Patch reports list which computers have a title, or a version of the title, installed.
|
|
599
|
+
They always show the computer name, username and last contact date. If reporting all
|
|
600
|
+
versions, the version on each computer will also be listed.
|
|
601
|
+
|
|
602
|
+
Commandline options can be used to add more data to the report, such as operating system,
|
|
603
|
+
department, site, and so on.
|
|
604
|
+
|
|
605
|
+
To see machines with an unknown version of a title, use '#{Xolo::UNKNOWN}' as the version.
|
|
606
|
+
|
|
607
|
+
NOTE: When using --json, all options are included in the data.
|
|
608
|
+
ENDDESC
|
|
609
|
+
display: "#{REPORT_CMD} title [version]",
|
|
610
|
+
opts: PATCH_REPORT_OPTIONS,
|
|
611
|
+
target: :title_or_version,
|
|
612
|
+
process_method: :patch_report
|
|
613
|
+
},
|
|
614
|
+
|
|
615
|
+
REPAIR_CMD => {
|
|
616
|
+
desc: 'Ensure all Title Editor and Jamf Objects exist and are correctly configured',
|
|
617
|
+
long_desc: <<~ENDDESC,
|
|
618
|
+
For each title and version in Xolo, there are many objects in the Title Editor and Jamf Pro,
|
|
619
|
+
including patch definitions, criteria, policies, patch policies, computer groups, extension attributes and so on.
|
|
620
|
+
|
|
621
|
+
Normally these are created, updated, and deleted as needed by the Xolo server. However,
|
|
622
|
+
sometimes things can get out-of-whack.
|
|
623
|
+
|
|
624
|
+
This process will ensure the necessary Title Editor and Jamf Pro objects exist and have the
|
|
625
|
+
correct settings for the given title or version.
|
|
626
|
+
|
|
627
|
+
When specifying only a title, just the objects related to the title are repaired, not its versions.
|
|
628
|
+
If you want to repair all the versions as well, use the --versions option.
|
|
629
|
+
|
|
630
|
+
When specifying a title and a version, only that version is repaired.
|
|
631
|
+
ENDDESC
|
|
632
|
+
display: "#{REPAIR_CMD} title [version]",
|
|
633
|
+
opts: REPAIR_OPTIONS,
|
|
634
|
+
target: :title_or_version,
|
|
635
|
+
process_method: :repair,
|
|
636
|
+
confirmation: true
|
|
637
|
+
},
|
|
638
|
+
|
|
639
|
+
CHANGELOG_CMD => {
|
|
640
|
+
desc: 'Show the changelog for a title',
|
|
641
|
+
long_desc: <<~ENDDESC,
|
|
642
|
+
The changelog is a list of all the changes made to the title and its versions.
|
|
643
|
+
ENDDESC
|
|
644
|
+
display: "#{CHANGELOG_CMD} title",
|
|
645
|
+
opts: {},
|
|
646
|
+
target: :title,
|
|
647
|
+
process_method: :show_changelog
|
|
648
|
+
},
|
|
649
|
+
|
|
650
|
+
CONFIG_CMD => {
|
|
651
|
+
desc: 'Configure xadm. Always interactive, implies --walkthru',
|
|
652
|
+
long_desc: <<~ENDLONG,
|
|
653
|
+
This will display and allow you to set the configuration for xadm.
|
|
654
|
+
The command is always interactive, as if you provided --walkthru.
|
|
655
|
+
Values you set will be saved in the xadm config file,
|
|
656
|
+
located at ~/Library/Preferences/com.pixar.xolo.admin.config.yaml
|
|
657
|
+
Your password will be stored in your login keychain.
|
|
658
|
+
|
|
659
|
+
The configuration values are:
|
|
660
|
+
|
|
661
|
+
#{Xolo::Admin::Configuration.help_desc_text}
|
|
662
|
+
|
|
663
|
+
ENDLONG
|
|
664
|
+
display: CONFIG_CMD,
|
|
665
|
+
usage: "#{Xolo::Admin::EXECUTABLE_FILENAME} #{CONFIG_CMD}",
|
|
666
|
+
opts: Xolo::Admin::Configuration.cli_opts,
|
|
667
|
+
walkthru_header: 'Editing xadm configuration',
|
|
668
|
+
no_login: true,
|
|
669
|
+
arg_banner: :none,
|
|
670
|
+
process_method: :update_config
|
|
671
|
+
},
|
|
672
|
+
|
|
673
|
+
LIST_GROUPS_CMD => {
|
|
674
|
+
desc: 'List all computer groups in Jamf pro',
|
|
675
|
+
display: LIST_GROUPS_CMD,
|
|
676
|
+
usage: "#{Xolo::Admin::EXECUTABLE_FILENAME} [global-options] #{LIST_GROUPS_CMD}",
|
|
677
|
+
opts: {},
|
|
678
|
+
arg_banner: :none,
|
|
679
|
+
process_method: :list_groups
|
|
680
|
+
},
|
|
681
|
+
|
|
682
|
+
LIST_CATEGORIES_CMD => {
|
|
683
|
+
desc: 'List all categories in Jamf pro',
|
|
684
|
+
display: LIST_CATEGORIES_CMD,
|
|
685
|
+
usage: "#{Xolo::Admin::EXECUTABLE_FILENAME} [global-options] #{LIST_CATEGORIES_CMD}",
|
|
686
|
+
opts: {},
|
|
687
|
+
arg_banner: :none,
|
|
688
|
+
process_method: :list_categories
|
|
689
|
+
},
|
|
690
|
+
|
|
691
|
+
SAVE_CLIENT_CODE_CMD => {
|
|
692
|
+
desc: 'Save the xolo client tool to a directory for packaging and deployment.',
|
|
693
|
+
long_desc: <<~ENDLONG,
|
|
694
|
+
Saves the 'xolo' client tool to the specified directory. If no
|
|
695
|
+
directory is given, saves to /tmp/. The version saved is the same
|
|
696
|
+
version as the xadm tool you are running.
|
|
697
|
+
|
|
698
|
+
Once saved, you can package and deploy the client tool to your
|
|
699
|
+
managed Macs in whatever way is appropriate for your environment.
|
|
700
|
+
|
|
701
|
+
'xolo' is a command-line tool for installing and otherwise working
|
|
702
|
+
with xolo-managed software on managed Macs. It is a single-file zsh script.
|
|
703
|
+
Fundamentally, it is a wrapper around the 'jamf policy' command, but it
|
|
704
|
+
also provides additional functionality.
|
|
705
|
+
See 'xolo help' for details.
|
|
706
|
+
ENDLONG
|
|
707
|
+
display: SAVE_CLIENT_CODE_CMD,
|
|
708
|
+
usage: "#{Xolo::Admin::EXECUTABLE_FILENAME} #{SAVE_CLIENT_CODE_CMD} [/path/to/dir]",
|
|
709
|
+
opts: {},
|
|
710
|
+
arg_banner: :none,
|
|
711
|
+
process_method: :save_client_code
|
|
712
|
+
},
|
|
713
|
+
|
|
714
|
+
HELP_CMD => {
|
|
715
|
+
desc: 'Get help for a specific command',
|
|
716
|
+
display: 'help command',
|
|
717
|
+
opts: {},
|
|
718
|
+
no_login: true
|
|
719
|
+
},
|
|
720
|
+
|
|
721
|
+
SERVER_STATUS_CMD => {
|
|
722
|
+
desc: '[Server Admins Only] Show status of Xolo server.',
|
|
723
|
+
long_desc: <<~ENDLONG,
|
|
724
|
+
Requires server-admin privileges.
|
|
725
|
+
Displays the current status of the server, including uptime, log level,
|
|
726
|
+
versions of various libraries, configuration, more.
|
|
727
|
+
ENDLONG
|
|
728
|
+
display: SERVER_STATUS_CMD,
|
|
729
|
+
opts: SERVER_STATUS_OPTIONS,
|
|
730
|
+
arg_banner: :none,
|
|
731
|
+
process_method: :server_status
|
|
732
|
+
},
|
|
733
|
+
|
|
734
|
+
SERVER_CLEANUP_CMD => {
|
|
735
|
+
desc: "[Server Admins Only] Run the server's cleanup process now.",
|
|
736
|
+
long_desc: <<~ENDLONG,
|
|
737
|
+
Requires server-admin privileges.
|
|
738
|
+
Once a version of a title is released, the preveiously released
|
|
739
|
+
version is marked as 'deprecated', and any older unreleased versions
|
|
740
|
+
are marked as 'skipped'. A nightly task will then delete all skipped
|
|
741
|
+
versions from xolo, as well as deprecated versions that have been than
|
|
742
|
+
deprecated more than some number of days, as configured configured on
|
|
743
|
+
the server. Running this command will do that cleanup now.
|
|
744
|
+
ENDLONG
|
|
745
|
+
display: SERVER_CLEANUP_CMD,
|
|
746
|
+
opts: {},
|
|
747
|
+
arg_banner: :none,
|
|
748
|
+
process_method: :server_cleanup,
|
|
749
|
+
confirmation: true
|
|
750
|
+
},
|
|
751
|
+
|
|
752
|
+
UPDATE_CLIENT_DATA_CMD => {
|
|
753
|
+
desc: '[Server Admins Only] Make the server update the client-data package now.',
|
|
754
|
+
long_desc: <<~ENDLONG,
|
|
755
|
+
Requires server-admin privileges.
|
|
756
|
+
Every time a change is made to a title or version, the server updates
|
|
757
|
+
a JSON file with the current state of all titles and versions. This
|
|
758
|
+
file is then packaged and deployed to all managed clients. Running
|
|
759
|
+
this command will force the server to update that file now.
|
|
760
|
+
ENDLONG
|
|
761
|
+
display: UPDATE_CLIENT_DATA_CMD,
|
|
762
|
+
opts: {},
|
|
763
|
+
arg_banner: :none,
|
|
764
|
+
process_method: :update_client_data,
|
|
765
|
+
confirmation: true
|
|
766
|
+
},
|
|
767
|
+
|
|
768
|
+
ROTATE_SERVER_LOGS_CMD => {
|
|
769
|
+
desc: '[Server Admins Only] Rotate the logs on the server now.',
|
|
770
|
+
long_desc: <<~ENDLONG,
|
|
771
|
+
Requires server-admin privileges.
|
|
772
|
+
Server log rotation is normally done nightly. Running this command
|
|
773
|
+
will rotate the logs now.
|
|
774
|
+
ENDLONG
|
|
775
|
+
display: ROTATE_SERVER_LOGS_CMD,
|
|
776
|
+
opts: {},
|
|
777
|
+
arg_banner: :none,
|
|
778
|
+
process_method: :rotate_server_logs,
|
|
779
|
+
confirmation: true
|
|
780
|
+
},
|
|
781
|
+
|
|
782
|
+
SET_SERVER_LOG_LEVEL_CMD => {
|
|
783
|
+
desc: '[Server Admins Only] Set the log level of the server logger.',
|
|
784
|
+
long_desc: <<~ENDLONG,
|
|
785
|
+
Requires server-admin privileges.
|
|
786
|
+
Sets the log level of the server logger to one of 'debug', 'info',
|
|
787
|
+
'warn', 'error', or 'fatal'. This will affect the amount of output
|
|
788
|
+
written to the server log file.
|
|
789
|
+
ENDLONG
|
|
790
|
+
display: SET_SERVER_LOG_LEVEL_CMD,
|
|
791
|
+
usage: "#{Xolo::Admin::EXECUTABLE_FILENAME} #{SET_SERVER_LOG_LEVEL_CMD} level [options]",
|
|
792
|
+
opts: {},
|
|
793
|
+
arg_banner: ' level: The log level to set, one of "debug", "info", "warn", "error", "fatal"',
|
|
794
|
+
process_method: :set_server_log_level,
|
|
795
|
+
confirmation: true
|
|
796
|
+
},
|
|
797
|
+
|
|
798
|
+
SHUTDOWN_SERVER_CMD => {
|
|
799
|
+
desc: '[Server Admins Only] Shutdown or restart the server gracefully.',
|
|
800
|
+
long_desc: <<~ENDLONG,
|
|
801
|
+
Requires server-admin privileges.
|
|
802
|
+
Gracefully stop the xolo server process, optionally restarting it automatically.
|
|
803
|
+
This will attempt to finish any in-progress operations before shutting down.
|
|
804
|
+
If you don't use --restart, you must reload the launchd plist, or reboot the server machine to restart the server process.
|
|
805
|
+
ENDLONG
|
|
806
|
+
display: "#{SHUTDOWN_SERVER_CMD} [--restart]",
|
|
807
|
+
opts: {
|
|
808
|
+
restart: {
|
|
809
|
+
label: 'Restart after shutdown',
|
|
810
|
+
cli: :r,
|
|
811
|
+
type: :boolean,
|
|
812
|
+
validate: :validate_boolean,
|
|
813
|
+
default: false,
|
|
814
|
+
desc: <<~ENDDESC
|
|
815
|
+
Restart the server automatically after shutdown. If not given, you must reload the launchd plist, or reboot the server machine to restart the server process.
|
|
816
|
+
ENDDESC
|
|
817
|
+
}
|
|
818
|
+
},
|
|
819
|
+
arg_banner: :none,
|
|
820
|
+
process_method: :shutdown_server,
|
|
821
|
+
confirmation: true
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
}.freeze
|
|
825
|
+
|
|
826
|
+
# The commands that add something to xolo - how their options are processed and validated
|
|
827
|
+
# differs from those commands that just edit or report things.
|
|
828
|
+
ADD_COMMANDS = [ADD_TITLE_CMD, ADD_VERSION_CMD].freeze
|
|
829
|
+
|
|
830
|
+
EDIT_COMMANDS = [EDIT_TITLE_CMD, EDIT_VERSION_CMD].freeze
|
|
831
|
+
|
|
832
|
+
DELETE_COMMANDS = [DELETE_TITLE_CMD, DELETE_VERSION_CMD].freeze
|
|
833
|
+
|
|
834
|
+
# For these commands, the title or version must exist
|
|
835
|
+
MUST_EXIST_COMMANDS = [
|
|
836
|
+
EDIT_TITLE_CMD, EDIT_VERSION_CMD,
|
|
837
|
+
DELETE_TITLE_CMD, DELETE_VERSION_CMD, RELEASE_VERSION_CMD,
|
|
838
|
+
FREEZE_TITLE_CMD, THAW_TITLE_CMD, LIST_FROZEN_CMD, CHANGELOG_CMD, REPAIR_CMD
|
|
839
|
+
].freeze
|
|
840
|
+
|
|
841
|
+
# we get the default min os from the server
|
|
842
|
+
DEFAULT_MIN_OS_ROUTE = '/default_min_os'
|
|
843
|
+
|
|
844
|
+
# Module methods
|
|
845
|
+
##############################
|
|
846
|
+
##############################
|
|
847
|
+
|
|
848
|
+
# when this module is included
|
|
849
|
+
def self.included(includer)
|
|
850
|
+
Xolo.verbose_include includer, self
|
|
851
|
+
end
|
|
852
|
+
|
|
853
|
+
# Get the default min_os from the server.
|
|
854
|
+
# If it's been customized in the server config, you
|
|
855
|
+
# will get that value, otherwise the Xolo default.
|
|
856
|
+
# The server route is not protected, so use a one-off faraday
|
|
857
|
+
# connection to get the value.
|
|
858
|
+
#
|
|
859
|
+
# @return [String] the default min_os for versions
|
|
860
|
+
####################
|
|
861
|
+
def self.default_min_os
|
|
862
|
+
return @default_min_os if @default_min_os
|
|
863
|
+
|
|
864
|
+
url = URI.parse("https://#{Xolo::Admin.config.hostname}#{DEFAULT_MIN_OS_ROUTE}")
|
|
865
|
+
val_from_server = Faraday.new(url).get.body
|
|
866
|
+
@default_min_os = JSON.parse(val_from_server, symbolize_names: true)[:min_os]
|
|
867
|
+
rescue StandardError
|
|
868
|
+
@default_min_os = Xolo::Core::BaseClasses::Version::DEFAULT_MIN_OS
|
|
869
|
+
end
|
|
870
|
+
|
|
871
|
+
# Instance Methods
|
|
872
|
+
##########################
|
|
873
|
+
##########################
|
|
874
|
+
|
|
875
|
+
# the command definition details from Xolo::Admin::Options::COMMANDS
|
|
876
|
+
#
|
|
877
|
+
# @param cmd [Symbol] A key from Xolo::Admin::Options::COMMANDS
|
|
878
|
+
# defaults to the current cli_cmd.commadn
|
|
879
|
+
#
|
|
880
|
+
# @return [Hash] The value for the key
|
|
881
|
+
#######################
|
|
882
|
+
def cmd_details(cmd = nil)
|
|
883
|
+
cmd ||= cli_cmd.command
|
|
884
|
+
Xolo::Admin::Options::COMMANDS[cmd]
|
|
885
|
+
end
|
|
886
|
+
|
|
887
|
+
# Are we running in interactive mode?
|
|
888
|
+
# --walkthru was givin in the global opts
|
|
889
|
+
# @return [Boolean]
|
|
890
|
+
#######################
|
|
891
|
+
def walkthru?
|
|
892
|
+
global_opts.walkthru
|
|
893
|
+
end
|
|
894
|
+
|
|
895
|
+
# are we auto-confirming?
|
|
896
|
+
# --auto-confirm was given in the global opts
|
|
897
|
+
# and we are not using --walkthru
|
|
898
|
+
# @return [Boolean]
|
|
899
|
+
#######################
|
|
900
|
+
def auto_confirm?
|
|
901
|
+
global_opts.auto_confirm && !global_opts.walkthru
|
|
902
|
+
end
|
|
903
|
+
|
|
904
|
+
# do we need to ask for confirmation?
|
|
905
|
+
# the command we are running wants confirmation
|
|
906
|
+
# and auto_confirm? is false
|
|
907
|
+
# @return [Boolean]
|
|
908
|
+
#######################
|
|
909
|
+
def need_confirmation?
|
|
910
|
+
cmd_details[:confirmation] && !auto_confirm?
|
|
911
|
+
end
|
|
912
|
+
|
|
913
|
+
# are we outputing JSON?
|
|
914
|
+
# @return [Boolean]
|
|
915
|
+
#######################
|
|
916
|
+
def json?
|
|
917
|
+
global_opts.json
|
|
918
|
+
end
|
|
919
|
+
|
|
920
|
+
# are we showing debug output?
|
|
921
|
+
# @return [Boolean]
|
|
922
|
+
#######################
|
|
923
|
+
def debug?
|
|
924
|
+
global_opts.debug
|
|
925
|
+
end
|
|
926
|
+
|
|
927
|
+
# are we being quiet?
|
|
928
|
+
# --quiet was given, but --debug was not
|
|
929
|
+
# @return [Boolean]
|
|
930
|
+
#######################
|
|
931
|
+
def quiet?
|
|
932
|
+
global_opts.quiet && !debug? && !json?
|
|
933
|
+
end
|
|
934
|
+
|
|
935
|
+
# Global Opts
|
|
936
|
+
#
|
|
937
|
+
# The CLI options from xadm that come before the
|
|
938
|
+
# xadm command
|
|
939
|
+
#
|
|
940
|
+
# These are always set by Optimist.
|
|
941
|
+
#
|
|
942
|
+
# See Xolo::Admin::Options.cli_cmd_opts below for
|
|
943
|
+
# a short discussion about the optimist hash.
|
|
944
|
+
#
|
|
945
|
+
# @return [OpenStruct]
|
|
946
|
+
############################
|
|
947
|
+
def global_opts
|
|
948
|
+
@global_opts ||= OpenStruct.new
|
|
949
|
+
end
|
|
950
|
+
|
|
951
|
+
# This will hold 2 or 3 items:
|
|
952
|
+
# :command - the xadm command we are processing
|
|
953
|
+
# :title - the title arg for the xadm command
|
|
954
|
+
# :version - the version arg, if the command processes a version
|
|
955
|
+
#
|
|
956
|
+
# e.g. running `xadm edit-title foobar`
|
|
957
|
+
# - Xolo::Admin::Options.cli_cmd.command => 'edit-title'
|
|
958
|
+
# - Xolo::Admin::Options.cli_cmd.title => 'foobar'
|
|
959
|
+
# - Xolo::Admin::Options.cli_cmd.version => nil
|
|
960
|
+
#
|
|
961
|
+
# e.g. running `xadm edit-version foobar 1.2.34`
|
|
962
|
+
# - Xolo::Admin::Options.cli_cmd.command => 'edit-version'
|
|
963
|
+
# - Xolo::Admin::Options.cli_cmd.title => 'foobar'
|
|
964
|
+
# - Xolo::Admin::Options.cli_cmd.version => '1.2.34'
|
|
965
|
+
#
|
|
966
|
+
# @return [OpenStruct]
|
|
967
|
+
############################
|
|
968
|
+
def cli_cmd
|
|
969
|
+
@cli_cmd ||= OpenStruct.new
|
|
970
|
+
end
|
|
971
|
+
|
|
972
|
+
# CLI Command Opts - the options given on the command line
|
|
973
|
+
# for processing an xadm command.
|
|
974
|
+
#
|
|
975
|
+
# Will be set by Optimist in command_line.rb
|
|
976
|
+
#
|
|
977
|
+
# The options gathered by a walkthru are available in
|
|
978
|
+
# Xolo::Admin::Options.walkthru_cmd_opts
|
|
979
|
+
#
|
|
980
|
+
# The optimist data will contain a key matching every
|
|
981
|
+
# key from the option definitions hash, even if the key
|
|
982
|
+
# wasn't given on the commandline.
|
|
983
|
+
#
|
|
984
|
+
# So if there's a ':foo_bar' option defined, but --foo-bar
|
|
985
|
+
# wasn't given on the commandline,
|
|
986
|
+
# Xolo::Admin::Options.cli_cmd_opts[:foo_bar] will be set, but will
|
|
987
|
+
# be nil.
|
|
988
|
+
#
|
|
989
|
+
# More importantly, for each option that IS given on the commandline
|
|
990
|
+
# the optimist hash will contain a ':opt_name_given' key set to true.
|
|
991
|
+
# so for validation, we can only care about the values for which there
|
|
992
|
+
# is a *_given key, e.g. :foo_bar_given in the example above.
|
|
993
|
+
# See also Xolo::Admin::Validate.cli_cmd_opts.
|
|
994
|
+
#
|
|
995
|
+
# After validating the individual options provided, the values from
|
|
996
|
+
# current_values will be added to cli_cmd_opts for any options not
|
|
997
|
+
# given on the command-line. After that, the whole will be validated
|
|
998
|
+
# for internal consistency.
|
|
999
|
+
#
|
|
1000
|
+
# @return [OpenStruct]
|
|
1001
|
+
############################
|
|
1002
|
+
def cli_cmd_opts
|
|
1003
|
+
@cli_cmd_opts ||= OpenStruct.new
|
|
1004
|
+
end
|
|
1005
|
+
|
|
1006
|
+
# Walkthru Command Opts - the options given via walkthrough
|
|
1007
|
+
# for processing an xadm command.
|
|
1008
|
+
#
|
|
1009
|
+
# This is intially set with the default, inherited, or existing
|
|
1010
|
+
# values for the object being created or edited.
|
|
1011
|
+
#
|
|
1012
|
+
# Before the walk through starts, its duped and the dup
|
|
1013
|
+
# used as the current_opt_values (see below)
|
|
1014
|
+
#
|
|
1015
|
+
# In walkthru, the current_opt_values are used to generate the menu
|
|
1016
|
+
# items showing the changes being made.
|
|
1017
|
+
#
|
|
1018
|
+
# e.g. if option :foo (label: 'Foo') starts with value 'bar'
|
|
1019
|
+
# at first the menu item will look like:
|
|
1020
|
+
#
|
|
1021
|
+
# 12) Foo: bar
|
|
1022
|
+
#
|
|
1023
|
+
# but if the walkthru user changes the value to 'baz', it'll look like this
|
|
1024
|
+
#
|
|
1025
|
+
# 12) Foo: bar => baz
|
|
1026
|
+
#
|
|
1027
|
+
# The changes themselves are reflected here in walkthru_cmd_opts, and it will be
|
|
1028
|
+
# used for validation of individual options, as well as overall internal
|
|
1029
|
+
# consistency, before being applied to the object at hand.
|
|
1030
|
+
#
|
|
1031
|
+
# @return [OpenStruct]
|
|
1032
|
+
############################
|
|
1033
|
+
def walkthru_cmd_opts
|
|
1034
|
+
@walkthru_cmd_opts ||= OpenStruct.new
|
|
1035
|
+
end
|
|
1036
|
+
|
|
1037
|
+
# If the command we are running manipulates a title or version (the target), then
|
|
1038
|
+
# before we process the options given on the commandline or show the walkthru menu,
|
|
1039
|
+
# we need to know the 'current' values.
|
|
1040
|
+
#
|
|
1041
|
+
# The current values are:
|
|
1042
|
+
#
|
|
1043
|
+
# For titles:
|
|
1044
|
+
# - the default values for new titles, if it doesn't exist and we are adding it.
|
|
1045
|
+
# NB: at the moment there are no default values for new titles.
|
|
1046
|
+
# - the current values for the title, if it exists and we are editing it
|
|
1047
|
+
#
|
|
1048
|
+
# For versions:
|
|
1049
|
+
# - The default values for new versions, if we are adding the first one in a title
|
|
1050
|
+
# - The values of the most recent version, if we are adding a subsequent one for the title
|
|
1051
|
+
# - The values of this version, if we are editing an existing one
|
|
1052
|
+
#
|
|
1053
|
+
# For xadm configuration:
|
|
1054
|
+
# - The values from the config file and/or credentials from the keychain
|
|
1055
|
+
# - keychain values are not displayed in walkthru, but are shown to be
|
|
1056
|
+
# already set, or needed.
|
|
1057
|
+
#
|
|
1058
|
+
# @return [OpenStruct]
|
|
1059
|
+
#####################
|
|
1060
|
+
def current_opt_values
|
|
1061
|
+
return @current_opt_values if @current_opt_values
|
|
1062
|
+
|
|
1063
|
+
@current_opt_values = OpenStruct.new
|
|
1064
|
+
|
|
1065
|
+
opts_defs = Xolo::Admin::Options::COMMANDS[cli_cmd.command][:opts]
|
|
1066
|
+
|
|
1067
|
+
# config?
|
|
1068
|
+
if cli_cmd.command == CONFIG_CMD
|
|
1069
|
+
# Xolo::Admin::Configuration::KEYS.each_key { |key| @current_opt_values[key] = config.send(key) }
|
|
1070
|
+
opts_defs.each_key { |key| @current_opt_values[key] = config.send(key) }
|
|
1071
|
+
|
|
1072
|
+
# titles
|
|
1073
|
+
elsif title_command?
|
|
1074
|
+
|
|
1075
|
+
# adding a new one? just use defaults, if there are any
|
|
1076
|
+
if add_command?
|
|
1077
|
+
# defaults
|
|
1078
|
+
opts_defs.each do |key, deets|
|
|
1079
|
+
next if deets[:default].nil?
|
|
1080
|
+
|
|
1081
|
+
@current_opt_values[key] = deets[:default].is_a?(Proc) ? deets[:default].call : deets[:default]
|
|
1082
|
+
end
|
|
1083
|
+
|
|
1084
|
+
# editing? just use the current values
|
|
1085
|
+
elsif edit_command?
|
|
1086
|
+
current_title = Xolo::Admin::Title.fetch cli_cmd.title, server_cnx
|
|
1087
|
+
opts_defs.each_key { |key| @current_opt_values[key] = current_title.send(key) }
|
|
1088
|
+
end
|
|
1089
|
+
|
|
1090
|
+
# versions
|
|
1091
|
+
elsif version_command?
|
|
1092
|
+
|
|
1093
|
+
# adding a new one?
|
|
1094
|
+
if add_command?
|
|
1095
|
+
prev_version = Xolo::Admin::Title.latest_version cli_cmd.title, server_cnx
|
|
1096
|
+
|
|
1097
|
+
# Use the most recent version if we have one
|
|
1098
|
+
if prev_version
|
|
1099
|
+
pvers = Xolo::Admin::Version.fetch cli_cmd.title, prev_version, server_cnx
|
|
1100
|
+
opts_defs.each do |key, deets|
|
|
1101
|
+
next if deets[:do_not_inherit]
|
|
1102
|
+
|
|
1103
|
+
@current_opt_values[key] = pvers.send key
|
|
1104
|
+
end
|
|
1105
|
+
|
|
1106
|
+
# publish date is always today to start with
|
|
1107
|
+
@current_opt_values[:publish_date] = Date.today.to_s
|
|
1108
|
+
|
|
1109
|
+
# no prev version, so use the defaults
|
|
1110
|
+
else
|
|
1111
|
+
opts_defs.each do |key, deets|
|
|
1112
|
+
next if deets[:default].nil?
|
|
1113
|
+
|
|
1114
|
+
@current_opt_values[key] = deets[:default].is_a?(Proc) ? deets[:default].call : deets[:default]
|
|
1115
|
+
end
|
|
1116
|
+
end
|
|
1117
|
+
|
|
1118
|
+
# editing? just use the current values
|
|
1119
|
+
elsif edit_command?
|
|
1120
|
+
# do stuff here to fetch current values from the server.
|
|
1121
|
+
current_vers = Xolo::Admin::Version.fetch cli_cmd.title, cli_cmd.version, server_cnx
|
|
1122
|
+
opts_defs.each_key { |key| @current_opt_values[key] = current_vers.send(key) }
|
|
1123
|
+
end
|
|
1124
|
+
end
|
|
1125
|
+
|
|
1126
|
+
@current_opt_values
|
|
1127
|
+
end
|
|
1128
|
+
|
|
1129
|
+
# The options for the running command that are marked as :required
|
|
1130
|
+
###########################
|
|
1131
|
+
def required_values
|
|
1132
|
+
@required_values ||= Xolo::Admin::Options::COMMANDS[cli_cmd.command][:opts].select { |_k, v| v[:required] }
|
|
1133
|
+
end
|
|
1134
|
+
|
|
1135
|
+
end # module Options
|
|
1136
|
+
|
|
1137
|
+
end # module Admin
|
|
1138
|
+
|
|
1139
|
+
end # module Xolo
|