-
Notifications
You must be signed in to change notification settings - Fork 4
/
sample-app.yaml
468 lines (432 loc) · 16.7 KB
/
sample-app.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
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
100
101
102
103
104
105
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
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
219
220
221
222
223
224
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
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
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
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
name: sample
description: A sample application demonstrating App Builder features
version: 0.1.1
author: R.I.Pienaar <[email protected]>
# We set the default help template, also try 'long', 'compact' and 'short'
help_template: default
# A top level cheat block enables cheats in general for this application,
# see other cheats added later on under exec
cheat:
label: sample
cheat: |
# to see all the commands available
sample --help-compact
commands:
- name: basics
description: Demonstrates basic features such as flags and arguments
type: parent
aliases:
- basic
- b
commands:
# Demonstrates the use of arguments and flags, mixing in arguments for main
# functionality and flags for optional behavior changes.
#
# Also uses Go templates to adjust the command based on the flags given and
# checks input is valid.
- name: required
description: Greet someone by name, name+surname with a customizable greeting
type: exec
# Here we use arguments for the name and surname, the name is required but surname is optional.
arguments:
- name: name
description: The name of the person to greet
required: true
validate: len(value) < 20
- name: surname
description: An optional surname of the person to greet
# We add an optional flag to override the "Hello" greeting
# It accepts only one of the 3 valid values
flags:
- name: greeting
description: The greeting to use instead of Hello
default: Hello
env: GREETING
short: g
enum:
- Hello
- Morning
- Halo
# We use go templates and the default + require functions to ensure users do not set empty
# strings such as "sample basics required ''" which would set the name to an empty string,
# in that case we would fail stating a name is required.
#
# In the case of an empty greeting, we fall back to the default "Hello"
command: |
{{ if .Arguments.surname }}
echo '{{ .Flags.greeting }} {{.Arguments.surname}}, {{ require .Arguments.name "a name is required" }} {{.Arguments.surname}}'
{{ else }}
echo '{{ .Flags.greeting }} {{ require .Arguments.name "a name is required" }}'
{{ end }}
# Here we add 2 boolean flags, the "banner" flag will have --no-banner and --banner
# flags added as it's defaulting to true
#
# The "silent" flag will not have --no-silent as the default is false
- name: booleans
description: Demonstrates the use of boolean flags
type: exec
flags:
- name: banner
description: Includes a descriptive banner
default: true
bool: true
- name: silent
description: Do not produce any output
bool: true
# Here we use a shell script to demonstrate accessing variables and doing
# logic on those variables, booleans will always be "true" and "false" strings
# in this pattern
shell: /bin/bash
script: |
if [ "{{ .Flags.silent }}" == "false" ]
then
if [ "{{ .Flags.banner }}" == "true" ]
then
echo ">> This is a banner describing the command, can be disabled with --no-banner"
echo ">> The command just shows "hello world" unless --silent is passed"
echo
fi
echo "Hello world"
fi
# The confirm_prompt will require user enters y/n before running the command,
# it will also add --no-prompt as an option to skip the prompt from within scripts
- name: confirm
description: Demonstrates use of confirm_prompt to ask for confirmation
type: exec
# adds a specific cheat accessible as "sample cheat exec"
cheat:
label: confirm
cheat: |
# to be asked a confirmation
sample exec confirm
sample exec confirm --no-prompt
confirm_prompt: Are you sure you wish to execute the command
command: echo "execution confirmed, will run command"
# Banners are shown to users before a command is run, use this if for example you will
# run a command through sudo to explain that the user will need to enter his password, or
# really just any time you want to pass on information to the user about the workings of
# a command
- name: banner
description: Demonstrates a warning banner above the execution
type: exec
banner: |
>>>
>>> This is a banner shown above the command, use it to warn or inform
>>> users about details about your command
>>>
command: echo "Command output"
- name: scaffold
description: Demonstrate scaffold features by creating some go files and processing with goimports and gofmt
type: scaffold
arguments:
- name: author
description: Who to create a file for
required: true
- name: package
description: The package URL to create
required: true
- name: target
description: The target to create the files in
required: true
flags:
- name: goversion
description: The version of Go to require
default: "1.21.0"
banner: |
>>>
>>> Creating basic go package {{.Arguments.package}} for Go {{.Flags.goversion}} in {{.Arguments.target}} run 'go mod tidy' to get started
>>>
target: "{{ .Arguments.target }}"
source:
"_partials":
"go_copyright": // Copyright {{ .Arguments.author }} {{ now | date "2006" }}
"md_copyright": '## Copyright {{ .Arguments.author }} {{ now | date "2006" }}'
"cmd":
"cmd.go": |
{{ render "_partials/go_copyright" . }}
package cmd
func Run() {
fmt.Println("Scaffolded using App Builder")
}
"main.go": |
{{ render "_partials/go_copyright" . }}
{{- render "_partials/md_copyright" . | write "README.md" }}
package main
import "{{ .Arguments.package }}/cmd"
func main() {cmd.Run()}
"go.mod": |
module {{.Arguments.package }}
go {{.Flags.goversion}}
post:
- "*.go": "gofmt -w"
- name: exec
description: Demonstrate exec features
type: parent
aliases:
- e
commands:
- name: hello
description: Basic exec example
type: exec
arguments:
- name: name
description: Who to greet
required: true
command: echo "Hello {{ .Arguments.name }}"
# Here we set an environment variable from a input argument and access it in the script
- name: env
description: Demonstrates setting custom environment variables from a required argument
type: exec
arguments:
- name: value
description: The value to pass into the environment
required: true
environment:
- APPVAR="{{.Arguments.value}}"
script: |
echo "The supplied value set in APPVAR: ${APPVAR?}"
- name: shell_helper
type: exec
description: Demonstrates using shell helper functions
script: |
set -e
. "{{ BashHelperPath }}"
AB_ANNOUNCE_PREFIX="???"
ab_announce Demonstrates using the shell helper
- name: form
type: form
description: Demonstrates use of the form based data generator
properties:
- name: listen
description: The network address and port to listen on
required: true
default: 127.0.0.1:-1
help: Examples include localhost:4222, 192.168.1.1:4222 or 127.0.0.1:4222
- name: accounts
description: Multiple accounts
help: |
Sets up local accounts for user access.
type: object
empty: absent
properties:
- name: users
description: Users to add to the account
required: true
type: array
properties:
- name: user
description: The username to connect as
required: true
- name: password
description: The password to connect with
type: password
required: true
- name: leafnode
description: Leafnode connection details
required: true
help: |
Configures individual leafnode connection properties
See https://docs.nats.io/running-a-nats-service/configuration/leafnodes/leafnode_conf
for details about all possible values
properties:
- name: listen
description: The network address and port to listen on
help: Examples include localhost:7422, 192.168.1.1:7422 or 127.0.0.1:7422
empty: absent
- name: remotes
description: List of remotes to connect to
type: array
required: true
properties:
- name: url
description: Connection URL
help: Choose the NGS endpoint location
enum:
- nats-leaf://connect.ngs.global:6222
- nats-leaf://apsoutheast2.aws.cloud.ngs.global
- nats-leaf://asiaeast1.gcp.cloud.ngs.global
- nats-leaf://australiaeast.az.cloud.ngs.global
- nats-leaf://europewest3.gcp.cloud.ngs.global
- nats-leaf://europewest.az.cloud.ngs.global
- nats-leaf://euwest1.aws.cloud.ngs.global
- nats-leaf://japaneast.az.cloud.ngs.global
- nats-leaf://uscentral1.gcp.cloud.ngs.global
- nats-leaf://useast1.gcp.cloud.ngs.global
- nats-leaf://useast2.aws.cloud.ngs.global
- nats-leaf://uswest1.gcp.cloud.ngs.global
- nats-leaf://uswest2.aws.cloud.ngs.global
- nats-leaf://uswest2.az.cloud.ngs.global
- name: credentials
description: NATS credentials file
help: Uses a credentials file to authenticate to the remote server
empty: absent
validation: hasPrefix(value, '/')
- name: thing
description: Adds a thing if accounts are set
empty: absent
conditional: Input.accounts != nil
- name: include
type: parent
include_file: go.yaml
- name: transforms
description: Demonstrate transform features
type: parent
aliases:
- transform
- trans
- t
commands:
# This fetches the latest release information from GitHub
# and transform the JSON response using JQ to show latest
# release and release notes.
#
# It requires curl in your PATH and access to the internet.
- name: jq
description: Demonstrates transforming data using jq
type: exec
arguments:
- name: owner
description: Sets a repository owner to query
default: choria-io
- name: repo
description: Sets a repository name to query
default: appbuilder
banner: |
>>>
>>> This command uses curl to fetch data from GitHub
>>>
transform:
jq:
query: |
if ( .message | length ) == 0 then
"The latest release is: " + .name + "\n\n" + .body
else
"Release lookup failed: " + .message + "\n\n"
end
command: |
curl -s https://api.github.com/repos/{{ .Arguments.owner }}/{{ .Arguments.repo }}/releases/latest
# This fetches weather forecast from wttr.in and draws the
# hourly forecast via a transform pipeline involving JQ to
# extract the data and a line graph to draw it
#
# It requires curl in your PATH and access to the internet.
- name: linegraph
description: Draws an ASCII line graph
type: exec
banner: |
>>>
>>> This command uses curl to fetch data from wttr.in
>>>
flags:
- name: caption
description: The graph caption
default: Hourly weather forecast (C)
transform:
pipeline:
- jq:
query: |
.weather[0].hourly|.[]|.FeelsLikeC
- line_graph:
width: 40
height: 10
caption: "{{ .Flags.caption }}"
command: |
curl -s wttr.in/?format=j1
# This fetches release information from GitHub, uses a pipeline
# to extract the assets using JQ and then a bar graph to draw
# release asset sizes by asset name
#
# It requires curl in your PATH and access to the internet.
- name: bargraph
description: Draws an ASCII bar graph
type: exec
banner: |
>>>
>>> This command uses curl to fetch data from GitHub
>>>
flags:
- name: caption
description: The graph caption
default: Latest release asset sizes
transform:
pipeline:
- jq:
query: |
.assets|map({(.name): .size})|reduce .[] as $a ({}; . + $a)
- bar_graph:
caption: "{{.Flags.caption}}"
bytes: true
command: |
curl -s https://api.github.com/repos/choria-io/appbuilder/releases/latest
# This uses a template transform with sprig functions to transform
# JSON input into a textual format
- name: template
type: exec
description: Demonstrates template processing of JSON input
command: |
echo '{"name": "James", "surname":"Bond"}'
transform:
template:
contents: |
Hello {{ .Input.name }} {{ .Input.surname | swapcase }}
# This fetches latest releases from github and uses the to_yaml transform
# to show it as yaml instead of JSON
- name: to_yaml
type: exec
banner: |
>>
>> This fetches information about the latest appbuilder release
>> rendered in YAML format
description: Demonstrates using a to_yaml transform
command: curl -s https://api.github.com/repos/choria-io/appbuilder/releases/latest
transform:
pipeline:
- to_yaml: {}
- write_file:
file: /tmp/report.yaml
# This fetches latest releases from github and uses the to_json transform
# to compact it into unindented json
- name: to_json
type: exec
banner: |
>>
>> This fetches information about the latest appbuilder release
>> rendered in unindented JSON format
description: Demonstrates using a to_json transform
command: curl -s https://api.github.com/repos/choria-io/appbuilder/releases/latest
transform:
pipeline:
- to_json: {}
- write_file:
file: /tmp/report.json
# This fetches latest releases from github and uses the report transform to
# turn that into a tabular report of downloads including a total downloads counter
- name: report
type: exec
banner: |
>>
>> This fetches information about the latest appbuilder release
>> and generates a report of asset sizes and downloads.
>>
>> The report is also saved to /tmp/report.txt.
>>
description: Demonstrates using a report writer transform
command: curl -s https://api.github.com/repos/nats-io/nats-server/releases/latest
transform:
pipeline:
- report:
name: Asset Report
initial_query: assets
header: |+
@||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
data.name
---------------------------------------------------------------------------------
body: |
Name: @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Size: @B###### Downloads: @###
row.name, row.size, row.download_count
footer: |+2
=====================
Total Downloads: @###
report.summary.download_count
- write_file:
file: /tmp/report.txt