gazer 0.2.17 → 0.2.18
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 +4 -4
- data/.gitignore +3 -0
- data/Gemfile.lock +2 -2
- data/README.md +91 -15
- data/lib/gzr/commands/dashboard.rb +2 -0
- data/lib/gzr/commands/dashboard/cat.rb +56 -4
- data/lib/gzr/modules/filehelper.rb +1 -1
- data/lib/gzr/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2748a37dd51a0543b381ea57739cff2f15d1d437
|
4
|
+
data.tar.gz: 8638b34bc120de4baa9a50365186bd6d05d9e787
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b580425e8b9c566d0413fc5e67cfd55df01887d73f13796a5eff46f20e1b552910f3d5b63d979fa40ac17e93941a33989fd388f7b57cbd37e0d075d87ce198d8
|
7
|
+
data.tar.gz: c51d839b274280e4722d72aaf9ed761be0304a04a4b6f07b8191423c09a7c1a45859ba315169673db5469d6c16b48efa96d54ccc6b976ff2d9a3eb819d11e4f2
|
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -129,7 +129,7 @@ gzr group ls --host foo.bar.mycompany.com
|
|
129
129
|
|
130
130
|
#### group member_groups
|
131
131
|
|
132
|
-
The command `gzr group member_group GROUP_ID` will list the
|
132
|
+
The command `gzr group member_group GROUP_ID` will list the groups that have been added
|
133
133
|
as members of the given group id.
|
134
134
|
|
135
135
|
```
|
@@ -143,7 +143,7 @@ $ gzr group member_group 24 --host foo.bar.mycompany.com
|
|
143
143
|
|
144
144
|
#### group member_users
|
145
145
|
|
146
|
-
The command `gzr group member_users GROUP_ID` will list the users that have been added
|
146
|
+
The command `gzr group member_users GROUP_ID` will list the users that have been added
|
147
147
|
as members of the given group id.
|
148
148
|
|
149
149
|
```
|
@@ -239,7 +239,7 @@ John Smith
|
|
239
239
|
└── (d) Indicator Dashboard 2011
|
240
240
|
```
|
241
241
|
|
242
|
-
The same arguments are accepted as
|
242
|
+
The same arguments are accepted as the `space ls` command.
|
243
243
|
|
244
244
|
#### space cat
|
245
245
|
|
@@ -302,9 +302,9 @@ Looks and Dashboards will be located in the space directories in files named lik
|
|
302
302
|
$ gzr space export 758 --host foo.bar.mycompany.com --dir .
|
303
303
|
```
|
304
304
|
|
305
|
-
One interesting
|
306
|
-
using a tool like git. In
|
307
|
-
of content can be restored if desired.
|
305
|
+
One interesting consequence of exporting a space into a directory tree is that you can then place its
|
306
|
+
contents under version control using a tool like git. In this way user defined content changes can be
|
307
|
+
tracked over time, and older versions of content can be restored if desired.
|
308
308
|
|
309
309
|
Alternately, the space can be exported into a `tar` style archive file with the switch `--tar FILENAME`.
|
310
310
|
|
@@ -366,8 +366,8 @@ $ gzr look rm 758 --host foo.bar.mycompany.com
|
|
366
366
|
The `look import LOOK_FILE SPACE_ID` command is used to import a look from a file. If a look by the same
|
367
367
|
name exists in that space then the `--force` switch must be used.
|
368
368
|
|
369
|
-
Gazer will attempt to update
|
370
|
-
|
369
|
+
Gazer will attempt to update an existing look of the same name, rather than create a new look. In
|
370
|
+
this way the look id, share URLs, schedules, permissions, etc. will be preserved.
|
371
371
|
|
372
372
|
```
|
373
373
|
$ gzr look import Path/To/Look_123_My\ Look.json 123 --host foo.bar.mycompany.com --force
|
@@ -389,6 +389,82 @@ JSON data for dashboard
|
|
389
389
|
The output document can be very long. Usually one will use the switch `--dir DIRECTORY` to
|
390
390
|
save to a file. The file will be named `Dashboard_{DASHBOARD_ID}_{DASHBOARD_TITLE}.json`.
|
391
391
|
|
392
|
+
The `--transform FILE` switch can be used to update the output document. This is useful to automatically
|
393
|
+
perform tasks when promoting dashboards to upper environments, such as adding header or footer
|
394
|
+
text tiles, replacing model or explore names, or updating filter expressions. The `FILE` parameter
|
395
|
+
accepts a fully-qualified path to a JSON file describing the transformations to apply.
|
396
|
+
|
397
|
+
```
|
398
|
+
$ gzr dashboard cat 192 --host foo.bar.mycompany.com --transform path/to/transforms.json
|
399
|
+
JSON data for dashboard modified by any transformations expressed in the transform file
|
400
|
+
```
|
401
|
+
|
402
|
+
The transform file uses a familiar JSON syntax. Within the file, you can define any number
|
403
|
+
of `dashboard_elements` to append to your existing dashboard. Elements must be placed in either
|
404
|
+
the top row or the bottom row of the existing dashboard, specified by the `position` attribute.
|
405
|
+
You must also specify the `width` and `height` of your new elements.
|
406
|
+
|
407
|
+
You can also define any number of `replacements`, which perform a simple find and replace
|
408
|
+
within the JSON output based on the key-value pairs listed. This can be used to automatically
|
409
|
+
replace model names or update filters for existing elements. You must escape double-quotes.
|
410
|
+
|
411
|
+
Example JSON transform file:
|
412
|
+
```
|
413
|
+
{
|
414
|
+
"dashboard_elements": [
|
415
|
+
{
|
416
|
+
"position": "top",
|
417
|
+
"width": 12,
|
418
|
+
"height": 2,
|
419
|
+
"body_text": "Production Version of Dashboard (deployed 2019-06-18)",
|
420
|
+
"body_text_as_html": "<p>Production Version of Dashboard (deployed 2019-06-18)</p>",
|
421
|
+
"note_display": null,
|
422
|
+
"note_state": null,
|
423
|
+
"note_text": null,
|
424
|
+
"note_text_as_html": null,
|
425
|
+
"subtitle_text": "",
|
426
|
+
"title": null,
|
427
|
+
"title_hidden": false,
|
428
|
+
"title_text": "",
|
429
|
+
"type": "text"
|
430
|
+
},
|
431
|
+
{
|
432
|
+
"position": "bottom",
|
433
|
+
"width": 6,
|
434
|
+
"height": 2,
|
435
|
+
"body_text": "Please contact the Business Intelligence Help Desk for any issues with this dashboard",
|
436
|
+
"body_text_as_html": "<p>Please contact the Business Intelligence Help Desk for any issues with this dashboard</p>",
|
437
|
+
"note_display": null,
|
438
|
+
"note_state": null,
|
439
|
+
"note_text": null,
|
440
|
+
"note_text_as_html": null,
|
441
|
+
"subtitle_text": "",
|
442
|
+
"title": null,
|
443
|
+
"title_hidden": false,
|
444
|
+
"title_text": "",
|
445
|
+
"type": "text"
|
446
|
+
}
|
447
|
+
],
|
448
|
+
"replacements": [
|
449
|
+
{
|
450
|
+
"\"model\": \"staging\",": "\"model\": \"production\","
|
451
|
+
},
|
452
|
+
{
|
453
|
+
"\"filter_expression\": \"not(is_null(${view.allowed_user}))\": "\"filter_expression\": \"${view.allowed_user} = _user_attributes['username']\","
|
454
|
+
}
|
455
|
+
]
|
456
|
+
}
|
457
|
+
```
|
458
|
+
| WARNING: You will not be able to overwrite dashboards that have been transformed! |
|
459
|
+
| --- |
|
460
|
+
|
461
|
+
In other words, you can’t use the `--force` switch to replace a previously-transformed dashboard. Instead,
|
462
|
+
you’ll need to delete and recreate the dashboard. If you have stable content URLs enabled on your
|
463
|
+
instance, the `slug` parameter ensures the URL for your dashboard won’t change.
|
464
|
+
|
465
|
+
This is because it is impossible to know the element IDs for elements that were added by the `--transform` operation,
|
466
|
+
which makes it impossible to synchronize these elements in the future.
|
467
|
+
|
392
468
|
#### dashboard rm
|
393
469
|
|
394
470
|
The `dashboard rm DASHBOARD_ID` command is used to delete a dashboard.
|
@@ -399,13 +475,13 @@ $ gzr dashboard rm 192 --host foo.bar.mycompany.com
|
|
399
475
|
|
400
476
|
#### dashboard import
|
401
477
|
|
402
|
-
The `dashboard import
|
403
|
-
its associated looks from a file. If a
|
478
|
+
The `dashboard import DASHBOARD_FILE SPACE_ID` command is used to import a dashboard and
|
479
|
+
its associated looks from a file. If a dashboard or look by the same
|
404
480
|
name exists in that space then the `--force` switch must be used.
|
405
481
|
|
406
|
-
Gazer will attempt to update
|
407
|
-
create a new dashboard or look. In
|
408
|
-
|
482
|
+
Gazer will attempt to update an existing dashboard or look of the same name,
|
483
|
+
rather than create a new dashboard or look. In this way the id, share URLs,
|
484
|
+
schedules, permissions, etc. will be preserved.
|
409
485
|
|
410
486
|
```
|
411
487
|
$ gzr dashboard import Path/To/Dashboard_123_My\ Dash.json 123 --host foo.bar.mycompany.com --force
|
@@ -417,7 +493,7 @@ The command `gzr connection help` will show details about subcommands of the con
|
|
417
493
|
|
418
494
|
#### connection ls
|
419
495
|
|
420
|
-
The command `gzr connection ls` will list the connections that
|
496
|
+
The command `gzr connection ls` will list the connections that exist in the Looker instance.
|
421
497
|
|
422
498
|
```
|
423
499
|
$ gzr connection ls --host foo.bar.mycompany.com
|
@@ -492,7 +568,7 @@ The command `gzr model help` will show details about subcommands of the model co
|
|
492
568
|
|
493
569
|
#### model ls
|
494
570
|
|
495
|
-
The command `gzr model ls` will list the models that
|
571
|
+
The command `gzr model ls` will list the models that exist in the Looker instance.
|
496
572
|
|
497
573
|
```
|
498
574
|
$ gzr model ls --host foo.bar.mycompany.com
|
@@ -36,6 +36,8 @@ module Gzr
|
|
36
36
|
desc: 'Directory to store output file'
|
37
37
|
method_option :plans, type: :boolean,
|
38
38
|
desc: 'Include scheduled plans'
|
39
|
+
method_option :transform, type: :string,
|
40
|
+
desc: 'Fully-qualified path to a JSON file describing the transformations to apply'
|
39
41
|
def cat(dashboard_id)
|
40
42
|
if options[:help]
|
41
43
|
invoke :help, ['cat']
|
@@ -43,8 +43,9 @@ module Gzr
|
|
43
43
|
def execute(*args, input: $stdin, output: $stdout)
|
44
44
|
say_warning("options: #{@options.inspect}") if @options[:debug]
|
45
45
|
with_session("3.1") do
|
46
|
-
|
47
|
-
data.to_attrs
|
46
|
+
result = query_dashboard(@dashboard_id)
|
47
|
+
data = result.to_attrs
|
48
|
+
data[:dashboard_elements].each_index do |i|
|
48
49
|
element = data[:dashboard_elements][i]
|
49
50
|
if element[:merge_result_id]
|
50
51
|
merge_result = merge_query(element[:merge_result_id])
|
@@ -56,8 +57,59 @@ module Gzr
|
|
56
57
|
end
|
57
58
|
end
|
58
59
|
data[:scheduled_plans] = query_scheduled_plans_for_dashboard(@dashboard_id,"all") if @options[:plans]
|
59
|
-
|
60
|
-
|
60
|
+
|
61
|
+
replacements = {}
|
62
|
+
if @options[:transform]
|
63
|
+
|
64
|
+
max_row = 0
|
65
|
+
data[:dashboard_layouts][0][:dashboard_layout_components].each_index do |i|
|
66
|
+
component = data[:dashboard_layouts][0][:dashboard_layout_components][i]
|
67
|
+
if component[:row] + component[:height] > max_row
|
68
|
+
max_row = component[:row] + component[:height] + 4
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
read_file(@options[:transform]) do |transform|
|
73
|
+
i = 0
|
74
|
+
transform[:dashboard_elements].collect! do |e|
|
75
|
+
i += 1
|
76
|
+
# there is no significance to 9900, we just need to prevent ID collisions
|
77
|
+
e['id'] = 9900 + i
|
78
|
+
data[:dashboard_elements] << e
|
79
|
+
|
80
|
+
# when inserting an element into the top row, shift the other elements down according to the height of the inserted element
|
81
|
+
if e[:position] === 'top'
|
82
|
+
data[:dashboard_layouts][0][:dashboard_layout_components].each_index do |i|
|
83
|
+
component = data[:dashboard_layouts][0][:dashboard_layout_components][i]
|
84
|
+
component[:row] = component[:row] + e[:height]
|
85
|
+
end
|
86
|
+
row = '0'
|
87
|
+
elsif e[:position] === 'bottom'
|
88
|
+
row = max_row.to_s
|
89
|
+
end
|
90
|
+
|
91
|
+
column = '0'
|
92
|
+
width = e[:width].to_s
|
93
|
+
height = e[:height].to_s
|
94
|
+
data[:dashboard_layouts][0][:dashboard_layout_components] << JSON.parse('{"id":' + e['id'].to_s + ',"dashboard_layout_id":1,"dashboard_element_id":' + e['id'].to_s + ''',"row":' + row + ',"column":' + column + ',"width":' + width + ',"height":' + height + ',"deleted":false,"element_title_hidden":false,"vis_type":"' + e[:type].to_s + '","can":{"index":true,"show":true,"create":true,"update":true,"destroy":true}}')
|
95
|
+
end
|
96
|
+
|
97
|
+
transform[:replacements].collect! do |e|
|
98
|
+
replacements[e.keys.first.to_s] = e[e.keys[0]]
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
outputJSON = JSON.pretty_generate(data)
|
105
|
+
|
106
|
+
replacements.each do |k,v|
|
107
|
+
say_warning("Replaced #{k} with #{v}") if @options[:debug]
|
108
|
+
outputJSON.gsub! k,v
|
109
|
+
end
|
110
|
+
|
111
|
+
write_file(@options[:dir] ? "Dashboard_#{result.id}_#{result.title}.json" : nil, @options[:dir], nil, output) do |f|
|
112
|
+
f.puts outputJSON
|
61
113
|
end
|
62
114
|
end
|
63
115
|
end
|
@@ -49,7 +49,7 @@ module Gzr
|
|
49
49
|
test_dir = base + Pathname.new(path_part)
|
50
50
|
Dir.mkdir(test_dir) unless (test_dir.exist? && test_dir.directory?)
|
51
51
|
end if p
|
52
|
-
file = Pathname.new(file_name.gsub('/',"\u{2215}")) if file_name
|
52
|
+
file = Pathname.new(file_name.gsub('/',"\u{2215}").gsub(':','')) if file_name
|
53
53
|
file = p + file if p
|
54
54
|
file = base + file if base
|
55
55
|
f = File.open(file, "wt") if file
|
data/lib/gzr/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gazer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.18
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike DeAngelo
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-11-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: tty-reader
|